Skip to content

Commit 38ee311

Browse files
davidlowrydudanicholasserra
authored andcommitted
Fix for "Footnote titles not translatable #244" (#247)
* Fix metadata extra to consume only initial fenced block As noted in Issue #234 #234 the metadata extra uses regex that is too greedy and can eat more than what is intended if links appear in the markdown. This small change corrects this. Resolves: #234 * Add David Lowry-Duda as a contributor * Updated fix on metadata to work without fences The previous commit towards resolving Issue #234 didn't incorporate previous behavior that fences shouldn't be necessary. First introduced in Pull Request #215, metadata should be accessible even without including `---` fences around opening metadata. This fix now preserves the ability to use either `---` fences (maybe without a subsequent blank line) or no fences (but with a blank line). Resolves: #234 * Add language support for footnotes As noted in Issue #244, it is not currently possible to customize the text used in footnotes. It is always "Jump back to footnote <number> in the text." It may be desirable to provide a programmable way to supply different text, such as in different languages. This provides that support when used from within the interpreter. Usage is markdowner = markdown2.Markdown(extras=["footnotes"]) markdowner.footnote_title = "Retournez vers footnote %d. " markdowner.convert(text) This also adds the ability to change the footnote link text, through markdowner.footnote_link_text = "<something>" because they are very similar. Resolves: #244 * Added footenoteBackLink class to footnotes * Make user-provided backlinks for custom footnotes more natural Users no longer need to include html closing tags in custom definitions for footnote_title or footnote_link_text. And naked except Exception statements have been replaced with the expected errors. These notes were made by nicholasserra in Pull Request #247 * "title=" no longer required for custom footnote title * Added ability to provide custom class variables to Markdown instance It is now possible to provide class variables to the Markdown instance in the testing library by creating a file.customargs file containing a dictionary. For example, one might have have a footnotes_customtitle test, which could be tested by making the following file. footnotes_customtitle.customargs --- {"footnote_title" : "Return to %d above"} --- When testing footnote_customtitle, the Markdown instance will be passed the variable, essentially like ``` markdowner = markdown2.Markdown(*opts) markdowner.footnote_title = "Return to %d above" text = markdowner.convert(html) ``` This was done to allow tests for #247 * Added missing quotes to footnote_titles * Added test for custom footnote_title to test suite There is now a test for custom footnote_titles in the test suite. Adds tests for: PR #247 Resolves: #244 * Change custom footnotes to function inline The behavior of custom footnote text is now implemented in the following way, as recommended in #247 ``` markdown2.markdown(text, extras=["footnotes"], footnote_title="Regresar a %d.") ``` This is in contrast to the previous implementation, which required an intermediate step defining a class variable. As the interface changed, it was necessary to rewrite the relevant test, which now defines the customization in the footnotes_custom.opts file.
1 parent 6a86207 commit 38ee311

File tree

5 files changed

+84
-10
lines changed

5 files changed

+84
-10
lines changed

lib/markdown2.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,22 +162,28 @@ class MarkdownError(Exception):
162162
def markdown_path(path, encoding="utf-8",
163163
html4tags=False, tab_width=DEFAULT_TAB_WIDTH,
164164
safe_mode=None, extras=None, link_patterns=None,
165+
footnote_title=None, footnote_return_symbol=None,
165166
use_file_vars=False):
166167
fp = codecs.open(path, 'r', encoding)
167168
text = fp.read()
168169
fp.close()
169170
return Markdown(html4tags=html4tags, tab_width=tab_width,
170171
safe_mode=safe_mode, extras=extras,
171172
link_patterns=link_patterns,
173+
footnote_title=footnote_title,
174+
footnote_return_symbol=footnote_return_symbol,
172175
use_file_vars=use_file_vars).convert(text)
173176

174177

175178
def markdown(text, html4tags=False, tab_width=DEFAULT_TAB_WIDTH,
176179
safe_mode=None, extras=None, link_patterns=None,
180+
footnote_title=None, footnote_return_symbol=None,
177181
use_file_vars=False):
178182
return Markdown(html4tags=html4tags, tab_width=tab_width,
179183
safe_mode=safe_mode, extras=extras,
180184
link_patterns=link_patterns,
185+
footnote_title=footnote_title,
186+
footnote_return_symbol=footnote_return_symbol,
181187
use_file_vars=use_file_vars).convert(text)
182188

183189

@@ -203,7 +209,9 @@ class Markdown(object):
203209
_ws_only_line_re = re.compile(r"^[ \t]+$", re.M)
204210

205211
def __init__(self, html4tags=False, tab_width=4, safe_mode=None,
206-
extras=None, link_patterns=None, use_file_vars=False):
212+
extras=None, link_patterns=None,
213+
footnote_title=None, footnote_return_symbol=None,
214+
use_file_vars=False):
207215
if html4tags:
208216
self.empty_element_suffix = ">"
209217
else:
@@ -233,6 +241,8 @@ def __init__(self, html4tags=False, tab_width=4, safe_mode=None,
233241
self._instance_extras = self.extras.copy()
234242

235243
self.link_patterns = link_patterns
244+
self.footnote_title = footnote_title
245+
self.footnote_return_symbol = footnote_return_symbol
236246
self.use_file_vars = use_file_vars
237247
self._outdent_re = re.compile(r'^(\t|[ ]{1,%d})' % tab_width, re.M)
238248

@@ -2037,15 +2047,31 @@ def _add_footnotes(self, text):
20372047
'<hr' + self.empty_element_suffix,
20382048
'<ol>',
20392049
]
2050+
2051+
if not self.footnote_title:
2052+
self.footnote_title = "Jump back to footnote %d in the text."
2053+
if not self.footnote_return_symbol:
2054+
self.footnote_return_symbol = "&#8617;"
2055+
20402056
for i, id in enumerate(self.footnote_ids):
20412057
if i != 0:
20422058
footer.append('')
20432059
footer.append('<li id="fn-%s">' % id)
20442060
footer.append(self._run_block_gamut(self.footnotes[id]))
2045-
backlink = ('<a href="#fnref-%s" '
2046-
'class="footnoteBackLink" '
2047-
'title="Jump back to footnote %d in the text.">'
2048-
'&#8617;</a>' % (id, i+1))
2061+
try:
2062+
backlink = ('<a href="#fnref-%s" ' +
2063+
'class="footnoteBackLink" ' +
2064+
'title="' + self.footnote_title + '">' +
2065+
self.footnote_return_symbol +
2066+
'</a>') % (id, i+1)
2067+
except TypeError:
2068+
log.debug("Footnote error. `footnote_title` "
2069+
"must include parameter. Using defaults.")
2070+
backlink = ('<a href="#fnref-%s" '
2071+
'class="footnoteBackLink" '
2072+
'title="Jump back to footnote %d in the text.">'
2073+
'&#8617;</a>' % (id, i+1))
2074+
20492075
if footer[-1].endswith("</p>"):
20502076
footer[-1] = footer[-1][:-len("</p>")] \
20512077
+ '&#160;' + backlink + "</p>"

