hyperbook 0.95.0 → 0.96.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.
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var PythonFriendlyErrorMessages=(()=>{var $=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var q=Object.prototype.hasOwnProperty;var U=(e,t)=>{for(var s in t)$(e,s,{get:t[s],enumerable:!0})},F=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let l of P(t))!q.call(e,l)&&l!==s&&$(e,l,{get:()=>t[l],enumerable:!(n=I(t,l))||n.enumerable});return e};var B=e=>F($({},"__esModule",{value:!0}),e);var K={};U(K,{friendlyExplain:()=>z,loadCopydeck:()=>E,loadCopydeckFor:()=>H,pyodideAdapter:()=>N,registerAdapter:()=>M,skulptAdapter:()=>R});var v=e=>e.replace(/[&<>"']/g,t=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[t]),w=(e,t)=>(e||"").replace(/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g,(s,n)=>n in t?String(t[n]):""),k=(e,t)=>{try{return new RegExp(e,"i").test(t||"")}catch{return!1}},b={adapters:{}},E=e=>b.copy=e,p=(e,t)=>b.copy?.ui?.[e]||t,M=(e,t)=>b.adapters[e]=t,O=(e,t,s)=>{if(e.raw!==void 0)return e;if(!s)throw new Error("Runtime is required when error is a string or Error. Pass opts.runtime or parse with an adapter first.");const n=b.adapters[s];if(!n)throw new Error(`No adapter registered for runtime "${s}".`);const l=typeof e=="string"?e:String(e.stack||e.message||e),a=n(l,t);if(!a)throw new Error(`Could not parse error for runtime "${s}".`);return a},j=(e,t)=>{const s=b.copy,n=e.type&&s?.errors[e.type]?e.type:"Other",l=s?.errors[n];if(!l)return null;const a=e.codeLine||"",d=e.message||"",i=o=>{const r=o.if;return r?!(r.match_message?.some(c=>k(c,d))===!1&&r.match_message?.length||r.not_message?.some(c=>k(c,d))||r.match_code?.some(c=>k(c,a))===!1&&r.match_code?.length||r.not_code?.some(c=>k(c,a))):!0},m=p("line","line"),u=p("in","in"),f=p("thisFile","this file"),h={loc:e.line&&e.file?`${m} ${e.line} ${u} ${e.file}`:e.line?`${m} ${e.line}`:e.file||f,name:e.name||"",codeLine:a};for(let o=0;o<l.variants.length;o++){const r=l.variants[o];if(!i(r))continue;const c=w(r.title,h),L=w(r.summary,h),x=r.why?w(r.why,h):void 0,_=r.steps?.map(g=>w(g,h)),C=r.badges;let y;if(e.type==="AttributeError"&&/\.push\s*\(/i.test(a))y=a.replace(/\.push\s*\(/i,".append(");else if(e.type==="NameError"&&e.name)y=`${e.name} = 0
|
|
2
|
+
${a}`;else if(e.type==="SyntaxError"&&/^(if|for|while|def|class|elif|else|try|except|with)\b/i.test(a)&&!/:$/.test(a.trim())){const g=a.replace(/\s*$/,"");y=/,\s*$/.test(g)?g.replace(/,\s*$/,":"):g+":"}else e.type==="TypeError"&&/\+\s*[A-Za-z_][A-Za-z0-9_]*/.test(a)&&(y=a.replace(/\+\s*([A-Za-z_][A-Za-z0-9_]*)/,"+ str($1)"));const S=[`<div class="pfem__title">${v(c)}</div>`,`<div class="pfem__summary">${L}</div>`,x?`<div class="pfem__why">${x}</div>`:"",_?.length?`<ul class="pfem__steps">${_.map(g=>`<li>${g}</li>`).join("")}</ul>`:"",y?`<pre class="pfem__patch">${v(y)}</pre>`:"",`<details class="pfem__details"><summary>${v(p("originalError","Original error"))}</summary><pre>${v((e.type||p("error","Error"))+": "+e.message)}</pre></details>`].filter(Boolean).join(`
|
|
3
|
+
`);return{variantId:`${n}/variants/${o}`,title:c,summary:L,why:x,steps:_,badges:C,patch:y,html:S}}return null},z=e=>{if(!b.copy)throw new Error("Copydeck not loaded");const t=e.code,s=O(e.error,t,e.runtime);if(t&&s.line&&!s.codeLine){const l=t.split(/\r?\n/);s.codeLine=l[s.line-1]?.trim()}const n=j(s,t);return n?{trace:s,...n}:{trace:s,variantId:"Other/variants/0",title:p("pythonError","Python error"),summary:p("fallbackSummary","Start with the last line of the trace (message) and the highlighted code line."),why:p("fallbackWhy","The last line of the trace tells you the error type and main cause."),steps:[p("fallbackStep","Try a fix and run again.")],html:void 0}},Y=e=>{const t=e.trim().split(/\r?\n/).filter(Boolean),s=t[t.length-1]||"",n=s.match(/^(\w+Error)\s*:\s*(.*)$/);return{type:n?n[1]:null,message:n?n[2]:s,tail:s,lines:t}},R=(e,t)=>{const{type:s,message:n,tail:l,lines:a}=Y(e);let d,i,m;for(const o of a){const r=o.match(/File\s+"([^"]+)",\s+line\s+(\d+)/i);r&&(d=r[1],i=parseInt(r[2],10))}if(!i){const o=l.match(/\b(?:on|at)\s+line\s+(\d+)\s+(?:of|in)\s+([^\s:]+)\b/i);o&&(i=parseInt(o[1],10),d=o[2])}let u;const f=(n||"").match(/["']([^"']+)["']/);if(f&&(u=f[1]),!!!(s||i||u))return null;const h={type:s,message:n,raw:e,file:d,line:i,col:m,frames:[],name:u,runtime:"skulpt"};if(t&&i){const o=t.split(/\r?\n/);h.codeLine=o[i-1]?.trim(),h.codeBefore=o.slice(Math.max(0,i-3),i-1),h.codeAfter=o.slice(i,i+2)}return h},Z=e=>{const t=e.trim().split(/\r?\n/).filter(Boolean),s=t[t.length-1]||"",n=s.match(/^(\w+Error)\s*:\s*(.*)$/);return{type:n?n[1]:null,message:n?n[2]:s,tail:s,lines:t}},N=(e,t)=>{const{type:s,message:n,tail:l,lines:a}=Z(e);let d,i,m;for(const o of a){const r=o.match(/File\s+"([^"]+)",\s+line\s+(\d+)/i);r&&(d=r[1],i=parseInt(r[2],10));const c=o.match(/column\s+(\d+)/i);c&&(m=parseInt(c[1],10))}let u;const f=(n||"").match(/["']([^"']+)["']/);if(f&&(u=f[1]),!!!(s||i||u))return null;const h={type:s,message:n,raw:e,file:d,line:i,col:m,frames:[],name:u,runtime:"pyodide"};if(t&&i){const o=t.split(/\r?\n/);h.codeLine=o[i-1]?.trim(),h.codeBefore=o.slice(Math.max(0,i-3),i-1),h.codeAfter=o.slice(i,i+2)}return h},W={meta:{language:"en",version:1},ui:{line:"line",in:"in",thisFile:"this file",originalError:"Original error",error:"Error",copydeckNotLoaded:"Copydeck not loaded",pythonError:"Python error",fallbackSummary:"Start with the last line of the trace (message) and the highlighted code line.",fallbackWhy:"The last line of the trace tells you the error type and main cause.",fallbackStep:"Try a fix and run again."},errors:{NameError:{variants:[{if:{not_message:["is not defined"]},title:"This variable doesn't exist yet",summary:`Your code uses the variable "{{name}}", but it hasn't been created yet. Check {{loc}}. If you meant to print the text <i>{{name}}</i>, put it in double quotes.`,why:"Without speech marks Python treats <i>{{name}}</i> as a variable, and this variable does not exist yet.",steps:["If it is meant to be text, put speech marks around {{name}}.","If it is meant to be a variable, make it first (for example: {{name}} = 0).","Check spelling and capital letters."]},{if:{match_message:["is not defined"]},title:"This variable doesn't exist here",summary:`"{{name}}" might be created somewhere else, but you're using it at {{loc}}. If you meant the text <i>{{name}}</i>, put it in double quotes.`,why:"A variable created in another place might not be available here.",steps:["Move the line that makes it to above where you use it.","Or set it here just before you use it."]}]},UnboundLocalError:{variants:[{title:"Variable used before it gets a value in this part of the code",summary:'Here, "{{name}}" is used at {{loc}} before you give it a value.',why:"You have used the variable before it has been given a value. If used within a subroutine, the variable must either be global and given a value outside the subroutine definition, or local and given a value inside the subroutine, before it is used. ",steps:["Give it a value first (add a line like {{name}} = ... before you use it)."]}]},SyntaxError:{variants:[{if:{match_code:["^(\\s*)(if|for|while|def|class|elif|else|try|except|with)\\b"],not_code:[":\\s*$",",\\s*$"]},title:"Missing colon (:) at the end",summary:"There is a colon (:) missing at the end of a line. Check {{loc}}: {{codeLine}}",why:"In Python constructs like if statements, for loops and while loops must have a colon at the end of their first line.",steps:["Add a colon (:) at the end of that line."]},{if:{match_code:["^(\\s*)(if|for|while|def|class|elif|else|try|except|with)\\b.*?,\\s*$"]},title:"Comma used where a colon is needed",summary:"This line ends with a comma, but this kind of Python line should end with a colon (:). Check {{loc}}: {{codeLine}}",why:"Lines that start a block (like if or for) need a colon, not a comma.",steps:["Replace the comma with a colon (:)."]},{if:{match_code:["^(\\s*)(if|for|while|def|class|elif|else|try|except|with)\\b.*::\\s*$"]},title:"Too many colons at the end",summary:"This line ends with more than one colon. Check {{loc}}: {{codeLine}}",why:"A block-starting line needs exactly one colon at the end.",steps:["Leave only one colon (:) at the end of the line."]},{if:{match_message:["was never closed"]},title:"A bracket or parenthesis was not closed",summary:"One of your brackets, braces, or parentheses is open but never closes.",why:"Python needs every opening symbol like (, [ or { to have a matching closing symbol.",steps:["Find the opening symbol that has no matching closing symbol.","Add the missing closing symbol.","Check nearby lines as the opening symbol may be earlier."]},{if:{match_message:["does not match","closing parenthesis","closing bracket","closing brace"]},title:"Closing bracket does not match the opening one",summary:"A closing symbol was used, but it does not match the opening symbol.",why:"Each opening symbol must be closed by the same kind: () [] or {}.",steps:["Find the opening symbol first.","Change the closing symbol so it matches.","Check that symbols are in the correct order."]},{if:{match_message:["unterminated string literal","EOL while scanning string literal"]},title:"A string was started but not finished",summary:"A string opens with a quote mark but does not close.",why:"Text in Python must have matching opening and closing quotes.",steps:["Find the string that starts but does not end.","Add the missing quote mark.","Use matching quote marks around the text."]},{if:{match_message:["perhaps you forgot a comma"]},title:"A comma is missing between items",summary:"Python expected a comma between values, but did not find one.",why:"Lists, dictionaries, tuples, and function arguments need commas to separate each item.",steps:["Check where two values are next to each other.","Add a comma between each separate item.","Run the code again to check for the next issue."]},{if:{match_message:["cannot assign to"],match_code:["^(\\s*)(if|elif|while)\\b.*="],not_code:["==","<=",">=","!="]},title:"Assignment used instead of comparison",summary:"This condition uses =, but conditions must compare values. Check {{loc}}: {{codeLine}}",why:"In conditions, = sets a value, but == compares values.",steps:["Use == to compare values in if, elif, or while conditions.","Keep = for setting a variable value outside comparisons."]},{if:{match_message:["unexpected EOF while parsing","incomplete input"]},title:"Python reached the end before the code was complete",summary:"Python got to the end of the file, but something was still unfinished.",why:"A line or block was started but not completed, such as a bracket, quote, or block body.",steps:["Check the final lines of your code first.","Look for missing closing brackets, quotes, or colons.","Make sure every started block has code inside it."]},{if:{match_code:["\\+\\+|--"]},title:"This operator is not valid in Python",summary:"This line contains ++ or --, which Python does not use.",why:"Python does not have increment/decrement operators like some other languages.",steps:["Use += 1 to increase a value by one.","Use -= 1 to decrease a value by one."]},{title:"The line is incomplete or mismatched",summary:"Something is missing or extra - like a colon, bracket, or quote.",why:"If (), [], {}, :, or quotes don't match, Python can't read the line.",steps:["Make (), [], and {} come in matching pairs.","Add the missing colon (:).","Use matching opening and closing quotes."]}]},IndentationError:{variants:[{title:"The indentation doesn't match",summary:"All lines in a block must start in the same column. Fix around {{loc}}.",why:"Python groups code by indentation. Mixing tabs and spaces or uneven indents breaks the block.",steps:["Use 4 spaces per level (not tabs).","Line up all lines in the block."]}]},TypeError:{variants:[{title:"These data types don't work together",summary:"You're joining (concatenating) different kinds of data types. For example, a number (integer or float) and a word (string).",why:"When using + to join text and variables together the variable must have a string data type.",steps:["Cast the variable as a string data type.",'Change the variable to the right kind: int("3") or str(7).']}]},AttributeError:{variants:[{if:{match_code:["\\.push\\s*\\("],match_message:["'push'"]},title:"Lists don't have that feature",summary:"You're calling a list method that doesn't exist.",why:"Lists use .append(value) or .extend([...]). There is no .push().",steps:["Use list.append(one_item).","Use list.extend([many, items])."]},{title:"This thing doesn't have that name after the dot",summary:"The thing you're using doesn't have that attribute or method.",why:"That kind of thing doesn't provide this feature.",steps:["Check the spelling after the dot.","Use a name that exists for this kind of thing."]}]},IndexError:{variants:[{title:"This index position does not exist",summary:"You are trying to use an index position that does not exist. The list is not that long.",why:'In this list: myList["A", "B", "C"] "A" has the index position 0, "B" has the index position 1 and "C" has the index position 2. Index position 3 does not exist.',steps:["Check the length with len(the_list).","Use an index position number smaller than len(the_list)."]}]},KeyError:{variants:[{title:"That key isn't in the dictionary",summary:"You looked up a key that the dictionary doesn't have.",why:"The dictionary has no value for that key.",steps:["Check the exact key (spelling and capital letters).","It might be missing, use dictionary.get(key, default) or add the key."]}]},ZeroDivisionError:{variants:[{title:"You can't divide by zero",summary:"You are trying to divide a number by zero, which is not possible.",why:"In mathematics, division by zero is undefined.",steps:["Change the calculation so that you are not dividing a number by 0."]}]},Other:{variants:[{title:"Python error",summary:"Start with the last line of the message and the highlighted code line.",why:"The last line of the traceback tells you the error type and main cause.",steps:["Fix one small thing and run again."]}]}}},A={en:W};async function H(e="en",t={}){const s=[e],n=e.split("-")[0];n!==e&&s.push(n),s.includes("en")||s.push("en");for(const l of s)if(A[l]){const a=A[l];return E(a),a}if(t.base){const l=new URL(t.base,window.location.origin);for(const a of s)try{const d=new URL(`${a}/copydeck.json`,l).toString(),i=await fetch(d);if(i.ok){const m=await i.json();return E(m),m}}catch{}}throw new Error(`No copydeck found for ${s.join(", ")}`)}return B(K);})();
|
|
@@ -54,6 +54,67 @@
|
|
|
54
54
|
color: #b42318;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
.directive-pyide .output .pfem {
|
|
58
|
+
font-family: inherit;
|
|
59
|
+
font-size: 0.9em;
|
|
60
|
+
line-height: 1.5;
|
|
61
|
+
padding: 8px 12px;
|
|
62
|
+
border-left: 3px solid #b42318;
|
|
63
|
+
background: color-mix(in srgb, #b42318 8%, transparent);
|
|
64
|
+
border-radius: 0 4px 4px 0;
|
|
65
|
+
white-space: normal;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.directive-pyide .output .pfem-title {
|
|
69
|
+
font-weight: bold;
|
|
70
|
+
color: #b42318;
|
|
71
|
+
margin-bottom: 4px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.directive-pyide .output .pfem-summary {
|
|
75
|
+
margin-bottom: 4px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.directive-pyide .output .pfem-why {
|
|
79
|
+
color: var(--color-text, #555);
|
|
80
|
+
font-style: italic;
|
|
81
|
+
margin-bottom: 4px;
|
|
82
|
+
opacity: 0.8;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.directive-pyide .output .pfem-steps {
|
|
86
|
+
margin: 4px 0 4px 18px;
|
|
87
|
+
padding: 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.directive-pyide .output .pfem-steps li {
|
|
91
|
+
margin: 2px 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.directive-pyide .output .pfem-details {
|
|
95
|
+
margin-top: 6px;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.directive-pyide .output .pfem-details > summary {
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
opacity: 0.6;
|
|
101
|
+
font-size: 0.85em;
|
|
102
|
+
user-select: none;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.directive-pyide .output .pfem-details > summary:hover {
|
|
106
|
+
opacity: 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.directive-pyide .output .pfem-details pre {
|
|
110
|
+
margin: 4px 0 0;
|
|
111
|
+
font-family: hyperbook-monospace, monospace;
|
|
112
|
+
font-size: 0.85em;
|
|
113
|
+
white-space: pre-wrap;
|
|
114
|
+
color: #b42318;
|
|
115
|
+
opacity: 0.85;
|
|
116
|
+
}
|
|
117
|
+
|
|
57
118
|
.directive-pyide .canvas-wrapper {
|
|
58
119
|
overflow: auto;
|
|
59
120
|
height: 100%;
|
|
@@ -61,6 +122,13 @@
|
|
|
61
122
|
border-radius: 8px;
|
|
62
123
|
border-top-left-radius: 0;
|
|
63
124
|
border-top-right-radius: 0;
|
|
125
|
+
background-color: #e8e8e8;
|
|
126
|
+
background-image: linear-gradient(45deg, #cccccc 25%, transparent 25%),
|
|
127
|
+
linear-gradient(-45deg, #cccccc 25%, transparent 25%),
|
|
128
|
+
linear-gradient(45deg, transparent 75%, #cccccc 75%),
|
|
129
|
+
linear-gradient(-45deg, transparent 75%, #cccccc 75%);
|
|
130
|
+
background-size: 20px 20px;
|
|
131
|
+
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
|
64
132
|
}
|
|
65
133
|
|
|
66
134
|
.directive-pyide .canvas {
|
package/dist/index.js
CHANGED
|
@@ -195661,7 +195661,7 @@ var remarkDirectivePyide_default = (ctx) => () => {
|
|
|
195661
195661
|
const hasCanvas = "canvas" in (node3.attributes || {});
|
|
195662
195662
|
const packageList = parsePackagesAttribute(packages);
|
|
195663
195663
|
expectContainerDirective(node3, file, name);
|
|
195664
|
-
registerDirective(file, name, ["client.js"], ["style.css"], []);
|
|
195664
|
+
registerDirective(file, name, ["python-friendly-error-messages.js", "client.js"], ["style.css"], []);
|
|
195665
195665
|
requestJS(file, ["codemirror", "codemirror.bundle.js"]);
|
|
195666
195666
|
let srcFile = "";
|
|
195667
195667
|
let tests = [];
|
|
@@ -202119,7 +202119,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"application/1d-interleaved-parityfec
|
|
|
202119
202119
|
/***/ ((module) => {
|
|
202120
202120
|
|
|
202121
202121
|
"use strict";
|
|
202122
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"hyperbook","version":"0.
|
|
202122
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"hyperbook","version":"0.96.0","author":"Mike Barkmin","homepage":"https://github.com/openpatch/hyperbook#readme","license":"MIT","bin":{"hyperbook":"./dist/index.js"},"files":["dist"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/openpatch/hyperbook.git","directory":"packages/hyperbook"},"bugs":{"url":"https://github.com/openpatch/hyperbook/issues"},"engines":{"node":">=18"},"scripts":{"version":"pnpm build","lint":"tsc --noEmit","dev":"ncc build ./index.ts -w -o dist/","build":"rimraf dist && ncc build ./index.ts -o ./dist/ --no-cache --no-source-map-register --external favicons --external sharp && node postbuild.mjs"},"dependencies":{"favicons":"^7.2.0"},"devDependencies":{"create-hyperbook":"workspace:*","@hyperbook/fs":"workspace:*","@hyperbook/markdown":"workspace:*","@hyperbook/types":"workspace:*","@pnpm/exportable-manifest":"1000.0.6","@types/archiver":"6.0.3","@types/async-retry":"1.4.9","@types/cross-spawn":"6.0.6","@types/lunr":"^2.3.7","@types/prompts":"2.4.9","@types/tar":"6.1.13","@types/ws":"^8.5.14","@vercel/ncc":"0.38.3","archiver":"7.0.1","async-retry":"1.3.3","chalk":"5.4.1","chokidar":"4.0.3","commander":"12.1.0","cpy":"11.1.0","cross-spawn":"7.0.6","domutils":"^3.2.2","extract-zip":"^2.0.1","got":"12.6.0","htmlparser2":"^10.0.0","lunr":"^2.3.9","lunr-languages":"^1.14.0","mime":"^4.0.6","prompts":"2.4.2","rimraf":"6.0.1","tar":"7.4.3","update-check":"1.5.4","ws":"^8.18.0"}}');
|
|
202123
202123
|
|
|
202124
202124
|
/***/ })
|
|
202125
202125
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyperbook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.96.0",
|
|
4
4
|
"author": "Mike Barkmin",
|
|
5
5
|
"homepage": "https://github.com/openpatch/hyperbook#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"ws": "^8.18.0",
|
|
59
59
|
"create-hyperbook": "0.3.6",
|
|
60
60
|
"@hyperbook/fs": "0.25.0",
|
|
61
|
-
"@hyperbook/
|
|
62
|
-
"@hyperbook/
|
|
61
|
+
"@hyperbook/markdown": "0.67.0",
|
|
62
|
+
"@hyperbook/types": "0.23.0"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"version": "pnpm build",
|