Giter VIP home page Giter VIP logo

md2conf's Introduction

Publish Markdown files to Confluence wiki

Contributors to software projects typically write documentation in Markdown format and host Markdown files in collaborative version control systems (VCS) such as GitHub or GitLab to track changes and facilitate the review process. However, not everyone at a company has access to VCS, and documents are often circulated in Confluence wiki instead.

Replicating documentation to Confluence by hand is tedious, and a lack of automated synchronization with the project repositories where the documents live leads to outdated documentation.

This Python package

  • parses Markdown files,
  • converts Markdown content into the Confluence Storage Format (XHTML),
  • invokes Confluence API endpoints to upload images and content.

Features

  • Sections and subsections
  • Text with bold, italic, monospace, underline and strikethrough
  • Link to external locations
  • Ordered and unordered lists
  • Code blocks (e.g. Python, JSON, XML)
  • Image references (uploaded as Confluence page attachments)
  • Table of Contents
  • Admonitions (converted into info, tip, note and warning Confluence panels)

Getting started

In order to get started, you will need

  • your organization domain name (e.g. instructure.atlassian.net),
  • base path for Confluence wiki (typically /wiki/ for managed Confluence, / for on-premise)
  • your Confluence username (e.g. [email protected]) (only if required by your deployment),
  • a Confluence API token (a string of alphanumeric characters), and
  • the space key in Confluence (e.g. DAP) you are publishing content to.

Obtaining an API token

  1. Log in to https://id.atlassian.com/manage/api-tokens.
  2. Click Create API token.
  3. From the dialog that appears, enter a memorable and concise Label for your token and click Create.
  4. Click Copy to clipboard, then paste the token to your script, or elsewhere to save.

Setting up the environment

Confluence organization domain, base path, username, API token and space key can be specified at runtime or set as Confluence environment variables (e.g. add to your ~/.profile on Linux, or ~/.bash_profile or ~/.zshenv on MacOS):

export CONFLUENCE_DOMAIN='instructure.atlassian.net'
export CONFLUENCE_PATH='/wiki/'
export CONFLUENCE_USER_NAME='[email protected]'
export CONFLUENCE_API_KEY='0123456789abcdef'
export CONFLUENCE_SPACE_KEY='DAP'

On Windows, these can be set via system properties.

Permissions

The tool requires appropriate permissions in Confluence in order to invoke endpoints.

If a Confluence username is set, the tool uses HTTP Basic authentication to pass the username and the API key to Confluence REST API endpoints. If no username is provided, the tool authenticates with HTTP Bearer, and passes the API key as the bearer token.

If you lack appropriate permissions, you will get an Unauthorized response from Confluence. The tool will emit a message that looks as follows:

2023-06-30 23:59:59,000 - ERROR - <module> [80] - 401 Client Error: Unauthorized for url: ...

Associating a Markdown file with a wiki page

Each Markdown file is associated with a Confluence wiki page with a Markdown comment:

<!-- confluence-page-id: 85668266616 -->

The above tells the tool to synchronize the Markdown file with the given Confluence page ID. This implies that the Confluence wiki page must exist such that it has an ID. The comment can be placed anywhere in the source file.

Setting the Confluence space

If you work in an environment where there are multiple Confluence spaces, and some Markdown pages may go into one space, whereas other pages may go into another, you can set the target space on a per-document basis:

<!-- confluence-space-key: DAP -->

This overrides the default space set via command-line arguments or environment variables.

Setting generated-by prompt text for wiki pages

In order to ensure readers are not editing a generated document, the tool adds a warning message at the top of the Confluence page as an info panel. You can customize the text that appears. The text can contain markup as per the Confluence Storage Format, and is emitted directly into the info panel macro.

Provide generated-by prompt text in the Markdown file with a tag:

<!-- generated-by: Do not edit! Check out the <a href="https://example.com/project">original source</a>. -->

Alternatively, use the --generated-by GENERATED_BY option. The tag takes precedence.

Running the tool

