diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..7585238 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +book diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 0000000..493e614 --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,30 @@ +[book] +title = "mdbook-utils' User Guide" +authors = ["John CD"] +description = "The user guide for the `mdbook-utils` tool." +language = "en" +multilingual = false + +[rust] +edition = "2021" + +[build] +create-missing = false +use-default-preprocessors = false + +[preprocessor.index] + +[output.html] +no-section-label = true +git-repository-url = "https://github.com/john-cd/mdbook-utils" +git-repository-icon = "fa-github" +edit-url-template = "https://github.com/john-cd/mdbook-utils/edit/master/guide/{path}" +site-url = "/mdbook-utils/" +# cname = "myproject.rs" + +[output.html.print] +enable = true # include support for printable output +page-break = true # insert page-break after each chapter + +[output.html.playground] +editable = true # allows editing the source code diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md new file mode 100644 index 0000000..a575a16 --- /dev/null +++ b/docs/src/SUMMARY.md @@ -0,0 +1,10 @@ +# Summary + +[Introduction](./introduction.md) + +- [Installation](./installation.md) +- [Definitions](./definitions.md) +- [Usage](./usage.md) +- [Configuration](./configuration.md) +- [Public API](./public_api.md) +- [Contributing](./contributing.md) diff --git a/docs/src/configuration.md b/docs/src/configuration.md new file mode 100644 index 0000000..6ce8dac --- /dev/null +++ b/docs/src/configuration.md @@ -0,0 +1,45 @@ +# Configuration + +Each subcommand uses defaults that are overwritten by values in `book.toml` (if present), by environment variables (if set), or command-line options (the latter trumps the former). + +You may export environment variables manually or store them in a `.env` file, which will be read automatically: + +```bash +# Root directory of the book +# `book.toml` is looked up in BOOK_ROOT_DIR_PATH, if set, +# in the current working directory otherwise. +export BOOK_ROOT_DIR_PATH=./test_book/ + +# Markdown source directory +export MARKDOWN_DIR_PATH=./test_book/src/ + +# Directory where mdbook outputs the book's HTML and JS; +# typically ./book/ or ./book/html/ +export BOOK_HTML_BUILD_DIR_PATH=./test_book/book/ + +# Directory where `mdbook` outputs the book's fully expanded Markdown, +# i.e. with all includes resolved, when `[output.markdown]` is added to `book.toml`. +# It is typically ./book/markdown/. +export BOOK_MARKDOWN_BUILD_DIR_PATH=./test_book/book/markdown/ + +# Directory where `Cargo.toml` may be found +export CARGO_TOML_DIR_PATH=./test_book/book/code/ + +# Default destination directory for mdbook-utils outputs. +export DEFAULT_DEST_DIR_PATH=./test_book/temp/ + +# Base url of the website where the book will be deployed +# (used to build sitemaps) +export BASE_URL=http://myexample.com/some_book/ +``` + +You may also set the [`RUST_LOG`][rust-log] environment variable to display the logs. + +See `cli/config.rs` in the [GitHub repo][mdbook-utils-github] for more details. + +Note: `mdbook-utils` is not a mdbook [preprocessor] or [backend] at this point. + +[backend]: https://rust-lang.github.io/mdBook/format/configuration/renderers.html +[mdbook-utils-github]: https://github.com/john-cd/mdbook-utils +[preprocessor]: https://rust-lang.github.io/mdBook/for_developers/preprocessors.html +[rust-log]: https://rust-lang-nursery.github.io/rust-cookbook/development_tools/debugging/config_log.html diff --git a/docs/src/contributing.md b/docs/src/contributing.md new file mode 100644 index 0000000..841a1b3 --- /dev/null +++ b/docs/src/contributing.md @@ -0,0 +1,103 @@ +# Contributing + +Pull requests, comments, and issue submissions are actively encouraged! + +## Repo structure + +`mdbook-utils` is written in [Rust][rust-lang] and follows the typical [cargo package layout][cargo-layout]. + +- The source code is in the `src` folder. The main executable is in `main.rs` and the `cli` module. It calls the API in `lib.rs`. +- A simple test `mdbook` book is found in `test_book`. +- The user guide' sources are in `docs`. +- The Dev Container and Docker (Compose) configuration files are found in `.devcontainer`. + - `devcontainer.json` uses Docker Compose (configured in `compose.yaml` and `compose.override.yaml`), which in turn runs a container from `Dockerfile`. +- `.github` contains the continuous integration (GitHub Actions) workflow. + +## Development Setup + +### Using VS Code + +Clone the repo and open the folder in [VS Code][vs-code]. Edit `.devcontainer/.env` if needed. VS Code should prompt you to open the code in a Docker container, which installs Rust tooling automatically. Make sure you have previously installed the following: + +- [Dev Container extension][dev-container-extension] +- [Docker Desktop][docker-desktop] (or at least the Docker engine). + +Note that opening the code folder in VS Code using Dev Containers may take a little while the first time around. + +### Other + +If you are not using VS Code, install the [Dev Container CLI][dev-container-CLI], use `docker compose` directly (see below), or simply install the required tools on your local machine. + +The following works with Ubuntu and WSL: + +```bash +sudo apt-get update +rustup update +rustup component add clippy + +rustup toolchain install nightly +rustup component add rustfmt --toolchain nightly +cargo install just +# Optional +cargo install mdbook +``` + +Review `.devcontainer/Dockerfile` for other optional dependencies. + +## Build and test the code + +The [`just`][just] command runner is configured to simplify compilation and testing. + +Type `just` at a shell prompt for a list of commands: + +```sh +just clean # Clean Cargo's `target` and mdbook's `book` folders + +just fmt # Format all code + +just check # Check whether the code can compile + +just build # Build all code and books + +just clippy # Scan all code for common mistakes + +just test # Test all code and books + +just run # Run the tool + +just doc # Build and display the `cargo doc` documentation + +just serve # Display the user guide + +just prep # Run all the steps required before pushing code to GitHub + +just update # Update Cargo.lock dependencies +``` + +## Docker Compose + +Test the `Docker Compose` setup used during developement (which `Dev Containers` runs) with: + +```bash +cd ./.devcontainer +docker compose build # uses compose.yaml and compose.override.yaml by default +docker compose up -d +# or simply +docker compose up --build -d +``` + +## Publish to crates.io + +- Go to `crates.io`, sign in, and create an API token in `Account Settings` > `API Tokens`. +- Use `cargo login` to save the token in `$CARGO_HOME/credentials.toml`. +- `just build; just clippy; just run; just doc; cargo package` +- Review the packaging output in `/cargo-target-mdbook-utils/target/package`. +- When ready, `cargo publish --dry-run; cargo publish` + +[cargo-layout]: https://doc.rust-lang.org/cargo/guide/project-layout.html +[dev-container-CLI]: https://github.com/devcontainers/cli +[dev-container-extension]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers +[docker-desktop]: https://www.docker.com/products/docker-desktop/ +[just]: https://just.systems/ +[rust-lang]: https://www.rust-lang.org/ +[vs-code]: https://code.visualstudio.com/ diff --git a/docs/src/definitions.md b/docs/src/definitions.md new file mode 100644 index 0000000..c33ecaa --- /dev/null +++ b/docs/src/definitions.md @@ -0,0 +1,39 @@ +# Definitions + +[`mdbook`](https://rust-lang.github.io/mdBook/) is a command-line tool to create books with [Markdown][markdown]. It is commonly used for Rust user guides, such as the [Rust book](https://doc.rust-lang.org/book/) and the [Rust How-to](https://www.john-cd.com/rust_howto/) book. + +[_Markdown_][markdown] is a lightweight, readable markup language for writing structured documents. + +A Markdown _link_ can be an _autolink_, e.g. ``, an _inline link_ like `[Example](https://example.com)`, or a _reference-style link_: `[The user will see this][thisisthelabel]`. + +A reference-style link requires a _reference definition_ with a matching _label_: + +~~~markdown +thisisthelabel: https://example.com/ +~~~ + +_Images_ can be inserted using `![Image alternative text](link/to/image.png)` or, reference-style, `![Image][1]` followed by a _reference definition_ `[1]: `. + +More details may be found in the [CommonMark](https://commonmark.org/) documentation. + +A status _badge_ is a small image that provides at-a-glance information, for example the build status of a code repository. Badges are commonly displayed on GitHub READMEs and inserted in `mdbook` documentation as links to a crate's [docs.rs](https://docs.rs/) documentation, GitHub repo, or [crates.io](https://crates.io/) page. More information about badges may be found in the [awesome-badges](https://github.com/badges/awesome-badges) repo and in the [shields.io](https://shields.io/) documentation. + +There is no "badge" concept in the Markdown specification. Badges are simply clickable images e.g. `[ ![image-alt-text](link-to-image) ](link-to-webpage)`. + +Markdown _fenced code blocks_ (we will call them _code examples_ as well) are inserted between two _code fences_ (e.g. sets of triple backticks), with an optional _info string_ (a.k.a. _attributes_ ) after the first backtick group: + +~~~markdown +```rust +fn main() {} +``` +~~~ + +`mdbook` allows [including files](https://rust-lang.github.io/mdBook/format/mdbook.html#including-files) into your book via an _include statement_ written as `{{#include file.md}}`. `mdbook` interprets included files as Markdown. Since the include syntax is usually used for inserting code snippets and examples, it is often wrapped with ``` + +~~~markdown +```rust +{{#include file.rs}} +``` +~~~ + +[markdown]: https://en.wikipedia.org/wiki/Markdown diff --git a/docs/src/installation.md b/docs/src/installation.md new file mode 100644 index 0000000..720473c --- /dev/null +++ b/docs/src/installation.md @@ -0,0 +1,21 @@ +# Installation + +Install the command-line tool using [`cargo`](https://doc.rust-lang.org/cargo/index.html): + +```bash +cargo install mdbook-utils +``` + +then invoke `mdbook-utils` at a shell prompt. + +For the bleeding edge development version, use: + +```bash +cargo install --git https://github.com/john-cd/mdbook-utils +``` + +To uninstall the tool, enter the following in a shell: + +```bash +cargo uninstall mdbook-utils +``` diff --git a/docs/src/introduction.md b/docs/src/introduction.md new file mode 100644 index 0000000..0dd8c71 --- /dev/null +++ b/docs/src/introduction.md @@ -0,0 +1,26 @@ +# Introduction + +## What is `mdbook-utils` for? + +The `mdbook-utils` command-line tool manages _links_, _reference definitions_, and _code blocks_ in large collections of Markdown files, especially [mdbook](https://rust-lang.github.io/mdBook/) source directories. It is the companion tool for the ["Rust How-to"](https://www.john-cd.com/rust_howto/) book ([github](https://github.com/john-cd/rust_howto)). + +`mdbook-utils` is useful for the following: + +- centralize all reference definitions in one file to make Markdown files more readable and ease link maintenance, +- replace simple Markdown links by badges, +- identify duplicate or broken links, +- generate a sitemap file for your book or website, +- extract fenced code bocks embedded into the Markdown to separate files for easier formatting, debugging and testing, +- replace code examples by `{{#include ... }}` statements, +- conversely replace includes by the file contents. + +`mdbook-utils`' underlying library also exposes a [public API](https://docs.rs/mdbook-utils/latest/mdbook_utils/) that may be used from your code. + +## Key Links + +`mdbook-utils` [(GitHub repo)][mdbook-utils-github] [(docs.rs)][mdbook-utils-docs-rs] [(crates.io)][mdbook-utils-crates-io] [(user guide - this book)][mdbook-utils-user-guide] + +[mdbook-utils-github]: https://github.com/john-cd/mdbook-utils +[mdbook-utils-docs-rs]: https://docs.rs/mdbook-utils/latest/mdbook_utils/ +[mdbook-utils-crates-io]: https://crates.io/crates/mdbook-utils +[mdbook-utils-user-guide]: https://john-cd.github.io/mdbook-utils diff --git a/docs/src/public_api.md b/docs/src/public_api.md new file mode 100644 index 0000000..29a249d --- /dev/null +++ b/docs/src/public_api.md @@ -0,0 +1,11 @@ +# Public API + +To use the library in your code, add the crate to your `Cargo.toml` as usual: + +```bash +cargo add mdbook-utils +``` + +and peruse its [documentation](https://docs.rs/mdbook-utils/latest/mdbook_utils/). + +Note that `cargo` changes the dash into an underscore, thus insert `use mdbook_utils::*;` or similar into your code. diff --git a/docs/src/usage.md b/docs/src/usage.md new file mode 100644 index 0000000..b338c5a --- /dev/null +++ b/docs/src/usage.md @@ -0,0 +1,104 @@ +# Usage + +Run the tool without arguments to display the the list of commands: + +```txt +Tools to manage links, reference definitions, and code examples in Markdown files, especially `mdbook` source directories. + +Usage: mdbook-utils [OPTIONS] + +Commands: + refdefs Manage reference definitions + links Manage links + markdown Manage code blocks (embedded examples) and includes + sitemap Generate a sitemap.xml file from the list of Markdown files in a source directory + debug Parse the entire Markdown code as events and write them to a file + help Print this message or the help of the given subcommand(s) + +Options: + -y, --yes Automatically answer `yes` to any user confirmation request + -h, --help Print help + -V, --version Print version +``` + +In turn, most commands offer a menu of subcommands. + +## Reference Definitions + +`mdbook-utils refdefs` offers the following subcommands: + +```txt +Manage reference definitions + +Usage: mdbook-utils refdefs [OPTIONS] + +Commands: + write Write existing reference definitions to a file + badges Generate badges (reference definitions) for e.g. Github links + help Print this message or the help of the given subcommand(s) + +Options: + -y, --yes Automatically answer `yes` to any user confirmation request + -h, --help Print help +``` + +## Links + +`mdbook-utils links` currently offers two main subcommands: + +```txt +Manage links + +Usage: mdbook-utils links [OPTIONS] + +Commands: + write-all Write all existing links to a Markdown file + write-inline Write all existing inline / autolinks (i.e., not written as reference-style links) to a Markdown file + help Print this message or the help of the given subcommand(s) + +Options: + -y, --yes Automatically answer `yes` to any user confirmation request + -h, --help Print help +``` + +## Markdown + +`mdbook-utils markdown` deals with fenced code blocks and includes: + +```txt +Manage code blocks (embedded examples) and includes + +Usage: mdbook-utils markdown [OPTIONS] + +Commands: + extract-code-examples Copy Rust code examples from the Markdown into .rs files + replace-code-examples-by-includes Replace Rust code examples from the Markdown by {{#include ...}} statements + replace-includes-by-contents Replace {{#include file.md}} by the file contents + remove-includes Remove {{#include }} statements (and replace them by a hard-coded string) + help Print this message or the help of the given subcommand(s) + +Options: + -y, --yes Automatically answer `yes` to any user confirmation request + -h, --help Print help +``` + +`mdbook-utils sitemap` and `mdbook-utils debug` do not have subcommands. + +## Command-line options + +Command-line options vary by subcommand and include `-o` to set the path of the output file; `-m` to set the path of the source Markdown directory (`./src` or `./drafts` by default, depending on the subcommand); `-c` to set the path to the directory containing the `Cargo.toml` that declares the dependencies (Rust crates) used in your book; and `-t` to set the path to the destination directory. `-y` is a global option that skips confirmation dialogs and is useful when calling `mdbook-utils` from a script. + +Use `mdbook-utils --help` or `help ` for more details. The following illustrates options for `mdbook-utils sitemap`: + +```txt +Generate a sitemap.xml file from the list of Markdown files in a source directory + +Usage: mdbook-utils sitemap [OPTIONS] + +Options: + -m, --markdown-dir Source directory containing the source Markdown files + -b, --base-url + -o, --output Path of the file to create + -y, --yes Automatically answer `yes` to any user confirmation request + -h, --help Print help +``` diff --git a/justfile b/justfile index 5bbae7a..f7e04c2 100644 --- a/justfile +++ b/justfile @@ -4,6 +4,7 @@ alias c := clippy alias t := test alias r := run alias d := doc +alias s := serve alias p := prep set windows-shell := ["cmd.exe", "/c"] @@ -12,22 +13,26 @@ default: @just --list --unsorted # or: @just --choose -# Clean Cargo's `target` +# Clean Cargo's `target` and mdbook's `book` folders clean: cargo clean + mdbook clean ./docs/ + mdbook clean ./test_book/ # Format all code fmt: cargo +nightly fmt --all -# Check all code +# Check whether the code can compile check: cargo check --all-targets --locked # `--all-targets`` is equivalent to specifying `--lib --bins --tests --benches --examples`. -# Build all code +# Build all code and books build: cargo build --all-targets --locked + mdbook build ./docs/ + mdbook build ./test_book/ # `--all-targets`` is equivalent to specifying `--lib --bins --tests --benches --examples`. # optional: --timings @@ -35,15 +40,17 @@ build: clippy: cargo clippy --all-targets --locked -# Test all code +# Test all code and books test: cargo test --all-targets --locked + mdbook test ./docs/ + mdbook test ./test_book/ # `--all-targets`` is equivalent to specifying `--lib --bins --tests --benches --examples`. help := 'help' empty := '' -# Run +# Run the tool run cmd=help subcmd=empty: cargo run --locked -- {{cmd}} {{subcmd}} @@ -54,7 +61,11 @@ doc: cargo doc --no-deps --locked --document-private-items cd /cargo-target-mdbook-utils/target/doc/ ; python3 -m http.server 9000 -# Prepare for git push +# Display the user guide +serve: + mdbook serve ./docs/ + +# Run all the steps required before pushing code to GitHub prep: fmt clean build clippy test doc ## Utilities -------------------------------------- diff --git a/test_book/drafts/example.md b/test_book/drafts/example.md index b19833c..9d695aa 100644 --- a/test_book/drafts/example.md +++ b/test_book/drafts/example.md @@ -15,3 +15,5 @@ Links: [ref]: https://reference-definition/ + +{{#include ./example2.md}} diff --git a/test_book/drafts/example2.md b/test_book/drafts/example2.md new file mode 100644 index 0000000..2de741e --- /dev/null +++ b/test_book/drafts/example2.md @@ -0,0 +1 @@ +I am included! diff --git a/test_book/src/chapter_1.md b/test_book/src/chapter_1.md index ab9b23e..30e4b16 100644 --- a/test_book/src/chapter_1.md +++ b/test_book/src/chapter_1.md @@ -9,7 +9,7 @@ fn main() {} {{#include ./included.md}} ```rust,ignore -{{#include ./wont-be-included-refs.rs}} +{{#include ./wont-be-included-refs.md}} ``` Links: diff --git a/test_book/src/wont-be-included-refs.md b/test_book/src/wont-be-included-refs.md new file mode 100644 index 0000000..fb86aab --- /dev/null +++ b/test_book/src/wont-be-included-refs.md @@ -0,0 +1,3 @@ +# Nope + +I will not be included!