Markdown 并包含多个文件

Posted

技术标签:

【中文标题】Markdown 并包含多个文件【英文标题】:Markdown and including multiple files 【发布时间】:2011-06-14 08:31:16 【问题描述】:

是否有任何 Markdown fork 允许您引用其他文件,例如包含文件?具体来说,我想创建一个单独的降价文件,其中包含我经常但不总是调用的链接(称为 B.md),然后当我在我正在编写的 md 文件(A.md)中通过引用链接时,我会喜欢从另一个文件(B.md)而不是从当前文件(A.md)的末尾提取链接。

【问题讨论】:

如果你的问题是github相关的markdown,你可以看看here Markdown 的经验法则是“可以 Markdown...”的答案通常是“不实用、不普遍或不容易”。 在github.com/jgm/pandoc/issues/553 和 commonmark 论坛talk.commonmark.org/t/… 上公开讨论如何最好地使用 Pandoc 进行此操作 【参考方案1】:

简短的回答是否定的。长答案是肯定的。 :-)

Markdown 旨在让人们编写简单易读的文本,这些文本可以轻松转换为简单的 html 标记。它并没有真正做文档布局。例如,没有真正的方法可以将图像向右或向左对齐。至于您的问题,在任何版本的降价中(据我所知)都没有降价命令可以包含从一个文件到另一个文件的单个链接。

您最接近此功能的是Pandoc。 Pandoc 允许您将文件合并为转换的一部分,这使您可以轻松地将多个文件渲染到单个输出中。例如,如果您正在创建一本书,那么您可以有这样的章节:

01_preface.md
02_introduction.md
03_why_markdown_is_useful.md
04_limitations_of_markdown.md
05_conclusions.md

您可以通过在同一目录中执行此命令来合并它们:

pandoc *.md > markdown_book.html

由于 pandoc 会在翻译之前合并所有文件,因此您可以将链接包含在最后一个文件中,如下所示:

01_preface.md
02_introduction.md
03_why_markdown_is_useful.md
04_limitations_of_markdown.md
05_conclusions.md
06_links.md

所以您的01_preface.md 的一部分可能如下所示:

I always wanted to write a book with [markdown][mkdnlink].

您的02_introduction.md 的一部分可能如下所示:

Let's start digging into [the best text-based syntax][mkdnlink] available.

只要您的最后一个文件包含以下行:

[mkdnlink]: http://daringfireball.net/projects/markdown

...之前使用的相同命令将执行合并和转换,同时包含该链接。只要确保在该文件的开头留下一两行空行即可。 pandoc documentation 说它在以这种方式合并的文件之间添加了一个空行,但是如果没有空行,这对我不起作用。

【讨论】:

这对我来说是一个非常有用的帖子!谢谢亚伦。一个常见的用例似乎是有一个 /chapters 目录,一个构建/合并章节的脚本,然后是一个包含如下步骤的***包装脚本:--include-before-body $(include_dir)/merged_chapters .html。这就是我将采取的方法来获得一些组织利益。 使用 pandoc 的另一个优点是它支持种类繁多的输出:您不仅可以生成 HTML,还可以生成从 docx 到 LaTeX 再到 ePUB 的所有内容。 pandoc *.md > markdown_book.html 结果为 pandoc: *.md: openfile: invalid argument (Invalid argument) - 它似乎不支持您指定的语法。 它正在我的系统上运行。我创建了一个sample repository on GitHub,因此您可以尝试使用我使用的所有文件。 我在 Windows 上也收到了 pandocc 2.2.1 的 invalid argument 错误。我必须明确列出文件:pandoc.exe 01_preface.md 02_introduction.md 03_why_markdown_is_useful.md 04_limitations_of_markdown.md 05_conclusions.md -s -o mybook.html【参考方案2】:

我只想提一下,您可以使用cat 命令连接输入文件,然后再将它们传送到markdown_py,这与pandoc 处理多个输入文件的效果相同。

cat *.md | markdown_py > youroutputname.html