You execute the command-line tool md2conf to synchronize the Markdown file with Confluence:

$ python3 -m md2conf sample/example.md

Use the --help switch to get a full list of supported command-line options:

$ python3 -m md2conf --help
usage: md2conf [-h] [-d DOMAIN] [-p PATH] [-u USERNAME] [-a APIKEY] [-s SPACE] [-l {debug,info,warning,error,critical}] [-r ROOT_PAGE] [--generated-by GENERATED_BY]
               [--no-generated-by] [--ignore-invalid-url] [--local]
               mdpath

positional arguments:
  mdpath                Path to Markdown file or directory to convert and publish.

optional arguments:
  -h, --help            show this help message and exit
  -d DOMAIN, --domain DOMAIN
                        Confluence organization domain.
  -p PATH, --path PATH  Base path for Confluence (default: '/wiki/').
  -u USERNAME, --username USERNAME
                        Confluence user name.
  -a APIKEY, --apikey APIKEY
                        Confluence API key. Refer to documentation how to obtain one.
  -s SPACE, --space SPACE
                        Confluence space key for pages to be published. If omitted, will default to user space.
  -l {debug,info,warning,error,critical}, --loglevel {debug,info,warning,error,critical}
                        Use this option to set the log verbosity.
  -r ROOT_PAGE          Root Confluence page to create new pages. If omitted, will raise exception when creating new pages.
  --generated-by GENERATED_BY
                        Add prompt to pages (default: 'This page has been generated with a tool.').
  --no-generated-by     Do not add 'generated by a tool' prompt to pages.
  --ignore-invalid-url  Emit a warning but otherwise ignore relative URLs that point to ill-specified locations.
  --local               Write XHTML-based Confluence Storage Format files locally without invoking Confluence API.

md2conf's People

Contributors

adamgagorik avatar dgeorges avatar gmous avatar hunyadi avatar jloeser avatar pavelkestefran avatar vladistan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

md2conf's Issues

Links from ./foo/bar.md to ../baz/foo-bar.md issues

Hi there, thanks for writing this project - its proving super helpful for one of my use cases.

I've noticed something that seems to be throwing consistent exceptions. (haven't had time to dig in yet but thought I'd log this one in case)

in a markdown file in a location like ./foo/bar.md that has a relative link to [link](../blah/something.md) It appears that the code throws this exception - Even though the relative link is valid for that file location.

File "/Users/user/src/work/md2conf/md2conf/converter.py", line 260, in _transform_link
    raise DocumentError(f"relative URL points to outside base path: {url}")
md2conf.converter.DocumentError: relative URL points to outside base path: ../blah/something.md

Will attempt to debug this soon and may submit a PR if I figure it out.

Thanks!

This page has been generated with a tool.

When I publish my markdown file to confluence, the confluence page shows a prompt at the top of the page saying "This page has been generated with a tool.". How do I disable it?

Is there any way to export a subfolder as a file?

Hello, first of all thanks for this great work.
Is there any way to export a subfolder as a file?
When I export a subfolder that contains some .md files they are being exported to the root page id (the one defined by the argument: -r $page_id) so there´s no way to have child pages like the ones used in Confluence.
Any workaround for this?

Thank you!

AttributeError: 'str' object has no attribute 'removeprefix'

Hi! When trying to use md2conf in a GitHub action I am getting this error:

