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 |
