def convert_markdown_to_html(clean_md): """ Take a string `clean_md` and return a string where the Markdown syntax is converted to HTML. """ assert isinstance(clean_md, unicode), "Input `clean_md` is not Unicode" new_html = markdown.markdown(clean_md, output_format="xhtml1", extensions=[ SmartEmphasisExtension(), FencedCodeExtension(), FootnoteExtension(), AttrListExtension(), DefListExtension(), TableExtension(), AbbrExtension(), Nl2BrExtension(), CodeHiliteExtension( noclasses=True, pygments_style=preferences.PREFS.get( const.MARKDOWN_SYNTAX_STYLE), linenums=preferences.PREFS.get( const.MARKDOWN_LINE_NUMS)), SaneListExtension() ], lazy_ol=False) assert isinstance(new_html, unicode) return new_html
def __init__(self, settings: MarkdownSettings): self.settings = settings self.extensions = [] if self.settings.enable_checklist: self.extensions.append(ChecklistExtension()) if self.settings.enable_codehilite: self.extensions.append( CodeHiliteExtension(**self.settings.codehilite_options) ) if self.settings.enable_fenced_code: self.extensions.append(FencedCodeExtension()) if self.settings.enable_footnotes: self.extensions.append(FootnoteExtension(**self.settings.footnotes_options)) if self.settings.enable_smartypants: self.extensions.append(SmartyExtension(**self.settings.smartypants_options)) if self.settings.enable_toc: self.extensions.append(TocExtension(**self.settings.toc_options)) if self.settings.enable_truly_sane_lists: self.extensions.append( TrulySaneListExtension(**self.settings.truly_sane_lists_options) ) super().__init__( output_format=self.settings.output_format, tab_length=self.settings.tab_length, extensions=self.extensions, )
def parse(text): """ https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions https://facelessuser.github.io/pymdown-extensions """ text = markdown.markdown(text, extensions=[ FootnoteExtension(), TableExtension(), FencedCodeExtension(), CodeHiliteExtension(), Nl2BrExtension(), TocExtension(slugify=slugs.uslugify, permalink=False), TrulySaneExt(), tilde.makeExtension(), caret.makeExtension(), ]) tags = 'a,h1,h2,h3,h4,h5,h6,p,div,pre,code,span,img,br,' \ 'ul,ol,li,table,tr,th,td,thead,tbody,blockquote,' \ 'del,em,strong,sub,sup' attrs = {'*': ['class'], 'a': ['href', 'rel'], 'img': ['alt']} attrs.update({f'h{n}': ['id'] for n in range(1, 7)}) # h1..h6 support TOC anchor text = bleach.clean( text, tags=tags.split(','), attributes=attrs, ) # HTML sanitizer return text
def parse_markdown(text, noclasses, style, line_nums, tab_len, mathext): extensions = [] if mathext: extensions.append(MathExtension()) extensions.extend([ FencedCodeExtension(), FootnoteExtension(), AttrListExtension(), DefListExtension(), TableExtension(), AbbrExtension(), Nl2BrExtension(), CodeHiliteExtension( noclasses=noclasses, pygments_style=style, linenums=line_nums, ), SaneListExtension(), SmartyExtension() ]) return markdown.markdown( text, output_format="xhtml1", extensions=extensions, lazy_ol=False, tab_length=tab_len, )
def format_text( text, useMarkdown, markdownStyle, markdownLineNums, markdownTabLength, ): if useMarkdown: noclasses = markdownStyle != 'default' html_ish = markdown.markdown( text, output_format="xhtml1", extensions=[ SmartEmphasisExtension(), FencedCodeExtension(), FootnoteExtension(), AttrListExtension(), DefListExtension(), TableExtension(), AbbrExtension(), Nl2BrExtension(), CodeHiliteExtension(noclasses=noclasses, pygments_style=markdownStyle, linenums=markdownLineNums), SaneListExtension(), SmartyExtension() ], lazy_ol=False, tab_length=markdownTabLength, ) else: # Preserve whitespace. html_ish = text.replace('\n', '<br>').replace(' ', ' ') return html_ish
def markdown_to_html(plain): """Convert Markdown to HTML""" import re import base64 from bs4 import BeautifulSoup import markdown from markdown.extensions.abbr import AbbrExtension from markdown.extensions.codehilite import CodeHiliteExtension from markdown.extensions.def_list import DefListExtension from markdown.extensions.fenced_code import FencedCodeExtension from markdown.extensions.footnotes import FootnoteExtension # Don't convert if plain text is really plain if re.match(r"[a-zA-Z0-9æøåÆØÅ ,.?+-]*$", plain): return plain # Fix whitespaces in input plain = plain.replace("\xc2\xa0", " ").replace("\xa0", " ") # For convenience: Fix mathjax escaping plain = plain.replace(r"\[", r"\\[") plain = plain.replace(r"\]", r"\\]") plain = plain.replace(r"\(", r"\\(") plain = plain.replace(r"\)", r"\\)") html = markdown.markdown(plain, extensions=[ AbbrExtension(), CodeHiliteExtension( noclasses=True, linenums=False, pygments_style='friendly', guess_lang=False, ), DefListExtension(), FencedCodeExtension(), FootnoteExtension(), ], output_format="html5") html_tree = BeautifulSoup(html, 'html.parser') tag = _get_first_tag(html_tree) if not tag: if not html: # Add space to prevent input field from shrinking in UI html = " " html_tree = BeautifulSoup(f"<div>{html}</div>", "html.parser") tag = _get_first_tag(html_tree) # Store original text as data-attribute on tree root # Note: convert newlines to <br> to make text readable in the Anki viewer original_html = base64.b64encode( plain.replace("\n", "<br />").encode('utf-8')).decode() tag['data-original-markdown'] = original_html return str(html_tree)
def FEED_ALTER_SETTINGS(settings): import six from markdown.extensions.footnotes import FootnoteExtension markdown_opts = settings['MARKDOWN'] for ext in list(markdown_opts['extensions']): is_str = isinstance(ext, six.string_types) if is_str and ext == 'markdown.extensions.footnotes': markdown_opts['extensions'].remove(ext) elif isinstance(ext, md_extensions.FootnoteExtExtension): markdown_opts['extensions'].remove(ext) # it's necessary to create instance to get unique_prefix being persistent markdown_opts['extensions'].append(FootnoteExtension(UNIQUE_IDS=True))
def strToClassEXt(extensions): e_idx = [] if ("nl2br" in extensions): e_idx.append(Nl2BrExtension()) if ("footnotes" in extensions): e_idx.append(FootnoteExtension()) if ("def_list" in extensions): e_idx.append(DefListExtension()) if ("md_in_html" in extensions): e_idx.append(MarkdownInHtmlExtension()) if ("pymdownx.caret" in extensions): e_idx.append(InsertSupExtension(smart_insert=False, insert=False)) if ("pymdownx.magiclink" in extensions): e_idx.append(MagiclinkExtension()) if ("pymdownx.smartsymbols" in extensions): e_idx.append(SmartSymbolsExtension()) return e_idx
def testInstanceExtension(self): """ Test Extension loading with a class instance. """ from markdown.extensions.footnotes import FootnoteExtension markdown.Markdown(extensions=[FootnoteExtension()])
from checkclock import ReadOnlyCheckclock, as_time, as_hours_and_minutes checkclock = ReadOnlyCheckclock( Path("~/.config/qtile/checkclock.sqlite").expanduser(), working_days="Mon-Fri" ) ordinal_pattern = re.compile(r"\b([0-9]{1,2})(st|nd|rd|th)\b") md = markdown.Markdown( output_format="html5", extensions=[ FencedCodeExtension(), CodeHiliteExtension(css_class="highlight", guess_lang=False), DefListExtension(), FootnoteExtension(), MetaExtension(), Nl2BrExtension(), SaneListExtension(), TocExtension(), StrikethroughExtension(), TableExtension(), AttrListExtension(), ], ) DOWNLOAD_EXTENSIONS = [".ods", ".odt"] LEXER_MAP = {"pgsql": "sql"} THEME_MODE_KEY = "theme-mode" DEFAULT_THEME_MODE = "light"
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from flask_security import Security from flask_sqlalchemy import SQLAlchemy from flask_mail import Mail from flask_bootstrap import Bootstrap from flask_flatpages import FlatPages from flask_moment import Moment from flask_wtf.csrf import CSRFProtect from flask_migrate import Migrate from markdown.extensions.tables import TableExtension from markdown.extensions.footnotes import FootnoteExtension from markdown.extensions.fenced_code import FencedCodeExtension from markdown.extensions.wikilinks import WikiLinkExtension db = SQLAlchemy() security = Security() bootstrap = Bootstrap() mail = Mail() pages = FlatPages() moment = Moment() csrf = CSRFProtect() migrate = Migrate() tables = TableExtension() footnotes = FootnoteExtension() fenced_code = FencedCodeExtension() wikilinks = WikiLinkExtension()
def markdown(eval_ctx, value, attr=''): return markdown_(value, extensions=[FootnoteExtension()])
class Wiki: DEFAULT_MD_EXTENSIONS = [ FootnoteExtension(), TocExtension(), TableExtension(), MetaExtension(), AutoTitleExtension(), HintedWikiLinkExtension(), SizeEnabledImageExtension() ] @staticmethod def link_to(page): return getattr(page, 'link_to', None) or '/page/' + page def __init__(self, md_extensions=[...]): if md_extensions[-1] is ...: md_extensions = md_extensions[:-1] + self.DEFAULT_MD_EXTENSIONS self.md = markdown.Markdown(extensions=md_extensions) self.title = 'UNSET TITLE' self.logo = '/static/logo.png' self.root_dir_path = None self.rsc_dir_path = None self.titles: Dict[str, Page] = {} # page keys are always in lowercase self.tags: Dict[str, List[Page]] = defaultdict(list) # tag names are always lowercase self.unique_pages: List[Page] = [] def set_root_path(self, path: Path): self.root_dir_path = path self.rsc_dir_path = path / 'rsc' def scan_path(self, clear=False): if clear: self.clear_pages() conf_path = self.root_dir_path / 'config.py' if conf_path.is_file(): exec(conf_path.read_text(), {'wiki': self}) for page_path in self.root_dir_path.glob('[!_]*.md'): try: with page_path.open() as r: page = Page(r.read(), self) except PageLoadError as e: raise PageLoadError('error loading page ' + str(page_path)) from e self.add_page(page) def clear_pages(self): self.titles.clear() self.tags.clear() self.unique_pages.clear() def add_page(self, page: Page): for title in page.titles: p = self.titles.setdefault(title.lower(), page) if p is not page: raise Exception('multiple pages sharing a title ' + title) for t in page.tags: self.tags[t].append(page) self.unique_pages.append(page) def match(self, main, hints): main_terms = split_terms(main) hint_terms = split_terms(hints) for p in self.unique_pages: s = p.score(main_terms, hint_terms) yield p, s def best_match(self, main, hints)->MaxStore: store = MaxStore() main_terms = split_terms(main) hint_terms = split_terms(hints) for p in self.unique_pages: s = p.score(main_terms, hint_terms, cutoff=store.cutoff) store.add(p, s) return store def __getitem__(self, name): name = name.lower() return self.titles.get(name), self.tags.get(name) def __contains__(self, item): return (item in self.titles) or (item in self.tags) @classmethod def from_dir(cls, dir_path): ret = cls() dir_path = Path(dir_path).absolute() if not dir_path.is_dir(): raise ValueError('path id not a directory') ret.set_root_path(dir_path) ret.scan_path() return ret