"Fossies" - the Fresh Open Source Software Archive

Member "julia-1.1.1/share/julia/stdlib/v1.1/Markdown/test/runtests.jl" (16 May 2019, 26924 Bytes) of package /linux/misc/julia-1.1.1-linux-i686.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Julia source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 # This file is a part of Julia. License is MIT: https://julialang.org/license
    2 
    3 using Test, Markdown
    4 import Markdown: MD, Paragraph, Header, Italic, Bold, LineBreak, plain, term, html, rst, Table, Code, LaTeX, Footnote
    5 import Base: show
    6 
    7 # Basics
    8 # Equality is checked by making sure the HTML output is
    9 # the same – the structure itself may be different.
   10 
   11 @test md"foo" == MD(Paragraph("foo"))
   12 @test md"foo *bar* baz" == MD(Paragraph(["foo ", Italic("bar"), " baz"]))
   13 @test md"foo _bar_ baz" == MD(Paragraph(["foo ", Italic("bar"), " baz"]))
   14 @test md"foo **bar** baz" == MD(Paragraph(["foo ", Bold("bar"), " baz"]))
   15 @test md"foo __bar__ baz" == MD(Paragraph(["foo ", Bold("bar"), " baz"]))
   16 @test md"""foo
   17 bar""" == MD(Paragraph(["foo bar"]))
   18 @test md"""foo\
   19 bar""" == MD(Paragraph(["foo", LineBreak(), "bar"]))
   20 
   21 @test md"#no title" == MD(Paragraph(["#no title"]))
   22 @test md"# title" == MD(Header{1}("title"))
   23 @test md"""
   24   #
   25   empty
   26   """ == MD(Header{1}(""), Paragraph("empty"))
   27 @test md"## section" == MD(Header{2}("section"))
   28 @test md"# title *foo* `bar` **baz**" ==
   29     MD(Header{1}(["title ", Italic("foo")," ",Code("bar")," ",Bold("baz")]))
   30 @test md"""
   31 h1
   32 ===""" == md"# h1"
   33 @test md"""
   34 h2
   35    ---""" == md"## h2"
   36 
   37 @test md"**foo *bar* baz**" == MD(Paragraph(Bold(["foo ", Italic("bar"), " baz"])))
   38 @test md"*foo **bar** baz*" == MD(Paragraph(Italic(["foo ", Bold("bar"), " baz"])))
   39 
   40 @test md"""```julia
   41 foo
   42 ```
   43 """ == MD(Code("julia", "foo"))
   44 
   45 @test md"foo ``bar`` baz" == MD(Paragraph(["foo ", LaTeX("bar"), " baz"]))
   46 
   47 @test md"""
   48 ```math
   49 ...
   50 ```
   51 """ == MD(LaTeX("..."))
   52 
   53 code_in_code = md"""
   54 ````
   55 ```
   56 ````
   57 """
   58 @test code_in_code == MD(Code("```"))
   59 @test plain(code_in_code) == "````\n```\n````\n"
   60 
   61 let text = "Foo ```bar` ``baz`` ```\n",
   62     md = Markdown.parse(text)
   63     @test text == Markdown.plain(md)
   64 end
   65 
   66 @test isempty(Markdown.parse("\r"))
   67 @test Markdown.parse("hello\r") == MD(Paragraph(["hello"]))
   68 @test Markdown.parse("hello\r*julia*") == MD(Paragraph(Any["hello ", Italic(Any["julia"])]))
   69 
   70 @test md"A footnote [^foo]." == MD(Paragraph(["A footnote ", Footnote("foo", nothing), "."]))
   71 
   72 @test md"[^foo]: footnote" == MD([Footnote("foo", Any[Paragraph(Any["footnote"])])])
   73 
   74 let text =
   75     """
   76     A paragraph with some footnotes,[^1] and another.[^note]
   77 
   78     [^1]: Footnote text for the first.
   79 
   80     [^note]: A longer footnote:
   81 
   82         Indented paragraphs are part of the footnote.
   83 
   84             some.code
   85 
   86         And *another* paragraph.
   87 
   88     This isn't part of the footnote.
   89     """,
   90     md = Markdown.parse(text)
   91     @test length(md.content) == 4
   92     @test isa(md.content[1], Markdown.Paragraph)
   93     @test isa(md.content[2], Markdown.Footnote)
   94     @test isa(md.content[3], Markdown.Footnote)
   95     @test isa(md.content[4], Markdown.Paragraph)
   96 
   97     @test md.content[2].id == "1"
   98     @test md.content[3].id == "note"
   99 
  100     @test length(md.content[3].text) == 4
  101 
  102     let expected =
  103             """
  104             A paragraph with some footnotes,[^1] and another.[^note]
  105 
  106             [^1]: Footnote text for the first.
  107 
  108             [^note]:
  109                 A longer footnote:
  110 
  111                 Indented paragraphs are part of the footnote.
  112 
  113                 ```
  114                 some.code
  115                 ```
  116 
  117                 And *another* paragraph.
  118 
  119 
  120             This isn't part of the footnote.
  121             """
  122         @test Markdown.plain(md) == expected
  123     end
  124     let expected =
  125             """
  126             A paragraph with some footnotes,[1]_ and another.[note]_
  127 
  128             .. [1] Footnote text for the first.
  129 
  130             .. [note]
  131                A longer footnote:
  132 
  133                Indented paragraphs are part of the footnote.
  134 
  135                .. code-block:: julia
  136 
  137                    some.code
  138 
  139                And *another* paragraph.
  140 
  141 
  142             This isn't part of the footnote.
  143             """
  144         @test Markdown.rst(md) == expected
  145     end
  146     let html = Markdown.html(md)
  147         @test occursin(",<a href=\"#footnote-1\" class=\"footnote\">[1]</a>", html)
  148         @test occursin(".<a href=\"#footnote-note\" class=\"footnote\">[note]</a>", html)
  149         @test occursin("<div class=\"footnote\" id=\"footnote-1\"><p class=\"footnote-title\">1</p>", html)
  150         @test occursin("<div class=\"footnote\" id=\"footnote-note\"><p class=\"footnote-title\">note</p>", html)
  151     end
  152     let latex = Markdown.latex(md)
  153         @test occursin(",\\footnotemark[1]", latex)
  154         @test occursin(".\\footnotemark[note]", latex)
  155         @test occursin("\n\\footnotetext[1]{Footnote text for", latex)
  156         @test occursin("\n\\footnotetext[note]{A longer footnote:\n", latex)
  157     end
  158 end
  159 
  160 let doc = md"""
  161 * one
  162 * two
  163 
  164 1. pirate
  165 2. ninja
  166 3. zombie"""
  167     @test isa(doc.content[1], Markdown.List)
  168     @test isa(doc.content[2], Markdown.List)
  169     @test doc.content[1].items[1][1].content[1] == "one"
  170     @test doc.content[1].items[2][1].content[1] == "two"
  171     @test doc.content[2].items[1][1].content[1] == "pirate"
  172     @test doc.content[2].items[2][1].content[1] == "ninja"
  173     @test doc.content[2].items[3][1].content[1] == "zombie"
  174 end
  175 
  176 let doc = Markdown.parse(
  177         """
  178         A paragraph...
  179         - one
  180         - two
  181            * three
  182            * four
  183         ... another paragraph.
  184         """
  185     )
  186     @test length(doc.content) === 3
  187     @test isa(doc.content[1], Markdown.Paragraph)
  188     @test isa(doc.content[2], Markdown.List)
  189     @test isa(doc.content[3], Markdown.Paragraph)
  190 
  191     @test length(doc.content[2].items) === 2
  192     @test doc.content[2].items[1][1].content[1] == "one"
  193     @test length(doc.content[2].items[2]) == 2
  194     @test doc.content[2].items[2][1].content[1] == "two"
  195 
  196     @test isa(doc.content[2].items[2][2], Markdown.List)
  197     @test length(doc.content[2].items[2][2].items) === 2
  198     @test doc.content[2].items[2][2].items[1][1].content[1] == "three"
  199     @test doc.content[2].items[2][2].items[2][1].content[1] == "four"
  200 end
  201 
  202 @test md"Foo [bar]" == MD(Paragraph("Foo [bar]"))
  203 @test md"Foo [bar](baz)" != MD(Paragraph("Foo [bar](baz)"))
  204 @test md"Foo \[bar](baz)" == MD(Paragraph("Foo [bar](baz)"))
  205 
  206 # Basic plain (markdown) output
  207 @test md"foo" |> plain == "foo\n"
  208 @test md"foo *bar* baz" |> plain == "foo *bar* baz\n"
  209 @test md"# title" |> plain == "# title\n"
  210 @test md"## section" |> plain == "## section\n"
  211 @test md"## section `foo`" |> plain == "## section `foo`\n"
  212 @test md"""Hello
  213 
  214 ---
  215 World""" |> plain == "Hello\n\n---\n\nWorld\n"
  216 @test md"[*a*](b)" |> plain == "[*a*](b)\n"
  217 @test md"""
  218 > foo
  219 >
  220 >   * bar
  221 >
  222 > ```
  223 > baz
  224 > ```""" |> plain == """> foo\n>\n>   * bar\n>\n> ```\n> baz\n> ```\n\n"""
  225 
  226 # Terminal (markdown) output
  227 
  228 # multiple whitespace is ignored
  229 @test sprint(term, md"a  b") == "  a b"
  230 @test sprint(term, md"[x](https://julialang.org)") == "  x (https://julialang.org)"
  231 @test sprint(term, md"[x](@ref)") == "  x"
  232 @test sprint(term, md"[x](@ref something)") == "  x"
  233 @test sprint(term, md"![x](https://julialang.org)") == "  (Image: x)"
  234 
  235 # enumeration is normalized
  236 let doc = Markdown.parse(
  237         """
  238         1. a
  239         3. b
  240         """
  241     )
  242     @test occursin("1. ", sprint(term, doc))
  243     @test occursin("2. ", sprint(term, doc))
  244     @test !occursin("3. ", sprint(term, doc))
  245 end
  246 
  247 # HTML output
  248 @test md"foo *bar* baz" |> html == "<p>foo <em>bar</em> baz</p>\n"
  249 @test md"something ***" |> html == "<p>something ***</p>\n"
  250 @test md"# h1## " |> html == "<h1>h1##</h1>\n"
  251 @test md"## h2 ### " |> html == "<h2>h2</h2>\n"
  252 @test md"###### h6" |> html == "<h6>h6</h6>\n"
  253 @test md"####### h7" |> html == "<p>####### h7</p>\n"
  254 @test md"   >" |> html == "<blockquote>\n</blockquote>\n"
  255 @test md"1. Hello" |> html == "<ol>\n<li><p>Hello</p>\n</li>\n</ol>\n"
  256 @test md"* World" |> html == "<ul>\n<li><p>World</p>\n</li>\n</ul>\n"
  257 @test md"# title *blah*" |> html == "<h1>title <em>blah</em></h1>\n"
  258 @test md"## title *blah*" |> html == "<h2>title <em>blah</em></h2>\n"
  259 @test md"<https://julialang.org>" |> html == """<p><a href="https://julialang.org">https://julialang.org</a></p>\n"""
  260 @test md"<mailto://a@example.com>" |> html == """<p><a href="mailto://a@example.com">mailto://a@example.com</a></p>\n"""
  261 @test md"<https://julialang.org/not a link>" |> html == "<p>&lt;https://julialang.org/not a link&gt;</p>\n"
  262 @test md"""<https://julialang.org/nota
  263 link>""" |> html == "<p>&lt;https://julialang.org/nota link&gt;</p>\n"
  264 @test md"""Hello
  265 
  266 ---
  267 World""" |> html == "<p>Hello</p>\n<hr />\n<p>World</p>\n"
  268 @test md"`escape</code>`" |> html == "<p><code>escape&lt;/code&gt;</code></p>\n"
  269 
  270 @test md"""
  271     code1
  272 
  273     code2
  274 """ |> html == "<pre><code>code1\n\ncode2</code></pre>\n" # single code block
  275 
  276 # @test md"""
  277 # - Foo
  278 #  ---
  279 # - Bar""" |> html == "<ul>\n<li>Foo</li>\n</ul>\n<hr />\n<ul>\n<li>Bar</li>\n</ul>\n"
  280 @test md"""
  281 h1
  282 ===
  283 h2
  284 ---
  285 not
  286 == =""" |> html == "<h1>h1</h1>\n<h2>h2</h2>\n<p>not &#61;&#61; &#61;</p>\n"
  287 
  288 # Latex output
  289 book = md"""
  290 # Title
  291 
  292 Some discussion
  293 
  294 > A quote
  295 
  296 ## Section *important*
  297 
  298 Some **bolded**
  299 
  300 - list1
  301 - list2
  302 """
  303 @test latex(book) == "\\section{Title}\nSome discussion\n\n\\begin{quote}\nA quote\n\n\\end{quote}\n\\subsection{Section \\emph{important}}\nSome \\textbf{bolded}\n\n\\begin{itemize}\n\\item list1\n\n\n\\item list2\n\n\\end{itemize}\n"
  304 table = md"""
  305  a | b
  306 ---|---
  307  1 | 2
  308 """
  309 @test latex(table) ==
  310     "\\begin{tabular}\n{r | r}\na & b \\\\\n\\hline\n1 & 2 \\\\\n\\end{tabular}\n"
  311 
  312 # mime output
  313 let out =
  314     @test sprint(show, "text/plain", book) ==
  315         "  Title\n  ≡≡≡≡≡≡≡\n\n  Some discussion\n\n  │  A quote\n\n  Section important\n  ===================\n\n  Some bolded\n\n    •    list1\n\n    •    list2"
  316     @test sprint(show, "text/markdown", book) ==
  317         """
  318         # Title
  319 
  320         Some discussion
  321 
  322         > A quote
  323 
  324 
  325         ## Section *important*
  326 
  327         Some **bolded**
  328 
  329           * list1
  330           * list2
  331         """
  332 end
  333 let out =
  334     """
  335     <div class="markdown"><h1>Title</h1>
  336     <p>Some discussion</p>
  337     <blockquote>
  338     <p>A quote</p>
  339     </blockquote>
  340     <h2>Section <em>important</em></h2>
  341     <p>Some <strong>bolded</strong></p>
  342     <ul>
  343     <li><p>list1</p>
  344     </li>
  345     <li><p>list2</p>
  346     </li>
  347     </ul>
  348     </div>"""
  349     @test sprint(show, "text/html", book) == out
  350 end
  351 let out =
  352     """
  353     \\section{Title}
  354     Some discussion
  355 
  356     \\begin{quote}
  357     A quote
  358 
  359     \\end{quote}
  360     \\subsection{Section \\emph{important}}
  361     Some \\textbf{bolded}
  362 
  363     \\begin{itemize}
  364     \\item list1
  365 
  366 
  367     \\item list2
  368 
  369     \\end{itemize}
  370     """
  371     @test sprint(show, "text/latex", book) == out
  372 end
  373 let out =
  374     """
  375     Title
  376     *****
  377 
  378 
  379     Some discussion
  380 
  381         A quote
  382 
  383 
  384     Section *important*
  385     ===================
  386 
  387 
  388     Some **bolded**
  389 
  390     * list1
  391     * list2
  392     """
  393     @test sprint(show, "text/rst", book) == out
  394 end
  395 
  396 # rst rendering
  397 for (input, output) in (
  398         md"foo *bar* baz"     => "foo *bar* baz\n",
  399         md"something ***"     => "something ***\n",
  400         md"# h1## "           => "h1##\n****\n\n",
  401         md"## h2 ### "        => "h2\n==\n\n",
  402         md"###### h6"         => "h6\n..\n\n",
  403         md"####### h7"        => "####### h7\n",
  404         md"   >"              => "    \n\n",
  405         md"1. Hello"          => "1. Hello\n",
  406         md"* World"           => "* World\n",
  407         md"``x + y``"         => ":math:`x + y`\n",
  408         md"# title *blah*"    => "title *blah*\n************\n\n",
  409         md"## title *blah*"   => "title *blah*\n============\n\n",
  410         md"[`x`](:func:`x`)"  => ":func:`x`\n",
  411         md"[`x`](:obj:`x`)"   => ":obj:`x`\n",
  412         md"[`x`](:ref:`x`)"   => ":ref:`x`\n",
  413         md"[`x`](:exc:`x`)"   => ":exc:`x`\n",
  414         md"[`x`](:class:`x`)" => ":class:`x`\n",
  415         md"[`x`](:const:`x`)" => ":const:`x`\n",
  416         md"[`x`](:data:`x`)"  => ":data:`x`\n",
  417         md"[`x`](:???:`x`)"   => "```x`` <:???:`x`>`_\n",
  418         md"[x](y)"            => "`x <y>`_\n",
  419     )
  420     @test rst(input) == output
  421 end
  422 
  423 # Interpolation / Custom types
  424 mutable struct Reference
  425     ref
  426 end
  427 
  428 ref(x) = Reference(x)
  429 
  430 ref(sum)
  431 
  432 show(io::IO, m::MIME"text/plain", r::Reference) =
  433     print(io, "$(r.ref) (see Julia docs)")
  434 
  435 sum_ref = md"Behaves like $(ref(sum))"
  436 @test plain(sum_ref) == "Behaves like sum (see Julia docs)\n"
  437 @test html(sum_ref) == "<p>Behaves like sum &#40;see Julia docs&#41;</p>\n"
  438 
  439 show(io::IO, m::MIME"text/html", r::Reference) =
  440     Markdown.withtag(io, :a, :href=>"test") do
  441         Markdown.htmlesc(io, Markdown.plaininline(r))
  442     end
  443 @test html(sum_ref) == "<p>Behaves like <a href=\"test\">sum &#40;see Julia docs&#41;</a></p>\n"
  444 
  445 @test md"""
  446 ````julia
  447 foo()
  448 ````""" == md"""
  449 ```julia
  450 foo()
  451 ```"""
  452 
  453 # GH tables
  454 @test md"""
  455     a  | b
  456     ---|---
  457     1  | 2""" == MD(Table(Any[["a","b"],
  458                               ["1","2"]], [:r, :r]))
  459 
  460 @test md"""
  461     | a  |  b | c |
  462     | :-- | --: | --- |
  463     | d`gh`hg | hgh**jhj**ge | f |""" == MD(Table(Any[["a","b","c"],
  464                                                       Any[["d",Code("gh"),"hg"],
  465                                                           ["hgh",Bold("jhj"),"ge"],
  466                                                           "f"]],
  467                                                   [:l, :r, :r]))
  468 @test md"""
  469 no|table
  470 no error
  471 """ == MD([Paragraph(Any["no|table no error"])])
  472 
  473 let t = """a   |   b
  474     :-- | --:
  475     1   |   2
  476     """
  477     @test Markdown.parse(t) == MD(Table(Any[Any["a", "b"], Any["1", "2"]], [:l, :r]))
  478 end
  479 
  480 let text =
  481     """
  482     | a   |   b |
  483     |:--- | ---:|
  484     | 1   |   2 |
  485     """,
  486     table = Markdown.parse(text)
  487     @test text == Markdown.plain(table)
  488 end
  489 let text =
  490     """
  491     | Markdown | Table |  Test |
  492     |:-------- |:-----:| -----:|
  493     | foo      | `bar` | *baz* |
  494     | `bar`    |  baz  | *foo* |
  495     """,
  496     table = Markdown.parse(text)
  497     @test text == Markdown.plain(table)
  498 end
  499 let text =
  500     """
  501     | a        |   b |
  502     |:-------- | ---:|
  503     | `x \\| y` |   2 |
  504     """,
  505     table = Markdown.parse(text)
  506     @test text == Markdown.plain(table)
  507 end
  508 
  509 # LaTeX extension
  510 let in_dollars =
  511     """
  512     We have \$x^2 < x\$ whenever:
  513 
  514     \$|x| < 1\$
  515 
  516     etc.
  517     """,
  518     in_backticks =
  519     """
  520     We have ``x^2 < x`` whenever:
  521 
  522     ```math
  523     |x| < 1
  524     ```
  525 
  526     etc.
  527     """,
  528     out_plain =
  529     """
  530     We have \$x^2 < x\$ whenever:
  531 
  532     \$\$
  533     |x| < 1
  534     \$\$
  535 
  536     etc.
  537     """,
  538     out_rst =
  539     """
  540     We have :math:`x^2 < x` whenever:
  541 
  542     .. math::
  543 
  544         |x| < 1
  545 
  546     etc.
  547     """,
  548     out_latex =
  549     """
  550     We have \$x^2 < x\$ whenever:
  551 
  552     \$\$|x| < 1\$\$
  553     etc.
  554 
  555     """,
  556     dollars   = Markdown.parse(in_dollars),
  557     backticks = Markdown.parse(in_backticks),
  558     latex_doc = MD(
  559         Any[Paragraph(Any["We have ", LaTeX("x^2 < x"), " whenever:"]),
  560             LaTeX("|x| < 1"),
  561             Paragraph(Any["etc."])
  562     ])
  563 
  564     @test out_plain == Markdown.plain(dollars)
  565     @test out_plain == Markdown.plain(backticks)
  566 
  567     @test out_rst   == Markdown.rst(dollars)
  568     @test out_rst   == Markdown.rst(backticks)
  569 
  570     @test out_latex == Markdown.latex(dollars)
  571     @test out_latex == Markdown.latex(backticks)
  572 
  573     @test latex_doc == dollars
  574     @test latex_doc == backticks
  575 end
  576 
  577 # Nested backticks for inline code and math.
  578 let t_1 = "`code` ``math`` ```code``` ````math```` `````code`````",
  579     t_2 = "`` `math` `` ``` `code` ``code`` ``` ```` `math` ``math`` ```math``` ````",
  580     t_3 = "`` ` `` ``` `` ` `` ` ` ```",
  581     t_4 = """`code
  582     over several
  583     lines` ``math
  584     over several
  585     lines`` ``math with
  586     ` some extra ` ` backticks`
  587     ``""",
  588     t_5 = "``code at end of string`",
  589     t_6 = "```math at end of string``"
  590     @test Markdown.parse(t_1) == MD(Paragraph([
  591         Code("code"),
  592         " ",
  593         LaTeX("math"),
  594         " ",
  595         Code("code"),
  596         " ",
  597         LaTeX("math"),
  598         " ",
  599         Code("code"),
  600     ]))
  601     @test Markdown.parse(t_2) == MD(Paragraph([
  602         LaTeX("`math`"),
  603         " ",
  604         Code("`code` ``code``"),
  605         " ",
  606         LaTeX("`math` ``math`` ```math```"),
  607     ]))
  608     @test Markdown.parse(t_3) == MD(Paragraph([
  609         LaTeX("`"),
  610         " ",
  611         Code("`` ` `` ` `"),
  612     ]))
  613     @test Markdown.parse(t_4) == MD(Paragraph([
  614         Code("code over several lines"),
  615         " ",
  616         LaTeX("math over several lines"),
  617         " ",
  618         LaTeX("math with ` some extra ` ` backticks`")
  619     ]))
  620     @test Markdown.parse(t_5) == MD(Paragraph([
  621         "`",
  622         Code("code at end of string"),
  623     ]))
  624     @test Markdown.parse(t_6) == MD(Paragraph([
  625         "`",
  626         LaTeX("math at end of string"),
  627     ]))
  628 end
  629 
  630 # Admonitions.
  631 let t_1 =
  632         """
  633         # Foo
  634 
  635         !!! note
  636 
  637         !!! warning "custom title"
  638 
  639         ## Bar
  640 
  641         !!! danger ""
  642 
  643         !!!
  644         """,
  645     t_2 =
  646         """
  647         !!! note
  648             foo bar baz
  649 
  650         !!! warning "custom title"
  651             - foo
  652             - bar
  653             - baz
  654 
  655             foo bar baz
  656 
  657         !!! danger ""
  658 
  659             ```
  660             foo
  661             ```
  662 
  663                 bar
  664 
  665             # baz
  666         """,
  667     m_1 = Markdown.parse(t_1),
  668     m_2 = Markdown.parse(t_2)
  669 
  670     # Content Tests.
  671 
  672     @test isa(m_1.content[2], Markdown.Admonition)
  673     @test m_1.content[2].category == "note"
  674     @test m_1.content[2].title == "Note"
  675     @test m_1.content[2].content == []
  676 
  677     @test isa(m_1.content[3], Markdown.Admonition)
  678     @test m_1.content[3].category == "warning"
  679     @test m_1.content[3].title == "custom title"
  680     @test m_1.content[3].content == []
  681 
  682     @test isa(m_1.content[5], Markdown.Admonition)
  683     @test m_1.content[5].category == "danger"
  684     @test m_1.content[5].title == ""
  685     @test m_1.content[5].content == []
  686 
  687     @test isa(m_1.content[6], Markdown.Paragraph)
  688 
  689     @test isa(m_2.content[1], Markdown.Admonition)
  690     @test m_2.content[1].category == "note"
  691     @test m_2.content[1].title == "Note"
  692     @test isa(m_2.content[1].content[1], Markdown.Paragraph)
  693 
  694     @test isa(m_2.content[2], Markdown.Admonition)
  695     @test m_2.content[2].category == "warning"
  696     @test m_2.content[2].title == "custom title"
  697     @test isa(m_2.content[2].content[1], Markdown.List)
  698     @test isa(m_2.content[2].content[2], Markdown.Paragraph)
  699 
  700     @test isa(m_2.content[3], Markdown.Admonition)
  701     @test m_2.content[3].category == "danger"
  702     @test m_2.content[3].title == ""
  703     @test isa(m_2.content[3].content[1], Markdown.Code)
  704     @test isa(m_2.content[3].content[2], Markdown.Code)
  705     @test isa(m_2.content[3].content[3], Markdown.Header{1})
  706 
  707     # Rendering Tests.
  708     let out = Markdown.plain(m_1),
  709         expected =
  710             """
  711             # Foo
  712 
  713             !!! note
  714             \n\n
  715             !!! warning "custom title"
  716             \n\n
  717             ## Bar
  718 
  719             !!! danger ""
  720             \n\n
  721             !!!
  722             """
  723         @test out == expected
  724     end
  725     let out = Markdown.rst(m_1),
  726         expected =
  727             """
  728             Foo
  729             ***
  730             \n
  731             .. note::
  732             \n\n
  733             .. warning:: custom title
  734             \n\n
  735             Bar
  736             ===
  737             \n
  738             .. danger::
  739             \n\n
  740             !!!
  741             """
  742         @test out == expected
  743     end
  744     let out = Markdown.latex(m_1),
  745         expected =
  746             """
  747             \\section{Foo}
  748             \\begin{quote}
  749             \\textbf{note}
  750 
  751             Note
  752 
  753             \\end{quote}
  754             \\begin{quote}
  755             \\textbf{warning}
  756 
  757             custom title
  758 
  759             \\end{quote}
  760             \\subsection{Bar}
  761             \\begin{quote}
  762             \\textbf{danger}
  763             \n\n
  764             \\end{quote}
  765             !!!
  766 
  767             """
  768         @test out == expected
  769     end
  770     let out = Markdown.html(m_1),
  771         expected =
  772             """
  773             <h1>Foo</h1>
  774             <div class="admonition note"><p class="admonition-title">Note</p></div>
  775             <div class="admonition warning"><p class="admonition-title">custom title</p></div>
  776             <h2>Bar</h2>
  777             <div class="admonition danger"><p class="admonition-title"></p></div>
  778             <p>&#33;&#33;&#33;</p>
  779             """
  780         @test out == expected
  781     end
  782 
  783     let out = Markdown.plain(m_2),
  784         expected =
  785             """
  786             !!! note
  787                 foo bar baz
  788 
  789 
  790             !!! warning "custom title"
  791                   * foo
  792                   * bar
  793                   * baz
  794 
  795                 foo bar baz
  796 
  797 
  798             !!! danger ""
  799                 ```
  800                 foo
  801                 ```
  802 
  803                 ```
  804                 bar
  805                 ```
  806 
  807                 # baz
  808 
  809             """
  810         @test out == expected
  811     end
  812     let out = Markdown.rst(m_2),
  813         expected =
  814             """
  815             .. note::
  816                foo bar baz
  817 
  818 
  819             .. warning:: custom title
  820                * foo
  821                * bar
  822                * baz
  823 
  824                foo bar baz
  825 
  826 
  827             .. danger::
  828                .. code-block:: julia
  829 
  830                    foo
  831 
  832                .. code-block:: julia
  833 
  834                    bar
  835 
  836                baz
  837                ***
  838 
  839             """
  840         @test out == expected
  841     end
  842 end
  843 
  844 # Nested Lists.
  845 let text =
  846         """
  847         1. A paragraph
  848            with two lines.
  849 
  850                indented code
  851 
  852            > A block quote.
  853 
  854         - one
  855 
  856          two
  857 
  858         - one
  859 
  860           two
  861 
  862 
  863         - baz
  864 
  865         + ```
  866           foo
  867           ```
  868 
  869         1. foo
  870         2. bar
  871         3. baz
  872         """,
  873     md = Markdown.parse(text)
  874 
  875     # Content and structure tests.
  876 
  877     @test length(md.content) == 6
  878     @test length(md.content[1].items) == 1
  879     @test length(md.content[1].items[1]) == 3
  880     @test isa(md.content[1].items[1][1], Markdown.Paragraph)
  881     @test isa(md.content[1].items[1][2], Markdown.Code)
  882     @test isa(md.content[1].items[1][3], Markdown.BlockQuote)
  883     @test length(md.content[2].items) == 1
  884     @test isa(md.content[2].items[1][1], Markdown.Paragraph)
  885     @test isa(md.content[3], Markdown.Paragraph)
  886     @test length(md.content[4].items) == 1
  887     @test isa(md.content[4].items[1][1], Paragraph)
  888     @test isa(md.content[4].items[1][2], Paragraph)
  889     @test length(md.content[5].items) == 2
  890     @test isa(md.content[5].items[1][1], Markdown.Paragraph)
  891     @test isa(md.content[5].items[2][1], Markdown.Code)
  892     @test length(md.content[6].items) == 3
  893     @test md.content[6].items[1][1].content[1] == "foo"
  894     @test md.content[6].items[2][1].content[1] == "bar"
  895     @test md.content[6].items[3][1].content[1] == "baz"
  896 
  897     # Rendering tests.
  898     let expected =
  899             """
  900             1. A paragraph with two lines.
  901 
  902                 ```
  903                 indented code
  904                 ```
  905 
  906                 > A block quote.
  907 
  908               * one
  909 
  910             two
  911 
  912               * one
  913 
  914                 two
  915 
  916               * baz
  917               * ```
  918                 foo
  919                 ```
  920 
  921             1. foo
  922             2. bar
  923             3. baz
  924             """
  925         @test expected == Markdown.plain(md)
  926     end
  927 
  928     let expected =
  929             """
  930             <ol>
  931             <li><p>A paragraph with two lines.</p>
  932             <pre><code>indented code</code></pre>
  933             <blockquote>
  934             <p>A block quote.</p>
  935             </blockquote>
  936             </li>
  937             </ol>
  938             <ul>
  939             <li><p>one</p>
  940             </li>
  941             </ul>
  942             <p>two</p>
  943             <ul>
  944             <li><p>one</p>
  945             <p>two</p>
  946             </li>
  947             </ul>
  948             <ul>
  949             <li><p>baz</p>
  950             </li>
  951             <li><pre><code>foo</code></pre>
  952             </li>
  953             </ul>
  954             <ol>
  955             <li><p>foo</p>
  956             </li>
  957             <li><p>bar</p>
  958             </li>
  959             <li><p>baz</p>
  960             </li>
  961             </ol>
  962             """
  963         @test expected == Markdown.html(md)
  964     end
  965 
  966     let expected =
  967             """
  968             1. A paragraph with two lines.
  969 
  970                .. code-block:: julia
  971 
  972                    indented code
  973 
  974                    A block quote.
  975 
  976             * one
  977 
  978             two
  979 
  980             * one
  981 
  982               two
  983 
  984             * baz
  985             * .. code-block:: julia
  986 
  987                   foo
  988 
  989             1. foo
  990             2. bar
  991             3. baz
  992             """
  993         @test expected == Markdown.rst(md)
  994     end
  995 end
  996 
  997 # Ordered list starting number.
  998 let text =
  999         """
 1000         42. foo
 1001         43. bar
 1002 
 1003 
 1004         1. foo
 1005         2. bar
 1006 
 1007 
 1008         - foo
 1009         - bar
 1010         """,
 1011     md = Markdown.parse(text)
 1012 
 1013     @test md.content[1].ordered == 42
 1014     @test md.content[2].ordered == 1
 1015     @test md.content[3].ordered == -1
 1016 
 1017     let expected =
 1018             """
 1019             <ol start="42">
 1020             <li><p>foo</p>
 1021             </li>
 1022             <li><p>bar</p>
 1023             </li>
 1024             </ol>
 1025             <ol>
 1026             <li><p>foo</p>
 1027             </li>
 1028             <li><p>bar</p>
 1029             </li>
 1030             </ol>
 1031             <ul>
 1032             <li><p>foo</p>
 1033             </li>
 1034             <li><p>bar</p>
 1035             </li>
 1036             </ul>
 1037             """
 1038         @test expected == Markdown.html(md)
 1039     end
 1040 
 1041     let expected =
 1042             """
 1043             \\begin{itemize}
 1044             \\item[42. ] foo
 1045 
 1046 
 1047             \\item[43. ] bar
 1048 
 1049             \\end{itemize}
 1050             \\begin{itemize}
 1051             \\item[1. ] foo
 1052 
 1053 
 1054             \\item[2. ] bar
 1055 
 1056             \\end{itemize}
 1057             \\begin{itemize}
 1058             \\item foo
 1059 
 1060 
 1061             \\item bar
 1062 
 1063             \\end{itemize}
 1064             """
 1065         @test expected == Markdown.latex(md)
 1066     end
 1067 end
 1068 
 1069 # issue 20225, check this can print
 1070 @test typeof(sprint(Markdown.term, Markdown.parse(" "))) == String
 1071 
 1072 # different output depending on whether color is requested: +# issue 20225, check this can print
 1073 let buf = IOBuffer()
 1074     @test typeof(sprint(Markdown.term, Markdown.parse(" "))) == String
 1075     show(buf, "text/plain", md"*emph*")
 1076     @test String(take!(buf)) == "  emph"
 1077     show(buf, "text/markdown", md"*emph*")
 1078     @test String(take!(buf)) == "*emph*\n"
 1079     show(IOContext(buf, :color=>true), "text/plain", md"*emph*")
 1080     @test String(take!(buf)) == "  \e[4memph\e[24m"
 1081 end
 1082 
 1083 # table rendering with term #25213
 1084 t = """
 1085     a   |   b
 1086     :-- | --:
 1087     1   |   2"""
 1088 @test sprint(Markdown.term, Markdown.parse(t), 0) == "a b\n– –\n1 2"
 1089 
 1090 # test Base.copy
 1091 let
 1092     md = doc"test"
 1093     md′ = copy(md)
 1094     @test length(md) == length(md′) == 1
 1095     push!(md, "new")
 1096     @test length(md) == 2
 1097     @test length(md′) == 1
 1098 
 1099     @test !haskey(md.meta, :foo)
 1100     md.meta[:foo] = 42
 1101     @test !haskey(md′.meta, :foo)
 1102 end
 1103 
 1104 let
 1105     v = Markdown.parse("foo\n\n- 1\n- 2\n\n- 3\n\n\n- 1\n- 2\n\nbar\n\n- 1\n\n  2\n- 4\n\nbuz\n\n- 1\n- 2\n  3\n- 4\n")
 1106     @test v.content[2].loose
 1107     @test !v.content[3].loose
 1108     @test v.content[5].loose
 1109     @test !v.content[7].loose
 1110 end
 1111 
 1112 # issue #29995
 1113 let m = Markdown.parse("---"), io = IOBuffer()
 1114     show(io, "text/latex", m)
 1115     @test String(take!(io)) == "\\rule{\\textwidth}{1pt}\n"
 1116 end