From 5c327e249e03ac303e7fef40e2df6c6ef834db66 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Thu, 8 Jul 2021 20:03:13 +0200 Subject: [PATCH] Switch to = for headings once again --- src/parse/mod.rs | 10 +++--- src/parse/scanner.rs | 6 ++-- src/parse/tokens.rs | 51 +++++++++++++++------------- src/pretty.rs | 4 +-- src/syntax/token.rs | 3 -- tests/ref/code/let.png | Bin 2231 -> 2245 bytes tests/ref/markup/heading.png | Bin 7446 -> 7328 bytes tests/typ/code/call-wide.typ | 2 +- tests/typ/code/importable/chap1.typ | 2 +- tests/typ/code/importable/chap2.typ | 2 +- tests/typ/code/include.typ | 2 +- tests/typ/code/let.typ | 2 +- tests/typ/coma.typ | 2 +- tests/typ/markup/heading.typ | 24 ++++++------- tools/support/typst.tmLanguage.json | 2 +- 15 files changed, 55 insertions(+), 57 deletions(-) diff --git a/src/parse/mod.rs b/src/parse/mod.rs index bdecc31f8..1d893ad9d 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -102,14 +102,12 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option { Token::Star => Node::Strong(span), Token::Underscore => Node::Emph(span), Token::Raw(t) => raw(p, t), - Token::Hashtag if *at_start => return Some(heading(p)), + Token::Eq if *at_start => return Some(heading(p)), Token::Hyph if *at_start => return Some(list_item(p)), Token::Numbering(number) if *at_start => return Some(enum_item(p, number)), // Line-based markup that is not currently at the start of the line. - Token::Hashtag | Token::Hyph | Token::Numbering(_) => { - Node::Text(p.peek_src().into()) - } + Token::Eq | Token::Hyph | Token::Numbering(_) => Node::Text(p.peek_src().into()), // Hashtag + keyword / identifier. Token::Ident(_) @@ -183,11 +181,11 @@ fn raw(p: &mut Parser, token: RawToken) -> Node { /// Parse a heading. fn heading(p: &mut Parser) -> Node { let start = p.next_start(); - p.assert(Token::Hashtag); + p.assert(Token::Eq); // Count depth. let mut level: usize = 1; - while p.eat_if(Token::Hashtag) { + while p.eat_if(Token::Eq) { level += 1; } diff --git a/src/parse/scanner.rs b/src/parse/scanner.rs index fad44e89f..af88aa684 100644 --- a/src/parse/scanner.rs +++ b/src/parse/scanner.rs @@ -88,12 +88,12 @@ impl<'s> Scanner<'s> { /// Checks whether the next char fulfills a condition. /// - /// Returns `false` if there is no next char. - pub fn check(&self, f: F) -> bool + /// Returns `default` if there is no next char. + pub fn check_or(&self, default: bool, f: F) -> bool where F: FnOnce(char) -> bool, { - self.peek().map(f).unwrap_or(false) + self.peek().map_or(default, f) } /// The previous index in the source string. diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index f21967402..aebe7b70d 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -89,19 +89,22 @@ impl<'s> Iterator for Tokens<'s> { impl<'s> Tokens<'s> { fn markup(&mut self, start: usize, c: char) -> Token<'s> { match c { + // Escape sequences. + '\\' => self.backslash(), + + // Keywords and identifiers. + '#' => self.hash(), + // Markup. '~' => Token::Tilde, '*' => Token::Star, '_' => Token::Underscore, - '\\' => self.backslash(), '`' => self.raw(), '$' => self.math(), '-' => self.hyph(start), + '=' if self.s.check_or(true, |c| c == '=' || c.is_whitespace()) => Token::Eq, c if c == '.' || c.is_ascii_digit() => self.numbering(start, c), - // Headings, keywords and identifiers. - '#' => self.hash(start), - // Plain text. _ => self.text(start), } @@ -143,7 +146,7 @@ impl<'s> Tokens<'s> { // Numbers. c if c.is_ascii_digit() - || (c == '.' && self.s.check(|n| n.is_ascii_digit())) => + || (c == '.' && self.s.check_or(false, |n| n.is_ascii_digit())) => { self.number(start, c) } @@ -157,7 +160,7 @@ impl<'s> Tokens<'s> { fn whitespace(&mut self, first: char) -> Token<'s> { // Fast path for just a single space - if first == ' ' && !self.s.check(char::is_whitespace) { + if first == ' ' && self.s.check_or(true, |c| !c.is_whitespace()) { Token::Space(0) } else { self.s.uneat(); @@ -188,8 +191,10 @@ impl<'s> Tokens<'s> { '/' => true, // Parentheses. '[' | ']' | '{' | '}' => true, + // Code. + '#' => true, // Markup. - '#' | '~' | '*' | '_' | '`' | '$' | '-' => true, + '~' | '*' | '_' | '`' | '$' | '-' => true, // Escaping. '\\' => true, // Just text. @@ -233,18 +238,16 @@ impl<'s> Tokens<'s> { } } - fn hash(&mut self, start: usize) -> Token<'s> { - if self.s.check(is_id_start) { + fn hash(&mut self) -> Token<'s> { + if self.s.check_or(false, is_id_start) { let read = self.s.eat_while(is_id_continue); if let Some(keyword) = keyword(read) { keyword } else { Token::Ident(read) } - } else if self.s.check(|c| c != '#' && !c.is_whitespace()) { - Token::Text(self.s.eaten_from(start)) } else { - Token::Hashtag + Token::Invalid("#") } } @@ -255,10 +258,10 @@ impl<'s> Tokens<'s> { } else { Token::HyphHyph } - } else if self.s.check(|c| !c.is_whitespace()) { - Token::Text(self.s.eaten_from(start)) - } else { + } else if self.s.check_or(true, char::is_whitespace) { Token::Hyph + } else { + Token::Text(self.s.eaten_from(start)) } } @@ -274,11 +277,11 @@ impl<'s> Tokens<'s> { None }; - if self.s.check(|c| !c.is_whitespace()) { - return Token::Text(self.s.eaten_from(start)); + if self.s.check_or(true, char::is_whitespace) { + Token::Numbering(number) + } else { + Token::Text(self.s.eaten_from(start)) } - - Token::Numbering(number) } fn raw(&mut self) -> Token<'s> { @@ -663,8 +666,8 @@ mod tests { // Test code symbols in text. t!(Markup[" /"]: "a():\"b" => Text("a():\"b")); t!(Markup[" /"]: ";:,|/+" => Text(";:,|"), Text("/+")); - t!(Markup[" /"]: "#-a" => Text("#"), Text("-"), Text("a")); - t!(Markup[" "]: "#123" => Text("#"), Text("123")); + t!(Markup[" /"]: "=-a" => Text("="), Text("-"), Text("a")); + t!(Markup[" "]: "#123" => Invalid("#"), Text("123")); // Test text ends. t!(Markup[""]: "hello " => Text("hello"), Space(0)); @@ -712,8 +715,8 @@ mod tests { // Test markup tokens. t!(Markup[" a1"]: "*" => Star); t!(Markup: "_" => Underscore); - t!(Markup[""]: "###" => Hashtag, Hashtag, Hashtag); - t!(Markup["a1/"]: "# " => Hashtag, Space(0)); + t!(Markup[""]: "===" => Eq, Eq, Eq); + t!(Markup["a1/"]: "= " => Eq, Space(0)); t!(Markup: "~" => Tilde); t!(Markup[" "]: r"\" => Backslash); t!(Markup["a "]: r"a--" => Text("a"), HyphHyph); @@ -776,7 +779,7 @@ mod tests { for &(s, t) in &list { t!(Markup[" "]: format!("#{}", s) => t); t!(Markup[" "]: format!("#{0}#{0}", s) => t, t); - t!(Markup[" /"]: format!("# {}", s) => Token::Hashtag, Space(0), Text(s)); + t!(Markup[" /"]: format!("# {}", s) => Token::Invalid("#"), Space(0), Text(s)); } for &(s, t) in &list { diff --git a/src/pretty.rs b/src/pretty.rs index 17609ceaf..ff8841f3e 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -169,7 +169,7 @@ impl Pretty for RawNode { impl Pretty for HeadingNode { fn pretty(&self, p: &mut Printer) { for _ in 0 .. self.level { - p.push('#'); + p.push('='); } p.push(' '); self.body.pretty(p); @@ -653,7 +653,7 @@ mod tests { roundtrip("\\ "); roundtrip("\n\n"); roundtrip("hi"); - roundtrip("# *Ok*"); + roundtrip("= *Ok*"); roundtrip("- Ok"); // Raw. diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 32a14d58f..425dac108 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -19,8 +19,6 @@ pub enum Token<'s> { Star, /// An underscore: `_`. Underscore, - /// A single hashtag: `#`. - Hashtag, /// A tilde: `~`. Tilde, /// Two hyphens: `--`. @@ -215,7 +213,6 @@ impl<'s> Token<'s> { Self::RightParen => "closing paren", Self::Star => "star", Self::Underscore => "underscore", - Self::Hashtag => "hashtag", Self::Tilde => "tilde", Self::HyphHyph => "en dash", Self::HyphHyphHyph => "em dash", diff --git a/tests/ref/code/let.png b/tests/ref/code/let.png index ae360b6b6b1dc1938d70f85696f86e5cf2500f00..e9c00064432e5061ff64bd25490607ef3fd2c574 100644 GIT binary patch delta 1843 zcmZ`)c{tnY7XF2Vpi@#o7$Xr=C1}LhV!4e}?8T^{8Z#B*)>cb3QzbV)8e1(7LTS;) zw6QPcp=QQXLnTHH9ko?0)lvJ>RurY&bne!F?qBD7&iB0UdEWD#@4PLD9z?c^Y!O@% z005Aw>H zzN1qN=UcpUPTk2Q1Rdhu{bDBAr)Lmm4!J`vK2Om8JGi?Ugt*-)lvb{Cmow@giUAqB z?+)>mTAb{NG_80eL0eho8_`w|YSVzgsejb})-QwLR^MnQh>vqzU43IDTxlZoO`ta8 z=yB z_cP_69ruqwn~7h-UZqwawzTyMbLL8h}0;$Bkx@Wsi|^re+c z{B*%xmi5OJmF8;axy)*H8Q$_bO&HR-Aj4%zq1Y0Lzrp>_#j2WNja#XyBXy3*()yCi z*JB2LURK`@Z8?v~wge)doiG2IrtzaCv<7SIQBrN9S@WMMq< z_Y=-yy{c?`Eqy)vSq~_0pc~%n6i0I^>!QNfp2y*%-%rbX1mDGy=as+^T*IG}KSq0< zq<~a-{VY(zPcx*Lix>?2l(go%u(55-cmUfIXuLj{)h?x>$L44Fmz3pUX7G;(NCxT7@$pX;%Fv1Sm((%eH8VMN@ zniWTYRpxR=fpr+9**Dw-6#9lgBxvt_mlR2>^$LenoURNr3nJ-CEH3LSFWwJL(FuJ* zOENTHNLDxZ1cnW(++74|u)HI(-;R#`%p`Uy_m;V2di0?cFb#LC{OZXSWxp2J(R<2M z4bg!n3#$%X9N9;jbaOtsP~O8?9_Tp-$-f8)Jr#yEMMo)`(y%E85FLz0-?lpnGg{I* zBkDjxCWs5Pi}ikc6KCvcSHG`peE1CgxblCap8Donc!;I2!9fWE)-fK8PLx5It)2zl z`(!VZ&MvS1=KA?^uh`v2i^qh&FKI(zr1s~EBHU=!#g;Xhlw;$WlAc~vg1;dw9?a=|)MA9AF@RI#0*jXVl&mpWd^*Wz|FTfeFveh=LsnEkc_1ey7S zhGPw~YdB8yZxX+x&H`h?Hr-c(m=ci3H`ncSTxGS)TnEc)A%W4hlP0Qoiug05U9X2* z9;U-UJ6HK?zZ!23?}&g#>3@Q#AQ9&i0vXTdvBJ?azQC2ZiX}x zR)BrecuV}WYHT-~@y8!b#^W?Gr$ller}z1ApefwLzSBcb=d;B(DOZ~3Q!Sj7gB0CM zEjE?YRf*Ihmq98RRKHeb|4N(xw=l&N=uBYT>I&4Vn5?;Bj1UFIsZ+>)d&Y?U{S|(D z_USfRo7dE3H~=QX!Q=n3n*Y}2I3t#u5W_aMf$=U%5E4^;;nbphy3=~QRH^7BC;gYG xb<1rIL+X<%gHKS-9`?T4e+)~^!dAhuC1xHyGd$Q5c#F*uaHP1}){!qH{u7`aEtCKN delta 1822 zcmYjSc{JPk7XK!KjM}2Spj8snL7pY5rLjf`)rOLy8WgcM8O-pys3jSGYE)^I(xIwe zo7xhwJkQkr#I$H@`YfTAs-d#xgrPCFB|%eE zS0u(k&2{tdjVbO2rWb$B5`A=~Bd1u!Gv!hI((~baDF3-N`f55nXXHXiexvB)&2H7# zT%kWrL=zXrR_aIbJM6eQoUw2V)T7WHt!oZ4siL6Wt(#_*dQsbJfwQrv_juOOxlDMGp*{|00a z0fnp#$%CQ*%kd1ZKF}nmWA0uF;}2ysA3Zm0HJ=PwM6#hDK<9ON-f`fo$l_d9z^jSf zW~>qVO2OTrryI6@#kyo{bpQp-OckdeDk4?o*Gxr}A63ipEfu{^ZOA!N9X*|TMgi{rD$kdq*5~<30YWURMMOECS zk%)Ag8JSw>Sp(Iu8A`yxv@Kv>C-pYGmI`BlDrHdbcgj{k?tCogk%H(`(`1&@Mm(^A z=o)f`b9iN`vV7%{QY`7c2AeTPfBKj_%u7;-xnNqa$<*7r zLq=U?X4O|0?UA`>TVAII=WKhydQ|KkHndj!wnCNl1mZ_0WXkFy#vp!fdu4{A{J#7L zq-l*0@x}^G7v{W!w4 z$QwmE1QLoC@w#DO*@4jpIIb5QJmct@@zO@!S6Sg)p^V|fEdK=-x!6ZS`IHY*t54k6iN=d7USS-UctXKLyP1_B~c^w)yX`_u=XMyT*UN^5NP8@)a)K80kRRsE??0U_mX)xm8NX zH-S}n=an~pa7}vjS65$9YL(g2GPhtKy+Yxo7MMK$kSHCU;5%o*qlr|qfWPX$xX42#6b~=BVga#X*pcqdu3gZv}l{%EEwCxL!~;9 zcb1BtB;T`MZczi?ZLWU*O|3a67kyw^vAZXn^@38$+LzRG^fG;@A+MAswXoqO7A3Mg5%Y5 z2O}`!vH_W#NHA1?DX>L7q|z}jSVrCdGyJYUl!Q_#jdkofq;ks|{&lj44lG1>bqJ-1 zqB?h5k diff --git a/tests/ref/markup/heading.png b/tests/ref/markup/heading.png index f69bb887d81410853684c0220d1847169ea498bb..35a589bd832c796aa4b140fde058c87d060a5201 100644 GIT binary patch literal 7328 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 literal 7446 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 diff --git a/tests/typ/code/call-wide.typ b/tests/typ/code/call-wide.typ index 54da540bd..996a052d1 100644 --- a/tests/typ/code/call-wide.typ +++ b/tests/typ/code/call-wide.typ @@ -7,7 +7,7 @@ --- // Test in heading. -# A #align!(right) B += A #align!(right) B C --- diff --git a/tests/typ/code/importable/chap1.typ b/tests/typ/code/importable/chap1.typ index a0f38d0d6..06a4c1a1a 100644 --- a/tests/typ/code/importable/chap1.typ +++ b/tests/typ/code/importable/chap1.typ @@ -2,7 +2,7 @@ #let name = "Klaus" -## Chapter 1 +== Chapter 1 #name stood in a field of wheat. There was nothing of particular interest about the field #name just casually surveyed for any paths on which the corn would not totally ruin his semi-new outdorsy jacket but then again, most of us spend diff --git a/tests/typ/code/importable/chap2.typ b/tests/typ/code/importable/chap2.typ index 51e116aa8..d4aedc60d 100644 --- a/tests/typ/code/importable/chap2.typ +++ b/tests/typ/code/importable/chap2.typ @@ -2,7 +2,7 @@ #let name = "Klaus" -## Chapter 2 +== Chapter 2 Their motivations, however, were pretty descript, so to speak. #name had not yet conceptualized their consequences, but that should change pretty quickly. #name approached the center of the field and picked up a 4-foot long disk made from diff --git a/tests/typ/code/include.typ b/tests/typ/code/include.typ index 8080c6e85..166c3945c 100644 --- a/tests/typ/code/include.typ +++ b/tests/typ/code/include.typ @@ -1,7 +1,7 @@ // Test include statements. --- -# Document += Document // Include a file #include "importable/chap1.typ" diff --git a/tests/typ/code/let.typ b/tests/typ/code/let.typ index 1a0bb10ea..d788a5639 100644 --- a/tests/typ/code/let.typ +++ b/tests/typ/code/let.typ @@ -79,6 +79,6 @@ Three // Error: 9 expected expression #let v = -// Should output `= 1`. +// Should output a heading `1`. // Error: 6-9 expected identifier, found string #let "v" = 1 diff --git a/tests/typ/coma.typ b/tests/typ/coma.typ index 5074bd9ea..161ac832d 100644 --- a/tests/typ/coma.typ +++ b/tests/typ/coma.typ @@ -30,7 +30,7 @@ // the parentheses. #align(center)[ // Markdown-like syntax for headings. - #### 3. Übungsblatt Computerorientierte Mathematik II #v(4mm) + ==== 3. Übungsblatt Computerorientierte Mathematik II #v(4mm) *Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) #v(4mm) *Alle Antworten sind zu beweisen.* ] diff --git a/tests/typ/markup/heading.typ b/tests/typ/markup/heading.typ index 8787d959a..e0dbd999a 100644 --- a/tests/typ/markup/heading.typ +++ b/tests/typ/markup/heading.typ @@ -4,39 +4,39 @@ // Different number of hashtags. // Valid levels. -# Level 1 -### Level 2 -###### Level 6 += Level 1 +=== Level 2 +====== Level 6 // Too many hashtags. // Warning: 1-8 should not exceed depth 6 -####### Level 7 +======= Level 7 --- // Heading vs. no heading. // Parsed as headings if at start of the context. -/**/ # Level 1 -{[## Level 2]} -#box[### Level 3] +/**/ = Level 1 +{[== Level 2]} +#box[=== Level 3] // Not at the start of the context. -No # heading +No = heading // Escaped. -\# No heading +\= No heading --- // While indented at least as much as the start, the heading continues. -# This += This is indented. -# This += This is not. // Code blocks continue heading. -# A { += A { "B" } diff --git a/tools/support/typst.tmLanguage.json b/tools/support/typst.tmLanguage.json index e1f416535..33e4c3db7 100644 --- a/tools/support/typst.tmLanguage.json +++ b/tools/support/typst.tmLanguage.json @@ -75,7 +75,7 @@ { "name": "markup.heading.typst", "contentName": "entity.name.section.typst", - "begin": "^\\s*#{1,6}\\s+", + "begin": "^\\s*={1,6}\\s+", "end": "\n", "beginCaptures": { "0": { "name": "punctuation.definition.heading.typst" } }, "patterns": [{ "include": "#markup" }]