Initial import.
authorAndreas Boehler <andreas@aboehler.at>
Wed, 11 Mar 2015 21:53:17 +0100
changeset 0 d5b5fe08c7eb
child 1 3139de083d8f
Initial import.
plugin.info.txt
style.css
syntax.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin.info.txt	Wed Mar 11 21:53:17 2015 +0100
@@ -0,0 +1,7 @@
+base   csstimeline
+author Andreas Boehler
+email  dev@aboehler.at
+date   2015-03-11
+name   csstimeline plugin
+desc   Create a CSS-only timeline; CSS is from http://nilswe.com/lab/css-timeline/
+url    http://www.aboehler.at
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/style.css	Wed Mar 11 21:53:17 2015 +0100
@@ -0,0 +1,288 @@
+body {	
+  margin: 0;
+  padding: 0;
+  background: rgb(230,230,230);
+  
+  color: rgb(50,50,50);
+  font-family: 'Open Sans', sans-serif;
+  font-size: 112.5%;
+  line-height: 1.6em;
+}
+
+/* ================ The Timeline ================ */
+
+.timeline {
+  position: relative;
+  width: 660px;
+  margin: 0 auto;
+  margin-top: 20px;
+  padding: 1em 0;
+  list-style-type: none;
+}
+
+.timeline:before {
+  position: absolute;
+  left: 50%;
+  top: 0;
+  content: ' ';
+  display: block;
+  width: 6px;
+  height: 100%;
+  margin-left: -3px;
+  background: rgb(80,80,80);
+  background: -moz-linear-gradient(top, rgba(80,80,80,0) 0%, rgb(80,80,80) 8%, rgb(80,80,80) 92%, rgba(80,80,80,0) 100%);
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(30,87,153,1)), color-stop(100%,rgba(125,185,232,1)));
+  background: -webkit-linear-gradient(top, rgba(80,80,80,0) 0%, rgb(80,80,80) 8%, rgb(80,80,80) 92%, rgba(80,80,80,0) 100%);
+  background: -o-linear-gradient(top, rgba(80,80,80,0) 0%, rgb(80,80,80) 8%, rgb(80,80,80) 92%, rgba(80,80,80,0) 100%);
+  background: -ms-linear-gradient(top, rgba(80,80,80,0) 0%, rgb(80,80,80) 8%, rgb(80,80,80) 92%, rgba(80,80,80,0) 100%);
+  background: linear-gradient(to bottom, rgba(80,80,80,0) 0%, rgb(80,80,80) 8%, rgb(80,80,80) 92%, rgba(80,80,80,0) 100%);
+  
+  z-index: 5;
+}
+
+.timeline li {
+  padding: 1em 0;
+  margin: 0;
+}
+
+.timeline li:after {
+  content: "";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+
+.direction-l {
+  position: relative;
+  width: 300px;
+  float: left;
+  text-align: right;
+}
+
+.direction-r {
+  position: relative;
+  width: 300px;
+  float: right;
+}
+
+.flag-wrapper {
+  position: relative;
+  display: inline-block;
+  
+  text-align: center;
+}
+
+.flag {
+  position: relative;
+  display: inline;
+  background: rgb(248,248,248);
+  padding: 6px 10px;
+  border-radius: 5px;
+  
+  font-weight: 600;
+  text-align: left;
+}
+
+.direction-l .flag {
+  -webkit-box-shadow: -1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
+  -moz-box-shadow: -1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
+  box-shadow: -1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
+}
+
+.direction-r .flag {
+  -webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
+  -moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
+  box-shadow: 1px 1px 1px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.15);
+}
+
+.direction-l .flag:before,
+.direction-r .flag:before {
+  position: absolute;
+  top: 50%;
+  right: -40px;
+  content: ' ';
+  display: block;
+  width: 12px;
+  height: 12px;
+  margin-top: -10px;
+  background: #fff;
+  border-radius: 10px;
+  border: 4px solid rgb(255,80,80);
+  z-index: 10;
+}
+
+.direction-r .flag:before {
+  left: -40px;
+}
+
+.direction-l .flag:after {
+  content: "";
+  position: absolute;
+  left: 100%;
+  top: 50%;
+  height: 0;
+  width: 0;
+  margin-top: -8px;
+  border: solid transparent;
+  border-left-color: rgb(248,248,248);
+  border-width: 8px;
+  pointer-events: none;
+}
+
+.direction-r .flag:after {
+  content: "";
+  position: absolute;
+  right: 100%;
+  top: 50%;
+  height: 0;
+  width: 0;
+  margin-top: -8px;
+  border: solid transparent;
+  border-right-color: rgb(248,248,248);
+  border-width: 8px;
+  pointer-events: none;
+}
+
+.time-wrapper {
+  display: inline;
+  
+  line-height: 1em;
+  font-size: 0.66666em;
+  color: rgb(250,80,80);
+  vertical-align: middle;
+}
+
+.direction-l .time-wrapper {
+  float: left;
+}
+
+.direction-r .time-wrapper {
+  float: right;
+}
+
+.time {
+  display: inline-block;
+  padding: 4px 6px;
+  background: rgb(248,248,248);
+}
+
+.desc {
+  margin: 1em 0.75em 0 0;
+  
+  font-size: 0.77777em;
+  font-style: italic;
+  line-height: 1.5em;
+}
+
+.direction-r .desc {
+  margin: 1em 0 0 0.75em;
+}
+
+/* ================ Timeline Media Queries ================ */
+
+@media screen and (max-width: 660px) {
+
+.timeline {
+ 	width: 100%;
+	padding: 4em 0 1em 0;
+}
+
+.timeline li {
+	padding: 2em 0;
+}
+
+.direction-l,
+.direction-r {
+	float: none;
+	width: 100%;
+
+	text-align: center;
+}
+
+.flag-wrapper {
+	text-align: center;
+}
+
+.flag {
+	background: rgb(255,255,255);
+	z-index: 15;
+}
+
+.direction-l .flag:before,
+.direction-r .flag:before {
+  position: absolute;
+  top: -30px;
+	left: 50%;
+	content: ' ';
+	display: block;
+	width: 12px;
+	height: 12px;
+	margin-left: -9px;
+	background: #fff;
+	border-radius: 10px;
+	border: 4px solid rgb(255,80,80);
+	z-index: 10;
+}
+
+.direction-l .flag:after,
+.direction-r .flag:after {
+	content: "";
+	position: absolute;
+	left: 50%;
+	top: -8px;
+	height: 0;
+	width: 0;
+	margin-left: -8px;
+	border: solid transparent;
+	border-bottom-color: rgb(255,255,255);
+	border-width: 8px;
+	pointer-events: none;
+}
+
+.time-wrapper {
+	display: block;
+	position: relative;
+	margin: 4px 0 0 0;
+	z-index: 14;
+}
+
+.direction-l .time-wrapper {
+	float: none;
+}
+
+.direction-r .time-wrapper {
+	float: none;
+}
+
+.desc {
+	position: relative;
+	margin: 1em 0 0 0;
+	padding: 1em;
+	background: rgb(245,245,245);
+	-webkit-box-shadow: 0 0 1px rgba(0,0,0,0.20);
+	-moz-box-shadow: 0 0 1px rgba(0,0,0,0.20);
+	box-shadow: 0 0 1px rgba(0,0,0,0.20);
+	
+  z-index: 15;
+}
+
+.direction-l .desc,
+.direction-r .desc {
+	position: relative;
+	margin: 1em 1em 0 1em;
+	padding: 1em;
+	
+  z-index: 15;
+}
+
+}
+
+@media screen and (min-width: 400px) and (max-width: 660px) {
+
+.direction-l .desc,
+.direction-r .desc {
+	margin: 1em 4em 0 4em;
+}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syntax.php	Wed Mar 11 21:53:17 2015 +0100
@@ -0,0 +1,123 @@
+<?php
+/**
+ * csstimeline Plugin - Create a CSS-only timeline
+ *
+ * Usage:
+ *
+ * <csstimeline>
+ * <entry>
+ * date: 04.12.2014
+ * title: My first timeline entry
+ * description: Within the description, you can even use Wiki markup
+ * </entry>
+ * <entry>
+ * date: 06.01.2015
+ * title: My second timeline entry
+ * description: This one is rendered at the other side of the timeline
+ * </entry>
+ * </csstimeline>
+ *
+ *
+ * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author     Andreas Böhler <dev@aboehler.at>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_csstimeline extends DokuWiki_Syntax_Plugin {
+
+
+    function getType() { 
+        return 'substition'; 
+    }
+    
+    function getPType() { 
+        return 'normal'; 
+    }
+    
+    function getAllowedTypes() { 
+        return array('container','substition','protected','disabled','paragraphs','formatting'); 
+    }
+    
+    function getSort() { 
+        return 777; 
+    }
+    
+    function connectTo($mode) { 
+        $this->Lexer->addSpecialPattern('<csstimeline>.*</csstimeline>',$mode,'plugin_csstimeline');
+    }
+
+   /**
+    * Handle the match. Use either the standard linking mechanism or, when enabled,
+    * pass the title through the parser
+    */
+    function handle($match, $state, $pos, Doku_Handler $handler) {
+        $match = substr($match, 13, -14);
+        $lines = explode("\n",$match);
+        $data = array();
+        $cnt = 0;
+        $data['entries'] = array();
+        foreach($lines as $line)
+        {
+            $line = trim($line);
+            if($line)
+            {
+                $lineSplit = explode(':', $line, 2);
+                switch(trim($lineSplit[0]))
+                {
+                    case '<entry>':
+                        break;
+                    case '</entry>':
+                        $cnt++;
+                        break;
+                    case 'description':
+                        $data['entries'][$cnt]['description'] = $this->render_text(trim($lineSplit[1]));
+                        break;
+                    default:
+                        $data['entries'][$cnt][$lineSplit[0]] = hsc(trim($lineSplit[1]));
+                        
+                
+                }
+            }
+        }
+
+        return $data;
+    }
+
+   /**
+    * Create output. This is largely based on the internal linking mechanism.
+    */
+    function render($mode, Doku_Renderer $renderer, $data) {
+        if (empty($data)) return false;
+        
+
+        if($mode == 'xhtml') {
+            $direction = 'r';
+            $renderer->doc .= '<div class="clearer"></div><div><ul class="timeline">';
+            foreach($data['entries'] as $entry)
+            {
+                $renderer->doc .= '<li>';
+                $renderer->doc .= '<div class="direction-'.$direction.'">';
+                $renderer->doc .= '<div class="flag-wrapper">';
+                $renderer->doc .= '<span class="flag">'.$entry['title'].'</span>';
+                $renderer->doc .= '<span class="time-wrapper"><span class="time">'.$entry['date'].'</span></span>';
+                $renderer->doc .= '</div>';
+                $renderer->doc .= '<div class="desc">'.$entry['description'].'</div>';
+                $renderer->doc .= '</li>';
+                if($direction === 'r')
+                    $direction = 'l';
+                else
+                    $direction = 'r';
+            }
+            $renderer->doc .= '</ul></div>';
+            
+        }
+        return false;
+    }
+}