{
  "version": 3,
  "sources": ["../../../../src/lib/utils/text/literalTyping.ts"],
  "sourcesContent": ["import { Extension } from '@tiptap/core'\nimport { ResolvedPos } from '@tiptap/pm/model'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { EditorView } from '@tiptap/pm/view'\n\nexport function isStraightQuote(text: string) {\n\treturn text === '\"' || text === \"'\"\n}\n\n/**\n * Whether the text is set in a monospace font, like a text shape with the mono font. The TipTap\n * editor has no link back to the shape's props, so this goes by the generic `monospace` family\n * that tldraw's mono font, and any sensible replacement for it, falls back to.\n */\nexport function isMonospace(view: EditorView) {\n\tconst fontFamily = view.dom.ownerDocument.defaultView?.getComputedStyle(view.dom).fontFamily\n\treturn !!fontFamily && /\\bmonospace\\b/.test(fontFamily)\n}\n\n/**\n * Whether the cursor sits after an unmatched backtick, in text the closing backtick will turn into\n * code. Backticks inside existing code are literal characters, not delimiters, so they don't count.\n */\nfunction isInOpenCodeSpan($pos: ResolvedPos) {\n\tlet backticks = 0\n\t$pos.parent.nodesBetween(0, $pos.parentOffset, (node, pos) => {\n\t\tif (!node.isText || node.marks.some((mark) => mark.type.spec.code)) return\n\t\tconst text = node.text!.slice(0, Math.max(0, $pos.parentOffset - pos))\n\t\tfor (const char of text) if (char === '`') backticks++\n\t})\n\treturn backticks % 2 === 1\n}\n\n/**\n * Types characters as themselves where Typography's rewrites would be wrong:\n *\n * - Between an opening backtick and the closing one that makes the text code. TipTap already skips\n *   input rules inside code, but until the closing backtick is typed the text isn't code yet:\n *   `` `say \"hi\"` `` would otherwise become code holding curly quotes, and `...` in `` `...args` ``\n *   an ellipsis.\n * - Quotes in monospace text, where curly quotes look out of place. The other rewrites stay on.\n */\nexport const LiteralTypingExtension = Extension.create({\n\tname: 'literalTyping',\n\n\t// Above Typography, so this gets the input first. The backtick itself is passed through, since\n\t// the code mark's own input rule is what closes the span.\n\tpriority: 200,\n\n\taddProseMirrorPlugins() {\n\t\treturn [\n\t\t\tnew Plugin({\n\t\t\t\tkey: new PluginKey('literalTyping'),\n\t\t\t\tprops: {\n\t\t\t\t\thandleTextInput(view, from, to, text) {\n\t\t\t\t\t\tif (view.composing || text.includes('`')) return false\n\t\t\t\t\t\tconst isLiteral =\n\t\t\t\t\t\t\t(!!view.state.schema.marks.code && isInOpenCodeSpan(view.state.doc.resolve(from))) ||\n\t\t\t\t\t\t\t(isStraightQuote(text) && isMonospace(view))\n\t\t\t\t\t\tif (!isLiteral) return false\n\t\t\t\t\t\tview.dispatch(view.state.tr.insertText(text, from, to))\n\t\t\t\t\t\treturn true\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t]\n\t},\n})\n"],
  "mappings": "AAAA,SAAS,iBAAiB;AAE1B,SAAS,QAAQ,iBAAiB;AAG3B,SAAS,gBAAgB,MAAc;AAC7C,SAAO,SAAS,OAAO,SAAS;AACjC;AAOO,SAAS,YAAY,MAAkB;AAC7C,QAAM,aAAa,KAAK,IAAI,cAAc,aAAa,iBAAiB,KAAK,GAAG,EAAE;AAClF,SAAO,CAAC,CAAC,cAAc,gBAAgB,KAAK,UAAU;AACvD;AAMA,SAAS,iBAAiB,MAAmB;AAC5C,MAAI,YAAY;AAChB,OAAK,OAAO,aAAa,GAAG,KAAK,cAAc,CAAC,MAAM,QAAQ;AAC7D,QAAI,CAAC,KAAK,UAAU,KAAK,MAAM,KAAK,CAAC,SAAS,KAAK,KAAK,KAAK,IAAI,EAAG;AACpE,UAAM,OAAO,KAAK,KAAM,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,eAAe,GAAG,CAAC;AACrE,eAAW,QAAQ,KAAM,KAAI,SAAS,IAAK;AAAA,EAC5C,CAAC;AACD,SAAO,YAAY,MAAM;AAC1B;AAWO,MAAM,yBAAyB,UAAU,OAAO;AAAA,EACtD,MAAM;AAAA;AAAA;AAAA,EAIN,UAAU;AAAA,EAEV,wBAAwB;AACvB,WAAO;AAAA,MACN,IAAI,OAAO;AAAA,QACV,KAAK,IAAI,UAAU,eAAe;AAAA,QAClC,OAAO;AAAA,UACN,gBAAgB,MAAM,MAAM,IAAI,MAAM;AACrC,gBAAI,KAAK,aAAa,KAAK,SAAS,GAAG,EAAG,QAAO;AACjD,kBAAM,YACJ,CAAC,CAAC,KAAK,MAAM,OAAO,MAAM,QAAQ,iBAAiB,KAAK,MAAM,IAAI,QAAQ,IAAI,CAAC,KAC/E,gBAAgB,IAAI,KAAK,YAAY,IAAI;AAC3C,gBAAI,CAAC,UAAW,QAAO;AACvB,iBAAK,SAAS,KAAK,MAAM,GAAG,WAAW,MAAM,MAAM,EAAE,CAAC;AACtD,mBAAO;AAAA,UACR;AAAA,QACD;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD;AACD,CAAC;",
  "names": []
}
