ChatGPT解决这个技术问题 Extra ChatGPT

Markdown and including multiple files

Is there any markdown fork that allows you to reference other files, something like an includes file? Specifically, I want to create a separate markdown file with links that I call often but not always (call this B.md), then when I link by reference in the md file I'm writing (A.md), I'd like it to pull the link from the other file (B.md) rather than from the end of the current file (A.md).

If your question is github related markdown, you might take a look here
The rule of thumb for Markdown is that the answer to 'Can Markdown...' is usually 'Not practically, universally or easily'.
There's an open discussion of how best to do this with Pandoc over at github.com/jgm/pandoc/issues/553 and on the commonmark forum at talk.commonmark.org/t/…

A
Aaron Massey

The short answer is no. The long answer is yes. :-)

Markdown was designed to allow people to write simple, readable text that could be easily converted to a simple HTML markup. It doesn't really do document layout. For example, there's no real way to align an image to the right or left. As to your question, there's no markdown command to include a single link from one file to another in any version of markdown (so far as I know).

The closest you could come to this functionality is Pandoc. Pandoc allows you to merge files as a part of the transformation, which allows you to easily render multiple files into a single output. For example, if you were creating a book, then you could have chapters like this:

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

You can merge them by doing executing this command within the same directory:

pandoc *.md > markdown_book.html

Since pandoc will merge all the files prior to doing the translation, you can include your links in the last file like this:

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

So part of your 01_preface.md could look like this:

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

And part of your 02_introduction.md could look like this:

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

As long as your last file includes the line:

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

...the same command used before will perform the merge and conversion while including that link throughout. Just make sure you leave a blank line or two at the beginning of that file. The pandoc documentation says that it adds a blank line between files that are merged this way, but this didn't work for me without the blank line.


This turns out to be an extremely useful post for me! Thanks Aaron. It seems it would be a common use case to have a /chapters dir, one script that builds/merges chapters, and then a top level wrapper script that includes a step like: --include-before-body $(include_dir)/merged_chapters.html. That's the approach I'll be taking to get some organizational benefit.
One other advantage of using pandoc is that it supports an enormous variety of outputs: you can generate not only HTML but also everything from docx to LaTeX to ePUB.
pandoc *.md > markdown_book.html results in pandoc: *.md: openfile: invalid argument (Invalid argument) - it doesn't appear to support the syntax you specified.
It is working on my system. I created a sample repository on GitHub so you can try it with all the files that I used.
I also get the invalid argument error with pandocc 2.2.1 on Windows. I had to list the files explicitly: 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
e
ephsmith

I would just mention that you can use the cat command to concatenate the input files prior to piping them to markdown_py which has the same effect as what pandoc does with multiple input files coming in.

cat *.md | markdown_py > youroutputname.html

works pretty much the same as the pandoc example above for the Python version of Markdown on my Mac.


@tprk77: except that Aaron's answer makes it clear that the cat command is redundant here..
The use of cat *.md implies an inflexible file naming convention. Not only would this convention necessarily prohibit recursive includes, for larger documentation projects it would be painful to add new files into the mix. You would have to do a lot of counting and renaming. The markdown project has had a preprocessor for this very purpose since the year 2010.
@ninegrid While MarkdownPP looks very useful, from looking at the source repo you referenced in your answer it seems to me (a) MarkdownPP is John Reese's project, only; (b) it's not part of "the markdown project" (any of the various flavors) at all; and (c) MarkdownPP outputs GFM, specifically. Correct? As I said, it looks interesting and helpful, but your comment here makes it sound like it's a standard Markdown feature that every Markdown implementation should come with. But from looking at the repo, the situation appears to be the complete opposite.
Fails to convert MD tables to HTML tables.
L
Lii

You can actually use the Markdown Preprocessor (MarkdownPP). Running with the hypothetical book example from the other answers, you would create .mdpp files representing your chapters. The .mdpp files can then use the !INCLUDE "path/to/file.mdpp" directive, which operates recursively replacing the directive with the contents of the referenced file in the final output.

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

You would then need an index.mdpp that contained the following:

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

To render your book you simply run the preprocessor on index.mdpp:

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

Don't forget to look at the readme.mdpp in the MarkdownPP repository for an exposition of preprocessor features suited for larger documentation projects.


T
Tunaki

My solution is to use m4. It's supported on most platforms and is included in the binutils package.

