]> git.quilime.com - plog_bk.git/commitdiff
moved local folder, added public folder, added markdown
authorGabriel Dunne <gdunne@quilime.com>
Wed, 7 Jul 2010 08:04:52 +0000 (01:04 -0700)
committerGabriel Dunne <gdunne@quilime.com>
Wed, 7 Jul 2010 08:04:52 +0000 (01:04 -0700)
41 files changed:
index.php [deleted file]
lib/data.php
lib/init.php
lib/markdown.php [new file with mode: 0755]
lib/output.php
lib/template.php
pages/about [new file with mode: 0644]
pages/links [new file with mode: 0644]
public/.htaccess [moved from .htaccess with 100% similarity]
public/aggregate [new symlink]
public/css/style.css [moved from css/style.css with 93% similarity]
public/css/style2.css [moved from css/style2.css with 100% similarity]
public/favicon.gif [moved from js/js.js with 100% similarity]
public/favicon.ico [new file with mode: 0644]
public/index.php [new file with mode: 0644]
public/js/jquery-1.3.2.min.js [moved from js/jquery-1.3.2.min.js with 100% similarity]
public/js/js.js [new file with mode: 0644]
public/js/prettify/lang-apollo.js [moved from js/prettify/lang-apollo.js with 100% similarity]
public/js/prettify/lang-css.js [moved from js/prettify/lang-css.js with 100% similarity]
public/js/prettify/lang-hs.js [moved from js/prettify/lang-hs.js with 100% similarity]
public/js/prettify/lang-lisp.js [moved from js/prettify/lang-lisp.js with 100% similarity]
public/js/prettify/lang-lua.js [moved from js/prettify/lang-lua.js with 100% similarity]
public/js/prettify/lang-ml.js [moved from js/prettify/lang-ml.js with 100% similarity]
public/js/prettify/lang-proto.js [moved from js/prettify/lang-proto.js with 100% similarity]
public/js/prettify/lang-sql.js [moved from js/prettify/lang-sql.js with 100% similarity]
public/js/prettify/lang-vb.js [moved from js/prettify/lang-vb.js with 100% similarity]
public/js/prettify/lang-wiki.js [moved from js/prettify/lang-wiki.js with 100% similarity]
public/js/prettify/prettify copy.css [moved from js/prettify/prettify copy.css with 100% similarity]
public/js/prettify/prettify.css [moved from js/prettify/prettify.css with 100% similarity]
public/js/prettify/prettify.js [moved from js/prettify/prettify.js with 100% similarity]
templates/about.html.tpl [deleted file]
templates/backup/log.html.tpl [moved from templates/log.html.tpl with 100% similarity]
templates/default.html.tpl
templates/default.rss.tpl [new file with mode: 0644]
templates/default.txt.tpl [new file with mode: 0644]
templates/entries.html.tpl [deleted file]
templates/entry.html.tpl
templates/head-inc.html.tpl
templates/links.html.tpl
templates/page.html.tpl [new file with mode: 0644]
templates/single.html.tpl [new file with mode: 0644]

diff --git a/index.php b/index.php
deleted file mode 100644 (file)
index 9058549..0000000
--- a/index.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-    require_once 'lib/init.php';
-
-    $url_parts = get_url();
-
-       list($response_format, $response_mime_type) = parse_format($url_parts['extension'], 'html');    
-       
-       $t = get_template_instance();   
-       $t->response_format = $response_format;
-
-       $t->assign('view', $_GET['v']);
-       
-       
-       # content folder
-       if (is_dir(CONTENT_DIR . DIRECTORY_SEPARATOR . $url_parts['url']) && $url_parts['basename']) {
-               list($data, $total) = get_data(array($url_parts['basename']));                  
-               $t->assign('data', $data);                              
-               $template = $url_parts['basename'] . '.' . $response_format . '.tpl';
-       }
-       
-       
-       # single file
-       else if (is_file( CONTENT_DIR . $url_parts['dirname'] . DIRECTORY_SEPARATOR . $url_parts['filename'])) {
-               $t->assign('single', true);
-               $t->assign('data', parse_config(CONTENT_DIR . $url_parts['dirname'] . DIRECTORY_SEPARATOR . $url_parts['filename']));
-               $t->assign('content', $url_parts['dirname'] . DIRECTORY_SEPARATOR . $url_parts['filename']);    
-               $template = $url_parts['dirname'] . '.' . $response_format . '.tpl';    
-       }
-       
-               
-       # direct template
-       else if (is_file( TEMPLATE_DIR . DIRECTORY_SEPARATOR . $url_parts['filename'] .'.'. $response_format . '.tpl'))
-       {
-               $template = $url_parts['filename'] . '.' . $response_format . '.tpl';
-       }
-
-
-       # 404
-       else if ($url_parts['basename']) {      
-               $template = '404.'.$response_format.'.tpl';
-       }
-
-
-       # default (index)
-       else {
-               list($data, $total) = get_data();
-               $t->assign('data', $data);
-               $template = 'default.'.$response_format.'.tpl';
-       }
-       
-       
-       
-       
-       # render template
-       $t->assign('total', $total);    
-    header("Content-Type: {$response_mime_type}; charset=UTF-8");
-       $t->render($template);
-?>
index 629f48816e81ac40a85b63fa5e77c66587c2253e..53d41c683e9ffc2627b9b25216d579789bc27716 100644 (file)
@@ -25,31 +25,12 @@ function get_data( $sources = array(),  $params  = array())
                                                continue;
                                }
                                
-                               $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);
+                               $parsed = parse_file($f);
                                                                
-                               if ($config['draft'])
+                               if ($parsed['draft'])
                                        continue;
                                
-                               $config['url'] = WEB_ROOT . DIRECTORY_SEPARATOR . $dir . DIRECTORY_SEPARATOR . basename($f);
-                               $config['timestamp'] = $config['date'] ? date('U', strtotime($config['date'])) : date('U', strtotime(filemtime($f)));
-                               $config['category'] = $dir;
-                               $config['content'] = $content;
-                               $config['tags'] = explode(' ', $config['tags']);
-                               
-                               $result[] = $config;
+                               $result[] = $parsed;
                                $result_total++;
                        }
                }
@@ -66,6 +47,54 @@ function get_data( $sources = array(),  $params  = array())
 }
 
 
+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'] = WEB_ROOT . DIRECTORY_SEPARATOR . $pathparts[sizeof($pathparts)-1] . DIRECTORY_SEPARATOR . basename($f);
+       $res['timestamp'] = $config['date'] ? date('U', strtotime($config['date'])) : date('U', strtotime(filemtime($f)));
+       $res['cat'] = $pathparts[sizeof($pathparts)-1];
+       $res['content'] = Markdown($content);
+       $res['tags'] = explode(', ', $config['tags']);
+       
+       return $res;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 
 function list_content($path, $args="")
 {
index a90c832ead2f605a541685d9b6000905d0b66c74..29a7dd8fa30263c4901b451445ee32a7abde497b 100644 (file)
@@ -5,14 +5,16 @@
        ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . dirname(realpath(__FILE__)));
 
        define ('SITE_TITLE', 'quilime');
-       define ('LOCAL_ROOT', '/home/quilime/quilime.com/');
-       define('WEB_ROOT', 'http://quilime.com');
+       define ('LOCAL_ROOT', '/home/quilime/quilime-site/');
+       define ('WEB_ROOT', 'http://quilime.com');
        define ('CONTENT_DIR', 'content');
        define ('TEMPLATE_DIR', 'templates');
