Sashmark / Blog

Markdown link open in new tab: target attributes in pandoc

Bobby Huang ·

The section Searching the spec for target and rel records grep counts on CommonMark 0.31.2 next to a control. Under Braces after an inline link, pandoc's HTML for lnt.md from the markdown reader appears in full. Under When link_attributes is turned off, output for that same file appears ASCII-normalized. The section Two commonmark reader runs compares plain commonmark with commonmark+attributes. Under Braces on a reference definition, four reader runs of lnt-ref.md are reported. Output for a tag written out in HTML is quoted in An a element typed by hand. Six numbered steps, three carrying grep counts, make up Check a link's attributes with pandoc.

Key takeaways

  • Three attribute-string counts on the spec, with a control count, appear in Searching the spec for target and rel.
  • Pandoc's markdown reader output for lnt.md is quoted in Braces after an inline link.
  • ASCII-normalized HTML for lnt.md sits in When link_attributes is turned off.
  • Output from plain commonmark and from commonmark+attributes is compared in Two commonmark reader runs.
  • Results for lnt-ref.md under four readers are reported in Braces on a reference definition.

You want a Markdown link to open in a new tab, and the attribute you have in mind is target="_blank", maybe with rel="noopener" next to it. CommonMark's link syntax has no slot for either one, so the real question is where pandoc lets you type them.

Here, a pandoc build numbered 3.8.3 read one inline link and one reference link on macOS, with four reader settings for each file. What follows quotes the HTML that came back. How that HTML behaves after some program loads it was never checked, so the post makes no claim there.

Searching the spec for target and rel

Begin with the CommonMark spec text, release 0.31.2. Searched there, grep -c '_blank' printed 0, grep -c 'target=' printed 0 and grep -c 'noopener' printed 0. A control count, grep -ci 'link', printed 261, so the search did read the text.

The spec builds an inline link from link text, then a left parenthesis, an optional destination, an optional title and a right parenthesis (lines 6894 to 6896). Anything typed after that closing parenthesis sits outside the link. For a reference definition, the spec lists a label, a colon, a destination and an optional title, then adds that no further character may occur (lines 2946 to 2955).

Pandoc adds the brace syntax through extensions. For the markdown reader, its filtered extension list included +link_attributes. The filtered list for commonmark printed -attributes, and a count of link_attributes in the full commonmark list came to 0.

Braces after an inline link

The test file lnt.md holds one sentence:

