Compare commits
58 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 | |||
| 81c65b3cce | |||
| 441c05f096 | |||
| 671573bc2e | |||
| 17b0bea213 | |||
| 0ad96058d5 | |||
| 092efca34d | |||
| 0303019641 | |||
| 8efff11ac2 | |||
| 4a6f8d90d8 | |||
| b572d957fc | |||
| 0f70fc7bf0 | |||
| a38b0dbea5 | |||
| 42f4bca8ba | |||
| 2f254fd355 | |||
| f54c388b1a | |||
| ee66a10fc3 | |||
| d52f58ecae | |||
| 376745b825 | |||
| 1c432afdbf | |||
| df731a8171 | |||
| 503bdbd527 | |||
| 8b153119ea | |||
| de3e1f1210 | |||
| e693abc079 | |||
| 72bf8d9410 | |||
| 8736cc97b4 | |||
| 2eac27a439 | |||
| bbbfba2e8f | |||
| 97c06514eb | |||
| 4c3e285547 | |||
| 40a86b41c7 | |||
| 301d81a637 | |||
| dc260a27d6 |
@@ -1,3 +1,6 @@
|
|||||||
wwwroot/*
|
mode:regex
|
||||||
nbproject/*
|
^_dist/
|
||||||
data/*
|
^sites/[^/]+/data/
|
||||||
|
^sites/[^/]+/wwwroot/
|
||||||
|
|
||||||
|
^shields_cache/
|
||||||
|
|||||||
3
.hgtags
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
42a17645b5b21d7fe395767de7fa3e26ee999014 release-r54
|
||||||
|
0f89ae041c2ee60cc1ea308d047fce816b19c490 release-r64
|
||||||
|
d4733a95c3428db8722ce0d0350d17bbbabc8720 release-r72
|
||||||
8
TODO.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
- Merge "written in" and "tags"
|
||||||
|
|
||||||
|
- RSS for recent changes
|
||||||
|
|
||||||
|
- RSS for all projects
|
||||||
|
|
||||||
|
- Switchable CSS (reddit theme, 4chan theme, HN theme)
|
||||||
46
_dist/README.txt
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
A static site generator for a portfolio website.
|
||||||
|
|
||||||
|
The scripts used to generate the code.ivysaur.me website.
|
||||||
|
|
||||||
|
Written in PHP, Bash
|
||||||
|
|
||||||
|
=FEATURES=
|
||||||
|
|
||||||
|
- Generates static website, minimising server load and decreasing attack surface compared to dynamic server-side PHP
|
||||||
|
- Automatic thumbnailing and sprite sheet generation
|
||||||
|
- Download file attachments per-project
|
||||||
|
- One-click rebuild, one-click deploy
|
||||||
|
- Parallel generation
|
||||||
|
|
||||||
|
=CHANGELOG=
|
||||||
|
|
||||||
|
2015-04-05: r72
|
||||||
|
- Feature: Support redirecting old project names
|
||||||
|
- Feature: Add file hash in download URLs to prevent filename collisions
|
||||||
|
- Fix an issue generating spritesheets even if no project images are present
|
||||||
|
- Don't include `ctime` when estimating project update time
|
||||||
|
|
||||||
|
2015-04-05: r64
|
||||||
|
- Feature: Support sorting projects
|
||||||
|
|
||||||
|
2015-04-04: r54
|
||||||
|
- Feature: Support multiple code sites
|
||||||
|
- Fix an issue with parallel builds on some versions of windows
|
||||||
|
- Fix an issue corrupting URL links with multiple parameters
|
||||||
|
- Fix a cosmetic issue with page overflow
|
||||||
|
- Fix a cosmetic issue with whitespace on code elements
|
||||||
|
|
||||||
|
2014-07-02: r39
|
||||||
|
- Feature: Tags
|
||||||
|
- Feature: Generate pages in parallel
|
||||||
|
- Enhancement: Support raw HTML sections in page content
|
||||||
|
- Fix an issue with URLs containing spaces
|
||||||
|
- Fix a cosmetic issue with image thumbnail backgrounds
|
||||||
|
- Fix a cosmetic issue with download sort order
|
||||||
|
- Fix a cosmetic issue with page layout
|
||||||
|
|
||||||
|
2013-09-28: r13
|
||||||
|
- Initial public source code release
|
||||||
|
|
||||||
|
2013-09-21: r3
|
||||||
|
- Initial deployment
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
|
|
||||||
start C:\path\to\cygwin\bin\mintty.exe /bin/bash -l -c "rsync -avz -e ""ssh -i /cygdrive/c/path/to/deploy_key"" --progress /cygdrive/c/path/to/code/wwwroot www-data@your-web-server:/var/www/path/to/code-site/"
|
|
||||||
16
deploy.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
LOCALDIR=/cygdrive/c/www/m6/code/sites/code.ivysaur.me/wwwroot
|
||||||
|
|
||||||
|
chmod -R 644 "$LOCALDIR"
|
||||||
|
chmod -R a+X "$LOCALDIR"
|
||||||
|
|
||||||
|
rsync --delete -avz -e "ssh -i /cygdrive/c/www/ms1_deploy_key -p 2222" --progress \
|
||||||
|
"$LOCALDIR" \
|
||||||
|
www-data@ms1.ivysaur.me:~/code.ivysaur.me/
|
||||||
|
|
||||||
|
# n.b. set chmod -R a+rX remote side?
|
||||||
|
|
||||||
|
read -p "Press any key to continue..."
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
<p>
|
|
||||||
Homepage blurb goes here.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<strong>PROJECTS</strong>
|
|
||||||
</p>
|
|
||||||
9
mkdist.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
tar cJvf "codesite-$(date +%s).tar.xz" \
|
||||||
|
rebuild.php rebuild.sh sites/codesite.example.com static_global \
|
||||||
|
--owner=0 --group=0
|
||||||
|
|
||||||
|
read -p "Press any key to continue..."
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
@echo off
|
|
||||||
C:\path\to\php_54\php.exe rebuild.php
|
|
||||||
pause
|
|
||||||
226
rebuild.php
@@ -3,15 +3,20 @@
|
|||||||
// Code-hosting website
|
// Code-hosting website
|
||||||
// ````````````````````
|
// ````````````````````
|
||||||
|
|
||||||
// CONFIGURATION
|
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;
|
||||||
|
|
||||||
define('BASEDIR', __DIR__.'\\');
|
if (file_exists($cache_path)) {
|
||||||
define('SITE_TITLE', 'codesite');
|
return file_get_contents($cache_path);
|
||||||
define('PAGE_THUMB_W', 60);
|
|
||||||
define('PAGE_THUMB_H', 60);
|
} else {
|
||||||
define('INDEX_THUMB_W', 90);
|
$retn = file_get_contents('https://img.shields.io/badge/'.$filename);
|
||||||
define('INDEX_THUMB_H', 32); // recommend a multiple of the jpg iDCT block size
|
file_put_contents($cache_path, $retn);
|
||||||
|
return $retn;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a thumbnail of an image. It overscales, centers, and crops to fit the
|
* Create a thumbnail of an image. It overscales, centers, and crops to fit the
|
||||||
@@ -97,23 +102,6 @@ function hesc($sz) {
|
|||||||
|
|
||||||
function text2html($sz) {
|
function text2html($sz) {
|
||||||
|
|
||||||
$sectionFmt = function($sz) {
|
|
||||||
$base = hesc($sz);
|
|
||||||
|
|
||||||
$base = preg_replace('~=+(.+)=+~', '<strong>\\1</strong>', $base);
|
|
||||||
$base = preg_replace('~(https?://[^ \\r\\n\\t]+)~i', '<a href="\\1">\\1</a>', $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>';
|
|
||||||
}
|
|
||||||
$base = implode('', $btparts);
|
|
||||||
}
|
|
||||||
|
|
||||||
return nl2br($base);
|
|
||||||
};
|
|
||||||
|
|
||||||
$identity = function($sz) {
|
$identity = function($sz) {
|
||||||
return $sz;
|
return $sz;
|
||||||
};
|
};
|
||||||
@@ -138,6 +126,31 @@ function text2html($sz) {
|
|||||||
return implode($join, $ret);
|
return implode($join, $ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$sectionFmt = function($sz) use($oddEven, $identity) {
|
||||||
|
$base = hesc($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) {
|
||||||
|
$class = 'code';
|
||||||
|
if (strpos($btparts[$i], "\n") !== false) {
|
||||||
|
$class .= ' code-multiline';
|
||||||
|
}
|
||||||
|
$btparts[$i] = '<span class="'.$class.'">'.$btparts[$i].'</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $oddEven($btparts, $identity, 'nl2br');
|
||||||
|
};
|
||||||
|
|
||||||
$htmlSections = $splitInside('<html>', '</html>', $sz);
|
$htmlSections = $splitInside('<html>', '</html>', $sz);
|
||||||
return $oddEven($htmlSections, $identity, $sectionFmt);
|
return $oddEven($htmlSections, $identity, $sectionFmt);
|
||||||
}
|
}
|
||||||
@@ -162,9 +175,12 @@ class CProject {
|
|||||||
public $projname;
|
public $projname;
|
||||||
public $shortdesc = '(no description)';
|
public $shortdesc = '(no description)';
|
||||||
public $subtag = '';
|
public $subtag = '';
|
||||||
|
public $lastupdate = 0;
|
||||||
private $longdesc = '';
|
private $longdesc = '';
|
||||||
|
private $prefix_html = '';
|
||||||
private $images = array();
|
private $images = array();
|
||||||
private $downloads = array();
|
private $downloads = array();
|
||||||
|
private $downloads_hashes = array();
|
||||||
public $tags = array();
|
public $tags = array();
|
||||||
|
|
||||||
public $homeimage = null;
|
public $homeimage = null;
|
||||||
@@ -176,11 +192,23 @@ class CProject {
|
|||||||
// Identify resources in folder
|
// Identify resources in folder
|
||||||
|
|
||||||
$ls = scandir($this->dir);
|
$ls = scandir($this->dir);
|
||||||
|
$found_real_lastupdate = false;
|
||||||
foreach($ls as $file) {
|
foreach($ls as $file) {
|
||||||
if ($file[0] == '.') continue;
|
if ($file[0] == '.') continue;
|
||||||
|
|
||||||
if ($file == 'README.txt') {
|
if ($file == 'README.txt') {
|
||||||
|
|
||||||
|
// 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');
|
$this->longdesc = file_get_contents($this->dir.'README.txt');
|
||||||
|
|
||||||
$matches = array();
|
$matches = array();
|
||||||
if (preg_match('~Written in ([^\\r\\n]+)~', $this->longdesc, $matches)) {
|
if (preg_match('~Written in ([^\\r\\n]+)~', $this->longdesc, $matches)) {
|
||||||
$this->subtag = rtrim($matches[1], ' .');
|
$this->subtag = rtrim($matches[1], ' .');
|
||||||
@@ -193,9 +221,37 @@ class CProject {
|
|||||||
$parts = explode("\n", $this->longdesc);
|
$parts = explode("\n", $this->longdesc);
|
||||||
$this->shortdesc = array_shift($parts);
|
$this->shortdesc = array_shift($parts);
|
||||||
$this->shortdesc[0] = strtolower($this->shortdesc[0]); // cosmetic lowercase
|
$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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)) {
|
if (is_image($file)) {
|
||||||
$this->images[] = $file;
|
$this->images[] = $file;
|
||||||
} else {
|
} else {
|
||||||
@@ -205,13 +261,19 @@ class CProject {
|
|||||||
|
|
||||||
natcasesort($this->downloads);
|
natcasesort($this->downloads);
|
||||||
$this->downloads = array_reverse($this->downloads);
|
$this->downloads = array_reverse($this->downloads);
|
||||||
|
|
||||||
|
for($i = 0, $e = count($this->downloads); $i !== $e; ++$i) {
|
||||||
|
$this->downloads_hashes[] = (
|
||||||
|
sha1_file($this->dir.$this->downloads[$i])
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function genHomeImage() {
|
public function genHomeImage() {
|
||||||
if (count($this->images)) {
|
if (count($this->images)) {
|
||||||
|
|
||||||
$this->homeimage = mkthumbnail(
|
$this->homeimage = mkthumbnail(
|
||||||
$this->dir.$this->images[0], //BASEDIR.'wwwroot/srv/'.$this->projname.'_0.'.str_ext($this->images[0]),
|
$this->dir.$this->images[0],
|
||||||
null, // raw handle
|
null, // raw handle
|
||||||
INDEX_THUMB_W, INDEX_THUMB_H
|
INDEX_THUMB_W, INDEX_THUMB_H
|
||||||
);
|
);
|
||||||
@@ -233,7 +295,21 @@ class CProject {
|
|||||||
// Copy downloads to wwwroot
|
// Copy downloads to wwwroot
|
||||||
|
|
||||||
foreach($this->downloads as $idx => $filename) {
|
foreach($this->downloads as $idx => $filename) {
|
||||||
copy($this->dir.$filename, BASEDIR.'wwwroot/srv/'.$filename);
|
$cmkdir = @mkdir( BASEDIR.'wwwroot/srv/'.$this->downloads_hashes[$idx] );
|
||||||
|
|
||||||
|
if (! $cmkdir) {
|
||||||
|
fputs(
|
||||||
|
STDOUT,
|
||||||
|
"WARNING: Couldn't create directory ".$this->downloads_hashes[$idx].
|
||||||
|
" for file '${filename}'".
|
||||||
|
" in project '".$this->projname."'!\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(
|
||||||
|
$this->dir.$filename,
|
||||||
|
BASEDIR.'wwwroot/srv/'.$this->downloads_hashes[$idx].'/'.$filename
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate index page
|
// Generate index page
|
||||||
@@ -254,28 +330,32 @@ class CProject {
|
|||||||
|
|
||||||
public function index() {
|
public function index() {
|
||||||
?>
|
?>
|
||||||
<h2><?=hesc($this->projname)?></h2>
|
<h2><?=hesc(str_replace('_', ' ', $this->projname))?></h2>
|
||||||
|
|
||||||
<div class="projinfo">
|
<div class="projinfo">
|
||||||
|
|
||||||
<div class="projbody projbody_<?=(count($this->images) ? 'half' : 'full')?>w">
|
<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>
|
<p><?=text2html($this->longdesc)?></p>
|
||||||
|
|
||||||
<?=file_get_contents(__DIR__.'/footer.htm')?>
|
<?=file_get_contents(BASEDIR.'/footer.htm')?>
|
||||||
|
|
||||||
<?php if (count($this->downloads)) { ?>
|
<?php if (count($this->downloads)) { ?>
|
||||||
|
|
||||||
<strong>DOWNLOAD</strong>
|
<strong>DOWNLOAD</strong>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach($this->downloads as $filename) { ?>
|
<?php foreach($this->downloads as $idx => $filename) { ?>
|
||||||
<li>
|
<li>
|
||||||
<a href="srv/<?=hesc(rawurlencode($filename))?>"><?=hesc($filename)?></a>
|
<a href="srv/<?=hesc($this->downloads_hashes[$idx])?>/<?=hesc(rawurlencode($filename))?>"><?=hesc($filename)?></a>
|
||||||
<small>
|
<small>
|
||||||
<?=hesc(fbytes(filesize(BASEDIR.'wwwroot/srv/'.$filename)))?>
|
<?=hesc(fbytes(filesize(BASEDIR.'wwwroot/srv/'.$this->downloads_hashes[$idx].'/'.$filename)))?>
|
||||||
</small>
|
</small>
|
||||||
</li>
|
</li>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
@@ -289,6 +369,9 @@ class CProject {
|
|||||||
<a href="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>.<?=str_ext($origname)?>"><img src="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>_thumb.jpg" class="thumbimage"></a>
|
<a href="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>.<?=str_ext($origname)?>"><img src="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>_thumb.jpg" class="thumbimage"></a>
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="clear:both;"></div>
|
||||||
|
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -306,7 +389,7 @@ function template($title, $content) {
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="Content-Type" content="text/html; 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="normalize.css">
|
||||||
<link type="text/css" rel="stylesheet" href="style.css">
|
<link type="text/css" rel="stylesheet" href="style.css">
|
||||||
<script type="text/javascript" src="site.js"></script>
|
<script type="text/javascript" src="site.js"></script>
|
||||||
@@ -315,7 +398,7 @@ function template($title, $content) {
|
|||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<?=file_get_contents(__DIR__.'/header.htm')?>
|
<?=file_get_contents(BASEDIR.'/header.htm')?>
|
||||||
<?=$content?>
|
<?=$content?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -333,6 +416,7 @@ function listprojects() {
|
|||||||
$projects = array();
|
$projects = array();
|
||||||
foreach($ls as $dirname) {
|
foreach($ls as $dirname) {
|
||||||
if ($dirname[0] == '.') continue;
|
if ($dirname[0] == '.') continue;
|
||||||
|
if (! is_dir(BASEDIR.'data/'.$dirname)) continue;
|
||||||
$matches = array();
|
$matches = array();
|
||||||
|
|
||||||
if (preg_match('~(?:\d+-)?(.+)~', $dirname, $matches)) {
|
if (preg_match('~(?:\d+-)?(.+)~', $dirname, $matches)) {
|
||||||
@@ -368,6 +452,8 @@ function buildcommon() {
|
|||||||
$handles = array();
|
$handles = array();
|
||||||
$handle_lookup = array();
|
$handle_lookup = array();
|
||||||
|
|
||||||
|
$alphasort = [];
|
||||||
|
|
||||||
foreach($projects as $dirname => $projectname) {
|
foreach($projects as $dirname => $projectname) {
|
||||||
|
|
||||||
$pr = new CProject($dirname, $projectname);
|
$pr = new CProject($dirname, $projectname);
|
||||||
@@ -381,12 +467,26 @@ function buildcommon() {
|
|||||||
$handle_lookup[$projectname] = count($handles);
|
$handle_lookup[$projectname] = count($handles);
|
||||||
$handles[] = $pr->homeimage;
|
$handles[] = $pr->homeimage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$alphasort[] = [$pr->projname, count($plist)-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($alphasort, function($a, $b) {
|
||||||
|
return strcasecmp($a[0], $b[0]);
|
||||||
|
});
|
||||||
|
|
||||||
|
$alphaidx = [];
|
||||||
|
|
||||||
|
foreach($alphasort as $a) {
|
||||||
|
$alphaidx[ $a[1] ] = count($alphaidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build homepage spritesheet
|
// Build homepage spritesheet
|
||||||
|
|
||||||
|
if (count($handles)) {
|
||||||
mkspritesheet($handles, BASEDIR.'wwwroot/logos.jpg', INDEX_THUMB_W, INDEX_THUMB_H);
|
mkspritesheet($handles, BASEDIR.'wwwroot/logos.jpg', INDEX_THUMB_W, INDEX_THUMB_H);
|
||||||
array_map('imagedestroy', $handles); // free
|
array_map('imagedestroy', $handles); // free
|
||||||
|
}
|
||||||
|
|
||||||
// Build index page
|
// Build index page
|
||||||
|
|
||||||
@@ -399,16 +499,21 @@ function buildcommon() {
|
|||||||
<!-- }} -->
|
<!-- }} -->
|
||||||
<?php } ?>
|
<?php } ?>
|
||||||
|
|
||||||
<table class="projtable">
|
<table id="projtable-main" class="projtable">
|
||||||
<?php foreach ($plist as $pr) { ?>
|
<?php foreach ($plist as $i => $pr) { ?>
|
||||||
<tr class="<?=$pr->getClassAttr()?>">
|
<tr class="<?=$pr->getClassAttr()?>"
|
||||||
|
data-sort-mt="-<?=$pr->lastupdate?>"
|
||||||
|
data-sort-ct="<?=$i?>"
|
||||||
|
data-sort-al="<?=$alphaidx[$i]?>"
|
||||||
|
>
|
||||||
<td>
|
<td>
|
||||||
<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>
|
<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>
|
||||||
<td>
|
<td>
|
||||||
<strong><?=hesc($pr->projname)?></strong>,
|
<strong><?=hesc(str_replace('_', ' ', $pr->projname))?></strong><?php if (SHOW_BLURBS) { ?>,
|
||||||
<?=hesc($pr->shortdesc)?>
|
<?=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)) { ?>
|
<?php if (strlen($pr->subtag) || count($pr->tags)) { ?>
|
||||||
<br>
|
<br>
|
||||||
<small>
|
<small>
|
||||||
@@ -433,12 +538,52 @@ function buildcommon() {
|
|||||||
// Done
|
// Done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildredirects($redirects) {
|
||||||
|
foreach($redirects as $oldname => $newname) {
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<meta http-equiv="refresh" content="0; url=<?=hesc($newname)?>.html">
|
||||||
|
<a href="<?=hesc($newname)?>.html">Moved »</a>
|
||||||
|
<?php
|
||||||
|
$page = ob_get_clean();
|
||||||
|
file_put_contents(BASEDIR.'wwwroot/'.$oldname.'.html', $page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function main($args) {
|
function main($args) {
|
||||||
|
$basedir = './';
|
||||||
$total = $args[0];
|
$total = $args[0];
|
||||||
$pos = $args[1];
|
$pos = $args[1];
|
||||||
|
|
||||||
|
// Parse configuration
|
||||||
|
|
||||||
|
$config = @parse_ini_file(
|
||||||
|
$basedir . 'config.ini',
|
||||||
|
true,
|
||||||
|
INI_SCANNER_RAW
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($config === false) {
|
||||||
|
die("[FATAL] Couldn't load '${basedir}/config.ini'!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
define('BASEDIR', $basedir);
|
||||||
|
define('SITE_TITLE', trim($config['codesite']['title']));
|
||||||
|
define('PAGE_THUMB_W', intval($config['codesite']['page_thumb_w']));
|
||||||
|
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
|
||||||
|
|
||||||
if ($pos == 0) {
|
if ($pos == 0) {
|
||||||
buildcommon();
|
buildcommon();
|
||||||
|
if (array_key_exists('redirect', $config)) {
|
||||||
|
buildredirects( $config['redirect'] );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buildprojects($pos, array_decimate(listprojects(), $total, $pos));
|
buildprojects($pos, array_decimate(listprojects(), $total, $pos));
|
||||||
}
|
}
|
||||||
@@ -448,6 +593,7 @@ function main($args) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
ini_set('display_errors', 'On');
|
ini_set('display_errors', 'On');
|
||||||
|
date_default_timezone_set('Etc/UTC');
|
||||||
error_reporting(E_ALL);
|
error_reporting(E_ALL);
|
||||||
|
|
||||||
main(array_slice($_SERVER['argv'], 1));
|
main(array_slice($_SERVER['argv'], 1));
|
||||||
|
|||||||
60
rebuild.sh
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
THREADS=4
|
||||||
|
|
||||||
|
buildsite() {
|
||||||
|
|
||||||
|
local basedir="$(realpath .)"
|
||||||
|
local rebuild="${basedir}/rebuild.php"
|
||||||
|
|
||||||
|
if [[ "$(uname -o)" == "Cygwin" ]] ; then
|
||||||
|
rebuild="$(cygpath -w "$rebuild")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Site: ${1}"
|
||||||
|
|
||||||
|
pushd "$1" >/dev/null
|
||||||
|
|
||||||
|
echo "Cleaning target directory..."
|
||||||
|
|
||||||
|
if [[ -d wwwroot ]] ; then
|
||||||
|
rm -r wwwroot
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p wwwroot/srv
|
||||||
|
|
||||||
|
if [[ ! -d static ]] ; then
|
||||||
|
mkdir static
|
||||||
|
fi
|
||||||
|
cp "${basedir}/static_global/"* wwwroot || true
|
||||||
|
cp static/* wwwroot || true
|
||||||
|
|
||||||
|
for htm in footer header homepage_blurb ; do
|
||||||
|
if [[ ! -f "${htm}.htm" ]] ; then
|
||||||
|
touch "${htm}.htm"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Building pages..."
|
||||||
|
|
||||||
|
for i in $(seq 0 "$THREADS") ; do
|
||||||
|
php "$rebuild" "$THREADS" "$i" &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
echo "Site: ${1} finished."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
popd >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
for site in sites/* ; do
|
||||||
|
buildsite "$site"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|
||||||
|
read -p "Press any key to continue..."
|
||||||
14
sites/code.ivysaur.me/config.ini
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[codesite]
|
||||||
|
title=code.ivysaur.me
|
||||||
|
page_thumb_w=60
|
||||||
|
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]
|
||||||
|
; old project name = new project name
|
||||||
|
code.ivysaur.me=codesite
|
||||||
11
sites/code.ivysaur.me/footer.htm
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<p>
|
||||||
|
<strong>CONTACT</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For bug reports, feature requests, or if you need any help, please
|
||||||
|
<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/code.ivysaur.me/header.htm
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<h1><a href="index.html"><div id="ivylogo"></div>code.ivysaur.me</a></h1>
|
||||||
26
sites/code.ivysaur.me/homepage_blurb.htm
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
<p>
|
||||||
|
It's said that if you're not disgusted by code you wrote six months ago, you've stopped learning.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<strong>OVERVIEW</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This page contains several assorted spare-time projects, which no longer have any relation. They are listed in roughly chronological order (newest first). <strong>Unless specified otherwise</strong>, you may feel free to use and modify both the binaries and any source code, for any purpose, on the general condition you do not misrepresent who the author is (BSD license).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some of these projects formerly appeared on Google Code <a href="https://code.google.com/p/mappy/">here</a>, but were moved following the discontinuation of the Google Code binary download system.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<select id="sortorder" style="float:right;">
|
||||||
|
<option value="a">Youngest project first</option>
|
||||||
|
<option value="b">Recent updates first</option>
|
||||||
|
<option value="c">Alphabetical</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<strong>PROJECTS</strong>
|
||||||
|
</p>
|
||||||
BIN
sites/code.ivysaur.me/static/favicon.ico
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
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 |
BIN
sites/code.ivysaur.me/static/ivysaur24.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
198
sites/code.ivysaur.me/static/style.css
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
/* style.css */
|
||||||
|
|
||||||
|
html {
|
||||||
|
overflow-y:scroll; /* always display scrollbar to prevent horizontal lurch */
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
border:0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color:#4078c0;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
cursor:pointer;
|
||||||
|
text-decoration:underline;
|
||||||
|
}
|
||||||
|
h1 a {
|
||||||
|
color:black;
|
||||||
|
text-decoration:none;
|
||||||
|
}
|
||||||
|
h1 a:hover {
|
||||||
|
color:black;
|
||||||
|
}
|
||||||
|
h1,h2,h3 {
|
||||||
|
margin-top:0;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
background: #F8F8F8;
|
||||||
|
font-family:Consolas,monospace;
|
||||||
|
white-space:pre;
|
||||||
|
}
|
||||||
|
.code-multiline {
|
||||||
|
display:inline-block;
|
||||||
|
padding:8px;
|
||||||
|
border-radius:8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
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:13px;
|
||||||
|
line-height:1.4;
|
||||||
|
background:#DDD url('greyzz.png'); /* thanks subtlepatterns.com ! */
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
|
||||||
|
#container {
|
||||||
|
margin:0 auto;
|
||||||
|
width:960px;
|
||||||
|
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: 860px; /* 740px full - 60px rhs column - 2px border */
|
||||||
|
}
|
||||||
|
.projbody_fullw {
|
||||||
|
|
||||||
|
}
|
||||||
|
.projimg {
|
||||||
|
float:right;
|
||||||
|
width:62px; /* 60px + 2px border */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
@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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
13
sites/codesite.example.com/config.ini
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[codesite]
|
||||||
|
title=codesite.example.com
|
||||||
|
page_thumb_w=60
|
||||||
|
page_thumb_h=60
|
||||||
|
index_thumb_w=90
|
||||||
|
index_thumb_h=32
|
||||||
|
|
||||||
|
; n.b. Recommend a multiple of the JPEG iDCT block size for index_thumb_h
|
||||||
|
|
||||||
|
[redirect]
|
||||||
|
; old project name = new project name
|
||||||
|
old-project-name=example-project
|
||||||
|
|
||||||
14
sites/codesite.example.com/homepage_blurb.htm
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
<p>
|
||||||
|
Homepage blurb goes here.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<select id="sortorder" style="float:right;">
|
||||||
|
<option value="a">Youngest project first</option>
|
||||||
|
<option value="b">Recent updates first</option>
|
||||||
|
<option value="c">Alphabetical</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<strong>PROJECTS</strong>
|
||||||
|
</p>
|
||||||
|
Before Width: | Height: | Size: 233 B After Width: | Height: | Size: 233 B |
|
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
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 |
BIN
sites/storytime.ivysaur.me/static/pixel_weave.png
Normal file
|
After Width: | Height: | Size: 233 B |
BIN
sites/storytime.ivysaur.me/static/pixel_weave_@2X.png
Normal file
|
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;
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 436 B After Width: | Height: | Size: 436 B |
@@ -33,7 +33,52 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var get_show_tag = function(tag) {
|
var get_show_tag = function(tag) {
|
||||||
return function() { show_tag(tag); return false; };
|
return function() {
|
||||||
|
show_tag(tag);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var sort_rows = function(cb) {
|
||||||
|
var tr = document.querySelectorAll(".projtable tr");
|
||||||
|
var items = [];
|
||||||
|
for (var i = 0, e = tr.length; i !== e; ++i) {
|
||||||
|
items.push([i, cb(tr[i])]);
|
||||||
|
}
|
||||||
|
items.sort(function(a, b) {
|
||||||
|
return (a[1] - b[1]);
|
||||||
|
});
|
||||||
|
for (var i = 0, e = items.length; i !== e; ++i) {
|
||||||
|
var el = tr[items[i][0]];
|
||||||
|
var parent = el.parentElement;
|
||||||
|
parent.removeChild(el);
|
||||||
|
parent.appendChild(el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var sort_update = function() {
|
||||||
|
var cb;
|
||||||
|
switch(document.getElementById('sortorder').value) {
|
||||||
|
case 'a':
|
||||||
|
default: {
|
||||||
|
cb = function(el) {
|
||||||
|
return el.getAttribute('data-sort-ct');
|
||||||
|
};
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 'b': {
|
||||||
|
cb = function(el) {
|
||||||
|
return el.getAttribute('data-sort-mt');
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case 'c': {
|
||||||
|
cb = function(el) {
|
||||||
|
return el.getAttribute('data-sort-al');
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
};
|
||||||
|
sort_rows(cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
@@ -42,5 +87,11 @@
|
|||||||
var tag = taglinks[i].getAttribute("data-tag");
|
var tag = taglinks[i].getAttribute("data-tag");
|
||||||
taglinks[i].addEventListener('click', get_show_tag(tag));
|
taglinks[i].addEventListener('click', get_show_tag(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var so = document.getElementById('sortorder');
|
||||||
|
if (so) {
|
||||||
|
so.addEventListener('change', sort_update);
|
||||||
|
sort_update();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||