chalk-talk 0.7.0 → 0.8.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/README.md +2 -1
- package/assets/player.html +2 -2
- package/package.json +1 -1
- package/player.js +3 -3
- package/scripts/build.mjs +42 -11
- package/scripts/contract.mjs +1 -1
- package/scripts/mermaid.mjs +1 -1
package/scripts/build.mjs
CHANGED
|
@@ -6,12 +6,15 @@
|
|
|
6
6
|
//
|
|
7
7
|
// node build.mjs <recipe.json|.chalk|.mmd|.md> [out.html] [--no-review]
|
|
8
8
|
// node build.mjs <one> <two> … --out course.html [--title "The course"] [--no-review]
|
|
9
|
+
// node build.mjs <recipe> [out.svg] --svg an SVG that draws itself, with no script: it plays inside an <img>,
|
|
10
|
+
// in a README on GitHub too (one SVG per lesson, named by its id)
|
|
9
11
|
//
|
|
10
|
-
// Only
|
|
11
|
-
// breaks the contract (nothing written); 2 bad arguments; 3 drawn, but the reviewer found something to fix (off
|
|
12
|
-
// paper, text over text, a line across a text). Needs Node 18 or later and
|
|
13
|
-
//
|
|
14
|
-
import { readFileSync, statSync, writeFileSync } from 'node:fs'
|
|
12
|
+
// Only paths ending in .html or .svg are ever written. Exit codes: 0 drawn and checked (or no browser to check with); 1 a
|
|
13
|
+
// recipe breaks the contract (nothing written); 2 bad arguments; 3 drawn, but the reviewer found something to fix (off
|
|
14
|
+
// the paper, text over text, a line across a text); 4 --svg with no browser to draw it in. Needs Node 18 or later and
|
|
15
|
+
// nothing else; the review and --svg use Chrome, Chromium or Edge.
|
|
16
|
+
import { mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'
|
|
17
|
+
import { tmpdir } from 'node:os'
|
|
15
18
|
import { basename, dirname, join, resolve } from 'node:path'
|
|
16
19
|
import { fileURLToPath } from 'node:url'
|
|
17
20
|
import { runPage } from './browser.mjs'
|
|
@@ -26,11 +29,13 @@ const option = (name) => {
|
|
|
26
29
|
const valued = new Set(['--out', '--title'])
|
|
27
30
|
const args = argv.filter((a, i) => !a.startsWith('--') && !valued.has(argv[i - 1]))
|
|
28
31
|
const noReview = argv.includes('--no-review')
|
|
32
|
+
const asSvg = argv.includes('--svg')
|
|
33
|
+
const ext = asSvg ? '.svg' : '.html'
|
|
29
34
|
const KINDS = ['.json', '.chalk', '.mmd', '.md']
|
|
30
35
|
const sources = args.filter((a) => KINDS.some((k) => a.endsWith(k)))
|
|
31
|
-
const outArg = option('--out') ?? args.find((a) => a.endsWith(
|
|
32
|
-
const usage = 'usage: node build.mjs <recipe.json> [out.html] [--no-review]\n node build.mjs <one.json> <two.json> … --out course.html [--title "…"] [--no-review]'
|
|
33
|
-
if (!sources.length || args.some((a) => !KINDS.some((k) => a.endsWith(k)) && !a.endsWith(
|
|
36
|
+
const outArg = option('--out') ?? args.find((a) => a.endsWith(ext))
|
|
37
|
+
const usage = 'usage: node build.mjs <recipe.json> [out.html] [--no-review]\n node build.mjs <one.json> <two.json> … --out course.html [--title "…"] [--no-review]\n node build.mjs <recipe.json> [out.svg] --svg'
|
|
38
|
+
if (!sources.length || args.some((a) => !KINDS.some((k) => a.endsWith(k)) && !a.endsWith(ext)) || (outArg && !outArg.endsWith(ext))) {
|
|
34
39
|
console.error(usage)
|
|
35
40
|
process.exit(2)
|
|
36
41
|
}
|
|
@@ -64,8 +69,11 @@ for (const file of sources) {
|
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
const course = scenes.length > 1
|
|
67
|
-
const
|
|
68
|
-
const
|
|
72
|
+
const slugOf = (scene, file) => String(scene.id || basename(file).replace(/\.[^.]+$/, '')).replace(/[^a-z0-9-]+/gi, '-').slice(0, 60) || 'drawing'
|
|
73
|
+
const slug = slugOf(scenes[0], sources[0])
|
|
74
|
+
// With --svg the page is only the browser's workbench: it goes to a folder of its own and away at the end.
|
|
75
|
+
const work = asSvg ? mkdtempSync(join(tmpdir(), 'chalk-talk-svg-')) : undefined
|
|
76
|
+
const out = work ? join(work, 'page.html') : resolve(outArg ?? join(dirname(resolve(sources[0])), `${slug}.html`))
|
|
69
77
|
const content = course ? { course: option('--title') ?? scenes[0].title, lessons: scenes } : scenes[0]
|
|
70
78
|
// JSON inside a <script> tag: "<" escaped so no text in a recipe can end the tag.
|
|
71
79
|
const recipe = JSON.stringify(content).replace(/</g, '\\u003c')
|
|
@@ -96,5 +104,28 @@ else {
|
|
|
96
104
|
}
|
|
97
105
|
}
|
|
98
106
|
}
|
|
99
|
-
|
|
107
|
+
if (!asSvg) {
|
|
108
|
+
console.log(`→ ${out} (${Math.round(statSync(out).size / 1024)} KB, opens offline${course ? `, ${scenes.length} lessons` : ''})`)
|
|
109
|
+
process.exit(code)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// --svg: each lesson drawn by the browser with its timing as CSS; one file, or one per lesson beside the first source.
|
|
113
|
+
const where = outArg && !course ? undefined : dirname(resolve(outArg ?? sources[0]))
|
|
114
|
+
for (let k = 0; k < scenes.length; k++) {
|
|
115
|
+
const r = runPage(out, 'svg', course ? `lesson=${k + 1}` : '')
|
|
116
|
+
if (!r) {
|
|
117
|
+
console.error('✗ svg no Chrome, Chromium or Edge here to draw it (set CHROME_PATH)')
|
|
118
|
+
code = 4
|
|
119
|
+
break
|
|
120
|
+
}
|
|
121
|
+
if (r.error) {
|
|
122
|
+
console.error(`✗ svg ${r.error}`)
|
|
123
|
+
code = 4
|
|
124
|
+
break
|
|
125
|
+
}
|
|
126
|
+
const file = where ? join(where, `${slugOf(scenes[k], sources[0])}.svg`) : resolve(outArg)
|
|
127
|
+
writeFileSync(file, r.svg)
|
|
128
|
+
console.log(`→ ${file} (${Math.round(statSync(file).size / 1024)} KB, draws itself in ${Math.round(r.ms / 1000)} s)`)
|
|
129
|
+
}
|
|
130
|
+
rmSync(work, { recursive: true, force: true })
|
|
100
131
|
process.exit(code)
|
package/scripts/contract.mjs
CHANGED
package/scripts/mermaid.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// GENERATED by tools/assets.mjs from the drawing engine v0.
|
|
1
|
+
// GENERATED by tools/assets.mjs from the drawing engine v0.244.0. Do not edit.
|
|
2
2
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
3
3
|
var OT=Object.create;var M1=Object.defineProperty;var BT=Object.getOwnPropertyDescriptor;var FT=Object.getOwnPropertyNames;var WT=Object.getPrototypeOf,HT=Object.prototype.hasOwnProperty;var PT=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,r)=>(typeof require<"u"?require:t)[r]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var Xe=(e,t)=>()=>(e&&(t=e(e=0)),t);var qt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),Bt=(e,t)=>{for(var r in t)M1(e,r,{get:t[r],enumerable:!0})},GT=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of FT(t))!HT.call(e,i)&&i!==r&&M1(e,i,{get:()=>t[i],enumerable:!(a=BT(t,i))||a.enumerable});return e};var Ua=(e,t,r)=>(r=e!=null?OT(WT(e)):{},GT(t||!e||!e.__esModule?M1(r,"default",{value:e,enumerable:!0}):r,e));var Yn=qt((PK,wy)=>{wy.exports={trueFunc:function(){return!0},falseFunc:function(){return!1}}});var rd=qt(Zi=>{"use strict";Object.defineProperty(Zi,"__esModule",{value:!0});Zi.AttributeAction=Zi.IgnoreCaseMode=Zi.SelectorType=void 0;var iI;(function(e){e.Attribute="attribute",e.Pseudo="pseudo",e.PseudoElement="pseudo-element",e.Tag="tag",e.Universal="universal",e.Adjacent="adjacent",e.Child="child",e.Descendant="descendant",e.Parent="parent",e.Sibling="sibling",e.ColumnCombinator="column-combinator"})(iI=Zi.SelectorType||(Zi.SelectorType={}));Zi.IgnoreCaseMode={Unknown:null,QuirksMode:"quirks",IgnoreCase:!0,CaseSensitive:!1};var sI;(function(e){e.Any="any",e.Element="element",e.End="end",e.Equals="equals",e.Exists="exists",e.Hyphen="hyphen",e.Not="not",e.Start="start"})(sI=Zi.AttributeAction||(Zi.AttributeAction={}))});var vy=qt(zo=>{"use strict";Object.defineProperty(zo,"__esModule",{value:!0});zo.parse=zo.isTraversal=void 0;var Yt=rd(),Sy=/^[^\\#]?(?:\\(?:[\da-f]{1,6}\s?|.)|[\w\-\u00b0-\uFFFF])+/,nI=/\\([\da-f]{1,6}\s?|(\s)|.)/gi,oI=new Map([[126,Yt.AttributeAction.Element],[94,Yt.AttributeAction.Start],[36,Yt.AttributeAction.End],[42,Yt.AttributeAction.Any],[33,Yt.AttributeAction.Not],[124,Yt.AttributeAction.Hyphen]]),lI=new Set(["has","not","matches","is","where","host","host-context"]);function Cy(e){switch(e.type){case Yt.SelectorType.Adjacent:case Yt.SelectorType.Child:case Yt.SelectorType.Descendant:case Yt.SelectorType.Parent:case Yt.SelectorType.Sibling:case Yt.SelectorType.ColumnCombinator:return!0;default:return!1}}zo.isTraversal=Cy;var uI=new Set(["contains","icontains"]);function cI(e,t,r){var a=parseInt(t,16)-65536;return a!==a||r?t:a<0?String.fromCharCode(a+65536):String.fromCharCode(a>>10|55296,a&1023|56320)}function vu(e){return e.replace(nI,cI)}function pg(e){return e===39||e===34}function Ey(e){return e===32||e===9||e===10||e===12||e===13}function hI(e){var t=[],r=My(t,"".concat(e),0);if(r<e.length)throw new Error("Unmatched selector: ".concat(e.slice(r)));return t}zo.parse=hI;function My(e,t,r){var a=[];function i(P){var F=t.slice(r+P).match(Sy);if(!F)throw new Error("Expected name, found ".concat(t.slice(r)));var I=F[0];return r+=P+I.length,vu(I)}function s(P){for(r+=P;r<t.length&&Ey(t.charCodeAt(r));)r++}function o(){r+=1;for(var P=r,F=1;F>0&&r<t.length;r++)t.charCodeAt(r)===40&&!n(r)?F++:t.charCodeAt(r)===41&&!n(r)&&F--;if(F)throw new Error("Parenthesis not matched");return vu(t.slice(P,r-1))}function n(P){for(var F=0;t.charCodeAt(--P)===92;)F++;return(F&1)===1}function l(){if(a.length>0&&Cy(a[a.length-1]))throw new Error("Did not expect successive traversals.")}function u(P){if(a.length>0&&a[a.length-1].type===Yt.SelectorType.Descendant){a[a.length-1].type=P;return}l(),a.push({type:P})}function c(P,F){a.push({type:Yt.SelectorType.Attribute,name:P,action:F,value:i(1),namespace:null,ignoreCase:"quirks"})}function f(){if(a.length&&a[a.length-1].type===Yt.SelectorType.Descendant&&a.pop(),a.length===0)throw new Error("Empty sub-selector");e.push(a)}if(s(0),t.length===r)return r;e:for(;r<t.length;){var h=t.charCodeAt(r);switch(h){case 32:case 9:case 10:case 12:case 13:{(a.length===0||a[0].type!==Yt.SelectorType.Descendant)&&(l(),a.push({type:Yt.SelectorType.Descendant})),s(1);break}case 62:{u(Yt.SelectorType.Child),s(1);break}case 60:{u(Yt.SelectorType.Parent),s(1);break}case 126:{u(Yt.SelectorType.Sibling),s(1);break}case 43:{u(Yt.SelectorType.Adjacent),s(1);break}case 46:{c("class",Yt.AttributeAction.Element);break}case 35:{c("id",Yt.AttributeAction.Equals);break}case 91:{s(1);var g=void 0,p=null;t.charCodeAt(r)===124?g=i(1):t.startsWith("*|",r)?(p="*",g=i(2)):(g=i(0),t.charCodeAt(r)===124&&t.charCodeAt(r+1)!==61&&(p=g,g=i(1))),s(0);var m=Yt.AttributeAction.Exists,x=oI.get(t.charCodeAt(r));if(x){if(m=x,t.charCodeAt(r+1)!==61)throw new Error("Expected `=`");s(2)}else t.charCodeAt(r)===61&&(m=Yt.AttributeAction.Equals,s(1));var y="",C=null;if(m!=="exists"){if(pg(t.charCodeAt(r))){for(var S=t.charCodeAt(r),R=r+1;R<t.length&&(t.charCodeAt(R)!==S||n(R));)R+=1;if(t.charCodeAt(R)!==S)throw new Error("Attribute value didn't end");y=vu(t.slice(r+1,R)),r=R+1}else{for(var N=r;r<t.length&&(!Ey(t.charCodeAt(r))&&t.charCodeAt(r)!==93||n(r));)r+=1;y=vu(t.slice(N,r))}s(0);var D=t.charCodeAt(r)|32;D===115?(C=!1,s(1)):D===105&&(C=!0,s(1))}if(t.charCodeAt(r)!==93)throw new Error("Attribute selector didn't terminate");r+=1;var O={type:Yt.SelectorType.Attribute,name:g,action:m,value:y,namespace:p,ignoreCase:C};a.push(O);break}case 58:{if(t.charCodeAt(r+1)===58){a.push({type:Yt.SelectorType.PseudoElement,name:i(2).toLowerCase(),data:t.charCodeAt(r)===40?o():null});continue}var H=i(1).toLowerCase(),U=null;if(t.charCodeAt(r)===40)if(lI.has(H)){if(pg(t.charCodeAt(r+1)))throw new Error("Pseudo-selector ".concat(H," cannot be quoted"));if(U=[],r=My(U,t,r+1),t.charCodeAt(r)!==41)throw new Error("Missing closing parenthesis in :".concat(H," (").concat(t,")"));r+=1}else{if(U=o(),uI.has(H)){var k=U.charCodeAt(0);k===U.charCodeAt(U.length-1)&&pg(k)&&(U=U.slice(1,-1))}U=vu(U)}a.push({type:Yt.SelectorType.Pseudo,name:H,data:U});break}case 44:{f(),a=[],s(1);break}default:{if(t.startsWith("/*",r)){var j=t.indexOf("*/",r+2);if(j<0)throw new Error("Comment was not terminated");r=j+2,a.length===0&&s(0);break}var p=null,X=void 0;if(h===42)r+=1,X="*";else if(h===124){if(X="",t.charCodeAt(r+1)===124){u(Yt.SelectorType.ColumnCombinator),s(2);break}}else if(Sy.test(t.slice(r)))X=i(0);else break e;t.charCodeAt(r)===124&&t.charCodeAt(r+1)!==124&&(p=X,t.charCodeAt(r+1)===42?(X="*",r+=2):X=i(1)),a.push(X==="*"?{type:Yt.SelectorType.Universal,namespace:p}:{type:Yt.SelectorType.Tag,name:X,namespace:p})}}}return f(),r}});var Ry=qt(Vo=>{"use strict";var ad=Vo&&Vo.__spreadArray||function(e,t,r){if(r||arguments.length===2)for(var a=0,i=t.length,s;a<i;a++)(s||!(a in t))&&(s||(s=Array.prototype.slice.call(t,0,a)),s[a]=t[a]);return e.concat(s||Array.prototype.slice.call(t))};Object.defineProperty(Vo,"__esModule",{value:!0});Vo.stringify=void 0;var mr=rd(),Ty=["\\",'"'],Iy=ad(ad([],Ty,!0),["(",")"],!1),dI=new Set(Ty.map(function(e){return e.charCodeAt(0)})),ky=new Set(Iy.map(function(e){return e.charCodeAt(0)})),Qo=new Set(ad(ad([],Iy,!0),["~","^","$","*","+","!","|",":","[","]"," ","."],!1).map(function(e){return e.charCodeAt(0)}));function Ny(e){return e.map(function(t){return t.map(fI).join("")}).join(", ")}Vo.stringify=Ny;function fI(e,t,r){switch(e.type){case mr.SelectorType.Child:return t===0?"> ":" > ";case mr.SelectorType.Parent:return t===0?"< ":" < ";case mr.SelectorType.Sibling:return t===0?"~ ":" ~ ";case mr.SelectorType.Adjacent:return t===0?"+ ":" + ";case mr.SelectorType.Descendant:return" ";case mr.SelectorType.ColumnCombinator:return t===0?"|| ":" || ";case mr.SelectorType.Universal:return e.namespace==="*"&&t+1<r.length&&"name"in r[t+1]?"":"".concat(Dy(e.namespace),"*");case mr.SelectorType.Tag:return $y(e);case mr.SelectorType.PseudoElement:return"::".concat(Ts(e.name,Qo)).concat(e.data===null?"":"(".concat(Ts(e.data,ky),")"));case mr.SelectorType.Pseudo:return":".concat(Ts(e.name,Qo)).concat(e.data===null?"":"(".concat(typeof e.data=="string"?Ts(e.data,ky):Ny(e.data),")"));case mr.SelectorType.Attribute:{if(e.name==="id"&&e.action===mr.AttributeAction.Equals&&e.ignoreCase==="quirks"&&!e.namespace)return"#".concat(Ts(e.value,Qo));if(e.name==="class"&&e.action===mr.AttributeAction.Element&&e.ignoreCase==="quirks"&&!e.namespace)return".".concat(Ts(e.value,Qo));var a=$y(e);return e.action===mr.AttributeAction.Exists?"[".concat(a,"]"):"[".concat(a).concat(pI(e.action),'="').concat(Ts(e.value,dI),'"').concat(e.ignoreCase===null?"":e.ignoreCase?" i":" s","]")}}}function pI(e){switch(e){case mr.AttributeAction.Equals:return"";case mr.AttributeAction.Element:return"~";case mr.AttributeAction.Start:return"^";case mr.AttributeAction.End:return"$";case mr.AttributeAction.Any:return"*";case mr.AttributeAction.Not:return"!";case mr.AttributeAction.Hyphen:return"|";case mr.AttributeAction.Exists:throw new Error("Shouldn't be here")}}function $y(e){return"".concat(Dy(e.namespace)).concat(Ts(e.name,Qo))}function Dy(e){return e!==null?"".concat(e==="*"?"*":Ts(e,Qo),"|"):""}function Ts(e,t){for(var r=0,a="",i=0;i<e.length;i++)t.has(e.charCodeAt(i))&&(a+="".concat(e.slice(r,i),"\\").concat(e.charAt(i)),r=i+1);return a.length>0?a+e.slice(r):e}});var ku=qt(qa=>{"use strict";var gI=qa&&qa.__createBinding||(Object.create?function(e,t,r,a){a===void 0&&(a=r);var i=Object.getOwnPropertyDescriptor(t,r);(!i||("get"in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,a,i)}:function(e,t,r,a){a===void 0&&(a=r),e[a]=t[r]}),mI=qa&&qa.__exportStar||function(e,t){for(var r in e)r!=="default"&&!Object.prototype.hasOwnProperty.call(t,r)&&gI(t,e,r)};Object.defineProperty(qa,"__esModule",{value:!0});qa.stringify=qa.parse=qa.isTraversal=void 0;mI(rd(),qa);var _y=vy();Object.defineProperty(qa,"isTraversal",{enumerable:!0,get:function(){return _y.isTraversal}});Object.defineProperty(qa,"parse",{enumerable:!0,get:function(){return _y.parse}});var AI=Ry();Object.defineProperty(qa,"stringify",{enumerable:!0,get:function(){return AI.stringify}})});var qg=qt(ux=>{var lx={};lx.StyleSheet=function(){this.parentStyleSheet=null};ux.StyleSheet=lx.StyleSheet});var $a=qt(cx=>{var wr={};wr.CSSRule=function(){this.parentRule=null,this.parentStyleSheet=null};wr.CSSRule.UNKNOWN_RULE=0;wr.CSSRule.STYLE_RULE=1;wr.CSSRule.CHARSET_RULE=2;wr.CSSRule.IMPORT_RULE=3;wr.CSSRule.MEDIA_RULE=4;wr.CSSRule.FONT_FACE_RULE=5;wr.CSSRule.PAGE_RULE=6;wr.CSSRule.KEYFRAMES_RULE=7;wr.CSSRule.KEYFRAME_RULE=8;wr.CSSRule.MARGIN_RULE=9;wr.CSSRule.NAMESPACE_RULE=10;wr.CSSRule.COUNTER_STYLE_RULE=11;wr.CSSRule.SUPPORTS_RULE=12;wr.CSSRule.DOCUMENT_RULE=13;wr.CSSRule.FONT_FEATURE_VALUES_RULE=14;wr.CSSRule.VIEWPORT_RULE=15;wr.CSSRule.REGION_STYLE_RULE=16;wr.CSSRule.prototype={constructor:wr.CSSRule};cx.CSSRule=wr.CSSRule});var Wu=qt(hx=>{var za={CSSStyleDeclaration:Qn().CSSStyleDeclaration,CSSRule:$a().CSSRule};za.CSSStyleRule=function(){za.CSSRule.call(this),this.selectorText="",this.style=new za.CSSStyleDeclaration,this.style.parentRule=this};za.CSSStyleRule.prototype=new za.CSSRule;za.CSSStyleRule.prototype.constructor=za.CSSStyleRule;za.CSSStyleRule.prototype.type=1;Object.defineProperty(za.CSSStyleRule.prototype,"cssText",{get:function(){var e;return this.selectorText?e=this.selectorText+" {"+this.style.cssText+"}":e="",e},set:function(e){var t=za.CSSStyleRule.parse(e);this.style=t.style,this.selectorText=t.selectorText}});za.CSSStyleRule.parse=function(e){for(var t=0,r="selector",a,i=t,s="",o={selector:!0,value:!0},n=new za.CSSStyleRule,l,u="",c;c=e.charAt(t);t++)switch(c){case" ":case" ":case"\r":case`
|
|
4
4
|
`:case"\f":if(o[r])switch(e.charAt(t-1)){case" ":case" ":case"\r":case`
|