Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 138a3c3342 | |||
| fc28e8c5c8 | |||
| d67c7fc926 | |||
| 8a9b36d3db | |||
| deea763923 | |||
| 8f34df0cbd | |||
| 87f6da2957 | |||
| 766fee12d5 | |||
| 6488bed03c | |||
| ea7092ebef | |||
| ac79051db4 | |||
| 1194223ddd | |||
| ad76f6fb7a | |||
| f39a05ba59 | |||
| 67f20f4379 | |||
| 2c857250c0 | |||
| 931b6e0208 | |||
| 8ea9ca2b2f | |||
| 9def31abeb | |||
| 1878d023bf | |||
| fef327ec61 | |||
| 5ddd86e4aa | |||
| 87dd96adbd | |||
| 9de0095c8d | |||
| 7480da7568 |
@@ -2,3 +2,5 @@ mode:regex
|
||||
^_dist/
|
||||
^sites/[^/]+/data/
|
||||
^sites/[^/]+/wwwroot/
|
||||
|
||||
^shields_cache/
|
||||
|
||||
1
.hgtags
@@ -1,2 +1,3 @@
|
||||
42a17645b5b21d7fe395767de7fa3e26ee999014 release-r54
|
||||
0f89ae041c2ee60cc1ea308d047fce816b19c490 release-r64
|
||||
d4733a95c3428db8722ce0d0350d17bbbabc8720 release-r72
|
||||
|
||||
93
rebuild.php
@@ -3,6 +3,21 @@
|
||||
// Code-hosting website
|
||||
// ````````````````````
|
||||
|
||||
function mkshield($left_str, $right_str, $color_str) {
|
||||
$filename = rawurlencode(str_replace('-', '--', $left_str)).'-'.rawurlencode(str_replace('-', '--', $right_str)).'-'.rawurlencode($color_str).'.svg';
|
||||
$cache_path = __DIR__.'/../../shields_cache/'.$filename;
|
||||
|
||||
if (file_exists($cache_path)) {
|
||||
return file_get_contents($cache_path);
|
||||
|
||||
} else {
|
||||
$retn = file_get_contents('https://img.shields.io/badge/'.$filename);
|
||||
file_put_contents($cache_path, $retn);
|
||||
return $retn;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a thumbnail of an image. It overscales, centers, and crops to fit the
|
||||
* target dimensions.
|
||||
@@ -116,11 +131,20 @@ function text2html($sz) {
|
||||
|
||||
$base = preg_replace('~^=+(.+)=+~m', '<strong>\\1</strong>', $base);
|
||||
$base = preg_replace('~(https?://[^ \\r\\n\\t]+)~i', '<a href="\\1">\\1</a>', $base);
|
||||
$base = preg_replace('~\\[b\\](.+?)\\[/b\\]~m', '<strong>\\1</strong>', $base);
|
||||
$base = preg_replace('~\\[i\\](.+?)\\[/i\\]~m', '<i>\\1</i>', $base);
|
||||
$base = preg_replace('~\\[spoiler\\](.+?)\\[/spoiler\\]~m', '<span class="spoiler">\\1</span>', $base);
|
||||
$base = preg_replace('~\\[entry=([^\\]]+?)\\](.+?)\\[/entry\\]~m', '<a href="\\1.html">\\2</a>', $base);
|
||||
$base = preg_replace('~\n- ~ms', "\n• ", $base);
|
||||
|
||||
$btparts = explode('`', $base);
|
||||
if (count($btparts) > 1 && (count($btparts) % 2)) {
|
||||
for ($i = 1, $e = count($btparts); $i < $e; $i += 2) {
|
||||
$btparts[$i] = '<span class="code">'.$btparts[$i].'</span>';
|
||||
$class = 'code';
|
||||
if (strpos($btparts[$i], "\n") !== false) {
|
||||
$class .= ' code-multiline';
|
||||
}
|
||||
$btparts[$i] = '<span class="'.$class.'">'.$btparts[$i].'</span>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,6 +177,7 @@ class CProject {
|
||||
public $subtag = '';
|
||||
public $lastupdate = 0;
|
||||
private $longdesc = '';
|
||||
private $prefix_html = '';
|
||||
private $images = array();
|
||||
private $downloads = array();
|
||||
private $downloads_hashes = array();
|
||||
@@ -167,13 +192,23 @@ class CProject {
|
||||
// Identify resources in folder
|
||||
|
||||
$ls = scandir($this->dir);
|
||||
$found_real_lastupdate = false;
|
||||
foreach($ls as $file) {
|
||||
if ($file[0] == '.') continue;
|
||||
|
||||
if ($file == 'README.txt') {
|
||||
$this->lastupdate = max($this->lastupdate, filectime($this->dir.$file)); // don't count README updates
|
||||
|
||||
// Guess 'last update' time
|
||||
$matches = [];
|
||||
if (preg_match('~\n(\d\d\d\d-\d\d-\d\d)~', $this->longdesc, $matches)) {
|
||||
// Use first date entry (assumed to be a CHANGELOG)
|
||||
$this->lastupdate = strtotime($matches[1]);
|
||||
$found_real_lastupdate = true;
|
||||
|
||||
}
|
||||
|
||||
$this->longdesc = file_get_contents($this->dir.'README.txt');
|
||||
|
||||
$matches = array();
|
||||
if (preg_match('~Written in ([^\\r\\n]+)~', $this->longdesc, $matches)) {
|
||||
$this->subtag = rtrim($matches[1], ' .');
|
||||
@@ -186,14 +221,36 @@ class CProject {
|
||||
$parts = explode("\n", $this->longdesc);
|
||||
$this->shortdesc = array_shift($parts);
|
||||
$this->shortdesc[0] = strtolower($this->shortdesc[0]); // cosmetic lowercase
|
||||
|
||||
// Filter longdesc
|
||||
$this->longdesc = str_replace("\r", "", $this->longdesc); // filter windows CR
|
||||
|
||||
$prefix_html = '';
|
||||
$this->longdesc = preg_replace_callback('~\r?\nWritten in ([^\\n]+)~ms', function($matches) use (&$prefix_html) {
|
||||
$prefix_html .= (
|
||||
(SHIELDS_PREFIX ? mkshield('build', 'success', 'brightgreen').' ' : '').
|
||||
mkshield('written in', $matches[1], 'blue')
|
||||
);
|
||||
return '';
|
||||
}, $this->longdesc);
|
||||
|
||||
while(strpos($this->longdesc, "\n\n\n") !== false) {
|
||||
$this->longdesc = str_replace("\n\n\n", "\n\n", $this->longdesc);
|
||||
}
|
||||
$this->longdesc = rtrim($this->longdesc, "\n");
|
||||
|
||||
$this->prefix_html = $prefix_html;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->lastupdate = max(
|
||||
$this->lastupdate,
|
||||
// filectime($this->dir.$file),
|
||||
filemtime($this->dir.$file)
|
||||
);
|
||||
|
||||
if (! $found_real_lastupdate) {
|
||||
$this->lastupdate = max(
|
||||
$this->lastupdate,
|
||||
// filectime($this->dir.$file),
|
||||
($file == 'README.txt' ? filectime($this->dir.$file) : filemtime($this->dir.$file)) // Don't count README updates
|
||||
);
|
||||
}
|
||||
|
||||
if (is_image($file)) {
|
||||
$this->images[] = $file;
|
||||
@@ -273,13 +330,17 @@ class CProject {
|
||||
|
||||
public function index() {
|
||||
?>
|
||||
<h2><?=hesc($this->projname)?></h2>
|
||||
<h2><?=hesc(str_replace('_', ' ', $this->projname))?></h2>
|
||||
|
||||
<div class="projinfo">
|
||||
|
||||
<div class="projbody projbody_<?=(count($this->images) ? 'half' : 'full')?>w">
|
||||
|
||||
<strong>ABOUT</strong>
|
||||
<?php if (strlen($this->prefix_html)) { ?>
|
||||
<p style="margin-top:0;"><?=$this->prefix_html?></p>
|
||||
<?php } ?>
|
||||
|
||||
<strong><?=hesc(strtoupper(ARTICLE_HEADER))?></strong>
|
||||
|
||||
<p><?=text2html($this->longdesc)?></p>
|
||||
|
||||
@@ -328,7 +389,7 @@ function template($title, $content) {
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
|
||||
<meta name="viewport" content="width=768px" >
|
||||
<meta name="viewport" content="width=960" >
|
||||
<link type="text/css" rel="stylesheet" href="normalize.css">
|
||||
<link type="text/css" rel="stylesheet" href="style.css">
|
||||
<script type="text/javascript" src="site.js"></script>
|
||||
@@ -355,6 +416,7 @@ function listprojects() {
|
||||
$projects = array();
|
||||
foreach($ls as $dirname) {
|
||||
if ($dirname[0] == '.') continue;
|
||||
if (! is_dir(BASEDIR.'data/'.$dirname)) continue;
|
||||
$matches = array();
|
||||
|
||||
if (preg_match('~(?:\d+-)?(.+)~', $dirname, $matches)) {
|
||||
@@ -448,9 +510,10 @@ function buildcommon() {
|
||||
<a href="<?=hesc(urlencode($pr->projname))?>.html"><?=(is_null($handle_lookup[$pr->projname]) ? '<div class="no-image"></div>' : '<div class="homeimage homeimage-sprite" style="background-position:0 -'.($handle_lookup[$pr->projname]*INDEX_THUMB_H).'px"></div>')?></a>
|
||||
</td>
|
||||
<td>
|
||||
<strong><?=hesc($pr->projname)?></strong>,
|
||||
<strong><?=hesc(str_replace('_', ' ', $pr->projname))?></strong><?php if (SHOW_BLURBS) { ?>,
|
||||
<?=hesc($pr->shortdesc)?>
|
||||
<a href="<?=hesc(urlencode($pr->projname))?>.html">more...</a>
|
||||
<?php } ?>
|
||||
<a href="<?=hesc(urlencode($pr->projname))?>.html" class="article-read-more">more...</a>
|
||||
<?php if (strlen($pr->subtag) || count($pr->tags)) { ?>
|
||||
<br>
|
||||
<small>
|
||||
@@ -510,6 +573,9 @@ function main($args) {
|
||||
define('PAGE_THUMB_H', intval($config['codesite']['page_thumb_h']));
|
||||
define('INDEX_THUMB_W', intval($config['codesite']['index_thumb_w']));
|
||||
define('INDEX_THUMB_H', intval($config['codesite']['index_thumb_h']));
|
||||
define('SHOW_BLURBS', !(isset($config['codesite']['blurbs']) && $config['codesite']['blurbs'] === 'off') );
|
||||
define('ARTICLE_HEADER', (isset($config['codesite']['article_header']) ? $config['codesite']['article_header'] : 'ABOUT') );
|
||||
define('SHIELDS_PREFIX', isset($config['codesite']['shields_prefix']));
|
||||
|
||||
// Perform build tasks
|
||||
|
||||
@@ -527,6 +593,7 @@ function main($args) {
|
||||
//
|
||||
|
||||
ini_set('display_errors', 'On');
|
||||
date_default_timezone_set('Etc/UTC');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
main(array_slice($_SERVER['argv'], 1));
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
PHP=/cygdrive/c/bin/php/php.exe
|
||||
THREADS=4
|
||||
|
||||
buildsite() {
|
||||
@@ -40,7 +39,7 @@ buildsite() {
|
||||
echo "Building pages..."
|
||||
|
||||
for i in $(seq 0 "$THREADS") ; do
|
||||
$PHP "$rebuild" "$THREADS" "$i" &
|
||||
php "$rebuild" "$THREADS" "$i" &
|
||||
done
|
||||
wait
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ page_thumb_h=60
|
||||
index_thumb_w=90
|
||||
index_thumb_h=32
|
||||
|
||||
shields_prefix=true
|
||||
|
||||
; n.b. Recommend a multiple of the JPEG iDCT block size for index_thumb_h
|
||||
|
||||
[redirect]
|
||||
|
||||
BIN
sites/code.ivysaur.me/static/greyzz.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
BIN
sites/code.ivysaur.me/static/greyzz_@2X.png
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
@@ -7,14 +7,15 @@ img {
|
||||
border:0;
|
||||
}
|
||||
a {
|
||||
color:black;
|
||||
text-decoration:underline;
|
||||
color:#4078c0;
|
||||
text-decoration:none;
|
||||
}
|
||||
a:hover {
|
||||
color:blue;
|
||||
cursor:pointer;
|
||||
text-decoration:underline;
|
||||
}
|
||||
h1 a {
|
||||
color:black;
|
||||
text-decoration:none;
|
||||
}
|
||||
h1 a:hover {
|
||||
@@ -28,6 +29,11 @@ h1,h2,h3 {
|
||||
font-family:Consolas,monospace;
|
||||
white-space:pre;
|
||||
}
|
||||
.code-multiline {
|
||||
display:inline-block;
|
||||
padding:8px;
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
@@ -41,14 +47,15 @@ html, body {
|
||||
|
||||
/* cosmetic */
|
||||
font-family:"Helvetica Neue","Segoe UI",Arial,sans-serif;
|
||||
font-size:12px;
|
||||
background:#DDD url('pixel_weave.png'); /* thanks subtlepatterns.com ! */
|
||||
font-size:13px;
|
||||
line-height:1.4;
|
||||
background:#DDD url('greyzz.png'); /* thanks subtlepatterns.com ! */
|
||||
color:#333;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin:0 auto;
|
||||
width:768px;
|
||||
width:960px;
|
||||
position:relative;
|
||||
|
||||
height:auto !important;
|
||||
@@ -119,7 +126,7 @@ html, body {
|
||||
}
|
||||
.projbody_halfw {
|
||||
float:left;
|
||||
width: 678px; /* 740px full - 60px rhs column - 2px border */
|
||||
width: 860px; /* 740px full - 60px rhs column - 2px border */
|
||||
}
|
||||
.projbody_fullw {
|
||||
|
||||
@@ -131,6 +138,24 @@ html, body {
|
||||
|
||||
/* */
|
||||
|
||||
@media screen and (max-width:960px) {
|
||||
|
||||
#container {
|
||||
width:100%;
|
||||
}
|
||||
.projimg {
|
||||
float:clear;
|
||||
width:100%;
|
||||
}
|
||||
.projbody_halfw {
|
||||
float:clear;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
#ivylogo {
|
||||
background:transparent url('ivysaur24.png') no-repeat 0 0;
|
||||
width:24px;
|
||||
|
||||
11
sites/storytime.ivysaur.me/config.ini
Normal file
@@ -0,0 +1,11 @@
|
||||
[codesite]
|
||||
title=storytime.ivysaur.me
|
||||
page_thumb_w=60
|
||||
page_thumb_h=60
|
||||
index_thumb_w=90
|
||||
index_thumb_h=32
|
||||
|
||||
blurbs=off
|
||||
article_header=ARTICLE
|
||||
|
||||
; n.b. Recommend a multiple of the JPEG iDCT block size for index_thumb_h
|
||||
10
sites/storytime.ivysaur.me/footer.htm
Normal file
@@ -0,0 +1,10 @@
|
||||
<p>
|
||||
<strong>CONTACT</strong>
|
||||
</p>
|
||||
<p>
|
||||
<a
|
||||
href="http://www.google.com/recaptcha/mailhide/d?k=01GuAWzMc9JjSdooo-2KCMQA==&c=kgR3dBrP39yhPIy8FvLFbuBLmWqorQBDc_Zjbw6NAmU="
|
||||
onclick="window.open('http://www.google.com/recaptcha/mailhide/d?k\07501GuAWzMc9JjSdooo-2KCMQA\75\75\46c\75kgR3dBrP39yhPIy8FvLFbuBLmWqorQBDc_Zjbw6NAmU\075', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;"
|
||||
title="Reveal this e-mail address"
|
||||
>Click here</a> to email me.
|
||||
</p>
|
||||
1
sites/storytime.ivysaur.me/header.htm
Normal file
@@ -0,0 +1 @@
|
||||
<h1><a href="index.html"><div id="ivylogo"></div>storytime.ivysaur.me</a></h1>
|
||||
12
sites/storytime.ivysaur.me/homepage_blurb.htm
Normal file
@@ -0,0 +1,12 @@
|
||||
<p>
|
||||
The stories and information posted here are artistic works of fiction and falsehood. Only a fool would take anything posted here as fact.
|
||||
</p>
|
||||
<p>
|
||||
<strong>LICENSE</strong>
|
||||
</p>
|
||||
<p>
|
||||
Please consider all articles on this page to be under the <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0 International license</a> unless otherwise specified.
|
||||
</p>
|
||||
<p>
|
||||
<strong>ARTICLES</strong>
|
||||
</p>
|
||||
BIN
sites/storytime.ivysaur.me/static/11.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
sites/storytime.ivysaur.me/static/favicon.ico
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
sites/storytime.ivysaur.me/static/ivysaur24.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
sites/storytime.ivysaur.me/static/no_image.png
Normal file
|
After Width: | Height: | Size: 416 B |
|
Before Width: | Height: | Size: 233 B After Width: | Height: | Size: 233 B |
|
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
187
sites/storytime.ivysaur.me/static/style.css
Normal file
@@ -0,0 +1,187 @@
|
||||
/* style.css */
|
||||
|
||||
html {
|
||||
overflow-y:scroll; /* always display scrollbar to prevent horizontal lurch */
|
||||
}
|
||||
img {
|
||||
border:0;
|
||||
}
|
||||
a {
|
||||
color:black;
|
||||
text-decoration:underline;
|
||||
}
|
||||
a:hover {
|
||||
color:blue;
|
||||
cursor:pointer;
|
||||
}
|
||||
h1 a {
|
||||
text-decoration:none;
|
||||
}
|
||||
h1 a:hover {
|
||||
color:black;
|
||||
}
|
||||
h1,h2,h3 {
|
||||
margin-top:0;
|
||||
}
|
||||
.code {
|
||||
background: #F8F8F8;
|
||||
font-family:Consolas,monospace;
|
||||
white-space:pre;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
html, body {
|
||||
/* structural */
|
||||
height:100%;
|
||||
min-height:100%;
|
||||
margin:0;
|
||||
border:0;
|
||||
padding:0;
|
||||
|
||||
/* cosmetic */
|
||||
font-family:"Helvetica Neue","Segoe UI",Arial,sans-serif;
|
||||
font-size:12px;
|
||||
background:#DDD url('pixel_weave.png'); /* thanks subtlepatterns.com ! */
|
||||
color:#333;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin:0 auto;
|
||||
width:768px;
|
||||
position:relative;
|
||||
|
||||
height:auto !important;
|
||||
height:100%; /* oldIE */
|
||||
min-height:100%;
|
||||
|
||||
/* cosmetic */
|
||||
background:white;
|
||||
}
|
||||
|
||||
#content {
|
||||
padding:14px;
|
||||
background:white;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
.tag::before {
|
||||
content:"";
|
||||
|
||||
display:inline-block;
|
||||
width:7px;
|
||||
height:7px;
|
||||
|
||||
margin-right:2px;
|
||||
|
||||
background:transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAZUlEQVQI12P4//8/Awyrqqp6KSkp/QdhFRWV7cgS+kDBN0B8RVlZuRikACahB+T8ger6BMTXwJJAiTwg4xvMOCj+ART3ZwCa3YYm8QcopgsyEWasDVT3W5AVMHcgO6gViNORXQ8A84NToxbSsJcAAAAASUVORK5CYII=') no-repeat 0 0;
|
||||
}
|
||||
|
||||
.tag-filter-warn {
|
||||
position:fixed;
|
||||
top:0;
|
||||
right:0;
|
||||
|
||||
padding:4px;
|
||||
|
||||
background:lightyellow;
|
||||
border-bottom: 1px solid #888;
|
||||
border-left:1px solid #888;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
.projtable {
|
||||
border-collapse: collapse;
|
||||
width:100%;
|
||||
}
|
||||
.projtable tr {
|
||||
transition:0.2s linear;
|
||||
}
|
||||
.projtable tr:hover {
|
||||
background:#F8F8F8;
|
||||
}
|
||||
.projtable td {
|
||||
padding: 2px 4px;
|
||||
}
|
||||
.projtable small {
|
||||
color:grey;
|
||||
font-style:italic;
|
||||
}
|
||||
.projtable tr td:first-child {
|
||||
width:95px;
|
||||
}
|
||||
|
||||
.projinfo {
|
||||
}
|
||||
.projbody {
|
||||
}
|
||||
.projbody_halfw {
|
||||
float:left;
|
||||
width: 678px; /* 740px full - 60px rhs column - 2px border */
|
||||
}
|
||||
.projbody_fullw {
|
||||
|
||||
}
|
||||
.projimg {
|
||||
float:right;
|
||||
width:62px; /* 60px + 2px border */
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
#ivylogo {
|
||||
background:transparent url('ivysaur24.png') no-repeat 0 0;
|
||||
width:24px;
|
||||
height:24px;
|
||||
display:inline-block;
|
||||
*display:block;
|
||||
*zoom:1;
|
||||
margin-right:4px;
|
||||
position:relative;
|
||||
top:4px;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
.homeimage {
|
||||
width:90px;
|
||||
height:32px;
|
||||
}
|
||||
|
||||
.homeimage-sprite {
|
||||
background: white url('logos.jpg') no-repeat 0 0;
|
||||
}
|
||||
|
||||
.thumbimage {
|
||||
width:60px;
|
||||
height:60px;
|
||||
opacity: 0.8;
|
||||
transition:0.2s opacity;
|
||||
border:1px solid lightgrey;
|
||||
}
|
||||
.thumbimage:hover {
|
||||
opacity:1.0;
|
||||
}
|
||||
|
||||
.no-image {
|
||||
width:90px;
|
||||
height:32px;
|
||||
display:block;
|
||||
background: white url('no_image.png') no-repeat 0 0;
|
||||
}
|
||||
|
||||
/* */
|
||||
|
||||
.spoiler {
|
||||
color:black;
|
||||
background:black;
|
||||
}
|
||||
.spoiler:hover {
|
||||
color:white;
|
||||
}
|
||||
|
||||
.article-read-more {
|
||||
display:none;
|
||||
}
|
||||