mirror of
https://github.com/sbrow/thor.git
synced 2026-10-25 10:11:55 -04:00
feat: Mis-spelled extension names now show up as hints.
This commit is contained in:
@@ -73,7 +73,7 @@ thor/
|
|||||||
| Package | Files | Responsibility |
|
| Package | Files | Responsibility |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `treesitter/` | `treesitter.odin` | FFI types (`Parser`, `Node`, `Query`, etc.), `@(link_prefix="ts_")` foreign bindings, grammar management (`Grammar_Store` with persistent allocator, `load_language`/`compile_query` building blocks, `ensure_parser`/`load_grammar` lazy loading, `preload_grammar`/`preload_grammars` for parallel loading with `sync.Mutex` cache protection), statically-linked HTML/CSS grammars |
|
| `treesitter/` | `treesitter.odin` | FFI types (`Parser`, `Node`, `Query`, etc.), `@(link_prefix="ts_")` foreign bindings, grammar management (`Grammar_Store` with persistent allocator, `load_language`/`compile_query` building blocks, `ensure_parser`/`load_grammar` lazy loading, `preload_grammar`/`preload_grammars` for parallel loading with `sync.Mutex` cache protection), statically-linked HTML/CSS grammars |
|
||||||
| `markdown/` | `markdown.odin` | `Extension` enum, `DEFAULT_EXTENSIONS`, `process(body, ext, file_path, allocator)` — full pipeline (clones cmark output, frees original), `parse_extension_list`, `apply_extension_config` |
|
| `markdown/` | `markdown.odin` | `Extension` enum, `DEFAULT_EXTENSIONS`, `EXTENSION_NAMES`, `process(body, ext, file_path, allocator)` — full pipeline (clones cmark output, frees original), `parse_extension_list` (with "did you mean?" hints via `diagnostics.suggest_correction`), `apply_extension_config` (same), `resolve_extension_conflicts` (Footnotes wins over Sidenotes) |
|
||||||
| | `footnotes.odin` | `strip_definitions` (pre-cmark, shared by `.Sidenotes` + `.Footnotes`), `inject_notes` (post-cmark sidenote rendering), `inject_footnotes` (post-cmark standard footnote rendering — numbered `<sup>` links + `<section class="footnotes"><ol>` at bottom). `.Sidenotes` and `.Footnotes` are mutually exclusive; `resolve_extension_conflicts` in `markdown.odin` picks `.Footnotes` if both are set. |
|
| | `footnotes.odin` | `strip_definitions` (pre-cmark, shared by `.Sidenotes` + `.Footnotes`), `inject_notes` (post-cmark sidenote rendering), `inject_footnotes` (post-cmark standard footnote rendering — numbered `<sup>` links + `<section class="footnotes"><ol>` at bottom). `.Sidenotes` and `.Footnotes` are mutually exclusive; `resolve_extension_conflicts` in `markdown.odin` picks `.Footnotes` if both are set. |
|
||||||
| | `alerts.odin` | `inject_alerts` — GitHub alert blocks (`> [!NOTE]`) → styled blockquotes with semantic class names (`alert-note` etc.) |
|
| | `alerts.odin` | `inject_alerts` — GitHub alert blocks (`> [!NOTE]`) → styled blockquotes with semantic class names (`alert-note` etc.) |
|
||||||
| | `emoji.odin` | `expand_emoji` — `:shortcode:` → unicode emoji |
|
| | `emoji.odin` | `expand_emoji` — `:shortcode:` → unicode emoji |
|
||||||
|
|||||||
@@ -13,8 +13,9 @@
|
|||||||
- [ ] [aliases](https://gohugo.io/methods/page/aliases/#redirects)?
|
- [ ] [aliases](https://gohugo.io/methods/page/aliases/#redirects)?
|
||||||
- [ ] Improve diagnostics
|
- [ ] Improve diagnostics
|
||||||
- [x] keep track of every error and don't report them more than once.
|
- [x] keep track of every error and don't report them more than once.
|
||||||
- [ ] show parsed arg when -extension is unrecognized
|
- [x] show parsed arg when -extension is unrecognized
|
||||||
- [ ] also do typo detection?
|
- [x] also do typo detection?
|
||||||
|
- [ ] show where the typo occurred (config file path for `apply_extension_config`, full `-ext:value` for `parse_extension_list`)
|
||||||
- [ ] `*` make sure the frontmatter parser has good diagnostics.
|
- [ ] `*` make sure the frontmatter parser has good diagnostics.
|
||||||
- [ ] fix the diagnostics in [DIAGNOSTIC TODOS](./DIAGNOSTIC_TODOS.yaml)
|
- [ ] fix the diagnostics in [DIAGNOSTIC TODOS](./DIAGNOSTIC_TODOS.yaml)
|
||||||
- [ ] only report format errors once.
|
- [ ] only report format errors once.
|
||||||
|
|||||||
+25
-3
@@ -6,6 +6,8 @@ import "core:encoding/json"
|
|||||||
import "core:log"
|
import "core:log"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
|
|
||||||
|
import diags "../diagnostics"
|
||||||
|
|
||||||
Extension :: enum {
|
Extension :: enum {
|
||||||
Emoji,
|
Emoji,
|
||||||
Sidenotes,
|
Sidenotes,
|
||||||
@@ -19,6 +21,11 @@ Extension :: enum {
|
|||||||
|
|
||||||
DEFAULT_EXTENSIONS :: bit_set[Extension]{.Emoji, .Sidenotes, .Alerts, .HeadingIDs, .DefLists}
|
DEFAULT_EXTENSIONS :: bit_set[Extension]{.Emoji, .Sidenotes, .Alerts, .HeadingIDs, .DefLists}
|
||||||
|
|
||||||
|
EXTENSION_NAMES :: []string{
|
||||||
|
"emoji", "sidenotes", "alerts", "highlight", "sections",
|
||||||
|
"heading_ids", "deflists", "footnotes",
|
||||||
|
}
|
||||||
|
|
||||||
// Caller is responsible for freeing string
|
// Caller is responsible for freeing string
|
||||||
process :: proc(
|
process :: proc(
|
||||||
body: string,
|
body: string,
|
||||||
@@ -69,7 +76,12 @@ parse_extension_list :: proc(s: string) -> (result: bit_set[Extension]) {
|
|||||||
e, ok := extension_from_name(name)
|
e, ok := extension_from_name(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
if name != "" {
|
if name != "" {
|
||||||
log.warnf("unknown extension '%s'", name)
|
suggestion := diags.suggest_correction(EXTENSION_NAMES, name)
|
||||||
|
if suggestion != "" {
|
||||||
|
log.warnf("unknown extension '%s' (did you mean '%s'?)", name, suggestion)
|
||||||
|
} else {
|
||||||
|
log.warnf("unknown extension '%s'", name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -81,9 +93,19 @@ parse_extension_list :: proc(s: string) -> (result: bit_set[Extension]) {
|
|||||||
// Given a map[Extension]bool, apply it to ext.
|
// Given a map[Extension]bool, apply it to ext.
|
||||||
apply_extension_config :: proc(ext: ^bit_set[Extension], config: json.Object) {
|
apply_extension_config :: proc(ext: ^bit_set[Extension], config: json.Object) {
|
||||||
for name, val in config {
|
for name, val in config {
|
||||||
// TODO: Silently discards invalid values.
|
|
||||||
enabled := val.(json.Boolean) or_continue
|
enabled := val.(json.Boolean) or_continue
|
||||||
e := extension_from_name(name) or_continue
|
|
||||||
|
e, ok := extension_from_name(name)
|
||||||
|
if !ok {
|
||||||
|
lower := strings.to_lower(name, context.temp_allocator)
|
||||||
|
suggestion := diags.suggest_correction(EXTENSION_NAMES, lower)
|
||||||
|
if suggestion != "" {
|
||||||
|
log.warnf("unknown extension '%s' (did you mean '%s'?)", name, suggestion)
|
||||||
|
} else {
|
||||||
|
log.warnf("unknown extension '%s'", name)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if enabled {
|
if enabled {
|
||||||
ext^ += {e}
|
ext^ += {e}
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"markdown_extensions": {
|
"markdown_extensions": {
|
||||||
"footnotes": true
|
// "footnotes": true
|
||||||
|
"foonotes": true
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
Reference in New Issue
Block a user