From b8e595a15c997ac9b4b8ce05fec3e6e4f85714e6 Mon Sep 17 00:00:00 2001
From: Gabriel Dunne '.$text.' code
+ // a comment perhaps
+
+line
+------
+break
diff --git a/content/cat2/test_post b/content/cat2/test_post
new file mode 100644
index 0000000..63f03f9
--- /dev/null
+++ b/content/cat2/test_post
@@ -0,0 +1,8 @@
+title = another test post
+date = 2010-07-01
+tags = with different tags
+--
+
+this is an older test post!
+
+`some code`
diff --git a/lib/data.php b/lib/data.php
new file mode 100644
index 0000000..6d04a9e
--- /dev/null
+++ b/lib/data.php
@@ -0,0 +1,119 @@
+ $row) {
+ $time[$key] = $row['timestamp'];
+ }
+ if ($time)
+ array_multisort($time, SORT_DESC, $result);
+
+ return array($result, $result_total);
+}
+
+
+/**
+ * parse data file
+ */
+function parse_file($f)
+{
+ $pathparts = explode("/", dirname($f));
+
+ $file_contents = explode("\n", file_get_contents($f, FILE_USE_INCLUDE_PATH));
+ $cc = "";
+ $content = "";
+ $conf = true;
+ foreach ( $file_contents as $fc ) {
+ if ($fc == CONFIG_DELIMITER) {
+ $conf = false;
+ continue;
+ }
+ if ($conf) $cc .= $fc . "\n";
+ else $content .= $fc . "\n";
+ }
+
+ $config = parse_ini_string($cc);
+
+ $res = $config;
+
+ $res['url'] = $res['is_page'] == 1 ? get_base_dir() . '/' . basename($f) . '/' : get_base_dir() . '/' . $pathparts[sizeof($pathparts)-1] . '/' . basename($f);
+ $res['timestamp'] = date('U', strtotime( $config['date'] ? $config['date'] : filemtime($f)));
+ $res['cat'] = $pathparts[sizeof($pathparts)-1];
+ $res['content'] = Markdown($content);
+ $res['tags'] = explode(' ', $config['tags']);
+
+ return $res;
+}
+
+
+/**
+ * get content folders
+ */
+function get_content_folders()
+{
+ $folders = glob(LOCAL_ROOT . CONTENT_DIR . DIRECTORY_SEPARATOR . '/*', GLOB_ONLYDIR);
+ $content_folders = array();
+ foreach($folders as $folder)
+ $content_folders[] = array(
+ 'basename' => basename($folder),
+ 'title' => basename($folder),
+ 'url' => get_base_dir() . '/' . basename($folder) . '/'
+ );
+ return $content_folders;
+}
+
+
+/**
+ * get pages
+ */
+function get_pages()
+{
+ $page_files = glob(LOCAL_ROOT . PAGE_DIR . DIRECTORY_SEPARATOR . '/*');
+ $pages = array();
+ foreach($page_files as $page) {
+ $arr = parse_file($page);
+ $arr['is_page'] = 1;
+ $pages[] = $arr;
+ }
+ return $pages;
+}
+
+?>
diff --git a/lib/init.php b/lib/init.php
new file mode 100644
index 0000000..e45c464
--- /dev/null
+++ b/lib/init.php
@@ -0,0 +1,21 @@
+
\ No newline at end of file
diff --git a/lib/markdown.php b/lib/markdown.php
new file mode 100755
index 0000000..dd1b9e5
--- /dev/null
+++ b/lib/markdown.php
@@ -0,0 +1,1732 @@
+
+#
+# Original Markdown
+# Copyright (c) 2004-2006 John Gruber
+#
", $text); + } + return $text; + } + + function mdwp_strip_p($t) { return preg_replace('{?p>}i', '', $t); } + + function mdwp_hide_tags($text) { + global $mdwp_hidden_tags, $mdwp_placeholders; + return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text); + } + function mdwp_show_tags($text) { + global $mdwp_hidden_tags, $mdwp_placeholders; + return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text); + } +} + + +### bBlog Plugin Info ### + +function identify_modifier_markdown() { + return array( + 'name' => 'markdown', + 'type' => 'modifier', + 'nicename' => 'Markdown', + 'description' => 'A text-to-HTML conversion tool for web writers', + 'authors' => 'Michel Fortin and John Gruber', + 'licence' => 'BSD-like', + 'version' => MARKDOWN_VERSION, + 'help' => 'Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...' + ); +} + + +### Smarty Modifier Interface ### + +function smarty_modifier_markdown($text) { + return Markdown($text); +} + + +### Textile Compatibility Mode ### + +# Rename this file to "classTextile.php" and it can replace Textile everywhere. + +if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) { + # Try to include PHP SmartyPants. Should be in the same directory. + @include_once 'smartypants.php'; + # Fake Textile class. It calls Markdown instead. + class Textile { + function TextileThis($text, $lite='', $encode='') { + if ($lite == '' && $encode == '') $text = Markdown($text); + if (function_exists('SmartyPants')) $text = SmartyPants($text); + return $text; + } + # Fake restricted version: restrictions are not supported for now. + function TextileRestricted($text, $lite='', $noimage='') { + return $this->TextileThis($text, $lite); + } + # Workaround to ensure compatibility with TextPattern 4.0.3. + function blockLite($text) { return $text; } + } +} + + + +# +# Markdown Parser Class +# + +class Markdown_Parser { + + # Regex to match balanced [brackets]. + # Needed to insert a maximum bracked depth while converting to PHP. + var $nested_brackets_depth = 6; + var $nested_brackets_re; + + var $nested_url_parenthesis_depth = 4; + var $nested_url_parenthesis_re; + + # Table of hash values for escaped characters: + var $escape_chars = '\`*_{}[]()>#+-.!'; + var $escape_chars_re; + + # Change to ">" for HTML output. + var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX; + var $tab_width = MARKDOWN_TAB_WIDTH; + + # Change to `true` to disallow markup or entities. + var $no_markup = false; + var $no_entities = false; + + # Predefined urls and titles for reference links and images. + var $predef_urls = array(); + var $predef_titles = array(); + + + function Markdown_Parser() { + # + # Constructor function. Initialize appropriate member variables. + # + $this->_initDetab(); + $this->prepareItalicsAndBold(); + + $this->nested_brackets_re = + str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth). + str_repeat('\])*', $this->nested_brackets_depth); + + $this->nested_url_parenthesis_re = + str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth). + str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth); + + $this->escape_chars_re = '['.preg_quote($this->escape_chars).']'; + + # Sort document, block, and span gamut in ascendent priority order. + asort($this->document_gamut); + asort($this->block_gamut); + asort($this->span_gamut); + } + + + # Internal hashes used during transformation. + var $urls = array(); + var $titles = array(); + var $html_hashes = array(); + + # Status flag to avoid invalid nesting. + var $in_anchor = false; + + + function setup() { + # + # Called before the transformation process starts to setup parser + # states. + # + # Clear global hashes. + $this->urls = $this->predef_urls; + $this->titles = $this->predef_titles; + $this->html_hashes = array(); + + $in_anchor = false; + } + + function teardown() { + # + # Called after the transformation process to clear any variable + # which may be taking up memory unnecessarly. + # + $this->urls = array(); + $this->titles = array(); + $this->html_hashes = array(); + } + + + function transform($text) { + # + # Main function. Performs some preprocessing on the input text + # and pass it through the document gamut. + # + $this->setup(); + + # Remove UTF-8 BOM and marker character in input, if present. + $text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text); + + # Standardize line endings: + # DOS to Unix and Mac to Unix + $text = preg_replace('{\r\n?}', "\n", $text); + + # Make sure $text ends with a couple of newlines: + $text .= "\n\n"; + + # Convert all tabs to spaces. + $text = $this->detab($text); + + # Turn block-level HTML blocks into hash entries + $text = $this->hashHTMLBlocks($text); + + # Strip any lines consisting only of spaces and tabs. + # This makes subsequent regexen easier to write, because we can + # match consecutive blank lines with /\n+/ instead of something + # contorted like /[ ]*\n+/ . + $text = preg_replace('/^[ ]+$/m', '', $text); + + # Run document gamut methods. + foreach ($this->document_gamut as $method => $priority) { + $text = $this->$method($text); + } + + $this->teardown(); + + return $text . "\n"; + } + + var $document_gamut = array( + # Strip link definitions, store in hashes. + "stripLinkDefinitions" => 20, + + "runBasicBlockGamut" => 30, + ); + + + function stripLinkDefinitions($text) { + # + # Strips link definitions from text, stores the URLs and titles in + # hash references. + # + $less_than_tab = $this->tab_width - 1; + + # Link defs are in the form: ^[id]: url "optional title" + $text = preg_replace_callback('{ + ^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1 + [ ]* + \n? # maybe *one* newline + [ ]* + (?: + <(.+?)> # url = $2 + | + (\S+?) # url = $3 + ) + [ ]* + \n? # maybe one newline + [ ]* + (?: + (?<=\s) # lookbehind for whitespace + ["(] + (.*?) # title = $4 + [")] + [ ]* + )? # title is optional + (?:\n+|\Z) + }xm', + array(&$this, '_stripLinkDefinitions_callback'), + $text); + return $text; + } + function _stripLinkDefinitions_callback($matches) { + $link_id = strtolower($matches[1]); + $url = $matches[2] == '' ? $matches[3] : $matches[2]; + $this->urls[$link_id] = $url; + $this->titles[$link_id] =& $matches[4]; + return ''; # String that will replace the block + } + + + function hashHTMLBlocks($text) { + if ($this->no_markup) return $text; + + $less_than_tab = $this->tab_width - 1; + + # Hashify HTML blocks: + # We only want to do this for block-level HTML tags, such as headers, + # lists, and tables. That's because we still want to wrap
s around + # "paragraphs" that are wrapped in non-block-level tags, such as anchors, + # phrase emphasis, and spans. The list of tags we're looking for is + # hard-coded: + # + # * List "a" is made of tags which can be both inline or block-level. + # These will be treated block-level when the start tag is alone on + # its line, otherwise they're not matched here and will be taken as + # inline later. + # * List "b" is made of tags which are always block-level; + # + $block_tags_a_re = 'ins|del'; + $block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'. + 'script|noscript|form|fieldset|iframe|math'; + + # Regular expression for the content of a block tag. + $nested_tags_level = 4; + $attr = ' + (?> # optional tag attributes + \s # starts with whitespace + (?> + [^>"/]+ # text outside quotes + | + /+(?!>) # slash not followed by ">" + | + "[^"]*" # text inside double quotes (tolerate ">") + | + \'[^\']*\' # text inside single quotes (tolerate ">") + )* + )? + '; + $content = + str_repeat(' + (?> + [^<]+ # content without tag + | + <\2 # nested opening tag + '.$attr.' # attributes + (?> + /> + | + >', $nested_tags_level). # end of opening tag + '.*?'. # last level nested tag content + str_repeat(' + \2\s*> # closing nested tag + ) + | + <(?!/\2\s*> # other tags with a different name + ) + )*', + $nested_tags_level); + $content2 = str_replace('\2', '\3', $content); + + # First, look for nested blocks, e.g.: + #
` blocks.
+ #
+ $text = preg_replace_callback('{
+ (?:\n\n|\A\n?)
+ ( # $1 = the code block -- one or more lines, starting with a space/tab
+ (?>
+ [ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
+ .*\n+
+ )+
+ )
+ ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
+ }xm',
+ array(&$this, '_doCodeBlocks_callback'), $text);
+
+ return $text;
+ }
+ function _doCodeBlocks_callback($matches) {
+ $codeblock = $matches[1];
+
+ $codeblock = $this->outdent($codeblock);
+ $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
+
+ # trim leading newlines and trailing newlines
+ $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
+
+ $codeblock = "$codeblock\n
";
+ return "\n\n".$this->hashBlock($codeblock)."\n\n";
+ }
+
+
+ function makeCodeSpan($code) {
+ #
+ # Create a code span markup for $code. Called from handleSpanToken.
+ #
+ $code = htmlspecialchars(trim($code), ENT_NOQUOTES);
+ return $this->hashPart("$code
");
+ }
+
+
+ var $em_relist = array(
+ '' => '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(?em_relist as $em => $em_re) {
+ foreach ($this->strong_relist as $strong => $strong_re) {
+ # Construct list of allowed token expressions.
+ $token_relist = array();
+ if (isset($this->em_strong_relist["$em$strong"])) {
+ $token_relist[] = $this->em_strong_relist["$em$strong"];
+ }
+ $token_relist[] = $em_re;
+ $token_relist[] = $strong_re;
+
+ # Construct master expression from list.
+ $token_re = '{('. implode('|', $token_relist) .')}';
+ $this->em_strong_prepared_relist["$em$strong"] = $token_re;
+ }
+ }
+ }
+
+ function doItalicsAndBold($text) {
+ $token_stack = array('');
+ $text_stack = array('');
+ $em = '';
+ $strong = '';
+ $tree_char_em = false;
+
+ while (1) {
+ #
+ # Get prepared regular expression for seraching emphasis tokens
+ # in current context.
+ #
+ $token_re = $this->em_strong_prepared_relist["$em$strong"];
+
+ #
+ # Each loop iteration search for the next emphasis token.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
+ $text_stack[0] .= $parts[0];
+ $token =& $parts[1];
+ $text =& $parts[2];
+
+ if (empty($token)) {
+ # Reached end of text span: empty stack without emitting.
+ # any more emphasis.
+ while ($token_stack[0]) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ break;
+ }
+
+ $token_len = strlen($token);
+ if ($tree_char_em) {
+ # Reached closing marker while inside a three-char emphasis.
+ if ($token_len == 3) {
+ # Three-char closing marker, close em and strong.
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ $strong = '';
+ } else {
+ # Other closing marker: close one em or strong and
+ # change current token state to match the other
+ $token_stack[0] = str_repeat($token{0}, 3-$token_len);
+ $tag = $token_len == 2 ? "strong" : "em";
+ $span = $text_stack[0];
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span$tag>";
+ $text_stack[0] = $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ $tree_char_em = false;
+ } else if ($token_len == 3) {
+ if ($em) {
+ # Reached closing marker for both em and strong.
+ # Closing strong marker:
+ for ($i = 0; $i < 2; ++$i) {
+ $shifted_token = array_shift($token_stack);
+ $tag = strlen($shifted_token) == 2 ? "strong" : "em";
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "<$tag>$span$tag>";
+ $text_stack[0] .= $this->hashPart($span);
+ $$tag = ''; # $$tag stands for $em or $strong
+ }
+ } else {
+ # Reached opening three-char emphasis marker. Push on token
+ # stack; will be handled by the special condition above.
+ $em = $token{0};
+ $strong = "$em$em";
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $tree_char_em = true;
+ }
+ } else if ($token_len == 2) {
+ if ($strong) {
+ # Unwind any dangling emphasis marker:
+ if (strlen($token_stack[0]) == 1) {
+ $text_stack[1] .= array_shift($token_stack);
+ $text_stack[0] .= array_shift($text_stack);
+ }
+ # Closing strong marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span";
+ $text_stack[0] .= $this->hashPart($span);
+ $strong = '';
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $strong = $token;
+ }
+ } else {
+ # Here $token_len == 1
+ if ($em) {
+ if (strlen($token_stack[0]) == 1) {
+ # Closing emphasis marker:
+ array_shift($token_stack);
+ $span = array_shift($text_stack);
+ $span = $this->runSpanGamut($span);
+ $span = "$span";
+ $text_stack[0] .= $this->hashPart($span);
+ $em = '';
+ } else {
+ $text_stack[0] .= $token;
+ }
+ } else {
+ array_unshift($token_stack, $token);
+ array_unshift($text_stack, '');
+ $em = $token;
+ }
+ }
+ }
+ return $text_stack[0];
+ }
+
+
+ function doBlockQuotes($text) {
+ $text = preg_replace_callback('/
+ ( # Wrap whole match in $1
+ (?>
+ ^[ ]*>[ ]? # ">" at the start of a line
+ .+\n # rest of the first line
+ (.+\n)* # subsequent consecutive lines
+ \n* # blanks
+ )+
+ )
+ /xm',
+ array(&$this, '_doBlockQuotes_callback'), $text);
+
+ return $text;
+ }
+ function _doBlockQuotes_callback($matches) {
+ $bq = $matches[1];
+ # trim one level of quoting - trim whitespace-only lines
+ $bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
+ $bq = $this->runBlockGamut($bq); # recurse
+
+ $bq = preg_replace('/^/m', " ", $bq);
+ # These leading spaces cause problem with content,
+ # so we need to fix that:
+ $bq = preg_replace_callback('{(\s*.+?
)}sx',
+ array(&$this, '_doBlockQuotes_callback2'), $bq);
+
+ return "\n". $this->hashBlock("\n$bq\n
")."\n\n";
+ }
+ function _doBlockQuotes_callback2($matches) {
+ $pre = $matches[1];
+ $pre = preg_replace('/^ /m', '', $pre);
+ return $pre;
+ }
+
+
+ function formParagraphs($text) {
+ #
+ # Params:
+ # $text - string to process with html tags
+ #
+ # Strip leading and trailing lines:
+ $text = preg_replace('/\A\n+|\n+\z/', '', $text);
+
+ $grafs = preg_split('/\n{2,}/', $text, -1, PREG_SPLIT_NO_EMPTY);
+
+ #
+ # Wrap
tags and unhashify HTML blocks
+ #
+ foreach ($grafs as $key => $value) {
+ if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
+ # Is a paragraph.
+ $value = $this->runSpanGamut($value);
+ $value = preg_replace('/^([ ]*)/', "
", $value);
+ $value .= "
";
+ $grafs[$key] = $this->unhash($value);
+ }
+ else {
+ # Is a block.
+ # Modify elements of @grafs in-place...
+ $graf = $value;
+ $block = $this->html_hashes[$graf];
+ $graf = $block;
+// if (preg_match('{
+// \A
+// ( # $1 = tag
+// ]*
+// \b
+// markdown\s*=\s* ([\'"]) # $2 = attr quote char
+// 1
+// \2
+// [^>]*
+// >
+// )
+// ( # $3 = contents
+// .*
+// )
+// () # $4 = closing tag
+// \z
+// }xs', $block, $matches))
+// {
+// list(, $div_open, , $div_content, $div_close) = $matches;
+//
+// # We can't call Markdown(), because that resets the hash;
+// # that initialization code should be pulled into its own sub, though.
+// $div_content = $this->hashHTMLBlocks($div_content);
+//
+// # Run document gamut methods on the content.
+// foreach ($this->document_gamut as $method => $priority) {
+// $div_content = $this->$method($div_content);
+// }
+//
+// $div_open = preg_replace(
+// '{\smarkdown\s*=\s*([\'"]).+?\1}', '', $div_open);
+//
+// $graf = $div_open . "\n" . $div_content . "\n" . $div_close;
+// }
+ $grafs[$key] = $graf;
+ }
+ }
+
+ return implode("\n\n", $grafs);
+ }
+
+
+ function encodeAttribute($text) {
+ #
+ # Encode text for a double-quoted HTML attribute. This function
+ # is *not* suitable for attributes enclosed in single quotes.
+ #
+ $text = $this->encodeAmpsAndAngles($text);
+ $text = str_replace('"', '"', $text);
+ return $text;
+ }
+
+
+ function encodeAmpsAndAngles($text) {
+ #
+ # Smart processing for ampersands and angle brackets that need to
+ # be encoded. Valid character entities are left alone unless the
+ # no-entities mode is set.
+ #
+ if ($this->no_entities) {
+ $text = str_replace('&', '&', $text);
+ } else {
+ # Ampersand-encoding based entirely on Nat Irons's Amputator
+ # MT plugin:
+ $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/',
+ '&', $text);;
+ }
+ # Encode remaining <'s
+ $text = str_replace('<', '<', $text);
+
+ return $text;
+ }
+
+
+ function doAutoLinks($text) {
+ $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i',
+ array(&$this, '_doAutoLinks_url_callback'), $text);
+
+ # Email addresses:
+ $text = preg_replace_callback('{
+ <
+ (?:mailto:)?
+ (
+ (?:
+ [-!#$%&\'*+/=?^_`.{|}~\w\x80-\xFF]+
+ |
+ ".*?"
+ )
+ \@
+ (?:
+ [-a-z0-9\x80-\xFF]+(\.[-a-z0-9\x80-\xFF]+)*\.[a-z]+
+ |
+ \[[\d.a-fA-F:]+\] # IPv4 & IPv6
+ )
+ )
+ >
+ }xi',
+ array(&$this, '_doAutoLinks_email_callback'), $text);
+
+ return $text;
+ }
+ function _doAutoLinks_url_callback($matches) {
+ $url = $this->encodeAttribute($matches[1]);
+ $link = "$url";
+ return $this->hashPart($link);
+ }
+ function _doAutoLinks_email_callback($matches) {
+ $address = $matches[1];
+ $link = $this->encodeEmailAddress($address);
+ return $this->hashPart($link);
+ }
+
+
+ function encodeEmailAddress($addr) {
+ #
+ # Input: an email address, e.g. "foo@example.com"
+ #
+ # Output: the email address as a mailto link, with each character
+ # of the address encoded as either a decimal or hex entity, in
+ # the hopes of foiling most address harvesting spam bots. E.g.:
+ #
+ #
+ #
+ # Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+ # With some optimizations by Milian Wolff.
+ #
+ $addr = "mailto:" . $addr;
+ $chars = preg_split('/(? $char) {
+ $ord = ord($char);
+ # Ignore non-ascii chars.
+ if ($ord < 128) {
+ $r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
+ # roughly 10% raw, 45% hex, 45% dec
+ # '@' *must* be encoded. I insist.
+ if ($r > 90 && $char != '@') /* do nothing */;
+ else if ($r < 45) $chars[$key] = ''.dechex($ord).';';
+ else $chars[$key] = ''.$ord.';';
+ }
+ }
+
+ $addr = implode('', $chars);
+ $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+ $addr = "$text";
+
+ return $addr;
+ }
+
+
+ function parseSpan($str) {
+ #
+ # Take the string $str and parse it into tokens, hashing embeded HTML,
+ # escaped characters and handling code spans.
+ #
+ $output = '';
+
+ $span_re = '{
+ (
+ \\\\'.$this->escape_chars_re.'
+ |
+ (?no_markup ? '' : '
+ |
+ # comment
+ |
+ <\?.*?\?> | <%.*?%> # processing instruction
+ |
+ <[/!$]?[-a-zA-Z0-9:_]+ # regular tags
+ (?>
+ \s
+ (?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
+ )?
+ >
+ ').'
+ )
+ }xs';
+
+ while (1) {
+ #
+ # Each loop iteration seach for either the next tag, the next
+ # openning code span marker, or the next escaped character.
+ # Each token is then passed to handleSpanToken.
+ #
+ $parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
+
+ # Create token from text preceding tag.
+ if ($parts[0] != "") {
+ $output .= $parts[0];
+ }
+
+ # Check if we reach the end.
+ if (isset($parts[1])) {
+ $output .= $this->handleSpanToken($parts[1], $parts[2]);
+ $str = $parts[2];
+ }
+ else {
+ break;
+ }
+ }
+
+ return $output;
+ }
+
+
+ function handleSpanToken($token, &$str) {
+ #
+ # Handle $token provided by parseSpan by determining its nature and
+ # returning the corresponding value that should replace it.
+ #
+ switch ($token{0}) {
+ case "\\":
+ return $this->hashPart("". ord($token{1}). ";");
+ case "`":
+ # Search for end marker in remaining text.
+ if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
+ $str, $matches))
+ {
+ $str = $matches[2];
+ $codespan = $this->makeCodeSpan($matches[1]);
+ return $this->hashPart($codespan);
+ }
+ return $token; // return as text since no ending marker found.
+ default:
+ return $this->hashPart($token);
+ }
+ }
+
+
+ function outdent($text) {
+ #
+ # Remove one level of line-leading tabs or spaces
+ #
+ return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
+ }
+
+
+ # String length function for detab. `_initDetab` will create a function to
+ # hanlde UTF-8 if the default function does not exist.
+ var $utf8_strlen = 'mb_strlen';
+
+ function detab($text) {
+ #
+ # Replace tabs with the appropriate amount of space.
+ #
+ # For each line we separate the line in blocks delemited by
+ # tab characters. Then we reconstruct every line by adding the
+ # appropriate number of space between each blocks.
+
+ $text = preg_replace_callback('/^.*\t.*$/m',
+ array(&$this, '_detab_callback'), $text);
+
+ return $text;
+ }
+ function _detab_callback($matches) {
+ $line = $matches[0];
+ $strlen = $this->utf8_strlen; # strlen function for UTF-8.
+
+ # Split in blocks.
+ $blocks = explode("\t", $line);
+ # Add each blocks to the line.
+ $line = $blocks[0];
+ unset($blocks[0]); # Do not add first block twice.
+ foreach ($blocks as $block) {
+ # Calculate amount of space, insert spaces, insert block.
+ $amount = $this->tab_width -
+ $strlen($line, 'UTF-8') % $this->tab_width;
+ $line .= str_repeat(" ", $amount) . $block;
+ }
+ return $line;
+ }
+ function _initDetab() {
+ #
+ # Check for the availability of the function in the `utf8_strlen` property
+ # (initially `mb_strlen`). If the function is not available, create a
+ # function that will loosely count the number of UTF-8 characters with a
+ # regular expression.
+ #
+ if (function_exists($this->utf8_strlen)) return;
+ $this->utf8_strlen = create_function('$text', 'return preg_match_all(
+ "/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
+ $text, $m);');
+ }
+
+
+ function unhash($text) {
+ #
+ # Swap back in all the tags hashed by _HashHTMLBlocks.
+ #
+ return preg_replace_callback('/(.)\x1A[0-9]+\1/',
+ array(&$this, '_unhash_callback'), $text);
+ }
+ function _unhash_callback($matches) {
+ return $this->html_hashes[$matches[0]];
+ }
+
+}
+
+/*
+
+PHP Markdown
+============
+
+Description
+-----------
+
+This is a PHP translation of the original Markdown formatter written in
+Perl by John Gruber.
+
+Markdown is a text-to-HTML filter; it translates an easy-to-read /
+easy-to-write structured text format into HTML. Markdown's text format
+is most similar to that of plain text email, and supports features such
+as headers, *emphasis*, code blocks, blockquotes, and links.
+
+Markdown's syntax is designed not as a generic markup language, but
+specifically to serve as a front-end to (X)HTML. You can use span-level
+HTML tags anywhere in a Markdown document, and you can use block level
+HTML tags (like and as well).
+
+For more information about Markdown's syntax, see:
+
+
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+
+
+Please include with your report: (1) the example input; (2) the output you
+expected; (3) the output Markdown actually produced.
+
+
+Version History
+---------------
+
+See the readme file for detailed release notes for this version.
+
+
+Copyright and License
+---------------------
+
+PHP Markdown
+Copyright (c) 2004-2009 Michel Fortin
+
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+* Neither the name "Markdown" nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as
+is" and any express or implied warranties, including, but not limited
+to, the implied warranties of merchantability and fitness for a
+particular purpose are disclaimed. In no event shall the copyright owner
+or contributors be liable for any direct, indirect, incidental, special,
+exemplary, or consequential damages (including, but not limited to,
+procurement of substitute goods or services; loss of use, data, or
+profits; or business interruption) however caused and on any theory of
+liability, whether in contract, strict liability, or tort (including
+negligence or otherwise) arising in any way out of the use of this
+software, even if advised of the possibility of such damage.
+
+*/
+?>
\ No newline at end of file
diff --git a/lib/output.php b/lib/output.php
new file mode 100644
index 0000000..e70c913
--- /dev/null
+++ b/lib/output.php
@@ -0,0 +1,153 @@
+template_dir = join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), '..', TEMPLATE_DIR));
+ $t->template_cache_dir = join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), '..', TEMPLATE_DIR, 'cache'));
+// $t->caching = 0;
+
+ return $t;
+}
+
+
+function parse_format($format, $default)
+{
+ $types = array('html' => 'text/html',
+ 'text' => 'text/plain',
+ 'rss' => 'application/rss+xml',
+ 'atom' => 'application/atom+xml',
+ 'json' => 'text/json',
+ 'js' => 'application/x-javascript',
+ 'xspf' => 'application/xspf+xml',
+ 'xml' => 'text/xml',
+ 'jpg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'm3u' => 'audio/x-mpegurl');
+ $format = empty($format) ? $default : $format;
+ return array($format, $types[$format]);
+}
+
+
+if( !function_exists('parse_ini_string') ) {
+ function parse_ini_string( $string ) {
+ $array = Array();
+ $lines = explode("\n", $string );
+ foreach( $lines as $line ) {
+ $statement = preg_match("/^(?!;)(?P[\w+\.\-]+?)\s*=\s*(?P.+?)\s*$/", $line, $match );
+ if( $statement ) {
+ $key = $match[ 'key' ];
+ $value = $match[ 'value' ];
+ # Remove quote
+ if( preg_match( "/^\".*\"$/", $value ) || preg_match( "/^'.*'$/", $value ) ) {
+ $value = mb_substr( $value, 1, mb_strlen( $value ) - 2 );
+ }
+ $array[ $key ] = $value;
+ }
+ }
+ return $array;
+ }
+}
+
+
+/**
+* @param int $seconds Number of seconds to convert into a human-readable timestamp
+* @return tring Human-readable approximate timestamp like "2 hours"
+*/
+function approximate_time($seconds)
+{
+ switch(true)
+ {
+ case abs($seconds) <= 90:
+ return 'moments';
+
+ case abs($seconds) <= 90 * 60:
+ return round(abs($seconds) / 60).' minutes';
+
+ case abs($seconds) <= 36 * 60 * 60:
+ return round(abs($seconds) / (60 * 60)).' hours';
+
+ default:
+ return round(abs($seconds) / (24 * 60 * 60)).' days';
+ }
+}
+
+
+/**
+* @param int $time Unix timestamp
+* @return string Relative time string like "2 hours earlier"
+*/
+function get_relative_time($time)
+{
+ $diff = $time - time();
+ return approximate_time($diff) . ($diff < 0 ? ' ago' : ' from now');
+}
+
+
+function get_rss_feed( $url )
+{
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ $feed = curl_exec($ch);
+ curl_close($ch);
+
+ $xml = new SimpleXMLElement($feed);
+ return $xml;
+}
+
+
+function die_with_code($code, $message)
+{
+ header("HTTP/1.1 {$code}");
+ die($message);
+}
+
+
+function get_base_dir()
+{
+ if(php_sapi_name() == 'cli') return CLI_BASE_DIRECTORY;
+ return rtrim(dirname($_SERVER['SCRIPT_NAME']), DIRECTORY_SEPARATOR);
+}
+
+
+function get_base_href()
+{
+ if(php_sapi_name() == 'cli') return '';
+ $query_pos = strpos($_SERVER['REQUEST_URI'], '?');
+ return ($query_pos === false) ? $_SERVER['REQUEST_URI']
+ : substr($_SERVER['REQUEST_URI'], 0, $query_pos);
+}
+
+
+function get_url_parts()
+{
+ $parts = explode('/', substr($_SERVER['SCRIPT_URL'], strlen(get_base_dir() . '/')));
+ return $parts[0] ? $parts : 0;
+}
+
+
+function get_url()
+{
+$path_info = pathinfo($_SERVER['SCRIPT_URL']);
+$path_info['url'] = $_SERVER['SCRIPT_URL'];
+ return $path_info; //substr($_SERVER['SCRIPT_URL'], strlen(get_base_dir() . '/'));
+}
+
+
+function get_domain_name()
+{
+ if(php_sapi_name() == 'cli') return CLI_DOMAIN_NAME;
+ return $_SERVER['SERVER_NAME'];
+}
+
+
+function get_url_domain($url)
+{
+ $parsed = parse_url($url);
+ return $parsed['host'];
+}
+
+
+?>
diff --git a/lib/static.php b/lib/static.php
new file mode 100644
index 0000000..ea0082e
--- /dev/null
+++ b/lib/static.php
@@ -0,0 +1,18 @@
+';
+ foreach ($entries as $e)
+ {
+ echo ''.$e['title'].' - '.$e['date'].' ';
+ }
+ echo '';
+
+
+
+
+
+?>
\ No newline at end of file
diff --git a/lib/template.php b/lib/template.php
new file mode 100644
index 0000000..abbb3b7
--- /dev/null
+++ b/lib/template.php
@@ -0,0 +1,65 @@
+ $val)
+ if ($key != '')
+ $this->_tpl_vars[$key] = $val;
+ } else {
+ if ($tpl_var != '')
+ $this->_tpl_vars[$tpl_var] = $value;
+ }
+ }
+
+
+ public function include_template ($template, $vars = array())
+ {
+ $this->_tpl_vars = array_merge($this->_tpl_vars, $vars);
+ $this->render($template);
+ }
+
+
+ public function render( $template )
+ {
+ extract( $this->_tpl_vars );
+
+
+ if (is_file( $this->template_dir . DIRECTORY_SEPARATOR . $template ))
+ include( $this->template_dir . DIRECTORY_SEPARATOR . $template );
+ else
+ include( $this->template_dir . DIRECTORY_SEPARATOR . 'default.' . $this->response_format . '.tpl');
+
+
+ }
+
+
+ function ob_file_callback($buffer)
+ {
+// fwrite($this->cache_file, $buffer);
+ }
+
+
+ public function title()
+ {
+ return "";
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/pages/about b/pages/about
new file mode 100644
index 0000000..bdfa8cd
--- /dev/null
+++ b/pages/about
@@ -0,0 +1,3 @@
+title = about
+--
+all about the about
\ No newline at end of file
diff --git a/pages/links b/pages/links
new file mode 100644
index 0000000..42637b7
--- /dev/null
+++ b/pages/links
@@ -0,0 +1,4 @@
+title = links
+--
++ [quilime](http://quilime.com) →
++ [gabriel dunne](http://gabrieldunne.com) →
\ No newline at end of file
diff --git a/public/.htaccess b/public/.htaccess
new file mode 100644
index 0000000..a57877b
--- /dev/null
+++ b/public/.htaccess
@@ -0,0 +1,9 @@
+
+
+
+RewriteEngine On
+RewriteBase /
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule . index.php [L]
+
diff --git a/public/css/style.css b/public/css/style.css
new file mode 100644
index 0000000..9488175
--- /dev/null
+++ b/public/css/style.css
@@ -0,0 +1,92 @@
+body { margin:80px 100px 50px 40px; }
+html, body, table { font-family: sans-serif; font-size:12px; line-height:1.4em; color:#44d ; }
+
+.nav { position:absolute; z-index:1; top:20px; left:30px; }
+.nav ul { margin-left:1em; }
+.nav h1 { margin-bottom:50px;}
+
+#head { position:absolute; top: 20px; left: 160px; }
+
+/*selection*/
+::-moz-selection {background: #08f !important; color:#fff;}
+::selection {background: #08f !important; color:#fff;}
+
+/*links*/
+a { color:#000; border:0; padding:0.2em 0.1em 0 0; }
+a img { border:0; }
+a.mute { text-decoration:none !important; }
+a:hover, a.mute:hover { color:#d15; text-decoration:none; }
+
+/*headings*/
+h1, h2, h3, h4, h5, h6 { font-size:1em; }
+h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { }
+h1 { margin:0 0 3em 0; }
+h2 { margin:0 0 0.5em 0; }
+h3 { margin:0 0 0 0; }
+
+ol li { list-style-type:decimal; }
+
+blockquote { font-family:times; background:#000; color:#aaa;
+margin:0; font-size:15px; line-height:1.4em; padding:2em 4em; font-style:italic; line-height:1.45em; max-width:600px;}
+
+#content p:first-child { margin-top:0; }
+
+p { max-width:720px; }
+
+ul, li { margin:0; padding:0; list-style-type:none; }
+table { margin:0; padding:0; border:0; }
+table .column { padding-right:100px; min-width:120px; max-width:400px; }
+table .column h2 a { text-decoration:none; }
+table h2, table h3 { margin-bottom:2em;}
+table .video li, table .image li { margin-bottom:2em; }
+table .reader li, table .bookmarks li { margin-bottom:1em; padding-bottom:1em; border-bottom:1px dotted #ddd; }
+.reader_links li, .bookmark_links li { padding-top:.75em; margin-bottom:.75em; }
+.bookmark_links li a { display:block; }
+.bookmark_links li span { font-style: italic; color:#444; }
+.image li a { background:none;}
+
+table.archive td {padding-right:20px; }
+
+.c_pop { position:absolute; background:#fff; display:none; border:5px outset #000; padding:1em 2em; z-index:5; }
+
+.func { font-weight:bold; color:#444; }
+
+#home_arrow { position: absolute; top:11px; left:23px; margin-left:250px; text-decoration:none; }
+
+#content { margin-left:120px; min-width:500px; position:absolute; top:20px; padding-bottom:200px; z-index:10;}
+ #content p { }
+ ul.inline_content {}
+ ul.inline_content li .content { }
+ ul.inline_content li { margin:0 0 150px 0; }
+ ul.inline_content li h3 { margin-bottom:1em; border-bottom:1px solid #ddd; padding-bottom:4px; }
+ ul.inline_content ol li { margin:0; padding:0; border:0;}
+ ul.thumbnails { }
+ ul.thumbnails li { display:inline-block; margin: 0px 60px 60px 0px; }
+ ul.thumbnails .thumbnail { width:160px; height:120px; text-align:center; background:#888; }
+ ul.thumbnails a:hover img {
+ filter:alpha(opacity=75);
+ -moz-opacity:0.75;
+ -khtml-opacity: 0.75;
+ opacity: 0.75;
+ }
+ ul.thumbnails a { text-decoration:none; }
+ ul.thumbnails .title { }
+
+ .date { color:#ccc;}
+ .func { margin-bottom:2em; }
+ .func a { background:#daa; padding:0.2em 1em 0.02em 1em; font-size:9px; text-transform:uppercase;}
+
+ .text { font-family:serif; font-size:15px; line-height:2.2em; margin-top:80px;}
+ .indent { text-indent:3em; }
+
+.entry { margin-bottom:100px; }
+.entry h2 { border-bottom:1px solid #ddd; padding-bottom:4px; }
+.entry h2 .title-date { font-weight:normal; color:#bbb; }
+.entry .metadata { margin-top:20px; font-style:italic; color:#aaa; }
+.entry .metadata .tags li { display:inline-block; margin-right:1em; }
+
+.caption { font-style:italic; margin-top:5px; color:#444; }
+.more, .home { text-decoration:none; color:#000; font-weight:bold; }
+
+#footer { margin-top:120px; }
+#footer .copy a { text-decoration:none; }
diff --git a/public/index.php b/public/index.php
new file mode 100644
index 0000000..204b88c
--- /dev/null
+++ b/public/index.php
@@ -0,0 +1,44 @@
+response_format = $response_format;
+ $t->assign('view', $_GET['v']);
+
+ # content folder
+ if (is_dir(LOCAL_ROOT . CONTENT_DIR . DIRECTORY_SEPARATOR . $url_parts['url']) && $url_parts['url'] != "/") {
+ list($data, $total) = get_data(array($url_parts['url']));
+ $t->assign('data', $data);
+ }
+ # single file
+ else if (is_file( LOCAL_ROOT . CONTENT_DIR . $url_parts['dirname'] . DIRECTORY_SEPARATOR . $url_parts['filename'])) {
+ $t->assign('single', true);
+ $t->assign('data', parse_file(LOCAL_ROOT . CONTENT_DIR . $url_parts['dirname'] . DIRECTORY_SEPARATOR . $url_parts['filename']));
+ $template = 'single.'.$response_format.'.tpl';
+ }
+ # page
+ else if (is_file( LOCAL_ROOT . PAGE_DIR . DIRECTORY_SEPARATOR . $url_parts['filename'] )) {
+ $t->assign('data', parse_file(LOCAL_ROOT . PAGE_DIR . DIRECTORY_SEPARATOR . $url_parts['filename']));
+ $template = 'page.' . $response_format . '.tpl';
+ }
+ # direct template
+ else if (is_file( LOCAL_ROOT . TEMPLATE_DIR . DIRECTORY_SEPARATOR . $url_parts['filename'] .'.'. $response_format . '.tpl')) {
+ $template = $url_parts['filename'] . '.' . $response_format . '.tpl';
+ }
+ # default (index)
+ else {
+ list($data, $total) = get_data();
+ $t->assign('data', $data);
+ }
+
+
+ # render template
+ $t->assign('total', $total);
+ header("Content-Type: {$response_mime_type}; charset=UTF-8");
+ $t->render($template);
+?>
diff --git a/scripts/content b/scripts/content
new file mode 100755
index 0000000..bbff300
--- /dev/null
+++ b/scripts/content
@@ -0,0 +1,22 @@
+DATE=$(date +%Y"-"%m"-"%d)
+FOLDER=$1
+
+echo -n "prepend filename with current date? (y/n) "
+read -e USE_DATE
+
+if $USE_DATE
+ then
+ FILE=$DATE_$2
+else
+ FILE=$2
+fi
+
+if test -d content/$FOLDER
+ then
+ echo "dir already exists..."
+else
+ mkdir content/$FOLDER
+fi
+
+echo -e "title = $2\ndate = $DATE\ndraft = true\n--\n\n" > content/$FOLDER/$FILE
+emacs content/$FOLDER/$FILE
\ No newline at end of file
diff --git a/templates/default.html.tpl b/templates/default.html.tpl
new file mode 100644
index 0000000..f41a3de
--- /dev/null
+++ b/templates/default.html.tpl
@@ -0,0 +1,24 @@
+
+
+
+ $this->include_template('head-inc.html.tpl') ?>
+
+ =SITE_TITLE?>=$this->title();?>
+
+
+
+
+ $this->include_template('nav.html.tpl') ?>
+
+
+
+ foreach($data as $entry): ?>
+ $this->include_template('entry.html.tpl', array('data' => $entry)); ?>
+ endforeach; ?>
+
+
+
+ $this->include_template('footer.html.tpl') ?>
+
+
+
diff --git a/templates/default.json.tpl b/templates/default.json.tpl
new file mode 100644
index 0000000..712719b
--- /dev/null
+++ b/templates/default.json.tpl
@@ -0,0 +1,5 @@
+{
+ "entries": print json_encode($entries); ?>,
+ "count": =$total?>,
+ "total": =$total?>
+}
diff --git a/templates/default.rss.tpl b/templates/default.rss.tpl
new file mode 100644
index 0000000..21cd06e
--- /dev/null
+++ b/templates/default.rss.tpl
@@ -0,0 +1,24 @@
+ echo ''; ?>
+
+
+
+
+
+
+ =SITE_TITLE?>
+ =WEB_ROOT?>
+
+
+ foreach($data as $entry): ?>
+ -
+
=$entry['title']?>
+ =htmlentities($entry['content']);?>
+ =$entry['url']?>
+ =$entry['url']?>
+ =date('r', $entry['timestamp'])?>
+
+ endforeach; ?>
+
+
+
+
diff --git a/templates/default.txt.tpl b/templates/default.txt.tpl
new file mode 100644
index 0000000..bfef63c
--- /dev/null
+++ b/templates/default.txt.tpl
@@ -0,0 +1,26 @@
+title : =SITE_TITLE?>=$this->title()."\n"; ?>
+author : gabriel dunne
+email : gdunne at quilime dot com
+copyright : 1997 - =date('Y');?>
+
+
+== entries ==
+
+ foreach($data as $entry): ?>
+
+=$entry['title'];?> - =get_relative_time($entry['timestamp']);?>
+
+================================================================================
+=trim(wordwrap(strip_tags($entry['content'], ''), 80, "\n"));?>
+
+----------
+posted =get_relative_time($entry['timestamp']);?> (=date("Y-m-d", $entry['timestamp']);?>) in =$entry['cat'];?>
+
+ foreach($entry['tags'] as $tag) : ?>#=$tag?> endforeach; ?>
+
+
+
+
+
+
+ endforeach; ?>
\ No newline at end of file
diff --git a/templates/entry.html.tpl b/templates/entry.html.tpl
new file mode 100644
index 0000000..d0f1a4a
--- /dev/null
+++ b/templates/entry.html.tpl
@@ -0,0 +1,23 @@
+
+
+
+ =$data['title']?>
+ ">=get_relative_time($data['timestamp']);?>
+
+
+
+ =$data['content']?>
+
+
+ if ($single) :?>
+
+ endif; ?>
+
+
diff --git a/templates/footer.html.tpl b/templates/footer.html.tpl
new file mode 100644
index 0000000..4ff0285
--- /dev/null
+++ b/templates/footer.html.tpl
@@ -0,0 +1,2 @@
+
+
diff --git a/templates/head-inc.html.tpl b/templates/head-inc.html.tpl
new file mode 100644
index 0000000..413686a
--- /dev/null
+++ b/templates/head-inc.html.tpl
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/templates/nav.html.tpl b/templates/nav.html.tpl
new file mode 100644
index 0000000..53d8efd
--- /dev/null
+++ b/templates/nav.html.tpl
@@ -0,0 +1,23 @@
+
diff --git a/templates/page.html.tpl b/templates/page.html.tpl
new file mode 100644
index 0000000..346fdef
--- /dev/null
+++ b/templates/page.html.tpl
@@ -0,0 +1,24 @@
+
+
+
+ $this->include_template('head-inc.html.tpl') ?>
+
+ =SITE_TITLE?>=$this->title();?>
+
+
+
+
+ $this->include_template('nav.html.tpl') ?>
+
+
+
+ =$data['title']?>
+
+ =$data['content'];?>
+
+
+
+ $this->include_template('footer.html.tpl') ?>
+
+
+
diff --git a/templates/single.html.tpl b/templates/single.html.tpl
new file mode 100644
index 0000000..ccb8623
--- /dev/null
+++ b/templates/single.html.tpl
@@ -0,0 +1,20 @@
+
+
+
+ $this->include_template('head-inc.html.tpl') ?>
+
+ =SITE_TITLE?>=$this->title(); ?>
+
+
+
+
+ $this->include_template('nav.html.tpl') ?>
+
+
+ $this->include_template('entry.html.tpl', array('data' => $data)); ?>
+
+
+ $this->include_template('footer.html.tpl') ?>
+
+
+
--
2.34.1