diff --git a/plugin.info.txt b/plugin.info.txt new file mode 100644 --- /dev/null +++ b/plugin.info.txt @@ -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 diff --git a/style.css b/style.css new file mode 100644 --- /dev/null +++ b/style.css @@ -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; +} + +} diff --git a/syntax.php b/syntax.php new file mode 100644 --- /dev/null +++ b/syntax.php @@ -0,0 +1,123 @@ + + * + * date: 04.12.2014 + * title: My first timeline entry + * description: Within the description, you can even use Wiki markup + * + * + * date: 06.01.2015 + * title: My second timeline entry + * description: This one is rendered at the other side of the timeline + * + * + * + * + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Andreas Böhler + */ + +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('.*',$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 '': + break; + case '': + $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 .= '
'; + + } + return false; + } +}