+       define ('PAGE_DIR', 'pages');   
        define ('CONFIG_DELIMITER', '--');      
        
     require_once 'data.php';
-    require_once 'output.php'; 
+    require_once 'output.php';
+    require_once 'markdown.php';       
     require_once 'template.php';       
 
     define_constants();
diff --git a/lib/markdown.php b/lib/markdown.php
new file mode 100755 (executable)
index 0000000..dd1b9e5
--- /dev/null
@@ -0,0 +1,1732 @@
+<?php
+#
+# Markdown  -  A text-to-HTML conversion tool for web writers
+#
+# PHP Markdown
+# Copyright (c) 2004-2009 Michel Fortin  
+# <http://michelf.com/projects/php-markdown/>
+#
+# Original Markdown
+# Copyright (c) 2004-2006 John Gruber  
+# <http://daringfireball.net/projects/markdown/>
+#
+
+
+define( 'MARKDOWN_VERSION',  "1.0.1n" ); # Sat 10 Oct 2009
+
+
+#
+# Global default settings:
+#
+
+# Change to ">" for HTML output
+@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX',  " />");
+
+# Define the width of a tab for code blocks.
+@define( 'MARKDOWN_TAB_WIDTH',     4 );
+
+
+#
+# WordPress settings:
+#
+
+# Change to false to remove Markdown from posts and/or comments.
+@define( 'MARKDOWN_WP_POSTS',      true );
+@define( 'MARKDOWN_WP_COMMENTS',   true );
+
+
+
+### Standard Function Interface ###
+
+@define( 'MARKDOWN_PARSER_CLASS',  'Markdown_Parser' );
+
+function Markdown($text) {
+#
+# Initialize the parser and return the result of its transform method.
+#
+       # Setup static parser variable.
+       static $parser;
+       if (!isset($parser)) {
+               $parser_class = MARKDOWN_PARSER_CLASS;
+               $parser = new $parser_class;
+       }
+
+       # Transform text using parser.
+       return $parser->transform($text);
+}
+
+
+### WordPress Plugin Interface ###
+
+/*
+Plugin Name: Markdown
+Plugin URI: http://michelf.com/projects/php-markdown/
+Description: <a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>
+Version: 1.0.1n
+Author: Michel Fortin
+Author URI: http://michelf.com/
+*/
+
+if (isset($wp_version)) {
+       # More details about how it works here:
+       # <http://michelf.com/weblog/2005/wordpress-text-flow-vs-markdown/>
+       
+       # Post content and excerpts
+       # - Remove WordPress paragraph generator.
+       # - Run Markdown on excerpt, then remove all tags.
+       # - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
+       if (MARKDOWN_WP_POSTS) {
+               remove_filter('the_content',     'wpautop');
+        remove_filter('the_content_rss', 'wpautop');
+               remove_filter('the_excerpt',     'wpautop');
+               add_filter('the_content',     'Markdown', 6);
+        add_filter('the_content_rss', 'Markdown', 6);
+               add_filter('get_the_excerpt', 'Markdown', 6);
+               add_filter('get_the_excerpt', 'trim', 7);
+               add_filter('the_excerpt',     'mdwp_add_p');
+               add_filter('the_excerpt_rss', 'mdwp_strip_p');
+               
+               remove_filter('content_save_pre',  'balanceTags', 50);
+               remove_filter('excerpt_save_pre',  'balanceTags', 50);
+               add_filter('the_content',         'balanceTags', 50);
+               add_filter('get_the_excerpt', 'balanceTags', 9);
+       }
+       
+       # Comments
+       # - Remove WordPress paragraph generator.
+       # - Remove WordPress auto-link generator.
+       # - Scramble important tags before passing them to the kses filter.
+       # - Run Markdown on excerpt then remove paragraph tags.
+       if (MARKDOWN_WP_COMMENTS) {
+               remove_filter('comment_text', 'wpautop', 30);
+               remove_filter('comment_text', 'make_clickable');
+               add_filter('pre_comment_content', 'Markdown', 6);
+               add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
+               add_filter('pre_comment_content', 'mdwp_show_tags', 12);
+               add_filter('get_comment_text',    'Markdown', 6);
+               add_filter('get_comment_excerpt', 'Markdown', 6);
+               add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
+       
+               global $mdwp_hidden_tags, $mdwp_placeholders;
+               $mdwp_hidden_tags = explode(' ',
+                       '<p> </p> <pre> </pre> <ol> </ol> <ul> </ul> <li> </li>');
+               $mdwp_placeholders = explode(' ', str_rot13(
+                       'pEj07ZbbBZ U1kqgh4w4p pre2zmeN6K QTi31t9pre ol0MP1jzJR '.
+                       'ML5IjmbRol ulANi1NsGY J7zRLJqPul liA8ctl16T K9nhooUHli'));
+       }
+       
+       function mdwp_add_p($text) {
+               if (!preg_match('{^$|^<(p|ul|ol|dl|pre|blockquote)>}i', $text)) {
+                       $text = '<p>'.$text.'</p>';
+                       $text = preg_replace('{\n{2,}}', "</p>\n\n<p>", $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'                  => '<a href="http://daringfireball.net/projects/markdown/syntax">Markdown syntax</a> allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by <a href="http://daringfireball.net/">John Gruber</a>. <a href="http://michelf.com/projects/php-markdown/">More...</a>'
+       );
+}
+
+
+### 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 <p>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.:
+               #       <div>
+               #               <div>
+               #               tags for inner block must be indented.
+               #               </div>
+               #       </div>
+               #
+               # The outermost tags must start at the left margin for this to match, and
+               # the inner nested divs must be indented.
+               # We need to do this before the next, more liberal match, because the next
+               # match will start at the first `<div>` and stop at the first `</div>`.
+               $text = preg_replace_callback('{(?>
+                       (?>
+                               (?<=\n\n)               # Starting after a blank line
+                               |                               # or
+                               \A\n?                   # the beginning of the doc
+                       )
+                       (                                               # save in $1
+
+                         # Match from `\n<tag>` to `</tag>\n`, handling nested tags 
+                         # in between.
+                                       
+                                               [ ]{0,'.$less_than_tab.'}
+                                               <('.$block_tags_b_re.')# start tag = $2
+                                               '.$attr.'>                      # attributes followed by > and \n
+                                               '.$content.'            # content, support nesting
+                                               </\2>                           # the matching end tag
+                                               [ ]*                            # trailing spaces/tabs
+                                               (?=\n+|\Z)      # followed by a newline or end of document
+
+                       | # Special version for tags of group a.
+
+                                               [ ]{0,'.$less_than_tab.'}
+                                               <('.$block_tags_a_re.')# start tag = $3
+                                               '.$attr.'>[ ]*\n        # attributes followed by >
+                                               '.$content2.'           # content, support nesting
+                                               </\3>                           # the matching end tag
+                                               [ ]*                            # trailing spaces/tabs
+                                               (?=\n+|\Z)      # followed by a newline or end of document
+                                       
+                       | # Special case just for <hr />. It was easier to make a special 
+                         # case than to make the other regex more complicated.
+                       
+                                               [ ]{0,'.$less_than_tab.'}
+                                               <(hr)                           # start tag = $2
+                                               '.$attr.'                       # attributes
+                                               /?>                                     # the matching end tag
+                                               [ ]*
+                                               (?=\n{2,}|\Z)           # followed by a blank line or end of document
+                       
+                       | # Special case for standalone HTML comments:
+                       
+                                       [ ]{0,'.$less_than_tab.'}
+                                       (?s:
+                                               <!-- .*? -->
+                                       )
+                                       [ ]*
+                                       (?=\n{2,}|\Z)           # followed by a blank line or end of document
+                       
+                       | # PHP and ASP-style processor instructions (<? and <%)
+                       
+                                       [ ]{0,'.$less_than_tab.'}
+                                       (?s:
+                                               <([?%])                 # $2
+                                               .*?
+                                               \2>
+                                       )
+                                       [ ]*
+                                       (?=\n{2,}|\Z)           # followed by a blank line or end of document
+                                       
+                       )
+                       )}Sxmi',
+                       array(&$this, '_hashHTMLBlocks_callback'),
+                       $text);
+
+               return $text;
+       }
+       function _hashHTMLBlocks_callback($matches) {
+               $text = $matches[1];
+               $key  = $this->hashBlock($text);
+               return "\n\n$key\n\n";
+       }
+       
+       
+       function hashPart($text, $boundary = 'X') {
+       #
+       # Called whenever a tag must be hashed when a function insert an atomic 
+       # element in the text stream. Passing $text to through this function gives
+       # a unique text-token which will be reverted back when calling unhash.
+       #
+       # The $boundary argument specify what character should be used to surround
+       # the token. By convension, "B" is used for block elements that needs not
+       # to be wrapped into paragraph tags at the end, ":" is used for elements
+       # that are word separators and "X" is used in the general case.
+       #
+               # Swap back any tag hash found in $text so we do not have to `unhash`
+               # multiple times at the end.
+               $text = $this->unhash($text);
+               
+               # Then hash the block.
+               static $i = 0;
+               $key = "$boundary\x1A" . ++$i . $boundary;
+               $this->html_hashes[$key] = $text;
+               return $key; # String that will replace the tag.
+       }
+
+
+       function hashBlock($text) {
+       #
+       # Shortcut function for hashPart with block-level boundaries.
+       #
+               return $this->hashPart($text, 'B');
+       }
+
+
+       var $block_gamut = array(
+       #
+       # These are all the transformations that form block-level
+       # tags like paragraphs, headers, and list items.
+       #
+               "doHeaders"         => 10,
+               "doHorizontalRules" => 20,
+               
+               "doLists"           => 40,
+               "doCodeBlocks"      => 50,
+               "doBlockQuotes"     => 60,
+               );
+
+       function runBlockGamut($text) {
+       #
+       # Run block gamut tranformations.
+       #
+               # We need to escape raw HTML in Markdown source before doing anything 
+               # else. This need to be done for each block, and not only at the 
+               # begining in the Markdown function since hashed blocks can be part of
+               # list items and could have been indented. Indented blocks would have 
+               # been seen as a code block in a previous pass of hashHTMLBlocks.
+               $text = $this->hashHTMLBlocks($text);
+               
+               return $this->runBasicBlockGamut($text);
+       }
+       
+       function runBasicBlockGamut($text) {
+       #
+       # Run block gamut tranformations, without hashing HTML blocks. This is 
+       # useful when HTML blocks are known to be already hashed, like in the first
+       # whole-document pass.
+       #
+               foreach ($this->block_gamut as $method => $priority) {
+                       $text = $this->$method($text);
+               }
+               
+               # Finally form paragraph and restore hashed blocks.
+               $text = $this->formParagraphs($text);
+
+               return $text;
+       }
+       
+       
+       function doHorizontalRules($text) {
+               # Do Horizontal Rules:
+               return preg_replace(
+                       '{
+                               ^[ ]{0,3}       # Leading space
+                               ([-*_])         # $1: First marker
+                               (?>                     # Repeated marker group
+                                       [ ]{0,2}        # Zero, one, or two spaces.
+                                       \1                      # Marker character
+                               ){2,}           # Group repeated at least twice
+                               [ ]*            # Tailing spaces
+                               $                       # End of line.
+                       }mx',
+                       "\n".$this->hashBlock("<hr$this->empty_element_suffix")."\n", 
+                       $text);
+       }
+
+
+       var $span_gamut = array(
+       #
+       # These are all the transformations that occur *within* block-level
+       # tags like paragraphs, headers, and list items.
+       #
+               # Process character escapes, code spans, and inline HTML
+               # in one shot.
+               "parseSpan"           => -30,
+
+               # Process anchor and image tags. Images must come first,
+               # because ![foo][f] looks like an anchor.
+               "doImages"            =>  10,
+               "doAnchors"           =>  20,
+               
+               # Make links out of things like `<http://example.com/>`
+               # Must come after doAnchors, because you can use < and >
+               # delimiters in inline links like [this](<url>).
+               "doAutoLinks"         =>  30,
+               "encodeAmpsAndAngles" =>  40,
+
+               "doItalicsAndBold"    =>  50,
+               "doHardBreaks"        =>  60,
+               );
+
+       function runSpanGamut($text) {
+       #
+       # Run span gamut tranformations.
+       #
+               foreach ($this->span_gamut as $method => $priority) {
+                       $text = $this->$method($text);
+               }
+
+               return $text;
+       }
+       
+       
+       function doHardBreaks($text) {
+               # Do hard breaks:
+               return preg_replace_callback('/ {2,}\n/', 
+                       array(&$this, '_doHardBreaks_callback'), $text);
+       }
+       function _doHardBreaks_callback($matches) {
+               return $this->hashPart("<br$this->empty_element_suffix\n");
+       }
+
+
+       function doAnchors($text) {
+       #
+       # Turn Markdown link shortcuts into XHTML <a> tags.
+       #
+               if ($this->in_anchor) return $text;
+               $this->in_anchor = true;
+               
+               #
+               # First, handle reference-style links: [link text] [id]
+               #
+               $text = preg_replace_callback('{
+                       (                                       # wrap whole match in $1
+                         \[
+                               ('.$this->nested_brackets_re.') # link text = $2
+                         \]
+
+                         [ ]?                          # one optional space
+                         (?:\n[ ]*)?           # one optional newline followed by spaces
+
+                         \[
+                               (.*?)           # id = $3
+                         \]
+                       )
+                       }xs',
+                       array(&$this, '_doAnchors_reference_callback'), $text);
+
+               #
+               # Next, inline-style links: [link text](url "optional title")
+               #
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         \[
+                               ('.$this->nested_brackets_re.') # link text = $2
+                         \]
+                         \(                    # literal paren
+                               [ \n]*
+                               (?:
+                                       <(.+?)> # href = $3
+                               |
+                                       ('.$this->nested_url_parenthesis_re.')  # href = $4
+                               )
+                               [ \n]*
+                               (                       # $5
+                                 ([\'"])       # quote char = $6
+                                 (.*?)         # Title = $7
+                                 \6            # matching quote
+                                 [ \n]*        # ignore any spaces/tabs between closing quote and )
+                               )?                      # title is optional
+                         \)
+                       )
+                       }xs',
+                       array(&$this, '_doAnchors_inline_callback'), $text);
+
+               #
+               # Last, handle reference-style shortcuts: [link text]
+               # These must come last in case you've also got [link text][1]
+               # or [link text](/foo)
+               #
+               $text = preg_replace_callback('{
+                       (                                       # wrap whole match in $1
+                         \[
+                               ([^\[\]]+)              # link text = $2; can\'t contain [ or ]
+                         \]
+                       )
+                       }xs',
+                       array(&$this, '_doAnchors_reference_callback'), $text);
+
+               $this->in_anchor = false;
+               return $text;
+       }
+       function _doAnchors_reference_callback($matches) {
+               $whole_match =  $matches[1];
+               $link_text   =  $matches[2];
+               $link_id     =& $matches[3];
+
+               if ($link_id == "") {
+                       # for shortcut links like [this][] or [this].
+                       $link_id = $link_text;
+               }
+               
+               # lower-case and turn embedded newlines into spaces
+               $link_id = strtolower($link_id);
+               $link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
+
+               if (isset($this->urls[$link_id])) {
+                       $url = $this->urls[$link_id];
+                       $url = $this->encodeAttribute($url);
+                       
+                       $result = "<a href=\"$url\"";
+                       if ( isset( $this->titles[$link_id] ) ) {
+                               $title = $this->titles[$link_id];
+                               $title = $this->encodeAttribute($title);
+                               $result .=  " title=\"$title\"";
+                       }
+               
+                       $link_text = $this->runSpanGamut($link_text);
+                       $result .= ">$link_text</a>";
+                       $result = $this->hashPart($result);
+               }
+               else {
+                       $result = $whole_match;
+               }
+               return $result;
+       }
+       function _doAnchors_inline_callback($matches) {
+               $whole_match    =  $matches[1];
+               $link_text              =  $this->runSpanGamut($matches[2]);
+               $url                    =  $matches[3] == '' ? $matches[4] : $matches[3];
+               $title                  =& $matches[7];
+
+               $url = $this->encodeAttribute($url);
+
+               $result = "<a href=\"$url\"";
+               if (isset($title)) {
+                       $title = $this->encodeAttribute($title);
+                       $result .=  " title=\"$title\"";
+               }
+               
+               $link_text = $this->runSpanGamut($link_text);
+               $result .= ">$link_text</a>";
+
+               return $this->hashPart($result);
+       }
+
+
+       function doImages($text) {
+       #
+       # Turn Markdown image shortcuts into <img> tags.
+       #
+               #
+               # First, handle reference-style labeled images: ![alt text][id]
+               #
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         !\[
+                               ('.$this->nested_brackets_re.')         # alt text = $2
+                         \]
+
+                         [ ]?                          # one optional space
+                         (?:\n[ ]*)?           # one optional newline followed by spaces
+
+                         \[
+                               (.*?)           # id = $3
+                         \]
+
+                       )
+                       }xs', 
+                       array(&$this, '_doImages_reference_callback'), $text);
+
+               #
+               # Next, handle inline images:  ![alt text](url "optional title")
+               # Don't forget: encode * and _
+               #
+               $text = preg_replace_callback('{
+                       (                               # wrap whole match in $1
+                         !\[
+                               ('.$this->nested_brackets_re.')         # alt text = $2
+                         \]
+                         \s?                   # One optional whitespace character
+                         \(                    # literal paren
+                               [ \n]*
+                               (?:
+                                       <(\S*)> # src url = $3
+                               |
+                                       ('.$this->nested_url_parenthesis_re.')  # src url = $4
+                               )
+                               [ \n]*
+                               (                       # $5
+                                 ([\'"])       # quote char = $6
+                                 (.*?)         # title = $7
+                                 \6            # matching quote
+                                 [ \n]*
+                               )?                      # title is optional
+                         \)
+                       )
+                       }xs',
+                       array(&$this, '_doImages_inline_callback'), $text);
+
+               return $text;
+       }
+       function _doImages_reference_callback($matches) {
+               $whole_match = $matches[1];
+               $alt_text    = $matches[2];
+               $link_id     = strtolower($matches[3]);
+
+               if ($link_id == "") {
+                       $link_id = strtolower($alt_text); # for shortcut links like ![this][].
+               }
+
+               $alt_text = $this->encodeAttribute($alt_text);
+               if (isset($this->urls[$link_id])) {
+                       $url = $this->encodeAttribute($this->urls[$link_id]);
+                       $result = "<img src=\"$url\" alt=\"$alt_text\"";
+                       if (isset($this->titles[$link_id])) {
+                               $title = $this->titles[$link_id];
+                               $title = $this->encodeAttribute($title);
+                               $result .=  " title=\"$title\"";
+                       }
+                       $result .= $this->empty_element_suffix;
+                       $result = $this->hashPart($result);
+               }
+               else {
+                       # If there's no such link ID, leave intact:
+                       $result = $whole_match;
+               }
+
+               return $result;
+       }
+       function _doImages_inline_callback($matches) {
+               $whole_match    = $matches[1];
+               $alt_text               = $matches[2];
+               $url                    = $matches[3] == '' ? $matches[4] : $matches[3];
+               $title                  =& $matches[7];
+
+               $alt_text = $this->encodeAttribute($alt_text);
+               $url = $this->encodeAttribute($url);
+               $result = "<img src=\"$url\" alt=\"$alt_text\"";
+               if (isset($title)) {
+                       $title = $this->encodeAttribute($title);
+                       $result .=  " title=\"$title\""; # $title already quoted
+               }
+               $result .= $this->empty_element_suffix;
+
+               return $this->hashPart($result);
+       }
+
+
+       function doHeaders($text) {
+               # Setext-style headers:
+               #         Header 1
+               #         ========
+               #  
+               #         Header 2
+               #         --------
+               #
+               $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
+                       array(&$this, '_doHeaders_callback_setext'), $text);
+
+               # atx-style headers:
+               #       # Header 1
+               #       ## Header 2
+               #       ## Header 2 with closing hashes ##
+               #       ...
+               #       ###### Header 6
+               #
+               $text = preg_replace_callback('{
+                               ^(\#{1,6})      # $1 = string of #\'s
+                               [ ]*
+                               (.+?)           # $2 = Header text
+                               [ ]*
+                               \#*                     # optional closing #\'s (not counted)
+                               \n+
+                       }xm',
+                       array(&$this, '_doHeaders_callback_atx'), $text);
+
+               return $text;
+       }
+       function _doHeaders_callback_setext($matches) {
+               # Terrible hack to check we haven't found an empty list item.
+               if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
+                       return $matches[0];
+               
+               $level = $matches[2]{0} == '=' ? 1 : 2;
+               $block = "<h$level>".$this->runSpanGamut($matches[1])."</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+       function _doHeaders_callback_atx($matches) {
+               $level = strlen($matches[1]);
+               $block = "<h$level>".$this->runSpanGamut($matches[2])."</h$level>";
+               return "\n" . $this->hashBlock($block) . "\n\n";
+       }
+
+
+       function doLists($text) {
+       #
+       # Form HTML ordered (numbered) and unordered (bulleted) lists.
+       #
+               $less_than_tab = $this->tab_width - 1;
+
+               # Re-usable patterns to match list item bullets and number markers:
+               $marker_ul_re  = '[*+-]';
+               $marker_ol_re  = '\d+[.]';
+               $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+               $markers_relist = array(
+                       $marker_ul_re => $marker_ol_re,
+                       $marker_ol_re => $marker_ul_re,
+                       );
+
+               foreach ($markers_relist as $marker_re => $other_marker_re) {
+                       # Re-usable pattern to match any entirel ul or ol list:
+                       $whole_list_re = '
+                               (                                                               # $1 = whole list
+                                 (                                                             # $2
+                                       ([ ]{0,'.$less_than_tab.'})     # $3 = number of spaces
+                                       ('.$marker_re.')                        # $4 = first list item marker
+                                       [ ]+
+                                 )
+                                 (?s:.+?)
+                                 (                                                             # $5
+                                         \z
+                                       |
+                                         \n{2,}
+                                         (?=\S)
+                                         (?!                                           # Negative lookahead for another list item marker
+                                               [ ]*
+                                               '.$marker_re.'[ ]+
+                                         )
+                                       |
+                                         (?=                                           # Lookahead for another kind of list
+                                           \n
+                                               \3                                              # Must have the same indentation
+                                               '.$other_marker_re.'[ ]+
+                                         )
+                                 )
+                               )
+                       '; // mx
+                       
+                       # We use a different prefix before nested lists than top-level lists.
+                       # See extended comment in _ProcessListItems().
+               
+                       if ($this->list_level) {
+                               $text = preg_replace_callback('{
+                                               ^
+                                               '.$whole_list_re.'
+                                       }mx',
+                                       array(&$this, '_doLists_callback'), $text);
+                       }
+                       else {
+                               $text = preg_replace_callback('{
+                                               (?:(?<=\n)\n|\A\n?) # Must eat the newline
+                                               '.$whole_list_re.'
+                                       }mx',
+                                       array(&$this, '_doLists_callback'), $text);
+                       }
+               }
+
+               return $text;
+       }
+       function _doLists_callback($matches) {
+               # Re-usable patterns to match list item bullets and number markers:
+               $marker_ul_re  = '[*+-]';
+               $marker_ol_re  = '\d+[.]';
+               $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+               
+               $list = $matches[1];
+               $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
+               
+               $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+               
+               $list .= "\n";
+               $result = $this->processListItems($list, $marker_any_re);
+               
+               $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+               return "\n". $result ."\n\n";
+       }
+
+       var $list_level = 0;
+
+       function processListItems($list_str, $marker_any_re) {
+       #
+       #       Process the contents of a single ordered or unordered list, splitting it
+       #       into individual list items.
+       #
+               # The $this->list_level global keeps track of when we're inside a list.
+               # Each time we enter a list, we increment it; when we leave a list,
+               # we decrement. If it's zero, we're not in a list anymore.
+               #
+               # We do this because when we're not inside a list, we want to treat
+               # something like this:
+               #
+               #               I recommend upgrading to version
+               #               8. Oops, now this line is treated
+               #               as a sub-list.
+               #
+               # As a single paragraph, despite the fact that the second line starts
+               # with a digit-period-space sequence.
+               #
+               # Whereas when we're inside a list (or sub-list), that line will be
+               # treated as the start of a sub-list. What a kludge, huh? This is
+               # an aspect of Markdown's syntax that's hard to parse perfectly
+               # without resorting to mind-reading. Perhaps the solution is to
+               # change the syntax rules such that sub-lists must start with a
+               # starting cardinal number; e.g. "1." or "a.".
+               
+               $this->list_level++;
+
+               # trim trailing blank lines:
+               $list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
+
+               $list_str = preg_replace_callback('{
+                       (\n)?                                                   # leading line = $1
+                       (^[ ]*)                                                 # leading whitespace = $2
+                       ('.$marker_any_re.'                             # list marker and space = $3
+                               (?:[ ]+|(?=\n)) # space only required if item is not empty
+                       )
+                       ((?s:.*?))                                              # list item text   = $4
+                       (?:(\n+(?=\n))|\n)                              # tailing blank line = $5
+                       (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
+                       }xm',
+                       array(&$this, '_processListItems_callback'), $list_str);
+
+               $this->list_level--;
+               return $list_str;
+       }
+       function _processListItems_callback($matches) {
+               $item = $matches[4];
+               $leading_line =& $matches[1];
+               $leading_space =& $matches[2];
+               $marker_space = $matches[3];
+               $tailing_blank_line =& $matches[5];
+
+               if ($leading_line || $tailing_blank_line || 
+                       preg_match('/\n{2,}/', $item))
+               {
+                       # Replace marker with the appropriate whitespace indentation
+                       $item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
+                       $item = $this->runBlockGamut($this->outdent($item)."\n");
+               }
+               else {
+                       # Recursion for sub-lists:
+                       $item = $this->doLists($this->outdent($item));
+                       $item = preg_replace('/\n+$/', '', $item);
+                       $item = $this->runSpanGamut($item);
+               }
+
+               return "<li>" . $item . "</li>\n";
+       }
+
+
+       function doCodeBlocks($text) {
+       #
+       #       Process Markdown `<pre><code>` 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 = "<pre><code>$codeblock\n</code></pre>";
+               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>$code</code>");
+       }
+
+
+       var $em_relist = array(
+               ''  => '(?:(?<!\*)\*(?!\*)|(?<!_)_(?!_))(?=\S|$)(?![.,:;]\s)',
+               '*' => '(?<=\S|^)(?<!\*)\*(?!\*)',
+               '_' => '(?<=\S|^)(?<!_)_(?!_)',
+               );
+       var $strong_relist = array(
+               ''   => '(?:(?<!\*)\*\*(?!\*)|(?<!_)__(?!_))(?=\S|$)(?![.,:;]\s)',
+               '**' => '(?<=\S|^)(?<!\*)\*\*(?!\*)',
+               '__' => '(?<=\S|^)(?<!_)__(?!_)',
+               );
+       var $em_strong_relist = array(
+               ''    => '(?:(?<!\*)\*\*\*(?!\*)|(?<!_)___(?!_))(?=\S|$)(?![.,:;]\s)',
+               '***' => '(?<=\S|^)(?<!\*)\*\*\*(?!\*)',
+               '___' => '(?<=\S|^)(?<!_)___(?!_)',
+               );
+       var $em_strong_prepared_relist;
+       
+       function prepareItalicsAndBold() {
+       #
+       # Prepare regular expressions for searching emphasis tokens in any
+       # context.
+       #
+               foreach ($this->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 = "<strong><em>$span</em></strong>";
+                                       $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 = "<strong>$span</strong>";
+                                       $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 = "<em>$span</em>";
+                                               $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 <pre> content, 
+               # so we need to fix that:
+               $bq = preg_replace_callback('{(\s*<pre>.+?</pre>)}sx', 
+                       array(&$this, '_doBlockQuotes_callback2'), $bq);
+
+               return "\n". $this->hashBlock("<blockquote>\n$bq\n</blockquote>")."\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 <p> 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 <p> 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('/^([ ]*)/', "<p>", $value);
+                               $value .= "</p>";
+                               $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 = <div> tag
+//                                       <div  \s+
+//                                       [^>]*
+//                                       \b
+//                                       markdown\s*=\s*  ([\'"])      #       $2 = attr quote char
+//                                       1
+//                                       \2
+//                                       [^>]*
+//                                       >
+//                                     )
+//                                     (                                                       # $3 = contents
+//                                     .*
+//                                     )
+//                                     (</div>)                                        # $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('"', '&quot;', $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('&', '&amp;', $text);
+               } else {
+                       # Ampersand-encoding based entirely on Nat Irons's Amputator
+                       # MT plugin: <http://bumppo.net/projects/amputator/>
+                       $text = preg_replace('/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/', 
+                                                               '&amp;', $text);;
+               }
+               # Encode remaining <'s
+               $text = str_replace('<', '&lt;', $text);
+
+               return $text;
+       }
+
+
+       function doAutoLinks($text) {
+               $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', 
+                       array(&$this, '_doAutoLinks_url_callback'), $text);
+
+               # Email addresses: <address@domain.foo>
+               $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 = "<a href=\"$url\">$url</a>";
+               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.:
+       #
+       #         <p><a href="&#109;&#x61;&#105;&#x6c;&#116;&#x6f;&#58;&#x66;o&#111;
+       #        &#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;&#101;&#46;&#x63;&#111;
+       #        &#x6d;">&#x66;o&#111;&#x40;&#101;&#x78;&#97;&#x6d;&#112;&#x6c;
+       #        &#101;&#46;&#x63;&#111;&#x6d;</a></p>
+       #
+       #       Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
+       #   With some optimizations by Milian Wolff.
+       #
+               $addr = "mailto:" . $addr;
+               $chars = preg_split('/(?<!^)(?!$)/', $addr);
+               $seed = (int)abs(crc32($addr) / strlen($addr)); # Deterministic seed.
+               
+               foreach ($chars as $key => $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] = '&#x'.dechex($ord).';';
+                               else              $chars[$key] = '&#'.$ord.';';
+                       }
+               }
+               
+               $addr = implode('', $chars);
+               $text = implode('', array_slice($chars, 7)); # text without `mailto:`
+               $addr = "<a href=\"$addr\">$text</a>";
+
+               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.'
+                               |
+                                       (?<![`\\\\])
+                                       `+                                              # code span marker
+                       '.( $this->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 <div> and <table> as well).
+
+For more information about Markdown's syntax, see:
+
+<http://daringfireball.net/projects/markdown/>
+
+
+Bugs
+----
+
+To file bug reports please send email to:
+
+<michel.fortin@michelf.com>
+
+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  
+<http://michelf.com/>  
+All rights reserved.
+
+Based on Markdown
+Copyright (c) 2003-2006 John Gruber   
+<http://daringfireball.net/>   
+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
index caf3ce1728b68fcc48484b0fd958ca7e4054a363..605dfdead8517e840dc67a425b510c805947fe57 100644 (file)
 <?php
 
 
-       function get_template_instance()
-       {
-           $t = new Template();
-           $t->template_dir = join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), '..', 'templates'));  
-           return $t;
-       }
-
-
-   /**
-    * @param    string  $format     "text", "xml", etc.
-    * @param    string  $default    Default format
-    * @return   array   Format, mime-type
-    */
-    function parse_format($format, $default)
-    {
-        $types = array('html' => 'text/html',
-                       'text' => 'text/plain',
-                       '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]);
+function get_template_instance()
+{
+    $t = new Template();
+    $t->template_dir = join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), '..', 'templates')); 
+    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<key>[\w+\.\-]+?)\s*=\s*(?P<value>.+?)\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;
     }
