mirror of
https://github.com/standardnotes/app.git
synced 2026-01-11 19:56:41 +00:00
Merge pull request #2952 from standardnotes/chore/reapply-reverted-changes
chore: reapply pdf fonts fix and lexical upgrade
This commit is contained in:
commit
8f318f02a7
103 changed files with 788 additions and 352 deletions
BIN
.yarn/cache/@floating-ui-core-npm-1.7.3-2fe40b3781-5adfb28ddf.zip
vendored
Normal file
BIN
.yarn/cache/@floating-ui-core-npm-1.7.3-2fe40b3781-5adfb28ddf.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@floating-ui-dom-npm-1.7.4-e1f6d76b3d-806923e6f5.zip
vendored
Normal file
BIN
.yarn/cache/@floating-ui-dom-npm-1.7.4-e1f6d76b3d-806923e6f5.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@floating-ui-react-npm-0.27.16-b1b80a3725-4f242f843c.zip
vendored
Normal file
BIN
.yarn/cache/@floating-ui-react-npm-0.27.16-b1b80a3725-4f242f843c.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@floating-ui-utils-npm-0.2.10-5e22e99242-ffc4c24a46.zip
vendored
Normal file
BIN
.yarn/cache/@floating-ui-utils-npm-0.2.10-5e22e99242-ffc4c24a46.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-clipboard-npm-0.38.1-d8b1f4e445-d56bd0b5db.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-clipboard-npm-0.38.1-d8b1f4e445-d56bd0b5db.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-code-npm-0.38.1-bcca5107b9-7d2273bb05.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-code-npm-0.38.1-bcca5107b9-7d2273bb05.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-devtools-core-npm-0.38.1-5706254649-00ed9e4c9b.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-devtools-core-npm-0.38.1-5706254649-00ed9e4c9b.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-dragon-npm-0.38.1-483ccfe64f-1771dc711d.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-dragon-npm-0.38.1-483ccfe64f-1771dc711d.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@lexical-extension-npm-0.38.1-68b14b30a1-36a2d22ee5.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-extension-npm-0.38.1-68b14b30a1-36a2d22ee5.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-hashtag-npm-0.38.1-0b8ffe2b43-4976559218.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-hashtag-npm-0.38.1-0b8ffe2b43-4976559218.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-headless-npm-0.38.1-c95092faa6-994a1e3750.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-headless-npm-0.38.1-c95092faa6-994a1e3750.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-history-npm-0.38.1-f57702de2b-12fe92f722.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-history-npm-0.38.1-f57702de2b-12fe92f722.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-html-npm-0.38.1-bcdd5e6b7a-effeae00d2.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-html-npm-0.38.1-bcdd5e6b7a-effeae00d2.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-link-npm-0.38.1-0dfa5a6ba1-18ffad2fe8.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-link-npm-0.38.1-0dfa5a6ba1-18ffad2fe8.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-list-npm-0.38.1-c17b749323-d2b288d3a4.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-list-npm-0.38.1-c17b749323-d2b288d3a4.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-mark-npm-0.38.1-be98b22665-3ec0f37e9a.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-mark-npm-0.38.1-be98b22665-3ec0f37e9a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-markdown-npm-0.38.1-56dd7e2c50-9aab4eb6e9.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-markdown-npm-0.38.1-56dd7e2c50-9aab4eb6e9.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-offset-npm-0.38.1-e5622a3bc4-bf397bc3db.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-offset-npm-0.38.1-e5622a3bc4-bf397bc3db.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-overflow-npm-0.38.1-e0de8c7a60-3812795f83.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-overflow-npm-0.38.1-e0de8c7a60-3812795f83.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-plain-text-npm-0.38.1-5dd2b5b300-4e2d79ced9.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-plain-text-npm-0.38.1-5dd2b5b300-4e2d79ced9.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-react-npm-0.38.1-7926fed74c-a9488dc3f2.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-react-npm-0.38.1-7926fed74c-a9488dc3f2.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-rich-text-npm-0.38.1-7afcc3c269-b8d2218d5a.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-rich-text-npm-0.38.1-7afcc3c269-b8d2218d5a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-selection-npm-0.38.1-1ebdbc83db-7e585e9149.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-selection-npm-0.38.1-1ebdbc83db-7e585e9149.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-table-npm-0.38.1-6dd61da93e-9ea4a6bee5.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-table-npm-0.38.1-6dd61da93e-9ea4a6bee5.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-utils-npm-0.38.1-71c1450f0f-121c1f2d4a.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-utils-npm-0.38.1-71c1450f0f-121c1f2d4a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@lexical-yjs-npm-0.38.1-0040cc11a9-fb9ab146ba.zip
vendored
Normal file
BIN
.yarn/cache/@lexical-yjs-npm-0.38.1-0040cc11a9-fb9ab146ba.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@preact-signals-core-npm-1.12.1-a218932129-55719713dc.zip
vendored
Normal file
BIN
.yarn/cache/@preact-signals-core-npm-1.12.1-a218932129-55719713dc.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-fns-npm-3.1.2-5b68a05f5c-4e8cdd32f2.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-fns-npm-3.1.2-5b68a05f5c-4e8cdd32f2.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-font-npm-4.0.2-25fe9134a7-547a64dd3f.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-font-npm-4.0.2-25fe9134a7-547a64dd3f.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-image-npm-3.0.3-9bc75136a5-893ebef74d.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-image-npm-3.0.3-9bc75136a5-893ebef74d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-layout-npm-4.4.0-5c06727bb4-385e27f00a.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-layout-npm-4.4.0-5c06727bb4-385e27f00a.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-pdfkit-npm-4.0.3-384052332d-209f064f04.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-pdfkit-npm-4.0.3-384052332d-209f064f04.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-png-js-npm-3.0.0-17565fff9e-90c1612d75.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-png-js-npm-3.0.0-17565fff9e-90c1612d75.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-primitives-npm-4.1.1-80eed5afd4-adadff1996.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-primitives-npm-4.1.1-80eed5afd4-adadff1996.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@react-pdf-reconciler-npm-1.1.4-0a87628369-d920898a1c.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-reconciler-npm-1.1.4-0a87628369-d920898a1c.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-render-npm-4.3.0-674828a2c0-c0ba6c8e35.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-render-npm-4.3.0-674828a2c0-c0ba6c8e35.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-renderer-npm-4.3.0-0712eccaac-aa54f134bc.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-renderer-npm-4.3.0-0712eccaac-aa54f134bc.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-stylesheet-npm-6.1.0-5231eae246-93998eef6e.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-stylesheet-npm-6.1.0-5231eae246-93998eef6e.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-textkit-npm-6.0.0-ad8481d0d8-5bc087ad2d.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-textkit-npm-6.0.0-ad8481d0d8-5bc087ad2d.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/@react-pdf-types-npm-2.9.0-4c17b18dcc-ed2f1854e1.zip
vendored
Normal file
BIN
.yarn/cache/@react-pdf-types-npm-2.9.0-4c17b18dcc-ed2f1854e1.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@types-node-npm-20.19.23-9e5fa45fa9-1f213fa438.zip
vendored
Normal file
BIN
.yarn/cache/@types-node-npm-20.19.23-9e5fa45fa9-1f213fa438.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/@types-whatwg-mimetype-npm-3.0.2-cf2bd6921c-30e2599ae0.zip
vendored
Normal file
BIN
.yarn/cache/@types-whatwg-mimetype-npm-3.0.2-cf2bd6921c-30e2599ae0.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/base64-js-npm-0.0.8-f2946f7960-e95d2fa4b9.zip
vendored
Normal file
BIN
.yarn/cache/base64-js-npm-0.0.8-f2946f7960-e95d2fa4b9.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/bidi-js-npm-1.0.3-0035393a88-877c5dcfd6.zip
vendored
Normal file
BIN
.yarn/cache/bidi-js-npm-1.0.3-0035393a88-877c5dcfd6.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/happy-dom-npm-20.0.8-9d375c4358-4d1131542c.zip
vendored
Normal file
BIN
.yarn/cache/happy-dom-npm-20.0.8-9d375c4358-4d1131542c.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/jay-peg-npm-1.1.1-0c591a2c0b-c3786552ca.zip
vendored
Normal file
BIN
.yarn/cache/jay-peg-npm-1.1.1-0c591a2c0b-c3786552ca.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/lexical-npm-0.38.1-adf999e94e-af080ba244.zip
vendored
Normal file
BIN
.yarn/cache/lexical-npm-0.38.1-adf999e94e-af080ba244.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/linebreak-npm-1.1.0-d845ecba6a-65cb66900b.zip
vendored
Normal file
BIN
.yarn/cache/linebreak-npm-1.1.0-d845ecba6a-65cb66900b.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/react-error-boundary-npm-6.0.0-66eefd4679-d6807004d2.zip
vendored
Normal file
BIN
.yarn/cache/react-error-boundary-npm-6.0.0-66eefd4679-d6807004d2.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/scheduler-npm-0.25.0-rc-603e6108-20241029-47acf774fb-c24fb37561.zip
vendored
Normal file
BIN
.yarn/cache/scheduler-npm-0.25.0-rc-603e6108-20241029-47acf774fb-c24fb37561.zip
vendored
Normal file
Binary file not shown.
BIN
.yarn/cache/unicode-script-npm-1.2.0-89c647c38e-8081850e75.zip
vendored
Normal file
BIN
.yarn/cache/unicode-script-npm-1.2.0-89c647c38e-8081850e75.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.yarn/cache/yoga-layout-npm-3.2.1-51ec934670-6d75e73f6b.zip
vendored
Normal file
BIN
.yarn/cache/yoga-layout-npm-3.2.1-51ec934670-6d75e73f6b.zip
vendored
Normal file
Binary file not shown.
|
|
@ -108,17 +108,18 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@ariakit/react": "^0.4.18",
|
||||
"@lexical/clipboard": "0.32.1",
|
||||
"@lexical/headless": "0.32.1",
|
||||
"@lexical/link": "0.32.1",
|
||||
"@lexical/list": "0.32.1",
|
||||
"@lexical/react": "0.32.1",
|
||||
"@lexical/rich-text": "0.32.1",
|
||||
"@lexical/utils": "0.32.1",
|
||||
"@lexical/clipboard": "0.38.1",
|
||||
"@lexical/headless": "0.38.1",
|
||||
"@lexical/link": "0.38.1",
|
||||
"@lexical/list": "0.38.1",
|
||||
"@lexical/react": "0.38.1",
|
||||
"@lexical/rich-text": "0.38.1",
|
||||
"@lexical/utils": "0.38.1",
|
||||
"@radix-ui/react-slot": "^1.0.1",
|
||||
"@react-pdf/renderer": "^3.3.2",
|
||||
"@react-pdf/renderer": "^4.3.0",
|
||||
"comlink": "^4.4.1",
|
||||
"fast-diff": "^1.3.0",
|
||||
"lexical": "0.32.1"
|
||||
"lexical": "0.38.1",
|
||||
"unicode-script": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
import { Font } from '@react-pdf/renderer'
|
||||
import { LexicalNode } from 'lexical'
|
||||
// @ts-expect-error No typing for this package
|
||||
import { unicodeScripts } from 'unicode-script'
|
||||
|
||||
enum UnicodeScript {
|
||||
Latin = 'Latin',
|
||||
Common = 'Common',
|
||||
Cyrillic = 'Cyrillic',
|
||||
Greek = 'Greek',
|
||||
Hebrew = 'Hebrew',
|
||||
Arabic = 'Arabic',
|
||||
Devanagari = 'Devanagari',
|
||||
Bengali = 'Bengali',
|
||||
Tamil = 'Tamil',
|
||||
Telugu = 'Telugu',
|
||||
Gujarati = 'Gujarati',
|
||||
Gurmukhi = 'Gurmukhi',
|
||||
Malayalam = 'Malayalam',
|
||||
Sinhala = 'Sinhala',
|
||||
Thai = 'Thai',
|
||||
Armenian = 'Armenian',
|
||||
Georgian = 'Georgian',
|
||||
Ethiopic = 'Ethiopic',
|
||||
Myanmar = 'Myanmar',
|
||||
Khmer = 'Khmer',
|
||||
Lao = 'Lao',
|
||||
Tibetan = 'Tibetan',
|
||||
Vietnamese = 'Vietnamese',
|
||||
Chinese = 'Chinese',
|
||||
Han = 'Han',
|
||||
Japanese = 'Japanese',
|
||||
Korean = 'Korean',
|
||||
Hangul = 'Hangul',
|
||||
}
|
||||
|
||||
export enum FontFamily {
|
||||
NotoSans = 'Noto Sans',
|
||||
NotoSansHebrew = 'Noto Sans Hebrew',
|
||||
NotoSansArabic = 'Noto Sans Arabic',
|
||||
NotoSansDevanagari = 'Noto Sans Devanagari',
|
||||
NotoSansBengali = 'Noto Sans Bengali',
|
||||
NotoSansTamil = 'Noto Sans Tamil',
|
||||
NotoSansTelugu = 'Noto Sans Telugu',
|
||||
NotoSansGujarati = 'Noto Sans Gujarati',
|
||||
NotoSansGurmukhi = 'Noto Sans Gurmukhi',
|
||||
NotoSansMalayalam = 'Noto Sans Malayalam',
|
||||
NotoSansSinhala = 'Noto Sans Sinhala',
|
||||
NotoSansThai = 'Noto Sans Thai',
|
||||
NotoSansArmenian = 'Noto Sans Armenian',
|
||||
NotoSansGeorgian = 'Noto Sans Georgian',
|
||||
NotoSansEthiopic = 'Noto Sans Ethiopic',
|
||||
NotoSansMyanmar = 'Noto Sans Myanmar',
|
||||
NotoSansKhmer = 'Noto Sans Khmer',
|
||||
NotoSansLao = 'Noto Sans Lao',
|
||||
NotoSansTibetan = 'Noto Sans Tibetan',
|
||||
NotoSansSC = 'Noto Sans SC',
|
||||
NotoSansJP = 'Noto Sans JP',
|
||||
NotoSansKR = 'Noto Sans KR',
|
||||
Courier = 'Courier',
|
||||
Helvetica = 'Helvetica',
|
||||
}
|
||||
|
||||
enum FontVariant {
|
||||
Normal = 'normal',
|
||||
Bold = 'bold',
|
||||
Italic = 'italic',
|
||||
BoldItalic = 'bolditalic',
|
||||
}
|
||||
|
||||
type FontWeight = 'normal' | 'bold'
|
||||
type FontStyle = 'normal' | 'italic'
|
||||
|
||||
const FONT_VARIANT_TO_FONT_OPTIONS: Record<FontVariant, { fontWeight: FontWeight; fontStyle: FontStyle }> = {
|
||||
[FontVariant.Normal]: {
|
||||
fontWeight: 'normal',
|
||||
fontStyle: 'normal',
|
||||
},
|
||||
[FontVariant.Bold]: {
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'normal',
|
||||
},
|
||||
[FontVariant.Italic]: {
|
||||
fontWeight: 'normal',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
[FontVariant.BoldItalic]: {
|
||||
fontWeight: 'bold',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
}
|
||||
|
||||
const FONT_ASSETS_BASE_PATH =
|
||||
process.env.NODE_ENV === 'development'
|
||||
? 'http://localhost:3001/assets/fonts'
|
||||
: 'https://assets.standardnotes.com/fonts'
|
||||
|
||||
const FALLBACK_FONT_SOURCE = '/noto-sans/NotoSans-Regular.ttf'
|
||||
|
||||
export const FALLBACK_FONT_FAMILY = FontFamily.Helvetica
|
||||
export const MONOSPACE_FONT_FAMILY = FontFamily.Courier
|
||||
|
||||
const FONT_FAMILY_TO_FONT_SOURCES: Partial<Record<FontFamily, Partial<Record<FontVariant, string>>>> = {
|
||||
[FontFamily.NotoSans]: {
|
||||
[FontVariant.Normal]: '/noto-sans/NotoSans-Regular.ttf',
|
||||
[FontVariant.Bold]: '/noto-sans/NotoSans-Bold.ttf',
|
||||
[FontVariant.Italic]: '/noto-sans/NotoSans-Italic.ttf',
|
||||
[FontVariant.BoldItalic]: '/noto-sans/NotoSans-BoldItalic.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansHebrew]: {
|
||||
[FontVariant.Normal]: '/noto-sans-hebrew/NotoSansHebrew-Regular.ttf',
|
||||
[FontVariant.Bold]: '/noto-sans-hebrew/NotoSansHebrew-Bold.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansArabic]: {
|
||||
[FontVariant.Normal]: '/noto-sans-arabic/NotoSansArabic-Regular.ttf',
|
||||
[FontVariant.Bold]: '/noto-sans-arabic/NotoSansArabic-Bold.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansDevanagari]: {
|
||||
[FontVariant.Normal]: '/noto-sans-devanagari/NotoSansDevanagari-Regular.ttf',
|
||||
[FontVariant.Bold]: '/noto-sans-devanagari/NotoSansDevanagari-Bold.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansBengali]: {
|
||||
[FontVariant.Normal]: '/noto-sans-bengali/NotoSansBengali-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansTamil]: {
|
||||
[FontVariant.Normal]: '/noto-sans-tamil/NotoSansTamil-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansTelugu]: {
|
||||
[FontVariant.Normal]: '/noto-sans-telugu/NotoSansTelugu-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansGujarati]: {
|
||||
[FontVariant.Normal]: '/noto-sans-gujarati/NotoSansGujarati-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansGurmukhi]: {
|
||||
[FontVariant.Normal]: '/noto-sans-gurmukhi/NotoSansGurmukhi-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansMalayalam]: {
|
||||
[FontVariant.Normal]: '/noto-sans-malayalam/NotoSansMalayalam-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansSinhala]: {
|
||||
[FontVariant.Normal]: '/noto-sans-sinhala/NotoSansSinhala-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansThai]: {
|
||||
[FontVariant.Normal]: '/noto-sans-thai/NotoSansThai-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansArmenian]: {
|
||||
[FontVariant.Normal]: '/noto-sans-armenian/NotoSansArmenian-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansGeorgian]: {
|
||||
[FontVariant.Normal]: '/noto-sans-georgian/NotoSansGeorgian-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansEthiopic]: {
|
||||
[FontVariant.Normal]: '/noto-sans-ethiopic/NotoSansEthiopic-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansMyanmar]: {
|
||||
[FontVariant.Normal]: '/noto-sans-myanmar/NotoSansMyanmar-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansKhmer]: {
|
||||
[FontVariant.Normal]: '/noto-sans-khmer/NotoSansKhmer-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansLao]: {
|
||||
[FontVariant.Normal]: '/noto-sans-lao/NotoSansLao-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansTibetan]: {
|
||||
[FontVariant.Normal]: '/noto-sans-tibetan/NotoSansTibetan-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansSC]: {
|
||||
[FontVariant.Normal]: '/noto-sans-sc/NotoSansSC-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansJP]: {
|
||||
[FontVariant.Normal]: '/noto-sans-jp/NotoSansJP-Regular.ttf',
|
||||
},
|
||||
[FontFamily.NotoSansKR]: {
|
||||
[FontVariant.Normal]: '/noto-sans-kr/NotoSansKR-Regular.ttf',
|
||||
},
|
||||
}
|
||||
|
||||
export const getFontFamilyForUnicodeScript = (script: UnicodeScript): FontFamily => {
|
||||
switch (script) {
|
||||
case UnicodeScript.Common:
|
||||
case UnicodeScript.Latin:
|
||||
case UnicodeScript.Cyrillic:
|
||||
case UnicodeScript.Greek:
|
||||
case UnicodeScript.Vietnamese:
|
||||
return FontFamily.NotoSans
|
||||
|
||||
case UnicodeScript.Hebrew:
|
||||
return FontFamily.NotoSansHebrew
|
||||
|
||||
case UnicodeScript.Arabic:
|
||||
return FontFamily.NotoSansArabic
|
||||
|
||||
case UnicodeScript.Devanagari:
|
||||
return FontFamily.NotoSansDevanagari
|
||||
|
||||
case UnicodeScript.Bengali:
|
||||
return FontFamily.NotoSansBengali
|
||||
|
||||
case UnicodeScript.Tamil:
|
||||
return FontFamily.NotoSansTamil
|
||||
|
||||
case UnicodeScript.Telugu:
|
||||
return FontFamily.NotoSansTelugu
|
||||
|
||||
case UnicodeScript.Gujarati:
|
||||
return FontFamily.NotoSansGujarati
|
||||
|
||||
case UnicodeScript.Gurmukhi:
|
||||
return FontFamily.NotoSansGurmukhi
|
||||
|
||||
case UnicodeScript.Malayalam:
|
||||
return FontFamily.NotoSansMalayalam
|
||||
|
||||
case UnicodeScript.Sinhala:
|
||||
return FontFamily.NotoSansSinhala
|
||||
|
||||
case UnicodeScript.Thai:
|
||||
return FontFamily.NotoSansThai
|
||||
|
||||
case UnicodeScript.Armenian:
|
||||
return FontFamily.NotoSansArmenian
|
||||
|
||||
case UnicodeScript.Georgian:
|
||||
return FontFamily.NotoSansGeorgian
|
||||
|
||||
case UnicodeScript.Ethiopic:
|
||||
return FontFamily.NotoSansEthiopic
|
||||
|
||||
case UnicodeScript.Myanmar:
|
||||
return FontFamily.NotoSansMyanmar
|
||||
|
||||
case UnicodeScript.Khmer:
|
||||
return FontFamily.NotoSansKhmer
|
||||
|
||||
case UnicodeScript.Lao:
|
||||
return FontFamily.NotoSansLao
|
||||
|
||||
case UnicodeScript.Tibetan:
|
||||
return FontFamily.NotoSansTibetan
|
||||
|
||||
case UnicodeScript.Chinese:
|
||||
case UnicodeScript.Han:
|
||||
return FontFamily.NotoSansSC
|
||||
|
||||
case UnicodeScript.Japanese:
|
||||
return FontFamily.NotoSansJP
|
||||
|
||||
case UnicodeScript.Korean:
|
||||
case UnicodeScript.Hangul:
|
||||
return FontFamily.NotoSansKR
|
||||
|
||||
default:
|
||||
return FontFamily.NotoSans
|
||||
}
|
||||
}
|
||||
|
||||
const getFontRegisterOptions = (fontFamily: FontFamily) => {
|
||||
const fallback = FONT_FAMILY_TO_FONT_SOURCES[fontFamily]?.[FontVariant.Normal] ?? FALLBACK_FONT_SOURCE
|
||||
|
||||
return {
|
||||
family: fontFamily,
|
||||
fonts: Object.entries(FONT_VARIANT_TO_FONT_OPTIONS).map(([variant, fontOptions]) => ({
|
||||
...fontOptions,
|
||||
src: `${FONT_ASSETS_BASE_PATH}${FONT_FAMILY_TO_FONT_SOURCES[fontFamily]?.[variant as FontVariant] ?? fallback}`,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
export const getFontFamiliesFromLexicalNode = (node: LexicalNode) => {
|
||||
const scripts: UnicodeScript[] = Array.from(unicodeScripts(node.getTextContent()))
|
||||
const fontFamilies = [FontFamily.NotoSans]
|
||||
scripts.forEach((script) => {
|
||||
const fontFamilyForScript = getFontFamilyForUnicodeScript(script)
|
||||
if (!fontFamilies.includes(fontFamilyForScript)) {
|
||||
fontFamilies.unshift(fontFamilyForScript)
|
||||
}
|
||||
})
|
||||
const fontFamiliesSet = new Set(fontFamilies)
|
||||
return Array.from(fontFamiliesSet)
|
||||
}
|
||||
|
||||
export const registerPDFFonts = (fontFamilies: FontFamily[]) => {
|
||||
const fontFamiliesToRegister = new Set(fontFamilies)
|
||||
fontFamiliesToRegister.forEach((fontFamily) => {
|
||||
const registerOptions = getFontRegisterOptions(fontFamily)
|
||||
Font.register(registerOptions)
|
||||
})
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ import { $isCollapsibleTitleNode } from '../../../Plugins/CollapsiblePlugin/Coll
|
|||
import PDFWorker, { PDFDataNode, PDFWorkerInterface } from './PDFWorker.worker'
|
||||
import { wrap } from 'comlink'
|
||||
import { PrefKey, PrefValue } from '@standardnotes/snjs'
|
||||
import { FALLBACK_FONT_FAMILY, FontFamily, MONOSPACE_FONT_FAMILY, getFontFamiliesFromLexicalNode } from './FontConfig'
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
page: {
|
||||
|
|
@ -144,6 +145,12 @@ const getFontSizeForHeading = (heading: HeadingNode) => {
|
|||
}
|
||||
|
||||
const getNodeTextAlignment = (node: ElementNode) => {
|
||||
const direction = node.getDirection()
|
||||
|
||||
if (direction === 'rtl') {
|
||||
return 'right'
|
||||
}
|
||||
|
||||
const formatType = node.getFormatType()
|
||||
|
||||
if (!formatType) {
|
||||
|
|
@ -161,7 +168,12 @@ const getNodeTextAlignment = (node: ElementNode) => {
|
|||
return formatType
|
||||
}
|
||||
|
||||
const getPDFDataNodeFromLexicalNode = (node: LexicalNode): PDFDataNode => {
|
||||
const getNodeDirection = (node: ElementNode) => {
|
||||
const direction = node.getDirection()
|
||||
return direction ?? 'ltr'
|
||||
}
|
||||
|
||||
const getPDFDataNodeFromLexicalNode = (node: LexicalNode, fontFamilies: FontFamily[]): PDFDataNode => {
|
||||
const parent = node.getParent()
|
||||
|
||||
if ($isLineBreakNode(node)) {
|
||||
|
|
@ -177,23 +189,23 @@ const getPDFDataNodeFromLexicalNode = (node: LexicalNode): PDFDataNode => {
|
|||
const isBold = node.hasFormat('bold')
|
||||
const isItalic = node.hasFormat('italic')
|
||||
const isHighlight = node.hasFormat('highlight')
|
||||
const nodeFontFamilies = getFontFamiliesFromLexicalNode(node)
|
||||
let fontFamily: FontFamily[] | FontFamily = [...nodeFontFamilies, FALLBACK_FONT_FAMILY]
|
||||
|
||||
let font = isInlineCode || isCodeNodeText ? 'Courier' : 'Helvetica'
|
||||
if (isBold || isItalic) {
|
||||
font += '-'
|
||||
if (isBold) {
|
||||
font += 'Bold'
|
||||
}
|
||||
if (isItalic) {
|
||||
font += 'Oblique'
|
||||
}
|
||||
if (isInlineCode && isCodeNodeText) {
|
||||
fontFamily = MONOSPACE_FONT_FAMILY
|
||||
} else {
|
||||
fontFamilies.push(...nodeFontFamilies)
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'Text',
|
||||
children: node.getTextContent(),
|
||||
style: {
|
||||
fontFamily: font,
|
||||
fontFamily,
|
||||
fontWeight: isBold ? 'bold' : 'normal',
|
||||
fontStyle: isItalic ? 'italic' : 'normal',
|
||||
direction: $isElementNode(parent) ? getNodeDirection(parent) : 'ltr',
|
||||
textDecoration: node.hasFormat('underline')
|
||||
? 'underline'
|
||||
: node.hasFormat('strikethrough')
|
||||
|
|
@ -237,7 +249,7 @@ const getPDFDataNodeFromLexicalNode = (node: LexicalNode): PDFDataNode => {
|
|||
type: 'View',
|
||||
style: [styles.row, styles.wrap],
|
||||
children: line.map((child) => {
|
||||
return getPDFDataNodeFromLexicalNode(child)
|
||||
return getPDFDataNodeFromLexicalNode(child, fontFamilies)
|
||||
}),
|
||||
}
|
||||
}),
|
||||
|
|
@ -267,7 +279,7 @@ const getPDFDataNodeFromLexicalNode = (node: LexicalNode): PDFDataNode => {
|
|||
const children =
|
||||
$isElementNode(node) || $isTableNode(node) || $isTableCellNode(node) || $isTableRowNode(node)
|
||||
? node.getChildren().map((child) => {
|
||||
return getPDFDataNodeFromLexicalNode(child)
|
||||
return getPDFDataNodeFromLexicalNode(child, fontFamilies)
|
||||
})
|
||||
: undefined
|
||||
|
||||
|
|
@ -427,8 +439,8 @@ const getPDFDataNodeFromLexicalNode = (node: LexicalNode): PDFDataNode => {
|
|||
}
|
||||
}
|
||||
|
||||
const getPDFDataNodesFromLexicalNodes = (nodes: LexicalNode[]): PDFDataNode[] => {
|
||||
return nodes.map(getPDFDataNodeFromLexicalNode)
|
||||
const getPDFDataNodesFromLexicalNodes = (nodes: LexicalNode[], fontFamilies: FontFamily[]): PDFDataNode[] => {
|
||||
return nodes.map((node) => getPDFDataNodeFromLexicalNode(node, fontFamilies))
|
||||
}
|
||||
|
||||
const pdfWorker = new PDFWorker()
|
||||
|
|
@ -438,17 +450,21 @@ const PDFWorkerComlink = wrap<PDFWorkerInterface>(pdfWorker)
|
|||
* @returns The PDF as an object url
|
||||
*/
|
||||
export function $generatePDFFromNodes(editor: LexicalEditor, pageSize: PrefValue[PrefKey.SuperNoteExportPDFPageSize]) {
|
||||
return new Promise<string>((resolve) => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
editor.getEditorState().read(() => {
|
||||
const root = $getRoot()
|
||||
const nodes = root.getChildren()
|
||||
const fontFamilies: FontFamily[] = []
|
||||
const pdfDataNodes = getPDFDataNodesFromLexicalNodes(nodes, fontFamilies)
|
||||
|
||||
const pdfDataNodes = getPDFDataNodesFromLexicalNodes(nodes)
|
||||
|
||||
void PDFWorkerComlink.renderPDF(pdfDataNodes, pageSize).then((blob) => {
|
||||
const url = URL.createObjectURL(blob)
|
||||
resolve(url)
|
||||
})
|
||||
void PDFWorkerComlink.renderPDF(pdfDataNodes, pageSize, fontFamilies)
|
||||
.then((blob) => {
|
||||
const url = URL.createObjectURL(blob)
|
||||
resolve(url)
|
||||
})
|
||||
.catch((error) => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
PageProps,
|
||||
} from '@react-pdf/renderer'
|
||||
import { expose } from 'comlink'
|
||||
import { FontFamily, registerPDFFonts } from './FontConfig'
|
||||
|
||||
export type PDFDataNode =
|
||||
| ((
|
||||
|
|
@ -94,7 +95,8 @@ const PDFDocument = ({ nodes, pageSize }: { nodes: PDFDataNode[]; pageSize: Page
|
|||
)
|
||||
}
|
||||
|
||||
const renderPDF = (nodes: PDFDataNode[], pageSize: PageProps['size']) => {
|
||||
const renderPDF = (nodes: PDFDataNode[], pageSize: PageProps['size'], fontFamilies: FontFamily[]) => {
|
||||
registerPDFFonts(fontFamilies)
|
||||
return pdf(<PDFDocument pageSize={pageSize} nodes={nodes} />).toBlob()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
}
|
||||
},
|
||||
): Promise<string> {
|
||||
let didThrow = false
|
||||
if (superString.length === 0) {
|
||||
return superString
|
||||
}
|
||||
|
|
@ -81,7 +82,7 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
|
||||
let content: string | undefined
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const handleFileNodes = () => {
|
||||
if (embedBehavior === 'reference') {
|
||||
resolve()
|
||||
|
|
@ -136,12 +137,16 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
}),
|
||||
)
|
||||
.then(() => resolve())
|
||||
.catch(console.error)
|
||||
.catch((error) => {
|
||||
didThrow = true
|
||||
console.error(error)
|
||||
reject(error)
|
||||
})
|
||||
}
|
||||
this.exportEditor.update(handleFileNodes, { discrete: true })
|
||||
})
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const convertToFormat = () => {
|
||||
switch (toFormat) {
|
||||
case 'txt':
|
||||
|
|
@ -164,10 +169,16 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
break
|
||||
case 'pdf': {
|
||||
void import('../Lexical/Utils/PDFExport/PDFExport').then(({ $generatePDFFromNodes }): void => {
|
||||
void $generatePDFFromNodes(this.exportEditor, config?.pdf?.pageSize || 'A4').then((pdf) => {
|
||||
content = pdf
|
||||
resolve()
|
||||
})
|
||||
void $generatePDFFromNodes(this.exportEditor, config?.pdf?.pageSize || 'A4')
|
||||
.then((pdf) => {
|
||||
content = pdf
|
||||
resolve()
|
||||
})
|
||||
.catch((error) => {
|
||||
didThrow = true
|
||||
console.error(error)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
break
|
||||
}
|
||||
|
|
@ -181,7 +192,7 @@ export class HeadlessSuperConverter implements SuperConverterServiceInterface {
|
|||
this.exportEditor.update(convertToFormat, { discrete: true })
|
||||
})
|
||||
|
||||
if (typeof content !== 'string') {
|
||||
if (didThrow || typeof content !== 'string') {
|
||||
throw new Error('Could not export note')
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue