asciidork_parser/tasks/
heading_level.rs1use crate::internal::*;
2
3impl<'arena> Parser<'arena> {
4 pub fn line_heading_level(&self, line: &Line) -> Option<u8> {
5 let unadjusted = line.unadjusted_heading_level()?;
6 Some(adjusted_leveloffset(
7 self
8 .lexer
9 .leveloffset(line.first_loc().unwrap().include_depth),
10 adjusted_leveloffset(self.ctx.leveloffset, unadjusted),
11 ))
12 }
13
14 pub fn section_start_level(
15 &self,
16 lines: &ContiguousLines<'arena>,
17 meta: &ChunkMeta<'arena>,
18 ) -> Option<u8> {
19 for line in lines.iter() {
20 if line.is_block_attr_list() || line.is_chunk_title() || line.is_comment() {
21 continue;
22 } else if let Some(level) = self.line_heading_level(line) {
23 return match meta.attrs.has_str_positional("discrete")
24 || meta.attrs.has_str_positional("float")
25 {
26 true => None,
27 false => Some(level),
28 };
29 } else {
30 return None;
31 }
32 }
33 None
34 }
35
36 pub fn adjust_leveloffset(leveloffset: &mut i8, value: &AttrValue) {
37 match value {
38 AttrValue::String(s) => {
39 if let Some(add) = s.strip_prefix('+') {
40 *leveloffset += add.parse::<i8>().unwrap_or(0);
41 } else if let Some(sub) = s.strip_prefix('-') {
42 *leveloffset -= sub.parse::<i8>().unwrap_or(0);
43 } else {
44 *leveloffset = s.parse::<i8>().unwrap_or(*leveloffset);
45 }
46 }
47 AttrValue::Bool(false) => *leveloffset = 0,
48 AttrValue::Bool(true) => {}
49 }
50 }
51}
52
53const fn adjusted_leveloffset(leveloffset: i8, heading_level: u8) -> u8 {
54 if leveloffset == 0 {
55 return heading_level;
56 }
57 let new_level = (heading_level as i8) + leveloffset;
58 if new_level < 0 {
59 0
60 } else {
61 new_level as u8
62 }
63}