Editor: Find & Replace, read-aloud, backup, typography, phonetic, org niceties
Writer power-ups (Phase 11), plus the selection-bubble vs copy/paste fix. - Find & Replace (Ctrl/Cmd+F): SearchHighlight decoration extension + FindReplace bar (match-case, replace-all back-to-front, scroll without popping the selection bubble). - Read-aloud (Web Speech, offline) on the word card and selection bubble. - Keyboard/touch access to the ESL helpers: Ctrl/Cmd+D look up word at caret, Ctrl/Cmd+J rewrite selection, touch long-press lookup. Refactored the right-click handler into a shared openWordLookup(pos). - Whole-corpus backup: GET /api/docs/export-all zips every doc (md/docx), de-dupes filenames, dated name; sidebar download links. TestExportAll. - Smart typography input rules (curly quotes/em-dash/ellipsis), ASCII-only so CJK is untouched. - Duplicate doc, sidebar sort (Recent/Title/Longest), toolbar outline popover. - English phonetic (chosen over pinyin for an English learner): ECDICT-built phonetic.json.gz (46,579 words) + Result.Phonetic + WordCard IPA line; scripts/build_phonetic.py (full build + --seed fallback). - Selection bubble no longer blocks copy/paste: deferred to pointer-up and made click-through except on its buttons. Claude-Session: https://claude.ai/code/session_016Yr6jELuRc7hyzYLccQKZd
This commit is contained in:
29
web/src/components/Editor/Typography.ts
Normal file
29
web/src/components/Editor/Typography.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Extension, textInputRule } from '@tiptap/core'
|
||||
|
||||
// Typography adds the small print-shop niceties as you type: curly quotes,
|
||||
// em-dashes, and a single-character ellipsis. Implemented as input rules (no
|
||||
// dependency, offline-friendly — matching FontSize.ts's hand-rolled approach),
|
||||
// and every one is plain Undo-able if it ever fires when you didn't want it.
|
||||
//
|
||||
// CJK is untouched: these rules only rewrite ASCII quotes/dashes/dots, never the
|
||||
// fullwidth forms a Mandarin sentence uses.
|
||||
export const Typography = Extension.create({
|
||||
name: 'petalTypography',
|
||||
|
||||
addInputRules() {
|
||||
return [
|
||||
// “ opening double quote — after start, whitespace, or an opening bracket.
|
||||
textInputRule({ find: /(?:^|[\s{[(<'"‘“])(")$/, replace: '“' }),
|
||||
// ” closing double quote — any other time you type a ".
|
||||
textInputRule({ find: /"$/, replace: '”' }),
|
||||
// ‘ opening single quote.
|
||||
textInputRule({ find: /(?:^|[\s{[(<'"‘“])(')$/, replace: '‘' }),
|
||||
// ’ closing single quote / apostrophe.
|
||||
textInputRule({ find: /'$/, replace: '’' }),
|
||||
// — em dash from a double hyphen.
|
||||
textInputRule({ find: /--$/, replace: '—' }),
|
||||
// … ellipsis from three dots.
|
||||
textInputRule({ find: /\.\.\.$/, replace: '…' }),
|
||||
]
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user