markdown-to-confluence 0.4.3__py3-none-any.whl → 0.4.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown-to-confluence
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: Publish Markdown files to Confluence wiki
5
5
  Author-email: Levente Hunyadi <hunyadi@gmail.com>
6
6
  Maintainer-email: Levente Hunyadi <hunyadi@gmail.com>
@@ -23,13 +23,13 @@ Classifier: Typing :: Typed
23
23
  Requires-Python: >=3.9
24
24
  Description-Content-Type: text/markdown
25
25
  License-File: LICENSE
26
- Requires-Dist: json_strong_typing>=0.3.9
26
+ Requires-Dist: json_strong_typing>=0.4
27
27
  Requires-Dist: lxml>=6.0
28
28
  Requires-Dist: markdown>=3.8
29
29
  Requires-Dist: pymdown-extensions>=10.16
30
30
  Requires-Dist: PyYAML>=6.0
31
31
  Requires-Dist: requests>=2.32
32
- Requires-Dist: typing_extensions>=4.14; python_version < "3.12"
32
+ Requires-Dist: typing-extensions>=4.14; python_version < "3.12"
33
33
  Provides-Extra: dev
34
34
  Requires-Dist: markdown_doc>=0.1.4; python_version >= "3.10" and extra == "dev"
35
35
  Requires-Dist: types-lxml>=2025.3.30; extra == "dev"
@@ -38,6 +38,8 @@ Requires-Dist: types-PyYAML>=6.0; extra == "dev"
38
38
  Requires-Dist: types-requests>=2.32; extra == "dev"
39
39
  Requires-Dist: mypy>=1.16; extra == "dev"
40
40
  Requires-Dist: ruff>=0.12; extra == "dev"
41
+ Provides-Extra: formulas
42
+ Requires-Dist: matplotlib>=3.9; extra == "formulas"
41
43
  Dynamic: license-file
42
44
 
43
45
  # Publish Markdown files to Confluence wiki
@@ -57,7 +59,7 @@ This Python package
57
59
  * Sections and subsections
58
60
  * Text with **bold**, *italic*, `monospace`, <ins>underline</ins> and ~~strikethrough~~
