comrak 0.0.3__tar.gz → 0.0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of comrak might be problematic. Click here for more details.

comrak-0.0.5/.aiignore ADDED
@@ -0,0 +1,9 @@
1
+ .aiignore
2
+ Cargo.lock
3
+ target
4
+ uv.lock
5
+ .git
6
+ .venv
7
+ .ruff_cache
8
+ dist
9
+ LICENSE
@@ -8,6 +8,8 @@ __pycache__/
8
8
  # C extensions
9
9
  *.so
10
10
 
11
+ *.sw[op]
12
+
11
13
  # Distribution / packaging
12
14
  .Python
13
15
  .venv/
@@ -234,6 +234,7 @@ dependencies = [
234
234
  "bon",
235
235
  "caseless",
236
236
  "clap",
237
+ "emojis",
237
238
  "entities",
238
239
  "memchr",
239
240
  "shell-words",
@@ -303,6 +304,15 @@ version = "1.6.0"
303
304
  source = "registry+https://github.com/rust-lang/crates.io-index"
304
305
  checksum = "339544cc9e2c4dc3fc7149fd630c5f22263a4fdf18a98afd0075784968b5cf00"
305
306
 
307
+ [[package]]
308
+ name = "emojis"
309
+ version = "0.6.4"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "99e1f1df1f181f2539bac8bf027d31ca5ffbf9e559e3f2d09413b9107b5c02f4"
312
+ dependencies = [
313
+ "phf",
314
+ ]
315
+
306
316
  [[package]]
307
317
  name = "entities"
308
318
  version = "1.0.1"
@@ -479,6 +489,24 @@ dependencies = [
479
489
  "pkg-config",
480
490
  ]
481
491
 
492
+ [[package]]
493
+ name = "phf"
494
+ version = "0.11.3"
495
+ source = "registry+https://github.com/rust-lang/crates.io-index"
496
+ checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
497
+ dependencies = [
498
+ "phf_shared",
499
+ ]
500
+
501
+ [[package]]
502
+ name = "phf_shared"
503
+ version = "0.11.3"
504
+ source = "registry+https://github.com/rust-lang/crates.io-index"
505
+ checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
506
+ dependencies = [
507
+ "siphasher",
508
+ ]
509
+
482
510
  [[package]]
483
511
  name = "pkg-config"
484
512
  version = "0.3.31"
@@ -717,6 +745,12 @@ version = "1.3.0"
717
745
  source = "registry+https://github.com/rust-lang/crates.io-index"
718
746
  checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
719
747
 
748
+ [[package]]
749
+ name = "siphasher"
750
+ version = "1.0.1"
751
+ source = "registry+https://github.com/rust-lang/crates.io-index"
752
+ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
753
+
720
754
  [[package]]
721
755
  name = "slug"
722
756
  version = "0.1.6"
@@ -1,5 +1,5 @@
1
1
  [dependencies]
2
- comrak_lib = {package = "comrak", version = "0.35.0"}
2
+ comrak_lib = {package = "comrak", version = "0.35.0", features = ["shortcodes"]}
3
3
  pyo3 = "0.23.3"
4
4
 
5
5
  [lib]
@@ -0,0 +1,7 @@
1
+ ## Release process
2
+
3
+ - `pre-commit run all-files`
4
+ - `maturin develop --release`
5
+ - `git push`
6
+ - `gh run download -p wheel*`
7
+ - `mv wheel*/* dist/ && rm -rf wheel* && pdm publish --no-build`
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: comrak
3
- Version: 0.0.3
3
+ Version: 0.0.5
4
4
  Classifier: Intended Audience :: Developers
5
5
  Classifier: License :: OSI Approved :: MIT License
6
6
  Classifier: Programming Language :: Rust
@@ -14,6 +14,8 @@ Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Programming Language :: Python :: 3.13
15
15
  Classifier: Programming Language :: Python :: 3.9
16
16
  Requires-Dist: maturin[patchelf]>=1.8.2 ; extra == 'dev'
17
+ Requires-Dist: pdm>=2.22.3 ; extra == 'dev'
18
+ Requires-Dist: pdm-bump>=0.9.10 ; extra == 'dev'
17
19
  Requires-Dist: pre-commit>=4.1.0 ; extra == 'dev'
18
20
  Requires-Dist: markdown>=3.7 ; extra == 'bench'
19
21
  Requires-Dist: markdown2>=2.5.3 ; extra == 'bench'
@@ -54,6 +56,22 @@ pip install comrak
54
56
 
55
57
  Fast Markdown to HTML parser in Rust, shipped for Python via PyO3.
56
58
 
59
+ ### Options
60
+
61
+ All options are exposed in a simple manner:
62
+
63
+ ```py
64
+ >>> import comrak
65
+ >>> opts = comrak.ExtensionOptions()
66
+ >>> comrak.render_markdown("foo :smile:", extension_options=opts)
67
+ '<p>foo :smile:</p>\n'
68
+ >>> opts.shortcodes = True
69
+ >>> comrak.render_markdown("foo :smile:", extension_options=opts)
70
+ '<p>foo 😄</p>\n'
71
+ ```
72
+
73
+ Refer to the [Comrak docs](https://docs.rs/comrak/latest/comrak/struct.Options.html) for all available options.
74
+
57
75
  ## Benchmarks
58
76
 
59
77
  Tested with small (8 lines) and medium (1200 lines) markdown strings
@@ -73,5 +91,5 @@ Maintained by [lmmx](https://github.com/lmmx). Contributions welcome!
73
91
 
74
92
  ## License
75
93
 
76
- This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
94
+ Licensed under the 2-Clause BSD License. See [LICENSE](https://github.com/lmmx/comrak/blob/master/LICENSE) for all the details.
77
95
 
@@ -24,6 +24,22 @@ pip install comrak
24
24
 
25
25
  Fast Markdown to HTML parser in Rust, shipped for Python via PyO3.
26
26
 
27
+ ### Options
28
+
29
+ All options are exposed in a simple manner:
30
+
31
+ ```py
32
+ >>> import comrak
33
+ >>> opts = comrak.ExtensionOptions()
34
+ >>> comrak.render_markdown("foo :smile:", extension_options=opts)
35
+ '<p>foo :smile:</p>\n'
36
+ >>> opts.shortcodes = True
37
+ >>> comrak.render_markdown("foo :smile:", extension_options=opts)
38
+ '<p>foo 😄</p>\n'
39
+ ```
40
+
41
+ Refer to the [Comrak docs](https://docs.rs/comrak/latest/comrak/struct.Options.html) for all available options.
42
+
27
43
  ## Benchmarks
28
44
 
29
45
  Tested with small (8 lines) and medium (1200 lines) markdown strings
@@ -43,4 +59,4 @@ Maintained by [lmmx](https://github.com/lmmx). Contributions welcome!
43
59
 
44
60
  ## License
45
61
 
46
- This project is licensed under the [MIT License](https://opensource.org/licenses/MIT).
62
+ Licensed under the 2-Clause BSD License. See [LICENSE](https://github.com/lmmx/comrak/blob/master/LICENSE) for all the details.
@@ -21,9 +21,6 @@ classifiers = [
21
21
  "Programming Language :: Python :: 3.13",
22
22
  "Programming Language :: Python :: 3.9"
23
23
  ]
24
- dynamic = [
25
- "version"
26
- ]
27
24
  authors = [
28
25
  {email = "louismmx@gmail.com", name = "Louis Maddox"}
29
26
  ]
@@ -37,7 +34,7 @@ keywords = [
37
34
  ]
38
35
  readme = "README.md"
39
36
  requires-python = ">=3.9"
40
- version = "0.0.3"
37
+ version = "0.0.5"
41
38
 
42
39
  [project.license]
43
40
  file = "LICENSE"
@@ -45,7 +42,9 @@ file = "LICENSE"
45
42
  [project.optional-dependencies]
46
43
  dev = [
47
44
  "maturin[patchelf]>=1.8.2",
48
- "pre-commit>=4.1.0"
45
+ "pdm>=2.22.3",
46
+ "pdm-bump>=0.9.10",
47
+ "pre-commit>=4.1.0",
49
48
  ]
50
49
  bench = [
51
50
  "markdown>=3.7",
@@ -0,0 +1,48 @@
1
+ use pyo3::prelude::*;
2
+
3
+ // We renamed the Rust library to `comrak_lib`
4
+ use comrak_lib::{markdown_to_html, Options as ComrakOptions};
5
+
6
+ // Import the Python option classes we defined
7
+ mod options;
8
+ use options::{PyExtensionOptions, PyParseOptions, PyRenderOptions};
9
+
10
+ /// Render a Markdown string to HTML, with optional Extension/Parse/Render overrides.
11
+ #[pyfunction(signature=(text, extension_options=None, parse_options=None, render_options=None))]
12
+ fn render_markdown(
13
+ text: &str,
14
+ extension_options: Option<PyExtensionOptions>,
15
+ parse_options: Option<PyParseOptions>,
16
+ render_options: Option<PyRenderOptions>,
17
+ ) -> PyResult<String> {
18
+ let mut opts = ComrakOptions::default();
19
+
20
+ // If user provided custom extension options, apply them.
21
+ if let Some(py_ext) = extension_options {
22
+ py_ext.update_extension_options(&mut opts.extension);
23
+ }
24
+
25
+ if let Some(py_parse) = parse_options {
26
+ py_parse.update_parse_options(&mut opts.parse);
27
+ }
28
+
29
+ if let Some(py_render) = render_options {
30
+ py_render.update_render_options(&mut opts.render);
31
+ }
32
+
33
+ let html = markdown_to_html(text, &opts);
34
+ Ok(html)
35
+ }
36
+
37
+ #[pymodule]
38
+ fn comrak(m: &Bound<'_, PyModule>) -> PyResult<()> {
39
+ // Expose the function
40
+ m.add_function(wrap_pyfunction!(render_markdown, m)?)?;
41
+
42
+ // Expose the classes
43
+ m.add_class::<PyExtensionOptions>()?;
44
+ m.add_class::<PyParseOptions>()?;
45
+ m.add_class::<PyRenderOptions>()?;
46
+
47
+ Ok(())
48
+ }
@@ -0,0 +1,246 @@
1
+ use pyo3::prelude::*;
2
+
3
+ // Import the Comrak (Rust) types under `comrak_lib::`
4
+ use comrak_lib::{
5
+ ExtensionOptions as ComrakExtensionOptions, ListStyleType, ParseOptions as ComrakParseOptions,
6
+ RenderOptions as ComrakRenderOptions,
7
+ };
8
+
9
+ /// Python class that mirrors Comrak’s `ExtensionOptions`
10
+ #[pyclass(name = "ExtensionOptions")]
11
+ #[derive(Clone)]
12
+ pub struct PyExtensionOptions {
13
+ #[pyo3(get, set)]
14
+ pub strikethrough: bool,
15
+ #[pyo3(get, set)]
16
+ pub tagfilter: bool,
17
+ #[pyo3(get, set)]
18
+ pub table: bool,
19
+ #[pyo3(get, set)]
20
+ pub autolink: bool,
21
+ #[pyo3(get, set)]
22
+ pub tasklist: bool,
23
+ #[pyo3(get, set)]
24
+ pub superscript: bool,
25
+ #[pyo3(get, set)]
26
+ pub header_ids: Option<String>,
27
+ #[pyo3(get, set)]
28
+ pub footnotes: bool,
29
+ #[pyo3(get, set)]
30
+ pub description_lists: bool,
31
+ #[pyo3(get, set)]
32
+ pub front_matter_delimiter: Option<String>,
33
+ #[pyo3(get, set)]
34
+ pub multiline_block_quotes: bool,
35
+ #[pyo3(get, set)]
36
+ pub alerts: bool,
37
+ #[pyo3(get, set)]
38
+ pub math_dollars: bool,
39
+ #[pyo3(get, set)]
40
+ pub math_code: bool,
41
+ #[pyo3(get, set)]
42
+ pub shortcodes: bool, // if your comrak_lib has the "shortcodes" feature
43
+ #[pyo3(get, set)]
44
+ pub wikilinks_title_after_pipe: bool,
45
+ #[pyo3(get, set)]
46
+ pub wikilinks_title_before_pipe: bool,
47
+ #[pyo3(get, set)]
48
+ pub underline: bool,
49
+ #[pyo3(get, set)]
50
+ pub subscript: bool,
51
+ #[pyo3(get, set)]
52
+ pub spoiler: bool,
53
+ #[pyo3(get, set)]
54
+ pub greentext: bool,
55
+ }
56
+
57
+ impl PyExtensionOptions {
58
+ /// **Rust-only** helper to copy from `PyExtensionOptions` into a real `ComrakExtensionOptions`.
59
+ pub fn update_extension_options(&self, opts: &mut ComrakExtensionOptions<'_>) {
60
+ opts.strikethrough = self.strikethrough;
61
+ opts.tagfilter = self.tagfilter;
62
+ opts.table = self.table;
63
+ opts.autolink = self.autolink;
64
+ opts.tasklist = self.tasklist;
65
+ opts.superscript = self.superscript;
66
+ opts.header_ids = self.header_ids.clone();
67
+ opts.footnotes = self.footnotes;
68
+ opts.description_lists = self.description_lists;
69
+ opts.front_matter_delimiter = self.front_matter_delimiter.clone();
70
+ opts.multiline_block_quotes = self.multiline_block_quotes;
71
+ opts.alerts = self.alerts;
72
+ opts.math_dollars = self.math_dollars;
73
+ opts.math_code = self.math_code;
74
+ opts.shortcodes = self.shortcodes;
75
+ opts.wikilinks_title_after_pipe = self.wikilinks_title_after_pipe;
76
+ opts.wikilinks_title_before_pipe = self.wikilinks_title_before_pipe;
77
+ opts.underline = self.underline;
78
+ opts.subscript = self.subscript;
79
+ opts.spoiler = self.spoiler;
80
+ opts.greentext = self.greentext;
81
+ }
82
+ }
83
+
84
+ #[pymethods]
85
+ impl PyExtensionOptions {
86
+ #[new]
87
+ pub fn new() -> Self {
88
+ let defaults = ComrakExtensionOptions::default();
89
+ Self {
90
+ strikethrough: defaults.strikethrough,
91
+ tagfilter: defaults.tagfilter,
92
+ table: defaults.table,
93
+ autolink: defaults.autolink,
94
+ tasklist: defaults.tasklist,
95
+ superscript: defaults.superscript,
96
+ header_ids: defaults.header_ids.clone(),
97
+ footnotes: defaults.footnotes,
98
+ description_lists: defaults.description_lists,
99
+ front_matter_delimiter: defaults.front_matter_delimiter.clone(),
100
+ multiline_block_quotes: defaults.multiline_block_quotes,
101
+ alerts: defaults.alerts,
102
+ math_dollars: defaults.math_dollars,
103
+ math_code: defaults.math_code,
104
+ shortcodes: false, // or `defaults.shortcodes` if your version has that
105
+ wikilinks_title_after_pipe: defaults.wikilinks_title_after_pipe,
106
+ wikilinks_title_before_pipe: defaults.wikilinks_title_before_pipe,
107
+ underline: defaults.underline,
108
+ subscript: defaults.subscript,
109
+ spoiler: defaults.spoiler,
110
+ greentext: defaults.greentext,
111
+ }
112
+ }
113
+ }
114
+
115
+ /// Python class that mirrors Comrak’s `ParseOptions`
116
+ #[pyclass(name = "ParseOptions")]
117
+ #[derive(Clone)]
118
+ pub struct PyParseOptions {
119
+ #[pyo3(get, set)]
120
+ pub smart: bool,
121
+ #[pyo3(get, set)]
122
+ pub default_info_string: Option<String>,
123
+ #[pyo3(get, set)]
124
+ pub relaxed_tasklist_matching: bool,
125
+ #[pyo3(get, set)]
126
+ pub relaxed_autolinks: bool,
127
+ }
128
+
129
+ impl PyParseOptions {
130
+ /// Rust-only helper
131
+ pub fn update_parse_options(&self, opts: &mut ComrakParseOptions<'_>) {
132
+ opts.smart = self.smart;
133
+ opts.default_info_string = self.default_info_string.clone();
134
+ opts.relaxed_tasklist_matching = self.relaxed_tasklist_matching;
135
+ opts.relaxed_autolinks = self.relaxed_autolinks;
136
+ }
137
+ }
138
+
139
+ #[pymethods]
140
+ impl PyParseOptions {
141
+ #[new]
142
+ pub fn new() -> Self {
143
+ let defaults = ComrakParseOptions::default();
144
+ Self {
145
+ smart: defaults.smart,
146
+ default_info_string: defaults.default_info_string.clone(),
147
+ relaxed_tasklist_matching: defaults.relaxed_tasklist_matching,
148
+ relaxed_autolinks: defaults.relaxed_autolinks,
149
+ }
150
+ }
151
+ }
152
+
153
+ /// Python class that mirrors Comrak’s `RenderOptions`
154
+ #[pyclass(name = "RenderOptions")]
155
+ #[derive(Clone)]
156
+ pub struct PyRenderOptions {
157
+ #[pyo3(get, set)]
158
+ pub hardbreaks: bool,
159
+ #[pyo3(get, set)]
160
+ pub github_pre_lang: bool,
161
+ #[pyo3(get, set)]
162
+ pub full_info_string: bool,
163
+ #[pyo3(get, set)]
164
+ pub width: usize,
165
+ #[pyo3(get, set)]
166
+ pub unsafe_: bool, // named 'unsafe_' because 'unsafe' is reserved
167
+ #[pyo3(get, set)]
168
+ pub escape: bool,
169
+ #[pyo3(get, set)]
170
+ pub list_style: u8, // store 42 = '*', 43 = '+', 45 = '-'
171
+ #[pyo3(get, set)]
172
+ pub sourcepos: bool,
173
+ #[pyo3(get, set)]
174
+ pub experimental_inline_sourcepos: bool,
175
+ #[pyo3(get, set)]
176
+ pub escaped_char_spans: bool,
177
+ #[pyo3(get, set)]
178
+ pub ignore_setext: bool,
179
+ #[pyo3(get, set)]
180
+ pub ignore_empty_links: bool,
181
+ #[pyo3(get, set)]
182
+ pub gfm_quirks: bool,
183
+ #[pyo3(get, set)]
184
+ pub prefer_fenced: bool,
185
+ #[pyo3(get, set)]
186
+ pub figure_with_caption: bool,
187
+ #[pyo3(get, set)]
188
+ pub tasklist_classes: bool,
189
+ #[pyo3(get, set)]
190
+ pub ol_width: usize,
191
+ }
192
+
193
+ impl PyRenderOptions {
194
+ /// Rust-only helper
195
+ pub fn update_render_options(&self, opts: &mut ComrakRenderOptions) {
196
+ opts.hardbreaks = self.hardbreaks;
197
+ opts.github_pre_lang = self.github_pre_lang;
198
+ opts.full_info_string = self.full_info_string;
199
+ opts.width = self.width;
200
+ opts.unsafe_ = self.unsafe_;
201
+ opts.escape = self.escape;
202
+ // convert integer to ListStyleType
203
+ opts.list_style = match self.list_style {
204
+ 43 => ListStyleType::Plus, // '+'
205
+ 42 => ListStyleType::Star, // '*'
206
+ _ => ListStyleType::Dash, // '-'
207
+ };
208
+ opts.sourcepos = self.sourcepos;
209
+ opts.experimental_inline_sourcepos = self.experimental_inline_sourcepos;
210
+ opts.escaped_char_spans = self.escaped_char_spans;
211
+ opts.ignore_setext = self.ignore_setext;
212
+ opts.ignore_empty_links = self.ignore_empty_links;
213
+ opts.gfm_quirks = self.gfm_quirks;
214
+ opts.prefer_fenced = self.prefer_fenced;
215
+ opts.figure_with_caption = self.figure_with_caption;
216
+ opts.tasklist_classes = self.tasklist_classes;
217
+ opts.ol_width = self.ol_width;
218
+ }
219
+ }
220
+
221
+ #[pymethods]
222
+ impl PyRenderOptions {
223
+ #[new]
224
+ pub fn new() -> Self {
225
+ let defaults = ComrakRenderOptions::default();
226
+ Self {
227
+ hardbreaks: defaults.hardbreaks,
228
+ github_pre_lang: defaults.github_pre_lang,
229
+ full_info_string: defaults.full_info_string,
230
+ width: defaults.width,
231
+ unsafe_: defaults.unsafe_,
232
+ escape: defaults.escape,
233
+ list_style: defaults.list_style as u8, // 45 if dash
234
+ sourcepos: defaults.sourcepos,
235
+ experimental_inline_sourcepos: defaults.experimental_inline_sourcepos,
236
+ escaped_char_spans: defaults.escaped_char_spans,
237
+ ignore_setext: defaults.ignore_setext,
238
+ ignore_empty_links: defaults.ignore_empty_links,
239
+ gfm_quirks: defaults.gfm_quirks,
240
+ prefer_fenced: defaults.prefer_fenced,
241
+ figure_with_caption: defaults.figure_with_caption,
242
+ tasklist_classes: defaults.tasklist_classes,
243
+ ol_width: defaults.ol_width,
244
+ }
245
+ }
246
+ }