如何在Markdown中链接到同一文档的某个部分?

1149

我正在编写一份大型的Markdown文档,想在开头放置一个目录,以便提供到文档中各个位置的链接。我该如何实现这个目录?

我尝试使用:

[a link](# MyTitle)

其中MyTitle是文档中的标题,但这并没有起作用。


3
R Markdown(Rmd)中的链接请参考https://dev59.com/cGct5IYBdhLWcg3wSbjY#jKPknYgBc1ULPQZF4Av-。 - Etienne Low-Décarie
1
你唯一的问题是MyTitle不应该是一个标题,而应该是文档中锚点的名称(例如<a name="MyTitle"></a>)。然后你就可以在文档的任何地方使用原始链接。 - userfuser
32
大多数人来说,被接受的答案实际上并不相关。请参考下面的第二个答案:https://dev59.com/PnE85IYBdhLWcg3wViE4#16426829 - BrainSlugs83
17个回答

1911

Github会自动解析您标题中的锚点标签。因此,您可以执行以下操作:

[Custom foo description](#foo)

# Foo

在上述情况中,Foo标题已生成一个名称为foo的锚点标签。 注意:所有标题大小仅需一个#,锚点名称前无空格,锚点标签名称必须小写,如果是多个单词则用破折号分隔。
[click on this link](#my-multi-word-header)

### My Multi Word Header

更新

pandoc开箱即用。


161
如果您的标题包含多个单词,例如“像这样的一个”,请在锚点[just](#like-this-one)中使用连字符替换空格。 - Mogsdad
6
这只适用于H1标题吗?如果链接到H2标题(即## Foo),我是否也需要在链接中加入两个井号,即Foo?我无法让您的语法或我的语法正常工作(带有额外的井号)。 - GrayedFox
15
@GrayedFox,如果您想为H2标题## Foo创建链接,请尝试使用此链接:this is my link to Foo……也就是说:只有一个井号,在井号和小写短横线命名的标题之间没有空格。 - Abdull
12
提示:在Github页眉旁边查看显示的锚点以获取相应的链接,即使它包含特殊字符,也会自动删除并显示正确的链接。 - Alexander Pacha
7
当标题有数字时怎么办?

3. 第三点

第三点 不起作用。
- Aditya
显示剩余15条评论

223

这个帖子可能已经过时了,但是要在Github中使用Markdown创建内部文档链接,请使用小写的#title...

# Contents
 - [Specification](#specification) 
 - [Dependencies Title](#dependencies-title) 

## Specification
Example text blah. Example text blah. Example text blah. Example text blah. 
Example text blah. Example text blah. Example text blah. Example text blah. 
Example text blah. Example text blah. Example text blah. Example text blah. 
Example text blah. Example text blah. 

## Dependencies Title
Example text blah. Example text blah. Example text blah. Example text blah. 
Example text blah. Example text blah. Example text blah. Example text blah. 
Example text blah. Example text blah. Example text blah. Example text blah. 
Example text blah. Example text blah. 

有一个好问题,所以我编辑了我的回答;

可以使用 - #, ##, ###, #### 将内部链接与任何标题大小关联起来。我在下面创建了一个快速示例... https://github.com/aogilvie/markdownLinkTest


2
在你的例子中,链接标签只有一个#,但它们所链接到的标题却有两个##;它们不应该是一样的吗? - Karim Bahgat
7
好问题。答案是否定的。(#dependencies-title)中的#符号告诉Github markdown这是一个内部链接。随后的文本可以是任何标题大小写。这里有一个我制作的示例测试...https://github.com/aogilvie/markdownLinkTest。 - Ally
2
这取决于Markdown的版本吗?在Markdown编辑器中似乎可以正常工作,但是当我保存为HTML或PDF时,ID不会添加到相应的标签中。我只需要将锚点放在那里,但是您的方法似乎更清洁和更快。 - meteorainer
这在Github的markdown实现中可能是正确的,但在纯markdown中不受支持(由规范https://daringfireball.net/projects/markdown/syntax#html定义)。在该规范中,标题不会自动创建锚点,因此显式锚点是唯一保证在任何地方都能正常工作的解决方案。 - Steve Powell
1
在 Boostnote 中,它是区分大小写的。 - galian
重要提示:在编程中应使用 kebab-case。 - Bernardo Dal Corno

162

在尝试过程中,我发现可以使用<div…/>来解决问题,但是一个更为明显的解决方案是在页面上放置自己的锚点,例如:

Experimenting, I found a solution using <div…/> but an obvious solution is to place your own anchor point in the page wherever you like, thus:

<a name="abcde">

之前

</a>

在你想要“链接”的行之后。然后使用类似于Markdown格式的链接:

[link text](#abcde)

文档中的任何位置都可以带你到那里。

<div…/>解决方案是插入一个“虚拟”区分来添加id属性,这可能会破坏页面结构,但<a name="abcde"/>解决方案应该是相当无害的。

(附:把锚点放在你想要链接的行里面可能也可以,如下所示:

## <a name="head1">Heading One</a>

但这取决于Markdown如何处理它。例如,我注意到Stack Overflow的答案格式化程序可以很好地处理这个!

但是这还要看Markdown如何处理它。例如,我注意到Stack Overflow的答案格式化程序对此很满意!


2
如果您这样做,应该意识到 div 会剥离其他 Markdown 格式,例如 ## headers - 2rs2ts
7
非常好,谢谢。如果有人想知道,这也适用于托管在GitHub并显示为Markdown文件的情况。 - Alex Dean
6
为了与 HTML5 兼容,我建议将 <a name="head1"/> 替换为 <a id="head1"/> - binki
@binki 要了解我为什么不建议使用 id=,请查看此处的答案:https://dev59.com/KG435IYBdhLWcg3wmxXz#7335259。 - Steve Powell
如果我正确地阅读了HTML5 §5.2.4,并且您的担忧是设置id属性会向Window/JavaScript全局对象添加新的命名属性,我认为<a name="head1"/>将与<a id="head"/>具有相同的问题(即使我测试过的浏览器似乎尚未实现)。 - binki
显示剩余13条评论

43

是的,Markdown可以实现这个功能,但需要指定名称锚点 <a name='xyx'>

下面是一个完整的示例:

创建链接:
[任务](#tasks)

在文档其他位置创建具有指定名称的锚点(无论它叫什么名字)。

<a name="tasks">
   my tasks
</a>

请注意,您也可以将其包装在标题周围。

<a name="tasks">
### Agile tasks (created by developer)
</a>

我尝试过了,它不起作用。 <a> 创建了一个指向无处的链接。 - KansaiRobot
@KansaiRobot 它不会创建一个链接,而是创建一个锚点,可以作为链接的目标。您必须编写一个链接才能访问它。此外,您必须给锚点命名,以便在链接中按名称引用它。 - Steve Powell
这只是一个已经回答过的浅复制。有何不同之处? - hc_dev

35

pandoc 中,如果你使用 --toc 参数来生成 html 文件,将会自动生成一个带有链接的目录,并且在每个小节标题处都有返回目录的链接。这和 pandoc 生成的其他格式(如 LaTeX、rtf、rst 等)类似。因此,使用以下命令:

pandoc --toc happiness.txt -o happiness.html

这是一段 Markdown 代码:

% True Happiness

Introduction
------------

Many have posed the question of true happiness.  In this blog post we propose to
solve it.

First Attempts
--------------

The earliest attempts at attaining true happiness of course aimed at pleasure. 
Soon, though, the downside of pleasure was revealed.

将产生以下内容作为html的主体:

<h1 class="title">
    True Happiness
</h1>
<div id="TOC">
    <ul>
        <li>
            <a href="#introduction">Introduction</a>
        </li>
        <li>
            <a href="#first-attempts">First Attempts</a>
        </li>
    </ul>
</div>
<div id="introduction">
    <h2>
        <a href="#TOC">Introduction</a>
    </h2>
    <p>
        Many have posed the question of true happiness. In this blog post we propose to solve it.
    </p>
</div>
<div id="first-attempts">
    <h2>
        <a href="#TOC">First Attempts</a>
    </h2>
    <p>
        The earliest attempts at attaining true happiness of course aimed at pleasure. Soon, though, the downside of pleasure was revealed.
    </p>
</div>

1
谢谢,这正是我所需要的。我之前一直在使用 Textmate 将 Markdown 转换为 HTML,现在会转向 pandoc。 - recipriversexclusion
1
你可以尝试在Github上使用demo Pandoc tmbundle(也可以使用emacs pandoc-mode等) 。tmbundle重用了MultiMarkdown特定的语法高亮器,因此有一些(非常)奇怪的地方。此外,许多相关脚本都是高度定制的--例如Context而不是LaTeX等--但是想法是用户会根据自己的需要修改它们,这很简单。为了简化集成,应该将其git clone到最低或最外层的tmbundle目录中,即 ~/Library/Application\ Support/TextMate/Bundles - applicative
我想知道在两个具有相同名称的标题的情况下,pandoc会做什么? - Steve Powell
2
它会在第一个id的重复处添加“-1”,在第二个id的重复处添加“-2”,以此类推。 - applicative
8
我发现在pandoc命令中添加--standalone选项可以使它实际输出输出目录表格。如果没有这个开关,它会将标题转换成指向#toc的链接锚点,但不会实际输出锚点和类似列表。 - Duncan Lock
显示剩余2条评论

27

pandoc手册介绍了如何使用标识符链接到标题。我没有检查其他解析器的支持情况,但有报道称在github上无法正常工作

标识符可以手动指定:

## my heading text {#mht}

Some normal text here,
including a [link to the header](#mht).

或者您可以使用自动生成的标识符(在这种情况下为#my-heading-text)。其中两者在pandoc手册中有详细说明。

注意:当转换为HTMLLaTexConTeXtTextileAsciiDoc时,仅限使用此功能。


21

只需遵循[text](#link)语法并遵循以下准则:

  • 按原样编写字母(小写)和数字
  • 用破折号-替换空格
  • 删除其余字符

例如,如果您有以下部分:

# 1. Python

# 2. c++

# 3. c++11

# 4. asp.net-core

您可以使用以下方式添加引用:

[1. Python](#1-python)
[2. c++](#2-c)
[3. c++11](#3-c11)
[4. asp.net-core](#4-aspnet-core)


请注意,asp.net-core 变成了 aspnet-core1. python 变成了 1-python 等等。

20

通用解决方案

根据Markdown的实现方式,这个问题似乎有不同的答案。
实际上,官方的Markdown文档对此没有明确说明。
在这种情况下,如果您需要一个可移植的解决方案,可以使用HTML。

在任何标题之前或同一行的标题中,使用某些HTML标签定义一个ID。
例如:<a id="Chapter1"></a>
您将在代码中看到这个标签,但在呈现的文档中不会显示出来。

完整示例:

这里查看完整示例(在线编辑)。

## Content

* [Chapter 1](#Chapter1)
* [Chapter 2](#Chapter2)

<div id="Chapter1"></div>
## Chapter 1

Some text here.  
Some text here.
Some text here.

## Chapter 2 <span id="Chapter2"><span>

Some text here.  
Some text here.
Some text here.

要测试这个例子,你必须在内容列表和第一章之间添加一些额外的空格或者减小窗口高度。
同时,不要在id名称中使用空格。


嗯...看起来不错。尝试了一下,发现两个问题:(1). ## 第一章 需要在它上面加一行空白行。(2). 链接无法使用... - musicformellons
1
啊,我用的Intellij Markdown插件不起作用;但在Macdown标记编辑器中可以正常工作。 - musicformellons
仍然,在Github上测试过:需要在头部上方打开一行,但它可以工作。 - musicformellons
@musicformellons,您可以尝试删除开头的行,但需要正确闭合span标签吗?<br><span id="Chapter1"><span> - ePi272314
对于我在GitHub上只有空行的方法才有效,这个空行位于<div...##之间。 - dadhi

12

如果你在标题中使用符号并希望进行导航,请记住以下一些额外的事项……

# What this is about


------


#### Table of Contents


- [About](#what-this-is-about)

- [&#9889; Sunopsis](#9889-tldr)

- [:gear: Grinders](#it-grinds-my-gears)

- [Attribution]


------


## &#9889; TLDR


Words for those short on time or attention.


___


## It Grinds my :gear:s


Here _`:gear:`_ is not something like &#9881; or &#9965;


___


## &#9956; Attribution


Probably to much time at a keyboard



[Attribution]: #9956-attribution
#;&: 等字符在标题字符串中通常被忽略或剥离而不是转义,并且可以使用引用样式链接使其更易于使用。

注意事项

GitHub支持在提交、自述文件等中使用:单词:语法,如果对此感兴趣,请参见gist(from rxaviers)。

而对于现代浏览器,几乎所有其他地方都可以使用十进制或十六进制;来自w3schools的速查表非常方便,特别是如果您喜欢使用CSS的::before::after伪元素与符号一起使用。

额外加分?

万一有人想知道如何将图像和其他链接解析为id...

- [Imaged](#alt-textbadge__examplehttpsexamplecom-to-somewhere)


## [![Alt Text][badge__example]](https://example.com) To Somewhere


[badge__example]:
  https://img.shields.io/badge/Left-Right-success.svg?labelColor=brown&logo=stackexchange
  "Eeak a mouse!"

注意事项

MarkDown渲染因地而异,因此诸如...

## methodName([options]) => <code>Promise</code>

在 GitHub 上的页面将会有一个具有类似 id 的元素...

id="methodnameoptions--promise"

... 而 普通的 卫生处理将导致 id 为...

id="methodnameoptions-codepromisecode"

这意味着从模板编写或编译MarkDown文件要么需要针对一种方式进行slugifeing,要么需要添加配置和脚本逻辑以满足各种聪明的方式来清理标题文本。


7
Markdown规范中没有这样的指令。抱歉。

哎呀!你知道MultiMarkdown或Textile是否支持它吗?我在考虑将所有文档迁移到MD,但这是个致命问题。感谢您的帮助! - recipriversexclusion
5
“directive”指令的意思是什么?这里已经发布了其他解决此问题的方法。 - Zelphir Kaltstahl
Markdown规范明确允许HTML标签,所以这是被允许的。而且它能够工作。至少在我上次尝试时是这样。 - Steve Powell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接