Skip to content

Commit

Permalink
Merge pull request #165 from tommilligan/99-custom-admonitions
Browse files Browse the repository at this point in the history
feat: custom directives
  • Loading branch information
tommilligan authored Dec 30, 2023
2 parents 26c344a + 1bb1468 commit c4a05da
Show file tree
Hide file tree
Showing 34 changed files with 857 additions and 142 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ jobs:
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.experimental }}
steps:
# This is required, otherwise we get files with CRLF on Windows
# Which causes tests relying on data loaded from files to fail
- name: Set git to use LF everywhere
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout sources
uses: actions/checkout@v4
- name: Cache build files
Expand Down
18 changes: 18 additions & 0 deletions Cargo.lock

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

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ anyhow = "1.0.75"
# Note: clap 4.4 increases MSRV to 1.70.0 (2023-06-01)
# To use MSRV supported dependencies, install using the lockfile with
# `cargo install mdbook-admonish --locked`
clap = { version = "4.3", default_features = false, features = ["std", "derive"], optional = true }
env_logger = { version = "0.10", default_features = false, optional = true }
clap = { version = "4.3", default-features = false, features = ["std", "derive"], optional = true }
env_logger = { version = "0.10", default-features = false, optional = true }
log = "0.4.20"
mdbook = "0.4.35"
once_cell = "1.18.0"
Expand All @@ -46,6 +46,7 @@ serde_json = "1.0.107"
toml_mdbook = { package = "toml", version = "0.5.11" }
toml = "0.8.1"
toml_edit = { version = "0.20.1", optional = true }
hex_color = { version = "3.0.0", features = ["serde"] }

[dev-dependencies]
pretty_assertions = "1.4.0"
Expand Down
7 changes: 6 additions & 1 deletion book/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ title = "The mdbook-admonish book"
command = "mdbook-admonish"
assets_version = "3.0.1" # do not edit: managed by `mdbook-admonish install`

[[preprocessor.admonish.custom]]
directive = "expensive"
icon = "./money-bag.svg"
color = "#24ab38"

[preprocessor.toc]
command = "mdbook-toc"
renderer = ["html"]

[output]

[output.html]
additional-css = ["./mdbook-admonish.css"]
additional-css = ["./mdbook-admonish.css", "./mdbook-admonish-custom.css"]
20 changes: 20 additions & 0 deletions book/mdbook-admonish-custom.css

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

6 changes: 6 additions & 0 deletions book/money-bag.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 44 additions & 1 deletion book/src/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ The default id is a normalized version of the admonishment's title,
prefixed with the `default.css_id_prefix`,
with an appended number if multiple blocks would have the same id.

Setting the `id` field will *ignore* all other ids and the duplicate counter.
Setting the `id` field will _ignore_ all other ids and the duplicate counter.

````
```admonish info title="My Info" id="my-special-info"
Expand All @@ -194,3 +194,46 @@ Will yield something like the following HTML, which you can then apply styles to
Content will be hidden initially.
```

### Custom blocks

You can add new block types via the `book.toml` config:

```toml
# book.toml

[[preprocessor.admonish.custom]]
directive = "expensive"
icon = "./money-bag.svg"
color = "#24ab38"
aliases = ["money", "cash", "budget"]
```

You must then generate the relevant CSS file, and reference it in the `output.html` section.
`mdbook-admonish` has a helper to quickly do this for you:

```bash
# Generates a file at ./mdbook-admonish-custom.css with your styles in
$ mdbook-admonish generate-custom ./mdbook-admonish-custom.css
```

```toml
# book.toml

[output.html]
# Reference the new file, so it's bundled in with book styles
additional-css = ["./mdbook-admonish.css", "./mdbook-admonish-custom.css"]
```

You can then reference the new directive (or alias) like usual in your blocks.

````
```admonish expensive
Remember, this operation costs money!
```
````

```admonish expensive
Remember, this operation costs money!
```

You can also set a default `title`. See the [Reference](./reference.md) page for more details.
27 changes: 27 additions & 0 deletions book/src/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,31 @@ Subfields:
- For the `html` renderer, the default value is `html`.
- For all other renderers, the default value is `preserve`.

### `custom`

Optional.

Additional type of block to support.
You must run `mdbook-admonish generate-custom` after updating these values, to generate the correct styles.

Add blocks using TOML's [Array of Tables](https://toml.io/en/v1.0.0#array-of-tables) notation:

```toml
[[preprocessor.admonish.custom]]
directive = "expensive"
icon = "./money-bag.svg"
color = "#24ab38"
aliases = ["money", "cash", "budget"]
```

Subfields:

- `directive`: The keyword to use this type of block.
- `icon`: A filepath relative to the book root to load an SVG icon from.
- `color`: An RGB hex encoded color to use for the icon.
- `aliases` (optional): One or more alternative directives to use this block.
- `title` (optional): The default title for this type of block. If not specified, defaults to the directive in title case. To give each alias a custom title, add multiple custom blocks.

### `command`

Required.
Expand All @@ -93,6 +118,8 @@ This is automatically updated by `mdbook-admonish install` and should not be edi

All supported directives are listed below.

Custom directives can be added via the `custom` config option above.

`note`

