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

[WJ-1244] Add the concept of the "layout" to ftml #17

Merged
merged 13 commits into from
Jul 16, 2024
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ keywords = ["wikidot", "wikijump", "ftml", "parsing", "html"]
categories = ["parser-implementations"]
exclude = [".gitignore", ".editorconfig"]

version = "1.24.0"
version = "1.25.0"
authors = ["Emmie Smith <[email protected]>"]
edition = "2021"

Expand Down
3 changes: 2 additions & 1 deletion src/includes/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
*/

use super::{include, DebugIncluder, PageRef};
use crate::layout::Layout;
use crate::settings::{WikitextMode, WikitextSettings};

#[test]
fn includes() {
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);

macro_rules! test {
($text:expr, $expected:expr $(,)?) => {{
Expand Down
49 changes: 49 additions & 0 deletions src/layout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* layout.rs
*
* ftml - Library to parse Wikidot text
* Copyright (C) 2019-2024 Wikijump Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/// Describes the desired (HTML) DOM layout to be emitted.
///
/// This is used as a transition mechanism between our dependencies on the pecularities
/// of old, legacy Wikidot HTML generation and a newer better system we are calling the
/// "Wikijump" layout.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum Layout {
Wikidot,
Wikijump,
}

impl Layout {
#[inline]
pub fn legacy(self) -> bool {
match self {
Layout::Wikidot => true,
Layout::Wikijump => false,
}
}

#[inline]
pub fn description(self) -> &'static str {
match self {
Layout::Wikidot => "Wikidot (legacy)",
Layout::Wikijump => "Wikijump",
}
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub mod wasm;
pub mod data;
pub mod includes;
pub mod info;
pub mod layout;
pub mod parsing;
pub mod preproc;
pub mod render;
Expand Down
3 changes: 2 additions & 1 deletion src/parsing/check_step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@ pub fn check_step<'r, 't>(
#[should_panic]
fn check_step_fail() {
use crate::data::PageInfo;
use crate::layout::Layout;
use crate::settings::{WikitextMode, WikitextSettings};

let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);
let tokenization = crate::tokenize("**Apple** banana");
let mut parser = Parser::new(&tokenization, &page_info, &settings);

Expand Down
3 changes: 2 additions & 1 deletion src/parsing/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,10 +583,11 @@ fn make_shared_vec<T>() -> Rc<RefCell<Vec<T>>> {

#[test]
fn parser_newline_flag() {
use crate::layout::Layout;
use crate::settings::WikitextMode;

let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);

macro_rules! check {
($input:expr, $expected_steps:expr $(,)?) => {{
Expand Down
3 changes: 2 additions & 1 deletion src/parsing/parser_wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ impl Drop for ParserWrap<'_, '_, '_> {
#[test]
fn wrap() {
use crate::data::PageInfo;
use crate::layout::Layout;
use crate::settings::{WikitextMode, WikitextSettings};

let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);
let tokens = crate::tokenize("Test input");
let mut parser = Parser::new(&tokens, &page_info, &settings);

Expand Down
7 changes: 4 additions & 3 deletions src/render/html/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use super::random::Random;
use crate::data::PageRef;
use crate::data::{Backlinks, PageInfo};
use crate::info;
use crate::layout::Layout;
use crate::next_index::{NextIndex, TableOfContentsIndex};
use crate::render::Handle;
use crate::settings::WikitextSettings;
Expand Down Expand Up @@ -109,7 +110,7 @@ impl<'i, 'h, 'e, 't> HtmlContext<'i, 'h, 'e, 't> {
// Build and return
HtmlContext {
body: String::with_capacity(capacity),
meta: Self::initial_metadata(info),
meta: Self::initial_metadata(info, settings.layout),
backlinks: Backlinks::new(),
info,
handle,
Expand All @@ -127,7 +128,7 @@ impl<'i, 'h, 'e, 't> HtmlContext<'i, 'h, 'e, 't> {
}
}

fn initial_metadata(info: &PageInfo<'i>) -> Vec<HtmlMeta> {
fn initial_metadata(info: &PageInfo<'i>, layout: Layout) -> Vec<HtmlMeta> {
// Initial version, we can tune how the metadata is generated later.

vec![
Expand All @@ -139,7 +140,7 @@ impl<'i, 'h, 'e, 't> HtmlContext<'i, 'h, 'e, 't> {
HtmlMeta {
tag_type: HtmlMetaType::Name,
name: str!("generator"),
value: info::VERSION.clone(),
value: format!("{} {}", *info::VERSION, layout.description()),
},
HtmlMeta {
tag_type: HtmlMetaType::Name,
Expand Down
3 changes: 2 additions & 1 deletion src/render/html/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@

use super::prelude::*;
use super::HtmlRender;
use crate::layout::Layout;
use crate::tree::BibliographyList;

#[test]
fn html() {
let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);
let result = SyntaxTree::from_element_result(
vec![],
vec![],
Expand Down
1 change: 1 addition & 0 deletions src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
mod prelude {
pub use super::Render;
pub use crate::data::PageInfo;
pub use crate::layout::Layout;
pub use crate::settings::{WikitextMode, WikitextSettings};
pub use crate::tree::{AttributeMap, Container, ContainerType, Element, SyntaxTree};
}
Expand Down
3 changes: 2 additions & 1 deletion src/render/null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ impl Render for NullRender {

#[test]
fn null() {
use crate::layout::Layout;
use crate::tree::BibliographyList;

let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);
let result = SyntaxTree::from_element_result(
vec![],
vec![],
Expand Down
13 changes: 12 additions & 1 deletion src/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

mod interwiki;

use crate::layout::Layout;

pub use self::interwiki::{InterwikiSettings, DEFAULT_INTERWIKI, EMPTY_INTERWIKI};

const DEFAULT_MINIFY_CSS: bool = true;
Expand All @@ -31,6 +33,11 @@ pub struct WikitextSettings {
/// What mode we're running in.
pub mode: WikitextMode,

/// What layout we're targeting.
///
/// For instance, generating Wikidot's legacy HTML structure.
pub layout: Layout,

/// Whether page-contextual syntax is permitted.
///
/// This currently refers to:
Expand Down Expand Up @@ -94,12 +101,13 @@ pub struct WikitextSettings {

impl WikitextSettings {
/// Returns the default settings for the given [`WikitextMode`].
pub fn from_mode(mode: WikitextMode) -> Self {
pub fn from_mode(mode: WikitextMode, layout: Layout) -> Self {
let interwiki = DEFAULT_INTERWIKI.clone();

match mode {
WikitextMode::Page => WikitextSettings {
mode,
layout,
enable_page_syntax: true,
use_include_compatibility: false,
use_true_ids: true,
Expand All @@ -110,6 +118,7 @@ impl WikitextSettings {
},
WikitextMode::Draft => WikitextSettings {
mode,
layout,
enable_page_syntax: true,
use_include_compatibility: false,
use_true_ids: false,
Expand All @@ -120,6 +129,7 @@ impl WikitextSettings {
},
WikitextMode::ForumPost | WikitextMode::DirectMessage => WikitextSettings {
mode,
layout,
enable_page_syntax: false,
use_include_compatibility: false,
use_true_ids: false,
Expand All @@ -130,6 +140,7 @@ impl WikitextSettings {
},
WikitextMode::List => WikitextSettings {
mode,
layout,
enable_page_syntax: true,
use_include_compatibility: false,
use_true_ids: false,
Expand Down
3 changes: 2 additions & 1 deletion src/test/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

use super::includer::TestIncluder;
use crate::data::{PageInfo, ScoreValue};
use crate::layout::Layout;
use crate::parsing::ParseError;
use crate::render::html::HtmlRender;
use crate::render::Render;
Expand Down Expand Up @@ -209,7 +210,7 @@ impl Test<'_> {
language: cow!("default"),
};

let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);

let (mut text, _pages) =
crate::include(&self.input, &settings, TestIncluder, || unreachable!())
Expand Down
2 changes: 2 additions & 0 deletions src/test/id_prefix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

use crate::data::{PageInfo, ScoreValue};
use crate::layout::Layout;
use crate::settings::{WikitextMode, WikitextSettings, EMPTY_INTERWIKI};
use crate::tree::{
AttributeMap, Container, ContainerType, Element, ImageSource, ListItem, ListType,
Expand Down Expand Up @@ -52,6 +53,7 @@ fn isolate_user_ids() {

let settings = WikitextSettings {
mode: WikitextMode::Page,
layout: Layout::Wikidot,
enable_page_syntax: true,
use_true_ids: true,
use_include_compatibility: false,
Expand Down
5 changes: 3 additions & 2 deletions src/test/large.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

use crate::data::PageInfo;
use crate::layout::Layout;
use crate::parsing::{ParseErrorKind, Token};
use crate::settings::{WikitextMode, WikitextSettings};
use crate::tree::{Element, SyntaxTree};
Expand All @@ -32,7 +33,7 @@ use std::borrow::Cow;
#[test]
fn recursion_depth() {
let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);

// Build wikitext input
let mut input = String::new();
Expand Down Expand Up @@ -76,7 +77,7 @@ fn large_payload() {
const ITERATIONS: usize = 500;

let page_info = PageInfo::dummy();
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);

// Build wikitext input
let mut input = String::new();
Expand Down
3 changes: 2 additions & 1 deletion src/test/prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

use crate::data::{PageInfo, PageRef};
use crate::layout::Layout;
use crate::render::{html::HtmlRender, text::TextRender, Render};
use crate::settings::{WikitextMode, WikitextSettings};
use crate::tree::attribute::SAFE_ATTRIBUTES;
Expand Down Expand Up @@ -447,7 +448,7 @@ fn render<R: Render>(
tree: SyntaxTree<'static>,
page_info: PageInfo<'static>,
) -> R::Output {
let settings = WikitextSettings::from_mode(WikitextMode::Page);
let settings = WikitextSettings::from_mode(WikitextMode::Page, Layout::Wikidot);
render.render(&tree, &page_info, &settings)
}

Expand Down
3 changes: 2 additions & 1 deletion src/test/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

use crate::data::PageInfo;
use crate::layout::Layout;
use crate::render::{html::HtmlRender, Render};
use crate::settings::{WikitextMode, WikitextSettings};

Expand All @@ -36,7 +37,7 @@ fn settings() {

macro_rules! check_individual {
($mode:expr, $input:expr, $substring:expr, $contains:expr) => {{
let settings = WikitextSettings::from_mode($mode);
let settings = WikitextSettings::from_mode($mode, Layout::Wikidot);
let mut text = str!($input);
crate::preprocess(&mut text);

Expand Down
11 changes: 9 additions & 2 deletions src/wasm/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

use super::prelude::*;
use crate::layout::Layout as RustLayout;
use crate::settings::{
WikitextMode as RustWikitextMode, WikitextSettings as RustWikitextSettings,
};
Expand Down Expand Up @@ -52,7 +53,7 @@ impl WikitextSettings {
}

#[wasm_bindgen]
pub fn from_mode(mode: String) -> Result<WikitextSettings, JsValue> {
pub fn from_mode(mode: String, layout: String) -> Result<WikitextSettings, JsValue> {
let rust_mode = match mode.as_str() {
"page" => RustWikitextMode::Page,
"draft" => RustWikitextMode::Draft,
Expand All @@ -62,8 +63,14 @@ impl WikitextSettings {
_ => return Err(JsValue::from_str("Unknown mode")),
};

let rust_layout = match layout.as_str() {
"wikidot" => RustLayout::Wikidot,
"wikijump" => RustLayout::Wikijump,
_ => return Err(JsValue::from_str("Unknown layout")),
};

Ok(WikitextSettings {
inner: Arc::new(RustWikitextSettings::from_mode(rust_mode)),
inner: Arc::new(RustWikitextSettings::from_mode(rust_mode, rust_layout)),
})
}
}
Loading