Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize mdast to markdown #127

Open
wants to merge 49 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
973f760
init mdast to markdown
bnchi Aug 24, 2024
691bb87
Handle texts in a simple way
bnchi Aug 24, 2024
b2a2ed3
Add container phrasing
bnchi Aug 27, 2024
25ee1b6
Fix minor typo
bnchi Aug 27, 2024
4ff2d02
Change comment
bnchi Aug 27, 2024
06e89f5
Update comment
bnchi Aug 27, 2024
78e6529
Add support for flow containers and default joins
bnchi Aug 28, 2024
9e5e9be
Add parents macro
bnchi Aug 28, 2024
21486d1
rename join default
bnchi Aug 28, 2024
66885de
Add unsafe
bnchi Aug 29, 2024
0733560
Fix typo
bnchi Aug 29, 2024
41d01f1
Make it safe
bnchi Aug 30, 2024
dd44b06
Fix clippy issues
bnchi Aug 31, 2024
dae7d26
Reduce some of the allocations
bnchi Sep 1, 2024
b598a26
Make things less pub for now
bnchi Sep 1, 2024
e9991fd
Move mdast to md into a workspace
bnchi Sep 3, 2024
558b316
A few refactors for parent nodes abstraction
bnchi Sep 3, 2024
973de93
Refactor
bnchi Sep 3, 2024
98243d3
Add support with tests for strong, paragraph and text
bnchi Sep 4, 2024
8e2055a
Add support for emphasis
bnchi Sep 4, 2024
0d939d1
Fix minor bug
bnchi Sep 5, 2024
3072d02
Add support for heading and break
bnchi Sep 5, 2024
464f327
Refactor compile pattern
bnchi Sep 5, 2024
e94d898
More refactor for compile pattern
bnchi Sep 5, 2024
3d1a896
Make inde_stack usize
bnchi Sep 5, 2024
16a3cb0
Add support for html
bnchi Sep 5, 2024
b9752b7
Fix minor bug in html
bnchi Sep 5, 2024
a8a2351
Add valid expected unwraps
bnchi Sep 6, 2024
c1e3758
Fix typos
bnchi Sep 6, 2024
4bf37ce
Add support for thematic break
bnchi Sep 6, 2024
67aa7ee
Add support for code
bnchi Sep 7, 2024
b542777
Add support for blockquote without full tests support
bnchi Sep 7, 2024
4969d1a
Add support for list and list item
bnchi Sep 9, 2024
04fb9e0
Add support for image
bnchi Sep 12, 2024
7ff2abb
Add support for link
bnchi Sep 14, 2024
3fa6bd2
Depend on Regex less in some trivial code
bnchi Sep 14, 2024
66f5024
Few updates
bnchi Sep 14, 2024
9b03c74
Add support for inline code
bnchi Sep 14, 2024
c43f209
Add support for root
bnchi Sep 15, 2024
f3efe18
Update break comment
bnchi Sep 15, 2024
8d34b35
Add support for definition
bnchi Sep 17, 2024
e062d85
make markdown utils pub
bnchi Sep 17, 2024
2b22136
Change util visibility and make decode_named and decode_numeric pub
bnchi Sep 17, 2024
ff30eb1
Refactor association
bnchi Sep 17, 2024
9c5e808
Update the name of the association mod
bnchi Sep 17, 2024
58ff3b8
Add support for image reference
bnchi Sep 17, 2024
f512a4c
merge
bnchi Sep 17, 2024
250a6cd
Update blockquote
bnchi Sep 17, 2024
04bdc71
Add support for link reference
bnchi Sep 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ keywords = ["commonmark", "markdown", "parse", "render", "tokenize"]
categories = ["compilers", "encoding", "parser-implementations", "parsing", "text-processing"]
include = ["src/", "license"]

[workspace]
members = ["generate", "mdast_util_to_markdown"]

[workspace.dependencies]
pretty_assertions = "1"

[[bench]]
name = "bench"
path = "benches/bench.rs"
Expand All @@ -31,14 +37,11 @@ serde = { version = "1", features = ["derive"], optional = true }
[dev-dependencies]
env_logger = "0.11"
criterion = "0.5"
pretty_assertions = "1"
pretty_assertions = { workspace = true }
serde_json = { version = "1" }
swc_core = { version = "0.100", features = [
"ecma_ast",
"ecma_visit",
"ecma_parser",
"common",
] }

[workspace]
members = ["generate"]
12 changes: 12 additions & 0 deletions mdast_util_to_markdown/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "mdast_util_to_markdown"
version = "0.0.0"
edition = "2018"
license = "MIT"

[dependencies]
markdown = { path = "../" }
regex = { version = "1.7.3" }
bnchi marked this conversation as resolved.
Show resolved Hide resolved

[dev-dependencies]
pretty_assertions = { workspace = true }
37 changes: 37 additions & 0 deletions mdast_util_to_markdown/src/association.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use alloc::string::String;
use markdown::mdast::{Definition, ImageReference, LinkReference};

pub trait Association {
fn identifier(&self) -> &String;
fn label(&self) -> &Option<String>;
}

impl Association for Definition {
fn identifier(&self) -> &String {
&self.identifier
}

fn label(&self) -> &Option<String> {
&self.label
}
}

impl Association for ImageReference {
fn identifier(&self) -> &String {
&self.identifier
}

fn label(&self) -> &Option<String> {
&self.label
}
}