First include a macro changequote() in the file to change the quoting characters to what you prefer (default is `'). The macro is removed when the file is processed.

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

On the commandline:

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

m4 is barely known, but is indeed an incredibly powerful tool when it comes to such generic include needs. Enough to have the documentation mention it can be "fairly addictive".
Now, that is a solution! Genius
+1 for the idea and reminder of m4! Funny thing is that when I saw the extensions above as 'md' I was thinking in my head of m4. That you would then include an example is great. I'm not sure if this question asks exactly what I'm after but it might do. Thank you either way.
a
aldoWan

Just recently I wrote something like this in Node called markdown-include that allows you to include markdown files with C style syntax, like so:

#include "my-file.md"

I believe this aligns nicely with the question you're asking. I know this an old one, but I wanted to update it at least.

You can include this in any markdown file you wish. That file can also have more includes and markdown-include will make an internal link and do all of the work for you.

You can download it via npm

npm install -g markdown-include

This has been very helpful! Thank you!
@leas Glad to be of service... I haven't worked on it in quite a few years but I always mean to get back to it at some point. Hopefully it does well for your purposes.
This would be awesome if it just works as a standalone cli. Feed it a document and it does the replacements per the projects defined token syntax.
M
Mike Mitterer

I use a includes.txt file with all my files in the right order the I execute pandoc like this:

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

Works like a charm!


Great approach. Specifying file order is fundamental, but it isn't accomplished with the glob methods unless you number files.
Could you include an explanation of the steps? Seems so powerful! I would like to know if it's possible to trim it down to make other conversions such as to .pdf and .tex.
e
eff

Multimarkdown has this natively. It calls it file transclusion:

{{some_other_file.txt}}

is all it takes. Weird name, but ticks all the boxes.


are there any Free and Open Source editors to render this syntax? I have asked this question here with more details. I would appreciate if you could help me with it.
@Foad: I'm afraid I'm a vim user and am unaware of any such editors. I see on your reddit Q you found that Asciidoc, and various editors of, supports this. I didn't know this - thanks.
Happy that it was useful. But does vim has live preview for MultiMarkDown? would you be kind to share your setup and dot files with some more details?
No live preview, I'm not that kind of guy. ;) The main reason I used markdown at all was because it aims to be human readable when not processed, so I really don't mind about previews too much (although I understand why others do). The only thing I am interested in, in this case, is syntax highlighting, and the default markdown syntax highlighting works well enough for me. Sorry to not be of more help.
It looks like it could be interesting, although I see no reason to choose it over markdown/asciidoc for my (meagre) purposes, at least.
B
Bram

Asciidoc is actually a markdown on steroids. Overall, Asciidoc and Markdown will look very similar and it is rather easy to switch. A huge benefit of Asciidoc over markdown is that it supports includes already, for other Asciidoc files but also for any format you like. You can even partly include files based on line numbers or tags inside your included files.

Including other files is really a life saver when you write docs.

You can for instance have an asciidoc file with such content:

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

and maintain your sample in script.pl

And I am sure you will wonder so yes, Github also supports asciidoc.


There seems to be a nice promise here but does not give a complete answer with how-to steps. Is it possible to state how to convert the multi-file document into a single one?
This is the best solution on this page so far. I came to this conclusion and addressed the issue here on Reddit. AsciiDoc has built-in include and it is rendered by GitHub. Atom and vscode both have nice plugins for live preview too. I wonder why AsciiDoc is not the industry standard already!
W
Wung Hugh

In fact you can use \input{filename} and \include{filename} which are latex commands, directly in Pandoc, because it supports nearly all html and latex syntax.

But beware, the included file will be treated as latex file. But you can compile your markdown to latex with Pandox easily.


d
dvorak4tzx

I think we better adopt a new file inclusion syntax (so won't mess up with code blocks, I think the C style inclusion is totally wrong), and I wrote a small tool in Perl, naming cat.pl, because it works like cat (cat a.txt b.txt c.txt will merge three files), but it merges files in depth, not in width. How to use?

$ perl cat.pl <your file>

The syntax in detail is:

recursive include files: @include <-=path=

just include one: %include <-=path=

It can properly handle file inclusion loops (if a.txt <- b.txt, b.txt <- a.txt, then what you expect?).

Example:

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

More examples at https://github.com/district10/cat/blob/master/tutorial_cat.pl_.md.

I also wrote a Java version having an identical effect (not the same, but close).


<<[include_file.md] (Marked 2 on macOS): gist.github.com/district10/d46a0e207d888d0526aef94fb8d8998c
Of note, @ is used for citations with pandoc-citeproc (e.g "@Darwin1859").
F
Foad S. Farimani

I'm actually surprised that no one in this page has offered any HTML solutions. As far I have understood MarkDown files can include wide portion (if not all) of HTML tags. So follow these steps:

From here: put your MarkDown files in ... tags to be sure they will be rendered as markdown. You have a whole lot of other style properties you can add. The one I like is the text-align:justify. From here: Include the files in your main file using the

P.S.1. this solution does not work on all MarkDown engines / renders. For example Typora did render the files correctly but Visual Studio Code didn't. It would be great if others could share their experience with other platforms. Specially I would like to hear about GitHub and GitLab ...

P.S.2. On further investigation there seems to be major incompatibility issues leading to this not being properly rendered on many platforms, including Typora, GitHub and Visual Studio code. Please do not use this till I resolve them. I will not delete the answer just for the sake of discussion and if maybe you can share your opinions.

P.S.3. To further investigate this issue I have asked this questions here on StackOverflow and here on Reddit.

P.S.4. After some through study, I came to the conclusion that for the moment AsciiDoc is a better option for documentation. It comes with built-in include functionality, it is rendered by GitHub, and major code editors like Atom and vscode have extensions for live preview. One can use Pandoc or other tools to automatically convert existing MarkDown Code to AsciiDoc with minor changes.

P.S.5. Another lightweight markup language with built-in include functionality is reStructuredText. It comes with .. include:: inclusion.txt syntax by standard. There is ReText editor with live preview as well.


r
redapemusic35

I know that this is an old question, but I have not seen any answers to this effect: Essentially, if you are using markdown and pandoc to convert your file to pdf, in your yaml data at the top of the page, you can include something like this:

---
header-includes:
- \usepackage{pdfpages}
output: pdf_document
---

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

# Section

Blah blah

## Section 

Blah blah

Since pandoc using latex to convert all of your documents, the header-includes section calls the pdfpages package. Then when you include \includepdf{/path/to/pdf/document.pdf} it will insert whatever is include in that document. Furthermore, you can include multiple pdf files this way.

As a fun bonus, and this is only because I often use markdown, if you would like to include files other than markdown, for instance latex files. I have modified this answer somewhat. Say that you have a markdown file markdown1.md:

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

And two addtional latex file document1, that looks like this:

\section{Section}

Profundity.

\subsection{Section}

Razor's edge.

And another, document2.tex, that looks like this:

\section{Section

Glah

\subsection{Section}

Balh Balh

Assuming that you want to include document1.tex and document2.tex into markdown1.md, you would just do this to markdown1.md

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

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

Run pandoc over it, e.g.

in terminal pandoc markdown1.md -o markdown1.pdf

Your final document will look somewhat like this:

Something Meaning Full

Talking Head

Section

Profundity.

Section

Razor's edge.

Section

Glah

Section

Balh Balh


Great solution! I use pandoc for serious documents and will employ it.
c
compound eye

The @import syntax is supported in vscode-markdown-preview-enhanced

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

which probably means its part of the the underlying tool mume

https://github.com/shd101wyy/mume

and other tools built on mume

https://github.com/gabyx/TechnicalMarkdown


p
phispi

If you are using pandoc for markdown processing there is no native solution yet (discussed in https://github.com/jgm/pandoc/issues/553), except using more than one input markdown files when calling pandoc.

However, using codebraid (actually intended to include auto-generated content to Markdown) this can be achieved:

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.

To convert it to any output format, use something like the following:

codebraid pandoc main.md --to markdown

Although codebraid might be considered overkill to "just" include external Markdown files, it allows much more e.g. like including CSV or Excel tables from external sources as well:

Details are shown in the following table:

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

D
David Clarke

Another HTML-based, client-side solution using markdown-it and jQuery. Below is a small HTML wrapper as a master document, that supports unlimited includes of markdown files, but not nested includes. Explanation is provided in the JS comments. Error handling is omitted.

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

p
paxos1977

I use Marked 2 on Mac OS X. It supports the following syntax for including other files.

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

Sadly, you can't feed that to pandoc as it doesn't understand the syntax. However, writing a script to strip the syntax out to construct a pandoc command line is easy enough.


would you happen to have the script instead of just saying it's easy? :)
M
Martin

Switch to asciidoc so that you don't have to work with a language like Markdown which is very primitive these days :)


e
eyllanesc

IMHO, You can get your result by concatenating your input *.md files like:

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