`md-inc` - Include files in Markdown docs ========================= ## Overview ![Preview](doc/md-inc.gif) * Include external files into your markdown documents - inline! * Input is inserted between command block and end block * Overwrites anything that was previously there * Transform included files * Wrap your input in code blocks or custom text * Filter specific lines * Add line numbers or other line decorators * Easily configure with `.md-inc.toml` file. * Specify 1 or more files to transform. * Specify base path used for relative file includes. * Replace `` tags - useful if you need to avoid conflicts or existing comments. ## Example Here is a code file, `file.rs`, that we want to include in our Markdown document: ```rust fn main() { println!("Hello, World!"); } ``` The file can be included using command tags, sneakily disguised as comments so they aren't rendered in the actual document: ```markdown Look at the following rust code: This will print 'Hello World' to the console. ``` After running `md-inc`, the file will be transformed into: ````markdown Look at the following rust code: ```rust fn main() { println!("Hello, World!"); } ``` This will print 'Hello World' to the console. ```` Note: The surrounding ` ```rust ` and ` ``` ` lines were inserted because we piped the input into the `code: rust` command. More on this later! ## Install ```bash cargo install md-inc ``` ## Run ```bash md-inc [FLAGS] [OPTIONS] [files]... ``` If no files are given, the `files` field in `.md-inc.toml` is used. ## Configuration `.md-inc.toml` can be configured by setting any of the following: `open_tag`: The opening tag for a command ```toml # # ^^^^^ open_tag = " # ^^^^ close_tag = "}-->" ``` `end_command`: The name to use for the end command ```toml # # <> # # ^^^ end_command = "end" ``` `base_dir`: The base directory for relative imported file paths, relative to the config file ```toml # For the directory tree: # ├╼ README.md # ├╼ .md-inc.toml # ╰╼ doc # ├╼ file.txt # ╰╼ other # ╰╼ file2.txt # If base_dir = "doc", then files can be named relative to doc # # ... # base_dir = "doc" ``` `files`: A list of files to be transformed, relative to the config file ```toml files = ["README.md", "doc/file.md"] ``` `depend_dirs`: A list of directories containing ".md-inc.toml" that will be visited before this one. ```toml depend_dirs = ["doc/example1", "doc/example2"] ``` `next_dirs`: A list of directories containing ".md-inc.toml" that will be visited after this one. ```toml next_dirs = ["doc/example1", "doc/example2"] ``` *Note*: "depend_dirs" and "next_dirs" are NOT called recursively. `out_dir`: An optional output directory for generated files. If this is defined, the generated files will be written to this directory instead of overwriting the original files. ```toml out_dir = "path/to/output" ``` ## Commands Included files can be manipulated by piping commands together. * [General Syntax](#general-syntax) * [Code Blocks](#code-language) * [Lines Range](#lines-first-last) * [After](#trim-leading-lines) * [Before](#trim-trailing-lines) * [Between](#trim-both-leading-and-trailing-lines) * [Line List](#line-list) * [Line Numbers](#line-numbers-separator) * [Wrap Document](#wrap-text-or-wrap-before-after) * [Wrap Lines](#wrap-lines-text-or-wrap-lines-before-after) ### General Syntax: Include `file.txt`: ```markdown ``` Include `file.txt` inside a code block: ```markdown ``` Include `file.py` inside a code block with python syntax highlighting: ```markdown ``` Include only lines 4 to 10 of `file.py` inside a code block with python syntax highlighting: ```markdown ``` * The first value should always be the filename. * Commands can be chained together using the pipe (`|`) operator. `"file.txt" | code` * Some commands may take space-separated arguments after a colon (`:`) character. `"file.txt | lines: 4 10` * Commands are applied to the included file from left to right. ### `code: [language]` * Wraps the file in a code block (triple backticks) * `language`: the language used for syntax highlighting. If given, this will be added directly after the top backticks. Without language: ````markdown ``` FILE_CONTENTS ``` ```` With language: ````markdown ```html FILE_CONTENTS ``` ```` ### `lines: first [last]` * Restricts the input to the given range of lines * (include line, if `first <= line <= last`) * `first`: The first line to import * `last`: The last line to import (1-based index) * If `last` is not provided, all lines will be included from `first` until the end of the input. Given the file, *alphabet.txt*: ```txt A B C D E ``` #### Trim leading lines *Input:* ````markdown ```` This keeps the 4th line until the end of the file. *Output:* ````markdown D E ```` #### Trim trailing lines *Input:* ````markdown ```` This keeps only lines 1 to 3 *Output:* ````markdown A B C ```` #### Trim both leading and trailing lines *Input:* ````markdown ```` This keeps only lines 2 to 4 *Output:* ````markdown B C D ```` ### `line: list...` * Restricts the input to the given list of line numbers (1-based index). * `list...`: A list of line numbers to included *Input:* ````markdown ```` *Output:* ````markdown C B A ```` ### `line-numbers: [separator] [width]` * Adds a line number to each line * `[separator]`: Optional separator used between the line number and the rest of the line. * If not provided, `: ` is used. * `[width]`: Optional width for line numbers. * If not provided, the width of the longest line number is used. **With Default Arguments:** *Input:* ````markdown ```` *Output:* ````markdown 8: H 9: I 10: J 11: K 12: L 13: M 14: N ```` **With Provided Arguments:** *Input:* ````markdown ```` *Output:* ````markdown 1 A 2 B 3 C 4 D 5 E ```` ### `wrap: text` or `wrap: before after` * Inserts text before and after the input. * `text`: Text that is inserted before and after the input (no newline) * `before`: Text that is inserted before the input (no newline). * `after`: Text that is inserted after the input (no newline). ### `wrap-lines: text` or `wrap-lines: before after` * Inserts text before and after each line of the input. * `text`: Text that is inserted before and after each line of the input. * `before`: Text that is inserted before each line of the input. * `after`: Text that is inserted after each line of the input. ### `match: pattern [group_num]` * Inserts text from a file that matches the pattern. * `pattern`: A regex pattern * `group_num`: The capture group matching `group_num` is inserted. * A group_num of `0` is the whole regex pattern For a file, `hello_world.rs`: ```rust // Main fn main() { println!("Hello, World!"); } // Goodbye fn goodbye() { println!("Goodbye, World!"); } ``` The `main()` function can be extracted using the `match` command: *Input:* ````markdown ```` *Output:* ````markdown ```rust fn main() { println!("Hello, World!"); } ``` ````