gitlab-glfm-markdown 0.0.24-x86_64-linux-musl
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Cargo.lock +1100 -0
- data/LICENSE +28 -0
- data/README.md +109 -0
- data/ext/glfm_markdown/Cargo.toml +23 -0
- data/ext/glfm_markdown/extconf.rb +8 -0
- data/ext/glfm_markdown/src/glfm.rs +93 -0
- data/ext/glfm_markdown/src/lib.rs +69 -0
- data/ext/glfm_markdown/src/main.rs +227 -0
- data/lib/glfm_markdown/3.1/glfm_markdown.so +0 -0
- data/lib/glfm_markdown/3.2/glfm_markdown.so +0 -0
- data/lib/glfm_markdown/3.3/glfm_markdown.so +0 -0
- data/lib/glfm_markdown/3.4/glfm_markdown.so +0 -0
- data/lib/glfm_markdown/loader.rb +8 -0
- data/lib/glfm_markdown/version.rb +5 -0
- data/lib/glfm_markdown.rb +47 -0
- metadata +120 -0
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Copyright (c) 2011-present GitLab B.V.
|
2
|
+
|
3
|
+
Portions of this software are licensed as follows:
|
4
|
+
|
5
|
+
* All content residing under the "doc/" directory of this repository is licensed under "Creative Commons: CC BY-SA 4.0 license".
|
6
|
+
* All content that resides under the "ee/" directory of this repository, if that directory exists, is licensed under the license defined in "ee/LICENSE".
|
7
|
+
* All content that resides under the "jh/" directory of this repository, if that directory exists, is licensed under the license defined in "jh/LICENSE".
|
8
|
+
* All client-side JavaScript (when served directly or after being compiled, arranged, augmented, or combined), is licensed under the "MIT Expat" license.
|
9
|
+
* All third party components incorporated into the GitLab Software are licensed under the original license provided by the owner of the applicable component.
|
10
|
+
* Content outside of the above mentioned directories or restrictions above is available under the "MIT Expat" license as defined below.
|
11
|
+
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
14
|
+
in the Software without restriction, including without limitation the rights
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
17
|
+
furnished to do so, subject to the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
20
|
+
copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# GitLab Flavored Markdown
|
2
|
+
|
3
|
+
[![Pipeline status](https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown/-/commits/main)
|
4
|
+
[![Latest Release](https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown/-/badges/release.svg)](https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown/-/releases)
|
5
|
+
|
6
|
+
Implements GLFM (as used by GitLab) using the Rust-based markdown parser [comrak](https://github.com/kivikakk/comrak)
|
7
|
+
and providing a Ruby interface.\
|
8
|
+
_Currently using `comrak 0.31.0`_.
|
9
|
+
|
10
|
+
This project is still in constant flux, so interfaces and functionality can change at any time.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Install the gem and add to the application's Gemfile by executing:
|
15
|
+
|
16
|
+
$ bundle add gitlab-glfm-markdown
|
17
|
+
|
18
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
19
|
+
|
20
|
+
$ gem install gitlab-glfm-markdown
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Try on command line:
|
25
|
+
|
26
|
+
```
|
27
|
+
rake compile
|
28
|
+
bin/console
|
29
|
+
|
30
|
+
GLFMMarkdown.to_html('# header', options: { sourcepos: true })
|
31
|
+
```
|
32
|
+
|
33
|
+
### Options
|
34
|
+
|
35
|
+
| Option name | Description |
|
36
|
+
|---------------------------------|---------------------------------------------------------------------------------------|
|
37
|
+
| `autolink` | Enable the `autolink` extension |
|
38
|
+
| `description_lists` | Enable the `description-lists` extension |
|
39
|
+
| `escape` | Escape raw HTML instead of clobbering it |
|
40
|
+
| `escape_char_spans` | Wrap escaped characters in a `<span>` to allow any post-processing to recognize them |
|
41
|
+
| `figure_with_caption` | Render the image as a figure element with the title as its caption |
|
42
|
+
| `footnotes` | Enable the `footnotes` extension |
|
43
|
+
| `full_info_string` | Enable full info strings for code blocks |
|
44
|
+
| `gemojis` | Enable the `gemojis` extensions - translate gemojis into UTF-8 characters |
|
45
|
+
| `gfm_quirks` | Enables GFM-style quirks in output HTML, such as not nesting <strong> tags |
|
46
|
+
| `github_pre_lang` | Use GitHub-style `<pre lang>` for code blocks |
|
47
|
+
| `greentext` | Enable the `greentext` extension - requires at least one space after a `>` character to generate a blockquote, and restarts blockquote nesting across unique lines of input |
|
48
|
+
| `hardbreaks` | Treat newlines as hard line breaks |
|
49
|
+
| `header_ids <PREFIX>` | Enable the `header-id` extension, with the given ID prefix |
|
50
|
+
| `ignore_empty_links` | Ignore empty links in input |
|
51
|
+
| `ignore_setext` | Ignore setext headings in input |
|
52
|
+
| `math_code` | Enables `math code` extension, using math code syntax |
|
53
|
+
| `math_dollars` | Enables `math dollars` extension, using math dollar syntax |
|
54
|
+
| `multiline_block_quotes` | Enable the `multiline-block-quotes` extension |
|
55
|
+
| `relaxed_autolinks` | Enable relaxing of autolink parsing, allowing links to be recognized when in brackets |
|
56
|
+
| `relaxed_tasklist_character` | Enable relaxing which character is allowed in tasklists |
|
57
|
+
| `sourcepos` | Include source mappings in HTML attributes |
|
58
|
+
| `experimental_inline_sourcepos` | Include inline sourcepos in HTML output, which is known to have issues |
|
59
|
+
| `smart` | Use smart punctuation |
|
60
|
+
| `spoiler` | Enable the `spoiler` extension - use double vertical bars |
|
61
|
+
| `strikethrough` | Enable the `strikethrough` extension |
|
62
|
+
| `superscript` | Enable the `superscript` extension |
|
63
|
+
| `table` | Enable the `table` extension |
|
64
|
+
| `tagfilter` | Enable the `tagfilter` extension |
|
65
|
+
| `tasklist` | Enable the `tasklist` extension |
|
66
|
+
| `underline` | Enables the `underline` extension - use double underscores |
|
67
|
+
| `unsafe` | Allow raw HTML and dangerous URLs |
|
68
|
+
| `wikilinks_title_after_pipe` | Enable the `wikilinks_title_after_pipe` extension |
|
69
|
+
| `wikilinks_title_before_pipe` | Enable the `wikilinks_title_before_pipe` extension |
|
70
|
+
| `debug` | Show debug information |
|
71
|
+
|
72
|
+
## Dingus / Demo
|
73
|
+
|
74
|
+
A demo is running via GitLab Pages, and can be accessed at:
|
75
|
+
|
76
|
+
https://gitlab-org.gitlab.io/ruby/gems/gitlab-glfm-markdown
|
77
|
+
|
78
|
+
## Development
|
79
|
+
|
80
|
+
A command line executable can be built for debugging.
|
81
|
+
|
82
|
+
```
|
83
|
+
cargo run --bin glfm_markdown --features="cli" -- --help
|
84
|
+
cargo run --bin glfm_markdown --features="cli" -- --sourcepos
|
85
|
+
```
|
86
|
+
|
87
|
+
There is a VSCode workspace that allows you to `Debug executable`
|
88
|
+
|
89
|
+
When developing another project locally and using `gitlab-glfm-markdown` by linking
|
90
|
+
directly to the gem's source directory, make sure that you're using the same version
|
91
|
+
of Ruby for the project and the gem. Otherwise you can see unexplained errors when
|
92
|
+
calling into the gem.
|
93
|
+
|
94
|
+
NOTE: This project generates a changelog automatically that gets attached to the release entry.
|
95
|
+
The normal [GitLab changelog entry process](https://docs.gitlab.com/ee/development/changelog.html)
|
96
|
+
should be followed.
|
97
|
+
|
98
|
+
### Releasing a new version
|
99
|
+
|
100
|
+
To release a new version, create a merge request and use the `Release` template, following it's instructions.
|
101
|
+
|
102
|
+
Once merged, the new version with precompiled, native gems will automatically be
|
103
|
+
published to [RubyGems](https://rubygems.org/gems/gitlab-glfm-markdown).
|
104
|
+
|
105
|
+
## Contributing
|
106
|
+
|
107
|
+
Bug reports and merge requests are welcome on GitLab at https://gitlab.com/gitlab-org/ruby/gems/gitlab-glfm-markdown.
|
108
|
+
|
109
|
+
Please refer to [CONTRIBUTING](CONTRIBUTING.md) for more details.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
[package]
|
2
|
+
name = "glfm_markdown"
|
3
|
+
version = "0.0.24"
|
4
|
+
edition = "2021"
|
5
|
+
authors = ["digitalmoksha <bwalker@gitlab.com>"]
|
6
|
+
description = "GitLab Flavored Markdown parser and formatter. 100% CommonMark-compatible. Experimental."
|
7
|
+
publish = false
|
8
|
+
|
9
|
+
[lib]
|
10
|
+
crate-type = ["cdylib"]
|
11
|
+
|
12
|
+
[[bin]]
|
13
|
+
name = "glfm_markdown"
|
14
|
+
required-features = ["cli"]
|
15
|
+
|
16
|
+
[dependencies]
|
17
|
+
clap = { version = "4.0", optional = true, features = ["derive", "string"] }
|
18
|
+
comrak = { version = "0.31.0", default-features = false, features = ["shortcodes"] }
|
19
|
+
magnus = "0.6.2"
|
20
|
+
rb-sys = { version = "0.9.86", default-features = false, features = ["stable-api-compiled-fallback"] }
|
21
|
+
|
22
|
+
[features]
|
23
|
+
cli = ["clap", "comrak/syntect"]
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#[derive(Debug)]
|
2
|
+
pub struct RenderOptions {
|
3
|
+
pub autolink: bool,
|
4
|
+
// pub default_info_string: String,
|
5
|
+
pub description_lists: bool,
|
6
|
+
pub escape: bool,
|
7
|
+
pub escaped_char_spans: bool,
|
8
|
+
pub figure_with_caption: bool,
|
9
|
+
pub footnotes: bool,
|
10
|
+
// pub front_matter_delimiter: String,
|
11
|
+
pub full_info_string: bool,
|
12
|
+
pub gemojis: bool,
|
13
|
+
pub gfm_quirks: bool,
|
14
|
+
pub github_pre_lang: bool,
|
15
|
+
pub greentext: bool,
|
16
|
+
pub hardbreaks: bool,
|
17
|
+
pub header_ids: Option<String>,
|
18
|
+
pub ignore_empty_links: bool,
|
19
|
+
pub ignore_setext: bool,
|
20
|
+
pub math_code: bool,
|
21
|
+
pub math_dollars: bool,
|
22
|
+
pub multiline_block_quotes: bool,
|
23
|
+
pub relaxed_autolinks: bool,
|
24
|
+
pub relaxed_tasklist_character: bool,
|
25
|
+
pub sourcepos: bool,
|
26
|
+
pub experimental_inline_sourcepos: bool,
|
27
|
+
pub smart: bool,
|
28
|
+
pub spoiler: bool,
|
29
|
+
pub strikethrough: bool,
|
30
|
+
pub subscript: bool,
|
31
|
+
pub superscript: bool,
|
32
|
+
// pub syntax_highlighting: String,
|
33
|
+
pub table: bool,
|
34
|
+
pub tagfilter: bool,
|
35
|
+
pub tasklist: bool,
|
36
|
+
pub underline: bool,
|
37
|
+
pub unsafe_: bool,
|
38
|
+
pub wikilinks_title_after_pipe: bool,
|
39
|
+
pub wikilinks_title_before_pipe: bool,
|
40
|
+
|
41
|
+
pub debug: bool,
|
42
|
+
}
|
43
|
+
|
44
|
+
pub fn render(text: String, options: RenderOptions) -> String {
|
45
|
+
render_comrak(text, options)
|
46
|
+
}
|
47
|
+
|
48
|
+
fn render_comrak(text: String, options: RenderOptions) -> String {
|
49
|
+
let mut comrak_options = comrak::ComrakOptions::default();
|
50
|
+
|
51
|
+
comrak_options.extension.autolink = options.autolink;
|
52
|
+
comrak_options.extension.description_lists = options.description_lists;
|
53
|
+
comrak_options.extension.footnotes = options.footnotes;
|
54
|
+
// comrak_options.extension.front_matter_delimiter = options.front_matter_delimiter;
|
55
|
+
comrak_options.extension.greentext = options.greentext;
|
56
|
+
comrak_options.extension.header_ids = options.header_ids;
|
57
|
+
comrak_options.extension.math_code = options.math_code;
|
58
|
+
comrak_options.extension.math_dollars = options.math_dollars;
|
59
|
+
comrak_options.extension.multiline_block_quotes = options.multiline_block_quotes;
|
60
|
+
comrak_options.extension.shortcodes = options.gemojis;
|
61
|
+
comrak_options.extension.spoiler = options.spoiler;
|
62
|
+
comrak_options.extension.strikethrough = options.strikethrough;
|
63
|
+
comrak_options.extension.subscript = options.subscript;
|
64
|
+
comrak_options.extension.superscript = options.superscript;
|
65
|
+
comrak_options.extension.table = options.table;
|
66
|
+
comrak_options.extension.tagfilter = options.tagfilter;
|
67
|
+
comrak_options.extension.tasklist = options.tasklist;
|
68
|
+
comrak_options.extension.underline = options.underline;
|
69
|
+
comrak_options.extension.wikilinks_title_after_pipe = options.wikilinks_title_after_pipe;
|
70
|
+
comrak_options.extension.wikilinks_title_before_pipe = options.wikilinks_title_before_pipe;
|
71
|
+
|
72
|
+
comrak_options.render.escape = options.escape;
|
73
|
+
comrak_options.render.escaped_char_spans = options.escaped_char_spans;
|
74
|
+
comrak_options.render.figure_with_caption = options.figure_with_caption;
|
75
|
+
comrak_options.render.full_info_string = options.full_info_string;
|
76
|
+
comrak_options.render.gfm_quirks = options.gfm_quirks;
|
77
|
+
comrak_options.render.github_pre_lang = options.github_pre_lang;
|
78
|
+
comrak_options.render.hardbreaks = options.hardbreaks;
|
79
|
+
comrak_options.render.ignore_empty_links = options.ignore_empty_links;
|
80
|
+
comrak_options.render.ignore_setext = options.ignore_setext;
|
81
|
+
comrak_options.render.sourcepos = options.sourcepos;
|
82
|
+
comrak_options.render.experimental_inline_sourcepos = options.experimental_inline_sourcepos;
|
83
|
+
// comrak_options.render.syntax_highlighting = options.syntax_highlighting;
|
84
|
+
|
85
|
+
comrak_options.render.unsafe_ = options.unsafe_;
|
86
|
+
|
87
|
+
// comrak_options.parse.default_info_string = options.default_info_string;
|
88
|
+
comrak_options.parse.relaxed_autolinks = options.relaxed_autolinks;
|
89
|
+
comrak_options.parse.relaxed_tasklist_matching = options.relaxed_tasklist_character;
|
90
|
+
comrak_options.parse.smart = options.smart;
|
91
|
+
|
92
|
+
comrak::markdown_to_html(&text, &comrak_options)
|
93
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
use magnus::{define_module, function, prelude::*, Error, RHash, Symbol};
|
2
|
+
|
3
|
+
mod glfm;
|
4
|
+
use glfm::{render, RenderOptions};
|
5
|
+
|
6
|
+
/// Lookup symbol in provided `RHash`. Returns `false` if the key is not present
|
7
|
+
/// or value cannot be converted to a boolean.
|
8
|
+
fn get_bool_opt(arg: &str, options: RHash) -> bool {
|
9
|
+
options.lookup(Symbol::new(arg)).unwrap_or_default()
|
10
|
+
}
|
11
|
+
|
12
|
+
fn get_string_opt(arg: &str, options: RHash) -> Option<String> {
|
13
|
+
options.lookup(Symbol::new(arg)).ok()
|
14
|
+
}
|
15
|
+
|
16
|
+
pub fn render_to_html_rs(text: String, options: RHash) -> String {
|
17
|
+
let render_options = RenderOptions {
|
18
|
+
autolink: get_bool_opt("autolink", options),
|
19
|
+
// default_info_string: get_string_opt("default_info_string", options),
|
20
|
+
description_lists: get_bool_opt("description_lists", options),
|
21
|
+
escape: get_bool_opt("escape", options),
|
22
|
+
escaped_char_spans: get_bool_opt("escaped_char_spans", options),
|
23
|
+
figure_with_caption: get_bool_opt("figure_with_caption", options),
|
24
|
+
footnotes: get_bool_opt("footnotes", options),
|
25
|
+
// front_matter_delimiter: get_string_opt("front_matter_delimiter", options),
|
26
|
+
full_info_string: get_bool_opt("full_info_string", options),
|
27
|
+
gemojis: get_bool_opt("gemojis", options),
|
28
|
+
gfm_quirks: get_bool_opt("gfm_quirks", options),
|
29
|
+
github_pre_lang: get_bool_opt("github_pre_lang", options),
|
30
|
+
greentext: get_bool_opt("greentext", options),
|
31
|
+
hardbreaks: get_bool_opt("hardbreaks", options),
|
32
|
+
header_ids: get_string_opt("header_ids", options),
|
33
|
+
ignore_empty_links: get_bool_opt("ignore_empty_links", options),
|
34
|
+
ignore_setext: get_bool_opt("ignore_setext", options),
|
35
|
+
math_code: get_bool_opt("math_code", options),
|
36
|
+
math_dollars: get_bool_opt("math_dollars", options),
|
37
|
+
multiline_block_quotes: get_bool_opt("multiline_block_quotes", options),
|
38
|
+
relaxed_autolinks: get_bool_opt("relaxed_autolinks", options),
|
39
|
+
relaxed_tasklist_character: get_bool_opt("relaxed_tasklist_character", options),
|
40
|
+
sourcepos: get_bool_opt("sourcepos", options),
|
41
|
+
experimental_inline_sourcepos: get_bool_opt("experimental_inline_sourcepos", options),
|
42
|
+
smart: get_bool_opt("smart", options),
|
43
|
+
spoiler: get_bool_opt("spoiler", options),
|
44
|
+
strikethrough: get_bool_opt("strikethrough", options),
|
45
|
+
subscript: get_bool_opt("subscript", options),
|
46
|
+
superscript: get_bool_opt("superscript", options),
|
47
|
+
// syntax_highlighting: get_string_opt("syntax_highlighting", options),
|
48
|
+
table: get_bool_opt("table", options),
|
49
|
+
tagfilter: get_bool_opt("tagfilter", options),
|
50
|
+
tasklist: get_bool_opt("tasklist", options),
|
51
|
+
underline: get_bool_opt("underline", options),
|
52
|
+
unsafe_: get_bool_opt("unsafe", options),
|
53
|
+
wikilinks_title_after_pipe: get_bool_opt("wikilinks_title_after_pipe", options),
|
54
|
+
wikilinks_title_before_pipe: get_bool_opt("wikilinks_title_before_pipe", options),
|
55
|
+
|
56
|
+
debug: get_bool_opt("debug", options),
|
57
|
+
};
|
58
|
+
|
59
|
+
render(text, render_options)
|
60
|
+
}
|
61
|
+
|
62
|
+
#[magnus::init]
|
63
|
+
fn init() -> Result<(), Error> {
|
64
|
+
let module = define_module("GLFMMarkdown")?;
|
65
|
+
|
66
|
+
module.define_singleton_method("render_to_html_rs", function!(render_to_html_rs, 2))?;
|
67
|
+
|
68
|
+
Ok(())
|
69
|
+
}
|
@@ -0,0 +1,227 @@
|
|
1
|
+
mod glfm;
|
2
|
+
use glfm::{render, RenderOptions};
|
3
|
+
use std::io::Read;
|
4
|
+
use std::io::Write;
|
5
|
+
|
6
|
+
use clap::Parser;
|
7
|
+
|
8
|
+
#[derive(Parser, Debug)]
|
9
|
+
#[command(author, version, about, long_about = None)]
|
10
|
+
struct Args {
|
11
|
+
/// CommonMark file(s) to parse; or standard input if none passed
|
12
|
+
#[arg(value_name = "FILE")]
|
13
|
+
file: Option<String>,
|
14
|
+
|
15
|
+
/// Enable 'autolink' extension
|
16
|
+
#[arg(long)]
|
17
|
+
autolink: bool,
|
18
|
+
|
19
|
+
/// Enable 'description-lists' extension
|
20
|
+
#[arg(long)]
|
21
|
+
description_lists: bool,
|
22
|
+
|
23
|
+
/// Escape raw HTML instead of clobbering it
|
24
|
+
#[arg(long)]
|
25
|
+
escape: bool,
|
26
|
+
|
27
|
+
/// Wrap escaped characters in a `<span>` to allow any post-processing to recognize them
|
28
|
+
#[arg(long)]
|
29
|
+
escaped_char_spans: bool,
|
30
|
+
|
31
|
+
/// Enable 'footnotes' extension
|
32
|
+
#[arg(long)]
|
33
|
+
footnotes: bool,
|
34
|
+
|
35
|
+
/// Ignore front-matter that starts and ends with the given string
|
36
|
+
// #[arg(long, value_name = "DELIMITER", allow_hyphen_values = true)]
|
37
|
+
// front_matter_delimiter: Option<String>,
|
38
|
+
|
39
|
+
/// Enable full info strings for code blocks
|
40
|
+
#[arg(long)]
|
41
|
+
full_info_string: bool,
|
42
|
+
|
43
|
+
/// Translate gemojis into UTF-8 characters
|
44
|
+
#[arg(long)]
|
45
|
+
gemojis: bool,
|
46
|
+
|
47
|
+
/// Enables GFM-style quirks in output HTML, such as not nesting <strong>
|
48
|
+
/// tags, which otherwise breaks CommonMark compatibility.
|
49
|
+
#[arg(long)]
|
50
|
+
gfm_quirks: bool,
|
51
|
+
|
52
|
+
/// Use GitHub-style <pre lang> for code blocks
|
53
|
+
#[arg(long)]
|
54
|
+
github_pre_lang: bool,
|
55
|
+
|
56
|
+
/// Requires at least one space after a `>` character to generate a blockquote,
|
57
|
+
/// and restarts blockquote nesting across unique lines of input
|
58
|
+
#[arg(long)]
|
59
|
+
greentext: bool,
|
60
|
+
|
61
|
+
/// Treat newlines as hard line breaks
|
62
|
+
#[arg(long)]
|
63
|
+
hardbreaks: bool,
|
64
|
+
|
65
|
+
/// Enable the 'header IDs` extension, with the given ID prefix
|
66
|
+
#[arg(long, value_name = "PREFIX")]
|
67
|
+
header_ids: Option<String>,
|
68
|
+
|
69
|
+
/// Ignore empty links in input.
|
70
|
+
#[arg(long)]
|
71
|
+
ignore_empty_links: bool,
|
72
|
+
|
73
|
+
/// Ignore setext headings in input.
|
74
|
+
#[arg(long)]
|
75
|
+
ignore_setext: bool,
|
76
|
+
|
77
|
+
/// Enables `math code` extension, using math code syntax
|
78
|
+
#[arg(long)]
|
79
|
+
math_code: bool,
|
80
|
+
|
81
|
+
/// Enables `math dollar` extension, using math dollar syntax
|
82
|
+
#[arg(long)]
|
83
|
+
math_dollars: bool,
|
84
|
+
|
85
|
+
/// Enable 'multiline block quotes' extension
|
86
|
+
#[arg(long)]
|
87
|
+
multiline_block_quotes: bool,
|
88
|
+
|
89
|
+
/// Write output to FILE instead of stdout
|
90
|
+
#[arg(short, long, value_name = "FILE")]
|
91
|
+
output: Option<String>,
|
92
|
+
|
93
|
+
/// Enable relaxing of autolink parsing, allowing links to be recognized when in brackets
|
94
|
+
#[arg(long)]
|
95
|
+
relaxed_autolinks: bool,
|
96
|
+
|
97
|
+
/// Enable relaxing which character is allowed in a tasklists
|
98
|
+
#[arg(long)]
|
99
|
+
relaxed_tasklist_character: bool,
|
100
|
+
|
101
|
+
/// Include source mappings in HTML attributes
|
102
|
+
#[arg(long)]
|
103
|
+
sourcepos: bool,
|
104
|
+
|
105
|
+
/// Include inline sourcepos in HTML output, which is known to have issues.
|
106
|
+
#[arg(long)]
|
107
|
+
experimental_inline_sourcepos: bool,
|
108
|
+
|
109
|
+
/// Use smart punctuation
|
110
|
+
#[arg(long)]
|
111
|
+
smart: bool,
|
112
|
+
|
113
|
+
/// Enables spoilers using double vertical bars
|
114
|
+
#[arg(long)]
|
115
|
+
spoiler: bool,
|
116
|
+
|
117
|
+
/// Enable 'strikethrough' extension
|
118
|
+
#[arg(long)]
|
119
|
+
strikethrough: bool,
|
120
|
+
|
121
|
+
/// Enable 'subscript' extension
|
122
|
+
#[arg(long)]
|
123
|
+
subscript: bool,
|
124
|
+
|
125
|
+
/// Enable 'superscript' extension
|
126
|
+
#[arg(long)]
|
127
|
+
superscript: bool,
|
128
|
+
|
129
|
+
/// Syntax highlighting for codefence blocks. Choose a theme or 'none' for disabling.
|
130
|
+
// #[arg(long, value_name = "THEME", default_value = "base16-ocean.dark")]
|
131
|
+
// syntax_highlighting: String,
|
132
|
+
|
133
|
+
/// Enable 'table' extension
|
134
|
+
#[arg(long)]
|
135
|
+
table: bool,
|
136
|
+
|
137
|
+
/// Enable 'tagfilter' extension
|
138
|
+
#[arg(long)]
|
139
|
+
tagfilter: bool,
|
140
|
+
|
141
|
+
/// Enable 'tasklist' extension
|
142
|
+
#[arg(long)]
|
143
|
+
tasklist: bool,
|
144
|
+
|
145
|
+
/// Enables underlines using double underscores
|
146
|
+
#[arg(long)]
|
147
|
+
underline: bool,
|
148
|
+
|
149
|
+
/// Allow raw HTML and dangerous URLs
|
150
|
+
#[arg(long = "unsafe")]
|
151
|
+
unsafe_: bool,
|
152
|
+
|
153
|
+
/// Enable 'wikilink_title_after_pipe' extension
|
154
|
+
#[arg(long)]
|
155
|
+
wikilinks_title_after_pipe: bool,
|
156
|
+
|
157
|
+
/// Enable 'wikilink_title_before_pipe' extension
|
158
|
+
#[arg(long)]
|
159
|
+
wikilinks_title_before_pipe: bool,
|
160
|
+
|
161
|
+
/// Show debug information
|
162
|
+
#[arg(long)]
|
163
|
+
debug: bool,
|
164
|
+
}
|
165
|
+
|
166
|
+
fn main() {
|
167
|
+
let mut s: Vec<u8> = Vec::with_capacity(2048);
|
168
|
+
let cli = Args::parse();
|
169
|
+
|
170
|
+
match cli.file {
|
171
|
+
None => {
|
172
|
+
std::io::stdin().read_to_end(&mut s).unwrap();
|
173
|
+
}
|
174
|
+
Some(fs) => {
|
175
|
+
s = std::fs::read(fs).unwrap();
|
176
|
+
}
|
177
|
+
};
|
178
|
+
|
179
|
+
let source = String::from_utf8_lossy(&s);
|
180
|
+
let options = RenderOptions {
|
181
|
+
autolink: cli.autolink,
|
182
|
+
// default_info_string:
|
183
|
+
description_lists: cli.description_lists,
|
184
|
+
escape: cli.escape,
|
185
|
+
escaped_char_spans: cli.escaped_char_spans,
|
186
|
+
footnotes: cli.footnotes,
|
187
|
+
// front_matter_delimiter:
|
188
|
+
full_info_string: cli.full_info_string,
|
189
|
+
gemojis: cli.gemojis,
|
190
|
+
gfm_quirks: cli.gfm_quirks,
|
191
|
+
github_pre_lang: cli.github_pre_lang,
|
192
|
+
greentext: cli.greentext,
|
193
|
+
hardbreaks: cli.hardbreaks,
|
194
|
+
header_ids: cli.header_ids,
|
195
|
+
ignore_empty_links: cli.ignore_empty_links,
|
196
|
+
ignore_setext: cli.ignore_setext,
|
197
|
+
math_code: cli.math_code,
|
198
|
+
math_dollars: cli.math_dollars,
|
199
|
+
multiline_block_quotes: cli.multiline_block_quotes,
|
200
|
+
relaxed_autolinks: cli.relaxed_autolinks,
|
201
|
+
relaxed_tasklist_character: cli.relaxed_tasklist_character,
|
202
|
+
sourcepos: cli.sourcepos,
|
203
|
+
experimental_inline_sourcepos: cli.experimental_inline_sourcepos,
|
204
|
+
smart: cli.smart,
|
205
|
+
spoiler: cli.spoiler,
|
206
|
+
strikethrough: cli.strikethrough,
|
207
|
+
subscript: cli.subscript,
|
208
|
+
superscript: cli.superscript,
|
209
|
+
// syntax_highlighting:
|
210
|
+
table: cli.table,
|
211
|
+
tagfilter: cli.tagfilter,
|
212
|
+
tasklist: cli.tasklist,
|
213
|
+
underline: cli.underline,
|
214
|
+
unsafe_: cli.unsafe_,
|
215
|
+
wikilinks_title_after_pipe: cli.wikilinks_title_after_pipe,
|
216
|
+
wikilinks_title_before_pipe: cli.wikilinks_title_before_pipe,
|
217
|
+
debug: cli.debug,
|
218
|
+
};
|
219
|
+
|
220
|
+
let result = render(source.to_string(), options);
|
221
|
+
|
222
|
+
if let Some(output_filename) = cli.output {
|
223
|
+
std::fs::write(output_filename, &result).unwrap();
|
224
|
+
} else {
|
225
|
+
std::io::stdout().write_all(result.as_bytes()).unwrap();
|
226
|
+
};
|
227
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'glfm_markdown/version'
|
4
|
+
require_relative 'glfm_markdown/loader'
|
5
|
+
|
6
|
+
load_rust_extension
|
7
|
+
|
8
|
+
module GLFMMarkdown
|
9
|
+
GLFM_DEFAULT_OPTIONS = {
|
10
|
+
autolink: true,
|
11
|
+
escaped_char_spans: false,
|
12
|
+
footnotes: true,
|
13
|
+
full_info_string: true,
|
14
|
+
gfm_quirks: true,
|
15
|
+
github_pre_lang: false,
|
16
|
+
hardbreaks: false,
|
17
|
+
math_code: false,
|
18
|
+
math_dollars: false,
|
19
|
+
multiline_block_quotes: true,
|
20
|
+
relaxed_autolinks: false,
|
21
|
+
sourcepos: true,
|
22
|
+
experimental_inline_sourcepos: true,
|
23
|
+
smart: false,
|
24
|
+
strikethrough: true,
|
25
|
+
table: true,
|
26
|
+
tagfilter: false,
|
27
|
+
tasklist: true,
|
28
|
+
unsafe: true,
|
29
|
+
|
30
|
+
debug: false
|
31
|
+
}.freeze
|
32
|
+
|
33
|
+
class << self
|
34
|
+
def to_html(markdown, options: {})
|
35
|
+
raise TypeError, 'markdown must be a String' unless markdown.is_a?(String)
|
36
|
+
raise TypeError, 'markdown must be UTF-8 encoded' unless markdown.encoding.name == "UTF-8"
|
37
|
+
raise TypeError, 'options must be a Hash' unless options.is_a?(Hash)
|
38
|
+
|
39
|
+
default_options = options[:glfm] ? GLFM_DEFAULT_OPTIONS : {}
|
40
|
+
|
41
|
+
# if you need to modify `options`, use `.merge` as `options` could be frozen
|
42
|
+
options = options.merge(unsafe: true) if options[:tagfilter]
|
43
|
+
|
44
|
+
render_to_html_rs(markdown, default_options.merge(options))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|