#!/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)