Developer / NetCloak
NetCloak was the angle-bracket templating system GuruHits pages ran on under the classic Mac OS WebSTAR server. This page documents the language and provides a clean, MIT-licensed PHP re-implementation you can download and reuse.
The live GuruHits .html files were never plain HTML. They were NetCloak templates — a system of
angle-bracket tags (<hide>, <show_variable …>, <macro …>, <exec_cgi …>) that the Mac web
server processed on every request before sending the page. This page documents that language and the
MIT-licensed PHP engine we wrote to faithfully run it again.
How NetCloak was served
- 2001 — WebSTAR. At launch, NetCloak ran as a plug-in to WebSTAR (the classic Mac OS web
server), which also called the HyperCard quiz engine through an ACGI (
<exec_cgi …>). GuruHits stayed on this WebSTAR + HyperCard combination for its whole life. - Oct–Nov 2002 — Tenon iTools (the rest of the network). Around this time Joe moved his wider
network of NetCloak sites off WebSTAR onto Tenon iTools — an Apache-httpd-based server on
Mac OS X 10.2 — where NetCloak ran via Apple's
redirect-acgiApache handler (AddHandler redirect-acgi nclk fdml). GuruHits itself couldn't follow: nothing ran its HyperCard ACGI backend under Apache, so the quiz kept running on WebSTAR. - Later (iTools 7) — FastCGI. On iTools, NetCloak then moved to Maxum's FastCGI module
(
mod_fastcgi.so), with the NetCloak runtime listening onlocalhost:9008. Adding.htmlto the handler list is exactly how NetCloak "cloaked" the.htmlpages it served.
The MIT engine
The re-implementation is a small, dependency-free library:
Lexer— tokenizes a template into text + tags (longest-command-first matching, soshow_variablewins overshow).Interpreter::render($template, $context)— the mode engine:hide/show/flipmodeset visibility; consecutive conditionals AND together (the latch that makes exactly one gated block show); plus all theinsert_*/set_*handling.Context— the per-request state (locals, variables, cookies, globals, redirect).- Two closures keep it game-independent: a
macroLoaderfor<macro /x.macro>includes and anacgiDispatchfor the<exec_cgi …>bridge.
Download & use
Download netcloak-php-1.0.0.zip
- Inside the zip:
src/(the four classes) + tests + a runnable example +composer.json+ MITLICENSE. - Machine-readable tag reference: tags.json.
use NetCloak\{Interpreter, Lexer, Context, Rng};
$interp = new Interpreter(new Lexer(), new Rng(),
fn($relPath) => file_get_contents("macros/$relPath"), // <macro /x> includes
fn($cmd, $ctx) => ''); // <exec_cgi …> hook
echo $interp->render('Hi <INSERT_VARIABLE name>!', new Context(variables: ['name' => 'Joe']));
Tag reference
Conversion cookbook (NetCloak → PHP)
Conditional blocks. A NetCloak gated block becomes a render of the same template against a
Context:
<hide><show_local rank = "Guru">You made Guru!<hide>
$ctx = new Context();
$ctx->setLocal('rank', $rank);
echo $interp->render($tpl, $ctx);
// chained conditionals AND together, so with several gated lines exactly one shows
Server-side includes. <macro /header.macro> is resolved by your macroLoader closure — point it
at wherever your .macro fragments live; the engine processes the included text too.
The CGI bridge. <exec_cgi hypercard.acgi quizresult> becomes a call into your acgiDispatch
closure: receive the command string (quizresult) + the Context, and return whatever HTML your
back-end produces. In GuruHits's reconstruction this dispatches to the ported HyperTalk quiz logic.
