Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 19 additions & 21 deletions md2cf/confluence_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def append(self, child):
self.children.append(child)


class ConfluenceRenderer(mistune.Renderer):
class ConfluenceRenderer(mistune.HTMLRenderer):
def __init__(
self,
strip_header=False,
Expand All @@ -81,14 +81,13 @@ def reinit(self):
self.relative_links = list()
self.title = None

def header(self, text, level, raw=None):
def heading(self, text, level, **attrs):
if self.title is None and level == 1:
self.title = text
# Don't duplicate page title as a header
if self.strip_header:
return ""

return super(ConfluenceRenderer, self).header(text, level, raw=raw)
return super().heading(text, level, **attrs)

def structured_macro(self, name):
return ConfluenceTag("structured-macro", attrib={"name": name})
Expand All @@ -103,60 +102,59 @@ def plain_text_body(self, text):
body_tag.text = text
return body_tag

def link(self, link, title, text):
parsed_link = urlparse(link)
def link(self, text, url, title=None):
parsed_link = urlparse(url)
if (
self.enable_relative_links
and (not parsed_link.scheme and not parsed_link.netloc)
and parsed_link.path
):
# relative link
replacement_link = f"md2cf-internal-link-{uuid.uuid4()}"
self.relative_links.append(
RelativeLink(
# make sure to unquote the url as relative paths
# might have escape sequences
path=unquote(parsed_link.path),
replacement=replacement_link,
fragment=parsed_link.fragment,
original=link,
escaped_original=mistune.escape_link(link),
original=url,
escaped_original=mistune.escape_url(url),
)
)
link = replacement_link
return super(ConfluenceRenderer, self).link(link, title, text)
url = replacement_link
return super().link(text, url, title)

def text(self, text):
if self.remove_text_newlines:
text = text.replace("\n", " ")

return super().text(text)

def block_code(self, code, lang=None):
def block_code(self, code, info=None, **attrs):
lang = None
if info is not None:
lang = info.strip().split(None, 1)[0]
root_element = self.structured_macro("code")
if lang is not None:
if lang:
lang_parameter = self.parameter(name="language", value=lang)
root_element.append(lang_parameter)
root_element.append(self.parameter(name="linenumbers", value="true"))
root_element.append(self.plain_text_body(code))
return root_element.render()

def image(self, src, title, text):
def image(self, text, url, title=None):
attributes = {"alt": text}
if title:
attributes["title"] = title

root_element = ConfluenceTag(name="image", attrib=attributes)
parsed_source = urlparse(src)
parsed_source = urlparse(url)
if not parsed_source.netloc:
# Local file, requires upload
basename = Path(src).name
basename = Path(url).name
url_tag = ConfluenceTag(
"attachment", attrib={"filename": basename}, namespace="ri"
)
self.attachments.append(src)
self.attachments.append(url)
else:
url_tag = ConfluenceTag("url", attrib={"value": src}, namespace="ri")
url_tag = ConfluenceTag("url", attrib={"value": url}, namespace="ri")
root_element.append(url_tag)

return root_element.render()
1 change: 0 additions & 1 deletion md2cf/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ def parse_page(
enable_relative_links: bool = False,
) -> Page:
renderer = ConfluenceRenderer(
use_xhtml=True,
strip_header=strip_header,
remove_text_newlines=remove_text_newlines,
enable_relative_links=enable_relative_links,
Expand Down
4 changes: 2 additions & 2 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pytest-mock==1.11.1
pytest-mock>=3.10.0,<4
pyfakefs
requests-mock==1.10.0
requests-mock>=1.10.0,<2
16 changes: 8 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
],
keywords="markdown confluence",
install_requires=[
"rich-argparse==1.0.0",
"rich==13.0.1",
"mistune==0.8.4",
"chardet==5.1.0",
"requests==2.31.0",
"PyYAML==6.0.1",
"gitignorefile==1.1.2",
"rich-argparse>=1.0.0,<2",
"rich>=13.0.0,<16",
"mistune>=3.0.0,<4",
"chardet>=5.1.0,<6",
"requests>=2.31.0,<3",
"PyYAML>=6.0.1,<7",
"gitignorefile>=1.1.2,<2",
],
python_requires=">=3.7",
python_requires=">=3.8",
entry_points={"console_scripts": ["md2cf=md2cf.__main__:main"]},
)
45 changes: 24 additions & 21 deletions test_package/functional/result.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ inspiration for Markdown's syntax is the format of plain text email.</p>
by one or more blank lines. (A blank line is any line that looks like a
blank line -- a line containing nothing but spaces or tabs is considered
blank.) Normal paragraphs should not be indented with spaces or tabs.</p>
<p>The implication of the "one or more consecutive lines of text" rule is
that Markdown supports "hard-wrapped" text paragraphs. This differs
<p>The implication of the &quot;one or more consecutive lines of text&quot; rule is
that Markdown supports &quot;hard-wrapped&quot; text paragraphs. This differs
significantly from most other text-to-HTML formatters (including Movable
Type's "Convert Line Breaks" option) which translate every line break
Type's &quot;Convert Line Breaks&quot; option) which translate every line break
character in a paragraph into a <code>&lt;br /&gt;</code> tag.</p>
<p>When you <em>do</em> want to insert a <code>&lt;br /&gt;</code> break tag using Markdown, you
end a line with two or more spaces, then type return.</p>
<h3>Headers</h3>
<p>Markdown supports two styles of headers, [Setext] [1] and [atx] [2].</p>
<p>Optionally, you may "close" atx-style headers. This is purely
<p>Optionally, you may &quot;close&quot; atx-style headers. This is purely
cosmetic -- you can use this if you think it looks better. The
closing hashes don't even need to match the number of hashes
used to open the header. (The number of opening hashes
Expand All @@ -60,30 +60,37 @@ determines the header level.)</p>
familiar with quoting passages of text in an email message, then you
know how to create a blockquote in Markdown. It looks best if you hard
wrap the text and put a <code>&gt;</code> before every line:</p>
<blockquote><p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
<blockquote>
<p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
<p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.</p>
</blockquote>
<p>Markdown allows you to be lazy and only put the <code>&gt;</code> before the first
line of a hard-wrapped paragraph:</p>
<blockquote><p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
<blockquote>
<p>This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>
</blockquote>
<blockquote>
<p>Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.</p>
</blockquote>
<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
adding additional levels of <code>&gt;</code>:</p>
<blockquote><p>This is the first level of quoting.</p>
<blockquote><p>This is nested blockquote.</p>
<blockquote>
<p>This is the first level of quoting.</p>
<blockquote>
<p>This is nested blockquote.</p>
</blockquote>
<p>Back to the first level.</p>
</blockquote>
<p>Blockquotes can contain other Markdown elements, including headers, lists,
and code blocks:</p>
<blockquote><h2>This is a header.</h2>
<blockquote>
<h2>This is a header.</h2>
<ol>
<li>This is the first list item.</li>
<li>This is the second list item.</li>
Expand Down Expand Up @@ -133,7 +140,7 @@ Markdown produces from the above list is:</p>
<li>Parish</li>
</ol>
<p>or even:</p>
<ol>
<ol start="3">
<li>Bird</li>
<li>McHale</li>
<li>Parish</li>
Expand Down Expand Up @@ -188,7 +195,8 @@ sit amet, consectetuer adipiscing elit.</p>
delimiters need to be indented:</p>
<ul>
<li><p>A list item with a blockquote:</p>
<blockquote><p>This is a blockquote
<blockquote>
<p>This is a blockquote
inside a list item.</p>
</blockquote>
</li>
Expand All @@ -211,17 +219,13 @@ in both <code>&lt;pre&gt;</code> and <code>&lt;code&gt;</code> tags.</p>
block by at least 4 spaces or 1 tab.</p>
<p>This is a normal paragraph:</p>
<ac:structured-macro ac:name="code"><ac:parameter ac:name="linenumbers">true</ac:parameter>
<ac:plain-text-body><![CDATA[This is a code block.

]]></ac:plain-text-body>
<ac:plain-text-body><![CDATA[This is a code block.]]></ac:plain-text-body>
</ac:structured-macro>
<p>Here is an example of AppleScript:</p>
<ac:structured-macro ac:name="code"><ac:parameter ac:name="linenumbers">true</ac:parameter>
<ac:plain-text-body><![CDATA[tell application "Foo"
beep
end tell

]]></ac:plain-text-body>
end tell]]></ac:plain-text-body>
</ac:structured-macro>
<p>A code block continues until it reaches a line that is not indented
(or the end of the article).</p>
Expand All @@ -233,17 +237,16 @@ ampersands and angle brackets. For example, this:</p>
<ac:structured-macro ac:name="code"><ac:parameter ac:name="linenumbers">true</ac:parameter>
<ac:plain-text-body><![CDATA[<div class="footer">
&copy; 2004 Foo Corporation
</div>

]]></ac:plain-text-body>
</div>]]></ac:plain-text-body>
</ac:structured-macro>
<p>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.</p>
<ac:structured-macro ac:name="code"><ac:parameter ac:name="linenumbers">true</ac:parameter>
<ac:plain-text-body><![CDATA[tell application "Foo"
beep
end tell]]></ac:plain-text-body>
end tell
]]></ac:plain-text-body>
</ac:structured-macro>
<h2>Span Elements</h2>
<h3>Links</h3>
Expand Down
Loading