impl Association for LinkReference {
fn identifier(&self) -> &String {
&self.identifier
}

fn label(&self) -> &Option<String> {
&self.label
}
}
52 changes: 52 additions & 0 deletions mdast_util_to_markdown/src/configure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#[allow(dead_code)]
pub struct Options {
pub bullet: char,
pub bullet_other: char,
pub bullet_ordered: char,
pub emphasis: char,
pub fence: char,
pub fences: bool,
pub list_item_indent: IndentOptions,
pub quote: char,
pub rule: char,
pub strong: char,
pub increment_list_marker: bool,
pub close_atx: bool,
pub resource_link: bool,
pub rule_spaces: bool,
pub setext: bool,
pub tight_definitions: bool,
pub rule_repetition: u32,
}

#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum IndentOptions {
Mixed,
One,
Tab,
}

impl Default for Options {
fn default() -> Self {
Self {
bullet: '*',
bullet_other: '-',
bullet_ordered: '.',
emphasis: '*',
fence: '`',
fences: true,
increment_list_marker: true,
rule_repetition: 3,
list_item_indent: IndentOptions::One,
quote: '"',
rule: '*',
strong: '*',
close_atx: false,
rule_spaces: false,
resource_link: false,
setext: false,
tight_definitions: false,
}
}
}
31 changes: 31 additions & 0 deletions mdast_util_to_markdown/src/construct_name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[derive(Clone, PartialEq)]
#[allow(dead_code)]
pub enum ConstructName {
Autolink,
Blockquote,
CodeIndented,
CodeFenced,
CodeFencedLangGraveAccent,
CodeFencedLangTilde,
CodeFencedMetaGraveAccent,
CodeFencedMetaTilde,
Definition,
DestinationLiteral,
DestinationRaw,
Emphasis,
HeadingAtx,
HeadingSetext,
Image,
ImageReference,
Label,
Link,
LinkReference,
List,
ListItem,
Paragraph,
Phrasing,
Reference,
Strong,
TitleApostrophe,
TitleQuote,
}
38 changes: 38 additions & 0 deletions mdast_util_to_markdown/src/handle/blockquote.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use alloc::string::String;
use markdown::mdast::{Blockquote, Node};

use crate::{
construct_name::ConstructName,
message::Message,
state::{Info, State},
util::indent_lines::indent_lines,
};

use super::Handle;

impl Handle for Blockquote {
fn handle(
&self,
state: &mut State,
_info: &Info,
_parent: Option<&Node>,
node: &Node,
) -> Result<alloc::string::String, Message> {
state.enter(ConstructName::Blockquote);
let value = indent_lines(&state.container_flow(node)?, map);
Ok(value)
}
}

fn map(value: &str, _line: usize, blank: bool) -> String {
let marker = ">";
let total_allocation = marker.len() + value.len() + 1;
let mut result = String::with_capacity(total_allocation);
result.push_str(marker);
if !blank {
let blank_str = " ";
result.push_str(blank_str);
}
result.push_str(value);
result
}
33 changes: 33 additions & 0 deletions mdast_util_to_markdown/src/handle/break.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use alloc::string::ToString;
use markdown::mdast::{Break, Node};

use crate::{
message::Message,
state::{Info, State},
util::pattern_in_scope::pattern_in_scope,
};

use super::Handle;

impl Handle for Break {
fn handle(
&self,
state: &mut State,
info: &Info,
_parent: Option<&Node>,
_node: &Node,
) -> Result<alloc::string::String, Message> {
for pattern in state.r#unsafe.iter() {
if pattern.character == '\n' && pattern_in_scope(&state.stack, pattern) {
let is_whitespace_or_tab = info.before.chars().any(|c| c == ' ' || c == '\t');
if is_whitespace_or_tab {
return Ok("".to_string());
}

return Ok(" ".to_string());
}
}

Ok("\\\n".to_string())
}
}
90 changes: 90 additions & 0 deletions mdast_util_to_markdown/src/handle/code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use alloc::{
format,
string::{String, ToString},
};
use markdown::mdast::{Code, Node};

use crate::{
construct_name::ConstructName,
message::Message,
state::{Info, State},
util::{
check_fence::check_fence, format_code_as_indented::format_code_as_indented,
indent_lines::indent_lines, longest_char_streak::longest_char_streak, safe::SafeConfig,
},
};

use super::Handle;

impl Handle for Code {
fn handle(
&self,
state: &mut State,
_info: &Info,
_parent: Option<&Node>,
_node: &Node,
) -> Result<alloc::string::String, Message> {
let marker = check_fence(state)?;

if format_code_as_indented(self, state) {
state.enter(ConstructName::CodeIndented);
let value = indent_lines(&self.value, map);
state.exit();
return Ok(value);
}

let sequence = marker
.to_string()
.repeat((longest_char_streak(&self.value, marker) + 1).max(3));

state.enter(ConstructName::CodeFenced);
let mut value = sequence.clone();

if let Some(lang) = &self.lang {
let code_fenced_lang_construct = if marker == '`' {
ConstructName::CodeFencedLangGraveAccent
} else {
ConstructName::CodeFencedLangTilde
};
state.enter(code_fenced_lang_construct);

value.push_str(&state.safe(lang, &SafeConfig::new(&value, " ", Some('`'))));

state.exit();

if let Some(meta) = &self.meta {
let code_fenced_meta_construct = if marker == '`' {
ConstructName::CodeFencedMetaGraveAccent
} else {
ConstructName::CodeFencedMetaTilde
};

state.enter(code_fenced_meta_construct);
value.push(' ');

value.push_str(&state.safe(meta, &SafeConfig::new(&value, "\n", Some('`'))));

state.exit();
}
}

value.push('\n');

if !self.value.is_empty() {
value.push_str(&self.value);
value.push('\n');
}

value.push_str(&sequence);

Ok(value)
}
}

fn map(value: &str, _line: usize, blank: bool) -> String {
if blank {
String::new()
} else {
format!(" {}", value)
}
}
Loading