@inshapardaz/likhari-react 0.1.21-dev.201 → 0.1.21-dev.202

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.
@@ -5,6 +5,7 @@ import { type EditorFeatureConfig, type FeatureConfigPresetName } from '@inshapa
5
5
  import { type FontOption } from './fonts/index.js';
6
6
  import { type DraftRestoreMode } from './components/DraftRestore.js';
7
7
  import { type AutoCorrectStore } from './autocorrect/autoCorrectStores.js';
8
+ import type { UrduNormalizationOptions } from './normalization/urduNormalize.js';
8
9
  import { type Locale } from './i18n/index.js';
9
10
  /** What happens when the user is about to leave with unsaved changes. */
10
11
  export type NavigationGuardMode = 'confirm' | 'save-draft' | 'off';
@@ -16,6 +17,8 @@ export interface EditorRootProps {
16
17
  documentId?: string;
17
18
  /** Where auto-corrections are loaded from and saved to, in priority order. Pass a stable array. */
18
19
  autoCorrectStores?: AutoCorrectStore[];
20
+ /** Urdu normalisation applied as part of auto-correct. Diacritics are kept unless `removeDiacritics` is set. */
21
+ urduNormalization?: UrduNormalizationOptions;
19
22
  initialContent?: EditorInitialContent;
20
23
  featureConfig?: EditorFeatureConfig;
21
24
  featurePreset?: FeatureConfigPresetName;
@@ -1 +1 @@
1
- {"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EditorRoot.d.ts","sourceRoot":"","sources":["../src/EditorRoot.tsx"],"names":[],"mappings":"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"}
@@ -48,7 +48,7 @@ function initialEditorStateJson(initialContent) {
48
48
  const state = defaultFormatRegistry.parse(initialContent.format, initialContent.value);
49
49
  return JSON.stringify(state);
50
50
  }
51
- export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorrectStores, initialContent, featureConfig, featurePreset, theme, colorScheme, accentColor, locale = 'en', placeholder, height = '480px', onChange, onSave, showSave = Boolean(onSave), onImageUpload, fetchImage, fontOptions, autosave = true, restoreDraft = 'prompt', navigationGuard = 'confirm', onDraftRestored, autosaveDelayMs = DEFAULT_AUTOSAVE_DELAY_MS, autosaveMaxBytes = DEFAULT_AUTOSAVE_MAX_BYTES, autosaveMaxDrafts = DEFAULT_AUTOSAVE_MAX_DRAFTS, }, ref) {
51
+ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorrectStores, urduNormalization, initialContent, featureConfig, featurePreset, theme, colorScheme, accentColor, locale = 'en', placeholder, height = '480px', onChange, onSave, showSave = Boolean(onSave), onImageUpload, fetchImage, fontOptions, autosave = true, restoreDraft = 'prompt', navigationGuard = 'confirm', onDraftRestored, autosaveDelayMs = DEFAULT_AUTOSAVE_DELAY_MS, autosaveMaxBytes = DEFAULT_AUTOSAVE_MAX_BYTES, autosaveMaxDrafts = DEFAULT_AUTOSAVE_MAX_DRAFTS, }, ref) {
52
52
  const config = useMemo(() => resolveFeatureConfig(featureConfig, featurePreset), [featureConfig, featurePreset]);
53
53
  const strings = useMemo(() => getStrings(locale), [locale]);
54
54
  const resolvedPlaceholder = placeholder ?? strings.editor.placeholder;
@@ -293,7 +293,7 @@ export const EditorRoot = forwardRef(function EditorRoot({ documentId, autoCorre
293
293
  const portalTargetSelector = `#${CSS.escape(portalTargetId)}`;
294
294
  return (_jsx(EditorThemeProvider, { theme: theme, colorScheme: colorScheme, accentColor: accentColor, scopeElementId: portalTargetId, children: _jsxs("div", { className: "likhari-root", dir: dir, ref: rootElementRef, "data-document-id": documentId, style: { height: typeof height === 'number' ? `${height}px` : height }, children: [_jsx("div", { id: portalTargetId, className: "likhari-portal-target" }), _jsx(PortalTargetContext.Provider, { value: portalTargetSelector, children: _jsxs(UiStringsContext.Provider, { value: strings, children: [_jsx(ImageOptionsContext.Provider, { value: imageOptions, children: _jsxs(LexicalComposer, { initialConfig: initialConfig, children: [_jsx(Toolbar, { config: config, onSave: handleSave, findOpen: openPanel === 'find', onToggleFind: () => togglePanel('find'), spellOpen: openPanel === 'spell', onToggleSpell: () => togglePanel('spell'), autoCorrectOpen: openPanel === 'autocorrect', onToggleAutoCorrect: () => togglePanel('autocorrect'), isDirty: isDirty, showSave: showSave, fontOptions: fontOptions, direction: dir, locale: locale, drafts: autosave
295
295
  ? { currentId: draftId, maxBytes: autosaveMaxBytes, adoptOnRestore: !documentId, onRestored: handleDraftRestored }
296
- : undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && openPanel === 'find' && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setOpenPanel(null) }), config.language.spellCheck && openPanel === 'spell' && (_jsx(SpellcheckPanel, { strings: strings, dir: dir, onClose: () => setOpenPanel(null) })), config.language.autocorrect && openPanel === 'autocorrect' && (_jsx(AutoCorrectPanel, { strings: strings, dir: dir, stores: stores, onSaved: () => setAutoCorrectVersion((v) => v + 1), onClose: () => setOpenPanel(null) })), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, spellCheck: false, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.language.spellCheck && _jsx(SpellHighlightPlugin, {}), config.language.autocorrect && _jsx(AutoCorrectPlugin, { stores: stores, version: autoCorrectVersion, enabled: true }), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
296
+ : undefined }), documentId && (_jsx(DraftRestore, { draftId: documentId, mode: restoreDraft, initialJson: initialContentJsonRef.current, locale: locale, onRestored: handleDraftRestored })), _jsxs("div", { className: "likhari-canvas-frame", children: [config.findReplace && openPanel === 'find' && _jsx(FindReplaceBar, { strings: strings, dir: dir, onClose: () => setOpenPanel(null) }), config.language.spellCheck && openPanel === 'spell' && (_jsx(SpellcheckPanel, { strings: strings, dir: dir, onClose: () => setOpenPanel(null) })), config.language.autocorrect && openPanel === 'autocorrect' && (_jsx(AutoCorrectPanel, { strings: strings, dir: dir, stores: stores, onSaved: () => setAutoCorrectVersion((v) => v + 1), onClose: () => setOpenPanel(null) })), _jsx("div", { className: "likhari-canvas", children: _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "likhari-content-editable", dir: dir, spellCheck: false, "aria-label": strings.editor.contentLabel }), placeholder: _jsx("div", { className: "likhari-placeholder", children: resolvedPlaceholder }), ErrorBoundary: LexicalErrorBoundary }) })] }), config.history && _jsx(HistoryPlugin, {}), (config.lists.bullet || config.lists.numbered || config.lists.check) && _jsx(ListPlugin, {}), config.lists.check && _jsx(CheckListPlugin, {}), config.links && _jsx(LinkPlugin, {}), config.links && _jsx(LinkPastePlugin, {}), config.blocks.pageBreak && _jsx(PageBreakPlugin, {}), config.language.spellCheck && _jsx(SpellHighlightPlugin, {}), config.language.autocorrect && _jsx(AutoCorrectPlugin, { stores: stores, version: autoCorrectVersion, enabled: true, urduNormalization: urduNormalization }), config.columns && _jsx(LayoutPlugin, {}), config.footnotes && _jsx(FootnotePlugin, {}), config.poetry.enabled && _jsx(PoetryPlugin, {}), config.poetry.enabled && _jsx(PoetryResizer, {}), config.tables && _jsx(TablePlugin, { hasCellMerge: true, hasTabHandler: true }), config.blocks.horizontalRule && _jsx(HorizontalRulePlugin, {}), _jsx(EditorInstancePlugin, { instanceRef: editorInstanceRef }), _jsx(OnChangePlugin, { onChange: handleChange })] }) }), _jsx(LeaveDialog, { opened: leavePrompt !== null, canSave: Boolean(onSave), canSaveDraft: autosave || navigationGuard === 'save-draft', draftFailed: leavePrompt?.draftFailed ?? false, onSave: () => {
297
297
  handleSave();
298
298
  settleLeave(true);
299
299
  }, onSaveDraft: () => {
@@ -1,5 +1,6 @@
1
1
  import { type LexicalCommand } from 'lexical';
2
2
  import { type AutoCorrectStore } from './autoCorrectStores.js';
3
+ import { type UrduNormalizationOptions } from '../normalization/urduNormalize.js';
3
4
  /** Keys that end a word: a space or punctuation, in Latin and Arabic-script forms. */
4
5
  /** Corrects every word in the document, e.g. after pasting or loading content. */
5
6
  export declare const CORRECT_DOCUMENT_COMMAND: LexicalCommand<void>;
@@ -10,9 +11,11 @@ export declare const CORRECT_DOCUMENT_COMMAND: LexicalCommand<void>;
10
11
  * the table reloads). The table used depends on the block's direction: RTL
11
12
  * blocks use the Urdu and Shahmukhi tables, LTR blocks the English one.
12
13
  */
13
- export declare function AutoCorrectPlugin({ stores, version, enabled }: {
14
+ export declare function AutoCorrectPlugin({ stores, version, enabled, urduNormalization, }: {
14
15
  stores: AutoCorrectStore[];
15
16
  version: number;
16
17
  enabled: boolean;
18
+ /** Urdu normalisation for right-to-left text; character mapping always applies. */
19
+ urduNormalization?: UrduNormalizationOptions;
17
20
  }): null;
18
21
  //# sourceMappingURL=AutoCorrectPlugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AutoCorrectPlugin.d.ts","sourceRoot":"","sources":["../../src/autocorrect/AutoCorrectPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4E,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAExH,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGjF,sFAAsF;AACtF,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,IAAI,CAA6C,CAAC;AAMxG;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,QA4EhI"}
1
+ {"version":3,"file":"AutoCorrectPlugin.d.ts","sourceRoot":"","sources":["../../src/autocorrect/AutoCorrectPlugin.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA4E,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAExH,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAiB,KAAK,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAG9F,sFAAsF;AACtF,kFAAkF;AAClF,eAAO,MAAM,wBAAwB,EAAE,cAAc,CAAC,IAAI,CAA6C,CAAC;AAMxG;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,OAAO,EACP,OAAO,EACP,iBAAiB,GAClB,EAAE;IACD,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CAC9C,QAiFA"}
@@ -3,6 +3,7 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
3
3
  import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
4
4
  import { $correctDocument, $correctWordBeforeCaret } from './autoCorrectActions.js';
5
5
  import { loadAutoCorrections } from './autoCorrectStores.js';
6
+ import { normalizeUrdu } from '../normalization/urduNormalize.js';
6
7
  /** Keys that end a word: a space or punctuation, in Latin and Arabic-script forms. */
7
8
  /** Corrects every word in the document, e.g. after pasting or loading content. */
8
9
  export const CORRECT_DOCUMENT_COMMAND = createCommand('CORRECT_DOCUMENT_COMMAND');
@@ -16,8 +17,12 @@ const RTL_LANGUAGES = ['ur', 'pa-shahmukhi'];
16
17
  * the table reloads). The table used depends on the block's direction: RTL
17
18
  * blocks use the Urdu and Shahmukhi tables, LTR blocks the English one.
18
19
  */
19
- export function AutoCorrectPlugin({ stores, version, enabled }) {
20
+ export function AutoCorrectPlugin({ stores, version, enabled, urduNormalization, }) {
20
21
  const [editor] = useLexicalComposerContext();
22
+ // Effects below run once per editor, so they reach the latest options through this ref.
23
+ const normalizeOptions = useRef(urduNormalization);
24
+ normalizeOptions.current = urduNormalization;
25
+ const normalizeRtl = (text) => normalizeUrdu(text, normalizeOptions.current);
21
26
  const tables = useRef(new Map());
22
27
  const rtlTable = useRef(new Map());
23
28
  useEffect(() => {
@@ -46,7 +51,7 @@ export function AutoCorrectPlugin({ stores, version, enabled }) {
46
51
  return;
47
52
  return editor.registerCommand(CORRECT_DOCUMENT_COMMAND, () => {
48
53
  editor.update(() => {
49
- $correctDocument(tables.current.get('en') ?? new Map(), rtlTable.current);
54
+ $correctDocument(tables.current.get('en') ?? new Map(), rtlTable.current, normalizeRtl);
50
55
  }, { discrete: true });
51
56
  return true;
52
57
  }, COMMAND_PRIORITY_EDITOR);
@@ -65,9 +70,10 @@ export function AutoCorrectPlugin({ stores, version, enabled }) {
65
70
  if (!$isRangeSelection(selection))
66
71
  return;
67
72
  const block = selection.anchor.getNode().getTopLevelElement();
68
- const table = tableFor(block?.getDirection() === 'rtl');
73
+ const rtl = block?.getDirection() === 'rtl';
74
+ const table = tableFor(rtl);
69
75
  if (table)
70
- $correctWordBeforeCaret(table);
76
+ $correctWordBeforeCaret(table, rtl ? normalizeRtl : undefined);
71
77
  }, { discrete: true });
72
78
  }, 0);
73
79
  };
@@ -4,12 +4,12 @@
4
4
  * correction replaces only the word, and the caret stays right after the
5
5
  * boundary. Returns true if a correction was made.
6
6
  */
7
- export declare function $correctWordBeforeCaret(table: Map<string, string>): boolean;
7
+ export declare function $correctWordBeforeCaret(table: Map<string, string>, normalize?: (word: string) => string): boolean;
8
8
  /**
9
9
  * Corrects every whole word in the document, for text that never went through
10
10
  * typing (pasted or loaded content). Words are found per paragraph or cell, so a
11
11
  * word split by formatting is still one word. Each block uses the table for its
12
12
  * direction. Returns how many words were corrected.
13
13
  */
14
- export declare function $correctDocument(ltr: Map<string, string>, rtl: Map<string, string>): number;
14
+ export declare function $correctDocument(ltr: Map<string, string>, rtl: Map<string, string>, normalizeRtl?: (text: string) => string): number;
15
15
  //# sourceMappingURL=autoCorrectActions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"autoCorrectActions.d.ts","sourceRoot":"","sources":["../../src/autocorrect/autoCorrectActions.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAiC3E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAkB3F"}
1
+ {"version":3,"file":"autoCorrectActions.d.ts","sourceRoot":"","sources":["../../src/autocorrect/autoCorrectActions.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAiCjH;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACxB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GACtC,MAAM,CA8BR"}
@@ -1,4 +1,4 @@
1
- import { $getSelection, $isRangeSelection, $isTextNode } from 'lexical';
1
+ import { $getRoot, $getSelection, $isRangeSelection, $isTextNode } from 'lexical';
2
2
  import { $locate, $replaceMatch, $textGroups } from '../find/findReplaceActions.js';
3
3
  import { wordsIn } from '../spellcheck/spellDictionaries.js';
4
4
  /** The part of a word that counts as word characters at its end. */
@@ -10,7 +10,7 @@ const WORD_CHAR = /[\p{L}\p{M}'’]/u;
10
10
  * correction replaces only the word, and the caret stays right after the
11
11
  * boundary. Returns true if a correction was made.
12
12
  */
13
- export function $correctWordBeforeCaret(table) {
13
+ export function $correctWordBeforeCaret(table, normalize) {
14
14
  const selection = $getSelection();
15
15
  if (!$isRangeSelection(selection) || !selection.isCollapsed())
16
16
  return false;
@@ -26,7 +26,7 @@ export function $correctWordBeforeCaret(table) {
26
26
  const word = WORD_END.exec(body)?.[0];
27
27
  if (!word)
28
28
  return false;
29
- const replacement = table.get(word);
29
+ const replacement = correctionFor(word, table, normalize);
30
30
  if (replacement === undefined || replacement === word)
31
31
  return false;
32
32
  const start = body.length - word.length;
@@ -47,19 +47,37 @@ export function $correctWordBeforeCaret(table) {
47
47
  * word split by formatting is still one word. Each block uses the table for its
48
48
  * direction. Returns how many words were corrected.
49
49
  */
50
- export function $correctDocument(ltr, rtl) {
50
+ export function $correctDocument(ltr, rtl, normalizeRtl) {
51
+ if (normalizeRtl) {
52
+ for (const node of $getRoot().getAllTextNodes()) {
53
+ if (node.getParentOrThrow().getDirection() !== 'rtl')
54
+ continue;
55
+ const text = node.getTextContent();
56
+ const normalized = normalizeRtl(text);
57
+ if (normalized !== text)
58
+ node.setTextContent(normalized);
59
+ }
60
+ }
51
61
  let corrected = 0;
52
62
  for (const group of $textGroups()) {
53
- const table = group[0].getParentOrThrow().getDirection() === 'rtl' ? rtl : ltr;
63
+ const rightToLeft = group[0].getParentOrThrow().getDirection() === 'rtl';
64
+ const table = rightToLeft ? rtl : ltr;
54
65
  const text = group.map((node) => node.getTextContent()).join('');
55
- const spans = wordsIn(text).filter((span) => table.has(span.word) && table.get(span.word) !== span.word);
66
+ const spans = wordsIn(text)
67
+ .map((span) => ({ span, replacement: correctionFor(span.word, table, rightToLeft ? normalizeRtl : undefined) }))
68
+ .filter((item) => item.replacement !== undefined && item.replacement !== item.span.word);
56
69
  // Right to left, so earlier positions stay valid as each word is replaced.
57
- for (const span of spans.reverse()) {
70
+ for (const { span, replacement } of spans.reverse()) {
58
71
  const start = $locate(group, span.start, false);
59
72
  const end = $locate(group, span.end, true);
60
- $replaceMatch({ anchorKey: start.key, anchorOffset: start.offset, focusKey: end.key, focusOffset: end.offset }, table.get(span.word));
73
+ $replaceMatch({ anchorKey: start.key, anchorOffset: start.offset, focusKey: end.key, focusOffset: end.offset }, replacement);
61
74
  corrected += 1;
62
75
  }
63
76
  }
64
77
  return corrected;
65
78
  }
79
+ /** What a word should become: its normalised form, then any table correction for that. */
80
+ function correctionFor(word, table, normalize) {
81
+ const normalized = normalize ? normalize(word) : word;
82
+ return table.get(normalized) ?? (normalized !== word ? normalized : undefined);
83
+ }
package/dist/index.d.ts CHANGED
@@ -11,4 +11,6 @@ export type { Locale, Strings } from './i18n/index.js';
11
11
  export { registerSpellDictionary, hasSpellDictionary, type HunspellFiles, type SpellLanguage } from './spellcheck/spellDictionaries.js';
12
12
  export { localStorageAutoCorrectStore, apiAutoCorrectStore, fileAutoCorrectStore } from './autocorrect/autoCorrectStores.js';
13
13
  export type { AutoCorrectStore, AutoCorrectEntry } from './autocorrect/autoCorrectStores.js';
14
+ export { normalizeUrdu, normalizeUrduCharacters, removeUrduDiacritics, replaceUrduDigits } from './normalization/urduNormalize.js';
15
+ export type { UrduNormalizationOptions } from './normalization/urduNormalize.js';
14
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC1G,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AACzF,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACrI,OAAO,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC1H,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAC1G,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AACzF,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACrI,OAAO,EAAE,4BAA4B,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAC1H,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAChI,YAAY,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC"}
package/dist/index.js CHANGED
@@ -5,3 +5,4 @@ export { DEFAULT_FONT_OPTIONS, URDU_WEB_FONT_OPTIONS, FONT_SIZES_PX } from './fo
5
5
  export { STRINGS, getStrings, useStrings, useUiStrings, UiStringsContext } from './i18n/index.js';
6
6
  export { registerSpellDictionary, hasSpellDictionary } from './spellcheck/spellDictionaries.js';
7
7
  export { localStorageAutoCorrectStore, apiAutoCorrectStore, fileAutoCorrectStore } from './autocorrect/autoCorrectStores.js';
8
+ export { normalizeUrdu, normalizeUrduCharacters, removeUrduDiacritics, replaceUrduDigits } from './normalization/urduNormalize.js';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Urdu character normalisation, ported from urduhack's `normalization/character.py`
3
+ * (MIT licence, https://github.com/urduhack/urduhack). The mapping replaces
4
+ * Arabic and presentation-form letters with the standard Urdu letter, and
5
+ * the tables below keep the same entries and order as the original, so the
6
+ * output matches it character for character.
7
+ */
8
+ /** Replaces Arabic and presentation-form letters with standard Urdu letters, character by character. */
9
+ export declare function normalizeUrduCharacters(text: string): string;
10
+ export declare function removeUrduDiacritics(text: string): string;
11
+ /** Converts Urdu digits to English digits, or the reverse. */
12
+ export declare function replaceUrduDigits(text: string, to: 'english' | 'urdu'): string;
13
+ export interface UrduNormalizationOptions {
14
+ /** Remove harakat. Off by default, since they are meaningful in poetry and religious text. */
15
+ removeDiacritics?: boolean;
16
+ /** Digit style to convert to; 'keep' (the default) leaves digits as they are. */
17
+ digits?: 'keep' | 'english' | 'urdu';
18
+ }
19
+ /**
20
+ * The normalisation urduhack's `normalize` applies, with the diacritic and
21
+ * digit steps made optional. Character mapping always runs.
22
+ */
23
+ export declare function normalizeUrdu(text: string, options?: UrduNormalizationOptions): string;
24
+ //# sourceMappingURL=urduNormalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urduNormalize.d.ts","sourceRoot":"","sources":["../../src/normalization/urduNormalize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA8EH,wGAAwG;AACxG,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAS9E;AAED,MAAM,WAAW,wBAAwB;IACvC,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAK1F"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Urdu character normalisation, ported from urduhack's `normalization/character.py`
3
+ * (MIT licence, https://github.com/urduhack/urduhack). The mapping replaces
4
+ * Arabic and presentation-form letters with the standard Urdu letter, and
5
+ * the tables below keep the same entries and order as the original, so the
6
+ * output matches it character for character.
7
+ */
8
+ const CORRECT_URDU_CHARACTERS = {
9
+ "آ": ["ﺁ", "ﺂ"],
10
+ "أ": ["ﺃ"],
11
+ "ا": ["ﺍ", "ﺎ"],
12
+ "ب": ["ﺏ", "ﺐ", "ﺑ", "ﺒ"],
13
+ "پ": ["ﭖ", "ﭘ", "ﭙ"],
14
+ "ت": ["ﺕ", "ﺖ", "ﺗ", "ﺘ"],
15
+ "ٹ": ["ﭦ", "ﭧ", "ﭨ", "ﭩ"],
16
+ "ث": ["ﺛ", "ﺜ", "ﺚ"],
17
+ "ج": ["ﺝ", "ﺞ", "ﺟ", "ﺠ"],
18
+ "ح": ["ﺡ", "ﺣ", "ﺤ", "ﺢ"],
19
+ "خ": ["ﺧ", "ﺨ", "ﺦ"],
20
+ "د": ["ﺩ", "ﺪ"],
21
+ "ذ": ["ﺬ", "ﺫ"],
22
+ "ر": ["ﺭ", "ﺮ"],
23
+ "ز": ["ﺯ", "ﺰ"],
24
+ "س": ["ﺱ", "ﺲ", "ﺳ", "ﺴ"],
25
+ "ش": ["ﺵ", "ﺶ", "ﺷ", "ﺸ"],
26
+ "ص": ["ﺹ", "ﺺ", "ﺻ", "ﺼ"],
27
+ "ض": ["ﺽ", "ﺾ", "ﺿ", "ﻀ"],
28
+ "ط": ["ﻃ", "ﻄ"],
29
+ "ظ": ["ﻅ", "ﻇ", "ﻈ"],
30
+ "ع": ["ﻉ", "ﻊ", "ﻋ", "ﻌ"],
31
+ "غ": ["ﻍ", "ﻏ", "ﻐ"],
32
+ "ف": ["ﻑ", "ﻒ", "ﻓ", "ﻔ"],
33
+ "ق": ["ﻕ", "ﻖ", "ﻗ", "ﻘ"],
34
+ "ل": ["ﻝ", "ﻞ", "ﻟ", "ﻠ"],
35
+ "م": ["ﻡ", "ﻢ", "ﻣ", "ﻤ"],
36
+ "ن": ["ﻥ", "ﻦ", "ﻧ", "ﻨ"],
37
+ "چ": ["ﭺ", "ﭻ", "ﭼ", "ﭽ"],
38
+ "ڈ": ["ﮈ", "ﮉ"],
39
+ "ڑ": ["ﮍ", "ﮌ"],
40
+ "ژ": ["ﮋ"],
41
+ "ک": ["ﮎ", "ﮏ", "ﮐ", "ﮑ", "ﻛ", "ك"],
42
+ "گ": ["ﮒ", "ﮓ", "ﮔ", "ﮕ"],
43
+ "ں": ["ﮞ", "ﮟ"],
44
+ "و": ["ﻮ", "ﻭ", "ﻮ"],
45
+ "ؤ": ["ﺅ"],
46
+ "ھ": ["ﮪ", "ﮬ", "ﮭ", "ﻬ", "ﻫ", "ﮫ"],
47
+ "ہ": ["ﻩ", "ﮦ", "ﻪ", "ﮧ", "ﮩ", "ﮨ", "ه"],
48
+ "ۂ": [],
49
+ "ۃ": ["ة"],
50
+ "ء": ["ﺀ"],
51
+ "ی": ["ﯼ", "ى", "ﯽ", "ﻰ", "ﻱ", "ﻲ", "ﯾ", "ﯿ", "ي"],
52
+ "ئ": ["ﺋ", "ﺌ"],
53
+ "ے": ["ﮮ", "ﮯ", "ﻳ", "ﻴ"],
54
+ "ۓ": [],
55
+ "۰": ["٠"],
56
+ "۱": ["١"],
57
+ "۲": ["٢"],
58
+ "۳": ["٣"],
59
+ "۴": ["٤"],
60
+ "۵": ["٥"],
61
+ "۶": ["٦"],
62
+ "۷": ["٧"],
63
+ "۸": ["٨"],
64
+ "۹": ["٩"],
65
+ "۔": [],
66
+ "؟": [],
67
+ "٫": [],
68
+ "،": [],
69
+ "لا": ["ﻻ", "ﻼ"],
70
+ "": ["ـ"],
71
+ };
72
+ const TRANSLATOR = new Map();
73
+ for (const [key, values] of Object.entries(CORRECT_URDU_CHARACTERS)) {
74
+ for (const value of values)
75
+ TRANSLATOR.set(value, key);
76
+ }
77
+ /** Combining diacritics (harakat and similar), as urduhack's URDU_DIACRITICS. */
78
+ const DIACRITICS = new Set(['َ', 'ً', 'ٰ', 'ِ', 'ُ', 'ٍ']);
79
+ const ENGLISH_DIGITS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
80
+ const URDU_DIGITS = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
81
+ /** Replaces Arabic and presentation-form letters with standard Urdu letters, character by character. */
82
+ export function normalizeUrduCharacters(text) {
83
+ let out = '';
84
+ for (const char of text)
85
+ out += TRANSLATOR.get(char) ?? char;
86
+ return out;
87
+ }
88
+ export function removeUrduDiacritics(text) {
89
+ let out = '';
90
+ for (const char of text)
91
+ if (!DIACRITICS.has(char))
92
+ out += char;
93
+ return out;
94
+ }
95
+ /** Converts Urdu digits to English digits, or the reverse. */
96
+ export function replaceUrduDigits(text, to) {
97
+ const from = to === 'english' ? URDU_DIGITS : ENGLISH_DIGITS;
98
+ const target = to === 'english' ? ENGLISH_DIGITS : URDU_DIGITS;
99
+ let out = '';
100
+ for (const char of text) {
101
+ const index = from.indexOf(char);
102
+ out += index === -1 ? char : target[index];
103
+ }
104
+ return out;
105
+ }
106
+ /**
107
+ * The normalisation urduhack's `normalize` applies, with the diacritic and
108
+ * digit steps made optional. Character mapping always runs.
109
+ */
110
+ export function normalizeUrdu(text, options = {}) {
111
+ let out = options.removeDiacritics ? removeUrduDiacritics(text) : text;
112
+ out = normalizeUrduCharacters(out);
113
+ if (options.digits === 'english' || options.digits === 'urdu')
114
+ out = replaceUrduDigits(out, options.digits);
115
+ return out;
116
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inshapardaz/likhari-react",
3
- "version": "0.1.21-dev.201",
3
+ "version": "0.1.21-dev.202",
4
4
  "description": "React implementation of the Likhari editor, built on @lexical/react.",
5
5
  "license": "MIT",
6
6
  "repository": {