refactor: rename field names to align with org-elements-api
This commit is contained in:
parent
f35c2d7bab
commit
93ed18602a
|
@ -3,7 +3,8 @@
|
||||||
pub struct Block;
|
pub struct Block;
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
pub fn parse(src: &str) -> Option<(usize, usize, usize, usize)> {
|
// return (name, args, contents-begin, contents-end, end)
|
||||||
|
pub fn parse(src: &str) -> Option<(&str, Option<&str>, usize, usize, usize)> {
|
||||||
if src.len() < 17 || !src[0..8].eq_ignore_ascii_case("#+BEGIN_") {
|
if src.len() < 17 || !src[0..8].eq_ignore_ascii_case("#+BEGIN_") {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +16,17 @@ impl Block {
|
||||||
let content = src.find(&format!("\n#+END_{}", &src[8..name]))?;
|
let content = src.find(&format!("\n#+END_{}", &src[8..name]))?;
|
||||||
let end = eol!(src, content + 1);
|
let end = eol!(src, content + 1);
|
||||||
|
|
||||||
Some((name, args, content, end + 1))
|
Some((
|
||||||
|
&src[8..name],
|
||||||
|
if name == args {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(&src[name..args])
|
||||||
|
},
|
||||||
|
args,
|
||||||
|
content + 1,
|
||||||
|
end + 1,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DynBlock<'a> {
|
pub struct DynBlock;
|
||||||
pub name: &'a str,
|
|
||||||
pub para: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DynBlock<'a> {
|
impl DynBlock {
|
||||||
pub fn parse(src: &'a str) -> Option<(DynBlock<'a>, usize, usize)> {
|
// return (name, parameters, contents-begin, contents-end, end)
|
||||||
|
pub fn parse(src: &str) -> Option<(&str, Option<&str>, usize, usize, usize)> {
|
||||||
if src.len() < 17 || !src[0..9].eq_ignore_ascii_case("#+BEGIN: ") {
|
if src.len() < 17 || !src[0..9].eq_ignore_ascii_case("#+BEGIN: ") {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -19,12 +17,15 @@ impl<'a> DynBlock<'a> {
|
||||||
let end = eol!(src, content + 1);
|
let end = eol!(src, content + 1);
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
DynBlock {
|
&src[9..name],
|
||||||
name: &src[9..name],
|
if name == args {
|
||||||
para: &src[name..args].trim(),
|
None
|
||||||
|
} else {
|
||||||
|
Some(&src[name..args].trim())
|
||||||
},
|
},
|
||||||
content,
|
args,
|
||||||
end,
|
content + 1,
|
||||||
|
end + 1,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,18 +35,11 @@ fn parse() {
|
||||||
// TODO: testing
|
// TODO: testing
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
DynBlock::parse(
|
DynBlock::parse(
|
||||||
r"#+BEGIN: clocktable :scope file :block yesterday
|
r"#+BEGIN: clocktable :scope file
|
||||||
CONTENTS
|
CONTENTS
|
||||||
#+END:
|
#+END:
|
||||||
"
|
"
|
||||||
),
|
),
|
||||||
Some((
|
Some(("clocktable", Some(":scope file"), 31, 41, 48))
|
||||||
DynBlock {
|
|
||||||
name: "clocktable",
|
|
||||||
para: ":scope file :block yesterday"
|
|
||||||
},
|
|
||||||
57,
|
|
||||||
64
|
|
||||||
))
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FnDef<'a> {
|
pub struct FnDef;
|
||||||
pub label: &'a str,
|
|
||||||
pub contents: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn valid_label(ch: u8) -> bool {
|
fn valid_label(ch: u8) -> bool {
|
||||||
ch.is_ascii_alphanumeric() || ch == b'-' || ch == b'_'
|
ch.is_ascii_alphanumeric() || ch == b'-' || ch == b'_'
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FnDef<'a> {
|
impl FnDef {
|
||||||
pub fn parse(src: &'a str) -> Option<(FnDef<'a>, usize)> {
|
pub fn parse(src: &str) -> Option<(&str, &str, usize)> {
|
||||||
starts_with!(src, "[fn:");
|
starts_with!(src, "[fn:");
|
||||||
|
|
||||||
let label = until_while!(src, 4, b']', valid_label);
|
let label = until_while!(src, 4, b']', valid_label);
|
||||||
|
@ -22,13 +19,7 @@ impl<'a> FnDef<'a> {
|
||||||
|
|
||||||
let end = eol!(src);
|
let end = eol!(src);
|
||||||
|
|
||||||
Some((
|
Some((&src[4..label], &src[label + 1..end], end))
|
||||||
FnDef {
|
|
||||||
label: &src[4..label],
|
|
||||||
contents: &src[label + 1..end],
|
|
||||||
},
|
|
||||||
end,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,42 +28,30 @@ fn parse() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
FnDef::parse("[fn:1] https://orgmode.org").unwrap(),
|
FnDef::parse("[fn:1] https://orgmode.org").unwrap(),
|
||||||
(
|
(
|
||||||
FnDef {
|
"1",
|
||||||
label: "1",
|
" https://orgmode.org",
|
||||||
contents: " https://orgmode.org",
|
|
||||||
},
|
|
||||||
"[fn:1] https://orgmode.org".len()
|
"[fn:1] https://orgmode.org".len()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
FnDef::parse("[fn:word_1] https://orgmode.org").unwrap(),
|
FnDef::parse("[fn:word_1] https://orgmode.org").unwrap(),
|
||||||
(
|
(
|
||||||
FnDef {
|
"word_1",
|
||||||
label: "word_1",
|
" https://orgmode.org",
|
||||||
contents: " https://orgmode.org",
|
|
||||||
},
|
|
||||||
"[fn:word_1] https://orgmode.org".len()
|
"[fn:word_1] https://orgmode.org".len()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
FnDef::parse("[fn:WORD-1] https://orgmode.org").unwrap(),
|
FnDef::parse("[fn:WORD-1] https://orgmode.org").unwrap(),
|
||||||
(
|
(
|
||||||
FnDef {
|
"WORD-1",
|
||||||
label: "WORD-1",
|
" https://orgmode.org",
|
||||||
contents: " https://orgmode.org",
|
|
||||||
},
|
|
||||||
"[fn:WORD-1] https://orgmode.org".len()
|
"[fn:WORD-1] https://orgmode.org".len()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
FnDef::parse("[fn:WORD]").unwrap(),
|
FnDef::parse("[fn:WORD]").unwrap(),
|
||||||
(
|
("WORD", "", "[fn:WORD]".len())
|
||||||
FnDef {
|
|
||||||
label: "WORD",
|
|
||||||
contents: "",
|
|
||||||
},
|
|
||||||
"[fn:WORD]".len()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
assert!(FnDef::parse("[fn:] https://orgmode.org").is_none());
|
assert!(FnDef::parse("[fn:] https://orgmode.org").is_none());
|
||||||
assert!(FnDef::parse("[fn:wor d] https://orgmode.org").is_none());
|
assert!(FnDef::parse("[fn:wor d] https://orgmode.org").is_none());
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Keyword<'a> {
|
pub struct Keyword;
|
||||||
pub key: &'a str,
|
|
||||||
pub value: &'a str,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Keyword<'a> {
|
impl Keyword {
|
||||||
pub fn parse(src: &'a str) -> Option<(Keyword<'a>, usize)> {
|
// return (key, value, offset)
|
||||||
|
pub fn parse(src: &str) -> Option<(&str, &str, usize)> {
|
||||||
if cfg!(test) {
|
if cfg!(test) {
|
||||||
starts_with!(src, "#+");
|
starts_with!(src, "#+");
|
||||||
}
|
}
|
||||||
|
@ -14,15 +12,9 @@ impl<'a> Keyword<'a> {
|
||||||
let key = until_while!(src, 2, b':', |c: u8| c.is_ascii_uppercase() || c == b'_');
|
let key = until_while!(src, 2, b':', |c: u8| c.is_ascii_uppercase() || c == b'_');
|
||||||
|
|
||||||
// includes the eol character
|
// includes the eol character
|
||||||
let end = src.find('\n').map(|i| i + 1).unwrap_or(src.len());
|
let end = src.find('\n').map(|i| i + 1).unwrap_or_else(|| src.len());
|
||||||
|
|
||||||
Some((
|
Some((&src[2..key], &src[key + 1..end].trim(), end))
|
||||||
Keyword {
|
|
||||||
key: &src[2..key],
|
|
||||||
value: &src[key + 1..end].trim(),
|
|
||||||
},
|
|
||||||
end,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,43 +110,19 @@ fn parse_key<'a>(key: &'a str) -> Option<AffKeywordKey<'a>> {
|
||||||
fn parse() {
|
fn parse() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Keyword::parse("#+KEY:").unwrap(),
|
Keyword::parse("#+KEY:").unwrap(),
|
||||||
(
|
("KEY", "", "#+KEY:".len())
|
||||||
Keyword {
|
|
||||||
key: "KEY",
|
|
||||||
value: "",
|
|
||||||
},
|
|
||||||
"#+KEY:".len()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Keyword::parse("#+KEY: VALUE").unwrap(),
|
Keyword::parse("#+KEY: VALUE").unwrap(),
|
||||||
(
|
("KEY", "VALUE", "#+KEY: VALUE".len())
|
||||||
Keyword {
|
|
||||||
key: "KEY",
|
|
||||||
value: "VALUE",
|
|
||||||
},
|
|
||||||
"#+KEY: VALUE".len()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Keyword::parse("#+K_E_Y: VALUE").unwrap(),
|
Keyword::parse("#+K_E_Y: VALUE").unwrap(),
|
||||||
(
|
("K_E_Y", "VALUE", "#+K_E_Y: VALUE".len())
|
||||||
Keyword {
|
|
||||||
key: "K_E_Y",
|
|
||||||
value: "VALUE",
|
|
||||||
},
|
|
||||||
"#+K_E_Y: VALUE".len()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Keyword::parse("#+KEY:VALUE\n").unwrap(),
|
Keyword::parse("#+KEY:VALUE\n").unwrap(),
|
||||||
(
|
("KEY", "VALUE", "#+KEY:VALUE\n".len())
|
||||||
Keyword {
|
|
||||||
key: "KEY",
|
|
||||||
value: "VALUE",
|
|
||||||
},
|
|
||||||
"#+KEY:VALUE\n".len()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
assert!(Keyword::parse("#+KE Y: VALUE").is_none());
|
assert!(Keyword::parse("#+KE Y: VALUE").is_none());
|
||||||
assert!(Keyword::parse("#+ KEY: VALUE").is_none());
|
assert!(Keyword::parse("#+ KEY: VALUE").is_none());
|
||||||
|
|
|
@ -2,12 +2,14 @@ pub mod block;
|
||||||
pub mod dyn_block;
|
pub mod dyn_block;
|
||||||
pub mod fn_def;
|
pub mod fn_def;
|
||||||
pub mod keyword;
|
pub mod keyword;
|
||||||
|
pub mod list;
|
||||||
pub mod rule;
|
pub mod rule;
|
||||||
|
|
||||||
pub use self::block::Block;
|
pub use self::block::Block;
|
||||||
pub use self::dyn_block::DynBlock;
|
pub use self::dyn_block::DynBlock;
|
||||||
pub use self::fn_def::FnDef;
|
pub use self::fn_def::FnDef;
|
||||||
pub use self::keyword::Keyword;
|
pub use self::keyword::Keyword;
|
||||||
|
pub use self::list::List;
|
||||||
pub use self::rule::Rule;
|
pub use self::rule::Rule;
|
||||||
|
|
||||||
#[cfg_attr(test, derive(PartialEq, Debug))]
|
#[cfg_attr(test, derive(PartialEq, Debug))]
|
||||||
|
@ -18,44 +20,55 @@ pub enum Element<'a> {
|
||||||
// trailing space
|
// trailing space
|
||||||
trailing: usize,
|
trailing: usize,
|
||||||
},
|
},
|
||||||
Keyword(Keyword<'a>),
|
Keyword {
|
||||||
FnDef(FnDef<'a>),
|
key: &'a str,
|
||||||
|
value: &'a str,
|
||||||
|
},
|
||||||
|
FnDef {
|
||||||
|
label: &'a str,
|
||||||
|
contents: &'a str,
|
||||||
|
},
|
||||||
CenterBlock {
|
CenterBlock {
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
content_end: usize,
|
contents_end: usize,
|
||||||
end: usize,
|
end: usize,
|
||||||
},
|
},
|
||||||
QuoteBlock {
|
QuoteBlock {
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
content_end: usize,
|
contents_end: usize,
|
||||||
end: usize,
|
end: usize,
|
||||||
},
|
},
|
||||||
SpecialBlock {
|
SpecialBlock {
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
name: &'a str,
|
name: &'a str,
|
||||||
content_end: usize,
|
contents_end: usize,
|
||||||
end: usize,
|
end: usize,
|
||||||
},
|
},
|
||||||
CommentBlock {
|
CommentBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
ExampleBlock {
|
ExampleBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
ExportBlock {
|
ExportBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
SrcBlock {
|
SrcBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
VerseBlock {
|
VerseBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
|
},
|
||||||
|
DynBlock {
|
||||||
|
args: Option<&'a str>,
|
||||||
|
name: &'a str,
|
||||||
|
contents_end: usize,
|
||||||
|
end: usize,
|
||||||
},
|
},
|
||||||
Rule,
|
Rule,
|
||||||
Comment(&'a str),
|
Comment(&'a str),
|
||||||
|
@ -75,9 +88,9 @@ impl<'a> Element<'a> {
|
||||||
loop {
|
loop {
|
||||||
// Unlike other element, footnote definition must starts at column 0
|
// Unlike other element, footnote definition must starts at column 0
|
||||||
if bytes[pos] == b'[' {
|
if bytes[pos] == b'[' {
|
||||||
if let Some((fd, off)) = FnDef::parse(&src[pos..]) {
|
if let Some((label, contents, off)) = FnDef::parse(&src[pos..]) {
|
||||||
return if pos == start {
|
return if pos == start {
|
||||||
(off + 1, Some(Element::FnDef(fd)), None)
|
(off + 1, Some(Element::FnDef { label, contents }), None)
|
||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
start,
|
start,
|
||||||
|
@ -85,7 +98,7 @@ impl<'a> Element<'a> {
|
||||||
end: pos - 1,
|
end: pos - 1,
|
||||||
trailing: pos,
|
trailing: pos,
|
||||||
}),
|
}),
|
||||||
Some((Element::FnDef(fd), off + 1)),
|
Some((Element::FnDef { label, contents }, off + 1)),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -103,7 +116,7 @@ impl<'a> Element<'a> {
|
||||||
(
|
(
|
||||||
start,
|
start,
|
||||||
Some(Element::Paragraph {
|
Some(Element::Paragraph {
|
||||||
end: end - 1,
|
end,
|
||||||
trailing: pos - 1,
|
trailing: pos - 1,
|
||||||
}),
|
}),
|
||||||
Some(($ele, $off)),
|
Some(($ele, $off)),
|
||||||
|
@ -113,14 +126,7 @@ impl<'a> Element<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes[pos] == b'\n' {
|
if bytes[pos] == b'\n' {
|
||||||
return (
|
return (start, Some(Element::Paragraph { end, trailing: pos }), None);
|
||||||
start,
|
|
||||||
Some(Element::Paragraph {
|
|
||||||
end: end - 1,
|
|
||||||
trailing: pos,
|
|
||||||
}),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: LaTeX environment
|
// TODO: LaTeX environment
|
||||||
|
@ -133,112 +139,99 @@ impl<'a> Element<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes[pos] == b'#' && bytes[pos + 1] == b'+' {
|
if bytes[pos] == b'#' && bytes.get(pos + 1).filter(|&&b| b == b'+').is_some() {
|
||||||
if let Some((name, args, content, end)) = Block::parse(&src[pos..]) {
|
if let Some((name, args, contents_beg, contents_end, end)) =
|
||||||
match &src[pos + 8..pos + name] {
|
Block::parse(&src[pos..])
|
||||||
block_name if block_name.eq_ignore_ascii_case("CENTER") => ret!(
|
{
|
||||||
Element::CenterBlock {
|
match name.to_uppercase().as_str() {
|
||||||
args: if name == args {
|
"COMMENT" => ret!(
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args])
|
|
||||||
},
|
|
||||||
content_end: content + 1,
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
pos + args
|
|
||||||
),
|
|
||||||
block_name if block_name.eq_ignore_ascii_case("QUOTE") => ret!(
|
|
||||||
Element::QuoteBlock {
|
|
||||||
args: if name == args {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args].trim())
|
|
||||||
},
|
|
||||||
content_end: content + 1,
|
|
||||||
end,
|
|
||||||
},
|
|
||||||
pos + args
|
|
||||||
),
|
|
||||||
block_name if block_name.eq_ignore_ascii_case("COMMENT") => ret!(
|
|
||||||
Element::CommentBlock {
|
Element::CommentBlock {
|
||||||
args: if name == args {
|
args,
|
||||||
None
|
contents: &src[pos + contents_beg + 1..pos + contents_end - 1],
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args])
|
|
||||||
},
|
|
||||||
content: &src[pos + args + 1..pos + content],
|
|
||||||
},
|
},
|
||||||
pos + end
|
pos + end
|
||||||
),
|
),
|
||||||
block_name if block_name.eq_ignore_ascii_case("EXAMPLE") => ret!(
|
"EXAMPLE" => ret!(
|
||||||
Element::ExampleBlock {
|
Element::ExampleBlock {
|
||||||
args: if name == args {
|
args,
|
||||||
None
|
contents: &src[pos + contents_beg + 1..pos + contents_end - 1],
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args])
|
|
||||||
},
|
|
||||||
content: &src[pos + args + 1..pos + content],
|
|
||||||
},
|
},
|
||||||
pos + end
|
pos + end
|
||||||
),
|
),
|
||||||
block_name if block_name.eq_ignore_ascii_case("EXPORT") => ret!(
|
"EXPORT" => ret!(
|
||||||
Element::ExportBlock {
|
Element::ExportBlock {
|
||||||
args: if name == args {
|
args,
|
||||||
None
|
contents: &src[pos + contents_beg + 1..pos + contents_end - 1],
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args])
|
|
||||||
},
|
|
||||||
content: &src[pos + args + 1..pos + content],
|
|
||||||
},
|
},
|
||||||
pos + end
|
pos + end
|
||||||
),
|
),
|
||||||
block_name if block_name.eq_ignore_ascii_case("SRC") => ret!(
|
"SRC" => ret!(
|
||||||
Element::SrcBlock {
|
Element::SrcBlock {
|
||||||
args: if name == args {
|
args,
|
||||||
None
|
contents: &src[pos + contents_beg + 1..pos + contents_end - 1],
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args])
|
|
||||||
},
|
|
||||||
content: &src[pos + args + 1..pos + content],
|
|
||||||
},
|
},
|
||||||
pos + end
|
pos + end
|
||||||
),
|
),
|
||||||
block_name if block_name.eq_ignore_ascii_case("VERSE") => ret!(
|
"VERSE" => ret!(
|
||||||
Element::VerseBlock {
|
Element::VerseBlock {
|
||||||
args: if name == args {
|
args,
|
||||||
None
|
contents: &src[pos + contents_beg + 1..pos + contents_end - 1],
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args])
|
|
||||||
},
|
|
||||||
content: &src[pos + args + 1..pos + content],
|
|
||||||
},
|
},
|
||||||
pos + end
|
pos + end
|
||||||
),
|
),
|
||||||
block_name => ret!(
|
"CENTER" => ret!(
|
||||||
Element::SpecialBlock {
|
Element::CenterBlock {
|
||||||
name: block_name,
|
args,
|
||||||
args: if name == args {
|
contents_end,
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(&src[pos + name..pos + args].trim())
|
|
||||||
},
|
|
||||||
content_end: content + 1,
|
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
pos + args
|
pos + contents_beg
|
||||||
|
),
|
||||||
|
"QUOTE" => ret!(
|
||||||
|
Element::QuoteBlock {
|
||||||
|
args,
|
||||||
|
contents_end,
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
pos + contents_beg
|
||||||
|
),
|
||||||
|
_ => ret!(
|
||||||
|
Element::SpecialBlock {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
contents_end,
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
pos + contents_beg
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((kw, off)) = Keyword::parse(&src[pos..]) {
|
if let Some((name, args, contents_beg, contents_end, end)) =
|
||||||
ret!(Element::Keyword(kw), off)
|
DynBlock::parse(&src[pos..])
|
||||||
|
{
|
||||||
|
ret!(
|
||||||
|
Element::DynBlock {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
contents_end,
|
||||||
|
end,
|
||||||
|
},
|
||||||
|
pos + contents_beg
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((key, value, off)) = Keyword::parse(&src[pos..]) {
|
||||||
|
ret!(Element::Keyword { key, value }, off)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comment
|
// Comment
|
||||||
if bytes[pos] == b'#' && bytes[pos + 1] == b' ' {
|
if bytes[pos] == b'#' && bytes.get(pos + 1).filter(|&&b| b == b' ').is_some() {
|
||||||
let eol = eol!(src, pos);
|
let eol = src[pos..]
|
||||||
|
.find('\n')
|
||||||
|
.map(|i| i + pos + 1)
|
||||||
|
.unwrap_or_else(|| src.len());
|
||||||
ret!(Element::Comment(&src[pos + 1..eol]), eol);
|
ret!(Element::Comment(&src[pos + 1..eol]), eol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use elements::{FnDef, Keyword};
|
#![allow(unused_variables)]
|
||||||
|
|
||||||
use export::Handler;
|
use export::Handler;
|
||||||
use headline::Headline;
|
use headline::Headline;
|
||||||
use objects::{Cookie, FnRef, InlineCall, InlineSrc, Link, Macros, RadioTarget, Snippet, Target};
|
use objects::{Cookie, FnRef, InlineCall, InlineSrc, Link, Macros, RadioTarget, Snippet, Target};
|
||||||
|
@ -53,25 +54,35 @@ impl<W: Write> Handler<W> for HtmlHandler {
|
||||||
fn handle_end_special_block(&mut self, w: &mut W) -> Result<()> {
|
fn handle_end_special_block(&mut self, w: &mut W) -> Result<()> {
|
||||||
write!(w, "</div>")
|
write!(w, "</div>")
|
||||||
}
|
}
|
||||||
fn handle_comment_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()> {
|
fn handle_comment_block(
|
||||||
|
&mut self,
|
||||||
|
w: &mut W,
|
||||||
|
contents: &str,
|
||||||
|
args: Option<&str>,
|
||||||
|
) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_example_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()> {
|
fn handle_example_block(
|
||||||
write!(w, "<pre><code>{}</code></pre>", content)
|
&mut self,
|
||||||
|
w: &mut W,
|
||||||
|
contents: &str,
|
||||||
|
args: Option<&str>,
|
||||||
|
) -> Result<()> {
|
||||||
|
write!(w, "<pre><code>{}</code></pre>", contents)
|
||||||
}
|
}
|
||||||
fn handle_export_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()> {
|
fn handle_export_block(&mut self, w: &mut W, contents: &str, args: Option<&str>) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_src_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()> {
|
fn handle_src_block(&mut self, w: &mut W, contents: &str, args: Option<&str>) -> Result<()> {
|
||||||
write!(w, "<pre><code>{}</code></pre>", content)
|
write!(w, "<pre><code>{}</code></pre>", contents)
|
||||||
}
|
}
|
||||||
fn handle_verse_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()> {
|
fn handle_verse_block(&mut self, w: &mut W, contents: &str, args: Option<&str>) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_dyn_block_start(&mut self, w: &mut W) -> Result<()> {
|
fn handle_start_dyn_block(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_dyn_block_end(&mut self, w: &mut W) -> Result<()> {
|
fn handle_end_dyn_block(&mut self, w: &mut W) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_list_start(&mut self, w: &mut W) -> Result<()> {
|
fn handle_list_start(&mut self, w: &mut W) -> Result<()> {
|
||||||
|
@ -89,7 +100,7 @@ impl<W: Write> Handler<W> for HtmlHandler {
|
||||||
fn handle_clock(&mut self, w: &mut W) -> Result<()> {
|
fn handle_clock(&mut self, w: &mut W) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_comment(&mut self, w: &mut W, content: &str) -> Result<()> {
|
fn handle_comment(&mut self, w: &mut W, contents: &str) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_table_start(&mut self, w: &mut W) -> Result<()> {
|
fn handle_table_start(&mut self, w: &mut W) -> Result<()> {
|
||||||
|
@ -104,10 +115,10 @@ impl<W: Write> Handler<W> for HtmlHandler {
|
||||||
fn handle_latex_env(&mut self, w: &mut W) -> Result<()> {
|
fn handle_latex_env(&mut self, w: &mut W) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_fn_def(&mut self, w: &mut W, fn_def: FnDef) -> Result<()> {
|
fn handle_fn_def(&mut self, w: &mut W, label: &str, contents: &str) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_keyword(&mut self, w: &mut W, kw: Keyword) -> Result<()> {
|
fn handle_keyword(&mut self, w: &mut W, key: &str, value: &str) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_rule(&mut self, w: &mut W) -> Result<()> {
|
fn handle_rule(&mut self, w: &mut W) -> Result<()> {
|
||||||
|
@ -140,8 +151,12 @@ impl<W: Write> Handler<W> for HtmlHandler {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn handle_snippet(&mut self, w: &mut W, snippet: Snippet) -> Result<()> {
|
fn handle_snippet(&mut self, w: &mut W, snippet: Snippet) -> Result<()> {
|
||||||
|
if snippet.name.eq_ignore_ascii_case("HTML") {
|
||||||
|
write!(w, "{}", snippet.value)
|
||||||
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
fn handle_target(&mut self, w: &mut W, target: Target) -> Result<()> {
|
fn handle_target(&mut self, w: &mut W, target: Target) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -169,13 +184,13 @@ impl<W: Write> Handler<W> for HtmlHandler {
|
||||||
fn handle_end_underline(&mut self, w: &mut W) -> Result<()> {
|
fn handle_end_underline(&mut self, w: &mut W) -> Result<()> {
|
||||||
write!(w, "</u>")
|
write!(w, "</u>")
|
||||||
}
|
}
|
||||||
fn handle_verbatim(&mut self, w: &mut W, content: &str) -> Result<()> {
|
fn handle_verbatim(&mut self, w: &mut W, contents: &str) -> Result<()> {
|
||||||
write!(w, "<code>{}</code>", content)
|
write!(w, "<code>{}</code>", contents)
|
||||||
}
|
}
|
||||||
fn handle_code(&mut self, w: &mut W, content: &str) -> Result<()> {
|
fn handle_code(&mut self, w: &mut W, contents: &str) -> Result<()> {
|
||||||
write!(w, "<code>{}</code>", content)
|
write!(w, "<code>{}</code>", contents)
|
||||||
}
|
}
|
||||||
fn handle_text(&mut self, w: &mut W, content: &str) -> Result<()> {
|
fn handle_text(&mut self, w: &mut W, contents: &str) -> Result<()> {
|
||||||
write!(w, "{}", content.replace('\n', " "))
|
write!(w, "{}", contents.replace('\n', " "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ mod html;
|
||||||
|
|
||||||
pub use self::html::HtmlHandler;
|
pub use self::html::HtmlHandler;
|
||||||
|
|
||||||
use elements::{FnDef, Keyword};
|
|
||||||
use headline::Headline;
|
use headline::Headline;
|
||||||
use objects::{Cookie, FnRef, InlineCall, InlineSrc, Link, Macros, RadioTarget, Snippet, Target};
|
use objects::{Cookie, FnRef, InlineCall, InlineSrc, Link, Macros, RadioTarget, Snippet, Target};
|
||||||
use parser::Parser;
|
use parser::Parser;
|
||||||
|
@ -26,25 +25,27 @@ pub trait Handler<W: Write> {
|
||||||
args: Option<&str>,
|
args: Option<&str>,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
fn handle_end_special_block(&mut self, w: &mut W) -> Result<()>;
|
fn handle_end_special_block(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_comment_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()>;
|
fn handle_comment_block(&mut self, w: &mut W, contents: &str, args: Option<&str>)
|
||||||
fn handle_example_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()>;
|
-> Result<()>;
|
||||||
fn handle_export_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()>;
|
fn handle_example_block(&mut self, w: &mut W, contents: &str, args: Option<&str>)
|
||||||
fn handle_src_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()>;
|
-> Result<()>;
|
||||||
fn handle_verse_block(&mut self, w: &mut W, content: &str, args: Option<&str>) -> Result<()>;
|
fn handle_export_block(&mut self, w: &mut W, contents: &str, args: Option<&str>) -> Result<()>;
|
||||||
fn handle_dyn_block_start(&mut self, w: &mut W) -> Result<()>;
|
fn handle_src_block(&mut self, w: &mut W, contents: &str, args: Option<&str>) -> Result<()>;
|
||||||
fn handle_dyn_block_end(&mut self, w: &mut W) -> Result<()>;
|
fn handle_verse_block(&mut self, w: &mut W, contents: &str, args: Option<&str>) -> Result<()>;
|
||||||
|
fn handle_start_dyn_block(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<()>;
|
||||||
|
fn handle_end_dyn_block(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_list_start(&mut self, w: &mut W) -> Result<()>;
|
fn handle_list_start(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_list_end(&mut self, w: &mut W) -> Result<()>;
|
fn handle_list_end(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_aff_keywords(&mut self, w: &mut W) -> Result<()>;
|
fn handle_aff_keywords(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_call(&mut self, w: &mut W) -> Result<()>;
|
fn handle_call(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_clock(&mut self, w: &mut W) -> Result<()>;
|
fn handle_clock(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_comment(&mut self, w: &mut W, content: &str) -> Result<()>;
|
fn handle_comment(&mut self, w: &mut W, contents: &str) -> Result<()>;
|
||||||
fn handle_table_start(&mut self, w: &mut W) -> Result<()>;
|
fn handle_table_start(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_table_end(&mut self, w: &mut W) -> Result<()>;
|
fn handle_table_end(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_table_cell(&mut self, w: &mut W) -> Result<()>;
|
fn handle_table_cell(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_latex_env(&mut self, w: &mut W) -> Result<()>;
|
fn handle_latex_env(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_fn_def(&mut self, w: &mut W, fn_def: FnDef) -> Result<()>;
|
fn handle_fn_def(&mut self, w: &mut W, label: &str, contents: &str) -> Result<()>;
|
||||||
fn handle_keyword(&mut self, w: &mut W, kw: Keyword) -> Result<()>;
|
fn handle_keyword(&mut self, w: &mut W, key: &str, value: &str) -> Result<()>;
|
||||||
fn handle_rule(&mut self, w: &mut W) -> Result<()>;
|
fn handle_rule(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_cookie(&mut self, w: &mut W, cookie: Cookie) -> Result<()>;
|
fn handle_cookie(&mut self, w: &mut W, cookie: Cookie) -> Result<()>;
|
||||||
fn handle_fn_ref(&mut self, w: &mut W, fn_ref: FnRef) -> Result<()>;
|
fn handle_fn_ref(&mut self, w: &mut W, fn_ref: FnRef) -> Result<()>;
|
||||||
|
@ -63,9 +64,9 @@ pub trait Handler<W: Write> {
|
||||||
fn handle_end_strike(&mut self, w: &mut W) -> Result<()>;
|
fn handle_end_strike(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_start_underline(&mut self, w: &mut W) -> Result<()>;
|
fn handle_start_underline(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_end_underline(&mut self, w: &mut W) -> Result<()>;
|
fn handle_end_underline(&mut self, w: &mut W) -> Result<()>;
|
||||||
fn handle_verbatim(&mut self, w: &mut W, content: &str) -> Result<()>;
|
fn handle_verbatim(&mut self, w: &mut W, contents: &str) -> Result<()>;
|
||||||
fn handle_code(&mut self, w: &mut W, content: &str) -> Result<()>;
|
fn handle_code(&mut self, w: &mut W, contents: &str) -> Result<()>;
|
||||||
fn handle_text(&mut self, w: &mut W, content: &str) -> Result<()>;
|
fn handle_text(&mut self, w: &mut W, contents: &str) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Render<'a, W: Write, H: Handler<W>> {
|
pub struct Render<'a, W: Write, H: Handler<W>> {
|
||||||
|
@ -107,28 +108,31 @@ impl<'a, W: Write, H: Handler<W>> Render<'a, W, H> {
|
||||||
.handle_start_special_block(&mut self.writer, name, args)?
|
.handle_start_special_block(&mut self.writer, name, args)?
|
||||||
}
|
}
|
||||||
EndSpecialBlock => self.handler.handle_end_special_block(&mut self.writer)?,
|
EndSpecialBlock => self.handler.handle_end_special_block(&mut self.writer)?,
|
||||||
CommentBlock { content, args } => {
|
CommentBlock { contents, args } => {
|
||||||
self.handler
|
self.handler
|
||||||
.handle_comment_block(&mut self.writer, content, args)?
|
.handle_comment_block(&mut self.writer, contents, args)?
|
||||||
}
|
}
|
||||||
ExampleBlock { content, args } => {
|
ExampleBlock { contents, args } => {
|
||||||
self.handler
|
self.handler
|
||||||
.handle_example_block(&mut self.writer, content, args)?
|
.handle_example_block(&mut self.writer, contents, args)?
|
||||||
}
|
}
|
||||||
ExportBlock { content, args } => {
|
ExportBlock { contents, args } => {
|
||||||
self.handler
|
self.handler
|
||||||
.handle_export_block(&mut self.writer, content, args)?
|
.handle_export_block(&mut self.writer, contents, args)?
|
||||||
}
|
}
|
||||||
SrcBlock { content, args } => {
|
SrcBlock { contents, args } => {
|
||||||
self.handler
|
self.handler
|
||||||
.handle_src_block(&mut self.writer, content, args)?
|
.handle_src_block(&mut self.writer, contents, args)?
|
||||||
}
|
}
|
||||||
VerseBlock { content, args } => {
|
VerseBlock { contents, args } => {
|
||||||
self.handler
|
self.handler
|
||||||
.handle_verse_block(&mut self.writer, content, args)?
|
.handle_verse_block(&mut self.writer, contents, args)?
|
||||||
}
|
}
|
||||||
DynBlockStart => self.handler.handle_dyn_block_start(&mut self.writer)?,
|
StartDynBlock { name, args } => {
|
||||||
DynBlockEnd => self.handler.handle_dyn_block_end(&mut self.writer)?,
|
self.handler
|
||||||
|
.handle_start_dyn_block(&mut self.writer, name, args)?
|
||||||
|
}
|
||||||
|
EndDynBlock => self.handler.handle_end_dyn_block(&mut self.writer)?,
|
||||||
ListStart => self.handler.handle_list_start(&mut self.writer)?,
|
ListStart => self.handler.handle_list_start(&mut self.writer)?,
|
||||||
ListEnd => self.handler.handle_list_end(&mut self.writer)?,
|
ListEnd => self.handler.handle_list_end(&mut self.writer)?,
|
||||||
AffKeywords => self.handler.handle_aff_keywords(&mut self.writer)?,
|
AffKeywords => self.handler.handle_aff_keywords(&mut self.writer)?,
|
||||||
|
@ -139,8 +143,13 @@ impl<'a, W: Write, H: Handler<W>> Render<'a, W, H> {
|
||||||
TableEnd => self.handler.handle_table_end(&mut self.writer)?,
|
TableEnd => self.handler.handle_table_end(&mut self.writer)?,
|
||||||
TableCell => self.handler.handle_table_cell(&mut self.writer)?,
|
TableCell => self.handler.handle_table_cell(&mut self.writer)?,
|
||||||
LatexEnv => self.handler.handle_latex_env(&mut self.writer)?,
|
LatexEnv => self.handler.handle_latex_env(&mut self.writer)?,
|
||||||
FnDef(f) => self.handler.handle_fn_def(&mut self.writer, f)?,
|
FnDef { label, contents } => {
|
||||||
Keyword(keyword) => self.handler.handle_keyword(&mut self.writer, keyword)?,
|
self.handler
|
||||||
|
.handle_fn_def(&mut self.writer, label, contents)?
|
||||||
|
}
|
||||||
|
Keyword { key, value } => {
|
||||||
|
self.handler.handle_keyword(&mut self.writer, key, value)?
|
||||||
|
}
|
||||||
Rule => self.handler.handle_rule(&mut self.writer)?,
|
Rule => self.handler.handle_rule(&mut self.writer)?,
|
||||||
Cookie(cookie) => self.handler.handle_cookie(&mut self.writer, cookie)?,
|
Cookie(cookie) => self.handler.handle_cookie(&mut self.writer, cookie)?,
|
||||||
FnRef(fnref) => self.handler.handle_fn_ref(&mut self.writer, fnref)?,
|
FnRef(fnref) => self.handler.handle_fn_ref(&mut self.writer, fnref)?,
|
||||||
|
@ -165,9 +174,9 @@ impl<'a, W: Write, H: Handler<W>> Render<'a, W, H> {
|
||||||
EndStrike => self.handler.handle_end_strike(&mut self.writer)?,
|
EndStrike => self.handler.handle_end_strike(&mut self.writer)?,
|
||||||
StartUnderline => self.handler.handle_start_underline(&mut self.writer)?,
|
StartUnderline => self.handler.handle_start_underline(&mut self.writer)?,
|
||||||
EndUnderline => self.handler.handle_end_underline(&mut self.writer)?,
|
EndUnderline => self.handler.handle_end_underline(&mut self.writer)?,
|
||||||
Verbatim(content) => self.handler.handle_verbatim(&mut self.writer, content)?,
|
Verbatim(contents) => self.handler.handle_verbatim(&mut self.writer, contents)?,
|
||||||
Code(content) => self.handler.handle_code(&mut self.writer, content)?,
|
Code(contents) => self.handler.handle_code(&mut self.writer, contents)?,
|
||||||
Text(content) => self.handler.handle_text(&mut self.writer, content)?,
|
Text(contents) => self.handler.handle_text(&mut self.writer, contents)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl<'a> Headline<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_tags(src: &'a str) -> (Option<&'a str>, usize) {
|
fn parse_tags(src: &'a str) -> (Option<&'a str>, usize) {
|
||||||
if let Some(last) = src.split_whitespace().last() {
|
if let Some(last) = src.split_whitespace().last() {
|
||||||
if last.starts_with(':') && last.ends_with(':') {
|
if last.len() > 2 && last.starts_with(':') && last.ends_with(':') {
|
||||||
(Some(last), src.rfind(':').unwrap() - last.len())
|
(Some(last), src.rfind(':').unwrap() - last.len())
|
||||||
} else {
|
} else {
|
||||||
(None, src.len())
|
(None, src.len())
|
||||||
|
|
|
@ -13,7 +13,7 @@ impl<'a> Cookie<'a> {
|
||||||
let num1 = until_while!(src, 1, |c| c == b'%' || c == b'/', |c: u8| c
|
let num1 = until_while!(src, 1, |c| c == b'%' || c == b'/', |c: u8| c
|
||||||
.is_ascii_digit());
|
.is_ascii_digit());
|
||||||
|
|
||||||
if src.len() > num1 && src.as_bytes()[num1 + 1] == b']' {
|
if src.as_bytes()[num1] == b'%' && *src.as_bytes().get(num1 + 1)? == b']' {
|
||||||
Some((
|
Some((
|
||||||
Cookie {
|
Cookie {
|
||||||
value: &src[0..num1 + 2],
|
value: &src[0..num1 + 2],
|
||||||
|
|
|
@ -11,10 +11,7 @@ impl<'a> Link<'a> {
|
||||||
starts_with!(src, "[[");
|
starts_with!(src, "[[");
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = until_while!(src, 2, b']', |c| c != b']'
|
let path = until_while!(src, 2, b']', |c| c != b'<' && c != b'>' && c != b'\n');
|
||||||
&& c != b'<'
|
|
||||||
&& c != b'>'
|
|
||||||
&& c != b'\n');
|
|
||||||
|
|
||||||
if cond_eq!(src, path + 1, b']') {
|
if cond_eq!(src, path + 1, b']') {
|
||||||
Some((
|
Some((
|
||||||
|
@ -25,10 +22,7 @@ impl<'a> Link<'a> {
|
||||||
path + 2,
|
path + 2,
|
||||||
))
|
))
|
||||||
} else if src.as_bytes()[path + 1] == b'[' {
|
} else if src.as_bytes()[path + 1] == b'[' {
|
||||||
let desc = until_while!(src, path + 2, b']', |c| c != b']'
|
let desc = until_while!(src, path + 2, b']', |c| c != b'[');
|
||||||
&& c != b'['
|
|
||||||
&& c != b'\n');
|
|
||||||
|
|
||||||
expect!(src, desc + 1, b']')?;
|
expect!(src, desc + 1, b']')?;
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
|
|
|
@ -9,14 +9,10 @@ pub enum Container {
|
||||||
Section { end: usize },
|
Section { end: usize },
|
||||||
|
|
||||||
Paragraph { end: usize, trailing: usize },
|
Paragraph { end: usize, trailing: usize },
|
||||||
CenterBlock { content_end: usize, end: usize },
|
CenterBlock { contents_end: usize, end: usize },
|
||||||
QuoteBlock { content_end: usize, end: usize },
|
QuoteBlock { contents_end: usize, end: usize },
|
||||||
SpecialBlock { content_end: usize, end: usize },
|
SpecialBlock { contents_end: usize, end: usize },
|
||||||
|
DynBlock { contents_end: usize, end: usize },
|
||||||
Drawer,
|
|
||||||
LatexEnv,
|
|
||||||
List,
|
|
||||||
Table,
|
|
||||||
|
|
||||||
Italic { end: usize },
|
Italic { end: usize },
|
||||||
Strike { end: usize },
|
Strike { end: usize },
|
||||||
|
@ -45,30 +41,33 @@ pub enum Event<'a> {
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
},
|
},
|
||||||
EndSpecialBlock,
|
EndSpecialBlock,
|
||||||
|
StartDynBlock {
|
||||||
|
name: &'a str,
|
||||||
|
args: Option<&'a str>,
|
||||||
|
},
|
||||||
|
EndDynBlock,
|
||||||
|
|
||||||
CommentBlock {
|
CommentBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
ExampleBlock {
|
ExampleBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
ExportBlock {
|
ExportBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
SrcBlock {
|
SrcBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
VerseBlock {
|
VerseBlock {
|
||||||
content: &'a str,
|
|
||||||
args: Option<&'a str>,
|
args: Option<&'a str>,
|
||||||
|
contents: &'a str,
|
||||||
},
|
},
|
||||||
|
|
||||||
DynBlockStart,
|
|
||||||
DynBlockEnd,
|
|
||||||
ListStart,
|
ListStart,
|
||||||
ListEnd,
|
ListEnd,
|
||||||
|
|
||||||
|
@ -85,8 +84,14 @@ pub enum Event<'a> {
|
||||||
TableCell,
|
TableCell,
|
||||||
|
|
||||||
LatexEnv,
|
LatexEnv,
|
||||||
FnDef(FnDef<'a>),
|
FnDef {
|
||||||
Keyword(Keyword<'a>),
|
label: &'a str,
|
||||||
|
contents: &'a str,
|
||||||
|
},
|
||||||
|
Keyword {
|
||||||
|
key: &'a str,
|
||||||
|
value: &'a str,
|
||||||
|
},
|
||||||
Rule,
|
Rule,
|
||||||
|
|
||||||
Cookie(Cookie<'a>),
|
Cookie(Cookie<'a>),
|
||||||
|
@ -172,21 +177,27 @@ impl<'a> Parser<'a> {
|
||||||
trailing: trailing + self.off,
|
trailing: trailing + self.off,
|
||||||
}),
|
}),
|
||||||
Element::QuoteBlock {
|
Element::QuoteBlock {
|
||||||
end, content_end, ..
|
end, contents_end, ..
|
||||||
} => self.stack.push(Container::QuoteBlock {
|
} => self.stack.push(Container::QuoteBlock {
|
||||||
content_end: content_end + self.off,
|
contents_end: contents_end + self.off,
|
||||||
end: end + self.off,
|
end: end + self.off,
|
||||||
}),
|
}),
|
||||||
Element::CenterBlock {
|
Element::CenterBlock {
|
||||||
end, content_end, ..
|
end, contents_end, ..
|
||||||
} => self.stack.push(Container::CenterBlock {
|
} => self.stack.push(Container::CenterBlock {
|
||||||
content_end: content_end + self.off,
|
contents_end: contents_end + self.off,
|
||||||
end: end + self.off,
|
end: end + self.off,
|
||||||
}),
|
}),
|
||||||
Element::SpecialBlock {
|
Element::SpecialBlock {
|
||||||
end, content_end, ..
|
end, contents_end, ..
|
||||||
} => self.stack.push(Container::SpecialBlock {
|
} => self.stack.push(Container::SpecialBlock {
|
||||||
content_end: content_end + self.off,
|
contents_end: contents_end + self.off,
|
||||||
|
end: end + self.off,
|
||||||
|
}),
|
||||||
|
Element::DynBlock {
|
||||||
|
end, contents_end, ..
|
||||||
|
} => self.stack.push(Container::DynBlock {
|
||||||
|
contents_end: contents_end + self.off,
|
||||||
end: end + self.off,
|
end: end + self.off,
|
||||||
}),
|
}),
|
||||||
_ => (),
|
_ => (),
|
||||||
|
@ -239,7 +250,7 @@ impl<'a> Parser<'a> {
|
||||||
Container::CenterBlock { .. } => Event::EndCenterBlock,
|
Container::CenterBlock { .. } => Event::EndCenterBlock,
|
||||||
Container::QuoteBlock { .. } => Event::EndQuoteBlock,
|
Container::QuoteBlock { .. } => Event::EndQuoteBlock,
|
||||||
Container::SpecialBlock { .. } => Event::EndSpecialBlock,
|
Container::SpecialBlock { .. } => Event::EndSpecialBlock,
|
||||||
_ => unimplemented!(),
|
Container::DynBlock { .. } => Event::EndDynBlock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,12 +259,11 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
type Item = Event<'a>;
|
type Item = Event<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Event<'a>> {
|
fn next(&mut self) -> Option<Event<'a>> {
|
||||||
let tail = &self.text[self.off..];
|
|
||||||
|
|
||||||
if self.stack.is_empty() {
|
if self.stack.is_empty() {
|
||||||
if self.off >= self.text.len() {
|
if self.off >= self.text.len() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
let tail = &self.text[self.off..];
|
||||||
Some(self.start_section_or_headline(tail))
|
Some(self.start_section_or_headline(tail))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -261,6 +271,7 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
|
|
||||||
Some(match last {
|
Some(match last {
|
||||||
Container::Headline { beg, end } => {
|
Container::Headline { beg, end } => {
|
||||||
|
let tail = &self.text[self.off..];
|
||||||
if self.off >= end {
|
if self.off >= end {
|
||||||
self.end()
|
self.end()
|
||||||
} else if self.off == beg {
|
} else if self.off == beg {
|
||||||
|
@ -269,20 +280,23 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
self.start_headline(tail)
|
self.start_headline(tail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Container::CenterBlock {
|
Container::DynBlock {
|
||||||
content_end, end, ..
|
contents_end, end, ..
|
||||||
|
}
|
||||||
|
| Container::CenterBlock {
|
||||||
|
contents_end, end, ..
|
||||||
}
|
}
|
||||||
| Container::QuoteBlock {
|
| Container::QuoteBlock {
|
||||||
content_end, end, ..
|
contents_end, end, ..
|
||||||
}
|
}
|
||||||
| Container::SpecialBlock {
|
| Container::SpecialBlock {
|
||||||
content_end, end, ..
|
contents_end, end, ..
|
||||||
} => {
|
} => {
|
||||||
if self.off >= content_end {
|
if self.off >= contents_end {
|
||||||
self.off = end;
|
self.off = end;
|
||||||
self.end()
|
self.end()
|
||||||
} else {
|
} else {
|
||||||
self.next_ele(content_end)
|
self.next_ele(contents_end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Container::Section { end } => {
|
Container::Section { end } => {
|
||||||
|
@ -311,7 +325,6 @@ impl<'a> Iterator for Parser<'a> {
|
||||||
self.next_obj(end)
|
self.next_obj(end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => unimplemented!(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,18 +357,19 @@ impl<'a> From<Element<'a>> for Event<'a> {
|
||||||
fn from(ele: Element<'a>) -> Self {
|
fn from(ele: Element<'a>) -> Self {
|
||||||
match ele {
|
match ele {
|
||||||
Element::Comment(c) => Event::Comment(c),
|
Element::Comment(c) => Event::Comment(c),
|
||||||
Element::FnDef(fd) => Event::FnDef(fd),
|
Element::FnDef { label, contents } => Event::FnDef { label, contents },
|
||||||
Element::Keyword(kw) => Event::Keyword(kw),
|
Element::Keyword { key, value } => Event::Keyword { key, value },
|
||||||
Element::Paragraph { .. } => Event::StartParagraph,
|
Element::Paragraph { .. } => Event::StartParagraph,
|
||||||
Element::Rule => Event::Rule,
|
Element::Rule => Event::Rule,
|
||||||
Element::CenterBlock { .. } => Event::StartCenterBlock,
|
Element::CenterBlock { .. } => Event::StartCenterBlock,
|
||||||
Element::QuoteBlock { .. } => Event::StartQuoteBlock,
|
Element::QuoteBlock { .. } => Event::StartQuoteBlock,
|
||||||
|
Element::DynBlock { name, args, .. } => Event::StartDynBlock { name, args },
|
||||||
Element::SpecialBlock { name, args, .. } => Event::StartSpecialBlock { name, args },
|
Element::SpecialBlock { name, args, .. } => Event::StartSpecialBlock { name, args },
|
||||||
Element::CommentBlock { args, content } => Event::CommentBlock { args, content },
|
Element::CommentBlock { args, contents } => Event::CommentBlock { args, contents },
|
||||||
Element::ExampleBlock { args, content } => Event::ExampleBlock { args, content },
|
Element::ExampleBlock { args, contents } => Event::ExampleBlock { args, contents },
|
||||||
Element::ExportBlock { args, content } => Event::ExportBlock { args, content },
|
Element::ExportBlock { args, contents } => Event::ExportBlock { args, contents },
|
||||||
Element::SrcBlock { args, content } => Event::SrcBlock { args, content },
|
Element::SrcBlock { args, contents } => Event::SrcBlock { args, contents },
|
||||||
Element::VerseBlock { args, content } => Event::VerseBlock { args, content },
|
Element::VerseBlock { args, contents } => Event::VerseBlock { args, contents },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,13 @@ macro_rules! expect {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! eol {
|
macro_rules! eol {
|
||||||
($src:expr) => {
|
($src:expr) => {
|
||||||
$src.find('\n').unwrap_or($src.len())
|
$src.find('\n').unwrap_or_else(|| $src.len())
|
||||||
};
|
};
|
||||||
($src:expr, $from:expr) => {
|
($src:expr, $from:expr) => {
|
||||||
$src[$from..]
|
$src[$from..]
|
||||||
.find('\n')
|
.find('\n')
|
||||||
.map(|i| i + $from)
|
.map(|i| i + $from)
|
||||||
.unwrap_or($src.len())
|
.unwrap_or_else(|| $src.len())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +132,9 @@ macro_rules! starts_with {
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! skip_space {
|
macro_rules! skip_space {
|
||||||
|
($src:ident) => {
|
||||||
|
until!($src, |c| c != b' ').unwrap_or(0)
|
||||||
|
};
|
||||||
($src:ident, $from:expr) => {
|
($src:ident, $from:expr) => {
|
||||||
until!($src[$from..], |c| c != b' ').unwrap_or(0) + $from
|
until!($src[$from..], |c| c != b' ').unwrap_or(0) + $from
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue