1
0
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:
Laurent Cozic 2020-01-30 21:05:23 +00:00
parent d687ef5c09
commit 688edd4b32
61 changed files with 4422 additions and 523 deletions

View File

@ -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

View File

@ -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",

View File

@ -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",

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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",

View File

@ -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",

View File

@ -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 "$@"

View File

@ -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) {

View File

@ -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');

View File

@ -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');

View File

@ -0,0 +1,3 @@
node_modules/
.vscode/
copyLib.bat

View 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;

View 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;

View 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;

View 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);
};
};

View File

@ -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);
};
};

View 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);
};
};

View File

@ -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);
};
};

View File

@ -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);
};
};

View File

@ -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);
};
};

View 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;
};
};

File diff suppressed because it is too large Load Diff

View File

@ -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);
};
};

View File

@ -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;
};
};

View 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);
}
}
}
```

View 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);
});

View File

@ -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;
}

View File

@ -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;
}

File diff suppressed because one or more lines are too long

View 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;

View 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',
};

View 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;

View File

@ -0,0 +1,7 @@
module.exports = {
MarkupToHtml: require('./MarkupToHtml'),
MdToHtml: require('./MdToHtml'),
HtmlToHtml: require('./HtmlToHtml'),
setupLinkify: require('./MdToHtml/setupLinkify'),
assetsToHeaders: require('./assetsToHeaders'),
};

View 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];
};

View 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
}
}
}

View 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"
}
}

View 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 };

View 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

View 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 };

View 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)
}));
});

View File

@ -0,0 +1,9 @@
{
"spec_dir": "tests",
"spec_files": [
"*.js",
"!test-utils.js"
],
"stopSpecOnExpectationFailure": true,
"random": true
}

View 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 };

View 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;

View 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;

View 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);

View 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;
}
});

View File

@ -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

View File

@ -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) {

View File

@ -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() {

View File

@ -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 {

View File

@ -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 {

View File

@ -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",

View File

@ -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",

View File

@ -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": {

View File

@ -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": {