markdown格式转化

2020年02月11日 星期二

本文主要讲如何应用python将markdown转化为html语句以及相关需要注意的事项……

​ 本文主要讲基于Django架构如何将markdown文件内容以markdown形式显示于html中。

有两个思路:

一是在Django通过内置插件类似于Django MarkdownX,通过将markdown文件内容存储于数据库中来实现;

二是基于已有的markdown文件,将其转换为html格式代码,然后再在模板中呈现相关参考文件:https://www.jianshu.com/p/0eff6cba1b7f

这里主要讲后者的应用。

1 转换为HTML代码

​ 采用markdown模块,相关说明文档:文档链接。本文中具体说明的是其应用。

import codecs, markdown
# 读取 markdown 文本
input_file = codecs.open("some_file.md", mode="r", encoding="utf-8")
text = input_file.read()
myext = ['markdown.extensions.fenced_code',  
         'markdown.extensions.attr_list',
         'markdown.extensions.abbr',
        'markdown.extensions.tables']
# 转为 html 文本
html = markdown.markdown(text,extensions=myext)

# 关闭所读取的文件
input_file.close()
# 保存为文件
output_file = codecs.open("some_file.html", mode="w", 
                          encoding="utf-8",errors="xmlcharrefreplace")
output_file.write(html)
output_file.close()

上述将会生成一个名称为some_file的html文件。需要理解上述转换做了什么事。就以上述代码块为例,其转换后的html代码为:

<pre><code class="python">import codecs, markdown

# 读取 markdown 文本

input_file = codecs.open(&quot;some_file.md&quot;, mode=&quot;r&quot;, encoding=&quot;utf-8&quot;)
text = input_file.read()
myext = ['markdown.extensions.fenced_code',  
         'markdown.extensions.attr_list',
         'markdown.extensions.abbr',
        'markdown.extensions.tables']

# 转为 html 文本

html = markdown.markdown(text,extensions=myext)

# 保存为文件

output_file = codecs.open(&quot;some_file.html&quot;, mode=&quot;w&quot;, 
                          encoding=&quot;utf-8&quot;,errors=&quot;xmlcharrefreplace&quot;)
output_file.write(html)
output_file.close()
</code></pre>

可以看到所做的内容就是增加了<pre><code></code></pre>标签,对于文字段落标签为<p></p>,依次类推,相应的能呈现出css样式所确定的格式。当然css样式需要额外添加。

​ 若要添加公式,则需要安装python-markdown-math模块,并采用下述修改后的代码:

import codecs, markdown
from mdx_math import MathExtension
# 读取 markdown 文本

input_file = codecs.open("some_file.md", mode="r", encoding="utf-8")
text = input_file.read()
myext = ['markdown.extensions.fenced_code',
         'markdown.extensions.attr_list',
        'markdown.extensions.abbr',
         'markdown.extensions.tables',
        MathExtension(enable_dollar_delimiter=True)]

# 转为 html 文本
html = markdown.markdown(text,extensions=myext)
# 保存为文件
output_file = codecs.open("some_file.html", mode="w", encoding="utf-8",
                          errors="xmlcharrefreplace")
output_file.write(html)
output_file.close()

在生成的html文件中还需增加以下代码用于显示公式。

<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-MML-AM_CHTML' async>
</script>

上述生成的是直接一个html对象可以通过json格式传递至模板中,如下所示

import codecs, markdown
from mdx_math import MathExtension
import os
# 得到项目根目录
PROJECT_ROOT = os.path.abspath(os.path.dirname('__file__'))

# 在数据库中得到文件markdown文件名
ret = Blog.objects.all()
aa=ret[0]
# 得到文件完整路径
file = PROJECT_ROOT + os.sep.join(['','polls', 'static','markdown',aa.title])+'.md'
input_file = codecs.open(file, mode="r", encoding="utf-8")
text = input_file.read()
myext = ['markdown.extensions.fenced_code',
         'markdown.extensions.attr_list',
        'markdown.extensions.abbr',
         'markdown.extensions.tables',
         'meta',
        MathExtension(enable_dollar_delimiter=True)]
# 转为 html 文本
html = markdown.markdown(text,extensions=myext)
context = {
    'html': html,
}
#把上下文传递到模板里
input_file.close()
return render(request,'polls/text.html',context)

2 添加CSS

​ 上面说到,上述转化后的HTML并没有添加合适的CSS。可以采用如css链接的等专门适用于Markdown的css格式或者网上寻找一个网页模板即可。

3 代码块CSS

​ 不过一般的css并无法高亮代码块,其需要配合专门的的js和css实现。相应也有两种实现方式:

  1. 在上述转化时亦对代码块进行进一步处理,增加 'markdown.extensions.codehilite',其原理是将<pre>标签中添加类<pre class="codehilite">
  2. 采用js控制方式,高亮js链接,相对而言这种方式比较好看

如果需要行号,具体做法可参见https://github.com/wcoder/highlightjs-line-numbers.js/

4 添加本地图片

为了正确的呈现图片,需要做到以下两项。

1)设置本地图片根目录

​ 考虑到在html代码中图片应具有\static\img\pic.jpg之类以static开头的路径,故将本地图片根目录设置为static文件夹上一级。

2) 在扩展项中增加'meta',使输出能忽略YAML(即存储有图片根目录信息)。

main2

可以通过对图片html进行设置来实现缩放。

<img src="/static/img/main2.jpg" alt="main2" style="width:50%;margin-left:25%;margin-right:25%;" />

main2

5 本博客Markdown样式示例

1)标题

四级标题

五级标题
六级标题

2)引用

《春眠》 唐 孟浩然

春眠不觉晓,处处闻啼鸟。

夜来风雨声,花落知多少。

3)列表

无序列

  • Red
  • Green
  • Blue

有序列

  1. Red
  2. Green
  3. Blue

4)任务列表

  • [x] a task list item
  • [ ] list syntax required
  • [x] normal formatting, @mentions, #1234 refs
  • [ ] incomplete
  • [x] completed

5)代码块

​ 需要注意的是对于代码格式的内容是均需作为代码块处理,否则无法正常显示。

6) 表格

First Header Second Header
Content Cell Content Cell
Content Cell Content Cell

7)分割线


8)公式

9)其他

下划线

==高亮==

加粗

6 html代码形式

1)音乐

2)表单

First name:
Last name:

3)css

阴影文字

你好

渐变背景

Lorem Ipsum Dolor

Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.

Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

图片加图名

Norway

The Troll's tongue in Hardanger, Norway

按钮

有些无法在markdown中显示,但能在网页中正常显示。如:

这是一条滚动信息 Ich liebe dich


精选博客

孔壁承压计算的错误

对于高强度承压型螺栓的计算,理论上规范就是有问题的。 (1)《钢结构设计标准》GB50017-2017中11.4.3条并没有规定孔壁承压到底该如何计算,只是在条文说明中提到: (2)从一些计算手册上来看按上述公式计算又有问题。……

继 续 阅 读

关于结构体系

在整理新体系的时候想起一个问题,有几个问题困扰着: (1)多层建筑采用异形柱是会比剪力墙更经济么? (2)一直有个核心筒的概念,那么剪力墙布置成核心筒形式会比剪力墙布置在外部会更好?……

继 续 阅 读

资治通鉴(摘录)

威烈王二十三年(戊寅,公元前四零三年)初命晋大夫魏斯、赵籍、韩虔为诸侯。臣光曰:臣闻天子之职莫大于礼,礼莫大于分,分莫大于名。何谓礼?纪纲是也;何谓分?君臣是也;何谓名?公、侯、卿、大夫是也。夫以四海之广,兆民之众,受制于一人,虽有绝伦之力,高世之智,莫敢不奔走而服役者,岂非以礼为之纲纪哉!是故天子统三公,三公率诸侯,诸侯制卿大夫,卿大夫治士庶人。贵以临贱,贱以承贵。上之使下,犹心腹之运手……

继 续 阅 读