code housekeeping
This commit is contained in:
		
							parent
							
								
									e1b6578b2a
								
							
						
					
					
						commit
						d3c3ff8e4e
					
				
					 10 changed files with 108 additions and 100 deletions
				
			
		| 
						 | 
				
			
			@ -6,14 +6,14 @@ use std::{net::Ipv4Addr, sync::Arc};
 | 
			
		|||
 | 
			
		||||
use axum::http::header::LOCATION;
 | 
			
		||||
use axum::{
 | 
			
		||||
    Router,
 | 
			
		||||
    extract::{Path, Query, RawQuery, State},
 | 
			
		||||
    http::{
 | 
			
		||||
        header::{CACHE_CONTROL, CONTENT_TYPE},
 | 
			
		||||
        HeaderValue, StatusCode,
 | 
			
		||||
        header::{CACHE_CONTROL, CONTENT_TYPE},
 | 
			
		||||
    },
 | 
			
		||||
    response::{Html, IntoResponse, Response},
 | 
			
		||||
    routing::get,
 | 
			
		||||
    Router,
 | 
			
		||||
};
 | 
			
		||||
use serde::Deserialize;
 | 
			
		||||
use tokio::net::TcpListener;
 | 
			
		||||
| 
						 | 
				
			
			@ -149,13 +149,12 @@ async fn branch(RawQuery(named_id): RawQuery, State(state): State<Arc<Server>>)
 | 
			
		|||
            });
 | 
			
		||||
        if let Some(branch_id) = branch_id {
 | 
			
		||||
            let branch = state.sources.treehouse.tree.branch(branch_id);
 | 
			
		||||
            if let Source::Tree { tree_path, .. } = state.sources.treehouse.source(branch.file_id) {
 | 
			
		||||
                if let Some(url) =
 | 
			
		||||
            if let Source::Tree { tree_path, .. } = state.sources.treehouse.source(branch.file_id)
 | 
			
		||||
                && let Some(url) =
 | 
			
		||||
                    vfs::url(&state.sources.config.site, &state.target.sync(), tree_path)
 | 
			
		||||
                {
 | 
			
		||||
                    let url = format!("{url}#{}", branch.html_id);
 | 
			
		||||
                    return (StatusCode::FOUND, [(LOCATION, url)]).into_response();
 | 
			
		||||
                }
 | 
			
		||||
            {
 | 
			
		||||
                let url = format!("{url}#{}", branch.html_id);
 | 
			
		||||
                return (StatusCode::FOUND, [(LOCATION, url)]).into_response();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,15 +3,15 @@ use std::{
 | 
			
		|||
    ops::ControlFlow,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use anyhow::{anyhow, Context};
 | 
			
		||||
use anyhow::{Context, anyhow};
 | 
			
		||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
use tracing::{error, info_span, instrument};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    html::highlight::{
 | 
			
		||||
        compiled::{compile_syntax, CompiledSyntax},
 | 
			
		||||
        Syntax,
 | 
			
		||||
        compiled::{CompiledSyntax, compile_syntax},
 | 
			
		||||
    },
 | 
			
		||||
    import_map::ImportRoot,
 | 
			
		||||
    vfs::{self, Content, Dir, DynDir, ImageSize, VPath, VPathBuf},
 | 
			
		||||
| 
						 | 
				
			
			@ -116,12 +116,11 @@ impl Config {
 | 
			
		|||
    #[instrument(name = "Config::autopopulate_emoji", skip(self))]
 | 
			
		||||
    pub fn autopopulate_emoji(&mut self, dir: &dyn Dir) -> anyhow::Result<()> {
 | 
			
		||||
        vfs::walk_dir_rec(dir, VPath::ROOT, &mut |path| {
 | 
			
		||||
            if path.extension().is_some_and(is_image_file) {
 | 
			
		||||
                if let Some(emoji_name) = path.file_stem() {
 | 
			
		||||
                    if !self.emoji.contains_key(emoji_name) {
 | 
			
		||||
                        self.emoji.insert(emoji_name.to_owned(), path.to_owned());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            if path.extension().is_some_and(is_image_file)
 | 
			
		||||
                && let Some(emoji_name) = path.file_stem()
 | 
			
		||||
                && !self.emoji.contains_key(emoji_name)
 | 
			
		||||
            {
 | 
			
		||||
                self.emoji.insert(emoji_name.to_owned(), path.to_owned());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ControlFlow::Continue(())
 | 
			
		||||
| 
						 | 
				
			
			@ -133,16 +132,16 @@ impl Config {
 | 
			
		|||
    #[instrument(name = "Config::autopopulate_pics", skip(self))]
 | 
			
		||||
    pub fn autopopulate_pics(&mut self, dir: &dyn Dir) -> anyhow::Result<()> {
 | 
			
		||||
        vfs::walk_dir_rec(dir, VPath::ROOT, &mut |path| {
 | 
			
		||||
            if path.extension().is_some_and(is_image_file) {
 | 
			
		||||
                if let Some(pic_name) = path.file_stem() {
 | 
			
		||||
                    let pic_id = pic_name
 | 
			
		||||
                        .split_once('-')
 | 
			
		||||
                        .map(|(before_dash, _after_dash)| before_dash)
 | 
			
		||||
                        .unwrap_or(pic_name);
 | 
			
		||||
            if path.extension().is_some_and(is_image_file)
 | 
			
		||||
                && let Some(pic_name) = path.file_stem()
 | 
			
		||||
            {
 | 
			
		||||
                let pic_id = pic_name
 | 
			
		||||
                    .split_once('-')
 | 
			
		||||
                    .map(|(before_dash, _after_dash)| before_dash)
 | 
			
		||||
                    .unwrap_or(pic_name);
 | 
			
		||||
 | 
			
		||||
                    if !self.pics.contains_key(pic_id) {
 | 
			
		||||
                        self.pics.insert(pic_id.to_owned(), path.to_owned());
 | 
			
		||||
                    }
 | 
			
		||||
                if !self.pics.contains_key(pic_id) {
 | 
			
		||||
                    self.pics.insert(pic_id.to_owned(), path.to_owned());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								src/doc.rs
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								src/doc.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,6 +3,7 @@ use codespan_reporting::diagnostic::{Diagnostic, Label};
 | 
			
		|||
use serde::Deserialize;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    config::Config,
 | 
			
		||||
    state::{FileId, TomlError, Treehouse, toml_error_to_diagnostic},
 | 
			
		||||
    tree::attributes::{Picture, timestamp_from_id},
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +78,11 @@ pub struct IncludeFeed {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
impl Doc {
 | 
			
		||||
    pub fn parse(treehouse: &mut Treehouse, file_id: FileId) -> (Doc, Vec<Diagnostic<FileId>>) {
 | 
			
		||||
    pub fn parse(
 | 
			
		||||
        treehouse: &mut Treehouse,
 | 
			
		||||
        config: &Config,
 | 
			
		||||
        file_id: FileId,
 | 
			
		||||
    ) -> (Doc, Vec<Diagnostic<FileId>>) {
 | 
			
		||||
        let mut diagnostics = vec![];
 | 
			
		||||
 | 
			
		||||
        let source = treehouse.source(file_id).input();
 | 
			
		||||
| 
						 | 
				
			
			@ -125,6 +130,17 @@ impl Doc {
 | 
			
		|||
                        ]),
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for tag in &attributes.tags {
 | 
			
		||||
                if !config.feed.tags.contains(tag) {
 | 
			
		||||
                    diagnostics.push(
 | 
			
		||||
                        Diagnostic::warning()
 | 
			
		||||
                            .with_code("attr")
 | 
			
		||||
                            .with_message(format!("doc has unregistered tag `{tag}`"))
 | 
			
		||||
                            .with_labels(vec![Label::primary(file_id, attributes_span.clone())]),
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,13 +1,13 @@
 | 
			
		|||
use std::{collections::HashMap, fmt, sync::Arc};
 | 
			
		||||
 | 
			
		||||
use anyhow::{ensure, Context};
 | 
			
		||||
use anyhow::{Context, ensure};
 | 
			
		||||
use handlebars::Handlebars;
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
use tracing::{info_span, instrument};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    dirs::Dirs,
 | 
			
		||||
    generate::{simple_template, BaseTemplateData},
 | 
			
		||||
    generate::BaseTemplateData,
 | 
			
		||||
    html::{breadcrumbs::breadcrumbs_to_html, tree},
 | 
			
		||||
    sources::Sources,
 | 
			
		||||
    state::FileId,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,9 +5,6 @@ use std::fmt::Write;
 | 
			
		|||
use std::ops::Range;
 | 
			
		||||
 | 
			
		||||
use codespan_reporting::diagnostic::Diagnostic;
 | 
			
		||||
use codespan_reporting::diagnostic::Label;
 | 
			
		||||
use codespan_reporting::diagnostic::LabelStyle;
 | 
			
		||||
use codespan_reporting::diagnostic::Severity;
 | 
			
		||||
use jotdown::Alignment;
 | 
			
		||||
use jotdown::Container;
 | 
			
		||||
use jotdown::Event;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +100,7 @@ impl<'a> Writer<'a> {
 | 
			
		|||
    fn render_event(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        e: &Event<'a>,
 | 
			
		||||
        range: Range<usize>,
 | 
			
		||||
        #[expect(unused)] range: Range<usize>,
 | 
			
		||||
        out: &mut String,
 | 
			
		||||
    ) -> std::fmt::Result {
 | 
			
		||||
        if matches!(&e, Event::Start(Container::LinkDefinition { .. }, ..)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -302,13 +299,13 @@ impl<'a> Writer<'a> {
 | 
			
		|||
                        class.parts().for_each(|part| write_attr(part, out));
 | 
			
		||||
                    }
 | 
			
		||||
                    // div class goes after classes from attrs
 | 
			
		||||
                    if let Container::Div { class } = c {
 | 
			
		||||
                        if !class.is_empty() {
 | 
			
		||||
                            if first_written {
 | 
			
		||||
                                out.push(' ');
 | 
			
		||||
                            }
 | 
			
		||||
                            out.push_str(class);
 | 
			
		||||
                    if let Container::Div { class } = c
 | 
			
		||||
                        && !class.is_empty()
 | 
			
		||||
                    {
 | 
			
		||||
                        if first_written {
 | 
			
		||||
                            out.push(' ');
 | 
			
		||||
                        }
 | 
			
		||||
                        out.push_str(class);
 | 
			
		||||
                    }
 | 
			
		||||
                    out.push('"');
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
use std::ops::Range;
 | 
			
		||||
 | 
			
		||||
use super::compiled::{CompiledSyntax, CompiledTokenTypes, TokenId, TOKEN_ID_DEFAULT};
 | 
			
		||||
use super::compiled::{CompiledSyntax, CompiledTokenTypes, TOKEN_ID_DEFAULT, TokenId};
 | 
			
		||||
 | 
			
		||||
pub struct Token {
 | 
			
		||||
    pub id: TokenId,
 | 
			
		||||
| 
						 | 
				
			
			@ -71,10 +71,10 @@ impl CompiledSyntax {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        for token in &mut tokens {
 | 
			
		||||
            if let Some(keyword) = self.keywords.get(&text[token.range.clone()]) {
 | 
			
		||||
                if keyword.only_replaces.is_none() || Some(token.id) == keyword.only_replaces {
 | 
			
		||||
                    token.id = keyword.into;
 | 
			
		||||
                }
 | 
			
		||||
            if let Some(keyword) = self.keywords.get(&text[token.range.clone()])
 | 
			
		||||
                && (keyword.only_replaces.is_none() || Some(token.id) == keyword.only_replaces)
 | 
			
		||||
            {
 | 
			
		||||
                token.id = keyword.into;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -87,11 +87,11 @@ fn push_token(tokens: &mut Vec<Token>, id: TokenId, range: Range<usize>) {
 | 
			
		|||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if let Some(previous_token) = tokens.last_mut() {
 | 
			
		||||
        if previous_token.id == id {
 | 
			
		||||
            previous_token.range.end = range.end;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    if let Some(previous_token) = tokens.last_mut()
 | 
			
		||||
        && previous_token.id == id
 | 
			
		||||
    {
 | 
			
		||||
        previous_token.range.end = range.end;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    tokens.push(Token { id, range });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ use crate::{
 | 
			
		|||
    html::navmap::NavigationMap,
 | 
			
		||||
    import_map::ImportMap,
 | 
			
		||||
    parse::parse_tree_with_diagnostics,
 | 
			
		||||
    state::{Source, Tag, Treehouse, report_diagnostics},
 | 
			
		||||
    state::{Source, Treehouse, report_diagnostics},
 | 
			
		||||
    tree::SemaRoots,
 | 
			
		||||
    vfs::{self, Cd, Content, VPath, VPathBuf},
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@ fn load_trees(config: &Config, dirs: &Dirs) -> anyhow::Result<Treehouse> {
 | 
			
		|||
 | 
			
		||||
    for path in &doc_paths {
 | 
			
		||||
        if let Some(input) =
 | 
			
		||||
            vfs::query::<Content>(&dirs.content, &path).and_then(|c| c.string().ok())
 | 
			
		||||
            vfs::query::<Content>(&dirs.content, path).and_then(|c| c.string().ok())
 | 
			
		||||
        {
 | 
			
		||||
            let file_id = treehouse.add_file(path.clone(), Source::Other(input));
 | 
			
		||||
            treehouse.files_by_doc_path.insert(path.clone(), file_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -155,31 +155,25 @@ fn load_trees(config: &Config, dirs: &Dirs) -> anyhow::Result<Treehouse> {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    for file_id in doc_file_ids {
 | 
			
		||||
        let (doc, mut doc_diagnostics) = Doc::parse(&mut treehouse, file_id);
 | 
			
		||||
        let (doc, mut doc_diagnostics) = Doc::parse(&mut treehouse, config, file_id);
 | 
			
		||||
        treehouse.docs.insert(file_id, doc);
 | 
			
		||||
        diagnostics.append(&mut doc_diagnostics);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Tags
 | 
			
		||||
 | 
			
		||||
    for (_, file_id) in &treehouse.files_by_tree_path {
 | 
			
		||||
    for file_id in treehouse.files_by_tree_path.values() {
 | 
			
		||||
        let roots = &treehouse.roots[file_id];
 | 
			
		||||
        for tag_name in &roots.attributes.tags {
 | 
			
		||||
            let tag = treehouse
 | 
			
		||||
                .tags
 | 
			
		||||
                .entry(tag_name.clone())
 | 
			
		||||
                .or_insert_with(Tag::default);
 | 
			
		||||
            let tag = treehouse.tags.entry(tag_name.clone()).or_default();
 | 
			
		||||
            tag.files.push(*file_id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (_, file_id) in &treehouse.files_by_doc_path {
 | 
			
		||||
    for file_id in treehouse.files_by_doc_path.values() {
 | 
			
		||||
        let doc = &treehouse.docs[file_id];
 | 
			
		||||
        for tag_name in &doc.attributes.tags {
 | 
			
		||||
            let tag = treehouse
 | 
			
		||||
                .tags
 | 
			
		||||
                .entry(tag_name.clone())
 | 
			
		||||
                .or_insert_with(Tag::default);
 | 
			
		||||
            let tag = treehouse.tags.entry(tag_name.clone()).or_default();
 | 
			
		||||
            tag.files.push(*file_id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								src/tree.rs
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								src/tree.rs
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -232,7 +232,7 @@ impl SemaBranch {
 | 
			
		|||
            diagnostics.push(
 | 
			
		||||
                Diagnostic::warning()
 | 
			
		||||
                    .with_code("sema")
 | 
			
		||||
                    .with_message(format!("two branches share the same id `{}`", named_id))
 | 
			
		||||
                    .with_message(format!("two branches share the same id `{named_id}`"))
 | 
			
		||||
                    .with_labels(vec![
 | 
			
		||||
                        Label {
 | 
			
		||||
                            style: LabelStyle::Primary,
 | 
			
		||||
| 
						 | 
				
			
			@ -345,23 +345,23 @@ impl SemaBranch {
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            // Check that link-type blocks are `+`-type to facilitate lazy loading.
 | 
			
		||||
            if let Content::Link(_) = &attributes.content {
 | 
			
		||||
                if branch.kind == BranchKind::Expanded {
 | 
			
		||||
                    diagnostics.push(Diagnostic {
 | 
			
		||||
                        severity: Severity::Warning,
 | 
			
		||||
                        code: Some("attr".into()),
 | 
			
		||||
                        message: "`content.link` branch is expanded by default".into(),
 | 
			
		||||
                        labels: vec![Label {
 | 
			
		||||
                            style: LabelStyle::Primary,
 | 
			
		||||
                            file_id,
 | 
			
		||||
                            range: branch.kind_span.clone(),
 | 
			
		||||
                            message: String::new(),
 | 
			
		||||
                        }],
 | 
			
		||||
                        notes: vec![
 | 
			
		||||
                            "note: `content.link` branches should normally be collapsed to allow for lazy loading".into(),
 | 
			
		||||
                        ],
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            if let Content::Link(_) = &attributes.content
 | 
			
		||||
                && branch.kind == BranchKind::Expanded
 | 
			
		||||
            {
 | 
			
		||||
                diagnostics.push(Diagnostic {
 | 
			
		||||
                    severity: Severity::Warning,
 | 
			
		||||
                    code: Some("attr".into()),
 | 
			
		||||
                    message: "`content.link` branch is expanded by default".into(),
 | 
			
		||||
                    labels: vec![Label {
 | 
			
		||||
                        style: LabelStyle::Primary,
 | 
			
		||||
                        file_id,
 | 
			
		||||
                        range: branch.kind_span.clone(),
 | 
			
		||||
                        message: String::new(),
 | 
			
		||||
                    }],
 | 
			
		||||
                    notes: vec![
 | 
			
		||||
                        "note: `content.link` branches should normally be collapsed to allow for lazy loading".into(),
 | 
			
		||||
                    ],
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Resolve content.links.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ use tracing::{info_span, instrument, warn};
 | 
			
		|||
 | 
			
		||||
use crate::config;
 | 
			
		||||
 | 
			
		||||
use super::{query, Content, Dir, ImageSize, Query, VPath, VPathBuf};
 | 
			
		||||
use super::{Content, Dir, ImageSize, Query, VPath, VPathBuf, query};
 | 
			
		||||
 | 
			
		||||
pub struct ImageSizeCache<T> {
 | 
			
		||||
    inner: T,
 | 
			
		||||
| 
						 | 
				
			
			@ -27,18 +27,18 @@ where
 | 
			
		|||
    T: Dir,
 | 
			
		||||
{
 | 
			
		||||
    fn compute_image_size(&self, path: &VPath) -> anyhow::Result<Option<ImageSize>> {
 | 
			
		||||
        if path.extension().is_some_and(config::is_image_file) {
 | 
			
		||||
            if let Some(content) = query::<Content>(&self.inner, path) {
 | 
			
		||||
                if path.extension() == Some("svg") {
 | 
			
		||||
                    return Ok(svg_size(&content.string()?));
 | 
			
		||||
                } else {
 | 
			
		||||
                    let _span = info_span!("raster_image_size").entered();
 | 
			
		||||
                    let reader = image::ImageReader::new(Cursor::new(content.bytes()))
 | 
			
		||||
                        .with_guessed_format()
 | 
			
		||||
                        .context("cannot guess image format")?;
 | 
			
		||||
                    let (width, height) = reader.into_dimensions()?;
 | 
			
		||||
                    return Ok(Some(ImageSize { width, height }));
 | 
			
		||||
                }
 | 
			
		||||
        if path.extension().is_some_and(config::is_image_file)
 | 
			
		||||
            && let Some(content) = query::<Content>(&self.inner, path)
 | 
			
		||||
        {
 | 
			
		||||
            if path.extension() == Some("svg") {
 | 
			
		||||
                return Ok(svg_size(&content.string()?));
 | 
			
		||||
            } else {
 | 
			
		||||
                let _span = info_span!("raster_image_size").entered();
 | 
			
		||||
                let reader = image::ImageReader::new(Cursor::new(content.bytes()))
 | 
			
		||||
                    .with_guessed_format()
 | 
			
		||||
                    .context("cannot guess image format")?;
 | 
			
		||||
                let (width, height) = reader.into_dimensions()?;
 | 
			
		||||
                return Ok(Some(ImageSize { width, height }));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -105,11 +105,11 @@ fn svg_size(svg: &str) -> Option<ImageSize> {
 | 
			
		|||
    let mut height: Option<u32> = None;
 | 
			
		||||
    let mut view_box: Option<[u32; 4]> = None;
 | 
			
		||||
    while let Some(Ok(token)) = tokenizer.next() {
 | 
			
		||||
        if let xmlparser::Token::ElementStart { local, .. } = &token {
 | 
			
		||||
            if local == "svg" {
 | 
			
		||||
                in_svg = true;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        if let xmlparser::Token::ElementStart { local, .. } = &token
 | 
			
		||||
            && local == "svg"
 | 
			
		||||
        {
 | 
			
		||||
            in_svg = true;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if in_svg {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,14 +57,15 @@ main.doc {
 | 
			
		|||
 | 
			
		||||
        & ul,
 | 
			
		||||
        & ol {
 | 
			
		||||
            /* Is there a better way to add spacing to the marker, other than adding whitespace? */
 | 
			
		||||
            margin-top: 0;
 | 
			
		||||
            margin-bottom: 0;
 | 
			
		||||
            padding-top: 0.5lh;
 | 
			
		||||
            padding-bottom: 0.5lh;
 | 
			
		||||
            padding-left: 3.2em;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & ul {
 | 
			
		||||
            /* Is there a better way to add spacing to the marker, other than adding whitespace? */
 | 
			
		||||
            list-style: "-  ";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +89,7 @@ main.doc {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    & section.feed {
 | 
			
		||||
        width: 40ch;
 | 
			
		||||
        max-width: 40ch;
 | 
			
		||||
        flex-shrink: 0;
 | 
			
		||||
        padding: 0.8rem;
 | 
			
		||||
        padding-top: 3.2rem;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,6 +104,7 @@ main.doc {
 | 
			
		|||
        & .vertical-center {
 | 
			
		||||
            --article-padding: 3.2rem;
 | 
			
		||||
            min-height: 0;
 | 
			
		||||
            flex-grow: 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        & footer {
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +112,8 @@ main.doc {
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        & section.feed {
 | 
			
		||||
            width: var(--doc-text-width);
 | 
			
		||||
            max-width: var(--doc-text-width);
 | 
			
		||||
            flex-grow: 1;
 | 
			
		||||
 | 
			
		||||
            margin-top: 2.4em;
 | 
			
		||||
            padding: 1.6rem;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue