Documenter.jl icon indicating copy to clipboard operation
Documenter.jl copied to clipboard

Check for use of "unbalanced or un-escaped \$ in the text" much earlier

Open fingolfin opened this issue 2 months ago • 5 comments

Currently both the HTMLWriter and LaTeXWriter contain code which print warnings of this kind:

Unexpected Julia interpolation in the Markdown. This probably means that you have an
unbalanced or un-escaped \$ in the text.

E.g. if the following is used in a Markdown file (this is the content of test/warnings/src/dollar.md):

# JuliaValue

It is possible to create pseudo-interpolations with the `Markdown` parser: $foo.

$([1 2 3; 4 5 6])

They do not get evaluated.

We used to not report any location for this; it got a bit better with PR #2793, in that now at least a file is reported. But that's not enough in general, if the source is a docstring (see PR #2820 for a test case demonstrating this: the .md file is reported as source, even though it just contains a @docs block pulling in the docstring which has the problem).

To fix this, I think we could be proactive: whenever we "import" a docstring from a source file, we know its location precisely (at least I believe so?). We could now run a little "pre-check" function, which scans for this problem, and if found, reports it immediately.

This way, not only do we get precise location info, but also the warning does not have to be implemented by each writer separately.

fingolfin avatar Nov 07 '25 12:11 fingolfin

Moving the check to be earlier seems reasonable to me. I also wonder if this should happen before or at the time when we convert to MarkdownAST.

mortenpi avatar Nov 07 '25 12:11 mortenpi

perhaps when we convert to MarkdownAST would be a good moment -- and perhaps this then would also be a good point to decide to not use MarkdownAST.CodeBlock directly, but our own version of that which tracks the origin of the code block?

fingolfin avatar Nov 07 '25 18:11 fingolfin

Some other things that could be tested at that point (and we in fact have custom tests for that in Oscar.jl):

  • test for an "unterminated jldoctest", i.e., there is a dcostring in which there is a ```jldoctest sequence but no matching ```
    • this happens quite a bit in our experience (especially at the end of a docstring)
  • check for invalid admonitions types

This is the code we have in Oscar for this:

admonition_types = string.((:note, :info, :tip, :danger, :warning, :compat, :todo, :details))

# this might not catch all broken jldoctests but seems to work for now
function has_broken_doctest(md::Markdown.MD)
  todo = copy(md.content)
  while !isempty(todo)
    elem = popfirst!(todo)
    # nested
    if elem isa Markdown.MD
      append!(todo, elem.content)
    else
      # proper docstrings are in a Markdown.Code block
      if elem isa Markdown.Paragraph
        for block in elem.content
          # unterminated jldoctests seem to end up inside some string in a Paragraph block
          if contains(string(block),"```jldoctest")
            return "Unterminated jldoctest: $(string(block))"
          end
        end
      elseif elem isa Markdown.Admonition
        if !(elem.category in admonition_types)
          return "Unknown admonition category: $(string(elem.category))"
        end
      end
    end
  end
  return nothing
end

CC @benlorenz @lgoettgens

fingolfin avatar Nov 09 '25 21:11 fingolfin

Another one: flagging use of @example etc. in doctrings (see #1859) could also be done at this point.

fingolfin avatar Nov 10 '25 00:11 fingolfin

And I just found issue #2059 which is strongly related (if not a duplicate... ah well)

fingolfin avatar Nov 10 '25 00:11 fingolfin