#!/usr/local/bin/python3 # -*- coding: utf-8 -*- # pylint: disable=fixme """ Pandoc filter that converts Agenda tag and people to Bootstrap badge span, i.e. `#XXX(...)` to `#XXX(...)` and `@XXX` to `@XXX` Letters, numbers, comas, underscore, hyphon and space are allowed in the parenthese. `tag` and `people` can be changed as you like Some special patterns will not be converted: 1. `XXX` == `eq:xxx-xxx`, as they will be used by pandoc-eqnos in LaTeX equations (no latex) 2. any #XXX(...) or @XXX in an isolated braket `[]`, since they will be processed by Biblatex to generate citation. N.B.: Nested brakets are not supported. Check your writing. minyez@github, Public License """ import re import panflute as pf # This can be customized to any Bootstrap badge class dict_html = {"#": "tag", "@": "people"} # pylint: disable=global-statement def generate_badge(el, text, doc, badgetag): '''Generate the Span ''' global dict_html if doc.format.startswith('html'): # convert to span only for html outputs return pf.Span(pf.Str(text), \ classes=["badge", "badge"+'-'+dict_html[badgetag]]) if doc.format.startswith('latex'): #TODO: define something for making the badge-like effect in latex template and put it here pass return el str_to_replace = '' in_square_braket_cite = False in_tag = False # REs to match IDEN_WITH_BOTH_PAR = re.compile("[#@][\w-]+\([\w,-]*\)") IDEN_WITH_NO_PAR = re.compile("[#@][\w-]+") IDEN_WITH_LEFT_PAR = re.compile("[#@][\w-]+\([\w,-]*") NONIDEN_WITH_RIGHT_PAR = re.compile("[^#@][\w,-]+\)") IS_EQU_REFS = re.compile("[#@]eq:[\w-]*") # pylint: disable=global-statement,too-many-return-statements,too-many-branches def convert_tag_people(el, doc): '''Convert Agenda tag and people to Bootstrap badge span ''' global str_to_replace global in_square_braket_cite global in_tag global IDEN_WITH_BOTH_PAR global IDEN_WITH_NO_PAR global IDEN_WITH_LEFT_PAR global NONIDEN_WITH_RIGHT_PAR global IS_EQU_REFS # Currently support html output only if not doc.format.startswith('html'): return el is_str = isinstance(el, pf.Str) if is_str: _text = el.text if _text.endswith("]"): in_square_braket_cite = False return el if _text.startswith("["): in_square_braket_cite = True return el if in_square_braket_cite: return el if not in_tag: if IDEN_WITH_BOTH_PAR.fullmatch(_text): str_to_replace = '' return generate_badge(el, _text, doc, _text[0]) if IDEN_WITH_NO_PAR.fullmatch(_text): if IS_EQU_REFS.fullmatch(_text): return el str_to_replace = '' return generate_badge(el, _text, doc, _text[0]) if IDEN_WITH_LEFT_PAR.fullmatch(_text): str_to_replace = _text in_tag = True return [] else: # inside the tag/people, check if end the tag/people. # Found right parenthese at the end, return the whole string if NONIDEN_WITH_RIGHT_PAR.fullmatch(_text): in_tag = False str_to_replace += _text return generate_badge(el, str_to_replace, doc, str_to_replace[0]) # no right parenthese found, purge it to str_to_replace, return empty element str_to_replace += _text return [] else: if in_tag and not in_square_braket_cite: #Within the tag/people and is a space, add space to str_to_replace if isinstance(el, pf.Space): str_to_replace += ' ' return [] return el if __name__ == "__main__": pf.toJSONFilter(convert_tag_people)