8
0

Merge branch 'development' of https://github.com/justinwalsh/daux.io into development

* 'development' of https://github.com/justinwalsh/daux.io:
  Add Table Of Contents feature
  Compile latest version
  Fix floating value read
  Improve toggle usability
  Generate can fall back to daux.phar, fixes #354
  Add an arrow to open sub-trees, fixes #277
  Updates
  Finalize search feature for merge
  Add `getPureContent` to Page to be able to get content without template
  Update the list of demos
  Fix dynamic website
  First checkin of search for static websites
  Compile latest version
  Add computed raw pages, to create special content at any time
  Small tweaks
Dieser Commit ist enthalten in:
Stéphane Goetz 2016-04-13 17:48:05 +02:00
Commit fb7343c109
54 geänderte Dateien mit 1306 neuen und 168 gelöschten Zeilen

Datei anzeigen

@ -16,9 +16,10 @@
"league/plates": "~3.1",
"guzzlehttp/guzzle": "~5.3",
"league/commonmark": "^0.13",
"symfony/console": "~2.7",
"symfony/finder": "~2.7",
"webuni/commonmark-table-extension": "0.4.*"
"symfony/console": "~3.0",
"symfony/finder": "~3.0",
"webuni/commonmark-table-extension": "0.4.*",
"myclabs/deep-copy": "^1.5"
},
"autoload": {
"psr-4": {

161
composer.lock generiert
Datei anzeigen

@ -1,10 +1,11 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "9be46791fa9d61c2ded921a54980712f",
"hash": "5d99c57e9efe49df55a765026a15f586",
"content-hash": "88197b6eaf8fc4b266eb8c72b115580a",
"packages": [
{
"name": "guzzlehttp/guzzle",
@ -167,16 +168,16 @@
},
{
"name": "league/commonmark",
"version": "0.13.0",
"version": "0.13.2",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "a4e93bc4fd1a8ff8f534040c4a07371ea5f4b484"
"reference": "35ac362082ca983a8123df2ee2cdfcf456ab6295"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/a4e93bc4fd1a8ff8f534040c4a07371ea5f4b484",
"reference": "a4e93bc4fd1a8ff8f534040c4a07371ea5f4b484",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/35ac362082ca983a8123df2ee2cdfcf456ab6295",
"reference": "35ac362082ca983a8123df2ee2cdfcf456ab6295",
"shasum": ""
},
"require": {
@ -188,12 +189,12 @@
},
"require-dev": {
"erusev/parsedown": "~1.0",
"jgm/commonmark": "0.24",
"jgm/commonmark": "0.25",
"michelf/php-markdown": "~1.4",
"mikehaertl/php-shellcommand": "~1.1.0",
"mikehaertl/php-shellcommand": "~1.2.0",
"phpunit/phpunit": "~4.3|~5.0",
"scrutinizer/ocular": "^1.1",
"symfony/finder": "~2.3"
"scrutinizer/ocular": "~1.1",
"symfony/finder": "~2.3|~3.0"
},
"suggest": {
"league/commonmark-extras": "Library of useful extensions including smart punctuation"
@ -220,7 +221,7 @@
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "http://www.colinodell.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
@ -231,7 +232,7 @@
"markdown",
"parser"
],
"time": "2016-01-14 04:29:54"
"time": "2016-03-27 19:10:13"
},
{
"name": "league/plates",
@ -286,17 +287,59 @@
"time": "2015-07-09 02:14:40"
},
{
"name": "react/promise",
"version": "v2.2.1",
"name": "myclabs/deep-copy",
"version": "1.5.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627"
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627",
"reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e3abefcd7f106677fd352cd7c187d6c969aa9ddc",
"reference": "e3abefcd7f106677fd352cd7c187d6c969aa9ddc",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"doctrine/collections": "1.*",
"phpunit/phpunit": "~4.1"
},
"type": "library",
"autoload": {
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"homepage": "https://github.com/myclabs/DeepCopy",
"keywords": [
"clone",
"copy",
"duplicate",
"object",
"object graph"
],
"time": "2015-11-07 22:20:37"
},
{
"name": "react/promise",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "f942da7b505d1a294284ab343d05df42d02ad6d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/f942da7b505d1a294284ab343d05df42d02ad6d9",
"reference": "f942da7b505d1a294284ab343d05df42d02ad6d9",
"shasum": ""
},
"require": {
@ -327,30 +370,30 @@
}
],
"description": "A lightweight implementation of CommonJS Promises/A for PHP",
"time": "2015-07-03 13:48:55"
"time": "2016-03-31 13:10:33"
},
{
"name": "symfony/console",
"version": "v2.8.2",
"version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "d0239fb42f98dd02e7d342f793c5d2cdee0c478d"
"reference": "6b1175135bc2a74c08a28d89761272de8beed8cd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/d0239fb42f98dd02e7d342f793c5d2cdee0c478d",
"reference": "d0239fb42f98dd02e7d342f793c5d2cdee0c478d",
"url": "https://api.github.com/repos/symfony/console/zipball/6b1175135bc2a74c08a28d89761272de8beed8cd",
"reference": "6b1175135bc2a74c08a28d89761272de8beed8cd",
"shasum": ""
},
"require": {
"php": ">=5.3.9",
"php": ">=5.5.9",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/event-dispatcher": "~2.1|~3.0.0",
"symfony/process": "~2.1|~3.0.0"
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/process": "~2.8|~3.0"
},
"suggest": {
"psr/log": "For using the console logger",
@ -360,7 +403,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
"dev-master": "3.0-dev"
}
},
"autoload": {
@ -387,29 +430,29 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2016-01-14 08:33:16"
"time": "2016-03-16 17:00:50"
},
{
"name": "symfony/finder",
"version": "v2.8.2",
"version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "c90fabdd97e431ee19b6383999cf35334dff27da"
"reference": "c54e407b35bc098916704e9fd090da21da4c4f52"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/c90fabdd97e431ee19b6383999cf35334dff27da",
"reference": "c90fabdd97e431ee19b6383999cf35334dff27da",
"url": "https://api.github.com/repos/symfony/finder/zipball/c54e407b35bc098916704e9fd090da21da4c4f52",
"reference": "c54e407b35bc098916704e9fd090da21da4c4f52",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
"dev-master": "3.0-dev"
}
},
"autoload": {
@ -436,11 +479,11 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2016-01-14 08:26:52"
"time": "2016-03-10 11:13:05"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.1.0",
"version": "v1.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@ -658,22 +701,24 @@
},
{
"name": "phpspec/prophecy",
"version": "v1.5.0",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7"
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7",
"reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
"reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
"shasum": ""
},
"require": {
"doctrine/instantiator": "^1.0.2",
"php": "^5.3|^7.0",
"phpdocumentor/reflection-docblock": "~2.0",
"sebastian/comparator": "~1.1"
"sebastian/comparator": "~1.1",
"sebastian/recursion-context": "~1.0"
},
"require-dev": {
"phpspec/phpspec": "~2.0"
@ -681,7 +726,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
"dev-master": "1.5.x-dev"
}
},
"autoload": {
@ -714,7 +759,7 @@
"spy",
"stub"
],
"time": "2015-08-13 10:07:40"
"time": "2016-02-15 07:46:21"
},
{
"name": "phpunit/php-code-coverage",
@ -958,16 +1003,16 @@
},
{
"name": "phpunit/phpunit",
"version": "4.8.21",
"version": "4.8.24",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "ea76b17bced0500a28098626b84eda12dbcf119c"
"reference": "a1066c562c52900a142a0e2bbf0582994671385e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea76b17bced0500a28098626b84eda12dbcf119c",
"reference": "ea76b17bced0500a28098626b84eda12dbcf119c",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1066c562c52900a142a0e2bbf0582994671385e",
"reference": "a1066c562c52900a142a0e2bbf0582994671385e",
"shasum": ""
},
"require": {
@ -1026,7 +1071,7 @@
"testing",
"xunit"
],
"time": "2015-12-12 07:45:58"
"time": "2016-03-14 06:16:08"
},
{
"name": "phpunit/phpunit-mock-objects",
@ -1202,16 +1247,16 @@
},
{
"name": "sebastian/environment",
"version": "1.3.3",
"version": "1.3.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
"reference": "6e7133793a8e5a5714a551a8324337374be209df"
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e7133793a8e5a5714a551a8324337374be209df",
"reference": "6e7133793a8e5a5714a551a8324337374be209df",
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
"reference": "dc7a29032cf72b54f36dac15a1ca5b3a1b6029bf",
"shasum": ""
},
"require": {
@ -1248,7 +1293,7 @@
"environment",
"hhvm"
],
"time": "2015-12-02 08:37:27"
"time": "2016-02-26 18:40:46"
},
{
"name": "sebastian/exporter",
@ -1457,16 +1502,16 @@
},
{
"name": "symfony/yaml",
"version": "v3.0.1",
"version": "v3.0.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "3df409958a646dad2bc5046c3fb671ee24a1a691"
"reference": "0047c8366744a16de7516622c5b7355336afae96"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/3df409958a646dad2bc5046c3fb671ee24a1a691",
"reference": "3df409958a646dad2bc5046c3fb671ee24a1a691",
"url": "https://api.github.com/repos/symfony/yaml/zipball/0047c8366744a16de7516622c5b7355336afae96",
"reference": "0047c8366744a16de7516622c5b7355336afae96",
"shasum": ""
},
"require": {
@ -1502,7 +1547,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2015-12-26 13:39:53"
"time": "2016-03-04 07:55:57"
}
],
"aliases": [],

