Skip to content

Commit

Permalink
Make wikilinks orders mutually exclusive
Browse files Browse the repository at this point in the history
  • Loading branch information
SamWilsn committed Dec 4, 2024
1 parent b9a17ea commit 2192e97
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 62 deletions.
5 changes: 2 additions & 3 deletions examples/s-expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const INDENT: usize = 4;
const CLOSE_NEWLINE: bool = false;

use comrak::nodes::{AstNode, NodeValue};
use comrak::{parse_document, Arena, ExtensionOptions, Options};
use comrak::{parse_document, Arena, ExtensionOptions, Options, WikiLinksMode};
use std::env;
use std::error::Error;
use std::fs::File;
Expand Down Expand Up @@ -86,8 +86,7 @@ fn dump(source: &str) -> io::Result<()> {
.multiline_block_quotes(true)
.math_dollars(true)
.math_code(true)
.wikilinks_title_after_pipe(true)
.wikilinks_title_before_pipe(true)
.wikilinks(WikiLinksMode::TitleFirst)
.build();

let opts = Options {
Expand Down
6 changes: 3 additions & 3 deletions src/cm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::nodes::{
use crate::nodes::{NodeList, TableAlignment};
#[cfg(feature = "shortcodes")]
use crate::parser::shortcodes::NodeShortCode;
use crate::parser::Options;
use crate::parser::{Options, WikiLinksMode};
use crate::scanners;
use crate::strings::trim_start_match;
use crate::{nodes, Plugins};
Expand Down Expand Up @@ -761,12 +761,12 @@ impl<'a, 'o> CommonMarkFormatter<'a, 'o> {
fn format_wikilink(&mut self, nl: &NodeWikiLink, entering: bool) -> bool {
if entering {
write!(self, "[[").unwrap();
if self.options.extension.wikilinks_title_after_pipe {
if self.options.extension.wikilinks == Some(WikiLinksMode::UrlFirst) {
self.output(nl.url.as_bytes(), false, Escaping::Url);
write!(self, "|").unwrap();
}
} else {
if self.options.extension.wikilinks_title_before_pipe {
if self.options.extension.wikilinks == Some(WikiLinksMode::TitleFirst) {
write!(self, "|").unwrap();
self.output(nl.url.as_bytes(), false, Escaping::Url);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ pub use parser::{
parse_document, BrokenLinkCallback, BrokenLinkReference, ExtensionOptions,
ExtensionOptionsBuilder, ListStyleType, Options, ParseOptions, ParseOptionsBuilder, Plugins,
PluginsBuilder, RenderOptions, RenderOptionsBuilder, RenderPlugins, RenderPluginsBuilder,
ResolvedReference, URLRewriter,
ResolvedReference, URLRewriter, WikiLinksMode,
};
pub use typed_arena::Arena;
pub use xml::format_document as format_xml;
Expand Down
20 changes: 17 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::path::PathBuf;
use std::process;

use clap::{Parser, ValueEnum};
use comrak::{ExtensionOptions, ParseOptions, RenderOptions};
use comrak::{ExtensionOptions, ParseOptions, RenderOptions, WikiLinksMode};

const EXIT_SUCCESS: i32 = 0;
const EXIT_PARSE_CONFIG: i32 = 2;
Expand Down Expand Up @@ -252,6 +252,21 @@ fn main() -> Result<(), Box<dyn Error>> {

let exts = &cli.extensions;

let wikilinks_title_after_pipe = exts.contains(&Extension::WikilinksTitleAfterPipe);
let wikilinks_title_before_pipe = exts.contains(&Extension::WikilinksTitleBeforePipe);
let wikilinks_mode = match (wikilinks_title_after_pipe, wikilinks_title_before_pipe) {
(false, false) => None,
(true, false) => Some(WikiLinksMode::UrlFirst),
(false, true) => Some(WikiLinksMode::TitleFirst),
(true, true) => {
eprintln!(concat!(
"cannot enable both wikilinks-title-after-pipe ",
"and wikilinks-title-before-pipe at the same time"
));
process::exit(EXIT_PARSE_CONFIG);
}
};

let extension = ExtensionOptions::builder()
.strikethrough(exts.contains(&Extension::Strikethrough) || cli.gfm)
.tagfilter(exts.contains(&Extension::Tagfilter) || cli.gfm)
Expand All @@ -265,8 +280,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.multiline_block_quotes(exts.contains(&Extension::MultilineBlockQuotes))
.math_dollars(exts.contains(&Extension::MathDollars))
.math_code(exts.contains(&Extension::MathCode))
.wikilinks_title_after_pipe(exts.contains(&Extension::WikilinksTitleAfterPipe))
.wikilinks_title_before_pipe(exts.contains(&Extension::WikilinksTitleBeforePipe))
.maybe_wikilinks(wikilinks_mode)
.underline(exts.contains(&Extension::Underline))
.subscript(exts.contains(&Extension::Subscript))
.spoiler(exts.contains(&Extension::Spoiler))
Expand Down
17 changes: 9 additions & 8 deletions src/parser/inlines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use std::str;
use typed_arena::Arena;
use unicode_categories::UnicodeCategories;

use super::WikiLinksMode;

const MAXBACKTICKS: usize = 80;
const MAX_LINK_LABEL_LENGTH: usize = 1000;
const MAX_MATH_DOLLARS: usize = 2;
Expand Down Expand Up @@ -235,8 +237,7 @@ impl<'a, 'r, 'o, 'd, 'i> Subject<'a, 'r, 'o, 'd, 'i> {

let mut wikilink_inl = None;

if (self.options.extension.wikilinks_title_after_pipe
|| self.options.extension.wikilinks_title_before_pipe)
if self.options.extension.wikilinks.is_some()
&& !self.within_brackets
&& self.peek_char() == Some(&(b'['))
{
Expand Down Expand Up @@ -1804,16 +1805,16 @@ impl<'a, 'r, 'o, 'd, 'i> Subject<'a, 'r, 'o, 'd, 'i> {
if self.peek_char() == Some(&(b']')) && self.peek_char_n(1) == Some(&(b']')) {
self.pos += 2;

if self.options.extension.wikilinks_title_after_pipe {
Some(WikilinkComponents {
match self.options.extension.wikilinks {
Some(WikiLinksMode::UrlFirst) => Some(WikilinkComponents {
url: left,
link_label: Some((right, right_startpos + 1, self.pos - 3)),
})
} else {
Some(WikilinkComponents {
}),
Some(WikiLinksMode::TitleFirst) => Some(WikilinkComponents {
url: right,
link_label: Some((left, left_startpos + 1, right_startpos - 1)),
})
}),
None => unreachable!(),
}
} else {
self.pos = left_startpos;
Expand Down
42 changes: 24 additions & 18 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,21 @@ where
}
}

#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Selects between wikilinks with the title first or the URL first.
///
/// See [`ExtensionOptions::wikilinks`].
pub enum WikiLinksMode {
/// Indicates that the URL precedes the title. For example: `[[http://example.com|link
/// title]]`.
UrlFirst,

/// Indicates that the title precedes the URL. For example: `[[link title|http://example.com]]`.
TitleFirst,
}

#[non_exhaustive]
#[derive(Default, Debug, Clone, Builder)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
Expand Down Expand Up @@ -466,37 +481,28 @@ pub struct ExtensionOptions {
#[builder(default)]
pub shortcodes: bool,

/// Enables wikilinks using title after pipe syntax
/// Enables wikilinks
///
/// With [`WikiLinksMode::TitleFirst`]:
///
/// ```` md
/// [[url|link label]]
/// [[link label|url]]
/// ````
///
/// ```
/// # use comrak::{markdown_to_html, Options};
/// let mut options = Options::default();
/// options.extension.wikilinks_title_after_pipe = true;
/// assert_eq!(markdown_to_html("[[url|link label]]", &options),
/// "<p><a href=\"url\" data-wikilink=\"true\">link label</a></p>\n");
/// ```
#[builder(default)]
pub wikilinks_title_after_pipe: bool,

/// Enables wikilinks using title before pipe syntax
/// With [`WikiLinksMode::UrlFirst`]:
///
/// ```` md
/// [[link label|url]]
/// [[url|link label]]
/// ````
///
/// ```
/// # use comrak::{markdown_to_html, Options};
/// # use comrak::{markdown_to_html, Options, WikiLinksMode};
/// let mut options = Options::default();
/// options.extension.wikilinks_title_before_pipe = true;
/// options.extension.wikilinks = Some(WikiLinksMode::TitleFirst);
/// assert_eq!(markdown_to_html("[[link label|url]]", &options),
/// "<p><a href=\"url\" data-wikilink=\"true\">link label</a></p>\n");
/// ```
#[builder(default)]
pub wikilinks_title_before_pipe: bool,
pub wikilinks: Option<WikiLinksMode>,

/// Enables underlines using double underscores
///
Expand Down
5 changes: 2 additions & 3 deletions src/tests/api.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::{Arc, Mutex};

use parser::BrokenLinkReference;
use parser::{BrokenLinkReference, WikiLinksMode};

use crate::{
adapters::{HeadingAdapter, HeadingMeta, SyntaxHighlighterAdapter},
Expand Down Expand Up @@ -69,8 +69,7 @@ fn exercise_full_api() {
let extension = extension.shortcodes(true);

let _extension = extension
.wikilinks_title_after_pipe(true)
.wikilinks_title_before_pipe(true)
.wikilinks(WikiLinksMode::UrlFirst)
.underline(true)
.subscript(true)
.spoiler(true)
Expand Down
3 changes: 2 additions & 1 deletion src/tests/commonmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use self::nodes::{Ast, LineColumn, ListType, NodeList};

use super::*;
use ntest::test_case;
use parser::WikiLinksMode;

#[test]
fn commonmark_removes_redundant_strong() {
Expand Down Expand Up @@ -83,7 +84,7 @@ fn math(markdown: &str, cm: &str) {
#[test_case("This [[url|link label]] that", "This [[url|link%20label]] that\n")]
fn wikilinks(markdown: &str, cm: &str) {
let mut options = Options::default();
options.extension.wikilinks_title_before_pipe = true;
options.extension.wikilinks = Some(WikiLinksMode::TitleFirst);

commonmark(markdown, cm, Some(&options));
}
Expand Down
Loading

0 comments on commit 2192e97

Please sign in to comment.