Merge branch 'master' into gh-pages

This commit is contained in:
Jeff Parsons 2017-06-29 08:12:53 -07:00
commit b692cfbd66
3 changed files with 54 additions and 42 deletions

View file

@ -160,8 +160,8 @@ To install Jekyll for use with PCjs:
1. Install Ruby (on OS X, it should already be installed) 1. Install Ruby (on OS X, it should already be installed)
2. Install Bundler (on OS X, run `sudo gem install bundler`) 2. Install Bundler (on OS X, run `sudo gem install bundler`)
3. Checkout the `gh-pages` branch, since only that branch contains all the Jekyll-related files 3. Checkout the *gh-pages* branch, since only that branch contains all the Jekyll-related files
4. Create a `Gemfile` containing `gem 'github-pages'` (this is already checked in) 4. Create a **Gemfile** containing `gem 'github-pages'` (this is already checked in)
5. Run `bundle install` (GitHub Pages alternatively suggests: `bundle exec jekyll build --safe`) 5. Run `bundle install` (GitHub Pages alternatively suggests: `bundle exec jekyll build --safe`)
6. Run `bundle exec jekyll serve` to start the web server 6. Run `bundle exec jekyll serve` to start the web server
@ -171,14 +171,14 @@ Some useful Jekyll server options include:
bundle exec jekyll serve --host=0.0.0.0 --config _config.yml,_developer.yml bundle exec jekyll serve --host=0.0.0.0 --config _config.yml,_developer.yml
The `--host` option makes it possible to access the web server from other devices on your local network; The *--host* option makes it possible to access the web server from other devices on your local network;
for example, you may want to run PCjs on your iPhone, iPad, or other wireless device. And by adding `_developer.yml`, for example, you may want to run PCjs on your iPhone, iPad, or other wireless device. And by adding **_developer.yml**,
you can override the Jekyll configuration defaults in `_config.yml`. Using development (non-production) settings in you can override the Jekyll configuration defaults in **_config.yml**. Using development (non-production) settings in
`_developer.yml` is analogous to running the Node web server with certain development options; see **_developer.yml** is analogous to running the Node web server with certain development options; see
[Debugging PCjs](#debugging-pcjs). [Debugging PCjs](#debugging-pcjs).
GitHub Pages says you can run `jekyll serve` instead of `bundle exec jekyll serve`, but with the addition of GitHub Pages says you can run `jekyll serve` instead of `bundle exec jekyll serve`, but with the addition of
more gems to `Gemfile` (eg, `jekyll-sitemap`), running `jekyll serve` may trigger dependency errors on some systems. more gems to **Gemfile** (eg, "jekyll-sitemap"), running `jekyll serve` may trigger dependency errors on some systems.
`bundle exec jekyll serve` should always work. `bundle exec jekyll serve` should always work.
Don't see any YML files in the root of your project? You probably forgot to switch to the Don't see any YML files in the root of your project? You probably forgot to switch to the
@ -198,7 +198,7 @@ However, in order to build and test PCjs modifications, you'll want to use [Grun
Grunt tasks defined by [Gruntfile.js](Gruntfile.js). Grunt tasks defined by [Gruntfile.js](Gruntfile.js).
Although Grunt was installed locally when you ran `npm install`, you'll also want to install the command-line Although Grunt was installed locally when you ran `npm install`, you'll also want to install the command-line
interface to Grunt. You can install that locally as well, but it's recommended you install it globally with `-g`; interface to Grunt. You can install that locally as well, but it's recommended you install it globally with *-g*;
OS X users may also need to preface this command with `sudo`: OS X users may also need to preface this command with `sudo`:
npm install grunt-cli -g npm install grunt-cli -g
@ -249,7 +249,7 @@ Here's what I installed to get Gulp working:
npm install --save-dev gulp gulp-concat gulp-rename gulp-replace gulp-header gulp-foreach gulp-wrapper run-sequence npm install --save-dev gulp gulp-concat gulp-rename gulp-replace gulp-header gulp-foreach gulp-wrapper run-sequence
npm install --save-dev google-closure-compiler-js npm install --save-dev google-closure-compiler-js
Running `gulp` should build a new `pcx86.js` in the [versions](/versions/) directory. However, Running `gulp` should build a new **pcx86.js** in the [versions](/versions/) directory. However,
you should consider Gulp support (and anything built with Gulp) as **experimental** until further notice. you should consider Gulp support (and anything built with Gulp) as **experimental** until further notice.
The [JavaScript-based Closure Compiler](https://github.com/google/closure-compiler-js) is in a state of The [JavaScript-based Closure Compiler](https://github.com/google/closure-compiler-js) is in a state of
flux as well; for example, *output_wrapper* support is documented in their flux as well; for example, *output_wrapper* support is documented in their
@ -354,8 +354,8 @@ you can start the server with some additional options; eg:
node server.js --logging --console --debug node server.js --logging --console --debug
The `--logging` option will create a [node.log](/logs/) that records all the HTTP requests, `--debug` The *--logging* option will create a [node.log](/logs/) that records all the HTTP requests, *--debug*
will generate additional debug-only messages (which will also be logged if `--logging` is enabled), and `--console` will generate additional debug-only messages (which will also be logged if *--logging* is enabled), and *--console*
will replicate any messages to your console as well. will replicate any messages to your console as well.
If you want server.js to use a different port (the default is 8088), set PORT in your environment before starting If you want server.js to use a different port (the default is 8088), set PORT in your environment before starting
@ -363,7 +363,7 @@ the server:
export PORT=80 export PORT=80
or add `--port` to your command-line: or add *--port* to your command-line:
node server.js --logging --console --debug --port=80 node server.js --logging --console --debug --port=80
@ -376,7 +376,7 @@ PCjs emulators much easier to debug, albeit much slower:
http://localhost:8088/?gort=debug http://localhost:8088/?gort=debug
The "gort=debug" command is unnecessary if the server is started with `--debug`; the server always serves uncompiled The "gort=debug" command is unnecessary if the server is started with *--debug*; the server always serves uncompiled
files when running in debug mode. files when running in debug mode.
Conversely, if the server is in debug mode but you want to test a compiled version of PCx86, use: Conversely, if the server is in debug mode but you want to test a compiled version of PCx86, use:

View file

@ -383,11 +383,16 @@ MarkOut.prototype.convertMD = function(sIndent)
var sMD = this.sMD; var sMD = this.sMD;
/* /*
* Convert any escaped asterisks, square brackets, etc, to their HTML-entity equivalents, * Convert any escaped asterisks, square brackets, etc, to their HTML entity equivalents,
* as a convenient way of avoiding parsing problems later. We also take this opportunity * as a convenient way of avoiding parsing problems later. We also take this opportunity
* to replace any \r\n sequences with \n. * to replace any \r\n sequences with \n.
*
* UPDATE: I've moved the HTML entity replacement into convertMDBlock(), AFTER we check for
* code blocks and call escapeHTML(), because otherwise we run into entity "double-encoding"
* problems. Hopefully, the aforementioned "parsing problems" don't rear their head before then.
*/ */
sMD = str.replaceArray(MarkOut.aHTMLEntities, sMD).replace(/\r\n/g, "\n").replace(/\r/g, "\n"); sMD = sMD.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
// sMD = str.replaceArray(MarkOut.aHTMLEntities, sMD).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
/* /*
* Before performing the original comment-elimination step, a new step has been added that * Before performing the original comment-elimination step, a new step has been added that
@ -402,7 +407,7 @@ MarkOut.prototype.convertMD = function(sIndent)
* triple-dash-style comments. * triple-dash-style comments.
*/ */
if (!this.fDebug) { if (!this.fDebug) {
sMD = sMD.replace(/\{%\s*if\s+page\.developer\s*%}[\s\S]*?{%\s*endif\s*%}\s*/g, ""); sMD = sMD.replace(/{%\s*if\s+page\.developer\s*%}[\s\S]*?{%\s*endif\s*%}\s*/g, "");
sMD = sMD.replace(/[ \t]*<!--+\s*begin:exclude\s*-+->[\s\S]*?<!--+\s*end:exclude\s*-+->[\r\n]*/gi, ""); sMD = sMD.replace(/[ \t]*<!--+\s*begin:exclude\s*-+->[\s\S]*?<!--+\s*end:exclude\s*-+->[\r\n]*/gi, "");
} }
@ -418,7 +423,7 @@ MarkOut.prototype.convertMD = function(sIndent)
* the lack of JavaScript support for the "s" (aka "dotall" or "multiline") option that enables * the lack of JavaScript support for the "s" (aka "dotall" or "multiline") option that enables
* "." to match newlines. * "." to match newlines.
*/ */
sMD = sMD.replace(/\{%\s*comment\s*%}[\s\S]*?{%\s*endcomment\s*%}\s*/g, ""); sMD = sMD.replace(/{%\s*comment\s*%}[\s\S]*?{%\s*endcomment\s*%}\s*/g, "");
sMD = sMD.replace(/<!--[\s\S]*?-->/g, ""); sMD = sMD.replace(/<!--[\s\S]*?-->/g, "");
/* /*
@ -601,7 +606,7 @@ MarkOut.prototype.convertMD = function(sIndent)
* you want the second paragraph to appear as a code block, it must be indented TWICE (by 8 spaces * you want the second paragraph to appear as a code block, it must be indented TWICE (by 8 spaces
* or 2 tabs). That behavior should fall out of this hack as well. * or 2 tabs). That behavior should fall out of this hack as well.
*/ */
var re = /(^|\n)( ? ?)([*+-]|[0-9]+\.)([^\n]*\n)([ \t]+[^\n]*\n|\n)+([ \t]+[^\n]+)/g; var re = /(^|\n)( {1,2} ?)([*+-]|[0-9]+\.)([^\n]*\n)([ \t]+[^\n]*\n|\n)+([ \t]+[^\n]+)/g;
//noinspection UnnecessaryLocalVariableJS //noinspection UnnecessaryLocalVariableJS
var sMDOrig = sMD; var sMDOrig = sMD;
while ((aMatch = re.exec(sMDOrig))) { while ((aMatch = re.exec(sMDOrig))) {
@ -742,9 +747,9 @@ MarkOut.prototype.convertMDBlock = function(sBlock, sIndent)
* No other conversions should occur in such a block, so we don't "fall into" the other conversions. * No other conversions should occur in such a block, so we don't "fall into" the other conversions.
*/ */
var aMatch; var aMatch;
var re = /^((^|\n)( |\t)([^\n]*))+$/; var re = /^((^|\n)( {4}|\t)([^\n]*))+$/;
if ((aMatch = re.exec(sBlock))) { if ((aMatch = re.exec(sBlock))) {
var sUndented = aMatch[0].replace(/(^|\n)( |\t)([^\n]*)/g, "$1$3"); var sUndented = aMatch[0].replace(/(^|\n)( {4}|\t)([^\n]*)/g, "$1$3");
sBlock = sBlock.replace(aMatch[0], "<pre><code>" + str.escapeHTML(sUndented.replace(/\t/g, " ")) + "</code></pre>"); sBlock = sBlock.replace(aMatch[0], "<pre><code>" + str.escapeHTML(sUndented.replace(/\t/g, " ")) + "</code></pre>");
sHTML += this.sIndent + sBlock + "\n"; sHTML += this.sIndent + sBlock + "\n";
return sHTML; return sHTML;
@ -771,8 +776,8 @@ MarkOut.prototype.convertMDBlock = function(sBlock, sIndent)
* treated as literal; we translate those to HTML entity "&#96;" to prevent them from being * treated as literal; we translate those to HTML entity "&#96;" to prevent them from being
* detected as part of a "single-backtick" sequence below. * detected as part of a "single-backtick" sequence below.
* *
* Note that we also do the entity replacement AFTER calling htmlspecialchars(), because * Note that we also do entity replacement AFTER calling escapeHTML(), our simplified version
* our implementation of htmlspecialchars() isn't smart enough to avoid the "double-encoding" * of PHP's htmlspecialchars(), because it isn't smart enough to avoid the "double-encoding"
* problem (ie, translating the leading "&" of an entity into yet another "&amp;" entity). * problem (ie, translating the leading "&" of an entity into yet another "&amp;" entity).
*/ */
var sBlockOrig = sBlock; var sBlockOrig = sBlock;
@ -790,11 +795,18 @@ MarkOut.prototype.convertMDBlock = function(sBlock, sIndent)
sBlock = sBlock.replace(aMatch[0], "<code>" + str.escapeHTML(aMatch[1]) + "</code>"); sBlock = sBlock.replace(aMatch[0], "<code>" + str.escapeHTML(aMatch[1]) + "</code>");
} }
/*
* As mentioned at the top of convertMD(), the Markdown escape-sequence-to-HTML-entity conversion
* has been moved here, after we've dealt with code blocks and escapeHTML() operations, in an effort
* to avoid HTML entity "double-encoding" issues.
*/
sBlock = str.replaceArray(MarkOut.aHTMLEntities, sBlock);
/* /*
* Per markdown syntax: "When you do want to insert a <br /> break tag using Markdown, * Per markdown syntax: "When you do want to insert a <br /> break tag using Markdown,
* you end a line with two or more spaces, then type return." * you end a line with two or more spaces, then type return."
*/ */
sBlock = sBlock.replace(/ +\n/g, "<br/>\n" + this.sIndent); sBlock = sBlock.replace(/ {2,}\n/g, "<br/>\n" + this.sIndent);
/* /*
* If the block looks like a list, convertMDList() will convert it; if not, then it will wrap the * If the block looks like a list, convertMDList() will convert it; if not, then it will wrap the
@ -890,10 +902,10 @@ MarkOut.prototype.convertMDList = function(sBlock, sIndent)
* If this list item contains one or more lines indented by 4 or more spaces (or 1 or more tabs) * If this list item contains one or more lines indented by 4 or more spaces (or 1 or more tabs)
* then we need to strip them, so that they can be parsed as a sub-list. * then we need to strip them, so that they can be parsed as a sub-list.
*/ */
re = /((^|\n)( |\t)([^\n]*))+/; re = /((^|\n)( {4}|\t)([^\n]*))+/;
if ((aMatch = re.exec(sListItem))) { if ((aMatch = re.exec(sListItem))) {
// if (this.fDebug) sList += this.encodeComment("subList", aMatch[0]); // if (this.fDebug) sList += this.encodeComment("subList", aMatch[0]);
var sSubList = aMatch[0].replace(/(^|\n)( |\t)([^\n]*)/g, "$1$3").replace(/\n\t\n/g, "\n\n"); var sSubList = aMatch[0].replace(/(^|\n)( {4}|\t)([^\n]*)/g, "$1$3").replace(/\n\t\n/g, "\n\n");
if (sSubList.charAt(0) == "\n") sSubList = sSubList.substr(1); if (sSubList.charAt(0) == "\n") sSubList = sSubList.substr(1);
sListItem = str.replaceAll(aMatch[0], "\n" + this.sIndent + this.convertMDBlocks(sSubList, sIndent).trim() + "\n" + this.sIndent, sListItem); sListItem = str.replaceAll(aMatch[0], "\n" + this.sIndent + this.convertMDBlocks(sSubList, sIndent).trim() + "\n" + this.sIndent, sListItem);
} else { } else {
@ -971,8 +983,8 @@ MarkOut.prototype.convertMDLinks = function(sBlock)
* page's Front Matter; however, unless/until we start using Node again to host the public site, * page's Front Matter; however, unless/until we start using Node again to host the public site,
* that's low priority. * that's low priority.
*/ */
sBlock = sBlock.replace(/([^\t])\{([{%]).*?\2}/g, "$1"); sBlock = sBlock.replace(/([^\t]){([{%]).*?\2}/g, "$1");
sBlock = sBlock.replace(/(\{)([{%])(.*?\2})/g, "<pre><code>$1$2$3</code></pre>"); sBlock = sBlock.replace(/({)([{%])(.*?\2})/g, "<pre><code>$1$2$3</code></pre>");
var aMatch; var aMatch;
var re = /\[([^\[\]]*)]\((.*?)(?:\s*"(.*?)"\)|\))/g; var re = /\[([^\[\]]*)]\((.*?)(?:\s*"(.*?)"\)|\))/g;
@ -1023,7 +1035,7 @@ MarkOut.prototype.convertMDImageLinks = function(sBlock, sIndent)
* (in case this Markdown file is part of a Jekyll installation) and convert them to Markdown-style links. * (in case this Markdown file is part of a Jekyll installation) and convert them to Markdown-style links.
*/ */
var aMatch; var aMatch;
var reIncludes = /\{%\s*include\s+screenshot\.html\s+(.*?)\s*%}/g; var reIncludes = /{%\s*include\s+screenshot\.html\s+(.*?)\s*%}/g;
while ((aMatch = reIncludes.exec(sBlock))) { while ((aMatch = reIncludes.exec(sBlock))) {
var option, aOptions = {}; var option, aOptions = {};
@ -1211,7 +1223,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
/* /*
* Ditto for any Liquid-style machine build links. * Ditto for any Liquid-style machine build links.
*/ */
sBlock = sBlock.replace(/\{%\s*include\s+machine-build\.html\s+id=(["'])(.*?)\1\s*%}/g, '<div class="buildpc" id=$1$2$1></div>'); sBlock = sBlock.replace(/{%\s*include\s+machine-build\.html\s+id=(["'])(.*?)\1\s*%}/g, '<div class="buildpc" id=$1$2$1></div>');
/* /*
* Start looking for Markdown-style machine links now... * Start looking for Markdown-style machine links now...
@ -1288,7 +1300,7 @@ MarkOut.prototype.convertMDMachineLinks = function(sBlock)
/* /*
* Last but not least, see if there are any Liquid-style machine command links that need to be converted. * Last but not least, see if there are any Liquid-style machine command links that need to be converted.
*/ */
reIncludes = /([ \t]*)\{%\s*include\s+machine-command\.html\s+(.*?)\s*%}/g; reIncludes = /([ \t]*){%\s*include\s+machine-command\.html\s+(.*?)\s*%}/g;
var findParm = function(aParms, sParm) { var findParm = function(aParms, sParm) {
sParm += '='; sParm += '=';

View file

@ -506,7 +506,7 @@ class Str {
} }
/** /**
* replace(sFind, sReplace, s) * replace(sSearch, sReplace, s)
* *
* The JavaScript replace() function ALWAYS interprets "$" specially in replacement strings, even when * The JavaScript replace() function ALWAYS interprets "$" specially in replacement strings, even when
* the search string is NOT a RegExp; specifically: * the search string is NOT a RegExp; specifically:
@ -521,36 +521,36 @@ class Str {
* So, if a replacement string containing dollar signs passes through a series of replace() calls, untold * So, if a replacement string containing dollar signs passes through a series of replace() calls, untold
* problems could result. Hence, this function, which simply uses the replacement string as-is. * problems could result. Hence, this function, which simply uses the replacement string as-is.
* *
* Similar to the JavaScript replace() method, this replaces only one occurrence (ie, the FIRST occurrence); * Similar to the JavaScript replace() method (when sSearch is a string), this replaces only ONE occurrence
* it might be nice to add options to replace the LAST occurrence and/or ALL occurrences, but we'll revisit * (ie, the FIRST occurrence); it might be nice to add options to replace the LAST occurrence and/or ALL
* that later. * occurrences, but we'll revisit that later.
* *
* @param {string} sFind * @param {string} sSearch
* @param {string} sReplace * @param {string} sReplace
* @param {string} s * @param {string} s
* @return {string} * @return {string}
*/ */
static replace(sFind, sReplace, s) static replace(sSearch, sReplace, s)
{ {
var i = s.indexOf(sFind); var i = s.indexOf(sSearch);
if (i >= 0) { if (i >= 0) {
s = s.substr(0, i) + sReplace + s.substr(i + sFind.length); s = s.substr(0, i) + sReplace + s.substr(i + sSearch.length);
} }
return s; return s;
} }
/** /**
* replaceAll(sFind, sReplace, s) * replaceAll(sSearch, sReplace, s)
* *
* @param {string} sFind * @param {string} sSearch
* @param {string} sReplace * @param {string} sReplace
* @param {string} s * @param {string} s
* @return {string} * @return {string}
*/ */
static replaceAll(sFind, sReplace, s) static replaceAll(sSearch, sReplace, s)
{ {
var a = {}; var a = {};
a[sFind] = sReplace; a[sSearch] = sReplace;
return Str.replaceArray(a, s); return Str.replaceArray(a, s);
} }