diff options
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | src/lib.rs | 38 | ||||
-rw-r--r-- | tests/files/README_01.md | 39 | ||||
-rw-r--r-- | tests/files/README_04_code_block_issues.md | 14 |
4 files changed, 65 insertions, 39 deletions
@@ -1,5 +1,5 @@ # `mktoc` -> Blazingly fast Markdown Table of Content generator +> Markdown Table of Content generator ![](https://github.com/kevingimbel/mktoc/workflows/Clippy%20check/badge.svg) @@ -9,6 +9,7 @@ - [Cargo](#cargo) - [Binary](#binary) - [Usage](#usage) + - [Update Markdown file](#update-markdown-file) - [Performance](#performance) - [License](#license) <!-- END mktoc --> @@ -33,6 +34,16 @@ Binaries are actually not available yet. If you know how releasing binaries with ## Usage +### Update Markdown file + +Add the following HTML comment into the Markdown file where the Table of Contents should be rendered. +``` +<!-- BEGIN mktoc --> +<!-- END mktoc --> +``` + +Everything between those comments will be replaced! + Specify `--write` to overwrite the given file, otherwise the modified content is written to stdout. ``` @@ -1,18 +1,6 @@ use std::fs::File; use std::io::prelude::*; -use structopt::StructOpt; - -#[derive(StructOpt, Debug)] -#[structopt(name = "mktoc")] -struct Cli { - #[structopt()] - file: String, - - #[structopt(long, short)] - write: bool, -} - const COMMENT_BEGIN: &str = "<!-- BEGIN mktoc -->"; const COMMENT_END: &str = "<!-- END mktoc -->"; @@ -24,10 +12,25 @@ fn read_file(file_path: String) -> Result<String, ::std::io::Error> { Ok(contents) } + +fn text_to_url(text: &str) -> String { + text.trim() + .replace(" ", "-") + .replace("(", "") + .replace(")", "") + .replace("`", "") + .replace("'", "") + .replace("\"", "") + .replace("[", "") + .replace("]", "") + .replace("{", "") + .replace("}", "") + .to_ascii_lowercase() +} + /// parses a string and extracts all headlines to build a table of contents /// -/// Uses basic regex "((#{1,6}\s))((.*))" to parse headings. Right now this produces errors because it also matches -/// comments in code blocks and if the headline contains images those will be matched, too. +/// Uses a basic regex "((#{1,6}\s))((.*))" to parse headings out of the pub fn generate_toc(original_content: String, min_depth: i32, max_depth: i32) -> String { let mut already_found_code_open = false; let mut code_block_found = false; @@ -35,7 +38,8 @@ pub fn generate_toc(original_content: String, min_depth: i32, max_depth: i32) -> let re = regex::Regex::new(r"((#{1,6}\s))((.*))").unwrap(); for line in original_content.lines() { - if line.starts_with("```") { + let line_s: String = line.chars().take(3).collect(); + if line_s == "```".to_owned() { code_block_found = true; } @@ -51,9 +55,8 @@ pub fn generate_toc(original_content: String, min_depth: i32, max_depth: i32) -> continue; } - let text = caps.get(3).unwrap().as_str(); - let link = text.replace(" ", "-").to_ascii_lowercase(); + let link = text_to_url(text); let spaces = match level { 3 => String::from(" "), 4 => String::from(" "), @@ -61,6 +64,7 @@ pub fn generate_toc(original_content: String, min_depth: i32, max_depth: i32) -> 6 => String::from(" "), _ => String::from(""), }; + new_toc = format!( "{old}\n{spaces}- [{text}](#{link})", old = new_toc.as_str(), diff --git a/tests/files/README_01.md b/tests/files/README_01.md index 66e5030..4af232a 100644 --- a/tests/files/README_01.md +++ b/tests/files/README_01.md @@ -1,26 +1,25 @@ This README.md is taken from [https://github.com/cloudposse/terraform-aws-route53-alias/blob/master/README.md](https://github.com/cloudposse/terraform-aws-route53-alias/blob/master/README.md) as part of the complex README parsing test. <!-- BEGIN mktoc --> -- [terraform-aws-route53-alias [![Codefresh Build Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-route53-alias?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d119fda4bb3780bc79a6395) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-route53-alias.svg)](https://github.com/cloudposse/terraform-aws-route53-alias/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)](#terraform-aws-route53-alias-[![Codefresh-Build-Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-route53-alias?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d119fda4bb3780bc79a6395)-[![Latest-Release](https://img.shields.io/github/release/cloudposse/terraform-aws-route53-alias.svg)](https://github.com/cloudposse/terraform-aws-route53-alias/releases/latest)-[![Slack-Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)) -- [Usage](#Usage) -- [Makefile Targets](#Makefile-Targets) -- [Inputs](#Inputs) -- [Outputs](#Outputs) -- [Share the Love ](#Share-the-Love-) -- [Related Projects](#Related-Projects) -- [Help](#Help) -- [Commercial Support](#Commercial-Support) -- [Terraform Module Development](#Terraform-Module-Development) -- [Slack Community](#Slack-Community) -- [Newsletter](#Newsletter) -- [Contributing](#Contributing) - - [Bug Reports & Feature Requests](#Bug-Reports-&-Feature-Requests) - - [Developing](#Developing) -- [Copyright](#Copyright) -- [License ](#License-) -- [Trademarks](#Trademarks) -- [About](#About) - - [Contributors](#Contributors) +- [terraform-aws-route53-alias [![Codefresh Build Status](https://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2Fterraform-aws-route53-alias?type=cf-1)](https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d119fda4bb3780bc79a6395) [![Latest Release](https://img.shields.io/github/release/cloudposse/terraform-aws-route53-alias.svg)](https://github.com/cloudposse/terraform-aws-route53-alias/releases/latest) [![Slack Community](https://slack.cloudposse.com/badge.svg)](https://slack.cloudposse.com)](#terraform-aws-route53-alias-!codefresh-build-statushttps://g.codefresh.io/api/badges/pipeline/cloudposse/terraform-modules%2fterraform-aws-route53-alias?type=cf-1https://g.codefresh.io/public/accounts/cloudposse/pipelines/5d119fda4bb3780bc79a6395-!latest-releasehttps://img.shields.io/github/release/cloudposse/terraform-aws-route53-alias.svghttps://github.com/cloudposse/terraform-aws-route53-alias/releases/latest-!slack-communityhttps://slack.cloudposse.com/badge.svghttps://slack.cloudposse.com) +- [Usage](#usage) +- [Makefile Targets](#makefile-targets) +- [Outputs](#outputs) +- [Share the Love ](#share-the-love) +- [Related Projects](#related-projects) +- [Help](#help) +- [Commercial Support](#commercial-support) +- [Terraform Module Development](#terraform-module-development) +- [Slack Community](#slack-community) +- [Newsletter](#newsletter) +- [Contributing](#contributing) + - [Bug Reports & Feature Requests](#bug-reports-&-feature-requests) + - [Developing](#developing) +- [Copyright](#copyright) +- [License ](#license) +- [Trademarks](#trademarks) +- [About](#about) + - [Contributors](#contributors) <!-- END mktoc --> <!-- START doctoc generated TOC please keep comment here to allow auto update --> diff --git a/tests/files/README_04_code_block_issues.md b/tests/files/README_04_code_block_issues.md index c327a37..8e14f98 100644 --- a/tests/files/README_04_code_block_issues.md +++ b/tests/files/README_04_code_block_issues.md @@ -1,9 +1,15 @@ # Test file <!-- BEGIN mktoc --> +- [Test file](#test-file) - [Test for issue #1](#test-for-issue-#1) - [Test Heading 3](#test-heading-3) - [Test Heading 4](#test-heading-4) + - [Test Heading 5](#test-heading-5) + - [Test Heading 6](#test-heading-6) +- [Test `code` in Header](#test-code-in-header) +- [Test (special chars)](#test-special-chars) + - [Test [1]](#test-1) <!-- END mktoc --> ## Test for issue #1 @@ -21,4 +27,10 @@ function test(A,B) { ##### Test Heading 5 -###### Test Heading 6
\ No newline at end of file +###### Test Heading 6 + +## Test `code` in Header + +## Test (special chars) + +### Test [1]
\ No newline at end of file |