@tiptap/extension-typography 3.22.1 → 3.22.2

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.
package/dist/index.cjs CHANGED
@@ -166,6 +166,7 @@ var Typography = import_core.Extension.create({
166
166
  };
167
167
  },
168
168
  addInputRules() {
169
+ var _a, _b;
169
170
  const rules = [];
170
171
  if (this.options.emDash !== false) {
171
172
  rules.push(emDash(this.options.emDash));
@@ -173,17 +174,36 @@ var Typography = import_core.Extension.create({
173
174
  if (this.options.ellipsis !== false) {
174
175
  rules.push(ellipsis(this.options.ellipsis));
175
176
  }
176
- if (this.options.openDoubleQuote !== false) {
177
- rules.push(openDoubleQuote(this.options.openDoubleQuote));
177
+ const isRTL = this.editor.options.textDirection === "rtl";
178
+ if ((_a = this.options.doubleQuotes) == null ? void 0 : _a.rtl) {
179
+ const { open, close } = this.options.doubleQuotes.rtl;
180
+ rules.push(openDoubleQuote(open));
181
+ rules.push(closeDoubleQuote(close));
182
+ } else if (isRTL) {
183
+ rules.push(openDoubleQuote("\u201D"));
184
+ rules.push(closeDoubleQuote("\u201C"));
185
+ } else {
186
+ if (this.options.openDoubleQuote !== false) {
187
+ rules.push(openDoubleQuote(this.options.openDoubleQuote));
188
+ }
189
+ if (this.options.closeDoubleQuote !== false) {
190
+ rules.push(closeDoubleQuote(this.options.closeDoubleQuote));
191
+ }
178
192
  }
179
- if (this.options.closeDoubleQuote !== false) {
180
- rules.push(closeDoubleQuote(this.options.closeDoubleQuote));
181
- }
182
- if (this.options.openSingleQuote !== false) {
183
- rules.push(openSingleQuote(this.options.openSingleQuote));
184
- }
185
- if (this.options.closeSingleQuote !== false) {
186
- rules.push(closeSingleQuote(this.options.closeSingleQuote));
193
+ if ((_b = this.options.singleQuotes) == null ? void 0 : _b.rtl) {
194
+ const { open, close } = this.options.singleQuotes.rtl;
195
+ rules.push(openSingleQuote(open));
196
+ rules.push(closeSingleQuote(close));
197
+ } else if (isRTL) {
198
+ rules.push(openSingleQuote("\u2019"));
199
+ rules.push(closeSingleQuote("\u2018"));
200
+ } else {
201
+ if (this.options.openSingleQuote !== false) {
202
+ rules.push(openSingleQuote(this.options.openSingleQuote));
203
+ }
204
+ if (this.options.closeSingleQuote !== false) {
205
+ rules.push(closeSingleQuote(this.options.closeSingleQuote));
206
+ }
187
207
  }
188
208
  if (this.options.leftArrow !== false) {
189
209
  rules.push(leftArrow(this.options.leftArrow));
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/typography.ts"],"sourcesContent":["import { Typography } from './typography.js'\n\nexport * from './typography.js'\n\nexport default Typography\n","import { Extension, textInputRule } from '@tiptap/core'\n\nexport interface TypographyOptions {\n /**\n * The em dash character.\n * @default '—'\n */\n emDash: false | string\n\n /**\n * The ellipsis character.\n * @default '…'\n */\n ellipsis: false | string\n\n /**\n * The open double quote character.\n * @default '“'\n */\n openDoubleQuote: false | string\n\n /**\n * The close double quote character.\n * @default '”'\n */\n closeDoubleQuote: false | string\n\n /**\n * The open single quote character.\n * @default '‘'\n */\n openSingleQuote: false | string\n\n /**\n * The close single quote character.\n * @default '’'\n */\n closeSingleQuote: false | string\n\n /**\n * The left arrow character.\n * @default '←'\n */\n leftArrow: false | string\n\n /**\n * The right arrow character.\n * @default '→'\n */\n rightArrow: false | string\n\n /**\n * The copyright character.\n * @default '©'\n */\n copyright: false | string\n\n /**\n * The trademark character.\n * @default '™'\n */\n trademark: false | string\n\n /**\n * The servicemark character.\n * @default '℠'\n */\n servicemark: false | string\n\n /**\n * The registered trademark character.\n * @default '®'\n */\n registeredTrademark: false | string\n\n /**\n * The one half character.\n * @default '½'\n */\n oneHalf: false | string\n\n /**\n * The plus minus character.\n * @default '±'\n */\n plusMinus: false | string\n\n /**\n * The not equal character.\n * @default '≠'\n */\n notEqual: false | string\n\n /**\n * The laquo character.\n * @default '«'\n */\n laquo: false | string\n\n /**\n * The raquo character.\n * @default '»'\n */\n raquo: false | string\n\n /**\n * The multiplication character.\n * @default '×'\n */\n multiplication: false | string\n\n /**\n * The superscript two character.\n * @default '²'\n */\n superscriptTwo: false | string\n\n /**\n * The superscript three character.\n * @default '³'\n */\n superscriptThree: false | string\n\n /**\n * The one quarter character.\n * @default '¼'\n */\n oneQuarter: false | string\n\n /**\n * The three quarters character.\n * @default '¾'\n */\n threeQuarters: false | string\n}\n\nexport const emDash = (override?: string) =>\n textInputRule({\n find: /--$/,\n replace: override ?? '—',\n })\n\nexport const ellipsis = (override?: string) =>\n textInputRule({\n find: /\\.\\.\\.$/,\n replace: override ?? '…',\n })\n\nexport const openDoubleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(\")$/,\n replace: override ?? '“',\n })\n\nexport const closeDoubleQuote = (override?: string) =>\n textInputRule({\n find: /\"$/,\n replace: override ?? '”',\n })\n\nexport const openSingleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(')$/,\n replace: override ?? '‘',\n })\n\nexport const closeSingleQuote = (override?: string) =>\n textInputRule({\n find: /'$/,\n replace: override ?? '’',\n })\n\nexport const leftArrow = (override?: string) =>\n textInputRule({\n find: /<-$/,\n replace: override ?? '←',\n })\n\nexport const rightArrow = (override?: string) =>\n textInputRule({\n find: /->$/,\n replace: override ?? '→',\n })\n\nexport const copyright = (override?: string) =>\n textInputRule({\n find: /\\(c\\)$/,\n replace: override ?? '©',\n })\n\nexport const trademark = (override?: string) =>\n textInputRule({\n find: /\\(tm\\)$/,\n replace: override ?? '™',\n })\n\nexport const servicemark = (override?: string) =>\n textInputRule({\n find: /\\(sm\\)$/,\n replace: override ?? '℠',\n })\n\nexport const registeredTrademark = (override?: string) =>\n textInputRule({\n find: /\\(r\\)$/,\n replace: override ?? '®',\n })\n\nexport const oneHalf = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/2)\\s$/,\n replace: override ?? '½',\n })\n\nexport const plusMinus = (override?: string) =>\n textInputRule({\n find: /\\+\\/-$/,\n replace: override ?? '±',\n })\n\nexport const notEqual = (override?: string) =>\n textInputRule({\n find: /!=$/,\n replace: override ?? '≠',\n })\n\nexport const laquo = (override?: string) =>\n textInputRule({\n find: /<<$/,\n replace: override ?? '«',\n })\n\nexport const raquo = (override?: string) =>\n textInputRule({\n find: />>$/,\n replace: override ?? '»',\n })\n\nexport const multiplication = (override?: string) =>\n textInputRule({\n find: /\\d+\\s?([*x])\\s?\\d+$/,\n replace: override ?? '×',\n })\n\nexport const superscriptTwo = (override?: string) =>\n textInputRule({\n find: /\\^2$/,\n replace: override ?? '²',\n })\n\nexport const superscriptThree = (override?: string) =>\n textInputRule({\n find: /\\^3$/,\n replace: override ?? '³',\n })\n\nexport const oneQuarter = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/4)\\s$/,\n replace: override ?? '¼',\n })\n\nexport const threeQuarters = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(3\\/4)\\s$/,\n replace: override ?? '¾',\n })\n\n/**\n * This extension allows you to add typography replacements for specific characters.\n * @see https://www.tiptap.dev/api/extensions/typography\n */\nexport const Typography = Extension.create<TypographyOptions>({\n name: 'typography',\n\n addOptions() {\n return {\n closeDoubleQuote: '”',\n closeSingleQuote: '’',\n copyright: '©',\n ellipsis: '…',\n emDash: '—',\n laquo: '«',\n leftArrow: '←',\n multiplication: '×',\n notEqual: '≠',\n oneHalf: '½',\n oneQuarter: '¼',\n openDoubleQuote: '“',\n openSingleQuote: '‘',\n plusMinus: '±',\n raquo: '»',\n registeredTrademark: '®',\n rightArrow: '→',\n servicemark: '℠',\n superscriptThree: '³',\n superscriptTwo: '²',\n threeQuarters: '¾',\n trademark: '™',\n }\n },\n\n addInputRules() {\n const rules = []\n\n if (this.options.emDash !== false) {\n rules.push(emDash(this.options.emDash))\n }\n\n if (this.options.ellipsis !== false) {\n rules.push(ellipsis(this.options.ellipsis))\n }\n\n if (this.options.openDoubleQuote !== false) {\n rules.push(openDoubleQuote(this.options.openDoubleQuote))\n }\n\n if (this.options.closeDoubleQuote !== false) {\n rules.push(closeDoubleQuote(this.options.closeDoubleQuote))\n }\n\n if (this.options.openSingleQuote !== false) {\n rules.push(openSingleQuote(this.options.openSingleQuote))\n }\n\n if (this.options.closeSingleQuote !== false) {\n rules.push(closeSingleQuote(this.options.closeSingleQuote))\n }\n\n if (this.options.leftArrow !== false) {\n rules.push(leftArrow(this.options.leftArrow))\n }\n\n if (this.options.rightArrow !== false) {\n rules.push(rightArrow(this.options.rightArrow))\n }\n\n if (this.options.copyright !== false) {\n rules.push(copyright(this.options.copyright))\n }\n\n if (this.options.trademark !== false) {\n rules.push(trademark(this.options.trademark))\n }\n\n if (this.options.servicemark !== false) {\n rules.push(servicemark(this.options.servicemark))\n }\n\n if (this.options.registeredTrademark !== false) {\n rules.push(registeredTrademark(this.options.registeredTrademark))\n }\n\n if (this.options.oneHalf !== false) {\n rules.push(oneHalf(this.options.oneHalf))\n }\n\n if (this.options.plusMinus !== false) {\n rules.push(plusMinus(this.options.plusMinus))\n }\n\n if (this.options.notEqual !== false) {\n rules.push(notEqual(this.options.notEqual))\n }\n\n if (this.options.laquo !== false) {\n rules.push(laquo(this.options.laquo))\n }\n\n if (this.options.raquo !== false) {\n rules.push(raquo(this.options.raquo))\n }\n\n if (this.options.multiplication !== false) {\n rules.push(multiplication(this.options.multiplication))\n }\n\n if (this.options.superscriptTwo !== false) {\n rules.push(superscriptTwo(this.options.superscriptTwo))\n }\n\n if (this.options.superscriptThree !== false) {\n rules.push(superscriptThree(this.options.superscriptThree))\n }\n\n if (this.options.oneQuarter !== false) {\n rules.push(oneQuarter(this.options.oneQuarter))\n }\n\n if (this.options.threeQuarters !== false) {\n rules.push(threeQuarters(this.options.threeQuarters))\n }\n\n return rules\n },\n})\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/typography.ts"],"sourcesContent":["import { Typography } from './typography.js'\n\nexport * from './typography.js'\n\nexport default Typography\n","import { Extension, textInputRule } from '@tiptap/core'\n\n/**\n * Configuration for directional quotes (open/close pair).\n */\nexport interface DirectionalQuotes {\n open: string\n close: string\n}\n\nexport interface TypographyOptions {\n /**\n * The em dash character.\n * @default '—'\n */\n emDash: false | string\n\n /**\n * The ellipsis character.\n * @default '…'\n */\n ellipsis: false | string\n\n /**\n * The open double quote character.\n * @default '“'\n */\n openDoubleQuote: false | string\n\n /**\n * The close double quote character.\n * @default '”'\n */\n closeDoubleQuote: false | string\n\n /**\n * The open single quote character.\n * @default '‘'\n */\n openSingleQuote: false | string\n\n /**\n * The close single quote character.\n * @default '’'\n */\n closeSingleQuote: false | string\n\n /**\n * The left arrow character.\n * @default '←'\n */\n leftArrow: false | string\n\n /**\n * The right arrow character.\n * @default '→'\n */\n rightArrow: false | string\n\n /**\n * The copyright character.\n * @default '©'\n */\n copyright: false | string\n\n /**\n * The trademark character.\n * @default '™'\n */\n trademark: false | string\n\n /**\n * The servicemark character.\n * @default '℠'\n */\n servicemark: false | string\n\n /**\n * The registered trademark character.\n * @default '®'\n */\n registeredTrademark: false | string\n\n /**\n * The one half character.\n * @default '½'\n */\n oneHalf: false | string\n\n /**\n * The plus minus character.\n * @default '±'\n */\n plusMinus: false | string\n\n /**\n * The not equal character.\n * @default '≠'\n */\n notEqual: false | string\n\n /**\n * The laquo character.\n * @default '«'\n */\n laquo: false | string\n\n /**\n * The raquo character.\n * @default '»'\n */\n raquo: false | string\n\n /**\n * The multiplication character.\n * @default '×'\n */\n multiplication: false | string\n\n /**\n * The superscript two character.\n * @default '²'\n */\n superscriptTwo: false | string\n\n /**\n * The superscript three character.\n * @default '³'\n */\n superscriptThree: false | string\n\n /**\n * The one quarter character.\n * @default '¼'\n */\n oneQuarter: false | string\n\n /**\n * The three quarters character.\n * @default '¾'\n */\n threeQuarters: false | string\n\n /**\n * Directional double quotes configuration.\n * Use this for explicit LTR/RTL quote control.\n * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.\n * @example\n * ```ts\n * Typography.configure({\n * doubleQuotes: {\n * rtl: { open: '\\u201D', close: '\\u201C' } // Swapped for RTL\n * }\n * })\n * ```\n */\n doubleQuotes?: {\n rtl?: DirectionalQuotes\n }\n\n /**\n * Directional single quotes configuration.\n * Use this for explicit LTR/RTL quote control.\n * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.\n * @example\n * ```ts\n * Typography.configure({\n * singleQuotes: {\n * rtl: { open: '\\u2019', close: '\\u2018' } // Swapped for RTL\n * }\n * })\n * ```\n */\n singleQuotes?: {\n rtl?: DirectionalQuotes\n }\n}\n\nexport const emDash = (override?: string) =>\n textInputRule({\n find: /--$/,\n replace: override ?? '—',\n })\n\nexport const ellipsis = (override?: string) =>\n textInputRule({\n find: /\\.\\.\\.$/,\n replace: override ?? '…',\n })\n\nexport const openDoubleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(\")$/,\n replace: override ?? '“',\n })\n\nexport const closeDoubleQuote = (override?: string) =>\n textInputRule({\n find: /\"$/,\n replace: override ?? '”',\n })\n\nexport const openSingleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(')$/,\n replace: override ?? '‘',\n })\n\nexport const closeSingleQuote = (override?: string) =>\n textInputRule({\n find: /'$/,\n replace: override ?? '’',\n })\n\nexport const leftArrow = (override?: string) =>\n textInputRule({\n find: /<-$/,\n replace: override ?? '←',\n })\n\nexport const rightArrow = (override?: string) =>\n textInputRule({\n find: /->$/,\n replace: override ?? '→',\n })\n\nexport const copyright = (override?: string) =>\n textInputRule({\n find: /\\(c\\)$/,\n replace: override ?? '©',\n })\n\nexport const trademark = (override?: string) =>\n textInputRule({\n find: /\\(tm\\)$/,\n replace: override ?? '™',\n })\n\nexport const servicemark = (override?: string) =>\n textInputRule({\n find: /\\(sm\\)$/,\n replace: override ?? '℠',\n })\n\nexport const registeredTrademark = (override?: string) =>\n textInputRule({\n find: /\\(r\\)$/,\n replace: override ?? '®',\n })\n\nexport const oneHalf = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/2)\\s$/,\n replace: override ?? '½',\n })\n\nexport const plusMinus = (override?: string) =>\n textInputRule({\n find: /\\+\\/-$/,\n replace: override ?? '±',\n })\n\nexport const notEqual = (override?: string) =>\n textInputRule({\n find: /!=$/,\n replace: override ?? '≠',\n })\n\nexport const laquo = (override?: string) =>\n textInputRule({\n find: /<<$/,\n replace: override ?? '«',\n })\n\nexport const raquo = (override?: string) =>\n textInputRule({\n find: />>$/,\n replace: override ?? '»',\n })\n\nexport const multiplication = (override?: string) =>\n textInputRule({\n find: /\\d+\\s?([*x])\\s?\\d+$/,\n replace: override ?? '×',\n })\n\nexport const superscriptTwo = (override?: string) =>\n textInputRule({\n find: /\\^2$/,\n replace: override ?? '²',\n })\n\nexport const superscriptThree = (override?: string) =>\n textInputRule({\n find: /\\^3$/,\n replace: override ?? '³',\n })\n\nexport const oneQuarter = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/4)\\s$/,\n replace: override ?? '¼',\n })\n\nexport const threeQuarters = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(3\\/4)\\s$/,\n replace: override ?? '¾',\n })\n\n/**\n * This extension allows you to add typography replacements for specific characters.\n * @see https://www.tiptap.dev/api/extensions/typography\n */\nexport const Typography = Extension.create<TypographyOptions>({\n name: 'typography',\n\n addOptions() {\n return {\n closeDoubleQuote: '”',\n closeSingleQuote: '’',\n copyright: '©',\n ellipsis: '…',\n emDash: '—',\n laquo: '«',\n leftArrow: '←',\n multiplication: '×',\n notEqual: '≠',\n oneHalf: '½',\n oneQuarter: '¼',\n openDoubleQuote: '“',\n openSingleQuote: '‘',\n plusMinus: '±',\n raquo: '»',\n registeredTrademark: '®',\n rightArrow: '→',\n servicemark: '℠',\n superscriptThree: '³',\n superscriptTwo: '²',\n threeQuarters: '¾',\n trademark: '™',\n }\n },\n\n addInputRules() {\n const rules = []\n\n if (this.options.emDash !== false) {\n rules.push(emDash(this.options.emDash))\n }\n\n if (this.options.ellipsis !== false) {\n rules.push(ellipsis(this.options.ellipsis))\n }\n\n // Determine if RTL mode is active based on explicit config or editor option\n const isRTL = this.editor.options.textDirection === 'rtl'\n\n // Double quotes: use explicit RTL config if provided, otherwise use automatic RTL detection\n if (this.options.doubleQuotes?.rtl) {\n const { open, close } = this.options.doubleQuotes.rtl\n\n rules.push(openDoubleQuote(open))\n rules.push(closeDoubleQuote(close))\n } else if (isRTL) {\n // Automatic RTL detection: swap open and close quotes\n rules.push(openDoubleQuote('\\u201D')) // Right double quotation mark\n rules.push(closeDoubleQuote('\\u201C')) // Left double quotation mark\n } else {\n if (this.options.openDoubleQuote !== false) {\n rules.push(openDoubleQuote(this.options.openDoubleQuote))\n }\n\n if (this.options.closeDoubleQuote !== false) {\n rules.push(closeDoubleQuote(this.options.closeDoubleQuote))\n }\n }\n\n // Single quotes: use explicit RTL config if provided, otherwise use automatic RTL detection\n if (this.options.singleQuotes?.rtl) {\n const { open, close } = this.options.singleQuotes.rtl\n\n rules.push(openSingleQuote(open))\n rules.push(closeSingleQuote(close))\n } else if (isRTL) {\n // Automatic RTL detection: swap open and close quotes\n rules.push(openSingleQuote('\\u2019')) // Right single quotation mark\n rules.push(closeSingleQuote('\\u2018')) // Left single quotation mark\n } else {\n if (this.options.openSingleQuote !== false) {\n rules.push(openSingleQuote(this.options.openSingleQuote))\n }\n\n if (this.options.closeSingleQuote !== false) {\n rules.push(closeSingleQuote(this.options.closeSingleQuote))\n }\n }\n\n if (this.options.leftArrow !== false) {\n rules.push(leftArrow(this.options.leftArrow))\n }\n\n if (this.options.rightArrow !== false) {\n rules.push(rightArrow(this.options.rightArrow))\n }\n\n if (this.options.copyright !== false) {\n rules.push(copyright(this.options.copyright))\n }\n\n if (this.options.trademark !== false) {\n rules.push(trademark(this.options.trademark))\n }\n\n if (this.options.servicemark !== false) {\n rules.push(servicemark(this.options.servicemark))\n }\n\n if (this.options.registeredTrademark !== false) {\n rules.push(registeredTrademark(this.options.registeredTrademark))\n }\n\n if (this.options.oneHalf !== false) {\n rules.push(oneHalf(this.options.oneHalf))\n }\n\n if (this.options.plusMinus !== false) {\n rules.push(plusMinus(this.options.plusMinus))\n }\n\n if (this.options.notEqual !== false) {\n rules.push(notEqual(this.options.notEqual))\n }\n\n if (this.options.laquo !== false) {\n rules.push(laquo(this.options.laquo))\n }\n\n if (this.options.raquo !== false) {\n rules.push(raquo(this.options.raquo))\n }\n\n if (this.options.multiplication !== false) {\n rules.push(multiplication(this.options.multiplication))\n }\n\n if (this.options.superscriptTwo !== false) {\n rules.push(superscriptTwo(this.options.superscriptTwo))\n }\n\n if (this.options.superscriptThree !== false) {\n rules.push(superscriptThree(this.options.superscriptThree))\n }\n\n if (this.options.oneQuarter !== false) {\n rules.push(oneQuarter(this.options.oneQuarter))\n }\n\n if (this.options.threeQuarters !== false) {\n rules.push(threeQuarters(this.options.threeQuarters))\n }\n\n return rules\n },\n})\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,13 @@
1
1
  import * as _tiptap_core from '@tiptap/core';
2
2
  import { Extension } from '@tiptap/core';
3
3
 
4
+ /**
5
+ * Configuration for directional quotes (open/close pair).
6
+ */
7
+ interface DirectionalQuotes {
8
+ open: string;
9
+ close: string;
10
+ }
4
11
  interface TypographyOptions {
5
12
  /**
6
13
  * The em dash character.
@@ -112,6 +119,38 @@ interface TypographyOptions {
112
119
  * @default '¾'
113
120
  */
114
121
  threeQuarters: false | string;
122
+ /**
123
+ * Directional double quotes configuration.
124
+ * Use this for explicit LTR/RTL quote control.
125
+ * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.
126
+ * @example
127
+ * ```ts
128
+ * Typography.configure({
129
+ * doubleQuotes: {
130
+ * rtl: { open: '\u201D', close: '\u201C' } // Swapped for RTL
131
+ * }
132
+ * })
133
+ * ```
134
+ */
135
+ doubleQuotes?: {
136
+ rtl?: DirectionalQuotes;
137
+ };
138
+ /**
139
+ * Directional single quotes configuration.
140
+ * Use this for explicit LTR/RTL quote control.
141
+ * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.
142
+ * @example
143
+ * ```ts
144
+ * Typography.configure({
145
+ * singleQuotes: {
146
+ * rtl: { open: '\u2019', close: '\u2018' } // Swapped for RTL
147
+ * }
148
+ * })
149
+ * ```
150
+ */
151
+ singleQuotes?: {
152
+ rtl?: DirectionalQuotes;
153
+ };
115
154
  }
116
155
  declare const emDash: (override?: string) => _tiptap_core.InputRule;
117
156
  declare const ellipsis: (override?: string) => _tiptap_core.InputRule;
@@ -141,4 +180,4 @@ declare const threeQuarters: (override?: string) => _tiptap_core.InputRule;
141
180
  */
142
181
  declare const Typography: Extension<TypographyOptions, any>;
143
182
 
144
- export { Typography, type TypographyOptions, closeDoubleQuote, closeSingleQuote, copyright, Typography as default, ellipsis, emDash, laquo, leftArrow, multiplication, notEqual, oneHalf, oneQuarter, openDoubleQuote, openSingleQuote, plusMinus, raquo, registeredTrademark, rightArrow, servicemark, superscriptThree, superscriptTwo, threeQuarters, trademark };
183
+ export { type DirectionalQuotes, Typography, type TypographyOptions, closeDoubleQuote, closeSingleQuote, copyright, Typography as default, ellipsis, emDash, laquo, leftArrow, multiplication, notEqual, oneHalf, oneQuarter, openDoubleQuote, openSingleQuote, plusMinus, raquo, registeredTrademark, rightArrow, servicemark, superscriptThree, superscriptTwo, threeQuarters, trademark };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  import * as _tiptap_core from '@tiptap/core';
2
2
  import { Extension } from '@tiptap/core';
3
3
 
4
+ /**
5
+ * Configuration for directional quotes (open/close pair).
6
+ */
7
+ interface DirectionalQuotes {
8
+ open: string;
9
+ close: string;
10
+ }
4
11
  interface TypographyOptions {
5
12
  /**
6
13
  * The em dash character.
@@ -112,6 +119,38 @@ interface TypographyOptions {
112
119
  * @default '¾'
113
120
  */
114
121
  threeQuarters: false | string;
122
+ /**
123
+ * Directional double quotes configuration.
124
+ * Use this for explicit LTR/RTL quote control.
125
+ * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.
126
+ * @example
127
+ * ```ts
128
+ * Typography.configure({
129
+ * doubleQuotes: {
130
+ * rtl: { open: '\u201D', close: '\u201C' } // Swapped for RTL
131
+ * }
132
+ * })
133
+ * ```
134
+ */
135
+ doubleQuotes?: {
136
+ rtl?: DirectionalQuotes;
137
+ };
138
+ /**
139
+ * Directional single quotes configuration.
140
+ * Use this for explicit LTR/RTL quote control.
141
+ * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.
142
+ * @example
143
+ * ```ts
144
+ * Typography.configure({
145
+ * singleQuotes: {
146
+ * rtl: { open: '\u2019', close: '\u2018' } // Swapped for RTL
147
+ * }
148
+ * })
149
+ * ```
150
+ */
151
+ singleQuotes?: {
152
+ rtl?: DirectionalQuotes;
153
+ };
115
154
  }
116
155
  declare const emDash: (override?: string) => _tiptap_core.InputRule;
117
156
  declare const ellipsis: (override?: string) => _tiptap_core.InputRule;
@@ -141,4 +180,4 @@ declare const threeQuarters: (override?: string) => _tiptap_core.InputRule;
141
180
  */
142
181
  declare const Typography: Extension<TypographyOptions, any>;
143
182
 
144
- export { Typography, type TypographyOptions, closeDoubleQuote, closeSingleQuote, copyright, Typography as default, ellipsis, emDash, laquo, leftArrow, multiplication, notEqual, oneHalf, oneQuarter, openDoubleQuote, openSingleQuote, plusMinus, raquo, registeredTrademark, rightArrow, servicemark, superscriptThree, superscriptTwo, threeQuarters, trademark };
183
+ export { type DirectionalQuotes, Typography, type TypographyOptions, closeDoubleQuote, closeSingleQuote, copyright, Typography as default, ellipsis, emDash, laquo, leftArrow, multiplication, notEqual, oneHalf, oneQuarter, openDoubleQuote, openSingleQuote, plusMinus, raquo, registeredTrademark, rightArrow, servicemark, superscriptThree, superscriptTwo, threeQuarters, trademark };
package/dist/index.js CHANGED
@@ -117,6 +117,7 @@ var Typography = Extension.create({
117
117
  };
118
118
  },
119
119
  addInputRules() {
120
+ var _a, _b;
120
121
  const rules = [];
121
122
  if (this.options.emDash !== false) {
122
123
  rules.push(emDash(this.options.emDash));
@@ -124,17 +125,36 @@ var Typography = Extension.create({
124
125
  if (this.options.ellipsis !== false) {
125
126
  rules.push(ellipsis(this.options.ellipsis));
126
127
  }
127
- if (this.options.openDoubleQuote !== false) {
128
- rules.push(openDoubleQuote(this.options.openDoubleQuote));
129
- }
130
- if (this.options.closeDoubleQuote !== false) {
131
- rules.push(closeDoubleQuote(this.options.closeDoubleQuote));
132
- }
133
- if (this.options.openSingleQuote !== false) {
134
- rules.push(openSingleQuote(this.options.openSingleQuote));
135
- }
136
- if (this.options.closeSingleQuote !== false) {
137
- rules.push(closeSingleQuote(this.options.closeSingleQuote));
128
+ const isRTL = this.editor.options.textDirection === "rtl";
129
+ if ((_a = this.options.doubleQuotes) == null ? void 0 : _a.rtl) {
130
+ const { open, close } = this.options.doubleQuotes.rtl;
131
+ rules.push(openDoubleQuote(open));
132
+ rules.push(closeDoubleQuote(close));
133
+ } else if (isRTL) {
134
+ rules.push(openDoubleQuote("\u201D"));
135
+ rules.push(closeDoubleQuote("\u201C"));
136
+ } else {
137
+ if (this.options.openDoubleQuote !== false) {
138
+ rules.push(openDoubleQuote(this.options.openDoubleQuote));
139
+ }
140
+ if (this.options.closeDoubleQuote !== false) {
141
+ rules.push(closeDoubleQuote(this.options.closeDoubleQuote));
142
+ }
143
+ }
144
+ if ((_b = this.options.singleQuotes) == null ? void 0 : _b.rtl) {
145
+ const { open, close } = this.options.singleQuotes.rtl;
146
+ rules.push(openSingleQuote(open));
147
+ rules.push(closeSingleQuote(close));
148
+ } else if (isRTL) {
149
+ rules.push(openSingleQuote("\u2019"));
150
+ rules.push(closeSingleQuote("\u2018"));
151
+ } else {
152
+ if (this.options.openSingleQuote !== false) {
153
+ rules.push(openSingleQuote(this.options.openSingleQuote));
154
+ }
155
+ if (this.options.closeSingleQuote !== false) {
156
+ rules.push(closeSingleQuote(this.options.closeSingleQuote));
157
+ }
138
158
  }
139
159
  if (this.options.leftArrow !== false) {
140
160
  rules.push(leftArrow(this.options.leftArrow));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/typography.ts","../src/index.ts"],"sourcesContent":["import { Extension, textInputRule } from '@tiptap/core'\n\nexport interface TypographyOptions {\n /**\n * The em dash character.\n * @default '—'\n */\n emDash: false | string\n\n /**\n * The ellipsis character.\n * @default '…'\n */\n ellipsis: false | string\n\n /**\n * The open double quote character.\n * @default '“'\n */\n openDoubleQuote: false | string\n\n /**\n * The close double quote character.\n * @default '”'\n */\n closeDoubleQuote: false | string\n\n /**\n * The open single quote character.\n * @default '‘'\n */\n openSingleQuote: false | string\n\n /**\n * The close single quote character.\n * @default '’'\n */\n closeSingleQuote: false | string\n\n /**\n * The left arrow character.\n * @default '←'\n */\n leftArrow: false | string\n\n /**\n * The right arrow character.\n * @default '→'\n */\n rightArrow: false | string\n\n /**\n * The copyright character.\n * @default '©'\n */\n copyright: false | string\n\n /**\n * The trademark character.\n * @default '™'\n */\n trademark: false | string\n\n /**\n * The servicemark character.\n * @default '℠'\n */\n servicemark: false | string\n\n /**\n * The registered trademark character.\n * @default '®'\n */\n registeredTrademark: false | string\n\n /**\n * The one half character.\n * @default '½'\n */\n oneHalf: false | string\n\n /**\n * The plus minus character.\n * @default '±'\n */\n plusMinus: false | string\n\n /**\n * The not equal character.\n * @default '≠'\n */\n notEqual: false | string\n\n /**\n * The laquo character.\n * @default '«'\n */\n laquo: false | string\n\n /**\n * The raquo character.\n * @default '»'\n */\n raquo: false | string\n\n /**\n * The multiplication character.\n * @default '×'\n */\n multiplication: false | string\n\n /**\n * The superscript two character.\n * @default '²'\n */\n superscriptTwo: false | string\n\n /**\n * The superscript three character.\n * @default '³'\n */\n superscriptThree: false | string\n\n /**\n * The one quarter character.\n * @default '¼'\n */\n oneQuarter: false | string\n\n /**\n * The three quarters character.\n * @default '¾'\n */\n threeQuarters: false | string\n}\n\nexport const emDash = (override?: string) =>\n textInputRule({\n find: /--$/,\n replace: override ?? '—',\n })\n\nexport const ellipsis = (override?: string) =>\n textInputRule({\n find: /\\.\\.\\.$/,\n replace: override ?? '…',\n })\n\nexport const openDoubleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(\")$/,\n replace: override ?? '“',\n })\n\nexport const closeDoubleQuote = (override?: string) =>\n textInputRule({\n find: /\"$/,\n replace: override ?? '”',\n })\n\nexport const openSingleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(')$/,\n replace: override ?? '‘',\n })\n\nexport const closeSingleQuote = (override?: string) =>\n textInputRule({\n find: /'$/,\n replace: override ?? '’',\n })\n\nexport const leftArrow = (override?: string) =>\n textInputRule({\n find: /<-$/,\n replace: override ?? '←',\n })\n\nexport const rightArrow = (override?: string) =>\n textInputRule({\n find: /->$/,\n replace: override ?? '→',\n })\n\nexport const copyright = (override?: string) =>\n textInputRule({\n find: /\\(c\\)$/,\n replace: override ?? '©',\n })\n\nexport const trademark = (override?: string) =>\n textInputRule({\n find: /\\(tm\\)$/,\n replace: override ?? '™',\n })\n\nexport const servicemark = (override?: string) =>\n textInputRule({\n find: /\\(sm\\)$/,\n replace: override ?? '℠',\n })\n\nexport const registeredTrademark = (override?: string) =>\n textInputRule({\n find: /\\(r\\)$/,\n replace: override ?? '®',\n })\n\nexport const oneHalf = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/2)\\s$/,\n replace: override ?? '½',\n })\n\nexport const plusMinus = (override?: string) =>\n textInputRule({\n find: /\\+\\/-$/,\n replace: override ?? '±',\n })\n\nexport const notEqual = (override?: string) =>\n textInputRule({\n find: /!=$/,\n replace: override ?? '≠',\n })\n\nexport const laquo = (override?: string) =>\n textInputRule({\n find: /<<$/,\n replace: override ?? '«',\n })\n\nexport const raquo = (override?: string) =>\n textInputRule({\n find: />>$/,\n replace: override ?? '»',\n })\n\nexport const multiplication = (override?: string) =>\n textInputRule({\n find: /\\d+\\s?([*x])\\s?\\d+$/,\n replace: override ?? '×',\n })\n\nexport const superscriptTwo = (override?: string) =>\n textInputRule({\n find: /\\^2$/,\n replace: override ?? '²',\n })\n\nexport const superscriptThree = (override?: string) =>\n textInputRule({\n find: /\\^3$/,\n replace: override ?? '³',\n })\n\nexport const oneQuarter = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/4)\\s$/,\n replace: override ?? '¼',\n })\n\nexport const threeQuarters = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(3\\/4)\\s$/,\n replace: override ?? '¾',\n })\n\n/**\n * This extension allows you to add typography replacements for specific characters.\n * @see https://www.tiptap.dev/api/extensions/typography\n */\nexport const Typography = Extension.create<TypographyOptions>({\n name: 'typography',\n\n addOptions() {\n return {\n closeDoubleQuote: '”',\n closeSingleQuote: '’',\n copyright: '©',\n ellipsis: '…',\n emDash: '—',\n laquo: '«',\n leftArrow: '←',\n multiplication: '×',\n notEqual: '≠',\n oneHalf: '½',\n oneQuarter: '¼',\n openDoubleQuote: '“',\n openSingleQuote: '‘',\n plusMinus: '±',\n raquo: '»',\n registeredTrademark: '®',\n rightArrow: '→',\n servicemark: '℠',\n superscriptThree: '³',\n superscriptTwo: '²',\n threeQuarters: '¾',\n trademark: '™',\n }\n },\n\n addInputRules() {\n const rules = []\n\n if (this.options.emDash !== false) {\n rules.push(emDash(this.options.emDash))\n }\n\n if (this.options.ellipsis !== false) {\n rules.push(ellipsis(this.options.ellipsis))\n }\n\n if (this.options.openDoubleQuote !== false) {\n rules.push(openDoubleQuote(this.options.openDoubleQuote))\n }\n\n if (this.options.closeDoubleQuote !== false) {\n rules.push(closeDoubleQuote(this.options.closeDoubleQuote))\n }\n\n if (this.options.openSingleQuote !== false) {\n rules.push(openSingleQuote(this.options.openSingleQuote))\n }\n\n if (this.options.closeSingleQuote !== false) {\n rules.push(closeSingleQuote(this.options.closeSingleQuote))\n }\n\n if (this.options.leftArrow !== false) {\n rules.push(leftArrow(this.options.leftArrow))\n }\n\n if (this.options.rightArrow !== false) {\n rules.push(rightArrow(this.options.rightArrow))\n }\n\n if (this.options.copyright !== false) {\n rules.push(copyright(this.options.copyright))\n }\n\n if (this.options.trademark !== false) {\n rules.push(trademark(this.options.trademark))\n }\n\n if (this.options.servicemark !== false) {\n rules.push(servicemark(this.options.servicemark))\n }\n\n if (this.options.registeredTrademark !== false) {\n rules.push(registeredTrademark(this.options.registeredTrademark))\n }\n\n if (this.options.oneHalf !== false) {\n rules.push(oneHalf(this.options.oneHalf))\n }\n\n if (this.options.plusMinus !== false) {\n rules.push(plusMinus(this.options.plusMinus))\n }\n\n if (this.options.notEqual !== false) {\n rules.push(notEqual(this.options.notEqual))\n }\n\n if (this.options.laquo !== false) {\n rules.push(laquo(this.options.laquo))\n }\n\n if (this.options.raquo !== false) {\n rules.push(raquo(this.options.raquo))\n }\n\n if (this.options.multiplication !== false) {\n rules.push(multiplication(this.options.multiplication))\n }\n\n if (this.options.superscriptTwo !== false) {\n rules.push(superscriptTwo(this.options.superscriptTwo))\n }\n\n if (this.options.superscriptThree !== false) {\n rules.push(superscriptThree(this.options.superscriptThree))\n }\n\n if (this.options.oneQuarter !== false) {\n rules.push(oneQuarter(this.options.oneQuarter))\n }\n\n if (this.options.threeQuarters !== false) {\n rules.push(threeQuarters(this.options.threeQuarters))\n }\n\n return rules\n },\n})\n","import { Typography } from './typography.js'\n\nexport * from './typography.js'\n\nexport default Typography\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/typography.ts","../src/index.ts"],"sourcesContent":["import { Extension, textInputRule } from '@tiptap/core'\n\n/**\n * Configuration for directional quotes (open/close pair).\n */\nexport interface DirectionalQuotes {\n open: string\n close: string\n}\n\nexport interface TypographyOptions {\n /**\n * The em dash character.\n * @default '—'\n */\n emDash: false | string\n\n /**\n * The ellipsis character.\n * @default '…'\n */\n ellipsis: false | string\n\n /**\n * The open double quote character.\n * @default '“'\n */\n openDoubleQuote: false | string\n\n /**\n * The close double quote character.\n * @default '”'\n */\n closeDoubleQuote: false | string\n\n /**\n * The open single quote character.\n * @default '‘'\n */\n openSingleQuote: false | string\n\n /**\n * The close single quote character.\n * @default '’'\n */\n closeSingleQuote: false | string\n\n /**\n * The left arrow character.\n * @default '←'\n */\n leftArrow: false | string\n\n /**\n * The right arrow character.\n * @default '→'\n */\n rightArrow: false | string\n\n /**\n * The copyright character.\n * @default '©'\n */\n copyright: false | string\n\n /**\n * The trademark character.\n * @default '™'\n */\n trademark: false | string\n\n /**\n * The servicemark character.\n * @default '℠'\n */\n servicemark: false | string\n\n /**\n * The registered trademark character.\n * @default '®'\n */\n registeredTrademark: false | string\n\n /**\n * The one half character.\n * @default '½'\n */\n oneHalf: false | string\n\n /**\n * The plus minus character.\n * @default '±'\n */\n plusMinus: false | string\n\n /**\n * The not equal character.\n * @default '≠'\n */\n notEqual: false | string\n\n /**\n * The laquo character.\n * @default '«'\n */\n laquo: false | string\n\n /**\n * The raquo character.\n * @default '»'\n */\n raquo: false | string\n\n /**\n * The multiplication character.\n * @default '×'\n */\n multiplication: false | string\n\n /**\n * The superscript two character.\n * @default '²'\n */\n superscriptTwo: false | string\n\n /**\n * The superscript three character.\n * @default '³'\n */\n superscriptThree: false | string\n\n /**\n * The one quarter character.\n * @default '¼'\n */\n oneQuarter: false | string\n\n /**\n * The three quarters character.\n * @default '¾'\n */\n threeQuarters: false | string\n\n /**\n * Directional double quotes configuration.\n * Use this for explicit LTR/RTL quote control.\n * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.\n * @example\n * ```ts\n * Typography.configure({\n * doubleQuotes: {\n * rtl: { open: '\\u201D', close: '\\u201C' } // Swapped for RTL\n * }\n * })\n * ```\n */\n doubleQuotes?: {\n rtl?: DirectionalQuotes\n }\n\n /**\n * Directional single quotes configuration.\n * Use this for explicit LTR/RTL quote control.\n * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.\n * @example\n * ```ts\n * Typography.configure({\n * singleQuotes: {\n * rtl: { open: '\\u2019', close: '\\u2018' } // Swapped for RTL\n * }\n * })\n * ```\n */\n singleQuotes?: {\n rtl?: DirectionalQuotes\n }\n}\n\nexport const emDash = (override?: string) =>\n textInputRule({\n find: /--$/,\n replace: override ?? '—',\n })\n\nexport const ellipsis = (override?: string) =>\n textInputRule({\n find: /\\.\\.\\.$/,\n replace: override ?? '…',\n })\n\nexport const openDoubleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(\")$/,\n replace: override ?? '“',\n })\n\nexport const closeDoubleQuote = (override?: string) =>\n textInputRule({\n find: /\"$/,\n replace: override ?? '”',\n })\n\nexport const openSingleQuote = (override?: string) =>\n textInputRule({\n find: /(?:^|[\\s{[(<'\"\\u2018\\u201C])(')$/,\n replace: override ?? '‘',\n })\n\nexport const closeSingleQuote = (override?: string) =>\n textInputRule({\n find: /'$/,\n replace: override ?? '’',\n })\n\nexport const leftArrow = (override?: string) =>\n textInputRule({\n find: /<-$/,\n replace: override ?? '←',\n })\n\nexport const rightArrow = (override?: string) =>\n textInputRule({\n find: /->$/,\n replace: override ?? '→',\n })\n\nexport const copyright = (override?: string) =>\n textInputRule({\n find: /\\(c\\)$/,\n replace: override ?? '©',\n })\n\nexport const trademark = (override?: string) =>\n textInputRule({\n find: /\\(tm\\)$/,\n replace: override ?? '™',\n })\n\nexport const servicemark = (override?: string) =>\n textInputRule({\n find: /\\(sm\\)$/,\n replace: override ?? '℠',\n })\n\nexport const registeredTrademark = (override?: string) =>\n textInputRule({\n find: /\\(r\\)$/,\n replace: override ?? '®',\n })\n\nexport const oneHalf = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/2)\\s$/,\n replace: override ?? '½',\n })\n\nexport const plusMinus = (override?: string) =>\n textInputRule({\n find: /\\+\\/-$/,\n replace: override ?? '±',\n })\n\nexport const notEqual = (override?: string) =>\n textInputRule({\n find: /!=$/,\n replace: override ?? '≠',\n })\n\nexport const laquo = (override?: string) =>\n textInputRule({\n find: /<<$/,\n replace: override ?? '«',\n })\n\nexport const raquo = (override?: string) =>\n textInputRule({\n find: />>$/,\n replace: override ?? '»',\n })\n\nexport const multiplication = (override?: string) =>\n textInputRule({\n find: /\\d+\\s?([*x])\\s?\\d+$/,\n replace: override ?? '×',\n })\n\nexport const superscriptTwo = (override?: string) =>\n textInputRule({\n find: /\\^2$/,\n replace: override ?? '²',\n })\n\nexport const superscriptThree = (override?: string) =>\n textInputRule({\n find: /\\^3$/,\n replace: override ?? '³',\n })\n\nexport const oneQuarter = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(1\\/4)\\s$/,\n replace: override ?? '¼',\n })\n\nexport const threeQuarters = (override?: string) =>\n textInputRule({\n find: /(?:^|\\s)(3\\/4)\\s$/,\n replace: override ?? '¾',\n })\n\n/**\n * This extension allows you to add typography replacements for specific characters.\n * @see https://www.tiptap.dev/api/extensions/typography\n */\nexport const Typography = Extension.create<TypographyOptions>({\n name: 'typography',\n\n addOptions() {\n return {\n closeDoubleQuote: '”',\n closeSingleQuote: '’',\n copyright: '©',\n ellipsis: '…',\n emDash: '—',\n laquo: '«',\n leftArrow: '←',\n multiplication: '×',\n notEqual: '≠',\n oneHalf: '½',\n oneQuarter: '¼',\n openDoubleQuote: '“',\n openSingleQuote: '‘',\n plusMinus: '±',\n raquo: '»',\n registeredTrademark: '®',\n rightArrow: '→',\n servicemark: '℠',\n superscriptThree: '³',\n superscriptTwo: '²',\n threeQuarters: '¾',\n trademark: '™',\n }\n },\n\n addInputRules() {\n const rules = []\n\n if (this.options.emDash !== false) {\n rules.push(emDash(this.options.emDash))\n }\n\n if (this.options.ellipsis !== false) {\n rules.push(ellipsis(this.options.ellipsis))\n }\n\n // Determine if RTL mode is active based on explicit config or editor option\n const isRTL = this.editor.options.textDirection === 'rtl'\n\n // Double quotes: use explicit RTL config if provided, otherwise use automatic RTL detection\n if (this.options.doubleQuotes?.rtl) {\n const { open, close } = this.options.doubleQuotes.rtl\n\n rules.push(openDoubleQuote(open))\n rules.push(closeDoubleQuote(close))\n } else if (isRTL) {\n // Automatic RTL detection: swap open and close quotes\n rules.push(openDoubleQuote('\\u201D')) // Right double quotation mark\n rules.push(closeDoubleQuote('\\u201C')) // Left double quotation mark\n } else {\n if (this.options.openDoubleQuote !== false) {\n rules.push(openDoubleQuote(this.options.openDoubleQuote))\n }\n\n if (this.options.closeDoubleQuote !== false) {\n rules.push(closeDoubleQuote(this.options.closeDoubleQuote))\n }\n }\n\n // Single quotes: use explicit RTL config if provided, otherwise use automatic RTL detection\n if (this.options.singleQuotes?.rtl) {\n const { open, close } = this.options.singleQuotes.rtl\n\n rules.push(openSingleQuote(open))\n rules.push(closeSingleQuote(close))\n } else if (isRTL) {\n // Automatic RTL detection: swap open and close quotes\n rules.push(openSingleQuote('\\u2019')) // Right single quotation mark\n rules.push(closeSingleQuote('\\u2018')) // Left single quotation mark\n } else {\n if (this.options.openSingleQuote !== false) {\n rules.push(openSingleQuote(this.options.openSingleQuote))\n }\n\n if (this.options.closeSingleQuote !== false) {\n rules.push(closeSingleQuote(this.options.closeSingleQuote))\n }\n }\n\n if (this.options.leftArrow !== false) {\n rules.push(leftArrow(this.options.leftArrow))\n }\n\n if (this.options.rightArrow !== false) {\n rules.push(rightArrow(this.options.rightArrow))\n }\n\n if (this.options.copyright !== false) {\n rules.push(copyright(this.options.copyright))\n }\n\n if (this.options.trademark !== false) {\n rules.push(trademark(this.options.trademark))\n }\n\n if (this.options.servicemark !== false) {\n rules.push(servicemark(this.options.servicemark))\n }\n\n if (this.options.registeredTrademark !== false) {\n rules.push(registeredTrademark(this.options.registeredTrademark))\n }\n\n if (this.options.oneHalf !== false) {\n rules.push(oneHalf(this.options.oneHalf))\n }\n\n if (this.options.plusMinus !== false) {\n rules.push(plusMinus(this.options.plusMinus))\n }\n\n if (this.options.notEqual !== false) {\n rules.push(notEqual(this.options.notEqual))\n }\n\n if (this.options.laquo !== false) {\n rules.push(laquo(this.options.laquo))\n }\n\n if (this.options.raquo !== false) {\n rules.push(raquo(this.options.raquo))\n }\n\n if (this.options.multiplication !== false) {\n rules.push(multiplication(this.options.multiplication))\n }\n\n if (this.options.superscriptTwo !== false) {\n rules.push(superscriptTwo(this.options.superscriptTwo))\n }\n\n if (this.options.superscriptThree !== false) {\n rules.push(superscriptThree(this.options.superscriptThree))\n }\n\n if (this.options.oneQuarter !== false) {\n rules.push(oneQuarter(this.options.oneQuarter))\n }\n\n if (this.options.threeQuarters !== false) {\n rules.push(threeQuarters(this.options.threeQuarters))\n }\n\n return rules\n },\n})\n","import { Typography } from './typography.js'\n\nexport * from './typography.js'\n\nexport default Typography\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/extension-typography",
3
3
  "description": "typography extension for tiptap",
4
- "version": "3.22.1",
4
+ "version": "3.22.2",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -31,10 +31,10 @@
31
31
  "dist"
32
32
  ],
33
33
  "devDependencies": {
34
- "@tiptap/core": "^3.22.1"
34
+ "@tiptap/core": "^3.22.2"
35
35
  },
36
36
  "peerDependencies": {
37
- "@tiptap/core": "^3.22.1"
37
+ "@tiptap/core": "^3.22.2"
38
38
  },
39
39
  "repository": {
40
40
  "type": "git",
package/src/typography.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import { Extension, textInputRule } from '@tiptap/core'
2
2
 
3
+ /**
4
+ * Configuration for directional quotes (open/close pair).
5
+ */
6
+ export interface DirectionalQuotes {
7
+ open: string
8
+ close: string
9
+ }
10
+
3
11
  export interface TypographyOptions {
4
12
  /**
5
13
  * The em dash character.
@@ -132,6 +140,40 @@ export interface TypographyOptions {
132
140
  * @default '¾'
133
141
  */
134
142
  threeQuarters: false | string
143
+
144
+ /**
145
+ * Directional double quotes configuration.
146
+ * Use this for explicit LTR/RTL quote control.
147
+ * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.
148
+ * @example
149
+ * ```ts
150
+ * Typography.configure({
151
+ * doubleQuotes: {
152
+ * rtl: { open: '\u201D', close: '\u201C' } // Swapped for RTL
153
+ * }
154
+ * })
155
+ * ```
156
+ */
157
+ doubleQuotes?: {
158
+ rtl?: DirectionalQuotes
159
+ }
160
+
161
+ /**
162
+ * Directional single quotes configuration.
163
+ * Use this for explicit LTR/RTL quote control.
164
+ * When `rtl` is configured, RTL-specific quote rules are used instead of default LTR.
165
+ * @example
166
+ * ```ts
167
+ * Typography.configure({
168
+ * singleQuotes: {
169
+ * rtl: { open: '\u2019', close: '\u2018' } // Swapped for RTL
170
+ * }
171
+ * })
172
+ * ```
173
+ */
174
+ singleQuotes?: {
175
+ rtl?: DirectionalQuotes
176
+ }
135
177
  }
136
178
 
137
179
  export const emDash = (override?: string) =>
@@ -311,20 +353,47 @@ export const Typography = Extension.create<TypographyOptions>({
311
353
  rules.push(ellipsis(this.options.ellipsis))
312
354
  }
313
355
 
314
- if (this.options.openDoubleQuote !== false) {
315
- rules.push(openDoubleQuote(this.options.openDoubleQuote))
316
- }
317
-
318
- if (this.options.closeDoubleQuote !== false) {
319
- rules.push(closeDoubleQuote(this.options.closeDoubleQuote))
320
- }
321
-
322
- if (this.options.openSingleQuote !== false) {
323
- rules.push(openSingleQuote(this.options.openSingleQuote))
356
+ // Determine if RTL mode is active based on explicit config or editor option
357
+ const isRTL = this.editor.options.textDirection === 'rtl'
358
+
359
+ // Double quotes: use explicit RTL config if provided, otherwise use automatic RTL detection
360
+ if (this.options.doubleQuotes?.rtl) {
361
+ const { open, close } = this.options.doubleQuotes.rtl
362
+
363
+ rules.push(openDoubleQuote(open))
364
+ rules.push(closeDoubleQuote(close))
365
+ } else if (isRTL) {
366
+ // Automatic RTL detection: swap open and close quotes
367
+ rules.push(openDoubleQuote('\u201D')) // Right double quotation mark
368
+ rules.push(closeDoubleQuote('\u201C')) // Left double quotation mark
369
+ } else {
370
+ if (this.options.openDoubleQuote !== false) {
371
+ rules.push(openDoubleQuote(this.options.openDoubleQuote))
372
+ }
373
+
374
+ if (this.options.closeDoubleQuote !== false) {
375
+ rules.push(closeDoubleQuote(this.options.closeDoubleQuote))
376
+ }
324
377
  }
325
378
 
326
- if (this.options.closeSingleQuote !== false) {
327
- rules.push(closeSingleQuote(this.options.closeSingleQuote))
379
+ // Single quotes: use explicit RTL config if provided, otherwise use automatic RTL detection
380
+ if (this.options.singleQuotes?.rtl) {
381
+ const { open, close } = this.options.singleQuotes.rtl
382
+
383
+ rules.push(openSingleQuote(open))
384
+ rules.push(closeSingleQuote(close))
385
+ } else if (isRTL) {
386
+ // Automatic RTL detection: swap open and close quotes
387
+ rules.push(openSingleQuote('\u2019')) // Right single quotation mark
388
+ rules.push(closeSingleQuote('\u2018')) // Left single quotation mark
389
+ } else {
390
+ if (this.options.openSingleQuote !== false) {
391
+ rules.push(openSingleQuote(this.options.openSingleQuote))
392
+ }
393
+
394
+ if (this.options.closeSingleQuote !== false) {
395
+ rules.push(closeSingleQuote(this.options.closeSingleQuote))
396
+ }
328
397
  }
329
398
 
330
399
  if (this.options.leftArrow !== false) {