diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f99f3c..9e9031a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- `--enable-line-numbers` CLI flag to opt in to line numbers for Confluence code blocks + ### Fixed - Pass title prefix through rendering pipeline so Confluence anchors use the correct prefixed page title @@ -15,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING (pre-1.0):** Confluence code block line numbers are now **off by default**. Existing users will lose line numbers on their next upload unless they pass `--enable-line-numbers`. - Use stdlib `html.parser.HTMLParser` for robust HTML-to-XHTML conversion instead of regex - Use dynamic default branch detection in publish-release script diff --git a/README.md b/README.md index 693fe7f..4fe7090 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,10 @@ In file.md: By default, relative links that point to non-existent files (or files that are not being uploaded in the current batch) will result in an error. To ignore these errors and keep the links as they are, use the `--ignore-relative-link-errors` flag. +## Code blocks + +By default, line numbers are disabled in Confluence code blocks for cleaner output. To render line numbers alongside your code, pass the `--enable-line-numbers` flag. + ## Directory arguments ### Uploading Folders Recursively diff --git a/mdfluence/__main__.py b/mdfluence/__main__.py index ca560b0..83b8867 100644 --- a/mdfluence/__main__.py +++ b/mdfluence/__main__.py @@ -245,6 +245,12 @@ def get_parser(): help="disable conversion of :shortcode: emoji to Unicode characters", ) + parser.add_argument( + "--enable-line-numbers", + action="store_true", + help="enable line numbers in Confluence code blocks", + ) + parser.add_argument( "--render-diagrams", action="store_true", @@ -710,6 +716,7 @@ def collect_pages_to_upload(args): mmdc_path=args.mmdc_path, plantuml_path=args.plantuml_path, title_prefix=args.prefix, + enable_line_numbers=args.enable_line_numbers, ) ) @@ -743,6 +750,7 @@ def collect_pages_to_upload(args): mmdc_path=args.mmdc_path, plantuml_path=args.plantuml_path, title_prefix=args.prefix, + enable_line_numbers=args.enable_line_numbers, ) else: try: @@ -761,6 +769,7 @@ def collect_pages_to_upload(args): mmdc_path=args.mmdc_path, plantuml_path=args.plantuml_path, title_prefix=args.prefix, + enable_line_numbers=args.enable_line_numbers, ) ) except FileNotFoundError: diff --git a/mdfluence/confluence_renderer.py b/mdfluence/confluence_renderer.py index 0bb4415..e3f248d 100644 --- a/mdfluence/confluence_renderer.py +++ b/mdfluence/confluence_renderer.py @@ -134,10 +134,12 @@ def __init__( render_diagrams=False, mmdc_path=None, plantuml_path=None, + enable_line_numbers=False, ): super().__init__(escape=False) self.strip_header = strip_header self.remove_text_newlines = remove_text_newlines + self.enable_line_numbers = enable_line_numbers self.attachments = list() self.title = None self.enable_relative_links = enable_relative_links @@ -274,7 +276,8 @@ def block_code(self, code, info=None): if info is not None: lang_parameter = self.parameter(name="language", value=info) root_element.append(lang_parameter) - root_element.append(self.parameter(name="linenumbers", value="true")) + linenumbers_value = "true" if self.enable_line_numbers else "false" + root_element.append(self.parameter(name="linenumbers", value=linenumbers_value)) root_element.append(self.plain_text_body(code)) return root_element.render() diff --git a/mdfluence/document.py b/mdfluence/document.py index 8dc3774..50ed1ff 100644 --- a/mdfluence/document.py +++ b/mdfluence/document.py @@ -131,6 +131,7 @@ def get_pages_from_directory( mmdc_path: str | None = None, plantuml_path: str | None = None, title_prefix: str | None = None, + enable_line_numbers: bool = False, ) -> List[Page]: """ Collect a list of markdown files recursively under the file_path directory. @@ -251,6 +252,7 @@ def get_pages_from_directory( mmdc_path=mmdc_path, plantuml_path=plantuml_path, title_prefix=title_prefix, + enable_line_numbers=enable_line_numbers, ) processed_page.parent_title = parent_page_title processed_pages.append(processed_page) @@ -275,6 +277,7 @@ def get_page_data_from_file_path( mmdc_path: str | None = None, plantuml_path: str | None = None, title_prefix: str | None = None, + enable_line_numbers: bool = False, ) -> Page: if not isinstance(file_path, Path): file_path = Path(file_path) @@ -299,6 +302,7 @@ def get_page_data_from_file_path( mmdc_path=mmdc_path, plantuml_path=plantuml_path, title_prefix=title_prefix, + enable_line_numbers=enable_line_numbers, ) if not page.title: @@ -320,6 +324,7 @@ def get_page_data_from_lines( mmdc_path: str | None = None, plantuml_path: str | None = None, title_prefix: str | None = None, + enable_line_numbers: bool = False, ) -> Page: frontmatter = get_document_frontmatter(markdown_lines) if "frontmatter_end_line" in frontmatter: @@ -339,6 +344,7 @@ def get_page_data_from_lines( mmdc_path=mmdc_path, plantuml_path=plantuml_path, title_prefix=title_prefix, + enable_line_numbers=enable_line_numbers, ) if "title" in frontmatter: @@ -366,6 +372,7 @@ def parse_page( mmdc_path: str | None = None, plantuml_path: str | None = None, title_prefix: str | None = None, + enable_line_numbers: bool = False, ) -> Page: markdown_text = "".join(markdown_lines) @@ -385,6 +392,7 @@ def parse_page( render_diagrams=render_diagrams, mmdc_path=mmdc_path, plantuml_path=plantuml_path, + enable_line_numbers=enable_line_numbers, ) confluence_mistune = mistune.Markdown(renderer=renderer) for plugin in [ diff --git a/test_package/functional/result.xml b/test_package/functional/result.xml index a93e555..44290d7 100644 --- a/test_package/functional/result.xml +++ b/test_package/functional/result.xml @@ -96,7 +96,7 @@ and code blocks:
Here's some example code:
-A list item with a code block:
-<pre> and <code> tags.
To produce a code block in Markdown, simply indent every line of the block by at least 4 spaces or 1 tab.
This is a normal paragraph:
-Here is an example of AppleScript:
-Regular Markdown syntax is not processed within code blocks. E.g., asterisks are just literal asterisks within a code block. This means it's also easy to use Markdown to write about Markdown's own syntax.
-