Skip to content

Commit

Permalink
Markup for doc strings (#177)
Browse files Browse the repository at this point in the history
Makes Rink parse out the links and date strings when using the token
format machinery. This is a new syntax in the definitions file with
`<abc>` for links and `#abc#` for dates.

Replaced ansi_term with nu-ansi-term because the former was
unmaintained. The latter comes with the ability to set hyperlinks.
  • Loading branch information
tiffany352 authored May 27, 2024
1 parent fb1b58a commit a13b9fc
Show file tree
Hide file tree
Showing 18 changed files with 554 additions and 102 deletions.
21 changes: 11 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ eyre = "0.6"
color-eyre = { version = "0.6", default-features = false }
humantime-serde = "1.0.1"
rustyline = { version = "9", default-features = false }
ansi_term = "0.12"
nu-ansi-term = "0.50"
async-std = { version = "1.9", features = ["attributes"], default-features = false }
ubyte = { version = "0.10.3", features = ["serde"] }

Expand All @@ -40,5 +40,8 @@ path = "../core"
version = "0.6"
path = "../sandbox"

[dev-dependencies]
similar-asserts = "1.1.0"

[package.metadata.wasm-pack.profile.profiling]
wasm-opt = ['-g', '-O']
6 changes: 5 additions & 1 deletion cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use crate::style_ser;
use ansi_term::{Color, Style};
use color_eyre::Result;
use curl::easy::Easy;
use eyre::{eyre, Report, WrapErr};
use nu_ansi_term::{Color, Style};
use rink_core::output::fmt::FmtToken;
use rink_core::parsing::datetime;
use rink_core::Context;
Expand Down Expand Up @@ -120,6 +120,8 @@ pub struct Theme {
prop_name: Style,
#[serde(with = "style_ser")]
date_time: Style,
#[serde(with = "style_ser")]
link: Style,
}

impl Theme {
Expand All @@ -135,6 +137,7 @@ impl Theme {
FmtToken::Pow => self.pow,
FmtToken::PropName => self.prop_name,
FmtToken::DateTime => self.date_time,
FmtToken::Link => self.link,

// Default styling since these are handled specially.
FmtToken::ListBegin => self.plain,
Expand Down Expand Up @@ -162,6 +165,7 @@ impl Default for Config {
pow: Style::default(),
prop_name: Style::new().fg(Color::Cyan),
date_time: Style::default(),
link: Style::new().fg(Color::Blue),
},
disabled_theme: Theme::default(),
}
Expand Down
198 changes: 193 additions & 5 deletions cli/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use ansi_term::{ANSIString, ANSIStrings};
use nu_ansi_term::{AnsiString, AnsiStrings};
use rink_core::output::fmt::{FmtToken, Span, TokenFmt};

use crate::config::{Config, Theme};
Expand All @@ -11,7 +11,7 @@ fn to_ansi_inner<'a>(
theme: &Theme,
long_output: bool,
mut indent: usize,
strings: &mut Vec<ANSIString<'a>>,
strings: &mut Vec<AnsiString<'a>>,
obj: &'a dyn TokenFmt<'a>,
) {
let spans = obj.to_spans();
Expand Down Expand Up @@ -39,6 +39,39 @@ fn to_ansi_inner<'a>(
strings.push(format!("\n{:width$}• ", "", width = indent * 2 - 2).into());
}

Span::Content {
text,
token: token @ FmtToken::DateTime,
} => {
let datetime =
chrono::naive::NaiveDateTime::parse_from_str(&text, "%Y-%m-%d %H:%M:%S");
let date = chrono::naive::NaiveDate::parse_from_str(&text, "%Y-%m-%d");
nothing_printed = false;
if let Ok(date) = datetime {
strings.push(
theme
.get_style(token)
.paint(date.format("%B %-d, %Y %H:%M:%S").to_string()),
);
} else if let Ok(date) = date {
strings.push(
theme
.get_style(token)
.paint(date.format("%B %-d, %Y").to_string()),
);
} else {
strings.push(theme.get_style(token).paint(text));
}
}

Span::Content {
text,
token: token @ FmtToken::Link,
} => {
nothing_printed = false;
strings.push(theme.get_style(token).paint(text.clone()).hyperlink(text));
}

Span::Content { text, token } => {
nothing_printed = false;
strings.push(theme.get_style(token).paint(text));
Expand All @@ -52,7 +85,7 @@ fn to_ansi_inner<'a>(
}
}

fn to_ansi<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) -> Vec<ANSIString<'a>> {
fn to_ansi<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) -> Vec<AnsiString<'a>> {
let mut strings = vec![];
to_ansi_inner(
config.get_theme(),
Expand All @@ -66,12 +99,167 @@ fn to_ansi<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) -> Vec<ANSIString<'a>

pub(crate) fn to_ansi_string<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) -> String {
let strings = to_ansi(config, obj);
let strings = ANSIStrings(&strings);
let strings = AnsiStrings(&strings);
format!("{}", strings)
}