See the [Doe site](https://example.com){target="_blank" rel="noopener"}.

Here is what pandoc -f markdown -t html lnt.md gave:

<p>See the <a href="https://example.com" target="_blank"
rel="noopener">Doe site</a>.</p>

Both names in the braces landed on the a element as attributes, in the order they were typed. No brace characters were left in the paragraph text. Pandoc broke the output line between the two attributes, and the quote above keeps that break.

When link_attributes is turned off

To see the braces without the extension, the next run was pandoc -f markdown-link_attributes -t html lnt.md. Its output holds non-ASCII characters, so it is shown here ASCII-normalized: pandoc wrote U+201C (left double quotation mark) where each value opens and U+201D (right double quotation mark) where it closes, and both appear below as a straight double quote.

<p>See the <a href="https://example.com">Doe site</a>{target="_blank"
rel="noopener"}.</p>

Only the href stayed on the a element. The braces remained as plain words just past the closing </a>, and the quote marks inside them changed shape. A count agrees: pandoc -f markdown-link_attributes -t html lnt.md | grep -c 'target="_blank"' printed 0, while the same pipe with grep -c '_blank' printed 1.

Two commonmark reader runs

With no extension switched on, pandoc -f commonmark -t html lnt.md returned:

<p>See the <a href="https://example.com">Doe site</a>{target="_blank"
rel="noopener"}.</p>

Here too the braces stayed as text after the link, and the straight quotes came through as typed. That matches the spec rule quoted above: the link ends at its closing parenthesis.

With pandoc's attributes extension switched on, the answer changed. pandoc -f commonmark+attributes -t html lnt.md returned:

<p>See the <a href="https://example.com" target="_blank"
rel="noopener">Doe site</a>.</p>

That is the same HTML the markdown run produced.

A plain text count can mislead at this point. pandoc -f commonmark -t html lnt.md | grep -c 'target="_blank"' printed 1, since the leftover brace text holds those characters too. Matching the end of the address plus the attribute name splits the two cases: pandoc -f commonmark -t html lnt.md | grep -c 'com" target=' printed 0; with commonmark+attributes instead, it printed 1.

Braces on a reference definition

In lnt-ref.md, the braces move onto a definition line:

See the [Doe site][doe].

[doe]: https://example.com {target="_blank"}

Pandoc's output for that file under markdown was:

<p>See the <a href="https://example.com" target="_blank">Doe
site</a>.</p>

The commonmark+attributes run returned those same two lines. With the extension removed, pandoc -f markdown-link_attributes -t html lnt-ref.md folded the braces into the address:

<p>See the <a href="https://example.com%20%7Btarget=%22_blank%22%7D">Doe
site</a>.</p>

The space, the braces and the quote marks turned up inside href as %20, %7B, %22 and %7D, and the element got no target attribute.

Plain commonmark made neither a link nor a definition:

<p>See the [Doe site][doe].</p>
<p>[doe]: https://example.com {target="_blank"}</p>

Both lines printed as paragraphs of text. That fits the spec's rule that no further character may follow the destination and title. The reference link walkthrough covers label matching and the other definition rules.

An a element typed by hand

Another test file, lnt-raw.md, skips the braces and writes the element out:

See the <a href="https://example.com" target="_blank">Doe site</a>.

Both readers returned the same lines, first via pandoc -f markdown -t html lnt-raw.md and then via pandoc -f commonmark -t html lnt-raw.md:

<p>See the <a href="https://example.com" target="_blank">Doe
site</a>.</p>

Pandoc passed the tag through with its target attribute intact. A filtered listing, pandoc --list-extensions=commonmark | grep raw_html, printed +raw_html. Where typed HTML may sit in a file, and the blank lines around it, are explained in the post on typed HTML. For braces after an image, see the image sizing post.

Check a link's attributes with pandoc

Pick the reader you mean to keep and test the file with it.

  1. Run cat lnt.md and find where the braces sit. Here they came right after the link's closing parenthesis.
  2. Convert it once, for instance through pandoc -f markdown -t html lnt.md, and check the line that opens the a element.
  3. Count the attribute on the element itself. pandoc -f markdown -t html lnt.md | grep -c 'com" target=' printed 1 here. Swap in -f commonmark and it printed 0.
  4. Count rel next. pandoc -f markdown -t html lnt.md | grep -c 'rel="noopener"' printed 1, and under -f markdown-link_attributes it printed 0.
  5. Run the step 3 count on lnt-ref.md to check a reference link. It printed 1 under commonmark+attributes and 0 under plain commonmark.
  6. Scan the href for %7B. That string appeared here when markdown-link_attributes read lnt-ref.md, and the braces had become part of the address.

Where Sashmark fits

If the v1 plan holds, Sashmark would let a person retype words right on the page in its rendered form. Saving would then run through the clean Round-Trip that is planned, with each untouched line coming back as identical bytes. Spotting whatever differs from your prior reading of the file would be the planned work of a Changes View, with git left out of that job. It is in development and has not been released. The app itself has no AI features. See the planned features, the help pages and the roadmap for where each part stands.

More at sashmark.com.

Questions

Where do target and rel go in a Markdown link?
Braces typed after a link, and the HTML pandoc made from them, are quoted in Braces after an inline link.
Why do my braces show up as text after the link?
The plain commonmark run on lnt.md, and its HTML, are quoted in Two commonmark reader runs.
Can a reference link carry the attribute?
Four reader runs of a definition line ending in braces are reported in Braces on a reference definition.
Is there a way to set it without braces?
A hand-typed tag and the HTML pandoc made from it are quoted in An a element typed by hand.

What Sashmark plans for v1: Features · Roadmap

View as Markdown