59
61
  * Link to [sections on the same page](#getting-started) or [external locations](http://example.com/)
60
- * Subscript and superscript (with HTML tags `<sub>` and `<sup>`)
62
+ * Subscript and superscript
61
63
  * Math formulas with LaTeX notation
62
64
  * Emoji
63
65
  * Ordered and unordered lists
@@ -69,8 +71,10 @@ This Python package
69
71
  * [Table of contents](https://docs.gitlab.com/ee/user/markdown.html#table-of-contents)
70
72
  * [Admonitions](https://python-markdown.github.io/extensions/admonition/) and alert boxes in [GitHub](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) and [GitLab](https://docs.gitlab.com/ee/development/documentation/styleguide/#alert-boxes)
71
73
  * [Collapsed sections](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections)
74
+ * [Tasklists](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-tasklists)
72
75
  * draw\.io diagrams
73
- * [Mermaid diagrams](https://mermaid.live/) in code blocks (converted to images)
76
+ * [Mermaid diagrams](https://mermaid.live/)
77
+ * Confluence status labels and date widget
74
78
 
75
79
  Whenever possible, the implementation uses [Confluence REST API v2](https://developer.atlassian.com/cloud/confluence/rest/v2/) to fetch space properties, and get, create or update page content.
76
80
 
@@ -92,13 +96,19 @@ pip install markdown-to-confluence
92
96
  npm install -g @mermaid-js/mermaid-cli
93
97
  ```
94
98
 
99
+ **Optional.** Converting formulas and equations to PNG or SVG images requires [Matplotlib](https://matplotlib.org/):
100
+
101
+ ```sh
102
+ pip install matplotlib
103
+ ```
104
+
95
105
  ### Marketplace apps
96
106
 
97
107
  As authors of *md2conf*, we don't endorse or support any particular Confluence marketplace apps.
98
108
 
99
109
  **Optional.** Editable draw\.io diagrams require [draw.io Diagrams marketplace app](https://marketplace.atlassian.com/apps/1210933/draw-io-diagrams-uml-bpmn-aws-erd-flowcharts). (Refer to `--no-render-drawio`.)
100
110
 
101
- **Optional.** Displaying Mermaid diagrams in Confluence without pre-rendering in the synchronization phase requires a marketplace app. (Refer to `--no-render-mermaid`.)
111
+ **Optional.** Displaying Mermaid diagrams in Confluence without pre-rendering in the synchronization phase requires a [marketplace app](https://marketplace.atlassian.com/apps/1226567/mermaid-diagrams-for-confluence). (Refer to `--no-render-mermaid`.)
102
112
 
103
113
  **Optional.** Displaying formulas and equations in Confluence requires [marketplace app](https://marketplace.atlassian.com/apps/1226109/latex-math-for-confluence-math-formula-equations), refer to [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/).
104
114
 
@@ -250,6 +260,12 @@ Root page
250
260
  └── Ethical considerations
251
261
  ```
252
262
 
263
+ ### Subscript and superscript
264
+
265
+ Subscripts may either use the character *tilde* (e.g. `CH~3~CH~2~OH`) or the HTML tag `<sub>`.
266
+
267
+ Superscripts may either use the character *caret* (e.g. `e^-ix^`) or the HTML tag `<sup>`.
268
+
253
269
  ### Emoji
254
270
 
255
271
  The short name notation `:smile:` in a Markdown document is converted into the corresponding emoji 😄 when publishing to Confluence.
@@ -276,10 +292,12 @@ Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <spa
276
292
  Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <span style="background-color: rgb(211,241,167);">lime</span> and <span style="background-color: rgb(254,222,200);">yellow</span>.
277
293
  ```
278
294
 
295
+ Highlighting is also supported via `==marks==`. However, the background color is not customizable.
296
+
279
297
  The following table shows standard text colors (CSS `color`) that are available via Confluence UI:
280
298
 
281
299
  | Color name | CSS attribute value |
282
- | ------------- | ------------------- |
300
+ | :------------ | :------------------ |
283
301
  | bold blue | rgb(7,71,166) |
284
302
  | blue | rgb(76,154,255) |
285
303
  | subtle blue | rgb(179,212,255) |
@@ -340,6 +358,47 @@ $$\int _{a}^{b}f(x)dx=F(b)-F(a)$$
340
358
 
341
359
  Displaying math formulas in Confluence requires the extension [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/).
342
360
 
361
+ ### HTML in Markdown
362
+
363
+ *md2conf* relays HTML elements nested in Markdown content to Confluence (such as `e<sup>x</sup>` for superscript). However, Confluence uses an extension of XHTML, i.e. the content must qualify as valid XML too. In particular, unterminated tags (e.g. `<br>` or `<img ...>`) or inconsistent nesting (e.g. `<b><i></b></i>`) are not permitted, and will raise an XML parsing error. When an HTML element has no content such as `<br>` or `<img>`, use a self-closing tag:
364
+
365
+ ```html
366
+ <br/>
367
+ <img src="image.png" width="24" height="24" />
368
+ ```
369
+
370
+ ### Confluence widgets
371
+
372
+ *md2conf* supports some Confluence widgets. If the appropriate code is found when a Markdown document is processed, it is automatically replaced with Confluence Storage Format XML that produces the corresponding widget.
373
+
374
+ | Markdown code | Confluence equivalent |
375
+ | :----------------------------------------- | :------------------------------------------------------ |
376
+ | `[[_TOC_]]` | table of contents (based on headings) |
377
+ | `[[_LISTING_]]` | child pages (of current page) |
378
+ | `![My label][STATUS-GRAY]` | gray status label (with specified label text) |
379
+ | `![My label][STATUS-PURPLE]` | purple status label |
380
+ | `![My label][STATUS-BLUE]` | blue status label |
381
+ | `![My label][STATUS-RED]` | red status label |
382
+ | `![My label][STATUS-YELLOW]` | yellow status label |
383
+ | `![My label][STATUS-GREEN]` | green status label |
384
+ | `<input type="date" value="YYYY-MM-DD" />` | date widget (with year, month and day set as specified) |
385
+
386
+ Use the pseudo-language `csf` in a Markdown code block to pass content directly to Confluence. The content must be a single XML node that conforms to Confluence Storage Format (typically an `ac:structured-macro`) but is otherwise not validated. The following example shows how to create a panel similar to an *info panel* but with custom background color and emoji. Notice that `ac:rich-text-body` uses XHTML, not Markdown.
387
+
388
+ ````md
389
+ ```csf
390
+ <ac:structured-macro ac:name="panel" ac:schema-version="1">
391
+ <ac:parameter ac:name="panelIcon">:slight_smile:</ac:parameter>
392
+ <ac:parameter ac:name="panelIconId">1f642</ac:parameter>
393
+ <ac:parameter ac:name="panelIconText">&#128578;</ac:parameter>
394
+ <ac:parameter ac:name="bgColor">#FFF0B3</ac:parameter>
395
+ <ac:rich-text-body>
396
+ <p>A <em>custom colored panel</em> with a 🙂 emoji</p>
397
+ </ac:rich-text-body>
398
+ </ac:structured-macro>
399
+ ```
400
+ ````
401
+
343
402
  ### Ignoring files
344
403
 
345
404
  Skip files in a directory with rules defined in `.mdignore`. Each rule should occupy a single line. Rules follow the syntax (and constraints) of [fnmatch](https://docs.python.org/3/library/fnmatch.html#fnmatch.fnmatch). Specifically, `?` matches any single character, and `*` matches zero or more characters. For example, use `up-*.md` to exclude Markdown files that start with `up-`. Lines that start with `#` are treated as comments.
@@ -364,13 +423,13 @@ This is useful if you have a page in a hierarchy that participates in parent-chi
364
423
 
365
424
  ### Page title
366
425
 
367
- *md2conf* makes a best-effort attempt at setting the Confluence wiki page title when it publishes a Markdown document the first time. The following are probed in this order:
426
+ *md2conf* makes a best-effort attempt at setting the Confluence wiki page title when it publishes a Markdown document the first time. The following act as sources for deriving a page title:
368
427
 
369
428
  1. The `title` attribute set in the [front-matter](https://daily-dev-tips.com/posts/what-exactly-is-frontmatter/). Front-matter is a block delimited by `---` at the beginning of a Markdown document. Both JSON and YAML syntax are supported.
370
429
  2. The text of the topmost unique Markdown heading (`#`). For example, if a document has a single first-level heading (e.g. `# My document`), its text is used. However, if there are multiple first-level headings, this step is skipped.
371
- 3. The file name (without the extension `.md`).
430
+ 3. The file name (without the extension `.md`) and a digest. The digest is included to ensure the title is unique across the Confluence space.
372
431
 
373
- If a matching Confluence page already exists for a Markdown file, the page title in Confluence is left unchanged.
432
+ If the `title` attribute (in the front-matter) or the topmost unique heading (in the document body) changes, the Confluence page title is updated. A warning is raised if the new title conflicts with the title of another page, and thus cannot be updated.
374
433
 
375
434
  ### Labels
376
435
 
@@ -405,16 +464,21 @@ The attribute `properties` is parsed as a dictionary with keys of type string an
405
464
 
406
465
  ### draw\.io diagrams
407
466
 
408
- With the command-line option `--no-render-drawio` (default), editable diagram data is extracted from images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`), and uploaded to Confluence as attachments. `*.drawio` and `*.drawio.xml` files are uploaded as-is. You need a [marketplace app](https://marketplace.atlassian.com/apps/1210933/draw-io-diagrams-uml-bpmn-aws-erd-flowcharts) to view and edit these diagrams on a Confluence page.
467
+ With the command-line option `--no-render-drawio` (default), editable diagram data is extracted from images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`), and uploaded to Confluence as attachments. Files that match `*.drawio` or `*.drawio.xml` are uploaded as-is. You need a [marketplace app](https://marketplace.atlassian.com/apps/1210933/draw-io-diagrams-uml-bpmn-aws-erd-flowcharts) to view and edit these diagrams on a Confluence page.
409
468
 
410
- With the command-line option `--render-drawio`, images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`) are uploaded unchanged, and shown on the Confluence page as images. These diagrams are not editable in Confluence. When both an SVG and a PNG image is available, PNG is preferred. `*.drawio` and `*.drawio.xml` files are converted into PNG or SVG images by invoking draw\.io as a command-line utility, and the generated images are uploaded to Confluence as attachments, and shown as images.
469
+ With the command-line option `--render-drawio`, images with embedded draw\.io diagrams (`*.drawio.png` and `*.drawio.svg`) are uploaded unchanged, and shown on the Confluence page as images. These diagrams are not editable in Confluence. When both an SVG and a PNG image is available, PNG is preferred. Files that match `*.drawio` or `*.drawio.xml` are converted into PNG or SVG images by invoking draw\.io as a command-line utility, and the generated images are uploaded to Confluence as attachments, and shown as images.
411
470
 
412
471
  ### Mermaid diagrams
413
472
 
414
- You can include [Mermaid diagrams](https://mermaid.js.org/) in your Markdown documents to create visual representations of systems, processes, and relationships. When a Markdown document contains a code block with the language specifier `mermaid`, *md2conf* offers two options to publish the diagram:
473
+ You can add [Mermaid diagrams](https://mermaid.js.org/) to your Markdown documents to create visual representations of systems, processes, and relationships. There are two ways to include a Mermaid diagram:
474
+
475
+ * an image reference to a `.mmd` or `.mermaid` file, i.e. `![My diagram](figure/diagram.mmd)`, or
476
+ * a fenced code block with the language specifier `mermaid`.
415
477
 
416
- 1. Pre-render into an image (command-line option `--render-mermaid`). The code block is interpreted by and converted into a PNG or SVG image with the Mermaid diagram utility [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). The generated image is then uploaded to Confluence as an attachment to the page. This is the approach we use and support.
417
- 2. Display on demand (command-line option `--no-render-mermaid`). The code block is transformed into a [diagram macro](https://atlasauthority.atlassian.net/wiki/spaces/MARKDOWNCLOUD/pages/2946826241/Diagram+Macro), which is processed by Confluence. You need a [marketplace app](https://marketplace.atlassian.com/apps/1211438/markdown-html-plantuml-latex-diagrams-open-api-mermaid) to turn macro definitions into images when a Confluence page is visited.
478
+ *md2conf* offers two options to publish the diagram:
479
+
480
+ 1. Pre-render into an image (command-line option `--render-mermaid`). The source file or code block is interpreted by and converted into a PNG or SVG image with the Mermaid diagram utility [mermaid-cli](https://github.com/mermaid-js/mermaid-cli). The generated image is then uploaded to Confluence as an attachment to the page. This is the approach we use and support.
481
+ 2. Display on demand (command-line option `--no-render-mermaid`). The code block is transformed into a [diagram macro](https://stratus-addons.atlassian.net/wiki/spaces/MDFC/overview), which is processed by Confluence. You need a separate [marketplace app](https://marketplace.atlassian.com/apps/1226567/mermaid-diagrams-for-confluence) to turn macro definitions into images when a Confluence page is visited.
418
482
 
419
483
  If you are running into issues with the pre-rendering approach (e.g. misaligned labels in the generated image), verify if `mermaid-cli` can process the Mermaid source:
420
484
 
@@ -424,6 +488,20 @@ mmdc -i sample.mmd -o sample.png -b transparent --scale 2
424
488
 
425
489
  Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
426
490
 
491
+ ### Links to attachments
492
+
493
+ If *md2conf* encounters a Markdown link that points to a file in the directory hierarchy being synchronized, it automatically uploads the file as an attachment to the Confluence page. Activating the link in Confluence downloads the file. Typical examples include PDFs (`*.pdf`), word processor documents (`*.docx`), spreadsheets (`*.xlsx`), plain text files (`*.txt`) or logs (`*.log`). The MIME type is set based on the file type.
494
+
495
+ ### Implicit URLs
496
+
497
+ *md2conf* implicitly defines some URLs, as if you included the following at the start of the Markdown document for each URL:
498
+
499
+ ```md
500
+ [CUSTOM-URL]: https://example.com/path/to/resource
501
+ ```
502
+
503
+ Specifically, image references for status labels (e.g. `![My label][STATUS-RED]`) are automatically resolved into internally defined URLs via this mechanism.
504
+
427
505
  ### Local output
428
506
 
429
507
  *md2conf* supports local output, in which the tool doesn't communicate with the Confluence REST API. Instead, it reads a single Markdown file or a directory of Markdown files, and writes Confluence Storage Format (`*.csf`) output for each document. (Confluence Storage Format is a derivative of XHTML with Confluence-specific tags for complex elements such as images with captions, code blocks, info panels, collapsed sections, etc.) You can push the generated output to Confluence by invoking the API (e.g. with `curl`).
@@ -440,10 +518,7 @@ Use the `--help` switch to get a full list of supported command-line options:
440
518
 
441
519
  ```console
442
520
  $ python3 -m md2conf --help
443
- usage: md2conf [-h] [--version] [-d DOMAIN] [-p PATH] [--api-url API_URL] [-u USERNAME] [-a API_KEY] [-s SPACE] [-l {debug,info,warning,error,critical}] [-r ROOT_PAGE] [--keep-hierarchy] [--flatten-hierarchy]
444
- [--generated-by GENERATED_BY] [--no-generated-by] [--render-drawio] [--no-render-drawio] [--render-mermaid] [--no-render-mermaid] [--render-mermaid-format {png,svg}] [--heading-anchors]
445
- [--no-heading-anchors] [--ignore-invalid-url] [--local] [--headers [KEY=VALUE ...]] [--webui-links]
446
- mdpath
521
+ usage: md2conf mdpath [OPTIONS]
447
522
 
448
523
  positional arguments:
449
524
  mdpath Path to Markdown file or directory to convert and publish.
@@ -467,17 +542,21 @@ options:
467
542
  --generated-by GENERATED_BY
468
543
  Add prompt to pages (default: 'This page has been generated with a tool.').
469
544
  --no-generated-by Do not add 'generated by a tool' prompt to pages.
470
- --render-drawio Render draw.io diagrams as image files and add as attachments. (Converter required.)
471
- --no-render-drawio Inline draw.io diagram in Confluence page. (Marketplace app required.)
472
- --render-mermaid Render Mermaid diagrams as image files and add as attachments. (Converter required.)
473
- --no-render-mermaid Inline Mermaid diagram in Confluence page. (Marketplace app required.)
474
- --render-mermaid-format {png,svg}
545
+ --render-drawio Render draw.io diagrams as image files. (Installed utility required to covert.)
546
+ --no-render-drawio Upload draw.io diagram sources as Confluence page attachments. (Marketplace app required to display.)
547
+ --render-mermaid Render Mermaid diagrams as image files. (Installed utility required to convert.)
548
+ --no-render-mermaid Upload Mermaid diagram sources as Confluence page attachments. (Marketplace app required to display.)
549
+ --render-latex Render LaTeX formulas as image files. (Matplotlib required to convert.)
550
+ --no-render-latex Inline LaTeX formulas in Confluence page. (Marketplace app required to display.)
551
+ --diagram-output-format {png,svg}
475
552
  Format for rendering Mermaid and draw.io diagrams (default: 'png').
553
+ --render-mermaid-format FORMAT
554
+ Format for rendering Mermaid diagrams (default: 'png').
476
555
  --heading-anchors Place an anchor at each section heading with GitHub-style same-page identifiers.
477
556
  --no-heading-anchors Don't place an anchor at each section heading.
478
557
  --ignore-invalid-url Emit a warning but otherwise ignore relative URLs that point to ill-specified locations.
479
558
  --local Write XHTML-based Confluence Storage Format files locally without invoking Confluence API.
480
- --headers [KEY=VALUE ...]
559
+ --headers KEY=VALUE [KEY=VALUE ...]
481
560
  Apply custom headers to all Confluence API requests.
482
561
  --webui-links Enable Confluence Web UI links. (Typically required for on-prem versions of Confluence.)
483
562
  ```
@@ -0,0 +1,33 @@
1
+ markdown_to_confluence-0.4.5.dist-info/licenses/LICENSE,sha256=56L-Y0dyZwyVlINRJRz3PNw-ka-oLVaAq-7d8zo6qlc,1077
2
+ md2conf/__init__.py,sha256=uvviya0xS1aCIW7IU3EfeI_QkC_d9T_PiVsLEMXo9S4,402
3
+ md2conf/__main__.py,sha256=gQncJ-mkhRyQyhrZg-uJ1RnN8aGw-sr0c83ydunFNj0,11661
4
+ md2conf/api.py,sha256=VjXD0da4de5YtPCbUCjK0k1oD6vl59IQLItEapj0pyM,37861
5
+ md2conf/application.py,sha256=PZDPUpoKjKBPTHwgVO20pGzTwER3paZuQbI-2_TWBgE,8563
6
+ md2conf/collection.py,sha256=EobgMRJgkYloWlY03NZJ52MRC_SGLpTVCHkltDbQyt0,837
7
+ md2conf/converter.py,sha256=hWqbXYSFymMkvobh-f3uUO6JG28EWHU_7s0QYPI6NKM,61400
8
+ md2conf/csf.py,sha256=WIzGrX-RXAkr4XsgLIUT11WM1qwhjgcXZHI_cALXpyM,6397
9
+ md2conf/domain.py,sha256=NpeGl-I9_rgKYCKKZT1Ygg3nl5U0-jJHYYrzDVpMSGQ,1965
10
+ md2conf/drawio.py,sha256=3RJFFzlp5a7SNVNCnwO_HCDfMy0DqYQeXfHWRPInOVE,8527
11
+ md2conf/entities.dtd,sha256=M6NzqL5N7dPs_eUA_6sDsiSLzDaAacrx9LdttiufvYU,30215
12
+ md2conf/extra.py,sha256=VuMxuOnnC2Qwy6y52ukIxsaYhrZArRqMmRHRE4QZl8g,687
13
+ md2conf/latex.py,sha256=yAClNclguPv-xWBMVWbqvYWLbyUHBVufc2aUzwyKHew,7586
14
+ md2conf/local.py,sha256=mvp2kA_eo6JUQ_rlM7zDdEFgBPVxMr3VKP_X1nsLjHE,3747
15
+ md2conf/markdown.py,sha256=czabU17tUfhSX1JQGiI_TrMrTmtoVThOwFu_To_Oi_w,3176
16
+ md2conf/matcher.py,sha256=m5rZjYZSjhKfdeKS8JdPq7cG861Mc6rVZBkrIOZTHGE,6916
17
+ md2conf/mermaid.py,sha256=7iziRC1Li3D85psR5NlnZ6BOePsOfFELgkNCAxahbZU,2240
18
+ md2conf/metadata.py,sha256=LzZM-oPNnzCULmLhF516tPlV5zZBknccwMHt8Nan-xg,1007
19
+ md2conf/processor.py,sha256=z2d2KMPEYWaxflOtH2UTwrjzpPU8TtLSEUvor85ez1Q,9732
20
+ md2conf/properties.py,sha256=RC1jY_TKVbOv2bJxXn27Fj4fNWzyoNUQt6ltgUyVQAQ,3987
21
+ md2conf/puppeteer-config.json,sha256=-dMTAN_7kNTGbDlfXzApl0KJpAWna9YKZdwMKbpOb60,159
22
+ md2conf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ md2conf/scanner.py,sha256=Cyvjab8tBvKgubttQvNagS8nailuTvFBqUGoiX5MNp8,5351
24
+ md2conf/text.py,sha256=fHOrUaPXAjE4iRhHqFq-CiI-knpo4wvyHCWp0crewqA,1736
25
+ md2conf/toc.py,sha256=hpqqDbFgNJg5-ul8qWjOglI3Am0sbwR-TLwGN5G9Qo0,2447
26
+ md2conf/uri.py,sha256=KbLBdRFtZTQTZd8b4j0LtE8Pb68Ly0WkemF4iW-EAB4,1158
27
+ md2conf/xml.py,sha256=Ybf3Ctt6EurVvel0eb1KezF33_e_cDpMwlUqHi4kNLE,5411
28
+ markdown_to_confluence-0.4.5.dist-info/METADATA,sha256=zhCjkqQkp71Z28iRzGH-vLMczWaELkd-2FU_kiNv61k,33724
29
+ markdown_to_confluence-0.4.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ markdown_to_confluence-0.4.5.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
31
+ markdown_to_confluence-0.4.5.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
32
+ markdown_to_confluence-0.4.5.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
33
+ markdown_to_confluence-0.4.5.dist-info/RECORD,,
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2022-2024 Levente Hunyadi
3
+ Copyright (c) 2022-2025 Levente Hunyadi
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
md2conf/__init__.py CHANGED
@@ -5,7 +5,7 @@ Parses Markdown files, converts Markdown content into the Confluence Storage For
5
5
  Confluence API endpoints to upload images and content.
6
6
  """
7
7
 
8
- __version__ = "0.4.3"
8
+ __version__ = "0.4.5"
9
9
  __author__ = "Levente Hunyadi"
10
10
  __copyright__ = "Copyright 2022-2025, Levente Hunyadi"
11
11
  __license__ = "MIT"
md2conf/__main__.py CHANGED
@@ -40,6 +40,7 @@ class Arguments(argparse.Namespace):
40
40
  generated_by: Optional[str]
41
41
  render_drawio: bool
42
42
  render_mermaid: bool
43
+ render_latex: bool
43
44
  diagram_output_format: Literal["png", "svg"]
44
45
  local: bool
45
46
  headers: dict[str, str]
@@ -186,26 +187,39 @@ def main() -> None:
186
187
  dest="render_drawio",
187
188
  action="store_true",
188
189
  default=True,
189
- help="Render draw.io diagrams as image files and add as attachments. (Installed utility required.)",
190
+ help="Render draw.io diagrams as image files. (Installed utility required to covert.)",
190
191
  )
191
192
  parser.add_argument(
192
193
  "--no-render-drawio",
193
194
  dest="render_drawio",
194
195
  action="store_false",
195
- help="Inline draw.io diagram in Confluence page. (Marketplace app required.)",
196
+ help="Upload draw.io diagram sources as Confluence page attachments. (Marketplace app required to display.)",
196
197
  )
197
198
  parser.add_argument(
198
199
  "--render-mermaid",
199
200
  dest="render_mermaid",
200
201
  action="store_true",
201
202
  default=True,
202
- help="Render Mermaid diagrams as image files and add as attachments. (Installed utility required.)",
203
+ help="Render Mermaid diagrams as image files. (Installed utility required to convert.)",
203
204
  )
204
205
  parser.add_argument(
205
206
  "--no-render-mermaid",
206
207
  dest="render_mermaid",
207
208
  action="store_false",
208
- help="Inline Mermaid diagram in Confluence page. (Marketplace app required.)",
209
+ help="Upload Mermaid diagram sources as Confluence page attachments. (Marketplace app required to display.)",
210
+ )
211
+ parser.add_argument(
212
+ "--render-latex",
213
+ dest="render_latex",
214
+ action="store_true",
215
+ default=True,
216
+ help="Render LaTeX formulas as image files. (Matplotlib required to convert.)",
217
+ )
218
+ parser.add_argument(
219
+ "--no-render-latex",
220
+ dest="render_latex",
221
+ action="store_false",
222
+ help="Inline LaTeX formulas in Confluence page. (Marketplace app required to display.)",
209
223
  )
210
224
  parser.add_argument(
211
225
  "--diagram-output-format",
@@ -277,6 +291,7 @@ def main() -> None:
277
291
  keep_hierarchy=args.keep_hierarchy,
278
292
  render_drawio=args.render_drawio,
279
293
  render_mermaid=args.render_mermaid,
294
+ render_latex=args.render_latex,
280
295
  diagram_output_format=args.diagram_output_format,
281
296
  webui_links=args.webui_links,
282
297
  )
md2conf/api.py CHANGED
@@ -27,6 +27,14 @@ from .properties import ArgumentError, ConfluenceConnectionProperties, Confluenc
27
27
 
28
28
  T = TypeVar("T")
29
29
 
30
+ mimetypes.add_type("application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx", strict=True)
31
+ mimetypes.add_type("text/vnd.mermaid", ".mmd", strict=True)
32
+ mimetypes.add_type("application/vnd.oasis.opendocument.presentation", ".odp", strict=True)
33
+ mimetypes.add_type("application/vnd.oasis.opendocument.spreadsheet", ".ods", strict=True)
34
+ mimetypes.add_type("application/vnd.oasis.opendocument.text", ".odt", strict=True)
35
+ mimetypes.add_type("application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx", strict=True)
36
+ mimetypes.add_type("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx", strict=True)
37
+
30
38
 
31
39
  def _json_to_object(
32
40
  typ: type[T],
@@ -642,7 +650,7 @@ class ConfluenceSession:
642
650
  return
643
651
  elif raw_data is not None:
644
652
  if not force and attachment.fileSize == len(raw_data):
645
- LOGGER.info("Up-to-date embedded image: %s", attachment_name)
653
+ LOGGER.info("Up-to-date embedded file: %s", attachment_name)
646
654
  return
647
655
  else:
648
656
  raise NotImplementedError("parameter match not exhaustive")
md2conf/application.py CHANGED
@@ -11,13 +11,14 @@ from pathlib import Path
11
11
  from typing import Optional
12
12
 
13
13
  from .api import ConfluenceContentProperty, ConfluenceLabel, ConfluenceSession, ConfluenceStatus
14
- from .converter import ConfluenceDocument, attachment_name, elements_from_string, get_volatile_attributes
14
+ from .converter import ConfluenceDocument, attachment_name, get_volatile_attributes, get_volatile_elements
15
+ from .csf import AC_ATTR, elements_from_string
15
16
  from .domain import ConfluenceDocumentOptions, ConfluencePageID
16
17
  from .extra import override, path_relative_to
17
18
  from .metadata import ConfluencePageMetadata
18
19
  from .processor import Converter, DocumentNode, Processor, ProcessorFactory
19
20
  from .properties import PageError
20
- from .xml import is_xml_equal
21
+ from .xml import is_xml_equal, unwrap_substitute
21
22
 
22
23
  LOGGER = logging.getLogger(__name__)
23
24
 
@@ -115,18 +116,20 @@ class SynchronizingProcessor(Processor):
115
116
  """
116
117
 
117
118
  base_path = path.parent
118
- for image_path in document.images:
119
+ for image_data in document.images:
119
120
  self.api.upload_attachment(
120
121
  page_id.page_id,
121
- attachment_name(path_relative_to(image_path, base_path)),
122
- attachment_path=image_path,
122
+ attachment_name(path_relative_to(image_data.path, base_path)),
123
+ attachment_path=image_data.path,
124
+ comment=image_data.description,
123
125
  )
124
126
 
125
- for name, data in document.embedded_images.items():
127
+ for name, file_data in document.embedded_files.items():
126
128
  self.api.upload_attachment(
127
129
  page_id.page_id,
128
130
  name,
129
- raw_data=data,
131
+ raw_data=file_data.data,
132
+ comment=file_data.description,
130
133
  )
131
134
 
132
135
  content = document.xhtml()
@@ -151,11 +154,16 @@ class SynchronizingProcessor(Processor):
151
154
  if not title: # empty or `None`
152
155
  title = page.title
153
156
 
157
+ # discard comments
158
+ tree = elements_from_string(page.content)
159
+ unwrap_substitute(AC_ATTR("inline-comment-marker"), tree)
160
+
154
161
  # check if page has any changes
155
162
  if page.title != title or not is_xml_equal(
156
163
  document.root,
157
- elements_from_string(page.content),
164
+ tree,
158
165
  skip_attributes=get_volatile_attributes(),
166
+ skip_elements=get_volatile_elements(),
159
167
  ):
160
168
  self.api.update_page(page_id.page_id, content, title=title, version=page.version.number + 1)
161
169
  else: