Skip to content

Commit

Permalink
feat!: support for controlling the amount of newlines after metadata …
Browse files Browse the repository at this point in the history
…blocks.
  • Loading branch information
Byron committed Mar 17, 2024
2 parents 002be03 + b8ae359 commit 834c74b
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 9 deletions.
17 changes: 15 additions & 2 deletions src/lib.rs
Expand Up @@ -104,6 +104,8 @@ pub struct Options<'a> {
pub newlines_after_list: usize,
pub newlines_after_blockquote: usize,
pub newlines_after_rest: usize,
/// The amount of newlines placed after TOML or YAML metadata blocks at the beginning of a document.
pub newlines_after_metadata: usize,
/// Token count for fenced code block. An appropriate value of this field can be decided by
/// [`calculate_code_block_token_count()`].
/// Note that the default value is `4` which allows for one level of nested code-blocks,
Expand All @@ -127,6 +129,7 @@ const DEFAULT_OPTIONS: Options<'_> = Options {
newlines_after_list: 2,
newlines_after_blockquote: 2,
newlines_after_rest: 1,
newlines_after_metadata: 1,
code_block_token_count: 4,
code_block_token: '`',
list_token: '*',
Expand Down Expand Up @@ -533,8 +536,18 @@ where
}
Ok(())
}
TagEnd::MetadataBlock(MetadataBlockKind::PlusesStyle) => formatter.write_str("+++"),
TagEnd::MetadataBlock(MetadataBlockKind::YamlStyle) => formatter.write_str("..."),
TagEnd::MetadataBlock(MetadataBlockKind::PlusesStyle) => {
if state.newlines_before_start < options.newlines_after_metadata {
state.newlines_before_start = options.newlines_after_metadata;
}
formatter.write_str("+++\n")
}
TagEnd::MetadataBlock(MetadataBlockKind::YamlStyle) => {
if state.newlines_before_start < options.newlines_after_metadata {
state.newlines_before_start = options.newlines_after_metadata;
}
formatter.write_str("---\n")
}
TagEnd::Table => {
if state.newlines_before_start < options.newlines_after_table {
state.newlines_before_start = options.newlines_after_table;
Expand Down
12 changes: 12 additions & 0 deletions tests/cat.sh
Expand Up @@ -81,3 +81,15 @@ title "stupicat"
WITH_SNAPSHOT="$snapshot/stupicat-indented-code-block" \
expect_run_sh $SUCCESSFULLY "${exe[*]} $fixture/indented-code-block.md 2>/dev/null"
)

(with "yaml frontmatter"
it "succeeds" && \
WITH_SNAPSHOT="$snapshot/stupicat-yaml-frontmatter-output" \
expect_run_sh $SUCCESSFULLY "${exe[*]} $fixture/yaml-frontmatter.md 2>/dev/null"
)

(with "toml frontmatter"
it "succeeds" && \
WITH_SNAPSHOT="$snapshot/stupicat-toml-frontmatter-output" \
expect_run_sh $SUCCESSFULLY "${exe[*]} $fixture/toml-frontmatter.md 2>/dev/null"
)
5 changes: 5 additions & 0 deletions tests/fixtures/snapshots/stupicat-toml-frontmatter-output
@@ -0,0 +1,5 @@
+++
key = value
+++

# Frontmatter should be supported
5 changes: 5 additions & 0 deletions tests/fixtures/snapshots/stupicat-yaml-frontmatter-output
@@ -0,0 +1,5 @@
---
key: value
---

# Frontmatter should be supported
5 changes: 5 additions & 0 deletions tests/fixtures/toml-frontmatter.md
@@ -0,0 +1,5 @@
+++
key = value
+++

# Frontmatter should be supported
5 changes: 5 additions & 0 deletions tests/fixtures/yaml-frontmatter.md
@@ -0,0 +1,5 @@
---
key: value
---

# Frontmatter should be supported
136 changes: 129 additions & 7 deletions tests/fmt.rs
Expand Up @@ -118,7 +118,7 @@ fn it_applies_newlines_before_start_before_text() {
newlines_before_start: 2,
last_was_text_without_trailing_newline: true,
..Default::default()
}
},
),
(
"\n\nt".into(),
Expand All @@ -140,7 +140,7 @@ fn it_applies_newlines_before_start_before_any_start_tag() {
newlines_before_start: 2,
last_was_text_without_trailing_newline: true,
..Default::default()
}
},
),
(
"\n\nh".into(),
Expand All @@ -166,7 +166,7 @@ mod padding {
padding: vec![" ".into()],
last_was_text_without_trailing_newline: true,
..Default::default()
}
},
),
(
"\n \n h".into(),
Expand Down Expand Up @@ -226,6 +226,7 @@ mod inline_elements {
fn autolinks_are_fully_resolved() {
assert_eq!(fmts("<http://a/b>").0, "<http://a/b>",)
}

#[test]
fn links() {
assert_eq!(
Expand Down Expand Up @@ -407,7 +408,7 @@ mod blockquote {
State {
padding: vec![" > ".into()],
..Default::default()
}
},
)
.1,
State {
Expand Down Expand Up @@ -443,18 +444,22 @@ mod blockquote {

assert_eq!(fmts(s).0, "\n > \n > <table>\n > </table>\n > ")
}

#[test]
fn with_inlinehtml() {
assert_eq!(fmts(" > <br>").0, "\n > \n > <br>")
}

#[test]
fn with_plaintext_in_html() {
assert_eq!(fmts("<del>\n*foo*\n</del>").0, "<del>\n*foo*\n</del>")
}

#[test]
fn with_markdown_nested_in_html() {
assert_eq!(fmts("<del>\n\n*foo*\n\n</del>").0, "<del>\n\n*foo*\n\n</del>")
}

#[test]
fn with_codeblock() {
let s = indoc!(
Expand All @@ -470,6 +475,7 @@ mod blockquote {

assert_eq!(fmts(s).0, "\n > \n > ````a\n > t1\n > t2\n > ````",)
}

#[test]
fn nested() {
let s = indoc!(
Expand Down Expand Up @@ -696,6 +702,7 @@ mod codeblock {
)
)
}

#[test]
fn simple() {
assert_eq!(
Expand Down Expand Up @@ -753,7 +760,7 @@ mod table {
table_alignments: vec![Alignment::None, Alignment::Center],
table_headers: vec!["a".into(), "b".into()],
..Default::default()
}
},
)
.1,
State {
Expand All @@ -762,11 +769,12 @@ mod table {
}
)
}

#[test]
fn it_keeps_track_of_alignments_and_headers() {
assert_eq!(
fmte(&[
Event::Start(Tag::Table(vec![TableAlignment::None, TableAlignment::Center,])),
Event::Start(Tag::Table(vec![TableAlignment::None, TableAlignment::Center])),
Event::Start(Tag::TableHead),
Event::Start(Tag::TableCell),
Event::Text("a".into()),
Expand All @@ -783,6 +791,7 @@ mod table {
}
)
}

#[test]
fn it_generates_equivalent_table_markdown() {
use pulldown_cmark::{Options, Parser};
Expand Down Expand Up @@ -992,7 +1001,7 @@ mod list {
State {
list_stack: vec![None, None],
..Default::default()
}
},
)
.1,
State {
Expand Down Expand Up @@ -1237,3 +1246,116 @@ mod heading {
assert_events_eq("# Heading { #id .class1 .class2 key1=val1 key2 }");
}
}

mod frontmatter {
use pulldown_cmark::{Options, Parser};
use pulldown_cmark_to_cmark::{cmark, cmark_with_options};

#[test]
fn yaml_frontmatter_should_be_supported() {
let input = "---
key1: value1
key2: value2
---
# Frontmatter should be supported";

let mut opts = Options::empty();
opts.insert(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS);
let events = Parser::new_ext(input, opts);

let mut output = String::new();
let state = cmark(events, &mut output).unwrap();
state.finalize(&mut output).unwrap();

assert_eq!(input, output);
}

#[test]
fn toml_frontmatter_should_be_supported() {
let input = "+++
key = value1
key = value2
+++
# Frontmatter should be supported";

let mut opts = Options::empty();
opts.insert(Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS);

let events = Parser::new_ext(input, opts);
let mut output = String::new();
let state = cmark(events, &mut output).unwrap();
state.finalize(&mut output).unwrap();

assert_eq!(input, output);
}

#[test]
fn yaml_frontmatter_supports_newline_option() {
let mut newlines = String::new();

for i in 0..10 {
let input = format!(
"---
key: value1
key: value2
---{newlines}
# Frontmatter should be supported"
);

let mut opts = Options::empty();
opts.insert(Options::ENABLE_YAML_STYLE_METADATA_BLOCKS);

let events = Parser::new_ext(&input, opts);
let mut output = String::new();
let state = cmark_with_options(
events,
&mut output,
pulldown_cmark_to_cmark::Options {
newlines_after_metadata: i,
..Default::default()
},
)
.unwrap();
state.finalize(&mut output).unwrap();

assert_eq!(input, output);
newlines.push('\n');
}
}

#[test]
fn toml_frontmatter_supports_newline_option() {
let mut newlines = String::new();

for i in 0..10 {
let input = format!(
"+++
key = value1
key = value2
+++{newlines}
# Frontmatter should be supported"
);

let mut opts = Options::empty();
opts.insert(Options::ENABLE_PLUSES_DELIMITED_METADATA_BLOCKS);

let events = Parser::new_ext(&input, opts);
let mut output = String::new();
let state = cmark_with_options(
events,
&mut output,
pulldown_cmark_to_cmark::Options {
newlines_after_metadata: i,
..Default::default()
},
)
.unwrap();
state.finalize(&mut output).unwrap();

assert_eq!(input, output);
newlines.push('\n');
}
}
}

0 comments on commit 834c74b

Please sign in to comment.