fredrikekre / Literate.jl

Simple package for literate programming in Julia
https://fredrikekre.github.io/Literate.jl
Other
534 stars 61 forks source link

Literate does not strip notebook references when source spans multiple lines #224

Closed kbarros closed 8 months ago

kbarros commented 1 year ago

For a notebook output, Literate will strip references for an input like this:

# Try this [Structure Factors with Classical Dynamics](@ref) tutorial.

but not this:

# This is the subject of our [Structure Factors with Classical
# Dynamics](@ref) tutorial.

The latter can appear when using a "line wrap" feature of an editor.

Perhaps this issue can be resolved if these regex's are allowed to span multiple lines: https://github.com/fredrikekre/Literate.jl/blob/master/src/Literate.jl#L212-L214

Specifically, can there be a trailing s on these three regex's?

        push!(repls, r"\[(.*?)\]\(@ref\)"s => s"\1")     # [foo](@ref) => foo
        push!(repls, r"\[(.*?)\]\(@ref .*?\)"s => s"\1") # [foo](@ref bar) => foo
        push!(repls, r"\[(.*?)\]\(@id .*?\)"s => s"\1")  # [foo](@id bar) => foo
fredrikekre commented 10 months ago

For regex 2 and 3 it make sense, I think. Do you want to submit a PR? You can probably find some tests for these replacements that you can augment too.

kbarros commented 8 months ago

After some investigation, I would propose these three modified regexes:

repls = []
push!(repls, r"\[([^]]+?)\]\(@ref\)"s => s"\1")     # [foo](@ref) => foo
push!(repls, r"\[([^]]+?)\]\(@ref .*?\)"s => s"\1") # [foo](@ref bar) => foo
push!(repls, r"\[([^]]+?)\]\(@id .*?\)"s => s"\1")  # [foo](@id bar) => foo

In addition to including the trailing s (which allows the match to cross between lines, https://perldoc.perl.org/perlre#Modifiers) I have also replaced (.*?) with ([^]]+?), which excludes the character ] from the matched ID within brackets.

These have the following behavior:

content = """
    # # [Example](@id example-id)
    # [foo](@ref), [bar](@ref bbaarr)
    x = 1
    """
for repl in repls
    content = replace(content, repl)
end
@assert content == """
    # # Example
    # foo, bar
    x = 1
    """

content = """
    # # [Example](@id example-id)
    #
    # [This is a long example which
    # wraps a line](@ref)
    #
    # [In this case the](@ref reference also
    # wraps a line)
    #    
    # x = 1
    """
for repl in repls
    content = replace(content, repl)
end
@assert content == """
    # # Example
    #
    # This is a long example which
    # wraps a line
    #
    # In this case the
    #    
    # x = 1
    """