```admonish note
Expand Down
4 changes: 3 additions & 1 deletion compile_assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "sass --no-source-map scss/mdbook-admonish.scss ../src/bin/assets/mdbook-admonish.css",
"build": "yarn run build-prod && yarn run build-custom-expected",
"build-prod": "sass --no-source-map scss/mdbook-admonish.scss ../src/bin/assets/mdbook-admonish.css",
"build-custom-expected": "sass --no-source-map scss/mdbook-admonish-custom-expected.scss ../src/test_data/mdbook-admonish-custom-expected.css",
"lint": "prettier --check .",
"fix": "prettier --write ."
},
Expand Down
55 changes: 10 additions & 45 deletions compile_assets/scss/admonition.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

@use "sass:color";
@use "sass:list";
@use "./lib";

// ----------------------------------------------------------------------------
// Variables
Expand Down Expand Up @@ -68,17 +69,9 @@ $admonitions: (
) !default;

// ----------------------------------------------------------------------------
// Rules: layout
// ----------------------------------------------------------------------------

// Admonition variables
:root {
@each $names, $props in $admonitions {
--md-admonition-icon--#{nth($names, 1)}: url("data:image/svg+xml;charset=utf-8,#{nth($props, 2)}");
}
--md-details-icon: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z'/></svg>");
}

// ----------------------------------------------------------------------------
// Static content - base for all admonitions
// ----------------------------------------------------------------------------

// Admonition
Expand Down Expand Up @@ -231,48 +224,20 @@ summary.admonition-title {
}
}

// ----------------------------------------------------------------------------
// Rules: flavours
// ----------------------------------------------------------------------------

@each $names, $props in $admonitions {
$name: list.nth($names, 1);
$tint: list.nth($props, 1);

// Admonition flavour selectors
$flavours: ();

@each $name in $names {
$flavours: list.join($flavours, ".#{$name}", $separator: comma);
}

// Admonition flavour
:is(.admonition):is(#{$flavours}) {
border-color: $tint;
}

// Admonition flavour title
:is(#{$flavours}) > :is(.admonition-title, summary.admonition-title) {
background-color: color.adjust($tint, $alpha: -0.9);

// Admonition icon
&::before {
background-color: $tint;
mask-image: var(--md-admonition-icon--#{$name});
-webkit-mask-image: var(--md-admonition-icon--#{$name});
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
}
:root {
--md-details-icon: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8.59 16.58 13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.42Z'/></svg>");
}

// Generate rules for each specified admonition variant
@include lib.from-admonitions($admonitions);

// ----------------------------------------------------------------------------
// Rules: themes
// ----------------------------------------------------------------------------
//
// One rule per builtin theme in mdbook, overriding the default fg/bg if matched
//
// This must be after the variant CSS, so it can override they styles set there

.navy {
& :is(.admonition) {
Expand Down
52 changes: 52 additions & 0 deletions compile_assets/scss/lib.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@use "sass:color";
@use "sass:list";

@mixin from-admonitions($admonitions) {
// ----------------------------------------------------------------------------
// Rules: layout
// ----------------------------------------------------------------------------

// Admonition variables
:root {
@each $names, $props in $admonitions {
--md-admonition-icon--#{nth($names, 1)}: url("data:image/svg+xml;charset=utf-8,#{nth($props, 2)}");
}
}

// ----------------------------------------------------------------------------
// Rules: flavours
// ----------------------------------------------------------------------------

@each $names, $props in $admonitions {
$name: list.nth($names, 1);
$tint: list.nth($props, 1);

// Admonition flavour selectors
$flavours: ();

@each $name in $names {
$flavours: list.join($flavours, ".#{$name}", $separator: comma);
}

// Admonition flavour
:is(.admonition):is(#{$flavours}) {
border-color: $tint;
}

// Admonition flavour title
:is(#{$flavours}) > :is(.admonition-title, summary.admonition-title) {
background-color: color.adjust($tint, $alpha: -0.9);

// Admonition icon
&::before {
background-color: $tint;
mask-image: var(--md-admonition-icon--#{$name});
-webkit-mask-image: var(--md-admonition-icon--#{$name});
mask-repeat: no-repeat;
-webkit-mask-repeat: no-repeat;
mask-size: contain;
-webkit-mask-repeat: no-repeat;
}
}
}
}
16 changes: 16 additions & 0 deletions compile_assets/scss/mdbook-admonish-custom-expected.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// This file aims to generate the subset of CSS specific to a single admonition directive.
//
// This is used for unit test data in the rust css generation module.

@use "sass:color";
@use "sass:list";
@use "./lib";
@import "./material-color";

$admonitions: (
admonish-note: $clr-blue-a200
"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z'/></svg>",
) !default;

// Generate rules for each specified admonition variant
@include lib.from-admonitions($admonitions);
9 changes: 7 additions & 2 deletions integration/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ title = "mdbook-admonish-integration"

[preprocessor.admonish]
command = "mdbook-admonish"
assets_version = "3.0.1" # do not edit: managed by `mdbook-admonish install`
assets_version = "3.0.2" # do not edit: managed by `mdbook-admonish install`
after = ["links"]

[[preprocessor.admonish.custom]]
directive = "frog"
icon = "./frog.svg"
color = "#9004CC"

[preprocessor.admonish.renderer.test]
render_mode = "strip"

[output]

[output.html]
additional-css = ["./mdbook-admonish.css"]
additional-css = ["./mdbook-admonish.css", "./mdbook-admonish-custom.css"]
Loading

0 comments on commit c4a05da

Please sign in to comment.