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

CLI: Allow configuring template using TOML file #73

Merged
merged 7 commits into from
Oct 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)

## [Unreleased]

### Changed

- Allow configuring pixels per scroll using new `ScrollOptions.pixels_per_scroll` field.
- Change some default values and set more default values during `TemplateOptions` deserialization.

## 0.3.0 - 2023-06-03

*(No substantial changes compared to the [0.3.0-beta.2 release](#030-beta2---2023-04-29))*
Expand Down
31 changes: 29 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ anyhow = "1.0.40"
assert_matches = "1.5.0"
doc-comment = "0.3.3"
test-casing = "0.1.1"
toml = "0.8.2"
tracing-capture = "0.1.0"
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
version-sync = "0.9.2"
Expand Down
1 change: 1 addition & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)

- Allow specifying the snapshot width in pixels using `--width`.
- Allow specifying at which char to hard-break lines using `--hard-wrap`.
- Allow reading template configuration using `--config-path`.

### Changed

Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ humantime = "2.1.0"
is-terminal = "0.4.9"
serde_json = "1.0"
termcolor = "1.3.0"
toml = "0.8.2"
tracing-subscriber = { version = "0.3.16", features = ["env-filter"], optional = true }

term-transcript = { version = "0.3.0", path = ".." }
Expand Down
60 changes: 34 additions & 26 deletions cli/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ impl From<LineNumbers> for svg::LineNumbers {

#[derive(Debug, Args)]
pub(crate) struct TemplateArgs {
/// Path to the configuration TOML file.
///
/// See https://slowli.github.io/term-transcript/term_transcript/svg/ for the configuration format.
#[arg(
long,
conflicts_with_all = [
"palette", "line_numbers", "window_frame", "additional_styles", "font_family", "width",
"scroll", "hard_wrap", "no_wrap",
]
)]
config_path: Option<PathBuf>,
/// Color palette to use.
#[arg(long, short = 'p', default_value = "gjm8", value_enum)]
palette: NamedPalette,
Expand Down Expand Up @@ -103,7 +114,7 @@ pub(crate) struct TemplateArgs {
/// Path to a custom Handlebars template to use. `-` means not to use a template at all,
/// and instead output JSON data that would be fed to a template.
///
/// See https://slowli.github.io/term-transcript/term_transcript/ for docs on templating.
/// See https://slowli.github.io/term-transcript/term_transcript/svg/ for docs on templating.
#[arg(long = "tpl")]
template_path: Option<PathBuf>,
/// File to save the rendered SVG into. If omitted, the output will be printed to stdout.
Expand Down Expand Up @@ -155,7 +166,18 @@ impl TemplateArgs {
let pure_svg = self.pure_svg;
let out_path = mem::take(&mut self.out);
let template_path = mem::take(&mut self.template_path);
let options = TemplateOptions::from(self);
let config_path = mem::take(&mut self.config_path);

let options = if let Some(path) = &config_path {
let config = fs::read_to_string(path)
.with_context(|| format!("cannot read TOML config from `{}`", path.display()))?;
toml::from_str(&config).with_context(|| {
format!("failed deserializing TOML config from `{}`", path.display())
})?
} else {
TemplateOptions::from(self)
};

let template = if let Some(template_path) = template_path {
if template_path.as_os_str() == "-" {
return Self::render_data(out_path.as_deref(), transcript, &options);
Expand All @@ -169,18 +191,11 @@ impl TemplateArgs {
};

if let Some(out_path) = out_path {
let out = File::create(&out_path).with_context(|| {
format!(
"cannot create output file `{}`",
out_path.as_os_str().to_string_lossy()
)
})?;
template.render(transcript, out).with_context(|| {
format!(
"cannot render template to `{}`",
out_path.as_os_str().to_string_lossy()
)
})?;
let out = File::create(&out_path)
.with_context(|| format!("cannot create output file `{}`", out_path.display()))?;
template
.render(transcript, out)
.with_context(|| format!("cannot render template to `{}`", out_path.display()))?;
} else {
template
.render(transcript, io::stdout())
Expand All @@ -198,17 +213,10 @@ impl TemplateArgs {
.render_data(transcript)
.context("cannot render data for Handlebars template")?;
if let Some(out_path) = out_path {
let out = File::create(out_path).with_context(|| {
format!(
"cannot create output file `{}`",
out_path.as_os_str().to_string_lossy()
)
})?;
let out = File::create(out_path)
.with_context(|| format!("cannot create output file `{}`", out_path.display()))?;
serde_json::to_writer(out, &data).with_context(|| {
format!(
"cannot write Handlebars data to `{}`",
out_path.as_os_str().to_string_lossy()
)
format!("cannot write Handlebars data to `{}`", out_path.display())
})?;
} else {
serde_json::to_writer(io::stdout(), &data)
Expand All @@ -221,13 +229,13 @@ impl TemplateArgs {
let template_string = fs::read_to_string(template_path).with_context(|| {
format!(
"cannot read Handlebars template from `{}`",
template_path.as_os_str().to_string_lossy()
template_path.display()
)
})?;
let template = HandlebarsTemplate::compile(&template_string).with_context(|| {
format!(
"cannot compile Handlebars template from `{}`",
template_path.as_os_str().to_string_lossy()
template_path.display()
)
})?;
Ok(template)
Expand Down
2 changes: 0 additions & 2 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ skip = [
skip-tree = [
# Used by `tracing-subscriber` together with the new version :(
{ name = "regex-automata", version = "^0.1" },
# Used by `clap` via `terminal_size`; likely to get updated soon.
{ name = "rustix", version = "^0.37" },
]

[sources]
Expand Down
15 changes: 15 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,21 @@ term-transcript exec -T 250ms --palette gjm8 --window \

[CSP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

## Configuration file

`--config-path` option allows reading rendering options from a TOML file. This enables
configuring low-level template details. The snapshot below uses a [configuration file](config.toml)
to customize palette colors and scroll animation step / interval.

![Snapshot with config read from file](custom-config.svg)

Generating command:

```shell
term-transcript exec -T 250ms --config-path config.toml \
'rainbow --long-lines'
```

## Failed inputs

Some shells may allow detecting whether an input resulted in a failure
Expand Down
26 changes: 26 additions & 0 deletions examples/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Custom template configuration.
width = 900
window_frame = true
line_numbers = 'continuous'
wrap = { hard_break_at = 100 }
scroll = { max_height = 300, pixels_per_scroll = 18, interval = 1.5 }

[palette.colors]
black = '#3c3836'
red = '#b85651'
green = '#8f9a52'
yellow = '#c18f41'
blue = '#68948a'
magenta = '#ab6c7d'
cyan = '#72966c'
white = '#a89984'

[palette.intense_colors]
black = '#5a524c'
red = '#b85651'
green = '#a9b665'
yellow = '#d8a657'
blue = '#7daea3'
magenta = '#d3869b'
cyan = '#89b482'
white = '#ddc7a1'
106 changes: 106 additions & 0 deletions examples/custom-config.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions examples/generate-snapshots.sh
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,8 @@ term-transcript exec $TT_ARGS --palette gjm8 --window \
--font 'Fira Mono, Consolas, Liberation Mono, Menlo' \
--styles '@import url(https://code.cdn.mozilla.net/fonts/fira.css);' rainbow \
> "$ROOT_DIR/examples/fira.$EXTENSION"

echo "Creating snapshot with custom config..."
term-transcript exec $TT_ARGS --config-path "$ROOT_DIR/examples/config.toml" \
'rainbow --long-lines' \
> "$ROOT_DIR/examples/custom-config.$EXTENSION"
1 change: 0 additions & 1 deletion src/svg/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ use crate::{svg::TemplateOptions, write::SvgLine, UserInput};
/// "white": "#f7f7fb",
/// },
/// },
/// "additional_styles": "",
/// "font_family": "Consolas, Menlo, monospace",
/// "window_frame": false,
/// "wrap": {
Expand Down
6 changes: 2 additions & 4 deletions src/svg/default.svg.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
"LINE_HEIGHT": 18,
{{! Height of the window frame }}
"WINDOW_FRAME_HEIGHT": 22,
{{! Pixels scrolled vertically per each animation frame }}
"PIXELS_PER_SCROLL": 52,
{{! Right offset of the scrollbar relative to the right border of the frame }}
"SCROLLBAR_RIGHT_OFFSET": 7,
{{! Height of the scrollbar in pixels }}
Expand Down Expand Up @@ -56,7 +54,7 @@
null
{{else}}
{{#scope
steps=(div (sub content_height scroll.max_height) const.PIXELS_PER_SCROLL round="up")
steps=(div (sub content_height scroll.max_height) scroll.pixels_per_scroll round="up")
y_step=0
view_box=""
scrollbar_y=""
Expand All @@ -65,7 +63,7 @@
{{y_step set=(div (sub scroll.max_height const.SCROLLBAR_HEIGHT) (steps))}}
{{#each (range 0 (add (steps) 1))}}
{{#sep}}{{#if @first}}""{{else}}";"{{/if}}{{/sep}}
{{#view_box}}"{{view_box}}{{sep}}0 {{mul ../const.PIXELS_PER_SCROLL @index}} {{../width}} {{../scroll.max_height}}"{{/view_box}}
{{#view_box}}"{{view_box}}{{sep}}0 {{mul ../scroll.pixels_per_scroll @index}} {{../width}} {{../scroll.max_height}}"{{/view_box}}
{{#scrollbar_y}}"{{scrollbar_y}}{{sep}}0 {{mul (y_step) @index round="nearest"}}"{{/scrollbar_y}}
{{/each}}

Expand Down
Loading