markdown-to-confluence 0.4.3__py3-none-any.whl → 0.4.4__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.4
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>
@@ -69,8 +69,10 @@ This Python package
69
69
  * [Table of contents](https://docs.gitlab.com/ee/user/markdown.html#table-of-contents)
70
70
  * [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
71
  * [Collapsed sections](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections)
72
+ * [Tasklists](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/about-tasklists)
72
73
  * draw\.io diagrams
73
74
  * [Mermaid diagrams](https://mermaid.live/) in code blocks (converted to images)
75
+ * Confluence status labels and date widget
74
76
 
75
77
  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
78
 
@@ -98,7 +100,7 @@ As authors of *md2conf*, we don't endorse or support any particular Confluence m
98
100
 
99
101
  **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
102
 
101
- **Optional.** Displaying Mermaid diagrams in Confluence without pre-rendering in the synchronization phase requires a marketplace app. (Refer to `--no-render-mermaid`.)
103
+ **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
104
 
103
105
  **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
106
 
@@ -279,7 +281,7 @@ Highlight in <span style="background-color: rgb(198,237,251);">teal</span>, <spa
279
281
  The following table shows standard text colors (CSS `color`) that are available via Confluence UI:
280
282
 
281
283
  | Color name | CSS attribute value |
282
- | ------------- | ------------------- |
284
+ | :------------ | :------------------ |
283
285
  | bold blue | rgb(7,71,166) |
284
286
  | blue | rgb(76,154,255) |
285
287
  | subtle blue | rgb(179,212,255) |
@@ -340,6 +342,45 @@ $$\int _{a}^{b}f(x)dx=F(b)-F(a)$$
340
342
 
341
343
  Displaying math formulas in Confluence requires the extension [LaTeX Math for Confluence - Math Formula & Equations](https://help.narva.net/latex-math-for-confluence/).
342
344
 
345
+ ### HTML in Markdown
346
+
347
+ *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:
348
+
349
+ ```html
350
+ <br/>
351
+ <img src="image.png" width="24" height="24" />
352
+ ```
353
+
354
+ ### Confluence widgets
355
+
356
+ *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.
357
+
358
+ | Markdown code | Confluence equivalent |
359
+ | :----------------------------------------- | :------------------------------------------------------ |
360
+ | `![My label][STATUS-GRAY]` | gray status label (with specified label text) |
361
+ | `![My label][STATUS-PURPLE]` | purple status label |
362
+ | `![My label][STATUS-BLUE]` | blue status label |
363
+ | `![My label][STATUS-RED]` | red status label |
364
+ | `![My label][STATUS-YELLOW]` | yellow status label |
365
+ | `![My label][STATUS-GREEN]` | green status label |
366
+ | `<input type="date" value="YYYY-MM-DD" />` | date widget (with year, month and day set as specified) |
367
+
368
+ 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.
369
+
370
+ ````md
371
+ ```csf
372
+ <ac:structured-macro ac:name="panel" ac:schema-version="1">
373
+ <ac:parameter ac:name="panelIcon">:slight_smile:</ac:parameter>
374
+ <ac:parameter ac:name="panelIconId">1f642</ac:parameter>
375
+ <ac:parameter ac:name="panelIconText">&#128578;</ac:parameter>
376
+ <ac:parameter ac:name="bgColor">#FFF0B3</ac:parameter>
377
+ <ac:rich-text-body>
378
+ <p>A <em>custom colored panel</em> with a 🙂 emoji</p>
379
+ </ac:rich-text-body>
380
+ </ac:structured-macro>
381
+ ```
382
+ ````
383
+
343
384
  ### Ignoring files
344
385
 
345
386
  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.
@@ -414,7 +455,7 @@ With the command-line option `--render-drawio`, images with embedded draw\.io di
414
455
  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:
415
456
 
416
457
  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.
458
+ 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 [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
459
 
419
460
  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
461
 
@@ -424,6 +465,16 @@ mmdc -i sample.mmd -o sample.png -b transparent --scale 2
424
465
 
425
466
  Ensure that `mermaid-cli` is set up, refer to *Installation* for instructions.
426
467
 
468
+ ### Implicit URLs
469
+
470
+ *md2conf* implicitly defines some URLs, as if you included the following at the start of the Markdown document for each URL:
471
+
472
+ ```md
473
+ [CUSTOM-URL]: https://example.com/path/to/resource
474
+ ```
475
+
476
+ Specifically, image references for status labels (e.g. `![My label][STATUS-RED]`) are automatically resolved into internally defined URLs via this mechanism.
477
+
427
478
  ### Local output
428
479
 
429
480
  *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`).
@@ -1,17 +1,17 @@
1
- markdown_to_confluence-0.4.3.dist-info/licenses/LICENSE,sha256=Pv43so2bPfmKhmsrmXFyAvS7M30-1i1tzjz6-dfhyOo,1077
2
- md2conf/__init__.py,sha256=ZEoZwOt29zT2OnQNpbYW9lO3zJEJ6soXwwjYX9PwNNo,402
1
+ markdown_to_confluence-0.4.4.dist-info/licenses/LICENSE,sha256=Pv43so2bPfmKhmsrmXFyAvS7M30-1i1tzjz6-dfhyOo,1077
2
+ md2conf/__init__.py,sha256=nfPrvkkECt_Szpol9kTkli5cL-tFqFzn8JefKlCyb3s,402
3
3
  md2conf/__main__.py,sha256=RImfFrO2m9C5iebmBrHKlLjosy_A8AY4O7PK9CmiWSw,11120
4
- md2conf/api.py,sha256=DbG1udDb9ti4OjqgSW3DSuHwxKNFPVDTkhjnaB1GNMI,37193
5
- md2conf/application.py,sha256=MsumqUFw1WPo6-57r06Poq4wg2DPd3hQ4jA5qC4Oios,8212
4
+ md2conf/api.py,sha256=-UrtFi3pFOVMsYj7VTgCqHIBinHsSLUucmGSeureEaE,37253
5
+ md2conf/application.py,sha256=MBV4Lg6s40Q0Z4SK7W9cSo-k2A-ckmu8wosuwo_2XWM,8301
6
6
  md2conf/collection.py,sha256=EobgMRJgkYloWlY03NZJ52MRC_SGLpTVCHkltDbQyt0,837
7
- md2conf/converter.py,sha256=mr5UvEhOnM7ZYRIGsgrW85PpxmlpXFjsKYsa8uGFxp0,50475
7
+ md2conf/converter.py,sha256=WNfxGEacibINQYCZXszaMoUvJIP4Rq8IDMjz5RSH0IY,51162
8
+ md2conf/csf.py,sha256=tEbl3e5UQmbRSQK3lQqmpADoy638tlJihutqJoWhumA,4374
8
9
  md2conf/domain.py,sha256=tA9V0vb5Vo9Nt0eQvwAFARaM9TX88LBVQ73nVvdcaqA,1851
9
10
  md2conf/drawio.py,sha256=P_t7Wp7Tg9XkZM2ZchWCWWEdBaU1KgZ_YX9ZlkZo4Dk,8293
10
- md2conf/emoji.py,sha256=UzDrxqFo59wHmbbJmMNdn0rYFDXbZE4qirOM-_egzXc,2603
11
11
  md2conf/entities.dtd,sha256=M6NzqL5N7dPs_eUA_6sDsiSLzDaAacrx9LdttiufvYU,30215
12
12
  md2conf/extra.py,sha256=VuMxuOnnC2Qwy6y52ukIxsaYhrZArRqMmRHRE4QZl8g,687
13
- md2conf/local.py,sha256=Cicfp9SJDJuX0aUWZPWCfWKPfQQWxEbifUsmqwxFjDU,3733
14
- md2conf/markdown.py,sha256=9BQbYD4GfpBYmx-3N1M36u2nVWY0VJ9UWKye2Jtnmnk,2901
13
+ md2conf/local.py,sha256=mUe2QBHhdZesygmYq5kXyGyl_ZmfUECgxDxylQwTa7g,3732
14
+ md2conf/markdown.py,sha256=z9sVTA_Hcn551DZgdO7Nbod-IZ-43B4eJLklrYQ2KYI,3141
15
15
  md2conf/matcher.py,sha256=m5rZjYZSjhKfdeKS8JdPq7cG861Mc6rVZBkrIOZTHGE,6916
16
16
  md2conf/mermaid.py,sha256=f0x7ISj-41ZMh4zTAFPhIWwr94SDcsVZUc1NWqmH_G4,2508
17
17
  md2conf/metadata.py,sha256=LzZM-oPNnzCULmLhF516tPlV5zZBknccwMHt8Nan-xg,1007
@@ -20,10 +20,12 @@ md2conf/properties.py,sha256=RC1jY_TKVbOv2bJxXn27Fj4fNWzyoNUQt6ltgUyVQAQ,3987
20
20
  md2conf/puppeteer-config.json,sha256=-dMTAN_7kNTGbDlfXzApl0KJpAWna9YKZdwMKbpOb60,159
21
21
  md2conf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  md2conf/scanner.py,sha256=Cyvjab8tBvKgubttQvNagS8nailuTvFBqUGoiX5MNp8,5351
23
- md2conf/xml.py,sha256=HoKJfF1yRZ3Gk8jTS-kRpOqVs0nQJZyr56l0Fo3y9fs,2193
24
- markdown_to_confluence-0.4.3.dist-info/METADATA,sha256=sU45yX796M_cZ0ssGMaDtuxb0xwtKaPTktNAy2rczMg,29119
25
- markdown_to_confluence-0.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- markdown_to_confluence-0.4.3.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
27
- markdown_to_confluence-0.4.3.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
28
- markdown_to_confluence-0.4.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
29
- markdown_to_confluence-0.4.3.dist-info/RECORD,,
23
+ md2conf/toc.py,sha256=hpqqDbFgNJg5-ul8qWjOglI3Am0sbwR-TLwGN5G9Qo0,2447
24
+ md2conf/uri.py,sha256=KbLBdRFtZTQTZd8b4j0LtE8Pb68Ly0WkemF4iW-EAB4,1158
25
+ md2conf/xml.py,sha256=ERkGLuJgVFrOkzsMLd1RHU5SGFfFSxxNFZAeKrfdtRs,3454
26
+ markdown_to_confluence-0.4.4.dist-info/METADATA,sha256=Ql8vwKX6wtZNtUVoT0z35HgiFQcW-fFWsWFUMLkNErw,32306
27
+ markdown_to_confluence-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
28
+ markdown_to_confluence-0.4.4.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
29
+ markdown_to_confluence-0.4.4.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
30
+ markdown_to_confluence-0.4.4.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
31
+ markdown_to_confluence-0.4.4.dist-info/RECORD,,
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.4"
9
9
  __author__ = "Levente Hunyadi"
10
10
  __copyright__ = "Copyright 2022-2025, Levente Hunyadi"
11
11
  __license__ = "MIT"
md2conf/api.py CHANGED
@@ -27,6 +27,8 @@ from .properties import ArgumentError, ConfluenceConnectionProperties, Confluenc
27
27
 
28
28
  T = TypeVar("T")
29
29
 
30
+ mimetypes.add_type("text/vnd.mermaid", ".mmd", strict=True)
31
+
30
32
 
31
33
  def _json_to_object(
32
34
  typ: type[T],
@@ -642,7 +644,7 @@ class ConfluenceSession:
642
644
  return
643
645
  elif raw_data is not None:
644
646
  if not force and attachment.fileSize == len(raw_data):
645
- LOGGER.info("Up-to-date embedded image: %s", attachment_name)
647
+ LOGGER.info("Up-to-date embedded file: %s", attachment_name)
646
648
  return
647
649
  else:
648
650
  raise NotImplementedError("parameter match not exhaustive")
md2conf/application.py CHANGED
@@ -11,7 +11,8 @@ 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 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
@@ -122,7 +123,7 @@ class SynchronizingProcessor(Processor):
122
123
  attachment_path=image_path,
123
124
  )
124
125
 
125
- for name, data in document.embedded_images.items():
126
+ for name, data in document.embedded_files.items():
126
127
  self.api.upload_attachment(
127
128
  page_id.page_id,
128
129
  name,
@@ -156,6 +157,7 @@ class SynchronizingProcessor(Processor):
156
157
  document.root,
157
158
  elements_from_string(page.content),
158
159
  skip_attributes=get_volatile_attributes(),
160
+ skip_elements=get_volatile_elements(),
159
161
  ):
160
162
  self.api.update_page(page_id.page_id, content, title=title, version=page.version.number + 1)
161
163
  else: