diff --git a/.travis.yml b/.travis.yml index f28afbab4..f32b0b528 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ after_success: jobs: include: - stage: "Documentation" - julia: 1.0 + julia: 1.2 os: linux script: - julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); diff --git a/Project.toml b/Project.toml index 0dc04958e..746d76990 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "JuDoc" uuid = "4ca9428c-4c75-11e9-2efb-bf5cb6c1e8f8" authors = ["Thibaut Lienart "] -version = "0.3.2" +version = "0.3.3" [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" diff --git a/src/JuDoc.jl b/src/JuDoc.jl index 8f618c69f..1487df742 100644 --- a/src/JuDoc.jl +++ b/src/JuDoc.jl @@ -12,7 +12,7 @@ import LiveServer using DocStringExtensions: SIGNATURES, TYPEDEF -export serve, publish, cleanpull, newsite, optimize +export serve, publish, cleanpull, newsite, optimize, jd2html # ----------------------------------------------------------------------------- # @@ -114,4 +114,18 @@ include("misc_html.jl") # ERROR TYPES include("error_types.jl") +""" +$SIGNATURES + +Return the HTML corresponding to a JuDoc-Markdown string. +""" +function jd2html(st::AbstractString)::String + def_GLOBAL_PAGE_VARS!() + def_GLOBAL_LXDEFS!() + CUR_PATH[] = "index.md" + m, v = convert_md(st * EOS, collect(values(GLOBAL_LXDEFS))) + h = convert_html(m, v) + return h +end + end # module diff --git a/src/converter/fixer.jl b/src/converter/fixer.jl index 25b4e7f91..e1248a6f5 100644 --- a/src/converter/fixer.jl +++ b/src/converter/fixer.jl @@ -56,7 +56,7 @@ function find_and_fix_md_links(hs::String)::String end end # move the head after the match - head = nextind(hs, m.offset + length(m.match) - 1) + head = nextind(hs, m.offset + lastindex(m.match) - 1) end strlen = lastindex(hs) (head < strlen) && write(h, subs(hs, head, strlen)) diff --git a/src/converter/html_blocks.jl b/src/converter/html_blocks.jl index 93259e465..04838b328 100644 --- a/src/converter/html_blocks.jl +++ b/src/converter/html_blocks.jl @@ -32,7 +32,7 @@ end """ $(SIGNATURES) -Helper function to process an individual block when the block is a `HIsDef` such as `{{ ifdef +Helper function to process an individual block when the block is a `HIsDef` such as `{{ isdef author }} {{ fill author }} {{ end }}`. Which checks if a variable exists and if it does, applies something. """ diff --git a/src/converter/md.jl b/src/converter/md.jl index 2b45c138b..a38cdf810 100644 --- a/src/converter/md.jl +++ b/src/converter/md.jl @@ -35,7 +35,6 @@ function convert_md(mds::String, pre_lxdefs::Vector{LxDef}=Vector{LxDef}(); #> 1. Tokenize tokens = find_tokens(mds, MD_TOKENS, MD_1C_TOKENS) fn_refs = validate_footnotes!(tokens) - #> 1b. Find indented blocks tokens = find_indented_blocks(tokens, mds) @@ -290,11 +289,18 @@ function convert_inter_html(ihtml::AS, !(hasli2) && (c2b ≤ strlen - 4) && ihtml[c2a:c2b] == "

" && (δ2 = 4) # write whatever is at the front, skip the extra space if still present - δ1 = ifelse(iszero(δ1) && !hasli1, 1, δ1) - prev = (m.offset - δ1 > 0) ? prevind(ihtml, m.offset - δ1) : 0 + prev = prevind(ihtml, m.offset - δ1) + if prev > 0 + prev -= ifelse(ihtml[prev] == ' ', 1, 0) + else + prev = 0 + end (head ≤ prev) && write(htmls, subs(ihtml, head:prev)) # move head appropriately - head = iend + δ2 + 1 + head = iend + δ2 + if head ≤ strlen + head += ifelse(ihtml[head] in (' ', '>'), 1, 0) + end # store the resolved block write(htmls, convert_block(blocks[i], lxcontext)) end diff --git a/src/converter/md_blocks.jl b/src/converter/md_blocks.jl index 2749946c5..13374fa82 100644 --- a/src/converter/md_blocks.jl +++ b/src/converter/md_blocks.jl @@ -123,7 +123,9 @@ $(SIGNATURES) Helper function for the code block case of `convert_block`. """ function convert_code_block(ss::SubString)::String - m = match(r"```([a-z-]*)(\:[a-zA-Z\\\/-_\.]+)?\s*\n?((?:.|\n)*)```", ss) + fencer = ifelse(startswith(ss, "`````"), "`````", "```") + reg = Regex("$fencer([a-z-]*)(\\:[a-zA-Z\\\\\\/-_\\.]+)?\\s*\\n?((?:.|\\n)*)$fencer") + m = match(reg, ss) lang = m.captures[1] rpath = m.captures[2] code = m.captures[3] @@ -187,7 +189,9 @@ function convert_indented_code_block(ss::SubString)::String # 1. decrease indentation of all lines (either frontal \n\t or \n⎵⎵⎵⎵) code = replace(ss, r"\n(?:\t| {4})" => "\n") # 2. return; lang is a LOCAL_PAGE_VARS that is julia by default and can be set - return html_code(strip(code), "{{fill lang}}") + sc = strip(code) + isempty(sc) && return "" + return html_code(sc, "{{fill lang}}") end """ diff --git a/src/parser/md_tokens.jl b/src/parser/md_tokens.jl index 1de6b4a64..c986dc0c4 100644 --- a/src/parser/md_tokens.jl +++ b/src/parser/md_tokens.jl @@ -40,7 +40,15 @@ const MD_TOKENS = Dict{Char, Vector{TokenFinder}}( ], ']' => [ isexactly("]: ") => :LINK_DEF, ], - '\\' => [ isexactly("\\{") => :INACTIVE, # See note [^1] + '\\' => [ # -- special characters, see `find_special_chars` in ocblocks + isexactly("\\\\") => :CHAR_LINEBREAK, # -->
+ isexactly("\\", (' ',)) => :CHAR_BACKSPACE, # --> \ + isexactly("\\*") => :CHAR_ASTERISK, # --> * + isexactly("\\_") => :CHAR_UNDERSCORE,# --> _ + isexactly("\\`") => :CHAR_BACKTICK, # --> ` + isexactly("\\@") => :CHAR_ATSIGN, # --> @ + # -- maths + isexactly("\\{") => :INACTIVE, # See note [^1] isexactly("\\}") => :INACTIVE, # See note [^1] isexactly("\\\$") => :INACTIVE, # See note [^1] isexactly("\\[") => :MATH_C_OPEN, # \[ ... @@ -51,10 +59,8 @@ const MD_TOKENS = Dict{Char, Vector{TokenFinder}}( isexactly("\\end{equation}") => :MATH_D_CLOSE, isexactly("\\begin{eqnarray}") => :MATH_EQA_OPEN, isexactly("\\end{eqnarray}") => :MATH_EQA_CLOSE, + # -- latex isexactly("\\newcommand") => :LX_NEWCOMMAND, - isexactly("\\\\") => :CHAR_LINEBREAK, # will be replaced by
- isexactly("\\", (' ',)) => :CHAR_BACKSPACE, # will be replaced by \ - isexactly("\\`") => :CHAR_BACKTICK, # will be replaced by ` incrlook((_, c) -> α(c)) => :LX_COMMAND, # \command⎵* ], '@' => [ isexactly("@def", (' ',)) => :MD_DEF_OPEN, # @def var = ... @@ -79,7 +85,9 @@ const MD_TOKENS = Dict{Char, Vector{TokenFinder}}( '`' => [ isexactly("`", ('`',), false) => :CODE_SINGLE, # `⎵ isexactly("``",('`',), false) => :CODE_DOUBLE, # ``⎵* isexactly("```", SPACER) => :CODE_TRIPLE, # ```⎵* - incrlook(is_language) => :CODE_LANG, # ```lang* + isexactly("`````", SPACER) => :CODE_PENTA, # `````⎵* + is_language() => :CODE_LANG, # ```lang* + is_language2() => :CODE_LANG2, # `````lang* ], ) # end dict #= NOTE @@ -134,7 +142,9 @@ const MD_OCB = [ # --------------------------------------------------------------------- OCProto(:COMMENT, :COMMENT_OPEN, (:COMMENT_CLOSE,), false), OCProto(:CODE_BLOCK_LANG, :CODE_LANG, (:CODE_TRIPLE,), false), + OCProto(:CODE_BLOCK_LANG, :CODE_LANG2, (:CODE_PENTA,), false), OCProto(:CODE_BLOCK, :CODE_TRIPLE, (:CODE_TRIPLE,), false), + OCProto(:CODE_BLOCK, :CODE_PENTA, (:CODE_PENTA,), false), OCProto(:CODE_BLOCK_IND, :LR_INDENT, (:LINE_RETURN,), false), OCProto(:CODE_INLINE, :CODE_DOUBLE, (:CODE_DOUBLE,), false), OCProto(:CODE_INLINE, :CODE_SINGLE, (:CODE_SINGLE,), false), @@ -217,3 +227,12 @@ MATH_BLOCKS_NAMES List of names of maths environments. """ const MATH_BLOCKS_NAMES = [e.name for e ∈ MD_OCB_MATH] + + +""" +MD_OCB_NO_INNER + +List of names of blocks which will deactivate any block contained within them. +See [`find_all_ocblocks`](@ref). +""" +const MD_OCB_NO_INNER = vcat(MD_OCB_ESC, MATH_BLOCKS_NAMES, :LXB) diff --git a/src/parser/ocblocks.jl b/src/parser/ocblocks.jl index a472c3fc9..e2168c2f6 100644 --- a/src/parser/ocblocks.jl +++ b/src/parser/ocblocks.jl @@ -80,15 +80,16 @@ function find_all_ocblocks(tokens::Vector{Token}, ocplist::Vector{OCProto}; inma append!(ocbs_all, ocbs) end # it may happen that a block is contained in a larger escape block. - # For instance this can happen if there is a code block in an escape block (see e.g. #151). - # To fix this, we browse the escape blocks in backwards order and check if there is any other - # block within it. + # For instance this can happen if there is a code block in an escape block + # (see e.g. #151) or if there's indentation in a math block. + # To fix this, we browse the escape blocks in backwards order and check if + # there is any other block within it. i = length(ocbs_all) active = ones(Bool, i) all_heads = from.(ocbs_all) while i > 1 cur_ocb = ocbs_all[i] - if active[i] && cur_ocb.name ∈ MD_OCB_ESC + if active[i] && cur_ocb.name ∈ MD_OCB_NO_INNER # find all blocks within the span of this block, deactivate all of them cur_head = all_heads[i] cur_tail = to(cur_ocb) @@ -221,6 +222,9 @@ function find_special_chars(tokens::Vector{Token}) spch = Vector{HTML_SPCH}() isempty(tokens) && return spch for τ in tokens + τ.name == :CHAR_ASTERISK && push!(spch, HTML_SPCH(τ.ss, "*")) + τ.name == :CHAR_UNDERSCORE && push!(spch, HTML_SPCH(τ.ss, "_")) + τ.name == :CHAR_ATSIGN && push!(spch, HTML_SPCH(τ.ss, "@")) τ.name == :CHAR_BACKSPACE && push!(spch, HTML_SPCH(τ.ss, "\")) τ.name == :CHAR_BACKTICK && push!(spch, HTML_SPCH(τ.ss, "`")) τ.name == :CHAR_LINEBREAK && push!(spch, HTML_SPCH(τ.ss, "
")) diff --git a/src/parser/tokens.jl b/src/parser/tokens.jl index 56d86c4c1..1a15b1e76 100644 --- a/src/parser/tokens.jl +++ b/src/parser/tokens.jl @@ -158,16 +158,16 @@ julia> s ``` """ function isexactly(refstring::AS, follow::NTuple{K,Char} where K = (), - isfollowed=true)::Tuple{Int,Bool,Function} + isfollowed=true)::Tuple{Int,Bool,Function,Nothing} # number of steps from the start character steps = prevind(refstring, lastindex(refstring)) # no offset (don't check next character) - isempty(follow) && return (steps, false, s -> (s == refstring)) + isempty(follow) && return (steps, false, s -> (s == refstring), nothing) # include next char for verification (--> offset of 1) steps = nextind(refstring, steps) - # verification function + # verification function; we want either (false false or true true)) λ(s) = (chop(s) == refstring) && !xor(isfollowed, s[end] ∈ follow) - return (steps, true, λ) + return (steps, true, λ, nothing) end @@ -193,7 +193,7 @@ a case where from a start character we lazily accept the next sequence of charac soon as a character fails to verify `λ(c)`. See also [`isexactly`](@ref). """ -incrlook(λ::Function) = (0, false, λ) +incrlook(λ::Function, validator=nothing) = (0, false, λ, validator) """ $(SIGNATURES) @@ -210,12 +210,33 @@ In combination with `incrlook`, checks to see if we have something that looks li backtick followed by a valid combination of letter defining a language. Triggering char is a first backtick. """ -function is_language(i::Int, c::Char) - i < 3 && return c=='`' # ` followed by `` forms the opening ``` - i == 3 && return α(c) # must be a letter - return α(c, ('-',)) # can be a letter or a hyphen, for instance ```objective-c +is_language() = incrlook(_is_language, _validate_language) + +function _is_language(i::Int, c::Char) + i < 3 && return c == '`' # ` followed by `` forms the opening ``` + i == 3 && return α(c) # must be a letter + return α(c, ('-',)) # can be a letter or a hyphen, for instance ```objective-c +end + +_validate_language(stack::AS) = match(r"^```[a-zA-Z]", stack) !== nothing + + +""" +$(SIGNATURES) + +See [`is_language`](@ref) but with 5 ticks. +""" +is_language2() = incrlook(_is_language2, _validate_language2) + +function _is_language2(i::Int, c::Char) + i < 5 && return c == '`' + i == 5 && return α(c) + return α(c, ('-',)) end +_validate_language2(stack::AS) = match(r"^`````[a-zA-Z]", stack) !== nothing + + """ $(SIGNATURES) @@ -242,7 +263,7 @@ TokenFinder Convenience type to define tokens. The Tuple comes from the output of functions such as [`isexactly`](@ref). """ -const TokenFinder = Pair{Tuple{Int,Bool,Function},Symbol} +const TokenFinder = Pair{Tuple{Int,Bool,Function,Union{Nothing,Function}},Symbol} """ @@ -277,7 +298,7 @@ function find_tokens(str::AS, # 2. is it one of the multi-char token? elseif haskey(tokens_dict, head) - for ((steps, offset, λ), case) ∈ tokens_dict[head] + for ((steps, offset, λ, ν), case) ∈ tokens_dict[head] #= ↪ steps = length of the lookahead, 0 if incremental ↪ offset = if we need to check one character 'too much' @@ -316,6 +337,10 @@ function find_tokens(str::AS, end endchar_idx = prevind(str, nextchar_idx) if endchar_idx > head_idx + # if the validator is unhappy, don't move the head and + # consider other rules + ν === nothing || ν(stack) || continue + # otherwise move ahead after the match push!(tokens, Token(case, stack)) head_idx = endchar_idx end diff --git a/test/converter/eval.jl b/test/converter/eval.jl index 68d4c28f5..6a9496ba9 100644 --- a/test/converter/eval.jl +++ b/test/converter/eval.jl @@ -23,8 +23,13 @@ @test isfile(opath) @test read(opath, String) == "25" - @test occursin("code:
a = 5\nprint(a^2)
", h) - @test occursin("then:
25
done.", h) + @test isapproxstr(h, raw""" +

Simple code: +

a = 5
+            print(a^2)
+ then: +
25
+ done.

""") end @testset "Eval (errs)" begin @@ -39,7 +44,11 @@ end done. """ * J.EOS |> seval - @test occursin("code:
a = 5\nprint(a**2)\n
done.", h) + @test isapproxstr(h, raw""" +

Simple code: +

a = 5
+            print(a**2)
+ done.

""") end @testset "Eval (rinput)" begin @@ -62,8 +71,13 @@ end @test isfile(opath) @test read(opath, String) == "25" - @test occursin("code:
a = 5\nprint(a^2)
", h) - @test occursin("then:
25
done.", h) + @test isapproxstr(h, """ +

Simple code: +

a = 5
+            print(a^2)
+ then: +
25
+ done.

""") # ------------ @@ -88,8 +102,12 @@ end @test isfile(opath) @test read(opath, String) == "25" - @test occursin("code:
a = 5\nprint(a^2)
", h) - @test occursin("then:
25
done.", h) + @test isapproxstr(h, """ +

Simple code: +

a = 5
+            print(a^2)
+ then: +
25
done.

""") end @testset "Eval (module)" begin diff --git a/test/converter/hyperref.jl b/test/converter/hyperref.jl index 37fc974f5..6a538a8cc 100644 --- a/test/converter/hyperref.jl +++ b/test/converter/hyperref.jl @@ -32,16 +32,38 @@ h = J.convert_html(m, J.PageVars()) - @test occursin("\\[ x = x \\]", h) - @test occursin("
  • Amari and Douglas: Why Natural Gradient, 1998.

    \n
  • ", h) - @test occursin("
  • Bardenet, Doucet and Holmes: On Markov Chain Monte Carlo Methods for Tall Data, 2017.

    \n
  • ", h) - - @test occursin("(1)", h) - @test occursin("Amari and Douglas., 1998", h) - @test occursin("(Bardenet et al., 2017)", h) - @test occursin("Amari and Douglas., 1998, Bardenet et al., 2017", h) + @test isapproxstr(h, """ +

    + Some string + \\[ x = x \\] + then as per Amari and Douglas., 1998 also this (Bardenet et al., 2017) and + Amari and Douglas., 1998, Bardenet et al., 2017 + Reference to equation: (1) . +

    +

    + Then maybe some text etc. +

    + + """) end +@testset "Href-space" begin + J.CUR_PATH[] = "index.md" + st = raw""" + A + $$ x = x \label{eq 1}$$ + B + C \eqref{eq 1}. + and *B $E$*. + """ * J.EOS + h = st |> seval + @test occursin(raw"""\[ x = x \]""", h) + @test occursin(raw"""(1).""", h) + @test occursin(raw"""B \(E\).""", h) +end @testset "Eqref" begin st = raw""" diff --git a/test/converter/markdown.jl b/test/converter/markdown.jl index eac72fe93..57ccd2981 100644 --- a/test/converter/markdown.jl +++ b/test/converter/markdown.jl @@ -62,10 +62,16 @@ end lxcontext = J.LxContext(lxcoms, lxdefs, braces) @test J.convert_block(blocks2insert[1], lxcontext) == "
    .
    " - @test J.convert_block(blocks2insert[2], lxcontext) == "\\[\\begin{array}{c} \\sin^2(x)+\\cos^2(x) &=& 1\\end{array}\\]" + @test isapproxstr(J.convert_block(blocks2insert[2], lxcontext), "\\[\\begin{array}{c} \\sin^2(x)+\\cos^2(x) &=& 1\\end{array}\\]") hstring = J.convert_inter_html(inter_html, blocks2insert, lxcontext) - @test hstring == "

    ab

    .
    \\[\\begin{array}{c} \\sin^2(x)+\\cos^2(x) &=& 1\\end{array}\\]

    \n" + @test isapproxstr(hstring, raw""" +

    + ab

    .
    + \[\begin{array}{c} + \sin^2(x)+\cos^2(x) &=& 1 + \end{array}\] +

    """) end @@ -85,13 +91,21 @@ end inter_md, mblocks = steps[:inter_md] inter_html, = steps[:inter_html] - @test inter_md == "text A1 text A2 ##JDINSERT## and\n ##JDINSERT## \n text C1 ##JDINSERT## text C2\n then ##JDINSERT## .\n" + @test isapproxstr(inter_md, """ + text A1 text A2 ##JDINSERT## and + ##JDINSERT## + text C1 ##JDINSERT## text C2 + then ##JDINSERT## .""") - @test inter_html == "

    text A1 text A2 ##JDINSERT## and ##JDINSERT## text C1 ##JDINSERT## text C2 then ##JDINSERT## .

    \n" + @test isapproxstr(inter_html, """

    text A1 text A2 ##JDINSERT## and ##JDINSERT## text C1 ##JDINSERT## text C2 then ##JDINSERT## .

    """) lxcontext = J.LxContext(lxcoms, lxdefs, braces) hstring = J.convert_inter_html(inter_html, blocks2insert, lxcontext) - @test hstring == "

    text A1 text A2 blah and \nescape B1\n text C1 \\(\\mathrm{ b}\\) text C2 then part1: AA and part2: BB.

    \n" + @test isapproxstr(hstring, """ +

    text A1 text A2 blah and + escape B1 + text C1 \\(\\mathrm{ b}\\) text C2 + then part1: AA and part2: BB.

    """) end diff --git a/test/global/cases1.jl b/test/global/cases1.jl index 3fb7ecaba..2f0d62aef 100644 --- a/test/global/cases1.jl +++ b/test/global/cases1.jl @@ -34,6 +34,8 @@ end \newcommand{\com}[1]{◲!#1◲} \com{A} """ * J.EOS + steps = st |> explore_md_steps + @test steps[:inter_md].inter_md == "\n ##JDINSERT## \n\n ##JDINSERT## \n" @test st |> conv == "⭒A⭒\n◲A◲" end @@ -197,4 +199,4 @@ end J.def_GLOBAL_LXDEFS!() r = st |> conv @test occursin("here done.", r) -end +end diff --git a/test/global/ordering.jl b/test/global/ordering.jl new file mode 100644 index 000000000..a934b6ff2 --- /dev/null +++ b/test/global/ordering.jl @@ -0,0 +1,125 @@ +# Following multiple issues over time with ordering, this attempts to have +# bunch of test cases where it's clear in what order things are tokenized / found + +@testset "Ordering-1" begin + st = raw""" + A + + B + """ * J.EOS + steps = st |> explore_md_steps + blocks, = steps[:ocblocks] + @test length(blocks) == 1 + @test blocks[1].name == :COMMENT + @test isapproxstr(st |> seval, """ +

    A

    +

    B

    + """) +end + +@testset "Ordering-2" begin + st = raw""" + A + \begin{eqnarray} + 1 + 1 &=& 2 + \end{eqnarray} + B + """ * J.EOS + steps = st |> explore_md_steps + blocks, = steps[:ocblocks] + @test length(blocks) == 1 + @test blocks[1].name == :MATH_EQA + + @test isapproxstr(st |> seval, raw""" +

    A + \[\begin{array}{c} + 1 + 1 &=& 2 + \end{array}\] + B

    """) +end + +@testset "Ordering-3" begin + st = raw""" + A + \begin{eqnarray} + 1 + 1 &=& 2 + \end{eqnarray} + B + + C + """ * J.EOS + steps = st |> explore_md_steps + blocks, = steps[:ocblocks] + @test length(blocks) == 2 + @test blocks[1].name == :COMMENT + @test blocks[2].name == :MATH_EQA + + @test isapproxstr(st |> seval, raw""" +

    A + \[\begin{array}{c} + 1 + 1 &=& 2 + \end{array}\] + B

    +

    C

    """) +end + +@testset "Ordering-4" begin + st = raw""" + \newcommand{\eqa}[1]{\begin{eqnarray}#1\end{eqnarray}} + A + \eqa{ + B + } + C + """ * J.EOS + steps = st |> explore_md_steps + blocks, = steps[:ocblocks] + + @test length(blocks) == 3 + @test all(getproperty.(blocks, :name) .== :LXB) + + @test isapproxstr(st |> seval, raw""" +

    A + \[\begin{array}{c} + B + \end{array}\] + C

    """) +end + +@testset "Ordering-5" begin + st = raw""" + A [❗️_ongoing_ ] C + """ * J.EOS + @test isapproxstr(st |> seval, raw""" +

    A [❗️ongoing ] C

    + """) + st = raw""" + 0 + * A + * B [❗️_ongoing_ ] + C + """ * J.EOS + @test isapproxstr(st |> seval, raw""" +

    0

    + +

    C

    + """) +end diff --git a/test/parser/markdown-extra.jl b/test/parser/markdown-extra.jl new file mode 100644 index 000000000..951529172 --- /dev/null +++ b/test/parser/markdown-extra.jl @@ -0,0 +1,76 @@ +@testset "Bold x*" begin # issue 223 + h = raw"**x\***" * J.EOS |> seval + @test h == "

    x*

    \n" + + h = raw"_x\__" * J.EOS |> seval + @test h == "

    x_

    \n" +end + +@testset "Bold code" begin # issue 222 + h = raw"""A **`master`** B.""" |> jd2html + @test h == "

    A master B.

    \n" +end + +@testset "Tickssss" begin # issue 219 + st = raw"""A `B` C""" * J.EOS + tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS) + @test tokens[1].name == :CODE_SINGLE + @test tokens[2].name == :CODE_SINGLE + + st = raw"""A ``B`` C""" * J.EOS + tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS) + @test tokens[1].name == :CODE_DOUBLE + @test tokens[2].name == :CODE_DOUBLE + + st = raw"""A ``` B ``` C""" * J.EOS + tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS) + @test tokens[1].name == :CODE_TRIPLE + @test tokens[2].name == :CODE_TRIPLE + + st = raw"""A ````` B ````` C""" * J.EOS + tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS) + @test tokens[1].name == :CODE_PENTA + @test tokens[2].name == :CODE_PENTA + + st = raw"""A ```b B ``` C""" * J.EOS + tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS) + @test tokens[1].name == :CODE_LANG + @test tokens[2].name == :CODE_TRIPLE + + st = raw"""A `````b B ````` C""" * J.EOS + tokens = J.find_tokens(st, J.MD_TOKENS, J.MD_1C_TOKENS) + @test tokens[1].name == :CODE_LANG2 + @test tokens[2].name == :CODE_PENTA + + h = raw""" + A + `````markdown + B + ````` + C + """ |> jd2html + + @test isapproxstr(h, raw""" +

    A +

    B
    +            
    C

    + """) + + h = raw""" + A + `````markdown + ```julia + B + ``` + ````` + C + """ |> jd2html + @test isapproxstr(h, raw""" +

    A +

    ```julia
    +            B
    +            ```
    +            
    C

    + """) + +end diff --git a/test/runtests.jl b/test/runtests.jl index 0c0a29e3d..3a3712164 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,6 +16,7 @@ println("🍺") # PARSER folder println("PARSER/MD+LX") include("parser/markdown+latex.jl") +include("parser/markdown-extra.jl") include("parser/footnotes.jl") println("🍺") println("PARSER/HTML") @@ -29,7 +30,6 @@ include("converter/markdown2.jl") include("converter/markdown3.jl") include("converter/hyperref.jl") println("🍺") - println("CONVERTER/HTML") include("converter/html.jl") println("🍺") @@ -43,6 +43,7 @@ println("🍺") println("INTEGRATION") include("global/cases1.jl") include("global/cases2.jl") +include("global/ordering.jl") begin # create temp dir to do complete integration testing (has to be here in order diff --git a/test/test_utils.jl b/test/test_utils.jl index 0539c7cb7..3fa773048 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -78,6 +78,10 @@ function explore_md_steps(mds) inter_html = J.md2html(inter_md; stripp=false) steps[:inter_html] = (inter_html=inter_html,) + lxcontext = J.LxContext(lxcoms, lxdefs, braces) + hstring = J.convert_inter_html(inter_html, mblocks, lxcontext) + steps[:hstring] = (hstring=hstring,) + return steps end