Document the render options the gem actually reads
What does this MR do and why?
I compared the options table in the README with the RenderOptions struct in ext/gitlab_glfm_markdown/src/glfm.rs, and three things in the README do not match what the gem reads:
escape_char_spansis not an option. The field isescaped_char_spans(glfm.rs:18), which is also how theonly_escape_charsrow spells it.to_htmlpasses the options hash to the nativerender_to_html_rs, which reads it withserde_magnus::deserialize(ext/gitlab_glfm_markdown/src/lib.rs:10), andRenderOptionsdoes not set#[serde(deny_unknown_fields)], so a key it does not know is ignored without an error: a caller who copies the name from the README gets no<span data-escaped-char>and no warning. The row has had that name since it was added in !37 (merged). I renamed it and moved it afterescape, where it now sorts.alertsandsubscripthad no row. Both are fields ofRenderOptions(glfm.rs:10andglfm.rs:58) and both are passed to Comrak (glfm.rs:75andglfm.rs:90). I added a row for each in its alphabetical place.- The Usage section did not mention
glfm: true.to_htmlreads that key itself (lib/gitlab-glfm-markdown.rb:38) and, when it is set, starts fromGLFMMarkdown::GLFM_DEFAULT_OPTIONSand merges the options passed over it; without it, an option that is not passed is off, becauseRenderOptionsderivesDefaultand sets#[serde(default)](glfm.rs:7andglfm.rs:8). I added two sentences and a one-line example.
GitLab's own renderer (lib/banzai/filter/markdown_engines/glfm_markdown.rb in gitlab-org/gitlab) passes alerts: true and escaped_char_spans: true, so two of the three rows this changes describe options GitLab itself relies on.
After the change the table has one row for each of the 43 RenderOptions fields, the new rows keep the column padding, and the rows stay in the order the table already used.
This touches README.md only, so I did not add a changelog entry.
How to set up and validate locally
-
Install the published gem 0.0.45, the release tagged at the current
main(c4575ff7):docker run --rm -it ruby:3.4 bash gem install gitlab-glfm-markdown -v 0.0.45 irb -
In
irb, compare the old and the new option name, then the two options the README did not list, thenglfm: true:require 'gitlab-glfm-markdown' GLFMMarkdown.to_html('a \* b', options: { sourcepos: false, escape_char_spans: true }) # => "<p>a * b</p>\n" GLFMMarkdown.to_html('a \* b', options: { sourcepos: false, escaped_char_spans: true }) # => "<p>a <span data-escaped-char>*</span> b</p>\n" GLFMMarkdown.to_html("> [!note]\n> Text\n", options: { sourcepos: false, alerts: true }) GLFMMarkdown.to_html('H~2~O', options: { sourcepos: false, subscript: true }) GLFMMarkdown.to_html("| a | b |\n|---|---|\n| 1 | 2 |\n", options: { glfm: true }) GLFMMarkdown.to_html("| a | b |\n|---|---|\n| 1 | 2 |\n", options: { glfm: true, sourcepos: false }) -
Read the rendered README on this branch: the
alerts,escaped_char_spansandsubscriptrows, and the paragraph under the first Ruby example.
Output from the published 0.0.45 gem (Docker ruby:3.4, Ruby 3.4.11, x86_64-linux)
1. escape_char_spans (README today) vs escaped_char_spans (what the gem reads)
1a: to_html("a \\* b", options: {sourcepos: false, escape_char_spans: true})
=> "<p>a * b</p>\n"
1b: to_html("a \\* b", options: {sourcepos: false, escaped_char_spans: true})
=> "<p>a <span data-escaped-char>*</span> b</p>\n"
2. alerts
2a: to_html("> [!note]\n> Text\n", options: {sourcepos: false})
=> "<blockquote>\n<p>[!note]\nText</p>\n</blockquote>\n"
2b: to_html("> [!note]\n> Text\n", options: {sourcepos: false, alerts: true})
=> "<div class=\"markdown-alert markdown-alert-note\">\n<p class=\"markdown-alert-title\">Note</p>\n<p>Text</p>\n</div>\n"
3. subscript
3a: to_html("H~2~O", options: {sourcepos: false})
=> "<p>H~2~O</p>\n"
3b: to_html("H~2~O", options: {sourcepos: false, subscript: true})
=> "<p>H<sub>2</sub>O</p>\n"
4. glfm
4a: to_html("| a | b |\n|---|---|\n| 1 | 2 |\n", options: {})
=> "<p>| a | b |\n|---|---|\n| 1 | 2 |</p>\n"
4b: to_html("| a | b |\n|---|---|\n| 1 | 2 |\n", options: {glfm: true})
=> "<table data-sourcepos=\"1:1-3:9\">\n<thead>\n<tr data-sourcepos=\"1:1-1:9\">\n<th data-sourcepos=\"1:2-1:4\">a</th>\n<th data-sourcepos=\"1:6-1:8\">b</th>\n</tr>\n</thead>\n<tbody>\n<tr data-sourcepos=\"3:1-3:9\">\n<td data-sourcepos=\"3:2-3:4\">1</td>\n<td data-sourcepos=\"3:6-3:8\">2</td>\n</tr>\n</tbody>\n</table>\n"
4c: to_html("| a | b |\n|---|---|\n| 1 | 2 |\n", options: {glfm: true, sourcepos: false})
=> "<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>2</td>\n</tr>\n</tbody>\n</table>\n"
5. an unknown key is ignored without an error
5a: to_html("x", options: {sourcepos: false, no_such_option: true})
=> "<p>x</p>\n"subscript beside strikethrough, which the new row describes:
"H~2~O ~~old~~" {sourcepos: false, strikethrough: true}
=> "<p>H<del>2</del>O <del>old</del></p>\n"
"H~2~O ~~old~~" {sourcepos: false, strikethrough: true, subscript: true}
=> "<p>H<sub>2</sub>O <del>old</del></p>\n"Other checks
- The table's option names against the
RenderOptionsfields (the three commented-out fields left aside): onmain,alertsandsubscriptare fields with no row andescape_char_spansis a row with no field; on this branch both lists hold the same 43 names. - The rows still sort in byte order (
LC_ALL=C sort -cover the option column), which is the order the table already used (escapebeforeescaped_char_spans,tasklist_classesbeforetasklist). - Rendering this branch's README with the gem itself gives 43 table rows, and the three new rows render with their code spans intact.
- The project runs no Markdown linter. With markdownlint-cli2 0.23.2 at its defaults, the only findings this branch adds over
mainare MD013 on the two added table rows, which every existing row also has.
Related to !37 (merged), !60 (merged) and !70 (merged), where escaped_char_spans, subscript and alerts were added.