BIN
daux.phar

Binäre Datei nicht angezeigt.

Datei anzeigen

@ -1,5 +1,7 @@
**Daux.io** is an documentation generator that uses a simple folder structure and Markdown files to create custom documentation on the fly. It helps you create great looking documentation in a developer friendly way.
[TOC]
## Features
### For Authors
@ -12,6 +14,7 @@
* [Multiple Languages Support](!Features/Multilanguage)
* [No Build Step](!Features/Live_mode)
* [Static Output Generation](!Features/Static_Site_Generation)
* [Table of Contents](!Features/Table_of_contents)
### For Developers
@ -34,13 +37,11 @@
This is a list of sites using Daux.io:
* [Daux.io](http://daux.io)
* [Gltn - An open-source word processor webapp](http://felkerdigitalmedia.com/gltn/docs/)
* [jDrupal](http://jdrupal.easystreet3.com/8/docs/)
* [DrupalGap](http://docs.drupalgap.org/8/)
* [Invade & Annex 3 - An Arma 3 Co-operative Mission](http://ia3.ahoyworld.co.uk/)
* [Munee: Standalone PHP 5.3 Asset Optimisation & Manipulation](http://mun.ee)
* [ICADMIN: An admin panel powered by CodeIgniter.](http://istocode.com/shared/ic-admin/)
* [TrackJs](http://docs.trackjs.com) (uses a customized theme)
* [wallabag](http://doc.wallabag.org/index)
* [Ultimo Docs](http://docs.ultimogroup.co.nz/)
Do you use Daux.io? Send us a pull request or open an [issue](https://github.com/justinwalsh/daux.io/issues) and I will add you to the list.

13
docs/01_Features/Search.md Normale Datei
Datei anzeigen

@ -0,0 +1,13 @@
Searching in a Daux.io documentation is possible, but only in static mode.
We don't provide this feature in live rendering as it would be too slow.
To enable the generated search, you can set `search` to true in the `html` section of your configuration
```json
{
"html": {
"search": true
}
}
```

Datei anzeigen

@ -0,0 +1,19 @@
Adding a table of contents becomes very easy with Daux.io
## Automatic
A table of contents can be added automatically to all pages.
If `[TOC]` isn't present it will add it at the beginning of the page.
You can enable this feature in your configuration
```json
{
"auto_toc": true
}
```
## Manual
Add `[TOC]` anywhere in your document and it will be replaced by a table of contents

Datei anzeigen

@ -62,6 +62,12 @@ Two helpers from the class `Todaymade\Daux\Tree\Builder` will greatly help you d
Both methods `getOrCreateDir` and `getOrCreatePage` take two parameters : `parent` and `title`
The page will automatically be treated as markdown and converted like a normal page.
If you create a new ContentType, like let's say LaTeX, you would set the title `My Page.tex` it will keep the title `My Page` and use your renderer.
If the extension is not mapped to a Generator, it will simply create the file as-is without manipulation.
### Extend the Markdown Generator
You can extend the Markdown Parser in any way wou want with this method.

Datei anzeigen

@ -18,6 +18,7 @@
* [Multiple Languages Support](!Features/Multilanguage)
* [No Build Step](!Features/Live_mode)
* [Static Output Generation](!Features/Static_Site_Generation)
* [Table of Contents](!Features/Table_of_contents)
</div>
<div class="col-sm-4">

Datei anzeigen

@ -64,7 +64,14 @@ software, even if advised of the possibility of such damage.
*/
require_once("vendor/autoload.php");
if (file_exists('vendor/autoload.php')) {
require_once('vendor/autoload.php');
} elseif (file_exists('daux.phar')) {
define('PHAR_DIR', __DIR__);
require_once("phar://" . __DIR__ . "/daux.phar/vendor/autoload.php");
} else {
throw new Exception("Impossible to load Daux, missing vendor/ or daux.phar");
}
$application = new \Todaymade\Daux\Console\Application();
$application->run();

Datei anzeigen

@ -18,6 +18,8 @@
"timezone": "America/Los_Angeles",
"auto_toc": false,
"live": {
"inherit_index": false,
"clean_urls": false
@ -30,6 +32,7 @@
"date_modified": false,
"float": false,
"auto_landing": true,
"search": true,
"repo": "",
"twitter": [],

Datei anzeigen

@ -19,9 +19,13 @@ var unusedRules = [
//We only use one glyphicon ...
".glyphicon-",
"!.glyphicon-chevron-right",
"!.glyphicon-search",
//we dont need all buttons
".btn-",
"!.btn-group",
"!.btn-default",
"!.btn-sm",
"!.btn-primary",
"!.btn-secondary",
"!.btn-hero",

Datei anzeigen

@ -81,7 +81,7 @@ if (file_exists('vendor/autoload.php')) {
define('PHAR_DIR', __DIR__);
require_once("phar://" . __DIR__ . "/daux.phar/vendor/autoload.php");
} else {
throw new Exception("Impossible to load Daux, missing vendor and phar");
throw new Exception("Impossible to load Daux, missing vendor/ or daux.phar");
}
\Todaymade\Daux\Server\Server::serve($_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], $_REQUEST);

3
libs/Console/Generate.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -20,7 +20,8 @@ class Generate extends SymfonyCommand
->addOption('processor', 'p', InputOption::VALUE_REQUIRED, 'Manipulations on the tree')
->addOption('source', 's', InputOption::VALUE_REQUIRED, 'Where to take the documentation from')
->addOption('delete', null, InputOption::VALUE_NONE, 'Delete pages not linked to a documentation page (confluence)')
->addOption('destination', 'd', InputOption::VALUE_REQUIRED, $description, 'static');
->addOption('destination', 'd', InputOption::VALUE_REQUIRED, $description, 'static')
->addOption('search', null, InputOption::VALUE_NONE, 'Generate full text search');
}
protected function execute(InputInterface $input, OutputInterface $output)

Datei anzeigen

@ -3,6 +3,8 @@
use League\CommonMark\DocParser;
use League\CommonMark\Environment;
use League\CommonMark\HtmlRenderer;
use Todaymade\Daux\ContentTypes\Markdown\TOC\Parser;
use Todaymade\Daux\ContentTypes\Markdown\TOC\TOCProcessor;
use Webuni\CommonMark\TableExtension\TableExtension;
class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter
@ -18,6 +20,10 @@ class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter
$environment->mergeConfig($config);
$environment->addExtension(new TableExtension());
// Table of Contents
$environment->addBlockParser(new Parser());
$environment->addDocumentProcessor(new TOCProcessor($config['daux']));
$this->extendEnvironment($environment);
if (array_key_exists('processor_instance', $config['daux'])) {

Datei anzeigen

@ -0,0 +1,50 @@
<?php namespace Todaymade\Daux\ContentTypes\Markdown\TOC;
use League\CommonMark\Block\Element\AbstractBlock;
use League\CommonMark\Cursor;
class Element extends AbstractBlock
{
/**
* Returns true if this block can contain the given block as a child node
*
* @param AbstractBlock $block
*
* @return bool
*/
public function canContain(AbstractBlock $block)
{
return false;
}
/**
* Returns true if block type can accept lines of text
*
* @return bool
*/
public function acceptsLines()
{
return false;
}
/**
* Whether this is a code block
*
* @return bool
*/
public function isCode()
{
return false;
}
/**
* @param Cursor $cursor
*
* @return bool
*/
public function matchesNextLine(Cursor $cursor)
{
return false;
}
}

Datei anzeigen

@ -0,0 +1,83 @@
<?php namespace Todaymade\Daux\ContentTypes\Markdown\TOC;
use League\CommonMark\Block\Element\Heading;
class Entry
{
protected $content;
protected $level;
protected $parent = null;
protected $children = [];
public function __construct(Heading $content)
{
$this->content = $content;
$this->level = $content->getLevel();
}
/**
* @return string
*/
public function getId()
{
return $this->content->data['attributes']['id'];
}
/**
* @return int
*/
public function getLevel()
{
return $this->level;
}
/**
* @return Entry
*/
public function getParent()
{
return $this->parent;
}
/**
* @return Heading
*/
public function getContent()
{
return $this->content;
}
/**
* @return Entry[]
*/
public function getChildren()
{
return $this->children;
}
/**
* @param Entry $parent
* @param bool $addChild
*/
public function setParent(Entry $parent, $addChild = true)
{
$this->parent = $parent;
if ($addChild) {
$parent->addChild($this);
}
}
/**
* @param Entry $child
*/
public function addChild(Entry $child)
{
$child->setParent($this, false);
$this->children[] = $child;
}
public function toString()
{
return $this->getLevel() . " - " . $this->getId();
}
}

Datei anzeigen

@ -0,0 +1,44 @@
<?php
/**
* Created by IntelliJ IDEA.
* User: onigoetz
* Date: 09/04/16
* Time: 23:03
*/
namespace Todaymade\Daux\ContentTypes\Markdown\TOC;
use League\CommonMark\Block\Parser\AbstractBlockParser;
use League\CommonMark\ContextInterface;
use League\CommonMark\Cursor;
class Parser extends AbstractBlockParser
{
/**
* @param ContextInterface $context
* @param Cursor $cursor
*
* @return bool
*/
public function parse(ContextInterface $context, Cursor $cursor)
{
if ($cursor->isIndented()) {
return false;
}
$previousState = $cursor->saveState();
$cursor->advanceToFirstNonSpace();
$fence = $cursor->match('/^\[TOC\]/');
if (is_null($fence)) {
$cursor->restoreState($previousState);
return false;
}
$context->addBlock(new Element());
return true;
}
}

Datei anzeigen

@ -0,0 +1,18 @@
<?php namespace Todaymade\Daux\ContentTypes\Markdown\TOC;
class RootEntry extends Entry
{
public function __construct()
{
$this->content = null;
$this->level = 0;
}
/**
* @return Entry
*/
public function getParent()
{
throw new \RuntimeException("No Parent Exception");
}
}

Datei anzeigen

@ -0,0 +1,203 @@
<?php namespace Todaymade\Daux\ContentTypes\Markdown\TOC;
use DeepCopy\DeepCopy;
use League\CommonMark\Block\Element\Document;
use League\CommonMark\Block\Element\Heading;
use League\CommonMark\Block\Element\ListBlock;
use League\CommonMark\Block\Element\ListData;
use League\CommonMark\Block\Element\ListItem;
use League\CommonMark\Block\Element\Paragraph;
use League\CommonMark\DocumentProcessorInterface;
use League\CommonMark\Inline\Element\Link;
use League\CommonMark\Inline\Element\Text;
use League\CommonMark\Node\Node;
use ReflectionMethod;
use Todaymade\Daux\Config;
use Todaymade\Daux\DauxHelper;
class TOCProcessor implements DocumentProcessorInterface
{
protected $config;
public function __construct(Config $config)
{
$this->config = $config;
}
public function hasAutoTOC()
{
return array_key_exists('auto_toc', $this->config) && $this->config['auto_toc'];
}
/**
* @param Document $document
*
* @return void
*/
public function processDocument(Document $document)
{
/** @var Element[] $tocs */
$tocs = [];
$headings = [];
$walker = $document->walker();
while ($event = $walker->next()) {
$node = $event->getNode();
if ($node instanceof Element && !$event->isEntering()) {
$tocs[] = $node;
continue;
}
if (!($node instanceof Heading) || !$event->isEntering()) {
continue;
}
$id = $this->addId($node);
$headings[] = new Entry($node, $id);
}
if (count($headings) && (count($tocs) || $this->hasAutoTOC())) {
$generated = $this->generate($headings);
if (count($tocs)) {
foreach ($tocs as $toc) {
$toc->replaceWith($this->render($generated->getChildren()));
}
} else {
$document->prependChild($this->render($generated->getChildren()));
}
}
}
protected function addId(Heading $node)
{
// If the node has an ID, no need to generate it
$attributes = $node->getData('attributes', []);
if (array_key_exists('id', $attributes) && !empty($attributes['id'])) {
// TODO :: check for uniqueness
return $attributes['id'];
}
// Well, seems we have to generate an ID
$walker = $node->walker();
$inside = [];
while ($event = $walker->next()) {
$insideNode = $event->getNode();
if ($insideNode instanceof Heading) {
continue;
}
$inside[] = $insideNode;
}
$text = '';
foreach ($inside as $other) {
if ($other instanceof Text) {
$text .= ' ' . $other->getContent();
}
}
$text = 'page_' . DauxHelper::slug(trim($text));
// TODO :: check for uniqueness
$node->data['attributes']['id'] = $text;
}
/**
* @param Entry[] $headings
* @return RootEntry
*/
public function generate($headings)
{
/** @var Entry $previous */
$root = $previous = new RootEntry();
foreach ($headings as $heading) {
if ($heading->getLevel() < $previous->getLevel()) {
$parent = $previous;
do {
$parent = $parent->getParent();
} while ($heading->getLevel() <= $parent->getLevel() || $parent->getLevel() != 0);
$parent->addChild($heading);
$previous = $heading;
continue;
}
if ($heading->getLevel() > $previous->getLevel()) {
$previous->addChild($heading);
$previous = $heading;
continue;
}
//if ($heading->getLevel() == $previous->getLevel()) {
$previous->getParent()->addChild($heading);
$previous = $heading;
continue;
//}
}
return $root;
}
/**
* @param Entry[] $entries
* @return ListBlock
*/
protected function render(array $entries)
{
$data = new ListData();
$data->type = ListBlock::TYPE_UNORDERED;
$list = new ListBlock($data);
$list->data['attributes']['class'] = 'TableOfContents';
foreach ($entries as $entry) {
$item = new ListItem($data);
$a = new Link('#' . $entry->getId());
foreach ($this->cloneChildren($entry->getContent()) as $node) {
$a->appendChild($node);
}
$p = new Paragraph();
$p->appendChild($a);
$item->appendChild($p);
if (!empty($entry->getChildren())) {
$item->appendChild($this->render($entry->getChildren()));
}
$list->appendChild($item);
}
return $list;
}
/**
* @param Heading $node
* @return Node[]
*/
protected function cloneChildren(Heading $node)
{
$deepCopy = new DeepCopy();
$firstClone = clone $node;
// We have no choice but to hack into the system to reset the parent, to avoid cloning the complete tree
$method = new ReflectionMethod(get_class($firstClone), 'setParent');
$method->setAccessible(true);
$method->invoke($firstClone, null);
return $deepCopy->copy($firstClone)->children();
}
}

Datei anzeigen

@ -306,7 +306,9 @@ class Daux
throw new \RuntimeException("Class '$class' not found. We cannot use it as a Processor");
}
//TODO :: check that it implements processor
if (!array_key_exists("Todaymade\\Daux\\Processor", class_parents($class))) {
throw new \RuntimeException("Class '$class' invalid, should extend '\\Todaymade\\Daux\\Processor'");
}
return $class;
}

Datei anzeigen

@ -0,0 +1,23 @@
<?php namespace Todaymade\Daux\Format\Base;
use Todaymade\Daux\Tree\ComputedRaw;
abstract class ComputedRawPage implements Page
{
protected $raw;
public function __construct(ComputedRaw $content)
{
$this->raw = $content;
}
public function getContent()
{
return $this->raw->getContent();
}
public function getPureContent()
{
return $this->raw->getContent();
}
}

Datei anzeigen

@ -21,6 +21,8 @@ abstract class ContentPage extends SimplePage
*/
protected $contentType;
protected $generatedContent;
public function __construct($title, $content)
{
$this->initializePage($title, $content);
@ -49,14 +51,18 @@ abstract class ContentPage extends SimplePage
$this->contentType = $contentType;
}
protected function convertPage($content)
public function getPureContent()
{
return $this->contentType->convert($content, $this->getFile());
if (!$this->generatedContent) {
$this->generatedContent = $this->contentType->convert($this->content, $this->getFile());
}
return $this->generatedContent;
}
protected function generatePage()
{
return $this->convertPage($this->content);
return $this->getPureContent();
}
public static function fromFile(Content $file, $params, ContentType $contentType)

Datei anzeigen

@ -2,5 +2,17 @@
interface Page
{
/**
* Get the converted content, without any template
*
* @return string
*/
public function getPureContent();
/**
* Get the full content
*
* @return mixed
*/
public function getContent();
}

Datei anzeigen

@ -16,6 +16,11 @@ abstract class RawPage implements Page
return $this->file;
}
public function getPureContent()
{
throw new Exception("you should not use this method to show a raw content");
}
public function getContent()
{
throw new Exception("you should not use this method to show a raw content");

Datei anzeigen

@ -11,6 +11,11 @@ abstract class SimplePage implements Page
$this->initializePage($title, $content);
}
public function getPureContent()
{
return $this->content;
}
public function getContent()
{
if (is_null($this->generated)) {

Datei anzeigen

@ -0,0 +1,6 @@
<?php namespace Todaymade\Daux\Format\HTML;
class ComputedRawPage extends \Todaymade\Daux\Format\Base\ComputedRawPage
{
}

Datei anzeigen

@ -81,7 +81,7 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage
'modified_time' => filemtime($this->file->getPath()),
'markdown' => $this->content,
'request' => $params['request'],
'content' => $this->convertPage($this->content),
'content' => $this->getPureContent(),
'breadcrumbs' => $params['html']['breadcrumbs'],
'prev' => $this->file->getPrevious(),
'next' => $this->file->getNext(),

81
libs/Format/HTML/Generator.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -9,7 +9,7 @@ use Todaymade\Daux\Daux;
use Todaymade\Daux\DauxHelper;
use Todaymade\Daux\Format\Base\LiveGenerator;
use Todaymade\Daux\GeneratorHelper;
use Todaymade\Daux\Tree\Content;
use Todaymade\Daux\Tree\ComputedRaw;
use Todaymade\Daux\Tree\Directory;
use Todaymade\Daux\Tree\Entry;
use Todaymade\Daux\Tree\Raw;
@ -21,6 +21,8 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
/** @var Daux */
protected $daux;
protected $indexed_pages = [];
/**
* @param Daux $daux
*/
@ -58,7 +60,61 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
);
$output->writeLn("Generating ...");
$this->generateRecursive($this->daux->tree, $destination, $params, $output, $width);
$params['html']['search'] = $input->getOption('search');
$this->generateRecursive($this->daux->tree, $destination, $params, $output, $width, $params['html']['search']);
if ($params['html']['search']) {
GeneratorHelper::copyRecursive(
$this->daux->local_base . DIRECTORY_SEPARATOR . 'tipuesearch' . DIRECTORY_SEPARATOR,
$destination . DIRECTORY_SEPARATOR . 'tipuesearch'
);
file_put_contents(
$destination . DIRECTORY_SEPARATOR . 'tipuesearch' . DIRECTORY_SEPARATOR . 'tipuesearch_content.json',
json_encode(['pages' => $this->indexed_pages])
);
}
}
/**
* Remove HTML tags, including invisible text such as style and
* script code, and embedded objects. Add line breaks around
* block-level tags to prevent word joining after tag removal.
* Also collapse whitespace to single space and trim result.
* modified from: http://nadeausoftware.com/articles/2007/09/php_tip_how_strip_html_tags_web_page
*/
private function strip_html_tags($text)
{
$text = preg_replace(
array(
// Remove invisible content
'@<head[^>]*?>.*?</head>@siu',
'@<style[^>]*?>.*?</style>@siu',
'@<script[^>]*?.*?</script>@siu',
'@<object[^>]*?.*?</object>@siu',
'@<embed[^>]*?.*?</embed>@siu',
'@<applet[^>]*?.*?</applet>@siu',
'@<noframes[^>]*?.*?</noframes>@siu',
'@<noscript[^>]*?.*?</noscript>@siu',
'@<noembed[^>]*?.*?</noembed>@siu',
// Add line breaks before and after blocks
'@</?((address)|(blockquote)|(center)|(del))@iu',
'@</?((div)|(h[1-9])|(ins)|(isindex)|(p)|(pre))@iu',
'@</?((dir)|(dl)|(dt)|(dd)|(li)|(menu)|(ol)|(ul))@iu',
'@</?((table)|(th)|(td)|(caption))@iu',
'@</?((form)|(button)|(fieldset)|(legend)|(input))@iu',
'@</?((label)|(select)|(optgroup)|(option)|(textarea))@iu',
'@</?((frameset)|(frame)|(iframe))@iu',
),
array(
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
"\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0", "\n\$0",
"\n\$0", "\n\$0",
),
$text
);
return trim(preg_replace('/\s+/', ' ', strip_tags($text)));
}
/**
@ -69,10 +125,11 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
* @param \Todaymade\Daux\Config $params
* @param OutputInterface $output
* @param integer $width
* @param boolean $index_pages
* @param string $base_url
* @throws \Exception
*/
private function generateRecursive(Directory $tree, $output_dir, $params, $output, $width, $base_url = '')
private function generateRecursive(Directory $tree, $output_dir, $params, $output, $width, $index_pages, $base_url = '')
{
DauxHelper::rebaseConfiguration($params, $base_url);
@ -84,7 +141,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
if ($node instanceof Directory) {
$new_output_dir = $output_dir . DIRECTORY_SEPARATOR . $key;
mkdir($new_output_dir);
$this->generateRecursive($node, $new_output_dir, $params, $output, $width, '../' . $base_url);
$this->generateRecursive($node, $new_output_dir, $params, $output, $width, $index_pages, '../' . $base_url);
// Rebase configuration again as $params is a shared object
DauxHelper::rebaseConfiguration($params, $base_url);
@ -93,14 +150,22 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
"- " . $node->getUrl(),
$output,
$width,
function() use ($node, $output_dir, $key, $params) {
if (!$node instanceof Content) {
function() use ($node, $output_dir, $key, $params, $index_pages) {
if ($node instanceof Raw) {
copy($node->getPath(), $output_dir . DIRECTORY_SEPARATOR . $key);
return;
}
$generated = $this->generateOne($node, $params);
file_put_contents($output_dir . DIRECTORY_SEPARATOR . $key, $generated->getContent());
if ($index_pages) {
$this->indexed_pages[] =[
'title' => $node->getTitle(),
'text' => utf8_encode($this->strip_html_tags($generated->getPureContent())),
'tags' => "",
'url' => $node->getUrl()
];
}
}
);
}
@ -118,6 +183,10 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator
return new RawPage($node->getPath());
}
if ($node instanceof ComputedRaw) {
return new ComputedRawPage($node);
}
$params['request'] = $node->getUrl();
return ContentPage::fromFile($node, $params, $this->daux->getContentTypeHandler()->getType($node));
}

Datei anzeigen

@ -78,10 +78,13 @@ class Template
$nav = "";
foreach ($entries as $entry) {
if (array_key_exists('children', $entry)) {
$icon = '<i class="arrow">&nbsp;</i>';
if (array_key_exists('href', $entry)) {
$link = '<a href="' . $entry['href'] . '" class="folder">' . $entry['title'] . '</a>';
$link = '<a href="' . $entry['href'] . '" class="folder">' . $icon . $entry['title'] . '</a>';
} else {
$link = '<a href="#" class="aj-nav folder">' . $entry['title'] . '</a>';
$link = '<a href="#" class="aj-nav folder">' . $icon . $entry['title'] . '</a>';
}
$link .= $this->renderNavigation($entry['children']);
@ -110,7 +113,7 @@ class Template
$nav[] = [
'title' => $node->getTitle(),
'href' => $base_page . $link,
'class' => ($current_url === $link) ? 'active' : ''
'class' => $current_url === $link ? 'active' : '',
];
} elseif ($node instanceof Directory) {
if (!$node->hasContent()) {
@ -121,7 +124,7 @@ class Template
$folder = [
'title' => $node->getTitle(),
'class' => (strpos($current_url, $link) === 0) ? 'open' : '',
'class' => strpos($current_url, $link) === 0 ? 'open' : '',
];
if ($mode === Daux::STATIC_MODE) {
@ -136,6 +139,10 @@ class Template
$new_path = ($path === '') ? $url : $path . '/' . $url;
$folder['children'] = $this->buildNavigation($node, $new_path, $current_url, $base_page, $mode);
if (!empty($folder['children'])) {
$folder['class'] .= ' has-children';
}
$nav[] = $folder;
}
}

2
libs/GeneratorHelper.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -50,7 +50,7 @@ class GeneratorHelper
* @param string $source
* @param string $destination
*/
protected static function copyRecursive($source, $destination)
public static function copyRecursive($source, $destination)
{
if (!is_dir($destination)) {
mkdir($destination);

Datei anzeigen

@ -33,7 +33,7 @@ class ErrorPage extends SimplePage
$params = $this->params;
$page = [
'title' => $this->title,
'content' => $this->content,
'content' => $this->getPureContent(),
'language' => '',
];

3
libs/Server/Server.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -99,6 +99,9 @@ class Server
$params['base_page'] .= 'index.php/';
}
// Text search would be too slow on live server
$params['html']['search'] = false;
return $params;
}

Datei anzeigen

@ -169,32 +169,35 @@ class Builder
*/
public static function getOrCreatePage(Directory $parent, $path)
{
$title = static::getName($path);
$extension = pathinfo($path, PATHINFO_EXTENSION);
// If the file doesn't have an extension, set .md as a default
if (pathinfo($path, PATHINFO_EXTENSION) == '') {
if ($extension == '') {
$extension = 'md';
$path .= '.md';
}
$uri = $slug = DauxHelper::slug($title);
if ($parent->getConfig()['mode'] === Daux::STATIC_MODE) {
$uri = $slug . ".html";
$raw = !in_array($extension, $parent->getConfig()['valid_content_extensions']);
$title = $uri = $path;
if (!$raw) {
$title = static::getName($path);
$uri = DauxHelper::slug($title);
if ($parent->getConfig()['mode'] === Daux::STATIC_MODE) {
$uri .= ".html";
}
}
if (array_key_exists($uri, $parent->getEntries())) {
return $parent->getEntries()[$uri];
}
$page = new Content($parent, $uri);
$page = $raw? new ComputedRaw($parent, $uri) : new Content($parent, $uri);
$page->setContent("-"); //set an almost empty content to avoid problems
$page->setName($path);
$page->setTitle($title);
if ($title == 'index') {
// TODO :: clarify the difference between 'index' and '_index'
$page->setName('_index.' . pathinfo($path, PATHINFO_EXTENSION));
if ($title == 'index' || $title == '_index') {
$page->setTitle($parent->getTitle());
} else {
$page->setName($path);
$page->setTitle($title);
}
return $page;

23
libs/Tree/ComputedRaw.php Normale Datei
Datei anzeigen

@ -0,0 +1,23 @@
<?php namespace Todaymade\Daux\Tree;
class ComputedRaw extends Entry
{
/** @var string */
protected $content;
/**
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* @param string $content
*/
public function setContent($content)
{
$this->content = $content;
}
}

Datei anzeigen

@ -72,6 +72,10 @@ class Content extends Entry
public function isIndex()
{
// At some point, it was recommended that
// an index page starts with an underscore.
// This is not mandatory anymore, both with
// and without underscore are supported.
return $this->name == 'index' || $this->name == '_index';
}

Datei anzeigen

@ -5,12 +5,12 @@
"devDependencies": {
"grunt": "^0.4.1",
"grunt-php": "^1.0.0",
"cssnano": "^3.4.0",
"gulp": "^3.9.0",
"gulp-connect-php": "^0.0.5",
"cssnano": "^3.5.2",
"gulp": "^3.9.1",
"gulp-connect-php": "^0.0.7",
"gulp-less": "^3.0.3",
"gulp-plumber": "^1.0.1",
"gulp-postcss": "^6.0.0",
"gulp-plumber": "^1.1.0",
"gulp-postcss": "^6.1.0",
"gulp-rename": "^1.2.2"
}
}

Datei anzeigen

@ -2,31 +2,17 @@
<article>
<?php if ($params['html']['date_modified']) { ?>
<div class="page-header sub-header clearfix">
<h1><?php
if ($page['breadcrumbs']) {
echo $this->get_breadcrumb_title($page, $base_page);
} else {
echo $page['title'];
}
?>
</h1>
<span style="float: left; font-size: 10px; color: gray;">
<?= date("l, F j, Y", $page['modified_time']); ?>
</span>
<span style="float: right; font-size: 10px; color: gray;">
<?= date("g:i A", $page['modified_time']); ?>
</span>
<h1><?= $page['breadcrumbs']? $this->get_breadcrumb_title($page, $base_page) : $page['title'] ?></h1>
<span style="float: left; font-size: 10px; color: gray;">
<?= date("l, F j, Y", $page['modified_time']); ?>
</span>
<span style="float: right; font-size: 10px; color: gray;">
<?= date("g:i A", $page['modified_time']); ?>
</span>
</div>
<?php } else { ?>
<div class="page-header">
<h1><?php
if ($page['breadcrumbs']) {
echo $this->get_breadcrumb_title($page, $base_page);
} else {
echo $page['title'];
}
?>
</h1>
<h1><?= $page['breadcrumbs']? $this->get_breadcrumb_title($page, $base_page) : $page['title'] ?></h1>
</div>
<?php } ?>

8
templates/home.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -45,7 +45,13 @@
<div class="container">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<?= $page['content']; ?>
<?php if ($params['html']['search']) { ?>
<div id="tipue_search_content" style="display:none"></div>
<?php } ?>
<div class="doc_content">
<?= $page['content']; ?>
</div>
</div>
</div>
</div>

26
templates/layout/00_layout.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -23,6 +23,11 @@
echo "<link href='$css' rel='stylesheet' type='text/css'>";
} ?>
<?php if ($params['html']['search']) { ?>
<!-- Tipue Search -->
<link href="<?= $base_url; ?>tipuesearch/tipuesearch.css" rel="stylesheet">
<?php } ?>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
@ -39,9 +44,8 @@
}
?>
<!-- jQuery -->
<?= '<script src="' . $base_url . 'themes/daux/js/jquery-1.11.3.min.js' . '"></script>' ?>
<script src="<?= $base_url; ?>themes/daux/js/jquery-1.11.3.min.js"></script>
<!-- hightlight.js -->
<script src="<?= $base_url; ?>themes/daux/js/highlight.pack.js"></script>
@ -53,5 +57,23 @@
} ?>
<script src="<?= $base_url; ?>themes/daux/js/daux.js"></script>
<?php if ($params['html']['search']) { ?>
<!-- Tipue Search -->
<script type="text/javascript" src="<?php echo $base_url; ?>tipuesearch/tipuesearch_set.js"></script>
<script type="text/javascript" src="<?php echo $base_url; ?>tipuesearch/tipuesearch.min.js"></script>
<script>
window.onunload = function(){}; // force $(document).ready to be called on back/forward navigation in firefox
$(document).ready(function() {
$('#tipue_search_input').tipuesearch({
'show': 10,
'mode': 'json',
'base_url': '<?php echo $base_url?>'
});
});
</script>
<?php } ?>
</body>
</html>

30
templates/layout/05_page.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -37,11 +37,21 @@
<?php
foreach ($params['html']['links'] as $name => $url) {
echo '<a href="' . $url . '" target="_blank">' . $name . '</a><br>';
}
if ($params['html']['toggle_code']) {
echo '<a href="#" id="toggleCodeBlockBtn" onclick="toggleCodeBlocks();">Show Code Blocks Inline</a><br>';
}
?>
} ?>
<div id="toggleCodeBlock">
<?php if ($params['html']['toggle_code'] && $params['html']['float']) { ?>
<br />
<span class="code-buttons-text">Code blocks</span>
<div class="btn-group" role="group">
<button id="code-hide" class="btn btn-sm btn-default">No</button>
<button id="code-below" class="btn btn-sm btn-default">Below</button>
<button id="code-float" class="btn btn-sm btn-default">Inline</button>
</div>
<?php } else if ($params['html']['toggle_code']) { ?>
<a id="toggleCodeBlockBtn" href="#" onclick="toggleCodeBlocks();">Show Code Blocks Inline</a><br>
<?php } ?>
</div>
<!-- Twitter -->
<?php foreach ($params['html']['twitter'] as $handle) { ?>
@ -54,13 +64,19 @@
<hr/>
<?php } ?>
<p><small>Documentation generated by <a href="http://daux.io">Daux.io</a></small></p>
</div>
</div>
</div>
<div class="right-column <?= $params['html']['float'] ? 'float-view' : ''; ?> content-area col-sm-9">
<div class="content-page">
<?= $this->section('content'); ?>
<?php if ($params['html']['search']) { ?>
<div id="tipue_search_content" style="display:none"></div>
<?php } ?>
<div class="doc_content">
<?= $this->section('content'); ?>
</div>
</div>
</div>
</div>

7
templates/partials/navbar_content.php Normale Datei → Ausführbare Datei
Datei anzeigen

@ -1 +1,8 @@
<a class="brand navbar-brand pull-left" href="<?= $params['base_page'] . $params['index']->getUri(); ?>"><?= $params['title']; ?></a>
<?php if ($params['html']['search']) { ?>
<div class="navbar-right navbar-form search">
<i class="glyphicon glyphicon-search search__icon">&nbsp;</i>
<input type="search" id="tipue_search_input" class="form-control search__field" placeholder="Search..." autocomplete="on" results=25 autosave=text_search>
</div>
<?php } ?>

Datei anzeigen

@ -1,6 +1,9 @@
<?php namespace Todaymade\Daux\Tree;
use Todaymade\Daux\Config;
use Todaymade\Daux\Daux;
class BuilderTest extends \PHPUnit_Framework_TestCase
{
public function providerRemoveSorting()
@ -34,4 +37,104 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
{
$this->assertEquals($expected, Builder::removeSortingInformations($value));
}
public function testGetOrCreateDirNew() {
$root = new Root(new Config(), '');
$dir = Builder::getOrCreateDir($root, 'directory');
$this->assertSame($root, $dir->getParent());
$this->assertEquals('directory', $dir->getTitle());
$this->assertEquals('directory', $dir->getUri());
}
public function testGetOrCreateDirExisting() {
$root = new Root(new Config(), '');
$directory = new Directory($root, 'directory');
$directory->setTitle('directory');
$dir = Builder::getOrCreateDir($root, 'directory');
$this->assertSame($root, $dir->getParent());
$this->assertEquals('directory', $dir->getTitle());
$this->assertEquals('directory', $dir->getUri());
$this->assertSame($directory, $dir);
}
public function getStaticRoot() {
$config = new Config();
$config['mode'] = Daux::STATIC_MODE;
$config['index_key'] = 'index.html';
$config['valid_content_extensions'] = ['md'];
return new Root($config, '');
}
public function testGetOrCreatePage()
{
$directory = new Directory($this->getStaticRoot(), 'dir');
$entry = Builder::getOrCreatePage($directory, 'A Page.md');
$this->assertSame($directory, $entry->getParent());
$this->assertEquals('dir/A_Page.html', $entry->getUrl());
$this->assertEquals('A_Page.html', $entry->getUri());
$this->assertEquals('A Page', $entry->getTitle());
$this->assertInstanceOf('Todaymade\Daux\Tree\Content', $entry);
}
public function testGetOrCreatePageAutoMarkdown()
{
$directory = new Directory($this->getStaticRoot(), 'dir');
$entry = Builder::getOrCreatePage($directory, 'A Page');
$this->assertSame($directory, $entry->getParent());
$this->assertEquals('dir/A_Page.html', $entry->getUrl());
$this->assertEquals('A_Page.html', $entry->getUri());
$this->assertEquals('A Page', $entry->getTitle());
$this->assertInstanceOf('Todaymade\Daux\Tree\Content', $entry);
}
public function testGetOrCreateIndexPage()
{
$directory = new Directory($this->getStaticRoot(), 'dir');
$directory->setTitle('Tutorials');
$entry = Builder::getOrCreatePage($directory, 'index.md');
$this->assertSame($directory, $entry->getParent());
$this->assertEquals('dir/index.html', $entry->getUrl());
$this->assertEquals('Tutorials', $entry->getTitle());
$this->assertInstanceOf('Todaymade\Daux\Tree\Content', $entry);
}
public function testGetOrCreatePageExisting()
{
$directory = new Directory($this->getStaticRoot(), 'dir');
$existingEntry = new Content($directory, 'A_Page.html');
$existingEntry->setContent('-');
$entry = Builder::getOrCreatePage($directory, 'A Page.md');
$this->assertSame($directory, $entry->getParent());
$this->assertSame($existingEntry, $entry);
$this->assertEquals('dir/A_Page.html', $entry->getUrl());
$this->assertEquals('A_Page.html', $entry->getUri());
$this->assertInstanceOf('Todaymade\Daux\Tree\Content', $entry);
}
public function testGetOrCreateRawPage()
{
$directory = new Directory($this->getStaticRoot(), 'dir');
$entry = Builder::getOrCreatePage($directory, 'file.json');
$this->assertSame($directory, $entry->getParent());
$this->assertEquals('dir/file.json', $entry->getUrl());
$this->assertEquals('file.json', $entry->getUri());
$this->assertInstanceOf('Todaymade\Daux\Tree\ComputedRaw', $entry);
}
}

Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist

Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist

Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist

Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist

Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist

Datei anzeigen

@ -37,16 +37,15 @@ _.debounce = function(func, wait, immediate) {
};
};
var codeBlocks, codeBlockView, toggleCodeBlockBtn, codeBlockState;
var codeBlocks, codeBlockView, toggleCodeBlockBtn, toggleCodeSection, codeBlockState;
function toggleCodeBlocks() {
var hasFloat = $(document.body).hasClass("with-float")? 3 : 2;
codeBlockState = (codeBlockState + 1) % hasFloat;
localStorage.setItem("codeBlockState", codeBlockState);
setCodeBlockStyle(codeBlockState);
setCodeBlockStyle(codeBlocks.hasClass('hidden') ? 1 : 0);
}
function setCodeBlockStyle(x) {
switch (x) {
function setCodeBlockStyle(codeBlockState) {
localStorage.setItem("codeBlockState", codeBlockState);
switch (codeBlockState) {
default:
case 0:
toggleCodeBlockBtn.html("Show Code Blocks");
@ -69,22 +68,35 @@ function setCodeBlockStyle(x) {
//Initialize CodeBlock Visibility Settings
$(function () {
codeBlocks = $('.content-page article > pre');
toggleCodeSection = $('#toggleCodeBlock');
toggleCodeBlockBtn = $('#toggleCodeBlockBtn');
// If there is no code block we hide the link
if (!codeBlocks.size()) {
toggleCodeBlockBtn.addClass('hidden');
toggleCodeSection.addClass('hidden');
return;
}
$('#code-hide').click(function() { setCodeBlockStyle(0); });
$('#code-below').click(function() { setCodeBlockStyle(1); });
$('#code-float').click(function() { setCodeBlockStyle(2); });
codeBlockView = $('.right-column');
if (!codeBlockView.size()) return;
var floating = $(document.body).hasClass("with-float");
codeBlockState = localStorage.getItem("codeBlockState");
if (!codeBlockState) {
codeBlockState = 2;
localStorage.setItem("codeBlockState", codeBlockState);
} else codeBlockState = parseInt(codeBlockState);
codeBlockState = floating? 2 : 1;
} else {
codeBlockState = parseInt(codeBlockState);
}
if (!floating && codeBlockState == 2) {
codeBlockState = 1;
}
setCodeBlockStyle(codeBlockState);
});
@ -98,6 +110,12 @@ $(function () {
$(this).next().slideToggle();
});
// New Tree navigation
$('ul.nav.nav-list > li.has-children > a > .arrow').click(function() {
$(this).parent().parent().toggleClass('open');
return false;
});
// Responsive navigation
$('#menu-spinner-button').click(function () {
$('#sub-nav-collapse').slideToggle();

Datei anzeigen

@ -19,13 +19,13 @@
@import "code.less";
@import "grid.less";
//@import "tables.less";
//@import "forms.less";
@import "forms.less";
@import "buttons.less";
// Components
//@import "component-animations.less";
//@import "dropdowns.less";
//@import "button-groups.less";
@import "button-groups.less";
//@import "input-groups.less";
@import "navs.less";
@import "navbar.less";

Datei anzeigen

@ -284,8 +284,7 @@
// Extension of the `.form-inline` with some extra flavor for optimum display in
// our navbars.
//DAUX.io / onigoetz; removed so we can safely remove forms.less
/*.navbar-form {
.navbar-form {
margin-left: -@navbar-padding-horizontal;
margin-right: -@navbar-padding-horizontal;
padding: 10px @navbar-padding-horizontal;
@ -320,7 +319,7 @@
padding-bottom: 0;
.box-shadow(none);
}
}*/
}
// Dropdown menus

Datei anzeigen

@ -68,21 +68,54 @@ code {
}
}
.code-buttons-text {
font-size: 12px;
line-height: 1.5;
padding: 6px 10px 6px 0;
display: inline-block;
vertical-align: middle;
}
//Sidebar Nav List
.nav.nav-list {
padding-left: 0px;
padding-right: 0px;
padding-left: 0;
padding-right: 0;
li {
a {
margin: 0px;
padding: 6px 15px;
margin: 0;
padding: 6px 15px 6px 20px;
.roboto-slab.regular;
color: @dark;
font-size: 15px;
text-shadow: none;
border-color: @lines;
.arrow {
display: inline-block;
position: relative;
width: 16px;
margin-left: -16px;
&:before {
position:absolute;
display:block;
content:"";
margin:-.25em 0 0 -.4em;
left:50%;
top: 50%;
width: 0.5em;
height: 0.5em;
border-right: 0.15em solid @dark;
border-top: 0.15em solid @dark;
transform: rotate(45deg);
transition-duration:.3s;
}
}
&:hover {
color: @dark;
text-shadow: none;
@ -100,11 +133,16 @@ code {
> ul {
display: block;
}
}
&:last-child {
&.open {
//border-bottom: none;
> a {
&, &:focus, &:hover {
background-color:transparent;
}
> .arrow:before {
margin-left:-.25em;
transform: rotate(135deg);
}
}
}
@ -128,10 +166,8 @@ code {
}
}
&.active {
a {
color: @dark;
}
&.active a {
color: @dark;
}
}
}
@ -325,3 +361,34 @@ table {
}
}
}
.search {
position: relative;
&__field {
padding-right: 30px;
}
&__icon {
position: absolute;
right: 12px;
top: 10px;
}
}
.TableOfContents {
font-size:16px;
padding-left:30px;
border-left:6px solid #efefef;
p {
margin-bottom:0;
}
.TableOfContents {
border-left-width:0;
padding-left:20px;
}
}

206
tipuesearch/tipuesearch.css Ausführbare Datei
Datei anzeigen

@ -0,0 +1,206 @@
/*
Tipue Search 5.0
Copyright (c) 2015 Tipue
Tipue Search is released under the MIT License
http://www.tipue.com/search
*/
/* bootstrap overrides the search field so let's undo that */
input[type="search"] {
-webkit-appearance: searchfield;
}
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: searchfield-cancel-button;
}
#tipue_search_input {
width: 170px;
font-size: medium;
}
#tipue_search_content {
background: #fff;
max-width: 650px;
padding: 15px;
margin: 0;
}
#tipue_search_warning {
font-weight:300;
font-size:15px;
line-height: 1.6;
color: #555;
margin: 7px 0;
}
#tipue_search_warning a {
color: #396;
text-decoration: none;
}
#tipue_search_warning a:hover {
color: #555;
}
#tipue_search_results_count {
font-weight:300;
font-size:15px;
line-height: 1.7;
color: #555;
}
.tipue_search_content_title {
font-weight:300;
font-size:21px;
line-height: 1.7;
margin-top: 23px;
}
.tipue_search_content_title a {
color: #333;
text-decoration: none;
}
.tipue_search_content_title a:hover {
color: #555;
}
.tipue_search_content_url {
font-weight:300;
font-size:14px;
line-height: 1.9;
word-wrap: break-word;
hyphens: auto;
}
.tipue_search_content_url a {
color: #396;
text-decoration: none;
}
.tipue_search_content_url a:hover {
color: #555;
}
.tipue_search_content_text {
font-weight:300;
font-size:15px;
line-height: 1.6;
color: #555;
word-wrap: break-word;
hyphens: auto;
margin-top: 3px;
}
.tipue_search_content_debug {
font-weight:300;
font-size:13px;
line-height: 1.6;
color: #555;
margin: 5px 0;
}
.h01 {
color: #333;
font-weight: 400;
}
#tipue_search_foot {
margin: 51px 0 21px 0;
padding: 0 10px;
}
#tipue_search_foot_boxes {
padding: 0;
margin: 0;
font-size: 12px;
width: auto;
float: none;
}
#tipue_search_foot_boxes li {
list-style: none;
margin: 0;
padding: 0;
display: inline;
}
#tipue_search_foot_boxes li a {
padding: 10px 17px 11px 17px;
background-color: #fff;
border: 1px solid #e2e2e2;
border-radius: 1px;
color: #333;
margin-right: 7px;
text-decoration: none;
text-align: center;
}
#tipue_search_foot_boxes li.current {
padding: 10px 17px 11px 17px;
background: #f6f6f6;
border: 1px solid #e2e2e2;
border-radius: 1px;
color: #333;
margin-right: 7px;
text-align: center;
}
#tipue_search_foot_boxes li a:hover {
background: #f6f6f6;
}
/* spinner */
.tipue_search_spinner {
padding: 31px 0;
width: 50px;
height: 28px;
}
.tipue_search_spinner > div {
background-color: #777;
height: 100%;
width: 3px;
display: inline-block;
margin-right: 2px;
-webkit-animation: stretchdelay 1.2s infinite ease-in-out;
animation: stretchdelay 1.2s infinite ease-in-out;
}
.tipue_search_spinner .tipue_search_rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.tipue_search_spinner .tipue_search_rect3 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
@-webkit-keyframes stretchdelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4)
}
20% {
-webkit-transform: scaleY(1.0)
}
}
@keyframes stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}

