fix: scan ahead panic

This commit is contained in:
trisua 2025-07-24 15:10:59 -04:00
parent 9fe5735127
commit 2cc9ed7445
3 changed files with 127 additions and 13 deletions

View file

@ -1,3 +1,4 @@
use crate::markdown::is_numeric;
use serde::{Deserialize, Serialize};
use serde_valid::Validate;
use std::fmt::Display;
@ -259,12 +260,64 @@ pub struct EntryMetadata {
#[serde(default, alias = "CONTAINER_SHADOW")]
#[validate(max_length = 32)]
pub container_shadow: String,
/// If the container is a flexbox.
#[serde(default, alias = "CONTAINER_FLEX")]
pub container_flex: bool,
/// The direction of the container's content (if container has flex enabled).
#[serde(default, alias = "CONTAINER_FLEX_DIRECTION")]
#[validate(max_length = 16)]
pub container_flex_direction: String,
/// The gap of the container's content (if container has flex enabled).
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/gap>
#[serde(default, alias = "CONTAINER_FLEX_GAP")]
#[validate(max_length = 16)]
pub container_flex_gap: String,
/// If the container's content wraps (if container has flex enabled).
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap>
#[serde(default, alias = "CONTAINER_FLEX_WRAP")]
pub container_flex_wrap: bool,
/// The alignment of the container's content horizontally (if container has flex enabled).
///
/// Swapped to vertical when direction is `column*`.
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content>
#[serde(default, alias = "CONTAINER_FLEX_ALIGN_HORIZONTAL")]
#[validate(max_length = 16)]
pub container_flex_align_horizontal: String,
/// The alignment of the container's content vertically (if container has flex enabled).
///
/// Swapped to horizontal when direction is `column*`.
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/align-items>
#[serde(default, alias = "CONTAINER_FLEX_ALIGN_VERTICAL")]
#[validate(max_length = 16)]
pub container_flex_align_vertical: String,
/// The shadow under text.
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow>
#[serde(default, alias = "CONTENT_TEXT_SHADOW")]
#[validate(max_length = 32)]
pub content_text_shadow: String,
/// The shadow under text.
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow>
#[serde(default, alias = "CONTENT_TEXT_SHADOW_COLOR")]
#[validate(max_length = 32)]
pub content_text_shadow_color: String,
/// The shadow under text.
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow>
#[serde(default, alias = "CONTENT_TEXT_SHADOW_OFFSET")]
#[validate(max_length = 32)]
pub content_text_shadow_offset: String,
/// The shadow under text.
///
/// Syntax: <https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow>
#[serde(default, alias = "CONTENT_TEXT_SHADOW_BLUR")]
#[validate(max_length = 32)]
pub content_text_shadow_blur: String,
/// The name of a font from Google Fonts to use.
#[serde(default, alias = "CONTENT_FONT")]
#[validate(max_length = 32)]
@ -287,6 +340,9 @@ pub struct EntryMetadata {
/// The color of links.
#[serde(default, alias = "CONTENT_TEXT_LINK_COLOR")]
pub content_text_link_color: String,
/// If paragraph elements have a margin below them.
#[serde(default, alias = "CONTENT_DISABLE_PARAGRAPH_MARGIN")]
pub content_disable_paragraph_margin: bool,
}
macro_rules! metadata_css {
@ -446,6 +502,31 @@ impl EntryMetadata {
));
}
if !self.content_text_shadow_color.is_empty() {
output.push_str(&format!(
".container {{ text-shadow: {} {} {}; }}",
self.content_text_shadow_offset,
self.content_text_shadow_blur,
self.content_text_shadow_color
));
}
if self.container_flex {
output.push_str(".container { display: flex; }");
metadata_css!(".container", "gap", self.container_flex_gap->output);
metadata_css!(".container", "flex-direction", self.container_flex_direction->output);
metadata_css!(".container", "align-items", self.container_flex_align_vertical->output);
metadata_css!(".container", "justify-content", self.container_flex_align_horizontal->output);
if self.container_flex_wrap {
output.push_str(".container { flex-wrap: wrap; }");
}
}
if self.content_disable_paragraph_margin {
output.push_str(".container p { margin: 0; }");
}
output + "</style>"
}
@ -482,13 +563,14 @@ impl EntryMetadata {
value = value.trim().to_string();
// determine if we need to stringify
let mut is_numeric = false;
for char in value.chars() {
is_numeric = char.is_numeric();
}
if !is_numeric && !value.starts_with("[") && !value.starts_with("\"") {
let is_numeric = is_numeric(&value);
if !is_numeric
&& !value.starts_with("[")
&& !value.starts_with("\"")
&& value != "true"
&& value != "false"
|| value.starts_with("#")
{
value = format!("\"{value}\"");
}