1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
/*
* settings/mod.rs
*
* ftml - Library to parse Wikidot text
* Copyright (C) 2019-2022 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/>.
*/
mod interwiki;
pub use self::interwiki::{InterwikiSettings, DEFAULT_INTERWIKI, EMPTY_INTERWIKI};
const DEFAULT_MINIFY_CSS: bool = true;
/// Settings to tweak behavior in the ftml parser and renderer.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct WikitextSettings {
/// What mode we're running in.
pub mode: WikitextMode,
/// Whether page-contextual syntax is permitted.
///
/// This currently refers to:
/// * Include
/// * Module
/// * Table of Contents
/// * Button
pub enable_page_syntax: bool,
/// Whether a literal `[[include]]` is permitted.
///
/// If this is true, then `[[include]]` is treated as an alias
/// for `[[include-messy]]`, which is necessary for Wikidot compatibility.
///
/// It is off by default.
pub use_include_compatibility: bool,
/// Whether IDs should have true values, or be excluded or randomly generated.
///
/// In the latter case, IDs can be used for navigation, for instance
/// the table of contents, but setting this to `true` is needed in any
/// context where more than one instance of rendered wikitext could be emitted.
pub use_true_ids: bool,
/// Whether to prefix user IDs with `u-`.
///
/// This is a behavior found in Wikidot (although implemented incompletely)
/// which prefixes IDs in HTML elements provided by the user with `u-` to ensure
/// isolation.
pub isolate_user_ids: bool,
/// Whether to minify CSS in `<style>` blocks.
pub minify_css: bool,
/// Whether local paths are permitted.
///
/// This should be disabled in contexts where there is no "local context"
/// to which these paths could be interpreted. For instance, on pages
/// you can reference an attached file, but on an arbitrary forum thread
/// no such file can exist.
///
/// This applies to:
/// * Files
/// * Images
pub allow_local_paths: bool,
/// What interwiki prefixes are supported.
///
/// All instances of `$$` in the destination URL are replaced with the link provided
/// in the interwiki link. For instance, `[wikipedia:SCP_Foundation SCP Wiki]`, then
/// `$$` will be replaced with `SCP_Foundation`.
///
/// # Notes
///
/// * These are matched case-sensitively.
/// * Prefixes may not contain colons, they are matched up to the first colon, and
/// any beyond that are considered part of the link.
/// * By convention, prefixes should be all-lowercase.
pub interwiki: InterwikiSettings,
}
impl WikitextSettings {
pub fn from_mode(mode: WikitextMode) -> Self {
let interwiki = DEFAULT_INTERWIKI.clone();
match mode {
WikitextMode::Page => WikitextSettings {
mode,
enable_page_syntax: true,
use_include_compatibility: false,
use_true_ids: true,
isolate_user_ids: false,
minify_css: DEFAULT_MINIFY_CSS,
allow_local_paths: true,
interwiki,
},
WikitextMode::Draft => WikitextSettings {
mode,
enable_page_syntax: true,
use_include_compatibility: false,
use_true_ids: false,
isolate_user_ids: false,
minify_css: DEFAULT_MINIFY_CSS,
allow_local_paths: true,
interwiki,
},
WikitextMode::ForumPost | WikitextMode::DirectMessage => WikitextSettings {
mode,
enable_page_syntax: false,
use_include_compatibility: false,
use_true_ids: false,
isolate_user_ids: false,
minify_css: DEFAULT_MINIFY_CSS,
allow_local_paths: false,
interwiki,
},
WikitextMode::List => WikitextSettings {
mode,
enable_page_syntax: true,
use_include_compatibility: false,
use_true_ids: false,
isolate_user_ids: false,
minify_css: DEFAULT_MINIFY_CSS,
allow_local_paths: true,
interwiki,
},
}
}
}
/// What mode parsing and rendering is done in.
///
/// Each variant has slightly different behavior associated
/// with them, beyond the typical flags for the rest of `WikitextSettings`.
///
/// The exact details of each are still being decided as this is implemented.
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Hash, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub enum WikitextMode {
/// Processing for the contents of a page on a site.
Page,
/// Processing for a draft of a page.
Draft,
/// Processing for the contents of a forum post, of which there may be many.
ForumPost,
/// Processing for the contents of a direct message, sent to a user.
DirectMessage,
/// Processing for modules or other contexts such as `ListPages`.
List,
}