pulldown-cmark-0.13.0/.cargo_vcs_info.json0000644000000001540000000000100140540ustar { "git": { "sha1": "f17d98ae9e7ef9c3be601fcb1c9fbd536d3cb873" }, "path_in_vcs": "pulldown-cmark" }pulldown-cmark-0.13.0/Cargo.lock0000644000000114540000000000100120340ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "aho-corasick" version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "bincode" version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ "serde", ] [[package]] name = "bitflags" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "getopts" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ "unicode-width", ] [[package]] name = "itoa" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "proc-macro2" version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "pulldown-cmark" version = "0.13.0" dependencies = [ "bincode", "bitflags", "getopts", "lazy_static", "memchr", "pulldown-cmark-escape", "regex", "serde", "serde_json", "unicase", ] [[package]] name = "pulldown-cmark-escape" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" [[package]] name = "quote" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] [[package]] name = "regex" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ryu" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "serde" version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "itoa", "memchr", "ryu", "serde", ] [[package]] name = "syn" version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "unicase" version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" [[package]] name = "unicode-width" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" pulldown-cmark-0.13.0/Cargo.toml0000644000000046540000000000100120630ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.71.1" name = "pulldown-cmark" version = "0.13.0" authors = [ "Raph Levien ", "Marcus Klaas de Vries ", ] build = "build.rs" exclude = [ "/third_party/**/*", "/tools/**/*", "/specs/**/*", "/azure-pipelines.yml", ] description = "A pull parser for CommonMark" readme = "README.md" keywords = [ "markdown", "commonmark", ] categories = ["text-processing"] license = "MIT" repository = "https://github.com/raphlinus/pulldown-cmark" [[bin]] name = "pulldown-cmark" doc = false required-features = ["getopts"] [[example]] name = "event-filter" doc-scrape-examples = true required-features = ["html"] [[example]] name = "footnote-rewrite" doc-scrape-examples = true required-features = ["html"] [[example]] name = "parser-map-event-print" doc-scrape-examples = true required-features = ["html"] [[example]] name = "parser-map-tag-print" doc-scrape-examples = true required-features = ["html"] [[example]] name = "string-to-string" doc-scrape-examples = true required-features = ["html"] [[example]] name = "broken-link-callbacks" doc-scrape-examples = true required-features = ["html"] [[example]] name = "normalize-wikilink" doc-scrape-examples = true required-features = ["html"] [dependencies.bitflags] version = "2" [dependencies.getopts] version = "0.2" optional = true [dependencies.memchr] version = "2.5" [dependencies.pulldown-cmark-escape] version = "0.11" optional = true [dependencies.serde] version = "1.0" features = ["derive"] optional = true [dependencies.unicase] version = "2.6" [dev-dependencies.bincode] version = "1.3.1" [dev-dependencies.lazy_static] version = "1.4" [dev-dependencies.regex] version = "1.6" [dev-dependencies.serde_json] version = "1.0.61" [features] default = [ "getopts", "html", ] gen-tests = [] html = ["pulldown-cmark-escape"] simd = ["pulldown-cmark-escape?/simd"] [lints.rust.unexpected_cfgs] level = "warn" priority = 0 pulldown-cmark-0.13.0/Cargo.toml.orig000064400000000000000000000036371046102023000155440ustar 00000000000000[package] name = "pulldown-cmark" version = "0.13.0" authors = [ "Raph Levien ", "Marcus Klaas de Vries ", ] license = "MIT" description = "A pull parser for CommonMark" repository = "https://github.com/raphlinus/pulldown-cmark" keywords = ["markdown", "commonmark"] categories = ["text-processing"] edition = "2021" rust-version = "1.71.1" # Update README.md, CONTRIBUTING.md, and GitHub action when changing this readme = "../README.md" exclude = [ "/third_party/**/*", "/tools/**/*", "/specs/**/*", "/azure-pipelines.yml", ] build = "build.rs" [[bin]] name = "pulldown-cmark" required-features = ["getopts"] doc = false [[example]] name = "event-filter" required-features = ["html"] doc-scrape-examples = true [[example]] name = "footnote-rewrite" required-features = ["html"] doc-scrape-examples = true [[example]] name = "parser-map-event-print" required-features = ["html"] doc-scrape-examples = true [[example]] name = "parser-map-tag-print" required-features = ["html"] doc-scrape-examples = true [[example]] name = "string-to-string" required-features = ["html"] doc-scrape-examples = true [[example]] name = "broken-link-callbacks" required-features = ["html"] doc-scrape-examples = true [[example]] name = "normalize-wikilink" required-features = ["html"] doc-scrape-examples = true [dependencies] bitflags = "2" unicase = "2.6" memchr = "2.5" getopts = { version = "0.2", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } pulldown-cmark-escape = { path = "../pulldown-cmark-escape", version = "0.11", optional = true } [dev-dependencies] lazy_static = "1.4" regex = "1.6" serde_json = "1.0.61" bincode = "1.3.1" [features] default = ["getopts", "html"] gen-tests = [] simd = ["pulldown-cmark-escape?/simd"] html = ["pulldown-cmark-escape"] [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(rustbuild)'] } pulldown-cmark-0.13.0/LICENSE000064400000000000000000000021011046102023000136430ustar 00000000000000The MIT License Copyright 2015 Google Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pulldown-cmark-0.13.0/README.md000064400000000000000000000161471046102023000141340ustar 00000000000000# pulldown-cmark [![Tests](https://github.com/pulldown-cmark/pulldown-cmark/actions/workflows/rust.yml/badge.svg)](https://github.com/pulldown-cmark/pulldown-cmark/actions/workflows/rust.yml) [![Docs](https://docs.rs/pulldown-cmark/badge.svg)](https://docs.rs/pulldown-cmark) [![Crates.io](https://img.shields.io/crates/v/pulldown-cmark.svg?maxAge=2592000)](https://crates.io/crates/pulldown-cmark) [Documentation](https://docs.rs/pulldown-cmark/) This library is a pull parser for [CommonMark](http://commonmark.org/), written in [Rust](http://www.rust-lang.org/). It comes with a simple command-line tool, useful for rendering to HTML, and is also designed to be easy to use from as a library. It is designed to be: * Fast; a bare minimum of allocation and copying * Safe; written in pure Rust with no unsafe blocks (except in the opt-in SIMD feature) * Versatile; in particular source-maps are supported * Correct; the goal is 100% compliance with the [CommonMark spec](http://spec.commonmark.org/) Further, it optionally supports parsing footnotes, [Github flavored tables](https://github.github.com/gfm/#tables-extension-), [Github flavored task lists](https://github.github.com/gfm/#task-list-items-extension-) and [strikethrough](https://github.github.com/gfm/#strikethrough-extension-). Rustc 1.71.1 or newer is required to build the crate. ## Example Example usage: ```rust // Create parser with example Markdown text. let markdown_input = "hello world"; let parser = pulldown_cmark::Parser::new(markdown_input); // Write to a new String buffer. let mut html_output = String::new(); pulldown_cmark::html::push_html(&mut html_output, parser); assert_eq!(&html_output, "

hello world

\n"); ``` ## Why a pull parser? There are many parsers for Markdown and its variants, but to my knowledge none use pull parsing. Pull parsing has become popular for XML, especially for memory-conscious applications, because it uses dramatically less memory than constructing a document tree, but is much easier to use than push parsers. Push parsers are notoriously difficult to use, and also often error-prone because of the need for user to delicately juggle state in a series of callbacks. In a clean design, the parsing and rendering stages are neatly separated, but this is often sacrificed in the name of performance and expedience. Many Markdown implementations mix parsing and rendering together, and even designs that try to separate them (such as the popular [hoedown](https://github.com/hoedown/hoedown)), make the assumption that the rendering process can be fully represented as a serialized string. Pull parsing is in some sense the most versatile architecture. It's possible to drive a push interface, also with minimal memory, and quite straightforward to construct an AST. Another advantage is that source-map information (the mapping between parsed blocks and offsets within the source text) is readily available; you can call `into_offset_iter()` to create an iterator that yields `(Event, Range)` pairs, where the second element is the event's corresponding range in the source document. While manipulating ASTs is the most flexible way to transform documents, operating on iterators is surprisingly easy, and quite efficient. Here, for example, is the code to transform soft line breaks into hard breaks: ```rust let parser = parser.map(|event| match event { Event::SoftBreak => Event::HardBreak, _ => event }); ``` Or expanding an abbreviation in text: ```rust let parser = parser.map(|event| match event { Event::Text(text) => Event::Text(text.replace("abbr", "abbreviation").into()), _ => event }); ``` Another simple example is code to determine the max nesting level: ```rust let mut max_nesting = 0; let mut level = 0; for event in parser { match event { Event::Start(_) => { level += 1; max_nesting = std::cmp::max(max_nesting, level); } Event::End(_) => level -= 1, _ => () } } ``` Note that consecutive text events can happen due to the manner in which the parser evaluates the source. A utility `TextMergeStream` exists to improve the comfort of iterating the events: ```rust use pulldown_cmark::{Event, Parser, Options}; let markdown_input = "Hello world, this is a ~~complicated~~ *very simple* example."; let iterator = TextMergeStream::new(Parser::new(markdown_input)); for event in iterator { match event { Event::Text(text) => println!("{}", text), _ => {} } } ``` There are some basic but fully functional examples of the usage of the crate in the `examples` directory of this repository. ## Using Rust idiomatically A lot of the internal scanning code is written at a pretty low level (it pretty much scans byte patterns for the bits of syntax), but the external interface is designed to be idiomatic Rust. Pull parsers are at heart an iterator of events (start and end tags, text, and other bits and pieces). The parser data structure implements the Rust Iterator trait directly, and Event is an enum. Thus, you can use the full power and expressivity of Rust's iterator infrastructure, including for loops and `map` (as in the examples above), collecting the events into a vector (for recording, playback, and manipulation), and more. Further, the `Text` event (representing text) is a small copy-on-write string. The vast majority of text fragments are just slices of the source document. For these, copy-on-write gives a convenient representation that requires no allocation or copying, but allocated strings are available when they're needed. Thus, when rendering text to HTML, most text is copied just once, from the source document to the HTML buffer. When using the pulldown-cmark's own HTML renderer, make sure to write to a buffered target like a `Vec` or `String`. Since it performs many (very) small writes, writing directly to stdout, files, or sockets is detrimental to performance. Such writers can be wrapped in a [`BufWriter`](https://doc.rust-lang.org/std/io/struct.BufWriter.html). ## Build options By default, the binary is built as well. If you don't want/need it, then build like this: ```bash > cargo build --no-default-features ``` Or add this package as dependency of your project using `cargo add`: ```bash > cargo add pulldown-cmark --no-default-features ``` SIMD accelerated scanners are available for the x64 platform from version 0.5 onwards. To enable them, build with simd feature: ```bash > cargo build --release --features simd ``` Or add this package as dependency of your project with the feature using `cargo add`: ```bash > cargo add pulldown-cmark --no-default-features --features=simd ``` For a higher release performance you may want this configuration in your profile release: ``` lto = true codegen-units = 1 panic = "abort" ``` ## Authors The main author is Raph Levien. The implementation of the new design (v0.3+) was completed by Marcus Klaas de Vries. Since 2023, the development has been driven by Martín Pozo, Michael Howell, Roope Salmi and Martin Geisler. ## License This software is under the MIT license. See details in [license file](./LICENSE). ## Contributions We gladly accept contributions via GitHub pull requests. Please see [CONTRIBUTING.md](CONTRIBUTING.md) for more details. pulldown-cmark-0.13.0/build.rs000064400000000000000000000203201046102023000143060ustar 00000000000000fn main() { generate_tests_from_spec() } // If the "gen-tests" feature is absent, // this function will be compiled down to nothing #[cfg(not(feature = "gen-tests"))] fn generate_tests_from_spec() {} // If the feature is present, generate tests // from any .txt file present in the specs/ directory // // Test cases are present in the files in the // following format: // // ```````````````````````````````` example // markdown // . // expected html output // ```````````````````````````````` #[cfg(feature = "gen-tests")] fn generate_tests_from_spec() { use std::fs::{self, File}; use std::io::{Read, Write}; use std::path::PathBuf; // This is a hardcoded path to the CommonMark spec because it is not situated in // the specs/ directory. It's in an array to easily chain it to the other iterator // and make it easy to eventually add other hardcoded paths in the future if needed let hardcoded = [ "./third_party/CommonMark/spec.txt", "./third_party/CommonMark/smart_punct.txt", "./third_party/GitHub/gfm_table.txt", "./third_party/GitHub/gfm_strikethrough.txt", "./third_party/GitHub/gfm_tasklist.txt", ]; let hardcoded_iter = hardcoded.iter().map(PathBuf::from); // Create an iterator over the files in the specs/ directory that have a .txt extension let mut spec_files = fs::read_dir("./specs") .expect("Could not find the 'specs' directory") .filter_map(Result::ok) .map(|d| d.path()) .filter(|p| p.extension().map(|e| e.to_owned()).is_some()) .chain(hardcoded_iter) .collect::>(); // Sort by spec names spec_files.sort_by(|p, q| p.file_stem().cmp(&q.file_stem())); let spec_files = spec_files; for file_path in &spec_files { let mut raw_spec = String::new(); File::open(&file_path) .and_then(|mut f| f.read_to_string(&mut raw_spec)) .expect("Could not read the spec file"); let rs_test_file = PathBuf::from("./tests/suite/") .join(file_path.file_name().expect("Invalid filename")) .with_extension("rs"); let mut spec_rs = File::create(&rs_test_file).expect(&format!("Could not create {:?}", rs_test_file)); let spec_name = file_path.file_stem().unwrap().to_str().unwrap(); let spec = Spec::new(&raw_spec); let mut n_tests = 0; spec_rs .write_all(b"// This file is auto-generated by the build script\n") .unwrap(); spec_rs .write_all(b"// Please, do not modify it manually\n") .unwrap(); spec_rs .write_all(b"\nuse super::test_markdown_html;\n") .unwrap(); for (i, testcase) in spec.enumerate() { spec_rs .write_fmt(format_args!( r###" #[test] fn {}_test_{i}() {{ let original = r##"{original}"##; let expected = r##"{expected}"##; test_markdown_html(original, expected, {smart_punct}, {metadata_blocks}, {old_footnotes}, {subscript}, {wikilinks}); }} "###, spec_name, i = i + 1, original = testcase.original, expected = testcase.expected, smart_punct = testcase.smart_punct, metadata_blocks = testcase.metadata_blocks, old_footnotes = testcase.old_footnotes, subscript = testcase.subscript, wikilinks = testcase.wikilinks, )) .unwrap(); n_tests += 1; } println!( "cargo:warning=Generated {} tests in {:?}", n_tests, rs_test_file ); } // write mods to suite/mod.rs let suite_mod_file = PathBuf::from("./tests/suite/mod").with_extension("rs"); let mut mod_rs = File::create(&suite_mod_file).expect(&format!("Could not create {:?}", &suite_mod_file)); mod_rs .write_all(b"// This file is auto-generated by the build script\n") .unwrap(); mod_rs .write_all(b"// Please, do not modify it manually\n") .unwrap(); mod_rs .write_all(b"\npub use super::test_markdown_html;\n\n") .unwrap(); for file_path in &spec_files { let mod_name = file_path.file_stem().unwrap().to_str().unwrap(); mod_rs.write_all(b"mod ").unwrap(); mod_rs.write_all(mod_name.as_bytes()).unwrap(); mod_rs.write_all(b";\n").unwrap(); } } #[cfg(feature = "gen-tests")] pub struct Spec<'a> { spec: &'a str, } #[cfg(feature = "gen-tests")] impl<'a> Spec<'a> { pub fn new(spec: &'a str) -> Self { Spec { spec } } } #[cfg(feature = "gen-tests")] pub struct TestCase { pub original: String, pub expected: String, pub smart_punct: bool, pub metadata_blocks: bool, pub old_footnotes: bool, pub subscript: bool, pub wikilinks: bool, } #[cfg(feature = "gen-tests")] impl<'a> Iterator for Spec<'a> { type Item = TestCase; fn next(&mut self) -> Option { let spec = self.spec; let prefix = "```````````````````````````````` example"; let (i_start, smart_punct, metadata_blocks, old_footnotes, subscript, wikilinks) = self.spec.find(prefix).and_then(|pos| { let smartpunct_suffix = "_smartpunct\n"; let metadata_blocks_suffix = "_metadata_blocks\n"; let old_footnotes_suffix = "_old_footnotes\n"; let super_sub_suffix = "_super_sub\n"; let wikilinks_suffix = "_wikilinks\n"; if spec[(pos + prefix.len())..].starts_with(smartpunct_suffix) { Some(( pos + prefix.len() + smartpunct_suffix.len(), true, false, false, false, false, )) } else if spec[(pos + prefix.len())..].starts_with(metadata_blocks_suffix) { Some(( pos + prefix.len() + metadata_blocks_suffix.len(), false, true, false, false, false, )) } else if spec[(pos + prefix.len())..].starts_with(old_footnotes_suffix) { Some(( pos + prefix.len() + old_footnotes_suffix.len(), false, false, true, false, false, )) } else if spec[(pos + prefix.len())..].starts_with(super_sub_suffix) { Some(( pos + prefix.len() + super_sub_suffix.len(), false, false, false, true, false, )) } else if spec[(pos + prefix.len())..].starts_with(wikilinks_suffix) { Some(( pos + prefix.len() + wikilinks_suffix.len(), false, false, false, false, true, )) } else if spec[(pos + prefix.len())..].starts_with('\n') { Some((pos + prefix.len() + 1, false, false, false, false, false)) } else { None } })?; let i_end = self.spec[i_start..] .find("\n.\n") .map(|pos| (pos + 1) + i_start)?; let e_end = self.spec[i_end + 2..] .find("````````````````````````````````\n") .map(|pos| pos + i_end + 2)?; self.spec = &self.spec[e_end + 33..]; let test_case = TestCase { original: spec[i_start..i_end].to_string().replace("→", "\t"), expected: spec[i_end + 2..e_end].to_string().replace("→", "\t"), smart_punct, metadata_blocks, old_footnotes, subscript, wikilinks, }; Some(test_case) } } pulldown-cmark-0.13.0/examples/broken-link-callbacks.rs000064400000000000000000000025411046102023000211620ustar 00000000000000use pulldown_cmark::{html, BrokenLink, Options, Parser}; fn main() { let input: &str = "Hello world, check out [my website][]."; println!("Parsing the following markdown string:\n{}", input); // Setup callback that sets the URL and title when it encounters // a reference to our home page. let callback = |broken_link: BrokenLink| { if broken_link.reference.as_ref() == "my website" { println!( "Replacing the markdown `{}` of type {:?} with a working link", &input[broken_link.span], broken_link.link_type, ); Some(("http://example.com".into(), "my example website".into())) } else { None } }; // Create a parser with our callback function for broken links. let parser = Parser::new_with_broken_link_callback(input, Options::empty(), Some(callback)); // Write to String buffer. let mut html_output: String = String::with_capacity(input.len() * 3 / 2); html::push_html(&mut html_output, parser); // Check that the output is what we expected. let expected_html: &str = "

Hello world, check out my website.

\n"; assert_eq!(expected_html, &html_output); // Write result to stdout. println!("\nHTML output:\n{}", &html_output); } pulldown-cmark-0.13.0/examples/event-filter.rs000064400000000000000000000020421046102023000174320ustar 00000000000000use std::io::Write as _; use pulldown_cmark::{html, Event, Options, Parser, Tag, TagEnd}; fn main() { let markdown_input: &str = "This is Peter on ![holiday in Greece](pearl_beach.jpg)."; println!("Parsing the following markdown string:\n{}", markdown_input); // Set up parser. We can treat is as any other iterator. We replace Peter by John // and image by its alt text. let parser = Parser::new_ext(markdown_input, Options::empty()) .map(|event| match event { Event::Text(text) => Event::Text(text.replace("Peter", "John").into()), _ => event, }) .filter(|event| match event { Event::Start(Tag::Image { .. }) | Event::End(TagEnd::Image) => false, _ => true, }); // Write to anything implementing the `Write` trait. This could also be a file // or network socket. let stdout = std::io::stdout(); let mut handle = stdout.lock(); handle.write_all(b"\nHTML output:\n").unwrap(); html::write_html_io(&mut handle, parser).unwrap(); } pulldown-cmark-0.13.0/examples/events.rs000064400000000000000000000010121046102023000163260ustar 00000000000000use std::io::Read; use pulldown_cmark::{Event, Parser}; /// Show all events from the text on stdin. fn main() { let mut text = String::new(); std::io::stdin().read_to_string(&mut text).unwrap(); eprintln!("{text:?} -> ["); let mut width = 0; for event in Parser::new(&text) { if let Event::End(_) = event { width -= 2; } eprintln!(" {:width$}{event:?}", ""); if let Event::Start(_) = event { width += 2; } } eprintln!("]"); } pulldown-cmark-0.13.0/examples/footnote-rewrite.rs000064400000000000000000000165571046102023000203620ustar 00000000000000use std::collections::HashMap; use std::fmt::Write as _; use std::io::Write as _; use pulldown_cmark::{html, CowStr, Event, Options, Parser, Tag, TagEnd}; /// This example shows how to do footnotes as bottom-notes, in the style of GitHub. fn main() { let markdown_input: &str = "This is an [^a] footnote [^a].\n\n[^a]: footnote contents"; println!("Parsing the following markdown string:\n{}", markdown_input); // To generate this style, you have to collect the footnotes at the end, while parsing. // You also need to count usages. let mut footnotes = Vec::new(); let mut in_footnote = Vec::new(); let mut footnote_numbers = HashMap::new(); // ENABLE_FOOTNOTES is used in this example, but ENABLE_OLD_FOOTNOTES would work, too. let parser = Parser::new_ext(markdown_input, Options::ENABLE_FOOTNOTES) .filter_map(|event| { match event { Event::Start(Tag::FootnoteDefinition(_)) => { in_footnote.push(vec![event]); None } Event::End(TagEnd::FootnoteDefinition) => { let mut f = in_footnote.pop().unwrap(); f.push(event); footnotes.push(f); None } Event::FootnoteReference(name) => { let n = footnote_numbers.len() + 1; let (n, nr) = footnote_numbers.entry(name.clone()).or_insert((n, 0usize)); *nr += 1; let html = Event::Html(format!(r##"[{n}]"##).into()); if in_footnote.is_empty() { Some(html) } else { in_footnote.last_mut().unwrap().push(html); None } } _ if !in_footnote.is_empty() => { in_footnote.last_mut().unwrap().push(event); None } _ => Some(event), } }); // Write to anything implementing the `Write` trait. This could also be a file // or network socket. let stdout = std::io::stdout(); let mut handle = stdout.lock(); handle.write_all(b"\nHTML output:\n").unwrap(); html::write_html_io(&mut handle, parser).unwrap(); // To make the footnotes look right, we need to sort them by their appearance order, not by // the in-tree order of their actual definitions. Unused items are omitted entirely. // // For example, this code: // // test [^1] [^2] // [^2]: second used, first defined // [^1]: test // // Gets rendered like *this* if you copy it into a GitHub comment box: // //

test [1] [2]

//
//
    //
  1. test ↩
  2. //
  3. second used, first defined ↩
  4. //
if !footnotes.is_empty() { footnotes.retain(|f| match f.first() { Some(Event::Start(Tag::FootnoteDefinition(name))) => { footnote_numbers.get(name).unwrap_or(&(0, 0)).1 != 0 } _ => false, }); footnotes.sort_by_cached_key(|f| match f.first() { Some(Event::Start(Tag::FootnoteDefinition(name))) => { footnote_numbers.get(name).unwrap_or(&(0, 0)).0 } _ => unreachable!(), }); handle .write_all(b"
    \n") .unwrap(); html::write_html_io( &mut handle, footnotes.into_iter().flat_map(|fl| { // To write backrefs, the name needs kept until the end of the footnote definition. let mut name = CowStr::from(""); // Backrefs are included in the final paragraph of the footnote, if it's normal text. // For example, this DOM can be produced: // // Markdown: // // five [^feet]. // // [^feet]: // A foot is defined, in this case, as 0.3048 m. // // Historically, the foot has not been defined this way, corresponding to many // subtly different units depending on the location. // // HTML: // //

    five [1].

    // //
      //
    1. //

      A foot is defined, in this case, as 0.3048 m.

      //

      Historically, the foot has not been defined this way, corresponding to many // subtly different units depending on the location.

      //
    2. //
    // // This is mostly a visual hack, so that footnotes use less vertical space. // // If there is no final paragraph, such as a tabular, list, or image footnote, it gets // pushed after the last tag instead. let mut has_written_backrefs = false; let fl_len = fl.len(); let footnote_numbers = &footnote_numbers; fl.into_iter().enumerate().map(move |(i, f)| match f { Event::Start(Tag::FootnoteDefinition(current_name)) => { name = current_name; has_written_backrefs = false; Event::Html(format!(r##"
  1. "##).into()) } Event::End(TagEnd::FootnoteDefinition) | Event::End(TagEnd::Paragraph) if !has_written_backrefs && i >= fl_len - 2 => { let usage_count = footnote_numbers.get(&name).unwrap().1; let mut end = String::with_capacity( name.len() + (r##"
  2. "##.len() * usage_count), ); for usage in 1..=usage_count { if usage == 1 { write!(&mut end, r##" "##) .unwrap(); } else { write!(&mut end, r##" ↩{usage}"##) .unwrap(); } } has_written_backrefs = true; if f == Event::End(TagEnd::FootnoteDefinition) { end.push_str("\n"); } else { end.push_str("

    \n"); } Event::Html(end.into()) } Event::End(TagEnd::FootnoteDefinition) => Event::Html("\n".into()), Event::FootnoteReference(_) => unreachable!("converted to HTML earlier"), f => f, }) }), ) .unwrap(); handle.write_all(b"
\n").unwrap(); } } pulldown-cmark-0.13.0/examples/normalize-wikilink.rs000064400000000000000000000051331046102023000206510ustar 00000000000000use pulldown_cmark::{html, CowStr, Event, LinkType, Options, Parser, Tag}; use regex::RegexBuilder; use std::io::Write; /// This example demonstrates how to normalize the href of a wikilink. The /// details of this implementation can be tweaked for different use cases. fn main() { let markdown_input: &str = r#" Example provided by [[https://example.org/]]. Some people might prefer the wikilink syntax for autolinks. Wanna go for a [[Wiki Walk]]?"#; let parser = Parser::new_ext(markdown_input, Options::ENABLE_WIKILINKS).map(|event| { if let Event::Start(Tag::Link { link_type: LinkType::WikiLink { has_pothole }, dest_url, title, id, }) = event { let new_link = normalize_wikilink(dest_url); Event::Start(Tag::Link { link_type: LinkType::WikiLink { has_pothole }, dest_url: new_link, title, id, }) } else { event } }); // Write to anything implementing the `Write` trait. This could also be a file // or network socket. let stdout = std::io::stdout(); let mut handle = stdout.lock(); handle.write_all(b"\nHTML output:\n").unwrap(); html::write_html_io(&mut handle, parser).unwrap(); } /// Performs wikilink normalization. fn normalize_wikilink(link: CowStr) -> CowStr { // your wiki is stored at "/wiki" let prefix: &str = "/wiki"; if link.is_empty() { return link; } // check if the link is absolute, if it is, return as is // according to RFC 3986; https://www.rfc-editor.org/rfc/rfc3986 let is_absolute = RegexBuilder::new("^(?:[a-z][a-z0-9+\\-.]*:)?//") .case_insensitive(true) .build() .expect("valid regex"); if is_absolute.is_match(&link) { return link; } let mut result = String::with_capacity(link.len() + 2); let mut i = 0; let mut mark = 0; let mut in_whitespace = false; result.push_str(prefix); if !link.starts_with('/') { result.push('/'); } while i < link.len() { if !in_whitespace && link.as_bytes()[i].is_ascii_whitespace() { in_whitespace = true; result.push_str(&link[mark..i]); } else if in_whitespace && !link.as_bytes()[i].is_ascii_whitespace() { result.push('_'); mark = i; in_whitespace = false; } i += 1; } if !in_whitespace { result.push_str(&link[mark..]); } if !result.ends_with('/') { result.push('/'); } result.into() } pulldown-cmark-0.13.0/examples/parser-map-event-print.rs000064400000000000000000000031041046102023000213460ustar 00000000000000use pulldown_cmark::{html, Event, Parser}; fn main() { let markdown_input = "# Example Heading\nExample paragraph with **lorem** _ipsum_ text."; println!( "\nParsing the following markdown string:\n{}\n", markdown_input ); // Set up the parser. We can treat is as any other iterator. // For each event, we print its details, such as the tag or string. // This filter simply returns the same event without any changes; // you can compare the `event-filter` example which alters the output. let parser = Parser::new(markdown_input).map(|event| { match &event { Event::Start(tag) => println!("Start: {:?}", tag), Event::End(tag) => println!("End: {:?}", tag), Event::Html(s) => println!("Html: {:?}", s), Event::InlineHtml(s) => println!("InlineHtml: {:?}", s), Event::Text(s) => println!("Text: {:?}", s), Event::Code(s) => println!("Code: {:?}", s), Event::DisplayMath(s) => println!("DisplayMath: {:?}", s), Event::InlineMath(s) => println!("Math: {:?}", s), Event::FootnoteReference(s) => println!("FootnoteReference: {:?}", s), Event::TaskListMarker(b) => println!("TaskListMarker: {:?}", b), Event::SoftBreak => println!("SoftBreak"), Event::HardBreak => println!("HardBreak"), Event::Rule => println!("Rule"), }; event }); let mut html_output = String::new(); html::push_html(&mut html_output, parser); println!("\nHTML output:\n{}\n", &html_output); } pulldown-cmark-0.13.0/examples/parser-map-tag-print.rs000064400000000000000000000104311046102023000210010ustar 00000000000000use pulldown_cmark::{Event, Options, Parser, Tag}; fn main() { let markdown_input = concat!( "# My Heading\n", "\n", "My paragraph.\n", "\n", "* a\n", "* b\n", "* c\n", "\n", "1. d\n", "2. e\n", "3. f\n", "\n", "> my block quote\n", "\n", "```\n", "my code block\n", "```\n", "\n", "*emphasis*\n", "**strong**\n", "~~strikethrough~~\n", "[My Link](http://example.com)\n", "![My Image](http://example.com/image.jpg)\n", "\n", "| a | b |\n", "| - | - |\n", "| c | d |\n", "\n", "hello[^1]\n", "[^1]: my footnote\n", ); println!( "\nParsing the following markdown string:\n{}\n", markdown_input ); // Set up the parser. We can treat is as any other iterator. // For each event, we print its details, such as the tag or string. // This filter simply returns the same event without any changes; // you can compare the `event-filter` example which alters the output. let parser = Parser::new_ext(markdown_input, Options::all()).map(|event| { match &event { Event::Start(tag) => match tag { Tag::HtmlBlock => println!("HtmlBlock"), Tag::Heading { level, id, classes, attrs, } => println!( "Heading heading_level: {} fragment identifier: {:?} classes: {:?} attrs: {:?}", level, id, classes, attrs ), Tag::Paragraph => println!("Paragraph"), Tag::List(ordered_list_first_item_number) => println!( "List ordered_list_first_item_number: {:?}", ordered_list_first_item_number ), Tag::DefinitionList => println!("Definition list"), Tag::DefinitionListTitle => println!("Definition title (definition list item)"), Tag::DefinitionListDefinition => println!("Definition (definition list item)"), Tag::Item => println!("Item (this is a list item)"), Tag::Emphasis => println!("Emphasis (this is a span tag)"), Tag::Superscript => println!("Superscript (this is a span tag)"), Tag::Subscript => println!("Subscript (this is a span tag)"), Tag::Strong => println!("Strong (this is a span tag)"), Tag::Strikethrough => println!("Strikethrough (this is a span tag)"), Tag::BlockQuote(kind) => println!("BlockQuote ({:?})", kind), Tag::CodeBlock(code_block_kind) => { println!("CodeBlock code_block_kind: {:?}", code_block_kind) } Tag::Link { link_type, dest_url, title, id, } => println!( "Link link_type: {:?} url: {} title: {} id: {}", link_type, dest_url, title, id ), Tag::Image { link_type, dest_url, title, id, } => println!( "Image link_type: {:?} url: {} title: {} id: {}", link_type, dest_url, title, id ), Tag::Table(column_text_alignment_list) => println!( "Table column_text_alignment_list: {:?}", column_text_alignment_list ), Tag::TableHead => println!("TableHead (contains TableRow tags"), Tag::TableRow => println!("TableRow (contains TableCell tags)"), Tag::TableCell => println!("TableCell (contains inline tags)"), Tag::FootnoteDefinition(label) => println!("FootnoteDefinition label: {}", label), Tag::MetadataBlock(kind) => println!("MetadataBlock: {:?}", kind), }, _ => (), }; event }); let mut html_output = String::new(); pulldown_cmark::html::push_html(&mut html_output, parser); println!("\nHTML output:\n{}\n", &html_output); } pulldown-cmark-0.13.0/examples/string-to-string.rs000064400000000000000000000017411046102023000202650ustar 00000000000000use pulldown_cmark::{html, Options, Parser}; fn main() { let markdown_input: &str = "Hello world, this is a ~~complicated~~ *very simple* example."; println!("Parsing the following markdown string:\n{}", markdown_input); // Set up options and parser. Strikethroughs are not part of the CommonMark standard // and we therefore must enable it explicitly. let mut options = Options::empty(); options.insert(Options::ENABLE_STRIKETHROUGH); let parser = Parser::new_ext(markdown_input, options); // Write to String buffer. let mut html_output: String = String::with_capacity(markdown_input.len() * 3 / 2); html::push_html(&mut html_output, parser); // Check that the output is what we expected. let expected_html: &str = "

Hello world, this is a complicated very simple example.

\n"; assert_eq!(expected_html, &html_output); // Write result to stdout. println!("\nHTML output:\n{}", &html_output); } pulldown-cmark-0.13.0/src/entities.rs000064400000000000000000001772411046102023000156410ustar 00000000000000// Copyright 2015 Google Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! Expansions of HTML5 entities // Autogenerated by mk_entities.py const ENTITIES: [(&[u8], &str); 2125] = [ (b"AElig", "\u{00C6}"), (b"AMP", "\u{0026}"), (b"Aacute", "\u{00C1}"), (b"Abreve", "\u{0102}"), (b"Acirc", "\u{00C2}"), (b"Acy", "\u{0410}"), (b"Afr", "\u{1D504}"), (b"Agrave", "\u{00C0}"), (b"Alpha", "\u{0391}"), (b"Amacr", "\u{0100}"), (b"And", "\u{2A53}"), (b"Aogon", "\u{0104}"), (b"Aopf", "\u{1D538}"), (b"ApplyFunction", "\u{2061}"), (b"Aring", "\u{00C5}"), (b"Ascr", "\u{1D49C}"), (b"Assign", "\u{2254}"), (b"Atilde", "\u{00C3}"), (b"Auml", "\u{00C4}"), (b"Backslash", "\u{2216}"), (b"Barv", "\u{2AE7}"), (b"Barwed", "\u{2306}"), (b"Bcy", "\u{0411}"), (b"Because", "\u{2235}"), (b"Bernoullis", "\u{212C}"), (b"Beta", "\u{0392}"), (b"Bfr", "\u{1D505}"), (b"Bopf", "\u{1D539}"), (b"Breve", "\u{02D8}"), (b"Bscr", "\u{212C}"), (b"Bumpeq", "\u{224E}"), (b"CHcy", "\u{0427}"), (b"COPY", "\u{00A9}"), (b"Cacute", "\u{0106}"), (b"Cap", "\u{22D2}"), (b"CapitalDifferentialD", "\u{2145}"), (b"Cayleys", "\u{212D}"), (b"Ccaron", "\u{010C}"), (b"Ccedil", "\u{00C7}"), (b"Ccirc", "\u{0108}"), (b"Cconint", "\u{2230}"), (b"Cdot", "\u{010A}"), (b"Cedilla", "\u{00B8}"), (b"CenterDot", "\u{00B7}"), (b"Cfr", "\u{212D}"), (b"Chi", "\u{03A7}"), (b"CircleDot", "\u{2299}"), (b"CircleMinus", "\u{2296}"), (b"CirclePlus", "\u{2295}"), (b"CircleTimes", "\u{2297}"), (b"ClockwiseContourIntegral", "\u{2232}"), (b"CloseCurlyDoubleQuote", "\u{201D}"), (b"CloseCurlyQuote", "\u{2019}"), (b"Colon", "\u{2237}"), (b"Colone", "\u{2A74}"), (b"Congruent", "\u{2261}"), (b"Conint", "\u{222F}"), (b"ContourIntegral", "\u{222E}"), (b"Copf", "\u{2102}"), (b"Coproduct", "\u{2210}"), (b"CounterClockwiseContourIntegral", "\u{2233}"), (b"Cross", "\u{2A2F}"), (b"Cscr", "\u{1D49E}"), (b"Cup", "\u{22D3}"), (b"CupCap", "\u{224D}"), (b"DD", "\u{2145}"), (b"DDotrahd", "\u{2911}"), (b"DJcy", "\u{0402}"), (b"DScy", "\u{0405}"), (b"DZcy", "\u{040F}"), (b"Dagger", "\u{2021}"), (b"Darr", "\u{21A1}"), (b"Dashv", "\u{2AE4}"), (b"Dcaron", "\u{010E}"), (b"Dcy", "\u{0414}"), (b"Del", "\u{2207}"), (b"Delta", "\u{0394}"), (b"Dfr", "\u{1D507}"), (b"DiacriticalAcute", "\u{00B4}"), (b"DiacriticalDot", "\u{02D9}"), (b"DiacriticalDoubleAcute", "\u{02DD}"), (b"DiacriticalGrave", "\u{0060}"), (b"DiacriticalTilde", "\u{02DC}"), (b"Diamond", "\u{22C4}"), (b"DifferentialD", "\u{2146}"), (b"Dopf", "\u{1D53B}"), (b"Dot", "\u{00A8}"), (b"DotDot", "\u{20DC}"), (b"DotEqual", "\u{2250}"), (b"DoubleContourIntegral", "\u{222F}"), (b"DoubleDot", "\u{00A8}"), (b"DoubleDownArrow", "\u{21D3}"), (b"DoubleLeftArrow", "\u{21D0}"), (b"DoubleLeftRightArrow", "\u{21D4}"), (b"DoubleLeftTee", "\u{2AE4}"), (b"DoubleLongLeftArrow", "\u{27F8}"), (b"DoubleLongLeftRightArrow", "\u{27FA}"), (b"DoubleLongRightArrow", "\u{27F9}"), (b"DoubleRightArrow", "\u{21D2}"), (b"DoubleRightTee", "\u{22A8}"), (b"DoubleUpArrow", "\u{21D1}"), (b"DoubleUpDownArrow", "\u{21D5}"), (b"DoubleVerticalBar", "\u{2225}"), (b"DownArrow", "\u{2193}"), (b"DownArrowBar", "\u{2913}"), (b"DownArrowUpArrow", "\u{21F5}"), (b"DownBreve", "\u{0311}"), (b"DownLeftRightVector", "\u{2950}"), (b"DownLeftTeeVector", "\u{295E}"), (b"DownLeftVector", "\u{21BD}"), (b"DownLeftVectorBar", "\u{2956}"), (b"DownRightTeeVector", "\u{295F}"), (b"DownRightVector", "\u{21C1}"), (b"DownRightVectorBar", "\u{2957}"), (b"DownTee", "\u{22A4}"), (b"DownTeeArrow", "\u{21A7}"), (b"Downarrow", "\u{21D3}"), (b"Dscr", "\u{1D49F}"), (b"Dstrok", "\u{0110}"), (b"ENG", "\u{014A}"), (b"ETH", "\u{00D0}"), (b"Eacute", "\u{00C9}"), (b"Ecaron", "\u{011A}"), (b"Ecirc", "\u{00CA}"), (b"Ecy", "\u{042D}"), (b"Edot", "\u{0116}"), (b"Efr", "\u{1D508}"), (b"Egrave", "\u{00C8}"), (b"Element", "\u{2208}"), (b"Emacr", "\u{0112}"), (b"EmptySmallSquare", "\u{25FB}"), (b"EmptyVerySmallSquare", "\u{25AB}"), (b"Eogon", "\u{0118}"), (b"Eopf", "\u{1D53C}"), (b"Epsilon", "\u{0395}"), (b"Equal", "\u{2A75}"), (b"EqualTilde", "\u{2242}"), (b"Equilibrium", "\u{21CC}"), (b"Escr", "\u{2130}"), (b"Esim", "\u{2A73}"), (b"Eta", "\u{0397}"), (b"Euml", "\u{00CB}"), (b"Exists", "\u{2203}"), (b"ExponentialE", "\u{2147}"), (b"Fcy", "\u{0424}"), (b"Ffr", "\u{1D509}"), (b"FilledSmallSquare", "\u{25FC}"), (b"FilledVerySmallSquare", "\u{25AA}"), (b"Fopf", "\u{1D53D}"), (b"ForAll", "\u{2200}"), (b"Fouriertrf", "\u{2131}"), (b"Fscr", "\u{2131}"), (b"GJcy", "\u{0403}"), (b"GT", "\u{003E}"), (b"Gamma", "\u{0393}"), (b"Gammad", "\u{03DC}"), (b"Gbreve", "\u{011E}"), (b"Gcedil", "\u{0122}"), (b"Gcirc", "\u{011C}"), (b"Gcy", "\u{0413}"), (b"Gdot", "\u{0120}"), (b"Gfr", "\u{1D50A}"), (b"Gg", "\u{22D9}"), (b"Gopf", "\u{1D53E}"), (b"GreaterEqual", "\u{2265}"), (b"GreaterEqualLess", "\u{22DB}"), (b"GreaterFullEqual", "\u{2267}"), (b"GreaterGreater", "\u{2AA2}"), (b"GreaterLess", "\u{2277}"), (b"GreaterSlantEqual", "\u{2A7E}"), (b"GreaterTilde", "\u{2273}"), (b"Gscr", "\u{1D4A2}"), (b"Gt", "\u{226B}"), (b"HARDcy", "\u{042A}"), (b"Hacek", "\u{02C7}"), (b"Hat", "\u{005E}"), (b"Hcirc", "\u{0124}"), (b"Hfr", "\u{210C}"), (b"HilbertSpace", "\u{210B}"), (b"Hopf", "\u{210D}"), (b"HorizontalLine", "\u{2500}"), (b"Hscr", "\u{210B}"), (b"Hstrok", "\u{0126}"), (b"HumpDownHump", "\u{224E}"), (b"HumpEqual", "\u{224F}"), (b"IEcy", "\u{0415}"), (b"IJlig", "\u{0132}"), (b"IOcy", "\u{0401}"), (b"Iacute", "\u{00CD}"), (b"Icirc", "\u{00CE}"), (b"Icy", "\u{0418}"), (b"Idot", "\u{0130}"), (b"Ifr", "\u{2111}"), (b"Igrave", "\u{00CC}"), (b"Im", "\u{2111}"), (b"Imacr", "\u{012A}"), (b"ImaginaryI", "\u{2148}"), (b"Implies", "\u{21D2}"), (b"Int", "\u{222C}"), (b"Integral", "\u{222B}"), (b"Intersection", "\u{22C2}"), (b"InvisibleComma", "\u{2063}"), (b"InvisibleTimes", "\u{2062}"), (b"Iogon", "\u{012E}"), (b"Iopf", "\u{1D540}"), (b"Iota", "\u{0399}"), (b"Iscr", "\u{2110}"), (b"Itilde", "\u{0128}"), (b"Iukcy", "\u{0406}"), (b"Iuml", "\u{00CF}"), (b"Jcirc", "\u{0134}"), (b"Jcy", "\u{0419}"), (b"Jfr", "\u{1D50D}"), (b"Jopf", "\u{1D541}"), (b"Jscr", "\u{1D4A5}"), (b"Jsercy", "\u{0408}"), (b"Jukcy", "\u{0404}"), (b"KHcy", "\u{0425}"), (b"KJcy", "\u{040C}"), (b"Kappa", "\u{039A}"), (b"Kcedil", "\u{0136}"), (b"Kcy", "\u{041A}"), (b"Kfr", "\u{1D50E}"), (b"Kopf", "\u{1D542}"), (b"Kscr", "\u{1D4A6}"), (b"LJcy", "\u{0409}"), (b"LT", "\u{003C}"), (b"Lacute", "\u{0139}"), (b"Lambda", "\u{039B}"), (b"Lang", "\u{27EA}"), (b"Laplacetrf", "\u{2112}"), (b"Larr", "\u{219E}"), (b"Lcaron", "\u{013D}"), (b"Lcedil", "\u{013B}"), (b"Lcy", "\u{041B}"), (b"LeftAngleBracket", "\u{27E8}"), (b"LeftArrow", "\u{2190}"), (b"LeftArrowBar", "\u{21E4}"), (b"LeftArrowRightArrow", "\u{21C6}"), (b"LeftCeiling", "\u{2308}"), (b"LeftDoubleBracket", "\u{27E6}"), (b"LeftDownTeeVector", "\u{2961}"), (b"LeftDownVector", "\u{21C3}"), (b"LeftDownVectorBar", "\u{2959}"), (b"LeftFloor", "\u{230A}"), (b"LeftRightArrow", "\u{2194}"), (b"LeftRightVector", "\u{294E}"), (b"LeftTee", "\u{22A3}"), (b"LeftTeeArrow", "\u{21A4}"), (b"LeftTeeVector", "\u{295A}"), (b"LeftTriangle", "\u{22B2}"), (b"LeftTriangleBar", "\u{29CF}"), (b"LeftTriangleEqual", "\u{22B4}"), (b"LeftUpDownVector", "\u{2951}"), (b"LeftUpTeeVector", "\u{2960}"), (b"LeftUpVector", "\u{21BF}"), (b"LeftUpVectorBar", "\u{2958}"), (b"LeftVector", "\u{21BC}"), (b"LeftVectorBar", "\u{2952}"), (b"Leftarrow", "\u{21D0}"), (b"Leftrightarrow", "\u{21D4}"), (b"LessEqualGreater", "\u{22DA}"), (b"LessFullEqual", "\u{2266}"), (b"LessGreater", "\u{2276}"), (b"LessLess", "\u{2AA1}"), (b"LessSlantEqual", "\u{2A7D}"), (b"LessTilde", "\u{2272}"), (b"Lfr", "\u{1D50F}"), (b"Ll", "\u{22D8}"), (b"Lleftarrow", "\u{21DA}"), (b"Lmidot", "\u{013F}"), (b"LongLeftArrow", "\u{27F5}"), (b"LongLeftRightArrow", "\u{27F7}"), (b"LongRightArrow", "\u{27F6}"), (b"Longleftarrow", "\u{27F8}"), (b"Longleftrightarrow", "\u{27FA}"), (b"Longrightarrow", "\u{27F9}"), (b"Lopf", "\u{1D543}"), (b"LowerLeftArrow", "\u{2199}"), (b"LowerRightArrow", "\u{2198}"), (b"Lscr", "\u{2112}"), (b"Lsh", "\u{21B0}"), (b"Lstrok", "\u{0141}"), (b"Lt", "\u{226A}"), (b"Map", "\u{2905}"), (b"Mcy", "\u{041C}"), (b"MediumSpace", "\u{205F}"), (b"Mellintrf", "\u{2133}"), (b"Mfr", "\u{1D510}"), (b"MinusPlus", "\u{2213}"), (b"Mopf", "\u{1D544}"), (b"Mscr", "\u{2133}"), (b"Mu", "\u{039C}"), (b"NJcy", "\u{040A}"), (b"Nacute", "\u{0143}"), (b"Ncaron", "\u{0147}"), (b"Ncedil", "\u{0145}"), (b"Ncy", "\u{041D}"), (b"NegativeMediumSpace", "\u{200B}"), (b"NegativeThickSpace", "\u{200B}"), (b"NegativeThinSpace", "\u{200B}"), (b"NegativeVeryThinSpace", "\u{200B}"), (b"NestedGreaterGreater", "\u{226B}"), (b"NestedLessLess", "\u{226A}"), (b"NewLine", "\u{000A}"), (b"Nfr", "\u{1D511}"), (b"NoBreak", "\u{2060}"), (b"NonBreakingSpace", "\u{00A0}"), (b"Nopf", "\u{2115}"), (b"Not", "\u{2AEC}"), (b"NotCongruent", "\u{2262}"), (b"NotCupCap", "\u{226D}"), (b"NotDoubleVerticalBar", "\u{2226}"), (b"NotElement", "\u{2209}"), (b"NotEqual", "\u{2260}"), (b"NotEqualTilde", "\u{2242}\u{0338}"), (b"NotExists", "\u{2204}"), (b"NotGreater", "\u{226F}"), (b"NotGreaterEqual", "\u{2271}"), (b"NotGreaterFullEqual", "\u{2267}\u{0338}"), (b"NotGreaterGreater", "\u{226B}\u{0338}"), (b"NotGreaterLess", "\u{2279}"), (b"NotGreaterSlantEqual", "\u{2A7E}\u{0338}"), (b"NotGreaterTilde", "\u{2275}"), (b"NotHumpDownHump", "\u{224E}\u{0338}"), (b"NotHumpEqual", "\u{224F}\u{0338}"), (b"NotLeftTriangle", "\u{22EA}"), (b"NotLeftTriangleBar", "\u{29CF}\u{0338}"), (b"NotLeftTriangleEqual", "\u{22EC}"), (b"NotLess", "\u{226E}"), (b"NotLessEqual", "\u{2270}"), (b"NotLessGreater", "\u{2278}"), (b"NotLessLess", "\u{226A}\u{0338}"), (b"NotLessSlantEqual", "\u{2A7D}\u{0338}"), (b"NotLessTilde", "\u{2274}"), (b"NotNestedGreaterGreater", "\u{2AA2}\u{0338}"), (b"NotNestedLessLess", "\u{2AA1}\u{0338}"), (b"NotPrecedes", "\u{2280}"), (b"NotPrecedesEqual", "\u{2AAF}\u{0338}"), (b"NotPrecedesSlantEqual", "\u{22E0}"), (b"NotReverseElement", "\u{220C}"), (b"NotRightTriangle", "\u{22EB}"), (b"NotRightTriangleBar", "\u{29D0}\u{0338}"), (b"NotRightTriangleEqual", "\u{22ED}"), (b"NotSquareSubset", "\u{228F}\u{0338}"), (b"NotSquareSubsetEqual", "\u{22E2}"), (b"NotSquareSuperset", "\u{2290}\u{0338}"), (b"NotSquareSupersetEqual", "\u{22E3}"), (b"NotSubset", "\u{2282}\u{20D2}"), (b"NotSubsetEqual", "\u{2288}"), (b"NotSucceeds", "\u{2281}"), (b"NotSucceedsEqual", "\u{2AB0}\u{0338}"), (b"NotSucceedsSlantEqual", "\u{22E1}"), (b"NotSucceedsTilde", "\u{227F}\u{0338}"), (b"NotSuperset", "\u{2283}\u{20D2}"), (b"NotSupersetEqual", "\u{2289}"), (b"NotTilde", "\u{2241}"), (b"NotTildeEqual", "\u{2244}"), (b"NotTildeFullEqual", "\u{2247}"), (b"NotTildeTilde", "\u{2249}"), (b"NotVerticalBar", "\u{2224}"), (b"Nscr", "\u{1D4A9}"), (b"Ntilde", "\u{00D1}"), (b"Nu", "\u{039D}"), (b"OElig", "\u{0152}"), (b"Oacute", "\u{00D3}"), (b"Ocirc", "\u{00D4}"), (b"Ocy", "\u{041E}"), (b"Odblac", "\u{0150}"), (b"Ofr", "\u{1D512}"), (b"Ograve", "\u{00D2}"), (b"Omacr", "\u{014C}"), (b"Omega", "\u{03A9}"), (b"Omicron", "\u{039F}"), (b"Oopf", "\u{1D546}"), (b"OpenCurlyDoubleQuote", "\u{201C}"), (b"OpenCurlyQuote", "\u{2018}"), (b"Or", "\u{2A54}"), (b"Oscr", "\u{1D4AA}"), (b"Oslash", "\u{00D8}"), (b"Otilde", "\u{00D5}"), (b"Otimes", "\u{2A37}"), (b"Ouml", "\u{00D6}"), (b"OverBar", "\u{203E}"), (b"OverBrace", "\u{23DE}"), (b"OverBracket", "\u{23B4}"), (b"OverParenthesis", "\u{23DC}"), (b"PartialD", "\u{2202}"), (b"Pcy", "\u{041F}"), (b"Pfr", "\u{1D513}"), (b"Phi", "\u{03A6}"), (b"Pi", "\u{03A0}"), (b"PlusMinus", "\u{00B1}"), (b"Poincareplane", "\u{210C}"), (b"Popf", "\u{2119}"), (b"Pr", "\u{2ABB}"), (b"Precedes", "\u{227A}"), (b"PrecedesEqual", "\u{2AAF}"), (b"PrecedesSlantEqual", "\u{227C}"), (b"PrecedesTilde", "\u{227E}"), (b"Prime", "\u{2033}"), (b"Product", "\u{220F}"), (b"Proportion", "\u{2237}"), (b"Proportional", "\u{221D}"), (b"Pscr", "\u{1D4AB}"), (b"Psi", "\u{03A8}"), (b"QUOT", "\u{0022}"), (b"Qfr", "\u{1D514}"), (b"Qopf", "\u{211A}"), (b"Qscr", "\u{1D4AC}"), (b"RBarr", "\u{2910}"), (b"REG", "\u{00AE}"), (b"Racute", "\u{0154}"), (b"Rang", "\u{27EB}"), (b"Rarr", "\u{21A0}"), (b"Rarrtl", "\u{2916}"), (b"Rcaron", "\u{0158}"), (b"Rcedil", "\u{0156}"), (b"Rcy", "\u{0420}"), (b"Re", "\u{211C}"), (b"ReverseElement", "\u{220B}"), (b"ReverseEquilibrium", "\u{21CB}"), (b"ReverseUpEquilibrium", "\u{296F}"), (b"Rfr", "\u{211C}"), (b"Rho", "\u{03A1}"), (b"RightAngleBracket", "\u{27E9}"), (b"RightArrow", "\u{2192}"), (b"RightArrowBar", "\u{21E5}"), (b"RightArrowLeftArrow", "\u{21C4}"), (b"RightCeiling", "\u{2309}"), (b"RightDoubleBracket", "\u{27E7}"), (b"RightDownTeeVector", "\u{295D}"), (b"RightDownVector", "\u{21C2}"), (b"RightDownVectorBar", "\u{2955}"), (b"RightFloor", "\u{230B}"), (b"RightTee", "\u{22A2}"), (b"RightTeeArrow", "\u{21A6}"), (b"RightTeeVector", "\u{295B}"), (b"RightTriangle", "\u{22B3}"), (b"RightTriangleBar", "\u{29D0}"), (b"RightTriangleEqual", "\u{22B5}"), (b"RightUpDownVector", "\u{294F}"), (b"RightUpTeeVector", "\u{295C}"), (b"RightUpVector", "\u{21BE}"), (b"RightUpVectorBar", "\u{2954}"), (b"RightVector", "\u{21C0}"), (b"RightVectorBar", "\u{2953}"), (b"Rightarrow", "\u{21D2}"), (b"Ropf", "\u{211D}"), (b"RoundImplies", "\u{2970}"), (b"Rrightarrow", "\u{21DB}"), (b"Rscr", "\u{211B}"), (b"Rsh", "\u{21B1}"), (b"RuleDelayed", "\u{29F4}"), (b"SHCHcy", "\u{0429}"), (b"SHcy", "\u{0428}"), (b"SOFTcy", "\u{042C}"), (b"Sacute", "\u{015A}"), (b"Sc", "\u{2ABC}"), (b"Scaron", "\u{0160}"), (b"Scedil", "\u{015E}"), (b"Scirc", "\u{015C}"), (b"Scy", "\u{0421}"), (b"Sfr", "\u{1D516}"), (b"ShortDownArrow", "\u{2193}"), (b"ShortLeftArrow", "\u{2190}"), (b"ShortRightArrow", "\u{2192}"), (b"ShortUpArrow", "\u{2191}"), (b"Sigma", "\u{03A3}"), (b"SmallCircle", "\u{2218}"), (b"Sopf", "\u{1D54A}"), (b"Sqrt", "\u{221A}"), (b"Square", "\u{25A1}"), (b"SquareIntersection", "\u{2293}"), (b"SquareSubset", "\u{228F}"), (b"SquareSubsetEqual", "\u{2291}"), (b"SquareSuperset", "\u{2290}"), (b"SquareSupersetEqual", "\u{2292}"), (b"SquareUnion", "\u{2294}"), (b"Sscr", "\u{1D4AE}"), (b"Star", "\u{22C6}"), (b"Sub", "\u{22D0}"), (b"Subset", "\u{22D0}"), (b"SubsetEqual", "\u{2286}"), (b"Succeeds", "\u{227B}"), (b"SucceedsEqual", "\u{2AB0}"), (b"SucceedsSlantEqual", "\u{227D}"), (b"SucceedsTilde", "\u{227F}"), (b"SuchThat", "\u{220B}"), (b"Sum", "\u{2211}"), (b"Sup", "\u{22D1}"), (b"Superset", "\u{2283}"), (b"SupersetEqual", "\u{2287}"), (b"Supset", "\u{22D1}"), (b"THORN", "\u{00DE}"), (b"TRADE", "\u{2122}"), (b"TSHcy", "\u{040B}"), (b"TScy", "\u{0426}"), (b"Tab", "\u{0009}"), (b"Tau", "\u{03A4}"), (b"Tcaron", "\u{0164}"), (b"Tcedil", "\u{0162}"), (b"Tcy", "\u{0422}"), (b"Tfr", "\u{1D517}"), (b"Therefore", "\u{2234}"), (b"Theta", "\u{0398}"), (b"ThickSpace", "\u{205F}\u{200A}"), (b"ThinSpace", "\u{2009}"), (b"Tilde", "\u{223C}"), (b"TildeEqual", "\u{2243}"), (b"TildeFullEqual", "\u{2245}"), (b"TildeTilde", "\u{2248}"), (b"Topf", "\u{1D54B}"), (b"TripleDot", "\u{20DB}"), (b"Tscr", "\u{1D4AF}"), (b"Tstrok", "\u{0166}"), (b"Uacute", "\u{00DA}"), (b"Uarr", "\u{219F}"), (b"Uarrocir", "\u{2949}"), (b"Ubrcy", "\u{040E}"), (b"Ubreve", "\u{016C}"), (b"Ucirc", "\u{00DB}"), (b"Ucy", "\u{0423}"), (b"Udblac", "\u{0170}"), (b"Ufr", "\u{1D518}"), (b"Ugrave", "\u{00D9}"), (b"Umacr", "\u{016A}"), (b"UnderBar", "\u{005F}"), (b"UnderBrace", "\u{23DF}"), (b"UnderBracket", "\u{23B5}"), (b"UnderParenthesis", "\u{23DD}"), (b"Union", "\u{22C3}"), (b"UnionPlus", "\u{228E}"), (b"Uogon", "\u{0172}"), (b"Uopf", "\u{1D54C}"), (b"UpArrow", "\u{2191}"), (b"UpArrowBar", "\u{2912}"), (b"UpArrowDownArrow", "\u{21C5}"), (b"UpDownArrow", "\u{2195}"), (b"UpEquilibrium", "\u{296E}"), (b"UpTee", "\u{22A5}"), (b"UpTeeArrow", "\u{21A5}"), (b"Uparrow", "\u{21D1}"), (b"Updownarrow", "\u{21D5}"), (b"UpperLeftArrow", "\u{2196}"), (b"UpperRightArrow", "\u{2197}"), (b"Upsi", "\u{03D2}"), (b"Upsilon", "\u{03A5}"), (b"Uring", "\u{016E}"), (b"Uscr", "\u{1D4B0}"), (b"Utilde", "\u{0168}"), (b"Uuml", "\u{00DC}"), (b"VDash", "\u{22AB}"), (b"Vbar", "\u{2AEB}"), (b"Vcy", "\u{0412}"), (b"Vdash", "\u{22A9}"), (b"Vdashl", "\u{2AE6}"), (b"Vee", "\u{22C1}"), (b"Verbar", "\u{2016}"), (b"Vert", "\u{2016}"), (b"VerticalBar", "\u{2223}"), (b"VerticalLine", "\u{007C}"), (b"VerticalSeparator", "\u{2758}"), (b"VerticalTilde", "\u{2240}"), (b"VeryThinSpace", "\u{200A}"), (b"Vfr", "\u{1D519}"), (b"Vopf", "\u{1D54D}"), (b"Vscr", "\u{1D4B1}"), (b"Vvdash", "\u{22AA}"), (b"Wcirc", "\u{0174}"), (b"Wedge", "\u{22C0}"), (b"Wfr", "\u{1D51A}"), (b"Wopf", "\u{1D54E}"), (b"Wscr", "\u{1D4B2}"), (b"Xfr", "\u{1D51B}"), (b"Xi", "\u{039E}"), (b"Xopf", "\u{1D54F}"), (b"Xscr", "\u{1D4B3}"), (b"YAcy", "\u{042F}"), (b"YIcy", "\u{0407}"), (b"YUcy", "\u{042E}"), (b"Yacute", "\u{00DD}"), (b"Ycirc", "\u{0176}"), (b"Ycy", "\u{042B}"), (b"Yfr", "\u{1D51C}"), (b"Yopf", "\u{1D550}"), (b"Yscr", "\u{1D4B4}"), (b"Yuml", "\u{0178}"), (b"ZHcy", "\u{0416}"), (b"Zacute", "\u{0179}"), (b"Zcaron", "\u{017D}"), (b"Zcy", "\u{0417}"), (b"Zdot", "\u{017B}"), (b"ZeroWidthSpace", "\u{200B}"), (b"Zeta", "\u{0396}"), (b"Zfr", "\u{2128}"), (b"Zopf", "\u{2124}"), (b"Zscr", "\u{1D4B5}"), (b"aacute", "\u{00E1}"), (b"abreve", "\u{0103}"), (b"ac", "\u{223E}"), (b"acE", "\u{223E}\u{0333}"), (b"acd", "\u{223F}"), (b"acirc", "\u{00E2}"), (b"acute", "\u{00B4}"), (b"acy", "\u{0430}"), (b"aelig", "\u{00E6}"), (b"af", "\u{2061}"), (b"afr", "\u{1D51E}"), (b"agrave", "\u{00E0}"), (b"alefsym", "\u{2135}"), (b"aleph", "\u{2135}"), (b"alpha", "\u{03B1}"), (b"amacr", "\u{0101}"), (b"amalg", "\u{2A3F}"), (b"amp", "\u{0026}"), (b"and", "\u{2227}"), (b"andand", "\u{2A55}"), (b"andd", "\u{2A5C}"), (b"andslope", "\u{2A58}"), (b"andv", "\u{2A5A}"), (b"ang", "\u{2220}"), (b"ange", "\u{29A4}"), (b"angle", "\u{2220}"), (b"angmsd", "\u{2221}"), (b"angmsdaa", "\u{29A8}"), (b"angmsdab", "\u{29A9}"), (b"angmsdac", "\u{29AA}"), (b"angmsdad", "\u{29AB}"), (b"angmsdae", "\u{29AC}"), (b"angmsdaf", "\u{29AD}"), (b"angmsdag", "\u{29AE}"), (b"angmsdah", "\u{29AF}"), (b"angrt", "\u{221F}"), (b"angrtvb", "\u{22BE}"), (b"angrtvbd", "\u{299D}"), (b"angsph", "\u{2222}"), (b"angst", "\u{00C5}"), (b"angzarr", "\u{237C}"), (b"aogon", "\u{0105}"), (b"aopf", "\u{1D552}"), (b"ap", "\u{2248}"), (b"apE", "\u{2A70}"), (b"apacir", "\u{2A6F}"), (b"ape", "\u{224A}"), (b"apid", "\u{224B}"), (b"apos", "\u{0027}"), (b"approx", "\u{2248}"), (b"approxeq", "\u{224A}"), (b"aring", "\u{00E5}"), (b"ascr", "\u{1D4B6}"), (b"ast", "\u{002A}"), (b"asymp", "\u{2248}"), (b"asympeq", "\u{224D}"), (b"atilde", "\u{00E3}"), (b"auml", "\u{00E4}"), (b"awconint", "\u{2233}"), (b"awint", "\u{2A11}"), (b"bNot", "\u{2AED}"), (b"backcong", "\u{224C}"), (b"backepsilon", "\u{03F6}"), (b"backprime", "\u{2035}"), (b"backsim", "\u{223D}"), (b"backsimeq", "\u{22CD}"), (b"barvee", "\u{22BD}"), (b"barwed", "\u{2305}"), (b"barwedge", "\u{2305}"), (b"bbrk", "\u{23B5}"), (b"bbrktbrk", "\u{23B6}"), (b"bcong", "\u{224C}"), (b"bcy", "\u{0431}"), (b"bdquo", "\u{201E}"), (b"becaus", "\u{2235}"), (b"because", "\u{2235}"), (b"bemptyv", "\u{29B0}"), (b"bepsi", "\u{03F6}"), (b"bernou", "\u{212C}"), (b"beta", "\u{03B2}"), (b"beth", "\u{2136}"), (b"between", "\u{226C}"), (b"bfr", "\u{1D51F}"), (b"bigcap", "\u{22C2}"), (b"bigcirc", "\u{25EF}"), (b"bigcup", "\u{22C3}"), (b"bigodot", "\u{2A00}"), (b"bigoplus", "\u{2A01}"), (b"bigotimes", "\u{2A02}"), (b"bigsqcup", "\u{2A06}"), (b"bigstar", "\u{2605}"), (b"bigtriangledown", "\u{25BD}"), (b"bigtriangleup", "\u{25B3}"), (b"biguplus", "\u{2A04}"), (b"bigvee", "\u{22C1}"), (b"bigwedge", "\u{22C0}"), (b"bkarow", "\u{290D}"), (b"blacklozenge", "\u{29EB}"), (b"blacksquare", "\u{25AA}"), (b"blacktriangle", "\u{25B4}"), (b"blacktriangledown", "\u{25BE}"), (b"blacktriangleleft", "\u{25C2}"), (b"blacktriangleright", "\u{25B8}"), (b"blank", "\u{2423}"), (b"blk12", "\u{2592}"), (b"blk14", "\u{2591}"), (b"blk34", "\u{2593}"), (b"block", "\u{2588}"), (b"bne", "\u{003D}\u{20E5}"), (b"bnequiv", "\u{2261}\u{20E5}"), (b"bnot", "\u{2310}"), (b"bopf", "\u{1D553}"), (b"bot", "\u{22A5}"), (b"bottom", "\u{22A5}"), (b"bowtie", "\u{22C8}"), (b"boxDL", "\u{2557}"), (b"boxDR", "\u{2554}"), (b"boxDl", "\u{2556}"), (b"boxDr", "\u{2553}"), (b"boxH", "\u{2550}"), (b"boxHD", "\u{2566}"), (b"boxHU", "\u{2569}"), (b"boxHd", "\u{2564}"), (b"boxHu", "\u{2567}"), (b"boxUL", "\u{255D}"), (b"boxUR", "\u{255A}"), (b"boxUl", "\u{255C}"), (b"boxUr", "\u{2559}"), (b"boxV", "\u{2551}"), (b"boxVH", "\u{256C}"), (b"boxVL", "\u{2563}"), (b"boxVR", "\u{2560}"), (b"boxVh", "\u{256B}"), (b"boxVl", "\u{2562}"), (b"boxVr", "\u{255F}"), (b"boxbox", "\u{29C9}"), (b"boxdL", "\u{2555}"), (b"boxdR", "\u{2552}"), (b"boxdl", "\u{2510}"), (b"boxdr", "\u{250C}"), (b"boxh", "\u{2500}"), (b"boxhD", "\u{2565}"), (b"boxhU", "\u{2568}"), (b"boxhd", "\u{252C}"), (b"boxhu", "\u{2534}"), (b"boxminus", "\u{229F}"), (b"boxplus", "\u{229E}"), (b"boxtimes", "\u{22A0}"), (b"boxuL", "\u{255B}"), (b"boxuR", "\u{2558}"), (b"boxul", "\u{2518}"), (b"boxur", "\u{2514}"), (b"boxv", "\u{2502}"), (b"boxvH", "\u{256A}"), (b"boxvL", "\u{2561}"), (b"boxvR", "\u{255E}"), (b"boxvh", "\u{253C}"), (b"boxvl", "\u{2524}"), (b"boxvr", "\u{251C}"), (b"bprime", "\u{2035}"), (b"breve", "\u{02D8}"), (b"brvbar", "\u{00A6}"), (b"bscr", "\u{1D4B7}"), (b"bsemi", "\u{204F}"), (b"bsim", "\u{223D}"), (b"bsime", "\u{22CD}"), (b"bsol", "\u{005C}"), (b"bsolb", "\u{29C5}"), (b"bsolhsub", "\u{27C8}"), (b"bull", "\u{2022}"), (b"bullet", "\u{2022}"), (b"bump", "\u{224E}"), (b"bumpE", "\u{2AAE}"), (b"bumpe", "\u{224F}"), (b"bumpeq", "\u{224F}"), (b"cacute", "\u{0107}"), (b"cap", "\u{2229}"), (b"capand", "\u{2A44}"), (b"capbrcup", "\u{2A49}"), (b"capcap", "\u{2A4B}"), (b"capcup", "\u{2A47}"), (b"capdot", "\u{2A40}"), (b"caps", "\u{2229}\u{FE00}"), (b"caret", "\u{2041}"), (b"caron", "\u{02C7}"), (b"ccaps", "\u{2A4D}"), (b"ccaron", "\u{010D}"), (b"ccedil", "\u{00E7}"), (b"ccirc", "\u{0109}"), (b"ccups", "\u{2A4C}"), (b"ccupssm", "\u{2A50}"), (b"cdot", "\u{010B}"), (b"cedil", "\u{00B8}"), (b"cemptyv", "\u{29B2}"), (b"cent", "\u{00A2}"), (b"centerdot", "\u{00B7}"), (b"cfr", "\u{1D520}"), (b"chcy", "\u{0447}"), (b"check", "\u{2713}"), (b"checkmark", "\u{2713}"), (b"chi", "\u{03C7}"), (b"cir", "\u{25CB}"), (b"cirE", "\u{29C3}"), (b"circ", "\u{02C6}"), (b"circeq", "\u{2257}"), (b"circlearrowleft", "\u{21BA}"), (b"circlearrowright", "\u{21BB}"), (b"circledR", "\u{00AE}"), (b"circledS", "\u{24C8}"), (b"circledast", "\u{229B}"), (b"circledcirc", "\u{229A}"), (b"circleddash", "\u{229D}"), (b"cire", "\u{2257}"), (b"cirfnint", "\u{2A10}"), (b"cirmid", "\u{2AEF}"), (b"cirscir", "\u{29C2}"), (b"clubs", "\u{2663}"), (b"clubsuit", "\u{2663}"), (b"colon", "\u{003A}"), (b"colone", "\u{2254}"), (b"coloneq", "\u{2254}"), (b"comma", "\u{002C}"), (b"commat", "\u{0040}"), (b"comp", "\u{2201}"), (b"compfn", "\u{2218}"), (b"complement", "\u{2201}"), (b"complexes", "\u{2102}"), (b"cong", "\u{2245}"), (b"congdot", "\u{2A6D}"), (b"conint", "\u{222E}"), (b"copf", "\u{1D554}"), (b"coprod", "\u{2210}"), (b"copy", "\u{00A9}"), (b"copysr", "\u{2117}"), (b"crarr", "\u{21B5}"), (b"cross", "\u{2717}"), (b"cscr", "\u{1D4B8}"), (b"csub", "\u{2ACF}"), (b"csube", "\u{2AD1}"), (b"csup", "\u{2AD0}"), (b"csupe", "\u{2AD2}"), (b"ctdot", "\u{22EF}"), (b"cudarrl", "\u{2938}"), (b"cudarrr", "\u{2935}"), (b"cuepr", "\u{22DE}"), (b"cuesc", "\u{22DF}"), (b"cularr", "\u{21B6}"), (b"cularrp", "\u{293D}"), (b"cup", "\u{222A}"), (b"cupbrcap", "\u{2A48}"), (b"cupcap", "\u{2A46}"), (b"cupcup", "\u{2A4A}"), (b"cupdot", "\u{228D}"), (b"cupor", "\u{2A45}"), (b"cups", "\u{222A}\u{FE00}"), (b"curarr", "\u{21B7}"), (b"curarrm", "\u{293C}"), (b"curlyeqprec", "\u{22DE}"), (b"curlyeqsucc", "\u{22DF}"), (b"curlyvee", "\u{22CE}"), (b"curlywedge", "\u{22CF}"), (b"curren", "\u{00A4}"), (b"curvearrowleft", "\u{21B6}"), (b"curvearrowright", "\u{21B7}"), (b"cuvee", "\u{22CE}"), (b"cuwed", "\u{22CF}"), (b"cwconint", "\u{2232}"), (b"cwint", "\u{2231}"), (b"cylcty", "\u{232D}"), (b"dArr", "\u{21D3}"), (b"dHar", "\u{2965}"), (b"dagger", "\u{2020}"), (b"daleth", "\u{2138}"), (b"darr", "\u{2193}"), (b"dash", "\u{2010}"), (b"dashv", "\u{22A3}"), (b"dbkarow", "\u{290F}"), (b"dblac", "\u{02DD}"), (b"dcaron", "\u{010F}"), (b"dcy", "\u{0434}"), (b"dd", "\u{2146}"), (b"ddagger", "\u{2021}"), (b"ddarr", "\u{21CA}"), (b"ddotseq", "\u{2A77}"), (b"deg", "\u{00B0}"), (b"delta", "\u{03B4}"), (b"demptyv", "\u{29B1}"), (b"dfisht", "\u{297F}"), (b"dfr", "\u{1D521}"), (b"dharl", "\u{21C3}"), (b"dharr", "\u{21C2}"), (b"diam", "\u{22C4}"), (b"diamond", "\u{22C4}"), (b"diamondsuit", "\u{2666}"), (b"diams", "\u{2666}"), (b"die", "\u{00A8}"), (b"digamma", "\u{03DD}"), (b"disin", "\u{22F2}"), (b"div", "\u{00F7}"), (b"divide", "\u{00F7}"), (b"divideontimes", "\u{22C7}"), (b"divonx", "\u{22C7}"), (b"djcy", "\u{0452}"), (b"dlcorn", "\u{231E}"), (b"dlcrop", "\u{230D}"), (b"dollar", "\u{0024}"), (b"dopf", "\u{1D555}"), (b"dot", "\u{02D9}"), (b"doteq", "\u{2250}"), (b"doteqdot", "\u{2251}"), (b"dotminus", "\u{2238}"), (b"dotplus", "\u{2214}"), (b"dotsquare", "\u{22A1}"), (b"doublebarwedge", "\u{2306}"), (b"downarrow", "\u{2193}"), (b"downdownarrows", "\u{21CA}"), (b"downharpoonleft", "\u{21C3}"), (b"downharpoonright", "\u{21C2}"), (b"drbkarow", "\u{2910}"), (b"drcorn", "\u{231F}"), (b"drcrop", "\u{230C}"), (b"dscr", "\u{1D4B9}"), (b"dscy", "\u{0455}"), (b"dsol", "\u{29F6}"), (b"dstrok", "\u{0111}"), (b"dtdot", "\u{22F1}"), (b"dtri", "\u{25BF}"), (b"dtrif", "\u{25BE}"), (b"duarr", "\u{21F5}"), (b"duhar", "\u{296F}"), (b"dwangle", "\u{29A6}"), (b"dzcy", "\u{045F}"), (b"dzigrarr", "\u{27FF}"), (b"eDDot", "\u{2A77}"), (b"eDot", "\u{2251}"), (b"eacute", "\u{00E9}"), (b"easter", "\u{2A6E}"), (b"ecaron", "\u{011B}"), (b"ecir", "\u{2256}"), (b"ecirc", "\u{00EA}"), (b"ecolon", "\u{2255}"), (b"ecy", "\u{044D}"), (b"edot", "\u{0117}"), (b"ee", "\u{2147}"), (b"efDot", "\u{2252}"), (b"efr", "\u{1D522}"), (b"eg", "\u{2A9A}"), (b"egrave", "\u{00E8}"), (b"egs", "\u{2A96}"), (b"egsdot", "\u{2A98}"), (b"el", "\u{2A99}"), (b"elinters", "\u{23E7}"), (b"ell", "\u{2113}"), (b"els", "\u{2A95}"), (b"elsdot", "\u{2A97}"), (b"emacr", "\u{0113}"), (b"empty", "\u{2205}"), (b"emptyset", "\u{2205}"), (b"emptyv", "\u{2205}"), (b"emsp", "\u{2003}"), (b"emsp13", "\u{2004}"), (b"emsp14", "\u{2005}"), (b"eng", "\u{014B}"), (b"ensp", "\u{2002}"), (b"eogon", "\u{0119}"), (b"eopf", "\u{1D556}"), (b"epar", "\u{22D5}"), (b"eparsl", "\u{29E3}"), (b"eplus", "\u{2A71}"), (b"epsi", "\u{03B5}"), (b"epsilon", "\u{03B5}"), (b"epsiv", "\u{03F5}"), (b"eqcirc", "\u{2256}"), (b"eqcolon", "\u{2255}"), (b"eqsim", "\u{2242}"), (b"eqslantgtr", "\u{2A96}"), (b"eqslantless", "\u{2A95}"), (b"equals", "\u{003D}"), (b"equest", "\u{225F}"), (b"equiv", "\u{2261}"), (b"equivDD", "\u{2A78}"), (b"eqvparsl", "\u{29E5}"), (b"erDot", "\u{2253}"), (b"erarr", "\u{2971}"), (b"escr", "\u{212F}"), (b"esdot", "\u{2250}"), (b"esim", "\u{2242}"), (b"eta", "\u{03B7}"), (b"eth", "\u{00F0}"), (b"euml", "\u{00EB}"), (b"euro", "\u{20AC}"), (b"excl", "\u{0021}"), (b"exist", "\u{2203}"), (b"expectation", "\u{2130}"), (b"exponentiale", "\u{2147}"), (b"fallingdotseq", "\u{2252}"), (b"fcy", "\u{0444}"), (b"female", "\u{2640}"), (b"ffilig", "\u{FB03}"), (b"fflig", "\u{FB00}"), (b"ffllig", "\u{FB04}"), (b"ffr", "\u{1D523}"), (b"filig", "\u{FB01}"), (b"fjlig", "\u{0066}\u{006A}"), (b"flat", "\u{266D}"), (b"fllig", "\u{FB02}"), (b"fltns", "\u{25B1}"), (b"fnof", "\u{0192}"), (b"fopf", "\u{1D557}"), (b"forall", "\u{2200}"), (b"fork", "\u{22D4}"), (b"forkv", "\u{2AD9}"), (b"fpartint", "\u{2A0D}"), (b"frac12", "\u{00BD}"), (b"frac13", "\u{2153}"), (b"frac14", "\u{00BC}"), (b"frac15", "\u{2155}"), (b"frac16", "\u{2159}"), (b"frac18", "\u{215B}"), (b"frac23", "\u{2154}"), (b"frac25", "\u{2156}"), (b"frac34", "\u{00BE}"), (b"frac35", "\u{2157}"), (b"frac38", "\u{215C}"), (b"frac45", "\u{2158}"), (b"frac56", "\u{215A}"), (b"frac58", "\u{215D}"), (b"frac78", "\u{215E}"), (b"frasl", "\u{2044}"), (b"frown", "\u{2322}"), (b"fscr", "\u{1D4BB}"), (b"gE", "\u{2267}"), (b"gEl", "\u{2A8C}"), (b"gacute", "\u{01F5}"), (b"gamma", "\u{03B3}"), (b"gammad", "\u{03DD}"), (b"gap", "\u{2A86}"), (b"gbreve", "\u{011F}"), (b"gcirc", "\u{011D}"), (b"gcy", "\u{0433}"), (b"gdot", "\u{0121}"), (b"ge", "\u{2265}"), (b"gel", "\u{22DB}"), (b"geq", "\u{2265}"), (b"geqq", "\u{2267}"), (b"geqslant", "\u{2A7E}"), (b"ges", "\u{2A7E}"), (b"gescc", "\u{2AA9}"), (b"gesdot", "\u{2A80}"), (b"gesdoto", "\u{2A82}"), (b"gesdotol", "\u{2A84}"), (b"gesl", "\u{22DB}\u{FE00}"), (b"gesles", "\u{2A94}"), (b"gfr", "\u{1D524}"), (b"gg", "\u{226B}"), (b"ggg", "\u{22D9}"), (b"gimel", "\u{2137}"), (b"gjcy", "\u{0453}"), (b"gl", "\u{2277}"), (b"glE", "\u{2A92}"), (b"gla", "\u{2AA5}"), (b"glj", "\u{2AA4}"), (b"gnE", "\u{2269}"), (b"gnap", "\u{2A8A}"), (b"gnapprox", "\u{2A8A}"), (b"gne", "\u{2A88}"), (b"gneq", "\u{2A88}"), (b"gneqq", "\u{2269}"), (b"gnsim", "\u{22E7}"), (b"gopf", "\u{1D558}"), (b"grave", "\u{0060}"), (b"gscr", "\u{210A}"), (b"gsim", "\u{2273}"), (b"gsime", "\u{2A8E}"), (b"gsiml", "\u{2A90}"), (b"gt", "\u{003E}"), (b"gtcc", "\u{2AA7}"), (b"gtcir", "\u{2A7A}"), (b"gtdot", "\u{22D7}"), (b"gtlPar", "\u{2995}"), (b"gtquest", "\u{2A7C}"), (b"gtrapprox", "\u{2A86}"), (b"gtrarr", "\u{2978}"), (b"gtrdot", "\u{22D7}"), (b"gtreqless", "\u{22DB}"), (b"gtreqqless", "\u{2A8C}"), (b"gtrless", "\u{2277}"), (b"gtrsim", "\u{2273}"), (b"gvertneqq", "\u{2269}\u{FE00}"), (b"gvnE", "\u{2269}\u{FE00}"), (b"hArr", "\u{21D4}"), (b"hairsp", "\u{200A}"), (b"half", "\u{00BD}"), (b"hamilt", "\u{210B}"), (b"hardcy", "\u{044A}"), (b"harr", "\u{2194}"), (b"harrcir", "\u{2948}"), (b"harrw", "\u{21AD}"), (b"hbar", "\u{210F}"), (b"hcirc", "\u{0125}"), (b"hearts", "\u{2665}"), (b"heartsuit", "\u{2665}"), (b"hellip", "\u{2026}"), (b"hercon", "\u{22B9}"), (b"hfr", "\u{1D525}"), (b"hksearow", "\u{2925}"), (b"hkswarow", "\u{2926}"), (b"hoarr", "\u{21FF}"), (b"homtht", "\u{223B}"), (b"hookleftarrow", "\u{21A9}"), (b"hookrightarrow", "\u{21AA}"), (b"hopf", "\u{1D559}"), (b"horbar", "\u{2015}"), (b"hscr", "\u{1D4BD}"), (b"hslash", "\u{210F}"), (b"hstrok", "\u{0127}"), (b"hybull", "\u{2043}"), (b"hyphen", "\u{2010}"), (b"iacute", "\u{00ED}"), (b"ic", "\u{2063}"), (b"icirc", "\u{00EE}"), (b"icy", "\u{0438}"), (b"iecy", "\u{0435}"), (b"iexcl", "\u{00A1}"), (b"iff", "\u{21D4}"), (b"ifr", "\u{1D526}"), (b"igrave", "\u{00EC}"), (b"ii", "\u{2148}"), (b"iiiint", "\u{2A0C}"), (b"iiint", "\u{222D}"), (b"iinfin", "\u{29DC}"), (b"iiota", "\u{2129}"), (b"ijlig", "\u{0133}"), (b"imacr", "\u{012B}"), (b"image", "\u{2111}"), (b"imagline", "\u{2110}"), (b"imagpart", "\u{2111}"), (b"imath", "\u{0131}"), (b"imof", "\u{22B7}"), (b"imped", "\u{01B5}"), (b"in", "\u{2208}"), (b"incare", "\u{2105}"), (b"infin", "\u{221E}"), (b"infintie", "\u{29DD}"), (b"inodot", "\u{0131}"), (b"int", "\u{222B}"), (b"intcal", "\u{22BA}"), (b"integers", "\u{2124}"), (b"intercal", "\u{22BA}"), (b"intlarhk", "\u{2A17}"), (b"intprod", "\u{2A3C}"), (b"iocy", "\u{0451}"), (b"iogon", "\u{012F}"), (b"iopf", "\u{1D55A}"), (b"iota", "\u{03B9}"), (b"iprod", "\u{2A3C}"), (b"iquest", "\u{00BF}"), (b"iscr", "\u{1D4BE}"), (b"isin", "\u{2208}"), (b"isinE", "\u{22F9}"), (b"isindot", "\u{22F5}"), (b"isins", "\u{22F4}"), (b"isinsv", "\u{22F3}"), (b"isinv", "\u{2208}"), (b"it", "\u{2062}"), (b"itilde", "\u{0129}"), (b"iukcy", "\u{0456}"), (b"iuml", "\u{00EF}"), (b"jcirc", "\u{0135}"), (b"jcy", "\u{0439}"), (b"jfr", "\u{1D527}"), (b"jmath", "\u{0237}"), (b"jopf", "\u{1D55B}"), (b"jscr", "\u{1D4BF}"), (b"jsercy", "\u{0458}"), (b"jukcy", "\u{0454}"), (b"kappa", "\u{03BA}"), (b"kappav", "\u{03F0}"), (b"kcedil", "\u{0137}"), (b"kcy", "\u{043A}"), (b"kfr", "\u{1D528}"), (b"kgreen", "\u{0138}"), (b"khcy", "\u{0445}"), (b"kjcy", "\u{045C}"), (b"kopf", "\u{1D55C}"), (b"kscr", "\u{1D4C0}"), (b"lAarr", "\u{21DA}"), (b"lArr", "\u{21D0}"), (b"lAtail", "\u{291B}"), (b"lBarr", "\u{290E}"), (b"lE", "\u{2266}"), (b"lEg", "\u{2A8B}"), (b"lHar", "\u{2962}"), (b"lacute", "\u{013A}"), (b"laemptyv", "\u{29B4}"), (b"lagran", "\u{2112}"), (b"lambda", "\u{03BB}"), (b"lang", "\u{27E8}"), (b"langd", "\u{2991}"), (b"langle", "\u{27E8}"), (b"lap", "\u{2A85}"), (b"laquo", "\u{00AB}"), (b"larr", "\u{2190}"), (b"larrb", "\u{21E4}"), (b"larrbfs", "\u{291F}"), (b"larrfs", "\u{291D}"), (b"larrhk", "\u{21A9}"), (b"larrlp", "\u{21AB}"), (b"larrpl", "\u{2939}"), (b"larrsim", "\u{2973}"), (b"larrtl", "\u{21A2}"), (b"lat", "\u{2AAB}"), (b"latail", "\u{2919}"), (b"late", "\u{2AAD}"), (b"lates", "\u{2AAD}\u{FE00}"), (b"lbarr", "\u{290C}"), (b"lbbrk", "\u{2772}"), (b"lbrace", "\u{007B}"), (b"lbrack", "\u{005B}"), (b"lbrke", "\u{298B}"), (b"lbrksld", "\u{298F}"), (b"lbrkslu", "\u{298D}"), (b"lcaron", "\u{013E}"), (b"lcedil", "\u{013C}"), (b"lceil", "\u{2308}"), (b"lcub", "\u{007B}"), (b"lcy", "\u{043B}"), (b"ldca", "\u{2936}"), (b"ldquo", "\u{201C}"), (b"ldquor", "\u{201E}"), (b"ldrdhar", "\u{2967}"), (b"ldrushar", "\u{294B}"), (b"ldsh", "\u{21B2}"), (b"le", "\u{2264}"), (b"leftarrow", "\u{2190}"), (b"leftarrowtail", "\u{21A2}"), (b"leftharpoondown", "\u{21BD}"), (b"leftharpoonup", "\u{21BC}"), (b"leftleftarrows", "\u{21C7}"), (b"leftrightarrow", "\u{2194}"), (b"leftrightarrows", "\u{21C6}"), (b"leftrightharpoons", "\u{21CB}"), (b"leftrightsquigarrow", "\u{21AD}"), (b"leftthreetimes", "\u{22CB}"), (b"leg", "\u{22DA}"), (b"leq", "\u{2264}"), (b"leqq", "\u{2266}"), (b"leqslant", "\u{2A7D}"), (b"les", "\u{2A7D}"), (b"lescc", "\u{2AA8}"), (b"lesdot", "\u{2A7F}"), (b"lesdoto", "\u{2A81}"), (b"lesdotor", "\u{2A83}"), (b"lesg", "\u{22DA}\u{FE00}"), (b"lesges", "\u{2A93}"), (b"lessapprox", "\u{2A85}"), (b"lessdot", "\u{22D6}"), (b"lesseqgtr", "\u{22DA}"), (b"lesseqqgtr", "\u{2A8B}"), (b"lessgtr", "\u{2276}"), (b"lesssim", "\u{2272}"), (b"lfisht", "\u{297C}"), (b"lfloor", "\u{230A}"), (b"lfr", "\u{1D529}"), (b"lg", "\u{2276}"), (b"lgE", "\u{2A91}"), (b"lhard", "\u{21BD}"), (b"lharu", "\u{21BC}"), (b"lharul", "\u{296A}"), (b"lhblk", "\u{2584}"), (b"ljcy", "\u{0459}"), (b"ll", "\u{226A}"), (b"llarr", "\u{21C7}"), (b"llcorner", "\u{231E}"), (b"llhard", "\u{296B}"), (b"lltri", "\u{25FA}"), (b"lmidot", "\u{0140}"), (b"lmoust", "\u{23B0}"), (b"lmoustache", "\u{23B0}"), (b"lnE", "\u{2268}"), (b"lnap", "\u{2A89}"), (b"lnapprox", "\u{2A89}"), (b"lne", "\u{2A87}"), (b"lneq", "\u{2A87}"), (b"lneqq", "\u{2268}"), (b"lnsim", "\u{22E6}"), (b"loang", "\u{27EC}"), (b"loarr", "\u{21FD}"), (b"lobrk", "\u{27E6}"), (b"longleftarrow", "\u{27F5}"), (b"longleftrightarrow", "\u{27F7}"), (b"longmapsto", "\u{27FC}"), (b"longrightarrow", "\u{27F6}"), (b"looparrowleft", "\u{21AB}"), (b"looparrowright", "\u{21AC}"), (b"lopar", "\u{2985}"), (b"lopf", "\u{1D55D}"), (b"loplus", "\u{2A2D}"), (b"lotimes", "\u{2A34}"), (b"lowast", "\u{2217}"), (b"lowbar", "\u{005F}"), (b"loz", "\u{25CA}"), (b"lozenge", "\u{25CA}"), (b"lozf", "\u{29EB}"), (b"lpar", "\u{0028}"), (b"lparlt", "\u{2993}"), (b"lrarr", "\u{21C6}"), (b"lrcorner", "\u{231F}"), (b"lrhar", "\u{21CB}"), (b"lrhard", "\u{296D}"), (b"lrm", "\u{200E}"), (b"lrtri", "\u{22BF}"), (b"lsaquo", "\u{2039}"), (b"lscr", "\u{1D4C1}"), (b"lsh", "\u{21B0}"), (b"lsim", "\u{2272}"), (b"lsime", "\u{2A8D}"), (b"lsimg", "\u{2A8F}"), (b"lsqb", "\u{005B}"), (b"lsquo", "\u{2018}"), (b"lsquor", "\u{201A}"), (b"lstrok", "\u{0142}"), (b"lt", "\u{003C}"), (b"ltcc", "\u{2AA6}"), (b"ltcir", "\u{2A79}"), (b"ltdot", "\u{22D6}"), (b"lthree", "\u{22CB}"), (b"ltimes", "\u{22C9}"), (b"ltlarr", "\u{2976}"), (b"ltquest", "\u{2A7B}"), (b"ltrPar", "\u{2996}"), (b"ltri", "\u{25C3}"), (b"ltrie", "\u{22B4}"), (b"ltrif", "\u{25C2}"), (b"lurdshar", "\u{294A}"), (b"luruhar", "\u{2966}"), (b"lvertneqq", "\u{2268}\u{FE00}"), (b"lvnE", "\u{2268}\u{FE00}"), (b"mDDot", "\u{223A}"), (b"macr", "\u{00AF}"), (b"male", "\u{2642}"), (b"malt", "\u{2720}"), (b"maltese", "\u{2720}"), (b"map", "\u{21A6}"), (b"mapsto", "\u{21A6}"), (b"mapstodown", "\u{21A7}"), (b"mapstoleft", "\u{21A4}"), (b"mapstoup", "\u{21A5}"), (b"marker", "\u{25AE}"), (b"mcomma", "\u{2A29}"), (b"mcy", "\u{043C}"), (b"mdash", "\u{2014}"), (b"measuredangle", "\u{2221}"), (b"mfr", "\u{1D52A}"), (b"mho", "\u{2127}"), (b"micro", "\u{00B5}"), (b"mid", "\u{2223}"), (b"midast", "\u{002A}"), (b"midcir", "\u{2AF0}"), (b"middot", "\u{00B7}"), (b"minus", "\u{2212}"), (b"minusb", "\u{229F}"), (b"minusd", "\u{2238}"), (b"minusdu", "\u{2A2A}"), (b"mlcp", "\u{2ADB}"), (b"mldr", "\u{2026}"), (b"mnplus", "\u{2213}"), (b"models", "\u{22A7}"), (b"mopf", "\u{1D55E}"), (b"mp", "\u{2213}"), (b"mscr", "\u{1D4C2}"), (b"mstpos", "\u{223E}"), (b"mu", "\u{03BC}"), (b"multimap", "\u{22B8}"), (b"mumap", "\u{22B8}"), (b"nGg", "\u{22D9}\u{0338}"), (b"nGt", "\u{226B}\u{20D2}"), (b"nGtv", "\u{226B}\u{0338}"), (b"nLeftarrow", "\u{21CD}"), (b"nLeftrightarrow", "\u{21CE}"), (b"nLl", "\u{22D8}\u{0338}"), (b"nLt", "\u{226A}\u{20D2}"), (b"nLtv", "\u{226A}\u{0338}"), (b"nRightarrow", "\u{21CF}"), (b"nVDash", "\u{22AF}"), (b"nVdash", "\u{22AE}"), (b"nabla", "\u{2207}"), (b"nacute", "\u{0144}"), (b"nang", "\u{2220}\u{20D2}"), (b"nap", "\u{2249}"), (b"napE", "\u{2A70}\u{0338}"), (b"napid", "\u{224B}\u{0338}"), (b"napos", "\u{0149}"), (b"napprox", "\u{2249}"), (b"natur", "\u{266E}"), (b"natural", "\u{266E}"), (b"naturals", "\u{2115}"), (b"nbsp", "\u{00A0}"), (b"nbump", "\u{224E}\u{0338}"), (b"nbumpe", "\u{224F}\u{0338}"), (b"ncap", "\u{2A43}"), (b"ncaron", "\u{0148}"), (b"ncedil", "\u{0146}"), (b"ncong", "\u{2247}"), (b"ncongdot", "\u{2A6D}\u{0338}"), (b"ncup", "\u{2A42}"), (b"ncy", "\u{043D}"), (b"ndash", "\u{2013}"), (b"ne", "\u{2260}"), (b"neArr", "\u{21D7}"), (b"nearhk", "\u{2924}"), (b"nearr", "\u{2197}"), (b"nearrow", "\u{2197}"), (b"nedot", "\u{2250}\u{0338}"), (b"nequiv", "\u{2262}"), (b"nesear", "\u{2928}"), (b"nesim", "\u{2242}\u{0338}"), (b"nexist", "\u{2204}"), (b"nexists", "\u{2204}"), (b"nfr", "\u{1D52B}"), (b"ngE", "\u{2267}\u{0338}"), (b"nge", "\u{2271}"), (b"ngeq", "\u{2271}"), (b"ngeqq", "\u{2267}\u{0338}"), (b"ngeqslant", "\u{2A7E}\u{0338}"), (b"nges", "\u{2A7E}\u{0338}"), (b"ngsim", "\u{2275}"), (b"ngt", "\u{226F}"), (b"ngtr", "\u{226F}"), (b"nhArr", "\u{21CE}"), (b"nharr", "\u{21AE}"), (b"nhpar", "\u{2AF2}"), (b"ni", "\u{220B}"), (b"nis", "\u{22FC}"), (b"nisd", "\u{22FA}"), (b"niv", "\u{220B}"), (b"njcy", "\u{045A}"), (b"nlArr", "\u{21CD}"), (b"nlE", "\u{2266}\u{0338}"), (b"nlarr", "\u{219A}"), (b"nldr", "\u{2025}"), (b"nle", "\u{2270}"), (b"nleftarrow", "\u{219A}"), (b"nleftrightarrow", "\u{21AE}"), (b"nleq", "\u{2270}"), (b"nleqq", "\u{2266}\u{0338}"), (b"nleqslant", "\u{2A7D}\u{0338}"), (b"nles", "\u{2A7D}\u{0338}"), (b"nless", "\u{226E}"), (b"nlsim", "\u{2274}"), (b"nlt", "\u{226E}"), (b"nltri", "\u{22EA}"), (b"nltrie", "\u{22EC}"), (b"nmid", "\u{2224}"), (b"nopf", "\u{1D55F}"), (b"not", "\u{00AC}"), (b"notin", "\u{2209}"), (b"notinE", "\u{22F9}\u{0338}"), (b"notindot", "\u{22F5}\u{0338}"), (b"notinva", "\u{2209}"), (b"notinvb", "\u{22F7}"), (b"notinvc", "\u{22F6}"), (b"notni", "\u{220C}"), (b"notniva", "\u{220C}"), (b"notnivb", "\u{22FE}"), (b"notnivc", "\u{22FD}"), (b"npar", "\u{2226}"), (b"nparallel", "\u{2226}"), (b"nparsl", "\u{2AFD}\u{20E5}"), (b"npart", "\u{2202}\u{0338}"), (b"npolint", "\u{2A14}"), (b"npr", "\u{2280}"), (b"nprcue", "\u{22E0}"), (b"npre", "\u{2AAF}\u{0338}"), (b"nprec", "\u{2280}"), (b"npreceq", "\u{2AAF}\u{0338}"), (b"nrArr", "\u{21CF}"), (b"nrarr", "\u{219B}"), (b"nrarrc", "\u{2933}\u{0338}"), (b"nrarrw", "\u{219D}\u{0338}"), (b"nrightarrow", "\u{219B}"), (b"nrtri", "\u{22EB}"), (b"nrtrie", "\u{22ED}"), (b"nsc", "\u{2281}"), (b"nsccue", "\u{22E1}"), (b"nsce", "\u{2AB0}\u{0338}"), (b"nscr", "\u{1D4C3}"), (b"nshortmid", "\u{2224}"), (b"nshortparallel", "\u{2226}"), (b"nsim", "\u{2241}"), (b"nsime", "\u{2244}"), (b"nsimeq", "\u{2244}"), (b"nsmid", "\u{2224}"), (b"nspar", "\u{2226}"), (b"nsqsube", "\u{22E2}"), (b"nsqsupe", "\u{22E3}"), (b"nsub", "\u{2284}"), (b"nsubE", "\u{2AC5}\u{0338}"), (b"nsube", "\u{2288}"), (b"nsubset", "\u{2282}\u{20D2}"), (b"nsubseteq", "\u{2288}"), (b"nsubseteqq", "\u{2AC5}\u{0338}"), (b"nsucc", "\u{2281}"), (b"nsucceq", "\u{2AB0}\u{0338}"), (b"nsup", "\u{2285}"), (b"nsupE", "\u{2AC6}\u{0338}"), (b"nsupe", "\u{2289}"), (b"nsupset", "\u{2283}\u{20D2}"), (b"nsupseteq", "\u{2289}"), (b"nsupseteqq", "\u{2AC6}\u{0338}"), (b"ntgl", "\u{2279}"), (b"ntilde", "\u{00F1}"), (b"ntlg", "\u{2278}"), (b"ntriangleleft", "\u{22EA}"), (b"ntrianglelefteq", "\u{22EC}"), (b"ntriangleright", "\u{22EB}"), (b"ntrianglerighteq", "\u{22ED}"), (b"nu", "\u{03BD}"), (b"num", "\u{0023}"), (b"numero", "\u{2116}"), (b"numsp", "\u{2007}"), (b"nvDash", "\u{22AD}"), (b"nvHarr", "\u{2904}"), (b"nvap", "\u{224D}\u{20D2}"), (b"nvdash", "\u{22AC}"), (b"nvge", "\u{2265}\u{20D2}"), (b"nvgt", "\u{003E}\u{20D2}"), (b"nvinfin", "\u{29DE}"), (b"nvlArr", "\u{2902}"), (b"nvle", "\u{2264}\u{20D2}"), (b"nvlt", "\u{003C}\u{20D2}"), (b"nvltrie", "\u{22B4}\u{20D2}"), (b"nvrArr", "\u{2903}"), (b"nvrtrie", "\u{22B5}\u{20D2}"), (b"nvsim", "\u{223C}\u{20D2}"), (b"nwArr", "\u{21D6}"), (b"nwarhk", "\u{2923}"), (b"nwarr", "\u{2196}"), (b"nwarrow", "\u{2196}"), (b"nwnear", "\u{2927}"), (b"oS", "\u{24C8}"), (b"oacute", "\u{00F3}"), (b"oast", "\u{229B}"), (b"ocir", "\u{229A}"), (b"ocirc", "\u{00F4}"), (b"ocy", "\u{043E}"), (b"odash", "\u{229D}"), (b"odblac", "\u{0151}"), (b"odiv", "\u{2A38}"), (b"odot", "\u{2299}"), (b"odsold", "\u{29BC}"), (b"oelig", "\u{0153}"), (b"ofcir", "\u{29BF}"), (b"ofr", "\u{1D52C}"), (b"ogon", "\u{02DB}"), (b"ograve", "\u{00F2}"), (b"ogt", "\u{29C1}"), (b"ohbar", "\u{29B5}"), (b"ohm", "\u{03A9}"), (b"oint", "\u{222E}"), (b"olarr", "\u{21BA}"), (b"olcir", "\u{29BE}"), (b"olcross", "\u{29BB}"), (b"oline", "\u{203E}"), (b"olt", "\u{29C0}"), (b"omacr", "\u{014D}"), (b"omega", "\u{03C9}"), (b"omicron", "\u{03BF}"), (b"omid", "\u{29B6}"), (b"ominus", "\u{2296}"), (b"oopf", "\u{1D560}"), (b"opar", "\u{29B7}"), (b"operp", "\u{29B9}"), (b"oplus", "\u{2295}"), (b"or", "\u{2228}"), (b"orarr", "\u{21BB}"), (b"ord", "\u{2A5D}"), (b"order", "\u{2134}"), (b"orderof", "\u{2134}"), (b"ordf", "\u{00AA}"), (b"ordm", "\u{00BA}"), (b"origof", "\u{22B6}"), (b"oror", "\u{2A56}"), (b"orslope", "\u{2A57}"), (b"orv", "\u{2A5B}"), (b"oscr", "\u{2134}"), (b"oslash", "\u{00F8}"), (b"osol", "\u{2298}"), (b"otilde", "\u{00F5}"), (b"otimes", "\u{2297}"), (b"otimesas", "\u{2A36}"), (b"ouml", "\u{00F6}"), (b"ovbar", "\u{233D}"), (b"par", "\u{2225}"), (b"para", "\u{00B6}"), (b"parallel", "\u{2225}"), (b"parsim", "\u{2AF3}"), (b"parsl", "\u{2AFD}"), (b"part", "\u{2202}"), (b"pcy", "\u{043F}"), (b"percnt", "\u{0025}"), (b"period", "\u{002E}"), (b"permil", "\u{2030}"), (b"perp", "\u{22A5}"), (b"pertenk", "\u{2031}"), (b"pfr", "\u{1D52D}"), (b"phi", "\u{03C6}"), (b"phiv", "\u{03D5}"), (b"phmmat", "\u{2133}"), (b"phone", "\u{260E}"), (b"pi", "\u{03C0}"), (b"pitchfork", "\u{22D4}"), (b"piv", "\u{03D6}"), (b"planck", "\u{210F}"), (b"planckh", "\u{210E}"), (b"plankv", "\u{210F}"), (b"plus", "\u{002B}"), (b"plusacir", "\u{2A23}"), (b"plusb", "\u{229E}"), (b"pluscir", "\u{2A22}"), (b"plusdo", "\u{2214}"), (b"plusdu", "\u{2A25}"), (b"pluse", "\u{2A72}"), (b"plusmn", "\u{00B1}"), (b"plussim", "\u{2A26}"), (b"plustwo", "\u{2A27}"), (b"pm", "\u{00B1}"), (b"pointint", "\u{2A15}"), (b"popf", "\u{1D561}"), (b"pound", "\u{00A3}"), (b"pr", "\u{227A}"), (b"prE", "\u{2AB3}"), (b"prap", "\u{2AB7}"), (b"prcue", "\u{227C}"), (b"pre", "\u{2AAF}"), (b"prec", "\u{227A}"), (b"precapprox", "\u{2AB7}"), (b"preccurlyeq", "\u{227C}"), (b"preceq", "\u{2AAF}"), (b"precnapprox", "\u{2AB9}"), (b"precneqq", "\u{2AB5}"), (b"precnsim", "\u{22E8}"), (b"precsim", "\u{227E}"), (b"prime", "\u{2032}"), (b"primes", "\u{2119}"), (b"prnE", "\u{2AB5}"), (b"prnap", "\u{2AB9}"), (b"prnsim", "\u{22E8}"), (b"prod", "\u{220F}"), (b"profalar", "\u{232E}"), (b"profline", "\u{2312}"), (b"profsurf", "\u{2313}"), (b"prop", "\u{221D}"), (b"propto", "\u{221D}"), (b"prsim", "\u{227E}"), (b"prurel", "\u{22B0}"), (b"pscr", "\u{1D4C5}"), (b"psi", "\u{03C8}"), (b"puncsp", "\u{2008}"), (b"qfr", "\u{1D52E}"), (b"qint", "\u{2A0C}"), (b"qopf", "\u{1D562}"), (b"qprime", "\u{2057}"), (b"qscr", "\u{1D4C6}"), (b"quaternions", "\u{210D}"), (b"quatint", "\u{2A16}"), (b"quest", "\u{003F}"), (b"questeq", "\u{225F}"), (b"quot", "\u{0022}"), (b"rAarr", "\u{21DB}"), (b"rArr", "\u{21D2}"), (b"rAtail", "\u{291C}"), (b"rBarr", "\u{290F}"), (b"rHar", "\u{2964}"), (b"race", "\u{223D}\u{0331}"), (b"racute", "\u{0155}"), (b"radic", "\u{221A}"), (b"raemptyv", "\u{29B3}"), (b"rang", "\u{27E9}"), (b"rangd", "\u{2992}"), (b"range", "\u{29A5}"), (b"rangle", "\u{27E9}"), (b"raquo", "\u{00BB}"), (b"rarr", "\u{2192}"), (b"rarrap", "\u{2975}"), (b"rarrb", "\u{21E5}"), (b"rarrbfs", "\u{2920}"), (b"rarrc", "\u{2933}"), (b"rarrfs", "\u{291E}"), (b"rarrhk", "\u{21AA}"), (b"rarrlp", "\u{21AC}"), (b"rarrpl", "\u{2945}"), (b"rarrsim", "\u{2974}"), (b"rarrtl", "\u{21A3}"), (b"rarrw", "\u{219D}"), (b"ratail", "\u{291A}"), (b"ratio", "\u{2236}"), (b"rationals", "\u{211A}"), (b"rbarr", "\u{290D}"), (b"rbbrk", "\u{2773}"), (b"rbrace", "\u{007D}"), (b"rbrack", "\u{005D}"), (b"rbrke", "\u{298C}"), (b"rbrksld", "\u{298E}"), (b"rbrkslu", "\u{2990}"), (b"rcaron", "\u{0159}"), (b"rcedil", "\u{0157}"), (b"rceil", "\u{2309}"), (b"rcub", "\u{007D}"), (b"rcy", "\u{0440}"), (b"rdca", "\u{2937}"), (b"rdldhar", "\u{2969}"), (b"rdquo", "\u{201D}"), (b"rdquor", "\u{201D}"), (b"rdsh", "\u{21B3}"), (b"real", "\u{211C}"), (b"realine", "\u{211B}"), (b"realpart", "\u{211C}"), (b"reals", "\u{211D}"), (b"rect", "\u{25AD}"), (b"reg", "\u{00AE}"), (b"rfisht", "\u{297D}"), (b"rfloor", "\u{230B}"), (b"rfr", "\u{1D52F}"), (b"rhard", "\u{21C1}"), (b"rharu", "\u{21C0}"), (b"rharul", "\u{296C}"), (b"rho", "\u{03C1}"), (b"rhov", "\u{03F1}"), (b"rightarrow", "\u{2192}"), (b"rightarrowtail", "\u{21A3}"), (b"rightharpoondown", "\u{21C1}"), (b"rightharpoonup", "\u{21C0}"), (b"rightleftarrows", "\u{21C4}"), (b"rightleftharpoons", "\u{21CC}"), (b"rightrightarrows", "\u{21C9}"), (b"rightsquigarrow", "\u{219D}"), (b"rightthreetimes", "\u{22CC}"), (b"ring", "\u{02DA}"), (b"risingdotseq", "\u{2253}"), (b"rlarr", "\u{21C4}"), (b"rlhar", "\u{21CC}"), (b"rlm", "\u{200F}"), (b"rmoust", "\u{23B1}"), (b"rmoustache", "\u{23B1}"), (b"rnmid", "\u{2AEE}"), (b"roang", "\u{27ED}"), (b"roarr", "\u{21FE}"), (b"robrk", "\u{27E7}"), (b"ropar", "\u{2986}"), (b"ropf", "\u{1D563}"), (b"roplus", "\u{2A2E}"), (b"rotimes", "\u{2A35}"), (b"rpar", "\u{0029}"), (b"rpargt", "\u{2994}"), (b"rppolint", "\u{2A12}"), (b"rrarr", "\u{21C9}"), (b"rsaquo", "\u{203A}"), (b"rscr", "\u{1D4C7}"), (b"rsh", "\u{21B1}"), (b"rsqb", "\u{005D}"), (b"rsquo", "\u{2019}"), (b"rsquor", "\u{2019}"), (b"rthree", "\u{22CC}"), (b"rtimes", "\u{22CA}"), (b"rtri", "\u{25B9}"), (b"rtrie", "\u{22B5}"), (b"rtrif", "\u{25B8}"), (b"rtriltri", "\u{29CE}"), (b"ruluhar", "\u{2968}"), (b"rx", "\u{211E}"), (b"sacute", "\u{015B}"), (b"sbquo", "\u{201A}"), (b"sc", "\u{227B}"), (b"scE", "\u{2AB4}"), (b"scap", "\u{2AB8}"), (b"scaron", "\u{0161}"), (b"sccue", "\u{227D}"), (b"sce", "\u{2AB0}"), (b"scedil", "\u{015F}"), (b"scirc", "\u{015D}"), (b"scnE", "\u{2AB6}"), (b"scnap", "\u{2ABA}"), (b"scnsim", "\u{22E9}"), (b"scpolint", "\u{2A13}"), (b"scsim", "\u{227F}"), (b"scy", "\u{0441}"), (b"sdot", "\u{22C5}"), (b"sdotb", "\u{22A1}"), (b"sdote", "\u{2A66}"), (b"seArr", "\u{21D8}"), (b"searhk", "\u{2925}"), (b"searr", "\u{2198}"), (b"searrow", "\u{2198}"), (b"sect", "\u{00A7}"), (b"semi", "\u{003B}"), (b"seswar", "\u{2929}"), (b"setminus", "\u{2216}"), (b"setmn", "\u{2216}"), (b"sext", "\u{2736}"), (b"sfr", "\u{1D530}"), (b"sfrown", "\u{2322}"), (b"sharp", "\u{266F}"), (b"shchcy", "\u{0449}"), (b"shcy", "\u{0448}"), (b"shortmid", "\u{2223}"), (b"shortparallel", "\u{2225}"), (b"shy", "\u{00AD}"), (b"sigma", "\u{03C3}"), (b"sigmaf", "\u{03C2}"), (b"sigmav", "\u{03C2}"), (b"sim", "\u{223C}"), (b"simdot", "\u{2A6A}"), (b"sime", "\u{2243}"), (b"simeq", "\u{2243}"), (b"simg", "\u{2A9E}"), (b"simgE", "\u{2AA0}"), (b"siml", "\u{2A9D}"), (b"simlE", "\u{2A9F}"), (b"simne", "\u{2246}"), (b"simplus", "\u{2A24}"), (b"simrarr", "\u{2972}"), (b"slarr", "\u{2190}"), (b"smallsetminus", "\u{2216}"), (b"smashp", "\u{2A33}"), (b"smeparsl", "\u{29E4}"), (b"smid", "\u{2223}"), (b"smile", "\u{2323}"), (b"smt", "\u{2AAA}"), (b"smte", "\u{2AAC}"), (b"smtes", "\u{2AAC}\u{FE00}"), (b"softcy", "\u{044C}"), (b"sol", "\u{002F}"), (b"solb", "\u{29C4}"), (b"solbar", "\u{233F}"), (b"sopf", "\u{1D564}"), (b"spades", "\u{2660}"), (b"spadesuit", "\u{2660}"), (b"spar", "\u{2225}"), (b"sqcap", "\u{2293}"), (b"sqcaps", "\u{2293}\u{FE00}"), (b"sqcup", "\u{2294}"), (b"sqcups", "\u{2294}\u{FE00}"), (b"sqsub", "\u{228F}"), (b"sqsube", "\u{2291}"), (b"sqsubset", "\u{228F}"), (b"sqsubseteq", "\u{2291}"), (b"sqsup", "\u{2290}"), (b"sqsupe", "\u{2292}"), (b"sqsupset", "\u{2290}"), (b"sqsupseteq", "\u{2292}"), (b"squ", "\u{25A1}"), (b"square", "\u{25A1}"), (b"squarf", "\u{25AA}"), (b"squf", "\u{25AA}"), (b"srarr", "\u{2192}"), (b"sscr", "\u{1D4C8}"), (b"ssetmn", "\u{2216}"), (b"ssmile", "\u{2323}"), (b"sstarf", "\u{22C6}"), (b"star", "\u{2606}"), (b"starf", "\u{2605}"), (b"straightepsilon", "\u{03F5}"), (b"straightphi", "\u{03D5}"), (b"strns", "\u{00AF}"), (b"sub", "\u{2282}"), (b"subE", "\u{2AC5}"), (b"subdot", "\u{2ABD}"), (b"sube", "\u{2286}"), (b"subedot", "\u{2AC3}"), (b"submult", "\u{2AC1}"), (b"subnE", "\u{2ACB}"), (b"subne", "\u{228A}"), (b"subplus", "\u{2ABF}"), (b"subrarr", "\u{2979}"), (b"subset", "\u{2282}"), (b"subseteq", "\u{2286}"), (b"subseteqq", "\u{2AC5}"), (b"subsetneq", "\u{228A}"), (b"subsetneqq", "\u{2ACB}"), (b"subsim", "\u{2AC7}"), (b"subsub", "\u{2AD5}"), (b"subsup", "\u{2AD3}"), (b"succ", "\u{227B}"), (b"succapprox", "\u{2AB8}"), (b"succcurlyeq", "\u{227D}"), (b"succeq", "\u{2AB0}"), (b"succnapprox", "\u{2ABA}"), (b"succneqq", "\u{2AB6}"), (b"succnsim", "\u{22E9}"), (b"succsim", "\u{227F}"), (b"sum", "\u{2211}"), (b"sung", "\u{266A}"), (b"sup", "\u{2283}"), (b"sup1", "\u{00B9}"), (b"sup2", "\u{00B2}"), (b"sup3", "\u{00B3}"), (b"supE", "\u{2AC6}"), (b"supdot", "\u{2ABE}"), (b"supdsub", "\u{2AD8}"), (b"supe", "\u{2287}"), (b"supedot", "\u{2AC4}"), (b"suphsol", "\u{27C9}"), (b"suphsub", "\u{2AD7}"), (b"suplarr", "\u{297B}"), (b"supmult", "\u{2AC2}"), (b"supnE", "\u{2ACC}"), (b"supne", "\u{228B}"), (b"supplus", "\u{2AC0}"), (b"supset", "\u{2283}"), (b"supseteq", "\u{2287}"), (b"supseteqq", "\u{2AC6}"), (b"supsetneq", "\u{228B}"), (b"supsetneqq", "\u{2ACC}"), (b"supsim", "\u{2AC8}"), (b"supsub", "\u{2AD4}"), (b"supsup", "\u{2AD6}"), (b"swArr", "\u{21D9}"), (b"swarhk", "\u{2926}"), (b"swarr", "\u{2199}"), (b"swarrow", "\u{2199}"), (b"swnwar", "\u{292A}"), (b"szlig", "\u{00DF}"), (b"target", "\u{2316}"), (b"tau", "\u{03C4}"), (b"tbrk", "\u{23B4}"), (b"tcaron", "\u{0165}"), (b"tcedil", "\u{0163}"), (b"tcy", "\u{0442}"), (b"tdot", "\u{20DB}"), (b"telrec", "\u{2315}"), (b"tfr", "\u{1D531}"), (b"there4", "\u{2234}"), (b"therefore", "\u{2234}"), (b"theta", "\u{03B8}"), (b"thetasym", "\u{03D1}"), (b"thetav", "\u{03D1}"), (b"thickapprox", "\u{2248}"), (b"thicksim", "\u{223C}"), (b"thinsp", "\u{2009}"), (b"thkap", "\u{2248}"), (b"thksim", "\u{223C}"), (b"thorn", "\u{00FE}"), (b"tilde", "\u{02DC}"), (b"times", "\u{00D7}"), (b"timesb", "\u{22A0}"), (b"timesbar", "\u{2A31}"), (b"timesd", "\u{2A30}"), (b"tint", "\u{222D}"), (b"toea", "\u{2928}"), (b"top", "\u{22A4}"), (b"topbot", "\u{2336}"), (b"topcir", "\u{2AF1}"), (b"topf", "\u{1D565}"), (b"topfork", "\u{2ADA}"), (b"tosa", "\u{2929}"), (b"tprime", "\u{2034}"), (b"trade", "\u{2122}"), (b"triangle", "\u{25B5}"), (b"triangledown", "\u{25BF}"), (b"triangleleft", "\u{25C3}"), (b"trianglelefteq", "\u{22B4}"), (b"triangleq", "\u{225C}"), (b"triangleright", "\u{25B9}"), (b"trianglerighteq", "\u{22B5}"), (b"tridot", "\u{25EC}"), (b"trie", "\u{225C}"), (b"triminus", "\u{2A3A}"), (b"triplus", "\u{2A39}"), (b"trisb", "\u{29CD}"), (b"tritime", "\u{2A3B}"), (b"trpezium", "\u{23E2}"), (b"tscr", "\u{1D4C9}"), (b"tscy", "\u{0446}"), (b"tshcy", "\u{045B}"), (b"tstrok", "\u{0167}"), (b"twixt", "\u{226C}"), (b"twoheadleftarrow", "\u{219E}"), (b"twoheadrightarrow", "\u{21A0}"), (b"uArr", "\u{21D1}"), (b"uHar", "\u{2963}"), (b"uacute", "\u{00FA}"), (b"uarr", "\u{2191}"), (b"ubrcy", "\u{045E}"), (b"ubreve", "\u{016D}"), (b"ucirc", "\u{00FB}"), (b"ucy", "\u{0443}"), (b"udarr", "\u{21C5}"), (b"udblac", "\u{0171}"), (b"udhar", "\u{296E}"), (b"ufisht", "\u{297E}"), (b"ufr", "\u{1D532}"), (b"ugrave", "\u{00F9}"), (b"uharl", "\u{21BF}"), (b"uharr", "\u{21BE}"), (b"uhblk", "\u{2580}"), (b"ulcorn", "\u{231C}"), (b"ulcorner", "\u{231C}"), (b"ulcrop", "\u{230F}"), (b"ultri", "\u{25F8}"), (b"umacr", "\u{016B}"), (b"uml", "\u{00A8}"), (b"uogon", "\u{0173}"), (b"uopf", "\u{1D566}"), (b"uparrow", "\u{2191}"), (b"updownarrow", "\u{2195}"), (b"upharpoonleft", "\u{21BF}"), (b"upharpoonright", "\u{21BE}"), (b"uplus", "\u{228E}"), (b"upsi", "\u{03C5}"), (b"upsih", "\u{03D2}"), (b"upsilon", "\u{03C5}"), (b"upuparrows", "\u{21C8}"), (b"urcorn", "\u{231D}"), (b"urcorner", "\u{231D}"), (b"urcrop", "\u{230E}"), (b"uring", "\u{016F}"), (b"urtri", "\u{25F9}"), (b"uscr", "\u{1D4CA}"), (b"utdot", "\u{22F0}"), (b"utilde", "\u{0169}"), (b"utri", "\u{25B5}"), (b"utrif", "\u{25B4}"), (b"uuarr", "\u{21C8}"), (b"uuml", "\u{00FC}"), (b"uwangle", "\u{29A7}"), (b"vArr", "\u{21D5}"), (b"vBar", "\u{2AE8}"), (b"vBarv", "\u{2AE9}"), (b"vDash", "\u{22A8}"), (b"vangrt", "\u{299C}"), (b"varepsilon", "\u{03F5}"), (b"varkappa", "\u{03F0}"), (b"varnothing", "\u{2205}"), (b"varphi", "\u{03D5}"), (b"varpi", "\u{03D6}"), (b"varpropto", "\u{221D}"), (b"varr", "\u{2195}"), (b"varrho", "\u{03F1}"), (b"varsigma", "\u{03C2}"), (b"varsubsetneq", "\u{228A}\u{FE00}"), (b"varsubsetneqq", "\u{2ACB}\u{FE00}"), (b"varsupsetneq", "\u{228B}\u{FE00}"), (b"varsupsetneqq", "\u{2ACC}\u{FE00}"), (b"vartheta", "\u{03D1}"), (b"vartriangleleft", "\u{22B2}"), (b"vartriangleright", "\u{22B3}"), (b"vcy", "\u{0432}"), (b"vdash", "\u{22A2}"), (b"vee", "\u{2228}"), (b"veebar", "\u{22BB}"), (b"veeeq", "\u{225A}"), (b"vellip", "\u{22EE}"), (b"verbar", "\u{007C}"), (b"vert", "\u{007C}"), (b"vfr", "\u{1D533}"), (b"vltri", "\u{22B2}"), (b"vnsub", "\u{2282}\u{20D2}"), (b"vnsup", "\u{2283}\u{20D2}"), (b"vopf", "\u{1D567}"), (b"vprop", "\u{221D}"), (b"vrtri", "\u{22B3}"), (b"vscr", "\u{1D4CB}"), (b"vsubnE", "\u{2ACB}\u{FE00}"), (b"vsubne", "\u{228A}\u{FE00}"), (b"vsupnE", "\u{2ACC}\u{FE00}"), (b"vsupne", "\u{228B}\u{FE00}"), (b"vzigzag", "\u{299A}"), (b"wcirc", "\u{0175}"), (b"wedbar", "\u{2A5F}"), (b"wedge", "\u{2227}"), (b"wedgeq", "\u{2259}"), (b"weierp", "\u{2118}"), (b"wfr", "\u{1D534}"), (b"wopf", "\u{1D568}"), (b"wp", "\u{2118}"), (b"wr", "\u{2240}"), (b"wreath", "\u{2240}"), (b"wscr", "\u{1D4CC}"), (b"xcap", "\u{22C2}"), (b"xcirc", "\u{25EF}"), (b"xcup", "\u{22C3}"), (b"xdtri", "\u{25BD}"), (b"xfr", "\u{1D535}"), (b"xhArr", "\u{27FA}"), (b"xharr", "\u{27F7}"), (b"xi", "\u{03BE}"), (b"xlArr", "\u{27F8}"), (b"xlarr", "\u{27F5}"), (b"xmap", "\u{27FC}"), (b"xnis", "\u{22FB}"), (b"xodot", "\u{2A00}"), (b"xopf", "\u{1D569}"), (b"xoplus", "\u{2A01}"), (b"xotime", "\u{2A02}"), (b"xrArr", "\u{27F9}"), (b"xrarr", "\u{27F6}"), (b"xscr", "\u{1D4CD}"), (b"xsqcup", "\u{2A06}"), (b"xuplus", "\u{2A04}"), (b"xutri", "\u{25B3}"), (b"xvee", "\u{22C1}"), (b"xwedge", "\u{22C0}"), (b"yacute", "\u{00FD}"), (b"yacy", "\u{044F}"), (b"ycirc", "\u{0177}"), (b"ycy", "\u{044B}"), (b"yen", "\u{00A5}"), (b"yfr", "\u{1D536}"), (b"yicy", "\u{0457}"), (b"yopf", "\u{1D56A}"), (b"yscr", "\u{1D4CE}"), (b"yucy", "\u{044E}"), (b"yuml", "\u{00FF}"), (b"zacute", "\u{017A}"), (b"zcaron", "\u{017E}"), (b"zcy", "\u{0437}"), (b"zdot", "\u{017C}"), (b"zeetrf", "\u{2128}"), (b"zeta", "\u{03B6}"), (b"zfr", "\u{1D537}"), (b"zhcy", "\u{0436}"), (b"zigrarr", "\u{21DD}"), (b"zopf", "\u{1D56B}"), (b"zscr", "\u{1D4CF}"), (b"zwj", "\u{200D}"), (b"zwnj", "\u{200C}"), ]; pub(crate) fn get_entity(bytes: &[u8]) -> Option<&'static str> { ENTITIES .binary_search_by_key(&bytes, |&(key, _value)| key) .ok() .map(|i| ENTITIES[i].1) } pulldown-cmark-0.13.0/src/firstpass.rs000064400000000000000000003304301046102023000160220ustar 00000000000000//! The first pass resolves all block structure, generating an AST. Within a block, items //! are in a linear chain with potential inline markup identified. use std::cmp::max; use std::ops::Range; use crate::parse::{ scan_containers, Allocations, FootnoteDef, HeadingAttributes, Item, ItemBody, LinkDef, LINK_MAX_NESTED_PARENS, }; use crate::strings::CowStr; use crate::tree::{Tree, TreeIndex}; use crate::Options; use crate::{ linklabel::{scan_link_label_rest, LinkLabel}, HeadingLevel, }; use crate::{scanners::*, MetadataBlockKind}; use unicase::UniCase; /// Runs the first pass, which resolves the block structure of the document, /// and returns the resulting tree. pub(crate) fn run_first_pass(text: &str, options: Options) -> (Tree, Allocations<'_>) { // This is a very naive heuristic for the number of nodes // we'll need. let start_capacity = max(128, text.len() / 32); let lookup_table = &create_lut(&options); let first_pass = FirstPass { text, tree: Tree::with_capacity(start_capacity), begin_list_item: None, last_line_blank: false, allocs: Allocations::new(), options, lookup_table, brace_context_next: 0, brace_context_stack: Vec::new(), }; first_pass.run() } // Each level of brace nesting adds another entry to a hash table. // To limit the amount of memory consumed, do not create a new brace // context beyond some amount deep. // // There are actually two limits at play here: this one, // and the one where the maximum amount of distinct contexts passes // the 255 item limit imposed by using `u8`. When over 255 distinct // contexts are created, it wraps around, while this one instead makes it // saturate, which is a better behavior. const MATH_BRACE_CONTEXT_MAX_NESTING: usize = 25; /// State for the first parsing pass. struct FirstPass<'a, 'b> { text: &'a str, tree: Tree, begin_list_item: Option, last_line_blank: bool, allocs: Allocations<'a>, options: Options, lookup_table: &'b LookupTable, /// Math environment brace nesting. brace_context_stack: Vec, brace_context_next: usize, } impl<'a, 'b> FirstPass<'a, 'b> { fn run(mut self) -> (Tree, Allocations<'a>) { let mut ix = 0; while ix < self.text.len() { ix = self.parse_block(ix); } while self.tree.spine_len() > 0 { self.pop(ix); } (self.tree, self.allocs) } /// Returns offset after block. fn parse_block(&mut self, mut start_ix: usize) -> usize { let bytes = self.text.as_bytes(); let mut line_start = LineStart::new(&bytes[start_ix..]); // math spans and their braces are tracked only within a single block self.brace_context_stack.clear(); self.brace_context_next = 0; let i = scan_containers(&self.tree, &mut line_start, self.options); for _ in i..self.tree.spine_len() { self.pop(start_ix); } if self.options.contains(Options::ENABLE_OLD_FOOTNOTES) { // finish footnote if it's still open and was preceded by blank line if let Some(node_ix) = self.tree.peek_up() { if let ItemBody::FootnoteDefinition(..) = self.tree[node_ix].item.body { if self.last_line_blank { self.pop(start_ix); } } } } // Process new containers loop { let save = line_start.clone(); let outer_indent = line_start.scan_space_upto(4); if outer_indent >= 4 { line_start = save; break; } if self.options.contains(Options::ENABLE_FOOTNOTES) { // Footnote definitions let container_start = start_ix + line_start.bytes_scanned(); if let Some(bytecount) = self.parse_footnote(container_start) { start_ix = container_start + bytecount; if self.options.contains(Options::ENABLE_OLD_FOOTNOTES) { // gfm footnotes need indented, but old footnotes don't // handle this, old footnotes treat the next line as part of the current line start_ix += scan_blank_line(&bytes[start_ix..]).unwrap_or(0); } line_start = LineStart::new(&bytes[start_ix..]); continue; } } let container_start = start_ix + line_start.bytes_scanned(); if let Some((ch, index, indent)) = line_start.scan_list_marker_with_indent(outer_indent) { let after_marker_index = start_ix + line_start.bytes_scanned(); self.continue_list(container_start - outer_indent, ch, index); self.tree.append(Item { start: container_start - outer_indent, end: after_marker_index, // will get updated later if item not empty body: ItemBody::ListItem(indent), }); self.tree.push(); if let Some(n) = scan_blank_line(&bytes[after_marker_index..]) { self.begin_list_item = Some(after_marker_index + n); return after_marker_index + n; } if self.options.contains(Options::ENABLE_TASKLISTS) { let task_list_marker = line_start.scan_task_list_marker().map(|is_checked| Item { start: after_marker_index, end: start_ix + line_start.bytes_scanned(), body: ItemBody::TaskListMarker(is_checked), }); if let Some(task_list_marker) = task_list_marker { if let Some(n) = scan_blank_line(&bytes[task_list_marker.end..]) { self.tree.append(task_list_marker); self.begin_list_item = Some(task_list_marker.end + n); return task_list_marker.end + n; } else { line_start.scan_all_space(); let ix = start_ix + line_start.bytes_scanned(); return self.parse_paragraph(ix, Some(task_list_marker)); } } } } else if let Some((indent, child, item)) = self .options .contains(Options::ENABLE_DEFINITION_LIST) .then(|| { self.tree .cur() .map(|cur| (self.tree[cur].child, &mut self.tree[cur].item)) }) .flatten() .filter(|(_, item)| { matches!( item, Item { body: ItemBody::Paragraph | ItemBody::TightParagraph | ItemBody::MaybeDefinitionListTitle | ItemBody::DefinitionListDefinition(_), .. } ) }) .and_then(|item| { Some(( line_start .scan_definition_list_definition_marker_with_indent(outer_indent)?, item.0, item.1, )) }) { match item.body { ItemBody::Paragraph | ItemBody::TightParagraph => { item.body = ItemBody::DefinitionList(true); let Item { start, end, .. } = *item; let list_idx = self.tree.cur().unwrap(); let title_idx = self.tree.create_node(Item { start, end, // will get updated later if item not empty body: ItemBody::DefinitionListTitle, }); self.tree[title_idx].child = child; self.tree[list_idx].child = Some(title_idx); self.tree.push(); } ItemBody::MaybeDefinitionListTitle => { item.body = ItemBody::DefinitionListTitle; } ItemBody::DefinitionListDefinition(_) => {} _ => unreachable!(), } let after_marker_index = start_ix + line_start.bytes_scanned(); self.tree.append(Item { start: container_start - outer_indent, end: after_marker_index, // will get updated later if item not empty body: ItemBody::DefinitionListDefinition(indent), }); if let Some(ItemBody::DefinitionList(ref mut is_tight)) = self.tree.peek_up().map(|cur| &mut self.tree[cur].item.body) { if self.last_line_blank { *is_tight = false; self.last_line_blank = false; } } self.tree.push(); if let Some(n) = scan_blank_line(&bytes[after_marker_index..]) { self.begin_list_item = Some(after_marker_index + n); return after_marker_index + n; } } else if line_start.scan_blockquote_marker() { let kind = if self.options.contains(Options::ENABLE_GFM) { line_start.scan_blockquote_tag() } else { None }; self.finish_list(start_ix); self.tree.append(Item { start: container_start, end: 0, // will get set later body: ItemBody::BlockQuote(kind), }); self.tree.push(); if kind.is_some() { // blockquote tag leaves us at the end of the line // we need to scan through all the container syntax for the next line // and break out if we can't re-scan all of them let ix = start_ix + line_start.bytes_scanned(); let mut lazy_line_start = LineStart::new(&bytes[ix..]); let tree_position = scan_containers(&self.tree, &mut lazy_line_start, self.options); let current_container = tree_position == self.tree.spine_len(); if !lazy_line_start.scan_space(4) && self.scan_paragraph_interrupt( &bytes[ix + lazy_line_start.bytes_scanned()..], current_container, tree_position, ) { return ix; } else { // blockquote tags act as if they were nested in a paragraph // so you can lazily continue the imaginary paragraph off of them line_start = lazy_line_start; line_start.scan_all_space(); start_ix = ix; break; } } } else { line_start = save; break; } } let ix = start_ix + line_start.bytes_scanned(); if let Some(n) = scan_blank_line(&bytes[ix..]) { if let Some(node_ix) = self.tree.peek_up() { match &mut self.tree[node_ix].item.body { ItemBody::BlockQuote(..) => (), ItemBody::ListItem(indent) | ItemBody::DefinitionListDefinition(indent) if self.begin_list_item.is_some() => { self.last_line_blank = true; // This is a blank list item. // While the list itself can be continued no matter how many blank lines // there are between this one and the next one, it cannot nest anything // else, so its indentation should not be subtracted from the line start. *indent = 0; } _ => { self.last_line_blank = true; } } } else { self.last_line_blank = true; } return ix + n; } // Save `remaining_space` here to avoid needing to backtrack `line_start` for HTML blocks let remaining_space = line_start.remaining_space(); let indent = line_start.scan_space_upto(4); if indent == 4 { self.finish_list(start_ix); let ix = start_ix + line_start.bytes_scanned(); let remaining_space = line_start.remaining_space(); return self.parse_indented_code_block(ix, remaining_space); } let ix = start_ix + line_start.bytes_scanned(); // metadata blocks cannot be indented if indent == 0 { if let Some((_n, metadata_block_ch)) = scan_metadata_block( &bytes[ix..], self.options .contains(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS), self.options .contains(Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS), ) { self.finish_list(start_ix); return self.parse_metadata_block(ix, metadata_block_ch); } } // HTML Blocks if bytes[ix] == b'<' { // Types 1-5 are all detected by one function and all end with the same // pattern if let Some(html_end_tag) = get_html_end_tag(&bytes[(ix + 1)..]) { self.finish_list(start_ix); return self.parse_html_block_type_1_to_5( ix, html_end_tag, remaining_space, indent, ); } // Detect type 6 if starts_html_block_type_6(&bytes[(ix + 1)..]) { self.finish_list(start_ix); return self.parse_html_block_type_6_or_7(ix, remaining_space, indent); } // Detect type 7 if let Some(_html_bytes) = scan_html_type_7(&bytes[ix..]) { self.finish_list(start_ix); return self.parse_html_block_type_6_or_7(ix, remaining_space, indent); } } if let Ok(n) = scan_hrule(&bytes[ix..]) { self.finish_list(start_ix); return self.parse_hrule(n, ix); } if let Some(atx_size) = scan_atx_heading(&bytes[ix..]) { self.finish_list(start_ix); return self.parse_atx_heading(ix, atx_size); } if let Some((n, fence_ch)) = scan_code_fence(&bytes[ix..]) { self.finish_list(start_ix); return self.parse_fenced_code_block(ix, indent, fence_ch, n); } // parse refdef while let Some((bytecount, label, link_def)) = self.parse_refdef_total(start_ix + line_start.bytes_scanned()) { self.allocs.refdefs.0.entry(label).or_insert(link_def); let container_start = start_ix + line_start.bytes_scanned(); let mut ix = container_start + bytecount; // Refdefs act as if they were contained within a paragraph, for purposes of lazy // continuations. For example: // // ``` // > [foo]: http://example.com // bar // ``` // // is equivalent to // // ``` // > bar // // [foo]: http://example.com // ``` if let Some(nl) = scan_blank_line(&bytes[ix..]) { ix += nl; } else { self.finish_list(start_ix); return ix; } if let Some(lazy_line_start) = self.scan_next_line_or_lazy_continuation(&bytes[ix..]) { line_start = lazy_line_start; start_ix = ix; } else { self.finish_list(start_ix); return ix; } } let ix = start_ix + line_start.bytes_scanned(); self.parse_paragraph(ix, None) } /// footnote definitions and GFM quote markers can be "interrupted" /// like paragraphs, but otherwise can't have other blocks after them. /// /// Call this at the end of the line to parse that. If it succeeeds, /// this returns the LineStart for the new line. fn scan_next_line_or_lazy_continuation<'input>( &mut self, bytes: &'input [u8], ) -> Option> { let mut line_start = LineStart::new(bytes); let tree_position = scan_containers(&self.tree, &mut line_start, self.options); let current_container = tree_position == self.tree.spine_len(); if !line_start.scan_space(4) && self.scan_paragraph_interrupt( &bytes[line_start.bytes_scanned()..], current_container, tree_position, ) { None } else { line_start.scan_all_space(); Some(line_start) } } /// Returns the offset of the first line after the table. /// Assumptions: current focus is a table element and the table header /// matches the separator line (same number of columns). fn parse_table( &mut self, table_cols: usize, head_start: usize, body_start: usize, ) -> Option { // filled empty cells are limited to protect against quadratic growth // https://github.com/raphlinus/pulldown-cmark/issues/832 let mut missing_empty_cells = 0; // parse header. this shouldn't fail because we made sure the table header is ok let (_sep_start, thead_ix) = self.parse_table_row_inner(head_start, table_cols, &mut missing_empty_cells)?; self.tree[thead_ix].item.body = ItemBody::TableHead; // parse body let mut ix = body_start; while let Some((next_ix, _row_ix)) = self.parse_table_row(ix, table_cols, &mut missing_empty_cells) { ix = next_ix; } self.pop(ix); Some(ix) } /// Call this when containers are taken care of. /// Returns bytes scanned, row_ix fn parse_table_row_inner( &mut self, mut ix: usize, row_cells: usize, missing_empty_cells: &mut usize, ) -> Option<(usize, TreeIndex)> { // Limit to prevent a malicious input from causing a denial of service. const MAX_AUTOCOMPLETED_CELLS: usize = 1 << 18; // = 0x40000 let bytes = self.text.as_bytes(); let mut cells = 0; let mut final_cell_ix = None; let old_cur = self.tree.cur(); let row_ix = self.tree.append(Item { start: ix, end: 0, // set at end of this function body: ItemBody::TableRow, }); self.tree.push(); loop { ix += scan_ch(&bytes[ix..], b'|'); let start_ix = ix; ix += scan_whitespace_no_nl(&bytes[ix..]); if let Some(eol_bytes) = scan_eol(&bytes[ix..]) { ix += eol_bytes; break; } let cell_ix = self.tree.append(Item { start: start_ix, end: ix, body: ItemBody::TableCell, }); self.tree.push(); let (next_ix, _brk) = self.parse_line(ix, None, TableParseMode::Active); self.tree[cell_ix].item.end = next_ix; self.tree.pop(); ix = next_ix; cells += 1; if cells == row_cells { final_cell_ix = Some(cell_ix); } } if let (Some(cur), 0) = (old_cur, cells) { self.pop(ix); self.tree[cur].next = None; return None; } // fill empty cells if needed // note: this is where GFM and commonmark-extra diverge. we follow // GFM here for _ in cells..row_cells { if *missing_empty_cells >= MAX_AUTOCOMPLETED_CELLS { return None; } *missing_empty_cells += 1; self.tree.append(Item { start: ix, end: ix, body: ItemBody::TableCell, }); } // drop excess cells if let Some(cell_ix) = final_cell_ix { self.tree[cell_ix].next = None; } self.pop(ix); Some((ix, row_ix)) } /// Returns first offset after the row and the tree index of the row. fn parse_table_row( &mut self, mut ix: usize, row_cells: usize, missing_empty_cells: &mut usize, ) -> Option<(usize, TreeIndex)> { let bytes = self.text.as_bytes(); let mut line_start = LineStart::new(&bytes[ix..]); let tree_position = scan_containers(&self.tree, &mut line_start, self.options); let current_container = tree_position == self.tree.spine_len(); if !current_container { return None; } line_start.scan_all_space(); ix += line_start.bytes_scanned(); if scan_paragraph_interrupt_no_table( &bytes[ix..], current_container, self.options.contains(Options::ENABLE_FOOTNOTES), self.options.contains(Options::ENABLE_DEFINITION_LIST), &self.tree, tree_position, ) { return None; } let (ix, row_ix) = self.parse_table_row_inner(ix, row_cells, missing_empty_cells)?; Some((ix, row_ix)) } /// Returns offset of line start after paragraph. fn parse_paragraph(&mut self, start_ix: usize, tasklist_marker: Option) -> usize { let body = if let Some(ItemBody::DefinitionList(_)) = self.tree.peek_up().map(|idx| self.tree[idx].item.body) { if self.tree.cur().map_or(true, |idx| { matches!( &self.tree[idx].item.body, ItemBody::DefinitionListDefinition(..) ) }) { // blank lines between the previous definition and this one don't count self.last_line_blank = false; ItemBody::MaybeDefinitionListTitle } else { self.finish_list(start_ix); ItemBody::Paragraph } } else { self.finish_list(start_ix); ItemBody::Paragraph }; let node_ix = self.tree.append(Item { start: start_ix, end: 0, // will get set later body, }); self.tree.push(); if let Some(item) = tasklist_marker { self.tree.append(item); } let bytes = self.text.as_bytes(); let mut ix = start_ix; loop { let scan_mode = if self.options.contains(Options::ENABLE_TABLES) && ix == start_ix { TableParseMode::Scan } else { TableParseMode::Disabled }; let (next_ix, brk) = self.parse_line(ix, None, scan_mode); // break out when we find a table if let Some(Item { body: ItemBody::Table(alignment_ix), .. }) = brk { let table_cols = self.allocs[alignment_ix].len(); self.tree[node_ix].item.body = ItemBody::Table(alignment_ix); // this clears out any stuff we may have appended - but there may // be a cleaner way self.tree[node_ix].child = None; self.tree.pop(); if body == ItemBody::MaybeDefinitionListTitle { self.finish_list(ix); } self.tree.push(); if let Some(ix) = self.parse_table(table_cols, ix, next_ix) { return ix; } } ix = next_ix; let mut line_start = LineStart::new(&bytes[ix..]); let tree_position = scan_containers(&self.tree, &mut line_start, self.options); let current_container = tree_position == self.tree.spine_len(); let trailing_backslash_pos = match brk { Some(Item { start, body: ItemBody::HardBreak(true), .. }) if bytes[start] == b'\\' => Some(start), _ => None, }; if !line_start.scan_space(4) { let ix_new = ix + line_start.bytes_scanned(); if current_container { if let Some(ix_setext) = self.parse_setext_heading(ix_new, node_ix, trailing_backslash_pos.is_some()) { if let Some(pos) = trailing_backslash_pos { self.tree.append_text(pos, pos + 1, false); } self.pop(ix_setext); if body == ItemBody::MaybeDefinitionListTitle { self.finish_list(ix); } return ix_setext; } } // first check for non-empty lists, then for other interrupts let suffix = &bytes[ix_new..]; if self.scan_paragraph_interrupt(suffix, current_container, tree_position) { if let Some(pos) = trailing_backslash_pos { self.tree.append_text(pos, pos + 1, false); } break; } } line_start.scan_all_space(); if line_start.is_at_eol() { if let Some(pos) = trailing_backslash_pos { self.tree.append_text(pos, pos + 1, false); } break; } ix = next_ix + line_start.bytes_scanned(); if let Some(item) = brk { self.tree.append(item); } } self.pop(ix); ix } /// Returns end ix of setext_heading on success. fn parse_setext_heading( &mut self, ix: usize, node_ix: TreeIndex, has_trailing_content: bool, ) -> Option { let bytes = self.text.as_bytes(); let (n, level) = scan_setext_heading(&bytes[ix..])?; let mut attrs = None; if let Some(cur_ix) = self.tree.cur() { let parent_ix = self.tree.peek_up().unwrap(); let header_start = self.tree[parent_ix].item.start; // Note that `self.tree[parent_ix].item.end` might be zero at this point. // Use the end position of the current node (i.e. the last known child // of the parent) instead. let header_end = self.tree[cur_ix].item.end; // extract the trailing attribute block let (content_end, attrs_) = self.extract_and_parse_heading_attribute_block(header_start, header_end); attrs = attrs_; // strip trailing whitespace let new_end = if has_trailing_content { content_end } else { let mut last_line_start = header_start; if attrs.is_some() { loop { let next_line_start = last_line_start + scan_nextline(&bytes[last_line_start..content_end]); if next_line_start >= content_end { break; } let mut line_start = LineStart::new(&bytes[next_line_start..content_end]); if scan_containers(&self.tree, &mut line_start, self.options) != self.tree.spine_len() { break; } last_line_start = next_line_start + line_start.bytes_scanned(); } } let trailing_ws = scan_rev_while( &bytes[last_line_start..content_end], is_ascii_whitespace_no_nl, ); content_end - trailing_ws }; if attrs.is_some() { // remove trailing block attributes self.tree.truncate_siblings(new_end); } if let Some(cur_ix) = self.tree.cur() { self.tree[cur_ix].item.end = new_end; } } self.tree[node_ix].item.body = ItemBody::Heading( level, attrs.map(|attrs| self.allocs.allocate_heading(attrs)), ); Some(ix + n) } /// Parse a line of input, appending text and items to tree. /// /// Returns: index after line and an item representing the break. fn parse_line( &mut self, start: usize, end: Option, mode: TableParseMode, ) -> (usize, Option) { let bytes = self.text.as_bytes(); let bytes = match end { Some(end) => &bytes[..end], None => bytes, }; let bytes_len = bytes.len(); let mut pipes = 0; let mut last_pipe_ix = start; let mut begin_text = start; let mut backslash_escaped = false; let (final_ix, brk) = iterate_special_bytes(self.lookup_table, bytes, start, |ix, byte| { match byte { b'\n' | b'\r' => { if let TableParseMode::Active = mode { return LoopInstruction::BreakAtWith(ix, None); } let mut i = ix; let eol_bytes = scan_eol(&bytes[ix..]).unwrap(); let end_ix = ix + eol_bytes; let trailing_backslashes = scan_rev_while(&bytes[..ix], |b| b == b'\\'); if trailing_backslashes % 2 == 1 && end_ix < bytes_len { i -= 1; self.tree.append_text(begin_text, i, backslash_escaped); backslash_escaped = false; return LoopInstruction::BreakAtWith( end_ix, Some(Item { start: i, end: end_ix, body: ItemBody::HardBreak(true), }), ); } if mode == TableParseMode::Scan && pipes > 0 { // check if we may be parsing a table let next_line_ix = ix + eol_bytes; let mut line_start = LineStart::new(&bytes[next_line_ix..]); if scan_containers(&self.tree, &mut line_start, self.options) == self.tree.spine_len() { let table_head_ix = next_line_ix + line_start.bytes_scanned(); let (table_head_bytes, alignment) = scan_table_head(&bytes[table_head_ix..]); if table_head_bytes > 0 { // computing header count from number of pipes let header_count = count_header_cols(bytes, pipes, start, last_pipe_ix); // make sure they match the number of columns we find in separator line if alignment.len() == header_count { let alignment_ix = self.allocs.allocate_alignment(alignment); let end_ix = table_head_ix + table_head_bytes; return LoopInstruction::BreakAtWith( end_ix, Some(Item { start: i, end: end_ix, // must update later body: ItemBody::Table(alignment_ix), }), ); } } } } let trailing_whitespace = scan_rev_while(&bytes[..ix], is_ascii_whitespace_no_nl); if trailing_whitespace >= 2 { i -= trailing_whitespace; self.tree.append_text(begin_text, i, backslash_escaped); backslash_escaped = false; return LoopInstruction::BreakAtWith( end_ix, Some(Item { start: i, end: end_ix, body: ItemBody::HardBreak(false), }), ); } self.tree .append_text(begin_text, ix - trailing_whitespace, backslash_escaped); backslash_escaped = false; LoopInstruction::BreakAtWith( end_ix, Some(Item { start: i, end: end_ix, body: ItemBody::SoftBreak, }), ) } b'\\' => { if ix + 1 < bytes_len && is_ascii_punctuation(bytes[ix + 1]) { self.tree.append_text(begin_text, ix, backslash_escaped); if bytes[ix + 1] == b'`' { let count = 1 + scan_ch_repeat(&bytes[(ix + 2)..], b'`'); self.tree.append(Item { start: ix + 1, end: ix + count + 1, body: ItemBody::MaybeCode(count, true), }); begin_text = ix + 1 + count; backslash_escaped = false; LoopInstruction::ContinueAndSkip(count) } else if bytes[ix + 1] == b'|' && TableParseMode::Active == mode { // Yeah, it's super weird that backslash escaped pipes in tables aren't "real" // backslash escapes. // // This tree structure is intended for the benefit of inline analysis, and it // is supposed to operate as-if backslash escaped pipes were stripped out in a // separate pass. begin_text = ix + 1; backslash_escaped = false; LoopInstruction::ContinueAndSkip(1) } else if ix + 2 < bytes_len && bytes[ix + 1] == b'\\' && bytes[ix + 2] == b'|' && TableParseMode::Active == mode { // To parse `\\|`, discard the backslashes and parse the `|` that follows it. begin_text = ix + 2; backslash_escaped = true; LoopInstruction::ContinueAndSkip(2) } else { begin_text = ix + 1; backslash_escaped = true; LoopInstruction::ContinueAndSkip(1) } } else { LoopInstruction::ContinueAndSkip(0) } } c @ b'*' | c @ b'_' | c @ b'~' | c @ b'^' => { let string_suffix = &self.text[ix..]; let count = 1 + scan_ch_repeat(&string_suffix.as_bytes()[1..], c); let can_open = delim_run_can_open( &self.text[start..], string_suffix, count, ix - start, mode, ); let can_close = delim_run_can_close( &self.text[start..], string_suffix, count, ix - start, mode, ); let is_valid_seq = (c != b'~' || count <= 2) || (c == b'~' && count == 2); if (can_open || can_close) && is_valid_seq { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; for i in 0..count { self.tree.append(Item { start: ix + i, end: ix + i + 1, body: ItemBody::MaybeEmphasis(count - i, can_open, can_close), }); } begin_text = ix + count; } LoopInstruction::ContinueAndSkip(count - 1) } b'$' => { let byte_suffix = &bytes[ix..]; let can_open = !byte_suffix[1..] .first() .copied() .map_or(true, is_ascii_whitespace); let can_close = ix > start && !bytes[..ix] .last() .copied() .map_or(true, is_ascii_whitespace); // 0xFFFF_FFFF... represents the root brace context. Using None would require // storing Option, which is bigger than u8. // // These shouldn't conflict unless you have 255 levels of nesting, which is // past the intended limit anyway. // // Unbalanced braces will cause the root to be changed, which is why it gets // stored here. let brace_context = if self.brace_context_stack.len() > MATH_BRACE_CONTEXT_MAX_NESTING { self.brace_context_next as u8 } else { self.brace_context_stack.last().copied().unwrap_or_else(|| { self.brace_context_stack.push(!0); !0 }) }; self.tree.append_text(begin_text, ix, backslash_escaped); self.tree.append(Item { start: ix, end: ix + 1, body: ItemBody::MaybeMath(can_open, can_close, brace_context), }); begin_text = ix + 1; LoopInstruction::ContinueAndSkip(0) } b'{' => { if self.brace_context_stack.len() == MATH_BRACE_CONTEXT_MAX_NESTING { self.brace_context_stack.push(self.brace_context_next as u8); self.brace_context_next = MATH_BRACE_CONTEXT_MAX_NESTING; } else if self.brace_context_stack.len() > MATH_BRACE_CONTEXT_MAX_NESTING { // When we reach the limit of nesting, switch from actually matching // braces to just counting them. self.brace_context_next += 1; } else if !self.brace_context_stack.is_empty() { // Store nothing if no math environment has been reached yet. self.brace_context_stack.push(self.brace_context_next as u8); self.brace_context_next += 1; } LoopInstruction::ContinueAndSkip(0) } b'}' => { if let &mut [ref mut top_level_context] = &mut self.brace_context_stack[..] { // Unbalanced Braces // // The initial, root top-level brace context is -1, but this is changed whenever an unbalanced // close brace is encountered: // // This is not a math environment: $}$ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|^ // -1 |-2 // // To ensure this can't get parsed as math, each side of the unbalanced // brace is an irreversibly separate brace context. As long as the math // environment itself contains balanced braces, they should share a top level context. // // Math environment contains 2+2: $}$2+2$ // ^^^ this is a math environment *top_level_context = top_level_context.wrapping_sub(1); } else if self.brace_context_stack.len() > MATH_BRACE_CONTEXT_MAX_NESTING { // When we exceed 25 levels of nesting, switch from accurately balancing braces // to just counting them. When we dip back below the limit, switch back. if self.brace_context_next <= MATH_BRACE_CONTEXT_MAX_NESTING { self.brace_context_stack.pop(); } else { self.brace_context_next -= 1; } } else { self.brace_context_stack.pop(); } LoopInstruction::ContinueAndSkip(0) } b'`' => { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; let count = 1 + scan_ch_repeat(&bytes[(ix + 1)..], b'`'); self.tree.append(Item { start: ix, end: ix + count, body: ItemBody::MaybeCode(count, false), }); begin_text = ix + count; LoopInstruction::ContinueAndSkip(count - 1) } b'<' if bytes.get(ix + 1) != Some(&b'\\') => { // Note: could detect some non-HTML cases and early escape here, but not // clear that's a win. self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + 1, body: ItemBody::MaybeHtml, }); begin_text = ix + 1; LoopInstruction::ContinueAndSkip(0) } b'!' => { if ix + 1 < bytes_len && bytes[ix + 1] == b'[' { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + 2, body: ItemBody::MaybeImage, }); begin_text = ix + 2; LoopInstruction::ContinueAndSkip(1) } else { LoopInstruction::ContinueAndSkip(0) } } b'[' => { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + 1, body: ItemBody::MaybeLinkOpen, }); begin_text = ix + 1; LoopInstruction::ContinueAndSkip(0) } b']' => { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + 1, body: ItemBody::MaybeLinkClose(true), }); begin_text = ix + 1; LoopInstruction::ContinueAndSkip(0) } b'&' => match scan_entity(&bytes[ix..]) { (n, Some(value)) => { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + n, body: ItemBody::SynthesizeText(self.allocs.allocate_cow(value)), }); begin_text = ix + n; LoopInstruction::ContinueAndSkip(n - 1) } _ => LoopInstruction::ContinueAndSkip(0), }, b'|' => { if ix != 0 && bytes[ix - 1] == b'\\' { LoopInstruction::ContinueAndSkip(0) } else if let TableParseMode::Active = mode { LoopInstruction::BreakAtWith(ix, None) } else { last_pipe_ix = ix; pipes += 1; LoopInstruction::ContinueAndSkip(0) } } b'.' => { if ix + 2 < bytes.len() && bytes[ix + 1] == b'.' && bytes[ix + 2] == b'.' { self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + 3, body: ItemBody::SynthesizeChar('…'), }); begin_text = ix + 3; LoopInstruction::ContinueAndSkip(2) } else { LoopInstruction::ContinueAndSkip(0) } } b'-' => { let count = 1 + scan_ch_repeat(&bytes[(ix + 1)..], b'-'); if count == 1 { LoopInstruction::ContinueAndSkip(0) } else { let itembody = if count == 2 { ItemBody::SynthesizeChar('–') } else if count == 3 { ItemBody::SynthesizeChar('—') } else { let (ems, ens) = match count % 6 { 0 | 3 => (count / 3, 0), 2 | 4 => (0, count / 2), 1 => (count / 3 - 1, 2), _ => (count / 3, 1), }; // – and — are 3 bytes each in utf8 let mut buf = String::with_capacity(3 * (ems + ens)); for _ in 0..ems { buf.push('—'); } for _ in 0..ens { buf.push('–'); } ItemBody::SynthesizeText(self.allocs.allocate_cow(buf.into())) }; self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + count, body: itembody, }); begin_text = ix + count; LoopInstruction::ContinueAndSkip(count - 1) } } c @ b'\'' | c @ b'"' => { let string_suffix = &self.text[ix..]; let can_open = delim_run_can_open(&self.text[start..], string_suffix, 1, ix - start, mode); let can_close = delim_run_can_close( &self.text[start..], string_suffix, 1, ix - start, mode, ); self.tree.append_text(begin_text, ix, backslash_escaped); backslash_escaped = false; self.tree.append(Item { start: ix, end: ix + 1, body: ItemBody::MaybeSmartQuote(c, can_open, can_close), }); begin_text = ix + 1; LoopInstruction::ContinueAndSkip(0) } _ => LoopInstruction::ContinueAndSkip(0), } }); if brk.is_none() { let trailing_whitespace = scan_rev_while(&bytes[begin_text..final_ix], is_ascii_whitespace_no_nl); // need to close text at eof self.tree.append_text( begin_text, final_ix - trailing_whitespace, backslash_escaped, ); } (final_ix, brk) } /// When start_ix is at the beginning of an HTML block of type 1 to 5, /// this will find the end of the block, adding the block itself to the /// tree and also keeping track of the lines of HTML within the block. /// /// The html_end_tag is the tag that must be found on a line to end the block. fn parse_html_block_type_1_to_5( &mut self, start_ix: usize, html_end_tag: &str, mut remaining_space: usize, mut indent: usize, ) -> usize { self.tree.append(Item { start: start_ix, end: 0, // set later body: ItemBody::HtmlBlock, }); self.tree.push(); let bytes = self.text.as_bytes(); let mut ix = start_ix; let end_ix; loop { let line_start_ix = ix; ix += scan_nextline(&bytes[ix..]); self.append_html_line(remaining_space.max(indent), line_start_ix, ix); let mut line_start = LineStart::new(&bytes[ix..]); let n_containers = scan_containers(&self.tree, &mut line_start, self.options); if n_containers < self.tree.spine_len() { end_ix = ix; break; } if self.text[line_start_ix..ix].contains(html_end_tag) { end_ix = ix; break; } let next_line_ix = ix + line_start.bytes_scanned(); if next_line_ix == self.text.len() { end_ix = next_line_ix; break; } ix = next_line_ix; remaining_space = line_start.remaining_space(); indent = 0; } self.pop(end_ix); ix } /// When start_ix is at the beginning of an HTML block of type 6 or 7, /// this will consume lines until there is a blank line and keep track of /// the HTML within the block. fn parse_html_block_type_6_or_7( &mut self, start_ix: usize, mut remaining_space: usize, mut indent: usize, ) -> usize { self.tree.append(Item { start: start_ix, end: 0, // set later body: ItemBody::HtmlBlock, }); self.tree.push(); let bytes = self.text.as_bytes(); let mut ix = start_ix; let end_ix; loop { let line_start_ix = ix; ix += scan_nextline(&bytes[ix..]); self.append_html_line(remaining_space.max(indent), line_start_ix, ix); let mut line_start = LineStart::new(&bytes[ix..]); let n_containers = scan_containers(&self.tree, &mut line_start, self.options); if n_containers < self.tree.spine_len() || line_start.is_at_eol() { end_ix = ix; break; } let next_line_ix = ix + line_start.bytes_scanned(); if next_line_ix == self.text.len() || scan_blank_line(&bytes[next_line_ix..]).is_some() { end_ix = next_line_ix; break; } ix = next_line_ix; remaining_space = line_start.remaining_space(); indent = 0; } self.pop(end_ix); ix } fn parse_indented_code_block(&mut self, start_ix: usize, mut remaining_space: usize) -> usize { self.tree.append(Item { start: start_ix, end: 0, // will get set later body: ItemBody::IndentCodeBlock, }); self.tree.push(); let bytes = self.text.as_bytes(); let mut last_nonblank_child = None; let mut last_nonblank_ix = 0; let mut end_ix = 0; self.last_line_blank = false; let mut ix = start_ix; loop { let line_start_ix = ix; ix += scan_nextline(&bytes[ix..]); self.append_code_text(remaining_space, line_start_ix, ix); // TODO(spec clarification): should we synthesize newline at EOF? if !self.last_line_blank { last_nonblank_child = self.tree.cur(); last_nonblank_ix = ix; end_ix = ix; } let mut line_start = LineStart::new(&bytes[ix..]); let n_containers = scan_containers(&self.tree, &mut line_start, self.options); if n_containers < self.tree.spine_len() || !(line_start.scan_space(4) || line_start.is_at_eol()) { break; } let next_line_ix = ix + line_start.bytes_scanned(); if next_line_ix == self.text.len() { break; } ix = next_line_ix; remaining_space = line_start.remaining_space(); self.last_line_blank = scan_blank_line(&bytes[ix..]).is_some(); } // Trim trailing blank lines. if let Some(child) = last_nonblank_child { self.tree[child].next = None; self.tree[child].item.end = last_nonblank_ix; } self.pop(end_ix); ix } fn parse_fenced_code_block( &mut self, start_ix: usize, indent: usize, fence_ch: u8, n_fence_char: usize, ) -> usize { let bytes = self.text.as_bytes(); let mut info_start = start_ix + n_fence_char; info_start += scan_whitespace_no_nl(&bytes[info_start..]); // TODO: info strings are typically very short. wouldn't it be faster // to just do a forward scan here? let mut ix = info_start + scan_nextline(&bytes[info_start..]); let info_end = ix - scan_rev_while(&bytes[info_start..ix], is_ascii_whitespace); let info_string = unescape(&self.text[info_start..info_end], self.tree.is_in_table()); self.tree.append(Item { start: start_ix, end: 0, // will get set later body: ItemBody::FencedCodeBlock(self.allocs.allocate_cow(info_string)), }); self.tree.push(); loop { let mut line_start = LineStart::new(&bytes[ix..]); let n_containers = scan_containers(&self.tree, &mut line_start, self.options); if n_containers < self.tree.spine_len() { // this line will get parsed again as not being part of the code // if it's blank, it should be parsed as a blank line self.pop(ix); return ix; } line_start.scan_space(indent); let mut close_line_start = line_start.clone(); if !close_line_start.scan_space(4 - indent) { let close_ix = ix + close_line_start.bytes_scanned(); if let Some(n) = scan_closing_code_fence(&bytes[close_ix..], fence_ch, n_fence_char) { ix = close_ix + n; self.pop(ix); // try to read trailing whitespace or it will register as a completely blank line return ix + scan_blank_line(&bytes[ix..]).unwrap_or(0); } } let remaining_space = line_start.remaining_space(); ix += line_start.bytes_scanned(); let next_ix = ix + scan_nextline(&bytes[ix..]); self.append_code_text(remaining_space, ix, next_ix); ix = next_ix; } } fn parse_metadata_block(&mut self, start_ix: usize, metadata_block_ch: u8) -> usize { let bytes = self.text.as_bytes(); let metadata_block_kind = match metadata_block_ch { b'-' => MetadataBlockKind::YamlStyle, b'+' => MetadataBlockKind::PlusesStyle, _ => panic!("Erroneous metadata block character when parsing metadata block"), }; // 3 delimiter characters let mut ix = start_ix + 3 + scan_nextline(&bytes[start_ix + 3..]); self.tree.append(Item { start: start_ix, end: 0, // will get set later body: ItemBody::MetadataBlock(metadata_block_kind), }); self.tree.push(); loop { let mut line_start = LineStart::new(&bytes[ix..]); let n_containers = scan_containers(&self.tree, &mut line_start, self.options); if n_containers < self.tree.spine_len() { break; } if let (_, 0) = calc_indent(&bytes[ix..], 4) { if let Some(n) = scan_closing_metadata_block(&bytes[ix..], metadata_block_ch) { ix += n; break; } } let remaining_space = line_start.remaining_space(); ix += line_start.bytes_scanned(); let next_ix = ix + scan_nextline(&bytes[ix..]); self.append_code_text(remaining_space, ix, next_ix); ix = next_ix; } self.pop(ix); // try to read trailing whitespace or it will register as a completely blank line ix + scan_blank_line(&bytes[ix..]).unwrap_or(0) } fn append_code_text(&mut self, remaining_space: usize, start: usize, end: usize) { if remaining_space > 0 { let cow_ix = self.allocs.allocate_cow(" "[..remaining_space].into()); self.tree.append(Item { start, end: start, body: ItemBody::SynthesizeText(cow_ix), }); } if self.text.as_bytes()[end - 2] == b'\r' { // Normalize CRLF to LF self.tree.append_text(start, end - 2, false); self.tree.append_text(end - 1, end, false); } else { self.tree.append_text(start, end, false); } } /// Appends a line of HTML to the tree. fn append_html_line(&mut self, remaining_space: usize, start: usize, end: usize) { if remaining_space > 0 { let cow_ix = self.allocs.allocate_cow(" "[..remaining_space].into()); self.tree.append(Item { start, end: start, body: ItemBody::SynthesizeText(cow_ix), }); } if self.text.as_bytes()[end - 2] == b'\r' { // Normalize CRLF to LF self.tree.append(Item { start, end: end - 2, body: ItemBody::Html, }); self.tree.append(Item { start: end - 1, end, body: ItemBody::Html, }); } else { self.tree.append(Item { start, end, body: ItemBody::Html, }); } } /// Pop a container, setting its end. fn pop(&mut self, ix: usize) { let cur_ix = self.tree.pop().unwrap(); self.tree[cur_ix].item.end = ix; if let ItemBody::DefinitionList(_) = self.tree[cur_ix].item.body { fixup_end_of_definition_list(&mut self.tree, cur_ix); self.begin_list_item = None; } if let ItemBody::List(true, _, _) | ItemBody::DefinitionList(true) = self.tree[cur_ix].item.body { surgerize_tight_list(&mut self.tree, cur_ix); self.begin_list_item = None; } } /// Close a list if it's open. Also set loose if last line was blank /// and end current list if it's a lone, empty item fn finish_list(&mut self, ix: usize) { self.finish_empty_list_item(); if let Some(node_ix) = self.tree.peek_up() { if let ItemBody::List(_, _, _) | ItemBody::DefinitionList(_) = self.tree[node_ix].item.body { self.pop(ix); } } if self.last_line_blank { if let Some(node_ix) = self.tree.peek_grandparent() { if let ItemBody::List(ref mut is_tight, _, _) | ItemBody::DefinitionList(ref mut is_tight) = self.tree[node_ix].item.body { *is_tight = false; } } self.last_line_blank = false; } } fn finish_empty_list_item(&mut self) { if let Some(begin_list_item) = self.begin_list_item { if self.last_line_blank { // A list item can begin with at most one blank line. if let Some(node_ix) = self.tree.peek_up() { if let ItemBody::ListItem(_) | ItemBody::DefinitionListDefinition(_) = self.tree[node_ix].item.body { self.pop(begin_list_item); } } } } self.begin_list_item = None; } /// Continue an existing list or start a new one if there's not an open /// list that matches. fn continue_list(&mut self, start: usize, ch: u8, index: u64) { self.finish_empty_list_item(); if let Some(node_ix) = self.tree.peek_up() { if let ItemBody::List(ref mut is_tight, existing_ch, _) = self.tree[node_ix].item.body { if existing_ch == ch { if self.last_line_blank { *is_tight = false; self.last_line_blank = false; } return; } } // TODO: this is not the best choice for end; maybe get end from last list item. self.finish_list(start); } self.tree.append(Item { start, end: 0, // will get set later body: ItemBody::List(true, ch, index), }); self.tree.push(); self.last_line_blank = false; } /// Parse a thematic break. /// /// Returns index of start of next line. fn parse_hrule(&mut self, hrule_size: usize, ix: usize) -> usize { self.tree.append(Item { start: ix, end: ix + hrule_size, body: ItemBody::Rule, }); ix + hrule_size } /// Parse an ATX heading. /// /// Returns index of start of next line. fn parse_atx_heading(&mut self, start: usize, atx_level: HeadingLevel) -> usize { let mut ix = start; let heading_ix = self.tree.append(Item { start, end: 0, // set later body: ItemBody::default(), // set later }); ix += atx_level as usize; // next char is space or eol (guaranteed by scan_atx_heading) let bytes = self.text.as_bytes(); if let Some(eol_bytes) = scan_eol(&bytes[ix..]) { self.tree[heading_ix].item.end = ix + eol_bytes; self.tree[heading_ix].item.body = ItemBody::Heading(atx_level, None); return ix + eol_bytes; } // skip leading spaces let skip_spaces = scan_whitespace_no_nl(&bytes[ix..]); ix += skip_spaces; // now handle the header text let header_start = ix; let header_node_idx = self.tree.push(); // so that we can set the endpoint later // trim the trailing attribute block before parsing the entire line, if necessary let (end, content_end, attrs) = if self.options.contains(Options::ENABLE_HEADING_ATTRIBUTES) { // the start of the next line is the end of the header since the // header cannot have line breaks let header_end = header_start + scan_nextline(&bytes[header_start..]); let (content_end, attrs) = self.extract_and_parse_heading_attribute_block(header_start, header_end); self.parse_line(ix, Some(content_end), TableParseMode::Disabled); (header_end, content_end, attrs) } else { let (line_ix, line_brk) = self.parse_line(ix, None, TableParseMode::Disabled); ix = line_ix; // Backslash at end is actually hard line break if let Some(Item { start, end, body: ItemBody::HardBreak(true), }) = line_brk { self.tree.append_text(start, end, false); } (ix, ix, None) }; self.tree[header_node_idx].item.end = end; // remove trailing matter from header text let mut empty_text_node = false; if let Some(cur_ix) = self.tree.cur() { // remove closing of the ATX heading let header_text = &bytes[header_start..content_end]; let mut limit = header_text .iter() .rposition(|&b| !(b == b'\n' || b == b'\r' || b == b' ')) .map_or(0, |i| i + 1); let closer = header_text[..limit] .iter() .rposition(|&b| b != b'#') .map_or(0, |i| i + 1); if closer == 0 { limit = closer; } else { let spaces = scan_rev_while(&header_text[..closer], |b| b == b' '); if spaces > 0 { limit = closer - spaces; } } // if text is only spaces, then remove them self.tree[cur_ix].item.end = limit + header_start; // limit = 0 when text is empty after removing spaces if limit == 0 { empty_text_node = true; } } if empty_text_node { self.tree.remove_node(); } else { self.tree.pop(); } self.tree[heading_ix].item.body = ItemBody::Heading( atx_level, attrs.map(|attrs| self.allocs.allocate_heading(attrs)), ); end } /// Returns the number of bytes scanned on success. fn parse_footnote(&mut self, start: usize) -> Option { let bytes = &self.text.as_bytes()[start..]; if !bytes.starts_with(b"[^") { return None; } let (mut i, label) = if self.options.has_gfm_footnotes() { // GitHub doesn't allow footnote definition labels to contain line breaks. // It actually does allow this for link definitions under certain circumstances, // but for this it's simpler to avoid it. scan_link_label_rest(&self.text[start + 2..], &|_| None, self.tree.is_in_table())? } else { self.parse_refdef_label(start + 2)? }; if self.options.has_gfm_footnotes() && label.bytes().any(|b| b == b'\r' || b == b'\n') { // GitHub doesn't allow footnote definition labels to contain line breaks, // even if they're escaped. return None; } i += 2; if bytes.get(i) != Some(&b':') { return None; } i += 1; self.finish_list(start); if let Some(node_ix) = self.tree.peek_up() { if let ItemBody::FootnoteDefinition(..) = self.tree[node_ix].item.body { // finish previous footnote if it's still open self.pop(start); } } if self.options.has_gfm_footnotes() { i += scan_whitespace_no_nl(&bytes[i..]); } self.allocs .footdefs .0 .insert(UniCase::new(label.clone()), FootnoteDef { use_count: 0 }); self.tree.append(Item { start, end: 0, // will get set later // TODO: check whether the label here is strictly necessary body: ItemBody::FootnoteDefinition(self.allocs.allocate_cow(label)), }); self.tree.push(); Some(i) } /// Tries to parse a reference label, which can be interrupted by new blocks. /// On success, returns the number of bytes of the label and the label itself. fn parse_refdef_label(&self, start: usize) -> Option<(usize, CowStr<'a>)> { scan_link_label_rest( &self.text[start..], &|bytes| { let mut line_start = LineStart::new(bytes); let tree_position = scan_containers(&self.tree, &mut line_start, self.options); let current_container = tree_position == self.tree.spine_len(); if line_start.scan_space(4) { return Some(line_start.bytes_scanned()); } let bytes_scanned = line_start.bytes_scanned(); let suffix = &bytes[bytes_scanned..]; if self.scan_paragraph_interrupt(suffix, current_container, tree_position) || (current_container && scan_setext_heading(suffix).is_some()) { None } else { Some(bytes_scanned) } }, self.tree.is_in_table(), ) } /// Returns number of bytes scanned, label and definition on success. fn parse_refdef_total(&mut self, start: usize) -> Option<(usize, LinkLabel<'a>, LinkDef<'a>)> { let bytes = &self.text.as_bytes()[start..]; if bytes.get(0) != Some(&b'[') { return None; } let (mut i, label) = self.parse_refdef_label(start + 1)?; i += 1; if bytes.get(i) != Some(&b':') { return None; } i += 1; let (bytecount, link_def) = self.scan_refdef(start, start + i)?; Some((bytecount + i, UniCase::new(label), link_def)) } /// Returns number of bytes and number of newlines fn scan_refdef_space(&self, bytes: &[u8], mut i: usize) -> Option<(usize, usize)> { let mut newlines = 0; loop { let whitespaces = scan_whitespace_no_nl(&bytes[i..]); i += whitespaces; if let Some(eol_bytes) = scan_eol(&bytes[i..]) { i += eol_bytes; newlines += 1; if newlines > 1 { return None; } } else { break; } let mut line_start = LineStart::new(&bytes[i..]); let tree_position = scan_containers(&self.tree, &mut line_start, self.options); let current_container = tree_position == self.tree.spine_len(); if !line_start.scan_space(4) { let suffix = &bytes[i + line_start.bytes_scanned()..]; if self.scan_paragraph_interrupt(suffix, current_container, tree_position) || scan_setext_heading(suffix).is_some() { return None; } } i += line_start.bytes_scanned(); } Some((i, newlines)) } // returns (bytelength, title_str) fn scan_refdef_title<'t>(&self, text: &'t str) -> Option<(usize, CowStr<'t>)> { let bytes = text.as_bytes(); let closing_delim = match bytes.first()? { b'\'' => b'\'', b'"' => b'"', b'(' => b')', _ => return None, }; let mut bytecount = 1; let mut linestart = 1; let mut linebuf = None; while let Some(&c) = bytes.get(bytecount) { match c { b'(' if closing_delim == b')' => { // https://spec.commonmark.org/0.30/#link-title // a sequence of zero or more characters between matching parentheses ((...)), // including a ( or ) character only if it is backslash-escaped. return None; } b'\n' | b'\r' => { // push text to line buffer // this is used to strip the block formatting: // // > [first]: http://example.com " // > second" // // should get turned into `first` let linebuf = if let Some(linebuf) = &mut linebuf { linebuf } else { linebuf = Some(String::new()); linebuf.as_mut().unwrap() }; linebuf.push_str(&text[linestart..bytecount]); linebuf.push('\n'); // normalize line breaks // skip line break bytecount += 1; if c == b'\r' && bytes.get(bytecount) == Some(&b'\n') { bytecount += 1; } let mut line_start = LineStart::new(&bytes[bytecount..]); let tree_position = scan_containers(&self.tree, &mut line_start, self.options); let current_container = tree_position == self.tree.spine_len(); if !line_start.scan_space(4) { let suffix = &bytes[bytecount + line_start.bytes_scanned()..]; if self.scan_paragraph_interrupt(suffix, current_container, tree_position) || scan_setext_heading(suffix).is_some() { return None; } } line_start.scan_all_space(); bytecount += line_start.bytes_scanned(); linestart = bytecount; if scan_blank_line(&bytes[bytecount..]).is_some() { // blank line - not allowed return None; } } b'\\' => { bytecount += 1; if let Some(c) = bytes.get(bytecount) { if c != &b'\r' && c != &b'\n' { bytecount += 1; } } } c if c == closing_delim => { let cow = if let Some(mut linebuf) = linebuf { linebuf.push_str(&text[linestart..bytecount]); CowStr::from(linebuf) } else { CowStr::from(&text[linestart..bytecount]) }; return Some((bytecount + 1, cow)); } _ => { bytecount += 1; } } } None } /// Returns # of bytes and definition. /// Assumes the label of the reference including colon has already been scanned. fn scan_refdef(&self, span_start: usize, start: usize) -> Option<(usize, LinkDef<'a>)> { let bytes = self.text.as_bytes(); // whitespace between label and url (including up to one newline) let (mut i, _newlines) = self.scan_refdef_space(bytes, start)?; // scan link dest let (dest_length, dest) = scan_link_dest(self.text, i, LINK_MAX_NESTED_PARENS)?; if dest_length == 0 { return None; } let dest = unescape(dest, self.tree.is_in_table()); i += dest_length; // no title let mut backup = ( i - start, LinkDef { dest, title: None, span: span_start..i, }, ); // scan whitespace between dest and label let (mut i, newlines) = if let Some((new_i, mut newlines)) = self.scan_refdef_space(bytes, i) { if i == self.text.len() { newlines += 1; } if new_i == i && newlines == 0 { return None; } if newlines > 1 { return Some(backup); }; (new_i, newlines) } else { return Some(backup); }; // scan title // if this fails but newline == 1, return also a refdef without title if let Some((title_length, title)) = self.scan_refdef_title(&self.text[i..]) { i += title_length; if scan_blank_line(&bytes[i..]).is_some() { backup.0 = i - start; backup.1.span = span_start..i; backup.1.title = Some(unescape(title, self.tree.is_in_table())); return Some(backup); } } if newlines > 0 { Some(backup) } else { None } } /// Checks whether we should break a paragraph on the given input. fn scan_paragraph_interrupt( &self, bytes: &[u8], current_container: bool, tree_position: usize, ) -> bool { if scan_paragraph_interrupt_no_table( bytes, current_container, self.options.contains(Options::ENABLE_FOOTNOTES), self.options.contains(Options::ENABLE_DEFINITION_LIST), &self.tree, tree_position, ) { return true; } // pulldown-cmark allows heavy tables, that have a `|` on the header row, // to interrupt paragraphs. // // ```markdown // This is a table // | a | b | c | // |---|---|---| // | d | e | f | // // This is not a table // a | b | c // ---|---|--- // d | e | f // ``` if !self.options.contains(Options::ENABLE_TABLES) || !bytes.starts_with(b"|") { return false; } // Checking if something's a valid table or not requires looking at two lines. // First line, count unescaped pipes. let mut pipes = 0; let mut next_line_ix = 0; let mut bsesc = false; let mut last_pipe_ix = 0; for (i, &byte) in bytes.iter().enumerate() { match byte { b'\\' => { bsesc = true; continue; } b'|' if !bsesc => { pipes += 1; last_pipe_ix = i; } b'\r' | b'\n' => { next_line_ix = i + scan_eol(&bytes[i..]).unwrap(); break; } _ => {} } bsesc = false; } // scan_eol can't return 0, so this can't be zero if next_line_ix == 0 { return false; } // Scan the table head. The part that looks like: // // |---|---|---| // // Also scan any containing items, since it's on its own line, and // might be nested inside a block quote or something // // > Table: First // > | first col | second col | // > |-----------|------------| // ^ // | need to skip over the `>` when checking for the table let mut line_start = LineStart::new(&bytes[next_line_ix..]); if scan_containers(&self.tree, &mut line_start, self.options) != self.tree.spine_len() { return false; } let table_head_ix = next_line_ix + line_start.bytes_scanned(); let (table_head_bytes, alignment) = scan_table_head(&bytes[table_head_ix..]); if table_head_bytes == 0 { return false; } // computing header count from number of pipes let header_count = count_header_cols(bytes, pipes, 0, last_pipe_ix); // make sure they match the number of columns we find in separator line alignment.len() == header_count } /// Extracts and parses a heading attribute block if exists. /// /// Returns `(end_offset_of_heading_content, (id, classes))`. /// /// If `header_end` is less than or equal to `header_start`, the given /// input is considered as empty. fn extract_and_parse_heading_attribute_block( &mut self, header_start: usize, header_end: usize, ) -> (usize, Option>) { if !self.options.contains(Options::ENABLE_HEADING_ATTRIBUTES) { return (header_end, None); } // extract the trailing attribute block let header_bytes = &self.text.as_bytes()[header_start..header_end]; let (content_len, attr_block_range_rel) = extract_attribute_block_content_from_header_text(header_bytes); let content_end = header_start + content_len; let attrs = attr_block_range_rel.and_then(|r| { parse_inside_attribute_block( &self.text[(header_start + r.start)..(header_start + r.end)], ) }); (content_end, attrs) } } /// Scanning modes for `Parser`'s `parse_line` method. #[derive(PartialEq, Eq, Copy, Clone)] enum TableParseMode { /// Inside a paragraph, scanning for table headers. Scan, /// Inside a table. Active, /// Inside a paragraph, not scanning for table headers. Disabled, } /// Computes the number of header columns in a table line by computing the number of dividing pipes /// that aren't followed or preceded by whitespace. fn count_header_cols( bytes: &[u8], mut pipes: usize, mut start: usize, last_pipe_ix: usize, ) -> usize { // was first pipe preceded by whitespace? if so, subtract one start += scan_whitespace_no_nl(&bytes[start..]); if bytes[start] == b'|' { pipes -= 1; } // was last pipe followed by whitespace? if so, sub one if scan_blank_line(&bytes[(last_pipe_ix + 1)..]).is_some() { pipes } else { pipes + 1 } } /// Checks whether we should break a paragraph on the given input. /// /// Use `FirstPass::scan_paragraph_interrupt` in any context that allows /// tables to interrupt the paragraph. fn scan_paragraph_interrupt_no_table( bytes: &[u8], current_container: bool, has_footnote: bool, definition_list: bool, tree: &Tree, tree_position: usize, ) -> bool { scan_eol(bytes).is_some() || scan_hrule(bytes).is_ok() || scan_atx_heading(bytes).is_some() || scan_code_fence(bytes).is_some() || scan_blockquote_start(bytes).is_some() || scan_listitem(bytes).map_or(false, |(ix, delim, index, _)| { ! current_container || tree.is_in_table() || // we don't allow interruption by either empty lists or // numbered lists starting at an index other than 1 (delim == b'*' || delim == b'-' || delim == b'+' || index == 1) && (scan_blank_line(&bytes[ix..]).is_none()) }) || bytes.starts_with(b"<") && (get_html_end_tag(&bytes[1..]).is_some() || starts_html_block_type_6(&bytes[1..])) || definition_list && ((current_container && tree.peek_up().map_or(false, |cur| { matches!( tree[cur].item.body, ItemBody::Paragraph | ItemBody::TightParagraph | ItemBody::MaybeDefinitionListTitle ) })) || tree.walk_spine().nth(tree_position).map_or(false, |cur| { matches!(tree[*cur].item.body, ItemBody::DefinitionListDefinition(_)) })) && bytes.starts_with(b":") || (has_footnote && bytes.starts_with(b"[^") && scan_link_label_rest( std::str::from_utf8(&bytes[2..]).unwrap(), &|_| None, tree.is_in_table(), ) .map_or(false, |(len, _)| bytes.get(2 + len) == Some(&b':'))) } /// Assumes `text_bytes` is preceded by `<`. fn get_html_end_tag(text_bytes: &[u8]) -> Option<&'static str> { static BEGIN_TAGS: &[&[u8]; 4] = &[b"pre", b"style", b"script", b"textarea"]; static ST_BEGIN_TAGS: &[&[u8]; 3] = &[b"!--", b"?", b"![CDATA["]; for (beg_tag, end_tag) in BEGIN_TAGS .iter() .zip(["", "", "", ""].iter()) { let tag_len = beg_tag.len(); if text_bytes.len() < tag_len { // begin tags are increasing in size break; } if !text_bytes[..tag_len].eq_ignore_ascii_case(beg_tag) { continue; } // Must either be the end of the line... if text_bytes.len() == tag_len { return Some(end_tag); } // ...or be followed by whitespace, newline, or '>'. let s = text_bytes[tag_len]; if is_ascii_whitespace(s) || s == b'>' { return Some(end_tag); } } for (beg_tag, end_tag) in ST_BEGIN_TAGS.iter().zip(["-->", "?>", "]]>"].iter()) { if text_bytes.starts_with(beg_tag) { return Some(end_tag); } } if text_bytes.len() > 1 && text_bytes[0] == b'!' && text_bytes[1].is_ascii_alphabetic() { Some(">") } else { None } } fn surgerize_tight_list(tree: &mut Tree, list_ix: TreeIndex) { let mut list_item = tree[list_ix].child; while let Some(listitem_ix) = list_item { let mut node_ix = tree[listitem_ix].child; while let Some(node) = node_ix { if let ItemBody::Paragraph = tree[node].item.body { tree[node].item.body = ItemBody::TightParagraph; } node_ix = tree[node].next; } list_item = tree[listitem_ix].next; } } fn fixup_end_of_definition_list(tree: &mut Tree, list_ix: TreeIndex) { let mut list_item = tree[list_ix].child; let mut previous_list_item = None; while let Some(listitem_ix) = list_item { match &mut tree[listitem_ix].item.body { ItemBody::DefinitionListTitle | ItemBody::DefinitionListDefinition(_) => { previous_list_item = list_item; list_item = tree[listitem_ix].next; } body @ ItemBody::MaybeDefinitionListTitle => { *body = ItemBody::Paragraph; break; } _ => break, } } if let Some(previous_list_item) = previous_list_item { tree.truncate_to_parent(previous_list_item); } } /// Determines whether the delimiter run starting at given index is /// left-flanking, as defined by the commonmark spec (and isn't intraword /// for _ delims). /// suffix is &s[ix..], which is passed in as an optimization, since taking /// a string subslice is O(n). fn delim_run_can_open( s: &str, suffix: &str, run_len: usize, ix: usize, mode: TableParseMode, ) -> bool { let next_char = if let Some(c) = suffix[run_len..].chars().next() { c } else { return false; }; if next_char.is_whitespace() { return false; } if ix == 0 { return true; } if mode == TableParseMode::Active { if s.as_bytes()[..ix].ends_with(b"|") && !s.as_bytes()[..ix].ends_with(br"\|") { return true; } if next_char == '|' { return false; } } let delim = suffix.bytes().next().unwrap(); // `*` and `~~` can be intraword, `_` and `~` cannot if delim == b'*' && !is_punctuation(next_char) { return true; } if delim == b'~' && run_len > 1 { return true; } let prev_char = s[..ix].chars().last().unwrap(); if delim == b'~' && prev_char == '~' && !is_punctuation(next_char) { return true; } prev_char.is_whitespace() || is_punctuation(prev_char) && (delim != b'\'' || ![']', ')'].contains(&prev_char)) } /// Determines whether the delimiter run starting at given index is /// right-flanking, as defined by the commonmark spec (and isn't intraword /// for _ delims) fn delim_run_can_close( s: &str, suffix: &str, run_len: usize, ix: usize, mode: TableParseMode, ) -> bool { if ix == 0 { return false; } let prev_char = s[..ix].chars().last().unwrap(); if prev_char.is_whitespace() { return false; } let next_char = if let Some(c) = suffix[run_len..].chars().next() { c } else { return true; }; if mode == TableParseMode::Active { if s.as_bytes()[..ix].ends_with(b"|") && !s.as_bytes()[..ix].ends_with(br"\|") { return false; } if next_char == '|' { return true; } } let delim = suffix.bytes().next().unwrap(); // `*` and `~~` can be intraword, `_` and `~` cannot if (delim == b'*' || (delim == b'~' && run_len > 1)) && !is_punctuation(prev_char) { return true; } if delim == b'~' && prev_char == '~' { return true; } next_char.is_whitespace() || is_punctuation(next_char) } fn create_lut(options: &Options) -> LookupTable { #[cfg(all(target_arch = "x86_64", feature = "simd"))] { LookupTable { simd: simd::compute_lookup(options), scalar: special_bytes(options), } } #[cfg(not(all(target_arch = "x86_64", feature = "simd")))] { special_bytes(options) } } fn special_bytes(options: &Options) -> [bool; 256] { let mut bytes = [false; 256]; let standard_bytes = [ b'\n', b'\r', b'*', b'_', b'&', b'\\', b'[', b']', b'<', b'!', b'`', ]; for &byte in &standard_bytes { bytes[byte as usize] = true; } if options.contains(Options::ENABLE_TABLES) { bytes[b'|' as usize] = true; } if options.contains(Options::ENABLE_STRIKETHROUGH) || options.contains(Options::ENABLE_SUBSCRIPT) { bytes[b'~' as usize] = true; } if options.contains(Options::ENABLE_SUPERSCRIPT) { bytes[b'^' as usize] = true; } if options.contains(Options::ENABLE_MATH) { bytes[b'$' as usize] = true; bytes[b'{' as usize] = true; bytes[b'}' as usize] = true; } if options.contains(Options::ENABLE_SMART_PUNCTUATION) { for &byte in &[b'.', b'-', b'"', b'\''] { bytes[byte as usize] = true; } } bytes } enum LoopInstruction { /// Continue looking for more special bytes, but skip next few bytes. ContinueAndSkip(usize), /// Break looping immediately, returning with the given index and value. BreakAtWith(usize, T), } #[cfg(all(target_arch = "x86_64", feature = "simd"))] struct LookupTable { simd: [u8; 16], scalar: [bool; 256], } #[cfg(not(all(target_arch = "x86_64", feature = "simd")))] type LookupTable = [bool; 256]; /// This function walks the byte slices from the given index and /// calls the callback function on all bytes (and their indices) that are in the following set: /// `` ` ``, `\`, `&`, `*`, `_`, `~`, `!`, `<`, `[`, `]`, `|`, `\r`, `\n` /// It is guaranteed not call the callback on other bytes. /// Whenever `callback(ix, byte)` returns a `ContinueAndSkip(n)` value, the callback /// will not be called with an index that is less than `ix + n + 1`. /// When the callback returns a `BreakAtWith(end_ix, opt+val)`, no more callbacks will be /// called and the function returns immediately with the return value `(end_ix, opt_val)`. /// If `BreakAtWith(..)` is never returned, this function will return the first /// index that is outside the byteslice bound and a `None` value. fn iterate_special_bytes( lut: &LookupTable, bytes: &[u8], ix: usize, callback: F, ) -> (usize, Option) where F: FnMut(usize, u8) -> LoopInstruction>, { #[cfg(all(target_arch = "x86_64", feature = "simd"))] { simd::iterate_special_bytes(lut, bytes, ix, callback) } #[cfg(not(all(target_arch = "x86_64", feature = "simd")))] { scalar_iterate_special_bytes(lut, bytes, ix, callback) } } fn scalar_iterate_special_bytes( lut: &[bool; 256], bytes: &[u8], mut ix: usize, mut callback: F, ) -> (usize, Option) where F: FnMut(usize, u8) -> LoopInstruction>, { while ix < bytes.len() { let b = bytes[ix]; if lut[b as usize] { match callback(ix, b) { LoopInstruction::ContinueAndSkip(skip) => { ix += skip; } LoopInstruction::BreakAtWith(ix, val) => { return (ix, val); } } } ix += 1; } (ix, None) } /// Split the usual heading content range and the content inside the trailing attribute block. /// /// Returns `(leading_content_len, Option)`. /// /// Note that `trailing_attr_block_range` will be empty range when the block /// is `{}`, since the range is content inside the wrapping `{` and `}`. /// /// The closing `}` of an attribute block can have trailing whitespaces. /// They are automatically trimmed when the attribute block is being searched. /// /// However, this method does not trim the trailing whitespaces of heading content. /// It is callers' responsibility to trim them if necessary. fn extract_attribute_block_content_from_header_text( heading: &[u8], ) -> (usize, Option>) { let heading_len = heading.len(); let mut ix = heading_len; ix -= scan_rev_while(heading, |b| { b == b'\n' || b == b'\r' || b == b' ' || b == b'\t' }); if ix == 0 { return (heading_len, None); } let attr_block_close = ix - 1; if heading.get(attr_block_close) != Some(&b'}') { // The last character is not `}`. No attribute blocks found. return (heading_len, None); } // move cursor before the closing right brace (`}`) ix -= 1; ix -= scan_rev_while(&heading[..ix], |b| { // Characters to be excluded: // * `{` and `}`: special characters to open and close an attribute block. // * `\\`: a special character to escape many characters and disable some syntaxes. // + Handling of this escape character differs among markdown processors. // + Escaped characters will be separate text node from neighbors, so // it is not easy to handle unescaped string and trim the trailing block. // * `<` and `>`: special characters to start and end HTML tag. // + No known processors converts `{#foo}` into // `id="<i>foo</>"` as of this writing, so hopefully // this restriction won't cause compatibility issues. // * `\n` and `\r`: a newline character. // + Setext heading can have multiple lines. However it is hard to support // attribute blocks that have newline inside, since the parsing proceeds line by // line and lines will be separate nodes even they are logically a single text. !matches!(b, b'{' | b'}' | b'<' | b'>' | b'\\' | b'\n' | b'\r') }); if ix == 0 { // `{` is not found. No attribute blocks available. return (heading_len, None); } let attr_block_open = ix - 1; if heading[attr_block_open] != b'{' { // `{` is not found. No attribute blocks available. return (heading_len, None); } (attr_block_open, Some(ix..attr_block_close)) } /// Parses an attribute block content, such as `.class1 #id .class2`. /// /// Returns `(id, classes)`. /// /// It is callers' responsibility to find opening and closing characters of the attribute /// block. Usually [`extract_attribute_block_content_from_header_text`] function does it for you. /// /// Note that this parsing requires explicit whitespace separators between /// attributes. This is intentional design with the reasons below: /// /// * to keep conversion simple and easy to understand for any possible input, /// * to avoid adding less obvious conversion rule that can reduce compatibility /// with other implementations more, and /// * to follow the major design of implementations with the support for the /// attribute blocks extension (as of this writing). /// /// See also: [`Options::ENABLE_HEADING_ATTRIBUTES`]. /// /// [`Options::ENABLE_HEADING_ATTRIBUTES`]: `crate::Options::ENABLE_HEADING_ATTRIBUTES` fn parse_inside_attribute_block(inside_attr_block: &str) -> Option> { let mut id = None; let mut classes = Vec::new(); let mut attrs = Vec::new(); for attr in inside_attr_block.split_ascii_whitespace() { // iterator returned by `str::split_ascii_whitespace` never emits empty // strings, so taking first byte won't panic. if attr.len() > 1 { let first_byte = attr.as_bytes()[0]; if first_byte == b'#' { id = Some(attr[1..].into()); } else if first_byte == b'.' { classes.push(attr[1..].into()); } else { let split = attr.split_once('='); if let Some((key, value)) = split { attrs.push((key.into(), Some(value.into()))); } else { attrs.push((attr.into(), None)); } } } } Some(HeadingAttributes { id, classes, attrs }) } #[cfg(all(target_arch = "x86_64", feature = "simd"))] mod simd { //! SIMD byte scanning logic. //! //! This module provides functions that allow walking through byteslices, calling //! provided callback functions on special bytes and their indices using SIMD. //! The byteset is defined in `compute_lookup`. //! //! The idea is to load in a chunk of 16 bytes and perform a lookup into a set of //! bytes on all the bytes in this chunk simultaneously. We produce a 16 bit bitmask //! from this and call the callback on every index corresponding to a 1 in this mask //! before moving on to the next chunk. This allows us to move quickly when there //! are no or few matches. //! //! The table lookup is inspired by this [great overview]. However, since all of the //! bytes we're interested in are ASCII, we don't quite need the full generality of //! the universal algorithm and are hence able to skip a few instructions. //! //! [great overview]: http://0x80.pl/articles/simd-byte-lookup.html use super::{LookupTable, LoopInstruction}; use crate::Options; use core::arch::x86_64::*; const VECTOR_SIZE: usize = std::mem::size_of::<__m128i>(); /// Generates a lookup table containing the bitmaps for our /// special marker bytes. This is effectively a 128 element 2d bitvector, /// that can be indexed by a four bit row index (the lower nibble) /// and a three bit column index (upper nibble). pub(super) fn compute_lookup(options: &Options) -> [u8; 16] { let mut lookup = [0u8; 16]; let standard_bytes = [ b'\n', b'\r', b'*', b'_', b'&', b'\\', b'[', b']', b'<', b'!', b'`', ]; for &byte in &standard_bytes { add_lookup_byte(&mut lookup, byte); } if options.contains(Options::ENABLE_TABLES) { add_lookup_byte(&mut lookup, b'|'); } if options.contains(Options::ENABLE_STRIKETHROUGH) || options.contains(Options::ENABLE_SUBSCRIPT) { add_lookup_byte(&mut lookup, b'~'); } if options.contains(Options::ENABLE_SUPERSCRIPT) { add_lookup_byte(&mut lookup, b'^'); } if options.contains(Options::ENABLE_MATH) { add_lookup_byte(&mut lookup, b'$'); add_lookup_byte(&mut lookup, b'{'); add_lookup_byte(&mut lookup, b'}'); } if options.contains(Options::ENABLE_SMART_PUNCTUATION) { for &byte in &[b'.', b'-', b'"', b'\''] { add_lookup_byte(&mut lookup, byte); } } lookup } fn add_lookup_byte(lookup: &mut [u8; 16], byte: u8) { lookup[(byte & 0x0f) as usize] |= 1 << (byte >> 4); } /// Computes a bit mask for the given byteslice starting from the given index, /// where the 16 least significant bits indicate (by value of 1) whether or not /// there is a special character at that byte position. The least significant bit /// corresponds to `bytes[ix]` and the most significant bit corresponds to /// `bytes[ix + 15]`. /// It is only safe to call this function when `bytes.len() >= ix + VECTOR_SIZE`. #[target_feature(enable = "ssse3")] #[inline] unsafe fn compute_mask(lut: &[u8; 16], bytes: &[u8], ix: usize) -> i32 { debug_assert!(bytes.len() >= ix + VECTOR_SIZE); let bitmap = _mm_loadu_si128(lut.as_ptr() as *const __m128i); // Small lookup table to compute single bit bitshifts // for 16 bytes at once. let bitmask_lookup = _mm_setr_epi8(1, 2, 4, 8, 16, 32, 64, -128, -1, -1, -1, -1, -1, -1, -1, -1); // Load input from memory. let raw_ptr = bytes.as_ptr().add(ix) as *const __m128i; let input = _mm_loadu_si128(raw_ptr); // Compute the bitmap using the bottom nibble as an index // into the lookup table. Note that non-ascii bytes will have // their most significant bit set and will map to lookup[0]. let bitset = _mm_shuffle_epi8(bitmap, input); // Compute the high nibbles of the input using a 16-bit rightshift of four // and a mask to prevent most-significant bit issues. let higher_nibbles = _mm_and_si128(_mm_srli_epi16(input, 4), _mm_set1_epi8(0x0f)); // Create a bitmask for the bitmap by perform a left shift of the value // of the higher nibble. Bytes with their most significant set are mapped // to -1 (all ones). let bitmask = _mm_shuffle_epi8(bitmask_lookup, higher_nibbles); // Test the bit of the bitmap by AND'ing the bitmap and the mask together. let tmp = _mm_and_si128(bitset, bitmask); // Check whether the result was not null. NEQ is not a SIMD intrinsic, // but comparing to the bitmask is logically equivalent. This also prevents us // from matching any non-ASCII bytes since none of the bitmaps were all ones // (-1). let result = _mm_cmpeq_epi8(tmp, bitmask); // Return the resulting bitmask. _mm_movemask_epi8(result) } /// Calls callback on byte indices and their value. /// Breaks when callback returns LoopInstruction::BreakAtWith(ix, val). And skips the /// number of bytes in callback return value otherwise. /// Returns the final index and a possible break value. pub(super) fn iterate_special_bytes( lut: &LookupTable, bytes: &[u8], ix: usize, callback: F, ) -> (usize, Option) where F: FnMut(usize, u8) -> LoopInstruction>, { if is_x86_feature_detected!("ssse3") && bytes.len() >= VECTOR_SIZE { unsafe { simd_iterate_special_bytes(&lut.simd, bytes, ix, callback) } } else { super::scalar_iterate_special_bytes(&lut.scalar, bytes, ix, callback) } } /// Calls the callback function for every 1 in the given bitmask with /// the index `offset + ix`, where `ix` is the position of the 1 in the mask. /// Returns `Ok(ix)` to continue from index `ix`, `Err((end_ix, opt_val)` to break with /// final index `end_ix` and optional value `opt_val`. unsafe fn process_mask( mut mask: i32, bytes: &[u8], mut offset: usize, callback: &mut F, ) -> Result)> where F: FnMut(usize, u8) -> LoopInstruction>, { while mask != 0 { let mask_ix = mask.trailing_zeros() as usize; offset += mask_ix; match callback(offset, *bytes.get_unchecked(offset)) { LoopInstruction::ContinueAndSkip(skip) => { offset += skip + 1; let shift = skip + 1 + mask_ix; if shift >= 32 { break; } mask >>= shift; } LoopInstruction::BreakAtWith(ix, val) => return Err((ix, val)), } } Ok(offset) } #[target_feature(enable = "ssse3")] /// Important: only call this function when `bytes.len() >= 16`. Doing /// so otherwise may exhibit undefined behaviour. unsafe fn simd_iterate_special_bytes( lut: &[u8; 16], bytes: &[u8], mut ix: usize, mut callback: F, ) -> (usize, Option) where F: FnMut(usize, u8) -> LoopInstruction>, { debug_assert!(bytes.len() >= VECTOR_SIZE); let upperbound = bytes.len() - VECTOR_SIZE; while ix < upperbound { let mask = compute_mask(lut, bytes, ix); let block_start = ix; ix = match process_mask(mask, bytes, ix, &mut callback) { Ok(ix) => std::cmp::max(ix, VECTOR_SIZE + block_start), Err((end_ix, val)) => return (end_ix, val), }; } if bytes.len() > ix { // shift off the bytes at start we have already scanned let mask = compute_mask(lut, bytes, upperbound) >> ix - upperbound; if let Err((end_ix, val)) = process_mask(mask, bytes, ix, &mut callback) { return (end_ix, val); } } (bytes.len(), None) } #[cfg(test)] mod simd_test { use super::super::create_lut; use super::{iterate_special_bytes, LoopInstruction}; use crate::Options; fn check_expected_indices(bytes: &[u8], expected: &[usize], skip: usize) { let mut opts = Options::empty(); opts.insert(Options::ENABLE_MATH); opts.insert(Options::ENABLE_TABLES); opts.insert(Options::ENABLE_FOOTNOTES); opts.insert(Options::ENABLE_STRIKETHROUGH); opts.insert(Options::ENABLE_SUPERSCRIPT); opts.insert(Options::ENABLE_TASKLISTS); let lut = create_lut(&opts); let mut indices = vec![]; iterate_special_bytes::<_, i32>(&lut, bytes, 0, |ix, _byte_ty| { indices.push(ix); LoopInstruction::ContinueAndSkip(skip) }); assert_eq!(&indices[..], expected); } #[test] fn simple_no_match() { check_expected_indices("abcdef0123456789".as_bytes(), &[], 0); } #[test] fn simple_match() { check_expected_indices("*bcd&f0123456789".as_bytes(), &[0, 4], 0); } #[test] fn single_open_fish() { check_expected_indices("<".as_bytes(), &[0], 0); } #[test] fn long_match() { check_expected_indices("0123456789abcde~*bcd&f0".as_bytes(), &[15, 16, 20], 0); } #[test] fn border_skip() { check_expected_indices("0123456789abcde~~~~d&f0".as_bytes(), &[15, 20], 3); } #[test] fn exhaustive_search() { let chars = [ b'\n', b'\r', b'*', b'_', b'~', b'^', b'|', b'&', b'\\', b'[', b']', b'<', b'!', b'`', b'$', b'{', b'}', ]; for &c in &chars { for i in 0u8..=255 { if !chars.contains(&i) { // full match let mut buf = [i; 18]; buf[3] = c; buf[6] = c; check_expected_indices(&buf[..], &[3, 6], 0); } } } } } } pulldown-cmark-0.13.0/src/html.rs000064400000000000000000000510531046102023000147510ustar 00000000000000// Copyright 2015 Google Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! HTML renderer that takes an iterator of events as input. use std::collections::HashMap; use crate::strings::CowStr; use crate::Event::*; use crate::{Alignment, BlockQuoteKind, CodeBlockKind, Event, LinkType, Tag, TagEnd}; use pulldown_cmark_escape::{ escape_href, escape_html, escape_html_body_text, FmtWriter, IoWriter, StrWrite, }; enum TableState { Head, Body, } struct HtmlWriter<'a, I, W> { /// Iterator supplying events. iter: I, /// Writer to write to. writer: W, /// Whether or not the last write wrote a newline. end_newline: bool, /// Whether if inside a metadata block (text should not be written) in_non_writing_block: bool, table_state: TableState, table_alignments: Vec, table_cell_index: usize, numbers: HashMap, usize>, } impl<'a, I, W> HtmlWriter<'a, I, W> where I: Iterator>, W: StrWrite, { fn new(iter: I, writer: W) -> Self { Self { iter, writer, end_newline: true, in_non_writing_block: false, table_state: TableState::Head, table_alignments: vec![], table_cell_index: 0, numbers: HashMap::new(), } } /// Writes a new line. #[inline] fn write_newline(&mut self) -> Result<(), W::Error> { self.end_newline = true; self.writer.write_str("\n") } /// Writes a buffer, and tracks whether or not a newline was written. #[inline] fn write(&mut self, s: &str) -> Result<(), W::Error> { self.writer.write_str(s)?; if !s.is_empty() { self.end_newline = s.ends_with('\n'); } Ok(()) } fn run(mut self) -> Result<(), W::Error> { while let Some(event) = self.iter.next() { match event { Start(tag) => { self.start_tag(tag)?; } End(tag) => { self.end_tag(tag)?; } Text(text) => { if !self.in_non_writing_block { escape_html_body_text(&mut self.writer, &text)?; self.end_newline = text.ends_with('\n'); } } Code(text) => { self.write("")?; escape_html_body_text(&mut self.writer, &text)?; self.write("")?; } InlineMath(text) => { self.write(r#""#)?; escape_html(&mut self.writer, &text)?; self.write("")?; } DisplayMath(text) => { self.write(r#""#)?; escape_html(&mut self.writer, &text)?; self.write("")?; } Html(html) | InlineHtml(html) => { self.write(&html)?; } SoftBreak => { self.write_newline()?; } HardBreak => { self.write("
\n")?; } Rule => { if self.end_newline { self.write("
\n")?; } else { self.write("\n
\n")?; } } FootnoteReference(name) => { let len = self.numbers.len() + 1; self.write("")?; let number = *self.numbers.entry(name).or_insert(len); write!(&mut self.writer, "{}", number)?; self.write("")?; } TaskListMarker(true) => { self.write("\n")?; } TaskListMarker(false) => { self.write("\n")?; } } } Ok(()) } /// Writes the start of an HTML tag. fn start_tag(&mut self, tag: Tag<'a>) -> Result<(), W::Error> { match tag { Tag::HtmlBlock => Ok(()), Tag::Paragraph => { if self.end_newline { self.write("

") } else { self.write("\n

") } } Tag::Heading { level, id, classes, attrs, } => { if self.end_newline { self.write("<")?; } else { self.write("\n<")?; } write!(&mut self.writer, "{}", level)?; if let Some(id) = id { self.write(" id=\"")?; escape_html(&mut self.writer, &id)?; self.write("\"")?; } let mut classes = classes.iter(); if let Some(class) = classes.next() { self.write(" class=\"")?; escape_html(&mut self.writer, class)?; for class in classes { self.write(" ")?; escape_html(&mut self.writer, class)?; } self.write("\"")?; } for (attr, value) in attrs { self.write(" ")?; escape_html(&mut self.writer, &attr)?; if let Some(val) = value { self.write("=\"")?; escape_html(&mut self.writer, &val)?; self.write("\"")?; } else { self.write("=\"\"")?; } } self.write(">") } Tag::Table(alignments) => { self.table_alignments = alignments; self.write("") } Tag::TableHead => { self.table_state = TableState::Head; self.table_cell_index = 0; self.write("") } Tag::TableRow => { self.table_cell_index = 0; self.write("") } Tag::TableCell => { match self.table_state { TableState::Head => { self.write(" { self.write(" self.write(" style=\"text-align: left\">"), Some(&Alignment::Center) => self.write(" style=\"text-align: center\">"), Some(&Alignment::Right) => self.write(" style=\"text-align: right\">"), _ => self.write(">"), } } Tag::BlockQuote(kind) => { let class_str = match kind { None => "", Some(kind) => match kind { BlockQuoteKind::Note => " class=\"markdown-alert-note\"", BlockQuoteKind::Tip => " class=\"markdown-alert-tip\"", BlockQuoteKind::Important => " class=\"markdown-alert-important\"", BlockQuoteKind::Warning => " class=\"markdown-alert-warning\"", BlockQuoteKind::Caution => " class=\"markdown-alert-caution\"", }, }; if self.end_newline { self.write(&format!("\n", class_str)) } else { self.write(&format!("\n\n", class_str)) } } Tag::CodeBlock(info) => { if !self.end_newline { self.write_newline()?; } match info { CodeBlockKind::Fenced(info) => { let lang = info.split(' ').next().unwrap(); if lang.is_empty() { self.write("
")
                        } else {
                            self.write("
")
                        }
                    }
                    CodeBlockKind::Indented => self.write("
"),
                }
            }
            Tag::List(Some(1)) => {
                if self.end_newline {
                    self.write("
    \n") } else { self.write("\n
      \n") } } Tag::List(Some(start)) => { if self.end_newline { self.write("
        \n") } Tag::List(None) => { if self.end_newline { self.write("
\n")?; } TagEnd::TableHead => { self.write("\n")?; self.table_state = TableState::Body; } TagEnd::TableRow => { self.write("\n")?; } TagEnd::TableCell => { match self.table_state { TableState::Head => { self.write("")?; } TableState::Body => { self.write("")?; } } self.table_cell_index += 1; } TagEnd::BlockQuote(_) => { self.write("\n")?; } TagEnd::CodeBlock => { self.write("\n")?; } TagEnd::List(true) => { self.write("\n")?; } TagEnd::List(false) => { self.write("\n")?; } TagEnd::Item => { self.write("\n")?; } TagEnd::DefinitionList => { self.write("\n")?; } TagEnd::DefinitionListTitle => { self.write("\n")?; } TagEnd::DefinitionListDefinition => { self.write("\n")?; } TagEnd::Emphasis => { self.write("")?; } TagEnd::Superscript => { self.write("")?; } TagEnd::Subscript => { self.write("")?; } TagEnd::Strong => { self.write("")?; } TagEnd::Strikethrough => { self.write("")?; } TagEnd::Link => { self.write("")?; } TagEnd::Image => (), // shouldn't happen, handled in start TagEnd::FootnoteDefinition => { self.write("\n")?; } TagEnd::MetadataBlock(_) => { self.in_non_writing_block = false; } } Ok(()) } // run raw text, consuming end tag fn raw_text(&mut self) -> Result<(), W::Error> { let mut nest = 0; while let Some(event) = self.iter.next() { match event { Start(_) => nest += 1, End(_) => { if nest == 0 { break; } nest -= 1; } Html(_) => {} InlineHtml(text) | Code(text) | Text(text) => { // Don't use escape_html_body_text here. // The output of this function is used in the `alt` attribute. escape_html(&mut self.writer, &text)?; self.end_newline = text.ends_with('\n'); } InlineMath(text) => { self.write("$")?; escape_html(&mut self.writer, &text)?; self.write("$")?; } DisplayMath(text) => { self.write("$$")?; escape_html(&mut self.writer, &text)?; self.write("$$")?; } SoftBreak | HardBreak | Rule => { self.write(" ")?; } FootnoteReference(name) => { let len = self.numbers.len() + 1; let number = *self.numbers.entry(name).or_insert(len); write!(&mut self.writer, "[{}]", number)?; } TaskListMarker(true) => self.write("[x]")?, TaskListMarker(false) => self.write("[ ]")?, } } Ok(()) } } /// Iterate over an `Iterator` of `Event`s, generate HTML for each `Event`, and /// push it to a `String`. /// /// # Examples /// /// ``` /// use pulldown_cmark::{html, Parser}; /// /// let markdown_str = r#" /// hello /// ===== /// /// * alpha /// * beta /// "#; /// let parser = Parser::new(markdown_str); /// /// let mut html_buf = String::new(); /// html::push_html(&mut html_buf, parser); /// /// assert_eq!(html_buf, r#"

hello

///
    ///
  • alpha
  • ///
  • beta
  • ///
/// "#); /// ``` pub fn push_html<'a, I>(s: &mut String, iter: I) where I: Iterator>, { write_html_fmt(s, iter).unwrap() } /// Iterate over an `Iterator` of `Event`s, generate HTML for each `Event`, and /// write it out to an I/O stream. /// /// **Note**: using this function with an unbuffered writer like a file or socket /// will result in poor performance. Wrap these in a /// [`BufWriter`](https://doc.rust-lang.org/std/io/struct.BufWriter.html) to /// prevent unnecessary slowdowns. /// /// # Examples /// /// ``` /// use pulldown_cmark::{html, Parser}; /// use std::io::Cursor; /// /// let markdown_str = r#" /// hello /// ===== /// /// * alpha /// * beta /// "#; /// let mut bytes = Vec::new(); /// let parser = Parser::new(markdown_str); /// /// html::write_html_io(Cursor::new(&mut bytes), parser); /// /// assert_eq!(&String::from_utf8_lossy(&bytes)[..], r#"

hello

///
    ///
  • alpha
  • ///
  • beta
  • ///
/// "#); /// ``` pub fn write_html_io<'a, I, W>(writer: W, iter: I) -> std::io::Result<()> where I: Iterator>, W: std::io::Write, { HtmlWriter::new(iter, IoWriter(writer)).run() } /// Iterate over an `Iterator` of `Event`s, generate HTML for each `Event`, and /// write it into Unicode-accepting buffer or stream. /// /// # Examples /// /// ``` /// use pulldown_cmark::{html, Parser}; /// /// let markdown_str = r#" /// hello /// ===== /// /// * alpha /// * beta /// "#; /// let mut buf = String::new(); /// let parser = Parser::new(markdown_str); /// /// html::write_html_fmt(&mut buf, parser); /// /// assert_eq!(buf, r#"

hello

///
    ///
  • alpha
  • ///
  • beta
  • ///
/// "#); /// ``` pub fn write_html_fmt<'a, I, W>(writer: W, iter: I) -> std::fmt::Result where I: Iterator>, W: std::fmt::Write, { HtmlWriter::new(iter, FmtWriter(writer)).run() } pulldown-cmark-0.13.0/src/lib.rs000064400000000000000000000640161046102023000145560ustar 00000000000000// Copyright 2015 Google Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. //! Pull parser for [CommonMark](https://commonmark.org). This crate provides a [Parser](struct.Parser.html) struct //! which is an iterator over [Event](enum.Event.html)s. This iterator can be used //! directly, or to output HTML using the [HTML module](html/index.html). //! //! By default, only CommonMark features are enabled. To use extensions like tables, //! footnotes or task lists, enable them by setting the corresponding flags in the //! [Options](struct.Options.html) struct. //! //! # Example //! ```rust //! use pulldown_cmark::{Parser, Options}; //! //! let markdown_input = "Hello world, this is a ~~complicated~~ *very simple* example."; //! //! // Set up options and parser. Strikethroughs are not part of the CommonMark standard //! // and we therefore must enable it explicitly. //! let mut options = Options::empty(); //! options.insert(Options::ENABLE_STRIKETHROUGH); //! let parser = Parser::new_ext(markdown_input, options); //! //! # #[cfg(feature = "html")] { //! // Write to String buffer. //! let mut html_output = String::new(); //! pulldown_cmark::html::push_html(&mut html_output, parser); //! //! // Check that the output is what we expected. //! let expected_html = "

Hello world, this is a complicated very simple example.

\n"; //! assert_eq!(expected_html, &html_output); //! # } //! ``` //! //! Note that consecutive text events can happen due to the manner in which the //! parser evaluates the source. A utility `TextMergeStream` exists to improve //! the comfort of iterating the events: //! //! ```rust //! use pulldown_cmark::{Event, Parser, TextMergeStream}; //! //! let markdown_input = "Hello world, this is a ~~complicated~~ *very simple* example."; //! //! let iterator = TextMergeStream::new(Parser::new(markdown_input)); //! //! for event in iterator { //! match event { //! Event::Text(text) => println!("{}", text), //! _ => {} //! } //! } //! ``` //! // When compiled for the rustc compiler itself we want to make sure that this is // an unstable crate. #![cfg_attr(rustbuild, feature(staged_api, rustc_private))] #![cfg_attr(rustbuild, unstable(feature = "rustc_private", issue = "27812"))] // Forbid unsafe code unless the SIMD feature is enabled. #![cfg_attr(not(feature = "simd"), forbid(unsafe_code))] #![warn(missing_debug_implementations)] #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; #[cfg(feature = "html")] pub mod html; pub mod utils; mod entities; mod firstpass; mod linklabel; mod parse; mod puncttable; mod scanners; mod strings; mod tree; use std::fmt::Display; pub use crate::parse::{ BrokenLink, BrokenLinkCallback, DefaultBrokenLinkCallback, OffsetIter, Parser, RefDefs, }; pub use crate::strings::{CowStr, InlineStr}; pub use crate::utils::*; /// Codeblock kind. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum CodeBlockKind<'a> { Indented, /// The value contained in the tag describes the language of the code, which may be empty. #[cfg_attr(feature = "serde", serde(borrow))] Fenced(CowStr<'a>), } impl<'a> CodeBlockKind<'a> { pub fn is_indented(&self) -> bool { matches!(*self, CodeBlockKind::Indented) } pub fn is_fenced(&self) -> bool { matches!(*self, CodeBlockKind::Fenced(_)) } pub fn into_static(self) -> CodeBlockKind<'static> { match self { CodeBlockKind::Indented => CodeBlockKind::Indented, CodeBlockKind::Fenced(s) => CodeBlockKind::Fenced(s.into_static()), } } } /// BlockQuote kind (Note, Tip, Important, Warning, Caution). #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum BlockQuoteKind { Note, Tip, Important, Warning, Caution, } /// Metadata block kind. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum MetadataBlockKind { YamlStyle, PlusesStyle, } /// Tags for elements that can contain other elements. #[derive(Clone, Debug, PartialEq)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub enum Tag<'a> { /// A paragraph of text and other inline elements. Paragraph, /// A heading, with optional identifier, classes and custom attributes. /// The identifier is prefixed with `#` and the last one in the attributes /// list is chosen, classes are prefixed with `.` and custom attributes /// have no prefix and can optionally have a value (`myattr` or `myattr=myvalue`). /// /// `id`, `classes` and `attrs` are only parsed and populated with [`Options::ENABLE_HEADING_ATTRIBUTES`], `None` or empty otherwise. Heading { level: HeadingLevel, id: Option>, classes: Vec>, /// The first item of the tuple is the attr and second one the value. attrs: Vec<(CowStr<'a>, Option>)>, }, /// A block quote. /// /// The `BlockQuoteKind` is only parsed & populated with [`Options::ENABLE_GFM`], `None` otherwise. /// /// ```markdown /// > regular quote /// /// > [!NOTE] /// > note quote /// ``` BlockQuote(Option), /// A code block. CodeBlock(CodeBlockKind<'a>), /// An HTML block. /// /// A line that begins with some predefined tags (HTML block tags) (see [CommonMark Spec](https://spec.commonmark.org/0.31.2/#html-blocks) for more details) or any tag that is followed only by whitespace. /// /// Most HTML blocks end on an empty line, though some e.g. `
` like `"##;
    let expected = r##"

Little header

"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_2() { let original = r##"Little header "##; let expected = r##"

Little header

"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_3() { let original = r##"Little header

Useless

?>"##; let expected = r##"

Little header

Useless

?>"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_4() { let original = r##"Little header "##; let expected = r##"

Little header

"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_5() { let original = r##"Little header

Useless

]]>"##; let expected = r##"

Little header

Useless

]]>"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_6() { let original = r##"Little header "##; let expected = r##"

Little header

"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_7() { let original = r##"Little header ----------- "##; let expected = r##"

Little header

"##; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_8() { let original = "A | B\n---|---\nfoo | bar"; let expected = r##"
AB
foobar
"##; let mut s = String::new(); let mut opts = Options::empty(); opts.insert(Options::ENABLE_TABLES); html::push_html(&mut s, Parser::new_ext(original, opts)); assert_eq!(expected, s); } #[test] fn html_test_9() { let original = "---"; let expected = "
\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_10() { let original = "* * *"; let expected = "
\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_11() { let original = "hi ~~no~~"; let expected = "

hi ~~no~~

\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn html_test_broken_callback() { let original = r##"[foo], [bar], [baz], [baz]: https://example.org "##; let expected = r##"

foo, [bar], baz,

"##; use pulldown_cmark::{html, Options, Parser}; let mut s = String::new(); let mut callback = |broken_link: BrokenLink| { if &*broken_link.reference == "foo" || &*broken_link.reference == "baz" { Some(("https://replaced.example.org".into(), "some title".into())) } else { None } }; let p = Parser::new_with_broken_link_callback(original, Options::empty(), Some(&mut callback)); html::push_html(&mut s, p); assert_eq!(expected, s); } #[test] fn newline_in_code() { let originals = ["`\n `x", "` \n`x"]; let expected = "

x

\n"; for original in originals { let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } } #[test] fn newline_start_end_of_code() { let original = "`\nx\n`x"; let expected = "

xx

\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } // https://github.com/raphlinus/pulldown-cmark/issues/715 #[test] fn trim_space_and_tab_at_end_of_paragraph() { let original = "one\ntwo \t"; let expected = "

one\ntwo

\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn newline_within_code() { let originals = ["`\nx \ny\n`x", "`x \ny`x", "`x\n y`x"]; let expected = "

x yx

\n"; for original in originals { let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } } #[test] fn trim_space_tab_nl_at_end_of_paragraph() { let original = "one\ntwo \t\n"; let expected = "

one\ntwo

\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn trim_space_nl_at_end_of_paragraph() { let original = "one\ntwo \n"; let expected = "

one\ntwo

\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } #[test] fn trim_space_before_soft_break() { let original = "one \ntwo"; let expected = "

one\ntwo

\n"; let mut s = String::new(); html::push_html(&mut s, Parser::new(original)); assert_eq!(expected, s); } // Can't easily use regression.txt due to newline normalization. #[test] fn issue_819() { let original = [ "# \\", "# \\\n", "# \\\n\n", "# \\\r\n", "# \\\r\n\r\n", "# \\\n\r\n", "# \\\r\n\n", ]; let expected = "

\\

"; for orig in original { let mut s = String::new(); html::push_html(&mut s, Parser::new(orig)); // Trailing newline doesn't matter. Just the actual HTML. assert_eq!(expected, s.trim_end_matches('\n')); } for orig in original { let mut s = String::new(); let mut opts = Options::empty(); opts.insert(Options::ENABLE_HEADING_ATTRIBUTES); html::push_html(&mut s, Parser::new_ext(orig, opts)); // Trailing newline doesn't matter. Just the actual HTML. assert_eq!(expected, s.trim_end_matches('\n')); } } pulldown-cmark-0.13.0/tests/lib.rs000064400000000000000000000034511046102023000151250ustar 00000000000000#![cfg(feature = "html")] use pulldown_cmark::{Options, Parser}; #[rustfmt::skip] mod suite; #[inline(never)] pub fn test_markdown_html( input: &str, output: &str, smart_punct: bool, metadata_blocks: bool, old_footnotes: bool, subscript: bool, wikilinks: bool, ) { let mut s = String::new(); let mut opts = Options::empty(); opts.insert(Options::ENABLE_MATH); opts.insert(Options::ENABLE_TABLES); opts.insert(Options::ENABLE_STRIKETHROUGH); opts.insert(Options::ENABLE_SUPERSCRIPT); if wikilinks { opts.insert(Options::ENABLE_WIKILINKS); } if subscript { opts.insert(Options::ENABLE_SUBSCRIPT); } opts.insert(Options::ENABLE_TASKLISTS); opts.insert(Options::ENABLE_GFM); if old_footnotes { opts.insert(Options::ENABLE_OLD_FOOTNOTES); } else { opts.insert(Options::ENABLE_FOOTNOTES); } if metadata_blocks { opts.insert(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS); opts.insert(Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS); } if smart_punct { opts.insert(Options::ENABLE_SMART_PUNCTUATION); } opts.insert(Options::ENABLE_HEADING_ATTRIBUTES); opts.insert(Options::ENABLE_DEFINITION_LIST); let p = Parser::new_ext(input, opts); pulldown_cmark::html::push_html(&mut s, p); // normalizing the HTML using html5ever may hide actual errors // assert_eq!(html_standardize(output), html_standardize(&s)); assert_eq!(html_standardize(output), html_standardize(&s)); } fn html_standardize(s: &str) -> String { s.replace("
", "
") .replace("
", "
") .replace("
", "
") .replace("
", "
") // permit extra or missing line breaks only between tags .replace(">\n<", "><") } pulldown-cmark-0.13.0/tests/serde.rs000064400000000000000000000060031046102023000154550ustar 00000000000000#[cfg(feature = "serde")] mod tests { use std::convert::TryInto; use pulldown_cmark::CowStr; #[test] fn escaped() { let must_be_escaped = "\""; let wire = serde_json::to_string(must_be_escaped).unwrap(); let de = serde_json::from_str::(&wire).unwrap(); assert_eq!(&*de, must_be_escaped); } #[test] fn cow_str_to_str_round_trip_bincode() { for i in &[ CowStr::Borrowed("dssa"), CowStr::Borrowed(""), CowStr::Boxed("hello".to_owned().into_boxed_str()), CowStr::Boxed("".to_owned().into_boxed_str()), CowStr::Inlined("inline".try_into().unwrap()), CowStr::Inlined("".try_into().unwrap()), ] { let encoded = bincode::serialize(i).unwrap(); let decoded1: CowStr = bincode::deserialize(&encoded).unwrap(); let decoded2: String = bincode::deserialize(&encoded).unwrap(); let decoded3: &str = bincode::deserialize(&encoded).unwrap(); assert_eq!(&decoded1, i); assert_eq!(decoded2, i.as_ref()); assert_eq!(decoded3, i.as_ref()); } } #[test] fn cow_str_to_str_round_trip_json() { for i in &[ CowStr::Borrowed("dssa"), CowStr::Borrowed(""), CowStr::Boxed("hello".to_owned().into_boxed_str()), CowStr::Boxed("".to_owned().into_boxed_str()), CowStr::Inlined("inline".try_into().unwrap()), CowStr::Inlined("".try_into().unwrap()), ] { let encoded = serde_json::to_string(i).unwrap(); let decoded1: CowStr = serde_json::from_str(&encoded).unwrap(); let decoded2: String = serde_json::from_str(&encoded).unwrap(); let decoded3: &str = serde_json::from_str(&encoded).unwrap(); assert_eq!(&decoded1, i); assert_eq!(decoded2, i.as_ref()); assert_eq!(decoded3, i.as_ref()); } } #[test] fn str_to_cow_str_json() { let str = "a borrowed str"; let string = "a owned str".to_owned(); let encoded_str = serde_json::to_string(&str).unwrap(); let encoded_string = serde_json::to_string(&string).unwrap(); let decoded_str: CowStr = serde_json::from_str(&encoded_str).unwrap(); let decoded_string: CowStr = serde_json::from_str(&encoded_string).unwrap(); assert_eq!(decoded_str.as_ref(), str); assert_eq!(decoded_string.as_ref(), string); } #[test] fn str_to_cow_str_bincode() { let str = "a borrowed str"; let string = "a owned str".to_owned(); let encoded_str = bincode::serialize(&str).unwrap(); let encoded_string = bincode::serialize(&string).unwrap(); let decoded_str: CowStr = bincode::deserialize(&encoded_str).unwrap(); let decoded_string: CowStr = bincode::deserialize(&encoded_string).unwrap(); assert_eq!(decoded_str.as_ref(), str); assert_eq!(decoded_string.as_ref(), string); } } pulldown-cmark-0.13.0/tests/suite/blockquotes_tags.rs000064400000000000000000000141351046102023000210620ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn blockquotes_tags_test_1() { let original = r##"> This is a normal blockquote without tag. "##; let expected = r##"

This is a normal blockquote without tag.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_2() { let original = r##"> [!NOTE] > Note blockquote "##; let expected = r##"

Note blockquote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_3() { let original = r##"> [!TIP] > Tip blockquote "##; let expected = r##"

Tip blockquote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_4() { let original = r##"> [!IMPORTANT] > Important blockquote "##; let expected = r##"

Important blockquote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_5() { let original = r##"> [!WARNING] > Warning blockquote "##; let expected = r##"

Warning blockquote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_6() { let original = r##"> [!CAUTION] > Caution blockquote "##; let expected = r##"

Caution blockquote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_7() { let original = r##"> [!CAUTION] "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_8() { let original = r##"> [!CAUTION] > Line 1. > Line 2. "##; let expected = r##"

Line 1. Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_9() { let original = r##"> [!CAUTION] > Line 1. > [!CAUTION] > Line 2. "##; let expected = r##"

Line 1. [!CAUTION] Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_10() { let original = r##"> [!CAUTION] > Line 1. > > [!TIP] > Line 2. "##; let expected = r##"

Line 1.

Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_11() { let original = r##"> [!CAUTION] > Line 1. > [!TIP] > Line 2. "##; let expected = r##"

Line 1.

Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_12() { let original = r##"> > [!CAUTION] > > Line 1. > Line 2. "##; let expected = r##"

Line 1. Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_13() { let original = r##"> [!CAUTION] > Line 1. > > [!NOTE] > > Line 2. "##; let expected = r##"

Line 1.

Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_14() { let original = r##"> [!caution] > Line 1. > > [!note] > > Line 2. "##; let expected = r##"

Line 1.

Line 2.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_15() { let original = r##" * loose lists > [!NOTE] > sink ships "##; let expected = r##"
  • loose lists

    sink ships

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_16() { let original = r##"> [!NOTE] sink ships > [!NOTE] > sink ships * loose lists > [!NOTE] sink ships > [!NOTE] > sink ships "##; let expected = r##"

sink ships

sink ships

  • loose lists

    sink ships

    sink ships

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_17() { let original = r##" * loose lists > [!NOTE] - sink ships > [!NOTE] > - sink ships "##; let expected = r##"
  • loose lists

    • sink ships
    • sink ships
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn blockquotes_tags_test_18() { let original = r##"> [!Hello] > This should be a normal block quote. "##; let expected = r##"

[!Hello] This should be a normal block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/definition_lists.rs000064400000000000000000000247431046102023000210650ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn definition_lists_test_1() { let original = r##"apple : red fruit orange : orange fruit "##; let expected = r##"
apple
red fruit
orange
orange fruit
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_2() { let original = r##"apple : red fruit orange : orange fruit "##; let expected = r##"
apple

red fruit

orange

orange fruit

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_3() { let original = r##"apple : red fruit "##; let expected = r##"
apple

red fruit

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_4() { let original = r##"apple : red fruit orange : orange fruit "##; let expected = r##"
apple
red fruit
orange
orange fruit
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_5() { let original = r##"apple : red fruit orange : orange fruit "##; let expected = r##"
apple

red fruit

orange

orange fruit

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_6() { let original = r##"*apple* : red fruit contains seeds, crisp, pleasant to taste *orange* : orange fruit { orange code block } > orange block quote "##; let expected = r##"
apple

red fruit

contains seeds, crisp, pleasant to taste

orange

orange fruit

{ orange code block }

orange block quote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_7() { let original = r##"term : 1. Para one Para two "##; let expected = r##"
term
  1. Para one

    Para two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_8() { let original = r##"apple : red fruit : computer company orange : orange fruit : telecom company "##; let expected = r##"
apple
red fruit
computer company
orange
orange fruit
telecom company
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_9() { let original = r##"apple : red fruit : computer company orange : orange fruit : telecom company "##; let expected = r##"
apple

red fruit

computer company

orange

orange fruit

telecom company

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_10() { let original = r##"apple : red fruit : computer company orange : orange fruit : telecom company "##; let expected = r##"
apple

red fruit

computer company

orange

orange fruit

telecom company

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_11() { let original = r##"apple : > computer company : red fruit orange : > telecom company : orange fruit chili's : > restaurant company : spicy fruit "##; let expected = r##"
apple

computer company : red fruit

orange

telecom company

orange fruit
chili's

restaurant company

spicy fruit
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_12() { let original = r##"> cherry > : keyboard company > pomegranate : tart fruit "##; let expected = r##"
cherry
keyboard company pomegranate : tart fruit
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_13() { let original = r##"a b\ c : foo "##; let expected = r##"
a b
c

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_14() { let original = r##"Foo bar : baz bim : bor "##; let expected = r##"

Foo

bar
baz
bim
bor
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_15() { let original = r##"bar : baz bim : bor Bloze "##; let expected = r##"
bar
baz
bim
bor

Bloze

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_16() { let original = r##"bar :baz Bloze "##; let expected = r##"

bar :baz

Bloze

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_17() { let original = r##"bar : baz Bloze "##; let expected = r##"
bar
baz

Bloze

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_18() { let original = r##"bar : baz bar : baz bar : baz bar : baz bar : baz "##; let expected = r##"
bar
  baz
bar
 baz
bar
baz
bar
baz

bar : baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_19() { let original = r##"*orange* : orange fruit { orange code block } > orange block quote *orange* : orange fruit { orange code block } > orange block quote "##; let expected = r##"
orange

orange fruit

{ orange code block }

orange block quote

orange
orange fruit

  { orange code block }

orange block quote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_20() { let original = r##"Test|Table ----|----- : first "##; let expected = r##"
TestTable
: first
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_21() { let original = r##"first : second Test|Table ----|----- : fourth "##; let expected = r##"
first
second
TestTable
: fourth
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_22() { let original = r##"My section ========== : first "##; let expected = r##"

My section

: first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_23() { let original = r##"first : second My section ========== : fourth "##; let expected = r##"
first
second

My section

: fourth

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_24() { let original = r##"## My subsection : first "##; let expected = r##"

My subsection

: first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_25() { let original = r##"first : second ## My subsection : fourth "##; let expected = r##"
first
second

My subsection

: fourth

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_26() { let original = r##"> first : second "##; let expected = r##"

first : second

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_27() { let original = r##"first\ : second third : fourth "##; let expected = r##"
first\
second
third
fourth
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_28() { let original = r##"
first
: second first : second
third
: fourth "##; let expected = r##"
first
: second
first
second
third
: fourth "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_29() { let original = r##"first : second third : fourth fifth : sixth "##; let expected = r##"
first
second
third
fourth
fifth
sixth
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn definition_lists_test_30() { let original = r##"level one : l1 level two : l2 level three : l3 level one : l1 "##; let expected = r##"
level one
l1 level two
l2 level three
l3
level one
l1
"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/footnotes.rs000064400000000000000000000653131046102023000175350ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn footnotes_test_1() { let original = r##"Lorem ipsum.[^a] [^missing] [^a]: Cool. "##; let expected = r##"

Lorem ipsum.1 [^missing]

1

Cool.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_2() { let original = r##"> This is the song that never ends.\ > Yes it goes on and on my friends.[^lambchops] > > [^lambchops]: "##; let expected = r##"

This is the song that never ends.
Yes it goes on and on my friends.1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_3() { let original = r##"Songs that simply loop are a popular way to annoy people. [^examples] [^examples]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) * [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) * [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) "##; let expected = r##"

Songs that simply loop are a popular way to annoy people. 1

1
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_4() { let original = r##"Songs that simply loop are a popular way to annoy people. [^examples] [^examples]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) * [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) * [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) "##; let expected = r##"

Songs that simply loop are a popular way to annoy people. 1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_5() { let original = r##"[^not-code] [^code] [^quote] [^not-quote] [^indented-quote] [^not-code]: not code [^code]: code [^quote]: > quote [^not-quote]: > external quote [^indented-quote]: > indented quote "##; let expected = r##"

1 2 3 4 5

1

not code

2
code
3

quote

4

external quote

5

indented quote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_6() { let original = r##"[^ab] [^cd] [^ab]: a b [^cd]: c\ d "##; let expected = r##"

1 2

1

a b

2

c
d

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_7() { let original = r##"[^lorem]: If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research. I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp. [^ipsum]: If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research. I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp. "##; let expected = r##"
1

If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.

I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.

2

If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.

I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_8() { let original = r##"[^ipsum]: How much wood would a woodchuck chuck. If a woodchuck could chuck wood. # Forms of entertainment that aren't childish "##; let expected = r##"
1

How much wood would a woodchuck chuck.

If a woodchuck could chuck wood.

Forms of entertainment that aren't childish

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_9() { let original = r##"Footnotes [^one] [^many]. [^one]: first paragraph inside footnote [^many]: first paragraph inside footnote second paragraph still inside footnote "##; let expected = r##"

Footnotes 1 2.

1

first paragraph inside footnote

2

first paragraph inside footnote

second paragraph still inside footnote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_10() { let original = r##"> He's also really stupid. [^why] > > [^why]: Because your mamma! As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet. "##; let expected = r##"

He's also really stupid. 1

1

Because your mamma!

As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_11() { let original = r##"Nested footnotes are considered poor style. [^a] [^xkcd] [^indent1] [^indent2] [^a]: This does not mean that footnotes cannot reference each other. [^b] [^b]: This means that a footnote definition cannot be directly inside another footnote definition. > This means that a footnote cannot be directly inside another footnote's body. [^e] > > [^e]: They can, however, be inside anything else. [^xkcd]: [The other kind of nested footnote is, however, considered poor style.](https://xkcd.com/1208/) [^indent1]: indent1 [^indent2]: indent2 "##; let expected = r##"

Nested footnotes are considered poor style. 1 2 3 4

1

This does not mean that footnotes cannot reference each other. 5

5

This means that a footnote definition cannot be directly inside another footnote definition.

This means that a footnote cannot be directly inside another footnote's body. 6

6

They can, however, be inside anything else.

3

indent1

4

indent2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_12() { let original = r##"[^foo] [^bar] [^foo]: [^bar]: 1 "##; let expected = r##"

1 2

1
2

1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_13() { let original = r##"[^Doh] Ray Me Fa So La Te Do! [^1] [^Doh]: I know. Wrong Doe. And it won't render right. [^1]: Common for people practicing music. "##; let expected = r##"

1 Ray Me Fa So La Te Do! 2

1

I know. Wrong Doe. And it won't render right.

2

Common for people practicing music.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_14() { let original = r##"Lorem ipsum.[^a] An unordered list before the footnotes: * Ipsum * Lorem [^a]: Cool. "##; let expected = r##"

Lorem ipsum.1

An unordered list before the footnotes:

  • Ipsum
  • Lorem
1

Cool.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_15() { let original = r##"Songs that simply loop are a popular way to annoy people. [^examples] [^examples]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) * [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) * [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) Songs that simply loop are a popular way to annoy people. [^examples2] [^examples2]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) 2 * [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) 2 - [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) 2 Songs that simply loop are a popular way to annoy people. [^examples3] [^examples3]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) 3 * [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) 3 * [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) 3 "##; let expected = r##"

Songs that simply loop are a popular way to annoy people. 1

Songs that simply loop are a popular way to annoy people. 2

Songs that simply loop are a popular way to annoy people. 3

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_16() { let original = r##"My [cmark-gfm][^c]. My [cmark-gfm][cmark-gfm][^c]. My [cmark-gfm][][^c]. My [cmark-gfm] [^c]. My [cmark-gfm[^c]]. [cmark-gfm]: https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702 [^c]: cmark-gfm is under the MIT license, so incorporating parts of its test suite into pulldown-cmark should be fine. My [otherlink[^c]]. [otherlink[^c]]: https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702 "##; let expected = r##"

My cmark-gfm1.

My cmark-gfm1.

My cmark-gfm1.

My cmark-gfm 1.

My [cmark-gfm1].

1

cmark-gfm is under the MIT license, so incorporating parts of its test suite into pulldown-cmark should be fine.

My [otherlink1].

[otherlink1]: https://github.com/github/cmark-gfm/blob/1e230827a584ebc9938c3eadc5059c55ef3c9abf/test/extensions.txt#L702

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_17() { let original = r##"[^1]: footnote definition text // indented code block fn main() { println!("hello world!"); } "##; let expected = r##"
1

footnote definition text

// indented code block
fn main() {
    println!("hello world!");
}
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_18() { let original = r##"[^1]: footnote definition text [^1]\: this is a reference, rather than a definition "##; let expected = r##"
1

footnote definition text 1: this is a reference, rather than a definition

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_19() { let original = r##"[^1]: | column1 | column2 | |---------|---------| | row1a | row1b | | row2a | row2b | "##; let expected = r##"
1
column1column2
row1arow1b
row2arow2b
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_20() { let original = r##"* First [^1]: test * Second [^1] test > first > [^2]: test > Second [^2] test First | Second -----------|---------- first | second [^3]: test | test [^3] | First | Second | |------------|-----------| | first | second | | [^4]: test | test [^4] | > [^5]: * test [^5] "##; let expected = r##"
  • First
    1

    test

  • Second 1 test

first

2

test Second 2 test

FirstSecond
firstsecond
3

test | test 3

FirstSecond
firstsecond
[^4]: testtest [^4]
4
  • test 4
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_21() { let original = r##"Test [^] link [^]: https://rust-lang.org "##; let expected = r##"

Test ^ link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_22() { let original = r##"[^foo\ bar]: not a footnote definition [baz\ quux]: https://rust-lang.org [first second]: https://rust-lang.org [^third fourth]: not a footnote definition [baz\ quux] [^foo\ bar] [first second] [^third fourth] "##; let expected = r##"

[^foo
bar]: not a footnote definition

[^third fourth]: not a footnote definition

baz
quux
[^foo
bar] first second [^third fourth]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_23() { let original = r##"[^foo ]: https://rust-lang.org [^foo ] "##; let expected = r##"

^foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_24() { let original = r##"footnote [^baz] footnote [^quux] [^quux]: x [^baz]: x "##; let expected = r##"

footnote 1 footnote [^quux]

[^quux]: x
1

x

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_25() { let original = r##"Lorem ipsum.[^a][^b] [^a]: Foo [^b]: Bar "##; let expected = r##"

Lorem ipsum.12

1

Foo

2

Bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn footnotes_test_26() { let original = r##"Lorem ipsum.[^a] [^b] [^a]: Foo [^b]: Bar "##; let expected = r##"

Lorem ipsum.1 2

1

Foo

2

Bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/gfm_strikethrough.rs000064400000000000000000000015541046102023000212450ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn gfm_strikethrough_test_1() { let original = r##"~~Hi~~ Hello, ~there~ world! "##; let expected = r##"

Hi Hello, there world!

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_strikethrough_test_2() { let original = r##"This ~~has a new paragraph~~. "##; let expected = r##"

This ~~has a

new paragraph~~.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_strikethrough_test_3() { let original = r##"This will ~~~not~~~ strike. "##; let expected = r##"

This will ~~~not~~~ strike.

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/gfm_table.rs000064400000000000000000000064211046102023000174300ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn gfm_table_test_1() { let original = r##"| foo | bar | | --- | --- | | baz | bim | "##; let expected = r##"
foo bar
baz bim
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_2() { let original = r##"| abc | defghi | :-: | -----------: bar | baz "##; let expected = r##"
abc defghi
bar baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_3() { let original = r##"| f\|oo | | ------ | | b `\|` az | | b **\|** im | "##; let expected = r##"
f|oo
b | az
b | im
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_4() { let original = r##"| abc | def | | --- | --- | | bar | baz | > bar "##; let expected = r##"
abc def
bar baz

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_5() { let original = r##"| abc | def | | --- | --- | | bar | baz | bar bar "##; let expected = r##"
abc def
bar baz
bar

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_6() { let original = r##"| abc | def | | --- | | bar | "##; let expected = r##"

| abc | def | | --- | | bar |

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_7() { let original = r##"| abc | def | | --- | --- | | bar | | bar | baz | boo | "##; let expected = r##"
abc def
bar
bar baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_8() { let original = r##"| abc | def | | --- | --- | "##; let expected = r##"
abc def
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_table_test_9() { let original = r##"Hello World | abc | def | | --- | --- | | bar | baz | "##; let expected = r##"

Hello World

abc def
bar baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/gfm_tasklist.rs000064400000000000000000000016031046102023000201740ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn gfm_tasklist_test_1() { let original = r##"- [ ] foo - [x] bar "##; let expected = r##"
  • foo
  • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn gfm_tasklist_test_2() { let original = r##"- [x] foo - [ ] bar - [x] baz - [ ] bim "##; let expected = r##"
  • foo
    • bar
    • baz
  • bim
"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/heading_attrs.rs000064400000000000000000000313371046102023000203300ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn heading_attrs_test_1() { let original = r##"with the ID {#myh1} =================== with a class {.myclass} ------------ with a custom attribute {myattr=myvalue} ======================================== multiple! {.myclass1 myattr #myh3 otherattr=value .myclass2} -- "##; let expected = r##"

with the ID

with a class

with a custom attribute

multiple!

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_2() { let original = r##"# with the ID {#myh1} ## with a class {.myclass} #### with a custom attribute {myattr=myvalue} ### multiple! {.myclass1 myattr #myh3 otherattr=value .myclass2} "##; let expected = r##"

with the ID

with a class

with a custom attribute

multiple!

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_3() { let original = r##"# H1 # {#id1} ## H2 ## with ## multiple ## hashes ## {#id2} ### with trailing hash # ### {#id3} #### non-attribute-block {#id4} #### "##; let expected = r##"

H1

H2 ## with ## multiple ## hashes

with trailing hash #

non-attribute-block {#id4}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_4() { let original = r##"# spaces {#myid1} ## tabs {#myid2} "##; let expected = r##"

spaces

tabs

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_5() { let original = r##"# H1 \ nextline "##; let expected = r##"

H1 \

nextline

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_6() { let original = r##"# H1 \ {#myid} ## H2 \ nextline {.class} ### H3 [link ](https://example.com/) {#myid3} "##; let expected = r##"

H1 \

{#myid}

H2 \

nextline {.class}

H3 [link

](https://example.com/) {#myid3}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_7() { let original = r##"H1 cont {#myid} == "##; let expected = r##"

H1 cont

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_8() { let original = r##"H1 { .class1 .class2 } == "##; let expected = r##"

H1 { .class1 .class2 }

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_9() { let original = r##"# without space, not recommended{#id1} ## recommended style with spaces {#id2} "##; let expected = r##"

without space, not recommended

recommended style with spaces

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_10() { let original = r##"# H1 { #id1 } ## H2 {.myclass #id2 } ### H3 { .myclass} "##; let expected = r##"

H1

H2

H3

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_11() { let original = r##"# H1 {#id1.class1.class2 .class3} ## H2 {.class1#id2.class2} "##; let expected = r##"

H1

H2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_12() { let original = r##"# H1 { #id1 ## H2 {#id2 "##; let expected = r##"

H1 { #id1

H2 {#id2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_13() { let original = r##"# H1 #id1 } ## H2 #id2} "##; let expected = r##"

H1 #id1 }

H2 #id2}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_14() { let original = r##"# H1 { #id1 } foo ## H2 {#id2} "##; let expected = r##"

H1 { #id1 } foo

H2 {#id2}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_15() { let original = r##"# *H1* { #id1 } ## **H2** {#id2} ### _H3_ {#id3} #### ~~H4~~ {#id4} ##### [text](uri) {#id5} "##; let expected = r##"

H1

H2

H3

H4

text
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_16() { let original = r##"# H1 {#first #second #last} "##; let expected = r##"

H1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_17() { let original = r##"# H1 {.z .a .zz} "##; let expected = r##"

H1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_18() { let original = r##"# H1 {.a .a .a} "##; let expected = r##"

H1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_19() { let original = r##"# H1 {.myclass #myid} ## H2 {.z #m .a} "##; let expected = r##"

H1

H2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_20() { let original = r##"# H1 {foo} ## H2 {#myid unknown this#is.ignored attr=value .myclass} "##; let expected = r##"

H1

H2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_21() { let original = r##"# Header # {myattr=value other_attr} "##; let expected = r##"

Header

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_22() { let original = r##"#### Header {#id myattr= .class1 other_attr=false} "##; let expected = r##"

Header

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_23() { let original = r##"# H1 {.foo{unknown} ## H2 {.foo{.bar} "##; let expected = r##"

H1 {.foo

H2 {.foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_24() { let original = r##"# H1 {.foo}bar} "##; let expected = r##"

H1 {.foo}bar}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_25() { let original = r##"# H1 {foo} "##; let expected = r##"

H1 {foo}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_26() { let original = r##"# H1 {.foo\} "##; let expected = r##"

H1 {.foo}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_27() { let original = r##"H1 {.foo .bar} == "##; let expected = r##"

H1 {.foo .bar}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_28() { let original = r##"H1 {} {} ===== ## H2 {} {} "##; let expected = r##"

H1 {}

H2 {}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_29() { let original = r##"## H2 {} ## "##; let expected = r##"

H2 {}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_30() { let original = r##"# H1 {\} ## this is also ok \{\} newline can be used for setext heading { } -- "##; let expected = r##"

H1 {}

this is also ok {}

newline can be used for setext heading { }

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_31() { let original = r##"# H1 \{.foo} ## H2 \\{.bar} ### stray backslash at the end is preserved \ "##; let expected = r##"

H1 \

H2 \

stray backslash at the end is preserved \

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_32() { let original = r##"H1 \{.foo} == H2 \\{.bar} -- stray backslash at the end is preserved \ -- "##; let expected = r##"

H1 \

H2 \

stray backslash at the end is preserved \

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_33() { let original = r##"# H1 {#`code`} ## H2 {#foo__bar__baz} ### H3 {#foo**bar**baz} "##; let expected = r##"

H1

H2

H3

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_34() { let original = r##"H1 {#`code`} == H2-1 {#foo__bar__baz} ---- H2-2 {#foo**bar**baz} -- "##; let expected = r##"

H1

H2-1

H2-2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_35() { let original = r##"# H1 {.foo#bar} ## H2 {#foo.bar} ### H3 {.a"b'c&d} "##; let expected = r##"

H1

H2

H3

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_36() { let original = r##"# H1 {#} ## H2 {.} "##; let expected = r##"

H1

H2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_37() { let original = r##"# H1 {#foo #} # H1 {.foo . . .bar} "##; let expected = r##"

H1

H1

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_38() { let original = r##"# {} ## {} ### {\} #### {} {} #{} "##; let expected = r##"

{}

{}

#{}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_39() { let original = r##"{} == \{} -- \ -- {\} == {}{} -- "##; let expected = r##"

\

\

{}

{}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_40() { let original = r##"# horizontal tab # horizontal tab {#ht} ## form feed ## form feed {#ff} ### vertical tab ### vertical tab {#vt} "##; let expected = r##"

horizontal tab

horizontal tab

form feed

form feed

vertical tab

vertical tab

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_41() { let original = r##"# horizontal tab (U+000A) {#ht .myclass} ## form feed (U+000C) {#ff .myclass} # vertical tab (U+000B) {#vt .myclass} "##; let expected = r##"

horizontal tab (U+000A)

form feed (U+000C)

vertical tab (U+000B)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn heading_attrs_test_42() { let original = r##"# EN SPACE (U+2002) {#en-space .myclass} ## IDEOGRAPHIC SPACE (U+3000) {#ideographic-space .myclass} "##; let expected = r##"

EN SPACE (U+2002)

IDEOGRAPHIC SPACE (U+3000)

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/math.rs000064400000000000000000000613611046102023000164450ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn math_test_1() { let original = r##"This sentence uses `$` delimiters to show math inline: $\sqrt{3x-1}+(1+x)^2$ $\sum_{k=1}^n a_k b_k$: Mathematical expression at head of line `\` may follow just after the first `$`: $\{1, 2, 3\}$ "##; let expected = r##"

This sentence uses $ delimiters to show math inline: \sqrt{3x-1}+(1+x)^2 \sum_{k=1}^n a_k b_k: Mathematical expression at head of line

\ may follow just after the first $: \{1, 2, 3\}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_2() { let original = r##"**The Cauchy-Schwarz Inequality** $$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$ "##; let expected = r##"

The Cauchy-Schwarz Inequality

\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_3() { let original = r##"Oops empty $$ expression. $$$$ "##; let expected = r##"

Oops empty $$ expression.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_4() { let original = r##"$x$$$$$$$y$$ $x$$$$$$y$$ $$x$$$$$$y$$ "##; let expected = r##"

xy

xy$

xy$$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_5() { let original = r##"$ac$ $${a*b*c} _c_ d$$ $not `code`$ $![not an](/image)$ $$ $α$ "##; let expected = r##"

a<b>c</b>

{a*b*c} _c_ d

not `code`

![not an](/image)

<https://not.a.link/>

&alpha;

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_6() { let original = r##"Hello $world. Dollar at end of line$ "##; let expected = r##"

Hello $world.

Dollar at end of line$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_7() { let original = r##"$5x + 2 = 17$ $$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$ "##; let expected = r##"

5x + 2 = 17

\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_8() { let original = r##"$not a\ hard break either$ "##; let expected = r##"

not a\ hard break either

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_9() { let original = r##"$\$$ $$y = \$ x$$ "##; let expected = r##"

\$

y = \$ x

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_10() { let original = r##"$x $ x$ $$ $ $$ "##; let expected = r##"

$x $ x$

$$ $ $$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_11() { let original = r##"alpha$$beta$gamma$$delta "##; let expected = r##"

alpha$betagamma$$delta

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_12() { let original = r##"these are not math texts: $ y=x$, $y=x $, $ y=x$ and $y=x $ >The start of a line counts as whitespace $2 + >$ While displays can start with whitespace, {${ they should not allow inlines to do that $$2 + $*$ "##; let expected = r##"

these are not math texts: $ y=x$, $y=x $, $ y=x$ and $y=x $

The start of a line counts as whitespace $2 + $

While displays can start with whitespace, {${ they should not allow inlines to do that $$2 + *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_13() { let original = r##"these are math texts: foo$y=x$bar and $y=x$bar and foo$y=x$ bar "##; let expected = r##"

these are math texts: fooy=xbar and y=xbar and fooy=x bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_14() { let original = r##"math texts: $x=y$! and $x=y$? and $x=y$: and $x=y$. and $x=y$" also math texts: !$x=y$! and ?$x=y$? and :$x=y$: and .$x=y$. and "$x=y$" braces: ($x=y$) [$x=y$] {$x=y$} "##; let expected = r##"

math texts: x=y! and x=y? and x=y: and x=y. and x=y"

also math texts: !x=y! and ?x=y? and :x=y: and .x=y. and "x=y"

braces: (x=y) [x=y] {x=y}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_15() { let original = r##"$x=y$ "##; let expected = r##"

x=y

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_16() { let original = r##"$a$$b$ $a$$$b$$ $$a$$$b$ $$a$$$$b$$ "##; let expected = r##"

ab

ab

ab

ab

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_17() { let original = r##"$Inline `first$ then` code `Code $first` then$ inline $$ Display `first $$ then` code `Code $$ first` then $$ display "##; let expected = r##"

Inline `first then` code

Code $first then$ inline

Display `first then` code

Code $$ first then $$ display

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_18() { let original = r##"$x + y - z$ $x + y - z$ $$ x + y > z $$ "##; let expected = r##"

x + y - z

$x + y

  • z$

$$ x + y

z $$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_19() { let original = r##"$not math$ $$ not math $$ "##; let expected = r##"

$not

math$

$$ not

math $$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_20() { let original = r##"- $not - * math$ "##; let expected = r##"
  • $not
    math$
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_21() { let original = r##"This is display math: $$ \text{Hello $x^2$} $$ And this is inline math: $\text{Hello $x$ there!}$ "##; let expected = r##"

This is display math: \text{Hello $x^2$} And this is inline math: \text{Hello $x$ there!}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_22() { let original = r##"This is not valid math: $}{$ Neither is this: { $}{$ } This is: $\}\{$ This is: $\}$ Math environment contains 2+2: $}$2+2$ Math environment contains y: $x {$ $ } $y$ "##; let expected = r##"

This is not valid math: $}{$

Neither is this: { $}{$ }

This is: \}\{

This is: \}

Math environment contains 2+2: $}2+2

Math environment contains y: $x {$ $ } y

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_23() { let original = r##"This is not display math. It is inline math: $$\text{first $$ second}$ $$$\text{first $$ second}$ This is display math: $$\text{first $$ second}$$ $$$\text{first $$ second}$$ This is also display math, but (counterintuitively) it's allowed to be empty and expected to be as short as possible: $$$$\text{first $$ second}$$ "##; let expected = r##"

This is not display math. It is inline math:

$\text{first $$ second}

$$\text{first $$ second}

This is display math:

\text{first $$ second}

$\text{first $$ second}

This is also display math, but (counterintuitively) it's allowed to be empty and expected to be as short as possible:

\text{first $$ second}$$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_24() { let original = r##"$\text{\$}$ $$x$x$$ ${$^$$ $}$$$$ $}$] $$ "##; let expected = r##"

\text{\$}

$xx$$

${^$

$}

$}$] $$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_25() { let original = r##"$x$ $`y`$ "##; let expected = r##"

x `y`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_26() { let original = r##"- $a$ ```math a ``` $$ a $$ - ```math b ``` $$ b $$ "##; let expected = r##"
  • a

    a
    

    a

  • b
    

    b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_27() { let original = r##"- ![node logo](https://nodejs.org/static/images/logo.svg) - $x$ "##; let expected = r##"
  • node logo
  • x
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_28() { let original = r##"
$A = 5$ $$ A = 5 $$
"##; let expected = r##"

A = 5

A = 5

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_29() { let original = r##"$aa<b

a<b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_30() { let original = r##"[^a] [^a]: Lorem $a$ "##; let expected = r##"

1

1

Lorem a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_31() { let original = r##"[$a$](x) "##; let expected = r##"

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_32() { let original = r##"a$x$ -$x$ 1$x$ "##; let expected = r##"

ax

-x

1x

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_33() { let original = r##"_$a$ equals $b$_ _$a$ equals $b$_ **$a$ equals $b$** "##; let expected = r##"

a equals b

a equals b

a equals b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_34() { let original = r##"$$ a $$ - $$ \text{$b$} $$ "##; let expected = r##"

a

  • \text{$b$}
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_35() { let original = r##"$\{a\,b\}$ "##; let expected = r##"

\{a\,b\}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_36() { let original = r##"$a c$ $[(a+b)c](d+e)$ ${a}_b c_{d}$ "##; let expected = r##"

a <b > c

[(a+b)c](d+e)

{a}_b c_{d}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_37() { let original = r##"When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are $$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$ "##; let expected = r##"

When a \ne 0, there are two solutions to (ax^2 + bx + c = 0) and they are x = {-b \pm \sqrt{b^2-4ac} \over 2a}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_38() { let original = r##"$x = \$$ "##; let expected = r##"

x = \$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_39() { let original = r##"_Equation $\Omega(69)$ in italic text_ "##; let expected = r##"

Equation \Omega(69) in italic text

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_40() { let original = r##"$\pi$ '$\pi$ "$\pi$ ($\pi$ [$\pi$ {$\pi$ /$\pi$ "##; let expected = r##"

\pi '\pi "\pi (\pi [\pi {\pi /\pi

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_41() { let original = r##"| first $|$ second | |--------|---------| | a ${ | }$ b | "##; let expected = r##"
first $$ second
a ${}$ b
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_42() { let original = r##"| first $\|$ second | |-------------------| | a ${ \| }$ b | "##; let expected = r##"
first | second
a { | } b
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_43() { let original = r##"| Description | Test case | |-------------|-----------| | Single | $\$ | | Double | $\\$ | | Basic test | $\|$ | | Basic test 2| $\|\|\$ | | Basic test 3| $x\|y\|z\$| | Not pipe | $\.$ | | Combo | $\.\|$ | | Combo 2 | $\.\|\$ | | Extra | $\\\.$ | | Wait, what? | $\\|$ | | Wait, what? | $\\\|$ | | Wait, what? | $\\\\|$ | | Wait, what? | $\\\\\|$ | "##; let expected = r##"
DescriptionTest case
Single$$
Double\\
Basic test|
Basic test 2$||$
Basic test 3$x|y|z$
Not pipe\.
Combo\.|
Combo 2$.|$
Extra\\\.
Wait, what?\|
Wait, what?\\|
Wait, what?\\\|
Wait, what?\\\\|
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_44() { let original = r##"This is not an inline math environment: $}{$ But, because it's nested too deeply, this is parsed as an inline math environment: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ improperly $}{$ nested }}}}}}}}}}}}}}}}}}}}}}}}}}}}}} But this still isn't, because the braces are still counted: $}{$ "##; let expected = r##"

This is not an inline math environment: $}{$ But, because it's nested too deeply, this is parsed as an inline math environment: {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ improperly }{ nested }}}}}}}}}}}}}}}}}}}}}}}}}}}}}} But this still isn't, because the braces are still counted: $}{$

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_45() { let original = r##"This is also deeply nested, but, unlike the first example, they don't have an equal number of close braces and open braces, so aren't detected as math. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ improperly $}$ nested ${$ example }}}}}}}}}}}}}}}}}}}}}}}}}}}}}} This, however, is detected ${}$ ${{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ another improperly nested example }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}$ "##; let expected = r##"

This is also deeply nested, but, unlike the first example, they don't have an equal number of close braces and open braces, so aren't detected as math. {{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ improperly $}$ nested ${$ example }}}}}}}}}}}}}}}}}}}}}}}}}}}}}} This, however, is detected {}

{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ another improperly nested example }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_46() { let original = r##"${}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 20 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 40 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 60 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 80 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 100 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 120 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 140 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 160 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 180 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 200 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 220 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 240 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{$ 255 brace pairs and one unclosed brace "##; let expected = r##"

{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 20 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 40 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 60 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 80 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 100 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 120 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 140 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 160 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 180 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 200 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 220 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{} 240 brace pairs {}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{ 255 brace pairs and one unclosed brace

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn math_test_47() { let original = r##"${{{{{{{{{{{{{{{{{{{{ 20 open braces {{{{{{{{{{{{{{{{{{{{ 40 open braces {{{{{{{{{{{{{{{{{{{{ 60 open braces {{{{{{{{{{{{{{{{{{{{ 80 open braces {{{{{{{{{{{{{{{{{{{{ 100 open braces {{{{{{{{{{{{{{{{{{{{ 110 open braces {{{{{{{{{{{{{{{{{{{{ 120 open braces {{{{{{{{{{{{{{{{{{{{ 140 open braces {{{{{{{{{{{{{{{{{{{{ 160 open braces {{{{{{{{{{{{{{{{{{{{ 180 open braces {{{{{{{{{{{{{{{{{{{{ 200 open braces {{{{{{{{{{{{{{{{{{{{ 220 open braces {{{{{{{{{{{{{{{{{{{{ 240 open braces {{{{{{{{{{{{{{{ 255 open braces }}}}}}}}}}}}}}}}}}}} 20 close braces }}}}}}}}}}}}}}}}}}}} 40 close braces }}}}}}}}}}}}}}}}}}}} 60 close braces }}}}}}}}}}}}}}}}}}}} 80 close braces }}}}}}}}}}}}}}}}}}}} 100 close braces }}}}}}}}}}}}}}}}}}}} 120 close braces }}}}}}}}}}}}}}}}}}}} 140 close braces }}}}}}}}}}}}}}}}}}}} 160 close braces }}}}}}}}}}}}}}}}}}}} 180 close braces }}}}}}}}}}}}}}}}}}}} 200 close braces }}}}}}}}}}}}}}}}}}}} 220 close braces }}}}}}}}}}}}}}}}}}}} 240 close braces }}}}}}}}}}}}}}}{$ 255 close braces and one open brace "##; let expected = r##"

${{{{{{{{{{{{{{{{{{{{ 20 open braces {{{{{{{{{{{{{{{{{{{{ 40 open braces {{{{{{{{{{{{{{{{{{{{ 60 open braces {{{{{{{{{{{{{{{{{{{{ 80 open braces {{{{{{{{{{{{{{{{{{{{ 100 open braces {{{{{{{{{{{{{{{{{{{{ 110 open braces {{{{{{{{{{{{{{{{{{{{ 120 open braces {{{{{{{{{{{{{{{{{{{{ 140 open braces {{{{{{{{{{{{{{{{{{{{ 160 open braces {{{{{{{{{{{{{{{{{{{{ 180 open braces {{{{{{{{{{{{{{{{{{{{ 200 open braces {{{{{{{{{{{{{{{{{{{{ 220 open braces {{{{{{{{{{{{{{{{{{{{ 240 open braces {{{{{{{{{{{{{{{ 255 open braces }}}}}}}}}}}}}}}}}}}} 20 close braces }}}}}}}}}}}}}}}}}}}} 40 close braces }}}}}}}}}}}}}}}}}}}} 60 close braces }}}}}}}}}}}}}}}}}}}} 80 close braces }}}}}}}}}}}}}}}}}}}} 100 close braces }}}}}}}}}}}}}}}}}}}} 120 close braces }}}}}}}}}}}}}}}}}}}} 140 close braces }}}}}}}}}}}}}}}}}}}} 160 close braces }}}}}}}}}}}}}}}}}}}} 180 close braces }}}}}}}}}}}}}}}}}}}} 200 close braces }}}}}}}}}}}}}}}}}}}} 220 close braces }}}}}}}}}}}}}}}}}}}} 240 close braces }}}}}}}}}}}}}}}{$ 255 close braces and one open brace

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/metadata_blocks.rs000064400000000000000000000060571046102023000206320ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn metadata_blocks_test_1() { let original = r##"--- title: example another_field: 0 --- "##; let expected = r##""##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_2() { let original = r##"--- title: example another_field: 0 "##; let expected = r##"

title: example another_field: 0

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_3() { let original = r##"--- --- "##; let expected = r##"

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_4() { let original = r##"--- title: example another_field: 0 --- "##; let expected = r##"

title: example another_field: 0

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_5() { let original = r##"My paragraph here. --- title: example another_field: 0 --- "##; let expected = r##"

My paragraph here.

title: example another_field: 0

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_6() { let original = r##"My paragraph here. --- title: example another_field: 0 --- "##; let expected = r##"

My paragraph here.

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_7() { let original = r##"--- title: example another_field: 0 --- --- - title: example another_field: 0 --- "##; let expected = r##"

title: example another_field: 0

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_8() { let original = r##"--- title: example another_field: 0 --- --- title: example another_field: 0 ---a "##; let expected = r##"

title: example another_field: 0 ---a

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_9() { let original = r##"--- title: example another_field: 0 ... "##; let expected = r##""##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_10() { let original = r##"+++ title: example another_field: 0 +++ "##; let expected = r##""##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_11() { let original = r##" --- Things --- "##; let expected = r##"
---
Things
---
"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn metadata_blocks_test_12() { let original = r##"--- - Item 1 - Item 2 --- "##; let expected = r##""##; test_markdown_html(original, expected, false, true, false, false, false); } pulldown-cmark-0.13.0/tests/suite/mod.rs000064400000000000000000000006341046102023000162670ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually pub use super::test_markdown_html; mod blockquotes_tags; mod definition_lists; mod footnotes; mod gfm_strikethrough; mod gfm_table; mod gfm_tasklist; mod heading_attrs; mod math; mod metadata_blocks; mod old_footnotes; mod regression; mod smart_punct; mod spec; mod strikethrough; mod super_sub; mod table; mod wikilinks; pulldown-cmark-0.13.0/tests/suite/old_footnotes.rs000064400000000000000000000250351046102023000203700ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn old_footnotes_test_1() { let original = r##"Lorem ipsum.[^a] [^a]: Cool. "##; let expected = r##"

Lorem ipsum.1

1

Cool.

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_2() { let original = r##"> This is the song that never ends.\ > Yes it goes on and on my friends.[^lambchops] > > [^lambchops]: "##; let expected = r##"

This is the song that never ends.
Yes it goes on and on my friends.1

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_3() { let original = r##"Songs that simply loop are a popular way to annoy people. [^examples] [^examples]: * [The song that never ends](https://www.youtube.com/watch?v=0U2zJOryHKQ) * [I know a song that gets on everybody's nerves](https://www.youtube.com/watch?v=TehWI09qxls) * [Ninety-nine bottles of beer on the wall](https://www.youtube.com/watch?v=qVjCag8XoHQ) "##; let expected = r##"

Songs that simply loop are a popular way to annoy people. 1

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_4() { let original = r##"[^lorem]: If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research. I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp. "##; let expected = r##"
1

If heaven ever wishes to grant me a boon, it will be a total effacing of the results of a mere chance which fixed my eye on a certain stray piece of shelf-paper. It was nothing on which I would naturally have stumbled in the course of my daily round, for it was an old number of an Australian journal, the Sydney Bulletin for April 18, 1925. It had escaped even the cutting bureau which had at the time of its issuance been avidly collecting material for my uncle's research.

I had largely given over my inquiries into what Professor Angell called the "Cthulhu Cult", and was visiting a learned friend in Paterson, New Jersey; the curator of a local museum and a mineralogist of note. Examining one day the reserve specimens roughly set on the storage shelves in a rear room of the museum, my eye was caught by an odd picture in one of the old papers spread beneath the stones. It was the Sydney Bulletin I have mentioned, for my friend had wide affiliations in all conceivable foreign parts; and the picture was a half-tone cut of a hideous stone image almost identical with that which Legrasse had found in the swamp.

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_5() { let original = r##"[^ipsum]: How much wood would a woodchuck chuck. If a woodchuck could chuck wood. # Forms of entertainment that aren't childish "##; let expected = r##"
1

How much wood would a woodchuck chuck.

If a woodchuck could chuck wood.

Forms of entertainment that aren't childish

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_6() { let original = r##"> He's also really stupid. [^why] > > [^why]: Because your mamma! As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet. "##; let expected = r##"

He's also really stupid. 1

1

Because your mamma!

As such, we can guarantee that the non-childish forms of entertainment are probably more entertaining to adults, since, having had a whole childhood doing the childish ones, the non-childish ones are merely the ones that haven't gotten boring yet.

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_7() { let original = r##"Nested footnotes are considered poor style. [^a] [^xkcd] [^a]: This does not mean that footnotes cannot reference each other. [^b] [^b]: This means that a footnote definition cannot be directly inside another footnote definition. > This means that a footnote cannot be directly inside another footnote's body. [^e] > > [^e]: They can, however, be inside anything else. [^xkcd]: [The other kind of nested footnote is, however, considered poor style.](https://xkcd.com/1208/) "##; let expected = r##"

Nested footnotes are considered poor style. 1 2

1

This does not mean that footnotes cannot reference each other. 3

3

This means that a footnote definition cannot be directly inside another footnote definition.

This means that a footnote cannot be directly inside another footnote's body. 4

4

They can, however, be inside anything else.

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_8() { let original = r##"[^Doh] Ray Me Fa So La Te Do! [^1] [^Doh]: I know. Wrong Doe. And it will render right. [^1]: Common for people practicing music. "##; let expected = r##"

1 Ray Me Fa So La Te Do! 2

1

I know. Wrong Doe. And it will render right.

2

Common for people practicing music.

"##; test_markdown_html(original, expected, false, false, true, false, false); } #[test] fn old_footnotes_test_9() { let original = r##"[Reference to footnotes A[^1], B[^2] and C[^3]. [^1]: Footnote A. [^2]: Footnote B. [^3]: Footnote C. "##; let expected = r##"

[Reference to footnotes A1, B2 and C3.

1

Footnote A.

2

Footnote B.

3

Footnote C.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn old_footnotes_test_10() { let original = r##"Lorem ipsum.[^a][^b] [^a]: Foo [^b]: Bar "##; let expected = r##"

Lorem ipsum.12

1

Foo

2

Bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn old_footnotes_test_11() { let original = r##"Lorem ipsum.[^a] [^b] [^a]: Foo [^b]: Bar "##; let expected = r##"

Lorem ipsum.1 2

1

Foo

2

Bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/regression.rs000064400000000000000000001757731046102023000177110ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn regression_test_1() { let original = r##"
Testing 1..2..3.. This is a test of the details element.
"##; let expected = r##"
Testing 1..2..3..

This is a test of the details element.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_2() { let original = r##"see the [many] [articles] [on] [QuickCheck]. [many]: https://medium.com/@jlouis666/quickcheck-advice-c357efb4e7e6 [articles]: http://www.quviq.com/products/erlang-quickcheck/ [on]: https://wiki.haskell.org/Introduction_to_QuickCheck1 [QuickCheck]: https://hackage.haskell.org/package/QuickCheck "##; let expected = r##"

see the many articles on QuickCheck.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_3() { let original = r##"[![debug-stub-derive on crates.io][cratesio-image]][cratesio] [![debug-stub-derive on docs.rs][docsrs-image]][docsrs] [cratesio-image]: https://img.shields.io/crates/v/debug_stub_derive.svg [cratesio]: https://crates.io/crates/debug_stub_derive [docsrs-image]: https://docs.rs/debug_stub_derive/badge.svg?version=0.3.0 [docsrs]: https://docs.rs/debug_stub_derive/0.3.0/ "##; let expected = r##"

debug-stub-derive on crates.io debug-stub-derive on docs.rs

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_4() { let original = r##"| Title A | Title B | | --------- | --------- | | Content | Content | | Title A | Title B | Title C | Title D | | --------- | --------- | --------- | ---------:| | Content | Content | Conent | Content | "##; let expected = r##"
Title ATitle B
ContentContent
Title ATitle BTitle CTitle D
ContentContentConentContent
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_5() { let original = r##"foo§__(bar)__ "##; let expected = r##"

foo§(bar)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_6() { let original = r##" hello "##; let expected = r##"

https://example.com hello

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_7() { let original = r##"[foo][bar] [bar]: a "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_8() { let original = r##" - **foo** (u8, u8) make something - **bar** (u16, u16) make something "##; let expected = r##"
  • foo (u8, u8)

    make something

  • bar (u16, u16)

    make something

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_9() { let original = r##"[` i8 `]( ../../../std/primitive.i8.html ) "##; let expected = r##"

i8

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_10() { let original = r##"[a] [a]: /url (title\\*) "##; let expected = r##"

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_11() { let original = r##"[a] [a]: /url (title\)) "##; let expected = r##"

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_12() { let original = r##"[a] [a]: /url (title)) "##; let expected = r##"

[a]

[a]: /url (title))

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_13() { let original = r##"a "##; let expected = r##"

a <?php this is not a valid processing tag

b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_14() { let original = r##"[a]: u\ foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_15() { let original = r##"\`foo` "##; let expected = r##"

`foo`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_16() { let original = r##"foo\\ bar "##; let expected = r##"

foo\ bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_17() { let original = r##"1\. foo 1\) bar "##; let expected = r##"

1. foo

1) bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_18() { let original = r##"1... 1.2.3. 1 2 3 . 1.|2.-3. 1)2)3) "##; let expected = r##"

1...

1.2.3.

1 2 3 .

1.|2.-3.

1)2)3)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_19() { let original = r##"[](<<>) "##; let expected = r##"

[](<<>)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_20() { let original = r##"\``foo``bar` "##; let expected = r##"

`foo``bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_21() { let original = r##"\\`foo` "##; let expected = r##"

\foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_22() { let original = r##"[\\]: x YOLO "##; let expected = r##"

YOLO

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_23() { let original = r##"lorem ipsum A | B ---|--- foo | bar "##; let expected = r##"

lorem ipsum A | B ---|--- foo | bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_24() { let original = r##"foo|bar ---|--- foo|bar "##; let expected = r##"
foobar
foobar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_25() { let original = r##"foo|bar\\ ---|--- foo|bar "##; let expected = r##"
foobar\
foobar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_26() { let original = r##"[](url) "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_27() { let original = r##"[bar](url) "##; let expected = r##"

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_28() { let original = r##"![](http://example.com/logo.png) "##; let expected = r##"

http://example.com

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_29() { let original = r##"[ ](url) "##; let expected = r##"

http://one http://two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_30() { let original = r##"Markdown | Less | Pretty --- | --- | --- some text "##; let expected = r##"
MarkdownLessPretty

some text

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_31() { let original = r##"1. > foo 2. > "##; let expected = r##"
  1. foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_32() { let original = r##"[ x ]: f "##; let expected = r##"

[ x

]: f

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_33() { let original = r##"[foo]: "##; let expected = r##"

[foo]:

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_34() { let original = r##"> [foo > bar]: /url > > [foo bar] "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_35() { let original = r##"> foo | bar > --- | --- yolo | swag "##; let expected = r##"
foobar

yolo | swag

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_36() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_37() { let original = r##" "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_38() { let original = r##"~~*_**__ __a__ "##; let expected = r##"

~~*_**__

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_39() { let original = r##"> ` > ` "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_40() { let original = r##"`\|` "##; let expected = r##"

\|

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_41() { let original = r##"Paragraph 1 Paragraph 2 "##; let expected = r##"

Paragraph 1

Paragraph 2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_42() { let original = r##"\[[link text](https://www.google.com/)\] "##; let expected = r##"

[link text]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_43() { let original = r##"foo | bar --- | --- [a](< | url>) "##; let expected = r##"
foobar
[a](<url>)
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_44() { let original = r##"[a](url " - - - ") "##; let expected = r##"

[a](url "


")

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_45() { let original = r##"[a](url ) "##; let expected = r##"

[a](url

)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_46() { let original = r##"[a](b " ") "##; let expected = r##"

[a](b "

")

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_47() { let original = r##" "##; let expected = r##"

<http:// >

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_48() { let original = r##" "##; let expected = r##"

<http://>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_49() { let original = r##"foo | bar --- | --- foobar <http://baz "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_50() { let original = r##"foo | bar --- | --- "##; let expected = r##"
foobar
<http://>
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_51() { let original = r##"\*hi\_ "##; let expected = r##"

*hi_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_52() { let original = r##"email: \_ "##; let expected = r##"

email: john@example.com_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_53() { let original = r##"> [link](/url 'foo > bar') "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_54() { let original = r##"> [foo > bar]: /url > > [foo bar] "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_55() { let original = r##"> [foo bar]: /url > > [foo > bar] "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_56() { let original = r##"> - [a > b c]: /foo [a b c] "##; let expected = r##"

a b c

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_57() { let original = r##"[a > b]: /foo [a b] [a > b] "##; let expected = r##"

[a

b]: /foo

[a b] [a > b]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_58() { let original = r##"[`cargo package`] [`cargo package`]: https://example.com "##; let expected = r##"

cargo package

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_59() { let original = r##"> [`cargo > package`] [`cargo package`]: https://example.com "##; let expected = r##"

cargo package

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_60() { let original = r##"> `cargo > package` "##; let expected = r##"

cargo package

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_61() { let original = r##"> Note: Though you should not rely on this, all pointers to title="Dynamically Sized Types">DSTs are currently twice the size of > the size of `usize` and have the same alignment. "##; let expected = r##"

Note: Though you should not rely on this, all pointers to DSTs are currently twice the size of the size of usize and have the same alignment.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_62() { let original = r##"Lorem ipsum.[^a] An unordered list before the footnotes: * Ipsum * Lorem [^a]: Cool. "##; let expected = r##"

Lorem ipsum.1

An unordered list before the footnotes:

  • Ipsum
  • Lorem
1

Cool.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_63() { let original = r##"[][a] [a]: b # assimp-rs [![][crates-badge]][crates] [crates]: https://crates.io/crates/assimp [crates-badge]: http://meritbadge.herokuapp.com/assimp "##; let expected = r##"

assimp-rs

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_64() { let original = r##"* A list. * A sublist. * Another sublist. * A list. * A sublist. * Another sublist. "##; let expected = r##"
  • A list.

    • A sublist.

    • Another sublist.

  • A list.

    • A sublist.

    • Another sublist.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_65() { let original = r##"<foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_66() { let original = r##"> > a > ="yo > > lo"> "##; let expected = r##"

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_67() { let original = r##" - the whitespace here are tabs "##; let expected = r##"
-	the whitespace here are tabs
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_68() { let original = r##"1. a 1. a a 2. a "##; let expected = r##"
  1. a
    1. a

a 2. a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_69() { let original = r##"1. a 2. a 2. a "##; let expected = r##"
  1. a
  2. a 2. a
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_70() { let original = r##"* [ ] foo * [ ] bar baz "##; let expected = r##"
  • foo

  • bar

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_71() { let original = r##"* foo + bar + baz "##; let expected = r##"
  • foo
    • bar
    • baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_72() { let original = r##"[`]: xx: [`]`] "##; let expected = r##"

[]]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_73() { let original = r##"~~foo~~bar "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_74() { let original = r##"foo~~bar~~ "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_75() { let original = r##"*~~__emphasis strike strong__~~* ~~*__strike emphasis strong__*~~ "##; let expected = r##"

emphasis strike strong strike emphasis strong

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_76() { let original = r##"*~~__emphasis strike strong__~~* ~~*__`strike emphasis strong code`__*~~ "##; let expected = r##"

emphasis strike strong strike emphasis strong code

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_77() { let original = r##"*~~`emphasis strike code`~~* ~~*__strike emphasis strong__*~~ "##; let expected = r##"

emphasis strike code strike emphasis strong

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_78() { let original = r##"*~~`emphasis strike code`~~* ~~*__`strike emphasis strong code`__*~~ "##; let expected = r##"

emphasis strike code strike emphasis strong code

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_79() { let original = r##"**~~_strong strike emphasis_~~** ~~*__strike emphasis strong__*~~ "##; let expected = r##"

strong strike emphasis strike emphasis strong

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_80() { let original = r##"**~~_strong strike emphasis_~~** ~~*__`strike emphasis strong code`__*~~ "##; let expected = r##"

strong strike emphasis strike emphasis strong code

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_81() { let original = r##"**~~`strong strike code`~~** ~~*__strike emphasis strong__*~~ "##; let expected = r##"

strong strike code strike emphasis strong

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_82() { let original = r##"**~~`strong strike code`~~** ~~*__`strike emphasis strong code`__*~~ "##; let expected = r##"

strong strike code strike emphasis strong code

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_83() { let original = r##" | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | | foo | bar | |-----|------| | baz | alef | "##; let expected = r##"
foobar
bazalef
foobar
bazalef
foobar
bazalef
foobar
bazalef
foobar
bazalef
foobar
bazalef
foobar
bazalef
foobar
bazalef
| foo | bar  |
|-----|------|
| baz | alef |

| foo | bar | |-----|------| | baz | alef |

| foo | bar  |
|-----|------|
| baz | alef |

| foo | bar | |-----|------| | baz | alef |

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_84() { let original = r##"### ### "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_85() { let original = r##"### "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_86() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_87() { let original = r##"| A | table | | ------ | ---- | | not | in | | a | list| * A blockquote: > inside a list item * A Heading: # inside a list item * A table: | inside | a | | ------ | ------- | | list | item | | with | leading | | empty | lines | * A table: | inside | a | | ------- | ------- | | list | item | | without | leading | | empty | lines | "##; let expected = r##"
Atable
notin
alist
  • A blockquote:

    inside a list item

  • A Heading:

    inside a list item

  • A table:

    insidea
    listitem
    withleading
    emptylines
  • A table:

    insidea
    listitem
    withoutleading
    emptylines
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_88() { let original = r##"a\ b "##; let expected = r##"

a\

b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_89() { let original = r##"a\ * b "##; let expected = r##"

a\

  • b
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_90() { let original = r##"a\ > b "##; let expected = r##"

a\

b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_91() { let original = r##"a\ # b "##; let expected = r##"

a\

b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_92() { let original = r##"a\ == "##; let expected = r##"

a\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_93() { let original = r##"> a\ > "##; let expected = r##"

a\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_94() { let original = r##"
"##; let expected = r##"

<a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_95() { let original = r##"
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_96() { let original = r##" quote "##; let expected = r##"

<a

quote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_97() { let original = r##"
not quote "##; let expected = r##"
not quote "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_98() { let original = r##"quote "##; let expected = r##"

<a

quote

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_99() { let original = r##"
not quote "##; let expected = r##"
not quote "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_100() { let original = r##"> alpha > | a | b | > |---|---| > | c | d | "##; let expected = r##"

alpha

ab
cd
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_101() { let original = r##"***R]*-* "##; let expected = r##"

*R]-

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_102() { let original = r##"****foo*bar*baz**** "##; let expected = r##"

foobarbaz**

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_103() { let original = r##"; * % "##; let expected = r##"

; * %

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_104() { let original = r##"; * % "##; let expected = r##"

; * %

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_105() { let original = r##"<@1> "##; let expected = r##"

<@1>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_106() { let original = r##"--- anything: indented4Spaces: true --- Things "##; let expected = r##"

Things

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_107() { let original = r##"--- something: nested: twice: true --- Things "##; let expected = r##"

Things

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_108() { let original = r##"--- lists: - indented 4 spaces --- Things "##; let expected = r##"

Things

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_109() { let original = r##"- - - - "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_110() { let original = r##"- - . "##; let expected = r##"
  • .

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_111() { let original = r##"j***5*=* "##; let expected = r##"

j*5=

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_112() { let original = r##"Not enough table | | Not enough table |x | Not enough table | |- Table |x |- Not enough table | col1 | col2 | | | ---- | Not enough table | col1 | col2 | | : | ---- | Table | col1 | col2 | | ---- | ---- | "##; let expected = r##"

Not enough table

| |

Not enough table

|x |

Not enough table

| |-

Table

x

Not enough table | col1 | col2 | | | ---- |

Not enough table | col1 | col2 | | : | ---- |

Table

col1col2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_113() { let original = r##"[x] is not a valid link definition, because parens aren't balanced. [x]: ( "##; let expected = r##"

[x] is not a valid link definition, because parens aren't balanced.

[x]: (

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_114() { let original = r##"Both of these two paragraphs are structurally the same, but the first one has an unmatched asterisk. _*_ *{*{ _x_ *{*{ "##; let expected = r##"

Both of these two paragraphs are structurally the same, but the first one has an unmatched asterisk.

* {{

x {{

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_115() { let original = r##"**a.*.**a*.**. "##; let expected = r##"

*a.*.a..

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_116() { let original = r##"_*__*_* _*xx*_* _*__-_- _*xx-_- "##; let expected = r##"

__*

xx*

*__--

*xx--

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_117() { let original = r##"- - - x - "##; let expected = r##"
-
  • x

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_118() { let original = r##"- - - x - "##; let expected = r##"
-
  • x

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_119() { let original = r##"[x\ ]: https://rust-lang.org "##; let expected = r##"

[x\

]: https://rust-lang.org

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_120() { let original = r##">>**#* > >**#* **#* |**#*| |----| |**#*| |**#* **#*| **#* "##; let expected = r##"

*#

*#

*#

*#
*#
*#
*#
*#
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_121() { let original = r##"The second hyphen should parse the same way in both samples. - >* - The second hyphen should parse the same way in both samples. - >x - "##; let expected = r##"

The second hyphen should parse the same way in both samples.

The second hyphen should parse the same way in both samples.

  • x

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_122() { let original = r##"> Rewriting it in [Rust] is usually a bad idea. > > [Rust]: https://rust-lang.org "##; let expected = r##"

Rewriting it in Rust is usually a bad idea.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_123() { let original = r##"[First try ---------- Second try]: https://rust-lang.org "##; let expected = r##"

[First try

Second try]: https://rust-lang.org

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_124() { let original = r##"[^foo][] [^foo][baz] [baz][^foo] [^foo]: bar [baz]: https://rust-lang.org "##; let expected = r##"

1[]

^foo

baz1

1

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_125() { let original = r##"# foo \ bar \ "##; let expected = r##"

foo \

bar \

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_126() { let original = r##"[third try]: - [third try] "##; let expected = r##"

[third try]:

[third try]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_127() { let original = r##"- [foo]: test bar > [bar]: test [baz]: rstr [bar] "##; let expected = r##"
  • bar

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_128() { let original = r##"> - [foo]: test > bar > > > [bar]: test > [baz]: rstr > [bar] "##; let expected = r##"
  • bar

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_129() { let original = r##"[bar]: test - "##; let expected = r##"

-

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_130() { let original = r##"[link]( foo) > [link]( > foo) "##; let expected = r##"

link

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_131() { let original = r##"[link](foo ) > [link](foo > ) "##; let expected = r##"

link

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_132() { let original = r##"[link](foo "bar" ) > [link](foo > "bar" > ) "##; let expected = r##"

link

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_133() { let original = r##"[link]( foo "bar" ) > [link]( > foo > "bar" > ) "##; let expected = r##"

link

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_134() { let original = r##"[linkme]: foo - baz "##; let expected = r##"

- baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_135() { let original = r##"[linkme-3]: [^foo]: [linkme-4]: [^bar]: GFM footnotes can interrupt link defs if they have three spaces, but not four. "##; let expected = r##"

[linkme-3]:

1

GFM footnotes can interrupt link defs if they have three spaces, but not four.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_136() { let original = r##"[linkme-3]: === [linkme-4]: === Setext heading can interrupt link def if it has three spaces, but not four. "##; let expected = r##"

[linkme-3]:

Setext heading can interrupt link def if it has three spaces, but not four.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_137() { let original = r##"[linkme-3]: a - a [linkme-4]: a - b List can interrupt the paragraph at the start of a link definition if it starts with three spaces, but not four. "##; let expected = r##"
  • a

- b

List can interrupt the paragraph at the start of a link definition if it starts with three spaces, but not four.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_138() { let original = r##"[first - second]: https://example.com [first - second] "##; let expected = r##"

[first

second]: https://example.com

[first

second]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_139() { let original = r##"[first - second]: https://example.com [first - second] "##; let expected = r##"

first - second

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_140() { let original = r##"[first]: https://example.com " - " [first] "##; let expected = r##"

"

"

first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_141() { let original = r##"[first]: https://example.com " - " [first] "##; let expected = r##"

first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_142() { let original = r##"> [first]: https://example.com > " > - > " > > [first] "##; let expected = r##"

"

"

first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_143() { let original = r##"> ``` > code > text "##; let expected = r##"
code

text

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_144() { let original = r##"> [first]: https://example.com > " > - > " > > [first] "##; let expected = r##"

first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_145() { let original = r##"[first]: https://example.com " \ " [first] "##; let expected = r##"

first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_146() { let original = r##"[first]: https://example.com " \ " [first] "##; let expected = r##"

" \

"

first

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_147() { let original = r##"[foo]: https://example.com '[foo]'bar "##; let expected = r##"

'foo'bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_148() { let original = r##"- [foo]: https://example.com '[foo]' [foo] "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_149() { let original = r##"[ a]: https://example.com [b ]: https://example.com [a] [b] "##; let expected = r##"

a b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_150() { let original = r##"> > ``` > > code > > > text "##; let expected = r##"
code

text

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_151() { let original = r##"- *foo - - baz* "##; let expected = r##"
  • *foo
    baz*
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_152() { let original = r##"- `foo - - baz` "##; let expected = r##"
  • `foo
    baz`
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_153() { let original = r##"- [foo - - baz](https://example.com) "##; let expected = r##"
  • [foo
    baz](https://example.com)
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_154() { let original = r##"[mylink] [mylink]: https://example.com ' part of the title' "##; let expected = r##"

mylink

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_155() { let original = r##"1. pulldown-cmark used to think this was code, but commonmark.js and commonmark-hs didn't. The dot in the list marker is at column two, so the child paragraph actually starts in column *three*. "##; let expected = r##"
  1. pulldown-cmark used to think this was code, but commonmark.js and commonmark-hs didn't. The dot in the list marker is at column two, so the child paragraph actually starts in column three.
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_156() { let original = r##"1. This is not in the list at all. It's a paragraph after it. "##; let expected = r##"

This is not in the list at all. It's a paragraph after it.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_157() { let original = r##"`\!\"\#\$\%\& \!\"\#\$\%\& \!\"\#\$\%\&` "##; let expected = r##"

\!\&quot;\#\$\%\& \!\&quot;\#\$\%\& \!\&quot;\#\$\%\&

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_158() { let original = r##"| -|- * "##; let expected = r##"

| -|- *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_159() { let original = r##" A paragraph is a paragraph and spaces must be removed. Another paragraph whose spaces must be removed. "##; let expected = r##"

A paragraph is a paragraph and spaces must be removed.

Another paragraph whose spaces must be removed.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_160() { let original = r##"![^1] [^1]: foo "##; let expected = r##"

!1

1

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_161() { let original = r##"First ![^1][] Second [^1]: foo "##; let expected = r##"

First !1[] Second

1

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_162() { let original = r##"� � "##; let expected = r##"

&#00000000; &#x0000000;

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_163() { let original = r##"� "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_164() { let original = r##"- _t # test t_ "##; let expected = r##"
  • _t

    test

    t_
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_165() { let original = r##"* *_ # N* "##; let expected = r##"
  • *_

    N*
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_166() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_167() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_168() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_169() { let original = r##"* "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_170() { let original = r##"* test "##; let expected = r##"
  • test

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_171() { let original = r##"*
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_172() { let original = r##"*
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_173() { let original = r##"*
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_174() { let original = r##"*
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_175() { let original = r##"*
"##; let expected = r##"
  • <div>
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_176() { let original = r##"[link]: test (() [link] "##; let expected = r##"

[link]: test (()

[link]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_177() { let original = r##"[link]: test (()) [link] "##; let expected = r##"

[link]: test (())

[link]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_178() { let original = r##"[link]: test (\(\)) [link] "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_179() { let original = r##"[link]: test """ [link] "##; let expected = r##"

[link]: test """

[link]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_180() { let original = r##"[link]: test "\"" [link] "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_181() { let original = r##"[link]: test ''' [link] "##; let expected = r##"

[link]: test '''

[link]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_182() { let original = r##"[link]: test '\'' [link] "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_183() { let original = r##"- test test2 "##; let expected = r##"
  • test
    

    test2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_184() { let original = r##" test test2 "##; let expected = r##"
test

test2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_185() { let original = r##"- test test2 "##; let expected = r##"
  • test
    
    test2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_186() { let original = r##"- test - test2 "##; let expected = r##"
  • test
    
  • test2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_187() { let original = r##"- test - test2 "##; let expected = r##"
  • test
    
  • test2

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_188() { let original = r##" <\!p> "##; let expected = r##"

<!p>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_189() { let original = r##"[linky] [linky]: ((())) "##; let expected = r##"

linky

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_190() { let original = r##">junk "##; let expected = r##"

<span title junk

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_191() { let original = r##" ~~~ ~~~ "##; let expected = r##"
   ~~~
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_192() { let original = r##" ~~~ ~~~ "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_193() { let original = r##"[link]: destination " text " [link] "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_194() { let original = r##"* _ _** ___ ^_ "##; let expected = r##"
  • _ _**
    ^_
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_195() { let original = r##"> [!Note] > - Foo "##; let expected = r##"
  • Foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_196() { let original = r##" --- -- --- "##; let expected = r##"

--

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_197() { let original = r##"[30](https://rust.org/something%3A((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))) [40](https://rust.org/something%3A((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))) "##; let expected = r##"

30 [40](https://rust.org/something%3A((((((((((((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))))))))))))

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_198() { let original = r##"- [x] \ - "##; let expected = r##"

\

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_199() { let original = r##"* [ ] --- bar "##; let expected = r##"

bar

"##; test_markdown_html(original, expected, false, true, false, false, false); } #[test] fn regression_test_200() { let original = r##"` ` "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_201() { let original = r##"* def this : def text def text "##; let expected = r##"
  • def this
    def text def text
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_202() { let original = r##"* def this : def text def text "##; let expected = r##"
  • def this

    def text def text

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_203() { let original = r##"**A:** > B C > I J :x: K > :x: L M > N O _P_ Q R. (S > T U, V W > :x:,:x:,:x:, and :x: but no :x: or > :x:.) "##; let expected = r##"

A:

B C I J :x: K
x: L M N O P Q R. (S T U, V W
x:,:x:,:x:, and :x: but no :x: or
x:.)
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_204() { let original = r##"[abc] check `foobar_raz` Some preamble `foobar_raz`, not `barfoo_raz` :D This should fix: > Something is wrong! "##; let expected = r##"
[abc] check foobar_raz Some preamble foobar_raz, not barfoo_raz
D

This should fix:

> Something is wrong!

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_205() { let original = r##"- Item definition [it ```rust ``` stuff](https://example.com) "##; let expected = r##"
  • Item definition [it
    stuff](https://example.com)
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_206() { let original = r##"foo {.class} === > foo > {.class} > === > > > foo > > {.class} > > === * > foo > {.class} > === > foo > {.class} > === "##; let expected = r##"

foo

foo

foo

  • foo

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_207() { let original = r##"the trailing space after the > should be stripped > {.bar} === "##; let expected = r##"

the trailing space after the > should be stripped >

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn regression_test_208() { let original = r##"[[Wiki<|Link]] "##; let expected = r##"

Link

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn regression_test_209() { let original = r##"* "##; let expected = r##"
  • <c
"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn regression_test_210() { let original = r##"- [x] * some text - [ ] > some text - [x] * some text - [ ] > some text "##; let expected = r##"
  • * some text
  • > some text
    • some text
  • some text

"##; test_markdown_html(original, expected, false, false, false, false, true); } pulldown-cmark-0.13.0/tests/suite/smart_punct.rs000064400000000000000000000106761046102023000200560ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn smart_punct_test_1() { let original = r##""Hello," said the spider. "'Shelob' is my name." "##; let expected = r##"

“Hello,” said the spider. “‘Shelob’ is my name.”

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_2() { let original = r##"'A', 'B', and 'C' are letters. "##; let expected = r##"

‘A’, ‘B’, and ‘C’ are letters.

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_3() { let original = r##"'Oak,' 'elm,' and 'beech' are names of trees. So is 'pine.' "##; let expected = r##"

‘Oak,’ ‘elm,’ and ‘beech’ are names of trees. So is ‘pine.’

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_4() { let original = r##"'He said, "I want to go."' "##; let expected = r##"

‘He said, “I want to go.”’

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_5() { let original = r##"Were you alive in the 70's? "##; let expected = r##"

Were you alive in the 70’s?

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_6() { let original = r##"Here is some quoted '`code`' and a "[quoted link](url)". "##; let expected = r##"

Here is some quoted ‘code’ and a “quoted link”.

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_7() { let original = r##"'tis the season to be 'jolly' "##; let expected = r##"

’tis the season to be ‘jolly’

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_8() { let original = r##"'We'll use Jane's boat and John's truck,' Jenna said. "##; let expected = r##"

‘We’ll use Jane’s boat and John’s truck,’ Jenna said.

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_9() { let original = r##""A paragraph with no closing quote. "Second paragraph by same speaker, in fiction." "##; let expected = r##"

“A paragraph with no closing quote.

“Second paragraph by same speaker, in fiction.”

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_10() { let original = r##"[a]'s b' "##; let expected = r##"

[a]’s b’

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_11() { let original = r##"\"This is not smart.\" This isn\'t either. 5\'8\" "##; let expected = r##"

"This is not smart." This isn't either. 5'8"

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_12() { let original = r##"Some dashes: em---em en--en em --- em en -- en 2--3 "##; let expected = r##"

Some dashes: em—em en–en em — em en – en 2–3

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_13() { let original = r##"one- two-- three--- four---- five----- six------ seven------- eight-------- nine--------- thirteen-------------. "##; let expected = r##"

one- two– three— four–– five—– six—— seven—–– eight–––– nine——— thirteen———––.

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_14() { let original = r##"Escaped hyphens: \-- \-\-\-. "##; let expected = r##"

Escaped hyphens: -- ---.

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_15() { let original = r##"Ellipses...and...and.... "##; let expected = r##"

Ellipses…and…and….

"##; test_markdown_html(original, expected, true, false, false, false, false); } #[test] fn smart_punct_test_16() { let original = r##"No ellipses\.\.\. "##; let expected = r##"

No ellipses...

"##; test_markdown_html(original, expected, true, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/spec.rs000064400000000000000000004504251046102023000164510ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn spec_test_1() { let original = r##" foo baz bim "##; let expected = r##"
foo	baz		bim
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_2() { let original = r##" foo baz bim "##; let expected = r##"
foo	baz		bim
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_3() { let original = r##" a a ὐ a "##; let expected = r##"
a	a
ὐ	a
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_4() { let original = r##" - foo bar "##; let expected = r##"
  • foo

    bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_5() { let original = r##"- foo bar "##; let expected = r##"
  • foo

      bar
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_6() { let original = r##"> foo "##; let expected = r##"
  foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_7() { let original = r##"- foo "##; let expected = r##"
  •   foo
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_8() { let original = r##" foo bar "##; let expected = r##"
foo
bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_9() { let original = r##" - foo - bar - baz "##; let expected = r##"
  • foo
    • bar
      • baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_10() { let original = r##"# Foo "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_11() { let original = r##"* * * "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_12() { let original = r##"\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~ "##; let expected = r##"

!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_13() { let original = r##"\ \A\a\ \3\φ\« "##; let expected = r##"

\ \A\a\ \3\φ\«

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_14() { let original = r##"\*not emphasized* \
not a tag \[not a link](/foo) \`not code` 1\. not a list \* not a list \# not a heading \[foo]: /url "not a reference" \ö not a character entity "##; let expected = r##"

*not emphasized* <br/> not a tag [not a link](/foo) `not code` 1. not a list * not a list # not a heading [foo]: /url "not a reference" &ouml; not a character entity

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_15() { let original = r##"\\*emphasis* "##; let expected = r##"

\emphasis

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_16() { let original = r##"foo\ bar "##; let expected = r##"

foo
bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_17() { let original = r##"`` \[\` `` "##; let expected = r##"

\[\`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_18() { let original = r##" \[\] "##; let expected = r##"
\[\]
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_19() { let original = r##"~~~ \[\] ~~~ "##; let expected = r##"
\[\]
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_20() { let original = r##" "##; let expected = r##"

https://example.com?find=\*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_21() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_22() { let original = r##"[foo](/bar\* "ti\*tle") "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_23() { let original = r##"[foo] [foo]: /bar\* "ti\*tle" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_24() { let original = r##"``` foo\+bar foo ``` "##; let expected = r##"
foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_25() { let original = r##"  & © Æ Ď ¾ ℋ ⅆ ∲ ≧̸ "##; let expected = r##"

  & © Æ Ď ¾ ℋ ⅆ ∲ ≧̸

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_26() { let original = r##"# Ӓ Ϡ � "##; let expected = r##"

# Ӓ Ϡ �

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_27() { let original = r##"" ആ ಫ "##; let expected = r##"

" ആ ಫ

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_28() { let original = r##"  &x; &#; &#x; � &#abcdef0; &ThisIsNotDefined; &hi?; "##; let expected = r##"

&nbsp &x; &#; &#x; &#87654321; &#abcdef0; &ThisIsNotDefined; &hi?;

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_29() { let original = r##"© "##; let expected = r##"

&copy

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_30() { let original = r##"&MadeUpEntity; "##; let expected = r##"

&MadeUpEntity;

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_31() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_32() { let original = r##"[foo](/föö "föö") "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_33() { let original = r##"[foo] [foo]: /föö "föö" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_34() { let original = r##"``` föö foo ``` "##; let expected = r##"
foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_35() { let original = r##"`föö` "##; let expected = r##"

f&ouml;&ouml;

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_36() { let original = r##" föfö "##; let expected = r##"
f&ouml;f&ouml;
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_37() { let original = r##"*foo* *foo* "##; let expected = r##"

*foo* foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_38() { let original = r##"* foo * foo "##; let expected = r##"

* foo

  • foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_39() { let original = r##"foo bar "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_40() { let original = r##" foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_41() { let original = r##"[a](url "tit") "##; let expected = r##"

[a](url "tit")

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_42() { let original = r##"- `one - two` "##; let expected = r##"
  • `one
  • two`
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_43() { let original = r##"*** --- ___ "##; let expected = r##"


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_44() { let original = r##"+++ "##; let expected = r##"

+++

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_45() { let original = r##"=== "##; let expected = r##"

===

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_46() { let original = r##"-- ** __ "##; let expected = r##"

-- ** __

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_47() { let original = r##" *** *** *** "##; let expected = r##"


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_48() { let original = r##" *** "##; let expected = r##"
***
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_49() { let original = r##"Foo *** "##; let expected = r##"

Foo ***

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_50() { let original = r##"_____________________________________ "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_51() { let original = r##" - - - "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_52() { let original = r##" ** * ** * ** * ** "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_53() { let original = r##"- - - - "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_54() { let original = r##"- - - - "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_55() { let original = r##"_ _ _ _ a a------ ---a--- "##; let expected = r##"

_ _ _ _ a

a------

---a---

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_56() { let original = r##" *-* "##; let expected = r##"

-

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_57() { let original = r##"- foo *** - bar "##; let expected = r##"
  • foo

  • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_58() { let original = r##"Foo *** bar "##; let expected = r##"

Foo


bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_59() { let original = r##"Foo --- bar "##; let expected = r##"

Foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_60() { let original = r##"* Foo * * * * Bar "##; let expected = r##"
  • Foo

  • Bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_61() { let original = r##"- Foo - * * * "##; let expected = r##"
  • Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_62() { let original = r##"# foo ## foo ### foo #### foo ##### foo ###### foo "##; let expected = r##"

foo

foo

foo

foo

foo
foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_63() { let original = r##"####### foo "##; let expected = r##"

####### foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_64() { let original = r##"#5 bolt #hashtag "##; let expected = r##"

#5 bolt

#hashtag

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_65() { let original = r##"\## foo "##; let expected = r##"

## foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_66() { let original = r##"# foo *bar* \*baz\* "##; let expected = r##"

foo bar *baz*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_67() { let original = r##"# foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_68() { let original = r##" ### foo ## foo # foo "##; let expected = r##"

foo

foo

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_69() { let original = r##" # foo "##; let expected = r##"
# foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_70() { let original = r##"foo # bar "##; let expected = r##"

foo # bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_71() { let original = r##"## foo ## ### bar ### "##; let expected = r##"

foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_72() { let original = r##"# foo ################################## ##### foo ## "##; let expected = r##"

foo

foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_73() { let original = r##"### foo ### "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_74() { let original = r##"### foo ### b "##; let expected = r##"

foo ### b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_75() { let original = r##"# foo# "##; let expected = r##"

foo#

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_76() { let original = r##"### foo \### ## foo #\## # foo \# "##; let expected = r##"

foo ###

foo ###

foo #

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_77() { let original = r##"**** ## foo **** "##; let expected = r##"

foo


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_78() { let original = r##"Foo bar # baz Bar foo "##; let expected = r##"

Foo bar

baz

Bar foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_79() { let original = r##"## # ### ### "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_80() { let original = r##"Foo *bar* ========= Foo *bar* --------- "##; let expected = r##"

Foo bar

Foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_81() { let original = r##"Foo *bar baz* ==== "##; let expected = r##"

Foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_82() { let original = r##" Foo *bar baz* ==== "##; let expected = r##"

Foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_83() { let original = r##"Foo ------------------------- Foo = "##; let expected = r##"

Foo

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_84() { let original = r##" Foo --- Foo ----- Foo === "##; let expected = r##"

Foo

Foo

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_85() { let original = r##" Foo --- Foo --- "##; let expected = r##"
Foo
---

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_86() { let original = r##"Foo ---- "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_87() { let original = r##"Foo --- "##; let expected = r##"

Foo ---

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_88() { let original = r##"Foo = = Foo --- - "##; let expected = r##"

Foo = =

Foo


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_89() { let original = r##"Foo ----- "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_90() { let original = r##"Foo\ ---- "##; let expected = r##"

Foo\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_91() { let original = r##"`Foo ---- ` "##; let expected = r##"

`Foo

`

<a title="a lot

of dashes"/>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_92() { let original = r##"> Foo --- "##; let expected = r##"

Foo


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_93() { let original = r##"> foo bar === "##; let expected = r##"

foo bar ===

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_94() { let original = r##"- Foo --- "##; let expected = r##"
  • Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_95() { let original = r##"Foo Bar --- "##; let expected = r##"

Foo Bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_96() { let original = r##"--- Foo --- Bar --- Baz "##; let expected = r##"

Foo

Bar

Baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_97() { let original = r##" ==== "##; let expected = r##"

====

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_98() { let original = r##"--- --- "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_99() { let original = r##"- foo ----- "##; let expected = r##"
  • foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_100() { let original = r##" foo --- "##; let expected = r##"
foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_101() { let original = r##"> foo ----- "##; let expected = r##"

foo


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_102() { let original = r##"\> foo ------ "##; let expected = r##"

> foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_103() { let original = r##"Foo bar --- baz "##; let expected = r##"

Foo

bar

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_104() { let original = r##"Foo bar --- baz "##; let expected = r##"

Foo bar


baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_105() { let original = r##"Foo bar * * * baz "##; let expected = r##"

Foo bar


baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_106() { let original = r##"Foo bar \--- baz "##; let expected = r##"

Foo bar --- baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_107() { let original = r##" a simple indented code block "##; let expected = r##"
a simple
  indented code block
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_108() { let original = r##" - foo bar "##; let expected = r##"
  • foo

    bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_109() { let original = r##"1. foo - bar "##; let expected = r##"
  1. foo

    • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_110() { let original = r##"
*hi* - one "##; let expected = r##"
<a/>
*hi*

- one
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_111() { let original = r##" chunk1 chunk2 chunk3 "##; let expected = r##"
chunk1

chunk2



chunk3
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_112() { let original = r##" chunk1 chunk2 "##; let expected = r##"
chunk1
  
  chunk2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_113() { let original = r##"Foo bar "##; let expected = r##"

Foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_114() { let original = r##" foo bar "##; let expected = r##"
foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_115() { let original = r##"# Heading foo Heading ------ foo ---- "##; let expected = r##"

Heading

foo

Heading

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_116() { let original = r##" foo bar "##; let expected = r##"
    foo
bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_117() { let original = r##" foo "##; let expected = r##"
foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_118() { let original = r##" foo "##; let expected = r##"
foo  
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_119() { let original = r##"``` < > ``` "##; let expected = r##"
<
 >
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_120() { let original = r##"~~~ < > ~~~ "##; let expected = r##"
<
 >
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_121() { let original = r##"`` foo `` "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_122() { let original = r##"``` aaa ~~~ ``` "##; let expected = r##"
aaa
~~~
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_123() { let original = r##"~~~ aaa ``` ~~~ "##; let expected = r##"
aaa
```
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_124() { let original = r##"```` aaa ``` `````` "##; let expected = r##"
aaa
```
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_125() { let original = r##"~~~~ aaa ~~~ ~~~~ "##; let expected = r##"
aaa
~~~
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_126() { let original = r##"``` "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_127() { let original = r##"````` ``` aaa "##; let expected = r##"

```
aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_128() { let original = r##"> ``` > aaa bbb "##; let expected = r##"
aaa

bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_129() { let original = r##"``` ``` "##; let expected = r##"

  
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_130() { let original = r##"``` ``` "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_131() { let original = r##" ``` aaa aaa ``` "##; let expected = r##"
aaa
aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_132() { let original = r##" ``` aaa aaa aaa ``` "##; let expected = r##"
aaa
aaa
aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_133() { let original = r##" ``` aaa aaa aaa ``` "##; let expected = r##"
aaa
 aaa
aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_134() { let original = r##" ``` aaa ``` "##; let expected = r##"
```
aaa
```
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_135() { let original = r##"``` aaa ``` "##; let expected = r##"
aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_136() { let original = r##" ``` aaa ``` "##; let expected = r##"
aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_137() { let original = r##"``` aaa ``` "##; let expected = r##"
aaa
    ```
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_138() { let original = r##"``` ``` aaa "##; let expected = r##"

aaa

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_139() { let original = r##"~~~~~~ aaa ~~~ ~~ "##; let expected = r##"
aaa
~~~ ~~
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_140() { let original = r##"foo ``` bar ``` baz "##; let expected = r##"

foo

bar

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_141() { let original = r##"foo --- ~~~ bar ~~~ # baz "##; let expected = r##"

foo

bar

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_142() { let original = r##"```ruby def foo(x) return 3 end ``` "##; let expected = r##"
def foo(x)
  return 3
end
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_143() { let original = r##"~~~~ ruby startline=3 $%@#$ def foo(x) return 3 end ~~~~~~~ "##; let expected = r##"
def foo(x)
  return 3
end
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_144() { let original = r##"````; ```` "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_145() { let original = r##"``` aa ``` foo "##; let expected = r##"

aa foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_146() { let original = r##"~~~ aa ``` ~~~ foo ~~~ "##; let expected = r##"
foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_147() { let original = r##"``` ``` aaa ``` "##; let expected = r##"
``` aaa
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_148() { let original = r##"
**Hello**,

_world_.
"##; let expected = r##"
**Hello**,

world.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_149() { let original = r##"
hi
okay. "##; let expected = r##"
hi

okay.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_150() { let original = r##"
*foo* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_152() { let original = r##"
*Markdown*
"##; let expected = r##"

Markdown

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_153() { let original = r##"
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_154() { let original = r##"
"##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_155() { let original = r##"
*foo* *bar* "##; let expected = r##"
*foo*

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_156() { let original = r##"
"##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_160() { let original = r##"
foo
"##; let expected = r##"
foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_161() { let original = r##"
``` c int x = 33; ``` "##; let expected = r##"
``` c int x = 33; ``` "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_162() { let original = r##" *bar* "##; let expected = r##" *bar* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_163() { let original = r##" *bar* "##; let expected = r##" *bar* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_164() { let original = r##" *bar* "##; let expected = r##" *bar* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_165() { let original = r##" *bar* "##; let expected = r##" *bar* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_166() { let original = r##" *foo* "##; let expected = r##" *foo* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_167() { let original = r##" *foo* "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_168() { let original = r##"*foo* "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_169() { let original = r##"

import Text.HTML.TagSoup

main :: IO ()
main = print $ parseTags tags
okay "##; let expected = r##"

import Text.HTML.TagSoup

main :: IO ()
main = print $ parseTags tags

okay

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_170() { let original = r##" okay "##; let expected = r##"

okay

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_171() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_172() { let original = r##" okay "##; let expected = r##"

okay

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_173() { let original = r##" *foo* "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_177() { let original = r##"*bar* *baz* "##; let expected = r##"*bar*

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_178() { let original = r##"1. *bar* "##; let expected = r##"1. *bar* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_179() { let original = r##" okay "##; let expected = r##"

okay

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_180() { let original = r##"'; ?> okay "##; let expected = r##"'; ?>

okay

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_181() { let original = r##" "##; let expected = r##" "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_182() { let original = r##" okay "##; let expected = r##"

okay

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_183() { let original = r##" "##; let expected = r##"
<!-- foo -->
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_184() { let original = r##"
"##; let expected = r##"
<div>
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_185() { let original = r##"Foo
bar
"##; let expected = r##"

Foo

bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_186() { let original = r##"
bar
*foo* "##; let expected = r##"
bar
*foo* "##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_187() { let original = r##"Foo baz "##; let expected = r##"

Foo baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_188() { let original = r##"
*Emphasized* text.
"##; let expected = r##"

Emphasized text.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_189() { let original = r##"
*Emphasized* text.
"##; let expected = r##"
*Emphasized* text.
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_190() { let original = r##"
Hi
"##; let expected = r##"
Hi
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_191() { let original = r##"
Hi
"##; let expected = r##"
<td>
  Hi
</td>
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_192() { let original = r##"[foo]: /url "title" [foo] "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_193() { let original = r##" [foo]: /url 'the title' [foo] "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_194() { let original = r##"[Foo*bar\]]:my_(url) 'title (with parens)' [Foo*bar\]] "##; let expected = r##"

Foo*bar]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_195() { let original = r##"[Foo bar]: 'title' [Foo bar] "##; let expected = r##"

Foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_196() { let original = r##"[foo]: /url ' title line1 line2 ' [foo] "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_197() { let original = r##"[foo]: /url 'title with blank line' [foo] "##; let expected = r##"

[foo]: /url 'title

with blank line'

[foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_198() { let original = r##"[foo]: /url [foo] "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_199() { let original = r##"[foo]: [foo] "##; let expected = r##"

[foo]:

[foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_200() { let original = r##"[foo]: <> [foo] "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_201() { let original = r##"[foo]: (baz) [foo] "##; let expected = r##"

[foo]: (baz)

[foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_202() { let original = r##"[foo]: /url\bar\*baz "foo\"bar\baz" [foo] "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_203() { let original = r##"[foo] [foo]: url "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_204() { let original = r##"[foo] [foo]: first [foo]: second "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_205() { let original = r##"[FOO]: /url [Foo] "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_206() { let original = r##"[ΑΓΩ]: /φου [αγω] "##; let expected = r##"

αγω

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_207() { let original = r##"[foo]: /url "##; let expected = r##""##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_208() { let original = r##"[ foo ]: /url bar "##; let expected = r##"

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_209() { let original = r##"[foo]: /url "title" ok "##; let expected = r##"

[foo]: /url "title" ok

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_210() { let original = r##"[foo]: /url "title" ok "##; let expected = r##"

"title" ok

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_211() { let original = r##" [foo]: /url "title" [foo] "##; let expected = r##"
[foo]: /url "title"

[foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_212() { let original = r##"``` [foo]: /url ``` [foo] "##; let expected = r##"
[foo]: /url

[foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_213() { let original = r##"Foo [bar]: /baz [bar] "##; let expected = r##"

Foo [bar]: /baz

[bar]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_214() { let original = r##"# [Foo] [foo]: /url > bar "##; let expected = r##"

Foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_215() { let original = r##"[foo]: /url bar === [foo] "##; let expected = r##"

bar

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_216() { let original = r##"[foo]: /url === [foo] "##; let expected = r##"

=== foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_217() { let original = r##"[foo]: /foo-url "foo" [bar]: /bar-url "bar" [baz]: /baz-url [foo], [bar], [baz] "##; let expected = r##"

foo, bar, baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_218() { let original = r##"[foo] > [foo]: /url "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_219() { let original = r##"aaa bbb "##; let expected = r##"

aaa

bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_220() { let original = r##"aaa bbb ccc ddd "##; let expected = r##"

aaa bbb

ccc ddd

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_221() { let original = r##"aaa bbb "##; let expected = r##"

aaa

bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_222() { let original = r##" aaa bbb "##; let expected = r##"

aaa bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_223() { let original = r##"aaa bbb ccc "##; let expected = r##"

aaa bbb ccc

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_224() { let original = r##" aaa bbb "##; let expected = r##"

aaa bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_225() { let original = r##" aaa bbb "##; let expected = r##"
aaa

bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_226() { let original = r##"aaa bbb "##; let expected = r##"

aaa
bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_227() { let original = r##" aaa # aaa "##; let expected = r##"

aaa

aaa

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_228() { let original = r##"> # Foo > bar > baz "##; let expected = r##"

Foo

bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_229() { let original = r##"># Foo >bar > baz "##; let expected = r##"

Foo

bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_230() { let original = r##" > # Foo > bar > baz "##; let expected = r##"

Foo

bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_231() { let original = r##" > # Foo > bar > baz "##; let expected = r##"
> # Foo
> bar
> baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_232() { let original = r##"> # Foo > bar baz "##; let expected = r##"

Foo

bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_233() { let original = r##"> bar baz > foo "##; let expected = r##"

bar baz foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_234() { let original = r##"> foo --- "##; let expected = r##"

foo


"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_235() { let original = r##"> - foo - bar "##; let expected = r##"
  • foo
  • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_236() { let original = r##"> foo bar "##; let expected = r##"
foo
bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_237() { let original = r##"> ``` foo ``` "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_238() { let original = r##"> foo - bar "##; let expected = r##"

foo - bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_239() { let original = r##"> "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_240() { let original = r##"> > > "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_241() { let original = r##"> > foo > "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_242() { let original = r##"> foo > bar "##; let expected = r##"

foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_243() { let original = r##"> foo > bar "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_244() { let original = r##"> foo > > bar "##; let expected = r##"

foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_245() { let original = r##"foo > bar "##; let expected = r##"

foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_246() { let original = r##"> aaa *** > bbb "##; let expected = r##"

aaa


bbb

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_247() { let original = r##"> bar baz "##; let expected = r##"

bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_248() { let original = r##"> bar baz "##; let expected = r##"

bar

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_249() { let original = r##"> bar > baz "##; let expected = r##"

bar

baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_250() { let original = r##"> > > foo bar "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_251() { let original = r##">>> foo > bar >>baz "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_252() { let original = r##"> code > not code "##; let expected = r##"
code

not code

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_253() { let original = r##"A paragraph with two lines. indented code > A block quote. "##; let expected = r##"

A paragraph with two lines.

indented code

A block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_254() { let original = r##"1. A paragraph with two lines. indented code > A block quote. "##; let expected = r##"
  1. A paragraph with two lines.

    indented code
    

    A block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_255() { let original = r##"- one two "##; let expected = r##"
  • one

two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_256() { let original = r##"- one two "##; let expected = r##"
  • one

    two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_257() { let original = r##" - one two "##; let expected = r##"
  • one
 two
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_258() { let original = r##" - one two "##; let expected = r##"
  • one

    two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_259() { let original = r##" > > 1. one >> >> two "##; let expected = r##"
  1. one

    two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_260() { let original = r##">>- one >> > > two "##; let expected = r##"
  • one

two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_261() { let original = r##"-one 2.two "##; let expected = r##"

-one

2.two

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_262() { let original = r##"- foo bar "##; let expected = r##"
  • foo

    bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_263() { let original = r##"1. foo ``` bar ``` baz > bam "##; let expected = r##"
  1. foo

    bar
    

    baz

    bam

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_264() { let original = r##"- Foo bar baz "##; let expected = r##"
  • Foo

    bar
    
    
    baz
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_265() { let original = r##"123456789. ok "##; let expected = r##"
  1. ok
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_266() { let original = r##"1234567890. not ok "##; let expected = r##"

1234567890. not ok

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_267() { let original = r##"0. ok "##; let expected = r##"
  1. ok
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_268() { let original = r##"003. ok "##; let expected = r##"
  1. ok
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_269() { let original = r##"-1. not ok "##; let expected = r##"

-1. not ok

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_270() { let original = r##"- foo bar "##; let expected = r##"
  • foo

    bar
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_271() { let original = r##" 10. foo bar "##; let expected = r##"
  1. foo

    bar
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_272() { let original = r##" indented code paragraph more code "##; let expected = r##"
indented code

paragraph

more code
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_273() { let original = r##"1. indented code paragraph more code "##; let expected = r##"
  1. indented code
    

    paragraph

    more code
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_274() { let original = r##"1. indented code paragraph more code "##; let expected = r##"
  1.  indented code
    

    paragraph

    more code
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_275() { let original = r##" foo bar "##; let expected = r##"

foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_276() { let original = r##"- foo bar "##; let expected = r##"
  • foo

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_277() { let original = r##"- foo bar "##; let expected = r##"
  • foo

    bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_278() { let original = r##"- foo - ``` bar ``` - baz "##; let expected = r##"
  • foo
  • bar
    
  • baz
    
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_279() { let original = r##"- foo "##; let expected = r##"
  • foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_280() { let original = r##"- foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_281() { let original = r##"- foo - - bar "##; let expected = r##"
  • foo
  • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_282() { let original = r##"- foo - - bar "##; let expected = r##"
  • foo
  • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_283() { let original = r##"1. foo 2. 3. bar "##; let expected = r##"
  1. foo
  2. bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_284() { let original = r##"* "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_285() { let original = r##"foo * foo 1. "##; let expected = r##"

foo *

foo 1.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_286() { let original = r##" 1. A paragraph with two lines. indented code > A block quote. "##; let expected = r##"
  1. A paragraph with two lines.

    indented code
    

    A block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_287() { let original = r##" 1. A paragraph with two lines. indented code > A block quote. "##; let expected = r##"
  1. A paragraph with two lines.

    indented code
    

    A block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_288() { let original = r##" 1. A paragraph with two lines. indented code > A block quote. "##; let expected = r##"
  1. A paragraph with two lines.

    indented code
    

    A block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_289() { let original = r##" 1. A paragraph with two lines. indented code > A block quote. "##; let expected = r##"
1.  A paragraph
    with two lines.

        indented code

    > A block quote.
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_290() { let original = r##" 1. A paragraph with two lines. indented code > A block quote. "##; let expected = r##"
  1. A paragraph with two lines.

    indented code
    

    A block quote.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_291() { let original = r##" 1. A paragraph with two lines. "##; let expected = r##"
  1. A paragraph with two lines.
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_292() { let original = r##"> 1. > Blockquote continued here. "##; let expected = r##"
  1. Blockquote continued here.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_293() { let original = r##"> 1. > Blockquote > continued here. "##; let expected = r##"
  1. Blockquote continued here.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_294() { let original = r##"- foo - bar - baz - boo "##; let expected = r##"
  • foo
    • bar
      • baz
        • boo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_295() { let original = r##"- foo - bar - baz - boo "##; let expected = r##"
  • foo
  • bar
  • baz
  • boo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_296() { let original = r##"10) foo - bar "##; let expected = r##"
  1. foo
    • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_297() { let original = r##"10) foo - bar "##; let expected = r##"
  1. foo
  • bar
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_298() { let original = r##"- - foo "##; let expected = r##"
    • foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_299() { let original = r##"1. - 2. foo "##; let expected = r##"
      1. foo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_300() { let original = r##"- # Foo - Bar --- baz "##; let expected = r##"
  • Foo

  • Bar

    baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_301() { let original = r##"- foo - bar + baz "##; let expected = r##"
  • foo
  • bar
  • baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_302() { let original = r##"1. foo 2. bar 3) baz "##; let expected = r##"
  1. foo
  2. bar
  1. baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_303() { let original = r##"Foo - bar - baz "##; let expected = r##"

Foo

  • bar
  • baz
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_304() { let original = r##"The number of windows in my house is 14. The number of doors is 6. "##; let expected = r##"

The number of windows in my house is 14. The number of doors is 6.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_305() { let original = r##"The number of windows in my house is 1. The number of doors is 6. "##; let expected = r##"

The number of windows in my house is

  1. The number of doors is 6.
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_306() { let original = r##"- foo - bar - baz "##; let expected = r##"
  • foo

  • bar

  • baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_307() { let original = r##"- foo - bar - baz bim "##; let expected = r##"
  • foo
    • bar
      • baz

        bim

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_308() { let original = r##"- foo - bar - baz - bim "##; let expected = r##"
  • foo
  • bar
  • baz
  • bim
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_309() { let original = r##"- foo notcode - foo code "##; let expected = r##"
  • foo

    notcode

  • foo

code
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_310() { let original = r##"- a - b - c - d - e - f - g "##; let expected = r##"
  • a
  • b
  • c
  • d
  • e
  • f
  • g
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_311() { let original = r##"1. a 2. b 3. c "##; let expected = r##"
  1. a

  2. b

  3. c

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_312() { let original = r##"- a - b - c - d - e "##; let expected = r##"
  • a
  • b
  • c
  • d - e
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_313() { let original = r##"1. a 2. b 3. c "##; let expected = r##"
  1. a

  2. b

3. c
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_314() { let original = r##"- a - b - c "##; let expected = r##"
  • a

  • b

  • c

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_315() { let original = r##"* a * * c "##; let expected = r##"
  • a

  • c

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_316() { let original = r##"- a - b c - d "##; let expected = r##"
  • a

  • b

    c

  • d

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_317() { let original = r##"- a - b [ref]: /url - d "##; let expected = r##"
  • a

  • b

  • d

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_318() { let original = r##"- a - ``` b ``` - c "##; let expected = r##"
  • a
  • b
    
    
    
  • c
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_319() { let original = r##"- a - b c - d "##; let expected = r##"
  • a
    • b

      c

  • d
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_320() { let original = r##"* a > b > * c "##; let expected = r##"
  • a

    b

  • c
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_321() { let original = r##"- a > b ``` c ``` - d "##; let expected = r##"
  • a

    b

    c
    
  • d
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_322() { let original = r##"- a "##; let expected = r##"
  • a
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_323() { let original = r##"- a - b "##; let expected = r##"
  • a
    • b
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_324() { let original = r##"1. ``` foo ``` bar "##; let expected = r##"
  1. foo
    

    bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_325() { let original = r##"* foo * bar baz "##; let expected = r##"
  • foo

    • bar

    baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_326() { let original = r##"- a - b - c - d - e - f "##; let expected = r##"
  • a

    • b
    • c
  • d

    • e
    • f
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_327() { let original = r##"`hi`lo` "##; let expected = r##"

hilo`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_328() { let original = r##"`foo` "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_329() { let original = r##"`` foo ` bar `` "##; let expected = r##"

foo ` bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_330() { let original = r##"` `` ` "##; let expected = r##"

``

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_331() { let original = r##"` `` ` "##; let expected = r##"

``

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_332() { let original = r##"` a` "##; let expected = r##"

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_333() { let original = r##"` b ` "##; let expected = r##"

 b 

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_334() { let original = r##"` ` ` ` "##; let expected = r##"

 

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_335() { let original = r##"`` foo bar baz `` "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_336() { let original = r##"`` foo `` "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_337() { let original = r##"`foo bar baz` "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_338() { let original = r##"`foo\`bar` "##; let expected = r##"

foo\bar`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_339() { let original = r##"``foo`bar`` "##; let expected = r##"

foo`bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_340() { let original = r##"` foo `` bar ` "##; let expected = r##"

foo `` bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_341() { let original = r##"*foo`*` "##; let expected = r##"

*foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_342() { let original = r##"[not a `link](/foo`) "##; let expected = r##"

[not a link](/foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_343() { let original = r##"`` "##; let expected = r##"

<a href="">`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_344() { let original = r##"
` "##; let expected = r##"

`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_345() { let original = r##"`` "##; let expected = r##"

<https://foo.bar.baz>`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_346() { let original = r##"` "##; let expected = r##"

https://foo.bar.`baz`

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_347() { let original = r##"```foo`` "##; let expected = r##"

```foo``

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_348() { let original = r##"`foo "##; let expected = r##"

`foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_349() { let original = r##"`foo``bar`` "##; let expected = r##"

`foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_350() { let original = r##"*foo bar* "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_351() { let original = r##"a * foo bar* "##; let expected = r##"

a * foo bar*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_352() { let original = r##"a*"foo"* "##; let expected = r##"

a*"foo"*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_353() { let original = r##"* a * "##; let expected = r##"

* a *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_354() { let original = r##"*$*alpha. *£*bravo. *€*charlie. "##; let expected = r##"

*$*alpha.

*£*bravo.

*€*charlie.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_355() { let original = r##"foo*bar* "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_356() { let original = r##"5*6*78 "##; let expected = r##"

5678

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_357() { let original = r##"_foo bar_ "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_358() { let original = r##"_ foo bar_ "##; let expected = r##"

_ foo bar_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_359() { let original = r##"a_"foo"_ "##; let expected = r##"

a_"foo"_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_360() { let original = r##"foo_bar_ "##; let expected = r##"

foo_bar_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_361() { let original = r##"5_6_78 "##; let expected = r##"

5_6_78

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_362() { let original = r##"пристаням_стремятся_ "##; let expected = r##"

пристаням_стремятся_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_363() { let original = r##"aa_"bb"_cc "##; let expected = r##"

aa_"bb"_cc

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_364() { let original = r##"foo-_(bar)_ "##; let expected = r##"

foo-(bar)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_365() { let original = r##"_foo* "##; let expected = r##"

_foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_366() { let original = r##"*foo bar * "##; let expected = r##"

*foo bar *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_367() { let original = r##"*foo bar * "##; let expected = r##"

*foo bar *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_368() { let original = r##"*(*foo) "##; let expected = r##"

*(*foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_369() { let original = r##"*(*foo*)* "##; let expected = r##"

(foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_370() { let original = r##"*foo*bar "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_371() { let original = r##"_foo bar _ "##; let expected = r##"

_foo bar _

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_372() { let original = r##"_(_foo) "##; let expected = r##"

_(_foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_373() { let original = r##"_(_foo_)_ "##; let expected = r##"

(foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_374() { let original = r##"_foo_bar "##; let expected = r##"

_foo_bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_375() { let original = r##"_пристаням_стремятся "##; let expected = r##"

_пристаням_стремятся

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_376() { let original = r##"_foo_bar_baz_ "##; let expected = r##"

foo_bar_baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_377() { let original = r##"_(bar)_. "##; let expected = r##"

(bar).

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_378() { let original = r##"**foo bar** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_379() { let original = r##"** foo bar** "##; let expected = r##"

** foo bar**

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_380() { let original = r##"a**"foo"** "##; let expected = r##"

a**"foo"**

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_381() { let original = r##"foo**bar** "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_382() { let original = r##"__foo bar__ "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_383() { let original = r##"__ foo bar__ "##; let expected = r##"

__ foo bar__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_384() { let original = r##"__ foo bar__ "##; let expected = r##"

__ foo bar__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_385() { let original = r##"a__"foo"__ "##; let expected = r##"

a__"foo"__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_386() { let original = r##"foo__bar__ "##; let expected = r##"

foo__bar__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_387() { let original = r##"5__6__78 "##; let expected = r##"

5__6__78

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_388() { let original = r##"пристаням__стремятся__ "##; let expected = r##"

пристаням__стремятся__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_389() { let original = r##"__foo, __bar__, baz__ "##; let expected = r##"

foo, bar, baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_390() { let original = r##"foo-__(bar)__ "##; let expected = r##"

foo-(bar)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_391() { let original = r##"**foo bar ** "##; let expected = r##"

**foo bar **

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_392() { let original = r##"**(**foo) "##; let expected = r##"

**(**foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_393() { let original = r##"*(**foo**)* "##; let expected = r##"

(foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_394() { let original = r##"**Gomphocarpus (*Gomphocarpus physocarpus*, syn. *Asclepias physocarpa*)** "##; let expected = r##"

Gomphocarpus (Gomphocarpus physocarpus, syn. Asclepias physocarpa)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_395() { let original = r##"**foo "*bar*" foo** "##; let expected = r##"

foo "bar" foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_396() { let original = r##"**foo**bar "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_397() { let original = r##"__foo bar __ "##; let expected = r##"

__foo bar __

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_398() { let original = r##"__(__foo) "##; let expected = r##"

__(__foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_399() { let original = r##"_(__foo__)_ "##; let expected = r##"

(foo)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_400() { let original = r##"__foo__bar "##; let expected = r##"

__foo__bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_401() { let original = r##"__пристаням__стремятся "##; let expected = r##"

__пристаням__стремятся

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_402() { let original = r##"__foo__bar__baz__ "##; let expected = r##"

foo__bar__baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_403() { let original = r##"__(bar)__. "##; let expected = r##"

(bar).

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_404() { let original = r##"*foo [bar](/url)* "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_405() { let original = r##"*foo bar* "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_406() { let original = r##"_foo __bar__ baz_ "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_407() { let original = r##"_foo _bar_ baz_ "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_408() { let original = r##"__foo_ bar_ "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_409() { let original = r##"*foo *bar** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_410() { let original = r##"*foo **bar** baz* "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_411() { let original = r##"*foo**bar**baz* "##; let expected = r##"

foobarbaz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_412() { let original = r##"*foo**bar* "##; let expected = r##"

foo**bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_413() { let original = r##"***foo** bar* "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_414() { let original = r##"*foo **bar*** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_415() { let original = r##"*foo**bar*** "##; let expected = r##"

foobar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_416() { let original = r##"foo***bar***baz "##; let expected = r##"

foobarbaz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_417() { let original = r##"foo******bar*********baz "##; let expected = r##"

foobar***baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_418() { let original = r##"*foo **bar *baz* bim** bop* "##; let expected = r##"

foo bar baz bim bop

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_419() { let original = r##"*foo [*bar*](/url)* "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_420() { let original = r##"** is not an empty emphasis "##; let expected = r##"

** is not an empty emphasis

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_421() { let original = r##"**** is not an empty strong emphasis "##; let expected = r##"

**** is not an empty strong emphasis

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_422() { let original = r##"**foo [bar](/url)** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_423() { let original = r##"**foo bar** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_424() { let original = r##"__foo _bar_ baz__ "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_425() { let original = r##"__foo __bar__ baz__ "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_426() { let original = r##"____foo__ bar__ "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_427() { let original = r##"**foo **bar**** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_428() { let original = r##"**foo *bar* baz** "##; let expected = r##"

foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_429() { let original = r##"**foo*bar*baz** "##; let expected = r##"

foobarbaz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_430() { let original = r##"***foo* bar** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_431() { let original = r##"**foo *bar*** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_432() { let original = r##"**foo *bar **baz** bim* bop** "##; let expected = r##"

foo bar baz bim bop

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_433() { let original = r##"**foo [*bar*](/url)** "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_434() { let original = r##"__ is not an empty emphasis "##; let expected = r##"

__ is not an empty emphasis

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_435() { let original = r##"____ is not an empty strong emphasis "##; let expected = r##"

____ is not an empty strong emphasis

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_436() { let original = r##"foo *** "##; let expected = r##"

foo ***

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_437() { let original = r##"foo *\** "##; let expected = r##"

foo *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_438() { let original = r##"foo *_* "##; let expected = r##"

foo _

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_439() { let original = r##"foo ***** "##; let expected = r##"

foo *****

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_440() { let original = r##"foo **\*** "##; let expected = r##"

foo *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_441() { let original = r##"foo **_** "##; let expected = r##"

foo _

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_442() { let original = r##"**foo* "##; let expected = r##"

*foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_443() { let original = r##"*foo** "##; let expected = r##"

foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_444() { let original = r##"***foo** "##; let expected = r##"

*foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_445() { let original = r##"****foo* "##; let expected = r##"

***foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_446() { let original = r##"**foo*** "##; let expected = r##"

foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_447() { let original = r##"*foo**** "##; let expected = r##"

foo***

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_448() { let original = r##"foo ___ "##; let expected = r##"

foo ___

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_449() { let original = r##"foo _\__ "##; let expected = r##"

foo _

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_450() { let original = r##"foo _*_ "##; let expected = r##"

foo *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_451() { let original = r##"foo _____ "##; let expected = r##"

foo _____

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_452() { let original = r##"foo __\___ "##; let expected = r##"

foo _

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_453() { let original = r##"foo __*__ "##; let expected = r##"

foo *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_454() { let original = r##"__foo_ "##; let expected = r##"

_foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_455() { let original = r##"_foo__ "##; let expected = r##"

foo_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_456() { let original = r##"___foo__ "##; let expected = r##"

_foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_457() { let original = r##"____foo_ "##; let expected = r##"

___foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_458() { let original = r##"__foo___ "##; let expected = r##"

foo_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_459() { let original = r##"_foo____ "##; let expected = r##"

foo___

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_460() { let original = r##"**foo** "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_461() { let original = r##"*_foo_* "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_462() { let original = r##"__foo__ "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_463() { let original = r##"_*foo*_ "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_464() { let original = r##"****foo**** "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_465() { let original = r##"____foo____ "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_466() { let original = r##"******foo****** "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_467() { let original = r##"***foo*** "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_468() { let original = r##"_____foo_____ "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_469() { let original = r##"*foo _bar* baz_ "##; let expected = r##"

foo _bar baz_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_470() { let original = r##"*foo __bar *baz bim__ bam* "##; let expected = r##"

foo bar *baz bim bam

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_471() { let original = r##"**foo **bar baz** "##; let expected = r##"

**foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_472() { let original = r##"*foo *bar baz* "##; let expected = r##"

*foo bar baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_473() { let original = r##"*[bar*](/url) "##; let expected = r##"

*bar*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_474() { let original = r##"_foo [bar_](/url) "##; let expected = r##"

_foo bar_

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_475() { let original = r##"* "##; let expected = r##"

*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_476() { let original = r##"** "##; let expected = r##"

**

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_477() { let original = r##"__ "##; let expected = r##"

__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_478() { let original = r##"*a `*`* "##; let expected = r##"

a *

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_479() { let original = r##"_a `_`_ "##; let expected = r##"

a _

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_480() { let original = r##"**a "##; let expected = r##"

**ahttps://foo.bar/?q=**

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_481() { let original = r##"__a "##; let expected = r##"

__ahttps://foo.bar/?q=__

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_482() { let original = r##"[link](/uri "title") "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_483() { let original = r##"[link](/uri) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_484() { let original = r##"[](./target.md) "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_485() { let original = r##"[link]() "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_486() { let original = r##"[link](<>) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_487() { let original = r##"[]() "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_488() { let original = r##"[link](/my uri) "##; let expected = r##"

[link](/my uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_489() { let original = r##"[link](
) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_490() { let original = r##"[link](foo bar) "##; let expected = r##"

[link](foo bar)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_491() { let original = r##"[link]() "##; let expected = r##"

[link]()

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_492() { let original = r##"[a]() "##; let expected = r##"

a

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_493() { let original = r##"[link]() "##; let expected = r##"

[link](<foo>)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_494() { let original = r##"[a]( [a](c) "##; let expected = r##"

[a](<b)c [a](<b)c> [a](c)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_495() { let original = r##"[link](\(foo\)) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_496() { let original = r##"[link](foo(and(bar))) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_497() { let original = r##"[link](foo(and(bar)) "##; let expected = r##"

[link](foo(and(bar))

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_498() { let original = r##"[link](foo\(and\(bar\)) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_499() { let original = r##"[link]() "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_500() { let original = r##"[link](foo\)\:) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_501() { let original = r##"[link](#fragment) [link](https://example.com#fragment) [link](https://example.com?foo=3#frag) "##; let expected = r##"

link

link

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_502() { let original = r##"[link](foo\bar) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_503() { let original = r##"[link](foo%20bä) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_504() { let original = r##"[link]("title") "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_505() { let original = r##"[link](/url "title") [link](/url 'title') [link](/url (title)) "##; let expected = r##"

link link link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_506() { let original = r##"[link](/url "title \""") "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_507() { let original = r##"[link](/url "title") "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_508() { let original = r##"[link](/url "title "and" title") "##; let expected = r##"

[link](/url "title "and" title")

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_509() { let original = r##"[link](/url 'title "and" title') "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_510() { let original = r##"[link]( /uri "title" ) "##; let expected = r##"

link

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_511() { let original = r##"[link] (/uri) "##; let expected = r##"

[link] (/uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_512() { let original = r##"[link [foo [bar]]](/uri) "##; let expected = r##"

link [foo [bar]]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_513() { let original = r##"[link] bar](/uri) "##; let expected = r##"

[link] bar](/uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_514() { let original = r##"[link [bar](/uri) "##; let expected = r##"

[link bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_515() { let original = r##"[link \[bar](/uri) "##; let expected = r##"

link [bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_516() { let original = r##"[link *foo **bar** `#`*](/uri) "##; let expected = r##"

link foo bar #

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_517() { let original = r##"[![moon](moon.jpg)](/uri) "##; let expected = r##"

moon

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_518() { let original = r##"[foo [bar](/uri)](/uri) "##; let expected = r##"

[foo bar](/uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_519() { let original = r##"[foo *[bar [baz](/uri)](/uri)*](/uri) "##; let expected = r##"

[foo [bar baz](/uri)](/uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_520() { let original = r##"![[[foo](uri1)](uri2)](uri3) "##; let expected = r##"

[foo](uri2)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_521() { let original = r##"*[foo*](/uri) "##; let expected = r##"

*foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_522() { let original = r##"[foo *bar](baz*) "##; let expected = r##"

foo *bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_523() { let original = r##"*foo [bar* baz] "##; let expected = r##"

foo [bar baz]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_524() { let original = r##"[foo "##; let expected = r##"

[foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_525() { let original = r##"[foo`](/uri)` "##; let expected = r##"

[foo](/uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_526() { let original = r##"[foo "##; let expected = r##"

[foohttps://example.com/?search=](uri)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_527() { let original = r##"[foo][bar] [bar]: /url "title" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_528() { let original = r##"[link [foo [bar]]][ref] [ref]: /uri "##; let expected = r##"

link [foo [bar]]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_529() { let original = r##"[link \[bar][ref] [ref]: /uri "##; let expected = r##"

link [bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_530() { let original = r##"[link *foo **bar** `#`*][ref] [ref]: /uri "##; let expected = r##"

link foo bar #

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_531() { let original = r##"[![moon](moon.jpg)][ref] [ref]: /uri "##; let expected = r##"

moon

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_532() { let original = r##"[foo [bar](/uri)][ref] [ref]: /uri "##; let expected = r##"

[foo bar]ref

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_533() { let original = r##"[foo *bar [baz][ref]*][ref] [ref]: /uri "##; let expected = r##"

[foo bar baz]ref

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_534() { let original = r##"*[foo*][ref] [ref]: /uri "##; let expected = r##"

*foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_535() { let original = r##"[foo *bar][ref]* [ref]: /uri "##; let expected = r##"

foo *bar*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_536() { let original = r##"[foo [ref]: /uri "##; let expected = r##"

[foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_537() { let original = r##"[foo`][ref]` [ref]: /uri "##; let expected = r##"

[foo][ref]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_538() { let original = r##"[foo [ref]: /uri "##; let expected = r##"

[foohttps://example.com/?search=][ref]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_539() { let original = r##"[foo][BaR] [bar]: /url "title" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_540() { let original = r##"[ẞ] [SS]: /url "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_541() { let original = r##"[Foo bar]: /url [Baz][Foo bar] "##; let expected = r##"

Baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_542() { let original = r##"[foo] [bar] [bar]: /url "title" "##; let expected = r##"

[foo] bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_543() { let original = r##"[foo] [bar] [bar]: /url "title" "##; let expected = r##"

[foo] bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_544() { let original = r##"[foo]: /url1 [foo]: /url2 [bar][foo] "##; let expected = r##"

bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_545() { let original = r##"[bar][foo\!] [foo!]: /url "##; let expected = r##"

[bar][foo!]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_546() { let original = r##"[foo][ref[] [ref[]: /uri "##; let expected = r##"

[foo][ref[]

[ref[]: /uri

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_547() { let original = r##"[foo][ref[bar]] [ref[bar]]: /uri "##; let expected = r##"

[foo][ref[bar]]

[ref[bar]]: /uri

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_548() { let original = r##"[[[foo]]] [[[foo]]]: /url "##; let expected = r##"

[[[foo]]]

[[[foo]]]: /url

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_549() { let original = r##"[foo][ref\[] [ref\[]: /uri "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_550() { let original = r##"[bar\\]: /uri [bar\\] "##; let expected = r##"

bar\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_551() { let original = r##"[] []: /uri "##; let expected = r##"

[]

[]: /uri

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_552() { let original = r##"[ ] [ ]: /uri "##; let expected = r##"

[ ]

[ ]: /uri

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_553() { let original = r##"[foo][] [foo]: /url "title" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_554() { let original = r##"[*foo* bar][] [*foo* bar]: /url "title" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_555() { let original = r##"[Foo][] [foo]: /url "title" "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_556() { let original = r##"[foo] [] [foo]: /url "title" "##; let expected = r##"

foo []

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_557() { let original = r##"[foo] [foo]: /url "title" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_558() { let original = r##"[*foo* bar] [*foo* bar]: /url "title" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_559() { let original = r##"[[*foo* bar]] [*foo* bar]: /url "title" "##; let expected = r##"

[foo bar]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_560() { let original = r##"[[bar [foo] [foo]: /url "##; let expected = r##"

[[bar foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_561() { let original = r##"[Foo] [foo]: /url "title" "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_562() { let original = r##"[foo] bar [foo]: /url "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_563() { let original = r##"\[foo] [foo]: /url "title" "##; let expected = r##"

[foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_564() { let original = r##"[foo*]: /url *[foo*] "##; let expected = r##"

*foo*

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_565() { let original = r##"[foo][bar] [foo]: /url1 [bar]: /url2 "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_566() { let original = r##"[foo][] [foo]: /url1 "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_567() { let original = r##"[foo]() [foo]: /url1 "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_568() { let original = r##"[foo](not a link) [foo]: /url1 "##; let expected = r##"

foo(not a link)

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_569() { let original = r##"[foo][bar][baz] [baz]: /url "##; let expected = r##"

[foo]bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_570() { let original = r##"[foo][bar][baz] [baz]: /url1 [bar]: /url2 "##; let expected = r##"

foobaz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_571() { let original = r##"[foo][bar][baz] [baz]: /url1 [foo]: /url2 "##; let expected = r##"

[foo]bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_572() { let original = r##"![foo](/url "title") "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_573() { let original = r##"![foo *bar*] [foo *bar*]: train.jpg "train & tracks" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_574() { let original = r##"![foo ![bar](/url)](/url2) "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_575() { let original = r##"![foo [bar](/url)](/url2) "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_576() { let original = r##"![foo *bar*][] [foo *bar*]: train.jpg "train & tracks" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_577() { let original = r##"![foo *bar*][foobar] [FOOBAR]: train.jpg "train & tracks" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_578() { let original = r##"![foo](train.jpg) "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_579() { let original = r##"My ![foo bar](/path/to/train.jpg "title" ) "##; let expected = r##"

My foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_580() { let original = r##"![foo]() "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_581() { let original = r##"![](/url) "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_582() { let original = r##"![foo][bar] [bar]: /url "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_583() { let original = r##"![foo][bar] [BAR]: /url "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_584() { let original = r##"![foo][] [foo]: /url "title" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_585() { let original = r##"![*foo* bar][] [*foo* bar]: /url "title" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_586() { let original = r##"![Foo][] [foo]: /url "title" "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_587() { let original = r##"![foo] [] [foo]: /url "title" "##; let expected = r##"

foo []

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_588() { let original = r##"![foo] [foo]: /url "title" "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_589() { let original = r##"![*foo* bar] [*foo* bar]: /url "title" "##; let expected = r##"

foo bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_590() { let original = r##"![[foo]] [[foo]]: /url "title" "##; let expected = r##"

![[foo]]

[[foo]]: /url "title"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_591() { let original = r##"![Foo] [foo]: /url "title" "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_592() { let original = r##"!\[foo] [foo]: /url "title" "##; let expected = r##"

![foo]

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_593() { let original = r##"\![foo] [foo]: /url "title" "##; let expected = r##"

!foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_594() { let original = r##" "##; let expected = r##"

http://foo.bar.baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_595() { let original = r##" "##; let expected = r##"

https://foo.bar.baz/test?q=hello&id=22&boolean

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_596() { let original = r##" "##; let expected = r##"

irc://foo.bar:2233/baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_597() { let original = r##" "##; let expected = r##"

MAILTO:FOO@BAR.BAZ

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_598() { let original = r##" "##; let expected = r##"

a+b+c:d

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_599() { let original = r##" "##; let expected = r##"

made-up-scheme://foo,bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_600() { let original = r##" "##; let expected = r##"

https://../

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_601() { let original = r##" "##; let expected = r##"

localhost:5001/foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_602() { let original = r##" "##; let expected = r##"

<https://foo.bar/baz bim>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_603() { let original = r##" "##; let expected = r##"

https://example.com/\[\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_604() { let original = r##" "##; let expected = r##"

foo@bar.example.com

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_605() { let original = r##" "##; let expected = r##"

foo+special@Bar.baz-bar0.com

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_606() { let original = r##" "##; let expected = r##"

<foo+@bar.example.com>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_607() { let original = r##"<> "##; let expected = r##"

<>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_608() { let original = r##"< https://foo.bar > "##; let expected = r##"

< https://foo.bar >

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_609() { let original = r##" "##; let expected = r##"

<m:abc>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_610() { let original = r##" "##; let expected = r##"

<foo.bar.baz>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_611() { let original = r##"https://example.com "##; let expected = r##"

https://example.com

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_612() { let original = r##"foo@bar.example.com "##; let expected = r##"

foo@bar.example.com

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_613() { let original = r##" "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_614() { let original = r##" "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_615() { let original = r##" "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_616() { let original = r##" "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_617() { let original = r##"Foo "##; let expected = r##"

Foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_618() { let original = r##"<33> <__> "##; let expected = r##"

<33> <__>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_619() { let original = r##"
"##; let expected = r##"

<a h*#ref="hi">

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_620() { let original = r##"
<a href="hi'> <a href=hi'>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_621() { let original = r##"< a>< foo> "##; let expected = r##"

< a>< foo><bar/ > <foo bar=baz bim!bop />

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_622() { let original = r##"
"##; let expected = r##"

<a href='bar'title=title>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_623() { let original = r##"
"##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_624() { let original = r##" "##; let expected = r##"

</a href="foo">

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_625() { let original = r##"foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_626() { let original = r##"foo foo --> foo foo --> "##; let expected = r##"

foo foo -->

foo foo -->

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_627() { let original = r##"foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_628() { let original = r##"foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_629() { let original = r##"foo &<]]> "##; let expected = r##"

foo &<]]>

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_630() { let original = r##"foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_631() { let original = r##"foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_632() { let original = r##" "##; let expected = r##"

<a href=""">

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_633() { let original = r##"foo baz "##; let expected = r##"

foo
baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_634() { let original = r##"foo\ baz "##; let expected = r##"

foo
baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_635() { let original = r##"foo baz "##; let expected = r##"

foo
baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_636() { let original = r##"foo bar "##; let expected = r##"

foo
bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_637() { let original = r##"foo\ bar "##; let expected = r##"

foo
bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_638() { let original = r##"*foo bar* "##; let expected = r##"

foo
bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_639() { let original = r##"*foo\ bar* "##; let expected = r##"

foo
bar

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_640() { let original = r##"`code span` "##; let expected = r##"

code span

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_641() { let original = r##"`code\ span` "##; let expected = r##"

code\ span

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_642() { let original = r##"
"##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_643() { let original = r##" "##; let expected = r##"

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_644() { let original = r##"foo\ "##; let expected = r##"

foo\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_645() { let original = r##"foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_646() { let original = r##"### foo\ "##; let expected = r##"

foo\

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_647() { let original = r##"### foo "##; let expected = r##"

foo

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_648() { let original = r##"foo baz "##; let expected = r##"

foo baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_649() { let original = r##"foo baz "##; let expected = r##"

foo baz

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_650() { let original = r##"hello $.;'there "##; let expected = r##"

hello $.;'there

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_651() { let original = r##"Foo χρῆν "##; let expected = r##"

Foo χρῆν

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn spec_test_652() { let original = r##"Multiple spaces "##; let expected = r##"

Multiple spaces

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/strikethrough.rs000064400000000000000000000073151046102023000204150ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn strikethrough_test_1() { let original = r##"~~This is *stricken out*~~ "##; let expected = r##"

This is stricken out

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_2() { let original = r##"~~This is \~\~stricken~~ "##; let expected = r##"

This is ~~stricken

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_3() { let original = r##"This~~is~~stricken "##; let expected = r##"

Thisisstricken

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_4() { let original = r##"~~This~~is~~stricken~~ "##; let expected = r##"

Thisisstricken

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_5() { let original = r##"Here I strike out an exclamation point~~!~~. "##; let expected = r##"

Here I strike out an exclamation point!.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_6() { let original = r##"~This is stricken out~ "##; let expected = r##"

This is stricken out

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_7() { let original = r##"~This is \~stricken~ "##; let expected = r##"

This is ~stricken

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_8() { let original = r##"This~is~nothing "##; let expected = r##"

This~is~nothing

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_9() { let original = r##"~This~is~nothing~ "##; let expected = r##"

This~is~nothing

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_10() { let original = r##"Here I fail to strike out an exclamation point~!~. "##; let expected = r##"

Here I fail to strike out an exclamation point~!~.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_11() { let original = r##"Here I fail to strike out a tilde ~~~. "##; let expected = r##"

Here I fail to strike out a tilde ~~~.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_12() { let original = r##"Here I fail to match up ~~tildes~. "##; let expected = r##"

Here I fail to match up ~~tildes~.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_13() { let original = r##"Here I fail to match up ~tildes~~. "##; let expected = r##"

Here I fail to match up ~tildes~~.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_14() { let original = r##"~~This ~is stricken.~~ "##; let expected = r##"

This ~is stricken.

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn strikethrough_test_15() { let original = r##"~This ~~is stricken.~ "##; let expected = r##"

This ~~is stricken.

"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/super_sub.rs000064400000000000000000000030161046102023000175140ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn super_sub_test_1() { let original = r##"^This is super^ ~This is sub~ "##; let expected = r##"

This is super This is sub

"##; test_markdown_html(original, expected, false, false, false, true, false); } #[test] fn super_sub_test_2() { let original = r##"~This is stricken out~ "##; let expected = r##"

This is stricken out

"##; test_markdown_html(original, expected, false, false, false, true, false); } #[test] fn super_sub_test_3() { let original = r##"~This is \~stricken~ "##; let expected = r##"

This is ~stricken

"##; test_markdown_html(original, expected, false, false, false, true, false); } #[test] fn super_sub_test_4() { let original = r##"~This~is~nothing~ "##; let expected = r##"

This~is~nothing

"##; test_markdown_html(original, expected, false, false, false, true, false); } #[test] fn super_sub_test_5() { let original = r##"~This ~~is stricken.~ "##; let expected = r##"

This ~~is stricken.

"##; test_markdown_html(original, expected, false, false, false, true, false); } #[test] fn super_sub_test_6() { let original = r##"~This ~~is stricken~ but this is not~~ "##; let expected = r##"

This ~~is stricken but this is not~~

"##; test_markdown_html(original, expected, false, false, false, true, false); } pulldown-cmark-0.13.0/tests/suite/table.rs000064400000000000000000000355421046102023000166050ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn table_test_1() { let original = r##"Test header ----------- "##; let expected = r##"

Test header

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_2() { let original = r##"Test|Table ----|----- "##; let expected = r##"
TestTable
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_3() { let original = r##"> Test | Table > ------|------ > Row 1 | Every > Row 2 | Day > > Paragraph "##; let expected = r##"
TestTable
Row 1Every
Row 2Day

Paragraph

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_4() { let original = r##" 1. First entry 2. Second entry Col 1|Col 2 -|- Row 1|Part 2 Row 2|Part 2 "##; let expected = r##"
  1. First entry

  2. Second entry

    Col 1Col 2
    Row 1Part 2
    Row 2Part 2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_5() { let original = r##"|Col 1|Col 2| |-----|-----| |R1C1 |R1C2 | |R2C1 |R2C2 | "##; let expected = r##"
Col 1Col 2
R1C1R1C2
R2C1R2C2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_6() { let original = r##"| Col 1 | Col 2 | |-------|-------| | | | | | | "##; let expected = r##"
Col 1Col 2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_7() { let original = r##"| Col 1 | Col 2 | |-------|-------| | x | | | | x | "##; let expected = r##"
Col 1Col 2
x
x
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_8() { let original = r##"|Col 1|Col 2| |-----|-----| |✓ |✓ | |✓ |✓ | "##; let expected = r##"
Col 1Col 2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_9() { let original = r##"| Target | std |rustc|cargo| notes | |-------------------------------|-----|-----|-----|----------------------------| | `x86_64-unknown-linux-musl` | ✓ | | | 64-bit Linux with MUSL | | `arm-linux-androideabi` | ✓ | | | ARM Android | | `arm-unknown-linux-gnueabi` | ✓ | ✓ | | ARM Linux (2.6.18+) | | `arm-unknown-linux-gnueabihf` | ✓ | ✓ | | ARM Linux (2.6.18+) | | `aarch64-unknown-linux-gnu` | ✓ | | | ARM64 Linux (2.6.18+) | | `mips-unknown-linux-gnu` | ✓ | | | MIPS Linux (2.6.18+) | | `mipsel-unknown-linux-gnu` | ✓ | | | MIPS (LE) Linux (2.6.18+) | "##; let expected = r##"
Targetstdrustccargonotes
x86_64-unknown-linux-musl64-bit Linux with MUSL
arm-linux-androideabiARM Android
arm-unknown-linux-gnueabiARM Linux (2.6.18+)
arm-unknown-linux-gnueabihfARM Linux (2.6.18+)
aarch64-unknown-linux-gnuARM64 Linux (2.6.18+)
mips-unknown-linux-gnuMIPS Linux (2.6.18+)
mipsel-unknown-linux-gnuMIPS (LE) Linux (2.6.18+)
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_10() { let original = r##"|-|-| |ぃ|い| "##; let expected = r##"

|-|-| |ぃ|い|

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_11() { let original = r##"|ぁ|ぃ| |-|-| |ぃ|ぃ| "##; let expected = r##"
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_12() { let original = r##"|Колонка 1|Колонка 2| |---------|---------| |Ячейка 1 |Ячейка 2 | "##; let expected = r##"
Колонка 1Колонка 2
Ячейка 1Ячейка 2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_13() { let original = r##"table a | a | b | | --- | --- | | c | d | table b | a | b | | --- | --- | | c | d | table c a | b --- | --- c | d table d a | b --|-- c | d table e a | b --|-- c | d table f | a | b | | --- | --- | | c | d | table g a | b --- | --- c | d table h a |-| b table i | a |- b table j | a - b "##; let expected = r##"

table a

ab
cd

table b | a | b | | --- | --- | | c | d |

table c a | b --- | --- c | d

table d a | b --|-- c | d

table e a | b --|-- c | d

table f

ab
cd

table g a | b --- | --- c | d

table h a |-| b

table i

a
b

table j | a

b

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_14() { let original = r##"a | b - | - 1 | 2 "##; let expected = r##"
ab
12
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_15() { let original = r##"a | b\ - | - 1 | 2 "##; let expected = r##"

a | b\

  • | - 1 | 2
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_16() { let original = r##"a\ | b | c | |---|---| | d | e | "##; let expected = r##"

a\

bc
de
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_17() { let original = r##"| Description | Test case | |-------------|-----------| | Single | `\` | | Double | `\\` | | Basic test | `\|` | | Basic test 2| `\|\|\` | | Basic test 3| `x\|y\|z\`| | Not pipe | `\.` | | Combo | `\.\|\` | | Extra | `\\\.` | | Wait, what? | `\\|` | | Wait, what? | `\\\|` | | Wait, what? | `\\\\|` | | Wait, what? | `\\\\\|` | | Wait, what? | \| | Wait, what? | \\| | Wait, what? | \\\| | Wait, what?x| \|x | Wait, what?x| \\|x | Wait, what?x| \\\|x | Direct trail| \.|x "##; let expected = r##"
DescriptionTest case
Single\
Double\\
Basic test|
Basic test 2||\
Basic test 3x|y|z\
Not pipe\.
Combo\.|\
Extra\\\.
Wait, what?\|
Wait, what?\\|
Wait, what?\\\|
Wait, what?\\\\|
Wait, what?|
Wait, what?|
Wait, what?\|
Wait, what?x|x
Wait, what?x|x
Wait, what?x\|x
Direct trail.
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_18() { let original = r##"| Single | `\|` | |--|--| | Single | `\|` | | Double | `\\|` | |--|--| | Double | `\\|` | | Double Twice | `\\|\\|` | |--|--| | Double Twice | `\\|\\|` | | Triple | `\\\|` | |--|--| | Triple | `\\\|` | "##; let expected = r##"
Single|
Single|
Double\|
Double\|
Double Twice\|\|
Double Twice\|\|
Triple\\|
Triple\\|
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_19() { let original = r##"| Table | Header | |-------|--------| | Table | Body | | | Not | Enough | | Table | Header | |-------|--------| | Table | Body | | | Not | Enough | "##; let expected = r##"
TableHeader
TableBody

| | Not | Enough |

TableHeader
TableBody

| | Not | Enough |

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_20() { let original = r##"| Table | Header | |-------|--------| | "##; let expected = r##"
TableHeader

|

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_21() { let original = r##"| |-------|--------| | Table | Body | "##; let expected = r##"

| |-------|--------| | Table | Body |

"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_22() { let original = r##"| Single | [test](first\|second) | |--|--| | Double | [test](first\\|second) | |--|--| | Triple | [test](first\\\|second) | |--|--| "##; let expected = r##"
Singletest
Doubletest
Tripletest
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_23() { let original = r##"| Single | [first\|second] | |--|--| | Double | [first\\|second] | |--|--| | Triple | [first\\\|second] | |--|--| [first\|second]: https://rust-lang.org [first\\|second]: https://docs.rs "##; let expected = r##"
Single[first|second]
Doublefirst|second
Triplefirst\|second
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_24() { let original = r##"Q: Knock knock. A: Who's there. Q: Interrupting cow. A: Interrupting —? | `Moo\\|ooo` | |-------------| | `ooo\\|ooo` | "##; let expected = r##"

Q: Knock knock. A: Who's there. Q: Interrupting cow. A: Interrupting —?

Moo\|ooo
ooo\|ooo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_25() { let original = r##"| ![Moo\\|Moo](image.png) | |-------------| | ![Moo\\\|Moo](image.png) | "##; let expected = r##"
Moo|Moo
Moo\|Moo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_26() { let original = r##"| [Moo](https://example.org "Example\\|Link") | |---------------------------------------------| | [Moo](https://example.org "Example\\\|Link") | "##; let expected = r##"
Moo
Moo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_27() { let original = r##"moo | moo ----|---- moo | moo * "##; let expected = r##"
moomoo
moomoo
"##; test_markdown_html(original, expected, false, false, false, false, false); } #[test] fn table_test_28() { let original = r##"moo | moo ----|---- moo | moo 2. "##; let expected = r##"
moomoo
moomoo
"##; test_markdown_html(original, expected, false, false, false, false, false); } pulldown-cmark-0.13.0/tests/suite/wikilinks.rs000064400000000000000000000134201046102023000175110ustar 00000000000000// This file is auto-generated by the build script // Please, do not modify it manually use super::test_markdown_html; #[test] fn wikilinks_test_1() { let original = r##"This is a [[WikiLink]]. "##; let expected = r##"

This is a WikiLink.

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_2() { let original = r##"This is a [[Main/WikiLink]]. "##; let expected = r##"

This is a Main/WikiLink.

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_3() { let original = r##"This is [[Ambiguous]]. [Ambiguous]: https://example.com/ "##; let expected = r##"

This is Ambiguous.

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_4() { let original = r##"[[squid] calamari is considered a delicacy](https://en.wikipedia.org/wiki/Squid) [calamari [squid]](https://en.wikipedia.org/wiki/Squid) "##; let expected = r##"

[squid] calamari is considered a delicacy

calamari [squid]

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_5() { let original = r##"This is [also [[Ambiguous]]](https://example.com/). "##; let expected = r##"

This is [also Ambiguous](https://example.com/).

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_6() { let original = r##" [[https://example.org/]] "##; let expected = r##"

https://example.org/

https://example.org/

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_7() { let original = r##"This is [[WikiLink|a pothole]]. "##; let expected = r##"

This is a pothole.

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_8() { let original = r##"This is a [[WikiLink/In/A/Directory|WikiLink]]. "##; let expected = r##"

This is a WikiLink.

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_9() { let original = r##"This is [[WikiLink|a **strong** pothole]]. "##; let expected = r##"

This is a strong pothole.

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_10() { let original = r##"This is a cute dog, linked to the page "WikiLink" [[WikiLink|![dog](dog.png)]] "##; let expected = r##"

This is a cute dog, linked to the page "WikiLink"

dog

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_11() { let original = r##"[[WikiLink|[[Fish]]]] "##; let expected = r##"

[[WikiLink|Fish]]

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_12() { let original = r##"[[WikiLink|[cat](cat.html)]] "##; let expected = r##"

[[WikiLink|cat]]

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_13() { let original = r##"This is a cute dog. ![[dog.png]] "##; let expected = r##"

This is a cute dog.

dog.png

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_14() { let original = r##"![[dog.png|a cute dog]] "##; let expected = r##"

a cute dog

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_15() { let original = r##"]] [[]] [[|]] [[|Symbol]] [[ "##; let expected = r##"

]] [[]] [[|]] [[|Symbol]] [[

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_16() { let original = r##"[inline link]([[url]]) "##; let expected = r##"

inline link

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_17() { let original = r##"[inline link]([[url)]] "##; let expected = r##"

inline link]]

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_18() { let original = r##"`[[code]]` "##; let expected = r##"

[[code]]

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_19() { let original = r##"emphasis **cross [[over** here]] "##; let expected = r##"

emphasis **cross over** here

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_20() { let original = r##"[[first\|second]] "##; let expected = r##"

second

"##; test_markdown_html(original, expected, false, false, false, false, true); } #[test] fn wikilinks_test_21() { let original = r##"[[first!second]] "##; let expected = r##"

first&#33;second

"##; test_markdown_html(original, expected, false, false, false, false, true); }