1.5提纲头疼中

This commit is contained in:
跨越晨昏 2024-10-05 18:25:00 +08:00
parent 900d999b7a
commit 54c2584b0f
2 changed files with 179 additions and 114 deletions

View File

@ -1,13 +1,14 @@
import xml
import emoji
from markdown.extensions import Extension
from markdown.treeprocessors import Treeprocessor
from markdown.inlinepatterns import Pattern as Pattern_
from markdown.preprocessors import Preprocessor
from markdown.inlinepatterns import InlineProcessor
from markdown.blockprocessors import BlockProcessor
from markdown import Markdown
from typing import *
import re
import xml
import emoji
Extensions = {
"Extra": "markdown.extensions.extra",
@ -120,6 +121,56 @@ class Emoji(InlineProcessor):
return emoji.emojize(match.group(0)), match.start(), match.end()
class Syllabus_(InlineProcessor):
"""
需要对HTML标签设置ID实现的样式
"""
def __init__(self, pattern: str):
"""
初始化
:param pattern: 正则表达式
"""
super().__init__(pattern)
def handleMatch(self, match, match_line):
tag = xml.etree.ElementTree.Element(f'h{len(match.group(1).split("."))}') # 创建标签
tag.text = match.group(1) + ' ' + match.group(3) # 设置标签内容
tag.set('id', match.group(1)) # 设置标签属性
return tag, match.start(), match.end()
class Syllabus(BlockProcessor):
# 定义提纲的正则表达式
ALERT_RE = r'(\d+(\.\d+)*)\s+(.*)'
def test(self, parent, block):
# 检查当前块是否匹配我们的正则表达式
return bool(self.ALERT_RE.match(block))
def run(self, parent, blocks):
# 处理匹配的块
block = blocks.pop(0)
m = self.ALERT_RE.search(block)
if m:
before = block[:m.start()] # 匹配之前的文本
after = block[m.end():] # 匹配之后的文本
if before:
# 如果匹配之前有文本,则创建一个新的段落来包含它
p = etree.SubElement(parent, 'p')
p.text = before.strip()
# 创建包含警告内容的 div 元素
div = etree.SubElement(parent, 'div', {'class': 'alert'})
div.text = m.group(1).strip()
# 如果匹配之后还有文本,则将其重新添加到块列表中以便后续处理
if after.strip():
blocks.insert(0, after)
else:
# 如果没有匹配,则保留原始块以便后续处理器处理
return False
class Basic(Extension):
"""
渲染基本样式
@ -136,92 +187,10 @@ class Basic(Extension):
md.inlinePatterns.register(ID(
r'\[(.*?)]-\((.*?)\)', tag='span', property_='title'), 'hide', 0
) # [在指定的文本里面隐藏一段文本]-(只有鼠标放在上面才会显示隐藏文本)
md.inlinePatterns.register(Emoji(
r':(.+?):'), 'emoji', 0
) # 将emoji短代码转换为emoji字符
class Syllabus(Preprocessor):
def run(self, lines: List[str]) -> List[str]:
return [
(lambda match, origen:
re.sub(f'^({match.groups()[0]})', # 按照提纲等级添加#和锚点
fr'{"#" * len(match.groups()[0].split("."))} \1', origen)
if match is not None else origen) # 对于不是提纲的行,直接返回原始字符
((lambda x: re.match(r'^([\d.]+) ', x) # 判断是否是提纲
if not any((x.startswith('.'), # 以.开头
re.search('\. ', x) is not None, # 存在.+空格
re.search('\.{2,}', x), # 存在连续的.
))
else None)(line), line) # 排除.在提纲号开头或结尾的情况
for line in lines # 分割并遍历文本的每一行
]
class Value(Preprocessor):
def run(self, lines: List[str]) -> List[str]:
values = {
key: value.strip() # 去除值两侧的空白字符
for line in lines
for match in [re.match(r'\{([^{}#]+)} ?= ?(.+?)(?=\n|$)', line)]
if match
for key, value in [match.groups()]
} # 识别变量定义
anchors = re.findall(r'\{#([^{}#]+)}', '\n'.join(lines)) # 识别锚点定义
text = '\n'.join(lines) # 先合并成一行
for item in anchors:
text = re.sub(r'\{#(' + item + ')}', r'<span id="\1"></span>', text) # 添加锚点
text = re.sub(r'\{' + item + '}', fr'<a href="#{item}">{item}</a>', text) # 添加页内链接
for k, v in values.items():
text = re.sub(r'\{' + k + '} ?= ?(.+?)(?=\n|$)', '', text) # 移除变量的定义
text = re.sub(r'\{' + k + '}', fr'{v}', text) # 给变量赋值
return text.split('\n') # 再分割为列表
class Tag(Treeprocessor):
def run(self, root):
"""
通过修改AST来给标题添加锚点
"""
for header in root.iter():
if header.tag in ('h1', 'h2', 'h3', 'h4', 'h5', 'h6'): # 查找标题
header.set('id', header.text.split(' ')[0]) # 给标题添加锚点
elif header.tag == 'ul': # 是无序列表
for i in header: # 遍历列表内容
try:
i[0].set('href', '#' + i[0].text.split(' ')[0]) # 是目录,更改链接为标准格式
except IndexError:
pass # 是普通的无序列表
class Basic_(Extension):
"""
基本扩展
"""
def extendMarkdown(self, md):
md.registerExtension(self) # 注册扩展
md.preprocessors.register(Syllabus(md), 'syllabus', 0)
class More(Extension):
"""
高级扩展
"""
def extendMarkdown(self, md):
md.preprocessors.register(Value(md), 'values', 0)
class Decorate(Extension):
"""
修饰扩展,最后处理
"""
def extendMarkdown(self, md):
md.treeprocessors.register(Tag(md), 'header', 0)
md.inlinePatterns.register(Emoji(r':(.+?):'), 'emoji', 0) # 将emoji短代码转换为emoji字符
md.inlinePatterns.register(Syllabus(r'(\d+(\.\d+)*)\s+(.*)'), 'syllabus', 0) # 渲染提纲
def main(text: str) -> Tuple[str, Dict[str, List[str]]]:
md = Markdown(extensions=[Basic(), Basic_(), More()] + list(Extensions.values()) + [Decorate()], safe_mode=False)
md = Markdown(extensions=[Basic()] + list(Extensions.values()), safe_mode=False)
return md.convert(text), md.Meta

View File

@ -29,17 +29,17 @@
</script>
<div class="toc">
<ul>
<li><a href="#CrossDown">CrossDown</a></li>
<li><a href="#crossdown">CrossDown</a></li>
<li><a href="#1">1 基本语法</a><ul>
<li><a href="#1.1">1.1 标题</a></li>
</ul>
</li>
<li><a href="#一级标题">一级标题</a><ul>
<li><a href="#二级标题">二级标题</a><ul>
<li><a href="#三级标题">三级标题</a><ul>
<li><a href="#四级标题">四级标题</a><ul>
<li><a href="#五级标题">五级标题</a><ul>
<li><a href="#六级标题">六级标题</a></li>
<li><a href="#_1">一级标题</a><ul>
<li><a href="#_2">二级标题</a><ul>
<li><a href="#_3">三级标题</a><ul>
<li><a href="#_4">四级标题</a><ul>
<li><a href="#_5">五级标题</a><ul>
<li><a href="#_6">六级标题</a></li>
</ul>
</li>
</ul>
@ -94,10 +94,12 @@
<li><a href="#7">7 提纲</a><ul>
<li><a href="#7.1">7.1 提纲号</a><ul>
<li><a href="#7.1.1">7.1.1 提纲号示例</a></li>
<li><a href="#7.1.2">7.1.2 错误示范</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#4">4 错误示范</a></li>
<li><a href="#8">8 注释</a><ul>
<li><a href="#8.1">8.1 强注释</a></li>
<li><a href="#8.2">8.2 弱注释</a></li>
@ -105,7 +107,7 @@
</li>
<li><a href="#9">9 列表</a><ul>
<li><a href="#9.1">9.1 有序列表</a></li>
<li><a href="#9.2">9.2 无序列表</a></li>
<li><a href="#9.2">9.2 无序列表klzzwxhklzzwxhklzzwxh:00800077- Cklzzwxh:0078- D</a></li>
</ul>
</li>
<li><a href="#10">10 表格</a></li>
@ -120,58 +122,112 @@
<li><a href="#14">14 扩展</a></li>
</ul>
</div>
<h1 id="CrossDown">CrossDown</h1>
<h1 id="crossdown">CrossDown</h1>
<p>自制的markdown,添加了一些自定义的语法klzzwxh:0001效果请见klzzwxh:0000</p>
<p>
<h1 id="1">1 基本语法</h1>
</p>
<p>
<h2 id="1.1">1.1 标题</h2>
<h1 id="一级标题">一级标题</h1>
<h2 id="二级标题">二级标题</h2>
<h3 id="三级标题">三级标题</h3>
<h4 id="四级标题">四级标题</h4>
<h5 id="五级标题">五级标题</h5>
<h6 id="六级标题">六级标题</h6>
</p>
<h1 id="_1">一级标题</h1>
<h2 id="_2">二级标题</h2>
<h3 id="_3">三级标题</h3>
<h4 id="_4">四级标题</h4>
<h5 id="_5">五级标题</h5>
<h6 id="_6">六级标题</h6>
<p>
<h2 id="1.2">1.2 样式</h2>
</p>
<p>
<h3 id="1.2.1">1.2.1 <em>斜体</em></h3>
</p>
<p>
<h3 id="1.2.2">1.2.2 <strong>粗体</strong></h3>
</p>
<p>
<h3 id="1.2.3">1.2.3 <strong><em>粗斜体</em></strong></h3>
</p>
<p>
<h3 id="1.2.4">1.2.4 <u>下划线</u></h3>
</p>
<p>
<h3 id="1.2.5">1.2.5 <s>删除线</s></h3>
</p>
<p>
<h3 id="1.2.6">1.2.6 <mark>高亮</mark></h3>
</p>
<p>
<h3 id="1.2.7">1.2.7 <ruby>在文本的正上方添加一行小文本<rt>主要用于标拼音</rt></ruby></h3>
</p>
<p>
<h3 id="1.2.8">1.2.8 <span title="只有鼠标放在上面才会显示隐藏文本">在指定的文本里面隐藏一段文本</span></h3>
</p>
<p>
<h3 id="1.2.9">1.2.9 分割线</h3>
</p>
<hr />
<hr />
<hr />
<p>
<h2 id="1.3">1.3 链接</h2>
</p>
<p>
<h3 id="1.3.1">1.3.1 普通链接</h3>
</p>
<p><a href="链接地址">链接文本</a></p>
<p><a href="https://crossdark.com">CrossDark</a></p>
<p><a href="https://crossdark.net/">https://crossdark.net/</a></p>
<p>
<h3 id="1.3.2">1.3.2 图片</h3>
</p>
<p><img alt="链接图片" src="链接地址" /></p>
<p><img alt="sea" src="https://crossdark.com/wp-content/uploads/2024/05/1715259682-sea.jpg" /></p>
<p>
<h3 id="1.3.3">1.3.3 变量链接</h3>
</p>
<p><a href="https://crossdark.com">链接文本</a></p>
<p>
<h1 id="2">2 <abbr title="长的文本">缩写</abbr></h1>
</p>
<p>
<h2 id="2.1">2.1 定义</h2>
</p>
<p>
<h2 id="2.2">2.2 赋值</h2>
</p>
<p>直接在文本中使用 <abbr title="长的文本">缩写</abbr> 即可</p>
<p>
<h1 id="3">3 锚点</h1>
<p>klzzwxh:0017klzzwxh:0018</p>
</p>
<p>{#锚点名}</p>
<p>
<h1 id="4">4 代码块</h1>
</p>
<p>
<h2 id="4.1">4.1 <code>单行</code></h2>
</p>
<p>
<h3 id="4.1.1">4.1.1 LaTex</h3>
</p>
<p><code>$CO_2$</code></p>
<p><code>$H_2O$</code></p>
<p>
<h3 id="4.1.2">4.1.2 函数</h3>
</p>
<p><code>¥y=x*2+1¥</code> // 不定义范围</p>
<p><code>¥y=x**2¥€-50,50€</code> // 定义了x范围</p>
<p><code>¥y=x**3¥€-50,50|-100,100€</code> // 定义了y范围</p>
<p>
<h3 id="4.1.3">4.1.3 强调</h3>
</p>
<p><code>{强调文本}</code></p>
<p>
<h2 id="4.2">4.2 多行</h2>
</p>
<p>
<h3 id="4.2.1">4.2.1 YAML</h3>
</p>
<div class="codehilite"><pre><span></span><code><span class="nt">A</span><span class="p">:</span>
<span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">1. a</span>
<span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2. b</span>
@ -182,11 +238,15 @@
<span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">c</span>
</code></pre></div>
<p>
<h3 id="4.2.2">4.2.2 Python</h3>
</p>
<div class="codehilite"><pre><span></span><code><span class="nb">print</span><span class="p">(</span><span class="s1">&#39;CrossDown&#39;</span><span class="p">)</span>
</code></pre></div>
<p>
<h3 id="4.2.3">4.2.3 Mermaid</h3>
</p>
<div class="codehilite"><pre><span></span><code><span class="nf">graph</span><span class="w"> </span><span class="n">LR</span>
<span class="w"> </span><span class="n">A</span><span class="o">--&gt;</span><span class="n">B</span>
<span class="w"> </span><span class="n">A</span><span class="o">--&gt;</span><span class="n">C</span>
@ -194,11 +254,15 @@
<span class="w"> </span><span class="n">C</span><span class="o">--&gt;</span><span class="n">D</span>
</code></pre></div>
<p>
<h1 id="5">5 转义</h1>
</p>
<p>\ </p>
<p>\a </p>
<p>*</p>
<p>
<h1 id="6">6 引用</h1>
</p>
<blockquote>
<p>一级引用</p>
<blockquote>
@ -216,42 +280,58 @@
</blockquote>
</blockquote>
</blockquote>
<p>引文内添加klzzwxhklzzwxhklzzwxh:00450042klzzwxh:0043</p>
<p>引文内添加klzzwxhklzzwxhklzzwxh:00990096klzzwxh:0097</p>
</blockquote>
<p>
<h1 id="7">7 提纲</h1>
</p>
<p>
<h2 id="7.1">7.1 提纲号</h2>
</p>
<p>以数字和点组成,通过空格与提纲名分隔,例如:</p>
<p>
<h3 id="7.1.1">7.1.1 提纲号示例</h3>
</p>
<p>点不能出现在开头或结尾,例如</p>
<p>.7.1.2 错误示范</p>
<p>.<h3 id="7.1.2">7.1.2 错误示范</h3>
</p>
<p>7.1.3. 错误示范</p>
<p>不能出现两个及以上连续的点,例如:</p>
<p>7..1&hellip;4 错误示范</p>
<p>7..1&hellip;<h1 id="4">4 错误示范</h1>
</p>
<p>提纲号会被自动配置为锚点,可直接使用{7}76.1}</p>
<p>
<h1 id="8">8 注释</h1>
</p>
<p>
<h2 id="8.1">8.1 强注释</h2>
<p>|=klzzwxhklzzwxhklzzwxh:00340029klzzwxh:0032=|</p>
</p>
<p>|=klzzwxhklzzwxhklzzwxh:00690064klzzwxh:0067=|</p>
<p>
<h2 id="8.2">8.2 弱注释</h2>
</p>
<!-- 这是注释 -->
<p>只有在 // 后面才会被移除</p>
<p><code>// 代码中的注释弱不会被移除</code></p>
<p>
<h1 id="9">9 列表</h1>
</p>
<p>
<h2 id="9.1">9.1 有序列表</h2>
</p>
<ol>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ol>
<h2 id="9.2">9.2 无序列表</h2>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p>
<h2 id="9.2">9.2 无序列表klzzwxhklzzwxhklzzwxh:00800077- Cklzzwxh:0078- D</h2>
</p>
<p>
<h1 id="10">10 表格</h1>
</p>
<table>
<thead>
<tr>
@ -273,19 +353,32 @@
</tr>
</tbody>
</table>
<p>
<h1 id="11">11 警告</h1>
</p>
<div class="admonition warning">
<p class="admonition-title">警告标题</p>
<p>警告内容</p>
</div>
<p>
<h1 id="12">12 Emoji</h1>
</p>
<p>🚴</p>
<p>这是一个笑脸😃图案</p>
<p>
<h1 id="13">13 脚注</h1>
</p>
<p>
<h2 id="13.1">13.1 使用</h2>
</p>
<p>这是一个<sup id="fnref:脚注"><a class="footnote-ref" href="#fn:脚注">1</a></sup></p>
<p>
<h2 id="13.2">13.2 定义</h2>
</p>
<p>
<h2 id="13.3">13.3 放置</h2>
</p>
<p>通过一下代码可以将文章中所有的脚注定义集中于一处</p>
<div class="footnote">
<hr />
<ol>
@ -294,6 +387,9 @@
</li>
</ol>
</div>
<p>否则所有定义将被集中在文章末尾</p>
<p>
<h1 id="14">14 扩展</h1>
</p>
</body>
</html>