Transclusion or including sub-documents for reuse

Coming from Foswiki, and now working on Docker documentation in markdown, I stongly miss having built in transclusion.

If there’s any chance something basic can be included in Standrd Markdown - ala http://fletcher.github.io/MultiMarkdown-4/transclusion that would be awesome - copy and paste is such a painfully pointless excercise…

5 Likes

I think it should be an extension - transclusion is not useful for all cases, and the resolution of the transcluded document name is inherently domain-specific.

+1 , this is a very nice feature. I don’t agree that “the resolution of the transcluded document name [should be] inherently domain-specific.” , if the “inclusion target” is specified to be a file name.

I have implemented this in a code documentation tool I’m writing, with the following syntax:

  • {{ my_file }} -> include the file and parse it as markdown

  • {{ my_file[start:end] }} -> include the lines comprised between start and end and parse them as markdown.

  • {{ my_file.recognized_language_extension#symbol_name } -> for example { my_file.c#foo_bar } , retrieve the symbol named foo_bar in my_file.c , and include its content as a markdown code block . the range syntax can also be used in combination with this, for example { my_file.c#foo_bar[2:4] } will only include the lines 2 to 4 in the local scope of the given symbol.

I think the first form is quite true to the spirit of the markdown, I’m a little biased about the second form because I’ve written too much python, and the third form could make sense if CommonMark supports anchors (not sure if it does).

As for it being an extension, I do think this feature can be generically useful.

4 Likes

I’ve added this topic to the list of proposed extensions and requested that the topic is moved to the “Extensions” category.

3 Likes

-1

Nice feature, but…

if the “inclusion target” is specified to be a file name.

In case of files there is no need in special support from CommonMark processor, because transclusion can be easily done by any external preprocessor, like cpp or m4.

Transclusion can be helpful in other cases, though. For example, transclusion of wiki pages. But in this case it is quite domain-specific.

1 Like

case of files there is no need in special support from CommonMark processor, because transclusion can be easily done by any external preprocessor

Not true, transclusion should not happen in code blocks for example

1 Like

Yeah, it could be done by another tool, like any other feature of MD.

I think the ability to include other files could give a lot more power to MD.
My main use is repository readmes, and I would really like to be able to include files in the main readme. Having to use an external tool would vanish the benefit.

2 Likes

Hi there,

I wanted to point out another transclusion syntax that I’ve grown quite fond of which is proposed in the hercule library and used to compose API Blueprints.

Simple extension of markdown link syntax :[Title](link.md) (preceding colon :)

The big plus is graceful degradation into links, and possible context passing.

2 Likes

The great text editor iA Writer has introduced content blocks with a new syntax (https://ia.net/writer/support/general/content-blocks#toc):

Simple example
/transclude.md 'Example link (title/caption is ignored for text file types)'

It would be nice to see a standard syntax emerge for transclusion. Such variation in syntax is frustrating and creates lock-in to specific tooling. As pointed out by @jmatsushita, one of the reasons hercule uses a precedinge colon is that it degrades to standard link in environments that don’t support transclusion, reducing the lock-in.

3 Likes

Looks reasonable to me, as long as the analogy to CommonMark’s “indirect” link syntax is also taken into account:

Simple extension of indirect link syntax :[here][ref] in _CommonMark_ text

[ref]: http://example.com/text.md "Example text to include"

But where does the here and Example text to include text strings go, when after all the string :[here][ref] is supposed to be replaced with the “transcluded” text? They would just be discarded and have no purpose, right?

So a symbolic reference or an in-line URL would be enough, either written as :[ref][] (with the same “fall-back” property), or as:

Simple analogy to indirect link syntax :[ref] in _CommonMark_ text.  
Analogy to direct link syntax :(http://example.com/text.md) in _CommonMark_ text.

[ref]: http://example.com/text.md

Now the first case looks suspiciously close in intent, syntax, and behaviour to

Existing syntax: &ref; in _CommonMark_ text (via *entity reference*).

while the second case (the inline URL) looks pretty ugly and error-prone to me.

And why shouldn’t we be honest and admit at this point that we re-invent external entities in CommonMark— the exact same thing that in XML would be done by placing

<!ENTITY ref SYSTEM "http://example.com/text.xml">

in the internal subset and then referencing (“transcluding”) this text with literally the same syntax &ref; as given in the example above?

And since we have re-invented external entities already, why not re-invent internal entities, too? Which could look in CommonMark like this:

Simple extension: insert &here; some internal entity.

[here]: "at this point"

Maybe it seems too far a step to use &ref; for these tricks too, and it may seem that :[ref] would indicate clearer that “something special” is going on here. But the flexibility and consistency that using &ref; in these cases too would entail—adopted directly from XML—is worth considering, I would think. (And note that this does in fact nothing else but replicate the purpose and use of external and internal XML entities in CommonMark.)

I like the iA Writer syntax. In the link @james posted, there’s some further examples for transcluding text, tables, and images:

/Section.txt "Section"
/Balance Sheet.csv 'Finances'
/images/Structure.jpg (Data Flow)

The use of a forward slash for all transcluded file types is easy to remember. I think the iA Writer syntax is even more intuitive for causal writers than Markdown’s regular image syntax.

In some ways this syntax is reinventing the wheel. In Markdown we already have a syntax for including images, which could be extended for other embedded files. For the iA Writer examples, we could use this syntax:

![Section](section.txt)
![Finances](Balance Sheet.csv)
![Data Flow](images/Structure.jpg)

However, the text in brackets or quotes in the iA Writer syntax is displayed as a caption - whereas in Markdown, alternative text is not displayed as a caption without some non-standard post-processing. So there might be a case for using the iA Writer syntax for embedded content with optional captions, rather than hijacking the Markdown image syntax reserved for alt or title to display figures.

There’s also the question of how this information should be transcluded. For example, iA Writer presents the CSV file as a table. So there would need to be file type specific rules regarding transclusion. This follows on from the embedded audio/video discussion.

As CommonMark extensions, would there be harm in supporting both? Markdown has always followed TMTOWTDI.

2 Likes

The generated HTML from /images/Structure.jpg (Data Flow) is:

<figure>
<img src="images/Structure.jpg" alt="Data Flow" />
<figcaption>Data Flow</figcaption>
</figure>

So, the figure caption doubles as the image’s alternative text, making it easier (and less repetitive) to add captioned images to a document quickly.

There was also some discussion earlier about making alt text optional in some scenarios (e.g. quickly adding a set of images to a forum post), so this might be a nicer solution for those cases (no empty square brackets). /images/Structure.jpg produces:

<figure>
<img src="images/Structure.jpg" alt="" />
</figure>
1 Like

iA Inc have published a spec for Markdown Content Blocks (transclusion) over on GitHub:

We think that content blocks are a natural extension of Markdown. We’d be happy if more apps supported them. We’re publishing this spec to aid the process, and to start the conversation around it. We’re just getting started. Your suggestions are welcome.

3 Likes

Transclusion is something that Ted Nelson talked about from the beginning and is important in text markup whether for xanadu, html, markdown or xml etc. There are several implementations in markdown that do transclusion, it would be interesting in this sense to have a common and unique markup for this. In such a connected, dynamic and unique world I believe this: transclusion in commonmark. In my opinion this feature would make my life easier - it would be something I could use more often, it would be a replacement for Obsidian, Notion, org-mode.

How to have transclusion or including subdocuments for reuse with tables or inline/embedded table?

  1. [Filename](filename.md) - @jmatsushita as a proposal
  2. #include "filename.md" - @anon20778841 as a proposal
  3. [cite](https://oleb.net/2020/swift-docker-linux/#:~:text=running,container) - @anon20778841 as a proposal: “Proposal to allow specifying a text snippet in a URL fragment inside blockquotes in CommonMarkdown”

I notice a banner up top:

Please note the CommonMark spec is currently frozen with respect to features , but there are supersets of or extensible implementations of CommonMark that may support what you need.

Does that include features like this that are already on the proposed list, or is it exclusive to fully novel features?

(My apologies if I missed something obvious - a read of commonmark.org and a quick google has failed to answer this question)

Since transclusion wasn’t a feature included in the original Markdown featureset, it would be outside the scope of the featureset specified in the core CommonMark spec.

There was some talk of creating specs for CommonMark extensions, but I imagine that would be left to third parties at this point.

It’s been challenging to push forward with this feature. Any new developments?

I would suggest this syntax for file inclusion:

+[Title](link.md)

I find + sign to be intuitive for adding/including something…
Is there anything new on inclusion of this extension into cmark?