在我的 Mac 上运行 Python 版本的 Markdown 与上面的 pandoc 示例几乎相同。

【讨论】:

@tprk77:除了 Aaron 的回答清楚地表明 cat 命令在这里是多余的.. cat *.md 的使用意味着不灵活的文件命名约定。该约定不仅必然禁止递归包含,而且对于较大的文档项目,将新文件添加到混合中会很痛苦。您将不得不做很多计数和重命名。自 2010 年以来,降价项目就为此目的配备了预处理器。 @ninegrid 虽然 MarkdownPP 看起来非常有用,但从您在回答中引用的源代码库来看,在我看来(a)MarkdownPP 只是 John Reese 的项目; (b)它根本不是“降价项目”(任何各种口味)的一部分; (c) MarkdownPP 具体输出 GFM。正确的?正如我所说,它看起来很有趣且很有帮助,但是您在这里的评论听起来像是每个 Markdown 实现都应该附带的标准 Markdown 功能。但从 repo 来看,情况似乎完全相反。 将 MD 表转换为 HTML 表失败。【参考方案3】:

您实际上可以使用 Markdown 预处理器 (MarkdownPP)。使用其他答案中的假设书籍示例运行,您将创建代表您的章节的 .mdpp 文件。然后.mdpp 文件可以使用!INCLUDE "path/to/file.mdpp" 指令,该指令以递归方式将指令替换为最终输出中引用文件的内容。

chapters/preface.mdpp
chapters/introduction.mdpp
chapters/why_markdown_is_useful.mdpp
chapters/limitations_of_markdown.mdpp
chapters/conclusions.mdpp

然后您需要一个包含以下内容的index.mdpp

!INCLUDE "chapters/preface.mdpp"
!INCLUDE "chapters/introduction.mdpp"
!INCLUDE "chapters/why_markdown_is_useful.mdpp"
!INCLUDE "chapters/limitations_of_markdown.mdpp"
!INCLUDE "chapters/conclusions.mdpp"

要渲染您的图书,您只需在 index.mdpp 上运行预处理器:

$ markdown-pp.py index.mdpp mybook.md

不要忘记查看MarkdownPP 存储库中的readme.mdpp,了解适用于大型文档项目的预处理器功能。

【讨论】:

【参考方案4】:

就在最近,我在 Node 中写了类似的东西,名为 markdown-include,它允许您包含具有 C 样式语法的 markdown 文件,如下所示:

#include "my-file.md"

我相信这与您提出的问题非常吻合。我知道这是一个旧的,但我至少想更新它。

您可以将其包含在您希望的任何降价文件中。该文件还可以包含更多包含,并且 ma​​rkdown-include 将创建一个内部链接并为您完成所有工作。

您可以通过npm下载它

npm install -g markdown-include

【讨论】:

这很有帮助!谢谢! @leas 很高兴为您服务...我已经有好几年没做这件事了,但我总是想在某个时候回到它。希望它对您的目的有好处。 如果它只是作为一个独立的 cli 工作,那就太棒了。给它一个文档,它会根据项目定义的令牌语法进行替换。【参考方案5】:

我在 Mac OS X 上使用 Marked 2。它支持以下语法来包含其他文件。

<<[chapters/chapter1.md]
<<[chapters/chapter2.md]
<<[chapters/chapter3.md]
<<[chapters/chapter4.md]

遗憾的是,您无法将其提供给 pandoc,因为它不理解语法。然而,编写一个脚本来去除语法以构建一个 pandoc 命令行是很容易的。

【讨论】:

你会不会碰巧有脚本而不是说它很简单? :)【参考方案6】:

事实上你可以使用\inputfilename\includefilename,它们是latex命令, 直接在Pandoc 中,因为它几乎支持所有htmllatex 语法。

但请注意,包含的文件将被视为latex 文件。但是您可以使用Pandox 轻松地将markdown 编译为latex

【讨论】:

【参考方案7】:

我的解决方案是使用 m4。它在大多数平台上都受支持,并且包含在 binutils 包中。

首先在文件中包含一个宏changequote() 以将引号字符更改为您喜欢的字符(默认为`')。处理文件时删除宏。

changequote(`', `')
include(other_file)

在命令行上:

m4 -I./dir_containing_other_file/ input.md > _tmp.md
pandoc -o output.html _tmp.md

【讨论】:

m4 鲜为人知,但是当涉及到这种通用的包含需求时,它确实是一个非常强大的工具。足以让文档提及它可能“相当令人上瘾”。 现在,that 是一个解决方案!天才 +1 为 m4 的想法和提醒!有趣的是,当我看到上面的扩展名是“md”时,我脑子里在想m4。然后,您将包含一个示例,这很棒。我不确定这个问题是否确切地问到我在追求什么,但它可能会。不管怎样,谢谢。【参考方案8】:

我认为我们最好采用新的文件包含语法(这样就不会搞砸了 代码块,我认为C风格的包含是完全错误的),我用Perl写了一个小工具,命名为cat.pl, 因为它cat一样工作(cat a.txt b.txt c.txt 将合并三个 文件),但它会合并文件深度,而不是宽度。如何使用?

$ perl cat.pl <your file>

详细语法是:

递归包含文件:@include &lt;-=path= 只包括一个:%include &lt;-=path=

