aboutsummaryrefslogtreecommitdiffstats
path: root/src/construct/partial_label.rs
diff options
context:
space:
mode:
authorLibravatar Titus Wormer <tituswormer@gmail.com>2022-06-17 17:45:50 +0200
committerLibravatar Titus Wormer <tituswormer@gmail.com>2022-06-17 17:45:50 +0200
commit24fec22e912c1aa2569e95683ca95edf1aafce8b (patch)
treed4b680ce042b7e1a6884f59f01a29087704f3378 /src/construct/partial_label.rs
parent60ea2fd3a09f10fa28bf48575736b47afebf3221 (diff)
downloadmarkdown-rs-24fec22e912c1aa2569e95683ca95edf1aafce8b.tar.gz
markdown-rs-24fec22e912c1aa2569e95683ca95edf1aafce8b.tar.bz2
markdown-rs-24fec22e912c1aa2569e95683ca95edf1aafce8b.zip
Add support for definitions
* Add definitions * Add partials for label, destination, title * Add `go`, to attempt something, and do something else on `ok`
Diffstat (limited to 'src/construct/partial_label.rs')
-rw-r--r--src/construct/partial_label.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/construct/partial_label.rs b/src/construct/partial_label.rs
new file mode 100644
index 0000000..c772c56
--- /dev/null
+++ b/src/construct/partial_label.rs
@@ -0,0 +1,100 @@
+// To do: pass token types in.
+
+use crate::constant::LINK_REFERENCE_SIZE_MAX;
+use crate::tokenizer::{Code, State, StateFnResult, TokenType, Tokenizer};
+
+/// To do.
+pub fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult {
+ match code {
+ Code::Char('[') => {
+ tokenizer.enter(TokenType::DefinitionLabel);
+ tokenizer.enter(TokenType::DefinitionLabelMarker);
+ tokenizer.consume(code);
+ tokenizer.exit(TokenType::DefinitionLabelMarker);
+ tokenizer.enter(TokenType::DefinitionLabelData);
+ (State::Fn(Box::new(|t, c| at_break(t, c, false, 0))), None)
+ }
+ // To do: allow?
+ _ => unreachable!("expected `[` at start of label"),
+ }
+}
+
+/// To do.
+fn at_break(tokenizer: &mut Tokenizer, code: Code, data: bool, size: usize) -> StateFnResult {
+ match code {
+ Code::None | Code::Char('[') => (State::Nok, None),
+ Code::Char(']') if !data => (State::Nok, None),
+ _ if size > LINK_REFERENCE_SIZE_MAX => (State::Nok, None),
+ Code::Char(']') => {
+ tokenizer.exit(TokenType::DefinitionLabelData);
+ tokenizer.enter(TokenType::DefinitionLabelMarker);
+ tokenizer.consume(code);
+ tokenizer.exit(TokenType::DefinitionLabelMarker);
+ tokenizer.exit(TokenType::DefinitionLabel);
+ (State::Ok, None)
+ }
+ Code::CarriageReturnLineFeed | Code::Char('\r' | '\n') => {
+ tokenizer.enter(TokenType::LineEnding);
+ tokenizer.consume(code);
+ tokenizer.exit(TokenType::LineEnding);
+ (
+ State::Fn(Box::new(move |t, c| at_break(t, c, data, size))),
+ None,
+ )
+ }
+ _ => {
+ tokenizer.enter(TokenType::ChunkString);
+ // To do: link.
+ label(tokenizer, code, data, size)
+ }
+ }
+}
+
+/// To do.
+fn label(tokenizer: &mut Tokenizer, code: Code, data: bool, size: usize) -> StateFnResult {
+ match code {
+ Code::None | Code::CarriageReturnLineFeed | Code::Char('\r' | '\n' | '[' | ']') => {
+ tokenizer.exit(TokenType::ChunkString);
+ at_break(tokenizer, code, data, size)
+ }
+ _ if size > LINK_REFERENCE_SIZE_MAX => {
+ tokenizer.exit(TokenType::ChunkString);
+ at_break(tokenizer, code, data, size)
+ }
+ Code::VirtualSpace | Code::Char('\t' | ' ') => {
+ tokenizer.consume(code);
+ (
+ State::Fn(Box::new(move |t, c| label(t, c, data, size + 1))),
+ None,
+ )
+ }
+ Code::Char('/') => {
+ tokenizer.consume(code);
+ (
+ State::Fn(Box::new(move |t, c| escape(t, c, true, size + 1))),
+ None,
+ )
+ }
+ Code::Char(_) => {
+ tokenizer.consume(code);
+ (
+ State::Fn(Box::new(move |t, c| label(t, c, true, size + 1))),
+ None,
+ )
+ }
+ }
+}
+
+/// To do.
+fn escape(tokenizer: &mut Tokenizer, code: Code, data: bool, size: usize) -> StateFnResult {
+ match code {
+ Code::Char('[' | '\\' | ']') => {
+ tokenizer.consume(code);
+ (
+ State::Fn(Box::new(move |t, c| label(t, c, true, size + 1))),
+ None,
+ )
+ }
+ _ => label(tokenizer, code, data, size),
+ }
+}