Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Section nested under page must respect its slug in the URL path #2369

Open
wants to merge 36 commits into
base: next
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8d16d17
Next version
Keats Mar 19, 2023
b00ae42
print error message when no config file found (#2168)
iEverX Apr 6, 2023
1ed722c
Speedup "zola check" command by reusing the Client (#2171)
MTRNord Apr 6, 2023
6a5c241
Implement replace_re filter (#2163)
cydave Apr 20, 2023
c48b61a
templates: add base URL for feed content (#2190)
jk-ozlabs Apr 23, 2023
7edf92b
Fix multi-lingual json index (#2197)
Jieiku Apr 28, 2023
7448309
Add search.index_format into the serialized config (#2165) (#2196)
Raymi306 May 1, 2023
4f77980
Fix typo in error message
Keats May 2, 2023
1321a83
Hard link serve panic fix (#2210)
Raymi306 May 6, 2023
b5a90db
Add support for lazy loading images (#2211)
sinofp May 6, 2023
1778707
Prevent spans crossing line boundaries in class-based code block form…
TheOnlyMrCat Jul 10, 2023
afc0e2c
always sort assets by filename (Windows/Linux difference) (#2236)
wold5 Jul 10, 2023
66f5bf5
Atom template authors (#2259)
heitorPB Jul 26, 2023
f962370
Add attributes to base_url link in atom template (#2261)
savq Jul 27, 2023
d3793cd
Fixes #2250; Error instead of panic when root directory or config fil…
Raymi306 Jul 30, 2023
fe1967f
Fix LFI in `zola serve` (#2258)
adeadfed Aug 4, 2023
b97a1d5
Update changelog
Keats Aug 4, 2023
f0b984d
Update edition
Keats Aug 4, 2023
57968be
Update deps
Keats Aug 4, 2023
c4341b1
Add ignored_static to config (#2209)
Raymi306 Aug 13, 2023
4474afa
template:feeds: add extra block (#2263)
heitorPB Aug 13, 2023
e81e139
Add Checking and Force Flag for Directory in Serve Command (#2265)
SquirrelHub Aug 17, 2023
674c433
fix: suppress highlight language warnings if highlight_code is false …
welpo Aug 30, 2023
1b423fb
Avoid unnecessary checking for already checked links (#2305)
biodranik Sep 24, 2023
2da4981
Clippy
Keats Sep 24, 2023
a41547c
Update changelog
Keats Sep 24, 2023
c8cc5f3
Update `grass` to 0.13 (#2321)
ISSOtm Sep 29, 2023
5d5d76e
Update deps
Keats Oct 19, 2023
d3cab30
Add apple arm (#2324)
technimad Oct 21, 2023
2e3fe2d
ignore kate-swp files (#2353)
selfisekai Nov 3, 2023
f20a1ba
elasticlunr-rs 3.0.2, hu language support (#2151)
sapati Nov 20, 2023
9afa349
Update changelog and deps
Keats Nov 20, 2023
252bbe0
Superfluous mut.
virtualritz Jul 24, 2023
fa254ca
Actually remove code blocks from search index
Keats Dec 7, 2023
b883c49
Remove dummy file
Keats Dec 7, 2023
b98420e
Spence section nested under page uses parent slug in url path (#1)
asimpletune Dec 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Prevent spans crossing line boundaries in class-based code block form…
…atter (#2237)

* Prevent spans crossing line boundaries in class formatter

* Add snapshot tests for classed highlighting
TheOnlyMrCat authored Jul 10, 2023
commit 1778707a6ed4a6a0eb7b9c3ff012b6ba9ed36c82
61 changes: 38 additions & 23 deletions components/markdown/src/codeblock/highlight.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,9 @@ use libs::syntect::highlighting::{Color, Theme};
use libs::syntect::html::{
line_tokens_to_classed_spans, styled_line_to_highlighted_html, ClassStyle, IncludeBackground,
};
use libs::syntect::parsing::{ParseState, ScopeStack, SyntaxReference, SyntaxSet};
use libs::syntect::parsing::{
ParseState, Scope, ScopeStack, SyntaxReference, SyntaxSet, SCOPE_REPO,
};
use libs::tera::escape_html;

/// Not public, but from syntect::html
@@ -18,17 +20,36 @@ fn write_css_color(s: &mut String, c: Color) {
}
}

/// Not public, but from syntect::html
fn scope_to_classes(s: &mut String, scope: Scope, style: ClassStyle) {
let repo = SCOPE_REPO.lock().unwrap();
for i in 0..(scope.len()) {
let atom = scope.atom_at(i as usize);
let atom_s = repo.atom_str(atom);
if i != 0 {
s.push(' ')
}
match style {
ClassStyle::Spaced => {}
ClassStyle::SpacedPrefixed { prefix } => {
s.push_str(prefix);
}
_ => {} // Non-exhaustive
}
s.push_str(atom_s);
}
}

pub(crate) struct ClassHighlighter<'config> {
syntax_set: &'config SyntaxSet,
open_spans: isize,
parse_state: ParseState,
scope_stack: ScopeStack,
}

impl<'config> ClassHighlighter<'config> {
pub fn new(syntax: &SyntaxReference, syntax_set: &'config SyntaxSet) -> Self {
let parse_state = ParseState::new(syntax);
Self { syntax_set, open_spans: 0, parse_state, scope_stack: ScopeStack::new() }
Self { syntax_set, parse_state, scope_stack: ScopeStack::new() }
}

/// Parse the line of code and update the internal HTML buffer with tagged HTML
@@ -39,24 +60,28 @@ impl<'config> ClassHighlighter<'config> {
debug_assert!(line.ends_with('\n'));
let parsed_line =
self.parse_state.parse_line(line, self.syntax_set).expect("failed to parse line");
let (formatted_line, delta) = line_tokens_to_classed_spans(

let mut formatted_line = String::with_capacity(line.len() + self.scope_stack.len() * 8); // A guess
for scope in self.scope_stack.as_slice() {
formatted_line.push_str("<span class=\"");
scope_to_classes(&mut formatted_line, *scope, CLASS_STYLE);
formatted_line.push_str("\">");
}

let (formatted_contents, _) = line_tokens_to_classed_spans(
line,
parsed_line.as_slice(),
CLASS_STYLE,
&mut self.scope_stack,
)
.expect("line_tokens_to_classed_spans should not fail");
self.open_spans += delta;
formatted_line
}
formatted_line.push_str(&formatted_contents);

/// Close all open `<span>` tags and return the finished HTML string
pub fn finalize(&mut self) -> String {
let mut html = String::with_capacity((self.open_spans * 7) as usize);
for _ in 0..self.open_spans {
html.push_str("</span>");
for _ in 0..self.scope_stack.len() {
formatted_line.push_str("</span>");
}
html

formatted_line
}
}

@@ -130,15 +155,6 @@ impl<'config> SyntaxHighlighter<'config> {
}
}

pub fn finalize(&mut self) -> Option<String> {
use SyntaxHighlighter::*;

match self {
Inlined(_) | NoHighlight => None,
Classed(h) => Some(h.finalize()),
}
}

/// Inlined needs to set the background/foreground colour on <pre>
pub fn pre_style(&self) -> Option<String> {
use SyntaxHighlighter::*;
@@ -210,7 +226,6 @@ mod tests {
for line in LinesWithEndings::from(code) {
out.push_str(&highlighter.highlight_line(line));
}
out.push_str(&highlighter.finalize());

assert!(out.starts_with("<span class"));
assert!(out.ends_with("</span>"));
4 changes: 0 additions & 4 deletions components/markdown/src/codeblock/mod.rs
Original file line number Diff line number Diff line change
@@ -168,10 +168,6 @@ impl<'config> CodeBlock<'config> {
}
}

if let Some(rest) = self.highlighter.finalize() {
buffer.push_str(&rest);
}

if self.line_numbers {
buffer.push_str("</tbody></table>");
}
97 changes: 73 additions & 24 deletions components/markdown/tests/codeblocks.rs
Original file line number Diff line number Diff line change
@@ -2,9 +2,24 @@ use config::Config;

mod common;

fn render_codeblock(content: &str, highlight_code: bool) -> String {
enum HighlightMode {
None,
Inlined,
Classed,
}

fn render_codeblock(content: &str, highlight_mode: HighlightMode) -> String {
let mut config = Config::default_for_test();
config.markdown.highlight_code = highlight_code;
match highlight_mode {
HighlightMode::None => {}
HighlightMode::Inlined => {
config.markdown.highlight_code = true;
}
HighlightMode::Classed => {
config.markdown.highlight_code = true;
config.markdown.highlight_theme = "css".to_owned();
}
}
common::render_with_config(content, config).unwrap().body
}

@@ -17,7 +32,7 @@ foo
bar
```
"#,
false,
HighlightMode::None,
);
insta::assert_snapshot!(body);
}
@@ -33,7 +48,7 @@ baz
bat
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -49,7 +64,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -65,7 +80,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -81,7 +96,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -97,7 +112,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
let body2 = render_codeblock(
r#"
@@ -108,7 +123,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
assert_eq!(body, body2);
}
@@ -124,7 +139,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -140,7 +155,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -156,7 +171,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -172,7 +187,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -188,7 +203,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -204,7 +219,7 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -220,7 +235,24 @@ bar
baz
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}

#[test]
fn can_highlight_with_classes() {
let body = render_codeblock(
r#"
```html,hl_lines=3-4
<link
rel="stylesheet"
type="text/css"
href="main.css"
/>
```
"#,
HighlightMode::Classed,
);
insta::assert_snapshot!(body);
}
@@ -234,14 +266,14 @@ foo
bar
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}

#[test]
fn can_add_line_numbers_windows_eol() {
let body = render_codeblock("```linenos\r\nfoo\r\nbar\r\n```\r\n", true);
let body = render_codeblock("```linenos\r\nfoo\r\nbar\r\n```\r\n", HighlightMode::Inlined);
insta::assert_snapshot!(body);
}

@@ -254,7 +286,7 @@ foo
bar
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -268,7 +300,24 @@ foo
bar
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}

#[test]
fn can_add_line_numbers_with_classes() {
let body = render_codeblock(
r#"
```html,linenos
<link
rel="stylesheet"
type="text/css"
href="main.css"
/>
```
"#,
HighlightMode::Classed,
);
insta::assert_snapshot!(body);
}
@@ -283,7 +332,7 @@ fn can_render_shortcode_in_codeblock() {
</div>
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -300,7 +349,7 @@ text2
text3
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -323,7 +372,7 @@ A quote
<!-- end text goes here -->
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
@@ -337,7 +386,7 @@ foo
bar
```
"#,
true,
HighlightMode::Inlined,
);
insta::assert_snapshot!(body);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: components/markdown/tests/codeblocks.rs
expression: body
---
<pre data-linenos data-lang="html" class="language-html z-code"><code class="language-html" data-lang="html"><table><tbody><tr><td>1</td><td><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"><span class="z-punctuation z-definition z-tag z-begin z-html">&lt;</span><span class="z-entity z-name z-tag z-inline z-any z-html">link</span>
</span></span></td></tr><tr><td>2</td><td><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"> <span class="z-meta z-attribute-with-value z-html"><span class="z-entity z-other z-attribute-name z-html">rel</span><span class="z-punctuation z-separator z-key-value z-html">=</span><span class="z-string z-quoted z-double z-html"><span class="z-punctuation z-definition z-string z-begin z-html">&quot;</span>stylesheet<span class="z-punctuation z-definition z-string z-end z-html">&quot;</span></span></span>
</span></span></td></tr><tr><td>3</td><td><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"> <span class="z-meta z-attribute-with-value z-html"><span class="z-entity z-other z-attribute-name z-html">type</span><span class="z-punctuation z-separator z-key-value z-html">=</span><span class="z-string z-quoted z-double z-html"><span class="z-punctuation z-definition z-string z-begin z-html">&quot;</span>text/css<span class="z-punctuation z-definition z-string z-end z-html">&quot;</span></span></span>
</span></span></td></tr><tr><td>4</td><td><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"> <span class="z-meta z-attribute-with-value z-html"><span class="z-entity z-other z-attribute-name z-html">href</span><span class="z-punctuation z-separator z-key-value z-html">=</span><span class="z-string z-quoted z-double z-html"><span class="z-punctuation z-definition z-string z-begin z-html">&quot;</span>main.css<span class="z-punctuation z-definition z-string z-end z-html">&quot;</span></span></span>
</span></span></td></tr><tr><td>5</td><td><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"><span class="z-punctuation z-definition z-tag z-end z-html">/&gt;</span></span>
</span></td></tr></tbody></table></code></pre>

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
source: components/markdown/tests/codeblocks.rs
expression: body
---
<pre data-lang="html" class="language-html z-code"><code class="language-html" data-lang="html"><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"><span class="z-punctuation z-definition z-tag z-begin z-html">&lt;</span><span class="z-entity z-name z-tag z-inline z-any z-html">link</span>
</span></span><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"> <span class="z-meta z-attribute-with-value z-html"><span class="z-entity z-other z-attribute-name z-html">rel</span><span class="z-punctuation z-separator z-key-value z-html">=</span><span class="z-string z-quoted z-double z-html"><span class="z-punctuation z-definition z-string z-begin z-html">&quot;</span>stylesheet<span class="z-punctuation z-definition z-string z-end z-html">&quot;</span></span></span>
</span></span><mark><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"> <span class="z-meta z-attribute-with-value z-html"><span class="z-entity z-other z-attribute-name z-html">type</span><span class="z-punctuation z-separator z-key-value z-html">=</span><span class="z-string z-quoted z-double z-html"><span class="z-punctuation z-definition z-string z-begin z-html">&quot;</span>text/css<span class="z-punctuation z-definition z-string z-end z-html">&quot;</span></span></span>
</span></span></mark><mark><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"> <span class="z-meta z-attribute-with-value z-html"><span class="z-entity z-other z-attribute-name z-html">href</span><span class="z-punctuation z-separator z-key-value z-html">=</span><span class="z-string z-quoted z-double z-html"><span class="z-punctuation z-definition z-string z-begin z-html">&quot;</span>main.css<span class="z-punctuation z-definition z-string z-end z-html">&quot;</span></span></span>
</span></span></mark><span class="z-text z-html z-basic"><span class="z-meta z-tag z-inline z-any z-html"><span class="z-punctuation z-definition z-tag z-end z-html">/&gt;</span></span>
</span></code></pre>