它可以正确处理文件包含循环(如果a.txt

例子:

a.txt:

a.txt

    a <- b

    @include <-=b.txt=

a.end

b.txt:

b.txt

    b <- a

    @include <-=a.txt=

b.end

perl cat.pl a.txt &gt; c.txt, c.txt:

a.txt

    a <- b

    b.txt

        b <- a

        a.txt

            a <- b

            @include <-=b.txt= (note:won't include, because it will lead to infinite loop.)

        a.end

    b.end

a.end

更多示例请访问https://github.com/district10/cat/blob/master/tutorial_cat.pl_.md。

我还写了一个Java版本,效果一样(不一样,但很接近)。

【讨论】:

&lt;&lt;[include_file.md](在 macOS 上标记为 2):gist.github.com/district10/d46a0e207d888d0526aef94fb8d8998c 请注意,@ 用于引用 pandoc-citeproc(例如“@Darwin1859”)。【参考方案9】:

我使用includes.txt 文件,其中所有文件的顺序都正确 我像这样执行pandoc:

pandoc -s $(cat includes.txt) --quiet -f markdown -t html5 --css pandoc.css -o index.html

像魅力一样工作!

【讨论】:

好方法。指定文件顺序是基本的,但除非您对文件进行编号,否则无法使用 glob 方法完成。 您能否解释一下这些步骤?看起来好强大!我想知道是否可以将其修剪以进行其他转换,例如 .pdf 和 .tex。【参考方案10】:

Asciidoc 实际上是对类固醇的降价。总的来说,Asciidoc 和 Markdown 看起来非常相似,而且切换起来相当容易。 Asciidoc 相对于 markdown 的一个巨大优势是它已经支持包含其他 Asciidoc 文件以及您喜欢的任何格式。您甚至可以根据包含文件中的行号或标签部分包含文件。

在编写文档时,包含其他文件确实可以挽救生命。

例如,您可以拥有一个包含此类内容的 asciidoc 文件:

// [source,perl]
// ----
// include::script.pl[]
// ----

并将您的样本保存在script.pl

我相信你会想知道,是的,Github 也支持 asciidoc。

【讨论】:

这里似乎有一个很好的承诺,但没有给出完整的操作步骤答案。是否可以说明如何将多文件文档转换为单个文档? 这是迄今为止此页面上最好的解决方案。我得出了这个结论并解决了这个问题here on Reddit。 AsciiDoc 有内置的包含,它由 GitHub 呈现。 Atom 和 vscode 都有不错的实时预览插件。我想知道为什么 AsciiDoc 还不是行业标准!【参考方案11】:

Multimarkdown 本身就有这个。它称之为file transclusion:

some_other_file.txt

就是这样。奇怪的名字,但勾选了所有的框。

【讨论】:

是否有任何免费和开源的编辑器来呈现这种语法?我已经问了这个问题here 并提供了更多详细信息。如果您能帮助我,我将不胜感激。 @Foad:恐怕我是 vim 用户,不知道有任何此类编辑器。我在您的 reddit Q 上看到您发现 Asciidoc 和各种编辑器支持这一点。我不知道 - 谢谢。 很高兴它很有用。但是 vim 有 MultiMarkDown 的实时预览吗?您愿意分享您的设置和点文件并提供更多详细信息吗? 没有实时预览,我不是那种人。 ;) 我完全使用 markdown 的主要原因是因为它的目标是在 not 处理时是人类可读的,所以我真的不太介意预览(尽管我理解其他人为什么这样做)。在这种情况下,我唯一感兴趣的是语法突出显示,默认的 markdown 语法突出显示对我来说已经足够好了。很抱歉没有提供更多帮助。 看起来它可能很有趣,尽管我认为没有理由至少为了我的(微不足道的)目的而选择它而不是 markdown/asciidoc。【参考方案12】:

恕我直言,您可以通过连接输入 *.md 文件来获得结果,例如:

$ pandoc -s -o outputDoc.pdf inputDoc1.md inputDoc2.md outputDoc3.md

【讨论】:

任何给-1的人,请添加评论。【参考方案13】:

我真的很惊讶这个页面上没有人提供任何 HTML 解决方案。据我所知,MarkDown 文件可以包含大部分(如果不是全部)HTML 标记。所以请按照以下步骤操作:

    来自here:将您的MarkDown 文件放在&lt;span style="display:block"&gt; ... &lt;/span&gt; 标记中,以确保它们将呈现为降价。您可以添加许多其他样式属性。我喜欢的是text-align:justify

    来自here:使用&lt;iframe src="/path/to/file.md" seamless&gt;&lt;/iframe&gt;将文件包含在主文件中

P.S.1.此解决方案不适用于所有 MarkDown 引擎/渲染器。例如,Typora 确实正确渲染了文件,但 Visual Studio Code 没有。如果其他人可以与其他平台分享他们的经验,那就太好了。特别想听听有关 GitHub 和 GitLab 的信息...

P.S.2. 在进一步调查中,似乎存在重大的不兼容问题,导致在包括 Typora、GitHub 和 Visual Studio 代码在内的许多平台上无法正确呈现。在我解决它们之前,请不要使用它。我不会仅仅为了讨论而删除答案,如果您可以分享您的意见。

P.S.3. 为了进一步调查这个问题,我问了这个问题here on *** 和here on Reddit。

P.S.4. 经过一番研究,我得出的结论是,目前 AsciiDoc 是一个更好的文档选择。它带有内置的包含功能,由 GitHub 渲染,Atom 和 vscode 等主要代码编辑器具有用于实时预览的扩展。可以使用 Pandoc 或其他工具将现有的 MarkDown 代码自动转换为 AsciiDoc,只需稍作更改。

P.S.5.另一种具有内置包含功能的轻量级标记语言是reStructuredText。它带有标准的.. include:: inclusion.txt 语法。 ReText editor 也有实时预览。

【讨论】:

【参考方案14】:

我知道这是一个老问题,但我还没有看到任何答案:本质上,如果您使用 markdown 和 pandoc 将文件转换为 pdf,请在页面顶部的 yaml 数据中,你可以包括这样的东西:

---
header-includes:
- \usepackagepdfpages
output: pdf_document
---

\includepdf/path/to/pdf/document.pdf

# Section

Blah blah

## Section 

Blah blah

由于 pandoc 使用 Latex 转换您的所有文档,header-includes 部分调用 pdfpages 包。然后,当您包含 \includepdf/path/to/pdf/document.pdf 时,它将插入该文档中包含的任何内容。此外,您可以通过这种方式包含多个 pdf 文件。

作为一个有趣的奖励,这只是因为我经常使用降价,如果你想包含降价以外的文件,例如乳胶文件。我已经稍微修改了这个answer。假设你有一个markdown文件markdown1.md:

---
title: Something meaning full
author: Talking head
---

还有两个额外的乳胶文件 document1,看起来像这样:

\sectionSection

Profundity.

\subsectionSection

Razor's edge.

另一个,document2.tex,看起来像这样:

\sectionSection

Glah

\subsectionSection

Balh Balh

假设您想将 document1.tex 和 document2.tex 包含到 markdown1.md 中,您只需对 markdown1.md 执行此操作

---
title: Something meaning full
author: Talking head
---

\input/path/to/document1
\input/path/to/document2

在它上面运行 pandoc,例如

在终端pandoc markdown1.md -o markdown1.pdf

您的最终文档将如下所示:

有意义的事情

会说话的头

部分

深度。

部分

剃刀的边缘。

部分

格拉赫

部分

呸呸呸

【讨论】:

很好的解决方案!我将 pandoc 用于严肃的文件并将使用它。【参考方案15】:

另一个使用markdown-it 和jQuery 的基于HTML 的客户端解决方案。下面是一个作为主文档的小型 HTML 包装器,它支持无限包含 markdown 文件,但不支持嵌套包含。 JS cmets 中提供了解释。省略了错误处理。

<script src="/markdown-it.min.js"></script>
<script src="/jquery-3.5.1.min.js"></script>

<script> 
  $(function() 
    var mdit = window.markdownit();
    mdit.options.html=true;
    // Process all div elements of class include.  Follow up with custom callback
    $('div.include').each( function() 
      var inc = $(this);
      // Use contents between div tag as the file to be included from server
      var filename = inc.html();
      // Unable to intercept load() contents.  post-process markdown rendering with callback
      inc.load(filename, function () 
        inc.html( mdit.render(this.innerHTML) );
      );
  );
)
</script>
</head>

<body>
<h1>Master Document </h1>

<h1>Section 1</h1>
<div class="include">sec_1.md</div>
<hr/>
<h1>Section 2</h1>
<div class="include">sec_2.md</div>

【讨论】:

【参考方案16】:

vscode-markdown-preview-enhanced 支持 @import 语法

https://github.com/shd101wyy/vscode-markdown-preview-enhanced

这可能意味着它是底层工具 mume 的一部分

https://github.com/shd101wyy/mume

以及其他基于 mume 构建的工具

https://github.com/gabyx/TechnicalMarkdown

【讨论】:

【参考方案17】:

如果您使用pandoc 进行降价处理,则还没有原生解决方案(在https://github.com/jgm/pandoc/issues/553 中讨论),除非在调用pandoc 时使用多个输入降价文件。

但是,使用codebraid(实际上是为了将自动生成的内容包含到 Markdown 中)可以实现:

This is the content of the main Markdown file `main.md`. 
Below this line, the content of the file `chapter01.md` is included:

```.python .cb.run
with open('chapter01.md') as fp:
    print(fp.read())
```

This line is printed below the external content.

要将其转换为任何输出格式,请使用以下内容:

codebraid pandoc main.md --to markdown

虽然 codebraid 可能被认为“仅仅”包含外部 Markdown 文件是多余的,但它允许更多,例如比如包括来自外部来源的 CSV 或 Excel 表格:

Details are shown in the following table:

```.python .cb.run
import pandas as pd
table = pd.read_csv('table.csv')
print(talbe.to_markdown())
```

【讨论】:

以上是关于Markdown 并包含多个文件的主要内容,如果未能解决你的问题,请参考以下文章

前端学Markdown

前端学Markdown

markdown 100%浏览器并包含div高度

使用脚本将多个目录中的多个 Markdown 文件转换为 HTML

markdown SSH Config文件多个服务器dengan多个密钥

markdown 将多个csv文件合并为一个java