Track general purpose custom markup

This commit is contained in:
RunasSudo 2020-06-20 23:10:01 +10:00
parent 4353265dca
commit 0196f3f86a
Signed by: RunasSudo
GPG Key ID: 7234E476BF21C61A
3 changed files with 127 additions and 4 deletions

2
.gitignore vendored
View File

@ -2,4 +2,4 @@
/index.pickle
__pycache__
/wikinote/markup_custom.py
/wikinote/markup_custom2.py

View File

@ -411,9 +411,13 @@ class FootnoteInlineProcessor(markdown.extensions.footnotes.FootnoteInlineProces
return None, None, None
# Custom directives and roles
from . import markup_custom
directives.update(markup_custom.directives)
roles.update(markup_custom.roles)
try:
from . import markup_custom
directives.update(markup_custom.directives)
roles.update(markup_custom.roles)
from . import markup_custom2
directives.update(markup_custom2.directives)
roles.update(markup_custom2.roles)
except ImportError:
pass

119
wikinote/markup_custom.py Normal file
View File

@ -0,0 +1,119 @@
# WikiNote3
# Copyright © 2020 Lee Yingtong Li (RunasSudo)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import flask
import os.path
import re
import xml.etree.ElementTree as ET
directives = {}
roles = {}
class DirectiveElement(ET.Element):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.directive = None
class Directive:
def __init__(self, md, arg=None, content=None):
self.md = md
self.arg = arg
self.content = content
class RoleElement(ET.Element):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.role = None
class Role:
def __init__(self, parser, content=None):
self.parser = parser
self.md = parser.md
self.content = content
def capitalise(n):
if n.startswith('('):
return '(' + capitalise(n[1:])
return n[0].upper() + n[1:]
class DirectiveTag(Directive):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.md.meta['tags'] = self.md.meta.get('tags', []) + self.arg.split(', ')
def render(self):
return DirectiveElement('div')
directives['tag'] = DirectiveTag
class DirectiveInclude(Directive):
def render(self):
el = DirectiveElement('div')
with open(flask.safe_join('./data', self.arg), 'r') as f:
self.md.parser.parseChunk(el, f.read())
return el
directives['include'] = DirectiveInclude
def make_role_ref(is_upper):
class RoleRef(Role):
def render(self):
if ';' in self.content:
label, path = self.content.split(';')
else:
path = self.content
label = path.split('/')[-1]
if is_upper:
label = label[0].upper() + label[1:]
else:
label = label[0].lower() + label[1:]
# Tooltip wrapper
el = RoleElement('span')
el.set('class', 'tooltip xref')
el.set('data-xref', path)
# Link
a = ET.SubElement(el, 'a')
if os.path.exists(flask.safe_join('./data/pages', path + '.md')):
a.set('class', 'ref')
else:
a.set('class', 'ref redlink')
self.md.meta['redlinks'] = self.md.meta.get('redlinks', []) + [path]
a.set('href', flask.url_for('page_view', path=path))
a.text = label
# Tooltip content container
div = ET.SubElement(el, 'span')
div.set('class', 'tooltip-content')
div.text = 'Loading…'
return el
return RoleRef
roles['ref'] = make_role_ref(False)
roles['Ref'] = make_role_ref(True)
class RoleImage(Role):
def render(self):
el = RoleElement('a')
el.set('href', flask.url_for('image_about', name=self.content))
img = ET.SubElement(el, 'img')
img.set('src', flask.url_for('image_view', name=self.content))
return el
roles['image'] = RoleImage