diff --git a/_includes/machine-engines.html b/_includes/machine-engines.html index c55626f5b..a299df49c 100644 --- a/_includes/machine-engines.html +++ b/_includes/machine-engines.html @@ -34,5 +34,5 @@ {% capture machine_template %}{{ site.baseurl }}/modules/{{ machine.type | remove:'-dbg' }}js/templates/components.xsl{% endcapture %} {% endif %} {% endif %} - + {% endfor %} diff --git a/disks/pc/os2/misc/1.0/debugger/README.md b/disks/pc/os2/misc/1.0/debugger/README.md index 815f02d8b..9d4bb0e13 100644 --- a/disks/pc/os2/misc/1.0/debugger/README.md +++ b/disks/pc/os2/misc/1.0/debugger/README.md @@ -7,9 +7,9 @@ machines: type: pc-dbg config: /devices/pc/machine/5170/ega/1152kb/rev3/machine.xml automount: - A: - name: OS/2 1.0 Debugger Boot Disk - path: /disks/pc/os2/misc/1.0/debugger/OS210-BOOT.json + A: + name: OS/2 1.0 Debugger Boot Disk + path: /disks/pc/os2/misc/1.0/debugger/OS210-BOOT.json --- OS/2 1.0 Debugger Boot Disk diff --git a/disks/pc/os2/misc/football/debugger/README.md b/disks/pc/os2/misc/football/debugger/README.md index ac90ebd66..8d8eb20de 100644 --- a/disks/pc/os2/misc/football/debugger/README.md +++ b/disks/pc/os2/misc/football/debugger/README.md @@ -7,9 +7,9 @@ machines: type: pc-dbg config: /devices/pc/machine/compaq/deskpro386/ega/2048kb/machine.xml automount: - A: - name: OS/2 FOOTBALL Boot Disk (v7.68.17) - path: /disks/pc/os2/misc/football/debugger/FOOTBALL-7.68.17.json + A: + name: OS/2 FOOTBALL Boot Disk (v7.68.17) + path: /disks/pc/os2/misc/football/debugger/FOOTBALL-7.68.17.json --- OS/2 FOOTBALL Boot Disk (v7.68.17) diff --git a/docs/pcjs/demos/pc-dbg.js b/docs/pcjs/demos/pc-dbg.js index 7282a30f3..a5bc3284b 100644 --- a/docs/pcjs/demos/pc-dbg.js +++ b/docs/pcjs/demos/pc-dbg.js @@ -1210,7 +1210,7 @@ function kr(a,b){a.A=null;var c=za(Aa()+"/api/v1/user?req=verify&user="+b),d=c[1 function jr(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=Xq(a,er);d.data=c;b=za(Aa()+"/api/v1/user",!1,d);d=b[1];if(b[0]){if(d){var e=d.indexOf("\n");0k.indexOf("/")&&(k=window.location.pathname+k);d?"{"==d.substr(0,1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(k?' url="'+k+'"':""))}k=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(k=new window.ActiveXObject("Microsoft.XMLDOM"), +function nr(a,b,c,d,e,f,g){function k(a,f){if(f)g(f,null);else{if(c){var k=b;k&&0>k.indexOf("/")&&(k=window.location.pathname+k);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(k?' url="'+k+'"':""))}k=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(k=new window.ActiveXObject("Microsoft.XMLDOM"), k.async=!1,k.loadXML(a)):k=(new window.DOMParser).parseFromString(a,"text/xml")}catch(B){k=null,a=B.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");za(e,!0,null,null,function(f,g,k){if(k||!g)c(a,"unable to resolve XML reference: "+d[0]+" ("+k+")");else{if(f=d[3])if(k=g.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var q=k[0],r,x=/( [a-z]+=)(['"])(.*?)\2/g;r=x.exec(f);)q=0>q.indexOf(r[1])?q.replace(">",r[0]+">"):q.replace(new RegExp(r[1]+"(['\"])(.*?)\\1"),r[0]);k[0]!=q&&(g=g.replace(k[0],q))}else{c(a,"missing <"+d[1]+"> in "+e);return}g=g.replace(/<\?xml[^>]*>[\r\n]*/, "");a=a.replace(d[0],g);yr(a,b,c)}})}else c(a,null)} diff --git a/docs/pcjs/demos/pc.js b/docs/pcjs/demos/pc.js index 4611562bc..eab14bf5b 100644 --- a/docs/pcjs/demos/pc.js +++ b/docs/pcjs/demos/pc.js @@ -1033,7 +1033,7 @@ function Om(a,b){a.B=null;var c=pa(qa()+"/api/v1/user?req=verify&user="+b),d=c[1 function Nm(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=zm(a,Hm);d.data=c;b=pa(qa()+"/api/v1/user",!1,d);d=b[1];if(b[0]){if(d){var e=d.indexOf("\n");0p.indexOf("/")&&(p=window.location.pathname+p);d?"{"==d.substr(0,1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(p?' url="'+p+'"':""))}p=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(p=new window.ActiveXObject("Microsoft.XMLDOM"), +function Rm(a,b,c,d,e,k,l){function p(a,k){if(k)l(k,null);else{if(c){var p=b;p&&0>p.indexOf("/")&&(p=window.location.pathname+p);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(p?' url="'+p+'"':""))}p=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(p=new window.ActiveXObject("Microsoft.XMLDOM"), p.async=!1,p.loadXML(a)):p=(new window.DOMParser).parseFromString(a,"text/xml")}catch(G){p=null,a=G.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");pa(e,!0,null,null,function(k,l,p){if(p||!l)c(a,"unable to resolve XML reference: "+d[0]+" ("+p+")");else{if(k=d[3])if(p=l.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var q=p[0],w,B=/( [a-z]+=)(['"])(.*?)\2/g;w=B.exec(k);)q=0>q.indexOf(w[1])?q.replace(">",w[0]+">"):q.replace(new RegExp(w[1]+"(['\"])(.*?)\\1"),w[0]);p[0]!=q&&(l=l.replace(p[0],q))}else{c(a,"missing <"+d[1]+"> in "+e);return}l=l.replace(/<\?xml[^>]*>[\r\n]*/, "");a=a.replace(d[0],l);Sm(a,b,c)}})}else c(a,null)} diff --git a/modules/htmlout/lib/htmlout.js b/modules/htmlout/lib/htmlout.js index 18a8aea4d..c2c5cfbc6 100644 --- a/modules/htmlout/lib/htmlout.js +++ b/modules/htmlout/lib/htmlout.js @@ -1850,7 +1850,10 @@ HTMLOut.prototype.processMachines = function(aMachines, done) var sScriptEmbed = ""; if (infoMachine['func']) { - sScriptEmbed = ''; + sScriptEmbed = ''; } var asFiles = []; diff --git a/modules/markout/lib/markout.js b/modules/markout/lib/markout.js index 446a9685e..bb8a851b7 100644 --- a/modules/markout/lib/markout.js +++ b/modules/markout/lib/markout.js @@ -231,14 +231,14 @@ MarkOut.setOptions = function(options) * The infoMachine object should contain, at a minimum: * * { - * 'class': sMachineClass, // eg, "pc" - * 'func': sMachineFunc, - * 'id': sMachineID, - * 'xml': sMachineXMLFile, - * 'xsl': sMachineXSLFile, - * 'version': sMachineVersion, // eg, "1.13.0" + * 'class': sMachineClass, // eg, "pc" + * 'func': sMachineFunc, + * 'id': sMachineID, + * 'xml': sMachineXMLFile, + * 'xsl': sMachineXSLFile, + * 'version': sMachineVersion,// eg, "1.13.0" * 'debugger': fDebugger, // eg, false - * 'state': sMachineState + * 'parms': sMachineParms * } * * This is an internal function, used by convertMDMachineLinks() to record all the machines defined @@ -375,16 +375,54 @@ MarkOut.prototype.convertMD = function(sIndent) for (var iMachine = 0; iMachine < asMachines.length; iMachine++) { if (!asMachines[iMachine]) continue; var id = null; - var aOptions, machine = {}; - var reOption = /([^\s]+):\s*([^\n]*)/g; + var aOptions, aaOptions = [], machine = {}; + var reOption = /([ \t]*)([^\s]+):[ \t]*([^\n]*)/g; while (aOptions = reOption.exec(asMachines[iMachine])) { - if (!id && aOptions[1] == "id") { - id = aOptions[2]; - } - else { - machine[aOptions[1]] = aOptions[2]; - } + aaOptions.push(aOptions); } + for (var iOption = 0; iOption < aaOptions.length; iOption++) { + var aOptions = aaOptions[iOption]; + var sSpace = aOptions[1], sName = aOptions[2], sValue = aOptions[3]; + if (!id && sName == 'id') { + id = sValue; + } else if (sName == 'automount') { + /* + * I take a simplistic approach to parsing the object definition associated with "automount", + * because I know it only consist of 1 or more drive letters, each of which may be followed by + * 1 or 2 additional properties (eg, "name" and "path"). If we need to support other JSON + * object definitions in the future, this will have to be generalized. + * + * Here's an example of "automount" output: + * + * {"A":{"name":"OS/2 FOOTBALL Boot Disk (v7.68.17)","path":"/disks/pc/os2/misc/football/debugger/FOOTBALL-7.68.17.json"}} + */ + sValue = '{'; + var cDrives = 0, cProps = 0, iProp; + for (iProp = iOption + 1; iProp < aaOptions.length; iProp++) { + var sPropSpace = aaOptions[iProp][1]; + if (sPropSpace.length <= sSpace.length) break; + var sPropName = aaOptions[iProp][2]; + var sPropValue = aaOptions[iProp][3]; + if (!sPropValue) { + if (cProps) sValue += '}'; + if (cDrives++) sValue += ','; + sValue += '"' + sPropName + '":{'; + cProps = 0; + } else { + if (cProps++) sValue += ','; + sValue += '"' + sPropName + '":"' + sPropValue + '"'; + } + } + if (cProps++) sValue += '}'; + sValue += '}'; + iOption = iProp - 1; + } + machine[sName] = sValue; + } + /* + * Any 'state' and 'automount' properties must now be merged into a 'parms' property. + */ + machine['parms'] = '{state:"' + (machine['state'] || "") + '",autoMount:' + machine['automount'] + '}'; if (id) this.aMachineDefs[id] = machine; } } @@ -952,7 +990,7 @@ MarkOut.prototype.convertMDImageLinks = function(sBlock, sIndent) * Before we call convertMDLinks() to process any normal Markdown-style links, we first look for our own * special flavor of "machine" Markdown links; ie: * - * [IBM PC](/devices/pc/machine/5150/mda/64kb/ "PCjs:demoPC:stylesheet:version:options:state") + * [IBM PC](/devices/pc/machine/5150/mda/64kb/ "PCjs:demoPC:stylesheet:version:options:parms") * * where a special title attribute triggers generation of an embedded machine rather than a link. * @@ -965,6 +1003,11 @@ MarkOut.prototype.convertMDImageLinks = function(sBlock, sIndent) * * If the link ends with a slash, then it's an implied reference to a "machine.xml". * + * UPDATE: Since parms containing JSON may also contain colons, machine Markdown links may now use '|' + * instead of ':' as separators; eg: + * + * [IBM PC](/devices/pc/machine/5150/mda/64kb/ "PCjs|demoPC|stylesheet|version|options|parms") + * * Granted, there are a number of things we could be smarter about. First, you probably don't care about the * ID for the
; it's purely a mechanism for telling the script where to embed the machine, so we could * auto-generate an ID for you, but on the other hand, there might actually be situations where you want to style @@ -989,7 +1032,7 @@ MarkOut.prototype.convertMDImageLinks = function(sBlock, sIndent) MarkOut.prototype.convertMDMachineLinks = function(sBlock) { var aMatch, sReplacement; - var sMachine, sMachineID, sMachineXMLFile, sMachineXSLFile, sMachineVersion, sMachineOptions, sMachineState; + var sMachine, sMachineID, sMachineXMLFile, sMachineXSLFile, sMachineVersion, sMachineOptions, sMachineParms; /* * Before we start looking for Markdown-style machine links, see if there are any Liquid-style machines, @@ -1008,8 +1051,8 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock) sMachineXMLFile = machine['config'] || "machine.xml"; sMachineXSLFile = machine['template'] || ""; sMachineVersion = (machine['uncompiled'] && machine['uncompiled'] == "true"? "uncompiled" : ""); - sMachineState = machine['state'] || ""; - sReplacement = "[Embedded PC](" + sMachineXMLFile + ' "' + sMachine + 'js:' + sMachineID + ':' + sMachineXSLFile + '::' + sMachineOptions + ':' + sMachineState + '")'; + sMachineParms = machine['parms'] || ""; + sReplacement = "[Embedded PC](" + sMachineXMLFile + ' "' + sMachine + 'js|' + sMachineID + '|' + sMachineXSLFile + '||' + sMachineOptions + '|' + sMachineParms + '")'; } sBlock = sBlock.replace(aMatch[0], sReplacement); reIncludes.lastIndex = 0; // reset lastIndex, since we just modified the string that reIncludes is iterating over @@ -1019,7 +1062,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock) * Start looking for Markdown-style machine links now... */ var cMatches = 0; - var reMachines = /\[(.*?)]\((.*?)\s*"(PC|C1P)js:(.*?)"\)/gi; + var reMachines = /\[(.*?)]\((.*?)\s*"(PC|C1P)js[:|](.*?)"\)/gi; while ((aMatch = reMachines.exec(sBlock))) { @@ -1029,14 +1072,14 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock) sMachine = aMatch[3].toUpperCase(); var sMachineFunc = "embed" + sMachine; var sMachineClass = sMachine.toLowerCase(); - var aMachineParms = aMatch[4].split(':'); + var aMachineParms = aMatch[4].split(aMatch[4].indexOf('|') > 0? '|' : ':'); var sMachineMessage = "Waiting for " + sMachine + "js to load"; sMachineID = aMachineParms[0]; sMachineXSLFile = aMachineParms[1] || ""; sMachineVersion = aMachineParms[2] || this.sMachineVersion; sMachineOptions = aMachineParms[3] || ""; - sMachineState = aMachineParms[4] || ""; + sMachineParms = aMachineParms[4] || ""; var aMachineOptions = sMachineOptions.split(','); var fDebugger = (aMachineOptions.indexOf("debugger") >= 0); @@ -1071,14 +1114,14 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock) cMatches++; this.addMachine({ - 'class': sMachineClass, // eg, a machine class, such as "pc" or "c1p" - 'func': sMachineFunc, - 'id': sMachineID, - 'xml': sMachineXMLFile, - 'xsl': sMachineXSLFile, - 'version': sMachineVersion, // eg, "1.10", "*" to select the current version, or "uncompiled"; "*" is the default + 'class': sMachineClass, // eg, a machine class, such as "pc" or "c1p" + 'func': sMachineFunc, + 'id': sMachineID, + 'xml': sMachineXMLFile, + 'xsl': sMachineXSLFile, + 'version': sMachineVersion,// eg, "1.10", "*" to select the current version, or "uncompiled"; "*" is the default 'debugger': fDebugger, // eg, true or false; false is the default - 'state': sMachineState} + 'parms': sMachineParms} ); } diff --git a/modules/shared/lib/embed.js b/modules/shared/lib/embed.js index df2694487..0a4b6c866 100644 --- a/modules/shared/lib/embed.js +++ b/modules/shared/lib/embed.js @@ -131,13 +131,22 @@ function parseXML(sXML, sXMLFile, idMachine, sParms, fResolve, display, done) */ if (!sParms) { sParms = '{'; - } else if (sParms.substr(0, 1) == '{') { + } else if (sParms.slice(-1) == '}') { sParms = sParms.slice(0, -1); if (sParms.length > 1) sParms += ','; - } else { // backward compatibility: sParms is actually sStateFile + } else { // sParms must just be a "state" file, so encode it as a "state" property sParms = '{state:"' + sParms + '",'; } sParms += 'url:"' + sURL + '"}'; + /* + * Note that while we no longer generate a machine XML file with a "state" attribute (because it's + * encoded inside the "parms" attribute), the XSL file must still cope with "state" attributes inside + * other XML files; for example, manifest XML files like /apps/pc/1981/visicalc/manifest.xml contain + * machine elements with "state" attributes that must still be passed down to the computer element + * "the old fashioned way". + * + * Until/unless that changes, components.xsl cannot be simplified as much as I might have hoped. + */ sXML = sXML.replace(/(]*\sid=)(['"]).*?\2/, "$1$2" + idMachine + "$2" + (sParms? " parms='" + sParms + "'" : "") + (sURL? ' url="' + sURL + '"' : '')); } /* diff --git a/versions/pcjs/1.20.4/pc-dbg.js b/versions/pcjs/1.20.4/pc-dbg.js index 7282a30f3..a5bc3284b 100644 --- a/versions/pcjs/1.20.4/pc-dbg.js +++ b/versions/pcjs/1.20.4/pc-dbg.js @@ -1210,7 +1210,7 @@ function kr(a,b){a.A=null;var c=za(Aa()+"/api/v1/user?req=verify&user="+b),d=c[1 function jr(a,b,c){if(c){var d={req:"store"};d.user=b;d.state=Xq(a,er);d.data=c;b=za(Aa()+"/api/v1/user",!1,d);d=b[1];if(b[0]){if(d){var e=d.indexOf("\n");0k.indexOf("/")&&(k=window.location.pathname+k);d?"{"==d.substr(0,1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(k?' url="'+k+'"':""))}k=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(k=new window.ActiveXObject("Microsoft.XMLDOM"), +function nr(a,b,c,d,e,f,g){function k(a,f){if(f)g(f,null);else{if(c){var k=b;k&&0>k.indexOf("/")&&(k=window.location.pathname+k);d?"}"==d.slice(-1)?(d=d.slice(0,-1),1]*\sid=)(['"]).*?\2/,"$1$2"+c+"$2"+(d?" parms='"+d+"'":"")+(k?' url="'+k+'"':""))}k=null;if("<"==a.charAt(0))try{e||(a=a.replace(/\s*/g,"")),window.ActiveXObject||"ActiveXObject"in window?(k=new window.ActiveXObject("Microsoft.XMLDOM"), k.async=!1,k.loadXML(a)):k=(new window.DOMParser).parseFromString(a,"text/xml")}catch(B){k=null,a=B.message}else a="unrecognized XML: "+(255/g.exec(a)){var e=d[2];b("Loading "+e+"...");za(e,!0,null,null,function(f,g,k){if(k||!g)c(a,"unable to resolve XML reference: "+d[0]+" ("+k+")");else{if(f=d[3])if(k=g.match(new RegExp("<"+d[1]+"[^>]*>"))){for(var q=k[0],r,x=/( [a-z]+=)(['"])(.*?)\2/g;r=x.exec(f);)q=0>q.indexOf(r[1])?q.replace(">",r[0]+">"):q.replace(new RegExp(r[1]+"(['\"])(.*?)\\1"),r[0]);k[0]!=q&&(g=g.replace(k[0],q))}else{c(a,"missing <"+d[1]+"> in "+e);return}g=g.replace(/<\?xml[^>]*>[\r\n]*/, "");a=a.replace(d[0],g);yr(a,b,c)}})}else c(a,null)}