<?php
include_once("BaseClasses.php");
include_once("Parsedown.php");
include_once("grads.php");
include_once("bugs.php");
/*
"/a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b\]/"
P
*/
function make_gradient_bg_css(array $colours, string $direction="to bottom", string $repeat="no-repeat")
{
$n = count($colours);
if( $n < 1 ) {
return null;
}
$bg = array();
array_push($bg,$colours[$n-1]);
if( $n > 1 ) {
$gradient_points = array();
for($i = 0; $i < $n; $i++) {
$pc = round($i*(100.0/($n-1)));
array_push($gradient_points,"$colours[$i] ${pc}%");
}
$direction = "to bottom";
$gradient = "linear-gradient($direction, ".implode(", ",$gradient_points).")";
array_push($bg,$gradient);
}
$css = "background: url('/marble2.png'), ".implode(" ",$bg)." $repeat;";
return $css;
}
function make_gradient_background() {
if( file_exists("grad.txt") ) {
$lines = file("grad.txt");
$line = $lines[0];
$bg_colours = preg_split("/[\\s,]+/",trim($line));
} else {
$bg_colours = pseudo_random_gradient(getcwd());
}
$css_bg = make_gradient_bg_css($bg_colours);
$last_colour = $bg_colours[count($bg_colours)-1];
$r = hexdec(substr($last_colour,1,2));
$g = hexdec(substr($last_colour,3,2));
$b = hexdec(substr($last_colour,5,2));
if( (($r + $g + $b) / 3) > 128 ) {
$light_bg = true;
} else {
$light_bg = false;
}
$css = "
body {
$css_bg
}
";
if( $light_bg ) {
$css .= "footer {
color: black;
}
footer a {
color: #007;
}
footer a:visited {
color: #01a;
}
";
} else {
$css .= "footer {
color: hsl(0,0%,80%);
}
footer a {
color: white;
}
footer a:visited {
color: #dde;
}
";
}
$style = "<style media='screen'>
$css
</style>";
return $style;
}
class WikiRendererParsedown1 extends WikiRenderer {
public function __construct() {
$this->protected = array();
$this->protected_prefix = strtolower(hash("sha256",time()));
}
public function render_view(array $vars): void {
$word = $vars["WIKI_WORD"];
$source = $vars["WIKI_PAGE_SOURCE"];
$vars["WIKI::FAVICON"] = '<link rel="icon" type="image/x-icon" href="/purple_tree_wiki_favicon.png">';
if( file_exists("favicon.png") ) {
$vars["WIKI::FAVICON"] = '<link rel="icon" type="image/x-icon" href="favicon.png">';
}
if( file_exists("favicon_view.png") ) {
$vars["WIKI::FAVICON"] = '<link rel="icon" type="image/x-icon" href="favicon_view.png">';
}
if( file_exists("bug.png") ) {
#$vars["BUG_BUG"] = '<img class="bug" height="256px" src="bug.png" style="position: absolute; z-index: 1; right: 3em; top: 1em;"/>';
$vars["BUG_BUG"] = '<img class="bug" height="'.BUG_HEIGHT.'" src="bug.png"/>';
} else if(file_exists("nobug") ) {
$vars["BUG_BUG"] = "";
} else {
$vars["BUG_BUG"] = get_random_bug(getcwd());
}
# convert tags
if( preg_match("@^tags:(.*)$@m",$source,$m) ) {
$tags = preg_split("@\s+@",trim($m[1]));
$source = explode("\n",$source,2)[1];
$t = [];
foreach($tags as $tag) {
switch($tag[0]) {
case "#":
$cls = "hashtag";
$x = substr($tag,1);
$h = "<a href='/tag/$x'>$tag</a>";
break;
case "%":
$cls = "category";
$h = "<a href='#'>$tag</a>";
break;
case "@":
$cls = "user";
$h = "<a href='#'>$tag</a>";
break;
default:
$cls = "other";
$h = "<a href='#'>$tag</a>";
}
array_push($t,"<li class='$cls'>$h</li>");
$x = implode("\n",$t);
$y = "<ul class='hashtags'>\n".$x."\n</ul>\n";
$vars["TAGS_TAGS"] = $y;
}
} else {
$vars["TAGS_TAGS"] = "";
}
$opts = [];
if( preg_match("@^options:(.*)$@m",$source,$m) ) {
$optsrc = preg_split("@\s+@",trim($m[1]));
$source = explode("\n",$source,2)[1];
foreach($optsrc as $opt) {
[$a,$b] = explode("=",$opt,2);
$opts[$a] = $b;
}
}
#var_dump($opts);
$mathjax = true;
if( array_key_exists("mathjax",$opts) ) {
$m = strtolower($opts["mathjax"]);
if( $m == "false" || $m == "no" ) {
$mathjax = false;
}
}
$this->mathjax = $mathjax;
$abcjs = false;
if( array_key_exists("abc",$opts) ) {
$m = strtolower($opts["abc"]);
if( $m == "true" || $m == "yes" ) {
$abcjs = true;
}
}
$this->abcjs = $abcjs;
if( $mathjax ) {
$vars["WIKI::MathJax"] = "<script>
MathJax = {
tex: {
inlineMath: [['\\\a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a7902699be42c8a8e46fbbb4501726517e86b22c56a189f7625a6da49081b2451']],
displayMath: [['\\\a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5ad4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35']]
},
svg: {
fontCache: 'global'
}
};
</script>
<script type='text/javascript' id='MathJax-script' async
src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js'>
</script>
";
} else {
$vars["WIKI::MathJax"] = "";
}
if( $abcjs ) {
$vars["WIKI::AbcJs"] = "<script src='/js/abcjs-basic-min.js'></script>
<script src='/js/abc-auto.js'></script>";
} else {
$vars["WIKI::AbcJs"] = "";
}
#echo "<pre>\n"; var_dump($vars); echo "</pre>\n";
$vars["GRAD_GRAD"] = make_gradient_background();
$source = preg_replace_callback("/^(```nohighlight\\s(.*?)^```)/ms",[$this,"protect_nohighlight_cb"],$source);
if( $this->abcjs ) {
$source = preg_replace_callback("/^(```abc\\s(.*?)^```)/ms",[$this,"protect_abc_cb"],$source);
}
$source = preg_replace_callback("/^(```(.*?)^```)/ms",[$this,"protect_block_cb"],$source);
$source = preg_replace_callback("/(`+)(.*?)(\\1)/s",[$this,"protect_backquote_cb"],$source);
$source = preg_replace_callback(HEADER_REGEX,[$this,"protect_header"],$source);
$source = preg_replace_callback(YOUTUBE_REGEX,[$this,"protect_youtube"],$source);
$source = preg_replace_callback(MD_IMGLINK_REGEX,[$this,"protect_mdimglink_cb"],$source);
$source = preg_replace_callback(OB_LINK_REGEX,[$this,"protect_oblink_cb"],$source);
$source = preg_replace_callback('@a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce]*)\]a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a2c624232cdd221771294dfbb310aca000a0df6ac8b66b696d90ef06fdefb64a3@',[$this,"protect_unwiki_cb"],$source);
$source = preg_replace_callback(MD_LINK_QUOTE_REGEX,[$this,"protect_mdlink_quote_cb"],$source);
$source = preg_replace_callback(MD_LINK_REGEX,[$this,"protect_mdlink_cb"],$source);
$source = preg_replace_callback(URL_REGEX,[$this,"protect_url_cb"],$source);
$source = preg_replace_callback(WIKIWORD_REGEX, [$this,"WikiWord_to_link"],$source);
foreach($this->protected as $id => $string) {
$source = str_replace($id,$string,$source);
}
#echo "<!--\n";
#var_dump($source);
#echo "-->\n";
$vars['WIKI_PAGE_SOURCE'] = $source;
$this->render_view_real($vars);
}
public function render_view_real(array $vars): void {
$source = $vars['WIKI_PAGE_SOURCE'];
#echo "<!-- render view real\n";
#var_dump($source);
#echo "-->\n";
# protect a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a19581e27de7ced00ff1ce50b2047e7a567c76b1cbaebabe5ef03f7c3017bb5b7 and a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a4b227777d4dd1fc61c6f884f48641d02b4d121d3fd328cb08b5531fcacdabf8a from Parsedown
$source = str_replace('\a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5aef2d127de37b942baad06145e54b0c619a1f22327b2ebbcfbec78f5564afe39d',HEXVISION,$source);
$source = str_replace('\a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a4a44dc15364204a80fe80e9039455cc1608281820fe2b24f1e5233ade6af1dd5',FRYTHEEWELL,$source);
$source = str_replace('\\{',COOKLITTLEPIGGY,$source);
$source = str_replace('\\}',COOKTHEEWELL,$source);
$this->protected = [];
if( $this->abcjs ) {
$source = preg_replace_callback("/^(?:```abc\\s(.*?)^```)/ms",[$this,"protect_abc_pd_cb"],$source);
}
$parsedown = new Parsedown();
$result = $parsedown->text($source);
foreach($this->protected as $id => $string) {
$result = str_replace($id,$string,$result);
}
$result = str_replace(MRFLIBBLE,'\a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5ae7f6c011776e8db7cd330b54174fd76f7d0216b612387a5ffcfb81e6f0919683',$result);
$result = str_replace(FRYLITTLEPIGGY,'\a4b64aa751cf795de53f23be2049cb5223ee8907ad6fc8130825c1f3b20a8d5a4fc82b26aecb47d2868c4efbe3581732a3e7cbcc6c2efb32062c08170a05eeb8',$result);
$result = str_replace(COOKLITTLEPIGGY,'\\{',$result);
$result = str_replace(COOKTHEEWELL,'\\}',$result);
$result = preg_replace("/(?<=[^-])---(?=[^-])/","—",$result);
$result = preg_replace("/(?<=[^-])--(?=[^-])/","–",$result);
$vars["WIKI_PAGE_BODY"] = $result;
if( preg_match("/Mobile/",$_SERVER["HTTP_USER_AGENT"]) ) {
$template = file_get_contents("view_template_mob.html");
} else {
$template = file_get_contents("view_template_md.html");
}
$this->render_template($template,$vars);
}
public function render_edit(array $vars): void {
$vars["WIKI::FAVICON"] = '<link rel="icon" type="image/x-icon" href="/purple_tree_edit_favicon.png">';
if( file_exists("favicon.png") ) {
$vars["WIKI::FAVICON"] = '<link rel="icon" type="image/x-icon" href="favicon.png">';
}
if( file_exists("favicon_edit.png") ) {
$vars["WIKI::FAVICON"] = '<link rel="icon" type="image/x-icon" href="favicon_edit.png">';
}
$vars["GRAD_GRAD"] = make_gradient_background();
if( $vars["WIKI_ERROR_STRING"] ) {
$vars["WIKI_ERROR_MESSAGE"] = $this->format_error_message($vars["WIKI_ERROR_STRING"]);
} else {
$vars["WIKI_ERROR_MESSAGE"] = "";
}
$template = file_get_contents("edit_template_mob.html");
$this->render_template($template,$vars);
}
public function render_versions(array $vars): void {
$versions = $vars['WIKI_VERSIONS'];
$word = $vars['WIKI_WORD'];
$body = "";
if( count($versions) == 0) {
$this->vars['WIKI_PAGE_SOURCE'] = "Word $word has no versions.";
} else {
foreach( $versions as $version) {
$body .= "1. [".date(DATE_COOKIE,intval($version))."]($word?version=$version)\n";
}
$body .= "1. [current]($word)\n";
}
$parsedown = new Parsedown();
$rendered = $parsedown->text($body);
$vars["WIKI_PAGE_BODY"] = $rendered;
$template = file_get_contents("versions_template_md.html");
$this->render_template($template,$vars);
}
private function protect(string $content): string {
$protid = strtolower(hash("sha256",$this->protect_count++));
$key = $this->protected_prefix.$protid; # generate unique string
$this->protected[$key] = $content;
return $key;
}
private function protect_cb(array $match): string {
return $this->protect($match[0]);
}
private function protect_nohighlight_cb(array $match): string {
return $this->protect($match[2]);
}
private function protect_abc_cb(array $match): string { # protect ABC from WikiWord
return $this->protect($match[0]);
}
private function protect_abc_pd_cb(array $match): string { # protect ABC from Parsedown, convert to div.abc
return $this->protect("<div class='abc'>\n$match[1]\n</div>");
}
private function protect_header(array $match): string {
return $this->protect($match[0]);
}
private function protect_youtube(array $match): string {
return $this->protect($match[0]);
}
private function protect_url_cb(array $match): string {
#echo "url: $match[0]<br/>\n";
return $this->protect($match[0]);
}
private function protect_mdimglink_cb(array $match): string {
#echo "mdimglink: $match[0]<br/>\n";
return $this->protect($match[0]);
}
private function protect_mdlink_cb(array $match): string {
#echo "mdlink: $match[0]<br/>\n";
return $this->protect($match[0]);
}
private function protect_unwiki_cb(array $match): string {
#echo "mdlink: $match[0]<br/>\n";
return $this->protect($match[1]);
}
private function protect_oblink_cb(array $match): string {
#echo "mdlink: $match[0]<br/>\n";
$l = $match[1];
$t = preg_replace("@[^a-zA-Z0-9._/-]+@","",$l);
if( strlen($t) == 0 ) {
return $this->protect("");
}
if( ! preg_match("@/@",$t) && ! preg_match(WIKIWORD_REGEX,$t) ) {
if( ! preg_match('@\.@',$t) ) {
# not a filename: make into PageSomething format
if( ! preg_match("@[A-Z]@",$t ) ) {
# ensure at least one capital
if( preg_match("@[a-z]@",$t) ) {
# is a lowercase letter we can uppercase
$t = preg_replace_callback('/^(.*?)([a-z])(.*)$/',function($m) { return $m[1].strtoupper($m[2]).$m[3]; }, $t);
} else {
$t = "N".$t; # basically a number
}
}
$t = "Page".$t;
}
}
return $this->protect("[$l]($t)");
}
private function protect_mdlink_quote_cb(array $match): string {
#echo "mdlink quote: $match[0] :: $match[1] $match[2]<br/>\n";
return $this->protect("[$match[1]]($match[2])");
}
private function protect_block_cb(array $match): string {
#echo "block: $match[0]<br/>\n";
return $this->protect($match[0]);
}
private function protect_backquote_cb(array $match): string {
#echo "backquote: $match[0]<br/>\n";
return $this->protect($match[0]);
}
private function WikiWord_to_link(array $match): string {
$word = $match[0];
return "[$word]($word)";
}
private function edit_link(string $word): string {
return "<div class='edit_link'><a href='$word?edit'>Edit</a></div>";
}
private function render_template(string $template, array $vars): void {
foreach($vars as $key => $value) {
if( is_string($value) ) { # silently ignore array vars
$template = str_replace($key,$value,$template);
}
}
echo $template;
exit();
}
private function format_error_message(string $err_msg): string {
return "<p class='error'>$err_msg</p>\n";
}
}