Mercurial > piecrust2
comparison piecrust/formatting/hoedownformatter.py @ 694:b917ae071994
formatting: Add a `hoedown` formatter.
The `hoedown` library is not yet in the dependency list however since I have
to figure out its availability on most platforms.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 23 Mar 2016 08:35:51 -0700 |
parents | |
children | 0c688063890f |
comparison
equal
deleted
inserted
replaced
693:d2a87365b85b | 694:b917ae071994 |
---|---|
1 import logging | |
2 import hoedown | |
3 from piecrust.formatting.base import Formatter | |
4 | |
5 | |
6 logger = logging.getLogger(__name__) | |
7 | |
8 | |
9 class HoedownFormatter(Formatter): | |
10 FORMAT_NAMES = ['hoedown'] | |
11 OUTPUT_FORMAT = 'html' | |
12 | |
13 def __init__(self): | |
14 super(HoedownFormatter, self).__init__() | |
15 self._formatter = None | |
16 | |
17 def render(self, format_name, txt): | |
18 assert format_name in self.FORMAT_NAMES | |
19 self._ensureInitialized() | |
20 return self._formatter.render(txt) | |
21 | |
22 def _ensureInitialized(self): | |
23 if self._formatter is not None: | |
24 return | |
25 | |
26 # Don't show warnings once for each worker when baking, so only | |
27 # show them for the first. If the variable is not set, we're not | |
28 # baking so do show them either way. | |
29 show_warnings = (self.app.config.get('baker/worker_id', 0) == 0) | |
30 | |
31 config = self.app.config.get('hoedown') | |
32 if config is None: | |
33 config = {} | |
34 elif not isinstance(config, dict): | |
35 raise Exception("The `hoedown` configuration setting must be " | |
36 "a dictionary.") | |
37 | |
38 extensions = config.get('extensions', []) | |
39 if isinstance(extensions, str): | |
40 extensions = [e.strip() for e in extensions.split(',')] | |
41 # Compatibility with PieCrust 1.x | |
42 if config.get('use_markdown_extra'): | |
43 extensions.append('extra') | |
44 | |
45 render_flags = config.get('render_flags') | |
46 if render_flags is None: | |
47 render_flags = [] | |
48 | |
49 # Translate standard Markdown formatter extensions to Hoedown | |
50 # extension/render flags to make it easier to use Hoedown as a drop-in | |
51 # replacement. | |
52 exts = 0 | |
53 rdrf = 0 | |
54 other = 0 | |
55 for n in extensions: | |
56 # Try an extension? | |
57 e = getattr(hoedown, 'EXT_' + n.upper(), None) | |
58 if e is not None: | |
59 exts |= e | |
60 continue | |
61 | |
62 # Try a render flag? | |
63 f = getattr(hoedown, 'HTML_' + n.upper(), None) | |
64 if f is not None: | |
65 rdrf |= f | |
66 | |
67 # Other flag? | |
68 f = getattr(hoedown, 'TABLE_' + n.upper(), None) | |
69 if f is not None: | |
70 other |= f | |
71 | |
72 # Try translating from a Markdown extension name. | |
73 t = ext_translate.get(n) | |
74 if t is None: | |
75 if show_warnings: | |
76 logger.warning("Unknown Hoedown Markdown extension or flag: " | |
77 "%s" % n) | |
78 continue | |
79 if not isinstance(t, list): | |
80 t = [t] | |
81 for i in t: | |
82 if i.startswith('EXT_'): | |
83 exts |= getattr(hoedown, i) | |
84 elif i.startswith('HTML_'): | |
85 rdrf |= getattr(hoedown, i) | |
86 elif show_warnings: | |
87 logger.warning("Unknown Hoedown Markdown extension or flag:" | |
88 "%s" % n) | |
89 if n == 'extra' and show_warnings: | |
90 # Special warning for the 'extra' extension. | |
91 logger.warning( | |
92 "The 'extra' extension doesn't have a full equivalent " | |
93 "in Hoedown Markdown. Only 'fenced_code', 'footnotes' and " | |
94 "'tables' extensions will be active. " | |
95 "To remove this warning, replace 'extra' with those 3 " | |
96 "specific extensions.") | |
97 | |
98 # Enable a few things by default. | |
99 exts |= hoedown.EXT_NO_INTRA_EMPHASIS | |
100 | |
101 renderer = hoedown.HtmlRenderer(flags=rdrf) | |
102 self._formatter = hoedown.Markdown( | |
103 renderer, extensions=(exts | other)) | |
104 | |
105 | |
106 ext_translate = { | |
107 'fenced_code': 'EXT_FENCED_CODE', | |
108 'footnotes': 'EXT_FOOTNOTES', | |
109 'tables': 'EXT_TABLES', | |
110 'nl2br': 'HTML_HARD_WRAP', | |
111 'smarty': 'HTML_SMARTYPANTS', | |
112 'smartypants': 'HTML_SMARTYPANTS', | |
113 'toc': 'HTML_TOC', | |
114 'extra': ['EXT_FENCED_CODE', 'EXT_FOOTNOTES', 'EXT_TABLES'] | |
115 } | |
116 |