Track general purpose custom markup
This commit is contained in:
parent
4353265dca
commit
0196f3f86a
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,4 @@
|
|||||||
/index.pickle
|
/index.pickle
|
||||||
__pycache__
|
__pycache__
|
||||||
|
|
||||||
/wikinote/markup_custom.py
|
/wikinote/markup_custom2.py
|
||||||
|
@ -411,9 +411,13 @@ class FootnoteInlineProcessor(markdown.extensions.footnotes.FootnoteInlineProces
|
|||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
# Custom directives and roles
|
# Custom directives and roles
|
||||||
try:
|
|
||||||
from . import markup_custom
|
from . import markup_custom
|
||||||
directives.update(markup_custom.directives)
|
directives.update(markup_custom.directives)
|
||||||
roles.update(markup_custom.roles)
|
roles.update(markup_custom.roles)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from . import markup_custom2
|
||||||
|
directives.update(markup_custom2.directives)
|
||||||
|
roles.update(markup_custom2.roles)
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
119
wikinote/markup_custom.py
Normal file
119
wikinote/markup_custom.py
Normal 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
|
Reference in New Issue
Block a user