mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Moved the Joplin renderer back to the main repository to make development easier
This commit is contained in:
parent
d687ef5c09
commit
688edd4b32
@ -47,6 +47,7 @@ Server/bin/
|
||||
Server/node_modules/
|
||||
ElectronClient/app/packageInfo.js
|
||||
ReactNativeClient/pluginAssets/
|
||||
ReactNativeClient/lib/joplin-renderer/vendor/fountain.min.js
|
||||
|
||||
# Ignore files generated from TypeScript files
|
||||
ElectronClient/app/gui/ShareNoteDialog.js
|
||||
|
158
CliClient/package-lock.json
generated
158
CliClient/package-lock.json
generated
@ -806,11 +806,6 @@
|
||||
"debug": "^2.6.9"
|
||||
}
|
||||
},
|
||||
"font-awesome-filetypes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/font-awesome-filetypes/-/font-awesome-filetypes-2.1.0.tgz",
|
||||
"integrity": "sha512-U6hi14GRjfZFIWsTNyVmCBuHyPhiizWEKVbaQqHipKQv3rA1l1PNvmKulzpqxonFnQMToty5ZhfWbc/0IjLDGA=="
|
||||
},
|
||||
"for-each-property": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/for-each-property/-/for-each-property-0.0.4.tgz",
|
||||
@ -1538,73 +1533,6 @@
|
||||
"integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==",
|
||||
"dev": true
|
||||
},
|
||||
"joplin-renderer": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/joplin-renderer/-/joplin-renderer-1.0.8.tgz",
|
||||
"integrity": "sha512-Q4SSYXl9ErcnUDTz7N4FjWcOOgfPEf5yyNRjU2J1fuxZ/1VbYt6MnfBB7OeiRW+XF+4Arhihk+/XVK++of4hEA==",
|
||||
"requires": {
|
||||
"base-64": "^0.1.0",
|
||||
"font-awesome-filetypes": "^2.1.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"katex": "^0.11.1",
|
||||
"markdown-it": "^10.0.0",
|
||||
"markdown-it-abbr": "^1.0.4",
|
||||
"markdown-it-anchor": "^5.2.5",
|
||||
"markdown-it-deflist": "^2.0.3",
|
||||
"markdown-it-emoji": "^1.4.0",
|
||||
"markdown-it-footnote": "^3.0.2",
|
||||
"markdown-it-ins": "^3.0.0",
|
||||
"markdown-it-mark": "^3.0.0",
|
||||
"markdown-it-multimd-table": "^4.0.1",
|
||||
"markdown-it-sub": "^1.0.0",
|
||||
"markdown-it-sup": "^1.0.0",
|
||||
"markdown-it-toc-done-right": "^4.1.0",
|
||||
"md5": "^2.2.1",
|
||||
"uslug": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.0.tgz",
|
||||
"integrity": "sha512-A97kI1KAUzKoAiEoaGcf2O9YPS8nbDTCRFokaaeBhnqjQTvbAuAJrQMm21zw8s8xzaMtCQBtgbyGXLGxdxQyqQ=="
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
|
||||
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~2.0.0",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"joplin-turndown": {
|
||||
"version": "4.0.19",
|
||||
"resolved": "https://registry.npmjs.org/joplin-turndown/-/joplin-turndown-4.0.19.tgz",
|
||||
@ -1708,21 +1636,6 @@
|
||||
"resolved": "https://registry.npmjs.org/jssha/-/jssha-2.3.1.tgz",
|
||||
"integrity": "sha1-FHshJTaQNcpLL30hDcU58Amz3po="
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
|
||||
"integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==",
|
||||
"requires": {
|
||||
"commander": "^2.19.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"klaw": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
|
||||
@ -1842,64 +1755,6 @@
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"markdown-it-abbr": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
|
||||
"integrity": "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g="
|
||||
},
|
||||
"markdown-it-anchor": {
|
||||
"version": "5.2.5",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz",
|
||||
"integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ=="
|
||||
},
|
||||
"markdown-it-deflist": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz",
|
||||
"integrity": "sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw=="
|
||||
},
|
||||
"markdown-it-emoji": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
|
||||
"integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw="
|
||||
},
|
||||
"markdown-it-footnote": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.2.tgz",
|
||||
"integrity": "sha512-JVW6fCmZWjvMdDQSbOT3nnOQtd9iAXmw7hTSh26+v42BnvXeVyGMDBm5b/EZocMed2MbCAHiTX632vY0FyGB8A=="
|
||||
},
|
||||
"markdown-it-ins": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.0.tgz",
|
||||
"integrity": "sha512-+vyAdBuMGwmT2yMlAFJSx2VR/0QZ1onQ/Mkkmr4l9tDFOh5sVoAgRbkgbuSsk+sxJ9vaMH/IQ323ydfvQrPO/Q=="
|
||||
},
|
||||
"markdown-it-mark": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.0.tgz",
|
||||
"integrity": "sha512-HqMWeKfMMOu4zBO0emmxsoMWmbf2cPKZY1wP6FsTbKmicFfp5y4L3KXAsNeO1rM6NTJVOrNlLKMPjWzriBGspw=="
|
||||
},
|
||||
"markdown-it-multimd-table": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-multimd-table/-/markdown-it-multimd-table-4.0.1.tgz",
|
||||
"integrity": "sha512-ZgRV8LlGz6JXTZ5zd82yCL8IVG5MRastMWxxrc6hQC8aC8kq/7zpp+ksBqVqcdTmTdabnkuSo/7h3SyKM31YCA==",
|
||||
"requires": {
|
||||
"markdown-it": "^8.4.2"
|
||||
}
|
||||
},
|
||||
"markdown-it-sub": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
|
||||
"integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g="
|
||||
},
|
||||
"markdown-it-sup": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
|
||||
"integrity": "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M="
|
||||
},
|
||||
"markdown-it-toc-done-right": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.1.0.tgz",
|
||||
"integrity": "sha512-UhD2Oj6cZV3ycYPoelt4hTkwKIK3zbPP1wjjdpCq7UGtWQOFalDFDv1s2zBYV6aR2gMs/X8kpJcOYsQmUbiXDw=="
|
||||
},
|
||||
"md5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
|
||||
@ -3234,11 +3089,6 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unpack-string": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unpack-string/-/unpack-string-0.0.2.tgz",
|
||||
@ -3278,14 +3128,6 @@
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
@ -44,7 +44,6 @@
|
||||
"html-minifier": "^3.5.15",
|
||||
"image-data-uri": "^2.0.0",
|
||||
"image-type": "^3.0.0",
|
||||
"joplin-renderer": "^1.0.8",
|
||||
"joplin-turndown": "^4.0.19",
|
||||
"joplin-turndown-plugin-gfm": "^1.0.12",
|
||||
"jssha": "^2.3.0",
|
||||
|
@ -6,7 +6,7 @@ const Setting = require('lib/models/Setting.js');
|
||||
const { shim } = require('lib/shim.js');
|
||||
const MasterKey = require('lib/models/MasterKey');
|
||||
const Note = require('lib/models/Note');
|
||||
const { MarkupToHtml } = require('joplin-renderer');
|
||||
const { MarkupToHtml } = require('lib/joplin-renderer');
|
||||
const { _, setLocale } = require('lib/locale.js');
|
||||
const { Logger } = require('lib/logger.js');
|
||||
const fs = require('fs-extra');
|
||||
|
@ -12,7 +12,7 @@ const urlUtils = require('lib/urlUtils');
|
||||
const Setting = require('lib/models/Setting');
|
||||
const RevisionService = require('lib/services/RevisionService');
|
||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||
const { MarkupToHtml, assetsToHeaders } = require('joplin-renderer');
|
||||
const { MarkupToHtml, assetsToHeaders } = require('lib/joplin-renderer');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const ReactTooltip = require('react-tooltip');
|
||||
const { urlDecode, substrWithEllipsis } = require('lib/string-utils');
|
||||
|
@ -16,7 +16,7 @@ const TagList = require('./TagList.min.js');
|
||||
const { connect } = require('react-redux');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { MarkupToHtml, assetsToHeaders } = require('joplin-renderer');
|
||||
const { MarkupToHtml, assetsToHeaders } = require('lib/joplin-renderer');
|
||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const { themeStyle } = require('../theme.js');
|
||||
|
172
ElectronClient/app/package-lock.json
generated
172
ElectronClient/app/package-lock.json
generated
@ -3353,11 +3353,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"font-awesome-filetypes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/font-awesome-filetypes/-/font-awesome-filetypes-2.1.0.tgz",
|
||||
"integrity": "sha512-U6hi14GRjfZFIWsTNyVmCBuHyPhiizWEKVbaQqHipKQv3rA1l1PNvmKulzpqxonFnQMToty5ZhfWbc/0IjLDGA=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
@ -3703,11 +3698,6 @@
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.0.tgz",
|
||||
"integrity": "sha512-A97kI1KAUzKoAiEoaGcf2O9YPS8nbDTCRFokaaeBhnqjQTvbAuAJrQMm21zw8s8xzaMtCQBtgbyGXLGxdxQyqQ=="
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
|
||||
@ -4100,68 +4090,6 @@
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
},
|
||||
"joplin-renderer": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/joplin-renderer/-/joplin-renderer-1.0.8.tgz",
|
||||
"integrity": "sha512-Q4SSYXl9ErcnUDTz7N4FjWcOOgfPEf5yyNRjU2J1fuxZ/1VbYt6MnfBB7OeiRW+XF+4Arhihk+/XVK++of4hEA==",
|
||||
"requires": {
|
||||
"base-64": "^0.1.0",
|
||||
"font-awesome-filetypes": "^2.1.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"katex": "^0.11.1",
|
||||
"markdown-it": "^10.0.0",
|
||||
"markdown-it-abbr": "^1.0.4",
|
||||
"markdown-it-anchor": "^5.2.5",
|
||||
"markdown-it-deflist": "^2.0.3",
|
||||
"markdown-it-emoji": "^1.4.0",
|
||||
"markdown-it-footnote": "^3.0.2",
|
||||
"markdown-it-ins": "^3.0.0",
|
||||
"markdown-it-mark": "^3.0.0",
|
||||
"markdown-it-multimd-table": "^4.0.1",
|
||||
"markdown-it-sub": "^1.0.0",
|
||||
"markdown-it-sup": "^1.0.0",
|
||||
"markdown-it-toc-done-right": "^4.1.0",
|
||||
"md5": "^2.2.1",
|
||||
"uslug": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
|
||||
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~2.0.0",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"joplin-turndown": {
|
||||
"version": "4.0.19",
|
||||
"resolved": "https://registry.npmjs.org/joplin-turndown/-/joplin-turndown-4.0.19.tgz",
|
||||
@ -4293,21 +4221,6 @@
|
||||
"resolved": "https://registry.npmjs.org/jssha/-/jssha-2.3.1.tgz",
|
||||
"integrity": "sha1-FHshJTaQNcpLL30hDcU58Amz3po="
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
|
||||
"integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==",
|
||||
"requires": {
|
||||
"commander": "^2.19.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"keyv": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
|
||||
@ -4502,78 +4415,6 @@
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"markdown-it-abbr": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
|
||||
"integrity": "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g="
|
||||
},
|
||||
"markdown-it-anchor": {
|
||||
"version": "5.2.5",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz",
|
||||
"integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ=="
|
||||
},
|
||||
"markdown-it-deflist": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz",
|
||||
"integrity": "sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw=="
|
||||
},
|
||||
"markdown-it-emoji": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
|
||||
"integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw="
|
||||
},
|
||||
"markdown-it-footnote": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.2.tgz",
|
||||
"integrity": "sha512-JVW6fCmZWjvMdDQSbOT3nnOQtd9iAXmw7hTSh26+v42BnvXeVyGMDBm5b/EZocMed2MbCAHiTX632vY0FyGB8A=="
|
||||
},
|
||||
"markdown-it-ins": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.0.tgz",
|
||||
"integrity": "sha512-+vyAdBuMGwmT2yMlAFJSx2VR/0QZ1onQ/Mkkmr4l9tDFOh5sVoAgRbkgbuSsk+sxJ9vaMH/IQ323ydfvQrPO/Q=="
|
||||
},
|
||||
"markdown-it-mark": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.0.tgz",
|
||||
"integrity": "sha512-HqMWeKfMMOu4zBO0emmxsoMWmbf2cPKZY1wP6FsTbKmicFfp5y4L3KXAsNeO1rM6NTJVOrNlLKMPjWzriBGspw=="
|
||||
},
|
||||
"markdown-it-multimd-table": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-multimd-table/-/markdown-it-multimd-table-4.0.1.tgz",
|
||||
"integrity": "sha512-ZgRV8LlGz6JXTZ5zd82yCL8IVG5MRastMWxxrc6hQC8aC8kq/7zpp+ksBqVqcdTmTdabnkuSo/7h3SyKM31YCA==",
|
||||
"requires": {
|
||||
"markdown-it": "^8.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"markdown-it": {
|
||||
"version": "8.4.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
|
||||
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~1.1.1",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown-it-sub": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
|
||||
"integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g="
|
||||
},
|
||||
"markdown-it-sup": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
|
||||
"integrity": "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M="
|
||||
},
|
||||
"markdown-it-toc-done-right": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.1.0.tgz",
|
||||
"integrity": "sha512-UhD2Oj6cZV3ycYPoelt4hTkwKIK3zbPP1wjjdpCq7UGtWQOFalDFDv1s2zBYV6aR2gMs/X8kpJcOYsQmUbiXDw=="
|
||||
},
|
||||
"matcher": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz",
|
||||
@ -6808,11 +6649,6 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
|
||||
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unused-filename": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-1.0.0.tgz",
|
||||
@ -6916,14 +6752,6 @@
|
||||
"integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
|
||||
"dev": true
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"utf8-byte-length": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
|
||||
|
@ -104,7 +104,6 @@
|
||||
"html-entities": "^1.2.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"image-type": "^3.0.0",
|
||||
"joplin-renderer": "^1.0.8",
|
||||
"joplin-turndown": "^4.0.19",
|
||||
"joplin-turndown-plugin-gfm": "^1.0.12",
|
||||
"jssha": "^2.3.1",
|
||||
|
@ -5,7 +5,5 @@ set script_dir=%mypath:~0,-1%
|
||||
call build.bat
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
rem xcopy /C /I /H /R /Y /S /Q D:\Docs\PROGS\Node\joplin-renderer %script_dir%\app\node_modules\joplin-renderer
|
||||
|
||||
cd %script_dir%\app
|
||||
call .\node_modules\.bin\electron.cmd . --env dev --log-level debug --no-welcome --open-dev-tools "$@"
|
||||
|
@ -48,7 +48,7 @@ async function main() {
|
||||
await fs.mkdirp(outputDir);
|
||||
|
||||
const encodedFiles = [];
|
||||
const sourceAssetDir = `${rootDir}/node_modules/joplin-renderer/assets`;
|
||||
const sourceAssetDir = `${rootDir}/lib/joplin-renderer/assets`;
|
||||
const files = walk(sourceAssetDir);
|
||||
|
||||
for (const file of files) {
|
||||
|
@ -8,7 +8,7 @@ const { themeStyle } = require('lib/components/global-style.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { shim } = require('lib/shim');
|
||||
const { assetsToHeaders } = require('joplin-renderer');
|
||||
const { assetsToHeaders } = require('lib/joplin-renderer');
|
||||
const shared = require('lib/components/shared/note-screen-shared.js');
|
||||
const markupLanguageUtils = require('lib/markupLanguageUtils');
|
||||
|
||||
|
@ -4,7 +4,7 @@ const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const Tag = require('lib/models/Tag.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const { MarkupToHtml } = require('joplin-renderer');
|
||||
const { MarkupToHtml } = require('lib/joplin-renderer');
|
||||
const { enexXmlToMd } = require('./import-enex-md-gen.js');
|
||||
const { enexXmlToHtml } = require('./import-enex-html-gen.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
|
3
ReactNativeClient/lib/joplin-renderer/.gitignore
vendored
Normal file
3
ReactNativeClient/lib/joplin-renderer/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
node_modules/
|
||||
.vscode/
|
||||
copyLib.bat
|
42
ReactNativeClient/lib/joplin-renderer/HtmlToHtml.js
Normal file
42
ReactNativeClient/lib/joplin-renderer/HtmlToHtml.js
Normal file
@ -0,0 +1,42 @@
|
||||
const htmlUtils = require('./htmlUtils');
|
||||
const utils = require('./utils');
|
||||
const noteStyle = require('./noteStyle');
|
||||
|
||||
class HtmlToHtml {
|
||||
constructor(options) {
|
||||
if (!options) options = {};
|
||||
this.resourceBaseUrl_ = 'resourceBaseUrl' in options ? options.resourceBaseUrl : null;
|
||||
this.ResourceModel_ = options.ResourceModel;
|
||||
}
|
||||
|
||||
render(markup, theme, options) {
|
||||
const html = htmlUtils.processImageTags(markup, data => {
|
||||
if (!data.src) return null;
|
||||
|
||||
const r = utils.imageReplacement(this.ResourceModel_, data.src, options.resources, this.resourceBaseUrl_);
|
||||
if (!r) return null;
|
||||
|
||||
if (typeof r === 'string') {
|
||||
return {
|
||||
type: 'replaceElement',
|
||||
html: r,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
type: 'setAttributes',
|
||||
attrs: r,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const cssStrings = noteStyle(theme, options);
|
||||
const styleHtml = `<style>${cssStrings.join('\n')}</style>`;
|
||||
|
||||
return {
|
||||
html: styleHtml + html,
|
||||
pluginAssets: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HtmlToHtml;
|
44
ReactNativeClient/lib/joplin-renderer/MarkupToHtml.js
Normal file
44
ReactNativeClient/lib/joplin-renderer/MarkupToHtml.js
Normal file
@ -0,0 +1,44 @@
|
||||
const MdToHtml = require('./MdToHtml');
|
||||
const HtmlToHtml = require('./HtmlToHtml');
|
||||
|
||||
class MarkupToHtml {
|
||||
constructor(options) {
|
||||
this.options_ = Object.assign({}, {
|
||||
ResourceModel: {
|
||||
isResourceUrl: () => false,
|
||||
},
|
||||
}, options);
|
||||
|
||||
this.renderers_ = {};
|
||||
}
|
||||
|
||||
renderer(markupLanguage) {
|
||||
if (this.renderers_[markupLanguage]) return this.renderers_[markupLanguage];
|
||||
|
||||
let RendererClass = null;
|
||||
|
||||
if (markupLanguage === MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN) {
|
||||
RendererClass = MdToHtml;
|
||||
} else if (markupLanguage === MarkupToHtml.MARKUP_LANGUAGE_HTML) {
|
||||
RendererClass = HtmlToHtml;
|
||||
} else {
|
||||
throw new Error(`Invalid markup language: ${markupLanguage}`);
|
||||
}
|
||||
|
||||
this.renderers_[markupLanguage] = new RendererClass(this.options_);
|
||||
return this.renderers_[markupLanguage];
|
||||
}
|
||||
|
||||
injectedJavaScript() {
|
||||
return '';
|
||||
}
|
||||
|
||||
render(markupLanguage, markup, theme, options) {
|
||||
return this.renderer(markupLanguage).render(markup, theme, options);
|
||||
}
|
||||
}
|
||||
|
||||
MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN = 1;
|
||||
MarkupToHtml.MARKUP_LANGUAGE_HTML = 2;
|
||||
|
||||
module.exports = MarkupToHtml;
|
243
ReactNativeClient/lib/joplin-renderer/MdToHtml.js
Normal file
243
ReactNativeClient/lib/joplin-renderer/MdToHtml.js
Normal file
@ -0,0 +1,243 @@
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const md5 = require('md5');
|
||||
const noteStyle = require('./noteStyle');
|
||||
const { fileExtension } = require('./pathUtils');
|
||||
const rules = {
|
||||
image: require('./MdToHtml/rules/image'),
|
||||
checkbox: require('./MdToHtml/rules/checkbox'),
|
||||
katex: require('./MdToHtml/rules/katex'),
|
||||
link_open: require('./MdToHtml/rules/link_open'),
|
||||
html_image: require('./MdToHtml/rules/html_image'),
|
||||
highlight_keywords: require('./MdToHtml/rules/highlight_keywords'),
|
||||
code_inline: require('./MdToHtml/rules/code_inline'),
|
||||
fountain: require('./MdToHtml/rules/fountain'),
|
||||
};
|
||||
const setupLinkify = require('./MdToHtml/setupLinkify');
|
||||
const hljs = require('highlight.js');
|
||||
const uslug = require('uslug');
|
||||
const markdownItAnchor = require('markdown-it-anchor');
|
||||
// The keys must match the corresponding entry in Setting.js
|
||||
const plugins = {
|
||||
mark: { module: require('markdown-it-mark') },
|
||||
footnote: { module: require('markdown-it-footnote') },
|
||||
sub: { module: require('markdown-it-sub') },
|
||||
sup: { module: require('markdown-it-sup') },
|
||||
deflist: { module: require('markdown-it-deflist') },
|
||||
abbr: { module: require('markdown-it-abbr') },
|
||||
emoji: { module: require('markdown-it-emoji') },
|
||||
insert: { module: require('markdown-it-ins') },
|
||||
multitable: { module: require('markdown-it-multimd-table'), options: { multiline: true, rowspan: true, headerless: true } },
|
||||
toc: { module: require('markdown-it-toc-done-right'), options: { listType: 'ul', slugify: uslugify } },
|
||||
};
|
||||
const defaultNoteStyle = require('./defaultNoteStyle');
|
||||
|
||||
function uslugify(s) {
|
||||
return uslug(s);
|
||||
}
|
||||
|
||||
class MdToHtml {
|
||||
constructor(options = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
// Must include last "/"
|
||||
this.resourceBaseUrl_ = 'resourceBaseUrl' in options ? options.resourceBaseUrl : null;
|
||||
|
||||
this.cachedOutputs_ = {};
|
||||
|
||||
this.lastCodeHighlightCacheKey_ = null;
|
||||
this.cachedHighlightedCode_ = {};
|
||||
this.ResourceModel_ = options.ResourceModel;
|
||||
this.pluginOptions_ = options.pluginOptions ? options.pluginOptions : {};
|
||||
}
|
||||
|
||||
pluginOptions(name) {
|
||||
let o = this.pluginOptions_[name] ? this.pluginOptions_[name] : {};
|
||||
o = Object.assign({
|
||||
enabled: true,
|
||||
}, o);
|
||||
return o;
|
||||
}
|
||||
|
||||
pluginEnabled(name) {
|
||||
return this.pluginOptions(name).enabled;
|
||||
}
|
||||
|
||||
processPluginAssets(pluginAssets) {
|
||||
const files = [];
|
||||
const cssStrings = [];
|
||||
for (const pluginName in pluginAssets) {
|
||||
for (const asset of pluginAssets[pluginName]) {
|
||||
let mime = asset.mime;
|
||||
|
||||
if (!mime && asset.inline) throw new Error('Mime type is required for inline assets');
|
||||
|
||||
if (!mime) {
|
||||
const ext = fileExtension(asset.name).toLowerCase();
|
||||
// For now it's only useful to support CSS and JS because that's what needs to be added
|
||||
// by the caller with <script> or <style> tags. Everything, like fonts, etc. is loaded
|
||||
// via CSS or some other ways.
|
||||
mime = 'application/octet-stream';
|
||||
if (ext === 'css') mime = 'text/css';
|
||||
if (ext === 'js') mime = 'application/javascript';
|
||||
}
|
||||
|
||||
if (asset.inline) {
|
||||
if (mime === 'text/css') {
|
||||
cssStrings.push(asset.text);
|
||||
} else {
|
||||
throw new Error(`Unsupported inline mime type: ${mime}`);
|
||||
}
|
||||
} else {
|
||||
files.push(Object.assign({}, asset, {
|
||||
name: `${pluginName}/${asset.name}`,
|
||||
mime: mime,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
files: files,
|
||||
cssStrings: cssStrings,
|
||||
};
|
||||
}
|
||||
|
||||
async render(body, style = null, options = null) {
|
||||
if (!options) options = {};
|
||||
if (!options.postMessageSyntax) options.postMessageSyntax = 'postMessage';
|
||||
if (!options.paddingBottom) options.paddingBottom = '0';
|
||||
if (!options.highlightedKeywords) options.highlightedKeywords = [];
|
||||
if (!options.codeTheme) options.codeTheme = 'atom-one-light.css';
|
||||
|
||||
if (!style) style = Object.assign({}, defaultNoteStyle);
|
||||
|
||||
// The "codeHighlightCacheKey" option indicates what set of cached object should be
|
||||
// associated with this particular Markdown body. It is only used to allow us to
|
||||
// clear the cache whenever switching to a different note.
|
||||
// If "codeHighlightCacheKey" is not specified, code highlighting won't be cached.
|
||||
if (options.codeHighlightCacheKey !== this.lastCodeHighlightCacheKey_ || !options.codeHighlightCacheKey) {
|
||||
this.cachedHighlightedCode_ = {};
|
||||
this.lastCodeHighlightCacheKey_ = options.codeHighlightCacheKey;
|
||||
}
|
||||
|
||||
const cacheKey = md5(escape(body + JSON.stringify(options) + JSON.stringify(style)));
|
||||
const cachedOutput = this.cachedOutputs_[cacheKey];
|
||||
if (cachedOutput) return cachedOutput;
|
||||
|
||||
const context = {
|
||||
css: {},
|
||||
pluginAssets: {},
|
||||
};
|
||||
|
||||
const ruleOptions = Object.assign({}, options, {
|
||||
resourceBaseUrl: this.resourceBaseUrl_,
|
||||
ResourceModel: this.ResourceModel_,
|
||||
});
|
||||
|
||||
const markdownIt = new MarkdownIt({
|
||||
breaks: !this.pluginEnabled('softbreaks'),
|
||||
typographer: this.pluginEnabled('typographer'),
|
||||
linkify: true,
|
||||
html: true,
|
||||
highlight: (str, lang) => {
|
||||
try {
|
||||
let hlCode = '';
|
||||
|
||||
const cacheKey = md5(`${str}_${lang}`);
|
||||
|
||||
if (options.codeHighlightCacheKey && this.cachedHighlightedCode_[cacheKey]) {
|
||||
hlCode = this.cachedHighlightedCode_[cacheKey];
|
||||
} else {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
hlCode = hljs.highlight(lang, str, true).value;
|
||||
} else {
|
||||
hlCode = hljs.highlightAuto(str).value;
|
||||
}
|
||||
this.cachedHighlightedCode_[cacheKey] = hlCode;
|
||||
}
|
||||
|
||||
context.pluginAssets['highlight.js'] = [
|
||||
{ name: options.codeTheme },
|
||||
];
|
||||
|
||||
return `<pre class="hljs"><code>${hlCode}</code></pre>`;
|
||||
} catch (error) {
|
||||
return `<pre class="hljs"><code>${markdownIt.utils.escapeHtml(str)}</code></pre>`;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// To add a plugin, there are three options:
|
||||
//
|
||||
// 1. If the plugin does not need any application specific data, use the standard way:
|
||||
//
|
||||
// const someMarkdownPlugin = require('someMarkdownPlugin');
|
||||
// markdownIt.use(someMarkdownPlugin);
|
||||
//
|
||||
// 2. If the plugin does not need any application specific data, and you want the user
|
||||
// to be able to toggle the plugin:
|
||||
//
|
||||
// Add the plugin to the plugins object
|
||||
// const plugins = {
|
||||
// plugin: require('someMarkdownPlugin'),
|
||||
// }
|
||||
//
|
||||
// And add a corresponding entry into Setting.js
|
||||
// 'markdown.plugin.mark': {value: true, type: Setting.TYPE_BOOL, section: 'plugins', public: true, appTypes: ['mobile', 'desktop'], label: () => _('Enable ==mark== syntax')},
|
||||
//
|
||||
// 3. If the plugin needs application data (in ruleOptions) or needs to pass data (CSS, files to load, etc.) back
|
||||
// to the application (using the context object), use the application-specific way:
|
||||
//
|
||||
// const imagePlugin = require('./MdToHtml/rules/image');
|
||||
// markdownIt.use(imagePlugin(context, ruleOptions));
|
||||
//
|
||||
// Using the `context` object, a plugin can define what additional assets they need (css, fonts, etc.) using context.pluginAssets.
|
||||
// The calling application will need to handle loading these assets.
|
||||
|
||||
markdownIt.use(rules.image(context, ruleOptions));
|
||||
markdownIt.use(rules.checkbox(context, ruleOptions));
|
||||
markdownIt.use(rules.link_open(context, ruleOptions));
|
||||
markdownIt.use(rules.html_image(context, ruleOptions));
|
||||
if (this.pluginEnabled('katex')) markdownIt.use(rules.katex(context, ruleOptions));
|
||||
if (this.pluginEnabled('fountain')) markdownIt.use(rules.fountain(context, ruleOptions));
|
||||
markdownIt.use(rules.highlight_keywords(context, ruleOptions));
|
||||
markdownIt.use(rules.code_inline(context, ruleOptions));
|
||||
markdownIt.use(markdownItAnchor, { slugify: uslugify });
|
||||
|
||||
for (let key in plugins) {
|
||||
if (this.pluginEnabled(key)) markdownIt.use(plugins[key].module, plugins[key].options);
|
||||
}
|
||||
|
||||
setupLinkify(markdownIt);
|
||||
|
||||
const renderedBody = markdownIt.render(body);
|
||||
|
||||
let cssStrings = noteStyle(style, options);
|
||||
|
||||
const pluginAssets = this.processPluginAssets(context.pluginAssets);
|
||||
cssStrings = cssStrings.concat(pluginAssets.cssStrings);
|
||||
|
||||
if (options.userCss) cssStrings.push(options.userCss);
|
||||
|
||||
const styleHtml = `<style>${cssStrings.join('\n')}</style>`;
|
||||
|
||||
const html = `${styleHtml}<div id="rendered-md">${renderedBody}</div>`;
|
||||
|
||||
const output = {
|
||||
html: html,
|
||||
pluginAssets: pluginAssets.files,
|
||||
};
|
||||
|
||||
// Fow now, we keep only the last entry in the cache
|
||||
this.cachedOutputs_ = {};
|
||||
this.cachedOutputs_[cacheKey] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
injectedJavaScript() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MdToHtml;
|
134
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
Normal file
134
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/checkbox.js
Normal file
@ -0,0 +1,134 @@
|
||||
let checkboxIndex_ = -1;
|
||||
|
||||
const checkboxStyle = `
|
||||
/* Remove the indentation from the checkboxes at the root of the document
|
||||
(otherwise they are too far right), but keep it for their children to allow
|
||||
nested lists. Make sure this value matches the UL margin. */
|
||||
|
||||
#rendered-md > ul > li.md-checkbox {
|
||||
margin-left: -1.7em;
|
||||
}
|
||||
|
||||
li.md-checkbox {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
li.md-checkbox input[type=checkbox] {
|
||||
margin-right: 1em;
|
||||
}
|
||||
`;
|
||||
|
||||
function createPrefixTokens(Token, id, checked, label, postMessageSyntax, sourceToken) {
|
||||
let token = null;
|
||||
const tokens = [];
|
||||
|
||||
// A bit hard to handle errors here and it's unlikely that the token won't have a valid
|
||||
// map parameter, but if it does set it to a very high value, which will be more easy to notice
|
||||
// in calling code.
|
||||
const lineIndex = sourceToken.map && sourceToken.map.length ? sourceToken.map[0] : 99999999;
|
||||
const checkedString = checked ? 'checked' : 'unchecked';
|
||||
|
||||
const labelId = `cb-label-${id}`;
|
||||
|
||||
const js = `
|
||||
${postMessageSyntax}('checkboxclick:${checkedString}:${lineIndex}');
|
||||
const label = document.getElementById("${labelId}");
|
||||
label.classList.remove(this.checked ? 'checkbox-label-unchecked' : 'checkbox-label-checked');
|
||||
label.classList.add(this.checked ? 'checkbox-label-checked' : 'checkbox-label-unchecked');
|
||||
return true;
|
||||
`;
|
||||
|
||||
token = new Token('checkbox_input', 'input', 0);
|
||||
token.attrs = [['type', 'checkbox'], ['id', id], ['onclick', js]];
|
||||
if (checked) token.attrs.push(['checked', 'true']);
|
||||
tokens.push(token);
|
||||
|
||||
token = new Token('label_open', 'label', 1);
|
||||
token.attrs = [['id', labelId], ['for', id], ['class', `checkbox-label-${checkedString}`]];
|
||||
tokens.push(token);
|
||||
|
||||
if (label) {
|
||||
token = new Token('text', '', 0);
|
||||
token.content = label;
|
||||
tokens.push(token);
|
||||
}
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
function createSuffixTokens(Token) {
|
||||
return [new Token('label_close', 'label', -1)];
|
||||
}
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions, context) {
|
||||
markdownIt.core.ruler.push('checkbox', state => {
|
||||
const tokens = state.tokens;
|
||||
const Token = state.Token;
|
||||
|
||||
const checkboxPattern = /^\[([x|X| ])\] (.*)$/;
|
||||
let currentListItem = null;
|
||||
let processedFirstInline = false;
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
|
||||
if (token.type === 'list_item_open') {
|
||||
currentListItem = token;
|
||||
processedFirstInline = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token.type === 'list_item_close') {
|
||||
currentListItem = null;
|
||||
processedFirstInline = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Note that we only support list items that start with "-" (not with "*")
|
||||
if (currentListItem && currentListItem.markup === '-' && !processedFirstInline && token.type === 'inline') {
|
||||
processedFirstInline = true;
|
||||
const firstChild = token.children && token.children.length ? token.children[0] : null;
|
||||
if (!firstChild) continue;
|
||||
|
||||
const matches = checkboxPattern.exec(firstChild.content);
|
||||
if (!matches || matches.length < 2) continue;
|
||||
|
||||
checkboxIndex_++;
|
||||
const checked = matches[1] !== ' ';
|
||||
const id = `md-checkbox-${checkboxIndex_}`;
|
||||
const label = matches.length >= 3 ? matches[2] : '';
|
||||
|
||||
// Prepend the text content with the checkbox markup and the opening <label> tag
|
||||
// then append the </label> tag at the end of the text content.
|
||||
|
||||
const prefix = createPrefixTokens(Token, id, checked, label, ruleOptions.postMessageSyntax, token);
|
||||
const suffix = createSuffixTokens(Token);
|
||||
|
||||
token.children = markdownIt.utils.arrayReplaceAt(token.children, 0, prefix);
|
||||
token.children = token.children.concat(suffix);
|
||||
|
||||
// Add a class to the <li> container so that it can be targetted with CSS.
|
||||
|
||||
let itemClass = currentListItem.attrGet('class');
|
||||
if (!itemClass) itemClass = '';
|
||||
itemClass += ' md-checkbox';
|
||||
currentListItem.attrSet('class', itemClass.trim());
|
||||
|
||||
if (!('checkbox' in context.pluginAssets)) {
|
||||
context.pluginAssets['checkbox'] = [
|
||||
{
|
||||
inline: true,
|
||||
text: checkboxStyle,
|
||||
mime: 'text/css',
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions, context);
|
||||
};
|
||||
};
|
@ -0,0 +1,22 @@
|
||||
function installRule(markdownIt) {
|
||||
const defaultRender =
|
||||
markdownIt.renderer.rules.code_inline ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
markdownIt.renderer.rules.code_inline = (tokens, idx, options, env, self) => {
|
||||
const token = tokens[idx];
|
||||
let tokenClass = token.attrGet('class');
|
||||
if (!tokenClass) tokenClass = '';
|
||||
tokenClass += ' inline-code';
|
||||
token.attrSet('class', tokenClass.trim());
|
||||
return defaultRender(tokens, idx, options, env, self);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
141
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fountain.js
Normal file
141
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/fountain.js
Normal file
@ -0,0 +1,141 @@
|
||||
const fountain = require('../../vendor/fountain.min.js');
|
||||
|
||||
const fountainCss = `
|
||||
.fountain {
|
||||
font-family: monospace;
|
||||
line-height: 107%;
|
||||
max-width: 1000px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.fountain .title-page,
|
||||
.fountain .page {
|
||||
box-shadow: 0 0 5px rgba(0,0,0,0.1);
|
||||
border: 1px solid #d2d2d2;
|
||||
padding: 10%;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.fountain h1,
|
||||
.fountain h2,
|
||||
.fountain h3,
|
||||
.fountain h4,
|
||||
.fountain p {
|
||||
font-weight: normal;
|
||||
line-height: 107%;
|
||||
margin: 1em 0;
|
||||
border: none;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.fountain .bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fountain .underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.fountain .centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fountain h2 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fountain .dialogue p.parenthetical {
|
||||
margin-left: 11%;
|
||||
}
|
||||
|
||||
.fountain .title-page .credit,
|
||||
.fountain .title-page .authors,
|
||||
.fountain .title-page .source {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fountain .title-page h1 {
|
||||
margin-bottom: 1.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fountain .title-page .source {
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.fountain .title-page .notes {
|
||||
text-align: right;
|
||||
margin: 3em 0;
|
||||
}
|
||||
|
||||
.fountain .title-page h1 {
|
||||
margin-bottom: 1.5em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fountain .dialogue {
|
||||
margin-left: 3em;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
.fountain .dialogue p,
|
||||
.fountain .dialogue h1,
|
||||
.fountain .dialogue h2,
|
||||
.fountain .dialogue h3,
|
||||
.fountain .dialogue h4 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.fountain .dialogue h1,
|
||||
.fountain .dialogue h2,
|
||||
.fountain .dialogue h3,
|
||||
.fountain .dialogue h4 {
|
||||
text-align: center;
|
||||
}
|
||||
`;
|
||||
|
||||
function renderFountainScript(content) {
|
||||
const result = fountain.parse(content);
|
||||
return `
|
||||
<div class="fountain">
|
||||
<div class="title-page">
|
||||
${result.html.title_page}
|
||||
</div>
|
||||
<div class="page">
|
||||
${result.html.script}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function addContextAssets(context) {
|
||||
if ('fountain' in context.pluginAssets) return;
|
||||
|
||||
context.pluginAssets['fountain'] = [
|
||||
{
|
||||
inline: true,
|
||||
text: fountainCss,
|
||||
mime: 'text/css',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions, context) {
|
||||
const defaultRender = markdownIt.renderer.rules.fence || function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
markdownIt.renderer.rules.fence = function(tokens, idx, options, env, self) {
|
||||
const token = tokens[idx];
|
||||
if (token.info !== 'fountain') return defaultRender(tokens, idx, options, env, self);
|
||||
addContextAssets(context);
|
||||
return renderFountainScript(token.content);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions, context);
|
||||
};
|
||||
};
|
@ -0,0 +1,67 @@
|
||||
const stringUtils = require('../../stringUtils.js');
|
||||
const md5 = require('md5');
|
||||
|
||||
function createHighlightedTokens(Token, splitted) {
|
||||
let token;
|
||||
const output = [];
|
||||
|
||||
for (let i = 0; i < splitted.length; i++) {
|
||||
const text = splitted[i];
|
||||
if (!text) continue;
|
||||
|
||||
if (i % 2 === 0) {
|
||||
token = new Token('text', '', 0);
|
||||
token.content = text;
|
||||
output.push(token);
|
||||
} else {
|
||||
token = new Token('highlighted_keyword_open', 'span', 1);
|
||||
token.attrs = [['class', 'highlighted-keyword']];
|
||||
output.push(token);
|
||||
|
||||
token = new Token('text', '', 0);
|
||||
token.content = text;
|
||||
output.push(token);
|
||||
|
||||
token = new Token('highlighted_keyword_close', 'span', -1);
|
||||
output.push(token);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const divider = md5(Date.now().toString() + Math.random().toString());
|
||||
|
||||
markdownIt.core.ruler.push('highlight_keywords', state => {
|
||||
const keywords = ruleOptions.highlightedKeywords;
|
||||
if (!keywords || !keywords.length) return;
|
||||
|
||||
const tokens = state.tokens;
|
||||
const Token = state.Token;
|
||||
|
||||
for (let i = 0; i < tokens.length; i++) {
|
||||
const token = tokens[i];
|
||||
|
||||
if (token.type !== 'inline') continue;
|
||||
|
||||
for (let j = 0; j < token.children.length; j++) {
|
||||
const child = token.children[j];
|
||||
if (child.type !== 'text') continue;
|
||||
|
||||
const splitted = stringUtils.surroundKeywords(keywords, child.content, divider, divider).split(divider);
|
||||
const splittedTokens = createHighlightedTokens(Token, splitted);
|
||||
if (splittedTokens.length <= 1) continue;
|
||||
|
||||
token.children = markdownIt.utils.arrayReplaceAt(token.children, j, splittedTokens);
|
||||
j += splittedTokens.length - 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
@ -0,0 +1,53 @@
|
||||
// const Resource = require('lib/models/Resource.js');
|
||||
const htmlUtils = require('../../htmlUtils.js');
|
||||
const utils = require('../../utils');
|
||||
|
||||
function renderImageHtml(before, src, after, ruleOptions) {
|
||||
const r = utils.imageReplacement(ruleOptions.ResourceModel, src, ruleOptions.resources, ruleOptions.resourceBaseUrl);
|
||||
if (typeof r === 'string') return r;
|
||||
if (r) return `<img ${before} ${htmlUtils.attributesHtml(r)} ${after}/>`;
|
||||
return `[Image: ${src}]`;
|
||||
}
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const Resource = ruleOptions.ResourceModel;
|
||||
|
||||
const htmlBlockDefaultRender =
|
||||
markdownIt.renderer.rules.html_block ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
const htmlInlineDefaultRender =
|
||||
markdownIt.renderer.rules.html_inline ||
|
||||
function(tokens, idx, options, env, self) {
|
||||
return self.renderToken(tokens, idx, options);
|
||||
};
|
||||
|
||||
const imageRegex = /<img(.*?)src=["'](.*?)["'](.*?)>/gi;
|
||||
|
||||
const handleImageTags = function(defaultRender) {
|
||||
return function(tokens, idx, options, env, self) {
|
||||
const token = tokens[idx];
|
||||
const content = token.content;
|
||||
|
||||
if (!content.match(imageRegex)) return defaultRender(tokens, idx, options, env, self);
|
||||
|
||||
return content.replace(imageRegex, (v, before, src, after) => {
|
||||
if (!Resource.isResourceUrl(src)) return defaultRender(tokens, idx, options, env, self);
|
||||
return renderImageHtml(before, src, after, ruleOptions);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// It seems images sometimes are inline, sometimes a block
|
||||
// to make sure they both render correctly.
|
||||
markdownIt.renderer.rules.html_block = handleImageTags(htmlBlockDefaultRender);
|
||||
markdownIt.renderer.rules.html_inline = handleImageTags(htmlInlineDefaultRender);
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
// const Resource = require('lib/models/Resource.js');
|
||||
const utils = require('../../utils');
|
||||
const htmlUtils = require('../../htmlUtils.js');
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
const defaultRender = markdownIt.renderer.rules.image;
|
||||
|
||||
markdownIt.renderer.rules.image = (tokens, idx, options, env, self) => {
|
||||
const Resource = ruleOptions.ResourceModel;
|
||||
|
||||
const token = tokens[idx];
|
||||
const src = utils.getAttr(token.attrs, 'src');
|
||||
const title = utils.getAttr(token.attrs, 'title');
|
||||
|
||||
if (!Resource.isResourceUrl(src) || ruleOptions.plainResourceRendering) return defaultRender(tokens, idx, options, env, self);
|
||||
|
||||
const r = utils.imageReplacement(ruleOptions.ResourceModel, src, ruleOptions.resources, ruleOptions.resourceBaseUrl);
|
||||
if (typeof r === 'string') return r;
|
||||
if (r) return `<img data-from-md ${htmlUtils.attributesHtml(Object.assign({}, r, { title: title }))}/>`;
|
||||
|
||||
return defaultRender(tokens, idx, options, env, self);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
262
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex.js
Normal file
262
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex.js
Normal file
@ -0,0 +1,262 @@
|
||||
// Based on https://github.com/waylonflinn/markdown-it-katex
|
||||
|
||||
'use strict';
|
||||
|
||||
let katex = require('katex');
|
||||
const md5 = require('md5');
|
||||
const mhchemModule = require('./katex_mhchem.js');
|
||||
|
||||
// Katex macros include circular references so we need
|
||||
// to serialize them with json-stringify-safe
|
||||
const stringifySafe = require('json-stringify-safe');
|
||||
|
||||
katex = mhchemModule(katex);
|
||||
|
||||
// Test if potential opening or closing delimieter
|
||||
// Assumes that there is a "$" at state.src[pos]
|
||||
function isValidDelim(state, pos) {
|
||||
var prevChar,
|
||||
nextChar,
|
||||
max = state.posMax,
|
||||
can_open = true,
|
||||
can_close = true;
|
||||
|
||||
prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1;
|
||||
nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1;
|
||||
|
||||
// Check non-whitespace conditions for opening and closing, and
|
||||
// check that closing delimeter isn't followed by a number
|
||||
if (prevChar === 0x20 /* " " */ || prevChar === 0x09 /* \t */ || (nextChar >= 0x30 /* "0" */ && nextChar <= 0x39) /* "9" */) {
|
||||
can_close = false;
|
||||
}
|
||||
if (nextChar === 0x20 /* " " */ || nextChar === 0x09 /* \t */) {
|
||||
can_open = false;
|
||||
}
|
||||
|
||||
return {
|
||||
can_open: can_open,
|
||||
can_close: can_close,
|
||||
};
|
||||
}
|
||||
|
||||
function math_inline(state, silent) {
|
||||
var start, match, token, res, pos;
|
||||
|
||||
if (state.src[state.pos] !== '$') {
|
||||
return false;
|
||||
}
|
||||
|
||||
res = isValidDelim(state, state.pos);
|
||||
if (!res.can_open) {
|
||||
if (!silent) {
|
||||
state.pending += '$';
|
||||
}
|
||||
state.pos += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// First check for and bypass all properly escaped delimieters
|
||||
// This loop will assume that the first leading backtick can not
|
||||
// be the first character in state.src, which is known since
|
||||
// we have found an opening delimieter already.
|
||||
start = state.pos + 1;
|
||||
match = start;
|
||||
while ((match = state.src.indexOf('$', match)) !== -1) {
|
||||
// Found potential $, look for escapes, pos will point to
|
||||
// first non escape when complete
|
||||
pos = match - 1;
|
||||
while (state.src[pos] === '\\') {
|
||||
pos -= 1;
|
||||
}
|
||||
|
||||
// Even number of escapes, potential closing delimiter found
|
||||
if ((match - pos) % 2 == 1) {
|
||||
break;
|
||||
}
|
||||
match += 1;
|
||||
}
|
||||
|
||||
// No closing delimter found. Consume $ and continue.
|
||||
if (match === -1) {
|
||||
if (!silent) {
|
||||
state.pending += '$';
|
||||
}
|
||||
state.pos = start;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if we have empty content, ie: $$. Do not parse.
|
||||
if (match - start === 0) {
|
||||
if (!silent) {
|
||||
state.pending += '$$';
|
||||
}
|
||||
state.pos = start + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for valid closing delimiter
|
||||
res = isValidDelim(state, match);
|
||||
if (!res.can_close) {
|
||||
if (!silent) {
|
||||
state.pending += '$';
|
||||
}
|
||||
state.pos = start;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!silent) {
|
||||
token = state.push('math_inline', 'math', 0);
|
||||
token.markup = '$';
|
||||
token.content = state.src.slice(start, match);
|
||||
}
|
||||
|
||||
state.pos = match + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
function math_block(state, start, end, silent) {
|
||||
var firstLine,
|
||||
lastLine,
|
||||
next,
|
||||
lastPos,
|
||||
found = false,
|
||||
token,
|
||||
pos = state.bMarks[start] + state.tShift[start],
|
||||
max = state.eMarks[start];
|
||||
|
||||
if (pos + 2 > max) {
|
||||
return false;
|
||||
}
|
||||
if (state.src.slice(pos, pos + 2) !== '$$') {
|
||||
return false;
|
||||
}
|
||||
|
||||
pos += 2;
|
||||
firstLine = state.src.slice(pos, max);
|
||||
|
||||
if (silent) {
|
||||
return true;
|
||||
}
|
||||
if (firstLine.trim().slice(-2) === '$$') {
|
||||
// Single line expression
|
||||
firstLine = firstLine.trim().slice(0, -2);
|
||||
found = true;
|
||||
}
|
||||
|
||||
for (next = start; !found;) {
|
||||
next++;
|
||||
|
||||
if (next >= end) {
|
||||
break;
|
||||
}
|
||||
|
||||
pos = state.bMarks[next] + state.tShift[next];
|
||||
max = state.eMarks[next];
|
||||
|
||||
if (pos < max && state.tShift[next] < state.blkIndent) {
|
||||
// non-empty line with negative indent should stop the list:
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
state.src
|
||||
.slice(pos, max)
|
||||
.trim()
|
||||
.slice(-2) === '$$'
|
||||
) {
|
||||
lastPos = state.src.slice(0, max).lastIndexOf('$$');
|
||||
lastLine = state.src.slice(pos, lastPos);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
state.line = next + 1;
|
||||
|
||||
token = state.push('math_block', 'math', 0);
|
||||
token.block = true;
|
||||
token.content = (firstLine && firstLine.trim() ? `${firstLine}\n` : '') + state.getLines(start + 1, next, state.tShift[start], true) + (lastLine && lastLine.trim() ? lastLine : '');
|
||||
token.map = [start, state.line];
|
||||
token.markup = '$$';
|
||||
return true;
|
||||
}
|
||||
|
||||
let cache_ = {};
|
||||
|
||||
module.exports = function(context) {
|
||||
// Keep macros that persist across Katex blocks to allow defining a macro
|
||||
// in one block and re-using it later in other blocks.
|
||||
// https://github.com/laurent22/joplin/issues/1105
|
||||
context.__katex = { macros: {} };
|
||||
|
||||
const addContextAssets = () => {
|
||||
context.pluginAssets['katex'] = [
|
||||
{ name: 'katex.css' },
|
||||
{ name: 'fonts/KaTeX_Main-Regular.woff2' },
|
||||
{ name: 'fonts/KaTeX_Math-Italic.woff2' },
|
||||
{ name: 'fonts/KaTeX_Size1-Regular.woff2' },
|
||||
];
|
||||
};
|
||||
|
||||
function renderToStringWithCache(latex, options) {
|
||||
console.info('OPTSON', stringifySafe(options));
|
||||
const cacheKey = md5(escape(latex) + escape(stringifySafe(options)));
|
||||
if (cacheKey in cache_) {
|
||||
return cache_[cacheKey];
|
||||
} else {
|
||||
const beforeMacros = stringifySafe(options.macros);
|
||||
const output = katex.renderToString(latex, options);
|
||||
const afterMacros = stringifySafe(options.macros);
|
||||
|
||||
// Don't cache the formulas that add macros, otherwise
|
||||
// they won't be added on second run.
|
||||
if (beforeMacros === afterMacros) cache_[cacheKey] = output;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
return function(md, options) {
|
||||
// Default options
|
||||
|
||||
options = options || {};
|
||||
options.macros = context.__katex.macros;
|
||||
options.trust = true;
|
||||
|
||||
// set KaTeX as the renderer for markdown-it-simplemath
|
||||
var katexInline = function(latex) {
|
||||
options.displayMode = false;
|
||||
try {
|
||||
return renderToStringWithCache(latex, options);
|
||||
} catch (error) {
|
||||
console.error('Katex error for:', latex, error);
|
||||
return latex;
|
||||
}
|
||||
};
|
||||
|
||||
var inlineRenderer = function(tokens, idx) {
|
||||
addContextAssets();
|
||||
return katexInline(tokens[idx].content);
|
||||
};
|
||||
|
||||
var katexBlock = function(latex) {
|
||||
options.displayMode = true;
|
||||
try {
|
||||
return `<p>${renderToStringWithCache(latex, options)}</p>`;
|
||||
} catch (error) {
|
||||
console.error('Katex error for:', latex, error);
|
||||
return latex;
|
||||
}
|
||||
};
|
||||
|
||||
var blockRenderer = function(tokens, idx) {
|
||||
addContextAssets();
|
||||
return `${katexBlock(tokens[idx].content)}\n`;
|
||||
};
|
||||
|
||||
md.inline.ruler.after('escape', 'math_inline', math_inline);
|
||||
md.block.ruler.after('blockquote', 'math_block', math_block, {
|
||||
alt: ['paragraph', 'reference', 'blockquote', 'list'],
|
||||
});
|
||||
md.renderer.rules.math_inline = inlineRenderer;
|
||||
md.renderer.rules.math_block = blockRenderer;
|
||||
};
|
||||
};
|
1732
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex_mhchem.js
Normal file
1732
ReactNativeClient/lib/joplin-renderer/MdToHtml/rules/katex_mhchem.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,74 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
const utils = require('../../utils');
|
||||
const urlUtils = require('../../urlUtils.js');
|
||||
const { getClassNameForMimeType } = require('font-awesome-filetypes');
|
||||
|
||||
function installRule(markdownIt, mdOptions, ruleOptions) {
|
||||
markdownIt.renderer.rules.link_open = function(tokens, idx) {
|
||||
const token = tokens[idx];
|
||||
let href = utils.getAttr(token.attrs, 'href');
|
||||
const resourceHrefInfo = urlUtils.parseResourceUrl(href);
|
||||
const isResourceUrl = !!resourceHrefInfo;
|
||||
let title = utils.getAttr(token.attrs, 'title', isResourceUrl ? '' : href);
|
||||
|
||||
let resourceIdAttr = '';
|
||||
let icon = '';
|
||||
let hrefAttr = '#';
|
||||
let mime = '';
|
||||
if (isResourceUrl) {
|
||||
const resourceId = resourceHrefInfo.itemId;
|
||||
|
||||
const result = ruleOptions.resources[resourceId];
|
||||
const resourceStatus = utils.resourceStatus(ruleOptions.ResourceModel, result);
|
||||
|
||||
if (result && result.item) {
|
||||
title = utils.getAttr(token.attrs, 'title', result.item.title);
|
||||
mime = result.item.mime;
|
||||
}
|
||||
|
||||
if (result && resourceStatus !== 'ready' && !ruleOptions.plainResourceRendering) {
|
||||
const icon = utils.resourceStatusFile(resourceStatus);
|
||||
return `<a class="not-loaded-resource resource-status-${resourceStatus}" data-resource-id="${resourceId}">` + `<img src="data:image/svg+xml;utf8,${htmlentities(icon)}"/>`;
|
||||
} else {
|
||||
href = `joplin://${resourceId}`;
|
||||
if (resourceHrefInfo.hash) href += `#${resourceHrefInfo.hash}`;
|
||||
resourceIdAttr = `data-resource-id='${resourceId}'`;
|
||||
|
||||
let iconType = getClassNameForMimeType(mime);
|
||||
if (!mime) {
|
||||
iconType = 'fa-joplin';
|
||||
}
|
||||
// Icons are defined in lib/renderers/noteStyle.js using inline svg
|
||||
// The icons are taken from fork-awesome but use the font-awesome naming scheme in order
|
||||
// to be more compatible with the getClass library
|
||||
icon = `<span class="resource-icon ${iconType}"></span>`;
|
||||
}
|
||||
} else {
|
||||
// If the link is a plain URL (as opposed to a resource link), set the href to the actual
|
||||
// link. This allows the link to be exported too when exporting to PDF.
|
||||
hrefAttr = href;
|
||||
}
|
||||
|
||||
// A single quote is valid in a URL but we don't want any because the
|
||||
// href is already enclosed in single quotes.
|
||||
// https://github.com/laurent22/joplin/issues/2030
|
||||
href = href.replace(/'/g, '%27');
|
||||
|
||||
let js = `${ruleOptions.postMessageSyntax}(${JSON.stringify(href)}); return false;`;
|
||||
if (hrefAttr.indexOf('#') === 0 && href.indexOf('#') === 0) js = ''; // If it's an internal anchor, don't add any JS since the webview is going to handle navigating to the right place
|
||||
|
||||
if (ruleOptions.plainResourceRendering) {
|
||||
return `<a data-from-md ${resourceIdAttr} title='${htmlentities(title)}' href='${hrefAttr}' type='${htmlentities(mime)}'>`;
|
||||
} else {
|
||||
return `<a data-from-md ${resourceIdAttr} title='${htmlentities(title)}' href='${hrefAttr}' onclick='${js}' type='${htmlentities(mime)}'>${icon}`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = function(context, ruleOptions) {
|
||||
|
||||
return function(md, mdOptions) {
|
||||
installRule(md, mdOptions, ruleOptions);
|
||||
};
|
||||
};
|
@ -0,0 +1,29 @@
|
||||
module.exports = function(markdownIt) {
|
||||
// Add `file:` protocol in linkify to allow text in the format of "file://..." to translate into
|
||||
// file-URL links in html view
|
||||
markdownIt.linkify.add('file:', {
|
||||
validate: function(text, pos, self) {
|
||||
var tail = text.slice(pos);
|
||||
if (!self.re.file) {
|
||||
// matches all local file URI on Win/Unix/MacOS systems including reserved characters in some OS (i.e. no OS specific sanity check)
|
||||
self.re.file = new RegExp('^[\\/]{2,3}[\\S]+');
|
||||
}
|
||||
if (self.re.file.test(tail)) {
|
||||
return tail.match(self.re.file)[0].length;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
});
|
||||
|
||||
// enable file link URLs in MarkdownIt. Keeps other URL restrictions of MarkdownIt untouched.
|
||||
// Format [link name](file://...)
|
||||
markdownIt.validateLink = function(url) {
|
||||
var BAD_PROTO_RE = /^(vbscript|javascript|data):/;
|
||||
var GOOD_DATA_RE = /^data:image\/(gif|png|jpeg|webp);/;
|
||||
|
||||
// url should be normalized at this point, and existing entities are decoded
|
||||
var str = url.trim().toLowerCase();
|
||||
|
||||
return BAD_PROTO_RE.test(str) ? (GOOD_DATA_RE.test(str) ? true : false) : true;
|
||||
};
|
||||
};
|
52
ReactNativeClient/lib/joplin-renderer/README.md
Normal file
52
ReactNativeClient/lib/joplin-renderer/README.md
Normal file
@ -0,0 +1,52 @@
|
||||
# Joplin Renderer
|
||||
|
||||
This is the renderer used by [Joplin](https://github.com/laurent22/joplin) to render notes in Markdown or HTML format.
|
||||
|
||||
## Installation
|
||||
|
||||
npm i -s joplin-renderer
|
||||
|
||||
Certain plugins require additional assets like CSS, fonts, etc. These assets are in the `/assets` directory and should be copied to wherever the application can find them at runtime.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const { MarkupToHtml } = require('joplin-renderer');
|
||||
|
||||
const options = {};
|
||||
|
||||
// The notes are rendered using the provided theme. The supported theme properties are in `defaultNoteStyle.js`
|
||||
// and this is what is used if no theme is provided. A `theme` object can be provided to override default theme
|
||||
// properties.
|
||||
const theme = {};
|
||||
|
||||
const markdown = "Testing `MarkupToHtml` renderer";
|
||||
|
||||
const markupToHtml = new MarkupToHtml(options);
|
||||
const result = await markupToHtml.render(MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN, markdown, theme, options);
|
||||
|
||||
console.info('HTML:', result.html);
|
||||
console.info('Plugin assets:', result.pluginAssets);
|
||||
```
|
||||
|
||||
When calling `render()`, an object with the following properties is returned:
|
||||
|
||||
- `html`: The rendered HTML code
|
||||
- `pluginAssets`: The assets required by the plugins
|
||||
|
||||
The assets need to be loaded by the calling application. For example this is how they are loaded in the Joplin desktop application:
|
||||
|
||||
```js
|
||||
function loadPluginAssets(assets) {
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
const asset = assets[i];
|
||||
|
||||
if (asset.mime === 'text/css') {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'pluginAssets/' + asset.name;
|
||||
document.getElementById('joplin-container-styleContainer').appendChild(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
30
ReactNativeClient/lib/joplin-renderer/Tools/buildAssets.js
Normal file
30
ReactNativeClient/lib/joplin-renderer/Tools/buildAssets.js
Normal file
@ -0,0 +1,30 @@
|
||||
const fs = require('fs-extra');
|
||||
const {dirname } = require('../pathUtils');
|
||||
|
||||
const rootDir = dirname(__dirname);
|
||||
const assetsDir = `${rootDir}/assets`;
|
||||
|
||||
async function copyFile(source, dest) {
|
||||
const fullDest = `${assetsDir}/${dest}`;
|
||||
const dir = dirname(fullDest);
|
||||
await fs.mkdirp(dir);
|
||||
await fs.copy(source, fullDest);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await fs.remove(assetsDir);
|
||||
|
||||
await copyFile(`${rootDir}/node_modules/katex/dist/katex.min.css`, 'katex/katex.css');
|
||||
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Main-Regular.woff2`, 'katex/fonts/KaTeX_Main-Regular.woff2');
|
||||
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Math-Italic.woff2`, 'katex/fonts/KaTeX_Math-Italic.woff2');
|
||||
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Size1-Regular.woff2`, 'katex/fonts/KaTeX_Size1-Regular.woff2');
|
||||
await copyFile(`${rootDir}/node_modules/katex/dist/fonts/KaTeX_Size2-Regular.woff2`, 'katex/fonts/KaTeX_Size2-Regular.woff2');
|
||||
|
||||
await copyFile(`${rootDir}/node_modules/highlight.js/styles/atom-one-light.css`, 'highlight.js/atom-one-light.css');
|
||||
await copyFile(`${rootDir}/node_modules/highlight.js/styles/atom-one-dark-reasonable.css`, 'highlight.js/atom-one-dark-reasonable.css');
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
|
||||
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
|
||||
|
||||
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
|
||||
|
||||
*/
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #abb2bf;
|
||||
background: #282c34;
|
||||
}
|
||||
.hljs-keyword, .hljs-operator {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match {
|
||||
color: #F92672;
|
||||
}
|
||||
.hljs-pattern-match .hljs-constructor {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-function .hljs-params {
|
||||
color: #A6E22E;
|
||||
}
|
||||
.hljs-function .hljs-params .hljs-typing {
|
||||
color: #FD971F;
|
||||
}
|
||||
.hljs-module-access .hljs-module {
|
||||
color: #7e57c2;
|
||||
}
|
||||
.hljs-constructor {
|
||||
color: #e2b93d;
|
||||
}
|
||||
.hljs-constructor .hljs-string {
|
||||
color: #9CCC65;
|
||||
}
|
||||
.hljs-comment, .hljs-quote {
|
||||
color: #b18eb1;
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-doctag, .hljs-formula {
|
||||
color: #c678dd;
|
||||
}
|
||||
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
|
||||
color: #e06c75;
|
||||
}
|
||||
.hljs-literal {
|
||||
color: #56b6c2;
|
||||
}
|
||||
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
|
||||
color: #98c379;
|
||||
}
|
||||
.hljs-built_in, .hljs-class .hljs-title {
|
||||
color: #e6c07b;
|
||||
}
|
||||
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
|
||||
color: #d19a66;
|
||||
}
|
||||
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
|
||||
color: #61aeee;
|
||||
}
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
|
||||
Atom One Light by Daniel Gamage
|
||||
Original One Light Syntax theme from https://github.com/atom/one-light-syntax
|
||||
|
||||
base: #fafafa
|
||||
mono-1: #383a42
|
||||
mono-2: #686b77
|
||||
mono-3: #a0a1a7
|
||||
hue-1: #0184bb
|
||||
hue-2: #4078f2
|
||||
hue-3: #a626a4
|
||||
hue-4: #50a14f
|
||||
hue-5: #e45649
|
||||
hue-5-2: #c91243
|
||||
hue-6: #986801
|
||||
hue-6-2: #c18401
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
padding: 0.5em;
|
||||
color: #383a42;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #a0a1a7;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-doctag,
|
||||
.hljs-keyword,
|
||||
.hljs-formula {
|
||||
color: #a626a4;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-name,
|
||||
.hljs-selector-tag,
|
||||
.hljs-deletion,
|
||||
.hljs-subst {
|
||||
color: #e45649;
|
||||
}
|
||||
|
||||
.hljs-literal {
|
||||
color: #0184bb;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-regexp,
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-meta-string {
|
||||
color: #50a14f;
|
||||
}
|
||||
|
||||
.hljs-built_in,
|
||||
.hljs-class .hljs-title {
|
||||
color: #c18401;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-type,
|
||||
.hljs-selector-class,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo,
|
||||
.hljs-number {
|
||||
color: #986801;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-link,
|
||||
.hljs-meta,
|
||||
.hljs-selector-id,
|
||||
.hljs-title {
|
||||
color: #4078f2;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-link {
|
||||
text-decoration: underline;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
18
ReactNativeClient/lib/joplin-renderer/assetsToHeaders.js
Normal file
18
ReactNativeClient/lib/joplin-renderer/assetsToHeaders.js
Normal file
@ -0,0 +1,18 @@
|
||||
// Utility function to convert the plugin assets to a list of LINK or SCRIPT tags
|
||||
// that can be included in the HEAD tag.
|
||||
function assetsToHeaders(pluginAssets) {
|
||||
const headers = [];
|
||||
for (let i = 0; i < pluginAssets.length; i++) {
|
||||
const asset = pluginAssets[i];
|
||||
if (asset.mime === 'text/css') {
|
||||
headers.push(`<link rel="stylesheet" href="pluginAssets/${asset.name}">`);
|
||||
} else if (asset.mime === 'application/javascript') {
|
||||
// NOT TESTED!!
|
||||
headers.push(`<script type="application/javascript" src="pluginAssets/${asset.name}"></script>`);
|
||||
}
|
||||
}
|
||||
|
||||
return headers.join('\n');
|
||||
}
|
||||
|
||||
module.exports = assetsToHeaders;
|
19
ReactNativeClient/lib/joplin-renderer/defaultNoteStyle.js
Normal file
19
ReactNativeClient/lib/joplin-renderer/defaultNoteStyle.js
Normal file
@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
htmlFontSize: '15px',
|
||||
htmlColor: '#222222',
|
||||
htmlLineHeight: '1.6em',
|
||||
htmlBackgroundColor: 'white',
|
||||
paddingBottom: 3,
|
||||
colorBright: '#000000', // For important text
|
||||
htmlCodeBorderColor: 'rgb(220, 220, 220)',
|
||||
htmlCodeBackgroundColor: 'rgb(243, 243, 243)',
|
||||
htmlDividerColor: 'rgb(230,230,230)',
|
||||
htmlLinkColor: 'rgb(80,130,190)',
|
||||
htmlTableBackgroundColor: 'rgb(247, 247, 247)',
|
||||
raisedBackgroundColor: '#e5e5e5',
|
||||
htmlCodeColor: 'rgb(0,0,0)',
|
||||
htmlCodeFontSize: '.9em',
|
||||
|
||||
editorTheme: 'chrome',
|
||||
codeThemeCss: 'atom-one-light.css',
|
||||
};
|
50
ReactNativeClient/lib/joplin-renderer/htmlUtils.js
Normal file
50
ReactNativeClient/lib/joplin-renderer/htmlUtils.js
Normal file
@ -0,0 +1,50 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
// [\s\S] instead of . for multiline matching
|
||||
// https://stackoverflow.com/a/16119722/561309
|
||||
const imageRegex = /<img([\s\S]*?)src=["']([\s\S]*?)["']([\s\S]*?)>/gi;
|
||||
|
||||
class HtmlUtils {
|
||||
|
||||
attributesHtml(attr) {
|
||||
const output = [];
|
||||
|
||||
for (const n in attr) {
|
||||
if (!attr.hasOwnProperty(n)) continue;
|
||||
output.push(`${n}="${htmlentities(attr[n])}"`);
|
||||
}
|
||||
|
||||
return output.join(' ');
|
||||
}
|
||||
|
||||
processImageTags(html, callback) {
|
||||
if (!html) return '';
|
||||
|
||||
return html.replace(imageRegex, (v, before, src, after) => {
|
||||
const action = callback({ src: src });
|
||||
|
||||
if (!action) return `<img${before}src="${src}"${after}>`;
|
||||
|
||||
if (action.type === 'replaceElement') {
|
||||
return action.html;
|
||||
}
|
||||
|
||||
if (action.type === 'replaceSource') {
|
||||
return `<img${before}src="${action.src}"${after}>`;
|
||||
}
|
||||
|
||||
if (action.type === 'setAttributes') {
|
||||
const attrHtml = this.attributesHtml(action.attrs);
|
||||
return `<img${before}${attrHtml}${after}>`;
|
||||
}
|
||||
|
||||
throw new Error(`Invalid action: ${action.type}`);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const htmlUtils = new HtmlUtils();
|
||||
|
||||
module.exports = htmlUtils;
|
7
ReactNativeClient/lib/joplin-renderer/index.js
Normal file
7
ReactNativeClient/lib/joplin-renderer/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
MarkupToHtml: require('./MarkupToHtml'),
|
||||
MdToHtml: require('./MdToHtml'),
|
||||
HtmlToHtml: require('./HtmlToHtml'),
|
||||
setupLinkify: require('./MdToHtml/setupLinkify'),
|
||||
assetsToHeaders: require('./assetsToHeaders'),
|
||||
};
|
291
ReactNativeClient/lib/joplin-renderer/noteStyle.js
Normal file
291
ReactNativeClient/lib/joplin-renderer/noteStyle.js
Normal file
@ -0,0 +1,291 @@
|
||||
module.exports = function(style, options) {
|
||||
// https://necolas.github.io/normalize.css/
|
||||
const normalizeCss = `
|
||||
html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}
|
||||
article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}
|
||||
pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}
|
||||
b,strong{font-weight:bolder}small{font-size:80%}img{border-style:none}
|
||||
`;
|
||||
|
||||
const fontFamily = '\'Avenir\', \'Arial\', sans-serif';
|
||||
|
||||
const css =
|
||||
`
|
||||
body {
|
||||
font-size: ${style.htmlFontSize};
|
||||
color: ${style.htmlColor};
|
||||
line-height: ${style.htmlLineHeight};
|
||||
background-color: ${style.htmlBackgroundColor};
|
||||
font-family: ${fontFamily};
|
||||
padding-bottom: ${options.paddingBottom};
|
||||
}
|
||||
strong {
|
||||
color: ${style.colorBright};
|
||||
}
|
||||
kbd {
|
||||
border: 1px solid ${style.htmlCodeBorderColor};
|
||||
box-shadow: inset 0 -1px 0 ${style.htmlCodeBorderColor};
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
background-color: ${style.htmlCodeBackgroundColor};
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
::-webkit-scrollbar-corner {
|
||||
background: none;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
border: none;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(100, 100, 100, 0.3);
|
||||
border-radius: 5px;
|
||||
}
|
||||
::-webkit-scrollbar-track:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(100, 100, 100, 0.7);
|
||||
}
|
||||
|
||||
/* Remove top padding and margin from first child so that top of rendered text is aligned to top of text editor text */
|
||||
#rendered-md h1:first-child,
|
||||
#rendered-md h2:first-child,
|
||||
#rendered-md h3:first-child,
|
||||
#rendered-md h4:first-child,
|
||||
#rendered-md ul:first-child,
|
||||
#rendered-md ol:first-child,
|
||||
#rendered-md table:first-child,
|
||||
#rendered-md blockquote:first-child,
|
||||
#rendered-md img:first-child,
|
||||
#rendered-md p:first-child {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6, ul, table {
|
||||
margin-top: .6em;
|
||||
margin-bottom: .65em;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid ${style.htmlDividerColor};
|
||||
padding-bottom: .3em;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.3em;
|
||||
font-weight: bold;
|
||||
padding-bottom: .1em; */
|
||||
}
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
h4, h5, h6 {
|
||||
font-size: 1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
a {
|
||||
color: ${style.htmlLinkColor};
|
||||
}
|
||||
ul, ol {
|
||||
padding-left: 0;
|
||||
margin-left: 1.7em;
|
||||
}
|
||||
li {
|
||||
margin-bottom: .4em;
|
||||
}
|
||||
li p {
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.resource-icon {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
top: .5em;
|
||||
text-decoration: none;
|
||||
width: 1.2em;
|
||||
height: 1.4em;
|
||||
margin-right: 0.4em;
|
||||
background-color: ${style.htmlLinkColor};
|
||||
}
|
||||
/* These icons are obtained from the wonderful ForkAwesome project by copying the src svgs
|
||||
* into the css classes below.
|
||||
* svgs are obtained from https://github.com/ForkAwesome/Fork-Awesome/tree/master/src/icons/svg
|
||||
* instead of the svg width, height property you must use a viewbox here, 0 0 1536 1792 is typically the actual size of the icon
|
||||
* each line begins with the pre-amble -webkit-mask: url("data:image/svg+xml;utf8,
|
||||
* and of course finishes with ");
|
||||
* to precvent artifacts it is also necessary to include -webkit-mask-repeat: no-repeat;
|
||||
* on the following line
|
||||
* */
|
||||
.fa-joplin {
|
||||
/* Awesome Font file */
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M373.834 128C168.227 128 0 296.223 0 501.834v788.336C0 1495.778 168.227 1664 373.834 1664h788.336c205.608 0 373.83-168.222 373.83-373.83V501.834C1536 296.224 1367.778 128 1162.17 128zm397.222 205.431h417.424a7.132 7.132 0 0 1 7.132 7.133v132.552c0 4.461-3.619 8.073-8.077 8.073h-57.23c-24.168 0-43.768 19.338-44.284 43.374v2.377h-.017v136.191h-.053l-.466 509.375c-5.02 77.667-39.222 149.056-96.324 201.046-60.28 54.834-141.948 85.017-229.962 85.017-12.45 0-25.208-.61-37.907-1.785-92.157-8.682-181.494-48.601-251.662-112.438-71.99-65.517-117.147-150.03-127.164-238-11.226-98.763 23.42-192.783 95.045-257.937 81.99-74.637 198.185-101.768 316.613-75.704 5.574 1.227 9.55 6.282 9.55 11.997v199.52c-.199 2.625-1.481 6.599-8.183 2.896-.663-.365-1.194-.511-1.653-.531-21.987-10.587-45.159-17.57-68.559-19.916-.38-.04-.757-.124-1.138-.163-.537-.048-1.034-.033-1.556-.075-4.13-.354-8.183-.517-12.203-.58-.87-.011-1.771-.127-2.641-.127-.486 0-.951.05-1.437.057-1.464.011-2.886.115-4.33.163-2.76.102-5.497.211-8.182.448-.273.024-.547.07-.835.097-25.509 2.4-47.864 11.104-65.012 25.47-.954.802-1.974 1.53-2.9 2.36a1.34 1.34 0 0 1-.168.146c-23.96 21.8-34.881 53.872-30.726 90.316 4.62 40.737 26.94 81.156 62.841 113.823 35.908 32.67 80.335 52.977 125.113 57.186 35.118 3.36 66.547-3.919 89.899-20.461a97.255 97.255 0 0 0 9.365-7.501c2.925-2.661 5.569-5.5 8.086-8.416.3-.348.672-.673.975-1.024 8.253-9.864 14.222-21.067 17.996-33.148.639-2.034 1.051-4.148 1.564-6.227.381-1.563.81-3.106 1.112-4.693.555-2.784.923-5.632 1.253-8.49.086-.709.183-1.414.237-2.128.492-4.893.693-9.858.55-14.91h.013V521.623c-2.01-22.626-20.78-40.434-43.928-40.434h-57.23a8.071 8.071 0 0 1-8.077-8.073V340.564a7.132 7.132 0 0 1 7.136-7.133z'/></svg>");
|
||||
}
|
||||
.fa-file-image {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zm-128-448v320H256v-192l192-192 128 128 384-384zm-832-192c-106 0-192-86-192-192s86-192 192-192 192 86 192 192-86 192-192 192z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-pdf {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zm-514-593c25 20 53 38 84 56 42-5 81-7 117-7 67 0 152 8 177 49 7 10 13 28 2 52-1 1-2 3-3 4v1c-3 18-18 38-71 38-64 0-161-29-245-73-139 15-285 46-392 83-103 176-182 262-242 262-10 0-19-2-28-7l-24-12c-3-1-4-3-6-5-5-5-9-16-6-36 10-46 64-123 188-188 8-5 18-2 23 6 1 1 2 3 2 4 31-51 67-116 107-197 45-90 80-178 104-262-32-109-42-221-24-287 7-25 22-40 42-40h22c15 0 27 5 35 15 12 14 15 36 9 68-1 3-2 6-4 8 1 3 1 5 1 8v30c-1 63-2 123-14 192 35 105 87 190 146 238zm-576 411c30-14 73-57 137-158-75 58-122 124-137 158zm398-920c-10 28-10 76-2 132 3-16 5-31 7-44 2-17 5-31 7-43 1-3 2-5 4-8-1-1-1-3-2-5-1-18-7-29-13-36 0 2-1 3-1 4zm-124 661c88-35 186-63 284-81-10-8-20-15-29-23-49-43-93-103-127-176-19 61-47 126-83 197-15 28-30 56-45 83zm646-16c-5-5-31-24-140-24 49 18 94 28 124 28 9 0 14 0 18-1 0-1-1-2-2-3z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-word {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zM233 768v107h70l164 661h159l128-485c5-15 8-30 10-46 1-8 2-16 2-24h4l3 24c3 14 4 30 9 46l128 485h159l164-661h70V768h-300v107h90l-99 438c-4 16-6 33-7 46l-2 21h-4c0-6-2-14-3-21-3-13-5-30-9-46L825 768H711l-144 545c-4 16-5 33-8 46l-4 21h-4l-2-21c-1-13-3-30-7-46l-99-438h90V768H233z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-powerpoint {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zm-992-234v106h327v-106h-93v-167h137c43 0 82-2 118-15 90-31 146-124 146-233s-54-193-137-228c-38-15-84-19-130-19H416v107h92v555h-92zm353-280H650V882h120c35 0 62 6 83 18 36 21 56 62 56 115 0 56-20 99-62 120-21 10-47 15-78 15z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-excel {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zm-979-234v106h281v-106h-75l103-161c12-19 18-34 21-34h2c1 4 3 7 5 10 4 8 10 14 17 24l107 161h-76v106h291v-106h-68l-192-273 195-282h67V768H828v107h74l-103 159c-12 19-21 34-21 33h-2c-1-4-3-7-5-10-4-7-9-14-17-23L648 875h76V768H434v107h68l189 272-194 283h-68z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-audio {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zM620 850c12 5 20 17 20 30v544c0 13-8 25-20 30-4 1-8 2-12 2-8 0-16-3-23-9l-166-167H288c-18 0-32-14-32-32v-192c0-18 14-32 32-32h131l166-167c10-9 23-12 35-7zm417 689c19 0 37-8 50-24 83-102 129-231 129-363s-46-261-129-363c-22-28-63-32-90-10-28 23-32 63-9 91 65 80 100 178 100 282s-35 202-100 282c-23 28-19 68 9 90 12 10 26 15 40 15zm-211-148c17 0 34-7 47-20 56-60 87-137 87-219s-31-159-87-219c-24-26-65-27-91-3-25 24-27 65-2 91 33 36 52 82 52 131s-19 95-52 131c-25 26-23 67 2 91 13 11 29 17 44 17z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-video {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zM768 768c70 0 128 58 128 128v384c0 70-58 128-128 128H384c-70 0-128-58-128-128V896c0-70 58-128 128-128h384zm492 2c12 5 20 17 20 30v576c0 13-8 25-20 30-4 1-8 2-12 2-8 0-17-3-23-9l-265-266v-90l265-266c6-6 15-9 23-9 4 0 8 1 12 2z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-archive {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M640 384V256H512v128h128zm128 128V384H640v128h128zM640 640V512H512v128h128zm128 128V640H640v128h128zm700-388c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H768v128H640V128H128v1536h1280zM781 943c85 287 107 349 107 349 5 17 8 34 8 52 0 111-108 192-256 192s-256-81-256-192c0-18 3-35 8-52 0 0 21-62 120-396V768h128v128h79c29 0 54 19 62 47zm-141 465c71 0 128-29 128-64s-57-64-128-64-128 29-128 64 57 64 128 64z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-code {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zM480 768c11-14 31-17 45-6l51 38c14 11 17 31 6 45l-182 243 182 243c11 14 8 34-6 45l-51 38c-14 11-34 8-45-6l-226-301c-8-11-8-27 0-38zm802 301c8 11 8 27 0 38l-226 301c-11 14-31 17-45 6l-51-38c-14-11-17-31-6-45l182-243-182-243c-11-14-8-34 6-45l51-38c14-11 34-8 45 6zm-620 461c-18-3-29-20-26-37l138-831c3-18 20-29 37-26l63 10c18 3 29 20 26 37l-138 831c-3 18-20 29-37 26z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file-alt, .fa-file-csv {
|
||||
/* fork-awesome doesn't have csv so we use the text icon */
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280zM384 800c0-18 14-32 32-32h704c18 0 32 14 32 32v64c0 18-14 32-32 32H416c-18 0-32-14-32-32v-64zm736 224c18 0 32 14 32 32v64c0 18-14 32-32 32H416c-18 0-32-14-32-32v-64c0-18 14-32 32-32h704zm0 256c18 0 32 14 32 32v64c0 18-14 32-32 32H416c-18 0-32-14-32-32v-64c0-18 14-32 32-32h704z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
.fa-file {
|
||||
-webkit-mask: url("data:image/svg+xml;utf8,<svg viewBox='0 0 1536 1792' xmlns='http://www.w3.org/2000/svg'><path d='M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280z'/></svg>");
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
}
|
||||
blockquote {
|
||||
border-left: 4px solid ${style.htmlCodeBorderColor};
|
||||
padding-left: 1.2em;
|
||||
margin-left: 0;
|
||||
opacity: .7;
|
||||
}
|
||||
table {
|
||||
text-align: left-align;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid ${style.htmlCodeBorderColor};
|
||||
background-color: ${style.htmlBackgroundColor};
|
||||
}
|
||||
td, th {
|
||||
padding: .5em 1em .5em 1em;
|
||||
font-size: ${style.htmlFontSize};
|
||||
color: ${style.htmlColor};
|
||||
font-family: ${fontFamily};
|
||||
}
|
||||
td {
|
||||
border: 1px solid ${style.htmlCodeBorderColor};
|
||||
}
|
||||
th {
|
||||
border: 1px solid ${style.htmlCodeBorderColor};
|
||||
border-bottom: 2px solid ${style.htmlCodeBorderColor};
|
||||
background-color: ${style.htmlTableBackgroundColor};
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background-color: ${style.htmlTableBackgroundColor};
|
||||
}
|
||||
tr:hover {
|
||||
background-color: ${style.raisedBackgroundColor};
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 2px solid ${style.htmlDividerColor};
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.inline-code {
|
||||
border: 1px solid ${style.htmlCodeBorderColor};
|
||||
background-color: ${style.htmlCodeBackgroundColor};
|
||||
padding-right: .2em;
|
||||
padding-left: .2em;
|
||||
border-radius: .25em;
|
||||
color: ${style.htmlCodeColor};
|
||||
font-size: ${style.htmlCodeFontSize};
|
||||
}
|
||||
|
||||
.highlighted-keyword {
|
||||
background-color: #F3B717;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.not-loaded-resource img {
|
||||
width: 1.15em;
|
||||
height: 1.15em;
|
||||
background: white;
|
||||
padding: 2px !important;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 3px #000000aa;
|
||||
}
|
||||
|
||||
a.not-loaded-resource img {
|
||||
margin-right: .2em;
|
||||
}
|
||||
|
||||
a.not-loaded-resource {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.md-checkbox input[type=checkbox]:checked {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.md-checkbox .checkbox-label-checked {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.exported-note-title {
|
||||
font-size: 2.2em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.exported-note {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.code, .inline-code {
|
||||
border: 1px solid #CBCBCB;
|
||||
}
|
||||
|
||||
#joplin-container-content {
|
||||
/* The height of the content is set dynamically by JavaScript (in updateBodyHeight) to go
|
||||
around various issues related to scrolling. However when printing we don't want this
|
||||
fixed size as that would crop the content. So we set it to auto here. "important" is
|
||||
needed to override the style set by JavaScript at the element-level. */
|
||||
height: auto !important;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
return [normalizeCss, css];
|
||||
};
|
394
ReactNativeClient/lib/joplin-renderer/package-lock.json
generated
Normal file
394
ReactNativeClient/lib/joplin-renderer/package-lock.json
generated
Normal file
@ -0,0 +1,394 @@
|
||||
{
|
||||
"name": "joplin-renderer",
|
||||
"version": "1.0.8",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"base-64": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
|
||||
"integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"charenc": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
|
||||
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"crypt": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
|
||||
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
|
||||
},
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
},
|
||||
"font-awesome-filetypes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/font-awesome-filetypes/-/font-awesome-filetypes-2.1.0.tgz",
|
||||
"integrity": "sha512-U6hi14GRjfZFIWsTNyVmCBuHyPhiizWEKVbaQqHipKQv3rA1l1PNvmKulzpqxonFnQMToty5ZhfWbc/0IjLDGA=="
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
},
|
||||
"handlebars": {
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
|
||||
"integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
|
||||
"requires": {
|
||||
"neo-async": "^2.6.0",
|
||||
"optimist": "^0.6.1",
|
||||
"source-map": "^0.6.1",
|
||||
"uglify-js": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.17.1",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.17.1.tgz",
|
||||
"integrity": "sha512-TA2/doAur5Ol8+iM3Ov7qy3jYcr/QiJ2eDTdRF4dfbjG7AaaB99J5G+zSl11ljbl6cIcahgPY6SKb3sC3EJ0fw==",
|
||||
"requires": {
|
||||
"handlebars": "^4.5.3"
|
||||
}
|
||||
},
|
||||
"html-entities": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
|
||||
"integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8="
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-buffer": {
|
||||
"version": "1.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
|
||||
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
|
||||
},
|
||||
"jasmine": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.5.0.tgz",
|
||||
"integrity": "sha512-DYypSryORqzsGoMazemIHUfMkXM7I7easFaxAvNM3Mr6Xz3Fy36TupTrAOxZWN8MVKEU5xECv22J4tUQf3uBzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.4",
|
||||
"jasmine-core": "~3.5.0"
|
||||
}
|
||||
},
|
||||
"jasmine-core": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.5.0.tgz",
|
||||
"integrity": "sha512-nCeAiw37MIMA9w9IXso7bRaLl+c/ef3wnxsoSAlYrzS+Ot0zTG6nU8G/cIfGkqpkjX2wNaIW9RFG0TwIFnG6bA==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
|
||||
"integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==",
|
||||
"requires": {
|
||||
"commander": "^2.19.0"
|
||||
}
|
||||
},
|
||||
"linkify-it": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
|
||||
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
|
||||
"requires": {
|
||||
"uc.micro": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
|
||||
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~2.0.0",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"markdown-it-abbr": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
|
||||
"integrity": "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g="
|
||||
},
|
||||
"markdown-it-anchor": {
|
||||
"version": "5.2.5",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz",
|
||||
"integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ=="
|
||||
},
|
||||
"markdown-it-deflist": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz",
|
||||
"integrity": "sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw=="
|
||||
},
|
||||
"markdown-it-emoji": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
|
||||
"integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw="
|
||||
},
|
||||
"markdown-it-footnote": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.2.tgz",
|
||||
"integrity": "sha512-JVW6fCmZWjvMdDQSbOT3nnOQtd9iAXmw7hTSh26+v42BnvXeVyGMDBm5b/EZocMed2MbCAHiTX632vY0FyGB8A=="
|
||||
},
|
||||
"markdown-it-ins": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.0.tgz",
|
||||
"integrity": "sha512-+vyAdBuMGwmT2yMlAFJSx2VR/0QZ1onQ/Mkkmr4l9tDFOh5sVoAgRbkgbuSsk+sxJ9vaMH/IQ323ydfvQrPO/Q=="
|
||||
},
|
||||
"markdown-it-mark": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.0.tgz",
|
||||
"integrity": "sha512-HqMWeKfMMOu4zBO0emmxsoMWmbf2cPKZY1wP6FsTbKmicFfp5y4L3KXAsNeO1rM6NTJVOrNlLKMPjWzriBGspw=="
|
||||
},
|
||||
"markdown-it-multimd-table": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-multimd-table/-/markdown-it-multimd-table-4.0.1.tgz",
|
||||
"integrity": "sha512-ZgRV8LlGz6JXTZ5zd82yCL8IVG5MRastMWxxrc6hQC8aC8kq/7zpp+ksBqVqcdTmTdabnkuSo/7h3SyKM31YCA==",
|
||||
"requires": {
|
||||
"markdown-it": "^8.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "8.4.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
|
||||
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~1.1.1",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown-it-sub": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
|
||||
"integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g="
|
||||
},
|
||||
"markdown-it-sup": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
|
||||
"integrity": "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M="
|
||||
},
|
||||
"markdown-it-toc-done-right": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.1.0.tgz",
|
||||
"integrity": "sha512-UhD2Oj6cZV3ycYPoelt4hTkwKIK3zbPP1wjjdpCq7UGtWQOFalDFDv1s2zBYV6aR2gMs/X8kpJcOYsQmUbiXDw=="
|
||||
},
|
||||
"md5": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
|
||||
"integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=",
|
||||
"requires": {
|
||||
"charenc": "~0.0.1",
|
||||
"crypt": "~0.0.1",
|
||||
"is-buffer": "~1.1.1"
|
||||
}
|
||||
},
|
||||
"mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
|
||||
"integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
|
||||
},
|
||||
"neo-async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
|
||||
"integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw=="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"optimist": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
|
||||
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
|
||||
"requires": {
|
||||
"minimist": "~0.0.1",
|
||||
"wordwrap": "~0.0.2"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"uc.micro": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.2.tgz",
|
||||
"integrity": "sha512-uhRwZcANNWVLrxLfNFEdltoPNhECUR3lc+UdJoG9CBpMcSnKyWA94tc3eAujB1GcMY5Uwq8ZMp4qWpxWYDQmaA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"commander": "~2.20.3",
|
||||
"source-map": "~0.6.1"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
39
ReactNativeClient/lib/joplin-renderer/package.json
Normal file
39
ReactNativeClient/lib/joplin-renderer/package.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "joplin-renderer",
|
||||
"version": "1.0.8",
|
||||
"description": "The Joplin note renderer, used the mobile and desktop application",
|
||||
"repository": "https://github.com/laurent22/joplin/tree/master/ReactNativeClient/lib/joplin-renderer",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "jasmine --config=tests/support/jasmine.json",
|
||||
"buildAssets": "node Tools/buildAssets.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"jasmine": "^3.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"base-64": "^0.1.0",
|
||||
"font-awesome-filetypes": "^2.1.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"katex": "^0.11.1",
|
||||
"markdown-it": "^10.0.0",
|
||||
"markdown-it-abbr": "^1.0.4",
|
||||
"markdown-it-anchor": "^5.2.5",
|
||||
"markdown-it-deflist": "^2.0.3",
|
||||
"markdown-it-emoji": "^1.4.0",
|
||||
"markdown-it-footnote": "^3.0.2",
|
||||
"markdown-it-ins": "^3.0.0",
|
||||
"markdown-it-mark": "^3.0.0",
|
||||
"markdown-it-multimd-table": "^4.0.1",
|
||||
"markdown-it-sub": "^1.0.0",
|
||||
"markdown-it-sup": "^1.0.0",
|
||||
"markdown-it-toc-done-right": "^4.1.0",
|
||||
"md5": "^2.2.1",
|
||||
"uslug": "^1.0.4"
|
||||
}
|
||||
}
|
32
ReactNativeClient/lib/joplin-renderer/pathUtils.js
Normal file
32
ReactNativeClient/lib/joplin-renderer/pathUtils.js
Normal file
@ -0,0 +1,32 @@
|
||||
function dirname(path) {
|
||||
if (!path) throw new Error('Path is empty');
|
||||
let s = path.split(/\/|\\/);
|
||||
s.pop();
|
||||
return s.join('/');
|
||||
}
|
||||
|
||||
function basename(path) {
|
||||
if (!path) throw new Error('Path is empty');
|
||||
let s = path.split(/\/|\\/);
|
||||
return s[s.length - 1];
|
||||
}
|
||||
|
||||
function filename(path, includeDir = false) {
|
||||
if (!path) throw new Error('Path is empty');
|
||||
let output = includeDir ? path : basename(path);
|
||||
if (output.indexOf('.') < 0) return output;
|
||||
|
||||
output = output.split('.');
|
||||
output.pop();
|
||||
return output.join('.');
|
||||
}
|
||||
|
||||
function fileExtension(path) {
|
||||
if (!path) throw new Error('Path is empty');
|
||||
|
||||
let output = path.split('.');
|
||||
if (output.length <= 1) return '';
|
||||
return output[output.length - 1];
|
||||
}
|
||||
|
||||
module.exports = { basename, dirname, filename, fileExtension };
|
14
ReactNativeClient/lib/joplin-renderer/publish.sh
Normal file
14
ReactNativeClient/lib/joplin-renderer/publish.sh
Normal file
@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
cd "$SCRIPT_DIR"
|
||||
npm run buildAssets
|
||||
npm version patch
|
||||
npm publish
|
||||
|
||||
NEW_VERSION=$(cat package.json | jq -r .version)
|
||||
git add -A
|
||||
git commit -m "v$NEW_VERSION"
|
||||
git tag "v$NEW_VERSION"
|
||||
git push && git push --tags
|
74
ReactNativeClient/lib/joplin-renderer/stringUtils.js
Normal file
74
ReactNativeClient/lib/joplin-renderer/stringUtils.js
Normal file
@ -0,0 +1,74 @@
|
||||
function pregQuote(str, delimiter = '') {
|
||||
return (`${str}`).replace(new RegExp(`[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\${delimiter || ''}-]`, 'g'), '\\$&');
|
||||
}
|
||||
|
||||
function replaceRegexDiacritics(regexString) {
|
||||
if (!regexString) return '';
|
||||
|
||||
const diacriticReplacements = {
|
||||
a: '[aàáâãäåāą]',
|
||||
A: '[AÀÁÂÃÄÅĀĄ]',
|
||||
c: '[cçćč]',
|
||||
C: '[CÇĆČ]',
|
||||
d: '[dđď]',
|
||||
D: '[DĐĎ]',
|
||||
e: '[eèéêëěēę]',
|
||||
E: '[EÈÉÊËĚĒĘ]',
|
||||
i: '[iìíîïī]',
|
||||
I: '[IÌÍÎÏĪ]',
|
||||
l: '[lł]',
|
||||
L: '[LŁ]',
|
||||
n: '[nñňń]',
|
||||
N: '[NÑŇŃ]',
|
||||
o: '[oòóôõöøō]',
|
||||
O: '[OÒÓÔÕÖØŌ]',
|
||||
r: '[rř]',
|
||||
R: '[RŘ]',
|
||||
s: '[sšś]',
|
||||
S: '[SŠŚ]',
|
||||
t: '[tť]',
|
||||
T: '[TŤ]',
|
||||
u: '[uùúûüůū]',
|
||||
U: '[UÙÚÛÜŮŪ]',
|
||||
y: '[yÿý]',
|
||||
Y: '[YŸÝ]',
|
||||
z: '[zžżź]',
|
||||
Z: '[ZŽŻŹ]',
|
||||
};
|
||||
|
||||
let output = '';
|
||||
for (let i = 0; i < regexString.length; i++) {
|
||||
let c = regexString[i];
|
||||
const r = diacriticReplacements[c];
|
||||
if (r) {
|
||||
output += r;
|
||||
} else {
|
||||
output += c;
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// keywords can either be a list of strings, or a list of objects with the format:
|
||||
// { value: 'actualkeyword', type: 'regex/string' }
|
||||
// The function surrounds the keywords wherever they are, even within other words.
|
||||
function surroundKeywords(keywords, text, prefix, suffix) {
|
||||
if (!keywords.length) return text;
|
||||
|
||||
let regexString = keywords
|
||||
.map(k => {
|
||||
if (k.type === 'regex') {
|
||||
return replaceRegexDiacritics(k.valueRegex);
|
||||
} else {
|
||||
const value = typeof k === 'string' ? k : k.value;
|
||||
return replaceRegexDiacritics(pregQuote(value));
|
||||
}
|
||||
})
|
||||
.join('|');
|
||||
regexString = `(${regexString})`;
|
||||
const re = new RegExp(regexString, 'gi');
|
||||
return text.replace(re, `${prefix}$1${suffix}`);
|
||||
}
|
||||
|
||||
module.exports = { surroundKeywords };
|
24
ReactNativeClient/lib/joplin-renderer/tests/MdToHtmlTest.js
Normal file
24
ReactNativeClient/lib/joplin-renderer/tests/MdToHtmlTest.js
Normal file
@ -0,0 +1,24 @@
|
||||
const { asyncTest } = require('./test-utils');
|
||||
const MdToHtml = require('../MdToHtml');
|
||||
|
||||
describe('MdToHtml', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
done();
|
||||
});
|
||||
|
||||
it('should convert Markdown to HTML', asyncTest(async () => {
|
||||
const mdToHtml = new MdToHtml({
|
||||
ResourceModel: null,
|
||||
});
|
||||
|
||||
const md = 'Testing: **Testing**';
|
||||
|
||||
const html = mdToHtml.render(md);
|
||||
|
||||
console.info(html);
|
||||
|
||||
// ![test.jpg](:/b08c25f72bea437ebef5f6470944c3b9)
|
||||
}));
|
||||
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"spec_dir": "tests",
|
||||
"spec_files": [
|
||||
"*.js",
|
||||
"!test-utils.js"
|
||||
],
|
||||
"stopSpecOnExpectationFailure": true,
|
||||
"random": true
|
||||
}
|
16
ReactNativeClient/lib/joplin-renderer/tests/test-utils.js
Normal file
16
ReactNativeClient/lib/joplin-renderer/tests/test-utils.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Wrap an async test in a try/catch block so that done() is always called
|
||||
// and display a proper error message instead of "unhandled promise error"
|
||||
function asyncTest(callback) {
|
||||
return async function(done) {
|
||||
try {
|
||||
await callback();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
expect('good').toBe('not good', 'Test has thrown an exception - see above error');
|
||||
} finally {
|
||||
done();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = { asyncTest };
|
32
ReactNativeClient/lib/joplin-renderer/urlUtils.js
Normal file
32
ReactNativeClient/lib/joplin-renderer/urlUtils.js
Normal file
@ -0,0 +1,32 @@
|
||||
const urlUtils = {};
|
||||
|
||||
const resourceRegex = /^(joplin:\/\/|:\/)([0-9a-zA-Z]{32})(|#[^\s]*)(|\s".*?")$/;
|
||||
|
||||
urlUtils.urlDecode = function(string) {
|
||||
return decodeURIComponent((`${string}`).replace(/\+/g, '%20'));
|
||||
};
|
||||
|
||||
urlUtils.isResourceUrl = function(url) {
|
||||
return !!url.match(resourceRegex);
|
||||
};
|
||||
|
||||
urlUtils.parseResourceUrl = function(url) {
|
||||
if (!urlUtils.isResourceUrl(url)) return null;
|
||||
|
||||
const match = url.match(resourceRegex);
|
||||
|
||||
const itemId = match[2];
|
||||
let hash = match[3].trim();
|
||||
|
||||
// In general we want the hash to be decoded so that non-alphabetical languages
|
||||
// appear as-is without being encoded with %.
|
||||
// Fixes https://github.com/laurent22/joplin/issues/1870
|
||||
if (hash) hash = urlUtils.urlDecode(hash.substr(1)); // Remove the first #
|
||||
|
||||
return {
|
||||
itemId: itemId,
|
||||
hash: hash,
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = urlUtils;
|
133
ReactNativeClient/lib/joplin-renderer/utils.js
Normal file
133
ReactNativeClient/lib/joplin-renderer/utils.js
Normal file
@ -0,0 +1,133 @@
|
||||
const Entities = require('html-entities').AllHtmlEntities;
|
||||
const htmlentities = new Entities().encode;
|
||||
|
||||
// Imported from models/Resource.js
|
||||
const FetchStatuses = {
|
||||
FETCH_STATUS_IDLE: 0,
|
||||
FETCH_STATUS_STARTED: 1,
|
||||
FETCH_STATUS_DONE: 2,
|
||||
FETCH_STATUS_ERROR: 3,
|
||||
};
|
||||
|
||||
const utils = {};
|
||||
|
||||
utils.getAttr = function(attrs, name, defaultValue = null) {
|
||||
for (let i = 0; i < attrs.length; i++) {
|
||||
if (attrs[i][0] === name) return attrs[i].length > 1 ? attrs[i][1] : null;
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
|
||||
utils.notDownloadedResource = function() {
|
||||
return `
|
||||
<svg width="1700" height="1536" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1280 1344c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm256 0c0-35-29-64-64-64s-64 29-64 64 29 64 64 64 64-29 64-64zm128-224v320c0 53-43 96-96 96H96c-53 0-96-43-96-96v-320c0-53 43-96 96-96h465l135 136c37 36 85 56 136 56s99-20 136-56l136-136h464c53 0 96 43 96 96zm-325-569c10 24 5 52-14 70l-448 448c-12 13-29 19-45 19s-33-6-45-19L339 621c-19-18-24-46-14-70 10-23 33-39 59-39h256V64c0-35 29-64 64-64h256c35 0 64 29 64 64v448h256c26 0 49 16 59 39z"/>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
utils.notDownloadedImage = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/file-image-o.svg
|
||||
// Height changed to 1795
|
||||
return `
|
||||
<svg width="1925" height="1792" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M640 576c0 106-86 192-192 192s-192-86-192-192 86-192 192-192 192 86 192 192zm1024 384v448H256v-192l320-320 160 160 512-512zm96-704H160c-17 0-32 15-32 32v1216c0 17 15 32 32 32h1600c17 0 32-15 32-32V288c0-17-15-32-32-32zm160 32v1216c0 88-72 160-160 160H160c-88 0-160-72-160-160V288c0-88 72-160 160-160h1600c88 0 160 72 160 160z"/>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
utils.notDownloadedFile = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/file-o.svg
|
||||
return `
|
||||
<svg width="1925" height="1792" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1468 380c37 37 68 111 68 164v1152c0 53-43 96-96 96H96c-53 0-96-43-96-96V96C0 43 43 0 96 0h896c53 0 127 31 164 68zm-444-244v376h376c-6-17-15-34-22-41l-313-313c-7-7-24-16-41-22zm384 1528V640H992c-53 0-96-43-96-96V128H128v1536h1280z"/>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
utils.errorImage = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/times-circle.svg
|
||||
return `
|
||||
<svg width="1795" height="1795" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1149 1122c0-17-7-33-19-45L949 896l181-181c12-12 19-28 19-45s-7-34-19-46l-90-90c-12-12-29-19-46-19s-33 7-45 19L768 715 587 534c-12-12-28-19-45-19s-34 7-46 19l-90 90c-12 12-19 29-19 46s7 33 19 45l181 181-181 181c-12 12-19 28-19 45s7 34 19 46l90 90c12 12 29 19 46 19s33-7 45-19l181-181 181 181c12 12 28 19 45 19s34-7 46-19l90-90c12-12 19-29 19-46zm387-226c0 424-344 768-768 768S0 1320 0 896s344-768 768-768 768 344 768 768z"/>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
utils.loaderImage = function() {
|
||||
// https://github.com/ForkAwesome/Fork-Awesome/blob/master/src/icons/svg/hourglass-half.svg
|
||||
return `
|
||||
<svg width="1536" height="1790" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1408 128c0 370-177 638-373 768 196 130 373 398 373 768h96c18 0 32 14 32 32v64c0 18-14 32-32 32H32c-18 0-32-14-32-32v-64c0-18 14-32 32-32h96c0-370 177-638 373-768-196-130-373-398-373-768H32c-18 0-32-14-32-32V32C0 14 14 0 32 0h1472c18 0 32 14 32 32v64c0 18-14 32-32 32h-96zm-128 0H256c0 146 33 275 85 384h854c52-109 85-238 85-384zm-57 1216c-74-193-207-330-340-384H653c-133 54-266 191-340 384h910z"/>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
utils.resourceStatusImage = function(state) {
|
||||
if (state === 'notDownloaded') return utils.notDownloadedResource();
|
||||
return utils.resourceStatusFile(state);
|
||||
};
|
||||
|
||||
utils.resourceStatusFile = function(state) {
|
||||
if (state === 'notDownloaded') return utils.notDownloadedResource();
|
||||
if (state === 'downloading') return utils.loaderImage();
|
||||
if (state === 'encrypted') return utils.loaderImage();
|
||||
if (state === 'error') return utils.errorImage();
|
||||
|
||||
throw new Error(`Unknown state: ${state}`);
|
||||
};
|
||||
|
||||
utils.resourceStatus = function(ResourceModel, resourceInfo) {
|
||||
if (!ResourceModel) return 'ready';
|
||||
|
||||
let resourceStatus = 'ready';
|
||||
|
||||
if (resourceInfo) {
|
||||
const resource = resourceInfo.item;
|
||||
const localState = resourceInfo.localState;
|
||||
|
||||
if (localState.fetch_status === FetchStatuses.FETCH_STATUS_IDLE) {
|
||||
resourceStatus = 'notDownloaded';
|
||||
} else if (localState.fetch_status === FetchStatuses.FETCH_STATUS_STARTED) {
|
||||
resourceStatus = 'downloading';
|
||||
} else if (localState.fetch_status === FetchStatuses.FETCH_STATUS_DONE) {
|
||||
if (resource.encryption_blob_encrypted || resource.encryption_applied) {
|
||||
resourceStatus = 'encrypted';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resourceStatus = 'notDownloaded';
|
||||
}
|
||||
|
||||
return resourceStatus;
|
||||
};
|
||||
|
||||
utils.imageReplacement = function(ResourceModel, src, resources, resourceBaseUrl) {
|
||||
if (!ResourceModel) return null;
|
||||
|
||||
if (!ResourceModel.isResourceUrl(src)) return null;
|
||||
|
||||
const resourceId = ResourceModel.urlToId(src);
|
||||
const result = resources[resourceId];
|
||||
const resource = result ? result.item : null;
|
||||
const resourceStatus = utils.resourceStatus(ResourceModel, result);
|
||||
|
||||
if (resourceStatus !== 'ready') {
|
||||
const icon = utils.resourceStatusImage(resourceStatus);
|
||||
return `<div class="not-loaded-resource resource-status-${resourceStatus}" data-resource-id="${resourceId}">` + `<img src="data:image/svg+xml;utf8,${htmlentities(icon)}"/>` + '</div>';
|
||||
}
|
||||
|
||||
const mime = resource.mime ? resource.mime.toLowerCase() : '';
|
||||
if (ResourceModel.isSupportedImageMimeType(mime)) {
|
||||
let newSrc = `./${ResourceModel.filename(resource)}`;
|
||||
if (resourceBaseUrl) newSrc = resourceBaseUrl + newSrc;
|
||||
return {
|
||||
'data-resource-id': resource.id,
|
||||
src: newSrc,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
module.exports = utils;
|
14
ReactNativeClient/lib/joplin-renderer/vendor/fountain.min.js
vendored
Normal file
14
ReactNativeClient/lib/joplin-renderer/vendor/fountain.min.js
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// https://github.com/mattdaly/Fountain.js/
|
||||
|
||||
(function(){var d={title_page:/^((?:title|credit|author[s]?|source|notes|draft date|date|contact|copyright)\:)/gim,scene_heading:/^((?:\*{0,3}_?)?(?:(?:int|ext|est|i\/e)[. ]).+)|^(?:\.(?!\.+))(.+)/i,scene_number:/( *#(.+)# *)/,transition:/^((?:FADE (?:TO BLACK|OUT)|CUT TO BLACK)\.|.+ TO\:)|^(?:> *)(.+)/,dialogue:/^([A-Z*_]+[0-9A-Z (._\-')]*)(\^?)?(?:\n(?!\n+))([\s\S]+)/,parenthetical:/^(\(.+\))$/,action:/^(.+)/g,centered:/^(?:> *)(.+)(?: *<)(\n.+)*/g,section:/^(#+)(?: *)(.*)/,synopsis:/^(?:\=(?!\=+) *)(.*)/,
|
||||
note:/^(?:\[{2}(?!\[+))(.+)(?:\]{2}(?!\[+))$/,note_inline:/(?:\[{2}(?!\[+))([\s\S]+?)(?:\]{2}(?!\[+))/g,boneyard:/(^\/\*|^\*\/)$/g,page_break:/^\={3,}$/,line_break:/^ {2}$/,emphasis:/(_|\*{1,3}|_\*{1,3}|\*{1,3}_)(.+)(_|\*{1,3}|_\*{1,3}|\*{1,3}_)/g,bold_italic_underline:/(_{1}\*{3}(?=.+\*{3}_{1})|\*{3}_{1}(?=.+_{1}\*{3}))(.+?)(\*{3}_{1}|_{1}\*{3})/g,bold_underline:/(_{1}\*{2}(?=.+\*{2}_{1})|\*{2}_{1}(?=.+_{1}\*{2}))(.+?)(\*{2}_{1}|_{1}\*{2})/g,italic_underline:/(?:_{1}\*{1}(?=.+\*{1}_{1})|\*{1}_{1}(?=.+_{1}\*{1}))(.+?)(\*{1}_{1}|_{1}\*{1})/g,
|
||||
bold_italic:/(\*{3}(?=.+\*{3}))(.+?)(\*{3})/g,bold:/(\*{2}(?=.+\*{2}))(.+?)(\*{2})/g,italic:/(\*{1}(?=.+\*{1}))(.+?)(\*{1})/g,underline:/(_{1}(?=.+_{1}))(.+?)(_{1})/g,splitter:/\n{2,}/g,cleaner:/^\n+|\n+$/,standardizer:/\r\n|\r/g,whitespacer:/^\t+|^ {3,}/gm},n={note:"<\!-- $1 --\>",line_break:"<br />",bold_italic_underline:'<span class="bold italic underline">$2</span>',bold_underline:'<span class="bold underline">$2</span>',italic_underline:'<span class="italic underline">$2</span>',bold_italic:'<span class="bold italic">$2</span>',
|
||||
bold:'<span class="bold">$2</span>',italic:'<span class="italic">$2</span>',underline:'<span class="underline">$2</span>',lexer:function(c){if(c){for(var j="underline,italic,bold,bold_italic,italic_underline,bold_underline,bold_italic_underline".split(","),k=j.length,g,b,c=c.replace(d.note_inline,n.note).replace(/\\\*/g,"[star]").replace(/\\_/g,"[underline]").replace(/\n/g,n.line_break);k--;)g=j[k],b=d[g],b.test(c)&&(c=c.replace(b,n[g]));return c.replace(/\[star\]/g,"*").replace(/\[underline\]/g,
|
||||
"_").trim()}}},h=function(c,d){return h.parse(c,d)};h.parse=function(c,j,k){var g;void 0===k&&"function"===typeof j&&(k=j,j=void 0);for(var b=c.replace(d.boneyard,"\n$1\n").replace(d.standardizer,"\n").replace(d.cleaner,"").replace(d.whitespacer,"").split(d.splitter),f=b.length,e,a,l,i,h,m,c=[];f--;)if(e=b[f],d.title_page.test(e)){a=e.replace(d.title_page,"\n$1").split(d.splitter).reverse();i=0;for(h=a.length;i<h;i++)l=a[i].replace(d.cleaner,"").split(/\:\n*/),c.push({type:l[0].trim().toLowerCase().replace(" ",
|
||||
"_"),text:l[1].trim()})}else if(a=e.match(d.scene_heading)){if(e=a[1]||a[2],e.indexOf(" ")!==e.length-2){if(a=e.match(d.scene_number))a=a[2],e=e.replace(d.scene_number,"");c.push({type:"scene_heading",text:e,scene_number:a||void 0})}}else if(a=e.match(d.centered))c.push({type:"centered",text:a[0].replace(/>|</g,"")});else if(a=e.match(d.transition))c.push({type:"transition",text:a[1]||a[2]});else if((a=e.match(d.dialogue))&&a[1].indexOf(" ")!==a[1].length-2){a[2]&&c.push({type:"dual_dialogue_end"});
|
||||
c.push({type:"dialogue_end"});l=a[3].split(/(\(.+\))(?:\n+)/).reverse();i=0;for(h=l.length;i<h;i++)e=l[i],0<e.length&&c.push({type:d.parenthetical.test(e)?"parenthetical":"dialogue",text:e});c.push({type:"character",text:a[1].trim()});c.push({type:"dialogue_begin",dual:a[2]?"right":m?"left":void 0});m&&c.push({type:"dual_dialogue_begin"});m=a[2]?!0:!1}else(a=e.match(d.section))?c.push({type:"section",text:a[2],depth:a[1].length}):(a=e.match(d.synopsis))?c.push({type:"synopsis",text:a[1]}):(a=e.match(d.note))?
|
||||
c.push({type:"note",text:a[1]}):(a=e.match(d.boneyard))?c.push({type:"/"===a[0][0]?"boneyard_begin":"boneyard_end"}):d.page_break.test(e)?c.push({type:"page_break"}):d.line_break.test(e)?c.push({type:"line_break"}):c.push({type:"action",text:e});m=c.length;f=[];for(a=[];m--;)switch(b=c[m],b.text=n.lexer(b.text),b.type){case "title":f.push("<h1>"+b.text+"</h1>");g=b.text.replace("<br />"," ").replace(/<(?:.|\n)*?>/g,"");break;case "credit":f.push('<p class="credit">'+b.text+"</p>");break;case "author":f.push('<p class="authors">'+
|
||||
b.text+"</p>");break;case "authors":f.push('<p class="authors">'+b.text+"</p>");break;case "source":f.push('<p class="source">'+b.text+"</p>");break;case "notes":f.push('<p class="notes">'+b.text+"</p>");break;case "draft_date":f.push('<p class="draft-date">'+b.text+"</p>");break;case "date":f.push('<p class="date">'+b.text+"</p>");break;case "contact":f.push('<p class="contact">'+b.text+"</p>");break;case "copyright":f.push('<p class="copyright">'+b.text+"</p>");break;case "scene_heading":a.push("<h3"+
|
||||
(b.scene_number?' id="'+b.scene_number+'">':">")+b.text+"</h3>");break;case "transition":a.push("<h2>"+b.text+"</h2>");break;case "dual_dialogue_begin":a.push('<div class="dual-dialogue">');break;case "dialogue_begin":a.push('<div class="dialogue'+(b.dual?" "+b.dual:"")+'">');break;case "character":a.push("<h4>"+b.text+"</h4>");break;case "parenthetical":a.push('<p class="parenthetical">'+b.text+"</p>");break;case "dialogue":a.push("<p>"+b.text+"</p>");break;case "dialogue_end":a.push("</div> ");
|
||||
break;case "dual_dialogue_end":a.push("</div> ");break;case "section":a.push('<p class="section" data-depth="'+b.depth+'">'+b.text+"</p>");break;case "synopsis":a.push('<p class="synopsis">'+b.text+"</p>");break;case "note":a.push("<\!-- "+b.text+"--\>");break;case "boneyard_begin":a.push("<\!-- ");break;case "boneyard_end":a.push(" --\>");break;case "action":a.push("<p>"+b.text+"</p>");break;case "centered":a.push('<p class="centered">'+b.text+"</p>");break;case "page_break":a.push("<hr />");break;
|
||||
case "line_break":a.push("<br />")}g={title:g,html:{title_page:f.join(""),script:a.join("")},tokens:j?c.reverse():void 0};g="function"===typeof k?k(g):g;return g};"undefined"!==typeof module?module.exports=h:this.fountain=h}).call(this);
|
110
ReactNativeClient/lib/joplin-renderer/webviewLib.js
Normal file
110
ReactNativeClient/lib/joplin-renderer/webviewLib.js
Normal file
@ -0,0 +1,110 @@
|
||||
const webviewLib = {};
|
||||
|
||||
let manualDownloadResourceElements = [];
|
||||
|
||||
webviewLib.onUnloadedResourceClick = function(event) {
|
||||
const resourceId = event.currentTarget.getAttribute('data-resource-id');
|
||||
webviewLib.options_.postMessage(`markForDownload:${resourceId}`);
|
||||
};
|
||||
|
||||
webviewLib.setupResourceManualDownload = function() {
|
||||
for (const element of manualDownloadResourceElements) {
|
||||
element.style.cursor = 'default';
|
||||
element.removeEventListener('click', webviewLib.onUnloadedResourceClick);
|
||||
}
|
||||
|
||||
manualDownloadResourceElements = [];
|
||||
|
||||
const elements = document.getElementsByClassName('resource-status-notDownloaded');
|
||||
|
||||
for (const element of elements) {
|
||||
element.style.cursor = 'pointer';
|
||||
element.addEventListener('click', webviewLib.onUnloadedResourceClick);
|
||||
manualDownloadResourceElements.push(element);
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.handleInternalLink = function(event, anchorNode) {
|
||||
const href = anchorNode.getAttribute('href');
|
||||
if (!href) return false;
|
||||
|
||||
if (href.indexOf('#') === 0) {
|
||||
event.preventDefault();
|
||||
let old_hash = location.hash;
|
||||
|
||||
location.hash = href;
|
||||
|
||||
// HACK
|
||||
// For some reason anchors at the bottom cause the webview to move itself
|
||||
// so that the content is aligned with the top of the screen
|
||||
// This basically refreshes the scroll view so that is returns to a normal
|
||||
// position, the scroll positions stays correct though
|
||||
// Additionally an anchor could not be clicked twice because the location
|
||||
// would not change, this fixes that also
|
||||
setTimeout(function() {
|
||||
location.hash = old_hash;
|
||||
}, 10);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
webviewLib.getParentAnchorElement = function(element) {
|
||||
let counter = 0;
|
||||
while (true) {
|
||||
if (counter++ >= 10000) {
|
||||
console.warn('been looping for too long - exiting');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!element) return null;
|
||||
if (element.nodeName === 'A') return element;
|
||||
element = element.parentElement;
|
||||
}
|
||||
};
|
||||
|
||||
webviewLib.cloneError = function(error) {
|
||||
return {
|
||||
message: error.message,
|
||||
stack: error.stack,
|
||||
};
|
||||
};
|
||||
|
||||
webviewLib.logEnabledEventHandler = function(fn) {
|
||||
return function(event) {
|
||||
try {
|
||||
return fn(event);
|
||||
} catch (error) {
|
||||
webviewLib.options_.postMessage(`error:${JSON.stringify(webviewLib.cloneError(error))}`);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
webviewLib.initialize = function(options) {
|
||||
webviewLib.options_ = options;
|
||||
};
|
||||
|
||||
document.addEventListener('click', function(event) {
|
||||
const anchor = webviewLib.getParentAnchorElement(event.target);
|
||||
if (!anchor) return;
|
||||
|
||||
// Prevent URLs added via <a> tags from being opened within the application itself
|
||||
// otherwise it would open the whole website within the WebView.
|
||||
|
||||
// Note that we already handle some links in html_inline.js, however not all of them
|
||||
// go through this plugin, in particular links coming from third-party packages such
|
||||
// as Katex.
|
||||
if (!anchor.hasAttribute('data-from-md')) {
|
||||
if (webviewLib.handleInternalLink(event, anchor)) return;
|
||||
event.preventDefault();
|
||||
if (anchor.getAttribute('href')) webviewLib.options_.postMessage(anchor.getAttribute('href'));
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is an internal link, jump to the anchor directly
|
||||
if (anchor.hasAttribute('data-from-md')) {
|
||||
if (webviewLib.handleInternalLink(event, anchor)) return;
|
||||
}
|
||||
});
|
@ -1,7 +1,7 @@
|
||||
const stringPadding = require('string-padding');
|
||||
const urlUtils = require('lib/urlUtils');
|
||||
const MarkdownIt = require('markdown-it');
|
||||
const { setupLinkify } = require('joplin-renderer');
|
||||
const { setupLinkify } = require('lib/joplin-renderer');
|
||||
|
||||
const markdownUtils = {
|
||||
// Not really escaping because that's not supported by marked.js
|
||||
|
@ -2,7 +2,7 @@ const markdownUtils = require('lib/markdownUtils');
|
||||
const htmlUtils = require('lib/htmlUtils');
|
||||
const Setting = require('lib/models/Setting');
|
||||
const Resource = require('lib/models/Resource');
|
||||
const { MarkupToHtml } = require('joplin-renderer');
|
||||
const { MarkupToHtml } = require('lib/joplin-renderer');
|
||||
|
||||
class MarkupLanguageUtils {
|
||||
lib_(language) {
|
||||
|
@ -11,7 +11,7 @@ const { _ } = require('lib/locale.js');
|
||||
const ArrayUtils = require('lib/ArrayUtils.js');
|
||||
const lodash = require('lodash');
|
||||
const urlUtils = require('lib/urlUtils.js');
|
||||
const { MarkupToHtml } = require('joplin-renderer');
|
||||
const { MarkupToHtml } = require('lib/joplin-renderer');
|
||||
|
||||
class Note extends BaseItem {
|
||||
static tableName() {
|
||||
|
@ -9,7 +9,7 @@ const { themeStyle } = require('../../theme.js');
|
||||
const { dirname } = require('lib/path-utils.js');
|
||||
const { escapeHtml } = require('lib/string-utils.js');
|
||||
const markupLanguageUtils = require('lib/markupLanguageUtils');
|
||||
const { assetsToHeaders } = require('joplin-renderer');
|
||||
const { assetsToHeaders } = require('lib/joplin-renderer');
|
||||
|
||||
class InteropService_Exporter_Html extends InteropService_Exporter_Base {
|
||||
|
||||
|
@ -22,7 +22,7 @@ const ApiResponse = require('lib/services/rest/ApiResponse');
|
||||
const SearchEngineUtils = require('lib/services/SearchEngineUtils');
|
||||
const { FoldersScreenUtils } = require('lib/folders-screen-utils.js');
|
||||
const uri2path = require('file-uri-to-path');
|
||||
const { MarkupToHtml } = require('joplin-renderer');
|
||||
const { MarkupToHtml } = require('lib/joplin-renderer');
|
||||
const { uuid } = require('lib/uuid');
|
||||
|
||||
class ApiError extends Error {
|
||||
|
176
ReactNativeClient/package-lock.json
generated
176
ReactNativeClient/package-lock.json
generated
@ -2691,11 +2691,6 @@
|
||||
"locate-path": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"font-awesome-filetypes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/font-awesome-filetypes/-/font-awesome-filetypes-2.1.0.tgz",
|
||||
"integrity": "sha512-U6hi14GRjfZFIWsTNyVmCBuHyPhiizWEKVbaQqHipKQv3rA1l1PNvmKulzpqxonFnQMToty5ZhfWbc/0IjLDGA=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
@ -2736,6 +2731,7 @@
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
@ -2745,7 +2741,8 @@
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3369,11 +3366,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.18.0",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.0.tgz",
|
||||
"integrity": "sha512-A97kI1KAUzKoAiEoaGcf2O9YPS8nbDTCRFokaaeBhnqjQTvbAuAJrQMm21zw8s8xzaMtCQBtgbyGXLGxdxQyqQ=="
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
|
||||
@ -3758,58 +3750,6 @@
|
||||
"integrity": "sha512-+f/4OLeqY8RAmXnonI1ffeY1DR8kMNJPhv5WMFehchf7U71cjMQVKkOz1n6asz6kfVoAqKNWJz1A/18i18AcXA==",
|
||||
"dev": true
|
||||
},
|
||||
"joplin-renderer": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/joplin-renderer/-/joplin-renderer-1.0.8.tgz",
|
||||
"integrity": "sha512-Q4SSYXl9ErcnUDTz7N4FjWcOOgfPEf5yyNRjU2J1fuxZ/1VbYt6MnfBB7OeiRW+XF+4Arhihk+/XVK++of4hEA==",
|
||||
"requires": {
|
||||
"base-64": "^0.1.0",
|
||||
"font-awesome-filetypes": "^2.1.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"highlight.js": "^9.17.1",
|
||||
"html-entities": "^1.2.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"katex": "^0.11.1",
|
||||
"markdown-it": "^10.0.0",
|
||||
"markdown-it-abbr": "^1.0.4",
|
||||
"markdown-it-anchor": "^5.2.5",
|
||||
"markdown-it-deflist": "^2.0.3",
|
||||
"markdown-it-emoji": "^1.4.0",
|
||||
"markdown-it-footnote": "^3.0.2",
|
||||
"markdown-it-ins": "^3.0.0",
|
||||
"markdown-it-mark": "^3.0.0",
|
||||
"markdown-it-multimd-table": "^4.0.1",
|
||||
"markdown-it-sub": "^1.0.0",
|
||||
"markdown-it-sup": "^1.0.0",
|
||||
"markdown-it-toc-done-right": "^4.1.0",
|
||||
"md5": "^2.2.1",
|
||||
"uslug": "^1.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"entities": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
|
||||
"integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
|
||||
"integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~2.0.0",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"uc.micro": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||
@ -3847,11 +3787,6 @@
|
||||
"jsonify": "~0.0.0"
|
||||
}
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz",
|
||||
@ -3873,21 +3808,6 @@
|
||||
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
|
||||
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
|
||||
},
|
||||
"katex": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/katex/-/katex-0.11.1.tgz",
|
||||
"integrity": "sha512-5oANDICCTX0NqYIyAiFCCwjQ7ERu3DQG2JFHLbYOf+fXaMoH8eg/zOq5WSYJsKMi/QebW+Eh3gSM+oss1H/bww==",
|
||||
"requires": {
|
||||
"commander": "^2.19.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
@ -4043,83 +3963,6 @@
|
||||
"uc.micro": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"markdown-it-abbr": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz",
|
||||
"integrity": "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g="
|
||||
},
|
||||
"markdown-it-anchor": {
|
||||
"version": "5.2.5",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.2.5.tgz",
|
||||
"integrity": "sha512-xLIjLQmtym3QpoY9llBgApknl7pxAcN3WDRc2d3rwpl+/YvDZHPmKscGs+L6E05xf2KrCXPBvosWt7MZukwSpQ=="
|
||||
},
|
||||
"markdown-it-deflist": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-deflist/-/markdown-it-deflist-2.0.3.tgz",
|
||||
"integrity": "sha512-/BNZ8ksW42bflm1qQLnRI09oqU2847Z7MVavrR0MORyKLtiUYOMpwtlAfMSZAQU9UCvaUZMpgVAqoS3vpToJxw=="
|
||||
},
|
||||
"markdown-it-emoji": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-emoji/-/markdown-it-emoji-1.4.0.tgz",
|
||||
"integrity": "sha1-m+4OmpkKljupbfaYDE/dsF37Tcw="
|
||||
},
|
||||
"markdown-it-footnote": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-3.0.2.tgz",
|
||||
"integrity": "sha512-JVW6fCmZWjvMdDQSbOT3nnOQtd9iAXmw7hTSh26+v42BnvXeVyGMDBm5b/EZocMed2MbCAHiTX632vY0FyGB8A=="
|
||||
},
|
||||
"markdown-it-ins": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-3.0.0.tgz",
|
||||
"integrity": "sha512-+vyAdBuMGwmT2yMlAFJSx2VR/0QZ1onQ/Mkkmr4l9tDFOh5sVoAgRbkgbuSsk+sxJ9vaMH/IQ323ydfvQrPO/Q=="
|
||||
},
|
||||
"markdown-it-mark": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-mark/-/markdown-it-mark-3.0.0.tgz",
|
||||
"integrity": "sha512-HqMWeKfMMOu4zBO0emmxsoMWmbf2cPKZY1wP6FsTbKmicFfp5y4L3KXAsNeO1rM6NTJVOrNlLKMPjWzriBGspw=="
|
||||
},
|
||||
"markdown-it-multimd-table": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-multimd-table/-/markdown-it-multimd-table-4.0.1.tgz",
|
||||
"integrity": "sha512-ZgRV8LlGz6JXTZ5zd82yCL8IVG5MRastMWxxrc6hQC8aC8kq/7zpp+ksBqVqcdTmTdabnkuSo/7h3SyKM31YCA==",
|
||||
"requires": {
|
||||
"markdown-it": "^8.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"markdown-it": {
|
||||
"version": "8.4.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
|
||||
"integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"entities": "~1.1.1",
|
||||
"linkify-it": "^2.0.0",
|
||||
"mdurl": "^1.0.1",
|
||||
"uc.micro": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"uc.micro": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"markdown-it-sub": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz",
|
||||
"integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g="
|
||||
},
|
||||
"markdown-it-sup": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz",
|
||||
"integrity": "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M="
|
||||
},
|
||||
"markdown-it-toc-done-right": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.1.0.tgz",
|
||||
"integrity": "sha512-UhD2Oj6cZV3ycYPoelt4hTkwKIK3zbPP1wjjdpCq7UGtWQOFalDFDv1s2zBYV6aR2gMs/X8kpJcOYsQmUbiXDw=="
|
||||
},
|
||||
"math-random": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz",
|
||||
@ -7261,11 +7104,6 @@
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
@ -7347,14 +7185,6 @@
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
},
|
||||
"uslug": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/uslug/-/uslug-1.0.4.tgz",
|
||||
"integrity": "sha1-uaIvCRTgqGFAYz2swwLl9PpFBnc=",
|
||||
"requires": {
|
||||
"unorm": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"utf8": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz",
|
||||
|
@ -19,7 +19,6 @@
|
||||
"events": "^1.1.1",
|
||||
"form-data": "^2.1.4",
|
||||
"html-entities": "^1.2.1",
|
||||
"joplin-renderer": "^1.0.8",
|
||||
"jsc-android": "241213.1.0",
|
||||
"markdown-it": "^8.4.0",
|
||||
"md5": "^2.2.1",
|
||||
|
@ -8,9 +8,6 @@
|
||||
"name": "Joplin Nextcloud App",
|
||||
"path": "D:/Web/www/nextcloud/apps/joplin"
|
||||
},
|
||||
{
|
||||
"path": "D:/Docs/PROGS/Node/joplin-renderer"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"files.exclude": {
|
||||
|
@ -7,7 +7,8 @@
|
||||
"linter-ci": "./node_modules/.bin/eslint --ext .js --ext .jsx --ext .ts --ext .tsx",
|
||||
"tsc": "tsc",
|
||||
"tsc-watch": "tsc --watch",
|
||||
"copyLib": "rsync --delete -a ReactNativeClient/lib/ ElectronClient/app/lib/"
|
||||
"copyLib": "rsync --delete -a ReactNativeClient/lib/ ElectronClient/app/lib/",
|
||||
"postinstall": "cd ReactNativeClient && cd lib && cd joplin-renderer && npm i"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
Loading…
Reference in New Issue
Block a user