forked from CrossDark/CrossDown
2.1 添加变量
This commit is contained in:
parent
9d31d7e1e5
commit
562aca135e
@ -1,3 +1,5 @@
|
|||||||
|
from re import Match
|
||||||
|
|
||||||
from markdown.extensions import Extension, extra, admonition, meta, sane_lists, toc, wikilinks, codehilite
|
from markdown.extensions import Extension, extra, admonition, meta, sane_lists, toc, wikilinks, codehilite
|
||||||
|
|
||||||
from pygments.formatters import HtmlFormatter
|
from pygments.formatters import HtmlFormatter
|
||||||
@ -5,6 +7,7 @@ from pygments.formatters import HtmlFormatter
|
|||||||
from markdown.treeprocessors import Treeprocessor
|
from markdown.treeprocessors import Treeprocessor
|
||||||
from markdown.inlinepatterns import InlineProcessor
|
from markdown.inlinepatterns import InlineProcessor
|
||||||
from markdown.blockprocessors import BlockProcessor
|
from markdown.blockprocessors import BlockProcessor
|
||||||
|
from markdown.preprocessors import Preprocessor
|
||||||
from markdown import Markdown
|
from markdown import Markdown
|
||||||
from typing import *
|
from typing import *
|
||||||
import re
|
import re
|
||||||
@ -53,6 +56,24 @@ Extensions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class PreProcess(Preprocessor):
|
||||||
|
"""预处理"""
|
||||||
|
def __init__(self, variable: Variable):
|
||||||
|
super().__init__()
|
||||||
|
self.variable = variable
|
||||||
|
|
||||||
|
def run(self, lines: List[str]) -> List[str]:
|
||||||
|
new_lines = []
|
||||||
|
for line in lines: # 逐行遍历
|
||||||
|
for value in re.findall(r'\{\[(.+?)]}', line): # 找到变量
|
||||||
|
if value in self.variable: # 变量已定义
|
||||||
|
line = re.sub(fr'\{{\[{value}]}}', self.variable[value], line) # 替换变量为值
|
||||||
|
else:
|
||||||
|
line = re.sub(fr'\{{\[{value}]}}', value, line) # 不替换变量
|
||||||
|
new_lines.append(line)
|
||||||
|
return new_lines
|
||||||
|
|
||||||
|
|
||||||
class Simple(InlineProcessor):
|
class Simple(InlineProcessor):
|
||||||
"""
|
"""
|
||||||
可通过简单的正则表达式和HTML标签实现的样式
|
可通过简单的正则表达式和HTML标签实现的样式
|
||||||
@ -67,11 +88,17 @@ class Simple(InlineProcessor):
|
|||||||
super().__init__(pattern)
|
super().__init__(pattern)
|
||||||
self.tag = tag
|
self.tag = tag
|
||||||
|
|
||||||
def handleMatch(self, match, match_line):
|
def handleMatch(self, m: Match[str], data: str) -> Tuple[xml.etree.ElementTree.Element, int, int] | Tuple[None, None, None]:
|
||||||
|
"""
|
||||||
|
处理匹配
|
||||||
|
:param m: re模块的匹配对象
|
||||||
|
:param data: 被匹配的原始文本
|
||||||
|
:return: 标签 匹配开始 匹配结束
|
||||||
|
"""
|
||||||
tag = xml.etree.ElementTree.Element(self.tag) # 创建标签
|
tag = xml.etree.ElementTree.Element(self.tag) # 创建标签
|
||||||
tag.text = match.group(1) # 获取匹配到的文本并设置为标签的内容
|
tag.text = m.group(1) # 获取匹配到的文本并设置为标签的内容
|
||||||
|
|
||||||
return tag, match.start(), match.end()
|
return tag, m.start(), m.end()
|
||||||
|
|
||||||
|
|
||||||
class Nest(InlineProcessor):
|
class Nest(InlineProcessor):
|
||||||
@ -90,13 +117,19 @@ class Nest(InlineProcessor):
|
|||||||
self.outer_tag = outer_tag
|
self.outer_tag = outer_tag
|
||||||
self.inner_tag = inner_tag
|
self.inner_tag = inner_tag
|
||||||
|
|
||||||
def handleMatch(self, match, match_line):
|
def handleMatch(self, m: Match[str], data: str) -> Tuple[xml.etree.ElementTree.Element, int, int] | Tuple[None, None, None]:
|
||||||
|
"""
|
||||||
|
处理匹配
|
||||||
|
:param m: re模块的匹配对象
|
||||||
|
:param data: 被匹配的原始文本
|
||||||
|
:return: 标签 匹配开始 匹配结束
|
||||||
|
"""
|
||||||
outer_tag = xml.etree.ElementTree.Element(self.outer_tag) # 创建外层标签
|
outer_tag = xml.etree.ElementTree.Element(self.outer_tag) # 创建外层标签
|
||||||
inner_tag = xml.etree.ElementTree.SubElement(outer_tag, self.inner_tag) # 创建内层标签
|
inner_tag = xml.etree.ElementTree.SubElement(outer_tag, self.inner_tag) # 创建内层标签
|
||||||
outer_tag.text = match.group(1) # 设置外层标签文本
|
outer_tag.text = m.group(1) # 设置外层标签文本
|
||||||
inner_tag.text = match.group(2) # 设置内层标签文本
|
inner_tag.text = m.group(2) # 设置内层标签文本
|
||||||
|
|
||||||
return outer_tag, match.start(), match.end()
|
return outer_tag, m.start(), m.end()
|
||||||
|
|
||||||
|
|
||||||
class ID(InlineProcessor):
|
class ID(InlineProcessor):
|
||||||
@ -117,12 +150,18 @@ class ID(InlineProcessor):
|
|||||||
self.property = property_
|
self.property = property_
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def handleMatch(self, match, match_line):
|
def handleMatch(self, m: Match[str], data: str) -> Tuple[xml.etree.ElementTree.Element, int, int] | Tuple[None, None, None]:
|
||||||
|
"""
|
||||||
|
处理匹配
|
||||||
|
:param m: re模块的匹配对象
|
||||||
|
:param data: 被匹配的原始文本
|
||||||
|
:return: 标签 匹配开始 匹配结束
|
||||||
|
"""
|
||||||
tag = xml.etree.ElementTree.Element(self.tag) # 创建标签
|
tag = xml.etree.ElementTree.Element(self.tag) # 创建标签
|
||||||
tag.text = match.group(1) # 设置标签内容
|
tag.text = m.group(1) # 设置标签内容
|
||||||
tag.set(self.property, match.group(2) if self.value is None else self.value) # 设置标签属性,属性的值默认为第二个匹配组
|
tag.set(self.property, m.group(2) if self.value is None else self.value) # 设置标签属性,属性的值默认为第二个匹配组
|
||||||
|
|
||||||
return tag, match.start(), match.end()
|
return tag, m.start(), m.end()
|
||||||
|
|
||||||
|
|
||||||
class Emoji(InlineProcessor):
|
class Emoji(InlineProcessor):
|
||||||
@ -137,19 +176,36 @@ class Emoji(InlineProcessor):
|
|||||||
"""
|
"""
|
||||||
super().__init__(pattern)
|
super().__init__(pattern)
|
||||||
|
|
||||||
def handleMatch(self, match, match_line):
|
def handleMatch(self, m: Match[str], data: str) -> Tuple[xml.etree.ElementTree.Element, int, int] | Tuple[None, None, None]:
|
||||||
return emoji.emojize(match.group(0)), match.start(), match.end()
|
"""
|
||||||
|
处理匹配
|
||||||
|
:param m: re模块的匹配对象
|
||||||
|
:param data: 被匹配的原始文本
|
||||||
|
:return: 标签 匹配开始 匹配结束
|
||||||
|
"""
|
||||||
|
return emoji.emojize(m.group(0)), m.start(), m.end()
|
||||||
|
|
||||||
|
|
||||||
class Syllabus(BlockProcessor):
|
class Syllabus(BlockProcessor):
|
||||||
# 定义提纲的正则表达式
|
# 定义提纲的正则表达式
|
||||||
syllabus_re = r'(\d+(\.\d+)*)\s+(.*)'
|
syllabus_re = r'(\d+(\.\d+)*)\s+(.*)'
|
||||||
|
|
||||||
def test(self, parent, block):
|
def test(self, parent: xml.etree.ElementTree.Element, block: str) -> Match[str] | None | bool:
|
||||||
# 检查当前块是否匹配正则表达式
|
"""
|
||||||
|
检查当前块是否匹配正则表达式
|
||||||
|
:param parent: 当前块的Element对象
|
||||||
|
:param block: 当前块的内容
|
||||||
|
:return: 匹配成功与否
|
||||||
|
"""
|
||||||
return re.match(self.syllabus_re, block)
|
return re.match(self.syllabus_re, block)
|
||||||
|
|
||||||
def run(self, parent, blocks):
|
def run(self, parent: xml.etree.ElementTree.Element, blocks: List[str]) -> bool | None:
|
||||||
|
"""
|
||||||
|
对匹配到的块进行处理
|
||||||
|
:param parent: 当前块的Element对象
|
||||||
|
:param blocks: 包含文本中剩余块的列表
|
||||||
|
:return: 匹配成功与否
|
||||||
|
"""
|
||||||
syllabus = re.match(self.syllabus_re, blocks[0]) # 匹配提纲的号和内容
|
syllabus = re.match(self.syllabus_re, blocks[0]) # 匹配提纲的号和内容
|
||||||
header = xml.etree.ElementTree.SubElement(parent, f'h{len(syllabus.group(1).split("."))}') # 按照提纲号等级创建标题
|
header = xml.etree.ElementTree.SubElement(parent, f'h{len(syllabus.group(1).split("."))}') # 按照提纲号等级创建标题
|
||||||
header.set('id', syllabus.group(1)) # 设置提纲ID
|
header.set('id', syllabus.group(1)) # 设置提纲ID
|
||||||
@ -160,6 +216,13 @@ class Syllabus(BlockProcessor):
|
|||||||
|
|
||||||
class BoxBlock(BlockProcessor):
|
class BoxBlock(BlockProcessor):
|
||||||
def __init__(self, parser, re_start, re_end, style):
|
def __init__(self, parser, re_start, re_end, style):
|
||||||
|
"""
|
||||||
|
初始化
|
||||||
|
:param parser:
|
||||||
|
:param re_start:
|
||||||
|
:param re_end:
|
||||||
|
:param style:
|
||||||
|
"""
|
||||||
super().__init__(parser)
|
super().__init__(parser)
|
||||||
self.re_start = re_start # start line, e.g., ` !!!!
|
self.re_start = re_start # start line, e.g., ` !!!!
|
||||||
self.re_end = re_end # last non-blank line, e.g, '!!!\n \n\n'
|
self.re_end = re_end # last non-blank line, e.g, '!!!\n \n\n'
|
||||||
@ -252,12 +315,23 @@ class CodeLine(Treeprocessor):
|
|||||||
code.text = key
|
code.text = key
|
||||||
|
|
||||||
|
|
||||||
|
class Pre(Extension):
|
||||||
|
"""预处理"""
|
||||||
|
def __init__(self, variable: Variable):
|
||||||
|
super().__init__()
|
||||||
|
self.variable = variable
|
||||||
|
|
||||||
|
def extendMarkdown(self, md: Markdown):
|
||||||
|
md.registerExtension(self) # 注册扩展
|
||||||
|
md.preprocessors.register(PreProcess(self.variable), 'pre_process', 0)
|
||||||
|
|
||||||
|
|
||||||
class Basic(Extension):
|
class Basic(Extension):
|
||||||
"""
|
"""
|
||||||
渲染基本样式
|
渲染基本样式
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def extendMarkdown(self, md):
|
def extendMarkdown(self, md: Markdown):
|
||||||
md.registerExtension(self) # 注册扩展
|
md.registerExtension(self) # 注册扩展
|
||||||
md.inlinePatterns.register(Simple(r'~~(.*?)~~', tag='s'), 'strikethrough', 176) # ~~删除线~~
|
md.inlinePatterns.register(Simple(r'~~(.*?)~~', tag='s'), 'strikethrough', 176) # ~~删除线~~
|
||||||
md.inlinePatterns.register(Simple(r'~(.*?)~', tag='u'), 'underline', 177) # ~下划线~
|
md.inlinePatterns.register(Simple(r'~(.*?)~', tag='u'), 'underline', 177) # ~下划线~
|
||||||
@ -289,7 +363,7 @@ class Box(Extension):
|
|||||||
|
|
||||||
# 黄框提醒
|
# 黄框提醒
|
||||||
md.inlinePatterns.register(ID(
|
md.inlinePatterns.register(ID(
|
||||||
r'!-!(.+?)!-!', tag='div', property_='style', value='display: inline-block; border: 1px solid yellow;'
|
r'!{2}(.+?)!{2}', tag='div', property_='style', value='display: inline-block; border: 1px solid yellow;'
|
||||||
), 'reminding_in_line', 192) # 行内
|
), 'reminding_in_line', 192) # 行内
|
||||||
md.parser.blockprocessors.register(BoxBlock(
|
md.parser.blockprocessors.register(BoxBlock(
|
||||||
md.parser, r'^ *!-! *\n', r'\n *!-!\s*$', 'display: inline-block; border: 1px solid yellow;'
|
md.parser, r'^ *!-! *\n', r'\n *!-!\s*$', 'display: inline-block; border: 1px solid yellow;'
|
||||||
@ -338,5 +412,5 @@ def main(text: str, variable: Variable = None) -> Tuple[str, Dict[str, Variable]
|
|||||||
"""
|
"""
|
||||||
if variable is None:
|
if variable is None:
|
||||||
variable = {}
|
variable = {}
|
||||||
md = Markdown(extensions=[Basic(), Box(), Anchor()] + list(Extensions.values()) + [Code(variable=variable)])
|
md = Markdown(extensions=[Pre(variable=variable), Basic(), Box(), Anchor()] + list(Extensions.values()) + [Code(variable=variable)])
|
||||||
return md.convert(text), md.Meta
|
return md.convert(text), md.Meta
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import *
|
from typing import *
|
||||||
|
|
||||||
|
|
||||||
Variable = Union[Dict[str, Union[str, Tuple[str], List[str]]], None]
|
Variable = Dict[str, Union[str, Tuple[str], List[str]]] | None
|
||||||
|
23
README.html
23
README.html
@ -75,6 +75,7 @@
|
|||||||
<li><a href="#4.2.3">4.2.3 Mermaid</a></li>
|
<li><a href="#4.2.3">4.2.3 Mermaid</a></li>
|
||||||
<li><a href="#4.2.4">4.2.4 shell</a></li>
|
<li><a href="#4.2.4">4.2.4 shell</a></li>
|
||||||
<li><a href="#4.2.5">4.2.5 latex</a></li>
|
<li><a href="#4.2.5">4.2.5 latex</a></li>
|
||||||
|
<li><a href="#4.2.6">4.2.6 HTML</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -116,6 +117,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#15">15 内部链接</a></li>
|
<li><a href="#15">15 内部链接</a></li>
|
||||||
|
<li><a href="#16">16 变量</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<h1 id="crossdown">CrossDown</h1>
|
<h1 id="crossdown">CrossDown</h1>
|
||||||
@ -230,6 +232,10 @@
|
|||||||
<span class="k">\end</span><span class="nb">{</span>document<span class="nb">}</span>
|
<span class="k">\end</span><span class="nb">{</span>document<span class="nb">}</span>
|
||||||
</code></pre></div>
|
</code></pre></div>
|
||||||
|
|
||||||
|
<h3 id="4.2.6">4.2.6 HTML</h3>
|
||||||
|
<div class="codehilite"><pre><span></span><code class="html">*斜体***粗体**~下划线~~~删除线~~==高亮==
|
||||||
|
</code></pre></div>
|
||||||
|
|
||||||
<h1 id="5">5 转义</h1>
|
<h1 id="5">5 转义</h1>
|
||||||
<p>\ </p>
|
<p>\ </p>
|
||||||
<p>\a </p>
|
<p>\a </p>
|
||||||
@ -265,6 +271,7 @@
|
|||||||
<p>7..1...4 错误示范</p>
|
<p>7..1...4 错误示范</p>
|
||||||
<p>提纲号会被自动配置为锚点,可直接使用<a href="#7">7</a><a href="#7.1">7.1</a></p>
|
<p>提纲号会被自动配置为锚点,可直接使用<a href="#7">7</a><a href="#7.1">7.1</a></p>
|
||||||
<h1 id="8">8 注释</h1>
|
<h1 id="8">8 注释</h1>
|
||||||
|
<p>|==| 注释</p>
|
||||||
<h2 id="8.1">8.1 强注释</h2>
|
<h2 id="8.1">8.1 强注释</h2>
|
||||||
<p>|=
|
<p>|=
|
||||||
无论如何都会被移除
|
无论如何都会被移除
|
||||||
@ -374,21 +381,23 @@
|
|||||||
<p>这是一条警告</p>
|
<p>这是一条警告</p>
|
||||||
</div>
|
</div>
|
||||||
<h2 id="14.2">14.2 提醒</h2>
|
<h2 id="14.2">14.2 提醒</h2>
|
||||||
<p>这是一个!-!提醒!-!……</p>
|
<p>这是一个!!提醒!!……</p>
|
||||||
<p>!-!
|
<p>!!
|
||||||
这是一条提醒
|
这是一条提醒
|
||||||
!-!</p>
|
!!</p>
|
||||||
<h2 id="14.3">14.3 安心</h2>
|
<h2 id="14.3">14.3 安心</h2>
|
||||||
<p>这是一个,,,安心,,,……</p>
|
<p>这是一个,,,安心,,,……</p>
|
||||||
<p>,,,
|
<p>,,,
|
||||||
这是一条安心
|
这是一条安心
|
||||||
,,,</p>
|
,,,</p>
|
||||||
<h2 id="14.4">14.4 怀疑</h2>
|
<h2 id="14.4">14.4 怀疑</h2>
|
||||||
<p>这是一个,-,怀疑,-,……</p>
|
<p>这是一个,,怀疑,,……</p>
|
||||||
<div style="display: inline-block; border: 1px solid blue;">
|
<p>,,
|
||||||
<p>这是一条怀疑</p>
|
这是一条怀疑
|
||||||
</div>
|
,,</p>
|
||||||
<h1 id="15">15 内部链接</h1>
|
<h1 id="15">15 内部链接</h1>
|
||||||
<p><a class="wikilink" href="/Bracketed/">Bracketed</a></p>
|
<p><a class="wikilink" href="/Bracketed/">Bracketed</a></p>
|
||||||
|
<h1 id="16">16 变量</h1>
|
||||||
|
<p>强调值</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
24
README.md
24
README.md
@ -180,6 +180,12 @@ cd ../..
|
|||||||
\end{document}
|
\end{document}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
4.2.6 HTML
|
||||||
|
|
||||||
|
```html
|
||||||
|
*斜体***粗体**~下划线~~~删除线~~==高亮==
|
||||||
|
```
|
||||||
|
|
||||||
5 转义
|
5 转义
|
||||||
|
|
||||||
\\
|
\\
|
||||||
@ -221,6 +227,8 @@ cd ../..
|
|||||||
|
|
||||||
8 注释
|
8 注释
|
||||||
|
|
||||||
|
|==| 注释
|
||||||
|
|
||||||
8.1 强注释
|
8.1 强注释
|
||||||
|
|
||||||
|=
|
|=
|
||||||
@ -324,11 +332,11 @@ Orange
|
|||||||
|
|
||||||
14.2 提醒
|
14.2 提醒
|
||||||
|
|
||||||
这是一个!-!提醒!-!……
|
这是一个!!提醒!!……
|
||||||
|
|
||||||
!-!
|
!!
|
||||||
这是一条提醒
|
这是一条提醒
|
||||||
!-!
|
!!
|
||||||
|
|
||||||
14.3 安心
|
14.3 安心
|
||||||
|
|
||||||
@ -340,12 +348,16 @@ Orange
|
|||||||
|
|
||||||
14.4 怀疑
|
14.4 怀疑
|
||||||
|
|
||||||
这是一个,-,怀疑,-,……
|
这是一个,,怀疑,,……
|
||||||
|
|
||||||
,-,
|
,,
|
||||||
这是一条怀疑
|
这是一条怀疑
|
||||||
,-,
|
,,
|
||||||
|
|
||||||
15 内部链接
|
15 内部链接
|
||||||
|
|
||||||
[[Bracketed]]
|
[[Bracketed]]
|
||||||
|
|
||||||
|
16 变量
|
||||||
|
|
||||||
|
{[强调变量]}
|
||||||
|
2
setup.py
2
setup.py
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="CrossDown",
|
name="CrossDown",
|
||||||
version="2.0.2",
|
version="2.1.0",
|
||||||
author="CrossDark",
|
author="CrossDark",
|
||||||
author_email="liuhanbo333@icloud.com",
|
author_email="liuhanbo333@icloud.com",
|
||||||
description="CrossDark's MarkDown",
|
description="CrossDark's MarkDown",
|
||||||
|
Loading…
Reference in New Issue
Block a user