test/test_markdown2.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ def _assertMarkdownPath(self, text_path, encoding="utf-8", opts=None,
9090
extra["metadata"] = json_loads(
9191
codecs.open(metadata_path, 'r', encoding=encoding).read())
9292
extra["metadata_path"] = metadata_path
93-
self._assertMarkdown(text, html, text_path, html_path, opts=opts,
94-
**extra)
93+
self._assertMarkdown(text, html, text_path, html_path, opts=opts, **extra)
9594

9695
def _assertMarkdown(self, text, html, text_path=None, html_path=None,
9796
opts=None, toc_html=None, toc_html_path=None, metadata=None,
@@ -197,9 +196,10 @@ def generate_tests(cls):
197196
if not exists(metadata_path):
198197
metadata_path = None
199198

200-
test_func = lambda self, t=text_path, o=opts, c=toc_html_path, m=metadata_path: \
201-
self._assertMarkdownPath(t, opts=o, toc_html_path=c,
202-
metadata_path=m)
199+
test_func = lambda self, t=text_path, o=opts, c=toc_html_path, \
200+
m=metadata_path: \
201+
self._assertMarkdownPath(t, opts=o, toc_html_path=c,
202+
metadata_path=m)
203203

204204
tags_path = splitext(text_path)[0] + ".tags"
205205
if exists(tags_path):

test/tm-cases/footnotes_custom.html

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<p>This is a para with a footnote.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p>
2+
3+
<p>This is another para with a footnote<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup> in it. Actually it has two<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup> of
4+
them. No, three<sup class="footnote-ref" id="fnref-4"><a href="#fn-4">4</a></sup>.</p>
5+
6+
<div class="footnotes">
7+
<hr />
8+
<ol>
9+
<li id="fn-1">
10+
<p>Here is the body of the first footnote.&#160;<a href="#fnref-1" class="footnoteBackLink" title="Yo Dawg, I heard you came from 1.">&#8617;</a></p>
11+
</li>
12+
13+
<li id="fn-2">
14+
<p>And of the second footnote.</p>
15+
16+
<p>This one has multiple paragraphs.&#160;<a href="#fnref-2" class="footnoteBackLink" title="Yo Dawg, I heard you came from 2.">&#8617;</a></p>
17+
</li>
18+
19+
<li id="fn-3">
20+
<p>Here is a footnote body that starts on next line.&#160;<a href="#fnref-3" class="footnoteBackLink" title="Yo Dawg, I heard you came from 3.">&#8617;</a></p>
21+
</li>
22+
23+
<li id="fn-4">
24+
<p>quickie "that looks like a link ref if not careful"&#160;<a href="#fnref-4" class="footnoteBackLink" title="Yo Dawg, I heard you came from 4.">&#8617;</a></p>
25+
</li>
26+
</ol>
27+
</div>

test/tm-cases/footnotes_custom.opts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{"extras": ["footnotes"],
2+
"footnote_title" : "Yo Dawg, I heard you came from %d."
3+
}

test/tm-cases/footnotes_custom.text

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
This is a para with a footnote.[^1]
2+
3+
This is another para with a footnote[^2] in it. Actually it has two[^3] of
4+
them. No, three[^4].
5+
6+
7+
[^1]: Here is the body of the first footnote.
8+
9+
[^2]: And of the second footnote.
10+
11+
This one has multiple paragraphs.
12+
13+
[^3]:
14+
Here is a footnote body that starts on next line.
15+
16+
[^4]: quickie "that looks like a link ref if not careful"
17+
18+

0 commit comments

Comments
 (0)