pub(crate) fn print_fmt<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) {
let strings = to_ansi(config, obj);
let strings = ANSIStrings(&strings);
let strings = AnsiStrings(&strings);
print!("{}", strings);
}

#[cfg(test)]
mod tests {
use nu_ansi_term::{AnsiString, AnsiStrings, Style};
use rink_core::{parsing::text_query, simple_context, Context};

use crate::{config::Config, fmt::to_ansi};

thread_local! {
static CONTEXT: Context = {
let mut ctx = simple_context().unwrap();
ctx.use_humanize = false;
ctx
};
}

fn test(input: &str, output: &[AnsiString]) {
let mut iter = text_query::TokenIterator::new(input.trim()).peekable();
let expr = text_query::parse_query(&mut iter);
CONTEXT.with(|ctx| {
let mut config = Config::default();
config.rink.long_output = true;
let res = ctx.eval_query(&expr);
let strings = match res {
Ok(ref res) => to_ansi(&config, res),
Err(ref res) => to_ansi(&config, res),
};
similar_asserts::assert_eq!(AnsiStrings(output), AnsiStrings(&strings));
});
}

#[test]
fn test_to_ansi() {
use nu_ansi_term::Color::*;

test(
"meter",
&[
Style::new().paint("Definition: "),
Style::new().fg(Cyan).paint("meter"),
Style::new().paint(" = "),
Style::new().paint("base unit of length"),
Style::new().paint(". "),
Style::new().italic().paint("The metre, symbol m, is the SI unit of length. It is defined by taking the fixed numerical value of the speed of light in vacuum c to be 299 792 458 when expressed in the unit m/s, where the second is defined in terms of Δν_Cs. 26th CGPM (2018, CR; 211)"),
],
);

test(
"foot",
&[
Style::new().paint("Definition: "),
Style::new().fg(Cyan).paint("foot"),
Style::new().paint(" = "),
Style::new().paint("12 inch"),
Style::new().paint(" = "),
Style::new().paint("304.8"),
Style::new().paint(" "),
Style::new().fg(Cyan).paint("millimeter"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("length"),
Style::new().paint("; "),
Style::new().fg(Cyan).paint("m"),
Style::new().paint(")"),
Style::new().paint(". "),
Style::new()
.italic()
.paint("International yard and pound, since "),
Style::new().paint("July 1, 1959"),
Style::new().italic().paint("."),
],
);

test("floppy", &[
Style::new().paint("Definition: "),
Style::new().fg(Cyan).paint("floppydisk"),
Style::new().paint(" = "),
Style::new().paint("1440 KiB"),
Style::new().paint(" = "),
Style::new().paint("1.47456"),
Style::new().paint(" "),
Style::new().fg(Cyan).paint("megabyte"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("information"),
Style::new().paint("; "),
Style::new().fg(Cyan).paint("bit"),
Style::new().paint(")"),
Style::new().paint(". "),
Style::new()
.italic()
.paint("The common 3.5 inch floppy disk in \"1.44 Meg\" format. The 1.44 comes from mixing decimal and binary prefixes (1000*1024 bytes). Equal to 512 B x 80 tracks x 18 sectors x 2 sides. Source: "),
Style::new().fg(Blue).paint("http://www.manmrk.net/tutorials/DOS/PSBOOK/book4/floppyd.htm").hyperlink("http://www.manmrk.net/tutorials/DOS/PSBOOK/book4/floppyd.htm"),
]);

test(
"asdf",
&[
Style::new().fg(Red).paint("No such unit "),
Style::new().bold().paint("asdf"),
],
);

test(
"search horse",
&[
Style::new().paint("Search results: "),
Style::new().paint("\n• "),
Style::new().fg(Cyan).paint("horsepower"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("power"),
Style::new().paint(")"),
Style::new().paint("\n• "),
Style::new().fg(Cyan).paint("brhorsepower"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("power"),
Style::new().paint(")"),
Style::new().paint("\n• "),
Style::new().fg(Cyan).paint("waterhorsepower"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("power"),
Style::new().paint(")"),
Style::new().paint("\n• "),
Style::new().fg(Cyan).paint("boilerhorsepower"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("power"),
Style::new().paint(")"),
Style::new().paint("\n• "),
Style::new().fg(Cyan).paint("metrichorsepower"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("power"),
Style::new().paint(")"),
],
);

test(
"volume of moon * (19.283 g/cm^3) * G / (radius of moon)^2 to gravity",
&[
Style::new().paint("approx. "),
Style::new().paint("0.9549987"),
Style::new().paint(" "),
Style::new().fg(Cyan).paint("gravity"),
Style::new().paint(" "),
Style::new().paint("("),
Style::new().fg(Cyan).dimmed().paint("acceleration"),
Style::new().paint(")"),
],
);
}
}
Loading

0 comments on commit a13b9fc

Please sign in to comment.