+}
 
 
-       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<key>[\w+\.\-]+?)\s*=\s*(?P<value>.+?)\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;
-           }
-       }
-           
-       
-       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_base_dir()
-    {
-        if(php_sapi_name() == 'cli') return CLI_BASE_DIRECTORY;
-        return rtrim(dirname($_SERVER['SCRIPT_NAME']), DIRECTORY_SEPARATOR);
-    }
-    
-    
-    function get_site_root()
-    {
-            return LOCAL_SITE_ROOT;
-    }
+/**
+* @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';
 
-    
-    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_domain($url)
-    {
-        $parsed = parse_url($url);
-        return $parsed['host'];
-    }
-    
-    
-    function include_template($template)
-    {
-        include ( TEMPLATE_DIR . $template );
-    }    
+       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';
+   }
+}
     
-       function exec_php( $matches ) 
-       {
-               try  {
-                       eval('ob_start();' . $matches[1] . '$inline_execute_output = ob_get_contents(); ob_end_clean();');
-               } 
-               catch (Exception $e) { }
-               return $inline_execute_output;
-       }
-    
-    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;        
-    }
-    
-    
-   /**
-    * @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');
-    }
-    
-    
-    /**
-     * Replace line breaks with <br />.  I don't usr nl2br because it doesn't remove the line breaks, it just adds the <br />
-     * @param string $str
-     * @return string
-     */
-    function clean($str) 
-    {
-      $str = str_replace("\r", "", $str);  // Remove \r
-      $str = str_replace("\n", "<br />", $str);  // Replace \n with <br />
-      return $str;
-    }
-    
-    
-  /**
-   * This function cleans up a string and make it ready to be displayed in a textarea field.
-   * Replaces <br /> with line breaks which is easier to read for the user.
-   *
-   * @param string $str
-   * @return string
-   */
-    function clean_for_textarea($str) {
-        $str = clean($str);
-        $str = str_replace("<br />", "\n", $str);
-        return $str;
-    }
 
