├── .gitignore ├── .vscode └── settings.json ├── License ├── README.md ├── docs ├── index.html └── static │ ├── css │ ├── base.css │ └── tailwind.min.css │ ├── img │ ├── 01c2c61129ca41ba9c49b27cd6938202.png │ ├── 0e3d523d743b401194b7dce4c28559b2.png │ ├── 2ee0fd5c3d824767bbf3c75eb537089a.png │ ├── 616b4aaf0ecd49f9bae25173b97ec259.png │ ├── 68f09159f31d4d92a43f61752d14999b.png │ ├── 70a2a1e5d7ee4ff698ecdf2d709e2441.png │ ├── 77564618dc974b8caa7359ecad692e45.png │ ├── a3b6d4fa237240f5a714559be1c8a84e.png │ ├── c7ba81a333e34266bd5f7fd23a305e54.png │ ├── c8030b852f8c43499b848d356ffc0803.png │ ├── dc8cb20d5d44433a9aac59f4acfc44b7.png │ ├── e31cb6ff1c3d4ae09fcd5ebe7bf1db26.png │ ├── f06295a5cf20468c8eda980e4c085dd8.png │ └── favicon.png │ ├── jyy │ └── jyy.css │ ├── katex │ ├── auto-render.min.js │ ├── katex.min.css │ └── katex.min.js │ └── reveal │ ├── reveal.css │ ├── reveal.js │ └── theme │ └── simple.css ├── example ├── Intro │ ├── img │ │ ├── author.png │ │ ├── step1.png │ │ ├── step10.png │ │ ├── step11.png │ │ ├── step12.png │ │ ├── step2.png │ │ ├── step3.png │ │ ├── step4.png │ │ ├── step5.png │ │ ├── step6.png │ │ ├── step7.png │ │ ├── step8.png │ │ └── step9.png │ └── slide.md └── jyy │ ├── img │ ├── ERA-1101.jpg │ ├── base.png │ ├── delay-memory-fig2-s.gif │ ├── eniacrun.jpg │ ├── first-bug.webp │ ├── frog-head.jpg │ ├── ics-logo.png │ ├── mariner.jpg │ ├── nju-logo.jpg │ ├── njucs-logo.jpg │ ├── os-classify.jpg │ ├── throw-ball.gif │ └── vaccum-tube.gif │ └── 操作系统概述.md ├── main.py ├── poetry.lock ├── pyproject.toml ├── resource ├── author.png └── example_of_author.png ├── src ├── __init__.py ├── backup │ ├── rouv │ │ ├── ruoshui255.html │ │ └── ruoshui255.md.py │ └── template │ │ ├── authortemp.html │ │ └── basetemp.html ├── converter.py ├── settings.py ├── static │ ├── css │ │ ├── base.css │ │ └── tailwind.min.css │ ├── img │ │ └── favicon.png │ ├── jyy │ │ └── jyy.css │ ├── katex │ │ ├── auto-render.min.js │ │ ├── fonts │ │ │ ├── KaTeX_Main-Regular.ttf │ │ │ ├── KaTeX_Main-Regular.woff │ │ │ ├── KaTeX_Main-Regular.woff2 │ │ │ ├── KaTeX_Math-Italic.ttf │ │ │ ├── KaTeX_Math-Italic.woff │ │ │ └── KaTeX_Math-Italic.woff2 │ │ ├── katex.min.css │ │ └── katex.min.js │ └── reveal │ │ ├── reveal.css │ │ ├── reveal.js │ │ └── theme │ │ └── simple.css └── util │ ├── __init__.py │ ├── file_util.py │ ├── md_util.py │ ├── net_util.py │ └── str_util.py └── test ├── .gitkeep ├── regression-testing.sh └── unit └── author.py /.gitignore: -------------------------------------------------------------------------------- 1 | .venv/ 2 | 3 | .vscode/launch.json 4 | 5 | **/.mypy_cache/ 6 | 7 | **/__pycache__/ 8 | **/dist/ 9 | 10 | **/.DS_Store 11 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[python]": { 3 | "editor.defaultFormatter": "ms-python.black-formatter", 4 | "editor.formatOnSave": true, 5 | "editor.codeActionsOnSave": { 6 | "source.organizeImports": "explicit" 7 | }, 8 | }, 9 | "mypy-type-checker.args": [ 10 | "--check-untyped-defs", 11 | ], 12 | "isort.args": [ 13 | "--profile", 14 | "black", 15 | ], 16 | } -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2019 Richard Littauer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jyyslide-md 2 | 3 | ❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗ 4 | 5 | 该项目目前有一些亟需优化的地方,我已经有了方案,但是由于工作,暂时没有精力实现,请同好们敬请期待。 6 | 1. 支持通过`pip`下载并通过命令使用 7 | >并不是所有人都了解Python、Poetry 8 | 2. 命令支持检测文件修改并自动编译(甚至自动刷新浏览器) 9 | >就像前端相关命令一样自然 10 | 3. 优化架构,初版开发个人的软件工程水平一般(当前现在也一般但是有一定提高) 11 | 4. 拓展**渐变垂直幻灯片**的功能,用户常用渐变实现一张幻灯片的不同部分的先后出现,但是目前需要将不同部分作为多个页,很麻烦 12 | 5. 开发VSCode的插件 13 | >就像上面说的,并不是所有人都了解命令行 14 | 15 | ❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗❗ 16 | 17 | 一款通过简约的Mardown方言生成具有[南大蒋炎岩老师幻灯片](http://jyywiki.cn/OS/2022/slides/1.slides#/)风格的Web幻灯片转换工具 18 | 准确的说是一款基于Reveal.js的定制主题Web幻灯片框架(类似reveal-md,不过定制主题和蒋老师的一样)。 19 | 20 | [Background](#background) | [Install](#install) | [Usage](#usage) | [Grammer](#grammer) | [Example](#example) | [Develop](#develop) | [Acknowledgement](#acknowledgement) | [License](#license) 21 | 22 | ## Background 23 | >可以从奥卡姆剃刀(如无必要,勿增实体)的角度考虑我开发本项目的发心。 24 | 25 | 说起幻灯片,首先想到的是微软的PowerPoint,PPT几乎成了幻灯片的代名词。但是在使用过程中我们会发现,它提供的很多的功能,为了使用这些功能需要很高的学习成本,但大多数场景我们用不到这么多功能;同时在使用别人的PPT模板是因为我们对功能的不熟练而不能展现模板PPT的全部效果。在幻灯片领域有类似Markdown之于Word的框架嘛? 26 | 27 | 除了能量点这样的制作幻灯片的软件外,还有基于Web的幻灯片,我基本都[尝试](https://github.com/zweix123/CS-notes/blob/master/Missing-Semester/slide.md)了一下。但是并没有完全满足我的要求的。 28 | 29 | [南京大学蒋炎岩老师](https://ics.nju.edu.cn/~jyy)开源了他的[操作系统课程](https://space.bilibili.com/202224425),相信上过他的课的同学除了会被他深入浅出的授课所折服外,也一定对他的幻灯片感兴趣。他的幻灯片是基于[Reveal.js](https://revealjs.com/)这款Web幻灯片框架,但不清楚他具体是如何制作的,在经过他的同意下,我制作了这个将Markdown方言转换成和他一个风格的幻灯片的工具。 30 | 31 | 对于Markdown扩展语法的设计尽可能简单,有些功能不是不能提供,但是提供会导致语法没有性价比的扩张,所以舍弃。让设计尽可能足够且简约。 32 | 33 | ## Install 34 | 35 | 本项目使用Python开发,模块管理使用Poetry,请确保您的机器上有版本足够的Python(**3.10以上**)并安装有第三方模块Poetry,同时也得益于Python,本项目应该可以运行于任何系统上。 36 | >关于Poetry可参考我的[笔记](https://github.com/zweix123/CS-notes/tree/master/Programing-Language/Python#poetry),当然下面会提供足够的用法。 37 | 38 | 1. 克隆项目到本地并进入: 39 | ```bash 40 | git clone https://github.com/zweix123/jyyslide-md.git 41 | cd jyyslide-md 42 | ``` 43 | 2. 利用Poetry下载第三方模块 44 | ```bash 45 | poetry install 46 | ``` 47 | 48 | >如果在win机器且出现乱码, 可以尝试下面的方案 49 | >`控制面板` -> `区域` -> `管理` -> `更改系统区域设置` -> 打开`Beta版` 50 | 51 | ## Usage 52 | >请确保已经[Install](#install)好了 53 | 54 | + 使用Peotry管理的Python有两种运行方式 55 | 1. 进入虚拟环境: 56 | ```bash 57 | poetry shell 58 | ``` 59 | 之后就可以正常的运行Python代码了 60 | 2. 使用前缀:在运行Python代码的命令前添加`poetry run` 61 | 62 | 比如[样例1](#example)中的命令应该是`poetry run python main.py example\jyy\操作系统概述.md` 63 | 64 | 命令格式如下 65 | ```bash 66 | python main.py [Markdown文件] 67 | ``` 68 | 在Markdown文件同级目录会出现一个`dist`文件夹,其下有一个index.html文件和一个static文件夹,前者即为生成的“Web幻灯片,static即为其相关静态文件。网页的title和Markdown文件同名、icon即为`static/img/favicon.png`,可通过替换这个文件修改icon。 69 | 70 | + PDF Export: [Manual](https://revealjs.com/pdf-export/) 71 | 72 | ### Grammer 73 | 74 | [教程](https://zweix123.github.io/jyyslide-md/):在这里可以结合效果来说明语法(**推荐**) 75 | >这个幻灯片就是用jyyslide-md制作而成的 76 | 77 | + 水平幻灯片使用`\n---\n`(三个)分割 78 | + 垂直幻灯片使用`\n----\n`(四个)分割 79 | + 渐变垂直幻灯片使用`\n++++\n`(四个)分割 80 | + 在同一张幻灯片中依次出现的部分使用`\n--\n`(两个)分割 81 | + 具体分割方式是从分割符到下一个分隔符或者本张幻灯片末尾的位置 82 | + 更多样式见[reveal.js官网对Fragments的解释](https://revealjs.com/fragments/) 83 | + 作者信息使用`\n+++++\n`(五个)和正文分割,使用Json格式 84 | 这里主要指指的是这部分 85 | 86 | 87 | 88 | 因为这部分是多个文字、图片、链接为一体,如果使用扩展Markdown语法的设置会让语法很凌乱。 89 | 实际上这样的页面只在第一页出现,即使不使用这样的语法,使用这样的形式 90 | ``` 91 | # Title 92 | 93 | >author 94 | ``` 95 | 96 | 97 | 在大多数场景也足够,所以从设计上将这部分从主题抽离出来 98 | 99 | 这部分的格式如下, 100 | 101 | >在[例子](#example)中的jyy中的Markdown文件 102 | 103 | ```json 104 | { 105 | "author": { 106 | "name": "蒋炎岩", 107 | "url": "https://ics.nju.edu.cn/~jyy/" 108 | }, 109 | "departments": [ 110 | { 111 | "name": " 南京大学 ", 112 | "url": "https://www.nju.edu.cn/main.htm", 113 | "img": "./img/nju-logo.jpg" 114 | }, 115 | { 116 | "name": "计算机科学与技术系", 117 | "url": "https://cs.nju.edu.cn/main.htm", 118 | "img": "./img/njucs-logo.jpg" 119 | }, 120 | { 121 | "name": "计算机软件研究所", 122 | "url": "https://www.nju.edu.cn/main.htm", 123 | "img": "./img/ics-logo.png" 124 | } 125 | ] 126 | } 127 | ``` 128 | 129 | 现也支持YAML格式(建议) 130 | 131 | ```yaml 132 | author: 133 | name: 蒋炎岩 134 | url: https://ics.nju.edu.cn/~jyy/ 135 | 136 | departments: 137 | - name: " 南京大学 " 138 | url: https://www.nju.edu.cn/main.htm, 139 | img: ./img/nju-logo.jpg 140 | 141 | - name: 计算机科学与技术系 142 | url: https://cs.nju.edu.cn/main.htm, 143 | img: ./img/njucs-logo.jpg 144 | 145 | - name: 计算机软件研究所 146 | url: https://www.nju.edu.cn/main.htm, 147 | img: ./img/ics-logo.png 148 | ``` 149 | 150 | --- 151 | 152 | + 对Markdown原生语法适配情况: 153 | >这里使用的Markdown语法使用的是**严格**语法。 154 | + 文字格式: 155 | + 通过Markdown原生语法支持**加粗**、*斜体* 156 | + 通过插入html支持删除线高亮标红 157 | + 支持注释 158 | + 支持列表 159 | + 支持代码和代码高亮 160 | >Reveal-md和Slidev支持的代码特定行高亮暂时不支持 161 | + 支持引用(链接和图片),图片推荐以插入HTML的方式使用 162 | ```html 163 | 164 | ``` 165 | 这里的src支持URL,相对地址和绝对地址,程序会将其down或者copy到dist下的img中 166 | >这里使用的爬虫是非常简单的爬虫,建议自己下载到本地使用。 167 | 168 | + 图片居中: 169 | ```html 170 | 171 | ``` 172 | + 图片右对齐: 173 | ```html 174 | 175 | ``` 176 | Markdown中的格式是流的形式,即图片是占位的,这里默认左对齐和居中的图片都是占位的,但是右对齐的图片不占位 177 | 178 | 其他格式调整STFW 179 | + 支持数学公式 180 | + 支持表格(表格的格式并不好看) 181 | + 关于Markdown的这个语法:大于三个的`-`是分割线`
`,我们发现这和扩展语法冲突,所以这里是大于四个的`-`是分割线,且这里的分割线在HTML中是空行的效果 182 | 183 | --- 184 | 185 | + 调整主题:如果您有CSS基础,可以调整蒋老师主题(主要指字号、字间距、行间距之类的微调),关于蒋老师主题的CSS文件在`dist/static/jyy/jyy.css`中。 186 | 187 | --- 188 | 189 | 蒋老师有而未设置专门语法的部分 190 | + 多个幻灯片并列 191 | ``` 192 |
193 | 194 | 195 | 196 |
197 | ``` 198 | 如果你想,你可以直接在Markdown中插入类似上面的代码 199 | 200 | + 插入B站 201 | 202 | ## Example 203 | 204 | + `example/jyy/操作系统概述.md`即为蒋老师2022年的第一节课 205 | 206 | ```bash 207 | python main.py example/jyy/操作系统概述.md 208 | ``` 209 | 210 | 打开`example\jyy\dist\index.html`即可查看 211 | 212 | + `example/Intro/slide.md`即为本项目介绍的幻灯片 213 | 214 | ```bash 215 | python main.py example/Intro/slide.md 216 | ``` 217 | 218 | 打开`example\Intro\dist\index.html`即可查看 219 | 220 | ## Develop 221 | 222 | + 根目录下的main.py是项目的入口,主体代码在src目录下,逻辑核心在converter.py,这个过程要维护很多配置信息和全局信息,所以我将其放在settings.py下,util目录则是些辅助函数 223 | + 不建议扩展标记,converter虽然不长,但是写的不是很优雅,可维护性低 224 | + 推荐从`src/util/md_util.py`入手,项目将Markdown转换成html的代码在这里,可以通过修改markdown模块相关来增加功能 225 | + 比如slidev的代码特定行高亮,这就是后续的开发计划 226 | + 格式化使用black,静态检查使用mypy 227 | + 依赖库中有很多用于静态检查的模块,如果想最小化本项目,可以重新加载依赖 228 | + 这个模块`pygments`,没有出现在代码的任何地方,但是在代码高亮中发挥重要作用,如果重新加载依赖,不要忘记它。 229 | 230 | ## Acknowledgement 231 | + 感谢[南京大学蒋炎岩老师](https://ics.nju.edu.cn/~jyy/)录制了如此优质的[操作系统课程](https://jyywiki.cn/) 232 | + 感谢[顾若水](https://github.com/ruoshui255)大佬提供的[思路和大量代码](./src/backup/rouv/ruoshui255.md.py) 233 | + 感谢[Jungle](https://github.com/Jungle430)对编码问题的提醒 234 | 235 | ## License 236 | 237 | [MIT](LICENSE) © Richard Littauer 238 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | slide 14 | 15 | 16 | 25 | 27 | 28 | 29 | 32 | 33 | 34 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

jyyslide-md

62 |
63 | 64 |
65 |

zweix

66 |

让我们试试不一样的交互方式

67 |
68 | 69 |
70 |

试试方向键
71 | 或者vim的hjkl
72 | 或者滑动屏幕(移动端)

73 |

基于Reveal.js框架的Web幻灯片交互方式

74 |
    75 |
  • 通过方向键或者hjkl切换幻灯片
  • 76 |
  • 幻灯片维度更高,除了水平幻灯片还有竖直幻灯片
  • 77 |
  • 其他快捷键:
      78 |
    • oesc:总览
    • 79 |
    • b或者v:息屏、亮屏
    • 80 |
    • f:全屏(esc退出全屏)
    • 81 |
    82 |
  • 83 |

发心

PowerPoint

84 |
85 |

可以从奥卡姆剃刀的角度考虑

86 |
87 |

能量点的功能非常丰富,但是功能多意味着学习成本大,但实际上我只需要很小部分的功能就能完成大部分的事情。
88 | 由于这种复杂性,我们在借鉴别人的PPT模板时也由于对PPT本身不熟悉而不能发挥模板的全部效果

基于Web的幻灯片

89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 |
框架说明
Reveal.js功能多,难度大
revael-mdReveal.js的前端,定制主题困难
Slidev完备的软件,不支持垂直幻灯片
VSCode插件、Obsidian默认插件功能少
115 |
116 | 117 |

并没有完全满足我的要求的框架

南京大学蒋炎岩老师幻灯片

118 |

蒋老师的幻灯片就很有意思,源码可以直接看,从代码上看大概也是使用了Reveal.js,但是自己定制了主题。
119 | 在得到蒋老师的同意后,我通过类比老师的HTML源码开发出了这个将Markdown扩展语法转换成蒋老师幻灯片风格的工具。

扩展语法的介绍

120 |
121 |

解析不是编译过程,
122 | 而且简单的split,
123 | 所以关键字不能用于正文

124 |

作者信息

125 |

我们观察蒋老师幻灯片的这部分 126 | 127 | 文字和图片对应且都是外链,想通过Markdown扩展语法实现会破坏语法的简约,所以我选择在Markdown的开头设置文件信息。

128 |
    129 |
  • 使用标记\n+++++\n和正文分割,其格式使用Json,
  • 130 |
131 |

这个样例就是上图效果。

水平幻灯片和垂直幻灯片

132 |

您已经体验过水平和垂直的幻灯片

133 |
    134 |
  • 使用\n---\n(三个减号的单独行)来划分水平幻灯片
  • 135 |
  • 使用\n----\n(四个减号的单独行)来幻灯水平幻灯片
  • 136 |
137 |
138 |

更多的减号就是Markdwon的分隔符<hr>

139 |
140 |

<hr>在幻灯片中的渲染不是分隔符而是空行

141 |
142 |

渐变幻灯片

143 |
144 |

下面展示一下典型应用

145 |

146 |
147 | 148 |
149 |

每张渐变幻灯片的格式规则和普通幻灯片是一样的

150 |

151 |
152 | 153 |
    154 |
  • 使用关键字\n++++\n来划分
  • 155 |

156 |
157 | 158 |

这里展示了渐变幻灯片的典型应用:展示变化的过程

159 |
160 | 161 |

它不会像默认的主题那样使用切换的方式而突兀

162 |
163 | 164 |

上面展示的就是广度优先搜索的过程

165 |

这是最后倒数第七张

166 |

这是最后倒数第六张

167 |

这是最后倒数第五张

168 |

这是最后倒数第四张

169 |

这是最后倒数第三张

170 |

这是最后倒数第二张

171 |

这是最后一张

每张幻灯片依次出现的部分

    174 |
  • 使用关键字\n--\n划分
  • 175 |
它划分的是从标记一下到下一个标记或者当前幻灯片末尾的部分
176 | 

对Markdown原生语法的适配

文本格式

177 |
    178 |
  • 通过Markdown原生语法支持加粗斜体
  • 179 |
180 |
+ 通过Markdown原生语法支持**加粗**和*斜体*
181 | 
182 | 183 |
    184 |
  • 通过插入HTML支持删除线高亮标红
  • 185 |
186 |
+ 通过插入HTML支持<del>删除线</del><mark>高亮</mark><red>标红</red>
187 | 
188 | 189 |
    190 |
  • Markdown语法:大于三个-的行
    191 | 在Markdown这语法是分割线<hr>,但是和我定义的扩展语法冲突,所以这里是大于四个的-才是,另外对转换后的<hr>,作用是空行而不是分割线。
  • 192 |

注释

193 |
194 |

这是注释

195 |

列表

196 |
    197 |
  • 这是无序列表
  • 198 |
  • 这是无序列表
  • 199 |
  • 这是无序列表
  • 200 |
201 |
202 | 203 |
    204 |
  1. 这是有序列表
  2. 205 |
  3. 这是有序列表
  4. 206 |
  5. 这是有序列表
  6. 207 |
208 |
209 | 210 |
    211 |
  • 这是嵌套列表
      212 |
    1. 1
    2. 213 |
    3. 2
    4. 214 |
    5. 3
    6. 215 |
    216 |
  • 217 |

代码高亮

218 |
#include <iostream>
219 | 
220 | int main() {
221 |     std::cout << "Hello World!" << std::endl;
222 | 
223 |     return 0;
224 | }
225 | 
226 | 227 |
228 |

Reveal-md和Slidev支持的代码特定行高亮暂时不支持

229 |

数学公式

230 |

$$\overbrace{1+2+\cdots+n}^{n个} \qquad \underbrace{a+b+\cdots+z}_{26}$$

231 |
$$\overbrace{1+2+\cdots+n}^{n个} \qquad \underbrace{a+b+\cdots+z}_{26}$$
232 | 
233 | 234 |
235 | 236 |

$$\lim_{x \to \infty} x^2_{22} - \int_{1}^{5}x\mathrm{d}x + \sum_{n=1}^{20} n^{2} = \prod_{j=1}^{3} y_{j} + \lim_{x \to -2} \frac{x-2}{x}$$

237 |
$$\lim_{x \to \infty} x^2_{22} - \int_{1}^{5}x\mathrm{d}x + \sum_{n=1}^{20} n^{2} = \prod_{j=1}^{3} y_{j}  + \lim_{x \to -2} \frac{x-2}{x}$$
238 | 

引用:普通引用

239 |

分布式存储系统Curve

240 |
[分布式存储系统Curve](https://github.com/opencurve/curve)
241 | 

引用:图片

242 |
243 |

支持Markdown原生图片引用语法:
244 | ![图片失效显示的文字](图片的路径或者网址)

245 |
246 |

建议使用插入HTML的方式

247 |
<img alt="图片失效显示的文字" src="图片的路径或者网址">
248 | 
249 | 250 |

这里alt并不是必须的

图片格式

251 |
    252 |
  • 图片居中
  • 253 |
254 |
<img alt=... class="center" src=...>
255 | 
256 | 257 |
258 |

顺序不关键

259 |
260 |
    261 |
  • 右对齐
  • 262 |
263 |
<img alt=... class="float-right" src=...>
264 | 
265 | 266 |
267 |

Markdown是流的形式,即图片是占位的,但是这里右对齐的图片不占位

268 |
269 |
    270 |
  • 大小
  • 271 |
272 |
<img ... src=... width="678px">
273 | 

其他

274 |
    275 |
  • 关于自定义(需要前端知识)
  • 276 |
277 |
278 |

自定义在本框架中是不推荐的,因为“像蒋炎岩”是项目的第一目的,其他的是次要,比如您需要自定义,要么您需要重构您的幻灯片,要么这个框架不适合您。

279 |
280 |

蒋老师的主题样式都在静态文件下jyy/jyy.css文件中,网页的主体都在.reveal .slides下,在这里修改即可全局修改(推荐只修改诸如字体、字间距、行间距这样的属性,zweix的前端也不好,不知道其他修改会发生什么)

谢谢

281 |
282 |

希望本工具能提高您的效率

283 |
284 |
285 |
286 | 287 | 288 | 289 | 305 | 306 | 307 | -------------------------------------------------------------------------------- /docs/static/css/base.css: -------------------------------------------------------------------------------- 1 | .watermark { 2 | position: fixed; 3 | opacity: 0.1; 4 | font-size: 128px; 5 | width: 100%; 6 | text-align: center; 7 | z-index: 1000; 8 | pointer-events: none; 9 | } 10 | 11 | .reveal .katex { 12 | font-size: 100%; 13 | } 14 | 15 | red { color: red; } 16 | green { color: green; } 17 | blue { color: blue; } 18 | 19 | .codehilite .hll { background-color: #ffffcc } 20 | .codehilite .c { color: #408080; font-style: italic } /* Comment */ 21 | .codehilite .err { border: 1px solid #FF0000 } /* Error */ 22 | .codehilite .k { color: #008000; font-weight: bold } /* Keyword */ 23 | .codehilite .o { color: #666666 } /* Operator */ 24 | .codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ 25 | .codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 26 | .codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ 27 | .codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ 28 | .codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ 29 | .codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ 30 | .codehilite .gd { color: #A00000 } /* Generic.Deleted */ 31 | .codehilite .ge { font-style: italic } /* Generic.Emph */ 32 | .codehilite .gr { color: #FF0000 } /* Generic.Error */ 33 | .codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 34 | .codehilite .gi { color: #00A000 } /* Generic.Inserted */ 35 | .codehilite .go { color: #888888 } /* Generic.Output */ 36 | .codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 37 | .codehilite .gs { font-weight: bold } /* Generic.Strong */ 38 | .codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 39 | .codehilite .gt { color: #0044DD } /* Generic.Traceback */ 40 | .codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 41 | .codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 42 | .codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 43 | .codehilite .kp { color: #008000 } /* Keyword.Pseudo */ 44 | .codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 45 | .codehilite .kt { color: #B00040 } /* Keyword.Type */ 46 | .codehilite .m { color: #666666 } /* Literal.Number */ 47 | .codehilite .s { color: #BA2121 } /* Literal.String */ 48 | .codehilite .na { color: #7D9029 } /* Name.Attribute */ 49 | .codehilite .nb { color: #008000 } /* Name.Builtin */ 50 | .codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 51 | .codehilite .no { color: #880000 } /* Name.Constant */ 52 | .codehilite .nd { color: #AA22FF } /* Name.Decorator */ 53 | .codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ 54 | .codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 55 | .codehilite .nf { color: #0000FF } /* Name.Function */ 56 | .codehilite .nl { color: #A0A000 } /* Name.Label */ 57 | .codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 58 | .codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ 59 | .codehilite .nv { color: #19177C } /* Name.Variable */ 60 | .codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 61 | .codehilite .w { color: #bbbbbb } /* Text.Whitespace */ 62 | .codehilite .mb { color: #666666 } /* Literal.Number.Bin */ 63 | .codehilite .mf { color: #666666 } /* Literal.Number.Float */ 64 | .codehilite .mh { color: #666666 } /* Literal.Number.Hex */ 65 | .codehilite .mi { color: #666666 } /* Literal.Number.Integer */ 66 | .codehilite .mo { color: #666666 } /* Literal.Number.Oct */ 67 | .codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ 68 | .codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ 69 | .codehilite .sc { color: #BA2121 } /* Literal.String.Char */ 70 | .codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ 71 | .codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 72 | .codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ 73 | .codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 74 | .codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ 75 | .codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 76 | .codehilite .sx { color: #008000 } /* Literal.String.Other */ 77 | .codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ 78 | .codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ 79 | .codehilite .ss { color: #19177C } /* Literal.String.Symbol */ 80 | .codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ 81 | .codehilite .fm { color: #0000FF } /* Name.Function.Magic */ 82 | .codehilite .vc { color: #19177C } /* Name.Variable.Class */ 83 | .codehilite .vg { color: #19177C } /* Name.Variable.Global */ 84 | .codehilite .vi { color: #19177C } /* Name.Variable.Instance */ 85 | .codehilite .vm { color: #19177C } /* Name.Variable.Magic */ 86 | .codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ 87 | -------------------------------------------------------------------------------- /docs/static/img/01c2c61129ca41ba9c49b27cd6938202.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/01c2c61129ca41ba9c49b27cd6938202.png -------------------------------------------------------------------------------- /docs/static/img/0e3d523d743b401194b7dce4c28559b2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/0e3d523d743b401194b7dce4c28559b2.png -------------------------------------------------------------------------------- /docs/static/img/2ee0fd5c3d824767bbf3c75eb537089a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/2ee0fd5c3d824767bbf3c75eb537089a.png -------------------------------------------------------------------------------- /docs/static/img/616b4aaf0ecd49f9bae25173b97ec259.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/616b4aaf0ecd49f9bae25173b97ec259.png -------------------------------------------------------------------------------- /docs/static/img/68f09159f31d4d92a43f61752d14999b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/68f09159f31d4d92a43f61752d14999b.png -------------------------------------------------------------------------------- /docs/static/img/70a2a1e5d7ee4ff698ecdf2d709e2441.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/70a2a1e5d7ee4ff698ecdf2d709e2441.png -------------------------------------------------------------------------------- /docs/static/img/77564618dc974b8caa7359ecad692e45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/77564618dc974b8caa7359ecad692e45.png -------------------------------------------------------------------------------- /docs/static/img/a3b6d4fa237240f5a714559be1c8a84e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/a3b6d4fa237240f5a714559be1c8a84e.png -------------------------------------------------------------------------------- /docs/static/img/c7ba81a333e34266bd5f7fd23a305e54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/c7ba81a333e34266bd5f7fd23a305e54.png -------------------------------------------------------------------------------- /docs/static/img/c8030b852f8c43499b848d356ffc0803.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/c8030b852f8c43499b848d356ffc0803.png -------------------------------------------------------------------------------- /docs/static/img/dc8cb20d5d44433a9aac59f4acfc44b7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/dc8cb20d5d44433a9aac59f4acfc44b7.png -------------------------------------------------------------------------------- /docs/static/img/e31cb6ff1c3d4ae09fcd5ebe7bf1db26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/e31cb6ff1c3d4ae09fcd5ebe7bf1db26.png -------------------------------------------------------------------------------- /docs/static/img/f06295a5cf20468c8eda980e4c085dd8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/f06295a5cf20468c8eda980e4c085dd8.png -------------------------------------------------------------------------------- /docs/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/docs/static/img/favicon.png -------------------------------------------------------------------------------- /docs/static/jyy/jyy.css: -------------------------------------------------------------------------------- 1 | .reveal .slide-number { 2 | font-size: 26px; 3 | border-radius: 5px; 4 | background-color: rgba(0, 0, 0, .3); 5 | } 6 | 7 | .reveal .slides { 8 | border: 1.5px #ddd solid; 9 | border-radius: 7px; 10 | text-align: left; 11 | font-weight: 300; 12 | } 13 | 14 | .reveal h1, 15 | .reveal h2, 16 | .reveal h3, 17 | .reveal h4 { 18 | font-family: 'Lato', 'SimHei', 'STXihei', 'Sans Serif'; 19 | font-weight: 400; 20 | } 21 | 22 | .reveal p, 23 | .reveal li, 24 | .reveal center { 25 | font-size: 32px; 26 | font-family: 'Lato', 'STHeiti', 'SimHei', 'Sans Serif'; 27 | } 28 | 29 | .reveal li+li { 30 | margin-top: 10px; 31 | } 32 | 33 | .reveal ul { 34 | display: block; 35 | margin-right: 15px; 36 | } 37 | 38 | .reveal p, 39 | .reveal h1, 40 | .reveal h2, 41 | .reveal h3, 42 | .reveal h4, 43 | .reveal h5 { 44 | padding: 0 25px 0 25px; 45 | } 46 | 47 | .reveal table { 48 | font-size: 32px; 49 | font-family: 'Lato', 'STHeiti', 'SimHei', 'Sans Serif'; 50 | margin-top: 15px; 51 | margin-bottom: 15px; 52 | } 53 | 54 | .reveal th { 55 | background-color: #eee; 56 | } 57 | 58 | .reveal tr:nth-child(even) { 59 | background-color: #efffff; 60 | } 61 | 62 | .reveal h1, 63 | .reveal h2, 64 | .reveal h3, 65 | .reveal h4, 66 | .reveal h5, 67 | .reveal h6 { 68 | text-align: left; 69 | margin: 0 0 20px 0; 70 | color: #222; 71 | font-weight: 400; 72 | line-height: 1.2; 73 | letter-spacing: normal; 74 | } 75 | 76 | .reveal h1 { 77 | margin: 0 10 0 10; 78 | font-size: 60px; 79 | } 80 | 81 | .reveal .middle h1 { 82 | text-align: center; 83 | } 84 | 85 | .reveal h2 { 86 | font-size: 48px; 87 | border-bottom: 2px solid rgb(106, 0, 95); 88 | padding-bottom: 5px; 89 | } 90 | 91 | .reveal h3 { 92 | font-size: 1.15em; 93 | } 94 | 95 | .reveal h4 { 96 | font-size: 1.05em; 97 | } 98 | 99 | .reveal .center { 100 | text-align: center; 101 | } 102 | 103 | .reveal .middle { 104 | height: 728px; 105 | display: flex; 106 | align-items: center; 107 | width: 100%; 108 | } 109 | 110 | .reveal pre { 111 | font-size: 28px; 112 | 113 | background-color: #eee; 114 | 115 | border-radius: 3mm; 116 | padding: 10px 10px 10px 10px; 117 | } 118 | 119 | .reveal pre code { 120 | max-height: none; 121 | } 122 | 123 | .reveal code { 124 | font-family: 'Inconsolata', 'STKaiti', 'KaiTi', 'Sans Serif', Monospace; 125 | } 126 | 127 | .reveal .middle blockquote { 128 | text-align: center; 129 | color: rgb(106, 0, 95); 130 | background: none; 131 | box-shadow: none; 132 | } 133 | 134 | .reveal .middle blockquote a { 135 | color: inherit; 136 | } 137 | 138 | .reveal blockquote p, 139 | .reveal blockquote li { 140 | font-family: 'Lato', 'STKaiti', 'KaiTi', 'Sans Serif'; 141 | } 142 | 143 | section .center { 144 | display: block; 145 | margin-left: auto; 146 | margin-right: auto; 147 | } 148 | 149 | .reveal .author-block { 150 | margin: 75px 0 35px 0; 151 | } 152 | 153 | .reveal .author-affiliation img { 154 | margin: 15px 0 0 0; 155 | } 156 | 157 | .reveal .author-block p, 158 | .reveal .author-affiliation p { 159 | font-family: 'Kaiti', 'STKaiti', 'Serif', 'Times', 'Times New Roman'; 160 | margin-block-start: 0em; 161 | margin-block-end: 0em; 162 | } 163 | 164 | .reveal .author-affiliation { 165 | display: inline-block; 166 | font-size: 90%; 167 | } 168 | 169 | .reveal hr { 170 | border: 10px solid rgba(0, 0, 0, 0); 171 | } 172 | 173 | .reveal li { 174 | margin-top: 10px; 175 | } -------------------------------------------------------------------------------- /docs/static/katex/auto-render.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var i=r[e];if(void 0!==i)return i.exports;var a=r[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var i={};return function(){n.d(i,{default:function(){return s}});var e=n(771),t=n.n(e),r=function(e,t,r){for(var n=r,i=0,a=e.length;n0&&(i.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var l=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[l].right,e,t[l].left.length)))break;var d=e.slice(0,n+t[l].right.length),s=a.test(d)?d:e.slice(t[l].left.length,n);i.push({type:"math",data:s,rawData:d,display:t[l].display}),e=e.slice(n+t[l].right.length)}return""!==e&&i.push({type:"text",data:e}),i},l=function(e,r){var n=o(e,r.delimiters);if(1===n.length&&"text"===n[0].type)return null;for(var i=document.createDocumentFragment(),a=0;a.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} 2 | -------------------------------------------------------------------------------- /docs/static/reveal/theme/simple.css: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is darkblue. 4 | * 5 | * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. 6 | * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | @import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); 9 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 10 | section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { 11 | color: #fff; } 12 | 13 | /********************************************* 14 | * GLOBAL STYLES 15 | *********************************************/ 16 | :root { 17 | --background-color: #fff; 18 | --main-font: Lato, sans-serif; 19 | --main-font-size: 40px; 20 | --main-color: #000; 21 | --block-margin: 20px; 22 | --heading-margin: 0 0 20px 0; 23 | --heading-font: News Cycle, Impact, sans-serif; 24 | --heading-color: #000; 25 | --heading-line-height: 1.2; 26 | --heading-letter-spacing: normal; 27 | --heading-text-transform: none; 28 | --heading-text-shadow: none; 29 | --heading-font-weight: normal; 30 | --heading1-text-shadow: none; 31 | --heading1-size: 3.77em; 32 | --heading2-size: 2.11em; 33 | --heading3-size: 1.55em; 34 | --heading4-size: 1em; 35 | --code-font: monospace; 36 | --link-color: #00008B; 37 | --link-color-hover: #0000f1; 38 | --selection-background-color: rgba(0, 0, 0, 0.99); 39 | --selection-color: #fff; } 40 | 41 | .reveal-viewport { 42 | background: #fff; 43 | background-color: #fff; } 44 | 45 | .reveal { 46 | font-family: "Lato", sans-serif; 47 | font-size: 40px; 48 | font-weight: normal; 49 | color: #000; } 50 | 51 | .reveal ::selection { 52 | color: #fff; 53 | background: rgba(0, 0, 0, 0.99); 54 | text-shadow: none; } 55 | 56 | .reveal ::-moz-selection { 57 | color: #fff; 58 | background: rgba(0, 0, 0, 0.99); 59 | text-shadow: none; } 60 | 61 | .reveal .slides section, 62 | .reveal .slides section > section { 63 | line-height: 1.3; 64 | font-weight: inherit; } 65 | 66 | /********************************************* 67 | * HEADERS 68 | *********************************************/ 69 | .reveal h1, 70 | .reveal h2, 71 | .reveal h3, 72 | .reveal h4, 73 | .reveal h5, 74 | .reveal h6 { 75 | margin: 0 0 20px 0; 76 | color: #000; 77 | font-family: "News Cycle", Impact, sans-serif; 78 | font-weight: normal; 79 | line-height: 1.2; 80 | letter-spacing: normal; 81 | text-transform: none; 82 | text-shadow: none; 83 | word-wrap: break-word; } 84 | 85 | .reveal h1 { 86 | font-size: 3.77em; } 87 | 88 | .reveal h2 { 89 | font-size: 2.11em; } 90 | 91 | .reveal h3 { 92 | font-size: 1.55em; } 93 | 94 | .reveal h4 { 95 | font-size: 1em; } 96 | 97 | .reveal h1 { 98 | text-shadow: none; } 99 | 100 | /********************************************* 101 | * OTHER 102 | *********************************************/ 103 | .reveal p { 104 | margin: 20px 0; 105 | line-height: 1.3; } 106 | 107 | /* Ensure certain elements are never larger than the slide itself */ 108 | .reveal img, 109 | .reveal video, 110 | .reveal iframe { 111 | max-width: 95%; 112 | max-height: 95%; } 113 | 114 | .reveal strong, 115 | .reveal b { 116 | font-weight: bold; } 117 | 118 | .reveal em { 119 | font-style: italic; } 120 | 121 | .reveal ol, 122 | .reveal dl, 123 | .reveal ul { 124 | display: inline-block; 125 | text-align: left; 126 | margin: 0 0 0 1em; } 127 | 128 | .reveal ol { 129 | list-style-type: decimal; } 130 | 131 | .reveal ul { 132 | list-style-type: disc; } 133 | 134 | .reveal ul ul { 135 | list-style-type: square; } 136 | 137 | .reveal ul ul ul { 138 | list-style-type: circle; } 139 | 140 | .reveal ul ul, 141 | .reveal ul ol, 142 | .reveal ol ol, 143 | .reveal ol ul { 144 | display: block; 145 | margin-left: 10px; } 146 | 147 | .reveal dt { 148 | font-weight: bold; } 149 | 150 | .reveal dd { 151 | margin-left: 40px; } 152 | 153 | .reveal blockquote { 154 | display: block; 155 | position: relative; 156 | width: 90%; 157 | margin: 20px auto; 158 | padding: 5px; 159 | background: rgba(0, 255, 255, 0.05); 160 | border-radius: 10px; 161 | box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2); 162 | } 163 | 164 | .reveal q { 165 | font-style: italic; } 166 | 167 | .reveal pre { 168 | display: block; 169 | position: relative; 170 | width: 90%; 171 | margin: 20px auto; 172 | text-align: left; 173 | font-size: 0.55em; 174 | font-family: monospace; 175 | line-height: 1.2em; 176 | word-wrap: break-word; 177 | box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } 178 | 179 | .reveal code { 180 | font-family: monospace; 181 | text-transform: none; } 182 | 183 | .reveal pre code { 184 | display: block; 185 | padding: 5px; 186 | overflow: auto; 187 | max-height: 400px; 188 | word-wrap: normal; } 189 | 190 | .reveal table { 191 | margin: auto; 192 | border-collapse: collapse; 193 | border-spacing: 0; } 194 | 195 | .reveal table th { 196 | font-weight: bold; } 197 | 198 | .reveal table th, 199 | .reveal table td { 200 | text-align: left; 201 | padding: 0.2em 0.5em 0.2em 0.5em; 202 | border-bottom: 1px solid; } 203 | 204 | .reveal table th[align="center"], 205 | .reveal table td[align="center"] { 206 | text-align: center; } 207 | 208 | .reveal table th[align="right"], 209 | .reveal table td[align="right"] { 210 | text-align: right; } 211 | 212 | .reveal table tbody tr:last-child th, 213 | .reveal table tbody tr:last-child td { 214 | border-bottom: none; } 215 | 216 | .reveal sup { 217 | vertical-align: super; 218 | font-size: smaller; } 219 | 220 | .reveal sub { 221 | vertical-align: sub; 222 | font-size: smaller; } 223 | 224 | .reveal small { 225 | display: inline-block; 226 | font-size: 0.6em; 227 | line-height: 1.2em; 228 | vertical-align: top; } 229 | 230 | .reveal small * { 231 | vertical-align: top; } 232 | 233 | .reveal img { 234 | margin: 20px 0; } 235 | 236 | /********************************************* 237 | * LINKS 238 | *********************************************/ 239 | .reveal a { 240 | color: #00008B; 241 | text-decoration: none; 242 | transition: color .15s ease; } 243 | 244 | .reveal a:hover { 245 | color: #0000f1; 246 | text-shadow: none; 247 | border: none; } 248 | 249 | .reveal .roll span:after { 250 | color: #fff; 251 | background: #00003f; } 252 | 253 | /********************************************* 254 | * Frame helper 255 | *********************************************/ 256 | .reveal .r-frame { 257 | border: 4px solid #000; 258 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } 259 | 260 | .reveal a .r-frame { 261 | transition: all .15s linear; } 262 | 263 | .reveal a:hover .r-frame { 264 | border-color: #00008B; 265 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } 266 | 267 | /********************************************* 268 | * NAVIGATION CONTROLS 269 | *********************************************/ 270 | .reveal .controls { 271 | color: #00008B; } 272 | 273 | /********************************************* 274 | * PROGRESS BAR 275 | *********************************************/ 276 | .reveal .progress { 277 | background: rgba(0, 0, 0, 0.2); 278 | color: #00008B; } 279 | 280 | /********************************************* 281 | * PRINT BACKGROUND 282 | *********************************************/ 283 | @media print { 284 | .backgrounds { 285 | background-color: #fff; } } 286 | -------------------------------------------------------------------------------- /example/Intro/img/author.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/author.png -------------------------------------------------------------------------------- /example/Intro/img/step1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step1.png -------------------------------------------------------------------------------- /example/Intro/img/step10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step10.png -------------------------------------------------------------------------------- /example/Intro/img/step11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step11.png -------------------------------------------------------------------------------- /example/Intro/img/step12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step12.png -------------------------------------------------------------------------------- /example/Intro/img/step2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step2.png -------------------------------------------------------------------------------- /example/Intro/img/step3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step3.png -------------------------------------------------------------------------------- /example/Intro/img/step4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step4.png -------------------------------------------------------------------------------- /example/Intro/img/step5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step5.png -------------------------------------------------------------------------------- /example/Intro/img/step6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step6.png -------------------------------------------------------------------------------- /example/Intro/img/step7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step7.png -------------------------------------------------------------------------------- /example/Intro/img/step8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step8.png -------------------------------------------------------------------------------- /example/Intro/img/step9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/Intro/img/step9.png -------------------------------------------------------------------------------- /example/Intro/slide.md: -------------------------------------------------------------------------------- 1 | # jyyslide-md 2 | 3 |
4 | 5 | >[zweix](https://github.com/zweix123) 6 | 7 | --- 8 | 9 | # 让我们试试不一样的交互方式 10 | 11 |
12 | 13 | >试试方向键 14 | >或者vim的`hjkl` 15 | >或者滑动屏幕(移动端) 16 | 17 | ---- 18 | 19 | ## 基于Reveal.js框架的Web幻灯片交互方式 20 | 21 | + 通过方向键或者`hjkl`切换幻灯片 22 | + 幻灯片维度更高,除了水平幻灯片还有竖直幻灯片 23 | + 其他快捷键: 24 | + `o`或`esc`:总览 25 | + `b`或者`v`:息屏、亮屏 26 | + `f`:全屏(`esc`退出全屏) 27 | 28 | --- 29 | 30 | # 发心 31 | 32 | ---- 33 | 34 | ## PowerPoint 35 | 36 | > 可以从奥卡姆剃刀的角度考虑 37 | 38 | 能量点的功能非常丰富,但是功能多意味着学习成本大,但实际上我只需要很小部分的功能就能完成大部分的事情。 39 | 由于这种复杂性,我们在借鉴别人的PPT模板时也由于对PPT本身不熟悉而不能发挥模板的全部效果 40 | 41 | ---- 42 | 43 | ## 基于Web的幻灯片 44 | 45 | | 框架 | 说明 | 46 | | :--------------------------: | :---------------------------: | 47 | | Reveal.js | 功能多,难度大 | 48 | | revael-md | Reveal.js的前端,定制主题困难 | 49 | | Slidev | 完备的软件,不支持垂直幻灯片 | 50 | | VSCode插件、Obsidian默认插件 | 功能少 | 51 | 52 |
53 | 54 | 并没有完全满足我的要求的框架 55 | 56 | ---- 57 | 58 | ## [南京大学蒋炎岩老师幻灯片](http://jyywiki.cn/OS/2022/slides/1.slides#/) 59 | 60 | 蒋老师的幻灯片就很有意思,源码可以直接看,从代码上看大概也是使用了Reveal.js,但是自己定制了主题。 61 | 在得到蒋老师的同意后,我通过类比老师的HTML源码开发出了这个将Markdown扩展语法转换成蒋老师幻灯片风格的工具。 62 | 63 | --- 64 | 65 | # 扩展语法的介绍 66 | >解析不是编译过程, 67 | >而且简单的split, 68 | >所以关键字不能用于正文 69 | 70 | ---- 71 | 72 | ## 作者信息 73 | 74 | 我们观察蒋老师幻灯片的这部分 75 | 76 | 文字和图片对应且都是外链,想通过Markdown扩展语法实现会破坏语法的简约,所以我选择在Markdown的开头设置文件信息。 77 | 78 | + 使用标记`\n+++++\n`和正文分割,其格式使用Json, 79 | 80 | [这个样例](https://github.com/zweix123/jyyslide-md/blob/master/example/jyy/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E6%A6%82%E8%BF%B0.md)就是上图效果。 81 | 82 | ---- 83 | 84 | ## 水平幻灯片和垂直幻灯片 85 | 86 | 您已经体验过水平和垂直的幻灯片 87 | 88 | + 使用`\n---\n`(三个减号的单独行)来划分水平幻灯片 89 | + 使用`\n----\n`(四个减号的单独行)来幻灯水平幻灯片 90 | 91 | >更多的减号就是Markdwon的分隔符`
` 92 | >>`
`在幻灯片中的渲染不是分隔符而是空行 93 | 94 | ---- 95 | 96 | # 渐变幻灯片 97 | 98 | >下面展示一下典型应用 99 | 100 | ---- 101 | 102 | 103 | 104 |
105 | 106 | >每张渐变幻灯片的格式规则和普通幻灯片是一样的 107 | 108 | ++++ 109 | 110 | 111 | 112 | 113 |
114 | 115 | + 使用关键字`\n++++\n`来划分 116 | 117 | ++++ 118 | 119 | 120 | 121 |
122 | 123 | 这里展示了渐变幻灯片的典型应用:展示变化的过程 124 | 125 | ++++ 126 | 127 | 128 | 129 |
130 | 131 | 它不会像默认的主题那样使用切换的方式而突兀 132 | 133 | ++++ 134 | 135 | 136 | 137 |
138 | 139 | 上面展示的就是广度优先搜索的过程 140 | 141 | ++++ 142 | 143 | 144 | 145 | 这是最后倒数第七张 146 | 147 | ++++ 148 | 149 | 150 | 151 | 这是最后倒数第六张 152 | 153 | ++++ 154 | 155 | 156 | 157 | 这是最后倒数第五张 158 | 159 | ++++ 160 | 161 | 162 | 163 | 这是最后倒数第四张 164 | 165 | ++++ 166 | 167 | 168 | 169 | 这是最后倒数第三张 170 | 171 | ++++ 172 | 173 | 174 | 175 | 这是最后倒数第二张 176 | 177 | ++++ 178 | 179 | 180 | 181 | 这是最后一张 182 | 183 | ---- 184 | 185 | ## 每张幻灯片依次出现的部分 186 | 187 | -- 188 | 189 | + 本质是Reveal.js的[fragments](https://revealjs.com/fragments/) 190 | 191 | -- 192 | 193 | + 使用关键字`\n--\n`划分 194 | 195 | -- 196 | 197 | 它划分的是从标记一下到下一个标记或者当前幻灯片末尾的部分 198 | 199 | --- 200 | 201 | # 对Markdown原生语法的适配 202 | 203 | ---- 204 | 205 | ## 文本格式 206 | 207 | + 通过Markdown原生语法支持**加粗**和*斜体* 208 | ``` 209 | + 通过Markdown原生语法支持**加粗**和*斜体* 210 | ``` 211 | + 通过插入HTML支持删除线高亮标红 212 | ``` 213 | + 通过插入HTML支持删除线高亮标红 214 | ``` 215 | + Markdown语法:`大于三个-的行` 216 | 在Markdown这语法是分割线`
`,但是和我定义的扩展语法冲突,所以这里是大于四个的`-`才是,另外对转换后的`
`,作用是空行而不是分割线。 217 | 218 | ---- 219 | 220 | ## 注释 221 | 222 | >这是注释 223 | 224 | ---- 225 | 226 | ## 列表 227 | 228 | + 这是无序列表 229 | + 这是无序列表 230 | + 这是无序列表 231 | 232 |
233 | 234 | 1. 这是有序列表 235 | 2. 这是有序列表 236 | 3. 这是有序列表 237 | 238 |
239 | 240 | + 这是嵌套列表 241 | 1. 1 242 | 2. 2 243 | 3. 3 244 | 245 | ---- 246 | 247 | ## 代码高亮 248 | 249 | ```c++ 250 | #include 251 | 252 | int main() { 253 | std::cout << "Hello World!" << std::endl; 254 | 255 | return 0; 256 | } 257 | ``` 258 | 259 | >Reveal-md和Slidev支持的代码特定行高亮暂时不支持 260 | 261 | ---- 262 | 263 | ## 数学公式 264 | 265 | $$\overbrace{1+2+\cdots+n}^{n个} \qquad \underbrace{a+b+\cdots+z}_{26}$$ 266 | ``` 267 | $$\overbrace{1+2+\cdots+n}^{n个} \qquad \underbrace{a+b+\cdots+z}_{26}$$ 268 | ``` 269 | 270 |
271 | 272 | $$\lim_{x \to \infty} x^2_{22} - \int_{1}^{5}x\mathrm{d}x + \sum_{n=1}^{20} n^{2} = \prod_{j=1}^{3} y_{j} + \lim_{x \to -2} \frac{x-2}{x}$$ 273 | ``` 274 | $$\lim_{x \to \infty} x^2_{22} - \int_{1}^{5}x\mathrm{d}x + \sum_{n=1}^{20} n^{2} = \prod_{j=1}^{3} y_{j} + \lim_{x \to -2} \frac{x-2}{x}$$ 275 | ``` 276 | ---- 277 | 278 | ## 引用:普通引用 279 | 280 | [分布式存储系统Curve](https://github.com/opencurve/curve) 281 | 282 | ``` 283 | [分布式存储系统Curve](https://github.com/opencurve/curve) 284 | ``` 285 | 286 | 287 | ---- 288 | 289 | ## 引用:图片 290 | >支持Markdown原生图片引用语法: 291 | >``` 292 | >![图片失效显示的文字](图片的路径或者网址) 293 | >``` 294 | 295 | 296 | 建议使用插入HTML的方式 297 | ```html 298 | 图片失效显示的文字 299 | ``` 300 | 这里`alt`并不是必须的 301 | 302 | 303 | ---- 304 | 305 | ## 图片格式 306 | 307 | + 图片居中 308 | ```html 309 | ... 310 | ``` 311 | 312 | >顺序不关键 313 | 314 | + 右对齐 315 | ```html 316 | ... 317 | ``` 318 | 319 | >Markdown是流的形式,即图片是占位的,但是这里右对齐的图片不占位 320 | 321 | + 大小 322 | 323 | ```html 324 | 325 | ``` 326 | 327 | ---- 328 | 329 | ## 其他 330 | 331 | + 关于自定义(需要前端知识) 332 | 333 | >自定义在本框架中是不推荐的,因为“像蒋炎岩”是项目的第一目的,其他的是次要,比如您需要自定义,要么您需要重构您的幻灯片,要么这个框架不适合您。 334 | 335 | 蒋老师的主题样式都在静态文件下`jyy/jyy.css`文件中,网页的主体都在`.reveal .slides`下,在这里修改即可全局修改(推荐只修改诸如字体、字间距、行间距这样的属性,zweix的前端也不好,不知道其他修改会发生什么) 336 | 337 | 338 | --- 339 | 340 | # 谢谢 341 | 342 | >希望本工具能提高您的效率 -------------------------------------------------------------------------------- /example/jyy/img/ERA-1101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/ERA-1101.jpg -------------------------------------------------------------------------------- /example/jyy/img/base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/base.png -------------------------------------------------------------------------------- /example/jyy/img/delay-memory-fig2-s.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/delay-memory-fig2-s.gif -------------------------------------------------------------------------------- /example/jyy/img/eniacrun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/eniacrun.jpg -------------------------------------------------------------------------------- /example/jyy/img/first-bug.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/first-bug.webp -------------------------------------------------------------------------------- /example/jyy/img/frog-head.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/frog-head.jpg -------------------------------------------------------------------------------- /example/jyy/img/ics-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/ics-logo.png -------------------------------------------------------------------------------- /example/jyy/img/mariner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/mariner.jpg -------------------------------------------------------------------------------- /example/jyy/img/nju-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/nju-logo.jpg -------------------------------------------------------------------------------- /example/jyy/img/njucs-logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/njucs-logo.jpg -------------------------------------------------------------------------------- /example/jyy/img/os-classify.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/os-classify.jpg -------------------------------------------------------------------------------- /example/jyy/img/throw-ball.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/throw-ball.gif -------------------------------------------------------------------------------- /example/jyy/img/vaccum-tube.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/example/jyy/img/vaccum-tube.gif -------------------------------------------------------------------------------- /example/jyy/操作系统概述.md: -------------------------------------------------------------------------------- 1 | author: 2 | name: 蒋炎岩 3 | url: https://ics.nju.edu.cn/~jyy/ 4 | 5 | departments: 6 | - name: " 南京大学 " 7 | url: https://www.nju.edu.cn/main.htm, 8 | img: ./img/nju-logo.jpg 9 | 10 | - name: 计算机科学与技术系 11 | url: https://cs.nju.edu.cn/main.htm, 12 | img: ./img/njucs-logo.jpg 13 | 14 | - name: 计算机软件研究所 15 | url: https://www.nju.edu.cn/main.htm, 16 | img: ./img/ics-logo.png 17 | +++++ 18 | 19 | # 操作系统概述 20 | 21 | ---- 22 | 23 | ## Overview 24 | 本次课回答的问题 25 | 26 | + **Q1** (Why): 为什么要学操作系统? 27 | + **Q2** (What): 到底什么是操作系统? 28 | + **Q3** (How): 怎么学操作系统? 29 | 30 |
31 | 32 | 本次课主要内容 33 | 34 | + 前导知识概述 35 | + 操作系统的历史/宏观概述 36 | 37 | --- 38 | 39 | # 个人/课程简介 40 | 41 | ---- 42 | 43 | ## 我是谁? 44 | 45 | 46 | 努力成为卷王的临时工✖️ ([计算机软件研究所](https://cs.nju.edu.cn/ics/index.htm)✔) 47 | 48 | + “软件自动化”:测试/分析;代码合成 49 | + Two ACM SIGSOFT Distinguished Paper 50 | Awards; Best Paper Award @ ICSE'21 51 | 52 |
53 | 54 | Co-Founder of Project-N 55 | 56 | + 在 bare-metal 上实现完整计算机系统 57 | 58 |
59 | 60 | JSOI/南京大学 ICPC 集训队教练 61 | 62 | + CCF NOI/NOIP 系列赛江苏赛区技术负责人 63 | + ICPC World Finals 49th Place (2009, team leader) 64 | + ICPC World Finals 13th Place (2019, co-coach) 65 | 66 | ---- 67 | 68 | ## 课程信息与成绩构成 69 | 70 | >所有课程信息都在[课程主页](http://jyywiki.cn/OS/2022/)发布 (请 RTFM)! 71 | 72 | 成绩构成 73 | 74 | + 期末考试 40% + 随堂期中测验 10% 75 | + 大实验 25% + 小实验 25% 76 | + soft + hard deadlines 77 | + 不要对编程抱有任何侥幸心理 78 | + 无论你基础如何,都相信自己能做到 79 | 80 |
81 | 82 | 不强制要求到课 83 | 84 | + 努力上传视频,但不保证设备不会翻车 85 | 86 | ---- 87 | 88 | ## 学术诚信 (Academic Integrity) 89 | [Academic integrity](https://integrity.mit.edu/) 不是底线,而是 “自发的要求” 90 | 91 | + 对 “不应该做的事情” 有清楚的认识 92 | + **不将代码上传到互联网** 93 | + **主动不参考别人完成的实验代码** 94 | + **不使用他人测试用例** (depends) 95 | + 有些行为可能使你**得到分数**,但**失去应有的训练** 96 | 97 |
98 | 99 | 只在 “绝对可以求助” 的时候才寻求帮助 100 | 101 | + 在全民内卷、不劳而获很容易的时代很难 102 | + 但坚持下来的人会变得很不一样 103 | 104 | ---- 105 | 106 | ## 四周目反思 107 | 108 | 四周目表现平稳 109 | 110 | + 增加了更多的代码课和代码示例 111 | + 非递归汉诺塔 112 | + `.dl` 二进制文件格式与动态加载器 113 | + model checker (本周目将得到大幅改进) 114 | 115 |
116 | 117 | 第五周目 118 | 119 | + 工具现代化 + 新手友好 120 | + 绝大部分代码示例都在 Windows 应用商店安装的 Ubuntu 121 | + 更多的 xv6 (大家有 RISC-V 的基础了) 122 | + 逐渐重构 Online Judge 123 | + 更新一部分实验 (如果可以的话,有一个 POSIX subsystem) 124 | 125 | --- 126 | 127 | # Q1: 为什么要学操作系统? 128 | 129 | ---- 130 | 131 | ## 为什么要学操作系统? 132 | 133 | 134 | 135 | 为什么要学操作系统呢? 136 | 137 | + 为什么要学微积分/离散数学/XXXX/……? 138 | + 长辈/学长:擦干泪不要问为什么 139 | 140 |
141 | 142 | 微积分 “被混起来” 的几件事 143 | 144 | + Newton 时代的微积分 (启蒙与应用) 145 | + 现代方法:Mathematica, [sympy](https://docs.sympy.org/latest/tutorial/index.html), [sage](http://sagemath.org/) 146 | + 这也是为什么我主张第一门语言学 Python 147 | + Cauchy 时代的微积分 (严格化与公理化) 148 | + 以及之后各种卡出的 bug (Weierstrass 函数、Peano 曲线……) 149 | + 微积分的现代应用 150 | + 优化、有限元、PID…… 151 | 152 | 153 | ---- 154 | 155 | ## 学习操作系统的目的 156 | 157 | 你体内的 “编程力量” 尚未完全觉醒 158 | 159 | + 每天都在用的东西,你还没搞明白 160 | + 窗口是怎么创建的?[为什么 Ctrl-C 有时不能退出程序?](https://stackoverflow.blog/2017/05/23/stack-overflow-helping-one-million-developers-exit-vim/) 161 | + 组里的服务器有 128 个处理器,但你的程序却只能用一个 😂 162 | + 你每天都在用的东西,你却实现不出来 163 | + 浏览器、编译器、IDE、游戏/外挂、任务管理器、杀毒软件、病毒…… 164 | 165 |
166 | 167 | 《操作系统》给你有关 “编程” 的全部 168 | 169 | + 悟性好:学完课程就在系统方向 “毕业” 170 | + 具有编写一切 “能写出来” 程序的能力 (具备阅读论文的能力) 171 | + 悟性差:内力大增 172 | + 可能工作中的某一天想起上课提及的内容 173 | 174 | ---- 175 | 176 | ## 学习操作系统的目的 177 | 178 | >充满热情而且相当聪明的学生...早就听说过物理学如何有趣...相对论、量子力学……但是,当他们学完两年以前那种课程后,许多人就泄气了……学的还是斜面、静电这样的内容 179 | > 180 | >——《The Feynman Lectures on Physics, 1963》 181 | 182 | 我学《操作系统》的时候 (2009),大家都说操作系统很难教 183 | 184 | + 使用豆瓣评分高达 5.7/10 的 “全国优秀教材” 185 | + 没有正经的实验 (写一些 16-bit code) 186 | + 完全错误的 toolchain,调试全靠蛮力和猜 187 | + 为了一点微不足道的分数内卷、沾沾自喜、失去 integrity 188 | + 这么玩,脖子都要被美国人掐断了 189 | + 这门课的另一个意义:告诉你可以去变得更强、真正的强 190 | 191 | --- 192 | 193 | # Q2: 到底什么是操作系统? 194 | 195 | ---- 196 | 197 | ## 什么是操作系统? 198 | 199 | >Operating System: A body of software, in fact, that is responsible for *making it easy to run programs* (even allowing you to seemingly run many at the same time), allowing programs to share memory, enabling programs to interact with devices, and other fun stuff like that. (OSTEP) 200 | 201 |
202 | 203 | -- 204 | 205 | 很多疑点 206 | 207 | + “programs” 就完了?那么多复杂的程序呢! 208 | + “shared memory, interact with devices, ...”? 209 | 210 | ---- 211 | 212 | 213 | ## 什么是操作系统? (cont'd) 214 | 215 | “管理软/硬件资源、为程序提供服务” 的程序? 216 | 217 | 218 | ---- 219 | 220 | ## 理解操作系统 221 | 222 | “精准” 的定义毫无意义 223 | 224 | + 问出正确的问题:操作系统如何从一开始变成现在这样的? 225 | + 三个重要的线索 226 | + 计算机 (硬件) 227 | + 程序 (软件) 228 | + 操作系统 (管理软件的软件) 229 | 230 |
231 | 232 | 本课程讨论狭义的操作系统 233 | 234 | + 对单一计算机硬件系统作出抽象、支撑程序执行的软件系统 235 | + 学术界谈论 “操作系统” 是更广义的 “System” (例子:OSDI/SOSP) 236 | 237 | ---- 238 | 239 | ## 1940s 的计算机 240 | 241 | 跨时代、非凡的天才设计,但很简单 (还不如我们数电实验课做的 CPU 复杂呢): 242 | 243 | + 计算机系统 = 状态机 (ICS 课程的 takeaway message) 244 | + 标准的 Mealy 型数字电路 245 | + ENIAC (1946.2.14;请在这个特殊的节日多陪陪你的电脑) 246 | 247 | 248 | 249 | ---- 250 | 251 | ## 1940s 的计算机 (cont'd) 252 | 253 | 电子计算机的实现 254 | 255 | + 逻辑门:[真空电子管](https://www.bilibili.com/video/av59005720/?vd_source=4ee99d4ebd507c7277fa312ed28dbdda) 256 | + 存储器:延迟线 (delay lines) 257 | + 输入/输出:打孔纸带/指示灯 258 | 259 | 260 |
261 | 262 | 263 | 264 |
265 | 266 | ---- 267 | 268 | ## 1940s 的程序 269 | 270 | ENIAC 程序是用物理线路 “hard-wire” 的 271 | 272 | + 重编程需要重新接线 273 | + [ENIAC Simulator; sieve.e](https://www.cs.drexel.edu/~bls96/eniac/) 274 | 275 |
276 | 277 | 最早成功运行的一系列程序:打印平方数、素数表、计算弹道…… 278 | 279 | + 大家还在和真正的 “bugs” 战斗 280 | 281 | 282 | 283 | ---- 284 | 285 | ## 1940s 的操作系统 286 | 287 | >没有操作系统。 288 | 289 | 能把程序放上去就很了不起了 290 | 291 | + 程序直接用指令操作硬件 292 | + 不需要画蛇添足的程序来管理它 293 | 294 | ---- 295 | 296 | ## 1950s 的计算机 297 | 更快更小的逻辑门 (晶体管)、更大的内存 (磁芯)、丰富的 I/O 设备 298 | 299 | + I/O 设备的速度已经严重低于处理器的速度,中断机制出现 (1953) 300 | 301 | 302 | 303 | 304 | ---- 305 | 306 | ## 1950s 的程序 307 | 308 | 可以执行更复杂的任务,包括通用的计算任务 309 | 310 | + 希望使用计算机的人越来越多;希望调用 API 而不是直接访问设备 311 | + Fortran 诞生 (1957) 312 | 313 | ``` 314 | C---- THIS PROGRAM READS INPUT FROM THE CARD READER, 315 | C---- 3 INTEGERS IN EACH CARD, CALCULATE AND OUTPUT 316 | C---- THE SUM OF THEM. 317 | 100 READ(5,10) I1, I2, I3 318 | 10 FORMAT(3I5) 319 | IF (I1.EQ.0 .AND. I2.EQ.0 .AND. I3.EQ.0) GOTO 200 320 | ISUM = I1 + I2 + I3 321 | WRITE(6,20) I1, I2, I3, ISUM 322 | 20 FORMAT(7HSUM OF , I5, 2H, , I5, 5H AND , I5, 323 | * 4H IS , I6) 324 | GOTO 100 325 | 200 STOP 326 | END 327 | ``` 328 | 329 | ---- 330 | 331 | # 省略 332 | 333 | --- 334 | 335 | # 省略 -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from src.converter import converter 3 | 4 | if __name__ == "__main__": 5 | parser = argparse.ArgumentParser() 6 | parser.add_argument("filepath", help="select a Markdown file to convert", type=str) 7 | args = parser.parse_args() 8 | 9 | converter(args.filepath) 10 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "jyyslide-md" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["zweix123 <1979803044@qq.com>"] 6 | readme = "README.md" 7 | package-mode = false 8 | 9 | [tool.poetry.dependencies] 10 | python = "^3.10" 11 | requests = "^2.28.2" 12 | jinja2 = "^3.1.2" 13 | markdown = "^3.4.1" 14 | pyquery = "^2.0.0" 15 | pygments = "^2.14.0" 16 | lxml = "^5.0.0" 17 | pyyaml = "^6.0.1" 18 | types-markdown = "^3.4.2.6" 19 | types-requests = "^2.28.11.17" 20 | types-pyyaml = "^6.0.12.12" 21 | 22 | 23 | [tool.poetry.group.dev.dependencies] 24 | black = "^23.1.0" 25 | mypy = "^1.1.1" 26 | 27 | [build-system] 28 | requires = ["poetry-core"] 29 | build-backend = "poetry.core.masonry.api" 30 | -------------------------------------------------------------------------------- /resource/author.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/resource/author.png -------------------------------------------------------------------------------- /resource/example_of_author.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/resource/example_of_author.png -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/src/__init__.py -------------------------------------------------------------------------------- /src/backup/rouv/ruoshui255.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | 这是 title 14 | 15 | 16 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 47 | 48 | 49 | 50 | 51 | 52 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 |
239 |
240 |
241 |
242 |

Test

243 |
244 |
245 |
246 |
247 | 248 |
249 |
250 |

顾若水

251 |
print("hello world")
252 | 
253 | 254 |
255 |
256 | 257 |
258 | 259 |
260 |

water

261 |
    262 |
  • action 1
  • 263 |
  • action 2
      264 |
    • action 2.1
    • 265 |
    266 |
  • 267 |
268 |
269 | 270 |
271 |

water

272 |
    273 |
  • action 3
      274 |
    • action 3.1
    • 275 |
    • action 3.2
    • 276 |
    277 |
  • 278 |
279 |
280 |
281 |
    282 |
  • action 4
      283 |
    • action 4.1
    • 284 |
    285 |
  • 286 |
287 |
288 |
289 |
290 |
291 | 292 | 308 | 309 | 20 | 21 | """ 22 | print(txt) 23 | exit(0) 24 | 25 | 26 | try: 27 | from pyquery import PyQuery as pq 28 | import markdown 29 | from markdown import Extension 30 | from markdown.blockprocessors import BlockProcessor 31 | except ImportError: 32 | run_help() 33 | 34 | 35 | output_folder = "." 36 | 37 | template_html = """ 38 | 39 | 40 | 41 | 42 | 44 | 45 | 46 | 47 | 49 | 这是 title 50 | 51 | 52 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 83 | 84 | 85 | 86 | 87 | 88 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 |
275 |
276 | {} 277 |
278 |
279 | 280 | 296 | 297 | ".format(file)) 328 | 329 | with open(file, 'w+', encoding="utf-8") as f: 330 | s = f.write(data) 331 | 332 | 333 | def get(filename): 334 | if os.path.exists(filename): 335 | with open(filename, 'r', encoding="utf-8") as f: 336 | s = f.read() 337 | return s 338 | else: 339 | print("{} not exist".format(filename)) 340 | exit(-1) 341 | 342 | 343 | def add_wrap(e): 344 | items = e('h1').parent() 345 | # items = e('h1') 346 | 347 | print("h1 {}".format(len(items))) 348 | for item in items: 349 | t = pq(item) 350 | t.wrap("
") 351 | t.wrap("
") 352 | 353 | 354 | class_data = { 355 | 'ul': " list-disc font-serif", 356 | 'li': " ml-8", 357 | "h2": " text-xl mt-2 pb-2 font-sans", 358 | "h1": " text-2xl mt-2 font-sans", 359 | "p": " font-serif my-1", 360 | "pre": " bg-gray-100 overflow-x-auto rounded p-2 mb-2 mt-2" 361 | } 362 | 363 | 364 | def add_class(e): 365 | for k, v in class_data.items(): 366 | items = e(k) 367 | for item in items: 368 | t = pq(item) 369 | t.add_class(v) 370 | 371 | 372 | def gen_html(md_html: str, output): 373 | # print(md_html) 374 | page = pq(md_html) 375 | add_wrap(page) 376 | add_class(page) 377 | 378 | items = page('body').children() 379 | print("div {}".format(len(items))) 380 | 381 | template = template_html 382 | sections = "\n".join([str(pq(e)) for e in items]) 383 | res = template.replace("{}", sections) 384 | # res = template.replace("{}", str(e)) 385 | 386 | write(res, output) 387 | 388 | 389 | class BoxBlockProcessor(BlockProcessor): 390 | first = True 391 | 392 | def test(self, parent, block): 393 | return self.first 394 | 395 | def run(self, parent, blocks): 396 | if self.first: 397 | self.first = False 398 | 399 | e = etree.SubElement(parent, 'div') 400 | # e.set('style', 'display: inline-block; border: 1px solid red;') 401 | self.parser.parseBlocks(e, blocks) 402 | # remove used blocks 403 | for i in range(0, len(blocks)): 404 | blocks.pop(0) 405 | return True # or could have had no return statement 406 | return False # equivalent to our test() routine returning False 407 | 408 | 409 | class BoxExtension(Extension): 410 | def extendMarkdown(self, md): 411 | md.parser.blockprocessors.register(BoxBlockProcessor(md.parser), 'box', 175) 412 | 413 | 414 | def md_to_html(md: str) -> str: 415 | extensions = [ 416 | BoxExtension(), 417 | 'meta', 'fenced_code', "codehilite", 'attr_list' 418 | ] 419 | # html = markdown.markdown(text, extensions=[MyExtension()]) 420 | res = markdown.markdown(md, extensions=extensions) 421 | return res 422 | 423 | 424 | def print_list(identifier: str, lst: list): 425 | for t in lst: 426 | print("\n{}".format(identifier)) 427 | print(t) 428 | print("{}".format(identifier)) 429 | 430 | 431 | def md_to_fragment(section: str): 432 | """ 433 | 2个横线 434 | class="fragment" data-fragment-index="2 435 | """ 436 | 437 | fragment_delimiter = "\n--\n" 438 | fragments = section.split(fragment_delimiter) 439 | 440 | res = [md_to_html(fragments[0])] 441 | 442 | template = "
{}
" 443 | for i in range(1, len(fragments)): 444 | t = template.format(i - 1, md_to_html(fragments[i])) 445 | res.append(t) 446 | return "\n".join(res) 447 | 448 | 449 | def md_to_vertical_section(vertical_md: str) -> str: 450 | """ 451 | 4个横线 452 | 表示section 453 | """ 454 | md_delimiter = "\n----\n" 455 | vertical_sections = vertical_md.split(md_delimiter) 456 | 457 | template = "\n
{}
" 458 | if len(vertical_sections) == 1: 459 | template = "{}" 460 | 461 | section = [] 462 | for t in vertical_sections: 463 | fragments = md_to_fragment(t) 464 | html = template.format(fragments) 465 | section.append(html) 466 | # print_list("--- section ---", section) 467 | 468 | res = "\n".join(section) 469 | return res 470 | 471 | 472 | def md_parse(md: str, output_file): 473 | """ 474 | 3个横线 475 | 表示 大 section 476 | 477 | 5个横线 478 | 表示
479 | 480 | """ 481 | big_section_delimiter = "\n---\n" 482 | mds = md.split(big_section_delimiter) 483 | print("mds[0] <{}>".format(mds[0])) 484 | 485 | sections = [] 486 | template = "
\n {} \n
" 487 | for t in mds: 488 | if t.isspace(): 489 | continue 490 | s = md_to_vertical_section(t) 491 | html = template.format(s) 492 | sections.append(html) 493 | # print_list("*** big sections ***", sections) 494 | 495 | # pq needs a parent 496 | md_html = "{}".format("\n".join(sections)) 497 | gen_html(md_html, output_file) 498 | 499 | 500 | def main(): 501 | # if len(sys.argv) == 1: 502 | # run_help() 503 | # print("no input file") 504 | # exit(0) 505 | # 506 | # print(sys.argv) 507 | # file = sys.argv[1] 508 | # # data = get(file) 509 | # 510 | # 511 | # name = file.split("/")[-1].split(".", 1)[0] 512 | # if not name: 513 | # name = file.split("\\")[-1].split(".", 1)[0] 514 | # print(f'name {name}') 515 | # 516 | # output_filename = "{}.html".format(name) 517 | 518 | data = demo 519 | output_filename = "demo.html" 520 | 521 | md_parse(data, output_filename) 522 | 523 | 524 | if __name__ == '__main__': 525 | main() 526 | -------------------------------------------------------------------------------- /src/backup/template/authortemp.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |

10 |
11 |

12 | {% for department in departments %} 13 | 21 | {% endfor %} 22 |
23 | 24 |

25 | -------------------------------------------------------------------------------- /src/backup/template/basetemp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | {{ title }} 14 | 15 | 16 | 25 | 27 | 28 | 29 | 32 | 33 | 34 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 | {{ body }} 62 |
63 |
64 | 65 | 66 | 67 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/converter.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import shutil 4 | 5 | import yaml 6 | from jinja2 import Template 7 | from pyquery import PyQuery # type: ignore 8 | 9 | from src.util import * 10 | 11 | from . import settings as st 12 | 13 | 14 | def process_html_elements(before_html): 15 | temp_html = "{}".format(before_html) 16 | page = PyQuery(temp_html) 17 | e = page 18 | for item in e("h1").parent(): 19 | t = PyQuery(item) 20 | t.wrap("
") 21 | t.wrap("
") 22 | class_data = { 23 | "ul": "list-disc font-serif", 24 | "li": "ml-8", 25 | "h2": "text-xl mt-2 pb-2 font-sans", 26 | "h1": "text-2xl mt-2 font-sans", 27 | "p": "font-serif my-1", 28 | "pre": "bg-gray-100 overflow-x-auto rounded p-2 mb-2 mt-2", 29 | # "img": "center", # 设置图片是否默认居中 30 | } 31 | for k, v in class_data.items(): 32 | for item in e(k): 33 | t = PyQuery(item) 34 | t.add_class(v) 35 | page = e 36 | items = page("body").children() 37 | return "".join([str(PyQuery(e)) for e in items]) 38 | 39 | 40 | def process_terminal(semi_html): 41 | semi_html += st.author_template 42 | st.author_template = "" 43 | temp = "
" + semi_html + "
" 44 | semi_html = process_html_elements(temp) 45 | return semi_html 46 | 47 | 48 | def vertical_to_fragment(vertical: str) -> str: 49 | fragments = vertical.split(st.op_index_fragment) 50 | 51 | fragment_list = [md_util.md_to_html(fragments[0])] 52 | template = "
{}
" 53 | 54 | for i in range(1, len(fragments)): 55 | fragment_list.append(template.format(i, md_util.md_to_html(fragments[i]))) 56 | 57 | return "".join(fragment_list) 58 | 59 | 60 | def vertical_to_animate(vertical: str) -> str: 61 | animates = vertical.split(st.op_animate_section) 62 | 63 | animate_list = list() 64 | template = "{}" 65 | 66 | for i in range(len(animates)): 67 | animate_list.append(template.format(md_util.md_to_html(animates[i]))) 68 | 69 | return "".join(animate_list) 70 | 71 | 72 | def horizontal_to_vertical(horizontal: str) -> str: 73 | verticals_divided_by_second = horizontal.split(st.op_second_section) 74 | 75 | sections = list() 76 | template_second = "
{}
" 77 | 78 | for vertical_divided_by_second in verticals_divided_by_second: 79 | if vertical_divided_by_second.isspace(): 80 | continue 81 | if st.op_animate_section in vertical_divided_by_second: 82 | verticals_divided_by_animate = vertical_divided_by_second.split( 83 | st.op_animate_section 84 | ) 85 | template_animate = "
{}
" 86 | for vertical_divided_by_animate in verticals_divided_by_animate: 87 | if vertical_divided_by_animate.isspace(): 88 | continue 89 | sections.append( 90 | template_animate.format( 91 | process_terminal( 92 | vertical_to_animate(vertical_divided_by_animate) 93 | ) 94 | ) 95 | ) 96 | elif st.op_index_fragment in vertical_divided_by_second: 97 | sections.append( 98 | template_second.format( 99 | process_terminal(vertical_to_fragment(vertical_divided_by_second)) 100 | ) 101 | ) 102 | else: 103 | sections.append( 104 | template_second.format( 105 | process_terminal(md_util.md_to_html(vertical_divided_by_second)) 106 | ) 107 | ) 108 | 109 | return "".join(sections) 110 | 111 | 112 | def md_divide_to_horizontal(content: str): 113 | horizontals = content.split(st.op_first_section) 114 | 115 | sections = list() 116 | template = "
{}
" 117 | 118 | for horizontal in horizontals: 119 | if horizontal.isspace(): 120 | continue 121 | html_second_sections = horizontal_to_vertical(horizontal) 122 | 123 | html = template.format(html_second_sections) 124 | sections.append(html) 125 | 126 | return "".join(sections) 127 | 128 | 129 | def get_body(content): 130 | html_first_sections = md_divide_to_horizontal(content) 131 | return html_first_sections 132 | 133 | 134 | def process_image_link(): 135 | def func(link): 136 | new_name, err = file_util.get_image_to_target( 137 | link, st.filepath, st.images_foldpath 138 | ) 139 | 140 | return ( 141 | os.path.join(".", "static", st.images_foldname, new_name) 142 | if err is False 143 | else "" 144 | ), err 145 | 146 | st.content = md_util.process_images(st.content, func) 147 | 148 | 149 | def process_front_matter(): 150 | if st.op_front_matter not in st.content: 151 | st.author_template = "" 152 | return 153 | 154 | parts = st.content.split(st.op_front_matter) 155 | 156 | front_matter = parts[0] 157 | st.content = "".join(parts[1:]) 158 | 159 | try: 160 | data = json.loads(front_matter) 161 | except Exception as e: 162 | data = yaml.load(front_matter, Loader=yaml.SafeLoader) 163 | 164 | for department in data["departments"]: 165 | new_name, err = file_util.get_image_to_target( 166 | department["img"], st.filepath, st.images_foldpath 167 | ) 168 | if err is False: 169 | department["img"] = os.path.join( 170 | ".", "static", st.images_foldname, new_name 171 | ) 172 | department["name"] = department["name"].replace(" ", " ") 173 | 174 | st.author_template = st.author_template.render(author=data["author"], departments=data["departments"]) # type: ignore 175 | 176 | 177 | def process_static(): 178 | if os.path.exists(st.output_foldpath) is True: 179 | shutil.rmtree(st.output_foldpath) 180 | os.mkdir(st.output_foldpath) 181 | shutil.copytree(st.static_path, st.static_foldpath) 182 | 183 | 184 | def converter(MDfilepath): 185 | st.Init(MDfilepath) 186 | process_static() 187 | 188 | st.template = Template(file_util.read(st.template_from)) 189 | st.author_template = Template(file_util.read(st.authortemp_from)) 190 | 191 | st.content = file_util.read(st.filepath) 192 | process_front_matter() # 解析markdown中的front_matter and render author_template(will change content) 193 | process_image_link() # 处理Markdown文本中的图片链接, 将它们get到静态文件, 同时修改content 194 | 195 | st.title = "".join(st.filename.split(".")[:-1]) 196 | st.body = get_body(st.content) 197 | 198 | st.template = st.template.render(title=st.title, body=st.body) 199 | 200 | file_util.write(st.output_filepath, st.template) 201 | -------------------------------------------------------------------------------- /src/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from jinja2 import Template 4 | 5 | settings_abspath = os.path.split(os.path.realpath(__file__))[0] 6 | projects_abspath = os.path.abspath(os.path.join(settings_abspath, "..")) 7 | 8 | static_path = os.path.join(projects_abspath, "src", "static") 9 | backup_path = os.path.join(projects_abspath, "src", "backup") 10 | template_from = os.path.join(backup_path, "template", "basetemp.html") 11 | authortemp_from = os.path.join(backup_path, "template", "authortemp.html") 12 | 13 | op_first_section = "\n---\n" 14 | op_second_section = "\n----\n" 15 | op_animate_section = "\n++++\n" 16 | op_index_fragment = "\n--\n" 17 | op_front_matter = "\n+++++\n" 18 | 19 | # 文件信息 20 | filename = str() 21 | filepath = str() 22 | output_foldname = "dist" 23 | output_filename = "index.html" 24 | output_foldpath = str() 25 | output_filepath = str() 26 | static_foldpath = str() 27 | images_foldname = "img" # 如果要修改还要修炼static下的img文件名,template中icon的文件路径 28 | images_foldpath = str() 29 | 30 | content = str() # MD内容 31 | 32 | template: str | Template = str() # HTML内容 33 | title = str() 34 | body = str() 35 | 36 | # 作者信息相关 37 | author_template: str | Template = str() 38 | 39 | 40 | def Init(target_filepath): 41 | global filename, filepath, output_foldname, output_filename, output_foldpath, output_filepath, static_foldpath, images_foldpath 42 | filename = os.path.basename(target_filepath) 43 | filepath = os.path.abspath(target_filepath) 44 | output_foldpath = os.path.join(filepath.split(filename)[0], output_foldname) 45 | output_filepath = os.path.join(output_foldpath, output_filename) 46 | 47 | static_foldpath = os.path.join(output_foldpath, "static") 48 | images_foldpath = os.path.join(static_foldpath, images_foldname) 49 | -------------------------------------------------------------------------------- /src/static/css/base.css: -------------------------------------------------------------------------------- 1 | .watermark { 2 | position: fixed; 3 | opacity: 0.1; 4 | font-size: 128px; 5 | width: 100%; 6 | text-align: center; 7 | z-index: 1000; 8 | pointer-events: none; 9 | } 10 | 11 | .reveal .katex { 12 | font-size: 100%; 13 | } 14 | 15 | red { color: red; } 16 | green { color: green; } 17 | blue { color: blue; } 18 | 19 | .codehilite .hll { background-color: #ffffcc } 20 | .codehilite .c { color: #408080; font-style: italic } /* Comment */ 21 | .codehilite .err { border: 1px solid #FF0000 } /* Error */ 22 | .codehilite .k { color: #008000; font-weight: bold } /* Keyword */ 23 | .codehilite .o { color: #666666 } /* Operator */ 24 | .codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */ 25 | .codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 26 | .codehilite .cp { color: #BC7A00 } /* Comment.Preproc */ 27 | .codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */ 28 | .codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */ 29 | .codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */ 30 | .codehilite .gd { color: #A00000 } /* Generic.Deleted */ 31 | .codehilite .ge { font-style: italic } /* Generic.Emph */ 32 | .codehilite .gr { color: #FF0000 } /* Generic.Error */ 33 | .codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 34 | .codehilite .gi { color: #00A000 } /* Generic.Inserted */ 35 | .codehilite .go { color: #888888 } /* Generic.Output */ 36 | .codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 37 | .codehilite .gs { font-weight: bold } /* Generic.Strong */ 38 | .codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 39 | .codehilite .gt { color: #0044DD } /* Generic.Traceback */ 40 | .codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ 41 | .codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ 42 | .codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ 43 | .codehilite .kp { color: #008000 } /* Keyword.Pseudo */ 44 | .codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ 45 | .codehilite .kt { color: #B00040 } /* Keyword.Type */ 46 | .codehilite .m { color: #666666 } /* Literal.Number */ 47 | .codehilite .s { color: #BA2121 } /* Literal.String */ 48 | .codehilite .na { color: #7D9029 } /* Name.Attribute */ 49 | .codehilite .nb { color: #008000 } /* Name.Builtin */ 50 | .codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 51 | .codehilite .no { color: #880000 } /* Name.Constant */ 52 | .codehilite .nd { color: #AA22FF } /* Name.Decorator */ 53 | .codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */ 54 | .codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 55 | .codehilite .nf { color: #0000FF } /* Name.Function */ 56 | .codehilite .nl { color: #A0A000 } /* Name.Label */ 57 | .codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 58 | .codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */ 59 | .codehilite .nv { color: #19177C } /* Name.Variable */ 60 | .codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 61 | .codehilite .w { color: #bbbbbb } /* Text.Whitespace */ 62 | .codehilite .mb { color: #666666 } /* Literal.Number.Bin */ 63 | .codehilite .mf { color: #666666 } /* Literal.Number.Float */ 64 | .codehilite .mh { color: #666666 } /* Literal.Number.Hex */ 65 | .codehilite .mi { color: #666666 } /* Literal.Number.Integer */ 66 | .codehilite .mo { color: #666666 } /* Literal.Number.Oct */ 67 | .codehilite .sa { color: #BA2121 } /* Literal.String.Affix */ 68 | .codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */ 69 | .codehilite .sc { color: #BA2121 } /* Literal.String.Char */ 70 | .codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */ 71 | .codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ 72 | .codehilite .s2 { color: #BA2121 } /* Literal.String.Double */ 73 | .codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 74 | .codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */ 75 | .codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 76 | .codehilite .sx { color: #008000 } /* Literal.String.Other */ 77 | .codehilite .sr { color: #BB6688 } /* Literal.String.Regex */ 78 | .codehilite .s1 { color: #BA2121 } /* Literal.String.Single */ 79 | .codehilite .ss { color: #19177C } /* Literal.String.Symbol */ 80 | .codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */ 81 | .codehilite .fm { color: #0000FF } /* Name.Function.Magic */ 82 | .codehilite .vc { color: #19177C } /* Name.Variable.Class */ 83 | .codehilite .vg { color: #19177C } /* Name.Variable.Global */ 84 | .codehilite .vi { color: #19177C } /* Name.Variable.Instance */ 85 | .codehilite .vm { color: #19177C } /* Name.Variable.Magic */ 86 | .codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */ 87 | -------------------------------------------------------------------------------- /src/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/src/static/img/favicon.png -------------------------------------------------------------------------------- /src/static/jyy/jyy.css: -------------------------------------------------------------------------------- 1 | .reveal .slide-number { 2 | font-size: 26px; 3 | border-radius: 5px; 4 | background-color: rgba(0, 0, 0, .3); 5 | } 6 | 7 | .reveal .slides { 8 | border: 1.5px #ddd solid; 9 | border-radius: 7px; 10 | text-align: left; 11 | font-weight: 300; 12 | } 13 | 14 | .reveal h1, 15 | .reveal h2, 16 | .reveal h3, 17 | .reveal h4 { 18 | font-family: 'Lato', 'SimHei', 'STXihei', 'Sans Serif'; 19 | font-weight: 400; 20 | } 21 | 22 | .reveal p, 23 | .reveal li, 24 | .reveal center { 25 | font-size: 32px; 26 | font-family: 'Lato', 'STHeiti', 'SimHei', 'Sans Serif'; 27 | } 28 | 29 | .reveal li+li { 30 | margin-top: 10px; 31 | } 32 | 33 | .reveal ul { 34 | display: block; 35 | margin-right: 15px; 36 | } 37 | 38 | .reveal p, 39 | .reveal h1, 40 | .reveal h2, 41 | .reveal h3, 42 | .reveal h4, 43 | .reveal h5 { 44 | padding: 0 25px 0 25px; 45 | } 46 | 47 | .reveal table { 48 | font-size: 32px; 49 | font-family: 'Lato', 'STHeiti', 'SimHei', 'Sans Serif'; 50 | margin-top: 15px; 51 | margin-bottom: 15px; 52 | } 53 | 54 | .reveal th { 55 | background-color: #eee; 56 | } 57 | 58 | .reveal tr:nth-child(even) { 59 | background-color: #efffff; 60 | } 61 | 62 | .reveal h1, 63 | .reveal h2, 64 | .reveal h3, 65 | .reveal h4, 66 | .reveal h5, 67 | .reveal h6 { 68 | text-align: left; 69 | margin: 0 0 20px 0; 70 | color: #222; 71 | font-weight: 400; 72 | line-height: 1.2; 73 | letter-spacing: normal; 74 | } 75 | 76 | .reveal h1 { 77 | margin: 0 10 0 10; 78 | font-size: 60px; 79 | } 80 | 81 | .reveal .middle h1 { 82 | text-align: center; 83 | } 84 | 85 | .reveal h2 { 86 | font-size: 48px; 87 | border-bottom: 2px solid rgb(106, 0, 95); 88 | padding-bottom: 5px; 89 | } 90 | 91 | .reveal h3 { 92 | font-size: 1.15em; 93 | } 94 | 95 | .reveal h4 { 96 | font-size: 1.05em; 97 | } 98 | 99 | .reveal .center { 100 | text-align: center; 101 | } 102 | 103 | .reveal .middle { 104 | height: 728px; 105 | display: flex; 106 | align-items: center; 107 | width: 100%; 108 | } 109 | 110 | .reveal pre { 111 | font-size: 28px; 112 | 113 | background-color: #eee; 114 | 115 | border-radius: 3mm; 116 | padding: 10px 10px 10px 10px; 117 | } 118 | 119 | .reveal pre code { 120 | max-height: none; 121 | } 122 | 123 | .reveal code { 124 | font-family: 'Inconsolata', 'STKaiti', 'KaiTi', 'Sans Serif', Monospace; 125 | } 126 | 127 | .reveal .middle blockquote { 128 | text-align: center; 129 | color: rgb(106, 0, 95); 130 | background: none; 131 | box-shadow: none; 132 | } 133 | 134 | .reveal .middle blockquote a { 135 | color: inherit; 136 | } 137 | 138 | .reveal blockquote p, 139 | .reveal blockquote li { 140 | font-family: 'Lato', 'STKaiti', 'KaiTi', 'Sans Serif'; 141 | } 142 | 143 | section .center { 144 | display: block; 145 | margin-left: auto; 146 | margin-right: auto; 147 | } 148 | 149 | .reveal .author-block { 150 | margin: 75px 0 35px 0; 151 | } 152 | 153 | .reveal .author-affiliation img { 154 | margin: 15px 0 0 0; 155 | } 156 | 157 | .reveal .author-block p, 158 | .reveal .author-affiliation p { 159 | font-family: 'Kaiti', 'STKaiti', 'Serif', 'Times', 'Times New Roman'; 160 | margin-block-start: 0em; 161 | margin-block-end: 0em; 162 | } 163 | 164 | .reveal .author-affiliation { 165 | display: inline-block; 166 | font-size: 90%; 167 | } 168 | 169 | .reveal hr { 170 | border: 10px solid rgba(0, 0, 0, 0); 171 | } 172 | 173 | .reveal li { 174 | margin-top: 10px; 175 | } -------------------------------------------------------------------------------- /src/static/katex/auto-render.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("katex")):"function"==typeof define&&define.amd?define(["katex"],t):"object"==typeof exports?exports.renderMathInElement=t(require("katex")):e.renderMathInElement=t(e.katex)}("undefined"!=typeof self?self:this,(function(e){return function(){"use strict";var t={771:function(t){t.exports=e}},r={};function n(e){var i=r[e];if(void 0!==i)return i.exports;var a=r[e]={exports:{}};return t[e](a,a.exports,n),a.exports}n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,{a:t}),t},n.d=function(e,t){for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};var i={};return function(){n.d(i,{default:function(){return s}});var e=n(771),t=n.n(e),r=function(e,t,r){for(var n=r,i=0,a=e.length;n0&&(i.push({type:"text",data:e.slice(0,n)}),e=e.slice(n));var l=t.findIndex((function(t){return e.startsWith(t.left)}));if(-1===(n=r(t[l].right,e,t[l].left.length)))break;var d=e.slice(0,n+t[l].right.length),s=a.test(d)?d:e.slice(t[l].left.length,n);i.push({type:"math",data:s,rawData:d,display:t[l].display}),e=e.slice(n+t[l].right.length)}return""!==e&&i.push({type:"text",data:e}),i},l=function(e,r){var n=o(e,r.delimiters);if(1===n.length&&"text"===n[0].type)return null;for(var i=document.createDocumentFragment(),a=0;a.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.27777778em;margin-right:-.55555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.83333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.16666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.66666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.45666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.14666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.71428571em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.85714286em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.14285714em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.28571429em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.42857143em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.71428571em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.05714286em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.46857143em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.96285714em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.55428571em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.55555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.66666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.77777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.88888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.11111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.33333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.30444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.76444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.41666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.58333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.66666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.83333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.72833333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.07333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.34722222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.41666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.48611111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.55555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.69444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.83333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.44027778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.72777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.28935185em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.34722222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.40509259em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.46296296em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.52083333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.69444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.83333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.20023148em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.43981481em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.24108004em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.28929605em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.33751205em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.38572806em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.43394407em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.48216008em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.57859209em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.69431051em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.83317261em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.19961427em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.20096463em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.24115756em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.28135048em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.32154341em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.36173633em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.40192926em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.48231511em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.57877814em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.69453376em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.83360129em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo} 2 | -------------------------------------------------------------------------------- /src/static/reveal/theme/simple.css: -------------------------------------------------------------------------------- 1 | /** 2 | * A simple theme for reveal.js presentations, similar 3 | * to the default theme. The accent color is darkblue. 4 | * 5 | * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed. 6 | * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 7 | */ 8 | @import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700); 9 | @import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic); 10 | section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 { 11 | color: #fff; } 12 | 13 | /********************************************* 14 | * GLOBAL STYLES 15 | *********************************************/ 16 | :root { 17 | --background-color: #fff; 18 | --main-font: Lato, sans-serif; 19 | --main-font-size: 40px; 20 | --main-color: #000; 21 | --block-margin: 20px; 22 | --heading-margin: 0 0 20px 0; 23 | --heading-font: News Cycle, Impact, sans-serif; 24 | --heading-color: #000; 25 | --heading-line-height: 1.2; 26 | --heading-letter-spacing: normal; 27 | --heading-text-transform: none; 28 | --heading-text-shadow: none; 29 | --heading-font-weight: normal; 30 | --heading1-text-shadow: none; 31 | --heading1-size: 3.77em; 32 | --heading2-size: 2.11em; 33 | --heading3-size: 1.55em; 34 | --heading4-size: 1em; 35 | --code-font: monospace; 36 | --link-color: #00008B; 37 | --link-color-hover: #0000f1; 38 | --selection-background-color: rgba(0, 0, 0, 0.99); 39 | --selection-color: #fff; } 40 | 41 | .reveal-viewport { 42 | background: #fff; 43 | background-color: #fff; } 44 | 45 | .reveal { 46 | font-family: "Lato", sans-serif; 47 | font-size: 40px; 48 | font-weight: normal; 49 | color: #000; } 50 | 51 | .reveal ::selection { 52 | color: #fff; 53 | background: rgba(0, 0, 0, 0.99); 54 | text-shadow: none; } 55 | 56 | .reveal ::-moz-selection { 57 | color: #fff; 58 | background: rgba(0, 0, 0, 0.99); 59 | text-shadow: none; } 60 | 61 | .reveal .slides section, 62 | .reveal .slides section > section { 63 | line-height: 1.3; 64 | font-weight: inherit; } 65 | 66 | /********************************************* 67 | * HEADERS 68 | *********************************************/ 69 | .reveal h1, 70 | .reveal h2, 71 | .reveal h3, 72 | .reveal h4, 73 | .reveal h5, 74 | .reveal h6 { 75 | margin: 0 0 20px 0; 76 | color: #000; 77 | font-family: "News Cycle", Impact, sans-serif; 78 | font-weight: normal; 79 | line-height: 1.2; 80 | letter-spacing: normal; 81 | text-transform: none; 82 | text-shadow: none; 83 | word-wrap: break-word; } 84 | 85 | .reveal h1 { 86 | font-size: 3.77em; } 87 | 88 | .reveal h2 { 89 | font-size: 2.11em; } 90 | 91 | .reveal h3 { 92 | font-size: 1.55em; } 93 | 94 | .reveal h4 { 95 | font-size: 1em; } 96 | 97 | .reveal h1 { 98 | text-shadow: none; } 99 | 100 | /********************************************* 101 | * OTHER 102 | *********************************************/ 103 | .reveal p { 104 | margin: 20px 0; 105 | line-height: 1.3; } 106 | 107 | /* Ensure certain elements are never larger than the slide itself */ 108 | .reveal img, 109 | .reveal video, 110 | .reveal iframe { 111 | max-width: 95%; 112 | max-height: 95%; } 113 | 114 | .reveal strong, 115 | .reveal b { 116 | font-weight: bold; } 117 | 118 | .reveal em { 119 | font-style: italic; } 120 | 121 | .reveal ol, 122 | .reveal dl, 123 | .reveal ul { 124 | display: inline-block; 125 | text-align: left; 126 | margin: 0 0 0 1em; } 127 | 128 | .reveal ol { 129 | list-style-type: decimal; } 130 | 131 | .reveal ul { 132 | list-style-type: disc; } 133 | 134 | .reveal ul ul { 135 | list-style-type: square; } 136 | 137 | .reveal ul ul ul { 138 | list-style-type: circle; } 139 | 140 | .reveal ul ul, 141 | .reveal ul ol, 142 | .reveal ol ol, 143 | .reveal ol ul { 144 | display: block; 145 | margin-left: 10px; } 146 | 147 | .reveal dt { 148 | font-weight: bold; } 149 | 150 | .reveal dd { 151 | margin-left: 40px; } 152 | 153 | .reveal blockquote { 154 | display: block; 155 | position: relative; 156 | width: 90%; 157 | margin: 20px auto; 158 | padding: 5px; 159 | background: rgba(0, 255, 255, 0.05); 160 | border-radius: 10px; 161 | box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2); 162 | } 163 | 164 | .reveal q { 165 | font-style: italic; } 166 | 167 | .reveal pre { 168 | display: block; 169 | position: relative; 170 | width: 90%; 171 | margin: 20px auto; 172 | text-align: left; 173 | font-size: 0.55em; 174 | font-family: monospace; 175 | line-height: 1.2em; 176 | word-wrap: break-word; 177 | box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15); } 178 | 179 | .reveal code { 180 | font-family: monospace; 181 | text-transform: none; } 182 | 183 | .reveal pre code { 184 | display: block; 185 | padding: 5px; 186 | overflow: auto; 187 | max-height: 400px; 188 | word-wrap: normal; } 189 | 190 | .reveal table { 191 | margin: auto; 192 | border-collapse: collapse; 193 | border-spacing: 0; } 194 | 195 | .reveal table th { 196 | font-weight: bold; } 197 | 198 | .reveal table th, 199 | .reveal table td { 200 | text-align: left; 201 | padding: 0.2em 0.5em 0.2em 0.5em; 202 | border-bottom: 1px solid; } 203 | 204 | .reveal table th[align="center"], 205 | .reveal table td[align="center"] { 206 | text-align: center; } 207 | 208 | .reveal table th[align="right"], 209 | .reveal table td[align="right"] { 210 | text-align: right; } 211 | 212 | .reveal table tbody tr:last-child th, 213 | .reveal table tbody tr:last-child td { 214 | border-bottom: none; } 215 | 216 | .reveal sup { 217 | vertical-align: super; 218 | font-size: smaller; } 219 | 220 | .reveal sub { 221 | vertical-align: sub; 222 | font-size: smaller; } 223 | 224 | .reveal small { 225 | display: inline-block; 226 | font-size: 0.6em; 227 | line-height: 1.2em; 228 | vertical-align: top; } 229 | 230 | .reveal small * { 231 | vertical-align: top; } 232 | 233 | .reveal img { 234 | margin: 20px 0; } 235 | 236 | /********************************************* 237 | * LINKS 238 | *********************************************/ 239 | .reveal a { 240 | color: #00008B; 241 | text-decoration: none; 242 | transition: color .15s ease; } 243 | 244 | .reveal a:hover { 245 | color: #0000f1; 246 | text-shadow: none; 247 | border: none; } 248 | 249 | .reveal .roll span:after { 250 | color: #fff; 251 | background: #00003f; } 252 | 253 | /********************************************* 254 | * Frame helper 255 | *********************************************/ 256 | .reveal .r-frame { 257 | border: 4px solid #000; 258 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); } 259 | 260 | .reveal a .r-frame { 261 | transition: all .15s linear; } 262 | 263 | .reveal a:hover .r-frame { 264 | border-color: #00008B; 265 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); } 266 | 267 | /********************************************* 268 | * NAVIGATION CONTROLS 269 | *********************************************/ 270 | .reveal .controls { 271 | color: #00008B; } 272 | 273 | /********************************************* 274 | * PROGRESS BAR 275 | *********************************************/ 276 | .reveal .progress { 277 | background: rgba(0, 0, 0, 0.2); 278 | color: #00008B; } 279 | 280 | /********************************************* 281 | * PRINT BACKGROUND 282 | *********************************************/ 283 | @media print { 284 | .backgrounds { 285 | background-color: #fff; } } 286 | -------------------------------------------------------------------------------- /src/util/__init__.py: -------------------------------------------------------------------------------- 1 | from . import file_util, net_util, str_util, md_util 2 | -------------------------------------------------------------------------------- /src/util/file_util.py: -------------------------------------------------------------------------------- 1 | import os, shutil, uuid 2 | from typing import Optional, Tuple 3 | from . import str_util, net_util 4 | 5 | 6 | def get_files_under_folder( 7 | folerpath: str, suffix_name: Optional[str] = None 8 | ) -> list[str]: 9 | """返回目录folderpath下后缀名为suffix_name的所有文件的绝对路径列表""" 10 | return [ 11 | os.path.abspath(os.path.join(dirpath, filename)) 12 | for dirpath, dirnames, filenames in os.walk(folerpath) 13 | for filename in filenames 14 | if suffix_name is None or str(filename).endswith("." + suffix_name) 15 | ] 16 | 17 | 18 | def read(filepath: str) -> str: # 读取文本文件内容 19 | if os.path.exists(filepath) is False: 20 | raise Exception("The path {} is not exists".format(filepath)) 21 | with open(filepath, "r", encoding="utf-8") as f: 22 | return str(f.read()) 23 | 24 | 25 | def write(filepath: str, data: str) -> None: # 向文件(覆)写内容 26 | dirpath = os.path.dirname(filepath) 27 | if os.path.exists(dirpath) is False: 28 | os.makedirs(dirpath) 29 | with open(filepath, "w", encoding="utf-8") as f: 30 | f.write(data) 31 | 32 | 33 | def get_abspath(basefile: str, filepath: str) -> str: # 从绝对路径变化成相对路径且符合当前的操作系统 34 | return os.path.normpath(os.path.join(os.path.dirname(basefile), filepath)) 35 | 36 | 37 | def get_image_to_target( 38 | link: str, from_filepath: str, target_foldpath: str 39 | ) -> Tuple[str, bool]: 40 | # 对于from_filepath(请使用其绝对地址)中的图床链接link, 它可能是url、绝对地址或相对地址, 我们会get它然后重命名并放到target_foldpath下, 并返回重命名后的名字 41 | # 这里对图片类型的判断是通过link的后缀名, 有些图片的url的末尾不是类型名, 就会有bug 42 | name = uuid.uuid4().hex + "." + link.split(".")[-1] 43 | if str_util.is_url(link): 44 | pass 45 | else: 46 | if os.path.isabs(link) is True: 47 | pass 48 | else: 49 | link = get_abspath(from_filepath, link) 50 | pass 51 | 52 | if str_util.is_url(link): 53 | net_util.down_image(link, os.path.join(target_foldpath, name)) 54 | else: 55 | if os.path.exists(link) is False: 56 | print("The path is not exists: ", link) 57 | return "", True 58 | shutil.copyfile(link, os.path.join(target_foldpath, name)) 59 | 60 | return name, False 61 | -------------------------------------------------------------------------------- /src/util/md_util.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import List, Union 3 | 4 | 5 | def process_images(content, func): 6 | """处理Markdown类型字符串中的图片链接, 返回处理过图片链接部分的Markdown字符串 7 | 8 | Args: 9 | content (_type_): Markdown类型字符串 10 | func (_type_): 处理图片链接的函数, 该函数接受图片链接字符串, 返回一个(有关图片链接的新串, 是否有错误)的元组 11 | """ 12 | 13 | def modify(match): 14 | # 下面是黑盒魔法 15 | tar = match.group() 16 | pre, mid, suf = str(), str(), str() 17 | if tar[-1] == ")": 18 | pre = tar[: tar.index("(") + 1] 19 | mid = tar[tar.index("(") + 1 : -1] 20 | suf = tar[-1] 21 | else: 22 | mid = re.search(r'src="([^"]*)"', tar).group(1) 23 | pre, suf = tar.split(mid) 24 | 25 | link = mid 26 | # 黑盒魔法结束 27 | new_name, err = func(link) 28 | return pre + (new_name if err is False else link) + suf 29 | 30 | patten = r"!\[.*?\]\((.*?)\)|" 31 | return re.sub(patten, modify, content) 32 | 33 | 34 | ### 35 | 36 | from markdown import markdown 37 | from markdown import Extension 38 | from markdown.blockprocessors import BlockProcessor 39 | import xml.etree.ElementTree as etree 40 | 41 | 42 | def md_to_html(md: str) -> str: 43 | class BoxBlockProcessor(BlockProcessor): 44 | first = True 45 | 46 | def run(self, parent, blocks): 47 | if self.first: 48 | self.first = False 49 | e = etree.SubElement(parent, "div") 50 | self.parser.parseBlocks(e, blocks) 51 | for _ in range(0, len(blocks)): 52 | blocks.pop(0) 53 | return True 54 | return False 55 | 56 | class BoxExtension(Extension): 57 | def extendMarkdown(self, md): 58 | md.parser.blockprocessors.register(BoxBlockProcessor(md.parser), "box", 175) 59 | 60 | extensions: List[Union[str, BoxExtension]] = [ 61 | BoxExtension(), 62 | "meta", 63 | "fenced_code", 64 | "codehilite", 65 | "extra", 66 | "attr_list", 67 | "tables", 68 | "toc", 69 | ] 70 | return markdown(md, extensions=extensions) 71 | -------------------------------------------------------------------------------- /src/util/net_util.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | 4 | def down_image(img_url, save_file_path): 5 | resp = requests.get(img_url) 6 | with open(save_file_path, "wb") as f: 7 | f.write(resp.content) 8 | -------------------------------------------------------------------------------- /src/util/str_util.py: -------------------------------------------------------------------------------- 1 | from urllib.parse import urlparse 2 | 3 | 4 | # 分辨URL和路径: 判断一个字符串是否为URL 5 | def is_url(string): 6 | result = urlparse(string) 7 | return all([result.scheme, result.netloc]) 8 | 9 | 10 | # 分辨URL和路径: 判断一个字符串是否为路径 11 | def is_path(string): 12 | result = urlparse(string) 13 | return not all([result.scheme, result.netloc]) 14 | -------------------------------------------------------------------------------- /test/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zweix123/jyyslide-md/b33c115558a20e1a254259559d115d25f4d24458/test/.gitkeep -------------------------------------------------------------------------------- /test/regression-testing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # TODO: Compatible with Windows operating system 4 | jyyslice_md_path=$(dirname $(dirname $(readlink -f $0))) 5 | export JYYSLICE_MD_PATH=$jyyslice_md_path 6 | 7 | # unit 8 | poetry run python unit/author.py 9 | 10 | # TODO: other tests 11 | -------------------------------------------------------------------------------- /test/unit/author.py: -------------------------------------------------------------------------------- 1 | # unit test for function process_front_matter 2 | # process_front_matter input is st.content 3 | # process_front_matter output is st.author_template 4 | 5 | 6 | import os 7 | import sys 8 | import unittest 9 | 10 | from jinja2 import Template # lib used in converter.py 11 | 12 | # add project root to sys.path, otherwise, the import below will fail 13 | sys.path = [os.environ["JYYSLICE_MD_PATH"]] + sys.path 14 | 15 | 16 | import src.settings as st 17 | from src.converter import process_front_matter 18 | 19 | # 这里没有使用项目中的template, 而是针对其使用的模版变量专门测试 20 | #! 假如未来模版内容修改, 当前单元测试无法感知, 导致作为回归测试的话会落后版本 21 | AUTHOR_TEMPLATE_STRING = """ 22 | {{ author.name }} 23 | {{ author.url }} 24 | {% for department in departments %} 25 | {{ department.name }} 26 | {{ department.url }} 27 | {{ department.img }} 28 | {% endfor %} 29 | """ 30 | 31 | 32 | class TestProcessFrontMatter(unittest.TestCase): 33 | def single_test(self, input: str, output: str): 34 | """ 35 | 单次测试 36 | Args: 37 | input (str): 要测试的markdown头 38 | output (str): 要测试的头部分的输出 39 | """ 40 | st.content = input 41 | st.author_template = Template(AUTHOR_TEMPLATE_STRING) # init st.author_template 42 | process_front_matter() 43 | self.assertEqual(st.author_template, output) 44 | 45 | def test_not_front_matter(self): 46 | self.single_test("", "") 47 | 48 | def test_common_json(self): 49 | author_info_md = ( 50 | """{ 51 | "author": { 52 | "name": "蒋炎岩", 53 | "url": "https://ics.nju.edu.cn/~jyy/" 54 | }, 55 | "departments": [ 56 | { 57 | "name": " 南京大学 ", 58 | "url": "https://www.nju.edu.cn/main.htm", 59 | "img": "./img/nju-logo.jpg" 60 | }, 61 | { 62 | "name": "计算机科学与技术系", 63 | "url": "https://cs.nju.edu.cn/main.htm", 64 | "img": "./img/njucs-logo.jpg" 65 | }, 66 | { 67 | "name": "计算机软件研究所", 68 | "url": "https://www.nju.edu.cn/main.htm", 69 | "img": "./img/ics-logo.png" 70 | } 71 | ] 72 | }""" 73 | + st.op_front_matter 74 | ) 75 | expected_output = """ 76 | 蒋炎岩 77 | https://ics.nju.edu.cn/~jyy/ 78 | 79 |   南京大学   80 | https://www.nju.edu.cn/main.htm 81 | ./img/nju-logo.jpg 82 | 83 | 计算机科学与技术系 84 | https://cs.nju.edu.cn/main.htm 85 | ./img/njucs-logo.jpg 86 | 87 | 计算机软件研究所 88 | https://www.nju.edu.cn/main.htm 89 | ./img/ics-logo.png 90 | """ 91 | 92 | self.single_test(author_info_md, expected_output) 93 | 94 | def test_common_yaml(self): 95 | author_info_md = ( 96 | """author: 97 | name: 蒋炎岩 98 | url: https://ics.nju.edu.cn/~jyy/ 99 | 100 | departments: 101 | - name: " 南京大学 " 102 | url: https://www.nju.edu.cn/main.htm, 103 | img: ./img/nju-logo.jpg 104 | 105 | - name: 计算机科学与技术系 106 | url: https://cs.nju.edu.cn/main.htm, 107 | img: ./img/njucs-logo.jpg 108 | 109 | - name: 计算机软件研究所 110 | url: https://www.nju.edu.cn/main.htm, 111 | img: ./img/ics-logo.png""" 112 | + st.op_front_matter 113 | ) 114 | expected_output = """ 115 | 蒋炎岩 116 | https://ics.nju.edu.cn/~jyy/ 117 | 118 |   南京大学   119 | https://www.nju.edu.cn/main.htm, 120 | ./img/nju-logo.jpg 121 | 122 | 计算机科学与技术系 123 | https://cs.nju.edu.cn/main.htm, 124 | ./img/njucs-logo.jpg 125 | 126 | 计算机软件研究所 127 | https://www.nju.edu.cn/main.htm, 128 | ./img/ics-logo.png 129 | """ 130 | 131 | self.single_test(author_info_md, expected_output) 132 | 133 | 134 | if __name__ == "__main__": 135 | unittest.main() 136 | --------------------------------------------------------------------------------