/**
* @fileoverview Builds default ("index.html") documents from HTML templates
* @author Jeff Parsons (@jeffpar)
* @copyright © Jeff Parsons 2012-2017
*
* This file is part of PCjs, a computer emulation software project at .
*
* PCjs is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* PCjs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCjs. If not,
* see .
*
* You are required to include the above copyright notice in every modified copy of this work
* and to display that copyright notice when the software starts running; see COPYRIGHT in
* .
*
* Some PCjs files also attempt to load external resource files, such as character-image files,
* ROM files, and disk image files. Those external resource files are not considered part of PCjs
* for purposes of the GNU General Public License, and the author does not claim any copyright
* as to their contents.
*/
"use strict";
var fs = require("fs");
var path = require("path");
var glob = require("glob");
/**
* @class exports
* @property {function(string)} sync
*/
var HTTPAPI = require("./httpapi");
var defines = require("../../shared/lib/defines");
var DumpAPI = require("../../shared/lib/dumpapi");
var MarkOut = require("../../markout");
var net = require("../../shared/lib/netlib");
var proc = require("../../shared/lib/proclib");
var str = require("../../shared/lib/strlib");
var usr = require("../../shared/lib/usrlib");
/**
* @class exports
* @property {string} name
* @property {string} version
* @property {Array.} c1pCSSFiles
* @property {Array.} c1pJSFiles
* @property {Array.} pcCSSFiles
* @property {Array.} pcX86Files
* @property {Array.} pc8080Files
* @property {Array.} pdp10Files
* @property {Array.} pdp11Files
*/
var pkg = require("../../../package.json");
/*
* fCache controls "index.html" caching; it is true by default and can be overridden using the setOptions()
* 'cache' property.
*
* NOTE: Even though we don't explicitly set fCache to true, that's the default, because we disable caching
* only when fCache is explicitly false; this is so we can detect when it has been explicitly set to true,
* ensuring that we cache files even when other settings (like fServerDebug) might suggest we shouldn't cache.
*/
var fCache;
/*
* fConsole controls console messages; it is false by default and can be overridden using the setOptions()
* 'console' property.
*/
var fConsole = false;
/*
* fServerDebug controls server-related debug features; it is false by default and can be enabled using the
* setOptions() 'debug' property (or from the server's command-line interface using "--debug").
*
* This used to be named fDebug, which was fine, but it has been renamed to make the distinction between the
* server's debug state (fServerDebug) and the debug state of HTMLOut instances (this.fDebug) clearer.
*/
var fServerDebug = false;
/*
* logFile is set by server.js using the setOptions() 'logfile' property, if the server has turned on
* logging. This allows us to "mingle" our logConsole() output with the server's log (typically "./logs/node.log").
*
* The same "mingled" messages will also appear on the console if fConsole has been turned on as well
* (using "--console" from our own command-line interface, or via the setOptions() 'console' property).
*/
var logFile = null;
/*
* fPrivate will be set to true to by setOptions() if the server was started with '--private', giving the Node
* server an option comparable to Jekyll's site.pcjs.private setting, and triggering the load of "private.js" as
* appropriate. Currently, the only (checked-in) use of the private setting is to set the client's PRIVATE global
* and trigger the loading of alternate (ie, private) XML files in embed.js.
*/
var fPrivate = false;
/*
* fRebuild controls the rebuilding of cached "index.html" files, assuming fCache is true; fRebuild is false
* by default, and it can be set for all requests using the setOptions() 'rebuild' property, or for individual
* requests using the fRebuild parameter to HTMLOut().
*/
var fRebuild = false;
/*
* fSendDefault determines what happens HTMLOut() determines that an up-to-date default document already exists;
* if false (default), HTMLOut() will return null, allowing our Express filter() function pass the request on
* as a normal static file request; otherwise, HTMLOut() will load the document and send the contents itself
* (this is the mode that the CLI uses).
*
* TODO: Consider honoring fSendDefault even when generating a new default document, although there may be some
* efficiency to sending new documents ourselves, because we don't have to wait for the writeFile() to complete.
*
* NOTE: I've since changed the fSendDefault from false to true, because I'm running into situations where, at
* least for directory URLs with default documents, the Express static file handler is reporting that the static
* content is "not modified" (304), which in turn causes Safari to occasionally display blank pages.
*
* The server (server.js) still has the option (via setOptions) to override this setting, but until the dreaded
* "Safari blank page" problem is fully understood and addressed, the server should probably not do that.
*
* TODO: Understand and properly address the "Safari blank page" problem (which I'm still seeing as of
* Safari v7.0.3); some folks claim it's a Safari bug, but I'm not convinced, because similar requests/responses
* from Apache don't cause the problem.
*/
var fSendDefault = true;
/*
* fSockets is set if the server tells us to enable client-side support.
*/
var fSockets = false;
/*
* sServerRoot is the root directory of the web server; it can (and should) be overridden using by the Express
* web server using setRoot().
*/
var sServerRoot = "/Users/Jeff/Sites/pcjs";
/*
* sDefaultFile is the default filename to use for web server directories, and sTemplateFile is the default HTML
* template to use.
*/
var sDefaultFile = "index.html";
var sTemplateFile = "./modules/shared/templates/common.html";
/*
* sReadMeFile is the default markdown file to load and convert to HTML when a "readme" token is detected in an
* HTML template file; sMachineXMLFile is a fallback file to look for when sReadMeFile doesn't exist.
*/
var sReadMeFile = "README.md";
var sMachineMDFile = "machine.md";
var sMachineXMLFile = "machine.xml";
var sManifestXMLFile = "manifest.xml";
/*
* We need lists of the uncompiled scripts for C1P and PCx86, indexed by machine type, so that if we have
* to inject those individual scripts into the current document, all the ordering dependencies will be honored
* (which is why processMachines() can't simply enumerate all the .js files in the respective script folder).
*
* We build these lists from the lists stored in the project's "package.json" file; also, we start with the
* complete lists (ie, with "debugger.js" included in the proper sequence) and then filter out the debugger
* later if it turns out we don't need it.
*
* We include any required CSS files in these lists as well, for convenience. CSS files are added just before
* the closing tag, and JS files are added just before the closing