This commit is contained in:
Maciej Jur 2024-04-18 22:42:39 +02:00
parent 2ae2ee0fd5
commit 6f9ae677b1
Signed by: kamov
GPG key ID: 191CBFF5F72ECAFD
3 changed files with 46 additions and 55 deletions

View file

@ -1,11 +1,10 @@
use hypertext::Renderable; use hypertext::Renderable;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag, TagEnd}; use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag, TagEnd, TextMergeStream};
use regex::Regex;
use crate::ts; use crate::ts;
use super::ruby;
static OPTS: Lazy<Options> = Lazy::new(|| static OPTS: Lazy<Options> = Lazy::new(||
Options::empty() Options::empty()
@ -33,7 +32,8 @@ static KATEX_B: Lazy<katex::Opts> = Lazy::new(||
pub fn parse(text: &str) -> String { pub fn parse(text: &str) -> String {
let stream = Parser::new_ext(text, *OPTS) let stream = Parser::new_ext(text, *OPTS);
let stream = TextMergeStream::new(stream)
.map(make_math) .map(make_math)
.map(make_emoji) .map(make_emoji)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -83,20 +83,50 @@ fn make_code(es: Vec<Event>) -> Vec<Event> {
buff buff
} }
fn make_ruby(event: Event) -> Vec<Event> { static RE_RUBY: Lazy<Regex> = Lazy::new(||
match event { Regex::new(r"\[([^\]]+)\]\{([^}]+)\}").unwrap()
Event::Text(text) => { );
let mut buff = Vec::new();
for item in ruby::annotate(&text) { #[derive(Debug)]
match item { enum Annotated<'a> {
ruby::Annotated::Text(text) => buff.push(Event::Text(text.to_owned().into())), Text(&'a str),
ruby::Annotated::Ruby(t, f) => buff.push(Event::InlineHtml(format!("<ruby>{t}<rp>(</rp><rt>{f}</rt><rp>)</rp></ruby>").into())), Ruby(&'a str, &'a str),
};
} }
buff
}, fn annotate(input: &str) -> Vec<Annotated> {
let mut parts: Vec<Annotated> = Vec::new();
let mut last_index = 0;
for cap in RE_RUBY.captures_iter(input) {
let text = cap.get(1).unwrap().as_str();
let ruby = cap.get(2).unwrap().as_str();
let index = cap.get(0).unwrap().start();
if index > last_index {
parts.push(Annotated::Text(&input[last_index..index]));
}
parts.push(Annotated::Ruby(text, ruby));
last_index = cap.get(0).unwrap().end();
}
if last_index < input.len() {
parts.push(Annotated::Text(&input[last_index..]));
}
parts
}
fn make_ruby(event: Event) -> Vec<Event> {
match event {
Event::Text(ref text) => annotate(&text)
.into_iter()
.map(|el| match el {
Annotated::Text(text) => Event::Text(text.to_owned().into()),
Annotated::Ruby(t, f) => Event::InlineHtml(format!("<ruby>{t}<rp>(</rp><rt>{f}</rt><rp>)</rp></ruby>").into()),
})
.collect(),
_ => vec![event], _ => vec![event],
} }
} }

View file

@ -1,2 +1 @@
pub mod md; pub mod md;
pub mod ruby;

View file

@ -1,38 +0,0 @@
use once_cell::sync::Lazy;
use regex::Regex;
static RE_RUBY: Lazy<Regex> = Lazy::new(||
Regex::new(r"\[([^\]]+)\]\{([^}]+)\}").unwrap()
);
#[derive(Debug)]
pub(crate) enum Annotated<'a> {
Text(&'a str),
Ruby(&'a str, &'a str),
}
pub fn annotate(input: &str) -> Vec<Annotated> {
let mut parts: Vec<Annotated> = Vec::new();
let mut last_index = 0;
for cap in RE_RUBY.captures_iter(input) {
let text = cap.get(1).unwrap().as_str();
let ruby = cap.get(2).unwrap().as_str();
let index = cap.get(0).unwrap().start();
if index > last_index {
parts.push(Annotated::Text(&input[last_index..index]));
}
parts.push(Annotated::Ruby(text, ruby));
last_index = cap.get(0).unwrap().end();
}
if last_index < input.len() {
parts.push(Annotated::Text(&input[last_index..]));
}
parts
}