Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面。 —— 来自[维基百科]
简单的来说,Markdown就是用“标记符号”表示“格式”。Markdown语法标签与HTML语法标签是一一对应的,比如Markdown的二级标题标签##
就对应着HTML中的<h2>...</h2>
标记,而且Markdown是兼容HTML语法的,如果你比较喜欢 HTML 的 <a>
或 <img>
标签,可以直接在Markdown文档中使用这些标记,而不用 Markdown 提供的链接或是图像标签语法。
CSDN Markdown编辑器是使用StackEdit修改而来的,但在StackEdit的基础上做了一些细节优化,使得体验更加友好,CSDN Markdown支持的功能很多:
在这篇文章,我先介绍CSDN Markdown的基本语法,我会从Markdown语法说明、例子、与其对应的HTML语法、例子效果、注意事项这几个方面进行详细介绍。后面会继续介绍如何插入图片、CSDN Markdown的扩展语法、如何写数学公式和画图等相关的内容。
Markdown 支持两种形式的标题语法:Setext形式和atx形式。
Markdown语法说明:
Setext 形式是采用底线的方式,利用若干个 =
(最高阶标题)和 -
(第二阶标题)完成。
例子:
这是标题1
=============
这是标题2
-------------
对应的HTML语法:
<h1>这是标题1</h1>
<h2>这是标题2</h2>
效果:
注意事项:
这里
#
或-
的数目是任意的,既可以写一个也可以写多个。
Markdown语法说明:
atx 形式则是在行首插入 1 到 6 个 #
,分别对应到标题 1 到 6 阶。
例子:
# 这是标题1
## 这是标题2
### 这是标题3
#### 这是标题4
##### 这是标题5
###### 这是标题6
转化为HTML后分别对应<h1>...<h6>
这6个标记。
效果:
注意事项:
- Setext形式的标题只能表示标题1和标题2这两阶,而atx形式的标题可以表示标题1~标题6共6阶。
- 上面#与文本之间的空格不是必需的,不加也可以,但加上是个好的习惯。
- 你可以选择性地「闭合」atx样式的标题,这纯粹只是美观用的,若是觉得这样看起来比较舒适,你就可以在行尾加上
#
,而行尾的#
数量也不用和开头一样(行首的#
数量决定标题的阶数)。
Markdown语法说明:
Markdown标记区块引用是使用 >
标记,一个段落既可以只用一个 >
标记(放在段首,属偷懒做法),也可以在一个段落的每一行前面加上 >
。
例子:
> 这是一个区块引用。
与上面文本属于一个段落,因此这一行前面可以不加`>`标记。
> 由于上面空了一行,因此这是另一个不同的段落,前面的 `>`必须添加。
>
虽然这也是另一个不同的段落,但上面空行加了 `>`,因此这里段落之前的 `>`也可以省略,相当于上面空行的 `>`属于这个段落。
对应的HTML语法:
<blockquote>
<p>这是一个区块引用。
与上面文本属于一个段落,因此这一行前面可以不加`>`标记。</p>
<p>由于上面空了一行,因此这是另一个不同的段落,前面的 `>`必须 添加。</p>
<p>虽然这也是另一个不同的段落,但上面空行加了 `>`,因此这里段落之前的 `>`也可以省略,相当于上面空行的 `>`属于这个段落。</p>
</blockquote>
效果:
这是一个区块引用。
与上面文本属于一个段落,因此这一行前面可以不加>
标记。由于上面空了一行,因此这是另一个不同的段落,前面的
>
必须添加。虽然这也是另一个不同的段落,但上面空行加了
>
,因此这里段落之前的>
也可以省略,相当于上面空行的>
属于这个段落。
注意事项:
区块引用可以嵌套使用,即引用内的引用,只要根据层次加上不同数量的 >
即可,比如两层就需要两个>
:
> 这是区块引用的第一层。
>
> > 这是嵌套引用,属于第二层,因此需要再加一个`>`,两个`>`之间的空格不是必需的。
>
> 回到区块引用的第一层。
效果为:
这是区块引用的第一层。
这是嵌套引用,属于第二层,因此需要再加一个
>
,两个>
之间的空格不是必需的。回到区块引用的第一层。
引用的区块内也可以使用其他的Markdown语法,包括标题、列表、代码块等:
> ## 这是一个标题。
>
> 1. 这是第一个列表项。
> 2. 这是第二个列表项。
>
> 这是一个代码例子:
>
> printf("Hello, Minmin!\n"); return 0;
效果为:
这是一个标题。
- 这是第一个列表项。
- 这是第二个列表项。
这是一个代码例子:
printf("Hello, Minmin!\n"); return 0;
Markdown语法说明:
你可以在一行中用三个或以上的星号*
、减号-
、底线_
来建立一个分隔线,行内不能有其他东西。你也可以在星号或是减号中间插入空格。下面每种写法都可以建立一条分隔线。
例子:
* * *
***
*****
- - -
---------------------------------------
对应的HTML语法:
<hr />
效果:
注意事项:
从上面例子可以看出,三个以上的标记之间允许存在空格,而且这三种标记可以混用,只要三种数量加起来大于等于3即可,比如下面这样:
**--
-*_***--_
我们知道在HTML中起到强调作用的有两个标签:<em>
和<strong>
,关于两者的区别可以自行Google或看这篇文章「em和strong的区别」,Markdown中也有这两种强调效果,使用的是星号*
和底线_
这两种标记。
Markdown语法说明:
*
或 _
来包围词句,相当于用 <em>
标签包围(内部就是这样转化的);*
或 _
包起来的话,则相当于使用 <strong>
。例子:
*使用一个星号的强调*
_使用一个 底线 的强调_
**使用两个星号的强调**
__使用两个底线 的强调__
对应的HTML语法:
<em>使用一个星号的强调</em>
<em>使用一个底线的强调</em>
<strong>使用两个星号的强调</strong>
<strong>使用两个底线的强调</strong>
效果:
使用一个星号的强调
使用一个底线的强调
使用两个星号的强调
使用两个底线 的强调
注意事项:
- 这里的
**
和__
两个相同的符号中间不能留有空白,否则它们就只会被当成普通的符号。- 注意
<em>
式的强调在不同的编辑器或浏览器里可能显示效果不一样,有的通过斜体来强调,有的通过下划点线来强调。
Markdown 支持有序列表和无序列表两种,且列表可以嵌套使用。
Markdown语法说明:
无序列表使用星号、加号或是减号作为列表标记,使用方法如下:
一个星号 / 一个加号 / 一个减号 + 若干个空格 + 列表项内容
例子:
* 条目1
* 条目2
* 条目3
这等同于:
+ 条目1
+ 条目2
+ 条目3
也等同于:
- 条目1
- 条目2
- 条目3
对应的HTML语法:
<ul>
<li>条目1</li>
<li>条目2</li>
<li>条目3</li>
</ul>
效果:
Markdown语法说明:
有序列表则直接使用数字作为列表标记,使用方法如下:
一个数字 + 一个英文句点 + 若干个空格 + 列表项内容
例子:
1. 第1点描述
2. 第2点描述
3. 第3点描述
对应的HTML语法:
<ol>
<li>第1点描述</li>
<li>第2点描述</li>
<li>第3点描述</li>
</ol>
效果:
(1)从有序列表所对应的HTML语法格式可以看出,你在有序列表标记上使用的数字并不会影响最终的按序输出,即如果你的列表标记写成:
1. 第1点描述
1. 第2点描述
1. 第3点描述
或甚至是:
4. 第1点描述
2. 第2点描述
9. 第3点描述
都会得到与上面完全相同的输出,你可以完全不用在意数字的正确性。
(2)列表标记后面一定要接着至少一个空格或制表符,否则就是普通的文本而非列表了,即下面的写法是列表不支持的:
*条目1
*条目2
*条目3
(3)如果列表条目间用空行分开,那么在输出时两个条目之间也会有一个空行,而且若有多个条目,只要其中有一个空行,输出结果时所有条目之间都会出现空行,保持一致性。比如:
* 条目1
* 条目2
* 条目3
输出效果为:
条目1
条目2
(4)每个列表条目下都可以包含多个段落,但这些段落都必须缩进 4 个空格或 1 个制表符:
1. 这是一个有两个段落的列表项,这是第一段。
这是第二段,段首已经缩进 4 个空格或 1 个制表符,否则就处在列表之外,自成一个普通段落,下面的列表条目也将自成另一个不同的列表,序号从1开始。
2. 这是列表的第二个条目。
效果为:
这是一个有两个段落的列表条目,这是第一段。
这是第二段,段首已经缩进 4 个空格或 1 个制表符,否则就处在列表之外,自成一个普通段落,下面的列表条目也将自成另一个不同的列表,序号从1开始。
这是列表的第二个条目。
(5) 如果要在列表条目内放进引用,那 >
就需要缩进:
* 含有引用的列表项,下面是引用元素:
> 这是一条引用。
> 前面需要缩进4个空格或1个制表符,跟段落一样。
效果为:
含有引用的列表条目,下面是引用元素:
这是一条引用。
前面需要缩进4 个空格或 1 个制表符,跟段落一样。
(6)如果要在列表项内放代码区块的话,该区块就需要缩进两次,也就是8个空格或是2个制表符:
* 含有代码块的列表项:
#include <stdio.h>
int main(void) {
printf("Hello, Minmin!\n");
return 0;
}
}
效果为:
含有代码块的列表项:
#include <stdio.h>
int main(void) {
printf("Hello, Minmin!\n");
return 0;
}
}
(7)避免产生不必要的列表项。
有时候,列表很可能会不小心产生,比如下面这样的写法:
1986. 这不是一个列表项。
也会产生一个下面这样的列表:
换句话说,也就是在行首出现数字-句点-空白,要避免这样的状况,你可以在句点前面加上反斜杠,具体可以查看后面的「反斜杠的用处 」一节。
1986\. 这不是一个列表项。
这样就对了:
1986. 这不是一个列表项。
Markdown的链接可分为自动链接和普通文本链接两种类型。
Markdown支持以比较简短的自动链接形式来处理网址和电子邮件信箱。
Markdown语法说明:
对于本身是个URL和Email的文本来说,只要是用尖括号包起来,Markdown就会自动把它转成链接。
例子:
这是一个可点击的URL:
<http://www.csdn.net/>
这是一个可点击的Email:
<address@example.com>
对应的HTML语法:
对于上面普通的URL,Markdown会转成下面的HTML语法:
<a href="http://www.csdn.net/">http://www.csdn.net/</a>
而对于Email的自动链接也很类似,只是Markdown会先做一个编码转换的过程,把文字字符转成 16 进位码的 HTML 实体,这样的格式可以糊弄一些不好的邮址收集机器人,例如对于上面的Email,Markdown 会转成:
<a href="mailto:addre ss@example.co
m">address@exa
mple.com</a>
在浏览器里面,这段字串会最终转成下面的HTML语法:
address@example.com
效果:
这是一个可点击的URL:
http://www.csdn.net/
这是一个可点击的Email:
address@example.com
注意事项:
对于邮件的自动链接,使用Markdown语法虽然可以糊弄不少的机器人,但并不能全部挡下来,不过总比什么都不做好些。不管怎样,公开你的信箱终究会引来广告信件的。
Markdown支持两种形式的普通文本链接语法: 行内式和参考式两种形式。
Markdown语法说明:
下面三种语法形式都是允许的:
[链接文字](链接URL '可选的链接title')
[链接文字](链接URL "可选的链接title")
[链接文字](链接URL (可选的链接title))
详细说明就是:
例子:
更多精彩的内容,可以访问[敏敏的CSDN博客](http://blog.csdn.net/lanxuezaipiao/ "敏敏的博客")(有title属性) 。
想更多的了解敏敏,可以访问[敏敏的新浪微博](http://weibo.com/lanxuezaipiao/) (无title属性)。
对应的HTML语法:
<p>更多精彩的内容,可以访问 <a href="http://blog.csdn.net/lanxuezaipiao/" title="敏敏的博客">敏敏的CSDN博客</a>(有title属性) 。</p>
<p>想更多的了解敏敏,可以访问<a href="http://weibo.com/lanxuezaipiao/">敏敏的新浪微博</a> (无title属性)。</p>
* 效果:*
更多精彩的内容,可以访问敏敏的CSDN博客 (有title属性)。
想更多的了解敏敏,可以访问敏敏的新浪微博 (无title属性)。
注意事项:
如果你是要链接到同一个主机的资源,可以使用相对路径,例如:
想要进一步了解,请访问 [About](/about/) 页。
Markdown语法说明:
[链接文字][链接id]
[链接id]: 真正的链接URL "可选的title"
可以发现参考式的链接中链接文字的后面不是一个圆括号而是另一个方括号,在该方括号里面要填入用以辨识链接的标记,注意两个方括号之间允许有空格,接着,在文档的任意处,你可以把这个标记的链接内容定义出来。
链接内容定义的形式为:
例子:
想知道敏敏都读过哪些书、看过哪些电影吗?请进入[敏敏的豆瓣][id]来了解下吧。
[id]: http://www.douban.com/people/44971294/ "敏敏的豆瓣"
对应的HTML语法:
<p>想知道敏敏都读过哪些书、看过哪些电影吗?请进入<a href="http://blog.csdn.net/lanxuezaipiao/" title="敏敏的豆瓣">敏敏的豆瓣</a>来了解下吧。</p>
效果:
想知道敏敏都读过哪些书、看过哪些电影吗?请进入敏敏的豆瓣来了解下吧。
注意事项:
(1)有一个已知的问题是 Markdown.pl 1.0.1 会忽略单引号包起来的链接 title,因此大家在使用时尽量选择用双引号或括弧,避免出错。
(2) 链接网址也可以用尖括号包起来,如:
[id]: <http://www.douban.com/people/44971294/> "敏敏的豆瓣"
(3)你也可以把 title 属性放到下一行,也可以加一些缩进,若网址太长的话,这样会比较好看:
[id]: http://blog.csdn.net/lanxuezaipiao/article/details/42554035
"敏敏的2014年总结"
(4)网址定义只有在产生链接的时候用到,并不会直接出现在文件之中,如上面的效果中没有出现[id]:
这样的网址定义。
(5)链接辨别标签可以有字母、数字、空白和标点符号,但是并不区分大小写,因此下面两个链接是一样的:
[链接文本][a]
[链接文本][A]
(6)还有一种隐式链接标记功能,可以让你省略指定链接标记,这种情形下,链接标记会视为等同于链接文字,要用隐式链接标记只要在链接文字后面加上一个空的方括号,如果你要让 “Google” 链接到 google.com,你可以简化成:
[Google][]
然后定义链接内容:
[Google]: http://google.com/
(7)链接的定义可以放在文件中的任何一个地方,我比较偏好直接放在链接出现段落的后面,你也可以把它放在文件最后面,就像是注解一样。
下面给出一个综合性的范例,来比较下这几种链接方式的差异:
采用行内式链接的方式:
我经常逛的网站或社区有: [CSDN](http://www.csdn.net/ "CSDN")、[知乎] (http://www.zhihu.com/ "知乎")还有[豆瓣](http://www.douban.com/ "豆瓣")。
采用参考式链接的方式:
我经常逛的网站或社区有: [CSDN] [1]、[知乎] [2] 还有[豆瓣] [3]。
[1]: http://www.csdn.net/ "CSDN"
[2]: http://www.zhihu.com/ "知乎"
[3]: http://www.douban.com/ "豆瓣"
采用链接名称的方式:
我经常逛的网站或社区有: [CSDN] []、[知乎] [] 还有[豆瓣] []。
[csdn]: http://www.csdn.net/ "CSDN"
[知乎]: http://www.zhihu.com/ "知乎"
[豆瓣]: http://www.douban.com/ "豆瓣"
上面三种写法产生的效果都一样:
那么现在一个问题来了:这三种写法到底该如何选用呢?哪种写法最好?
我个人认为这是自己的喜好问题,你看哪个写的舒服就选用哪个方法?不过从官方来看,较推荐参考式的链接写法。参考式的链接其实重点不在于它比较好写,而是它比较好读,比较一下上面的范例,使用参考式的文章本身读起来很简洁(因为链接标记单独成段了),但是用行内形式的看起来就很臃肿,还容易看错。
使用 Markdown 的参考式链接,可以让文件更像是浏览器最后产生的结果,让你可以把一些标记相关的元数据移到段落文字之外,你就可以增加链接而不让文章的阅读感觉被打断。
关于Markdown的代码语法,下面分为行内代码和代码区块两类来说明。
Markdown语法说明:
如果要标记一小段行内代码,你可以用反引号(就是跟~
在一起的那个按键)把它包起来(`
)即可:
`你要标记的行内代码`
例子:
让我们看看`printf()` 函数有哪些参数。
对应的HTML语法:
<p>让我们看看<code>printf()</code> 函数有哪些参数。</p>
效果:
让我们看看printf()
函数有哪些参数。
注意事项:
如果要在行代码段内插入反引号,你可以用多个反引号来开启和结束代码段:
这是一个反引号 (`)。
就能正常输出反引号:
这是一个反引号 (`)。
如果要在代码段的起始处或结尾处插入一个正常的反引号,这时会有连续三个反引号连在一块的情况,且达不到想要的效果。这时就需要在代码段的起始和结束端各放入一个空白,起始端后面一个,结束端前面一个,例如:
这是代码片段中的反引号:`
这样就能产生想要的效果:
这是代码片段中的反引号:`
和程序相关的写作通常会有已经排版好的代码区块,通常这些区块我们并不希望它以一般段落文件的方式去排版(如果用一般段落的方式那么段首所有的空格都被消除了),而是照原来的样子显示,Markdown 会用 <pre>
和 <code>
标签来把代码区块包起来。
Markdown语法说明:
要在 Markdown 中建立代码区块很简单,只要简单地缩进 4 个空格或是 1 个制表符就可以。
例子:
这是一个普通段落:
这是一个代码区块。
对应的HTML语法:
<p>这是一个普通段落:</p>
<pre><code>这是一个代码区块。
</code></pre>
这个每行一阶的缩进(4 个空格或是 1 个制表符),都会被移除,举一个具体的代码实例。
例子:
下面是一个简单的Java实例:
public class Test{
public static void main (String[] args){
System.out.println("欢迎访问lanxuezaipiao!");
}
效果:
下面是一个简单的Java实例:
public class Test{
public static void main (String[] args){
System.out.println("欢迎访问lanxuezaipiao!");
}
注意事项:
在代码区块中,一般的 Markdown 语法不会被转换,像是星号便只是星号,即用两个星号将一句话包围起来也不会转化为强调,这表示你可以很容易地以 Markdown 语法撰写 Markdown 语法相关的文件,不用担心代码中包含一些特殊的Markdown语法标记。
Markdown可以利用反斜杠来插入一些在语法中有其它意义的符号,例如:如果你想要用星号加在文字旁边的方式来做出强调效果,你可以在星号的前面加上反斜杠:
\*重点描述文本\*
效果就是:*重点描述文本*
Markdown支持以下这些符号前面加上反斜杠来帮助插入普通的符号而非Markdown语法标签:
\ 反斜线
` 反引号
* 星号
_ 底线
{} 花括号
[] 方括号
() 括弧
# 井号
+ 加号
- 减号
. 英文句点
! 惊叹号
问题1:Markdown如何添加多个空行?
我们知道Markdown的段落是由前后各一个空行形成,人为的添加多个空行会被Markdown语法自动忽略仅剩一个空行,这是比较人性化的,因为不需要人为删除一些多余的空行了。但两个段落之间也有需要多个空行的情况,比如上面给出一些谜题,谜底一般放在最下面,中间需要大部分的留白,这时候就需要借助HTML换行标签来达到这个目的了(前面已经提过Markdown语法是兼容HTML的):即在需要空行的地方插入 <br />
标签或 <p>
标签。
大家如果有其它任何问题,可以在下面留言,我会将大家提问的问题都整理到这里来。