From 54c2584b0fb9029a8de22d63624dda4c1bddd4a6 Mon Sep 17 00:00:00 2001
From: crossdark
Date: Sat, 5 Oct 2024 18:25:00 +0800
Subject: [PATCH] =?UTF-8?q?1.5=E6=8F=90=E7=BA=B2=E5=A4=B4=E7=96=BC?=
=?UTF-8?q?=E4=B8=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CrossDown/Core.py | 143 +++++++++++++++++--------------------------
README.html | 150 +++++++++++++++++++++++++++++++++++++---------
2 files changed, 179 insertions(+), 114 deletions(-)
diff --git a/CrossDown/Core.py b/CrossDown/Core.py
index 6c33d28..2bd158d 100644
--- a/CrossDown/Core.py
+++ b/CrossDown/Core.py
@@ -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'', text) # 添加锚点
- text = re.sub(r'\{' + item + '}', fr'{item}', 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
diff --git a/README.html b/README.html
index 6881a3b..c4f3dfb 100644
--- a/README.html
+++ b/README.html
@@ -29,17 +29,17 @@
- CrossDown
+ CrossDown
自制的markdown,添加了一些自定义的语法klzzwxh:0001效果请见klzzwxh:0000
+
1 基本语法
+
+
1.1 标题
- 一级标题
- 二级标题
- 三级标题
- 四级标题
- 五级标题
- 六级标题
+
+ 一级标题
+ 二级标题
+ 三级标题
+ 四级标题
+ 五级标题
+ 六级标题
+
1.2 样式
+
+
1.2.1 斜体
+
+
1.2.2 粗体
+
+
1.2.3 粗斜体
+
+
1.2.4 下划线
+
+
1.2.5 删除线
+
+
1.2.6 高亮
+
+
1.2.7 在文本的正上方添加一行小文本
+
+
1.2.8 在指定的文本里面隐藏一段文本
+
+
1.2.9 分割线
+
+
1.3 链接
+
+
1.3.1 普通链接
+
链接文本
CrossDark
https://crossdark.net/
+
1.3.2 图片
+
+
1.3.3 变量链接
+
链接文本
+
2 缩写
+
+
2.1 定义
+
+
2.2 赋值
+
直接在文本中使用 缩写 即可
+
3 锚点
- klzzwxh:0017klzzwxh:0018
+
+ {#锚点名}
+
4 代码块
+
+
4.1 单行
+
+
4.1.1 LaTex
+
$CO_2$
$H_2O$
+
4.1.2 函数
+
¥y=x*2+1¥
// 不定义范围
¥y=x**2¥€-50,50€
// 定义了x范围
¥y=x**3¥€-50,50|-100,100€
// 定义了y范围
+
4.1.3 强调
+
{强调文本}
+
4.2 多行
+
+
4.2.1 YAML
+
A:
1. a
2. b
@@ -182,11 +238,15 @@
- c
+
4.2.2 Python
+
+
4.2.3 Mermaid
+
graph LR
A-->B
A-->C
@@ -194,11 +254,15 @@
C-->D
+
5 转义
+
\
\a
*
+
6 引用
+
一级引用
@@ -216,42 +280,58 @@
- 引文内添加klzzwxhklzzwxhklzzwxh:00450042klzzwxh:0043
+ 引文内添加klzzwxhklzzwxhklzzwxh:00990096klzzwxh:0097
+
7 提纲
+
+
7.1 提纲号
+
以数字和点组成,通过空格与提纲名分隔,例如:
+
7.1.1 提纲号示例
+
点不能出现在开头或结尾,例如
- .7.1.2 错误示范
+ .
7.1.2 错误示范
+
7.1.3. 错误示范
不能出现两个及以上连续的点,例如:
- 7..1…4 错误示范
+ 7..1…
4 错误示范
+
提纲号会被自动配置为锚点,可直接使用{7}76.1}
+
8 注释
+
+
8.1 强注释
- |=klzzwxhklzzwxhklzzwxh:00340029klzzwxh:0032=|
+
+ |=klzzwxhklzzwxhklzzwxh:00690064klzzwxh:0067=|
+
8.2 弱注释
+
只有在 // 后面才会被移除
// 代码中的注释弱不会被移除
+
9 列表
+
+
9.1 有序列表
+
- a
- b
- c
- d
- 9.2 无序列表
-
+
+
9.2 无序列表klzzwxhklzzwxhklzzwxh:00800077- Cklzzwxh:0078- D
+
+
10 表格
+
+
11 警告
+
+
12 Emoji
+
🚴
这是一个笑脸😃图案
+
13 脚注
+
+
13.1 使用
+
这是一个
+
13.2 定义
+
+
13.3 放置
+
+ 通过一下代码可以将文章中所有的脚注定义集中于一处
+ 否则所有定义将被集中在文章末尾
+
14 扩展
+