wayver's git archive


an obsidian renderer
git clone https://git.wayver.dev/sable

sable-markdown/src/parser/inline/code_span.rs@main

raw
Date Commit Message Author Files + -
2026-02-23 01:55 initial mvp wayverd 139 17808 0
...

1use nom::{
2    IResult, Parser,
3    branch::alt,
4    bytes::complete::tag,
5    character::complete::{anychar, char, line_ending, space0},
6    combinator::{not, peek, recognize, value},
7    multi::many1,
8    sequence::preceded,
9};
10
11pub(super) fn code_span(input: &str) -> IResult<&str, String> {
12    let (input, open_ticks) = backtick_string(input)?;
13    let tick_count = open_ticks.len();
14    let closing_tag_value = "`".repeat(tick_count);
15
16    let not_a_closing_tag = (tag(closing_tag_value.as_str()), char('`'));
17    let closing_tag = preceded(
18        peek(not(not_a_closing_tag)),
19        tag(closing_tag_value.as_str()),
20    );
21    let empty_line = (line_ending, space0, line_ending);
22    let content_parser = preceded(
23        peek(not(alt((value((), closing_tag), value((), empty_line))))),
24        anychar,
25    );
26
27    let (input, content) = recognize(many1(content_parser)).parse(input)?;
28    let (input, _) = tag(closing_tag_value.as_str()).parse(input)?;
29
30    let mut content = content.replace("\r\n", " ").replace('\n', " ");
31    if content.starts_with(' ') && content.ends_with(' ') && content.trim() != "" {
32        content = content[1..content.len() - 1].to_string();
33    }
34
35    Ok((input, content))
36}
37
38fn backtick_string(input: &str) -> IResult<&str, &str> {
39    recognize(many1(char('`'))).parse(input)
40}
41