refer to page number using scrivomatic / pandoc


I use Scrivener with Scrivomatic / Pandoc to get an docx-file as output. I have a problem when trying to refer to a specific page by using <$p>. In the docx output it doesn’t show the page number but only question marks.
Can anyone help? I would really appreciate it!

Given that you are using Pandoc, it would be more helpful if this was posted in the “MultiMarkdown and LaTeX” forum, as Windows users using version 3 (Beta at the moment) are more likely to find it there and get useful tips from any discussion that follows.

Just a thought!

@NonTroppo is the person to help and he is very active in that forum, though as a Mac user he does also respond here.



The main problem here is that you are trying to mix a tool intended for word processing output with a Markdown workflow, which unfortunately cannot work because it depends upon Scrivener being in full control of both the target location’s bookmark and the reference marker pointing to it. When the compiler is creating an RTF file, it can do this right at the point where the heading is inserted, it naturally knows what the bookmark should be called and can use that bookmark ID to generate the page reference code. But when you compile a Markdown file the heading gets turned into something like this in plain-text:

### Name of Subsection ###

It is then up to Pandoc to take that and turn it into the DOCX XML code that makes “Name of Subsection” a properly styled heading—and important to what we want to do, inserts a bookmark so that it can be referred to from elsewhere. That happens after Scrivener is done with its part of the job, so it does not know what these bookmarks are called, and thus can do nothing meaningful with the <$p> link you inserted.

Internal linking is how you would typically handle this kind of thing in Markdown, rather than using Scrivener. For example, elsewhere in the text you would type in this:

[Name of Subsection]

The Markdown engine is in full control of both the bookmark and the pointer you request, so it can link them together and create a useful hyperlink pointing from A to B. For DOCX, Pandoc unfortunately does not yet support internal linking (pg. 87), you’ll find this:

I’m not sure why it hasn’t been added yet—if I had to guess it is because the cross-ref syntax is too simple to express the various ways in which people may want to accomplish this (you want page numbers, some else wants the section title, etc.).

Disclaimer: nontroppo may come along and point out there is a perfectly native solution to this with pandocomatic or something else I’m not familiar with. I’m not a huge Pandoc expert myself. The method I describe below uses Scrivener’s tools to enhance your output, rather than post-production or Pandoc-specific solutions.

If we do know what we want then we can do this ourselves. One way of doing that is through its own Lua scripting mechanism—but a method I like to try and use is Scrivener itself. Refer to the attached project to find a working demo of the technique. In the project’s compile window, double-click on the Format to edit it, and navigate to the Styles pane.[size=80][1][/size]

The two styles you’ll be interested in are “XREF Title” and “XREF Page”. These have been added to an otherwise stock copy of the “Pandoc Word Document” compile format. In a nutshell they are using Scrivener’s style prefix/suffix system to inject raw DOCX XML into the output using a mechanism Pandoc has for doing so.[size=80][2][/size]

What you’re probably more interested in is testing how it works. So make note of the two style names, or change their names to something you prefer. You are going to need to create one or both of these styles in your project, so that you can mark text in the editor with it, and have the compiler turn that text into a bookmark. The attached project has a simple sample set up in “scene a” to demonstrate both forms. If you compile this project, you should get fully functional cross-ref fields in your word processor.

As you can see from the editor, the key thing here is that you need to type in what the internal bookmark ID will be in the file. For the most part the result can be reliably guessed at. To return to our earlier example, we would want to type in “name-of-subsection” and then mark it with the XREF Page style. Pandoc is going to insert a bookmark by that name into the DOCX file, and this format will create a page number style cross-ref pointing right at it. Rule of thumb: replace all spaces with hyphens and remove any quotations. Alternatively you can open the .docx in any word processor and peruse the bookmark list to see how Pandoc generated it.[size=80][3][/size]

Let me know if you have any questions.


[size=80][1] From here you can save the style to “My Formats” to make it globally available beyond this sample project.[/size]
[size=80][2] By the way, if you already have a custom Format of your own, you can Copy and Paste style settings between formats—just do so on a new style as Paste doesn’t paste the style, only its settings.[/size]
[size=80][3] You will run into issues with complex headings. I’ve noticed that at a certain level of complexity, Pandoc gives up on trying to clean the bookmark name to something human-friendly, and creates a randomly generated ID which will I suspect be useless to this technique.[/size]

Moderator Note: This topic has been moved to the MultiMarkdown & LaTeX board. (135 KB)

Wow, what an elegant solution from AmberV!!! 8)

At least in my version of Word, you will need to “Update Fields” to see them but it works great. And Scrivener’s solution means you can use a different Compile format down the road if you need to output to other formats like HTML or LaTeX.

A Pandoc solution would indeed require writing a Lua filter, for reference here is an example that would do this for LaTeX output: As the filter knows the output format it could be made to support multiple outputs too.

Pandoc does support cross referencing headings (documentation), so you could replace [XREF Title] with markdown links if you really wanted, but you still need to use AmberV’s [XRef Page] style so in the end it is probably better to keep the same mechanism for text and page.

The documentation for how Pandoc generates bookmark names is here BTW: … dentifiers

Wow, thank you so much for this AmberV! This sounds good and I will try this solution and probably be back with questions.
Also, thank you Nontroppo! If AmberV’s solution works I’ll probably leave it at that.

Thanks again!