@nebularstreams/statify 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.DS_Store +0 -0
- package/dist/website.simple/webfonts/fa-brands-400.woff2 +0 -0
- package/dist/website.simple/webfonts/fa-solid-900.eot +0 -0
- package/dist/website.simple/webfonts/fa-solid-900.svg +4649 -0
- package/dist/website.simple/webfonts/fa-solid-900.ttf +0 -0
- package/dist/website.simple/webfonts/fa-solid-900.woff +0 -0
- package/dist/website.simple/webfonts/fa-solid-900.woff2 +0 -0
- package/dist/website.simple/website.css +32 -0
- package/dist/website.simple/website.min.js +6 -0
- package/dist/website.software/webfonts/fa-brands-400.woff2 +0 -0
- package/dist/website.software/webfonts/fa-solid-900.eot +0 -0
- package/dist/website.software/webfonts/fa-solid-900.svg +4649 -0
- package/dist/website.software/webfonts/fa-solid-900.ttf +0 -0
- package/dist/website.software/webfonts/fa-solid-900.woff +0 -0
- package/dist/website.software/webfonts/fa-solid-900.woff2 +0 -0
- package/dist/website.software/website.css +32 -0
- package/dist/website.software/website.min.js +6 -0
- package/dist/website.worlds/webfonts/fa-brands-400.woff2 +0 -0
- package/dist/website.worlds/webfonts/fa-solid-900.eot +0 -0
- package/dist/website.worlds/webfonts/fa-solid-900.svg +4649 -0
- package/dist/website.worlds/webfonts/fa-solid-900.ttf +0 -0
- package/dist/website.worlds/webfonts/fa-solid-900.woff +0 -0
- package/dist/website.worlds/webfonts/fa-solid-900.woff2 +0 -0
- package/dist/website.worlds/website.css +32 -0
- package/dist/website.worlds/website.min.js +6 -0
- package/package.json +49 -0
- package/readme.md +105 -0
- package/src/publisher-lib.js +179 -0
- package/src/publisher-list.js +91 -0
- package/src/publisher.js +38 -0
- package/src/util/cdn/nobj.cdn.js +88 -0
- package/src/util/htmlroute.js +39 -0
- package/src/util/markdown/lib.showdown.icon.js +62 -0
- package/src/util/markdown/lib.showdown.yt.js +54 -0
- package/src/util/markdown/markdown.js +144 -0
- package/src/util/navibar/util.navibar.js +63 -0
- package/src/util/sha.js +20 -0
- package/src/util/tokenizer.js +234 -0
- package/src/util/widgets/NoticeWidget.js +30 -0
- package/src/util/widgets/app.widgets.js +70 -0
- package/src/util/widgets/util.definewidget.js +14 -0
- package/src/widgets/Cookies.js +55 -0
- package/src/widgets/Frameset-simple.js +114 -0
- package/src/widgets/Frameset.js +124 -0
- package/src/widgets/Page.js +356 -0
- package/src/widgets/RightSide.js +93 -0
- package/src/widgets/Snippets.js +75 -0
- package/src/widgets/Tail.js +11 -0
- package/src/widgets/Widgets.js +10 -0
- package/src/widgets.client/Client.js +22 -0
- package/src/widgets.features/FeatureList.js +364 -0
- package/src/widgets.features/Youtube.js +23 -0
- package/src/widgets.features/bootcol.js +29 -0
- package/src/widgets.features/css/feature.css +112 -0
- package/src/widgets.features/css/tail.css +4 -0
- package/src/widgets.howto/Faq.js +201 -0
- package/src/widgets.howto/HowTo.js +419 -0
- package/src/widgets.howto/Tiles.js +51 -0
- package/src/widgets.howto/script-contractable.js +31 -0
- package/src/widgets.markdown/Document.js +84 -0
- package/src/widgets.market/MarketItem.js +278 -0
- package/src/widgets.market/MarketItem.orig.js +268 -0
- package/src/widgets.market/MarketItem.strips.js +276 -0
- package/src/widgets.market/StoryLicenseWIdget.js +45 -0
- package/src/widgets.market/app.utils.js +238 -0
- package/src.website/css/app/animations.css +27 -0
- package/src.website/css/app/ismobile.css +7 -0
- package/src.website/css/app/style.css +51 -0
- package/src.website/css/app/style.fullheight.css +9 -0
- package/src.website/css/app/style.mdblocks.css +59 -0
- package/src.website/css/app/style.putosafari.css +3 -0
- package/src.website/css/bootstrap/bootstrap-tiny-core.css +47 -0
- package/src.website/css/bootstrap/bootstrap-tiny-media-columns.css +1276 -0
- package/src.website/css/bootstrap/bootstrap-tiny-media-custom.css +59 -0
- package/src.website/css/bootstrap/bootstrap-tiny-media-display.css +279 -0
- package/src.website/css/bootstrap/bootstrap-tiny-media-flex.css +881 -0
- package/src.website/css/bootstrap/bootstrap-tiny-media-fonts.css +39 -0
- package/src.website/css/bootstrap/bootstrap-tiny-media-paddings.css +1348 -0
- package/src.website/css/css-core/core.ext.css +65 -0
- package/src.website/css/css-core/frontpage.css +28 -0
- package/src.website/css/css-core/root.css +34 -0
- package/src.website/css/css-core/root.fullheight.css +12 -0
- package/src.website/css/css-core/ui.dialog.round.css +14 -0
- package/src.website/css/css-core/ui.navibar.css +28 -0
- package/src.website/css/css-core/ui.notifications.css +12 -0
- package/src.website/css/css-featurelist/feature.css +196 -0
- package/src.website/css/css-featurelist/tail.css +4 -0
- package/src.website/css/css-screens/doc.css +22 -0
- package/src.website/css/css-screens/screens-meta.css +3 -0
- package/src.website/css/css-unsplash/unsplash.css +32 -0
- package/src.website/css/css-videos/youtube.css +28 -0
- package/src.website/css/css-wiki/wiki.css +206 -0
- package/src.website/css/css-wiki/wiki.sidepane.css +16 -0
- package/src.website/css/fontawesome/fa-brands.css +18 -0
- package/src.website/css/fontawesome/fa-solid.css +16 -0
- package/src.website/css/fontawesome/fa.css +4359 -0
- package/src.website/css/skin/mierda.css +15 -0
- package/src.website/css/skin/skin.dark.css +85 -0
- package/src.website/css/skin/skin.light.css +27 -0
- package/src.website/css/skin/vars.font.css +8 -0
- package/src.website/css/skin/vars.sizes.css +4 -0
- package/src.website/package-lock.json +2160 -0
- package/src.website/package.json +28 -0
- package/src.website/public/webfonts/fa-brands-400.woff2 +0 -0
- package/src.website/public/webfonts/fa-solid-900.eot +0 -0
- package/src.website/public/webfonts/fa-solid-900.svg +4649 -0
- package/src.website/public/webfonts/fa-solid-900.ttf +0 -0
- package/src.website/public/webfonts/fa-solid-900.woff +0 -0
- package/src.website/public/webfonts/fa-solid-900.woff2 +0 -0
- package/src.website/rollup.simple.mjs +36 -0
- package/src.website/rollup.software.mjs +36 -0
- package/src.website/rollup.terser.mjs +24 -0
- package/src.website/rollup.worlds.mjs +36 -0
- package/src.website/src/app/app.style.mjs +36 -0
- package/src.website/src/app/index.mjs +118 -0
- package/src.website/src/config.js +8 -0
- package/src.website/src/core/cdnmodel.mjs +7 -0
- package/src.website/src/core/clientruntime.mjs +41 -0
- package/src.website/src/core.cookies/analytics.mjs +96 -0
- package/src.website/src/core.cookies/cookiemanager.mjs +128 -0
- package/src.website/src/core.cookies/css/cookies.css +80 -0
- package/src.website/src/core.cookies/css/nocookies.css +48 -0
- package/src.website/src/core.extra/css/contractable.css +12 -0
- package/src.website/src/core.extra/css/faq.css +42 -0
- package/src.website/src/core.extra/css/howto.css +81 -0
- package/src.website/src/core.extra/extra.document.mjs +83 -0
- package/src.website/src/core.extra/extra.faq.mjs +30 -0
- package/src.website/src/core.extra/extra.mjs +62 -0
- package/src.website/src/main.simple.mjs +4 -0
- package/src.website/src/main.software.mjs +10 -0
- package/src.website/src/main.worlds.mjs +9 -0
- package/src.website/src/support/ismobile.mjs +4 -0
- package/src.website/src/support/nonce.mjs +4 -0
- package/src.website/src/support/persistsettings.mjs +41 -0
- package/src.website/src/support/qrcode.mjs +1269 -0
- package/src.website/src/support/timeutils.mjs +237 -0
- package/src.website/src/widgets/index.mjs +22 -0
- package/src.website/src.widgets/widgets.market/index.mjs +11 -0
- package/src.website/src.widgets/widgets.market/widgets/market/DiscoverWidget.mjs +401 -0
- package/src.website/src.widgets/widgets.market/widgets/market/EmptyNew.mjs +28 -0
- package/src.website/src.widgets/widgets.market/widgets/market/MarketDetail.mjs +78 -0
- package/src.website/src.widgets/widgets.market/widgets/market/MarketItem.mjs +349 -0
- package/src.website/src.widgets/widgets.market/widgets/market/MarketWidget.mjs +437 -0
- package/src.website/src.widgets/widgets.market/widgets/market/StoryLicenseWidget.mjs +34 -0
- package/src.website/src.widgets/widgets.market/widgets/market/css/market.css +394 -0
- package/src.website/src.widgets/widgets.market/widgets/market/css/notice.css +6 -0
- package/src.website/src.widgets/widgets.market/widgets/navibar/NaviBarWidget.mjs +58 -0
- package/src.website/src.widgets/widgets.market/widgets/navibar/css/titlebar.css +68 -0
- package/src.website/src.widgets/widgets.market/widgets/navibar/css/ui.navibar.css +28 -0
- package/src.website/src.widgets/widgets.software/index.mjs +9 -0
- package/src.website/src.widgets/widgets.software/widgets/BootStrapColumnWidget.mjs +17 -0
- package/src.website/src.widgets/widgets.software/widgets/DownloadWidget.mjs +210 -0
- package/src.website/src.widgets/widgets.software/widgets/LicenseWidget.js +103 -0
- package/src.website/src.widgets/widgets.software/widgets/css/download/download.css +110 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/beta.css +28 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/button.css +30 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/front.css +46 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/licenses.css +13 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/overstate.css +15 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/story.css +8 -0
- package/src.website/src.widgets/widgets.software/widgets/css/license/toolbar.css +9 -0
- package/src.website/src.widgets/widgets.software/widgets/support/version.mjs +88 -0
- package/src.website/src.widgets/widgets.worlds/index.mjs +11 -0
- package/src.website/src.widgets/widgets.worlds/widgets/LocalBrowser.mjs +386 -0
- package/src.website/src.widgets/widgets.worlds/widgets/LocalLauncher.code.mjs +247 -0
- package/src.website/src.widgets/widgets.worlds/widgets/LocalLauncher.mjs +239 -0
- package/src.website/src.widgets/widgets.worlds/widgets/css/input.css +32 -0
- package/src.website/src.widgets/widgets.worlds/widgets/css/localprojects.css +188 -0
- package/templates/documentation/assets/docs.css +7 -0
- package/templates/documentation/assets/images/right.webp +0 -0
- package/templates/documentation/images.json +12 -0
- package/templates/documentation/metadata.json +120 -0
- package/templates/documentation/pages/cookies.md +25 -0
- package/templates/documentation/pages/index.md +13 -0
- package/templates/documentation/pages/privacy.md +50 -0
- package/templates/documentation/pages/tos.md +49 -0
- package/templates/landing/assets/res/carousel/image-1.webp +0 -0
- package/templates/landing/assets/res/carousel/image-2.webp +0 -0
- package/templates/landing/assets/res/carousel/image-3.webp +0 -0
- package/templates/landing/assets/res/custom.css +122 -0
- package/templates/landing/assets/res/logos/favicon.ico +0 -0
- package/templates/landing/assets/res/logos/favicon.png +0 -0
- package/templates/landing/assets/res/logos/logo.medallion.png +0 -0
- package/templates/landing/assets/res/logos/logo.white.png +0 -0
- package/templates/landing/assets/res/proj/banda-tech-client.webp +0 -0
- package/templates/landing/assets/res/proj/banda-tech-server.webp +0 -0
- package/templates/landing/assets/res/proj/proj-common-ground.webp +0 -0
- package/templates/landing/assets/res/proj/proj-fieldnote.webp +0 -0
- package/templates/landing/assets/res/proj/proj-tribes.webp +0 -0
- package/templates/landing/images.json +932 -0
- package/templates/landing/metadata.json +115 -0
- package/templates/landing/pages/index.json +268 -0
- package/tool/cli.js +183 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/* eslint-disable import/no-dynamic-require */
|
|
2
|
+
const
|
|
3
|
+
m = require("mithril"),
|
|
4
|
+
render = require("mithril-node-render"),
|
|
5
|
+
{Cdn} = require("./util/cdn/nobj.cdn"),
|
|
6
|
+
|
|
7
|
+
PageWidget = require("./widgets/Page"),
|
|
8
|
+
footer = require("./widgets/Cookies"),
|
|
9
|
+
{convertMarkdownFile} = require("./util/markdown/markdown"),
|
|
10
|
+
{parseImageUrl} = require("./util/htmlroute"),
|
|
11
|
+
{getSnippet} = require("./widgets/Snippets"),
|
|
12
|
+
|
|
13
|
+
// use lambda to insert .html into the request
|
|
14
|
+
// but use non-html here
|
|
15
|
+
|
|
16
|
+
EXTENSION_HTML = "";
|
|
17
|
+
|
|
18
|
+
function saniLink(link, newext) {
|
|
19
|
+
if (link.indexOf(".json")) {
|
|
20
|
+
return link.split(".json")
|
|
21
|
+
.join(newext);
|
|
22
|
+
}
|
|
23
|
+
return link;
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getLevels(basePath, metadata) {
|
|
28
|
+
return basePath.split("/")
|
|
29
|
+
.filter((o) => !!o)
|
|
30
|
+
.reduce((tot, item, idx, all) => {
|
|
31
|
+
tot.push({name: item, link: (idx ? all[idx - 1] + "/" : "") + item});
|
|
32
|
+
return tot;
|
|
33
|
+
}, [])
|
|
34
|
+
.filter((item) => ((metadata["links.metadata"] || {})[item.link]))
|
|
35
|
+
.map((item) => ({...item, submeta: metadata["links.metadata"][item.link]}));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function generateLinks(levels, metadata, nextLevelLinks = []) {
|
|
39
|
+
|
|
40
|
+
const
|
|
41
|
+
lastLevel = levels.length ? levels[levels.length - 1] : undefined,
|
|
42
|
+
previousLevel = levels.length > 1 ? levels[levels.length - 2] : undefined;
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
...previousLevel
|
|
46
|
+
? {
|
|
47
|
+
[previousLevel.name]: {
|
|
48
|
+
class: "inter",
|
|
49
|
+
url: [metadata.canonical, previousLevel.link, "index"].join("/"),
|
|
50
|
+
...(previousLevel.submeta || {})
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
: {},
|
|
54
|
+
...lastLevel
|
|
55
|
+
? {
|
|
56
|
+
[lastLevel.name]: {
|
|
57
|
+
class: "inter",
|
|
58
|
+
url: [metadata.canonical, lastLevel.link, "index"].join("/"),
|
|
59
|
+
...(lastLevel.submeta || {})
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
: {
|
|
63
|
+
...(metadata["links.doc"] || {})
|
|
64
|
+
},
|
|
65
|
+
...nextLevelLinks
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getPageMetadata(filename, metadata, relativeRoute, levels, baseFilename) {
|
|
70
|
+
|
|
71
|
+
if (filename.endsWith(".md")) {
|
|
72
|
+
|
|
73
|
+
const
|
|
74
|
+
|
|
75
|
+
relativeFolder = relativeRoute.substring(0, relativeRoute.lastIndexOf("/")),
|
|
76
|
+
document = convertMarkdownFile(filename, {
|
|
77
|
+
metadata,
|
|
78
|
+
relativeRoute: relativeFolder,
|
|
79
|
+
relativeFile: baseFilename
|
|
80
|
+
}),
|
|
81
|
+
|
|
82
|
+
{images, index} = document,
|
|
83
|
+
parsedImages = images.map(
|
|
84
|
+
(image) => parseImageUrl(image, metadata, relativeFolder)
|
|
85
|
+
),
|
|
86
|
+
lastLevel = levels.length ? levels[levels.length - 1] : undefined;
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
title: index[0].text,
|
|
90
|
+
description: index[0].next,
|
|
91
|
+
submeta: lastLevel && lastLevel.submeta,
|
|
92
|
+
widget: "Markdown",
|
|
93
|
+
image: {
|
|
94
|
+
url: images[0]
|
|
95
|
+
},
|
|
96
|
+
document,
|
|
97
|
+
links: generateLinks(
|
|
98
|
+
levels,
|
|
99
|
+
metadata,
|
|
100
|
+
{
|
|
101
|
+
[index[0].text]: {
|
|
102
|
+
class: "grows"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
),
|
|
106
|
+
snippet: getSnippet(
|
|
107
|
+
"Article",
|
|
108
|
+
index[0].text,
|
|
109
|
+
parsedImages,
|
|
110
|
+
undefined,
|
|
111
|
+
metadata.author,
|
|
112
|
+
metadata.publisher
|
|
113
|
+
)
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return require(filename);
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function publish(filename, source, htmlRoot = "pages", dynamicData = undefined) {
|
|
121
|
+
|
|
122
|
+
if (filename && source) {
|
|
123
|
+
|
|
124
|
+
const
|
|
125
|
+
metadata = require(source + "/metadata.json"),
|
|
126
|
+
{links, navibar, site} = metadata,
|
|
127
|
+
{name, domain, nocookies, cookies} = site,
|
|
128
|
+
filePath = filename.split("/"),
|
|
129
|
+
navibarLinks = navibar?.links || links;
|
|
130
|
+
|
|
131
|
+
filePath.shift();
|
|
132
|
+
|
|
133
|
+
const
|
|
134
|
+
relativeRoute = saniLink(filePath.join("/"), EXTENSION_HTML),
|
|
135
|
+
baseSource = filePath.pop(),
|
|
136
|
+
basePath = filePath.join("/");
|
|
137
|
+
|
|
138
|
+
if (!domain) {
|
|
139
|
+
throw new Error("Please set domain in metadata");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!navibarLinks) {
|
|
143
|
+
throw new Error("Please set navigation bar in metadata, or define missing page");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const
|
|
147
|
+
|
|
148
|
+
cdnModel = new Cdn(domain),
|
|
149
|
+
absoluteFileRoute = [source, htmlRoot, ...basePath ? [basePath] : [], baseSource].join("/"),
|
|
150
|
+
levels = getLevels(basePath, metadata),
|
|
151
|
+
pageMetadata = getPageMetadata(absoluteFileRoute, metadata, relativeRoute, levels, baseSource),
|
|
152
|
+
|
|
153
|
+
cookiesDialog = nocookies ? undefined : (footer[cookies || "full"](name, domain)),
|
|
154
|
+
|
|
155
|
+
result = await render(
|
|
156
|
+
m(PageWidget, {
|
|
157
|
+
baseSource,
|
|
158
|
+
basePath,
|
|
159
|
+
pageMetadata,
|
|
160
|
+
relativeRoute,
|
|
161
|
+
levels,
|
|
162
|
+
metadata,
|
|
163
|
+
dynamicData,
|
|
164
|
+
source,
|
|
165
|
+
cdnModel,
|
|
166
|
+
...cookiesDialog && {
|
|
167
|
+
footer: cookiesDialog
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
return ["<!DOCTYPE html>", result].join("\n");
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
throw new Error("No file specified");
|
|
176
|
+
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports = publish;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* eslint-disable import/no-dynamic-require,no-await-in-loop */
|
|
2
|
+
const
|
|
3
|
+
axios = require("axios"),
|
|
4
|
+
fs = require("fs"),
|
|
5
|
+
{ tokenizeStrict } = require("./util/tokenizer"),
|
|
6
|
+
publish = require("./publisher-lib");
|
|
7
|
+
|
|
8
|
+
function parseArgs(argv) {
|
|
9
|
+
|
|
10
|
+
const
|
|
11
|
+
name = "publisher-list.js",
|
|
12
|
+
initial = argv[0].endsWith(name)
|
|
13
|
+
? 1 : argv[1].endsWith(name)
|
|
14
|
+
? 2
|
|
15
|
+
: 0;
|
|
16
|
+
if (initial) return argv.slice(initial, argv.length);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function stderr(...data) {
|
|
21
|
+
process.stderr.write(data.join(" ") + "\n");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function parseItem(source, listname, metadata, type, item, outpath) {
|
|
25
|
+
stderr("+ Found Item, list", listname, "type", type, "item", item.id);
|
|
26
|
+
return publish("./" + listname, source, "lists", { meta: metadata, item, relative: outpath }, metadata);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function writeFile(outpath, contents) {
|
|
30
|
+
|
|
31
|
+
// const outfile = outpath + "/index.html";
|
|
32
|
+
const outfile = outpath + ".html";
|
|
33
|
+
|
|
34
|
+
stderr("- Generating page", outfile);
|
|
35
|
+
if (!fs.existsSync(outpath)) {
|
|
36
|
+
stderr("- Creating folder", outpath);
|
|
37
|
+
fs.mkdirSync(outpath, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
fs.writeFileSync(outfile, contents, { encoding: "utf-8" });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function parseList(source, metadata, listname, list, outpublish, filtername) {
|
|
43
|
+
const { items, type } = list;
|
|
44
|
+
|
|
45
|
+
stderr("> Parsing list type", type, "items", items.length, "filter", filtername);
|
|
46
|
+
|
|
47
|
+
for (const item of items) {
|
|
48
|
+
|
|
49
|
+
if (filtername && item.id !== filtername) continue;
|
|
50
|
+
|
|
51
|
+
const
|
|
52
|
+
outpath = tokenizeStrict(metadata.listout, { item, type }),
|
|
53
|
+
html = await parseItem(source, listname, metadata, type, item, outpath);
|
|
54
|
+
|
|
55
|
+
await writeFile(outpublish + (outpath ? "/" + outpath : ""), html);
|
|
56
|
+
|
|
57
|
+
}
|
|
58
|
+
stderr("< List", listname, "parsed");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function init() {
|
|
62
|
+
|
|
63
|
+
const
|
|
64
|
+
args = parseArgs(process.argv);
|
|
65
|
+
|
|
66
|
+
if (args[0] && args[1] && args[2]) {
|
|
67
|
+
|
|
68
|
+
const
|
|
69
|
+
[listname, source, outpublish, filtername] = args,
|
|
70
|
+
metadata = require(source + "/lists/" + listname);
|
|
71
|
+
|
|
72
|
+
stderr("- Loading List", listname, "from", metadata.list);
|
|
73
|
+
stderr("- Source folder", source);
|
|
74
|
+
|
|
75
|
+
const
|
|
76
|
+
list = await axios({ url: metadata.list });
|
|
77
|
+
|
|
78
|
+
await parseList(source, metadata, listname, list.data, outpublish, filtername);
|
|
79
|
+
} else {
|
|
80
|
+
throw new Error("Usage: publisher-list listname source output filterid");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
init()
|
|
85
|
+
.then(() => {
|
|
86
|
+
stderr("! Finished.");
|
|
87
|
+
})
|
|
88
|
+
.catch((e) => {
|
|
89
|
+
console.error(e);
|
|
90
|
+
process.exitCode = 1;
|
|
91
|
+
});
|
package/src/publisher.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/* eslint-disable import/no-dynamic-require */
|
|
2
|
+
const
|
|
3
|
+
publish = require("./publisher-lib");
|
|
4
|
+
|
|
5
|
+
function parseArgs(argv) {
|
|
6
|
+
|
|
7
|
+
const
|
|
8
|
+
name = "publisher.js",
|
|
9
|
+
initial = argv[0].endsWith(name)
|
|
10
|
+
? 1 : argv[1].endsWith(name)
|
|
11
|
+
? 2
|
|
12
|
+
: 0;
|
|
13
|
+
if (initial) return argv.slice(initial, argv.length);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function init() {
|
|
18
|
+
|
|
19
|
+
const
|
|
20
|
+
args = parseArgs(process.argv);
|
|
21
|
+
|
|
22
|
+
if (args[0] && args[1]) {
|
|
23
|
+
|
|
24
|
+
const
|
|
25
|
+
[filename, source] = args;
|
|
26
|
+
|
|
27
|
+
publish(filename, source)
|
|
28
|
+
.then((txt) => {
|
|
29
|
+
console.log(txt);
|
|
30
|
+
})
|
|
31
|
+
.catch((e) => {
|
|
32
|
+
console.error(e);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
init();
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
function Cdn(ncsdom) {
|
|
2
|
+
|
|
3
|
+
const
|
|
4
|
+
PROTO = "https://",
|
|
5
|
+
PUBLICCDNROOT = PROTO + ncsdom,
|
|
6
|
+
PUBLICPLATFORMROOT = PUBLICCDNROOT + "/all",
|
|
7
|
+
PUBLICRESOURCES = PUBLICCDNROOT + "/res",
|
|
8
|
+
PUBLICCHANNELROOT = PUBLICCDNROOT + "/cdn",
|
|
9
|
+
PUBLICLISTROOT = PUBLICPLATFORMROOT + "/list";
|
|
10
|
+
|
|
11
|
+
function channelPath(name, path) {
|
|
12
|
+
return PUBLICCHANNELROOT + "/" + name + (path ? "/" + path : "");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function platformPath(path) {
|
|
16
|
+
return PUBLICPLATFORMROOT + (path ? "/" + path : "");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function resourcesPath(path) {
|
|
20
|
+
return PUBLICRESOURCES + (path ? "/" + path : "");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function platformListPath(entityType, name = "index") {
|
|
24
|
+
return PUBLICLISTROOT + "/" + entityType + (name ? "/list." + name + ".json" : "");
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function platformFilesPath(entityType, name, path) {
|
|
28
|
+
return PUBLICPLATFORMROOT + "/files" + (path ? "/" + path : "");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// cdn/nebular/world/list.index.json
|
|
32
|
+
function channelListPath(channelName, entityType, listName = "index") {
|
|
33
|
+
return channelPath(channelName, entityType + "/list." + listName + ".json");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function channelFilesPath(channelName, path) {
|
|
37
|
+
return channelPath(channelName, "files/" + (path ? "/" + path : ""));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function channelEntityPath(channelName, entityType, entityName, path = "index.json", short = false) {
|
|
41
|
+
return channelPath(channelName, (short ? "" : "obj/") + entityType + "/" + entityName + (path ? "/" + path : ""));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
channel: {
|
|
46
|
+
// @deprecated
|
|
47
|
+
listPath: channelListPath,
|
|
48
|
+
entityPath: channelEntityPath,
|
|
49
|
+
filesPath: channelFilesPath,
|
|
50
|
+
path: channelPath,
|
|
51
|
+
list: channelListPath,
|
|
52
|
+
},
|
|
53
|
+
platform: {
|
|
54
|
+
path: platformPath,
|
|
55
|
+
list: platformListPath,
|
|
56
|
+
|
|
57
|
+
// @deprecated
|
|
58
|
+
listPath: platformListPath,
|
|
59
|
+
|
|
60
|
+
filesPath: platformFilesPath,
|
|
61
|
+
resources: resourcesPath,
|
|
62
|
+
channel: name => new CdnChannel(ncsdom, name)
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function CdnChannel(ncsdom, channelName) {
|
|
68
|
+
|
|
69
|
+
const
|
|
70
|
+
{channel} = new Cdn(ncsdom),
|
|
71
|
+
{
|
|
72
|
+
list, entityPath, path, filesPath
|
|
73
|
+
} = channel;
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
|
|
77
|
+
// @deprecated
|
|
78
|
+
listPath: (entityType, listName) => list(channelName, entityType, listName),
|
|
79
|
+
|
|
80
|
+
entityPath: (entityType, entityName, rest) => entityPath(channelName, entityType, entityName, rest),
|
|
81
|
+
filesPath: rest => filesPath(channelName, rest),
|
|
82
|
+
path: rest => path(channelName, rest),
|
|
83
|
+
list: (entityType, listName) => list(channelName, entityType, listName),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = {Cdn, CdnChannel};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const
|
|
2
|
+
absoRoute = (url, metadata, relativeRoute, relativeFile = "index") => (
|
|
3
|
+
((url.indexOf("://") !== -1) || url.startsWith("mailto:"))
|
|
4
|
+
? url
|
|
5
|
+
: (url.startsWith("#"))
|
|
6
|
+
? ([
|
|
7
|
+
metadata.canonical,
|
|
8
|
+
...relativeRoute
|
|
9
|
+
? [relativeRoute]
|
|
10
|
+
: [],
|
|
11
|
+
relativeFile
|
|
12
|
+
]).join("/") + url
|
|
13
|
+
: (url.startsWith("/"))
|
|
14
|
+
? [metadata.site.url, url.substring(1)].join("/")
|
|
15
|
+
: ([
|
|
16
|
+
metadata.canonical,
|
|
17
|
+
...relativeRoute
|
|
18
|
+
? [relativeRoute]
|
|
19
|
+
: [],
|
|
20
|
+
|
|
21
|
+
...url
|
|
22
|
+
? [url]
|
|
23
|
+
: []
|
|
24
|
+
].join("/"))
|
|
25
|
+
);
|
|
26
|
+
const
|
|
27
|
+
absoFolder = (url, metadata, relativeRoute) => {
|
|
28
|
+
if (url.indexOf("://") !== -1) return url;
|
|
29
|
+
if (url.startsWith("/")) return [metadata.canonical, url].join("/");
|
|
30
|
+
const relati = relativeRoute.split("/");
|
|
31
|
+
relati.pop();
|
|
32
|
+
const finalRelate = relati.join("/");
|
|
33
|
+
return ([metadata.canonical, ...finalRelate ? [finalRelate] : [], url].join("/"));
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
parseImage = ({ url, alt }, metadata, relativeRoute) => ({ url: absoFolder(url, metadata, relativeRoute), alt, "@type": "ImageObject" }),
|
|
37
|
+
parseImageUrl = (url, metadata, relativeRoute) => (absoFolder(url, metadata, relativeRoute));
|
|
38
|
+
|
|
39
|
+
module.exports = { absoRoute, absoFolder, parseImage, parseImageUrl };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Showdown Icon Extension, Glyphicon and FontAwesome support for showdown
|
|
3
|
+
* http://github.com/dbtek/showdown-icon
|
|
4
|
+
* 2014, Ismail Demirbilek
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
(function (extension) {
|
|
8
|
+
|
|
9
|
+
// UML - Universal Module Loader
|
|
10
|
+
// This enables the extension to be loaded in different environments
|
|
11
|
+
if (typeof showdown !== "undefined") {
|
|
12
|
+
// global (browser or nodejs global)
|
|
13
|
+
extension(showdown);
|
|
14
|
+
} else if (typeof define === "function" && define.amd) {
|
|
15
|
+
// AMD
|
|
16
|
+
define(["showdown"], extension);
|
|
17
|
+
} else if (typeof exports === "object") {
|
|
18
|
+
// Node, CommonJS-like
|
|
19
|
+
module.exports = extension(require("showdown"));
|
|
20
|
+
} else {
|
|
21
|
+
// showdown was not found so we throw
|
|
22
|
+
throw Error("Could not find showdown library");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
}(function (showdown) {
|
|
26
|
+
"use strict";
|
|
27
|
+
|
|
28
|
+
//This is the extension code per se
|
|
29
|
+
|
|
30
|
+
// Here you have a safe sandboxed environment where you can use "static code"
|
|
31
|
+
// that is, code and data that is used accros instances of the extension itself
|
|
32
|
+
// If you have regexes or some piece of calculation that is immutable
|
|
33
|
+
// this is the best place to put them.
|
|
34
|
+
|
|
35
|
+
// The following method will register the extension with showdown
|
|
36
|
+
showdown.extension("icon", function () {
|
|
37
|
+
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
type: "lang",
|
|
41
|
+
regex: "\\B(\\\\)?@glyphicon-([\\S]+)\\b",
|
|
42
|
+
replace(a, b, c) {
|
|
43
|
+
return b === "\\" ? a : `<span class="glyphicon glyphicon-${c}"></span>`;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: "lang",
|
|
48
|
+
regex: "\\B(\\\\)?@fa-([\\S]+)\\b",
|
|
49
|
+
replace(a, b, c) {
|
|
50
|
+
return b === "\\" ? a : `<i class="fa fa-${c}"></i>`;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: "lang",
|
|
55
|
+
regex: "\\B(\\\\)?@fabrd-([\\S]+)\\b",
|
|
56
|
+
replace(a, b, c) {
|
|
57
|
+
return b === "\\" ? a : `<i class="fa fabrd fa-${c}"></i>`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
];
|
|
61
|
+
});
|
|
62
|
+
}));
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Showdown Icon Extension, Glyphicon and FontAwesome support for showdown
|
|
3
|
+
* http://github.com/dbtek/showdown-icon
|
|
4
|
+
* 2014, Ismail Demirbilek
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
(function (extension) {
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
// UML - Universal Module Loader
|
|
11
|
+
// This enables the extension to be loaded in different environments
|
|
12
|
+
if (typeof showdown !== "undefined") {
|
|
13
|
+
// global (browser or nodejs global)
|
|
14
|
+
extension(showdown);
|
|
15
|
+
} else if (typeof define === "function" && define.amd) {
|
|
16
|
+
// AMD
|
|
17
|
+
define(["showdown"], extension);
|
|
18
|
+
} else if (typeof exports === "object") {
|
|
19
|
+
// Node, CommonJS-like
|
|
20
|
+
module.exports = extension(require("showdown"));
|
|
21
|
+
} else {
|
|
22
|
+
// showdown was not found so we throw
|
|
23
|
+
throw Error("Could not find showdown library");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}(function (showdown) {
|
|
27
|
+
"use strict";
|
|
28
|
+
|
|
29
|
+
function getYouTubeImage(ref) {
|
|
30
|
+
return `https://i3.ytimg.com/vi/${ref}/hqdefault.jpg`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//This is the extension code per se
|
|
34
|
+
|
|
35
|
+
// Here you have a safe sandboxed environment where you can use "static code"
|
|
36
|
+
// that is, code and data that is used accros instances of the extension itself
|
|
37
|
+
// If you have regexes or some piece of calculation that is immutable
|
|
38
|
+
// this is the best place to put them.
|
|
39
|
+
|
|
40
|
+
function getVideo(id) {
|
|
41
|
+
return "<md-wrap><md-yt><iframe data-img=\"" + getYouTubeImage(id) + "\" data-src=\"https://www.youtube.com/embed/" + id + "?rel=0&modestbranding=1\" allow=\"encrypted-media; picture-in-picture\" allowfullscreen></iframe></md-yt></md-wrap>";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The following method will register the extension with showdown
|
|
45
|
+
showdown.extension("youtube", function () {
|
|
46
|
+
return [{
|
|
47
|
+
type: "lang",
|
|
48
|
+
regex: "\\B(\\\\)?@yt-([a-zA-Z0-9_\\-]+)\\b",
|
|
49
|
+
replace: function (a, b, c) {
|
|
50
|
+
return b === "\\" ? a : getVideo(c);
|
|
51
|
+
}
|
|
52
|
+
}];
|
|
53
|
+
});
|
|
54
|
+
}));
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* eslint-disable import/no-dynamic-require */
|
|
2
|
+
const
|
|
3
|
+
fs = require("fs"),
|
|
4
|
+
showdown = require("showdown"),
|
|
5
|
+
{ absoRoute } = require("../htmlroute"),
|
|
6
|
+
MARKDOWN_EXTENSION = ".md"; // ".html"
|
|
7
|
+
|
|
8
|
+
require("./lib.showdown.icon");
|
|
9
|
+
require("./lib.showdown.yt");
|
|
10
|
+
|
|
11
|
+
function getHrefLink(link, options) {
|
|
12
|
+
return absoRoute(link, options.metadata, options.relativeRoute, options.relativeFile)
|
|
13
|
+
.split(MARKDOWN_EXTENSION)
|
|
14
|
+
.join("");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getImageLink(link, options) {
|
|
18
|
+
return absoRoute(link, options.metadata, options.relativeRoute);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function replaceLink(html, pattern, getLink, options) {
|
|
22
|
+
|
|
23
|
+
// noinspection JSUnresolvedVariable,JSUnresolvedFunction
|
|
24
|
+
const
|
|
25
|
+
parts = html.split(pattern)
|
|
26
|
+
.map((linkPart, index) => {
|
|
27
|
+
|
|
28
|
+
if (!index) {
|
|
29
|
+
return linkPart;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const
|
|
33
|
+
linkEndIndex = linkPart.indexOf("\"");
|
|
34
|
+
|
|
35
|
+
if (linkEndIndex === -1 || !getLink) {
|
|
36
|
+
return linkPart;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const
|
|
40
|
+
link = linkPart.substring(0, linkEndIndex),
|
|
41
|
+
remaining = linkPart.substring(linkEndIndex);
|
|
42
|
+
|
|
43
|
+
return getLink(link, options) + remaining;
|
|
44
|
+
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return parts.join(pattern);
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function convert(text, options = {}) {
|
|
52
|
+
|
|
53
|
+
// noinspection JSUnresolvedVariable,JSUnresolvedFunction
|
|
54
|
+
const
|
|
55
|
+
Converter = new showdown.Converter({
|
|
56
|
+
ghCompatibleHeaderId: true,
|
|
57
|
+
openLinksInNewWindow: false,
|
|
58
|
+
strikethrough: true,
|
|
59
|
+
emoji: true,
|
|
60
|
+
metadata: true,
|
|
61
|
+
tasklist: true,
|
|
62
|
+
tables: true,
|
|
63
|
+
moreStyling: true,
|
|
64
|
+
extensions: ["icon", "youtube"]
|
|
65
|
+
}),
|
|
66
|
+
metadata = Converter.getMetadata(undefined);
|
|
67
|
+
|
|
68
|
+
// noinspection JSUnresolvedFunction
|
|
69
|
+
let
|
|
70
|
+
html = Converter.makeHtml(text);
|
|
71
|
+
|
|
72
|
+
html = replaceLink(html, " href=\"", getHrefLink, options);
|
|
73
|
+
html = replaceLink(html, " src=\"", getImageLink, options);
|
|
74
|
+
html = html
|
|
75
|
+
.split("<table>")
|
|
76
|
+
.join("<div class=\"w-100\"><div class=\"scrollx\"><table>")
|
|
77
|
+
.split("</table>")
|
|
78
|
+
.join("</table></div></div>");
|
|
79
|
+
|
|
80
|
+
return { html, metadata };
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function getId(line) {
|
|
85
|
+
const idpart = line.split("id=\"")[1];
|
|
86
|
+
return idpart ? idpart.split("\"")[0] : undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function insertImage(line, index) {
|
|
90
|
+
const img = line.split("<img src=\"")[1];
|
|
91
|
+
if (img) {
|
|
92
|
+
index.push(img.split("\"")[0]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function insertIndex(line, level, index, indexed, next) {
|
|
97
|
+
if (line.startsWith("<h" + level)) {
|
|
98
|
+
const id = getId(line),
|
|
99
|
+
item = {
|
|
100
|
+
level,
|
|
101
|
+
id,
|
|
102
|
+
text:
|
|
103
|
+
(line.substring(line.indexOf(">") + 1))
|
|
104
|
+
.split("</h" + level + ">")[0],
|
|
105
|
+
next: next.substring(next.indexOf(">") + 1)
|
|
106
|
+
.split("<")[0]
|
|
107
|
+
};
|
|
108
|
+
index.push(item);
|
|
109
|
+
indexed[id] = item;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function convertMarkdown(text, options = {}) {
|
|
114
|
+
|
|
115
|
+
const
|
|
116
|
+
output = convert(text, options),
|
|
117
|
+
index = [],
|
|
118
|
+
images = [],
|
|
119
|
+
indexed = {},
|
|
120
|
+
buffer = output.html.split("\n");
|
|
121
|
+
|
|
122
|
+
let i = 0;
|
|
123
|
+
for (const line of buffer) {
|
|
124
|
+
insertIndex(line, 1, index, indexed, buffer[i + 1]);
|
|
125
|
+
insertIndex(line, 2, index, indexed, buffer[i + 1]);
|
|
126
|
+
insertIndex(line, 3, index, indexed, buffer[i + 1]);
|
|
127
|
+
insertImage(line, images);
|
|
128
|
+
i++;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return { html: output.html, index, indexed, images };
|
|
132
|
+
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function convertMarkdownFile(path, options = {}) {
|
|
136
|
+
|
|
137
|
+
const
|
|
138
|
+
text = fs.readFileSync(path, { encoding: "UTF-8" });
|
|
139
|
+
|
|
140
|
+
return convertMarkdown(text, options);
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = { convert, convertMarkdown, convertMarkdownFile };
|