# 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 . 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