Traceback (most recent call last):
  File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/runner/.local/lib/python3.8/site-packages/md2conf/__main__.py", line 59, in <module>
    synchronize_page(api, args.mdfile)
  File "/home/runner/.local/lib/python3.8/site-packages/md2conf/application.py", line 28, in synchronize_page
    update_document(api, document, base_path)
  File "/home/runner/.local/lib/python3.8/site-packages/md2conf/application.py", line [11](https://github.com/scrive/…#step:5:12), in update_document
    api.upload_attachment(
  File "/home/runner/.local/lib/python3.8/site-packages/md2conf/api.py", line 240, in upload_attachment
    self._update_attachment(page_id, attachment_id, version, attachment_name)
  File "/home/runner/.local/lib/python3.8/site-packages/md2conf/api.py", line 245, in _update_attachment
    id = attachment_id.removeprefix("att")
AttributeError: 'str' object has no attribute 'removeprefix'

Is it something I can fix on my end?

Improve internal links (=header anchors) handling

Currently, only external links are supported. However, there might be documents using header anchors for internal reference.

Example:

$ cat internal-link.md
<!-- confluence-page-id: 367198209 -->

Foo

# Test1

Bar

# Test2

See [link](#test1)

See [link](internal-link.md#test2)

Both links are valid (GitLab flavored) Markdown according to https://docs.gitlab.com/ee/user/markdown.html#links

Actual behavior is DocumentError:

2023-08-16 12:15:33,798 - DEBUG - _transform_link [180] - found link #test1 relative to /home/user/internal-link.md
Traceback (most recent call last):
...
md2conf.converter.DocumentError: relative URL points to outside base path: #test1

Would be nice to either convert them them accordingly in Confluence (no idea if this is feasible) or to somehow ignore them/change representation. In any case, a valid document should be created.

400 client error for a child attachment

The file I'm trying to publish has an image linked in it.
The Confluence API returns a 400 when I use md2conf.

Unfortunately the API is not very talkative about the reason of the error, and perhaps the image is a red herring and the real reson is elsewhere.

Here is the stacktrace:

2023-05-30 17:46:45,724 - INFO - upload_attachment [221] - Uploading attachment: ./multi-sign-graph.png
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/site-packages/md2conf/__main__.py", line 59, in <module>
    synchronize_page(api, args.mdfile)
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/site-packages/md2conf/application.py", line 28, in synchronize_page
    update_document(api, document, base_path)
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/site-packages/md2conf/application.py", line 11, in update_document
    api.upload_attachment(
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/site-packages/md2conf/api.py", line 228, in upload_attachment
    response.raise_for_status()
  File "/opt/hostedtoolcache/Python/3.10.11/x64/lib/python3.10/site-packages/requests/models.py", line 10[21](https://github.com/[…]), in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://[…]/child/attachment

Relative links to gitlab files

Hi,

I have some Gitlab Markdown documents that I want to export to Confluence. Everything is working smooth except relative links to files in gitlab.

Example:
- [.gitlab-ci.yml](.gitlab-ci.yml)

It returns the following error:
Processing README.md 2023-11-06 11:35:02,249 - INFO - _synchronize_page [87] - Synchronizing page: README.md Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/local/lib/python3.12/site-packages/md2conf/__main__.py", line 85, in <module> Application(api, ConfluenceDocumentOptions(args.generated_by)).synchronize( File "/usr/local/lib/python3.12/site-packages/md2conf/application.py", line 34, in synchronize self.synchronize_page(path) File "/usr/local/lib/python3.12/site-packages/md2conf/application.py", line 41, in synchronize_page self._synchronize_page(page_path, dict()) File "/usr/local/lib/python3.12/site-packages/md2conf/application.py", line 88, in _synchronize_page document = ConfluenceDocument(page_path, self.options, page_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 531, in __init__ converter.visit(self.root) File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 198, in visit self.visit(source) File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 194, in visit target = self.transform(source) ^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 420, in transform return self._transform_link(child) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 260, in _transform_link raise DocumentError(f"unable to find matching page for URL: {url}") md2conf.converter.DocumentError: unable to find matching page for URL: .gitlab-ci.yml

Is there an option or possibility to add a feature, that relative links will be converted to text, so the pipeline will not fail? Or does someone have a better idea?

Thanks a lot!

Fail to update page with attached image. It tries to upload it again

With the markdown file

<!-- confluence-space-key: MYSPACE -->
<!-- confluence-page-id: 1234567890 -->

# example

![confluence log](./img/confluence.png)

I get

2023-09-18 15:20:46,528 - ERROR - <module> [93] - {'statusCode': 400, 'data': {'authorized': True, 'valid': True, 'errors': [], 'successful': True}, 'message': 'com.atlassian.confluence.api.service.exceptions.BadRequestException: Cannot add a new attachment with same file name as an existing attachment: confluence.png'}

"unable to find matching page for URL: {url}"

Since version 0.19 I experience a problem when rendering email addresses. The following error message appears:

2023-10-19 06:33:28,517 - INFO - _synchronize_page [87] - Synchronizing page: README.md Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/local/lib/python3.12/site-packages/md2conf/__main__.py", line 85, in <module> Application(api, ConfluenceDocumentOptions(args.generated_by)).synchronize( File "/usr/local/lib/python3.12/site-packages/md2conf/application.py", line 34, in synchronize self.synchronize_page(path) File "/usr/local/lib/python3.12/site-packages/md2conf/application.py", line 41, in synchronize_page self._synchronize_page(page_path, dict()) File "/usr/local/lib/python3.12/site-packages/md2conf/application.py", line 88, in _synchronize_page document = ConfluenceDocument(page_path, self.options, page_metadata) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 5[31](https://gitlab.*****), in __init__ converter.visit(self.root) File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 198, in visit self.visit(source) File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 198, in visit self.visit(source) File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 194, in visit target = self.transform(source) ^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line [42](https://gitlab*****)0, in transform return self._transform_link(child) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/md2conf/converter.py", line 260, in _transform_link raise DocumentError(f"unable to find matching page for URL: {url}") md2conf.converter.DocumentError: unable to find matching page for URL: mailto:[email protected]

warning and notes appear to render incorrectly

I just published a test page

!!! info "optional explicit title within double quotes"
    Any number of other indented markdown elements.

    This is the second paragraph.

!!! warning
    You should note that the title will be automatically capitalized.

!!! tip
    You should note that the title will be automatically capitalized.

!!! note
    "Don't try this at home"
    ...

Appears to render in confluence as

image

I'd expect the note to render as
image

warning to be
image

And error to be
image

Pictures in a subfolder don't show

When a markdown document references a picture in a subfolder:

![my picture](images/picture.jpg)

The picture is properly uploaded as attachment to the confluence page. But it is not displayed.

When looking at the attachment in confluence (which is named images/picture.jpg, I cannot display the picture either.

This is a common use case, so documenting this as limitation is not very friendly.

Support "Info Panel" (incl. all other derivates) in text

We already use an Info Panel for the generated-by message at the very top of the document.

Could we enable this feature also in the normal text including its derivatives ("Note", "Success", "Warning", "Error")?

The current notation I am using in Markdown for such boxes (there is no concept of "Info Panels" in Markdown) is:

Normal text.

> **_NOTE:_**
> This is my Note. There can be **many** lines.
> Last one is this one.

Normal text.

Invalid href with local url

Hi,
I found that commit
This related to self ref href.
With markdown the valid syntax is :

## Test of link

## Test of Href
[test](#test-of-link)

With [test](#Test-of-link) markdown lint will show a warning

However the confluence link is not generated properly as it should be smth like:

https://url-of-page#1.2.4.-Test-of-link
1.2.4 is the index in the toc and first letter of the lin shall be capitalize.
Something related to this portion of the code might need an update to make that work:

        if (
            not relative_url.scheme
            and not relative_url.netloc
            and not relative_url.path
            and not relative_url.params
            and not relative_url.query
        ):
            LOGGER.debug(f"found local URL: {url}")
            anchor.attrib["href"] = url
            return

Thanks in advance

Conversion is not working properly

I'm trying to publish a markdown file and the format and the style is really bad, am I doing something wrong?

Neither the text or the code block is showed properly:
Captura de pantalla 2023-08-29 a las 17 03 40
Captura de pantalla 2023-08-29 a las 17 05 59

Enable URL auto-linking

See https://docs.gitlab.com/ee/user/markdown.html#url-auto-linking

This behavior corresponds to default Confluence behavior when you insert a simple URL.

Would it be nice to have this feature? Maybe this behavior can be enabled/disabled via cmdline option?

At the moment you need the following to have link in Confluence which is clickable:

See [https://foobar.com](https://foobar.com) for more information.

Instead of:

See https://foobar.com for more information.

On the other side there might be cases where you explicitly do not want a URL to be clickable 🤔

only convert, do not publish?

Hey,

I would like to use your script in an ansible playbook. As the publish part is already done, and I really like that to stay in native ansible, I would only need to convert my markdown with your python script.

Is this possible somehow?

Error: Confluence returns a format that is not JSON as expected

Confluence version: 8.2.3 Server Edition
markdown-to-confluence installed with pip, version: 0.1.10

Confluence returns: "<Response [200]>"

Exception message:

2023-12-06 13:47:11,617 - INFO - _synchronize_page [87] - Synchronizing page: test.md
Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/requests/models.py", line 971, in json
    return complexjson.loads(self.text, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.6_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/__main__.py", line 85, in <module>
    Application(api, ConfluenceDocumentOptions(args.generated_by)).synchronize(
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/application.py", line 34, in synchronize
    self.synchronize_page(path)
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/application.py", line 41, in synchronize_page
    self._synchronize_page(page_path, dict())
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/application.py", line 94, in _synchronize_page
    self._update_document(document, base_path)
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/application.py", line 104, in _update_document
    self.api.update_page(document.id.page_id, content)
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/api.py", line 343, in update_page
    page = self.get_page(page_id)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/api.py", line 320, in get_page
    data = typing.cast(Dict[str, JsonType], self._invoke(path, query))
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/md2conf/api.py", line 188, in _invoke
    return response.json()
           ^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/requests/models.py", line 975, in json
    raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Setting the Confluence space doesn't work

According to the docs you can change the space key on per-document basis:

<!-- confluence-space-key: DAP -->

This overrides the default space set via command-line arguments or environment variables.

This doesn't seem to work for me (someother is another valid space key) :

$ head testing.md -n2
<!-- confluence-page-id: 367198209 -->
<!-- confluence-space-key: ~62dfb0d2b6b0b70770d7d76c -->
$ python3 -m md2conf testing.md -s someother
2023-08-23 12:39:34,798 - INFO - _synchronize_page [87] - Synchronizing page: testing.md
2023-08-23 12:39:34,978 - INFO - update_page [363] - Updating page: 367198209
2023-08-23 12:39:35,086 - ERROR - <module> [89] - 400 Client Error: Bad Request for url: https://atix.atlassian.net/wiki/rest/api/content/367198209
2023-08-23 12:39:35,086 - ERROR - <module> [94] - {'statusCode': 400, 'data': {'authorized': True, 'valid': False, 'errors': [{'message': {'key': "You can't change an existing page's space.", 'args': []}}], 'successful': False}, 'message': 'com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not update Content of type : class com.atlassian.confluence.pages.Page with id 367198209'}

Another question is why is there a space key required via command-line arguments or environment variables at all? A space key tag in the document should be sufficient or not?

$ echo $CONFLUENCE_SPACE_KEY

$ head testing.md -n2
<!-- confluence-space-key: ~62dfb0d2b6b0b70770d7d76c -->
<!-- confluence-page-id: 367198209 -->
$ python3 -m md2conf testing.md
Traceback (most recent call last):
  File "/usr/lib64/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib64/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/jloeser/devel/envs/md2conf-env/lib/python3.10/site-packages/md2conf/__main__.py", line 82, in <module>
    with ConfluenceAPI(
  File "/home/jloeser/devel/envs/md2conf-env/lib/python3.10/site-packages/md2conf/api.py", line 117, in __init__
    raise ConfluenceError("Confluence space key not specified")
md2conf.api.ConfluenceError: Confluence space key not specified

Tested version of md2conf is revision 6627f42.

md2conf for cloud hosted Confluence

Hi,
in the Atlasian python API, there is a cloud boolean parameter, which change the API used.
I do not think it possible to do with md2conf as of today, moreover you do not use the python atlasian toolkit.
Is there a parameter to change the api used ?

thanks in advance

Markdown validator

Hello,

Just looking for assistance on what would be the best way to make md2conf compatible with terraform-docs.

I could successfully publish README.md existing in current repo but fail to upload every generated by terraform-docs

sequence of commands:

terraform-docs markdown document . --output-file README.md --sort-by required
python -m md2conf -l debug README.md

Exception
`
2024-04-01 19:24:11,572 - INFO - _synchronize_page [76] - Synchronizing page: adl-athena-workgroups/README.md
2024-04-01 19:24:11,580 - DEBUG - registerExtensions [182] - Successfully loaded extension "markdown.extensions.admonition.AdmonitionExtension".
2024-04-01 19:24:11,580 - DEBUG - build_extension [226] - Successfully imported extension module "markdown.extensions.tables".
2024-04-01 19:24:11,580 - DEBUG - registerExtensions [182] - Successfully loaded extension "markdown.extensions.tables.TableExtension".
2024-04-01 19:24:11,582 - DEBUG - build_extension [226] - Successfully imported extension module "markdown.extensions.fenced_code".
2024-04-01 19:24:11,583 - DEBUG - registerExtensions [182] - Successfully loaded extension "markdown.extensions.fenced_code.FencedCodeExtension".
2024-04-01 19:24:11,587 - DEBUG - build_extension [226] - Successfully imported extension module "pymdownx.magiclink".
2024-04-01 19:24:11,589 - DEBUG - registerExtensions [182] - Successfully loaded extension "pymdownx.magiclink.MagiclinkExtension".
2024-04-01 19:24:11,590 - DEBUG - build_extension [226] - Successfully imported extension module "pymdownx.tilde".
2024-04-01 19:24:11,590 - DEBUG - registerExtensions [182] - Successfully loaded extension "pymdownx.tilde.DeleteSubExtension".
2024-04-01 19:24:11,590 - DEBUG - registerExtensions [182] - Successfully loaded extension "markdown.extensions.sane_lists.SaneListExtension".
Traceback (most recent call last):
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/converter.py", line 86, in _elements_from_strings
return ET.fromstringlist(data, parser=parser)
File "src/lxml/etree.pyx", line 3309, in lxml.etree.fromstringlist
File "src/lxml/parser.pxi", line 1331, in lxml.etree._FeedParser.feed
File "src/lxml/parser.pxi", line 1451, in lxml.etree._FeedParser.feed
File "src/lxml/parser.pxi", line 624, in lxml.etree._ParserContext._handleParseResult
File "src/lxml/parser.pxi", line 633, in lxml.etree._ParserContext._handleParseResultDoc
File "src/lxml/parser.pxi", line 743, in lxml.etree._handleParseResult
File "src/lxml/parser.pxi", line 672, in lxml.etree._raiseParseError
File "", line 201
lxml.etree.XMLSyntaxError: Opening and ending tag mismatch: br line 201 and pre, line 201, column 70

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/runpy.py", line 196, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/main.py", line 118, in
).synchronize(args.mdpath)
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/application.py", line 34, in synchronize
self.synchronize_page(path)
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/application.py", line 41, in synchronize_page
self._synchronize_page(page_path, {})
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/application.py", line 77, in _synchronize_page
document = ConfluenceDocument(page_path, self.options, page_metadata)
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/converter.py", line 568, in init
self.root = elements_from_strings(content)
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/converter.py", line 97, in elements_from_strings
return _elements_from_strings(dtd_path, items)
File "/opt/homebrew/Caskroom/miniconda/base/envs/310/lib/python3.10/site-packages/md2conf/converter.py", line 88, in _elements_from_strings
raise ParseError(e)
md2conf.converter.ParseError: Opening and ending tag mismatch: br line 201 and pre, line 201, column 70 (, line 201)
`
Can not share file content but maybe by the stack trace it will be clear what is wrong.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.