Linking to different document with same title

Howdy! I’m working on a Scrivener project to export to MD and then to LaTeX. I am working on a roleplaying game, and have a few cases where documents in one section have the same titles as one in another. For example, there’s an overview section with a brief document describing Skills, then later, a whole section for Skills. I would like to be able to make a link from one to the other, but I’m finding myself stymied. If I try to make an internal link to the other document, Scrivener exports a blank link, just as though I were linking the document to itself.
Clearly I need to explicitly set the text Scrivener will export after the heading (the {#skills} bit) but have no idea if it’s possible to explicitly set that. Perhaps there’s another way to do what I want, short of giving these documents different titles.

Whether using Pandoc or MultiMarkdown dialect, both systems have a way of addressing this particular problem at the syntax level. As with all things Markdown related, Scrivener can usually either (a) have it handle the matter entirely, (b) be easily coerced into doing it for you or (c) live just fine with you using syntax yourself. In this specific case, you can choose from all three.

The Easy Way (a)

First, the basics. Scrivener’s default mode of operation is to presume that internal hyperlinks are strictly an authorial tool, and that as a tool meant only to benefit you’re own writing process, they have no function as an end-reader tool for navigating your writings. If you want all of your links to be functional, then we need to tell Scrivener what’s up:

  1. Go into File/Compile...
  2. In the general Options tab on the right, click Convert links to MultiMarkdown.
  3. Give that a test compile.

In a sample project I created, which uses your described structure to a limited degree, if I compile to MultiMarkdown plain, this is what I get:

# Character One #

## Description ##

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua...

Also refer to [Character Two's skill set][ref1].

## Skills ##

# Character Two #

## Skills [ref1] ##```

If I set this to Pandoc syntax I would get a slightly different output in terms of syntax, but the concept would be the same. Scrivener automatically detects title duplication within the scheduled compile content list and builds a list of serialised labels to use for both that heading, and the cross-reference link itself.

So, again, if that’s all you want—you’re probably all set. :slight_smile:

The Flexible Way (c) and a bit of (b)

You can take more control over the process yourself if you want. Maybe you’re going to need to live in the .tex file in the long term, and having to work with a bunch of ref28 and ref89 labels doesn’t sound appealing—or maybe you would like a mix of being able to use internal links internally, as well as having some of them turn into reader cross-references.

For that, you’ll want to devise some way of getting that appropriate syntax into what Scrivener compiles. If you look back at the above sample, one very obvious and somewhat crude way of accomplishing a custom ID is to simply type it right into the binder title, “Skills [character-two-skills]”, for example.[1]

But we can make that a little nicer if we want to. The approach I take is with custom metadata. I create a text field called “Section ID”. If a section needs a custom label for whatever reason (sometimes brevity is just as good a reason as avoiding duplicates), then I’ll type “[character-two-skills]” into that field. I can add this field to the Outliner for easy reference.

With the custom field readily accessible in the inspector and outliner, it’s a simple matter to fetch the key when you need it, to make a link pointing to that item.

Lastly, for making all of that functional in compile, you need to print the value of the custom field into the heading:

  1. Double-click the “Basic MultiMarkdown” or “Basic Pandoc” format, depending on which you prefer, to duplicate and edit (or just go from what you already have customised).

  2. On the Section Layouts that print headings, select the “Title Options” tab, and insert " <$custom:Section ID>" into the Title Suffix field (noting the space, so it doesn’t run into the title).

    For Pandoc, you’ll want to disable the Place suffix inside hashes option, below that field, as Pandoc requires the {#custom-id} to fall outside of the hashmarks.[2]

And that’s it, of course with this approach you are more closely using Markdown to write, and would turn off the option to convert links (otherwise you may end up with links inside of links if you combine personal linking with reader cross-referencing).

The nice thing is that if there is nothing to print for the Section ID field, nothing prints—so only the items where you’ve supplied a custom ID will print anything here. (You might be tempted to leave the syntax out of the field, just type in “character-two-skills” and let the compiler add the brackets and such—but you’ll have to clean up the stuff left behind in cases of empty fields if you do that.)


  1. With Pandoc you would type in “Skills {#character-two-skills}” instead. Be aware of the caveat mentioned in the following note. The option to add hashes after the title will need to be disabled for this to work out of the box, as the attribute brackets need to fall after any hashes.

    • For macOS: this option can be disabled in the compile Format, as described in §24.2.2, General Section Layout Options, with the Add closing hashes to titles setting.
    • For Windows: at the time of this writing the aforementioned option does not exist in the GUI, but so long as you are using a Pandoc compile Format created in 3.1.2 or greater, this setting has been disabled in the format file itself. If this version has yet to be released, get in touch with me and I’ll send you a copy.
  2. If you are creating a copy of one of the Pandoc-specific Formats, or “Markdown Outline”, then the option to add hashes after the title will be disabled by default, meaning you don’t need to use the Place suffix inside hashes option. This note is applicable only for formats duplicated from versions 3.2.4 on Mac, and 3.1.2 on Windows, or greater (which, at the time of this writing, have not been released yet).

1 Like

AmberV, thank you so much for your response! I will look through the file you provided, I’m sure that solution is what I’m looking for!

OK, so I see what’s happening with the example file… I made that change to the compile settings (disabling “Place suffix inside hashes”) and here is what Scrivener produces:

## Skills ## [character-two-skills]

When I think what I need would be, as you mention earlier:

## Skills ## {#character-two-skills}

But that’s not a problem as I can make the latter the section ID metadata no problem. If you have a way to transform the […] syntax automatically, I find it more readable, but it’s hardly a big deal.

For linking, I just use:

The following is a [link](#character-two-skills)

As for changing the square brackets to curly-braces, normally I would say no problem! You’d just paste this formula into the Replacements pane for the compile format:

<Replacement RegEx="Yes">
    <Replace><![CDATA[(?<=# )\[([^\]]+)\]$]]></Replace>

That will scan for any square-bracketed phrases that fall at the very end of a line, and are preceded by at least one hashmark and space. That should sufficiently isolate it down to only these custom IDs.

But, I ran into a weird bug while double-checking that it worked—it looks like this replacement works on items that lack text content, but fails on items that have text. So I’m afraid it may not be terribly useful at the moment—though you might as well give it a shot, in case my test project’s conditions are narrower than yours somehow. And also if you don’t need to actually compile for a good while, it may be we fix the bug before then.

Either way, you could clean these up using a text editor that can do regexes anyway. Replacements are just an automation for that process.

I would like to “compute” the heading ID (linkid) in the following way:

    # remove 1.2.3 at the beginning
    linkid = re.sub(r'^[0-9][0-9.]* ', '', heading)
    # replace/remove nonsense chars
    linkid = re.sub(r"[^a-zA-Z0-9 -]", "", linkid).lower().strip().replace(" ", "-").replace("--", "-")
    # add a 3-letter hash from the path, i.e., higher-level headings
    linkid = linkid+'-'+hash3(path)

Is there anyway to hook this logic into Scrivener, or does Scrivener has a cli for me to set the heading ID programmatically?

Yes, Scrivener has CLI integration. Double-click your compile Format to edit it, and check out the Processing pane. You can embed a script right into the settings or keep it stored external and call it like you would Pandoc or whatever. What you put into the field should be a self-contained fully functional script of some sort, so it should start with a hashbang to let the system know which interpreter to use, /bin/bash or whatever you want, and will need to handle file input and output.

You’ll find documentation for this in the user manual PDF, under §24.22.

Thanks for your directions, AmberV. I can hook up a script to process the MMD output now. But key information on internal links is missing unless I do a lot of manual work.

Take the example from above:

Is it possible, in some automated way, during compilation:
(1) add T_{$hn} as ID for each title
(2) when exported to mmd, the internal link automatically receives a link to [T_{$hn}] of the link target

This way repeated titles are automatically identified, and an external process script can do a lot of things. For that matter, the internal UUID exported as title ID and link target would also work.

I don’t believe you should run into any issues with doing that, and what you are referring to should all be documented:

Chiefly you are looking for the behaviour provided by the Document Title Links pane, in the Format Designer window. You’ll find documentation for it in §24.8, Document Title Links. The two cross-references at the top of this section are crucial to the other things you want to do as well—for example, it sounds like you may not have yet encountered the Title Suffix feature.