Markdown和包括多个文件

是否有任何markdown fork允许你引用其他文件,比如包含文件?具体来说,我想创建一个单独的markdown文件,其中包含我经常调用但不总是调用的链接(调用此B.md),然后当我通过引用链接到我正在写入的md文件(A.md)时,我希望它从另一个文件(B.md)中拉出链接,而不是从当前文件(A.md)的末尾。

236331 次浏览

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

Markdown的设计目的是让人们能够编写简单、可读的文本,这些文本可以很容易地转换为简单的HTML标记。它不做文档布局。例如,没有真正的方法来将图像向左或向右对齐。至于你的问题,在任何版本的markdown中都没有包含从一个文件到另一个文件的单个链接的markdown命令(据我所知)。

最接近这个功能的是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文档说它在以这种方式合并的文件之间添加了一个空行,但如果没有空行,这对我来说行不通。

我只想提一下,在将输入文件连接到markdown_py之前,可以使用cat命令将输入文件连接起来,这与pandoc处理多个输入文件的效果相同。

cat *.md | markdown_py > youroutputname.html

在我的Mac上,Python版本的Markdown的工作原理与上面的pandoc示例几乎相同。

你实际上可以使用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,以了解适合大型文档项目的预处理器特性。

就在最近,我在Node中写了一些类似的东西,叫做markdown-include,它允许你用C风格的语法包含markdown文件,像这样:

#include "my-file.md"

我相信这和你问的问题很吻合。我知道这是一个旧的,但我至少想更新它。

您可以将此包含在任何您希望的标记文件中。该文件还可以有更多include, markdown-include将创建一个内部链接并为你完成所有工作。

你可以通过npm下载它

npm install -g markdown-include

我在Mac OS x上使用标记2,它支持以下语法来包含其他文件。

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

遗憾的是,您不能将其提供给pandoc,因为它不理解语法。但是,编写一个脚本来剥离语法来构造一个pandoc命令行是非常容易的。

事实上,你可以使用\input{filename}\include{filename}这两个乳胶命令, 直接在Pandoc中,因为它几乎支持所有的htmllatex语法

但注意,包含的文件将被视为latex文件。但是你可以很容易地用Pandox将你的markdown编译为latex

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

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

changequote(`\{\{', `}}')
include(\{\{other_file}})

在命令行中:

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

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

$ perl cat.pl <your file>

详细语法为:

  • @include <-=path=
  • 只需要包含一个:%include <-=path=

它可以正确地处理文件包含循环(如果a.txt <- b.txt, b.txt <- 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 > 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版本,具有相同的效果(不相同,但接近)。

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

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

效果好极了!

Asciidoc实际上是类固醇的降价。总的来说,Asciidoc和Markdown看起来非常相似,而且很容易切换。与markdown相比,Asciidoc的巨大的优点是它已经支持include,适用于其他Asciidoc文件,也适用于任何你喜欢的格式。您甚至可以根据所包含文件中的行号或标记部分包含文件。

当你写文档时,包含其他文件真的是一个救星。

例如,你可以有一个包含以下内容的asciidoc文件:

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

并在script.pl中维护你的样本

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

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

\{\{some_other_file.txt}}

这就是一切。名字很奇怪,但符合所有条件。

恕我直言,你可以通过连接你的输入得到你的结果*。Md文件如下:

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

实际上,让我感到惊讶的是,这个页面上没有人提供任何HTML解决方案。据我所知,MarkDown文件可以包括大部分(如果不是全部)HTML标签。所以请遵循以下步骤:

  1. here:把你的MarkDown文件放在<span style="display:block"> ... </span>标签中,以确保它们将被渲染为MarkDown。你有很多其他的样式属性可以添加。我喜欢的一个是text-align:justify

  2. From here:使用<iframe src="/path/to/file.md" seamless></iframe> . Include在你的主文件中的文件

p.s. 1。这个解决方案不工作在所有MarkDown引擎/渲染。例如,Typora确实正确地渲染了文件,但Visual Studio Code却没有。如果其他人能在其他平台上分享他们的经验,那就太好了。我特别想了解GitHub和GitLab…

P.S.2。在进一步的调查中,似乎是主要的不兼容问题导致这不能在许多平台上正确呈现,包括Typora, GitHub和Visual Studio代码。在我解决之前请不要用这个。我不会删除答案只是为了讨论,如果你可以分享你的意见。

为了进一步调查这个问题,我问了这个问题这里是StackOverflow这里是Reddit

经过一些深入的研究,我得出的结论是,目前AsciiDoc是一个更好的文档选择。它带有内置的包含功能,由GitHub呈现,Atom和vscode等主要代码编辑器都有用于实时预览的扩展。可以使用Pandoc或其他工具自动将现有MarkDown代码转换为AsciiDoc,并进行微小的更改。

另一种内置包含功能的轻量级标记语言是reStructuredText。它带有..包括::inclusion.txt 语法。还有带有实时预览的ReText编辑器。< / p >

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

---
header-includes:
- \usepackage{pdfpages}
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文件。

作为一个有趣的奖励,这只是因为我经常使用markdown,如果您想包括markdown以外的文件,例如latex文件。我稍微修改了这个回答。假设你有一个markdown1.md文件:

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


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

\section{Section}


Profundity.


\subsection{Section}


Razor's edge.

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

\section{Section


Glah


\subsection{Section}


Balh Balh

假设您想将document1.tex和document2.tex包含到markdown1中。Md,你只要这样做,就可以降低1。Md

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


\input{/path/to/document1}
\input{/path/to/document2}

用pandoc检查一下。

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

你的最终文档看起来是这样的:

有意义的事

的头部特写

部分

深刻。

部分

剃刀边缘。

部分

Glah

部分

Balh Balh

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

<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>

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

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

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

https://github.com/shd101wyy/mume

以及其他基于mume的工具

https://github.com/gabyx/TechnicalMarkdown

下面是我如何在我的文档中使用它的一个例子,我用vcode -markdown-preview-enhanced处理:


[[Epigenetics]]
@import "epigenetics.md"


如果你正在使用pandoc进行markdown处理,除了在调用pandoc时使用多个输入markdown文件外,还没有本机解决方案(在https://github.com/jgm/pandoc/issues/553中讨论)。

然而,使用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可能被认为过于“just”;包括外部Markdown文件,它允许更多,如包括CSV或Excel表从外部来源以及:

Details are shown in the following table:


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

切换到asciidoc,这样你就不必使用Markdown这样的语言了,这些语言现在非常原始:)

奥利弗·马修斯的回答的启发,你可以创建一个perl脚本,递归地查找语法![[B.md]],并用B.md内容替换它


让我们创建名为parseMd.sh的递归脚本

#!/usr/bin/env bash
perl -ne 's#^!\[\[(.+?)\]\].*#`'$0' "$1"`#e;print' "$@"

像这样使用它

./parseMd.sh A.md > result.md

使用它和pandoc一起导出为pdf

pandoc <(./parseMd.sh A.md) -o result.pdf