1
tipuesearch/tipuesearch.min.js vendored Normale Datei

Dateidiff unterdrückt, weil mindestens eine Zeile zu lang ist

Datei anzeigen

@ -0,0 +1,34 @@
/*
Tipue Search 5.0
Copyright (c) 2015 Tipue
Tipue Search is released under the MIT License
http://www.tipue.com/search
*/
// Stop words (list from http://www.ranks.nl/stopwords)
var tipuesearch_stop_words = ["a", "about", "above", "after", "again", "against", "all", "am", "an", "and", "any", "are", "aren't", "as", "at", "be", "because", "been", "before", "being", "below", "between", "both", "but", "by", "can't", "cannot", "could", "couldn't", "did", "didn't", "do", "does", "doesn't", "doing", "don't", "down", "during", "each", "few", "for", "from", "further", "had", "hadn't", "has", "hasn't", "have", "haven't", "having", "he", "he'd", "he'll", "he's", "her", "here", "here's", "hers", "herself", "him", "himself", "his", "how", "how's", "i", "i'd", "i'll", "i'm", "i've", "if", "in", "into", "is", "isn't", "it", "it's", "its", "itself", "let's", "me", "more", "most", "mustn't", "my", "myself", "no", "nor", "not", "of", "off", "on", "once", "only", "or", "other", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "shan't", "she", "she'd", "she'll", "she's", "should", "shouldn't", "so", "some", "such", "than", "that", "that's", "the", "their", "theirs", "them", "themselves", "then", "there", "there's", "these", "they", "they'd", "they'll", "they're", "they've", "this", "those", "through", "to", "too", "under", "until", "up", "very", "was", "wasn't", "we", "we'd", "we'll", "we're", "we've", "were", "weren't", "what", "what's", "when", "when's", "where", "where's", "which", "while", "who", "who's", "whom", "why", "why's", "with", "won't", "would", "wouldn't", "you", "you'd", "you'll", "you're", "you've", "your", "yours", "yourself", "yourselves"];
// Word replace
var tipuesearch_replace = {'words': []};
// Weighting
var tipuesearch_weight = {'weight': []};
// Stemming
var tipuesearch_stem = {'words': []};
// Internal strings
var tipuesearch_string_1 = 'No title';
var tipuesearch_string_2 = 'Showing results for';
var tipuesearch_string_3 = 'Search instead for';
var tipuesearch_string_4 = '1 result';
var tipuesearch_string_5 = 'results';
var tipuesearch_string_6 = 'Prev';
var tipuesearch_string_7 = 'Next';
var tipuesearch_string_8 = 'Nothing found';
var tipuesearch_string_9 = 'Common words are largely ignored';
var tipuesearch_string_10 = 'Search too short';
var tipuesearch_string_11 = 'Should be one character or more';
var tipuesearch_string_12 = 'Should be';
var tipuesearch_string_13 = 'characters or more';