Skip to content

OCR markup: # to tags/headings, @ to Wikilinks - #123

Closed
philips-clanker wants to merge 1 commit into
keywords-links-exportfrom
ocr-hashtag-mention-markup
Closed

OCR markup: # to tags/headings, @ to Wikilinks#123
philips-clanker wants to merge 1 commit into
keywords-links-exportfrom
ocr-hashtag-mention-markup

Conversation

@philips-clanker

Copy link
Copy Markdown
Collaborator

Summary

Split out of #81 (by @Floper), stacked on #122 (needs the noteKeywordTags map built there so this note's own brand-new keyword stars are recognised before they're indexed as vault tags).

Supernote's handwriting recognition renders starred keywords in OCR text as #Word and its own internal-link mentions as @Word(s). A new processHashtagsAndMentions() post-processes each page's OCR text:

  • #Word (or # Word; two-word combos also checked as #word_otherword): becomes an inline tag if Word is a known vault tag or one of this note's own keyword-star tags, otherwise a Markdown heading.
  • @Word(s): takes the rest of the line as a Wikilink ([[Word(s)]]), so multi-word note names work.

Gated behind a new "Convert # and @ in recognized text to tags and wikilinks" setting, on by default. Wrapped in try/catch at the call site so a pathological page's OCR text can't break the whole export.

Test plan

  • npm run build - clean
  • npx eslint src/main.ts src/settings.ts - 0 errors
  • npx vitest run - 22 passed
  • Manual test in Obsidian: a .note file whose OCR text contains #SomeTag (both a known vault tag and a novel one) and @Some Note, confirming tag/heading/Wikilink output

Supernote's handwriting recognition renders starred keywords in OCR
text as "#Word" and its own internal-link mentions as "@word(s)". A
new processHashtagsAndMentions() post-processes each page's OCR text:

- "#Word" (or "# Word", two-word combos also checked as
  "#word_otherword"): an inline tag if Word is a known vault tag or one
  of this note's own keyword-star tags (see the noteKeywordTags map
  built in writeMarkdownFile, stacked on #122's keyword-page-mapping
  work), otherwise a Markdown heading.
- "@word(s)": takes the rest of the line as a Wikilink, so multi-word
  note names work.

Gated behind a new "Convert # and @ in recognized text to tags and
wikilinks" setting, on by default. Wrapped in try/catch at the call
site so a pathological page's OCR text can't break the whole export.

Split out of #81 (by @Floper), ported onto the current
processSupernoteText/VaultWriter shape.
@philips philips closed this Jul 29, 2026
pull Bot pushed a commit to ben-vargas/supernote-obsidian-plugin that referenced this pull request Jul 29, 2026
…gins

Extends PageTextProcessorContext (registerPageTextProcessor's hook, see
ocr-plugins.md) with per-page fields an external companion plugin has
had no way to see until now: starred keywords, internal links, PAGEID,
orientation, and recognition status. Previously the hook only exposed
a flat OCR-text string and rasterized image bytes, which was enough to
reproduce the OCR-text-pattern half of philips#123 but not philips#122's genuine
keyword-star/link handling - see the discussion on philips#145.

sn.keywords/sn.links are grouped per page using the same
first-4-characters-of-the-Record-key convention supernote-typescript's
_parseLinks documents (more reliable than IKeyword.KEYWORDPAGE, which
can be '0'/invalid). Verified against a real device-created fixture
(supernote-typescript/tests/input/nomad-3.26.40-link-tag-3p.note).

Titles were considered too (same "device-native structured signal"
category as keywords/links) but dropped from this pass: ITitle has no
decoded text, only a bounding box + bitmap, so getting title text needs
correlating that box against page.recognitionElements' word boxes -
real new logic, not just wiring through an existing field.

Bumps the supernote-typescript submodule pointer to a branch (not yet
merged) that exports RecognitionStatuses from its index, needed to
type the new recognitionStatus field as that enum rather than a bare
string - see supernote-typescript#38.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants