~autumnull/flatiron

fe4c3fca8713d11b037dbc3f9d87b6c0c8fdfc99 — Autumn! 2 years ago c526023
Added blockcode class and refactored.
8 files changed, 65 insertions(+), 51 deletions(-)

M Cargo.lock
M Cargo.toml
M src/lib.rs
M src/parse/block.rs
M src/render.rs
M src/structs.rs
R samples/textism.html => tests/html/textism.html
M tests/integrated.rs
M Cargo.lock => Cargo.lock +1 -1
@@ 4,7 4,7 @@ version = 3

[[package]]
name = "flatiron"
version = "1.0.1"
version = "1.0.2"
dependencies = [
 "nom",
]

M Cargo.toml => Cargo.toml +1 -1
@@ 1,6 1,6 @@
[package]
name = "flatiron"
version = "1.0.1"
version = "1.0.2"
edition = "2021"
description = "A parser and HTML renderer for the Textile markup language"
license-file = "LICENSE.textile"

M src/lib.rs => src/lib.rs +3 -5
@@ 15,11 15,9 @@ mod structs;
/// ```
/// use flatiron::convert;
///
/// fn example() {
///     let textile = String::from("h1. Is this thing on?");
///     let html = convert(textile);
///     assert_eq!(html, String::from("<h1>Is this thing on?</h1>\n"));
/// }
/// let textile = String::from("h1. Is this thing on?");
/// let html = convert(textile);
/// assert_eq!(html, String::from("<h1>Is this thing on?</h1>\n"));
/// ```
pub fn convert(input: String) -> String {
    let (_, textile) = complete(parse::textile)(&input).unwrap();

M src/parse/block.rs => src/parse/block.rs +4 -30
@@ 58,7 58,10 @@ pub fn block(input: &str) -> IResult<&str, BlockTag> {
    let (rest, _) = alt((eof, end_of_block))(&rest[i..])?;

    match kind {
        BlockKind::Paragraph | BlockKind::Header(_) | BlockKind::BlockQuote => {
        BlockKind::Paragraph
        | BlockKind::Header(_)
        | BlockKind::Footnote(_)
        | BlockKind::BlockQuote => {
            let (_, content) = complete(phrase)(body)?;
            Ok((
                rest,


@@ 73,35 76,6 @@ pub fn block(input: &str) -> IResult<&str, BlockTag> {
                },
            ))
        }
        BlockKind::Footnote(n) => {
            let mut attributes = attributes.unwrap_or(Attributes {
                class: None,
                id: None,
                style: None,
                language: None,
            });
            attributes.class = match attributes.class {
                Some(s) => Some(format!("footnote {}", s)),
                None => Some(String::from("footnote")),
            };
            attributes.id = match attributes.id {
                Some(s) => Some(format!("fn{} {}", n, s)),
                None => Some(format!("fn{}", n)),
            };
            let (_, content) = complete(phrase)(body)?;
            Ok((
                rest,
                BlockTag::Basic {
                    kind,
                    header: BlockHeader {
                        indent,
                        align,
                        attributes: Some(attributes),
                    },
                    content,
                },
            ))
        }
        BlockKind::BlockCode | BlockKind::Preformatted => {
            let mut content = String::from(body);
            if let Ok((_, stripped)) = complete(strip_flatiron_extended)(body) {

M src/render.rs => src/render.rs +49 -7
@@ 25,10 25,32 @@ impl fmt::Display for BlockTag {
                content,
            } => match kind {
                BlockKind::Footnote(n) => {
                    // prepend footnote class and id
                    let mut attributes =
                        header.attributes.clone().unwrap_or(Attributes {
                            class: None,
                            id: None,
                            style: None,
                            language: None,
                        });
                    attributes.class = match attributes.class {
                        Some(s) => Some(format!("footnote {}", s)),
                        None => Some(String::from("footnote")),
                    };
                    attributes.id = match attributes.id {
                        Some(s) => Some(format!("fn{} {}", n, s)),
                        None => Some(format!("fn{}", n)),
                    };
                    let new_header = BlockHeader {
                        attributes: Some(attributes),
                        indent: header.indent.clone(),
                        align: header.align,
                    };

                    write!(
                        f,
                        "<p{}><sup>{}</sup>{}<a href=\"#fnr{}\">&21A9;</a></p>",
                        header, n, content, n
                        new_header, n, content, n
                    )
                }
                BlockKind::Paragraph


@@ 46,12 68,32 @@ impl fmt::Display for BlockTag {
                BlockKind::Preformatted => {
                    write!(f, "<pre{}>{}</pre>", header, html_escape(content))
                }
                BlockKind::BlockCode => write!(
                    f,
                    "<pre{}><code>{}</code></pre>",
                    header,
                    html_escape(content)
                ),
                BlockKind::BlockCode => {
                    // prepend blockcode class
                    let mut attributes =
                        header.attributes.clone().unwrap_or(Attributes {
                            class: None,
                            id: None,
                            style: None,
                            language: None,
                        });
                    attributes.class = match attributes.class {
                        Some(s) => Some(format!("blockcode {}", s)),
                        None => Some(String::from("blockcode")),
                    };
                    let new_header = BlockHeader {
                        attributes: Some(attributes),
                        indent: header.indent.clone(),
                        align: header.align,
                    };

                    write!(
                        f,
                        "<pre{}><code>{}</code></pre>",
                        new_header,
                        html_escape(content)
                    )
                }
                _ => Err(fmt::Error), // other kinds should not be possible here
            },
            BlockTag::List { header, content } => {

M src/structs.rs => src/structs.rs +2 -2
@@ 88,7 88,7 @@ pub enum CellKind {
    Data,
}

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub struct Indent {
    pub left: usize,
    pub right: usize,


@@ 109,7 109,7 @@ pub enum VerticalAlign {
    Bottom,
}

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub struct Attributes {
    pub class: Option<String>,
    pub id: Option<String>,

R samples/textism.html => tests/html/textism.html +4 -4
@@ 1,7 1,7 @@
<h2 style="color:green">This is a title</h2>
<h3>This is a subhead</h3>
<p style="color:red">This is some text of dubious character. Isn’t the use of “quotes” just lazy writing — and theft of ‘intellectual property’ besides? I think the time has come to see a block quote.</p>
<blockquote lang="fr">This is a block quote. I’ll admit it’s not the most exciting block quote ever devised.</blockquote>
<p style="color:red">This is some text of dubious character. Isn&#8217;t the use of &#8220;quotes&#8221; just lazy writing &#8212; and theft of &#8216;intellectual property&#8217; besides? I think the time has come to see a block quote.</p>
<blockquote lang="fr">This is a block quote. I&#8217;ll admit it&#8217;s not the most exciting block quote ever devised.</blockquote>
<p>Simple list:</p>
<ol style="color:blue">
<li>one</li>


@@ 74,10 74,10 @@
That was a linebreak. And something to indicate <strong>strength</strong>. Of course I could use <em>my own <span class="caps">HTML</span> tags</em> if I <strong>felt</strong> like it.</p>
<h3>Coding</h3>
<p>This <code>is some code, "isn't it"</code>. Watch those quote marks! Now for some preformatted text:</p>
<pre><code>$text = str_replace("&lt;p&gt;%::%&lt;/p&gt;","",$text);
<pre class="blockcode"><code>$text = str_replace("&lt;p&gt;%::%&lt;/p&gt;","",$text);
$text = str_replace("%::%&lt;/p&gt;","",$text);
$text = str_replace("%::%","",$text);</code></pre>
<p>This isn’t code.</p>
<p>This isn&#8217;t code.</p>
<p>So you see, my friends:</p>
<ul>
<li>The time is now</li>

M tests/integrated.rs => tests/integrated.rs +1 -1
@@ 12,7 12,7 @@ fn example() {
fn textism() {
    let textile = fs::read_to_string("samples/textism.textile")
        .expect("Something went wrong while reading the textile file");
    let target_html = fs::read_to_string("samples/textism.html")
    let target_html = fs::read_to_string("tests/html/textism.html")
        .expect("Something went wrong while reading the HTML file");

    let html = convert(textile);