+/**
+* @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 die_with_code($code, $message)
-    {
-        header("HTTP/1.1 {$code}");
-        die($message);
-    }
 
-    
-    function print_pre($arr)
-    {
-        echo '<pre style="position:absolute;z-index:1000; background:#232323; padding:10px; ">';
-        print_r($arr);
-        echo '</pre>';
-    }
+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 generate_thumbs($src, $dest, $w, $h)
-    {
-        exec('ls -1 ' . $src, $files);
-       foreach ($files as $f) {
-               system("convert " . $src . $f . " -resize " . $w . "x" . $h . " " . $dest . $f);
-       }
-    }
-    
-    if(false)
-        generate_thumbs(
-            '/home/quilime/gabrieldunne.com/dev/projects/bay_area_transit/images/',
-            '/home/quilime/gabrieldunne.com/dev/projects/bay_area_transit/images/thumbs_lg/',
-            900,
-            800
-            );
-
-
-    function qt($args)
-    {
-       ?>
-               <object 
-                   classid="clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b" 
-                   id="qt_object" 
-                   width="<?=$args['width']?>" 
-                   height="<?=$args['height']?>" 
-                   codebase="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0">
-                       <param name="type" value="video/quicktime"><param name="name" value="qt_object">
-                       <param name="nocache" value="true"><param name="false" value="true">
-                       <param name="controller" value="true">
-                       <param name="bgcolor" value="#000000">
-                       <param name="src" value="<?=$args['file']?>">
-                       <param name="pluginspage" value="http://www.apple.com/quicktime/download/indext.html">          
-                       <embed 
-                           name="qt_object" 
-                           width="<?=$args['width']?>" 
-                           height="<?=$args['height']?>" 
-                           controller="true" 
-                           autoplay="false" 
-                           src="<?=$args['file']?>" 
-                           nocache="true" 
-                           type="video/quicktime" 
-                           bgcolor="#000000" 
-                           border="0" 
-                           pluginspage="http://www.apple.com/quicktime/download/indext.html" 
-                           enablejavascript="true">
-                       </embed>
-               </object>
-       <?
-    }
 
+function die_with_code($code, $message)
+{
+   header("HTTP/1.1 {$code}");
+   die($message);
+}   
 
-        
-    
- ?>
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+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_base_dir()
+{
+    if(php_sapi_name() == 'cli') return CLI_BASE_DIRECTORY;
+    return rtrim(dirname($_SERVER['SCRIPT_NAME']), DIRECTORY_SEPARATOR);
+}
+
+
+function get_site_root()
+{
+        return LOCAL_SITE_ROOT;
+}
+
+
+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_domain($url)
+{
+    $parsed = parse_url($url);
+    return $parsed['host'];
+}
+
+
+
+?>
\ No newline at end of file
index 31598dac2131632cd25d4f39140d8404d82733d8..b66cd1d200be257a44e3429dc3d77a54d0bee8e0 100644 (file)
@@ -7,7 +7,6 @@ class Template
        
        var $_tpl_vars = array();
 
-       
        function __construct()
        {
                
@@ -44,6 +43,12 @@ class Template
                        include( $this->template_dir . DIRECTORY_SEPARATOR . 'default.'.$this->response_format.'.tpl' );                
                        
        }
+       
+       
+       public function title()
+       {
+               return "";
+       }
 }
 
 ?>
\ No newline at end of file
diff --git a/pages/about b/pages/about
new file mode 100644 (file)
index 0000000..4d30f20
--- /dev/null
@@ -0,0 +1,12 @@
+title = about
+--
+a codification of exploration, resources, and creativity.
+
+**author**: gabriel dunne ([email](&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#x67;&#x64;&#x75;&#x6e;&#110;&#x65;&#x40;&#x71;&#117;&#105;&#x6c;&#x69;&#x6d;&#101;&#x2e;&#x63;&#111;&#x6d;), [www](http://gabrieldunne.com))  
+**elsewhere**: 
+[flickr](http://flickr.com/photos/quilime/), 
+[delicious](http://delicious.com/quilime/), 
+[vimeo](http://vimeo.com/quilime/), 
+[github](http://github.com/quilime/)
+
+[rss](http://quilime.com/.rss)
\ No newline at end of file
diff --git a/pages/links b/pages/links
new file mode 100644 (file)
index 0000000..908153e
--- /dev/null
@@ -0,0 +1,22 @@
+title = links
+type = page
+markdown = true
+--
++ [stephanie sherriff](http://ssherriff.com) &rarr;
++ [ryan alexander](http://onecm.com) &rarr;
++ [daniel massey](http://oddsympathy.com) &rarr;
++ [joshua nimoy](http://jtnimoy.net) &rarr;
++ [keith pasko](http://keithpasko.com) &rarr;
++ [jeff lubow](http://dabkitsch.com/jml/) &rarr;
++ [carbon workshop (gustavo huber & shelly brown)](http://carbonworkshop.com) &rarr;
++ [sascha pohflepp](http://pohflepp.com) &rarr;
++ [mylinh trieu](http://mylinhtrieu.com) &rarr;
++ [aaron meyers](http://universaloscillation.com) &rarr;
++ [tom carden](http://tom-carden.co.uk) &rarr;
++ [michal migurski](http://mike.teczno.com) &rarr;
++ [adam roth](http://ripevessel.com) &rarr;
++ [david rager](http://davidrager.org) &rarr;
++ [marc nimoy](http://digitanalog.net) &rarr;
++ [matthew gale](http://makaga.com) &rarr;
++ [frédéric eyl](http://fredericeyl.de) &rarr;
++ [the green eyl](http://thegreeneyl.com) &rarr;
\ No newline at end of file
similarity index 100%
rename from .htaccess
rename to public/.htaccess
diff --git a/public/aggregate b/public/aggregate
new file mode 120000 (symlink)
index 0000000..d9055e4
--- /dev/null
@@ -0,0 +1 @@
+/home/quilime/media.quilime.com/aggregate/
\ No newline at end of file
similarity index 93%
rename from css/style.css
rename to public/css/style.css
index 3aff87e98af976303011ba9171f82b5aabf13e6e..b50e99878341dabfb27b69ee19b8b93e2c0aa781 100644 (file)
@@ -29,6 +29,8 @@ 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; }
@@ -79,6 +81,9 @@ table.archive td {padding-right:20px; }
     
 .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; }
similarity index 100%
rename from css/style2.css
rename to public/css/style2.css
similarity index 100%
rename from js/js.js
rename to public/favicon.gif
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/public/index.php b/public/index.php
new file mode 100644 (file)
index 0000000..c3442e0
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+
+    require_once '../lib/init.php';
+
+    $url_parts = get_url();
+
+       list($response_format, $response_mime_type) = parse_format($url_parts['extension'], 'html');    
+       
+       $t = get_template_instance();   
+       $t->response_format = $response_format;
+       $t->assign('view', $_GET['v']);
+       $template = 'default.'.$response_format.'.tpl';
+               
+       # 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/public/js/js.js b/public/js/js.js
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/templates/about.html.tpl b/templates/about.html.tpl
deleted file mode 100644 (file)
index c212426..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<html>
-
-<head>
-
-    <?php $this->include_template( 'head-inc.html.tpl' ); ?>
-        
-    <title><?php echo SITE_TITLE ?> - about</title>
-    
-<? $page = "about"; ?>
-
-</head>
-
-<body>
-    
-    <?php include('nav.html'); ?>
-
-    <div id="content">
-       
-        <p>
-               
-                       &lsquo;quilime&rsquo; is a codification of exploration, resources, and creativity.
-                       <br/>
-                       <br/>
-                       <strong>author</strong>: gabriel dunne (<a href="&#x6d;&#x61;&#x69;&#108;&#x74;&#111;&#x3a;&#x67;&#x64;&#x75;&#x6e;&#110;&#x65;&#x40;&#x71;&#117;&#105;&#x6c;&#x69;&#x6d;&#101;&#x2e;&#x63;&#111;&#x6d;">email</a>, <a href="http://gabrieldunne.com">www</a>)
-                                       <br/>   
-                       <strong>elsewhere</strong>:
-       <a href="http://flickr.com/photos/quilime/">flickr</a>, 
-       <a href="http://delicious.com/quilime/">delicious</a>,
-       <a href="http://vimeo.com/quilime/">vimeo</a>,  
-       <a href="http://github.com/quilime/">github</a>
-               </p>
-       <br/>
-
-
-
-       
-
-    </div>
-    
-</body>
-
-</html>
\ No newline at end of file
index 698ed55c3741e196878d44a3c5a0dbd59799c0ae..eaab793eba72dd5b1b2b074d21d51df5795a974f 100644 (file)
@@ -3,7 +3,7 @@
     
     <? $this->include_template('head-inc.html.tpl') ?>
     
-    <title><?=SITE_TITLE?></title>
+    <title><?=SITE_TITLE?><?=$this->title(); ?></title>
     
 </head>
 <body>
 <div id="content">
 
        <? foreach($data as $entry): ?>
-       <? $this->include_template('entry.html.tpl', array('entry' => $entry)); ?>
-       <? endforeach; ?>
-       
-       <? if ($view == "archive") : ?>
-               <a href="<?=$list_url?>">view list</a>
-       <? else : ?>
-               <a href="<?=$archive_url?>">view archive</a>
-       <? endif; ?>    
+       <? $this->include_template('entry.html.tpl', array('data' => $entry)); ?>
+       <? endforeach; ?>       
        
 </div>
 
-
        <? $this->include_template('footer.html.tpl') ?>
 
 </body>
diff --git a/templates/default.rss.tpl b/templates/default.rss.tpl
new file mode 100644 (file)
index 0000000..005bc1f
--- /dev/null
@@ -0,0 +1,24 @@
+<? echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
+<rss version="2.0">
+       
+       <channel>
+               
+       <atom:link rel="hub" href="http://quilime.com" xmlns:atom="http://www.w3.org/2005/Atom"/>
+
+       <title>quilime</title>
+       <link>http://www.quilime.com/</link>
+       <description>a codification of exploration, resources, and creativity by gabriel dunne</description>
+
+       <? foreach($data as $entry): ?>
+       <item>
+               <title><?=$entry['title']?></title>
+               <description><?=htmlentities($entry['content']);?></description>
+               <link><?=$entry['url']?></link>
+               <guid><?=$entry['url']?></guid>
+               <pubDate><?=date('r', $entry['timestamp'])?></pubDate>          
+       </item>
+       <? endforeach; ?>               
+
+       </channel>
+       
+</rss>
diff --git a/templates/default.txt.tpl b/templates/default.txt.tpl
new file mode 100644 (file)
index 0000000..bfef63c
--- /dev/null
@@ -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'], '<img>'), 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/entries.html.tpl b/templates/entries.html.tpl
deleted file mode 100644 (file)
index 02ebf5f..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-<html>
-
-<head>
-
-    <? $this->include_template('head-inc.html.tpl') ?>
-        
-    <title>
-        <?=SITE_TITLE; ?>
-        <? if ($single): ?> 
-                       - log: <?= $data['title']; ?> 
-                       [<?=date("Y M d", strtotime($data['date']));?>]
-               <? else: ?>
-                       - log
-               <? endif; ?>
-       </title>
-
-</head>
-
-<body>
-    
-    <?php $this->include_template('nav.html'); ?>
-
-    <div id="content">
-
-        <?php if ($single) : ?>
-       
-                       <? //$this->include_template('entry.html.tpl', array('entry' => $item)); ?>             
-
-               <h2>
-                   <a title="posted <?php echo get_relative_time($data['timestamp']); ?>" href="<?php echo $data['url'];?>">
-                       <?php echo $data['title']; ?>
-                               </a><small>[<?php echo date("Y M d", strtotime($data['date']));?>]</small>
-               </h2>           
-       
-            <div class="content">
-            <?=$data['inline_content'];?>
-            </div>                     
-
-        <?php elseif ($view == 'archive'): ?>
-        
-           <table class="archive" cellspacing="0" cellpadding="0">
-                <tr>
-                <td style="text-align:right; padding-right:1em;">
-             
-                </td>
-                <td>
-                </td>
-                <?php 
-                    $c = 1; 
-                    foreach($data as $log): 
-                ?>
-                <tr>
-                <td style="text-align:right; padding-right:1em;">
-                <span class="date"><?php echo date("m/d/Y", $log['timestamp']); ?></span>
-                </td>
-                <td>
-                    <strong>
-                                   <a onmouseout="$('.c_pop').hide();" onmouseover="$('.c_pop').hide(); $('#c_<?php echo $c; ?>').show();" href="<?php echo $log['url']?>"><?php echo $log['title']; ?></a>
-                               </strong>
-                    <div id="c_<?php echo $c; ?>" class="c_pop">
-                    <?=$log['content']; ?>
-                    </div>
-                </td>
-                </tr>
-            <?  $c++;  endforeach; ?>
-            </table> 
-            
-            <br/>
-            
-                <a class="func" href="/log/">view inline</a>
-          
-            
-
-
-            
-        <?php else: ?>
-       
-            <ul class="inline_content log">
-            <?php foreach($data as $log): ?>
-                   <li>
-                       <h3>
-                               
-                           <a title="<?php echo get_relative_time($log['timestamp']); ?>" href="<?php echo $log['url'];?>">
-                               <?php echo $log['title']; ?></a>   
-                       </h3>      
-                    <div class="content">              
-                    <?php echo $log['content']; ?>
-                    </div>
-                </li>
-            <? endforeach; ?>
-            </ul>
-            
-            <br/>            
-            <a class="func" href="/log/?v=archive">view archive</a>
-           
-            
-        <?php endif; ?>
-                
-    </div>
-    
-</body>
-
-</html>
\ No newline at end of file
index 168b73004f7a179b205b45668b51000e9624311a..d0f1a4a11753ad1410f6dbc49b49ddd0e1283617 100644 (file)
@@ -1,13 +1,23 @@
 <div class="entry">
-       
+
        <h2>
-               <a title="posted on <?=$entry['date']?>" href="<?=$entry['url']?>"><?=$entry['title']?></a>
+               <a title="posted on <?=$data['date']?>" href="<?=$data['url']?>"><?=$data['title']?></a>
+               <span class="title-date" title="<?=date("F d, Y", $data['timestamp'])?>"><?=get_relative_time($data['timestamp']);?></span>             
        </h2>
-       
+
        <div class="content">
-               
-       <?=$entry['content']?>
-       
+               <?=$data['content']?>
        </div>
-       
+
+       <? if ($single) :?>
+       <div class="metadata">
+               posted <?=date("F d, Y", $data['timestamp'])?> in <a href="/<?=$data['cat'];?>/"><?=$data['cat'];?></a><br/>
+               <ul class="tags">
+               <? foreach($data['tags'] as $tag) : ?>
+               <li>#<?=$tag?></li>
+               <? endforeach; ?>
+               </ul>
+       </div>
+       <? endif; ?>
+
 </div>
index 5904973f91f5b77ae4dc03e0fa9ab5fd2f291e92..d02f1e39580a51bfcf5474c9aa1e7a3e627f986c 100644 (file)
@@ -1,6 +1,7 @@
 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">    
 <meta name="google-site-verification" content="1OBSuW_Qc3OFWC8whRGv2DJxQUUZkjcaY_cdd6PpdR8" />
+<link rel="alternate" type="application/rss+xml" title="RSS" href="<?= get_base_dir(); ?>/.rss" />
 
 <script type="text/javascript" src="<?= get_base_dir(); ?>/js/jquery-1.3.2.min.js"></script>
 <!-- code prettifyier -->
index 112ef3d1bd652e6885b32a30d5f1760aaf9a7dcf..7b4e1eefa77a21c2494fc41e96b304d947c71b9f 100644 (file)
@@ -54,6 +54,8 @@
                     );
         ?>
 
+
+
         <ul>
             <?php linklist($people); ?>
         </ul>
diff --git a/templates/page.html.tpl b/templates/page.html.tpl
new file mode 100644 (file)
index 0000000..84d6e84
--- /dev/null
@@ -0,0 +1,22 @@
+<html>
+<head>
+    
+    <? $this->include_template('head-inc.html.tpl') ?>
+    
+    <title><?=SITE_TITLE?><?=$this->title();?></title>
+    
+</head>
+<body>
+    
+    <? $this->include_template('nav.html') ?>
+    
+<div id="content">
+
+       <?=$data['content'];?>
+       
+</div>
+
+       <? $this->include_template('footer.html.tpl') ?>
+
+</body>
+</html>
diff --git a/templates/single.html.tpl b/templates/single.html.tpl
new file mode 100644 (file)
index 0000000..4f0d526
--- /dev/null
@@ -0,0 +1,20 @@
+<html>
+<head>
+    
+    <? $this->include_template('head-inc.html.tpl') ?>
+    
+    <title><?=SITE_TITLE?><?=$this->title(); ?></title>
+    
+</head>
+<body>
+    
+    <? $this->include_template('nav.html') ?>
+    
+       <div id="content">
+               <? $this->include_template('entry.html.tpl', array('data' => $data)); ?>        
+       </div>
+
+       <? $this->include_template('footer.html.tpl') ?>
+
+</body>
+</html>