refactor: utils macros
This commit is contained in:
parent
93ed18602a
commit
75362bd2a8
|
@ -11,7 +11,7 @@ impl Block {
|
||||||
|
|
||||||
let args = eol!(src);
|
let args = eol!(src);
|
||||||
let name = until_while!(src, 8, |c| c == b' ' || c == b'\n', |c: u8| c
|
let name = until_while!(src, 8, |c| c == b' ' || c == b'\n', |c: u8| c
|
||||||
.is_ascii_alphabetic());
|
.is_ascii_alphabetic())?;
|
||||||
// TODO: ignore case match
|
// TODO: ignore case match
|
||||||
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);
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl DynBlock {
|
||||||
|
|
||||||
let args = eol!(src);
|
let args = eol!(src);
|
||||||
let name = until_while!(src, 9, |c| c == b' ' || c == b'\n', |c: u8| c
|
let name = until_while!(src, 9, |c| c == b' ' || c == b'\n', |c: u8| c
|
||||||
.is_ascii_alphabetic());
|
.is_ascii_alphabetic())?;
|
||||||
// TODO: ignore case matching
|
// TODO: ignore case matching
|
||||||
let content = src.find("\n#+END:")?;
|
let content = src.find("\n#+END:")?;
|
||||||
let end = eol!(src, content + 1);
|
let end = eol!(src, content + 1);
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl FnDef {
|
||||||
pub fn parse(src: &str) -> Option<(&str, &str, 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)?;
|
||||||
|
|
||||||
if label == 4 {
|
if label == 4 {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -9,7 +9,7 @@ impl Keyword {
|
||||||
starts_with!(src, "#+");
|
starts_with!(src, "#+");
|
||||||
}
|
}
|
||||||
|
|
||||||
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_else(|| src.len());
|
let end = src.find('\n').map(|i| i + 1).unwrap_or_else(|| src.len());
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub struct Rule;
|
||||||
impl Rule {
|
impl Rule {
|
||||||
pub fn parse(src: &str) -> Option<usize> {
|
pub fn parse(src: &str) -> Option<usize> {
|
||||||
let end = eol!(src);
|
let end = eol!(src);
|
||||||
let leading = until_while!(src, 0, b'-', |c| c == b' ' || c == b'\t');
|
let leading = until_while!(src, 0, b'-', |c| c == b' ' || c == b'\t')?;
|
||||||
if src[leading..end].chars().all(|c| c == '-') && end - leading > 4 {
|
if src[leading..end].chars().all(|c| c == '-') && end - leading > 4 {
|
||||||
Some(end)
|
Some(end)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -11,7 +11,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.as_bytes()[num1] == b'%' && *src.as_bytes().get(num1 + 1)? == b']' {
|
if src.as_bytes()[num1] == b'%' && *src.as_bytes().get(num1 + 1)? == b']' {
|
||||||
Some((
|
Some((
|
||||||
|
@ -21,7 +21,7 @@ impl<'a> Cookie<'a> {
|
||||||
num1 + 2,
|
num1 + 2,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let num2 = until_while!(src, num1 + 1, b']', |c: u8| c.is_ascii_digit());
|
let num2 = until_while!(src, num1 + 1, b']', |c: u8| c.is_ascii_digit())?;
|
||||||
Some((
|
Some((
|
||||||
Cookie {
|
Cookie {
|
||||||
value: &src[0..=num2],
|
value: &src[0..=num2],
|
||||||
|
|
|
@ -3,7 +3,7 @@ pub struct Emphasis;
|
||||||
impl Emphasis {
|
impl Emphasis {
|
||||||
// TODO: return usize instead of Option<usize>
|
// TODO: return usize instead of Option<usize>
|
||||||
pub fn parse(src: &str, marker: u8) -> Option<usize> {
|
pub fn parse(src: &str, marker: u8) -> Option<usize> {
|
||||||
expect!(src, 1, |c: u8| !c.is_ascii_whitespace());
|
expect!(src, 1, |c: u8| !c.is_ascii_whitespace())?;
|
||||||
|
|
||||||
let mut lines = 0;
|
let mut lines = 0;
|
||||||
let end = until_while!(src, 1, marker, |c| {
|
let end = until_while!(src, 1, marker, |c| {
|
||||||
|
@ -11,9 +11,9 @@ impl Emphasis {
|
||||||
lines += 1;
|
lines += 1;
|
||||||
}
|
}
|
||||||
lines < 2
|
lines < 2
|
||||||
});
|
})?;
|
||||||
|
|
||||||
expect!(src, end - 1, |c: u8| !c.is_ascii_whitespace());
|
expect!(src, end - 1, |c: u8| !c.is_ascii_whitespace())?;
|
||||||
|
|
||||||
if end < src.len() - 1 {
|
if end < src.len() - 1 {
|
||||||
expect!(src, end + 1, |ch| ch == b' '
|
expect!(src, end + 1, |ch| ch == b' '
|
||||||
|
@ -26,7 +26,7 @@ impl Emphasis {
|
||||||
|| ch == b'\''
|
|| ch == b'\''
|
||||||
|| ch == b'\n'
|
|| ch == b'\n'
|
||||||
|| ch == b')'
|
|| ch == b')'
|
||||||
|| ch == b'}');
|
|| ch == b'}')?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(end)
|
Some(end)
|
||||||
|
|
|
@ -7,7 +7,7 @@ impl<'a> Entity<'a> {
|
||||||
pub fn parse(src: &'a str) -> Option<(Entity<'a>, usize)> {
|
pub fn parse(src: &'a str) -> Option<(Entity<'a>, usize)> {
|
||||||
expect!(src, 0, b'\\')?;
|
expect!(src, 0, b'\\')?;
|
||||||
|
|
||||||
let name = position!(src, 1, |c| !c.is_ascii_alphabetic());
|
let name = 0;
|
||||||
|
|
||||||
if src.as_bytes()[name] == b'[' {
|
if src.as_bytes()[name] == b'[' {
|
||||||
Some((
|
Some((
|
||||||
|
|
|
@ -13,7 +13,7 @@ impl<'a> FnRef<'a> {
|
||||||
pub fn parse(src: &'a str) -> Option<(FnRef<'a>, usize)> {
|
pub fn parse(src: &'a str) -> Option<(FnRef<'a>, usize)> {
|
||||||
starts_with!(src, "[fn:");
|
starts_with!(src, "[fn:");
|
||||||
|
|
||||||
let label = until_while!(src, 4, |c| c == b']' || c == b':', valid_label);
|
let label = until_while!(src, 4, |c| c == b']' || c == b':', valid_label)?;
|
||||||
|
|
||||||
if src.as_bytes()[label] == b':' {
|
if src.as_bytes()[label] == b':' {
|
||||||
let mut pairs = 1;
|
let mut pairs = 1;
|
||||||
|
|
|
@ -14,28 +14,28 @@ impl<'a> InlineCall<'a> {
|
||||||
starts_with!(src, "call_");
|
starts_with!(src, "call_");
|
||||||
|
|
||||||
let mut pos = until_while!(src, 5, |c| c == b'[' || c == b'(', |c: u8| c
|
let mut pos = until_while!(src, 5, |c| c == b'[' || c == b'(', |c: u8| c
|
||||||
.is_ascii_graphic());
|
.is_ascii_graphic())?;
|
||||||
let mut pos_;
|
let mut pos_;
|
||||||
|
|
||||||
let name = &src[5..pos];
|
let name = &src[5..pos];
|
||||||
|
|
||||||
let inside_header = if src.as_bytes()[pos] == b'[' {
|
let inside_header = if src.as_bytes()[pos] == b'[' {
|
||||||
pos_ = pos;
|
pos_ = pos;
|
||||||
pos = until_while!(src, pos, b']', |c: u8| c != b'\n') + 1;
|
pos = until_while!(src, pos, b']', |c: u8| c != b'\n')? + 1;
|
||||||
expect!(src, pos, b'(');
|
expect!(src, pos, b'(')?;
|
||||||
Some(&src[pos_ + 1..pos - 1])
|
Some(&src[pos_ + 1..pos - 1])
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
pos_ = pos;
|
pos_ = pos;
|
||||||
pos = until_while!(src, pos, b')', |c| c != b'\n');
|
pos = until_while!(src, pos, b')', |c| c != b'\n')?;
|
||||||
let args = &src[pos_ + 1..pos];
|
let args = &src[pos_ + 1..pos];
|
||||||
|
|
||||||
let end_header = if src.len() > pos + 1 && src.as_bytes()[pos + 1] == b'[' {
|
let end_header = if src.len() > pos + 1 && src.as_bytes()[pos + 1] == b'[' {
|
||||||
pos_ = pos;
|
pos_ = pos;
|
||||||
pos = until_while!(src, pos_ + 1, |c| c == b']', |c: u8| c != b'\n'
|
pos = until_while!(src, pos_ + 1, |c| c == b']', |c: u8| c != b'\n'
|
||||||
&& c != b')');
|
&& c != b')')?;
|
||||||
Some(&src[pos_ + 2..pos])
|
Some(&src[pos_ + 2..pos])
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -11,15 +11,15 @@ impl<'a> InlineSrc<'a> {
|
||||||
starts_with!(src, "src_");
|
starts_with!(src, "src_");
|
||||||
|
|
||||||
let lang = until_while!(src, 4, |c| c == b'[' || c == b'{', |c: u8| !c
|
let lang = until_while!(src, 4, |c| c == b'[' || c == b'{', |c: u8| !c
|
||||||
.is_ascii_whitespace());
|
.is_ascii_whitespace())?;
|
||||||
|
|
||||||
if lang == 4 {
|
if lang == 4 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if src.as_bytes()[lang] == b'[' {
|
if src.as_bytes()[lang] == b'[' {
|
||||||
let option = until_while!(src, lang, b']', |c| c != b'\n');
|
let option = until_while!(src, lang, b']', |c| c != b'\n')?;
|
||||||
let body = until_while!(src, option, b'}', |c| c != b'\n');
|
let body = until_while!(src, option, b'}', |c| c != b'\n')?;
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
InlineSrc {
|
InlineSrc {
|
||||||
|
@ -30,7 +30,7 @@ impl<'a> InlineSrc<'a> {
|
||||||
body + 1,
|
body + 1,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let body = until_while!(src, lang, b'}', |c| c != b'\n');
|
let body = until_while!(src, lang, b'}', |c| c != b'\n')?;
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
InlineSrc {
|
InlineSrc {
|
||||||
|
|
|
@ -11,7 +11,7 @@ impl<'a> Link<'a> {
|
||||||
starts_with!(src, "[[");
|
starts_with!(src, "[[");
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = until_while!(src, 2, b']', |c| c != b'<' && c != b'>' && c != b'\n');
|
let path = until_while!(src, 2, b']', |c| c != b'<' && c != b'>' && c != b'\n')?;
|
||||||
|
|
||||||
if cond_eq!(src, path + 1, b']') {
|
if cond_eq!(src, path + 1, b']') {
|
||||||
Some((
|
Some((
|
||||||
|
@ -22,7 +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'[')?;
|
||||||
expect!(src, desc + 1, b']')?;
|
expect!(src, desc + 1, b']')?;
|
||||||
|
|
||||||
Some((
|
Some((
|
||||||
|
|
|
@ -15,9 +15,9 @@ impl<'a> Macros<'a> {
|
||||||
pub fn parse(src: &'a str) -> Option<(Macros<'a>, usize)> {
|
pub fn parse(src: &'a str) -> Option<(Macros<'a>, usize)> {
|
||||||
starts_with!(src, "{{{");
|
starts_with!(src, "{{{");
|
||||||
|
|
||||||
expect!(src, 3, |c: u8| c.is_ascii_alphabetic());
|
expect!(src, 3, |c: u8| c.is_ascii_alphabetic())?;
|
||||||
|
|
||||||
let name = until_while!(src, 3, |c| c == b'}' || c == b'(', valid_name);
|
let name = until_while!(src, 3, |c| c == b'}' || c == b'(', valid_name)?;
|
||||||
|
|
||||||
if src.as_bytes()[name] == b'}' {
|
if src.as_bytes()[name] == b'}' {
|
||||||
expect!(src, name + 1, b'}')?;
|
expect!(src, name + 1, b'}')?;
|
||||||
|
|
|
@ -13,7 +13,7 @@ impl<'a> Snippet<'a> {
|
||||||
starts_with!(src, "@@");
|
starts_with!(src, "@@");
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = until_while!(src, 2, b':', |c: u8| c.is_ascii_alphanumeric() || c == b'-');
|
let name = until_while!(src, 2, b':', |c: u8| c.is_ascii_alphanumeric() || c == b'-')?;
|
||||||
|
|
||||||
if name == 2 {
|
if name == 2 {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
@ -9,11 +9,11 @@ impl<'a> RadioTarget<'a> {
|
||||||
starts_with!(src, "<<<");
|
starts_with!(src, "<<<");
|
||||||
}
|
}
|
||||||
|
|
||||||
expect!(src, 3, |c| c != b' ');
|
expect!(src, 3, |c| c != b' ')?;
|
||||||
|
|
||||||
let end = until_while!(src, 3, b'>', |c| c != b'<' && c != b'\n');
|
let end = until_while!(src, 3, b'>', |c| c != b'<' && c != b'\n')?;
|
||||||
|
|
||||||
expect!(src, end - 1, |c| c != b' ');
|
expect!(src, end - 1, |c| c != b' ')?;
|
||||||
expect!(src, end + 1, b'>')?;
|
expect!(src, end + 1, b'>')?;
|
||||||
expect!(src, end + 2, b'>')?;
|
expect!(src, end + 2, b'>')?;
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ impl<'a> Target<'a> {
|
||||||
starts_with!(src, "<<");
|
starts_with!(src, "<<");
|
||||||
}
|
}
|
||||||
|
|
||||||
expect!(src, 2, |c| c != b' ');
|
expect!(src, 2, |c| c != b' ')?;
|
||||||
|
|
||||||
let end = until_while!(src, 2, b'>', |c| c != b'<' && c != b'\n');
|
let end = until_while!(src, 2, b'>', |c| c != b'<' && c != b'\n')?;
|
||||||
|
|
||||||
expect!(src, end - 1, |c| c != b' ');
|
expect!(src, end - 1, |c| c != b' ')?;
|
||||||
expect!(src, end + 1, b'>')?;
|
expect!(src, end + 1, b'>')?;
|
||||||
|
|
||||||
Some((Target(&src[2..end]), end + 2))
|
Some((Target(&src[2..end]), end + 2))
|
||||||
|
|
95
src/utils.rs
95
src/utils.rs
|
@ -3,13 +3,10 @@
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! expect {
|
macro_rules! expect {
|
||||||
($src:ident, $index:expr, $expect:tt) => {
|
($src:ident, $index:expr, $expect:tt) => {
|
||||||
$src.as_bytes().get($index).filter(|&b| b == &$expect)
|
$src.as_bytes().get($index).filter(|&&b| b == $expect)
|
||||||
};
|
};
|
||||||
($src:ident, $index:expr, $expect:expr) => {
|
($src:ident, $index:expr, $expect:expr) => {
|
||||||
// $src.as_bytes().get($index).filter($expect)
|
$src.as_bytes().get($index).filter(|&&b| $expect(b))
|
||||||
if $index >= $src.len() || !$expect($src.as_bytes()[$index]) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,30 +27,30 @@ macro_rules! eol {
|
||||||
macro_rules! until {
|
macro_rules! until {
|
||||||
($src:expr, $until:tt) => {{
|
($src:expr, $until:tt) => {{
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
while pos < $src.len() {
|
loop {
|
||||||
if $until == $src.as_bytes()[pos] {
|
if pos >= $src.len() {
|
||||||
break;
|
break None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if $until == $src.as_bytes()[pos] {
|
||||||
|
break Some(pos);
|
||||||
|
} else {
|
||||||
|
pos += 1;
|
||||||
}
|
}
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == $src.len() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(pos)
|
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
($src:expr, $until:expr) => {{
|
($src:expr, $until:expr) => {{
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
while pos < $src.len() {
|
loop {
|
||||||
if $until($src.as_bytes()[pos]) {
|
if pos >= $src.len() {
|
||||||
break;
|
break None;
|
||||||
|
}
|
||||||
|
|
||||||
|
if $until($src.as_bytes()[pos]) {
|
||||||
|
break Some(pos);
|
||||||
|
} else {
|
||||||
|
pos += 1;
|
||||||
}
|
}
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
if pos == $src.len() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(pos)
|
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -62,41 +59,33 @@ macro_rules! until {
|
||||||
macro_rules! until_while {
|
macro_rules! until_while {
|
||||||
($src:expr, $start:expr, $until:tt, $while:expr) => {{
|
($src:expr, $start:expr, $until:tt, $while:expr) => {{
|
||||||
let mut pos = $start;
|
let mut pos = $start;
|
||||||
while pos < $src.len() {
|
loop {
|
||||||
// println!("pos {} char {} ", pos, $src.as_bytes()[pos] as char,);
|
if pos >= $src.len() {
|
||||||
if $until == $src.as_bytes()[pos] {
|
break None;
|
||||||
break;
|
} else if $until == $src.as_bytes()[pos] {
|
||||||
|
break Some(pos);
|
||||||
} else if $while($src.as_bytes()[pos]) {
|
} else if $while($src.as_bytes()[pos]) {
|
||||||
pos += 1;
|
pos += 1;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
return None;
|
break None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if pos == $src.len() {
|
|
||||||
return None;
|
|
||||||
} else {
|
|
||||||
pos
|
|
||||||
}
|
|
||||||
}};
|
}};
|
||||||
($src:expr, $start:expr, $until:expr, $while:expr) => {{
|
($src:expr, $start:expr, $until:expr, $while:expr) => {{
|
||||||
let mut pos = $start;
|
let mut pos = $start;
|
||||||
while pos < $src.len() {
|
loop {
|
||||||
// println!("pos {} char {}", pos, $src.as_bytes()[pos] as char);
|
if pos >= $src.len() {
|
||||||
if $until($src.as_bytes()[pos]) {
|
break None;
|
||||||
break;
|
} else if $until($src.as_bytes()[pos]) {
|
||||||
|
break Some(pos);
|
||||||
} else if $while($src.as_bytes()[pos]) {
|
} else if $while($src.as_bytes()[pos]) {
|
||||||
pos += 1;
|
pos += 1;
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
return None;
|
break None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if pos == $src.len() {
|
|
||||||
return None;
|
|
||||||
} else {
|
|
||||||
pos
|
|
||||||
}
|
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,16 +100,6 @@ macro_rules! cond_eq {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! position {
|
|
||||||
($s:ident, $i:expr, $p:expr) => {
|
|
||||||
match $s[$i..].chars().position($p) {
|
|
||||||
Some(x) => x + $i,
|
|
||||||
None => return None,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! starts_with {
|
macro_rules! starts_with {
|
||||||
($s:ident, $p:expr) => {
|
($s:ident, $p:expr) => {
|
||||||
|
@ -144,13 +123,13 @@ macro_rules! skip_space {
|
||||||
macro_rules! skip_empty_line {
|
macro_rules! skip_empty_line {
|
||||||
($src:ident, $from:expr) => {{
|
($src:ident, $from:expr) => {{
|
||||||
let mut pos = $from;
|
let mut pos = $from;
|
||||||
while pos < $src.len() {
|
loop {
|
||||||
if $src.as_bytes()[pos] != b'\n' {
|
if pos >= $src.len() || $src.as_bytes()[pos] != b'\n' {
|
||||||
break;
|
break pos;
|
||||||
|
} else {
|
||||||
|
pos += 1;
|
||||||
}
|
}
|
||||||
pos += 1;
|
|
||||||
}
|
}
|
||||||
pos
|
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue