What do you think? add a callback to Documents.Page() to allow modification of *.md pages on the fly before parsing

Hello,
for my project I need to add some common parts to the markdown files that will be processed by Documenter.jl to become HTML pages, like a footer section to add a @raw html block to allow comments, a sort of header to add a list of videos, etc.
I don’t want to do this by editing each md pages for several reasons.
Do you think it would be reasonable to add a callback function in Documents.page(), just after the actual reading of the page and before the Markdown parsing, so that users can modify the page on the fly?

For example changing:

mdpage = Markdown.parse(read(source, String))

with something like:

pagecontent = read(source, String)
pagecontent = editsource(pagecontent,source)
mdpage      = Markdown.parse(pagecontent)

and the default editsource() callback defined as:

editsource = (pagecontent,source) -> return pagecontent

I can take care to start a pull request for it, but I did want first to ask if it looks like a good idea to add this kind of flexibility or there are better ways to achieve it. What do yo think?
Also, would be better an in-place version editsource!() ?

Why not just manipulate the file before calling makedocs?

Because:

  • I don’t want to distract users of the raw files from this “presentation” details (the raw files are actual *.jl files processed by Literate to .md that the students are invited to play with)
  • if I want to change something in the way I manage these additional blocks, I would have to do it for all the pages, while with this approach I can change it only once in the make.jl script
  • because it is boring to manually repeat a large code chunk when it only change vids of youtube and I can do it programmatically :slight_smile:

I would like to keep in the callback the path of the file, so I can always apply my custom logic and filter where to do the modifications, or how to do it (in my case for example I will use a dictionary of vids per page) .

In that case, Literate already support Custom pre- and post-processing.

I mean’t that you would write a function that does it so you you would only have to change this function that you run on all the pages.

Thank you. I wasn’t aware of it, but I do actually have a mix of .jl and original .md files in my project [ source - rendered ], so having it in the final step (in Documenter) is more flexible…

So, I had a look on the documentation on Custom pre- and post-processing functionalities on Literate, and indeed it’s exacly my need, just moved up to Documenter as I need it for oiriginal md and Literate processed jl files.
So, should I go on and try to implement a preprocess callback for Documenter?

Would it make sense to pass to the callback the actual file content and the path?

Do you want the preprocessing to happen at the text level or AST level? If the former, it still seems like something you could do yourself in make.jl between the Literate and makedocs calls?

I could surely change the text file in make.jl before calling makedocs, but that would change the file on disk. And I don’t want that. First, because I build the documentation several times, at each new version of my project, secondly because I want to keep a distinction between the content of the page and the presentation/widgets/addons/ stuff that I want to add to my pages.
And I don’t have only literate → md workflow (in that case I could use postprocess from Literate.jl), but I also have some “original” *.md pages, so having the preprocess function in Documenter is the more natural option for my user case…

ok, so I managed to add the preprocess::Function argument to Documents.Document() and save it as a new field on the User struct.

On the other hand, I added preprocess to addPage!(doc, src, dst, workdir, preprocess) that then call Page(src, dst, workdir, preprocess).

Now my point is how do I move the preprocess argument from the User struct to the addPage!() call ?

ugh, I think I got it… in Selectors.runner… need to test it now…

Works :slight_smile: :slight_smile: :slight_smile:

I have created a pull request