diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml new file mode 100644 index 0000000..2694ce3 --- /dev/null +++ b/.github/workflows/php.yml @@ -0,0 +1,85 @@ +name: CI + +on: [push] + +jobs: + build: + strategy: + max-parallel: 15 + matrix: + # TODO : enable tests on windows + operating-system: [ubuntu-latest, macOS-latest] + php-versions: ['7.2', '7.3', '7.4'] + exclude: + - operating-system: macos-latest + php-versions: 7.4 + + name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} + runs-on: ${{ matrix.operating-system }} + + steps: + - uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + extension-csv: mbstring, dom, intl + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Install tools + run: ./scripts/install_tools.sh + + - name: Run test suite + run: composer run-script test + + sonarcloud: + name: "SonarCloud" + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + steps: + - uses: actions/checkout@v1 + - name: Setup PHP + uses: shivammathur/setup-php@master + with: + php-version: 7.4 + extension-csv: mbstring, dom, intl + coverage: pcov + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Install tools + run: ./scripts/install_tools.sh + + - name: Run test suite + run: composer run-script test -- --coverage-clover=coverage.clover --log-junit=test-report.xml + + - name: Fix reports + run: scripts/fix_reports.sh + + - name: SonarCloud Scan + uses: SonarSource/sonarcloud-github-action@v1.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + documentation: + runs-on: ubuntu-latest + if: github.repository == 'dauxio/daux.io' && github.event_name != 'pull_request' && github.ref == 'refs/heads/master' + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + - name: Generate documentation + run: bin/daux generate --value html.plausible_domain=daux.io + - uses: JamesIves/github-pages-deploy-action@2.0.3 + env: + FOLDER: "static" + BRANCH: gh-pages + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index a2fd533..5f960a6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,11 @@ node_modules static /vendor +/build +.phpunit.result.cache +.php_cs.cache +coverage.clover +test-report.xml /prettier.config.js /.eslintrc.js diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..a4ed81f --- /dev/null +++ b/.php_cs @@ -0,0 +1,28 @@ +exclude('vendor') + ->exclude('templates') + ->in(__DIR__) +; + +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR2' => true, + '@PHP70Migration' => true, + '@PHP71Migration' => true, + '@PhpCsFixer' => true, + 'explicit_string_variable' => false, + 'single_blank_line_before_namespace' => false, + 'no_short_echo_tag' => false, + 'blank_line_after_opening_tag' => false, + 'yoda_style' => false, + 'concat_space' => ['spacing' => 'one'], + 'php_unit_internal_class' => false, + 'php_unit_test_class_requires_covers' => false, + 'phpdoc_align' => false, + 'multiline_whitespace_before_semicolons' => false, + 'ordered_class_elements' => ['use_trait', 'constant_public', 'constant_protected', 'constant_private', 'property_public', 'property_protected', 'property_private', 'construct', 'method'] + ]) + ->setFinder($finder) +; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f12c7eb..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -language: php - -php: - - '7.1' - - '7.2' - - '7.3' - - nightly - -matrix: - allow_failures: - - php: nightly - -before_script: - - composer install --dev --prefer-source - -script: - - vendor/bin/phpunit --coverage-clover=coverage.clover - -after_script: - - wget https://scrutinizer-ci.com/ocular.phar - - php ocular.phar code-coverage:upload --format=php-clover coverage.clover - -jobs: - include: - - stage: "Deploy Documentation" - php: "7.3" - script: skip - before_deploy: - - composer install - - bin/daux generate - deploy: - provider: pages - local_dir: static - skip_cleanup: true - github_token: $GITHUB_TOKEN # Set in travis-ci.org dashboard - on: - branch: master diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index da46639..ddbafd3 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -14,22 +14,22 @@ appearance, race, religion, or sexual identity and orientation. Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting ## Our Responsibilities diff --git a/Dockerfile b/Dockerfile index 0da44df..e7655df 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM composer:1.7.2 AS composer +FROM composer:1.10.5 AS composer FROM php:7-stretch diff --git a/README.md b/README.md index e4bfc27..9897909 100755 --- a/README.md +++ b/README.md @@ -1,51 +1,48 @@ # Daux.io - [![Latest Version](https://img.shields.io/github/release/dauxio/daux.io.svg?style=flat-square)](https://github.com/dauxio/daux.io/releases) [![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/dauxio/daux.io/blob/master/LICENSE.md) -[![Build Status](https://img.shields.io/travis/dauxio/daux.io/master.svg?style=flat-square)](https://travis-ci.org/dauxio/daux.io) +![GitHub Workflow Status](https://img.shields.io/github/workflow/status/dauxio/daux.io/CI?style=flat-square) [![Coverage Status](https://img.shields.io/scrutinizer/coverage/g/dauxio/daux.io.svg?style=flat-square)](https://scrutinizer-ci.com/g/dauxio/daux.io/code-structure) [![Quality Score](https://img.shields.io/scrutinizer/g/dauxio/daux.io.svg?style=flat-square)](https://scrutinizer-ci.com/g/dauxio/daux.io) [![Total Downloads](https://img.shields.io/packagist/dt/daux/daux.io.svg?style=flat-square)](https://packagist.org/packages/daux/daux.io) - **Daux.io** is a 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. ## Features -* 100% Mobile Responsive -* CommonMark compliant (a Markdown specification) -* Supports Markdown tables -* Auto created homepage/landing page -* Auto Syntax Highlighting -* Auto Generated Navigation -* 4 Built-In Themes or roll your own -* Functional, Flat Design Style -* Shareable/Linkable SEO Friendly URLs -* Built On Bootstrap -* No Build Step -* Git/SVN Friendly -* Supports Google Analytics and Piwik Analytics -* Optional code float layout -* Static Output Generation +- 100% Mobile Responsive +- CommonMark compliant (a Markdown specification) +- Supports Markdown tables +- Auto created homepage/landing page +- Auto Syntax Highlighting +- Auto Generated Navigation +- 4 Built-In Themes or roll your own +- Functional, Flat Design Style +- Shareable/Linkable SEO Friendly URLs +- Built On Bootstrap +- No Build Step +- Git/SVN Friendly +- Supports Google Analytics and Piwik Analytics +- Optional code float layout +- Static Output Generation ## Demos This is a list of sites using Daux.io: -- With a custom theme: - * [Crafty](https://swissquote.github.io/crafty) - * [Pixolution flow](https://docs.pixolution.org) - * [Soisy](https://doc.soisy.it/) - * [Vulkan Tutorial](https://vulkan-tutorial.com) - * [3Q](https://docs.3q.video/) -- With the default Theme - * [Daux.io](https://daux.io/) - * [DoctrineWatcher](https://dsentker.github.io/WatcherDocumentation/) - * [DrupalGap](http://docs.drupalgap.org/8/) - * [ICADMIN: An admin panel powered by CodeIgniter.](http://istocode.com/shared/ic-admin/) - * [Munee: Standalone PHP 5.3 Asset Optimisation & Manipulation](http://mun.ee) - * [Nuntius: A PHP framework for bots](https://roysegall.github.io/nuntius-bot/) +- With a custom theme: + - [Crafty](https://swissquote.github.io/crafty) + - [Pixolution flow](https://docs.pixolution.org) \* [Soisy](https://doc.soisy.it/) + - [Vulkan Tutorial](https://vulkan-tutorial.com) \* [3Q](https://docs.3q.video/) + - [The Advanced RSS Environment](https://thearsse.com/manual/) +- With the default Theme + - [Daux.io](https://daux.io/) + _ [DoctrineWatcher](https://dsentker.github.io/WatcherDocumentation/) + _ [DrupalGap](http://docs.drupalgap.org/8/) + - [ICADMIN: An admin panel powered by CodeIgniter.](http://istocode.com/shared/ic-admin/) + - [Munee: Standalone PHP 5.3 Asset Optimisation & Manipulation](http://mun.ee) + - [Nuntius: A PHP framework for bots](https://roysegall.github.io/nuntius-bot/) Do you use Daux.io? Send me a pull request or open an [issue](https://github.com/dauxio/daux.io/issues) and I will add you to the list. @@ -100,18 +97,18 @@ You must use underscores instead of spaces. Here are some example file names and **Good:** -* 01_Getting_Started.md = Getting Started -* API_Calls.md = API Calls -* 200_Something_Else-Cool.md = Something Else-Cool -* _5_Ways_to_Be_Happy.md = 5 Ways To Be Happy +- 01_Getting_Started.md = Getting Started +- API_Calls.md = API Calls +- 200_Something_Else-Cool.md = Something Else-Cool +- \_5_Ways_to_Be_Happy.md = 5 Ways To Be Happy **Bad:** -* File Name With Space.md = FAIL +- File Name With Space.md = FAIL ## Sorting -To sort your files and folders in a specific way, you can prefix them with a number and underscore, e.g. `/docs/01_Hello_World.md` and `/docs/05_Features.md` This will list *Hello World* before *Features*, overriding the default alpha-numeric sorting. The numbers will be stripped out of the navigation and urls. For the file `6 Ways to Get Rich`, you can use `/docs/_6_Ways_to_Get_Rich.md` +To sort your files and folders in a specific way, you can prefix them with a number and underscore, e.g. `/docs/01_Hello_World.md` and `/docs/05_Features.md` This will list _Hello World_ before _Features_, overriding the default alpha-numeric sorting. The numbers will be stripped out of the navigation and urls. For the file `6 Ways to Get Rich`, you can use `/docs/_6_Ways_to_Get_Rich.md` ## Landing page @@ -119,9 +116,9 @@ If you want to create a beautiful landing page for your project, simply create a ```json { - "title": "Daux.io", - "tagline": "The Easiest Way To Document Your Project", - "image": "app.png" + "title": "Daux.io", + "tagline": "The Easiest Way To Document Your Project", + "image": "app.png" } ``` @@ -137,42 +134,46 @@ To customize the look and feel of your documentation, you can create a `config.j The `config.json` file is a simple JSON object that you can use to change some of the basic settings of the documentation. ### Title + Change the title bar in the docs ```json { - "title": "Daux.io" + "title": "Daux.io" } ``` ### Themes + We have 4 built-in Bootstrap themes. To use one of the themes, just set the `theme` option to one of the following: -* daux-blue -* daux-green -* daux-navy -* daux-red +- daux-blue +- daux-green +- daux-navy +- daux-red ```json { - "html": { "theme": "daux-green" } + "html": { "theme": "daux-green" } } ``` ### More options + Many other options are available: -- [Global options](http://daux.io/Configuration/index) -- [HTML Options](http://daux.io/Configuration/Html_export) -- [Confluence options](http://daux.io/Configuration/Confluence_upload) + +- [Global options](http://daux.io/Configuration/index) +- [HTML Options](http://daux.io/Configuration/Html_export) +- [Confluence options](http://daux.io/Configuration/Confluence_upload) ## Running Remotely -Copy the files from the repo to a web server that can run PHP 5.4 or greater. +Copy the files from the repo to a web server that can run PHP 7.2.0 or newer. ## Running Locally There are several ways to run the docs locally. -The recommended way is to run `daux serve` which will execute PHP's embedded server. +The recommended way is to run `daux serve` which will execute PHP's embedded server. By default the server will run at: http://localhost:8085 @@ -192,8 +193,8 @@ daux --source=docs --destination=static If you have set up a local or remote IIS web site, you may need a `web.config` with: -* A rewrite configuration, for handling clean urls. -* A mime type handler for less files, if using a custom theme. +- A rewrite configuration, for handling clean urls. +- A mime type handler for less files, if using a custom theme. ### Clean URLs @@ -201,45 +202,44 @@ The `web.config` needs an entry for `` under ``: ```xml - - - - - - - - - - - - - - + + + + + + + + + + + + + + ``` To use clean URLs on IIS 6, you will need to use a custom URL rewrite module, such as [URL Rewriter](http://urlrewriter.net/). -## Docker - -A docker configuration is also provided to run daux within a container, you can either run daux with php5 or php7. - -``` -cd docker -docker-compose -f docker-compose.7.yml up -d -``` - -You can then point your browser to http://localhost:8086 - ## PHP Requirements -Daux.io is compatible with PHP 7.1.3 and up. - -The reason is because some dependencies we have (mainly Symfony and Guzzle) do not support PHP 5.6 anymore. +Daux.io is compatible with the [officially supported](https://www.php.net/supported-versions.php) PHP versions; 7.2.0 and up. ### Extensions -PHP Needs the following extension to work : `php-mbstring` and `php-xml`. +Daux.io needs the following PHP extensions to work : `php-mbstring` and `php-xml`. If you encounter an error similar to `utf8_decode() not found` this means that you're missing the `php-xml` package. diff --git a/composer.json b/composer.json index 38914b3..49e6ddc 100644 --- a/composer.json +++ b/composer.json @@ -17,18 +17,19 @@ ], "bin": ["bin/daux"], "require": { - "php": ">=7.1.3", + "php": ">=7.2", "guzzlehttp/guzzle": "~6.0", - "league/commonmark": "^0.18", + "league/commonmark": "^1.0.0", "league/plates": "~3.1", "myclabs/deep-copy": "^1.5", - "symfony/console": "^4.0", - "symfony/http-foundation": "^4.0", + "scrivo/highlight.php": "^9.15", + "symfony/console": "^5.0", + "symfony/http-foundation": "^5.0", + "symfony/mime": "^5.0", "symfony/polyfill-intl-icu": "^1.10", - "symfony/process": "^4.0", - "webuni/commonmark-table-extension": "0.9.*", + "symfony/process": "^5.0", "webuni/front-matter": "^1.0.0", - "scrivo/highlight.php": "^9.15" + "ext-json": "*" }, "suggest":{ "ext-intl": "Allows to translate the modified at date" @@ -42,10 +43,12 @@ "justinwalsh/daux.io": "*" }, "require-dev": { - "phpunit/phpunit": "~7.4", "mikey179/vfsstream": "^1.6" }, "scripts": { - "test": "phpunit" + "test": "build/phpunit", + "test:coverage-html": "build/phpunit --coverage-html=build/coverage", + "lint": "build/php-cs-fixer fix --config=.php_cs --dry-run -v", + "lint:fix": "build/php-cs-fixer fix --config=.php_cs" } } diff --git a/composer.lock b/composer.lock index dffd4ef..7f06831 100644 --- a/composer.lock +++ b/composer.lock @@ -4,31 +4,33 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3df8e368fea890f0e123788f898cddc9", + "content-hash": "65f848621b7969a7bce29ea7d2e3f7b7", "packages": [ { "name": "guzzlehttp/guzzle", - "version": "6.3.3", + "version": "6.5.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", - "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/aab4ebd862aa7d04f01a4b51849d657db56d882e", + "reference": "aab4ebd862aa7d04f01a4b51849d657db56d882e", "shasum": "" }, "require": { + "ext-json": "*", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.4", - "php": ">=5.5" + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.11" }, "require-dev": { "ext-curl": "*", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.0" + "psr/log": "^1.1" }, "suggest": { "psr/log": "Required for using the Log middleware" @@ -36,16 +38,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\": "src/" - } + }, + "files": [ + "src/functions_include.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -69,7 +71,7 @@ "rest", "web service" ], - "time": "2018-04-22T15:46:56+00:00" + "time": "2020-04-18T10:38:46+00:00" }, { "name": "guzzlehttp/promises", @@ -124,33 +126,37 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.5.2", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "9f83dded91781a01c63574e387eaa769be769115" + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", - "reference": "9f83dded91781a01c63574e387eaa769be769115", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", "shasum": "" }, "require": { "php": ">=5.4.0", "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5" + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" }, "provide": { "psr/http-message-implementation": "1.0" }, "require-dev": { + "ext-zlib": "*", "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.5-dev" + "dev-master": "1.6-dev" } }, "autoload": { @@ -187,41 +193,41 @@ "uri", "url" ], - "time": "2018-12-04T20:46:45+00:00" + "time": "2019-07-01T23:21:34+00:00" }, { "name": "league/commonmark", - "version": "0.18.5", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "f94e18d68260f43a7d846279cad88405854b1306" + "reference": "412639f7cfbc0b31ad2455b2fe965095f66ae505" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/f94e18d68260f43a7d846279cad88405854b1306", - "reference": "f94e18d68260f43a7d846279cad88405854b1306", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/412639f7cfbc0b31ad2455b2fe965095f66ae505", + "reference": "412639f7cfbc0b31ad2455b2fe965095f66ae505", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=5.6.5" + "php": "^7.1" }, - "replace": { - "colinodell/commonmark-php": "*" + "conflict": { + "scrutinizer/ocular": "1.7.*" }, "require-dev": { "cebe/markdown": "~1.0", - "commonmark/commonmark.js": "0.28", + "commonmark/commonmark.js": "0.29.1", "erusev/parsedown": "~1.0", + "ext-json": "*", + "github/gfm": "0.29.0", "michelf/php-markdown": "~1.4", - "mikehaertl/php-shellcommand": "^1.2", - "phpunit/phpunit": "^5.7.27|^6.5.14", - "scrutinizer/ocular": "^1.1", - "symfony/finder": "^3.0|^4.0" - }, - "suggest": { - "league/commonmark-extras": "Library of useful extensions including smart punctuation" + "mikehaertl/php-shellcommand": "^1.4", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5", + "scrutinizer/ocular": "^1.5", + "symfony/finder": "^4.2" }, "bin": [ "bin/commonmark" @@ -229,12 +235,12 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "0.19-dev" + "dev-master": "1.4-dev" } }, "autoload": { "psr-4": { - "League\\CommonMark\\": "src/" + "League\\CommonMark\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -249,14 +255,45 @@ "role": "Lead Developer" } ], - "description": "PHP Markdown parser based on the CommonMark spec", - "homepage": "https://github.com/thephpleague/commonmark", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", "keywords": [ "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", "markdown", + "md", "parser" ], - "time": "2019-03-28T13:52:31+00:00" + "funding": [ + { + "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", + "type": "custom" + }, + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://www.patreon.com/colinodell", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2020-05-04T22:15:21+00:00" }, { "name": "league/plates", @@ -315,16 +352,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.9.3", + "version": "1.9.5", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea" + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/007c053ae6f31bba39dfa19a7726f56e9763bbea", - "reference": "007c053ae6f31bba39dfa19a7726f56e9763bbea", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef", + "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef", "shasum": "" }, "require": { @@ -359,7 +396,7 @@ "object", "object graph" ], - "time": "2019-08-09T12:45:53+00:00" + "time": "2020-01-17T21:11:47+00:00" }, { "name": "psr/container", @@ -462,24 +499,24 @@ }, { "name": "ralouphie/getallheaders", - "version": "2.0.5", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + "reference": "120b605dfeb996808c31b6477290a714d356e822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", - "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", "shasum": "" }, "require": { - "php": ">=5.3" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "~3.7.0", - "satooshi/php-coveralls": ">=1.0" + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" }, "type": "library", "autoload": { @@ -498,20 +535,20 @@ } ], "description": "A polyfill for getallheaders.", - "time": "2016-02-11T07:05:27+00:00" + "time": "2019-03-08T08:55:37+00:00" }, { "name": "scrivo/highlight.php", - "version": "v9.15.10.0", + "version": "v9.18.1.1", "source": { "type": "git", "url": "https://github.com/scrivo/highlight.php.git", - "reference": "9ad3adb4456dc91196327498dbbce6aa1ba1239e" + "reference": "52fc21c99fd888e33aed4879e55a3646f8d40558" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/9ad3adb4456dc91196327498dbbce6aa1ba1239e", - "reference": "9ad3adb4456dc91196327498dbbce6aa1ba1239e", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/52fc21c99fd888e33aed4879e55a3646f8d40558", + "reference": "52fc21c99fd888e33aed4879e55a3646f8d40558", "shasum": "" }, "require": { @@ -521,7 +558,9 @@ }, "require-dev": { "phpunit/phpunit": "^4.8|^5.7", - "symfony/finder": "^2.8" + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4", + "symfony/var-dumper": "^2.8|^3.4" }, "suggest": { "ext-dom": "Needed to make use of the features in the utilities namespace" @@ -543,18 +582,18 @@ "authors": [ { "name": "Geert Bergman", - "role": "Project Author", - "homepage": "http://www.scrivo.org/" + "homepage": "http://www.scrivo.org/", + "role": "Project Author" }, { "name": "Vladimir Jimenez", - "role": "Contributor", - "homepage": "https://allejo.io" + "homepage": "https://allejo.io", + "role": "Maintainer" }, { "name": "Martin Folkers", - "role": "Contributor", - "homepage": "https://twobrain.io" + "homepage": "https://twobrain.io", + "role": "Contributor" } ], "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", @@ -565,44 +604,45 @@ "highlight.php", "syntax" ], - "time": "2019-08-27T04:27:48+00:00" + "time": "2020-03-02T05:59:21+00:00" }, { "name": "symfony/console", - "version": "v4.3.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "de63799239b3881b8a08f8481b22348f77ed7b36" + "reference": "5fa1caadc8cdaa17bcfb25219f3b53fe294a9935" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/de63799239b3881b8a08f8481b22348f77ed7b36", - "reference": "de63799239b3881b8a08f8481b22348f77ed7b36", + "url": "https://api.github.com/repos/symfony/console/zipball/5fa1caadc8cdaa17bcfb25219f3b53fe294a9935", + "reference": "5fa1caadc8cdaa17bcfb25219f3b53fe294a9935", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": "^7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/service-contracts": "^1.1" + "symfony/service-contracts": "^1.1|^2" }, "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3", - "symfony/process": "<3.3" + "symfony/dependency-injection": "<4.4", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~3.4|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "^4.3", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.4|~4.0", - "symfony/var-dumper": "^4.3" + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" }, "suggest": { "psr/log": "For using the console logger", @@ -613,7 +653,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -640,35 +680,49 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-03-30T11:42:42+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.3.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc" + "reference": "e47fdf8b24edc12022ba52923150ec6484d7f57d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d804bea118ff340a12e22a79f9c7e7eb56b35adc", - "reference": "d804bea118ff340a12e22a79f9c7e7eb56b35adc", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e47fdf8b24edc12022ba52923150ec6484d7f57d", + "reference": "e47fdf8b24edc12022ba52923150ec6484d7f57d", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/mime": "^4.3", + "php": "^7.2.5", + "symfony/mime": "^4.4|^5.0", "symfony/polyfill-mbstring": "~1.1" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "~3.4|~4.0" + "symfony/expression-language": "^4.4|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -695,28 +749,42 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:55:16+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-04-18T20:50:06+00:00" }, { "name": "symfony/intl", - "version": "v4.3.3", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "741376a9127841ffae39f197f8bd0ab2d4772157" + "reference": "dc50ad5039ac685ca87306a346dc119cacdfea25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/741376a9127841ffae39f197f8bd0ab2d4772157", - "reference": "741376a9127841ffae39f197f8bd0ab2d4772157", + "url": "https://api.github.com/repos/symfony/intl/zipball/dc50ad5039ac685ca87306a346dc119cacdfea25", + "reference": "dc50ad5039ac685ca87306a346dc119cacdfea25", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": "^7.2.5", "symfony/polyfill-intl-icu": "~1.0" }, "require-dev": { - "symfony/filesystem": "~3.4|~4.0" + "symfony/filesystem": "^4.4|^5.0" }, "suggest": { "ext-intl": "to use the component with locales other than \"en\"" @@ -724,7 +792,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -770,35 +838,52 @@ "l10n", "localization" ], - "time": "2019-07-24T14:47:54+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-04-12T14:40:17+00:00" }, { "name": "symfony/mime", - "version": "v4.3.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "987a05df1c6ac259b34008b932551353f4f408df" + "reference": "5d6c81c39225a750f3f43bee15f03093fb9aaa0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/987a05df1c6ac259b34008b932551353f4f408df", - "reference": "987a05df1c6ac259b34008b932551353f4f408df", + "url": "https://api.github.com/repos/symfony/mime/zipball/5d6c81c39225a750f3f43bee15f03093fb9aaa0b", + "reference": "5d6c81c39225a750f3f43bee15f03093fb9aaa0b", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": "^7.2.5", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, + "conflict": { + "symfony/mailer": "<4.4" + }, "require-dev": { "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "~3.4|^4.1" + "symfony/dependency-injection": "^4.4|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -829,20 +914,34 @@ "mime", "mime-type" ], - "time": "2019-08-22T08:16:11+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-04-17T03:29:44+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "550ebaac289296ce228a706d0867afc34687e3f4" + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/550ebaac289296ce228a706d0867afc34687e3f4", - "reference": "550ebaac289296ce228a706d0867afc34687e3f4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", "shasum": "" }, "require": { @@ -854,7 +953,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -887,20 +986,34 @@ "polyfill", "portable" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:14:59+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "66810b9d6eb4af54d543867909d65ab9af654d7e" + "reference": "4ef3923e4a86e1b6ef72d42be59dbf7d33a685e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/66810b9d6eb4af54d543867909d65ab9af654d7e", - "reference": "66810b9d6eb4af54d543867909d65ab9af654d7e", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/4ef3923e4a86e1b6ef72d42be59dbf7d33a685e3", + "reference": "4ef3923e4a86e1b6ef72d42be59dbf7d33a685e3", "shasum": "" }, "require": { @@ -913,7 +1026,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -945,26 +1058,40 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:14:59+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2" + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", - "reference": "6af626ae6fa37d396dc90a399c0ff08e5cfc45b2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a", "shasum": "" }, "require": { "php": ">=5.3.3", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.9" + "symfony/polyfill-php72": "^1.10" }, "suggest": { "ext-intl": "For best performance" @@ -972,7 +1099,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -1007,20 +1134,34 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17" + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b42a2f66e8f1b15ccf25652c3424265923eb4f17", - "reference": "b42a2f66e8f1b15ccf25652c3424265923eb4f17", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", "shasum": "" }, "require": { @@ -1032,7 +1173,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -1066,20 +1207,34 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "04ce3335667451138df4307d6a9b61565560199e" + "reference": "f048e612a3905f34931127360bdd2def19a5e582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/04ce3335667451138df4307d6a9b61565560199e", - "reference": "04ce3335667451138df4307d6a9b61565560199e", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", "shasum": "" }, "require": { @@ -1088,7 +1243,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -1121,20 +1276,34 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.12.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188" + "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/2ceb49eaccb9352bff54d22570276bb75ba4a188", - "reference": "2ceb49eaccb9352bff54d22570276bb75ba4a188", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a760d8964ff79ab9bf057613a5808284ec852ccc", + "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc", "shasum": "" }, "require": { @@ -1143,7 +1312,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.12-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -1179,29 +1348,43 @@ "portable", "shim" ], - "time": "2019-08-06T08:03:45+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-12T16:47:27+00:00" }, { "name": "symfony/process", - "version": "v4.3.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a" + "reference": "3179f68dff5bad14d38c4114a1dab98030801fd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e89969c00d762349f078db1128506f7f3dcc0d4a", - "reference": "e89969c00d762349f078db1128506f7f3dcc0d4a", + "url": "https://api.github.com/repos/symfony/process/zipball/3179f68dff5bad14d38c4114a1dab98030801fd7", + "reference": "3179f68dff5bad14d38c4114a1dab98030801fd7", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.2.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.3-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1228,24 +1411,38 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2019-08-26T08:26:39+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-04-15T15:59:10+00:00" }, { "name": "symfony/service-contracts", - "version": "v1.1.6", + "version": "v2.0.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3" + "reference": "144c5e51266b281231e947b51223ba14acf1a749" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/ea7263d6b6d5f798b56a45a5b8d686725f2719a3", - "reference": "ea7263d6b6d5f798b56a45a5b8d686725f2719a3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749", + "reference": "144c5e51266b281231e947b51223ba14acf1a749", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": "^7.2.5", "psr/container": "^1.0" }, "suggest": { @@ -1254,7 +1451,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1286,20 +1483,20 @@ "interoperability", "standards" ], - "time": "2019-08-20T14:44:19+00:00" + "time": "2019-11-18T17:27:11+00:00" }, { "name": "symfony/yaml", - "version": "v4.2.9", + "version": "v4.4.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "6712daf03ee25b53abb14e7e8e0ede1a770efdb1" + "reference": "b385dce1c0e9f839b384af90188638819433e252" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/6712daf03ee25b53abb14e7e8e0ede1a770efdb1", - "reference": "6712daf03ee25b53abb14e7e8e0ede1a770efdb1", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b385dce1c0e9f839b384af90188638819433e252", + "reference": "b385dce1c0e9f839b384af90188638819433e252", "shasum": "" }, "require": { @@ -1310,7 +1507,7 @@ "symfony/console": "<3.4" }, "require-dev": { - "symfony/console": "~3.4|~4.0" + "symfony/console": "^3.4|^4.0|^5.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -1318,7 +1515,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.4-dev" } }, "autoload": { @@ -1345,66 +1542,21 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2019-03-30T15:58:42+00:00" - }, - { - "name": "webuni/commonmark-table-extension", - "version": "0.9.0", - "source": { - "type": "git", - "url": "https://github.com/webuni/commonmark-table-extension.git", - "reference": "94bc98d802d0b706e748716854e5fa0bd3644df3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webuni/commonmark-table-extension/zipball/94bc98d802d0b706e748716854e5fa0bd3644df3", - "reference": "94bc98d802d0b706e748716854e5fa0bd3644df3", - "shasum": "" - }, - "require": { - "league/commonmark": "^0.16|^0.17|^0.18", - "php": "^5.6|^7.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^2.9", - "phpunit/phpunit": "^5.4|^6.0", - "symfony/var-dumper": "^3.0|^4.0", - "vimeo/psalm": "~0.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9-dev" - } - }, - "autoload": { - "psr-4": { - "Webuni\\CommonMark\\TableExtension\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Martin Hasoň", - "email": "martin.hason@gmail.com" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Webuni s.r.o.", - "homepage": "https://www.webuni.cz" + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "The table extension for CommonMark PHP implementation", - "homepage": "https://github.com/webuni/commonmark-table-extension", - "keywords": [ - "commonmark", - "markdown", - "table" - ], - "abandoned": "league/commonmark-ext-table", - "time": "2018-11-28T11:29:11+00:00" + "time": "2020-04-28T17:55:16+00:00" }, { "name": "webuni/front-matter", @@ -1476,74 +1628,18 @@ } ], "packages-dev": [ - { - "name": "doctrine/instantiator", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "a2c590166b2133a4633738648b6b064edae0814a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", - "reference": "a2c590166b2133a4633738648b6b064edae0814a", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2019-03-17T17:37:11+00:00" - }, { "name": "mikey179/vfsstream", - "version": "v1.6.7", + "version": "v1.6.8", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", - "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb" + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb", - "reference": "2b544ac3a21bcc4dde5d90c4ae8d06f4319055fb", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", "shasum": "" }, "require": { @@ -1570,1320 +1666,13 @@ "authors": [ { "name": "Frank Kleine", - "role": "Developer", - "homepage": "http://frankkleine.de/" + "homepage": "http://frankkleine.de/", + "role": "Developer" } ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", - "time": "2019-08-01T01:38:37+00:00" - }, - { - "name": "phar-io/manifest", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2018-07-08T19:23:20+00:00" - }, - { - "name": "phar-io/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2018-07-08T19:19:57+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "~6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2018-08-07T13:53:10+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "4.3.2", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "reference": "b83ff7cfcfee7827e1e78b637a5904fe6a96698e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" - }, - "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-09-12T14:27:41+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "shasum": "" - }, - "require": { - "php": "^7.1", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.8.1", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", - "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0|^3.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.8.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2019-06-13T12:50:23+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "6.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "suggest": { - "ext-xdebug": "^2.6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "6.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2018-10-31T16:06:48+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "050bedf145a257b1ff02746c31894800e5122946" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", - "reference": "050bedf145a257b1ff02746c31894800e5122946", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2018-09-13T20:33:42+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2015-06-21T13:50:34+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "2.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", - "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "role": "lead", - "email": "sebastian@phpunit.de" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2019-06-07T04:22:29+00:00" - }, - { - "name": "phpunit/php-token-stream", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e899757bb3df5ff6e95089132f32cd59aac2220a", - "reference": "e899757bb3df5ff6e95089132f32cd59aac2220a", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2019-07-25T05:29:42+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "7.5.16", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "316afa6888d2562e04aeb67ea7f2017a0eb41661" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/316afa6888d2562e04aeb67ea7f2017a0eb41661", - "reference": "316afa6888d2562e04aeb67ea7f2017a0eb41661", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, - "require-dev": { - "ext-pdo": "*" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.5-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2019-09-14T09:08:39+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" - }, - { - "name": "sebastian/comparator", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", - "shasum": "" - }, - "require": { - "php": "^7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2018-07-12T15:12:46+00:00" - }, - { - "name": "sebastian/diff", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "time": "2019-02-04T06:01:07+00:00" - }, - { - "name": "sebastian/environment", - "version": "4.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", - "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.5" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2019-05-05T09:05:15+00:00" - }, - { - "name": "sebastian/exporter", - "version": "3.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", - "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2019-09-14T09:02:43+00:00" - }, - { - "name": "sebastian/global-state", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "time": "2017-04-27T15:39:26+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", - "shasum": "" - }, - "require": { - "php": "^7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-08-03T12:35:26+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "773f97c67f28de00d397be301821b06708fca0be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", - "reference": "773f97c67f28de00d397be301821b06708fca0be", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2017-03-29T09:07:27+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2017-03-03T06:23:57+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", - "shasum": "" - }, - "require": { - "php": "^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2018-10-04T04:07:39+00:00" - }, - { - "name": "sebastian/version", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2019-06-13T22:48:21+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0", - "symfony/polyfill-ctype": "^1.8" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2019-08-24T08:43:50+00:00" + "time": "2019-10-30T15:31:00+00:00" } ], "aliases": [], @@ -2892,7 +1681,9 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.1.3" + "php": ">=7.2", + "ext-json": "*" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/crafty.config.js b/crafty.config.js index 32a1bb7..e403eec 100644 --- a/crafty.config.js +++ b/crafty.config.js @@ -1,6 +1,5 @@ module.exports = { - browsers: - "> 0.25%, Edge >= 15, Safari >= 10, iOS >= 10, Chrome >= 56, Firefox >= 51, IE >= 11, not op_mini all", + browsers: "defaults, not op_mini all", presets: [ "@swissquote/crafty-preset-babel", "@swissquote/crafty-runner-rollup", @@ -23,11 +22,13 @@ module.exports = { js: { search: { runner: "rollup", + format: "iife", source: "src/js/search/index.js", destination: "daux_libraries/search.min.js" }, theme_daux: { runner: "rollup", + format: "iife", source: "src/js/theme_daux/index.js", destination: "themes/daux/js/daux.min.js" } @@ -58,5 +59,9 @@ module.exports = { destination: "themes/daux_singlepage/css/main.min.css", watch: ["src/css/**/*.scss"] } + }, + postcss(crafty, config, bundle) { + // Add postcss-page-break + config.processor("postcss-page-break").before("autoprefixer"); } }; diff --git a/daux_libraries/search.min.js b/daux_libraries/search.min.js index 0caa4ef..0099ec0 100644 --- a/daux_libraries/search.min.js +++ b/daux_libraries/search.min.js @@ -1,2 +1,2 @@ -function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function e(t,e){for(var n=0;n3)for(n=[n],i=3;i=i&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(e,this.o),this.F&&this.F(this.o))),this}function r(t,e){const n=t.length,i=m(e),r=[];for(let s=0,o=0;s=o&&((t=(t=t[l-(r+.5>>0)])[n]||(t[n]=[]))[t.length]=i),r)}function u(t,e){if(t){const n=Object.keys(t);for(let i=0,r=n.length;i(t=t.length-e.length)?1:t?-1:0}function p(t,e){return(t=t[T])<(e=e[T])?-1:t>e?1:0}function d(t,e){const n=T.length;for(let i=0;ie?1:0}function _(t,e,n){return t?{page:t,next:e?""+e:null,result:n}:n}function g(t,e,n,i,r,s,o){let l,h=[];if(!0===n){n="0";var c=""}else c=n&&n.split(":");const u=t.length;if(1o&&(c=0),(l=(c=c||0)+e)=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:t,content:e}),this.c[o]=""+this.C,n&&n(),this;if(!s){if(this.async&&"function"!=typeof importScripts){let r=this;return o=new Promise((function(n){setTimeout((function(){r.add(t,e,null,i,!0),r=null,n()}))})),n?(o.then(n),this):o}if(n)return this.add(t,e,null,i,!0),n(),this}if(!(e=this.encode(e)).length)return this;s=m(n=this.f)?n(e):e.split(this.split),this.filter&&(s=r(s,this.filter));const p=x();p._ctx=x();const d=s.length,_=this.threshold,g=this.depth,y=this.b,v=this.i,b=this.D;for(let e=0;ef;n--)c(v,p,a=l.substring(f,n),t,e,u,_,y-1)}break;default:if(h=c(v,p,l,t,1,u,_,y-1),g&&1=_)for(h=p._ctx[l]||(p._ctx[l]=x()),l=this.h[l]||(this.h[l]=k(y-(_||0))),0>(u=e-g)&&(u=0),(a=e+g+1)>d&&(a=d);ur;n--)i=s[n-1],s[n]=i,e[i]=n;s[r]=t,e[t]=r}}}return e},t}();return n}(function(){const t={},e="undefined"!=typeof Blob&&"undefined"!=typeof URL&&URL.createObjectURL;return function(n,i,r,s,o){return r=e?URL.createObjectURL(new Blob(["("+r.toString()+")()"],{type:"text/javascript"})):n+".min.js",t[n+="-"+i]||(t[n]=[]),t[n][o]=new Worker(r),t[n][o].onmessage=s,t[n][o]}}()),M)})),W=window.searchTranslation,B=W.Link_previous,F=W.Link_next,z=W.Search_no_results,H=W.Search_one_character_or_more,q=W.Search_one_result,G=W.Search_results,$=W.Search_should_be_x_or_more,J=W.Search_too_short,V=B,K=F,Q=z,X=H,Y=q,Z=G,tt=$,et=J;function nt(t){var e,n=t.counter,i=t.start,r=t.settings,s=t.onPageSelect,o=Math.ceil(n/r.show),l=i/r.show;e=l<=2?Math.min(o,3):Math.min(o,l+2);for(var h=[],c=function(t){t===l?h.push(v("li",{className:"current"},t+1)):h.push(v("li",null,v("a",{className:"SearchResults__footer__link",onClick:function(){return s(t*r.show)}},t+1)))},u=0;u0&&v("li",{className:"Pager--prev"},v("a",{className:"SearchResults__footer__link",onClick:function(){return s(i-r.show)}},V)),h,l+1!==o&&v("li",{className:"Pager--next"},v("a",{className:"SearchResults__footer__link",onClick:function(){return s(i+r.show)}},K))))}function it(t){var e,n=t.settings,i=t.item;return i.text&&(e=i.text.split(" ").slice(0,n.descriptiveWords).join(" "),i.text.length=e&&ie.show&&v(nt,{counter:r,start:o,settings:e,onPageSelect:this.handlePaginate})))}}]),i}(),st=document.title;function ot(t){var e=new RegExp("[?|&]".concat(t,"=([^&;]+?)(&|#|;|$)")).exec(window.location.search);return decodeURIComponent((e&&e[1]||"").replace(/\+/g,"%20"))||null}var lt=function(){function e(n){var s=this;t(this,e),this.keyUpHandler=function(t){27===t.which&&s.handleClose()},this.handleClose=function(){document.title=st,document.removeEventListener("keyup",s.keyUpHandler),document.body.classList.remove("with-search"),I(null,s.resultContainer),s.resultContainer=null},this.settings=function(t){for(var e=1;e3)for(n=[n],i=3;i=i&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(e,this.o),this.F&&this.F(this.o))),this}function r(t,e){const n=t.length,i=m(e),r=[];for(let s=0,o=0;s=o&&((t=(t=t[l-(r+.5>>0)])[n]||(t[n]=[]))[t.length]=i),r)}function u(t,e){if(t){const n=Object.keys(t);for(let i=0,r=n.length;i(t=t.length-e.length)?1:t?-1:0}function d(t,e){return(t=t[T])<(e=e[T])?-1:t>e?1:0}function p(t,e){const n=T.length;for(let i=0;ie?1:0}function _(t,e,n){return t?{page:t,next:e?""+e:null,result:n}:n}function g(t,e,n,i,r,s,o){let l,c=[];if(!0===n){n="0";var h=""}else h=n&&n.split(":");const u=t.length;if(1o&&(h=0),l=(h=h||0)+e,l=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:t,content:e}),this.c[o]=""+this.C,n&&n(),this;if(!s){if(this.async&&"function"!=typeof importScripts){let r=this;return o=new Promise((function(n){setTimeout((function(){r.add(t,e,null,i,!0),r=null,n()}))})),n?(o.then(n),this):o}if(n)return this.add(t,e,null,i,!0),n(),this}if(!(e=this.encode(e)).length)return this;s=m(n=this.f)?n(e):e.split(this.split),this.filter&&(s=r(s,this.filter));const d=x();d._ctx=x();const p=s.length,_=this.threshold,g=this.depth,y=this.b,v=this.i,b=this.D;for(let e=0;ef;n--)h(v,d,a=l.substring(f,n),t,e,u,_,y-1)}break;default:if(c=h(v,d,l,t,1,u,_,y-1),g&&1=_)for(c=d._ctx[l]||(d._ctx[l]=x()),l=this.h[l]||(this.h[l]=k(y-(_||0))),0>(u=e-g)&&(u=0),(a=e+g+1)>p&&(a=p);ur;n--)i=s[n-1],s[n]=i,e[i]=n;s[r]=t,e[t]=r}}}return e},t}();return n}(function(){const t={},e="undefined"!=typeof Blob&&"undefined"!=typeof URL&&URL.createObjectURL;return function(n,i,r,s,o){return r=e?URL.createObjectURL(new Blob(["("+r.toString()+")()"],{type:"text/javascript"})):n+".min.js",t[n+="-"+i]||(t[n]=[]),t[n][o]=new Worker(r),t[n][o].onmessage=s,t[n][o]}}()),B)})),z=window.searchTranslation,F=z.Link_previous,H=z.Link_next,q=z.Search_no_results,G=z.Search_one_character_or_more,$=z.Search_one_result,J=z.Search_results,V=z.Search_should_be_x_or_more,K=z.Search_too_short,Q=F,X=H,Y=q,Z=G,tt=$,et=J,nt=V,it=K;function rt(t){var e,n=t.counter,i=t.start,r=t.settings,s=t.onPageSelect,o=Math.ceil(n/r.show),l=i/r.show;e=l<=2?Math.min(o,3):Math.min(o,l+2);for(var c=[],h=function(t){t===l?c.push(b("li",{className:"current"},t+1)):c.push(b("li",null,b("a",{className:"SearchResults__footer__link",onClick:function(){return s(t*r.show)}},t+1)))},u=0;u0&&b("li",{className:"Pager--prev"},b("a",{className:"SearchResults__footer__link",onClick:function(){return s(i-r.show)}},Q)),c,l+1!==o&&b("li",{className:"Pager--next"},b("a",{className:"SearchResults__footer__link",onClick:function(){return s(i+r.show)}},X))))}function st(t){var e,n=t.settings,i=t.item;return i.text&&(e=i.text.split(" ").slice(0,n.descriptiveWords).join(" "),i.text.length=e&&ie.show&&b(rt,{counter:r,start:o,settings:e,onPageSelect:this.handlePaginate})))}}]),r}(x),lt=document.title;function ct(t){var e=new RegExp("[?|&]".concat(t,"=([^&;]+?)(&|#|;|$)")).exec(window.location.search);return decodeURIComponent((e&&e[1]||"").replace(/\+/g,"%20"))||null}var ht=function(){function e(n){var s=this;t(this,e),this.keyUpHandler=function(t){27===t.which&&s.handleClose()},this.handleClose=function(){document.title=lt,document.removeEventListener("keyup",s.keyUpHandler),document.body.classList.remove("with-search"),M(null,s.resultContainer),s.resultContainer=null},this.settings=function(t){for(var e=1;e3)for(u=[u],t=3;t2&&(l.children=e.slice.call(arguments,2)),v(n.type,l,l.key||n.key,l.ref||n.ref)}function O(n){var l={},u={__c:\"__cC\"+o++,__p:n,Consumer:function(n,l){return this.shouldComponentUpdate=function(n,u,t){return t!==l},n.children(l)},Provider:function(n){var t,i=this;return this.getChildContext||(t=[],this.getChildContext=function(){return l[u.__c]=i,l},this.shouldComponentUpdate=function(n){t.some(function(l){l.__P&&(l.context=n.value,k(l))})},this.sub=function(n){t.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){t.splice(t.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Consumer.contextType=u,u}n={},l=function(n){return null!=n&&void 0===n.constructor},m.prototype.setState=function(n,l){var u=this.__s!==this.state&&this.__s||(this.__s=s({},this.state));(\"function\"!=typeof n||(n=n(u,this.props)))&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this))},m.prototype.forceUpdate=function(n){var l,u,t,i=this.__v,r=this.__v.__e,o=this.__P;o&&(l=!1!==n,u=[],t=$(o,i,s({},i),this.__n,void 0!==o.ownerSVGElement,null,u,l,null==r?w(i):r),j(u,i),t!=r&&g(i)),n&&n()},m.prototype.render=y,u=[],t=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,i=n.debounceRendering,n.__e=function(n,l,u){for(var t;l=l.__p;)if((t=l.__c)&&!t.__p)try{if(t.constructor&&null!=t.constructor.getDerivedStateFromError)t.setState(t.constructor.getDerivedStateFromError(n));else{if(null==t.componentDidCatch)continue;t.componentDidCatch(n)}return k(t.__E=t)}catch(l){n=l}throw n},r=f,o=0;export{I as render,L as hydrate,h as createElement,h,y as Fragment,p as createRef,l as isValidElement,m as Component,M as cloneElement,O as createContext,x as toChildArray,D as _unmount,n as options};\n//# sourceMappingURL=preact.module.js.map\n","/*\r\n FlexSearch v0.6.30\r\n Copyright 2019 Nextapps GmbH\r\n Author: Thomas Wilkerling\r\n Released under the Apache 2.0 Licence\r\n https://github.com/nextapps-de/flexsearch\r\n*/\r\n'use strict';(function(K,R,w){let L;(L=w.define)&&L.amd?L([],function(){return R}):(L=w.modules)?L[K.toLowerCase()]=R:\"object\"===typeof exports?module.exports=R:w[K]=R})(\"FlexSearch\",function ma(K){function w(a,c){const b=c?c.id:a&&a.id;this.id=b||0===b?b:na++;this.init(a,c);fa(this,\"index\",function(){return this.a?Object.keys(this.a.index[this.a.keys[0]].c):Object.keys(this.c)});fa(this,\"length\",function(){return this.index.length})}function L(a,c,b,d){this.u!==this.g&&(this.o=this.o.concat(b),this.u++,\r\nd&&this.o.length>=d&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(c,this.o),this.F&&this.F(this.o)));return this}function S(a){const c=B();for(const b in a)if(a.hasOwnProperty(b)){const d=a[b];F(d)?c[b]=d.slice(0):G(d)?c[b]=S(d):c[b]=d}return c}function W(a,c){const b=a.length,d=O(c),e=[];for(let g=0,f=0;g=f&&(a=a[h-(e+.5>>0)],a=a[b]||(a[b]=[]),\r\na[a.length]=d);return e}function ba(a,c){if(a){const b=Object.keys(a);for(let d=0,e=b.length;da?1:a?-1:0}function pa(a,c){a=a[M];c=c[M];return ac?1:0}function oa(a,c){const b=M.length;for(let d=0;dc?1:0}function T(a,c,b){return a?{page:a,next:c?\"\"+c:null,result:b}:b}function ha(a,c,b,d,e,g,f){let h,k=[];if(!0===b){b=\"0\";var l=\"\"}else l=b&&b.split(\":\");const n=a.length;if(1f&&(l=0),l=l||0,h=l+c,h=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:a,\r\ncontent:c}),this.c[g]=\"\"+this.C,b&&b(),this;if(!e){if(this.async&&\"function\"!==typeof importScripts){let t=this;g=new Promise(function(v){setTimeout(function(){t.add(a,c,null,d,!0);t=null;v()})});if(b)g.then(b);else return g;return this}if(b)return this.add(a,c,null,d,!0),b(),this}c=this.encode(c);if(!c.length)return this;b=this.f;e=O(b)?b(c):c.split(this.split);this.filter&&(e=W(e,this.filter));const p=B();p._ctx=B();const m=e.length,u=this.threshold,q=this.depth,A=this.b,z=this.i,y=this.D;for(let t=\r\n0;tn;x--)l=f.substring(n,x),V(z,p,l,a,v,k,u,A-1)}break;default:if(h=V(z,p,f,a,1,k,u,A-1),q&&1=u)for(h=p._ctx[f]||(p._ctx[f]=B()),f=this.h[f]||(this.h[f]=ia(A-(u||0))),k=t-q,l=t+q+1,0>k&&(k=0),l>\r\nm&&(l=m);kf;d--)e=h[d-1],h[d]=e,g[e]=d;h[f]=c;g[c]=f}}}return b};return a}();return w}(function(){const K={},R=\"undefined\"!==typeof Blob&&\"undefined\"!==typeof URL&&URL.createObjectURL;return function(w,L,S,W,P){S=R?URL.createObjectURL(new Blob([\"(\"+S.toString()+\")()\"],{type:\"text/javascript\"})):w+\".min.js\";w+=\"-\"+L;K[w]||(K[w]=[]);K[w][P]=new Worker(S);K[w][P].onmessage=W;return K[w][P]}}()),this);\r\n","/* eslint-disable camelcase */\nconst {\n Link_previous,\n Link_next,\n Search_no_results,\n Search_one_character_or_more,\n Search_one_result,\n Search_results,\n Search_should_be_x_or_more,\n Search_too_short\n} = window.searchTranslation;\n\nconst textLinkPrevious = Link_previous;\nconst textLinkNext = Link_next;\nconst textSearchNoResults = Search_no_results;\nconst textSearchOneCharacterOrMore = Search_one_character_or_more;\nconst textSearchOneResult = Search_one_result;\nconst textSearchResults = Search_results;\nconst textSearchShouldBeXOrMore = Search_should_be_x_or_more;\nconst textSearchTooShort = Search_too_short;\n/* eslint-enable camelcase */\n\nexport {\n textLinkPrevious,\n textLinkNext,\n textSearchNoResults,\n textSearchOneCharacterOrMore,\n textSearchOneResult,\n textSearchResults,\n textSearchShouldBeXOrMore,\n textSearchTooShort\n};\n","import * as preact from \"preact\";\nimport { textLinkPrevious, textLinkNext } from \"./translation\";\n/** @jsx preact.h */\n\nexport default function Pagination({ counter, start, settings, onPageSelect }) {\n const pages = Math.ceil(counter / settings.show);\n const page = start / settings.show;\n\n let displayedPages;\n if (page <= 2) {\n // Display max three pages\n displayedPages = Math.min(pages, 3);\n } else {\n // Display two more pages, but don't overflow\n displayedPages = Math.min(pages, page + 2);\n }\n\n const items = [];\n\n for (let f = 0; f < displayedPages; f++) {\n if (f === page) {\n items.push(
  • {f + 1}
  • );\n } else {\n items.push(\n
  • \n onPageSelect(f * settings.show)}\n >\n {f + 1}\n \n
  • \n );\n }\n }\n\n return (\n
    \n
      \n {start > 0 && (\n
    • \n onPageSelect(start - settings.show)}\n >\n {textLinkPrevious}\n \n
    • \n )}\n {items}\n {page + 1 !== pages && (\n
    • \n onPageSelect(start + settings.show)}\n >\n {textLinkNext}\n \n
    • \n )}\n
    \n
    \n );\n}\n","import * as preact from \"preact\";\n/** @jsx preact.h */\n\n// TODO :: restore highlight\n/*function highlightText(search, text) {\n if (settings.highlightTerms) {\n var pattern = new RegExp(\n `(${search})`,\n settings.highlightEveryTerm ? \"gi\" : \"i\"\n );\n text = text.replace(\n pattern,\n '$1'\n );\n }\n\n return text;\n}*/\n\nexport default function Result({ settings, item }) {\n let text;\n if (item.text) {\n text = item.text\n .split(\" \")\n .slice(0, settings.descriptiveWords)\n .join(\" \");\n if (\n item.text.length < text.length &&\n text.charAt(text.length - 1) !== \".\"\n ) {\n text += \" ...\";\n }\n }\n\n return (\n
    \n \n {settings.showURL && (\n \n )}\n {text &&
    {text}
    }\n
    \n );\n}\n","import * as preact from \"preact\";\n\nimport Pagination from \"./Pagination\";\nimport Result from \"./Result\";\nimport {\n textSearchNoResults,\n textSearchOneCharacterOrMore,\n textSearchOneResult,\n textSearchResults,\n textSearchShouldBeXOrMore,\n textSearchTooShort\n} from \"./translation\";\n\n/** @jsx preact.h */\n\nexport default class Search extends preact.Component {\n constructor(props) {\n super(props);\n\n this.state = {\n search: this.props.settings.field.value || \"\",\n start: 0\n };\n }\n\n // \"click\", \".SearchResults__close\"\n handleClose = () => {\n this.props.onClose();\n };\n\n scrollTop = () => {\n if (this.resultRef) {\n this.resultRef.scrollTop = 0;\n }\n };\n\n handlePaginate = start => {\n this.setState({ start }, this.scrollTop);\n };\n\n handleChange = event => {\n this.setState({ search: event.target.value, start: 0 }, this.scrollTop);\n\n this.props.settings.field.value = event.target.value;\n };\n\n getResults() {\n const { settings } = this.props;\n const { start } = this.state;\n\n const warnings = [];\n let counter = 0;\n let results = [];\n\n if (this.state.search.length < settings.minimumLength) {\n warnings.push(textSearchTooShort);\n warnings.push(\n settings.minimumLength === 1\n ? textSearchOneCharacterOrMore\n : textSearchShouldBeXOrMore.replace(\n \"!min\",\n settings.minimumLength\n )\n );\n\n return { warnings, counter, results, start };\n }\n\n const found = this.props.onSearch(this.state.search);\n\n counter = found.length;\n\n if (counter === 0) {\n warnings.push(textSearchNoResults);\n return { warnings, counter, results, start };\n }\n\n if (settings.showTitleCount) {\n this.props.onTitleChange(`(${counter})`);\n }\n\n results = found.filter(\n (item, itemNumber) =>\n itemNumber >= start && itemNumber < settings.show + start\n );\n\n return { warnings, counter, results, start };\n }\n\n render() {\n const { settings } = this.props;\n const { warnings, counter, results, start } = this.getResults();\n\n return (\n
    \n
    \n (this.resultRef = el)}\n >\n \n \n ×\n \n
    \n {counter === 1\n ? textSearchOneResult\n : textSearchResults.replace(\"!count\", counter)}\n
    \n {warnings.map(warning => (\n
    \n {warning}\n
    \n ))}\n {results.map(result => (\n \n ))}\n {counter > settings.show && (\n \n )}\n
    \n
    \n );\n }\n}\n","import * as preact from \"preact\";\nimport FlexSearch from \"flexsearch\";\n\nimport Search from \"./Search\";\n\n/** @jsx preact.h */\n\nconst originalTitle = document.title;\n\nfunction getURLP(name) {\n const elements = new RegExp(`[?|&]${name}=([^&;]+?)(&|#|;|$)`).exec(\n window.location.search\n );\n\n return (\n decodeURIComponent(\n ((elements && elements[1]) || \"\").replace(/\\+/g, \"%20\")\n ) || null\n );\n}\n\nclass SearchEngine {\n constructor(options) {\n this.settings = {\n field: document.getElementById(\"search_input\"),\n show: 10,\n showURL: true,\n showTitleCount: true,\n minimumLength: 3,\n descriptiveWords: 25,\n highlightTerms: true,\n highlightEveryTerm: false,\n contentLocation: \"daux_search_index.json\",\n ...options\n };\n\n this.searchIndex = {\n pages: []\n };\n }\n\n loadData() {\n if (!this.loadingPromise) {\n this.loadingPromise = fetch(\n this.settings.base_url + this.settings.contentLocation\n )\n .then(data => data.json())\n .then(json => {\n this.searchIndex = new FlexSearch({\n doc: {\n id: \"url\",\n field: [\"title\", \"text\", \"tags\"]\n }\n });\n\n let pages = json.pages;\n\n // Only keep the pages related to the current language\n if (window.searchLanguage) {\n const pagePrefix = `${window.searchLanguage}/`;\n pages = pages.filter(\n item => item.url.indexOf(pagePrefix) === 0\n );\n }\n\n this.searchIndex.add(pages);\n });\n }\n\n return this.loadingPromise;\n }\n\n run() {\n if (getURLP(\"q\")) {\n this.settings.field.value = getURLP(\"q\");\n\n this.loadData().then(() => {\n this.displaySearch();\n });\n }\n\n this.settings.field.addEventListener(\"keyup\", event => {\n // Start loading index once the user types text in the field, not before\n this.loadData();\n\n if (parseInt(event.keyCode, 10) === 13) {\n this.loadData().then(() => {\n this.displaySearch();\n });\n }\n });\n }\n\n keyUpHandler = e => {\n if (e.which === 27) {\n //escape\n this.handleClose();\n }\n };\n\n handleClose = () => {\n document.title = originalTitle;\n\n document.removeEventListener(\"keyup\", this.keyUpHandler);\n\n document.body.classList.remove(\"with-search\");\n preact.render(null, this.resultContainer);\n this.resultContainer = null;\n };\n\n displaySearch() {\n if (!this.resultContainer) {\n this.resultContainer = document.createElement(\"div\");\n document.body.appendChild(this.resultContainer);\n }\n\n document.addEventListener(\"keyup\", this.keyUpHandler);\n\n preact.render(\n this.searchIndex.search(term)}\n onClose={this.handleClose}\n onTitleChange={title => {\n document.title = `${title} ${originalTitle}`;\n }}\n settings={this.settings}\n />,\n this.resultContainer\n );\n\n document.body.classList.add(\"with-search\");\n document.body.scrollTop = 0;\n }\n}\n\n// Main containers\n\nfunction search(options) {\n const instance = new SearchEngine(options);\n instance.run();\n}\n\n// Declare globally\nwindow.search = search;\n"],"names":["n","u","t","i","r","f","e","c","s","l","a","parentNode","removeChild","h","o","arguments","length","push","children","defaultProps","key","ref","v","type","props","__k","__p","__b","__e","__c","constructor","vnode","y","m","this","context","w","indexOf","k","__d","debounceRendering","_","sort","__v","pop","forceUpdate","b","p","d","g","x","$","appendChild","nextSibling","insertBefore","value","D","A","Array","isArray","P","setProperty","test","N","style","cssText","replace","toLowerCase","slice","addEventListener","T","removeEventListener","removeAttributeNS","setAttributeNS","removeAttribute","setAttribute","event","C","contextType","__E","prototype","render","H","sub","state","__n","__h","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","componentWillUpdate","__r","__P","getChildContext","getSnapshotBeforeUpdate","base","call","componentDidUpdate","z","diffed","j","nodeType","localName","document","createTextNode","createElementNS","createElement","data","childNodes","dangerouslySetInnerHTML","__html","innerHTML","checked","current","unmount","componentWillUnmount","I","ownerSVGElement","setState","Promise","then","bind","resolve","setTimeout","getDerivedStateFromError","componentDidCatch","K","R","L","define","amd","modules","module","ma","id","na","init","fa","Object","keys","index","concat","cache","set","F","W","O","ha","page","next","result","where","M","split","oa","pa","defineProperty","get","RegExp","Q","V","ba","splice","G","ca","qa","B","da","X","ea","Y","E","parseInt","J","ra","q","Z","ia","create","sa","self","onmessage","search","content","threshold","limit","postMessage","add","update","remove","clear","info","worker","console","log","register","options","async","Function","substring","lastIndexOf","ta","cursor","suggest","toString","encode","depth","ja","memory","speed","match","score","balance","fast","aa","ka","la","registerMatcher","hasOwnProperty","registerEncoder","U","registerLanguage","filter","stemmer","preset","Worker","tokenize","rtl","resolution","matcher","addMatcher","lang","doc","S","field","tag","store","ua","importScripts","_ctx","query","callback","bool","all","apply","find","items","contextual","destroy","export","serialize","JSON","stringify","import","parse","va","icase","simple","advanced","extra","join","count","Blob","URL","createObjectURL","window","searchTranslation","Link_previous","Link_next","Search_no_results","Search_one_character_or_more","Search_one_result","Search_results","Search_should_be_x_or_more","Search_too_short","textLinkPrevious","textLinkNext","textSearchNoResults","textSearchOneCharacterOrMore","textSearchOneResult","textSearchResults","textSearchShouldBeXOrMore","textSearchTooShort","Pagination","displayedPages","counter","start","settings","onPageSelect","pages","Math","ceil","show","min","preact.h","className","onClick","Result","text","item","descriptiveWords","charAt","href","base_url","url","title","showURL","Search","handleClose","onClose","scrollTop","_this","resultRef","handlePaginate","handleChange","target","preact","warnings","results","minimumLength","found","onSearch","showTitleCount","onTitleChange","itemNumber","getResults","el","_this2","placeholder","autoComplete","autoSave","onInput","map","warning","originalTitle","getURLP","name","elements","exec","location","decodeURIComponent","SearchEngine","keyUpHandler","which","body","classList","resultContainer","getElementById","highlightTerms","highlightEveryTerm","contentLocation","searchIndex","loadingPromise","fetch","json","FlexSearch","searchLanguage","pagePrefix","loadData","_this3","displaySearch","keyCode","term","_this4","run"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"search.min.js.map","sources":["../node_modules/preact/dist/preact.module.js","../node_modules/flexsearch/dist/flexsearch.min.js","../src/js/search/translation.js","../src/js/search/Pagination.js","../src/js/search/Result.js","../src/js/search/Search.js","../src/js/search/index.js"],"sourcesContent":["var n,l,u,i,t,o,r,f,e={},c=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function v(n){var l=n.parentNode;l&&l.removeChild(n)}function h(n,l,u){var i,t=arguments,o={};for(i in l)\"key\"!==i&&\"ref\"!==i&&(o[i]=l[i]);if(arguments.length>3)for(u=[u],i=3;i2&&(l.children=c.slice.call(arguments,2)),u={},l)\"key\"!==i&&\"ref\"!==i&&(u[i]=l[i]);return y(n.type,u,l.key||n.key,l.ref||n.ref,null)}function M(n){var l={},u={__c:\"__cC\"+f++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var i,t=this;return this.getChildContext||(i=[],this.getChildContext=function(){return l[u.__c]=t,l},this.shouldComponentUpdate=function(n){t.props.value!==n.value&&i.some(function(l){l.context=n.value,g(l)})},this.sub=function(n){i.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){i.splice(i.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Consumer.contextType=u,u.Provider.__=u,u}n={__e:function(n,l){for(var u,i;l=l.__;)if((u=l.__c)&&!u.__)try{if(u.constructor&&null!=u.constructor.getDerivedStateFromError&&(i=!0,u.setState(u.constructor.getDerivedStateFromError(n))),null!=u.componentDidCatch&&(i=!0,u.componentDidCatch(n)),i)return g(u.__E=u)}catch(l){n=l}throw n}},l=function(n){return null!=n&&void 0===n.constructor},m.prototype.setState=function(n,l){var u;u=this.__s!==this.state?this.__s:this.__s=s({},this.state),\"function\"==typeof n&&(n=n(u,this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),g(this))},m.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),g(this))},m.prototype.render=d,u=[],i=0,t=\"function\"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,r=e,f=0;export{H as render,I as hydrate,h as createElement,h,d as Fragment,p as createRef,l as isValidElement,m as Component,L as cloneElement,M as createContext,x as toChildArray,D as _unmount,n as options};\n//# sourceMappingURL=preact.module.js.map\n","/*\n FlexSearch v0.6.30\n Copyright 2019 Nextapps GmbH\n Author: Thomas Wilkerling\n Released under the Apache 2.0 Licence\n https://github.com/nextapps-de/flexsearch\n*/\n'use strict';(function(K,R,w){let L;(L=w.define)&&L.amd?L([],function(){return R}):(L=w.modules)?L[K.toLowerCase()]=R:\"object\"===typeof exports?module.exports=R:w[K]=R})(\"FlexSearch\",function ma(K){function w(a,c){const b=c?c.id:a&&a.id;this.id=b||0===b?b:na++;this.init(a,c);fa(this,\"index\",function(){return this.a?Object.keys(this.a.index[this.a.keys[0]].c):Object.keys(this.c)});fa(this,\"length\",function(){return this.index.length})}function L(a,c,b,d){this.u!==this.g&&(this.o=this.o.concat(b),this.u++,\nd&&this.o.length>=d&&(this.u=this.g),this.u===this.g&&(this.cache&&this.j.set(c,this.o),this.F&&this.F(this.o)));return this}function S(a){const c=B();for(const b in a)if(a.hasOwnProperty(b)){const d=a[b];F(d)?c[b]=d.slice(0):G(d)?c[b]=S(d):c[b]=d}return c}function W(a,c){const b=a.length,d=O(c),e=[];for(let f=0,h=0;f=h&&(a=a[g-(e+.5>>0)],a=a[b]||(a[b]=[]),\na[a.length]=d);return e}function ba(a,c){if(a){const b=Object.keys(a);for(let d=0,e=b.length;da?1:a?-1:0}function pa(a,c){a=a[M];c=c[M];return ac?1:0}function oa(a,c){const b=M.length;for(let d=0;dc?1:0}function T(a,c,b){return a?{page:a,next:c?\"\"+c:null,result:b}:b}function ha(a,c,b,d,e,f,h){let g,k=[];if(!0===b){b=\"0\";var l=\"\"}else l=b&&b.split(\":\");const p=a.length;if(1h&&(l=0),l=l||0,g=l+c,g=this.m.length&&(this.C=0),this.m[this.C].postMessage({add:!0,id:a,\ncontent:c}),this.c[f]=\"\"+this.C,b&&b(),this;if(!e){if(this.async&&\"function\"!==typeof importScripts){let t=this;f=new Promise(function(v){setTimeout(function(){t.add(a,c,null,d,!0);t=null;v()})});if(b)f.then(b);else return f;return this}if(b)return this.add(a,c,null,d,!0),b(),this}c=this.encode(c);if(!c.length)return this;b=this.f;e=O(b)?b(c):c.split(this.split);this.filter&&(e=W(e,this.filter));const n=B();n._ctx=B();const m=e.length,u=this.threshold,q=this.depth,A=this.b,z=this.i,y=this.D;for(let t=\n0;tp;x--)l=h.substring(p,x),V(z,n,l,a,v,k,u,A-1)}break;default:if(g=V(z,n,h,a,1,k,u,A-1),q&&1=u)for(g=n._ctx[h]||(n._ctx[h]=B()),h=this.h[h]||(this.h[h]=ia(A-(u||0))),k=t-q,l=t+q+1,0>k&&(k=0),l>\nm&&(l=m);kh;d--)e=g[d-1],g[d]=e,f[e]=d;g[h]=c;f[c]=h}}}return b};return a}();return w}(function(){const K={},R=\"undefined\"!==typeof Blob&&\n\"undefined\"!==typeof URL&&URL.createObjectURL;return function(w,L,S,W,P){S=R?URL.createObjectURL(new Blob([\"(\"+S.toString()+\")()\"],{type:\"text/javascript\"})):w+\".min.js\";w+=\"-\"+L;K[w]||(K[w]=[]);K[w][P]=new Worker(S);K[w][P].onmessage=W;return K[w][P]}}()),this);\n","/* eslint-disable camelcase */\nconst {\n Link_previous,\n Link_next,\n Search_no_results,\n Search_one_character_or_more,\n Search_one_result,\n Search_results,\n Search_should_be_x_or_more,\n Search_too_short\n} = window.searchTranslation;\n\nconst textLinkPrevious = Link_previous;\nconst textLinkNext = Link_next;\nconst textSearchNoResults = Search_no_results;\nconst textSearchOneCharacterOrMore = Search_one_character_or_more;\nconst textSearchOneResult = Search_one_result;\nconst textSearchResults = Search_results;\nconst textSearchShouldBeXOrMore = Search_should_be_x_or_more;\nconst textSearchTooShort = Search_too_short;\n/* eslint-enable camelcase */\n\nexport {\n textLinkPrevious,\n textLinkNext,\n textSearchNoResults,\n textSearchOneCharacterOrMore,\n textSearchOneResult,\n textSearchResults,\n textSearchShouldBeXOrMore,\n textSearchTooShort\n};\n","import * as preact from \"preact\";\nimport { textLinkPrevious, textLinkNext } from \"./translation\";\n/** @jsx preact.h */\n\nexport default function Pagination({ counter, start, settings, onPageSelect }) {\n const pages = Math.ceil(counter / settings.show);\n const page = start / settings.show;\n\n let displayedPages;\n if (page <= 2) {\n // Display max three pages\n displayedPages = Math.min(pages, 3);\n } else {\n // Display two more pages, but don't overflow\n displayedPages = Math.min(pages, page + 2);\n }\n\n const items = [];\n\n for (let f = 0; f < displayedPages; f++) {\n if (f === page) {\n items.push(
  • {f + 1}
  • );\n } else {\n items.push(\n
  • \n onPageSelect(f * settings.show)}\n >\n {f + 1}\n \n
  • \n );\n }\n }\n\n return (\n
    \n
      \n {start > 0 && (\n
    • \n onPageSelect(start - settings.show)}\n >\n {textLinkPrevious}\n \n
    • \n )}\n {items}\n {page + 1 !== pages && (\n
    • \n onPageSelect(start + settings.show)}\n >\n {textLinkNext}\n \n
    • \n )}\n
    \n
    \n );\n}\n","import * as preact from \"preact\";\n/** @jsx preact.h */\n\n// TODO :: restore highlight\n/*function highlightText(search, text) {\n if (settings.highlightTerms) {\n var pattern = new RegExp(\n `(${search})`,\n settings.highlightEveryTerm ? \"gi\" : \"i\"\n );\n text = text.replace(\n pattern,\n '$1'\n );\n }\n\n return text;\n}*/\n\nexport default function Result({ settings, item }) {\n let text;\n if (item.text) {\n text = item.text\n .split(\" \")\n .slice(0, settings.descriptiveWords)\n .join(\" \");\n if (\n item.text.length < text.length &&\n text.charAt(text.length - 1) !== \".\"\n ) {\n text += \" ...\";\n }\n }\n\n return (\n
    \n \n {settings.showURL && (\n \n )}\n {text &&
    {text}
    }\n
    \n );\n}\n","import * as preact from \"preact\";\n\nimport Pagination from \"./Pagination\";\nimport Result from \"./Result\";\nimport {\n textSearchNoResults,\n textSearchOneCharacterOrMore,\n textSearchOneResult,\n textSearchResults,\n textSearchShouldBeXOrMore,\n textSearchTooShort\n} from \"./translation\";\n\n/** @jsx preact.h */\n\nexport default class Search extends preact.Component {\n constructor(props) {\n super(props);\n\n this.state = {\n search: this.props.settings.field.value || \"\",\n start: 0\n };\n }\n\n // \"click\", \".SearchResults__close\"\n handleClose = () => {\n this.props.onClose();\n };\n\n scrollTop = () => {\n if (this.resultRef) {\n this.resultRef.scrollTop = 0;\n }\n };\n\n handlePaginate = start => {\n this.setState({ start }, this.scrollTop);\n };\n\n handleChange = event => {\n this.setState({ search: event.target.value, start: 0 }, this.scrollTop);\n\n this.props.settings.field.value = event.target.value;\n };\n\n getResults() {\n const { settings } = this.props;\n const { start } = this.state;\n\n const warnings = [];\n let counter = 0;\n let results = [];\n\n if (this.state.search.length < settings.minimumLength) {\n warnings.push(textSearchTooShort);\n warnings.push(\n settings.minimumLength === 1\n ? textSearchOneCharacterOrMore\n : textSearchShouldBeXOrMore.replace(\n \"!min\",\n settings.minimumLength\n )\n );\n\n return { warnings, counter, results, start };\n }\n\n const found = this.props.onSearch(this.state.search);\n\n counter = found.length;\n\n if (counter === 0) {\n warnings.push(textSearchNoResults);\n return { warnings, counter, results, start };\n }\n\n if (settings.showTitleCount) {\n this.props.onTitleChange(`(${counter})`);\n }\n\n results = found.filter(\n (item, itemNumber) =>\n itemNumber >= start && itemNumber < settings.show + start\n );\n\n return { warnings, counter, results, start };\n }\n\n render() {\n const { settings } = this.props;\n const { warnings, counter, results, start } = this.getResults();\n\n return (\n
    \n
    \n (this.resultRef = el)}\n >\n \n \n ×\n \n
    \n {counter === 1\n ? textSearchOneResult\n : textSearchResults.replace(\"!count\", counter)}\n
    \n {warnings.map(warning => (\n
    \n {warning}\n
    \n ))}\n {results.map(result => (\n \n ))}\n {counter > settings.show && (\n \n )}\n
    \n
    \n );\n }\n}\n","import * as preact from \"preact\";\nimport FlexSearch from \"flexsearch\";\n\nimport Search from \"./Search\";\n\n/** @jsx preact.h */\n\nconst originalTitle = document.title;\n\nfunction getURLP(name) {\n const elements = new RegExp(`[?|&]${name}=([^&;]+?)(&|#|;|$)`).exec(\n window.location.search\n );\n\n return (\n decodeURIComponent(\n ((elements && elements[1]) || \"\").replace(/\\+/g, \"%20\")\n ) || null\n );\n}\n\nclass SearchEngine {\n constructor(options) {\n this.settings = {\n field: document.getElementById(\"search_input\"),\n form: document.getElementById(\"search_form\"),\n show: 10,\n showURL: true,\n showTitleCount: true,\n minimumLength: 3,\n descriptiveWords: 25,\n highlightTerms: true,\n highlightEveryTerm: false,\n contentLocation: \"daux_search_index.js\",\n ...options\n };\n\n this.searchIndex = {\n pages: []\n };\n }\n\n loadData() {\n if (!this.loadingPromise) {\n // We do this as jsonp instead of an XHR or fetch request\n // to be compatible with usage from filesystem\n const po = document.createElement(\"script\");\n po.type = \"text/javascript\";\n po.async = true;\n po.src = this.settings.base_url + this.settings.contentLocation;\n const s = document.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(po, s);\n\n this.loadingPromise = new Promise(resolve => {\n window.load_search_index = data => resolve(data);\n }).then(json => {\n this.searchIndex = new FlexSearch({\n doc: {\n id: \"url\",\n field: [\"title\", \"text\", \"tags\"]\n }\n });\n\n let pages = json.pages;\n\n // Only keep the pages related to the current language\n if (window.searchLanguage) {\n const pagePrefix = `${window.searchLanguage}/`;\n pages = pages.filter(\n item => item.url.indexOf(pagePrefix) === 0\n );\n }\n\n this.searchIndex.add(pages);\n });\n }\n\n return this.loadingPromise;\n }\n\n run() {\n if (getURLP(\"q\")) {\n this.settings.field.value = getURLP(\"q\");\n\n this.loadData().then(() => {\n this.displaySearch();\n });\n }\n\n this.settings.field.addEventListener(\"keyup\", event => {\n // Start loading index once the user types text in the field, not before\n this.loadData();\n\n if (parseInt(event.keyCode, 10) === 13) {\n this.loadData().then(() => {\n this.displaySearch();\n });\n }\n });\n\n this.settings.form.addEventListener(\"submit\", event => {\n event.preventDefault();\n this.loadData().then(() => {\n this.displaySearch();\n });\n });\n }\n\n keyUpHandler = e => {\n if (e.which === 27) {\n //escape\n this.handleClose();\n }\n };\n\n handleClose = () => {\n document.title = originalTitle;\n\n document.removeEventListener(\"keyup\", this.keyUpHandler);\n\n document.body.classList.remove(\"with-search\");\n preact.render(null, this.resultContainer);\n this.resultContainer = null;\n };\n\n displaySearch() {\n if (!this.resultContainer) {\n this.resultContainer = document.createElement(\"div\");\n document.body.appendChild(this.resultContainer);\n }\n\n document.addEventListener(\"keyup\", this.keyUpHandler);\n\n preact.render(\n this.searchIndex.search(term)}\n onClose={this.handleClose}\n onTitleChange={title => {\n document.title = `${title} ${originalTitle}`;\n }}\n settings={this.settings}\n />,\n this.resultContainer\n );\n\n document.body.classList.add(\"with-search\");\n document.body.scrollTop = 0;\n }\n}\n\n// Main containers\n\nfunction search(options) {\n const instance = new SearchEngine(options);\n instance.run();\n}\n\n// Declare globally\nwindow.search = search;\n"],"names":["n","u","i","t","o","r","e","c","a","s","l","v","parentNode","removeChild","h","arguments","length","push","children","defaultProps","y","key","ref","type","props","__k","__","__b","__e","__d","__c","constructor","__v","vnode","d","m","this","context","w","indexOf","k","base","g","debounceRendering","_","sort","some","f","__P","z","__n","ownerSVGElement","T","b","p","x","A","P","C","Array","isArray","appendChild","nextSibling","insertBefore","value","D","j","setProperty","test","style","cssText","replace","toLowerCase","slice","addEventListener","N","removeEventListener","removeAttributeNS","setAttributeNS","removeAttribute","setAttribute","event","contextType","__E","prototype","render","E","sub","state","__h","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","componentWillUpdate","componentDidUpdate","__r","getChildContext","getSnapshotBeforeUpdate","$","diffed","call","nodeType","localName","document","createTextNode","createElementNS","createElement","is","data","childNodes","dangerouslySetInnerHTML","attributes","name","__html","innerHTML","checked","current","unmount","componentWillUnmount","H","getDerivedStateFromError","setState","componentDidCatch","forceUpdate","Promise","then","bind","resolve","setTimeout","K","R","L","define","amd","modules","module","ma","id","na","init","fa","Object","keys","index","concat","cache","set","F","W","O","ha","page","next","result","where","M","split","oa","pa","defineProperty","get","RegExp","Q","V","ba","splice","G","ca","qa","B","I","da","X","ea","Y","parseInt","J","ra","q","Z","ia","create","sa","self","onmessage","search","content","threshold","limit","postMessage","add","update","remove","clear","info","worker","console","log","register","options","async","Function","substring","lastIndexOf","ta","cursor","suggest","toString","encode","depth","ja","memory","speed","match","score","balance","fast","aa","ka","la","registerMatcher","hasOwnProperty","registerEncoder","U","registerLanguage","filter","stemmer","preset","Worker","tokenize","rtl","resolution","matcher","addMatcher","lang","doc","S","field","tag","store","ua","importScripts","_ctx","query","callback","bool","all","apply","find","items","contextual","destroy","export","serialize","JSON","stringify","import","parse","va","icase","simple","advanced","extra","join","count","Blob","URL","createObjectURL","window","searchTranslation","Link_previous","Link_next","Search_no_results","Search_one_character_or_more","Search_one_result","Search_results","Search_should_be_x_or_more","Search_too_short","textLinkPrevious","textLinkNext","textSearchNoResults","textSearchOneCharacterOrMore","textSearchOneResult","textSearchResults","textSearchShouldBeXOrMore","textSearchTooShort","Pagination","displayedPages","counter","start","settings","onPageSelect","pages","Math","ceil","show","min","preact.h","className","onClick","Result","text","item","descriptiveWords","charAt","href","base_url","url","title","showURL","Search","handleClose","onClose","scrollTop","_this","resultRef","handlePaginate","handleChange","target","warnings","results","minimumLength","found","onSearch","showTitleCount","onTitleChange","itemNumber","getResults","el","_this2","placeholder","autoComplete","autoSave","onInput","map","warning","preact","originalTitle","getURLP","elements","exec","location","decodeURIComponent","SearchEngine","keyUpHandler","which","body","classList","resultContainer","getElementById","form","highlightTerms","highlightEveryTerm","contentLocation","searchIndex","loadingPromise","po","src","getElementsByTagName","load_search_index","json","FlexSearch","searchLanguage","pagePrefix","loadData","_this3","displaySearch","keyCode","preventDefault","term","_this4","run"],"mappings":"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"} \ No newline at end of file diff --git a/docker/docker-compose.7.yml b/docker/docker-compose.7.yml index 65d6149..41153cb 100644 --- a/docker/docker-compose.7.yml +++ b/docker/docker-compose.7.yml @@ -12,7 +12,7 @@ services: - phpserver phpserver: - image: php:7.0-fpm + image: php:7.4-fpm working_dir: /var/www/ volumes: - ../:/var/www/ diff --git a/docs/00_Getting_Started.md b/docs/00_Getting_Started.md index a3dc07b..82c0e89 100644 --- a/docs/00_Getting_Started.md +++ b/docs/00_Getting_Started.md @@ -6,49 +6,48 @@ ### For Authors -* [Auto Generated Navigation / Page sorting](01_Features/Navigation_and_Sorting.md) -* [Internal documentation links](01_Features/Internal_links.md) -* [CommonMark compliant](01_Features/CommonMark_compliant.md) -* [Auto created homepage/landing page](01_Features/Landing_page.md) -* [Multiple Output Formats](01_Features/Multiple_Output_Formats.md) -* [Multiple Languages Support](01_Features/Multilanguage.md) -* [No Build Step](01_Features/Live_mode.md) -* [Static Output Generation](01_Features/Static_Site_Generation.md) -* [Table of Contents](01_Features/Table_of_contents.md) +- [Auto Generated Navigation / Page sorting](01_Features/Navigation_and_Sorting.md) +- [Internal documentation links](01_Features/Internal_links.md) +- [CommonMark compliant](01_Features/CommonMark_compliant.md) +- [Auto created homepage/landing page](01_Features/Landing_page.md) +- [Multiple Output Formats](01_Features/Multiple_Output_Formats.md) +- [Multiple Languages Support](01_Features/Multilanguage.md) +- [No Build Step](01_Features/Live_mode.md) +- [Static Output Generation](01_Features/Static_Site_Generation.md) +- [Table of Contents](01_Features/Table_of_contents.md) ### For Developers -* [Auto Syntax Highlighting](01_Features/Auto_Syntax_Highlight.md) -* [Extend Daux.io with Processors](01_For_Developers/Creating_a_Processor.md) -* Full access to the internal API to create new pages programatically -* Work with pages metadata +- [Auto Syntax Highlighting](01_Features/Auto_Syntax_Highlight.md) +- [Extend Daux.io with Processors](01_For_Developers/Creating_a_Processor.md) +- Full access to the internal API to create new pages programatically +- Work with pages metadata ### For Marketing -* 100% Mobile Responsive -* 4 Built-In Themes or roll your own -* Functional, Flat Design Style -* Optional code float layout -* Shareable/Linkable SEO Friendly URLs -* Supports Google Analytics and Piwik Analytics +- 100% Mobile Responsive +- 4 Built-In Themes or roll your own +- Functional, Flat Design Style +- Optional code float layout +- Shareable/Linkable SEO Friendly URLs +- Supports Google Analytics and Piwik Analytics ## Demos This is a list of sites using Daux.io: -- With a custom theme: - * [Crafty](https://swissquote.github.io/crafty) - * [Pixolution flow](https://docs.pixolution.org) - * [Soisy](https://doc.soisy.it/) - * [Vulkan Tutorial](https://vulkan-tutorial.com) - * [3Q](https://docs.3q.video/) -- With the default Theme - * [Daux.io](https://daux.io/) - * [DoctrineWatcher](https://dsentker.github.io/WatcherDocumentation/) - * [DrupalGap](http://docs.drupalgap.org/8/) - * [ICADMIN: An admin panel powered by CodeIgniter.](http://istocode.com/shared/ic-admin/) - * [Munee: Standalone PHP 5.3 Asset Optimisation & Manipulation](http://mun.ee) - * [Nuntius: A PHP framework for bots](https://roysegall.github.io/nuntius-bot/) +- With a custom theme: + - [Crafty](https://swissquote.github.io/crafty) + - [Pixolution flow](https://docs.pixolution.org) \* [Soisy](https://doc.soisy.it/) + - [Vulkan Tutorial](https://vulkan-tutorial.com) + - [3Q](https://docs.3q.video/) +- With the default Theme + - [Daux.io](https://daux.io/) + _ [DoctrineWatcher](https://dsentker.github.io/WatcherDocumentation/) + _ [DrupalGap](http://docs.drupalgap.org/8/) + - [ICADMIN: An admin panel powered by CodeIgniter.](http://istocode.com/shared/ic-admin/) + - [Munee: Standalone PHP 5.3 Asset Optimisation & Manipulation](http://mun.ee) + - [Nuntius: A PHP framework for bots](https://roysegall.github.io/nuntius-bot/) Do you use Daux.io? Send us a pull request or open an [issue](https://github.com/dauxio/daux.io/issues) and I will add you to the list. @@ -81,10 +80,10 @@ docker run --rm -it -w /build -v "$PWD":/build daux/daux.io daux Any parameter valid in the PHP version is valid in the Docker version - ### Writing pages Creating new pages is very easy: + 1. Create a markdown file (`*.md` or `*.markdown`) 2. Start writing @@ -98,14 +97,14 @@ You must use underscores instead of spaces. Here are some example file names and **Good:** -* 01_Getting_Started.md = Getting Started -* API_Calls.md = API Calls -* 200_Something_Else-Cool.md = Something Else-Cool -* _5_Ways_to_Be_Happy.md = 5 Ways To Be Happy +- 01_Getting_Started.md = Getting Started +- API_Calls.md = API Calls +- 200_Something_Else-Cool.md = Something Else-Cool +- \_5_Ways_to_Be_Happy.md = 5 Ways To Be Happy **Bad:** -* File Name With Space.md = FAIL +- File Name With Space.md = FAIL ### See your pages @@ -129,9 +128,9 @@ Upload your files to an apache / nginx server and see your documentation Daux.io is extendable and comes by default with three export formats: -- Export to HTML, same as the website, but can be hosted without PHP. -- Export all documentation in a single HTML page -- Upload to your Atlassian Confluence server. +- Export to HTML, same as the website, but can be hosted without PHP. +- Export all documentation in a single HTML page +- Upload to your Atlassian Confluence server. [See a detailed feature comparison matrix](01_Features/Multiple_Output_Formats.md) @@ -145,20 +144,13 @@ Now that you got the basics, you can also [see what you can configure](05_Config ## PHP Requirements -Daux.io is compatible with PHP 7.1.3 and up. - -The reason is because some dependencies we have (mainly Symfony and Guzzle) do not support PHP 5.6 anymore. +Daux.io is compatible with the [officially supported](https://www.php.net/supported-versions.php) PHP versions; 7.2.0 and up. ### Extensions -PHP Needs the following extension to work : `php-mbstring` and `php-xml`. - -If you encounter an error similar to `utf8_decode() not found` this means that you're missing the `php-xml` package. (We've seen it happen only on PHP 7) - -## Known Issues - -- __Windows UTF-8 files support__ Files with UTF-8 characters cannot be handled on windows with PHP5, PHP7 should work fine. +Daux.io needs the following PHP extensions to work : `php-mbstring` and `php-xml`. +If you encounter an error similar to `utf8_decode() not found` this means that you're missing the `php-xml` package. ## Support diff --git a/docs/01_Features/CommonMark_compliant.md b/docs/01_Features/CommonMark_compliant.md index 228efa7..9075e95 100644 --- a/docs/01_Features/CommonMark_compliant.md +++ b/docs/01_Features/CommonMark_compliant.md @@ -1,17 +1,14 @@ - As we support CommonMark, a broad range of markdown features is available to you. Many of the features shown below were known as Github Flavored Markdown. - -We all like making lists ------------------------- +## We all like making lists The above header should be an H2 tag. Now, for a list of fruits: -* Red Apples -* Purple Grapes -* Green Kiwifruits +- Red Apples +- Purple Grapes +- Green Kiwifruits Let's get crazy: @@ -27,18 +24,17 @@ Let's get crazy: What about some code **in** a list? That's insane, right? -1. In Ruby you can map like this: +1. In Ruby you can map like this: ['a', 'b'].map { |x| x.uppercase } -2. In Rails, you can do a shortcut: +2. In Rails, you can do a shortcut: ['a', 'b'].map(&:uppercase) Some people seem to like definition lists -I am a robot ------------- +## I am a robot Maybe you want to print `robot` to the console 1000 times. Why not? @@ -54,8 +50,7 @@ How about we throw some angle braces and ampersands in there? © 2004 Foo Corporation -Set in stone ------------- +## Set in stone Preformatted blocks are useful for ASCII art: @@ -73,8 +68,7 @@ Preformatted blocks are useful for ASCII art: ___|_____________ -Playing the blame game ----------------------- +## Playing the blame game If you need to blame someone, the best way to do so is by quoting them: @@ -92,26 +86,23 @@ Or perhaps someone a little less eloquent: > just put me under the spot here, and maybe I'm not as quick on my feet > as I should be in coming up with one. -Table for two -------------- +## Table for two -ID | Name | Rank ----|:------:|------: -1 | Tom Preston-Werner | Awesome -2 | Albert Einstein | Nearly as awesome +| ID | Name | Rank | +| --- | :----------------: | ----------------: | +| 1 | Tom Preston-Werner | Awesome | +| 2 | Albert Einstein | Nearly as awesome | -Crazy linking action --------------------- +## Crazy linking action -I get 10 times more traffic from [Google] [1] than from -[Yahoo] [2] or [MSN] [3]. +I get 10 times more traffic from [Google][1] than from +[Yahoo][2] or [MSN][3]. - [1]: http://google.com/ "Google" - [2]: http://search.yahoo.com/ "Yahoo Search" - [3]: http://search.msn.com/ "MSN Search" +[1]: http://google.com/ "Google" +[2]: http://search.yahoo.com/ "Yahoo Search" +[3]: http://search.msn.com/ "MSN Search" -Images ------- +## Images Here's an image. @@ -119,4 +110,4 @@ Here's an image. Note: to use images on a landing page (index.md), prefix the image URL with the name of the directory it appears in, omitting the numerical prefix used to order the sections. For example in this section, to display this image on the landing page (index.md), the URL for the image would be "Features/sampleimage.png" to display the same image. -*View the [source of this content](https://github.com/dauxio/daux.io/blob/master/docs/01_Features/CommonMark_compliant.md).* +_View the [source of this content](https://github.com/dauxio/daux.io/blob/master/docs/01_Features/CommonMark_compliant.md)._ diff --git a/docs/01_Features/Edit_on_GitHub_links.md b/docs/01_Features/Edit_on_GitHub_links.md index de229ab..76af370 100644 --- a/docs/01_Features/Edit_on_GitHub_links.md +++ b/docs/01_Features/Edit_on_GitHub_links.md @@ -1,4 +1,3 @@ - As you can see on the top of this page, you can add "Edit on Github" links to your pages, this feature can be enabled with a single parameter. The value has to be the path to the root of your documentation folder in your repository. @@ -7,12 +6,11 @@ In the value you see below, Daux's documentation is in the `docs` folder in the Daux.io will handle the rest - ```json { - "html": { - "edit_on_github": "dauxio/daux.io/blob/master/docs" - } + "html": { + "edit_on_github": "dauxio/daux.io/blob/master/docs" + } } ``` @@ -22,14 +20,13 @@ While GitHub is the most popular, it isn't the only, collaborative VCS out there As long as you can refer your files by a URL, you can create an edit link for your VCS with the following configuration: - ```json { - "html": { - "edit_on": { - "name": "Bitbucket", - "basepath": "https://bitbucket.org/dauxio/daux.io/src/master/docs" + "html": { + "edit_on": { + "name": "Bitbucket", + "basepath": "https://bitbucket.org/dauxio/daux.io/src/master/docs" + } } - } } ``` diff --git a/docs/01_Features/Landing_page.md b/docs/01_Features/Landing_page.md index ae73dc8..ba37806 100644 --- a/docs/01_Features/Landing_page.md +++ b/docs/01_Features/Landing_page.md @@ -2,9 +2,9 @@ If you want to create a beautiful landing page for your project, create a `_inde ```json { - "title": "Daux.io", - "tagline": "The Easiest Way To Document Your Project", - "image": "app.png" + "title": "Daux.io", + "tagline": "The Easiest Way To Document Your Project", + "image": "app.png" } ``` @@ -14,8 +14,8 @@ To disable the automatic landing page, you can set `auto_landing` to false in th ```json { - "html": { - "auto_landing": false - } + "html": { + "auto_landing": false + } } ``` diff --git a/docs/01_Features/Live_mode.md b/docs/01_Features/Live_mode.md index 343f044..b095426 100644 --- a/docs/01_Features/Live_mode.md +++ b/docs/01_Features/Live_mode.md @@ -10,7 +10,6 @@ The easiest is to use PHP's built-in server. For that i've included a short command, run `daux serve` in the projects folder to start the local web server. By default the server will run at: http://localhost:8085 - ## Running Remotely ### Clean URLs configuration @@ -20,15 +19,15 @@ To enable the same, set the toggle in the `config.json` file in the `/docs` fold ```json { - "live": { - "clean_urls": true - } + "live": { + "clean_urls": true + } } ``` ### Apache -Copy the files from the repo to a web server that can run PHP 5.6 or greater. +Copy the files from the repo to a web server that can run PHP 7.2.0 or newer. There is an included `.htaccess` for Apache web server. @@ -70,8 +69,8 @@ server { If you have set up a local or remote IIS web site, you may need a `web.config` with: -* A rewrite configuration, for handling clean urls. -* A mime type handler for less files, if using a custom theme. +- A rewrite configuration, for handling clean urls. +- A mime type handler for less files, if using a custom theme. ### Clean URLs @@ -79,20 +78,32 @@ The `web.config` needs an entry for `` under ``: ```xml - - - - - - - - - - - - - - + + + + + + + + + + + + + + ``` @@ -114,4 +125,4 @@ ENTRYPOINT [ "php", "-S", "0.0.0.0:80", "index.php" ] When you add this to a `Dockerfile` and run `docker build --name my-daux-doc .` and then `docker --rm run -p 8000:80 my-daux-doc` -You can access your documentation at `localhost:8000` \ No newline at end of file +You can access your documentation at `localhost:8000` diff --git a/docs/01_Features/Multilanguage.md b/docs/01_Features/Multilanguage.md index 4017c14..e409299 100644 --- a/docs/01_Features/Multilanguage.md +++ b/docs/01_Features/Multilanguage.md @@ -4,11 +4,12 @@ Add this to your config.json : ```json { - "languages": { "en": "English", "de": "German" } + "languages": { "en": "English", "de": "German" } } ``` You will the need separate directories for each language in `docs/` folder. + ``` ├── docs/ │ ├── _index.md diff --git a/docs/01_Features/Multiple_Output_Formats.md b/docs/01_Features/Multiple_Output_Formats.md index 5835ddf..c684c39 100644 --- a/docs/01_Features/Multiple_Output_Formats.md +++ b/docs/01_Features/Multiple_Output_Formats.md @@ -1,21 +1,21 @@ Daux.io is extendable and comes by default with three export formats: -- Export to HTML -- Export all documentation in a single HTML page -- Upload to your Atlassian Confluence server +- Export to HTML +- Export all documentation in a single HTML page +- Upload to your Atlassian Confluence server ## Feature Matrix -Feature | HTML | Single Page HTML | Confluence ---------------:|:----:|:----------------:|:----------: -Multilanguage | √ | X (Planned) | X -Landing Pages | √ | X | X -Index Pages | √ | √ | √ -Internal Links | √ | X (Planned) | √ -Code Highlight | √ | X (Planned) | √ (Using macros) -Live Mode | √ | X | X -Pages Ordering | √ | √ | X (API Limitation) -Google / Piwik analytics | √ | √ | √ (Configured on Conflence) +| Feature | HTML | Single Page HTML | Confluence | +| -----------------------: | :--: | :--------------: | :-------------------------: | +| Multilanguage | √ | X (Planned) | X | +| Landing Pages | √ | X | X | +| Index Pages | √ | √ | √ | +| Internal Links | √ | X (Planned) | √ | +| Code Highlight | √ | X (Planned) | √ (Using macros) | +| Live Mode | √ | X | X | +| Pages Ordering | √ | √ | X (API Limitation) | +| Google / Piwik analytics | √ | √ | √ (Configured on Conflence) | ## Confluence Example diff --git a/docs/01_Features/Navigation_and_Sorting.md b/docs/01_Features/Navigation_and_Sorting.md index 63b0a69..b1f4366 100644 --- a/docs/01_Features/Navigation_and_Sorting.md +++ b/docs/01_Features/Navigation_and_Sorting.md @@ -1,4 +1,3 @@ - ## Navigation The navigation is generated automatically with all pages that end with `.md` or `.markdown` @@ -12,21 +11,21 @@ For example, `/docs/02_Examples` has a landing page for that section since there ## Sorting To sort your files and folders in a specific way, you can prefix them with a number and underscore, e.g. `/docs/01_Hello_World.md` and `/docs/05_Features.md`. -This will list *Hello World* before *Features*, overriding the default alpha-numeric sorting. +This will list _Hello World_ before _Features_, overriding the default alpha-numeric sorting. The numbers will be stripped out of the navigation and urls. For the file `6 Ways to Get Rich`, you can use `/docs/_6_Ways_to_Get_Rich.md` You might also wish to stick certain links to the bottom of a page. -You can do so by prefixing the file name with a '-', e.g. a new file `/docs/-Contact_Us.md` will always appear at the bottom of the current list. +You can do so by prefixing the file name with a '-', e.g. a new file `/docs/-Contact_Us.md` will always appear at the bottom of the current list. Weights can also be added to further sort the bottom entries. e.g. `/docs/-01_Coming.md` will appear before `/docs/-02_Soon.md` but both will only appear after all positive or non-weighted files. It works the same for files prefixed with `+`. Page order priorities are like this: -- `+` in front of the filename and numbers in front -- `+` in front of the filename -- The index page -- Numbers in the front -- Pages without prefix -- `-` in front of the filename and numbers in front -- `-` in front of the filename +- `+` in front of the filename and numbers in front +- `+` in front of the filename +- The index page +- Numbers in the front +- Pages without prefix +- `-` in front of the filename and numbers in front +- `-` in front of the filename diff --git a/docs/01_Features/Search.md b/docs/01_Features/Search.md index c264fa1..27428af 100644 --- a/docs/01_Features/Search.md +++ b/docs/01_Features/Search.md @@ -6,8 +6,8 @@ To enable the generated search, you can set `search` to true in the `html` secti ```json { - "html": { - "search": true - } + "html": { + "search": true + } } ``` diff --git a/docs/01_Features/Static_Site_Generation.md b/docs/01_Features/Static_Site_Generation.md index dc1e3e4..e1a3c56 100644 --- a/docs/01_Features/Static_Site_Generation.md +++ b/docs/01_Features/Static_Site_Generation.md @@ -1,9 +1,8 @@ +If you don't want to serve the live version of your site, you can also generate files, these can be one of the three supported formats : -If you don't want to serve the live version of your site, you can also generate files, these can be one of the three supported formats : - -- HTML output -- Single page HTML output -- Atlassian Confluence upload +- HTML output +- Single page HTML output +- Atlassian Confluence upload Generating a complete set of pages, with navigation @@ -13,7 +12,7 @@ daux --destination=[Output Directory Relative Direction] ## Options -For more options, run +For more options, run ```bash daux generate --help @@ -32,7 +31,7 @@ daux --format=html ### Specify a processor -A processor can be specified through the `--processor` option, this should be the name of a class inside the `Todaymade\Daux\Extension` namespace. +A processor can be specified through the `--processor` option, this should be the name of a class inside the `Todaymade\Daux\Extension` namespace. By running : diff --git a/docs/01_Features/Table_of_contents.md b/docs/01_Features/Table_of_contents.md index c9c6a8c..fbaceb4 100644 --- a/docs/01_Features/Table_of_contents.md +++ b/docs/01_Features/Table_of_contents.md @@ -18,10 +18,8 @@ You can enable this feature in your configuration ```json { - "html": { - "auto_toc": true - } + "html": { + "auto_toc": true + } } ``` - - diff --git a/docs/02_Examples/05_Code_Highlighting.md b/docs/02_Examples/05_Code_Highlighting.md index 0d0807b..3c96a77 100644 --- a/docs/02_Examples/05_Code_Highlighting.md +++ b/docs/02_Examples/05_Code_Highlighting.md @@ -7,8 +7,9 @@ Highlight.js is a powerful but heavy library, since we don't know which language The good news is; if you use a fenced code block (` ``` `) with the language defined, the rendering is done on server side and entirely skips loading Highlight.js on the page. While still having the same end-result on your code. +[TOC] -**Python** +## Python ```python @requires_authorization @@ -24,2077 +25,2072 @@ class SomeClass:
    pass ... prompt''' ``` -**Python's profiler output** - - 261917242 function calls in 686.251 CPU seconds - - ncalls tottime filename:lineno(function) - 152824 513.894 {method 'sort' of 'list' objects} - 129590630 83.894 rrule.py:842(__cmp__) - 129590630 82.439 {cmp} - 153900 1.296 rrule.py:399(_iter) - 304393/151570 0.963 rrule.py:102(_iter_cached) - - -**Ruby** - - class A < B; def self.create(object = User) object end end - class Zebra; def inspect; "X#{2 + self.object_id}" end end - - module ABC::DEF - include Comparable - - # @param test - # @return [String] nothing - def foo(test) - Thread.new do |blockvar| - ABC::DEF.reverse(:a_symbol, :'a symbol', :<=>, 'test' + test) - end.join - end - - def [](index) self[index] end - def ==(other) other == self end - end - - anIdentifier = an_identifier - Constant = 1 - render action: :new - -**Haml** - - !!! XML - %html - %body - %h1.jumbo{:id=>"a", :style=>'font-weight: normal', :title=>title} highlight.js - /html comment - -# ignore this line - %ul(style='margin: 0') - -items.each do |i| - %i= i - = variable - =variable2 - ~ variable3 - ~variable4 - The current year is #{DataTime.now.year}. - -**Perl** - - # loads object - sub load - { - my $flds = $c->db_load($id,@_) || do { - Carp::carp "Can`t load (class: $c, id: $id): '$!'"; return undef - }; - my $o = $c->_perl_new(); - $id12 = $id / 24 / 3600; - $o->{'ID'} = $id12 + 123; - #$o->{'SHCUT'} = $flds->{'SHCUT'}; - my $p = $o->props; - my $vt; - $string =~ m/^sought_text$/; - $items = split //, 'abc'; - for my $key (keys %$p) - { - if(${$vt.'::property'}) { - $o->{$key . '_real'} = $flds->{$key}; - tie $o->{$key}, 'CMSBuilder::Property', $o, $key; - } - } - $o->save if delete $o->{'_save_after_load'}; - return $o; - } - - =head1 NAME - POD till the end of file - -**PHP** - - require_once 'Zend/Uri/Http.php'; - - abstract class URI extends BaseURI - { - - /** - * Returns a URI - * - * @return URI - */ - static public function _factory($stats = array(), $uri = 'http') - { - $uri = explode(':', $uri, 0b10); - $schemeSpecific = isset($uri[1]) ? $uri[1] : ''; - $desc = 'Multi - line description'; - - // Security check - if (!ctype_alnum($scheme)) { - throw new Zend_Uri_Exception('Illegal scheme'); - } - - return [ - 'uri' => $uri, - 'value' => null, - ]; - } - } - - __halt_compiler () ; datahere - datahere - datahere */ - datahere - -**Scala** - - object abstractTypes extends Application { - abstract class SeqBuffer { - type T; val element: Seq[T]; def length = element.length - } - } - - /** Turn command line arguments to uppercase */ - object Main { - def main(args: Array[String]) { - val res = for (a <- args) yield a.toUpperCase - println("Arguments: " + res.toString) - } - } - - /** Maps are easy to use in Scala. */ - object Maps { - val colors = Map("red" -> 0xFF0000, - "turquoise" -> 0x00FFFF, - "black" -> 0x000000, - "orange" -> 0xFF8040, - "brown" -> 0x804000) - def main(args: Array[String]) { - for (name <- args) println( - colors.get(name) match { - case Some(code) => - name + " has code: " + code - case None => - "Unknown color: " + name - } - ) - } - } - -**Go** - - package main - - import ( - "fmt" - "rand" - "os" - ) - - const ( - Sunday = iota - Partyday - numberOfDays // this constant is not exported - ) - - type Foo interface { - FooFunc(int, float32) (complex128, []int) - } - - // simple comment - type Bar struct { - os.File /* multi - line - comment */ - - PublicData chan int - } - - func main() { - ch := make(chan int) - ch <- 1 - x, ok := <- ch - ok = true - x = nil - float_var := 1.0e10 - defer fmt.Println('\'') - defer fmt.Println(`exitting now\`) - var fv1 float64 = 0.75 - go println(len("hello world!")) - return - } - -**XML** - - - - Ok - - magical. - ]]> - - - - -**HTML (with inline css and javascript)** - - - Title - - - - - - -

    Title

    - - - -**Lasso** - - 10 - ORDER BY `Name` LIMIT 30'); - Inline: -Username=$DBuser, -Password=$DBpass, -Database=$DBname, -sql=#query; - var("class.name" = (found_count != 0 ? `subtotal` | `nonefound`)); - records; - output: ?>[loop_count]
    [found_count]
    - [noprocess] causes [delimiters] to be skipped until the next [/noprocess] - { - local(result = #value->append(#other->asString)) - return #result - } - /**! descriptive text */ - define person => type { - data name::string, protected nickname - data birthdate::date - data private ssn = null - public showName() => return .'name' - protected fullName() => '"' + .nickname + '"' + .'name' - public ssnListed => .ssn ? true | false - } - define person->name=(value) => { - .'name' = #value - return self->'name' - } - // query expression - with n in array(-1, 0xABCD, 3.14159e14) - let swapped = pair(#n->second, #n->first) - group #swapped by #n->first into t - let key = #t->key - order by #key - select pair(#key, #t) - do {^ - #n->upperCase - ^} - ?> - -**Markdown** - - # hello world - - you can write text [with links](http://example.com). - - * one _thing_ has *em*phasis - * two __things__ are **bold** +## Python's profiler output + + 261917242 function calls in 686.251 CPU seconds + + ncalls tottime filename:lineno(function) + 152824 513.894 {method 'sort' of 'list' objects} + 129590630 83.894 rrule.py:842(__cmp__) + 129590630 82.439 {cmp} + 153900 1.296 rrule.py:399(_iter) + 304393/151570 0.963 rrule.py:102(_iter_cached) + +## Ruby + + class A < B; def self.create(object = User) object end end + class Zebra; def inspect; "X#{2 + self.object_id}" end end + + module ABC::DEF + include Comparable + + # @param test + # @return [String] nothing + def foo(test) + Thread.new do |blockvar| + ABC::DEF.reverse(:a_symbol, :'a symbol', :<=>, 'test' + test) + end.join + end + + def [](index) self[index] end + def ==(other) other == self end + end + + anIdentifier = an_identifier + Constant = 1 + render action: :new + +## Haml + + !!! XML + %html + %body + %h1.jumbo{:id=>"a", :style=>'font-weight: normal', :title=>title} highlight.js + /html comment + -# ignore this line + %ul(style='margin: 0') + -items.each do |i| + %i= i + = variable + =variable2 + ~ variable3 + ~variable4 + The current year is #{DataTime.now.year}. + +## Perl + + # loads object + sub load + { + my $flds = $c->db_load($id,@_) || do { + Carp::carp "Can`t load (class: $c, id: $id): '$!'"; return undef + }; + my $o = $c->_perl_new(); + $id12 = $id / 24 / 3600; + $o->{'ID'} = $id12 + 123; + #$o->{'SHCUT'} = $flds->{'SHCUT'}; + my $p = $o->props; + my $vt; + $string =~ m/^sought_text$/; + $items = split //, 'abc'; + for my $key (keys %$p) + { + if(${$vt.'::property'}) { + $o->{$key . '_real'} = $flds->{$key}; + tie $o->{$key}, 'CMSBuilder::Property', $o, $key; + } + } + $o->save if delete $o->{'_save_after_load'}; + return $o; + } + + =head1 NAME + POD till the end of file + +## PHP + + require_once 'Zend/Uri/Http.php'; + + abstract class URI extends BaseURI + { + + /** + * Returns a URI + * + * @return URI + */ + static public function _factory($stats = array(), $uri = 'http') + { + $uri = explode(':', $uri, 0b10); + $schemeSpecific = isset($uri[1]) ? $uri[1] : ''; + $desc = 'Multi + line description'; + + // Security check + if (!ctype_alnum($scheme)) { + throw new Zend_Uri_Exception('Illegal scheme'); + } + + return [ + 'uri' => $uri, + 'value' => null, + ]; + } + } + + __halt_compiler () ; datahere + datahere + datahere */ + datahere + +## Scala + + object abstractTypes extends Application { + abstract class SeqBuffer { + type T; val element: Seq[T]; def length = element.length + } + } + + /** Turn command line arguments to uppercase */ + object Main { + def main(args: Array[String]) { + val res = for (a <- args) yield a.toUpperCase + println("Arguments: " + res.toString) + } + } + + /** Maps are easy to use in Scala. */ + object Maps { + val colors = Map("red" -> 0xFF0000, + "turquoise" -> 0x00FFFF, + "black" -> 0x000000, + "orange" -> 0xFF8040, + "brown" -> 0x804000) + def main(args: Array[String]) { + for (name <- args) println( + colors.get(name) match { + case Some(code) => + name + " has code: " + code + case None => + "Unknown color: " + name + } + ) + } + } + +## Go + + package main + + import ( + "fmt" + "rand" + "os" + ) + + const ( + Sunday = iota + Partyday + numberOfDays // this constant is not exported + ) + + type Foo interface { + FooFunc(int, float32) (complex128, []int) + } + + // simple comment + type Bar struct { + os.File /* multi + line + comment */ + + PublicData chan int + } + + func main() { + ch := make(chan int) + ch <- 1 + x, ok := <- ch + ok = true + x = nil + float_var := 1.0e10 + defer fmt.Println('\'') + defer fmt.Println(`exitting now\`) + var fv1 float64 = 0.75 + go println(len("hello world!")) + return + } + +## XML + + + + Ok + + magical. + ]]> +
    + + +## HTML (with inline css and javascript) + + + Title + + + + + + +

    Title

    + + + +## Lasso + + 10 + ORDER BY `Name` LIMIT 30'); + Inline: -Username=$DBuser, -Password=$DBpass, -Database=$DBname, -sql=#query; + var("class.name" = (found_count != 0 ? `subtotal` | `nonefound`)); + records; + output: ?>[loop_count]
    [found_count]
    + [noprocess] causes [delimiters] to be skipped until the next [/noprocess] + { + local(result = #value->append(#other->asString)) + return #result + } + /**! descriptive text */ + define person => type { + data name::string, protected nickname + data birthdate::date + data private ssn = null + public showName() => return .'name' + protected fullName() => '"' + .nickname + '"' + .'name' + public ssnListed => .ssn ? true | false + } + define person->name=(value) => { + .'name' = #value + return self->'name' + } + // query expression + with n in array(-1, 0xABCD, 3.14159e14) + let swapped = pair(#n->second, #n->first) + group #swapped by #n->first into t + let key = #t->key + order by #key + select pair(#key, #t) + do {^ + #n->upperCase + ^} + ?> + +## Markdown + + # hello world + + you can write text [with links](http://example.com). + + * one _thing_ has *em*phasis + * two __things__ are **bold** + + --- + + hello world + =========== + + + + > markdown is so cool - --- + so are code segments - hello world - =========== + 1. one thing (yeah!) + 2. two thing `i can write code`, and `more` wipee! - +## AsciiDoc - > markdown is so cool + Hello, World! + ============ + Author Name, - so are code segments + you can write text http://example.com[with links], optionally + using an explicit link:http://example.com[link prefix]. - 1. one thing (yeah!) - 2. two thing `i can write code`, and `more` wipee! + * single quotes around a phrase place 'emphasis' + ** alternatively, you can put underlines around a phrase to add _emphasis_ + * astericks around a phrase make the text *bold* + * pluses around a phrase make it +monospaced+ -**AsciiDoc** + - escape characters are supported + - you can escape a quote inside emphasized text like 'here\'s johnny!' - Hello, World! - ============ - Author Name, + term:: definition + another term:: another definition - you can write text http://example.com[with links], optionally - using an explicit link:http://example.com[link prefix]. + // this is just a comment + + Let's make a break. + + ''' - * single quotes around a phrase place 'emphasis' - ** alternatively, you can put underlines around a phrase to add _emphasis_ - * astericks around a phrase make the text *bold* - * pluses around a phrase make it +monospaced+ + //// + we'll be right with you - - escape characters are supported - - you can escape a quote inside emphasized text like 'here\'s johnny!' + after this brief interruption. + //// - term:: definition - another term:: another definition + == We're back! - // this is just a comment - - Let's make a break. - - ''' + Want to see a image::images/tiger.png[Tiger]? - //// - we'll be right with you + .Nested highlighting + ++++ + + ++++ - after this brief interruption. - //// + ____ + asciidoc is so powerful. + ____ - == We're back! + another quote: - Want to see a image::images/tiger.png[Tiger]? + [quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes] + ____ + When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth. + ____ - .Nested highlighting - ++++ - - ++++ + Getting Literal + --------------- - ____ - asciidoc is so powerful. - ____ + want to get literal? prefix a line with a space. - another quote: + .... + I'll join that party, too. + .... - [quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes] - ____ - When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth. - ____ + . one thing (yeah!) + . two thing `i can write code`, and `more` wipee! - Getting Literal - --------------- + NOTE: AsciiDoc is quite cool, you should try it. - want to get literal? prefix a line with a space. +## Django templates - .... - I'll join that party, too. - .... + {% if articles|length %} + {% for article in articles %} - . one thing (yeah!) - . two thing `i can write code`, and `more` wipee! + {# Striped table #} + + {{ article|default:"Hi... "|escape }} + {{ article.date|date:"d.m.Y" }} + - NOTE: AsciiDoc is quite cool, you should try it. + {% endfor %} + {% endif %} -**Django templates** + {% comment %} + Comments may be long and + multiline. + {% endcomment %} - {% if articles|length %} - {% for article in articles %} +## Handlebars - {# Striped table #} - - {{ article|default:"Hi... "|escape }} - {{ article.date|date:"d.m.Y" }} - +

    Hours

    - {% endfor %} - {% endif %} +
      + {{#each content.users}} +
    • {{firstName}}
    • + {{/each}} +
    - {% comment %} - Comments may be long and - multiline. - {% endcomment %} +## CSS + + @media screen and (-webkit-min-device-pixel-ratio: 0) { + body:first-of-type pre::after { + content: 'highlight: ' attr(class); + } + body { + background: linear-gradient(45deg, blue, red); + } + } + + @import url('print.css'); + @page:right { + margin: 1cm 2cm 1.3cm 4cm; + } + + @font-face { + font-family: Chunkfive; src: url('Chunkfive.otf'); + } + + div.text, + #content, + li[lang=ru] { + font: Tahoma, Chunkfive, sans-serif; + background: url('hatch.png') /* wtf? */; color: #F0F0F0 !important; + width: 100%; + } + +## SCSS + + @import "compass/reset"; + + // variables + $colorGreen: #008000; + $colorGreenDark: darken($colorGreen, 10); + + @mixin container { + max-width: 980px; + } + + // mixins with parameters + @mixin button($color:green) { + @if ($color == green) { + background-color: #008000; + } + @else if ($color == red) { + background-color: #B22222; + } + } + + button { + @include button(red); + } + + div, + .navbar, + #header, + input[type="input"] { + font-family: "Helvetica Neue", Arial, sans-serif; + width: auto; + margin: 0 auto; + display: block; + } + + .row-12 > [class*="spans"] { + border-left: 1px solid #B5C583; + } + + // nested definitions + ul { + width: 100%; + padding: { + left: 5px; right: 5px; + } + li { + float: left; margin-right: 10px; + .home { + background: url('http://placehold.it/20') scroll no-repeat 0 0; + } + } + } + + .banner { + @extend .container; + } + + a { + color: $colorGreen; + &:hover { color: $colorGreenDark; } + &:visited { color: #c458cb; } + } + + @for $i from 1 through 5 { + .span#{$i} { + width: 20px*$i; + } + } + + @mixin mobile { + @media screen and (max-width : 600px) { + @content; + } + } + +## JSON + + [ + { + "title": "apples", + "count": [12000, 20000], + "description": {"text": "...", "sensitive": false} + }, + { + "title": "oranges", + "count": [17500, null], + "description": {"text": "...", "sensitive": false} + } + ] + +## JavaScript + + function $initHighlight(block, flags) { + try { + if (block.className.search(/\bno\-highlight\b/) != -1) + return processBlock(block, true, 0x0F) + ' class=""'; + } catch (e) { + /* handle exception */ + + var e4x = +
    Example +

    1234

    ; + } + for (var i = 0 / 2; i < classes.length; i++) { // "0 / 2" should not be parsed as regexp + if (checkCondition(classes[i]) === undefined) + return /\d+[\s/]/g; + } + } + +## CoffeeScript + + # Divisions + x = 6/foo/i + x = 6 /foo + x = 6 / foo + x = 6 /foo * 2/gm + x = f /foo + x = f / foo / gm + x = f /foo * 2/6 + + # Regexps + x = f /6 * 2/ - 3 + x = f /foo * 2/gm + x = if true then /\n/ else /[.,]+/ + + grade = (student, period=(if b? then 7 else 6), messages={"A": "Excellent"}) -> + if student.excellentWork + "A+" + else if student.okayStuff + if student.triedHard then "B" else "B-" + else + "C" + + square = (x) -> x * x + + two = -> 2 + + math = + root: Math.sqrt + square: square + cube: (x) -> x * square x + + race = (winner, runners...) -> + print winner, runners + + class Animal extends Being + constructor: (@name) -> + + move: (meters) -> + alert @name + " moved #{meters}m." + + hi = `function() { + return [document.title, "Hello JavaScript"].join(": "); + }` + + heredoc = """ + CoffeeScript subst test #{ 010 + 0xf / 0b10 + "nested string #{ /\n/ }"} + """ + + ### + CoffeeScript Compiler v1.2.0 + Released under the MIT License + ### + + OPERATOR = /// ^ ( + ?: [-=]> # function + ) /// + +## ActionScript + + package org.example.dummy { + import org.dummy.*; + + /*define package inline interface*/ + public interface IFooBarzable { + public function foo(... pairs):Array; + } + + public class FooBar implements IFooBarzable { + static private var cnt:uint = 0; + private var bar:String; + + //constructor + public function TestBar(bar:String):void { + bar = bar; + ++cnt; + } + + public function foo(... pairs):Array { + pairs.push(bar); + return pairs; + } + } + } + +## VB.NET + + Import System + Import System.IO + #Const DEBUG = True + + Namespace Highlighter.Test + ''' This is an example class. + Public Class Program + Protected Shared hello As Integer = 3 + Private Const ABC As Boolean = False + + #Region "Code" + ' Cheers! + _ + Public Shared Sub Main(ByVal args() As String, ParamArray arr As Object) Handles Form1.Click + On Error Resume Next + If ABC Then + While ABC : Console.WriteLine() : End While + For i As Long = 0 To 1000 Step 123 + Try + System.Windows.Forms.MessageBox.Show(CInt("1").ToString()) + Catch ex As Exception ' What are you doing? Well... + Dim exp = CType(ex, IOException) + REM ORZ + Return + End Try + Next + Else + Dim l As New System.Collections.List() + SyncLock l + If TypeOf l Is Decimal And l IsNot Nothing Then + RemoveHandler button1.Paint, delegate + End If + Dim d = New System.Threading.Thread(AddressOf ThreadProc) + Dim a = New Action(Sub(x, y) x + y) + Static u = From x As String In l Select x.Substring(2, 4) Where x.Length > 0 + End SyncLock + Do : Laugh() : Loop Until hello = 4 + End If + End Sub + #End Region + End Class + End Namespace + +## HTTP + + POST /task?id=1 HTTP/1.1 + Host: example.org + Content-Type: application/json; charset=utf-8 + Content-Length: 19 + + {"status": "ok", "extended": true} + +## Lua + + --[[ + Simple signal/slot implementation + ]] + local signal_mt = { + __index = { + register = table.insert + } + } + function signal_mt.__index:emit(... --[[ Comment in params ]]) + for _, slot in ipairs(self) do + slot(self, ...) + end + end + local function create_signal() + return setmetatable({}, signal_mt) + end + + -- Signal test + local signal = create_signal() + signal:register(function(signal, ...) + print(...) + end) + signal:emit('Answer to Life, the Universe, and Everything:', 42) + + --[==[ [=[ [[ + Nested ]] + multi-line ]=] + comment ]==] + [==[ Nested + [=[ multi-line + [[ string + ]] ]=] ]==] + +## AppleScript + + repeat 5 times + if foo is greater than bar then + display dialog "Hello there" + else + beep + end if + end repeat + + (* comment (*nested comment*) *) + on do_something(s, y) + return {s + pi, y mod 4} + end do_something + + do shell script "/bin/echo 'hello'" + +## Delphi + + TList=Class(TObject) + Private + Some: String; + Public + Procedure Inside; // Suxx + End;{TList} + + Procedure CopyFile(InFileName,var OutFileName:String); + Const + BufSize=4096; (* Huh? *) + Var + InFile,OutFile:TStream; + Buffer:Array[1..BufSize] Of Byte; + ReadBufSize:Integer; + Begin + InFile:=Nil; + OutFile:=Nil; + Try + InFile:=TFileStream.Create(InFileName,fmOpenRead); + OutFile:=TFileStream.Create(OutFileName,fmCreate); + Repeat + ReadBufSize:=InFile.Read(Buffer,BufSize); + OutFile.Write(Buffer,ReadBufSize); + Until ReadBufSize<>BufSize; + Log('File '''+InFileName+''' copied'#13#10); + Finally + InFile.Free; + OutFile.Free; + End;{Try} + End;{CopyFile} + +## Java + + /** + * @author John Smith + * @version 1.0 + */ + package l2f.gameserver.model; + + import java.util.ArrayList; + + public abstract class L2Character extends L2Object { + public static final Short ABNORMAL_EFFECT_BLEEDING = 0x0001; // not sure + + public void moveTo(int x, int y, int z) { + _ai = null; + _log.warning("Should not be called"); + if (1 > 5) { + return; + } + } + + /** Task of AI notification */ + @SuppressWarnings( { "nls", "unqualified-field-access", "boxing" }) + public class NotifyAITask implements Runnable { + private final CtrlEvent _evt; + + public void run() { + try { + getAI().notifyEvent(_evt, null, null); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + } + +## C++ + + #include + + int main(int argc, char *argv[]) { + + /* An annoying "Hello World" example */ + for (auto i = 0; i < 0xFFFF; i++) + cout << "Hello, World!" << endl; + + char c = '\n'; + unordered_map > m; + m["key"] = "\\\\"; // this is an error + + return -2e3 + 12l; + } + +## Objective C + + #import + #import "Dependency.h" + + @protocol WorldDataSource + @optional + - (NSString*)worldName; + @required + - (BOOL)allowsToLive; + @end + + @interface Test : NSObject { + NSString *_greeting; + } + + @property (nonatomic, readonly) NSString *greeting; + - (IBAction) show; + @end + + @implementation Test + + @synthesize test=_test; + + + (id) test { + return [self testWithGreeting:@"Hello, world!\nFoo bar!"]; + } + + + (id) testWithGreeting:(NSString*)greeting { + return [[[self alloc] initWithGreeting:greeting] autorelease]; + } + + - (id) initWithGreeting:(NSString*)greeting { + if ( (self = [super init]) ) { + _greeting = [greeting retain]; + } + return self; + } + + - (void) dealloc { + [_greeting release]; + [super dealloc]; + } + + @end + +## Vala + + using DBus; + + namespace Test { + class Foo : Object { + public signal void some_event (); // definition of the signal + public void method () { + some_event (); // emitting the signal (callbacks get invoked) + } + } + } + + /* defining a class */ + class Track : GLib.Object, Test.Foo { /* subclassing 'GLib.Object' */ + public double mass; /* a public field */ + public double name { get; set; } /* a public property */ + private bool terminated = false; /* a private field */ + public void terminate() { /* a public method */ + terminated = true; + } + } + + const ALL_UPPER_CASE = "you should follow this convention"; + + var t = new Track(); // same as: Track t = new Track(); + var s = "hello"; // same as: string s = "hello"; + var l = new List(); // same as: List l = new List(); + var i = 10; // same as: int i = 10; + + + #if (ololo) + Regex regex = /foo/; + #endif + + /* + * Entry point can be outside class + */ + void main () { + var long_string = """ + Example of "verbatim string". + Same as in @"string" in C# + """ + var foo = new Foo (); + foo.some_event.connect (callback_a); // connecting the callback functions + foo.some_event.connect (callback_b); + foo.method (); + } + +## C + + using System; + + #pragma warning disable 414, 3021 + + public class Program + { + /// The entry point to the program. + public static int Main(string[] args) + { + Console.WriteLine("Hello, World!"); + string s = @"This + ""string"" + spans + multiple + lines!"; + return 0; + } + } + + async Task AccessTheWebAsync() + { + // ... + string urlContents = await getStringTask; + return urlContents.Length; + } + +## F + + open System + + // Single line comment... + (* + This is a + multiline comment. + *) + let checkList alist = + match alist with + | [] -> 0 + | [a] -> 1 + | [a; b] -> 2 + | [a; b; c] -> 3 + | _ -> failwith "List is too big!" + + + type IEncoding = + abstract Encode : string -> string + abstract Decode : string -> string + + let text = "Some text..." + let text2 = @"A ""verbatim"" string..." + let catalog = """ + Some "long" string... + """ + + let rec fib x = if x <= 2 then 1 else fib(x-1) + fib(x-2) + + let fibs = + Async.Parallel [ for i in 0..40 -> async { return fib(i) } ] + |> Async.RunSynchronously + + type Sprocket(gears) = + member this.Gears : int = gears + + [] + type Animal = + abstract Speak : unit -> unit + + type Widget = + | RedWidget + | GreenWidget + + type Point = {X: float; Y: float;} + + [] + type s + let minutte = 60 + +## D + + #!/usr/bin/rdmd + // Computes average line length for standard input. + import std.stdio; + + /+ + this is a /+ nesting +/ comment + +/ + + enum COMPILED_ON = __TIMESTAMP__; // special token + + enum character = '©'; + enum copy_valid = '©'; + enum backslash_escaped = '\\'; + + // string literals + enum str = `hello "world"!`; + enum multiline = r"lorem + ipsum + dolor"; // wysiwyg string, no escapes here allowed + enum multiline2 = "sit + amet + \"adipiscing\" + elit."; + enum hex = x"66 6f 6f"; // same as "foo" + + #line 5 + + // float literals + enum f = [3.14f, .1, 1., 1e100, 0xc0de.01p+100]; + + static if (something == true) { + import std.algorithm; + } + + void main() pure nothrow @safe { + ulong lines = 0; + double sumLength = 0; + foreach (line; stdin.byLine()) { + ++lines; + sumLength += line.length; + } + writeln("Average line length: ", + lines ? sumLength / lines : 0); + } + +## RenderMan RSL + + #define TEST_DEFINE 3.14 + /* plastic surface shader + * + * Pixie is: + * (c) Copyright 1999-2003 Okan Arikan. All rights reserved. + */ + + surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1; + color specularcolor = 1;) { + normal Nf = faceforward (normalize(N),I); + Ci = Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * + specular(Nf,-normalize(I),roughness); + Oi = Os; + Ci *= Oi; + } -**Handlebars** +## RenderMan RIB + + FrameBegin 0 + Display "Scene" "framebuffer" "rgb" + Option "searchpath" "shader" "+&:/home/kew" + Option "trace" "int maxdepth" [4] + Attribute "visibility" "trace" [1] + Attribute "irradiance" "maxerror" [0.1] + Attribute "visibility" "transmission" "opaque" + Format 640 480 1.0 + ShadingRate 2 + PixelFilter "catmull-rom" 1 1 + PixelSamples 4 4 + Projection "perspective" "fov" 49.5502811377 + Scale 1 1 -1 -

    Hours

    + WorldBegin -
      - {{#each content.users}} -
    • {{firstName}}
    • - {{/each}} -
    - -**CSS** - - @media screen and (-webkit-min-device-pixel-ratio: 0) { - body:first-of-type pre::after { - content: 'highlight: ' attr(class); - } - body { - background: linear-gradient(45deg, blue, red); - } - } - - @import url('print.css'); - @page:right { - margin: 1cm 2cm 1.3cm 4cm; - } - - @font-face { - font-family: Chunkfive; src: url('Chunkfive.otf'); - } - - div.text, - #content, - li[lang=ru] { - font: Tahoma, Chunkfive, sans-serif; - background: url('hatch.png') /* wtf? */; color: #F0F0F0 !important; - width: 100%; - } - -**SCSS** - - @import "compass/reset"; - - // variables - $colorGreen: #008000; - $colorGreenDark: darken($colorGreen, 10); - - @mixin container { - max-width: 980px; - } - - // mixins with parameters - @mixin button($color:green) { - @if ($color == green) { - background-color: #008000; - } - @else if ($color == red) { - background-color: #B22222; - } - } - - button { - @include button(red); - } - - div, - .navbar, - #header, - input[type="input"] { - font-family: "Helvetica Neue", Arial, sans-serif; - width: auto; - margin: 0 auto; - display: block; - } - - .row-12 > [class*="spans"] { - border-left: 1px solid #B5C583; - } - - // nested definitions - ul { - width: 100%; - padding: { - left: 5px; right: 5px; - } - li { - float: left; margin-right: 10px; - .home { - background: url('http://placehold.it/20') scroll no-repeat 0 0; - } - } - } - - .banner { - @extend .container; - } - - a { - color: $colorGreen; - &:hover { color: $colorGreenDark; } - &:visited { color: #c458cb; } - } - - @for $i from 1 through 5 { - .span#{$i} { - width: 20px*$i; - } - } - - @mixin mobile { - @media screen and (max-width : 600px) { - @content; - } - } - -**JSON** - - [ - { - "title": "apples", - "count": [12000, 20000], - "description": {"text": "...", "sensitive": false} - }, - { - "title": "oranges", - "count": [17500, null], - "description": {"text": "...", "sensitive": false} - } - ] - -**JavaScript** - - function $initHighlight(block, flags) { - try { - if (block.className.search(/\bno\-highlight\b/) != -1) - return processBlock(block, true, 0x0F) + ' class=""'; - } catch (e) { - /* handle exception */ - - var e4x = -
    Example -

    1234

    ; - } - for (var i = 0 / 2; i < classes.length; i++) { // "0 / 2" should not be parsed as regexp - if (checkCondition(classes[i]) === undefined) - return /\d+[\s/]/g; - } - } - -**CoffeeScript** - - # Divisions - x = 6/foo/i - x = 6 /foo - x = 6 / foo - x = 6 /foo * 2/gm - x = f /foo - x = f / foo / gm - x = f /foo * 2/6 - - # Regexps - x = f /6 * 2/ - 3 - x = f /foo * 2/gm - x = if true then /\n/ else /[.,]+/ - - grade = (student, period=(if b? then 7 else 6), messages={"A": "Excellent"}) -> - if student.excellentWork - "A+" - else if student.okayStuff - if student.triedHard then "B" else "B-" - else - "C" - - square = (x) -> x * x - - two = -> 2 - - math = - root: Math.sqrt - square: square - cube: (x) -> x * square x - - race = (winner, runners...) -> - print winner, runners - - class Animal extends Being - constructor: (@name) -> - - move: (meters) -> - alert @name + " moved #{meters}m." - - hi = `function() { - return [document.title, "Hello JavaScript"].join(": "); - }` - - heredoc = """ - CoffeeScript subst test #{ 010 + 0xf / 0b10 + "nested string #{ /\n/ }"} - """ - - ### - CoffeeScript Compiler v1.2.0 - Released under the MIT License - ### - - OPERATOR = /// ^ ( - ?: [-=]> # function - ) /// - -**ActionScript** - - package org.example.dummy { - import org.dummy.*; - - /*define package inline interface*/ - public interface IFooBarzable { - public function foo(... pairs):Array; - } - - public class FooBar implements IFooBarzable { - static private var cnt:uint = 0; - private var bar:String; - - //constructor - public function TestBar(bar:String):void { - bar = bar; - ++cnt; - } - - public function foo(... pairs):Array { - pairs.push(bar); - return pairs; - } - } - } - -**VB.NET** - - Import System - Import System.IO - #Const DEBUG = True - - Namespace Highlighter.Test - ''' This is an example class. - Public Class Program - Protected Shared hello As Integer = 3 - Private Const ABC As Boolean = False - - #Region "Code" - ' Cheers! - _ - Public Shared Sub Main(ByVal args() As String, ParamArray arr As Object) Handles Form1.Click - On Error Resume Next - If ABC Then - While ABC : Console.WriteLine() : End While - For i As Long = 0 To 1000 Step 123 - Try - System.Windows.Forms.MessageBox.Show(CInt("1").ToString()) - Catch ex As Exception ' What are you doing? Well... - Dim exp = CType(ex, IOException) - REM ORZ - Return - End Try - Next - Else - Dim l As New System.Collections.List() - SyncLock l - If TypeOf l Is Decimal And l IsNot Nothing Then - RemoveHandler button1.Paint, delegate - End If - Dim d = New System.Threading.Thread(AddressOf ThreadProc) - Dim a = New Action(Sub(x, y) x + y) - Static u = From x As String In l Select x.Substring(2, 4) Where x.Length > 0 - End SyncLock - Do : Laugh() : Loop Until hello = 4 - End If - End Sub - #End Region - End Class - End Namespace - - -**HTTP** - - POST /task?id=1 HTTP/1.1 - Host: example.org - Content-Type: application/json; charset=utf-8 - Content-Length: 19 - - {"status": "ok", "extended": true} - -**Lua** - - --[[ - Simple signal/slot implementation - ]] - local signal_mt = { - __index = { - register = table.insert - } - } - function signal_mt.__index:emit(... --[[ Comment in params ]]) - for _, slot in ipairs(self) do - slot(self, ...) - end - end - local function create_signal() - return setmetatable({}, signal_mt) - end - - -- Signal test - local signal = create_signal() - signal:register(function(signal, ...) - print(...) - end) - signal:emit('Answer to Life, the Universe, and Everything:', 42) - - --[==[ [=[ [[ - Nested ]] - multi-line ]=] - comment ]==] - [==[ Nested - [=[ multi-line - [[ string - ]] ]=] ]==] - -**AppleScript** - - repeat 5 times - if foo is greater than bar then - display dialog "Hello there" - else - beep - end if - end repeat - - (* comment (*nested comment*) *) - on do_something(s, y) - return {s + pi, y mod 4} - end do_something - - do shell script "/bin/echo 'hello'" - - -**Delphi** - - TList=Class(TObject) - Private - Some: String; - Public - Procedure Inside; // Suxx - End;{TList} - - Procedure CopyFile(InFileName,var OutFileName:String); - Const - BufSize=4096; (* Huh? *) - Var - InFile,OutFile:TStream; - Buffer:Array[1..BufSize] Of Byte; - ReadBufSize:Integer; - Begin - InFile:=Nil; - OutFile:=Nil; - Try - InFile:=TFileStream.Create(InFileName,fmOpenRead); - OutFile:=TFileStream.Create(OutFileName,fmCreate); - Repeat - ReadBufSize:=InFile.Read(Buffer,BufSize); - OutFile.Write(Buffer,ReadBufSize); - Until ReadBufSize<>BufSize; - Log('File '''+InFileName+''' copied'#13#10); - Finally - InFile.Free; - OutFile.Free; - End;{Try} - End;{CopyFile} - -**Java** - - /** - * @author John Smith - * @version 1.0 - */ - package l2f.gameserver.model; - - import java.util.ArrayList; - - public abstract class L2Character extends L2Object { - public static final Short ABNORMAL_EFFECT_BLEEDING = 0x0001; // not sure - - public void moveTo(int x, int y, int z) { - _ai = null; - _log.warning("Should not be called"); - if (1 > 5) { - return; - } - } - - /** Task of AI notification */ - @SuppressWarnings( { "nls", "unqualified-field-access", "boxing" }) - public class NotifyAITask implements Runnable { - private final CtrlEvent _evt; - - public void run() { - try { - getAI().notifyEvent(_evt, null, null); - } catch (Throwable t) { - t.printStackTrace(); - } - } - } - } - -**C++** - - #include - - int main(int argc, char *argv[]) { - - /* An annoying "Hello World" example */ - for (auto i = 0; i < 0xFFFF; i++) - cout << "Hello, World!" << endl; - - char c = '\n'; - unordered_map > m; - m["key"] = "\\\\"; // this is an error - - return -2e3 + 12l; - } - -**Objective C** - - #import - #import "Dependency.h" - - @protocol WorldDataSource - @optional - - (NSString*)worldName; - @required - - (BOOL)allowsToLive; - @end - - @interface Test : NSObject { - NSString *_greeting; - } - - @property (nonatomic, readonly) NSString *greeting; - - (IBAction) show; - @end - - @implementation Test - - @synthesize test=_test; - - + (id) test { - return [self testWithGreeting:@"Hello, world!\nFoo bar!"]; - } - - + (id) testWithGreeting:(NSString*)greeting { - return [[[self alloc] initWithGreeting:greeting] autorelease]; - } - - - (id) initWithGreeting:(NSString*)greeting { - if ( (self = [super init]) ) { - _greeting = [greeting retain]; - } - return self; - } - - - (void) dealloc { - [_greeting release]; - [super dealloc]; - } - - @end - -**Vala** - - using DBus; - - namespace Test { - class Foo : Object { - public signal void some_event (); // definition of the signal - public void method () { - some_event (); // emitting the signal (callbacks get invoked) - } - } - } - - /* defining a class */ - class Track : GLib.Object, Test.Foo { /* subclassing 'GLib.Object' */ - public double mass; /* a public field */ - public double name { get; set; } /* a public property */ - private bool terminated = false; /* a private field */ - public void terminate() { /* a public method */ - terminated = true; - } - } - - const ALL_UPPER_CASE = "you should follow this convention"; - - var t = new Track(); // same as: Track t = new Track(); - var s = "hello"; // same as: string s = "hello"; - var l = new List(); // same as: List l = new List(); - var i = 10; // same as: int i = 10; - - - #if (ololo) - Regex regex = /foo/; - #endif - - /* - * Entry point can be outside class - */ - void main () { - var long_string = """ - Example of "verbatim string". - Same as in @"string" in C# - """ - var foo = new Foo (); - foo.some_event.connect (callback_a); // connecting the callback functions - foo.some_event.connect (callback_b); - foo.method (); - } - -**C** - - using System; - - #pragma warning disable 414, 3021 - - public class Program - { - /// The entry point to the program. - public static int Main(string[] args) - { - Console.WriteLine("Hello, World!"); - string s = @"This - ""string"" - spans - multiple - lines!"; - return 0; - } - } - - async Task AccessTheWebAsync() - { - // ... - string urlContents = await getStringTask; - return urlContents.Length; - } - -**F** - - open System - - // Single line comment... - (* - This is a - multiline comment. - *) - let checkList alist = - match alist with - | [] -> 0 - | [a] -> 1 - | [a; b] -> 2 - | [a; b; c] -> 3 - | _ -> failwith "List is too big!" - - - type IEncoding = - abstract Encode : string -> string - abstract Decode : string -> string - - let text = "Some text..." - let text2 = @"A ""verbatim"" string..." - let catalog = """ - Some "long" string... - """ - - let rec fib x = if x <= 2 then 1 else fib(x-1) + fib(x-2) - - let fibs = - Async.Parallel [ for i in 0..40 -> async { return fib(i) } ] - |> Async.RunSynchronously - - type Sprocket(gears) = - member this.Gears : int = gears - - [] - type Animal = - abstract Speak : unit -> unit - - type Widget = - | RedWidget - | GreenWidget - - type Point = {X: float; Y: float;} - - [] - type s - let minutte = 60 - -**D** - - #!/usr/bin/rdmd - // Computes average line length for standard input. - import std.stdio; - - /+ - this is a /+ nesting +/ comment - +/ - - enum COMPILED_ON = __TIMESTAMP__; // special token - - enum character = '©'; - enum copy_valid = '©'; - enum backslash_escaped = '\\'; - - // string literals - enum str = `hello "world"!`; - enum multiline = r"lorem - ipsum - dolor"; // wysiwyg string, no escapes here allowed - enum multiline2 = "sit - amet - \"adipiscing\" - elit."; - enum hex = x"66 6f 6f"; // same as "foo" - - #line 5 - - // float literals - enum f = [3.14f, .1, 1., 1e100, 0xc0de.01p+100]; - - static if (something == true) { - import std.algorithm; - } - - void main() pure nothrow @safe { - ulong lines = 0; - double sumLength = 0; - foreach (line; stdin.byLine()) { - ++lines; - sumLength += line.length; - } - writeln("Average line length: ", - lines ? sumLength / lines : 0); - } - -**RenderMan RSL** - - #define TEST_DEFINE 3.14 - /* plastic surface shader - * - * Pixie is: - * (c) Copyright 1999-2003 Okan Arikan. All rights reserved. - */ - - surface plastic (float Ka = 1, Kd = 0.5, Ks = 0.5, roughness = 0.1; - color specularcolor = 1;) { - normal Nf = faceforward (normalize(N),I); - Ci = Cs * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks * - specular(Nf,-normalize(I),roughness); - Oi = Os; - Ci *= Oi; - } - -**RenderMan RIB** - - FrameBegin 0 - Display "Scene" "framebuffer" "rgb" - Option "searchpath" "shader" "+&:/home/kew" - Option "trace" "int maxdepth" [4] - Attribute "visibility" "trace" [1] - Attribute "irradiance" "maxerror" [0.1] - Attribute "visibility" "transmission" "opaque" - Format 640 480 1.0 - ShadingRate 2 - PixelFilter "catmull-rom" 1 1 - PixelSamples 4 4 - Projection "perspective" "fov" 49.5502811377 - Scale 1 1 -1 - - WorldBegin - - ReadArchive "Lamp.002_Light/instance.rib" - Surface "plastic" - ReadArchive "Cube.004_Mesh/instance.rib" - # ReadArchive "Sphere.010_Mesh/instance.rib" - # ReadArchive "Sphere.009_Mesh/instance.rib" - ReadArchive "Sphere.006_Mesh/instance.rib" - - WorldEnd - FrameEnd - -**MEL (Maya Embedded Language)** - - proc string[] getSelectedLights() - - { - string $selectedLights[]; - - string $select[] = `ls -sl -dag -leaf`; - - for ( $shape in $select ) - { - // Determine if this is a light. - // - string $class[] = getClassification( `nodeType $shape` ); - - - if ( ( `size $class` ) > 0 && ( "light" == $class[0] ) ) - { - $selectedLights[ `size $selectedLights` ] = $shape; - } - } - - // Result is an array of all lights included in - - // current selection list. - return $selectedLights; - } - -**GLSL** - - // vertex shader - #version 150 - in vec2 in_Position; - in vec3 in_Color; - - out vec3 ex_Color; - void main(void) { - gl_Position = vec4(in_Position.x, in_Position.y, 0.0, 1.0); - ex_Color = in_Color; - } - - - // geometry shader - #version 150 - - layout(triangles) in; - layout(triangle_strip, max_vertices = 3) out; - - void main() { - for(int i = 0; i < gl_in.length(); i++) { - gl_Position = gl_in[i].gl_Position; - EmitVertex(); - } - EndPrimitive(); - } - - - // fragment shader - #version 150 - precision highp float; - - in vec3 ex_Color; - out vec4 gl_FragColor; - - void main(void) { - gl_FragColor = vec4(ex_Color, 1.0); - } - -**SQL** - - BEGIN; - CREATE TABLE "topic" ( - "id" serial NOT NULL PRIMARY KEY, - "forum_id" integer NOT NULL, - "subject" varchar(255) NOT NULL - ); - ALTER TABLE "topic" ADD CONSTRAINT forum_id FOREIGN KEY ("forum_id") REFERENCES "forum" ("id"); - - -- Initials - insert into "topic" ("forum_id", "subject") values (2, 'D''artagnian'); - - select count(*) from cicero_forum; - - -- this line lacks ; at the end to allow people to be sloppy and omit it in one-liners - COMMIT - -**SmallTalk** - - Object>>method: num - "comment 123" - | var1 var2 | - (1 to: num) do: [:i | |var| ^i]. - Klass with: var1. - Klass new. - arr := #('123' 123.345 #hello Transcript var $@). - arr := #(). - var2 = arr at: 3. - ^ self abc - - heapExample - "HeapTest new heapExample" - "Multiline - decription" - | n rnd array time sorted | - n := 5000. - "# of elements to sort" - rnd := Random new. - array := (1 to: n) - collect: [:i | rnd next]. - "First, the heap version" - time := Time - millisecondsToRun: [sorted := Heap withAll: array. - 1 - to: n - do: [:i | - sorted removeFirst. - sorted add: rnd next]]. - Transcript cr; show: 'Time for Heap: ' , time printString , ' msecs'. - "The quicksort version" - time := Time - millisecondsToRun: [sorted := SortedCollection withAll: array. - 1 - to: n - do: [:i | - sorted removeFirst. - sorted add: rnd next]]. - Transcript cr; show: 'Time for SortedCollection: ' , time printString , ' msecs' - -**Lisp** - - #!/usr/bin/env csi - - (defun prompt-for-cd () - "Prompts - for CD" - (prompt-read "Title" 1.53 1 2/4 1.7 1.7e0 2.9E-4 +42 -7 #b001 #b001/100 #o777 #O777 #xabc55 #c(0 -5.6)) - (prompt-read "Artist" &rest) - (or (parse-integer (prompt-read "Rating") :junk-allowed t) 0) - (if x (format t "yes") (format t "no" nil) ;and here comment - ) - ;; second line comment - '(+ 1 2) - (defvar *lines*) ; list of all lines - (position-if-not #'sys::whitespacep line :start beg)) - (quote (privet 1 2 3)) - '(hello world) - (* 5 7) - (1 2 34 5) - (:use "aaaa") - (let ((x 10) (y 20)) - (print (+ x y)) - ) - -**Clojure** - - ; You must not remove this notice, or any other, from this software. - - (ns ^{:doc "The core Clojure language." - :author "Rich Hickey"} - clojure.core) - - (def unquote) - - (def - ^{:macro true - :added "1.0"} - let (fn* let [&form &env & decl] (cons 'let* decl))) - - (def - - defn (fn defn [&form &env name & fdecl] - (let [m (conj {:arglists (list 'quote (sigs fdecl))} m) - m (let [inline (:inline m) - ifn (first inline) - iname (second inline)] - ;; same as: (if (and (= 'fn ifn) (not (symbol? iname))) ...) - (if (if (clojure.lang.Util/equiv 'fn ifn) - (if (instance? clojure.lang.Symbol iname) false true)) - ;; inserts the same fn name to the inline fn if it does not have one - (assoc m :inline (cons ifn (cons (clojure.lang.Symbol/intern (.concat (.getName ^clojure.lang.Symbol name) "__inliner")) - (next inline)))) - m)) - m (conj (if (meta name) (meta name) {}) m)] - (list 'def (with-meta name m) - ;;todo - restore propagation of fn name - ;;must figure out how to convey primitive hints to self calls first - (cons `fn fdecl) )))) - - (. (var defn) (setMacro)) - -**Ini file** - - ;Settings relating to the location and loading of the database - [Database] - ProfileDir=. - ShowProfileMgr=smart - Profile1_Name[] = "\|/_-=MegaDestoyer=-_\|/" - DefaultProfile=True - AutoCreate = no - - [AutoExec] - use-prompt="prompt" - Glob=autoexec_*.ini - AskAboutIgnoredPlugins=0 - -**Apache** - - # rewrite`s rules for wordpress pretty url - LoadModule rewrite_module modules/mod_rewrite.so - RewriteCond %{REQUEST_FILENAME} !-f - RewriteCond %{REQUEST_FILENAME} !-d - RewriteRule . index.php [NC,L] - - ExpiresActive On - ExpiresByType application/x-javascript "access plus 1 days" - - - RewriteMap map txt:map.txt - RewriteMap lower int:tolower - RewriteCond %{REQUEST_URI} ^/([^/.]+)\.html$ [NC] - RewriteCond ${map:${lower:%1}|NOT_FOUND} !NOT_FOUND - RewriteRule .? /index.php?q=${map:${lower:%1}} [NC,L] - - -**nginx** - - user www www; - worker_processes 2; - pid /var/run/nginx.pid; - error_log /var/log/nginx.error_log debug | info | notice | warn | error | crit; - - events { - connections 2000; - use kqueue | rtsig | epoll | /dev/poll | select | poll; - } - - http { - log_format main '$remote_addr - $remote_user [$time_local] ' - '"$request" $status $bytes_sent ' - '"$http_referer" "$http_user_agent" ' - '"$gzip_ratio"'; - - send_timeout 3m; - client_header_buffer_size 1k; - - gzip on; - gzip_min_length 1100; - - #lingering_time 30; - - server { - server_name one.example.com www.one.example.com; - access_log /var/log/nginx.access_log main; - - rewrite (.*) /index.php?page=$1 break; - - location / { - proxy_pass http://127.0.0.1/; - proxy_redirect off; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - charset koi8-r; - } - - location /api/ { - fastcgi_pass 127.0.0.1:9000; - } - - location ~* \.(jpg|jpeg|gif)$ { - root /spool/www; - } - } - } - -**Diff** - - Index: languages/ini.js - =================================================================== - --- languages/ini.js (revision 199) - +++ languages/ini.js (revision 200) - @@ -1,8 +1,7 @@ - hljs.LANGUAGES.ini = - { - case_insensitive: true, - - defaultMode: - - { - + defaultMode: { - contains: ['comment', 'title', 'setting'], - illegal: '[^\\s]' - }, - - *** /path/to/original timestamp - --- /path/to/new timestamp - *************** - *** 1,3 **** - --- 1,9 ---- - + This is an important - + notice! It should - + therefore be located at - + the beginning of this - + document! - - ! compress the size of the - ! changes. - - It is important to spell - -**DOS batch files** - - cd \ - copy a b - ping 192.168.0.1 - @rem ping 192.168.0.1 - net stop sharedaccess - del %tmp% /f /s /q - del %temp% /f /s /q - ipconfig /flushdns - taskkill /F /IM JAVA.EXE /T - - cd Photoshop/Adobe Photoshop CS3/AMT/ - if exist application.sif ( - ren application.sif _application.sif - ) else ( - ren _application.sif application.sif - ) - - taskkill /F /IM proquota.exe /T - - sfc /SCANNOW - - set path = test - - xcopy %1\*.* %2 - -**Bash** - - #!/bin/bash - - ###### BEGIN CONFIG - ACCEPTED_HOSTS="/root/.hag_accepted.conf" - BE_VERBOSE=false - ###### END CONFIG - - if [ "$UID" -ne 0 ] - then - echo "Superuser rights is required" - echo 'Printing the # sign' - exit 2 - fi - - if test $# -eq 0 - then - elif test [ $1 == 'start' ] - else - fi - - genApacheConf(){ - if [[ "$2" = "www" ]] - then - full_domain=$1 - else - full_domain=$2.$1 - fi - host_root="${APACHE_HOME_DIR}$1/$2/$(title)" - echo -e "# Host $1/$2 :" - } - -**CMake** - - project(test) - cmake_minimum_required(VERSION 2.6) - - # IF LINUX - if (${CMAKE_SYSTEM_NAME} MATCHES Linux) - message("\nOS:\t\tLinux") - endif() - - # IF WINDOWS - if (${CMAKE_SYSTEM_NAME} MATCHES Windows) - message("\nOS:\t\tWindows") - endif() - - set(test test0.cpp test1.cpp test2.cpp) - - include_directories(./) - - set(EXECUTABLE_OUTPUT_PATH ../bin) - - add_subdirectory(src) - - add_executable(test WIN32 ${test}) - - target_link_libraries(test msimg32) - -**Axapta** - - class ExchRateLoadBatch extends RunBaseBatch { - ExchRateLoad rbc; - container currencies; - boolean actual; - boolean overwrite; - date beg; - date end; - - #define.CurrentVersion(5) - - #localmacro.CurrentList - currencies, - actual, - beg, - end - #endmacro - } - - public boolean unpack(container packedClass) { - container base; - boolean ret; - Integer version = runbase::getVersion(packedClass); - - switch (version) { - case #CurrentVersion: - [version, #CurrentList] = packedClass; - return true; - default: - return false; - } - return ret; - } - -**Oracle Rules Language** - - //This is a comment - ABORT "You experienced an abort."; - WARN "THIS IS A WARNING"; - CALL "RIDER_X"; - DONE; - FOR EACH X IN CSV_FILE "d:\lodestar\user\d377.lse" - LEAVE FOR; - END FOR; - IF ((BILL_KW = 0) AND (KW > 0)) THEN - END IF; - INCLUDE "R1"; - LEAVE RIDER; - SELECT BILL_PERIOD - WHEN "WINTER" - BLOCK KWH - FROM 0 TO 400 CHARGE $0.03709 - FROM 400 CHARGE $0.03000 - TOTAL $ENERGY_CHARGE_WIN; - WHEN "SUMMER" - $VOLTAGE_DISCOUNT_SUM = $0.00 - OTHERWISE - $VOLTAGE_DISCOUNT_SUM = $1.00 - END SELECT; - /* Report top five peaks */ - LABEL PK.NM "Peak Number"; - SAVE_UPDATE MV TO TABLE "METERVALUE"; - - FOR EACH INX IN ARRAYUPPERBOUND(#MYARRAY[]) - #MYARRAY[INX].VALUE = 2; - CLEAR #MYARRAY[]; - END FOR - - //Interval Data - HNDL_1_ADD_EDI = INTDADDATTRIBUTE(HNDL_1, "EDI_TRANSACTION", EDI_ID); - HNDL_1_ADD_VAL_MSG = INTDADDVMSG(HNDL_1,"Missing (Status Code 9) values found"); - EMPTY_HNDL = INTDCREATEHANDLE('05/03/2006 00:00:00', '05/03/2006 23:59:59', 3600, "Y", "0", " "); - -**1С** - - #Если Клиент Тогда - Перем СимвольныйКодКаталога = "ля-ля-ля"; //комментарий - Функция Сообщить(Знач ТекстСообщения, ТекстСообщения2) Экспорт //комментарий к функции - x=ТекстСообщения+ТекстСообщения2+" - |строка1 - |строка2 - |строка3"; - КонецФункции - #КонецЕсли - - // Процедура ПриНачалеРаботыСистемы - // - Процедура ПриНачалеРаботыСистемы() - Обработки.Помощник.ПолучитьФорму("Форма").Открыть(); - d = '21.01.2008' - КонецПроцедуры - -**AVR Assembler** - - ;* Title: Block Copy Routines - ;* Version: 1.1 - - .include "8515def.inc" - - rjmp RESET ;reset handle - - .def flashsize=r16 ;size of block to be copied - - flash2ram: - lpm ;get constant - st Y+,r0 ;store in SRAM and increment Y-pointer - adiw ZL,1 ;increment Z-pointer - dec flashsize - brne flash2ram ;if not end of table, loop more - ret - - .def ramtemp =r1 ;temporary storage register - .def ramsize =r16 ;size of block to be copied - -**VHDL** - - /* - * RS-trigger with assynch. reset - */ - - library ieee; - use ieee.std_logic_1164.all; - - entity RS_trigger is - generic (T: Time := 0ns); - port ( R, S : in std_logic; - Q, nQ : out std_logic; - reset, clock : in std_logic ); - end RS_trigger; - - architecture behaviour of RS_trigger is - signal QT: std_logic; -- Q(t) - begin - process(clock, reset) is - subtype RS is std_logic_vector (1 downto 0); - begin - if reset = '0' then - QT <= '0'; - else - if rising_edge(C) then - if not (R'stable(T) and S'stable(T)) then - QT <= 'X'; - else - case RS'(R&S) is - when "01" => QT <= '1'; - when "10" => QT <= '0'; - when "11" => QT <= 'X'; - when others => null; - end case; - end if; - end if; - end if; - end process; - - Q <= QT; - nQ <= not QT; - end architecture behaviour; - -**Parser 3** - - @CLASS - base - - @USE - module.p - - @BASE - class - - # Comment for code - @create[aParam1;aParam2][local1;local2] - ^connect[mysql://host/database?ClientCharset=windows-1251] - ^for[i](1;10){ -

    ^eval($i+10)

    - ^connect[mysql://host/database]{ - $tab[^table::sql{select * from `table` where a='1'}] - $var_Name[some${value}] - } - } - - ^rem{ - Multiline comment with code: $var - ^while(true){ - ^for[i](1;10){ - ^sleep[] - } - } - } - ^taint[^#0A] - - @GET_base[] - ## Comment for code - # Isn't comment - $result[$.hash_item1[one] $.hash_item2[two]] - -**TeX** - - \documentclass{article} - \usepackage[koi8-r]{inputenc} - \hoffset=0pt - \voffset=.3em - \tolerance=400 - \newcommand{\eTiX}{\TeX} - \begin{document} - \section*{Highlight.js} - \begin{table}[c|c] - $\frac 12\, + \, \frac 1{x^3}\text{Hello \! world}$ & \textbf{Goodbye\~ world} \\\eTiX $ \pi=400 $ - \end{table} - Ch\'erie, \c{c}a ne me pla\^\i t pas! % comment \b - G\"otterd\"ammerung~45\%=34. - $$ - \int\limits_{0}^{\pi}\frac{4}{x-7}=3 - $$ - \end{document} - -**Haskell** - - {-# LANGUAGE TypeSynonymInstances #-} - module Network.UDP - ( DataPacket(..) - , openBoundUDPPort - , openListeningUDPPort - , pingUDPPort - , sendUDPPacketTo - , recvUDPPacket - , recvUDPPacketFrom - ) where - - {- this is a {- nested -} comment -} - - import qualified Data.ByteString as Strict (ByteString, concat, singleton) - import qualified Data.ByteString.Lazy as Lazy (ByteString, toChunks, fromChunks) - import Data.ByteString.Char8 (pack, unpack) - import Network.Socket hiding (sendTo, recv, recvFrom) - import Network.Socket.ByteString (sendTo, recv, recvFrom) - - -- Type class for converting StringLike types to and from strict ByteStrings - class DataPacket a where - toStrictBS :: a -> Strict.ByteString - fromStrictBS :: Strict.ByteString -> a - - instance DataPacket Strict.ByteString where - toStrictBS = id - {-# INLINE toStrictBS #-} - fromStrictBS = id - {-# INLINE fromStrictBS #-} - - openBoundUDPPort :: String -> Int -> IO Socket - openBoundUDPPort uri port = do - s <- getUDPSocket - bindAddr <- inet_addr uri - let a = SockAddrInet (toEnum port) bindAddr - bindSocket s a - return s - - pingUDPPort :: Socket -> SockAddr -> IO () - pingUDPPort s a = sendTo s (Strict.singleton 0) a >> return () - -**Erlang** - - -module(ssh_cli). - - -behaviour(ssh_channel). - - -include("ssh.hrl"). - %% backwards compatibility - -export([listen/1, listen/2, listen/3, listen/4, stop/1]). - - %% state - -record(state, { - cm, - channel - }). - - test(Foo)->Foo. - - init([Shell, Exec]) -> - {ok, #state{shell = Shell, exec = Exec}}; - init([Shell]) -> - false = not true, - io:format("Hello, \"~p!~n", [atom_to_list('World')]), - {ok, #state{shell = Shell}}. - - concat([Single]) -> Single; - concat(RList) -> - EpsilonFree = lists:filter( - fun (Element) -> - case Element of - epsilon -> false; - _ -> true - end - end, - RList), - case EpsilonFree of - [Single] -> Single; - Other -> {concat, Other} - end. - - union_dot_union({union, _}=U1, {union, _}=U2) -> - union(lists:flatten( - lists:map( - fun (X1) -> - lists:map( - fun (X2) -> - concat([X1, X2]) - end, - union_to_list(U2) - ) - end, - union_to_list(U1) - ))). - - -**Erlang REPL** - - 1> Str = "abcd". - "abcd" - 2> L = test:length(Str). - 4 - 3> Descriptor = {L, list_to_atom(Str)}. - {4,abcd} - 4> L. - 4 - 5> b(). - Descriptor = {4,abcd} - L = 4 - Str = "abcd" - ok - 6> f(L). - ok - 7> b(). - Descriptor = {4,abcd} - Str = "abcd" - ok - 8> {L, _} = Descriptor. - {4,abcd} - 9> L. - 4 - 10> 2#101. - 5 - 11> 1.85e+3. - 1850 - -**Rust** - - use std; - - import std::io; - export fac, test1; - - 123; // type int - 123u; // type uint - 123_u; // type uint - 0xff00; // type int - 0xff_u8; // type u8 - 0b1111_1111_1001_0000_i32; // type i32 - 123.0; // type float - 0.1; // type float - 3f; // type float - 0.1f32; // type f32 - 12E+99_f64; // type f64 - - /* Factorial */ - fn fac(n: int) -> int { - let s: str = "This is - a multi-line string. - - It ends with an unescaped '\"'."; - let c: char = 'Ф'; - - let result = 1, i = 1; - while i <= n { // No parens around the condition - result *= i; - i += 1; - } - ret result; - } - - pure fn pure_length(ls: list) -> uint { /* ... */ } - - type t = map::hashtbl; - let x = id::(10); - - // Define some modules. - #[path = "foo.rs"] - mod foo; - - iface seq { - fn len() -> uint; - } - - impl of seq for [T] { - fn len() -> uint { vec::len(self) } - fn iter(b: fn(T)) { - for elt in self { b(elt); } - } - } - - enum list { - nil; - cons(T, @list); - } - - let a: list = cons(7, @cons(13, @nil)); - -**Matlab** - - n = 20; % number of points - points = [random('unid', 100, n, 1), random('unid', 100, n, 1)]; - len = zeros(1, n - 1); - points = sortrows(points); - %% Initial set of points - plot(points(:,1),points(:,2)); - for i = 1: n-1 - len(i) = points(i + 1, 1) - points(i, 1); - end - while(max(len) > 2 * min(len)) - [d, i] = max(len); - k = on_margin(points, i, d, -1); - m = on_margin(points, i + 1, d, 1); - xm = 0; ym = 0; - %% New point - if(i == 1 || i + 1 == n) - xm = mean(points([i,i+1],1)) - ym = mean(points([i,i+1],2)) - else - [xm, ym] = dlg1(points([k, i, i + 1, m], 1), ... - points([k, i, i + 1, m], 2)) - end - - points = [ points(1:i, :); [xm, ym]; points(i + 1:end, :)]; - end - - function [net] = get_fit_network(inputs, targets) - % Create Network - numHiddenNeurons = 20; % Adjust as desired - net = newfit(inputs,targets,numHiddenNeurons); - net.trainParam.goal = 0.01; - net.trainParam.epochs = 1000; - % Train and Apply Network - [net,tr] = train(net,inputs,targets); - end - - foo_matrix = [1, 2, 3; 4, 5, 6]'''; - foo_cell = {1, 2, 3; 4, 5, 6}''.'.'; - -**R** - - library(ggplot2) - - centre <- function(x, type, ...) { - switch(type, - mean = mean(x), - median = median(x), - trimmed = mean(x, trim = .1)) - } - - myVar1 - myVar.2 - data$x - foo "bar" baz - # test "test" - "test # test" - - (123) (1) (10) (0.1) (.2) (1e-7) - (1.2e+7) (2e) (3e+10) (0x0) (0xa) - (0xabcdef1234567890) (123L) (1L) - (0x10L) (10000000L) (1e6L) (1.1L) - (1e-3L) (4123.381E-10i) - (3.) (3.E10) # BUG: .E10 should be part of number - - # Numbers in some different contexts - 1L - 0x40 - .234 - 3. - 1L + 30 - plot(cars, xlim=20) - plot(cars, xlim=0x20) - foo<-30 - my.data.3 <- read() # not a number - c(1,2,3) - 1%%2 - - "this is a quote that spans - multiple lines - \" - - is this still a quote? it should be. - # even still! - - " # now we're done. - - 'same for - single quotes #' - - # keywords - NULL, NA, TRUE, FALSE, Inf, NaN, NA_integer_, - NA_real_, NA_character_, NA_complex_, function, - while, repeat, for, if, in, else, next, break, - ..., ..1, ..2 - - # not keywords - the quick brown fox jumped over the lazy dogs - null na true false inf nan na_integer_ na_real_ - na_character_ na_complex_ Function While Repeat - For If In Else Next Break .. .... "NULL" `NULL` 'NULL' - - # operators - +, -, *, /, %%, ^, >, >=, <, <=, ==, !=, !, &, |, ~, - ->, <-, <<-, $, :, :: - - # infix operator - foo %union% bar - %"test"% - `"test"` - -**Mizar** - - ::: ## Lambda calculus - - environ - - vocabularies LAMBDA, - NUMBERS, - NAT_1, XBOOLE_0, SUBSET_1, FINSEQ_1, XXREAL_0, CARD_1, - ARYTM_1, ARYTM_3, TARSKI, RELAT_1, ORDINAL4, FUNCOP_1; - - :: etc... - - begin - - reserve D for DecoratedTree, - p,q,r for FinSequence of NAT, - x for set; - - definition - let D; - - attr D is LambdaTerm-like means - (dom D qua Tree) is finite & - ::> *143,306 - for r st r in dom D holds - r is FinSequence of {0,1} & - r^<*0*> in dom D implies D.r = 0; - end; - - registration - cluster LambdaTerm-like for DecoratedTree of NAT; - existence; - ::> *4 - end; - - definition - mode LambdaTerm is LambdaTerm-like DecoratedTree of NAT; - end; - - ::: Then we extend this ordinary one-step beta reduction, that is, - ::: any subterm is also allowed to reduce. - definition - let M,N; - - pred M beta N means - ex p st - M|p beta_shallow N|p & - for q st not p is_a_prefix_of q holds - [r,x] in M iff [r,x] in N; - end; - - theorem Th4: - ProperPrefixes (v^<*x*>) = ProperPrefixes v \/ {v} - proof - thus ProperPrefixes (v^<*x*>) c= ProperPrefixes v \/ {v} - proof - let y; - assume y in ProperPrefixes (v^<*x*>); - then consider v1 such that - A1: y = v1 and - A2: v1 is_a_proper_prefix_of v^<*x*> by TREES_1:def 2; - v1 is_a_prefix_of v & v1 <> v or v1 = v by A2,TREES_1:9; - then - v1 is_a_proper_prefix_of v or v1 in {v} by TARSKI:def 1,XBOOLE_0:def 8; - then y in ProperPrefixes v or y in {v} by A1,TREES_1:def 2; - hence thesis by XBOOLE_0:def 3; - end; - let y; - assume y in ProperPrefixes v \/ {v}; - then A3: y in ProperPrefixes v or y in {v} by XBOOLE_0:def 3; - A4: now - assume y in ProperPrefixes v; - then consider v1 such that - A5: y = v1 and - A6: v1 is_a_proper_prefix_of v by TREES_1:def 2; - v is_a_prefix_of v^<*x*> by TREES_1:1; - then v1 is_a_proper_prefix_of v^<*x*> by A6,XBOOLE_1:58; - hence thesis by A5,TREES_1:def 2; - end; - v^{} = v by FINSEQ_1:34; - then - v is_a_prefix_of v^<*x*> & v <> v^<*x*> by FINSEQ_1:33,TREES_1:1; - then v is_a_proper_prefix_of v^<*x*> by XBOOLE_0:def 8; - then y in ProperPrefixes v or y = v & v in ProperPrefixes (v^<*x*>) - by A3,TARSKI:def 1,TREES_1:def 2; - hence thesis by A4; - end; + ReadArchive "Lamp.002_Light/instance.rib" + Surface "plastic" + ReadArchive "Cube.004_Mesh/instance.rib" + # ReadArchive "Sphere.010_Mesh/instance.rib" + # ReadArchive "Sphere.009_Mesh/instance.rib" + ReadArchive "Sphere.006_Mesh/instance.rib" + + WorldEnd + FrameEnd + +## MEL (Maya Embedded Language) + + proc string[] getSelectedLights() + + { + string $selectedLights[]; + + string $select[] = `ls -sl -dag -leaf`; + + for ( $shape in $select ) + { + // Determine if this is a light. + // + string $class[] = getClassification( `nodeType $shape` ); + + + if ( ( `size $class` ) > 0 && ( "light" == $class[0] ) ) + { + $selectedLights[ `size $selectedLights` ] = $shape; + } + } + + // Result is an array of all lights included in + + // current selection list. + return $selectedLights; + } + +## GLSL + + // vertex shader + #version 150 + in vec2 in_Position; + in vec3 in_Color; + + out vec3 ex_Color; + void main(void) { + gl_Position = vec4(in_Position.x, in_Position.y, 0.0, 1.0); + ex_Color = in_Color; + } + + + // geometry shader + #version 150 + + layout(triangles) in; + layout(triangle_strip, max_vertices = 3) out; + + void main() { + for(int i = 0; i < gl_in.length(); i++) { + gl_Position = gl_in[i].gl_Position; + EmitVertex(); + } + EndPrimitive(); + } + + + // fragment shader + #version 150 + precision highp float; + + in vec3 ex_Color; + out vec4 gl_FragColor; + + void main(void) { + gl_FragColor = vec4(ex_Color, 1.0); + } + +## SQL + + BEGIN; + CREATE TABLE "topic" ( + "id" serial NOT NULL PRIMARY KEY, + "forum_id" integer NOT NULL, + "subject" varchar(255) NOT NULL + ); + ALTER TABLE "topic" ADD CONSTRAINT forum_id FOREIGN KEY ("forum_id") REFERENCES "forum" ("id"); + + -- Initials + insert into "topic" ("forum_id", "subject") values (2, 'D''artagnian'); + + select count(*) from cicero_forum; + + -- this line lacks ; at the end to allow people to be sloppy and omit it in one-liners + COMMIT + +## SmallTalk + + Object>>method: num + "comment 123" + | var1 var2 | + (1 to: num) do: [:i | |var| ^i]. + Klass with: var1. + Klass new. + arr := #('123' 123.345 #hello Transcript var $@). + arr := #(). + var2 = arr at: 3. + ^ self abc + + heapExample + "HeapTest new heapExample" + "Multiline + decription" + | n rnd array time sorted | + n := 5000. + "# of elements to sort" + rnd := Random new. + array := (1 to: n) + collect: [:i | rnd next]. + "First, the heap version" + time := Time + millisecondsToRun: [sorted := Heap withAll: array. + 1 + to: n + do: [:i | + sorted removeFirst. + sorted add: rnd next]]. + Transcript cr; show: 'Time for Heap: ' , time printString , ' msecs'. + "The quicksort version" + time := Time + millisecondsToRun: [sorted := SortedCollection withAll: array. + 1 + to: n + do: [:i | + sorted removeFirst. + sorted add: rnd next]]. + Transcript cr; show: 'Time for SortedCollection: ' , time printString , ' msecs' + +## Lisp + + #!/usr/bin/env csi + + (defun prompt-for-cd () + "Prompts + for CD" + (prompt-read "Title" 1.53 1 2/4 1.7 1.7e0 2.9E-4 +42 -7 #b001 #b001/100 #o777 #O777 #xabc55 #c(0 -5.6)) + (prompt-read "Artist" &rest) + (or (parse-integer (prompt-read "Rating") :junk-allowed t) 0) + (if x (format t "yes") (format t "no" nil) ;and here comment + ) + ;; second line comment + '(+ 1 2) + (defvar *lines*) ; list of all lines + (position-if-not #'sys::whitespacep line :start beg)) + (quote (privet 1 2 3)) + '(hello world) + (* 5 7) + (1 2 34 5) + (:use "aaaa") + (let ((x 10) (y 20)) + (print (+ x y)) + ) + +## Clojure + + ; You must not remove this notice, or any other, from this software. + + (ns ^{:doc "The core Clojure language." + :author "Rich Hickey"} + clojure.core) + + (def unquote) + + (def + ^{:macro true + :added "1.0"} + let (fn* let [&form &env & decl] (cons 'let* decl))) + + (def + + defn (fn defn [&form &env name & fdecl] + (let [m (conj {:arglists (list 'quote (sigs fdecl))} m) + m (let [inline (:inline m) + ifn (first inline) + iname (second inline)] + ;; same as: (if (and (= 'fn ifn) (not (symbol? iname))) ...) + (if (if (clojure.lang.Util/equiv 'fn ifn) + (if (instance? clojure.lang.Symbol iname) false true)) + ;; inserts the same fn name to the inline fn if it does not have one + (assoc m :inline (cons ifn (cons (clojure.lang.Symbol/intern (.concat (.getName ^clojure.lang.Symbol name) "__inliner")) + (next inline)))) + m)) + m (conj (if (meta name) (meta name) {}) m)] + (list 'def (with-meta name m) + ;;todo - restore propagation of fn name + ;;must figure out how to convey primitive hints to self calls first + (cons `fn fdecl) )))) + + (. (var defn) (setMacro)) + +## Ini file + + ;Settings relating to the location and loading of the database + [Database] + ProfileDir=. + ShowProfileMgr=smart + Profile1_Name[] = "\|/_-=MegaDestoyer=-_\|/" + DefaultProfile=True + AutoCreate = no + + [AutoExec] + use-prompt="prompt" + Glob=autoexec_*.ini + AskAboutIgnoredPlugins=0 + +## Apache + + # rewrite`s rules for wordpress pretty url + LoadModule rewrite_module modules/mod_rewrite.so + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . index.php [NC,L] + + ExpiresActive On + ExpiresByType application/x-javascript "access plus 1 days" + + + RewriteMap map txt:map.txt + RewriteMap lower int:tolower + RewriteCond %{REQUEST_URI} ^/([^/.]+)\.html$ [NC] + RewriteCond ${map:${lower:%1}|NOT_FOUND} !NOT_FOUND + RewriteRule .? /index.php?q=${map:${lower:%1}} [NC,L] + + +## nginx + + user www www; + worker_processes 2; + pid /var/run/nginx.pid; + error_log /var/log/nginx.error_log debug | info | notice | warn | error | crit; + + events { + connections 2000; + use kqueue | rtsig | epoll | /dev/poll | select | poll; + } + + http { + log_format main '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $bytes_sent ' + '"$http_referer" "$http_user_agent" ' + '"$gzip_ratio"'; + + send_timeout 3m; + client_header_buffer_size 1k; + + gzip on; + gzip_min_length 1100; + + #lingering_time 30; + + server { + server_name one.example.com www.one.example.com; + access_log /var/log/nginx.access_log main; + + rewrite (.*) /index.php?page=$1 break; + + location / { + proxy_pass http://127.0.0.1/; + proxy_redirect off; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + charset koi8-r; + } + + location /api/ { + fastcgi_pass 127.0.0.1:9000; + } + + location ~* \.(jpg|jpeg|gif)$ { + root /spool/www; + } + } + } + +## Diff + + Index: languages/ini.js + =================================================================== + --- languages/ini.js (revision 199) + +++ languages/ini.js (revision 200) + @@ -1,8 +1,7 @@ + hljs.LANGUAGES.ini = + { + case_insensitive: true, + - defaultMode: + - { + + defaultMode: { + contains: ['comment', 'title', 'setting'], + illegal: '[^\\s]' + }, + + *** /path/to/original timestamp + --- /path/to/new timestamp + *************** + *** 1,3 **** + --- 1,9 ---- + + This is an important + + notice! It should + + therefore be located at + + the beginning of this + + document! + + ! compress the size of the + ! changes. + + It is important to spell + +## DOS batch files + + cd \ + copy a b + ping 192.168.0.1 + @rem ping 192.168.0.1 + net stop sharedaccess + del %tmp% /f /s /q + del %temp% /f /s /q + ipconfig /flushdns + taskkill /F /IM JAVA.EXE /T + + cd Photoshop/Adobe Photoshop CS3/AMT/ + if exist application.sif ( + ren application.sif _application.sif + ) else ( + ren _application.sif application.sif + ) + + taskkill /F /IM proquota.exe /T + + sfc /SCANNOW + + set path = test + + xcopy %1\*.* %2 + +## Bash + + #!/bin/bash + + ###### BEGIN CONFIG + ACCEPTED_HOSTS="/root/.hag_accepted.conf" + BE_VERBOSE=false + ###### END CONFIG + + if [ "$UID" -ne 0 ] + then + echo "Superuser rights is required" + echo 'Printing the # sign' + exit 2 + fi + + if test $# -eq 0 + then + elif test [ $1 == 'start' ] + else + fi + + genApacheConf(){ + if [[ "$2" = "www" ]] + then + full_domain=$1 + else + full_domain=$2.$1 + fi + host_root="${APACHE_HOME_DIR}$1/$2/$(title)" + echo -e "# Host $1/$2 :" + } + +## CMake + + project(test) + cmake_minimum_required(VERSION 2.6) + + # IF LINUX + if (${CMAKE_SYSTEM_NAME} MATCHES Linux) + message("\nOS:\t\tLinux") + endif() + + # IF WINDOWS + if (${CMAKE_SYSTEM_NAME} MATCHES Windows) + message("\nOS:\t\tWindows") + endif() + + set(test test0.cpp test1.cpp test2.cpp) + + include_directories(./) + + set(EXECUTABLE_OUTPUT_PATH ../bin) + + add_subdirectory(src) + + add_executable(test WIN32 ${test}) + + target_link_libraries(test msimg32) + +## Axapta + + class ExchRateLoadBatch extends RunBaseBatch { + ExchRateLoad rbc; + container currencies; + boolean actual; + boolean overwrite; + date beg; + date end; + + #define.CurrentVersion(5) + + #localmacro.CurrentList + currencies, + actual, + beg, + end + #endmacro + } + + public boolean unpack(container packedClass) { + container base; + boolean ret; + Integer version = runbase::getVersion(packedClass); + + switch (version) { + case #CurrentVersion: + [version, #CurrentList] = packedClass; + return true; + default: + return false; + } + return ret; + } + +## Oracle Rules Language + + //This is a comment + ABORT "You experienced an abort."; + WARN "THIS IS A WARNING"; + CALL "RIDER_X"; + DONE; + FOR EACH X IN CSV_FILE "d:\lodestar\user\d377.lse" + LEAVE FOR; + END FOR; + IF ((BILL_KW = 0) AND (KW > 0)) THEN + END IF; + INCLUDE "R1"; + LEAVE RIDER; + SELECT BILL_PERIOD + WHEN "WINTER" + BLOCK KWH + FROM 0 TO 400 CHARGE $0.03709 + FROM 400 CHARGE $0.03000 + TOTAL $ENERGY_CHARGE_WIN; + WHEN "SUMMER" + $VOLTAGE_DISCOUNT_SUM = $0.00 + OTHERWISE + $VOLTAGE_DISCOUNT_SUM = $1.00 + END SELECT; + /* Report top five peaks */ + LABEL PK.NM "Peak Number"; + SAVE_UPDATE MV TO TABLE "METERVALUE"; + + FOR EACH INX IN ARRAYUPPERBOUND(#MYARRAY[]) + #MYARRAY[INX].VALUE = 2; + CLEAR #MYARRAY[]; + END FOR + + //Interval Data + HNDL_1_ADD_EDI = INTDADDATTRIBUTE(HNDL_1, "EDI_TRANSACTION", EDI_ID); + HNDL_1_ADD_VAL_MSG = INTDADDVMSG(HNDL_1,"Missing (Status Code 9) values found"); + EMPTY_HNDL = INTDCREATEHANDLE('05/03/2006 00:00:00', '05/03/2006 23:59:59', 3600, "Y", "0", " "); + +## 1С + + #Если Клиент Тогда + Перем СимвольныйКодКаталога = "ля-ля-ля"; //комментарий + Функция Сообщить(Знач ТекстСообщения, ТекстСообщения2) Экспорт //комментарий к функции + x=ТекстСообщения+ТекстСообщения2+" + |строка1 + |строка2 + |строка3"; + КонецФункции + #КонецЕсли + + // Процедура ПриНачалеРаботыСистемы + // + Процедура ПриНачалеРаботыСистемы() + Обработки.Помощник.ПолучитьФорму("Форма").Открыть(); + d = '21.01.2008' + КонецПроцедуры + +## AVR Assembler + + ;* Title: Block Copy Routines + ;* Version: 1.1 + + .include "8515def.inc" + + rjmp RESET ;reset handle + + .def flashsize=r16 ;size of block to be copied + + flash2ram: + lpm ;get constant + st Y+,r0 ;store in SRAM and increment Y-pointer + adiw ZL,1 ;increment Z-pointer + dec flashsize + brne flash2ram ;if not end of table, loop more + ret + + .def ramtemp =r1 ;temporary storage register + .def ramsize =r16 ;size of block to be copied + +## VHDL + + /* + * RS-trigger with assynch. reset + */ + + library ieee; + use ieee.std_logic_1164.all; + + entity RS_trigger is + generic (T: Time := 0ns); + port ( R, S : in std_logic; + Q, nQ : out std_logic; + reset, clock : in std_logic ); + end RS_trigger; + + architecture behaviour of RS_trigger is + signal QT: std_logic; -- Q(t) + begin + process(clock, reset) is + subtype RS is std_logic_vector (1 downto 0); + begin + if reset = '0' then + QT <= '0'; + else + if rising_edge(C) then + if not (R'stable(T) and S'stable(T)) then + QT <= 'X'; + else + case RS'(R&S) is + when "01" => QT <= '1'; + when "10" => QT <= '0'; + when "11" => QT <= 'X'; + when others => null; + end case; + end if; + end if; + end if; + end process; + + Q <= QT; + nQ <= not QT; + end architecture behaviour; + +## Parser 3 + + @CLASS + base + + @USE + module.p + + @BASE + class + + # Comment for code + @create[aParam1;aParam2][local1;local2] + ^connect[mysql://host/database?ClientCharset=windows-1251] + ^for[i](1;10){ +

    ^eval($i+10)

    + ^connect[mysql://host/database]{ + $tab[^table::sql{select * from `table` where a='1'}] + $var_Name[some${value}] + } + } + + ^rem{ + Multiline comment with code: $var + ^while(true){ + ^for[i](1;10){ + ^sleep[] + } + } + } + ^taint[^#0A] + + @GET_base[] + ## Comment for code + # Isn't comment + $result[$.hash_item1[one] $.hash_item2[two]] + +## TeX + + \documentclass{article} + \usepackage[koi8-r]{inputenc} + \hoffset=0pt + \voffset=.3em + \tolerance=400 + \newcommand{\eTiX}{\TeX} + \begin{document} + \section*{Highlight.js} + \begin{table}[c|c] + $\frac 12\, + \, \frac 1{x^3}\text{Hello \! world}$ & \textbf{Goodbye\~ world} \\\eTiX $ \pi=400 $ + \end{table} + Ch\'erie, \c{c}a ne me pla\^\i t pas! % comment \b + G\"otterd\"ammerung~45\%=34. + $$ + \int\limits_{0}^{\pi}\frac{4}{x-7}=3 + $$ + \end{document} + +## Haskell + + {-# LANGUAGE TypeSynonymInstances #-} + module Network.UDP + ( DataPacket(..) + , openBoundUDPPort + , openListeningUDPPort + , pingUDPPort + , sendUDPPacketTo + , recvUDPPacket + , recvUDPPacketFrom + ) where + + {- this is a {- nested -} comment -} + + import qualified Data.ByteString as Strict (ByteString, concat, singleton) + import qualified Data.ByteString.Lazy as Lazy (ByteString, toChunks, fromChunks) + import Data.ByteString.Char8 (pack, unpack) + import Network.Socket hiding (sendTo, recv, recvFrom) + import Network.Socket.ByteString (sendTo, recv, recvFrom) + + -- Type class for converting StringLike types to and from strict ByteStrings + class DataPacket a where + toStrictBS :: a -> Strict.ByteString + fromStrictBS :: Strict.ByteString -> a + + instance DataPacket Strict.ByteString where + toStrictBS = id + {-# INLINE toStrictBS #-} + fromStrictBS = id + {-# INLINE fromStrictBS #-} + + openBoundUDPPort :: String -> Int -> IO Socket + openBoundUDPPort uri port = do + s <- getUDPSocket + bindAddr <- inet_addr uri + let a = SockAddrInet (toEnum port) bindAddr + bindSocket s a + return s + + pingUDPPort :: Socket -> SockAddr -> IO () + pingUDPPort s a = sendTo s (Strict.singleton 0) a >> return () + +## Erlang + + -module(ssh_cli). + + -behaviour(ssh_channel). + + -include("ssh.hrl"). + %% backwards compatibility + -export([listen/1, listen/2, listen/3, listen/4, stop/1]). + + %% state + -record(state, { + cm, + channel + }). + + test(Foo)->Foo. + + init([Shell, Exec]) -> + {ok, #state{shell = Shell, exec = Exec}}; + init([Shell]) -> + false = not true, + io:format("Hello, \"~p!~n", [atom_to_list('World')]), + {ok, #state{shell = Shell}}. + + concat([Single]) -> Single; + concat(RList) -> + EpsilonFree = lists:filter( + fun (Element) -> + case Element of + epsilon -> false; + _ -> true + end + end, + RList), + case EpsilonFree of + [Single] -> Single; + Other -> {concat, Other} + end. + + union_dot_union({union, _}=U1, {union, _}=U2) -> + union(lists:flatten( + lists:map( + fun (X1) -> + lists:map( + fun (X2) -> + concat([X1, X2]) + end, + union_to_list(U2) + ) + end, + union_to_list(U1) + ))). + +## Erlang REPL + + 1> Str = "abcd". + "abcd" + 2> L = test:length(Str). + 4 + 3> Descriptor = {L, list_to_atom(Str)}. + {4,abcd} + 4> L. + 4 + 5> b(). + Descriptor = {4,abcd} + L = 4 + Str = "abcd" + ok + 6> f(L). + ok + 7> b(). + Descriptor = {4,abcd} + Str = "abcd" + ok + 8> {L, _} = Descriptor. + {4,abcd} + 9> L. + 4 + 10> 2#101. + 5 + 11> 1.85e+3. + 1850 + +## Rust + + use std; + + import std::io; + export fac, test1; + + 123; // type int + 123u; // type uint + 123_u; // type uint + 0xff00; // type int + 0xff_u8; // type u8 + 0b1111_1111_1001_0000_i32; // type i32 + 123.0; // type float + 0.1; // type float + 3f; // type float + 0.1f32; // type f32 + 12E+99_f64; // type f64 + + /* Factorial */ + fn fac(n: int) -> int { + let s: str = "This is + a multi-line string. + + It ends with an unescaped '\"'."; + let c: char = 'Ф'; + + let result = 1, i = 1; + while i <= n { // No parens around the condition + result *= i; + i += 1; + } + ret result; + } + + pure fn pure_length(ls: list) -> uint { /* ... */ } + + type t = map::hashtbl; + let x = id::(10); + + // Define some modules. + #[path = "foo.rs"] + mod foo; + + iface seq { + fn len() -> uint; + } + + impl of seq for [T] { + fn len() -> uint { vec::len(self) } + fn iter(b: fn(T)) { + for elt in self { b(elt); } + } + } + + enum list { + nil; + cons(T, @list); + } + + let a: list = cons(7, @cons(13, @nil)); + +## Matlab + + n = 20; % number of points + points = [random('unid', 100, n, 1), random('unid', 100, n, 1)]; + len = zeros(1, n - 1); + points = sortrows(points); + %% Initial set of points + plot(points(:,1),points(:,2)); + for i = 1: n-1 + len(i) = points(i + 1, 1) - points(i, 1); + end + while(max(len) > 2 * min(len)) + [d, i] = max(len); + k = on_margin(points, i, d, -1); + m = on_margin(points, i + 1, d, 1); + xm = 0; ym = 0; + %% New point + if(i == 1 || i + 1 == n) + xm = mean(points([i,i+1],1)) + ym = mean(points([i,i+1],2)) + else + [xm, ym] = dlg1(points([k, i, i + 1, m], 1), ... + points([k, i, i + 1, m], 2)) + end + + points = [ points(1:i, :); [xm, ym]; points(i + 1:end, :)]; + end + + function [net] = get_fit_network(inputs, targets) + % Create Network + numHiddenNeurons = 20; % Adjust as desired + net = newfit(inputs,targets,numHiddenNeurons); + net.trainParam.goal = 0.01; + net.trainParam.epochs = 1000; + % Train and Apply Network + [net,tr] = train(net,inputs,targets); + end + + foo_matrix = [1, 2, 3; 4, 5, 6]'''; + foo_cell = {1, 2, 3; 4, 5, 6}''.'.'; + +## R + + library(ggplot2) + + centre <- function(x, type, ...) { + switch(type, + mean = mean(x), + median = median(x), + trimmed = mean(x, trim = .1)) + } + + myVar1 + myVar.2 + data$x + foo "bar" baz + # test "test" + "test # test" + + (123) (1) (10) (0.1) (.2) (1e-7) + (1.2e+7) (2e) (3e+10) (0x0) (0xa) + (0xabcdef1234567890) (123L) (1L) + (0x10L) (10000000L) (1e6L) (1.1L) + (1e-3L) (4123.381E-10i) + (3.) (3.E10) # BUG: .E10 should be part of number + + # Numbers in some different contexts + 1L + 0x40 + .234 + 3. + 1L + 30 + plot(cars, xlim=20) + plot(cars, xlim=0x20) + foo<-30 + my.data.3 <- read() # not a number + c(1,2,3) + 1%%2 + + "this is a quote that spans + multiple lines + \" + + is this still a quote? it should be. + # even still! + + " # now we're done. + + 'same for + single quotes #' + + # keywords + NULL, NA, TRUE, FALSE, Inf, NaN, NA_integer_, + NA_real_, NA_character_, NA_complex_, function, + while, repeat, for, if, in, else, next, break, + ..., ..1, ..2 + + # not keywords + the quick brown fox jumped over the lazy dogs + null na true false inf nan na_integer_ na_real_ + na_character_ na_complex_ Function While Repeat + For If In Else Next Break .. .... "NULL" `NULL` 'NULL' + + # operators + +, -, *, /, %%, ^, >, >=, <, <=, ==, !=, !, &, |, ~, + ->, <-, <<-, $, :, :: + + # infix operator + foo %union% bar + %"test"% + `"test"` + +## Mizar + + ::: ## Lambda calculus + + environ + + vocabularies LAMBDA, + NUMBERS, + NAT_1, XBOOLE_0, SUBSET_1, FINSEQ_1, XXREAL_0, CARD_1, + ARYTM_1, ARYTM_3, TARSKI, RELAT_1, ORDINAL4, FUNCOP_1; + + :: etc... + + begin + + reserve D for DecoratedTree, + p,q,r for FinSequence of NAT, + x for set; + + definition + let D; + + attr D is LambdaTerm-like means + (dom D qua Tree) is finite & + ::> *143,306 + for r st r in dom D holds + r is FinSequence of {0,1} & + r^<*0*> in dom D implies D.r = 0; + end; + + registration + cluster LambdaTerm-like for DecoratedTree of NAT; + existence; + ::> *4 + end; + + definition + mode LambdaTerm is LambdaTerm-like DecoratedTree of NAT; + end; + + ::: Then we extend this ordinary one-step beta reduction, that is, + ::: any subterm is also allowed to reduce. + definition + let M,N; + + pred M beta N means + ex p st + M|p beta_shallow N|p & + for q st not p is_a_prefix_of q holds + [r,x] in M iff [r,x] in N; + end; + + theorem Th4: + ProperPrefixes (v^<*x*>) = ProperPrefixes v \/ {v} + proof + thus ProperPrefixes (v^<*x*>) c= ProperPrefixes v \/ {v} + proof + let y; + assume y in ProperPrefixes (v^<*x*>); + then consider v1 such that + A1: y = v1 and + A2: v1 is_a_proper_prefix_of v^<*x*> by TREES_1:def 2; + v1 is_a_prefix_of v & v1 <> v or v1 = v by A2,TREES_1:9; + then + v1 is_a_proper_prefix_of v or v1 in {v} by TARSKI:def 1,XBOOLE_0:def 8; + then y in ProperPrefixes v or y in {v} by A1,TREES_1:def 2; + hence thesis by XBOOLE_0:def 3; + end; + let y; + assume y in ProperPrefixes v \/ {v}; + then A3: y in ProperPrefixes v or y in {v} by XBOOLE_0:def 3; + A4: now + assume y in ProperPrefixes v; + then consider v1 such that + A5: y = v1 and + A6: v1 is_a_proper_prefix_of v by TREES_1:def 2; + v is_a_prefix_of v^<*x*> by TREES_1:1; + then v1 is_a_proper_prefix_of v^<*x*> by A6,XBOOLE_1:58; + hence thesis by A5,TREES_1:def 2; + end; + v^{} = v by FINSEQ_1:34; + then + v is_a_prefix_of v^<*x*> & v <> v^<*x*> by FINSEQ_1:33,TREES_1:1; + then v is_a_proper_prefix_of v^<*x*> by XBOOLE_0:def 8; + then y in ProperPrefixes v or y = v & v in ProperPrefixes (v^<*x*>) + by A3,TARSKI:def 1,TREES_1:def 2; + hence thesis by A4; + end; diff --git a/docs/02_Examples/index.md b/docs/02_Examples/index.md index b6889cb..18ad171 100644 --- a/docs/02_Examples/index.md +++ b/docs/02_Examples/index.md @@ -1,2 +1,3 @@ ### This is a landing page for the Examples section -Adding a landing page is pretty simple, all you need to do is add an "index.md" file to the related folder. \ No newline at end of file + +Adding a landing page is pretty simple, all you need to do is add an "index.md" file to the related folder. diff --git a/docs/05_Configuration/Confluence_upload.md b/docs/05_Configuration/Confluence_upload.md index 99e0168..81035a5 100644 --- a/docs/05_Configuration/Confluence_upload.md +++ b/docs/05_Configuration/Confluence_upload.md @@ -1,21 +1,23 @@ -__Table of contents__ +**Table of contents** [TOC] ## Configuring the connection + The connection requires three parameters `base_url`, `user` and `pass`. While `user` and `pass` don't really need an explanation, for `base_url` you need to set the path to the server without `rest/api`, this will be added automatically. ```json { - "confluence": { - "base_url": "http://my_confluence_server.com/", - "user" : "my_username", - "pass" : "my_password" - } + "confluence": { + "base_url": "http://my_confluence_server.com/", + "user": "my_username", + "pass": "my_password" + } } ``` ## Where to upload + Now that the connection is defined, you need to tell it where you want your documentation to be uploaded. For that you need a `space_id` (name that appears at the beginning of the urls) and an `ancestor_id`; the id of the page that will be the parent of the documentation's homepage. @@ -24,10 +26,10 @@ You can obtain the `ancestor_id` id by editing the page you want to define as a ```json { - "confluence": { - "space_id": "my_space", - "ancestor_id": 50370632 - } + "confluence": { + "space_id": "my_space", + "ancestor_id": 50370632 + } } ``` @@ -36,20 +38,22 @@ You can also provide a `root_id` instead of an `ancestor_id` in this case, you s You can use that when you're uploading your documentation to the root of a Confluence Space or if your page already exists. ## Prefix + Because confluence can't have two pages with the same name in a space, I recommend you define a prefix for your pages. ```json { - "confluence": { "prefix": "DAUX -" } + "confluence": { "prefix": "DAUX -" } } ``` ## Update threshold + To make the upload quicker, we try to determine if a page changed or not, first with a strict comparison and if it's not completely identical, we compute the difference. ```json { - "confluence": { "update_threshold": 1 } + "confluence": { "update_threshold": 1 } } ``` @@ -59,22 +63,22 @@ By default the threshold is 2%. Setting the value to `0` disables the feature altogether. - ## Delete old pages + When a page is renamed, there is no way to tell it was renamed, so when uploading to Confluence, the page will be uploaded and the old page will stay here. By default, it will inform you that some pages aren't needed anymore and you can delete them by hand. ```json { - "confluence": { "delete": true } + "confluence": { "delete": true } } ``` By setting `delete` to `true` (or running `daux` with the `--delete` flag) you tell the generator that it can safely delete the pages. - ## Information message + When you create your page. there is no indication that the upload process will override the content of the pages. It happens sometimes that users edit the pages to add / fix an information. @@ -83,9 +87,9 @@ You can add a text in a "information" macro on top of the document by setting th ```json { - "confluence": { - "header": "These pages are updated automatically, your changes will be overriden." - } + "confluence": { + "header": "These pages are updated automatically, your changes will be overriden." + } } ``` diff --git a/docs/05_Configuration/Html_export.md b/docs/05_Configuration/Html_export.md index 4175751..abdfaa3 100644 --- a/docs/05_Configuration/Html_export.md +++ b/docs/05_Configuration/Html_export.md @@ -1,24 +1,26 @@ -__Table of contents__ +**Table of contents** [TOC] ## Analytics ### Google Analytics + This will embed the google analytics tracking code. ```json { - "html": { "google_analytics": "UA-XXXXXXXXX-XX" } + "html": { "google_analytics": "UA-XXXXXXXXX-XX" } } ``` ### Piwik Analytics + This will embed the piwik tracking code. ```json { - "html": { "piwik_analytics": "my-url-for-piwik.com" } + "html": { "piwik_analytics": "my-url-for-piwik.com" } } ``` @@ -26,110 +28,130 @@ You can Also give a specific Piwik ID as well. ```json { - "html": { "piwik_analytics_id": "43" } + "html": { "piwik_analytics_id": "43" } +} +``` + +### Plausible Analytics + +This will embed the https://plausible.io/ tracking code. + +```json +{ + "html": { "plausible_domain": "daux.io" } } ``` ## Automatic Table of Contents + You can add a table of contents on each page automatically, read about it [here](../01_Features/Table_of_contents.md) - ## Buttons + You can add buttons to the landing page. ```json { - "html": { - "buttons": { - "My Website": "http://example.com" + "html": { + "buttons": { + "My Website": "http://example.com" + } } - } } ``` ## Breadcrumb titles -Daux.io provides the option to present page titles as breadcrumb navigation. -You can *optionally* specify the separator used for breadcrumbs. + +Daux.io provides the option to present page titles as breadcrumb navigation. +You can _optionally_ specify the separator used for breadcrumbs. ```json { - "html": { - "breadcrumbs": true, - "breadcrumb_separator" : " > " - } + "html": { + "breadcrumbs": true, + "breadcrumb_separator": " > " + } } ``` ## Date Modified -By default, daux.io will display the last modified time as reported by the system underneath the title for each document. + +By default, daux.io will display the last modified time as reported by the system underneath the title for each document. To disable this, change the option in your config.json to `false`. ```json { - "html": { "date_modified": false } + "html": { "date_modified": false } } ``` ## GitHub Repo + Add a 'Fork me on GitHub' ribbon. ```json { - "html": { "repo": "dauxio/daux.io" } + "html": { "repo": "dauxio/daux.io" } } ``` ## Inherit Index + This feature will instructs the navigation generator to seek the first available file to use when there is no index in a folder. ```json { - "html": { "inherit_index": true } + "html": { "inherit_index": true } } ``` ## Jump buttons + You can have previous/next buttons on each page. They can be disabled by setting `jump_buttons` to `false`. ```json { - "html": { "jump_buttons": false } + "html": { "jump_buttons": false } } ``` ## Landing page -The automatic landing page can be disabled through the `auto_landing` option, read about it [here](../01_Features/Landing_page.md) + +The automatic landing page can be disabled through the `auto_landing` option, read about it [here](../01_Features/Landing_page.md) ## Links + Include custom links in the sidebar. ```json { - "html": { - "links": { - "GitHub Repo": "https://github.com/dauxio/daux.io", - "Help/Support/Bugs": "https://github.com/dauxio/daux.io/issues", - "Made by Todaymade": "http://todaymade.com" + "html": { + "links": { + "GitHub Repo": "https://github.com/dauxio/daux.io", + "Help/Support/Bugs": "https://github.com/dauxio/daux.io/issues", + "Made by Todaymade": "http://todaymade.com" + } } - } } ``` ## Search + Daux has an embedded search engine read all about it [here](../01_Features/Search.md) ## Themes + We have 4 built-in Bootstrap themes. To use one of the themes, just set the `theme` option to one of the following: -* daux-blue -* daux-green -* daux-navy -* daux-red +- daux-blue +- daux-green +- daux-navy +- daux-red ```json { - "html": { "theme": "daux-blue" } + "html": { "theme": "daux-blue" } } ``` @@ -137,25 +159,27 @@ To use a custom theme, just copy over the theme folder into the `themes` directo ```json { - "html": { "theme": "new-theme" } + "html": { "theme": "new-theme" } } ``` ## Toggling Code Blocks -Some users might wish to hide the code blocks & view just the documentation. + +Some users might wish to hide the code blocks & view just the documentation. By setting the `toggle_code` property to `true`, you can offer a toggle button on the page. ```json { - "html": { "toggle_code": true } + "html": { "toggle_code": true } } ``` ## Twitter + Include twitter follow buttons in the sidebar. ```json { - "html": { "twitter": ["justin_walsh", "todaymade"] } + "html": { "twitter": ["justin_walsh", "todaymade"] } } ``` diff --git a/docs/05_Configuration/_index.md b/docs/05_Configuration/_index.md index 0e6f885..b0f97fc 100644 --- a/docs/05_Configuration/_index.md +++ b/docs/05_Configuration/_index.md @@ -1,91 +1,100 @@ To customize the look and feel of your documentation, you can create a `config.json` file in the of the `/docs` folder. The `config.json` file is a JSON object that you can use to change some of the basic settings of the documentation. -__Table of contents__ +**Table of contents** [TOC] ### Title + Change the title bar in the docs ```json { - "title": "Daux.io" + "title": "Daux.io" } ``` ### Tagline + Change the tagline bar in the docs ```json { - "tagline": "The Easiest Way To Document Your Project" + "tagline": "The Easiest Way To Document Your Project" } ``` ### Author + Change the documentation's author ```json { - "author": "Stéphane Goetz" + "author": "Stéphane Goetz" } ``` ### Image + An image to show on the landing page. A relative path from the documentation root. ```json { - "image": "image.png" + "image": "image.png" } ``` ### Format + Change the output format. It is recommended you set only formats that support the live mode as this will also be read by the integrated web server. And you set the other formats (like confluence) only by command line ```json { - "format": "html" + "format": "html" } ``` -- __html__ with [its options](./Html_export.md) -- __confluence__ with [its options](./Confluence_upload.md) +- **html** with [its options](./Html_export.md) +- **confluence** with [its options](./Confluence_upload.md) -Available formats are __HTML__ and __Confluence__ +Available formats are **HTML** and **Confluence** ### Ignore + Set custom files and entire folders to ignore within your `/docs` folder. For files make sure to include the file extension in the name. For both files and folders, names are case-sensitive. ```json { - "ignore": { - "files": ["Work_In_Progress.md"], - "folders": ["99_Not_Ready"] - } + "ignore": { + "files": ["Work_In_Progress.md"], + "folders": ["99_Not_Ready"] + } } ``` ### Timezone + If your server does not have a default timezone set in php.ini, it may return errors when it tries to generate the last modified date/time for docs. To fix these errors, specify a timezone in your config file. Valid options are available in the [PHP Manual](http://php.net/manual/en/timezones.php). ```json { - "timezone": "America/Los_Angeles" + "timezone": "America/Los_Angeles" } ``` ### Multi-language + Enables multi-language support which needs separate directories for each language in `docs/` folder. ```json { - "languages": {"en": "English", "de": "German"} + "languages": { "en": "English", "de": "German" } } ``` Directory structure: + ``` ├── docs/ │ ├── _index.md @@ -113,7 +122,7 @@ You can change the default language with the `language` option. ```json { - "language": "fr" + "language": "fr" } ``` @@ -124,31 +133,28 @@ A string that isn't found will fall back to english. ```json { - "strings": { - "fr": { - "CodeBlocks_title": "Afficher le code", - "CodeBlocks_hide": "Non", - "CodeBlocks_below": "En Dessous", - "CodeBlocks_inline": "A côté", - "CodeBlocks_show": "Afficher le code", - "Search_placeholder": "Rechercher...", - "Link_previous": "Précédent", - "Link_next": "Suivant", - "Edit_on": "Editer sur :name:", - "View_on_github": "Voir sur GitHub", - "View_documentation": "Voir la Documentation" + "strings": { + "fr": { + "CodeBlocks_show": "Afficher le code", + "Search_placeholder": "Rechercher...", + "Link_previous": "Précédent", + "Link_next": "Suivant", + "Edit_on": "Editer sur :name:", + "View_on_github": "Voir sur GitHub", + "View_documentation": "Voir la Documentation" + } } - } } ``` ### Processor + You can set the processor in the documentation or as an option to the command line. If you need it when running the server, you should add it to the configuration. More information on how to create a Processor can be found [here](!For_Developers/Creating_a_Processor). - + ```json { - "processor": "MyProcessor" + "processor": "MyProcessor" } ``` diff --git a/docs/10_For_Developers/Creating_a_Processor.md b/docs/10_For_Developers/Creating_a_Processor.md index 2bf56c1..d5ecc79 100644 --- a/docs/10_For_Developers/Creating_a_Processor.md +++ b/docs/10_For_Developers/Creating_a_Processor.md @@ -7,7 +7,7 @@ The main advantage, is that you can run it with the source or with `daux` indepe Next to your `docs` directory, you can create a `daux` directory that can contain your Processor. The classes must respect the PSR-4 Naming convention. And have `\Todaymade\Daux\Extension` as a base namespace. - + By default, we created a `daux/Processor.php` file to get you started. ## A quick test ? @@ -40,7 +40,7 @@ There are a few methods that you can override to add some By default, Daux.io parses your directory to find pages. but, for a reason or another, you might want to programmatically add some pages. -This can be done with: +This can be done with: ```php public function manipulateTree(Root $root) @@ -65,7 +65,7 @@ Both methods `getOrCreateDir` and `getOrCreatePage` take two parameters : `paren 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 @@ -82,9 +82,9 @@ See the details on [CommonMark's website](http://commonmark.thephpleague.com/cus ### Add new generators -You can add new generators to Daux.io and use them right away, they must implement the -`\Todaymade\Daux\Format\Base\Generator` interface and if you want to use the live mode with your generator -you have to implement `\Todaymade\Daux\Format\Base\LiveGenerator`. +You can add new generators to Daux.io and use them right away, they must implement the +`\Todaymade\Daux\Format\Base\Generator` interface and if you want to use the live mode with your generator +you have to implement `\Todaymade\Daux\Format\Base\LiveGenerator`. ```php public function addGenerators() @@ -92,4 +92,3 @@ public function addGenerators() return ['custom_generator' => '\Todaymade\Daux\Extension\MyNewGenerator']; } ``` - diff --git a/docs/10_For_Developers/Creating_a_Theme.md b/docs/10_For_Developers/Creating_a_Theme.md index a8e50b4..4174a66 100644 --- a/docs/10_For_Developers/Creating_a_Theme.md +++ b/docs/10_For_Developers/Creating_a_Theme.md @@ -2,49 +2,56 @@ In its simplest form, a theme is an empty folder with a `config.json` file conta After that, every setting is optional, but you can override everything if you'd like to. +> **Overriding styles** +> +> If you want to tweak a few styles, you can create a `style.css` file at the root of your documentation +> directory and it will be included automatically. By doing this, you don't need to create a new theme. + ## `config.json` options Here is an example `config.json` file : ```json { - "favicon": "img/favicon.png", - "css": ["css/theme.min.css"], - "js": [], - "fonts": ["https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700&subset=latin,cyrillic-ext,cyrillic"], - "variants": { - "blue": { - "favicon": "img/favicon-blue.png", - "css": ["css/theme-blue.min.css"] - }, - "green": { - "favicon": "img/favicon-green.png", - "css": ["css/theme-green.min.css"] + "favicon": "img/favicon.png", + "css": ["css/theme.min.css"], + "js": [], + "fonts": [ + "https://fonts.googleapis.com/css?family=Roboto+Slab:400,100,300,700&subset=latin,cyrillic-ext,cyrillic" + ], + "variants": { + "blue": { + "favicon": "img/favicon-blue.png", + "css": ["css/theme-blue.min.css"] + }, + "green": { + "favicon": "img/favicon-green.png", + "css": ["css/theme-green.min.css"] + } } - } } ``` There are five options : -- __`favicon`__: The URL to your favicon -- __`css`__: An array of CSS Stylesheets to add to the page -- __`js`__: An array of JavaScript files to load -- __`fonts`__: An array of Font sources, these are added as stylesheets -- __`variants`__: An object containing sub-themes. Each sub theme, can provide the same configurations as the main theme (`favicon`, `css`, `js`, `fonts`) +- **`favicon`**: The URL to your favicon +- **`css`**: An array of CSS Stylesheets to add to the page +- **`js`**: An array of JavaScript files to load +- **`fonts`**: An array of Font sources, these are added as stylesheets +- **`variants`**: An object containing sub-themes. Each sub theme, can provide the same configurations as the main theme (`favicon`, `css`, `js`, `fonts`) - -You will also notice this `` in the url. +You will also notice this `` in the url. This is automatically substituted with the final url to the theme when generating the final page. There are two possible substitutions : - - __``__: The url to the current theme - - __``__: The url to the documentation root - + +- **``**: The url to the current theme +- **``**: The url to the documentation root + ## Theme variants - + Like the default Daux.io theme, you might want to provide variants of your theme. - + In the example before, there were two variants : blue and green. The configuration of a variant is added to the configuration of the main theme, it doesn't replace it. @@ -63,10 +70,10 @@ Change the `theme` option inside `html` ```json { - "themes_directory": "/home/user/themes", - "html": { - "theme": "{theme}-{variant}" - } + "themes_directory": "/home/user/themes", + "html": { + "theme": "{theme}-{variant}" + } } ``` @@ -85,11 +92,12 @@ You can create a folder named `templates` in your theme, copy-paste the original You can even do it one template at a time if you wish to do only small changes. By default, we have the following templates : -- `content.php`: The content page. -- `home.php`: The landing page. -- `error.php`: The page to show when a page is not found or some other error happened. -- `partials/navbar_content.php`: The content of the top navigation bar. -- `partials/google_analytics.php`: The script to load Google Analytics. -- `partials/piwik_analytics.php`: The script to load Piwik Analytics. -- `layout/00_layout.php`: The master template, containing the `` tag. -- `layout/05_page.php`: The page layout, with left navigation. + +- `content.php`: The content page. +- `home.php`: The landing page. +- `error.php`: The page to show when a page is not found or some other error happened. +- `partials/navbar_content.php`: The content of the top navigation bar. +- `partials/google_analytics.php`: The script to load Google Analytics. +- `partials/piwik_analytics.php`: The script to load Piwik Analytics. +- `layout/00_layout.php`: The master template, containing the `` tag. +- `layout/05_page.php`: The page layout, with left navigation. diff --git a/docs/_index.md b/docs/_index.md index c42b25d..87a9ca7 100644 --- a/docs/_index.md +++ b/docs/_index.md @@ -13,37 +13,37 @@ #### For Authors -* [Auto Generated Navigation / Page sorting](01_Features/Navigation_and_Sorting.md) -* [Internal documentation links](01_Features/Internal_links.md) -* [CommonMark compliant](01_Features/CommonMark_compliant.md) -* [Auto created homepage/landing page](01_Features/Landing_page.md) -* [Multiple Output Formats](01_Features/Multiple_Output_Formats.md) -* [Multiple Languages Support](01_Features/Multilanguage.md) -* [No Build Step](01_Features/Live_mode.md) -* [Static Output Generation](01_Features/Static_Site_Generation.md) -* [Table of Contents](01_Features/Table_of_contents.md) +- [Auto Generated Navigation / Page sorting](01_Features/Navigation_and_Sorting.md) +- [Internal documentation links](01_Features/Internal_links.md) +- [CommonMark compliant](01_Features/CommonMark_compliant.md) +- [Auto created homepage/landing page](01_Features/Landing_page.md) +- [Multiple Output Formats](01_Features/Multiple_Output_Formats.md) +- [Multiple Languages Support](01_Features/Multilanguage.md) +- [No Build Step](01_Features/Live_mode.md) +- [Static Output Generation](01_Features/Static_Site_Generation.md) +- [Table of Contents](01_Features/Table_of_contents.md)
    #### For Developers -* [Auto Syntax Highlighting](01_Features/Auto_Syntax_Highlight.md) -* [Extend Daux.io with Processors](01_For_Developers/Creating_a_Processor.md) -* Full access to the internal API to create new pages programatically -* Work with pages metadata +- [Auto Syntax Highlighting](01_Features/Auto_Syntax_Highlight.md) +- [Extend Daux.io with Processors](01_For_Developers/Creating_a_Processor.md) +- Full access to the internal API to create new pages programatically +- Work with pages metadata
    #### For Marketing -* 100% Mobile Responsive -* 4 Built-In Themes or roll your own -* Functional, Flat Design Style -* Optional code float layout -* Shareable/Linkable SEO Friendly URLs -* Supports Google Analytics and Piwik Analytics +- 100% Mobile Responsive +- 4 Built-In Themes or roll your own +- Functional, Flat Design Style +- Optional code float layout +- Shareable/Linkable SEO Friendly URLs +- Supports Google Analytics and Piwik Analytics
    @@ -52,7 +52,7 @@ ### Installation and usage -If you have __PHP__ and Composer installed +If you have **PHP** and Composer installed ```bash composer global require daux/daux.io @@ -61,7 +61,7 @@ composer global require daux/daux.io daux generate ``` -Or if you wish to use __Docker__ +Or if you wish to use **Docker** ```bash # Next to your `docs` folder, run @@ -69,18 +69,3 @@ docker run --rm -it -w /build -v "$PWD":/build daux/daux.io daux generate ``` --- - - - - - - diff --git a/docs/app-thumbs.png b/docs/app-thumbs.png index 8dff7c7..50096ec 100644 Binary files a/docs/app-thumbs.png and b/docs/app-thumbs.png differ diff --git a/docs/app.png b/docs/app.png index bb408b2..4d30e7b 100644 Binary files a/docs/app.png and b/docs/app.png differ diff --git a/docs/config.json b/docs/config.json index 5d17c32..ddcdf20 100644 --- a/docs/config.json +++ b/docs/config.json @@ -21,13 +21,14 @@ "repo": "dauxio/daux.io", "edit_on_github": "dauxio/daux.io/blob/master/docs", "twitter": ["onigoetz"], - "google_analytics": "UA-3551397-7", + "google_analytics": false, + "plausible_domain": false, "links": { - "Download": "https://github.com/dauxio/daux.io/archive/master.zip", - "GitHub Repo": "https://github.com/dauxio/daux.io", - "Help/Support/Bugs": "https://github.com/dauxio/daux.io/issues" + "GitHub Repository": "https://github.com/dauxio/daux.io", + "Help/Support/Bugs": "https://github.com/dauxio/daux.io/issues", + "Packagist": "https://packagist.org/packages/daux/daux.io", + "Docker Images": "https://hub.docker.com/r/daux/daux.io" }, - "powered_by": "Powered by Daux.io" }, "confluence": { diff --git a/global.json b/global.json index 606d4a3..6bf4853 100755 --- a/global.json +++ b/global.json @@ -22,10 +22,6 @@ "strings": { "en": { - "CodeBlocks_title": "Code blocks", - "CodeBlocks_hide": "No", - "CodeBlocks_below": "Below", - "CodeBlocks_inline": "Inline", "CodeBlocks_show": "Show Code Blocks", "Search_placeholder": "Search...", "Search_one_result": "1 result", @@ -44,10 +40,6 @@ "Toggle_navigation": "Toggle navigation" }, "fr": { - "CodeBlocks_title": "Afficher le code", - "CodeBlocks_hide": "Non", - "CodeBlocks_below": "En Dessous", - "CodeBlocks_inline": "A côté", "CodeBlocks_show": "Afficher le code", "Search_placeholder": "Rechercher...", "Search_one_result": "1 résultat", @@ -65,10 +57,6 @@ "Table_of_contents": "Table des matières" }, "de": { - "CodeBlocks_title": "Code-Blöcke", - "CodeBlocks_hide": "Aus", - "CodeBlocks_below": "Unterhalb", - "CodeBlocks_inline": "Linear", "CodeBlocks_show": "Code-Blöcke anzeigen", "Search_placeholder": "Suchen...", "Search_one_result": "1 Ergebnis", @@ -86,10 +74,6 @@ "Table_of_contents": "Inhaltsverzeichnis" }, "it": { - "CodeBlocks_title": "Blocchi di codice", - "CodeBlocks_hide": "No", - "CodeBlocks_below": "Sotto", - "CodeBlocks_inline": "In linea", "CodeBlocks_show": "Mostra blocchi di codice", "Search_one_result": "1 risultato", "Search_results": "!count risultati", diff --git a/libs/BaseConfig.php b/libs/BaseConfig.php index 7a867dc..01a9601 100644 --- a/libs/BaseConfig.php +++ b/libs/BaseConfig.php @@ -5,7 +5,7 @@ use ArrayObject; class BaseConfig extends ArrayObject { /** - * Merge an array into the object + * Merge an array into the object. * * @param array $newValues * @param bool $override @@ -15,8 +15,9 @@ class BaseConfig extends ArrayObject foreach ($newValues as $key => $value) { // If the key doesn't exist yet, // we can simply set it. - if (!array_key_exists($key, $this)) { + if (!array_key_exists($key, (array) $this)) { $this[$key] = $value; + continue; } @@ -36,4 +37,19 @@ class BaseConfig extends ArrayObject } } } + + public function hasValue($key) + { + return array_key_exists($key, (array) $this); + } + + public function getValue($key) + { + return $this[$key]; + } + + public function setValue($key, $value) + { + $this[$key] = $value; + } } diff --git a/libs/Cache.php b/libs/Cache.php index e1f88bc..288d2a8 100644 --- a/libs/Cache.php +++ b/libs/Cache.php @@ -1,16 +1,14 @@ getValue('title'); + } + + public function hasAuthor(): bool + { + return $this->hasValue('author'); + } + + public function getAuthor() + { + return $this->getValue('author'); + } + + public function hasTagline(): bool + { + return $this->hasValue('tagline'); + } + + public function getTagline() + { + return $this->getValue('tagline'); } public function getCurrentPage() { - return $this['current_page']; + return $this->getValue('current_page'); } public function setCurrentPage(Content $entry) { - $this['current_page'] = $entry; + $this->setValue('current_page', $entry); } public function getDocumentationDirectory() { - return $this['docs_directory']; - } - - public function setDocumentationDirectory($documentationPath) - { - $this['docs_directory'] = $documentationPath; + return $this->getValue('docs_directory'); } public function getThemesDirectory() { - return $this['themes_directory']; - } - - public function setThemesDirectory($directory) - { - $this['themes_directory'] = $directory; - } - - public function setThemesPath($themePath) - { - $this['themes_path'] = $themePath; + return $this->getValue('themes_directory'); } public function getThemesPath() { - return $this['themes_path']; - } - - public function setFormat($format) - { - $this['format'] = $format; + return $this->getValue('themes_path'); } public function getFormat() { - return $this['format']; + return $this->getValue('format'); } - public function hasTimezone() + public function hasTimezone(): bool { return isset($this['timezone']); } public function getTimezone() { - return $this['timezone']; + return $this->getValue('timezone'); } - public function isMultilanguage() + public function getTree() { - return array_key_exists('languages', $this) && !empty($this['languages']); + return $this->getValue('tree'); + } + + public function setTree($tree) + { + $this->setValue('tree', $tree); + } + + public function isMultilanguage(): bool + { + return $this->hasValue('languages') && !empty($this->getValue('languages')); + } + + public function getLanguages(): array + { + return $this->getValue('languages'); + } + + public function getLanguage(): string + { + return $this->getValue('language'); + } + + public function getMode() + { + return $this->getValue('mode'); } public function isLive() { - return $this['mode'] == Daux::LIVE_MODE; + return $this->getValue('mode') == Daux::LIVE_MODE; } public function isStatic() { - return $this['mode'] == Daux::STATIC_MODE; + return $this->getValue('mode') == Daux::STATIC_MODE; } public function shouldInheritIndex() @@ -90,41 +118,52 @@ class Config extends BaseConfig // As the global configuration is always present, we // need to test for the existence of the legacy value // first. Then use the current value. - if (array_key_exists('live', $this) && array_key_exists('inherit_index', $this['live'])) { + if ($this->hasValue('live') && array_key_exists('inherit_index', $this['live'])) { return $this['live']['inherit_index']; } return $this['html']['inherit_index']; } - public function setConfigurationOverrideFile($override_file) + public function getIndexKey() { - $this['override_file'] = $override_file; + return $this->getValue('mode') == Daux::STATIC_MODE ? 'index.html' : 'index'; } - public function getConfigurationOverrideFile() + public function getProcessor() { - if (array_key_exists('override_file', $this)) { - return $this['override_file']; - } - - return null; + return $this->getValue('processor'); } - public function getConfluenceConfiguration() + public function getConfluenceConfiguration(): ConfluenceConfig { - return $this['confluence']; + return new ConfluenceConfig($this->hasValue('confluence') ? $this->getValue('confluence') : []); } - public function getHTML() + public function getHTML(): HTMLConfig { - return new HTMLConfig($this['html']); + return new HTMLConfig($this->hasValue('html') ? $this->getValue('html') : []); + } + + public function getTheme(): ?Theme + { + return $this->hasValue('theme') ? new Theme($this->getValue('theme')) : null; + } + + public function getValidContentExtensions() + { + return $this->getValue('valid_content_extensions'); + } + + public function setValidContentExtensions(array $value) + { + $this->setValue('valid_content_extensions', $value); } public function canCache() { - if (array_key_exists('cache', $this)) { - return $this['cache']; + if ($this->hasValue('cache')) { + return $this->getValue('cache'); } return false; @@ -139,4 +178,128 @@ class Config extends BaseConfig return sha1(json_encode($cloned)); } + + public function hasTranslationKey($language, $key): bool + { + return array_key_exists($language, $this['strings']) && array_key_exists($key, $this['strings'][$language]); + } + + public function getTranslationKey($language, $key) + { + return $this['strings'][$language][$key]; + } + + public function hasImage(): bool + { + return $this->hasValue('image') && !empty($this->getValue('image')); + } + + public function getImage() + { + return $this->getValue('image'); + } + + public function setImage($value) + { + $this->setValue('image', $value); + } + + public function getLocalBase() + { + return $this->getValue('local_base'); + } + + public function getTemplates() + { + return $this->getValue('templates'); + } + + public function getBaseUrl() + { + return $this->getValue('base_url'); + } + + public function getBasePage() + { + if ($this->isLive()) { + $value = '//' . $this->getBaseUrl(); + if (!$this['live']['clean_urls']) { + $value .= 'index.php/'; + } + + return $value; + } + + return $this->getBaseUrl(); + } + + public function hasEntryPage(): bool + { + return $this->hasValue('entry_page') && !empty($this->getValue('entry_page')); + } + + public function getEntryPage() + { + return $this->getValue('entry_page'); + } + + public function setEntryPage($value) + { + $this->setValue('entry_page', $value); + } + + public function hasRequest(): bool + { + return $this->hasValue('request') && !empty($this->getValue('request')); + } + + public function getRequest() + { + return $this->getValue('request'); + } + + public function setRequest($value) + { + $this->setValue('request', $value); + } + + public function getIndex() + { + return $this->getValue('index'); + } + + public function setIndex($value) + { + $this->setValue('index', $value); + } + + public function hasProcessorInstance() + { + return $this->hasValue('processor_instance'); + } + + public function getProcessorInstance() + { + return $this->getValue('processor_instance'); + } + + public function setProcessorInstance($value) + { + $this->setValue('processor_instance', $value); + } + + public function getIgnore() + { + return $this->getValue('ignore'); + } + + public function hasHost() + { + return $this->hasValue('host'); + } + + public function getHost() + { + return $this->getValue('host'); + } } diff --git a/libs/ConfigBuilder.php b/libs/ConfigBuilder.php new file mode 100644 index 0000000..473effc --- /dev/null +++ b/libs/ConfigBuilder.php @@ -0,0 +1,327 @@ +config = new Config(); + $this->config['mode'] = $mode; + $this->config['local_base'] = dirname(__DIR__); + } + + public static function fromFile($file): Config + { + return unserialize(file_get_contents($file)); + } + + public static function withMode($mode = Daux::STATIC_MODE): ConfigBuilder + { + $builder = new ConfigBuilder($mode); + $builder->loadBaseConfiguration(); + + return $builder; + } + + public function with(array $values): ConfigBuilder + { + $this->config->merge($values); + + return $this; + } + + private function setValue(Config $array, $key, $value) + { + if (is_null($key)) { + return $array = $value; + } + $keys = explode('.', $key); + while (count($keys) > 1) { + $key = array_shift($keys); + if (!isset($array[$key]) || !is_array($array[$key])) { + $array[$key] = []; + } + $array = &$array[$key]; + } + $array[array_shift($keys)] = $value; + } + + public function withValues(array $values): ConfigBuilder + { + $this->overrideValues = $values; + + return $this; + } + + public function withDocumentationDirectory($dir): ConfigBuilder + { + $this->config['docs_directory'] = $dir; + + return $this; + } + + public function withValidContentExtensions(array $value): ConfigBuilder + { + $this->config['valid_content_extensions'] = $value; + + return $this; + } + + public function withThemesPath($themePath): ConfigBuilder + { + $this->config['themes_path'] = $themePath; + + return $this; + } + + public function withThemesDirectory($directory): ConfigBuilder + { + $this->config['themes_directory'] = $directory; + + return $this; + } + + public function withCache(bool $value): ConfigBuilder + { + $this->config['cache'] = $value; + + return $this; + } + + public function withFormat($format): ConfigBuilder + { + $this->config['format'] = $format; + + return $this; + } + + public function withConfigurationOverride($file): ConfigBuilder + { + $this->configuration_override_file = $file; + + return $this; + } + + public function withProcessor($value): ConfigBuilder + { + $this->config['processor'] = $value; + + return $this; + } + + public function withConfluenceDelete($value): ConfigBuilder + { + $this->config['confluence']['delete'] = $value; + + return $this; + } + + public function build(): Config + { + $this->initializeConfiguration(); + + foreach ($this->overrideValues as $value) { + $this->setValue($this->config, $value[0], $value[1]); + } + + return $this->config; + } + + private function resolveThemeVariant() + { + $theme = $this->config->getHTML()->getTheme(); + $themesPath = $this->config->getThemesPath() . DIRECTORY_SEPARATOR; + + // If theme directory exists, we're good with that + if (is_dir(realpath(($themesPath . $theme)))) { + return [$theme, '']; + } + + $themePieces = explode('-', $theme); + $variant = ''; + + // Do we have a variant or only a theme ? + if (count($themePieces) > 1) { + $variant = array_pop($themePieces); + $theme = implode('-', $themePieces); + } + + if (!is_dir(realpath($themesPath . $theme))) { + throw new \RuntimeException("Theme '{$theme}' not found"); + } + + return [$theme, $variant]; + } + + /** + * @param string $override_file + * + * @throws Exception + */ + private function initializeConfiguration() + { + // Validate and set theme path + $docs_path = $this->normalizeDocumentationPath($this->config->getDocumentationDirectory()); + $this->config['docs_directory'] = $docs_path; + + // Read documentation overrides + $this->loadConfiguration($docs_path . DIRECTORY_SEPARATOR . 'config.json'); + + // Read command line overrides + $override_file = $this->getConfigurationOverride($this->configuration_override_file); + if ($override_file !== null) { + $this->loadConfiguration($override_file); + } + + // Validate and set theme path + $this->withThemesPath($this->normalizeThemePath($this->config->getThemesDirectory())); + + // Resolve variant once + $theme = $this->resolveThemeVariant(); + $this->config['html']['theme'] = $theme[0]; + $this->config['html']['theme-variant'] = $theme[1]; + + // Set a valid default timezone + if ($this->config->hasTimezone()) { + date_default_timezone_set($this->config->getTimezone()); + } elseif (!ini_get('date.timezone')) { + date_default_timezone_set('GMT'); + } + + // Text search would be too slow on live server + if ($this->config->isLive()) { + $this->config['html']['search'] = false; + } + } + + private function normalizeThemePath($path) + { + $validPath = $this->findLocation($path, $this->config->getLocalBase(), 'dir'); + + if (!$validPath) { + throw new Exception('The Themes directory does not exist. Check the path again : ' . $path); + } + + return $validPath; + } + + private function normalizeDocumentationPath($path) + { + $validPath = $this->findLocation($path, $this->config->getLocalBase(), 'dir'); + + if (!$validPath) { + throw new Exception('The Docs directory does not exist. Check the path again : ' . $path); + } + + return $validPath; + } + + /** + * Load and validate the global configuration. + * + * @throws Exception + */ + private function loadBaseConfiguration() + { + // Set the default configuration + $this->config->merge([ + 'docs_directory' => 'docs', + 'valid_content_extensions' => ['md', 'markdown'], + + //Paths and tree + 'templates' => 'templates', + + 'base_url' => '', + ]); + + // Load the global configuration + $this->loadConfiguration($this->config->getLocalBase() . DIRECTORY_SEPARATOR . 'global.json', false); + } + + /** + * @param string $config_file + * @param bool $optional + * + * @throws Exception + */ + private function loadConfiguration($config_file, $optional = true) + { + if (!file_exists($config_file)) { + if ($optional) { + return; + } + + throw new Exception('The configuration file is missing. Check path : ' . $config_file); + } + + $config = json_decode(file_get_contents($config_file), true); + if (!isset($config)) { + throw new Exception('The configuration file "' . $config_file . '" is corrupt. Is your JSON well-formed ?'); + } + $this->config->merge($config); + } + + /** + * Get the file requested for configuration overrides. + * + * @param null|string $path + * + * @throws Exception + * + * @return null|string the path to a file to load for configuration overrides + */ + private function getConfigurationOverride($path) + { + $validPath = $this->findLocation($path, $this->config->getLocalBase(), 'file'); + + if ($validPath === null) { + return null; + } + + if (!$validPath) { + throw new Exception('The configuration override file does not exist. Check the path again : ' . $path); + } + + return $validPath; + } + + /** + * @param null|string $path + * @param string $basedir + * @param string $type + * + * @return null|false|string + */ + private function findLocation($path, $basedir, $type) + { + // If Path is explicitly null, it's useless to go further + if ($path === null) { + return null; + } + + // VFS, used only in tests + if (substr($path, 0, 6) == 'vfs://') { + return $path; + } + + // Check if it's relative to the current directory or an absolute path + if (DauxHelper::is($path, $type)) { + return DauxHelper::getAbsolutePath($path); + } + + // Check if it exists relative to Daux's root + $newPath = $basedir . DIRECTORY_SEPARATOR . $path; + if (DauxHelper::is($newPath, $type)) { + return $newPath; + } + + return false; + } +} diff --git a/libs/Console/Application.php b/libs/Console/Application.php index 3682361..073ca30 100644 --- a/libs/Console/Application.php +++ b/libs/Console/Application.php @@ -12,16 +12,16 @@ class Application extends SymfonyApplication $this->add(new Serve()); $this->add(new ClearCache()); - $app_name = "daux/daux.io"; + $app_name = 'daux/daux.io'; $up = '..' . DIRECTORY_SEPARATOR; $composer = __DIR__ . DIRECTORY_SEPARATOR . $up . $up . $up . $up . $up . 'composer.lock'; - $version = "unknown"; + $version = 'unknown'; if (file_exists($composer)) { $app = json_decode(file_get_contents($composer)); $packages = $app->packages; - + foreach ($packages as $package) { if ($package->name == $app_name) { $version = $package->version; diff --git a/libs/Console/ClearCache.php b/libs/Console/ClearCache.php index b8a2087..dd73d50 100644 --- a/libs/Console/ClearCache.php +++ b/libs/Console/ClearCache.php @@ -16,8 +16,10 @@ class ClearCache extends SymfonyCommand protected function execute(InputInterface $input, OutputInterface $output) { - $output->writeln("Clearing cache at '" . Cache::getDirectory() ."'"); + $output->writeln("Clearing cache at '" . Cache::getDirectory() . "'"); Cache::clear(); - $output->writeln("Cache cleared"); + $output->writeln('Cache cleared'); + + return 0; } } diff --git a/libs/Console/DauxCommand.php b/libs/Console/DauxCommand.php index b207e07..175177c 100644 --- a/libs/Console/DauxCommand.php +++ b/libs/Console/DauxCommand.php @@ -4,86 +4,64 @@ use Symfony\Component\Console\Command\Command as SymfonyCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Todaymade\Daux\ConfigBuilder; use Todaymade\Daux\Daux; class DauxCommand extends SymfonyCommand { - protected function configure() + protected function configure() { $this ->addOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Configuration file') - ->addOption('value', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Set different configuration values') ->addOption('source', 's', InputOption::VALUE_REQUIRED, 'Where to take the documentation from') ->addOption('processor', 'p', InputOption::VALUE_REQUIRED, 'Manipulations on the tree') - ->addOption('no-cache', null, InputOption::VALUE_NONE, 'Disable Cache'); - - // HTML Format only - $this->addOption('themes', 't', InputOption::VALUE_REQUIRED, 'Set a different themes directory'); + ->addOption('no-cache', null, InputOption::VALUE_NONE, 'Disable Cache') + ->addOption('themes', 't', InputOption::VALUE_REQUIRED, 'Set a different themes directory (Used by HTML format only)') + ->addOption('value', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Set different configuration values'); } - private function setValue(&$array, $key, $value) + protected function prepareConfig($mode, InputInterface $input, OutputInterface $output): ConfigBuilder { - if (is_null($key)) { - return $array = $value; - } - $keys = explode('.', $key); - while (count($keys) > 1) { - $key = array_shift($keys); - if (!isset($array[$key]) || !is_array($array[$key])) { - $array[$key] = []; - } - $array = &$array[$key]; - } - $array[array_shift($keys)] = $value; - return $array; - } + $builder = ConfigBuilder::withMode($mode); - private function applyConfiguration(array $options, Daux $daux) - { - $values = array_map( - function($value) { - return array_map("trim", explode('=', $value)); - }, - $options - ); - - foreach ($values as $value) { - $this->setValue($daux->options, $value[0], $value[1]); - } - } - - protected function prepareDaux(InputInterface $input, OutputInterface $output) - { - $daux = new Daux(Daux::STATIC_MODE, $output); - - // Set the format if requested - if ($input->hasOption('format') && $input->getOption('format')) { - $daux->getParams()->setFormat($input->getOption('format')); + if ($input->getOption('configuration')) { + $builder->withConfigurationOverride($input->getOption('configuration')); } - // Set the source directory if ($input->getOption('source')) { - $daux->getParams()->setDocumentationDirectory($input->getOption('source')); + $builder->withDocumentationDirectory($input->getOption('source')); } - if ($input->getOption('themes')) { - $daux->getParams()->setThemesDirectory($input->getOption('themes')); - } - - $daux->initializeConfiguration($input->getOption('configuration')); - - if ($input->hasOption('delete') && $input->getOption('delete')) { - $daux->getParams()['confluence']['delete'] = true; - } - - if ($input->hasOption('value')) { - $this->applyConfiguration($input->getOption('value'), $daux); + if ($input->getOption('processor')) { + $builder->withProcessor($input->getOption('processor')); } if ($input->getOption('no-cache')) { - $daux->getParams()['cache'] = false; + $builder->withCache(false); } - return $daux; + if ($input->getOption('themes')) { + $builder->withThemesDirectory($input->getOption('themes')); + } + + if ($input->hasOption('value')) { + $values = array_map( + function ($value) { + return array_map('trim', explode('=', $value)); + }, + $input->getOption('value') + ); + $builder->withValues($values); + } + + return $builder; + } + + protected function prepareProcessor(Daux $daux, $width) + { + $class = $daux->getProcessorClass(); + if (!empty($class)) { + $daux->setProcessor(new $class($daux, $daux->getOutput(), $width)); + } } } diff --git a/libs/Console/Generate.php b/libs/Console/Generate.php index 158ef9d..d12a695 100755 --- a/libs/Console/Generate.php +++ b/libs/Console/Generate.php @@ -6,6 +6,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Terminal; +use Todaymade\Daux\ConfigBuilder; use Todaymade\Daux\Daux; class Generate extends DauxCommand @@ -25,8 +26,23 @@ class Generate extends DauxCommand // Confluence format only ->addOption('delete', null, InputOption::VALUE_NONE, 'Delete pages not linked to a documentation page (confluence)') - ->addOption('destination', 'd', InputOption::VALUE_REQUIRED, $description, 'static') - ->addOption('search', null, InputOption::VALUE_NONE, 'Generate full text search'); + ->addOption('destination', 'd', InputOption::VALUE_REQUIRED, $description, 'static'); + } + + protected function prepareConfig($mode, InputInterface $input, OutputInterface $output): ConfigBuilder + { + $builder = parent::prepareConfig($mode, $input, $output); + + // Set the format if requested + if ($input->hasOption('format') && $input->getOption('format')) { + $builder->withFormat($input->getOption('format')); + } + + if ($input->hasOption('delete') && $input->getOption('delete')) { + $builder->withConfluenceDelete(true); + } + + return $builder; } protected function execute(InputInterface $input, OutputInterface $output) @@ -42,29 +58,20 @@ class Generate extends DauxCommand $input = new ArgvInput($argv, $this->getDefinition()); } - $daux = $this->prepareDaux($input, $output); + $builder = $this->prepareConfig(Daux::STATIC_MODE, $input, $output); + $daux = new Daux($builder->build(), $output); - $width = (new Terminal)->getWidth(); + $width = (new Terminal())->getWidth(); // Instiantiate the processor if one is defined - $this->prepareProcessor($daux, $input, $output, $width); + $this->prepareProcessor($daux, $width); // Generate the tree $daux->generateTree(); // Generate the documentation $daux->getGenerator()->generateAll($input, $output, $width); - } - protected function prepareProcessor(Daux $daux, InputInterface $input, OutputInterface $output, $width) - { - if ($input->getOption('processor')) { - $daux->getParams()['processor'] = $input->getOption('processor'); - } - - $class = $daux->getProcessorClass(); - if (!empty($class)) { - $daux->setProcessor(new $class($daux, $output, $width)); - } + return 0; } } diff --git a/libs/Console/RunAction.php b/libs/Console/RunAction.php index 66cfe11..1c58dd7 100644 --- a/libs/Console/RunAction.php +++ b/libs/Console/RunAction.php @@ -5,7 +5,8 @@ use Todaymade\Daux\Daux; trait RunAction { - protected function getLength($content) { + protected function getLength($content) + { return function_exists('mb_strlen') ? mb_strlen($content) : strlen($content); } @@ -25,6 +26,7 @@ trait RunAction }); } catch (\Exception $e) { $this->status($padding, '[ FAIL ]'); + throw $e; } $this->status($padding, '[ OK ]'); diff --git a/libs/Console/Serve.php b/libs/Console/Serve.php index 242fc4a..94eb28e 100755 --- a/libs/Console/Serve.php +++ b/libs/Console/Serve.php @@ -1,13 +1,11 @@ setName('serve') ->setDescription('Serve documentation') - // Serve the current documentation - ->addOption('serve', null, InputOption::VALUE_NONE, 'Serve the current directory') ->addOption('host', null, InputOption::VALUE_REQUIRED, 'The host to serve on', 'localhost') ->addOption('port', null, InputOption::VALUE_REQUIRED, 'The port to serve on', 8085); } @@ -30,23 +26,44 @@ class Serve extends DauxCommand $host = $input->getOption('host'); $port = $input->getOption('port'); - $daux = $this->prepareDaux($input, $output); + $builder = $this->prepareConfig(Daux::LIVE_MODE, $input, $output); // Daux can only serve HTML - $daux->getParams()->setFormat('html'); + $builder->withFormat('html'); + + $daux = new Daux($builder->build(), $output); + + $width = (new Terminal())->getWidth(); + + // Instiantiate the processor if one is defined + $this->prepareProcessor($daux, $width); + + // Write the current configuration to a file to read it from the other serving side + $file = tmpfile(); + + if ($file === false) { + $output->writeln('Failed to create temporary file for configuration'); + + return 1; + } + + $path = stream_get_meta_data($file)['uri']; + fwrite($file, serialize($daux->getConfig())); chdir(__DIR__ . '/../../'); - putenv('DAUX_SOURCE=' . $daux->getParams()->getDocumentationDirectory()); - putenv('DAUX_THEME=' . $daux->getParams()->getThemesPath()); - putenv('DAUX_CONFIGURATION=' . $daux->getParams()->getConfigurationOverrideFile()); + putenv('DAUX_CONFIG=' . $path); + putenv('DAUX_VERBOSITY=' . $output->getVerbosity()); putenv('DAUX_EXTENSION=' . DAUX_EXTENSION); $base = escapeshellarg(__DIR__ . '/../../'); - $binary = escapeshellarg((new PhpExecutableFinder)->find(false)); + $binary = escapeshellarg((new PhpExecutableFinder())->find(false)); echo "Daux development server started on http://{$host}:{$port}/\n"; passthru("{$binary} -S {$host}:{$port} {$base}/index.php"); + fclose($file); + + return 0; } } diff --git a/libs/ContentTypes/ContentType.php b/libs/ContentTypes/ContentType.php index 3bb8244..188872c 100644 --- a/libs/ContentTypes/ContentType.php +++ b/libs/ContentTypes/ContentType.php @@ -8,7 +8,7 @@ interface ContentType public function __construct(Config $config); /** - * Get the file extensions supported by this Content Type + * Get the file extensions supported by this Content Type. * * @return string[] */ @@ -17,6 +17,7 @@ interface ContentType /** * @param string $raw The raw text to render * @param Content $node The original node we are converting + * * @return string The generated output */ public function convert($raw, Content $node); diff --git a/libs/ContentTypes/ContentTypeHandler.php b/libs/ContentTypes/ContentTypeHandler.php index 3234afc..fd73424 100644 --- a/libs/ContentTypes/ContentTypeHandler.php +++ b/libs/ContentTypes/ContentTypeHandler.php @@ -18,7 +18,7 @@ class ContentTypeHandler } /** - * Get all valid content file extensions + * Get all valid content file extensions. * * @return string[] */ @@ -33,9 +33,8 @@ class ContentTypeHandler } /** - * Get the ContentType able to handle this node + * Get the ContentType able to handle this node. * - * @param Content $node * @return ContentType */ public function getType(Content $node) diff --git a/libs/ContentTypes/Markdown/CommonMarkConverter.php b/libs/ContentTypes/Markdown/CommonMarkConverter.php index 4c1a479..ad24c53 100644 --- a/libs/ContentTypes/Markdown/CommonMarkConverter.php +++ b/libs/ContentTypes/Markdown/CommonMarkConverter.php @@ -1,22 +1,25 @@ mergeConfig($config); + $environment->addExtension(new AutolinkExtension()); + $environment->addExtension(new SmartPunctExtension()); + $environment->addExtension(new StrikethroughExtension()); $environment->addExtension(new TableExtension()); // Table of Contents @@ -24,12 +27,11 @@ class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter $this->extendEnvironment($environment, $config['daux']); - if (array_key_exists('processor_instance', $config['daux'])) { - $config['daux']['processor_instance']->extendCommonMarkEnvironment($environment); + if ($config['daux']->hasProcessorInstance()) { + $config['daux']->getProcessorInstance()->extendCommonMarkEnvironment($environment); } - $this->docParser = new DocParser($environment); - $this->htmlRenderer = new HtmlRenderer($environment); + parent::__construct($config, $environment); } protected function getLinkRenderer(Environment $environment) @@ -39,6 +41,6 @@ class CommonMarkConverter extends \League\CommonMark\CommonMarkConverter protected function extendEnvironment(Environment $environment, Config $config) { - $environment->addInlineRenderer('Link', $this->getLinkRenderer($environment)); + $environment->addInlineRenderer(InlineElement\Link::class, $this->getLinkRenderer($environment)); } } diff --git a/libs/ContentTypes/Markdown/ContentType.php b/libs/ContentTypes/Markdown/ContentType.php index 07f5636..9788c17 100644 --- a/libs/ContentTypes/Markdown/ContentType.php +++ b/libs/ContentTypes/Markdown/ContentType.php @@ -12,12 +12,25 @@ class ContentType implements \Todaymade\Daux\ContentTypes\ContentType protected $config; /** @var CommonMarkConverter */ - protected $converter; + private $converter; public function __construct(Config $config) { $this->config = $config; - $this->converter = new CommonMarkConverter(['daux' => $config]); + } + + protected function createConverter() + { + return new CommonMarkConverter(['daux' => $this->config]); + } + + protected function getConverter() + { + if (!$this->converter) { + $this->converter = $this->createConverter(); + } + + return $this->converter; } /** @@ -30,30 +43,34 @@ class ContentType implements \Todaymade\Daux\ContentTypes\ContentType protected function doConversion($raw) { - Daux::writeln("Running conversion", OutputInterface::VERBOSITY_VERBOSE); - return $this->converter->convertToHtml($raw); + Daux::writeln('Running conversion', OutputInterface::VERBOSITY_VERBOSE); + + return $this->getConverter()->convertToHtml($raw); } public function convert($raw, Content $node) { $this->config->setCurrentPage($node); - if (!$this->config->canCache()) { - return $this->doConversion($raw); - } + $can_cache = $this->config->canCache(); // TODO :: add daux version to cache key $cacheKey = $this->config->getCacheKey() . sha1($raw); $payload = Cache::get($cacheKey); - if ($payload) { - Daux::writeln("Using cached version", OutputInterface::VERBOSITY_VERBOSE); - } else { - Daux::writeln("Not found in the cache, generating...", OutputInterface::VERBOSITY_VERBOSE); + if ($can_cache && $payload) { + Daux::writeln('Using cached version', OutputInterface::VERBOSITY_VERBOSE); + } + + if (!$can_cache || !$payload) { + Daux::writeln($can_cache ? 'Not found in the cache, generating...' : 'Cache disabled, generating...', OutputInterface::VERBOSITY_VERBOSE); $payload = $this->doConversion($raw); + } + + if ($can_cache) { Cache::put($cacheKey, $payload); - } + } return $payload; } diff --git a/libs/ContentTypes/Markdown/LinkRenderer.php b/libs/ContentTypes/Markdown/LinkRenderer.php index 13018b7..773e362 100644 --- a/libs/ContentTypes/Markdown/LinkRenderer.php +++ b/libs/ContentTypes/Markdown/LinkRenderer.php @@ -4,102 +4,58 @@ use League\CommonMark\ElementRendererInterface; use League\CommonMark\HtmlElement; use League\CommonMark\Inline\Element\AbstractInline; use League\CommonMark\Inline\Element\Link; +use League\CommonMark\Inline\Renderer\InlineRendererInterface; +use League\CommonMark\Util\ConfigurationAwareInterface; +use League\CommonMark\Util\ConfigurationInterface; use Todaymade\Daux\Config; use Todaymade\Daux\DauxHelper; use Todaymade\Daux\Exception\LinkNotFoundException; -use Todaymade\Daux\Tree\Entry; -class LinkRenderer extends \League\CommonMark\Inline\Renderer\LinkRenderer +class LinkRenderer implements InlineRendererInterface, ConfigurationAwareInterface { /** * @var Config */ protected $daux; + /** + * @var \League\CommonMark\Inline\Renderer\LinkRenderer + */ + protected $parent; + public function __construct($daux) { $this->daux = $daux; - } - - /** - * @param string $url - * @return Entry - * @throws LinkNotFoundException - */ - protected function resolveInternalFile($url) - { - $triedAbsolute = false; - - // Legacy absolute paths could start with - // "!" In this case we will try to find - // the file starting at the root - if ($url[0] == '!' || $url[0] == '/') { - $url = ltrim($url, '!/'); - - if ($file = DauxHelper::getFile($this->daux['tree'], $url)) { - return $file; - } - - $triedAbsolute = true; - } - - // Seems it's not an absolute path or not found, - // so we'll continue with the current folder - if ($file = DauxHelper::getFile($this->daux->getCurrentPage()->getParent(), $url)) { - return $file; - } - - // If we didn't already try it, we'll - // do a pass starting at the root - if (!$triedAbsolute && $file = DauxHelper::getFile($this->daux['tree'], $url)) { - return $file; - } - - throw new LinkNotFoundException("Could not locate file '$url'"); - } - - protected function isValidUrl($url) - { - return !empty($url) && $url[0] != '#'; - } - - protected function isExternalUrl($url) - { - return preg_match('#^(?:[a-z]+:)?//|^mailto:#', $url); + $this->parent = new \League\CommonMark\Inline\Renderer\LinkRenderer(); } /** * @param AbstractInline|Link $inline - * @param ElementRendererInterface $htmlRenderer - * @return HtmlElement + * * @throws LinkNotFoundException + * + * @return HtmlElement */ public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer) { - // This can't be in the method type as - // the method is an abstract and should - // have the same interface - if (!$inline instanceof Link) { - throw new \RuntimeException( - 'Wrong type passed to ' . __CLASS__ . '::' . __METHOD__ . - " the expected type was 'League\\CommonMark\\Inline\\Element\\Link' but '" . - get_class($inline) . "' was provided" - ); + if (!($inline instanceof Link)) { + throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline)); } - $element = parent::render($inline, $htmlRenderer); + $element = $this->parent->render($inline, $htmlRenderer); $url = $inline->getUrl(); // empty urls and anchors should // not go through the url resolver - if (!$this->isValidUrl($url)) { + if (!DauxHelper::isValidUrl($url)) { return $element; } // Absolute urls, shouldn't either - if ($this->isExternalUrl($url)) { + if (DauxHelper::isExternalUrl($url)) { $element->setAttribute('class', 'Link--external'); + $element->setAttribute('rel', 'noopener noreferrer'); return $element; } @@ -112,22 +68,19 @@ class LinkRenderer extends \League\CommonMark\Inline\Renderer\LinkRenderer $foundWithHash = false; try { - $file = $this->resolveInternalFile($url); + $file = DauxHelper::resolveInternalFile($this->daux, $url); $url = DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl()); } catch (LinkNotFoundException $e) { - - - // For some reason, the filename could contain a # and thus the link needs to resolve to that. try { - if (strlen($urlAndHash[1] ?? "") > 0) { - $file = $this->resolveInternalFile($url . '#' . $urlAndHash[1]); + if (strlen($urlAndHash[1] ?? '') > 0) { + $file = DauxHelper::resolveInternalFile($this->daux, $url . '#' . $urlAndHash[1]); $url = DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl()); $foundWithHash = true; } } catch (LinkNotFoundException $e2) { - // If it's still not found here, we'll only - // report on the first error as the second + // If it's still not found here, we'll only + // report on the first error as the second // one will tell the same. } @@ -135,7 +88,7 @@ class LinkRenderer extends \League\CommonMark\Inline\Renderer\LinkRenderer if ($this->daux->isStatic()) { throw $e; } - + $element->setAttribute('class', 'Link--broken'); } } @@ -148,4 +101,9 @@ class LinkRenderer extends \League\CommonMark\Inline\Renderer\LinkRenderer return $element; } + + public function setConfiguration(ConfigurationInterface $configuration) + { + $this->parent->setConfiguration($configuration); + } } diff --git a/libs/ContentTypes/Markdown/TableOfContents.php b/libs/ContentTypes/Markdown/TableOfContents.php index 81384e4..69f5c88 100644 --- a/libs/ContentTypes/Markdown/TableOfContents.php +++ b/libs/ContentTypes/Markdown/TableOfContents.php @@ -6,43 +6,22 @@ use League\CommonMark\Cursor; class TableOfContents extends AbstractBlock { /** - * Returns true if this block can contain the given block as a child node - * - * @param AbstractBlock $block - * - * @return bool + * Returns true if this block can contain the given block as a child node. */ - public function canContain(AbstractBlock $block) + public function canContain(AbstractBlock $block): bool { return false; } /** - * Returns true if block type can accept lines of text - * - * @return bool + * Whether this is a code block. */ - public function acceptsLines() + public function isCode(): bool { 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) + public function matchesNextLine(Cursor $cursor): bool { return false; } diff --git a/libs/ContentTypes/Markdown/TableOfContentsParser.php b/libs/ContentTypes/Markdown/TableOfContentsParser.php index 73a2a5d..5e822ec 100644 --- a/libs/ContentTypes/Markdown/TableOfContentsParser.php +++ b/libs/ContentTypes/Markdown/TableOfContentsParser.php @@ -1,18 +1,12 @@ isIndented()) { return false; diff --git a/libs/Daux.php b/libs/Daux.php index 0f99e63..799eebf 100644 --- a/libs/Daux.php +++ b/libs/Daux.php @@ -4,8 +4,6 @@ use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; use Todaymade\Daux\ContentTypes\ContentTypeHandler; use Todaymade\Daux\Tree\Builder; -use Todaymade\Daux\Tree\Content; -use Todaymade\Daux\Tree\Directory; use Todaymade\Daux\Tree\Root; class Daux @@ -15,8 +13,11 @@ class Daux public static $output; - /** @var string */ - public $local_base; + /** @var Tree\Root */ + public $tree; + + /** @var Config */ + public $config; /** @var \Todaymade\Daux\Format\Base\Generator */ protected $generator; @@ -24,182 +25,35 @@ class Daux /** @var ContentTypeHandler */ protected $typeHandler; - /** - * @var string[] - */ + /** @var string[] */ protected $validExtensions; /** @var Processor */ protected $processor; - /** @var Tree\Root */ - public $tree; - - /** @var Config */ - public $options; - - /** @var string */ - private $mode; - /** @var bool */ private $merged_tree = false; - /** - * @param string $mode - */ - public function __construct($mode, OutputInterface $output) + public function __construct(Config $config, OutputInterface $output) { Daux::$output = $output; - $this->mode = $mode; - $this->local_base = dirname(__DIR__); - - // global.json - $this->loadBaseConfiguration(); + $this->config = $config; } /** - * @param string $override_file - * @throws Exception - */ - public function initializeConfiguration($override_file = null) - { - $params = $this->getParams(); - - // Validate and set theme path - $params->setDocumentationDirectory( - $docs_path = $this->normalizeDocumentationPath($this->getParams()->getDocumentationDirectory()) - ); - - // Read documentation overrides - $this->loadConfiguration($docs_path . DIRECTORY_SEPARATOR . 'config.json'); - - // Read command line overrides - $override_file = $this->getConfigurationOverride($override_file); - if ($override_file !== null) { - $params->setConfigurationOverrideFile($override_file); - $this->loadConfiguration($override_file); - } - - // Validate and set theme path - $params->setThemesPath($this->normalizeThemePath($params->getThemesDirectory())); - - // Set a valid default timezone - if ($params->hasTimezone()) { - date_default_timezone_set($params->getTimezone()); - } elseif (!ini_get('date.timezone')) { - date_default_timezone_set('GMT'); - } - } - - /** - * Get the file requested for configuration overrides - * - * @param string|null $path - * @return string|null the path to a file to load for configuration overrides - * @throws Exception - */ - public function getConfigurationOverride($path) - { - $validPath = DauxHelper::findLocation($path, $this->local_base, 'DAUX_CONFIGURATION', 'file'); - - if ($validPath === null) { - return null; - } - - if (!$validPath) { - throw new Exception('The configuration override file does not exist. Check the path again : ' . $path); - } - - return $validPath; - } - - public function normalizeThemePath($path) - { - $validPath = DauxHelper::findLocation($path, $this->local_base, 'DAUX_THEME', 'dir'); - - if (!$validPath) { - throw new Exception('The Themes directory does not exist. Check the path again : ' . $path); - } - - return $validPath; - - } - - public function normalizeDocumentationPath($path) - { - $validPath = DauxHelper::findLocation($path, $this->local_base, 'DAUX_SOURCE', 'dir'); - - if (!$validPath) { - throw new Exception('The Docs directory does not exist. Check the path again : ' . $path); - } - - return $validPath; - } - - /** - * Load and validate the global configuration - * - * @throws Exception - */ - protected function loadBaseConfiguration() - { - $this->options = new Config(); - - // Set the default configuration - $this->options->merge([ - 'docs_directory' => 'docs', - 'valid_content_extensions' => ['md', 'markdown'], - - //Paths and tree - 'mode' => $this->mode, - 'local_base' => $this->local_base, - 'templates' => 'templates', - - 'index_key' => 'index.html', - 'base_page' => '', - 'base_url' => '', - ]); - - // Load the global configuration - $this->loadConfiguration($this->local_base . DIRECTORY_SEPARATOR . 'global.json', false); - } - - /** - * @param string $config_file - * @param bool $optional - * @throws Exception - */ - protected function loadConfiguration($config_file, $optional = true) - { - if (!file_exists($config_file)) { - if ($optional) { - return; - } - - throw new Exception('The configuration file is missing. Check path : ' . $config_file); - } - - $config = json_decode(file_get_contents($config_file), true); - if (!isset($config)) { - throw new Exception('The configuration file "' . $config_file . '" is corrupt. Is your JSON well-formed ?'); - } - $this->options->merge($config); - } - - /** - * Generate the tree that will be used + * Generate the tree that will be used. */ public function generateTree() { - $this->options['valid_content_extensions'] = $this->getContentExtensions(); + $this->config->setValidContentExtensions($this->getContentExtensions()); - $this->tree = new Root($this->getParams()); - Builder::build($this->tree, $this->options['ignore']); + $this->tree = new Root($this->getConfig()); + Builder::build($this->tree, $this->config->getIgnore()); // Apply the language name as Section title - if ($this->options->isMultilanguage()) { - foreach ($this->options['languages'] as $key => $node) { + if ($this->config->isMultilanguage()) { + foreach ($this->config->getLanguages() as $key => $node) { $this->tree->getEntries()[$key]->setTitle($node); } } @@ -216,22 +70,35 @@ class Daux /** * @return Config */ - public function getParams() + public function getConfig() { if ($this->tree && !$this->merged_tree) { - $this->options['tree'] = $this->tree; - $this->options['index'] = $this->tree->getIndexPage() ?: $this->tree->getFirstPage(); - if ($this->options->isMultilanguage()) { - foreach ($this->options['languages'] as $key => $name) { - $this->options['entry_page'][$key] = $this->tree->getEntries()[$key]->getFirstPage(); + $this->config->setTree($this->tree); + $this->config->setIndex($this->tree->getIndexPage() ?: $this->tree->getFirstPage()); + $entry_page = null; + if ($this->config->isMultilanguage()) { + $entry_page = []; + foreach ($this->config->getLanguages() as $key => $name) { + $entry_page[$key] = $this->tree->getEntries()[$key]->getFirstPage(); } } else { - $this->options['entry_page'] = $this->tree->getFirstPage(); + $entry_page = $this->tree->getFirstPage(); } + $this->config->setEntryPage($entry_page); $this->merged_tree = true; } - return $this->options; + return $this->config; + } + + /** + * @return Config + * + * @deprecated Use getConfig instead + */ + public function getParams() + { + return $this->getConfig(); } /** @@ -246,17 +113,14 @@ class Daux return $this->processor; } - /** - * @param Processor $processor - */ public function setProcessor(Processor $processor) { $this->processor = $processor; // This is not the cleanest but it's - // the best i've found to use the + // the best I've found to use the // processor in very remote places - $this->options['processor_instance'] = $processor; + $this->config->setProcessorInstance($processor); } public function getGenerators() @@ -272,10 +136,9 @@ class Daux return array_replace($default, $extended); } - public function getProcessorClass() { - $processor = $this->getParams()['processor']; + $processor = $this->getConfig()->getProcessor(); if (empty($processor)) { return null; @@ -293,7 +156,8 @@ class Daux return $class; } - protected function findAlternatives($input, $words) { + protected function findAlternatives($input, $words) + { $alternatives = []; foreach ($words as $word) { @@ -318,7 +182,7 @@ class Daux $generators = $this->getGenerators(); - $format = $this->getParams()->getFormat(); + $format = $this->getConfig()->getFormat(); if (!array_key_exists($format, $generators)) { $message = "The format '$format' doesn't exist, did you forget to set your processor ?"; @@ -365,7 +229,7 @@ class Daux } /** - * Get all content file extensions + * Get all content file extensions. * * @return string[] */ @@ -378,7 +242,8 @@ class Daux return $this->validExtensions = $this->getContentTypeHandler()->getContentExtensions(); } - public static function getOutput() { + public static function getOutput() + { if (!Daux::$output) { Daux::$output = new NullOutput(); } @@ -389,25 +254,28 @@ class Daux /** * Writes a message to the output. * - * @param string|array $messages The message as an array of lines or a single string + * @param array|string $messages The message as an array of lines or a single string * @param bool $newline Whether to add a newline * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL */ - public static function write($messages, $newline = false, $options = 0) { + public static function write($messages, $newline = false, $options = 0) + { Daux::getOutput()->write($messages, $newline, $options); } /** * Writes a message to the output and adds a newline at the end. * - * @param string|array $messages The message as an array of lines of a single string + * @param array|string $messages The message as an array of lines of a single string * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL */ - public static function writeln($messages, $options = 0) { + public static function writeln($messages, $options = 0) + { Daux::getOutput()->write($messages, true, $options); } - public static function getVerbosity() { + public static function getVerbosity() + { return Daux::getOutput()->getVerbosity(); } } diff --git a/libs/DauxHelper.php b/libs/DauxHelper.php index 845121c..79431f1 100644 --- a/libs/DauxHelper.php +++ b/libs/DauxHelper.php @@ -1,65 +1,48 @@ getBaseUrl() == $base_url && !empty($config->getTheme())) { return; } // Change base url for all links on the pages - $config['base_url'] = $config['base_page'] = $base_url; + $config['base_url'] = $base_url; $config['theme'] = static::getTheme($config, $base_url); - $config['image'] = str_replace('', $base_url, $config['image']); - } - - protected static function resolveVariant(Config $params) - { - if (array_key_exists('theme-variant', $params['html'])) { - return; - } - - if (is_dir(realpath(($params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme'])))) { - return; - } - - $theme = explode('-', $params['html']['theme']); - - // do we have a variant or only a theme ? - if (isset($theme[1])) { - $params['html']['theme-variant'] = array_pop($theme); - $params['html']['theme'] = implode('-', $theme); - } else { - $params['html']['theme'] = array_pop($theme); - } - - if (!is_dir(realpath($params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme']))) { - throw new \RuntimeException("Theme '{$params['html']['theme']}' not found"); - } + $config['image'] = str_replace('', $base_url, $config->getImage()); } /** - * @param Config $params * @param string $current_url + * * @return array */ - protected static function getTheme(Config $params, $current_url) + protected static function getTheme(Config $config, $current_url) { - self::resolveVariant($params); + static $cache = []; - $theme_folder = $params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme']; - $theme_url = $params['base_url'] . 'themes/' . $params['html']['theme'] . '/'; + $htmlTheme = $config->getHTML()->getTheme(); + + $theme_folder = $config->getThemesPath() . DIRECTORY_SEPARATOR . $htmlTheme; + $theme_url = $config->getBaseUrl() . 'themes/' . $htmlTheme . '/'; + + $cache_key = "$current_url-$htmlTheme"; + if (array_key_exists($cache_key, $cache)) { + return $cache[$cache_key]; + } $theme = []; if (is_file($theme_folder . DIRECTORY_SEPARATOR . 'config.json')) { @@ -69,19 +52,20 @@ class DauxHelper } } - //Default parameters for theme + // Default parameters for theme $theme += [ - 'name' => $params['html']['theme'], + 'name' => $htmlTheme, 'css' => [], 'js' => [], 'fonts' => [], 'favicon' => 'themes/daux/img/favicon.png', 'templates' => $theme_folder . DIRECTORY_SEPARATOR . 'templates', 'variants' => [], + 'with_search' => $config->getHTML()->hasSearch() ]; - if (array_key_exists('theme-variant', $params['html'])) { - $variant = $params['html']['theme-variant']; + if ($config->getHTML()->hasThemeVariant()) { + $variant = $config->getHTML()->getThemeVariant(); if (!array_key_exists($variant, $theme['variants'])) { throw new Exception("Variant '$variant' not found for theme '$theme[name]'"); } @@ -101,8 +85,16 @@ class DauxHelper } } + if ($theme['with_search']) { + $theme['css'][] = 'daux_libraries/search.css'; + } + + if (is_file($config->getDocumentationDirectory() . DIRECTORY_SEPARATOR . 'style.css')) { + $theme['css'][]= 'style.css'; + } + $substitutions = [ - '' => $params['local_base'], + '' => $config->getLocalBase(), '' => $current_url, '' => $theme_url, ]; @@ -117,13 +109,16 @@ class DauxHelper } } + $cache[$cache_key] = $theme; + return $theme; } /** - * Remove all '/./' and '/../' in a path, without actually checking the path + * Remove all '/./' and '/../' in a path, without actually checking the path. * * @param string $path + * * @return string */ public static function getCleanPath($path) @@ -148,13 +143,13 @@ class DauxHelper /** * Get the possible output file names for a source file. * - * @param Config $config * @param string $part + * * @return string[] */ public static function getFilenames(Config $config, $part) { - $extensions = implode('|', array_map('preg_quote', $config['valid_content_extensions'])) . '|html'; + $extensions = implode('|', array_map('preg_quote', $config->getValidContentExtensions())) . '|html'; $raw = preg_replace('/(.*)?\\.(' . $extensions . ')$/', '$1', $part); $raw = Builder::removeSortingInformations($raw); @@ -163,11 +158,12 @@ class DauxHelper } /** - * Locate a file in the tree. Returns the file if found or false + * Locate a file in the tree. Returns the file if found or false. * * @param Directory $tree * @param string $request - * @return Tree\Content|Tree\Raw|false + * + * @return false|Tree\Content|Tree\Raw */ public static function getFile($tree, $request) { @@ -186,16 +182,24 @@ class DauxHelper if ($node == '..') { $tree = $tree->getParent(); + continue; } - $node = DauxHelper::slug(urldecode($node)); - // if the node exists in the current request tree, // change the $tree variable to reference the new // node and proceed to the next url part if (isset($tree->getEntries()[$node])) { $tree = $tree->getEntries()[$node]; + + continue; + } + + // We try a second time by decoding the url + $node = DauxHelper::slug(urldecode($node)); + if (isset($tree->getEntries()[$node])) { + $tree = $tree->getEntries()[$node]; + continue; } @@ -205,6 +209,7 @@ class DauxHelper foreach (static::getFilenames($tree->getConfig(), $node) as $filename) { if (isset($tree->getEntries()[$filename])) { $tree = $tree->getEntries()[$filename]; + continue 2; } } @@ -237,15 +242,18 @@ class DauxHelper * Taken from Stringy * * @param string $title + * * @return string */ public static function slug($title) { // Convert to ASCII - foreach (static::charsArray() as $key => $value) { - $title = str_replace($value, $key, $title); + if (function_exists('transliterator_transliterate')) { + $title = transliterator_transliterate('Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC;', $title); } + $title = iconv('utf-8', 'ASCII//TRANSLIT//IGNORE', $title); + // Remove unsupported characters $title = preg_replace('/[^\x20-\x7E]/u', '', $title); @@ -253,7 +261,7 @@ class DauxHelper // Convert all dashes into underscores $title = preg_replace('![' . preg_quote('-') . ']+!u', $separator, $title); - // Remove all characters that are not valid in a URL: + // Remove all characters that are not valid in a URL: // $-_.+!*'(), separator, letters, numbers, or whitespace. $title = preg_replace('![^-' . preg_quote($separator) . '\!\'\(\),\.\+\*\$\pL\pN\s]+!u', '', $title); @@ -263,149 +271,10 @@ class DauxHelper return trim($title, $separator); } - /** - * Returns the replacements for the slug() method. - * - * Taken from Stringy - * - * @return array An array of replacements. - */ - public static function charsArray() - { - static $charsArray; - - if (isset($charsArray)) { - return $charsArray; - } - - return $charsArray = [ - 'a' => [ - 'à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ', - 'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ä', 'ā', 'ą', - 'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ', - 'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ', - 'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', ], - 'b' => ['б', 'β', 'Ъ', 'Ь', 'ب'], - 'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ'], - 'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', - 'д', 'δ', 'د', 'ض', ], - 'e' => ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ', - 'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ', - 'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э', - 'є', 'ə', ], - 'f' => ['ф', 'φ', 'ف'], - 'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ج'], - 'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه'], - 'i' => ['í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į', - 'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ', - 'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ', - 'ῗ', 'і', 'ї', 'и', ], - 'j' => ['ĵ', 'ј', 'Ј'], - 'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك'], - 'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل'], - 'm' => ['м', 'μ', 'م'], - 'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن'], - 'o' => ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ', - 'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő', - 'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό', - 'ö', 'о', 'و', 'θ', ], - 'p' => ['п', 'π'], - 'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر'], - 's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص'], - 't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط'], - 'u' => ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ', - 'ự', 'ü', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', ], - 'v' => ['в'], - 'w' => ['ŵ', 'ω', 'ώ'], - 'x' => ['χ'], - 'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', - 'ϋ', 'ύ', 'ΰ', 'ي', ], - 'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز'], - 'aa' => ['ع'], - 'ae' => ['æ'], - 'ch' => ['ч'], - 'dj' => ['ђ', 'đ'], - 'dz' => ['џ'], - 'gh' => ['غ'], - 'kh' => ['х', 'خ'], - 'lj' => ['љ'], - 'nj' => ['њ'], - 'oe' => ['œ'], - 'ps' => ['ψ'], - 'sh' => ['ш'], - 'shch' => ['щ'], - 'ss' => ['ß'], - 'th' => ['þ', 'ث', 'ذ', 'ظ'], - 'ts' => ['ц'], - 'ya' => ['я'], - 'yu' => ['ю'], - 'zh' => ['ж'], - '(c)' => ['©'], - 'A' => ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ', - 'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Ä', 'Å', 'Ā', - 'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ', - 'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ', - 'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А', ], - 'B' => ['Б', 'Β'], - 'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ'], - 'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'], - 'E' => ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ', - 'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ', - 'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э', - 'Є', 'Ə', ], - 'F' => ['Ф', 'Φ'], - 'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'], - 'H' => ['Η', 'Ή'], - 'I' => ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į', - 'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ', - 'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', ], - 'K' => ['К', 'Κ'], - 'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ'], - 'M' => ['М', 'Μ'], - 'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'], - 'O' => ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ', - 'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ö', 'Ø', 'Ō', - 'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ', - 'Ὸ', 'Ό', 'О', 'Θ', 'Ө', ], - 'P' => ['П', 'Π'], - 'R' => ['Ř', 'Ŕ', 'Р', 'Ρ'], - 'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'], - 'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'], - 'U' => ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ', - 'Ự', 'Û', 'Ü', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', ], - 'V' => ['В'], - 'W' => ['Ω', 'Ώ'], - 'X' => ['Χ'], - 'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', - 'Ы', 'Й', 'Υ', 'Ϋ', ], - 'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ'], - 'AE' => ['Æ'], - 'CH' => ['Ч'], - 'DJ' => ['Ђ'], - 'DZ' => ['Џ'], - 'KH' => ['Х'], - 'LJ' => ['Љ'], - 'NJ' => ['Њ'], - 'PS' => ['Ψ'], - 'SH' => ['Ш'], - 'SHCH' => ['Щ'], - 'SS' => ['ẞ'], - 'TH' => ['Þ'], - 'TS' => ['Ц'], - 'YA' => ['Я'], - 'YU' => ['Ю'], - 'ZH' => ['Ж'], - ' ' => ["\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81", - "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84", - "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87", - "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A", - "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80", ], - ]; - } - /** * @param string $from * @param string $to + * * @return string */ public static function getRelativePath($from, $to) @@ -432,10 +301,10 @@ class DauxHelper // add traversals up to first matching dir $padLength = (count($relPath) + $remaining - 1) * -1; $relPath = array_pad($relPath, $padLength, '..'); + break; - } else { - //$relPath[0] = './' . $relPath[0]; } + //$relPath[0] = './' . $relPath[0]; } } @@ -446,11 +315,13 @@ class DauxHelper { if (!is_string($path)) { $mess = sprintf('String expected but was given %s', gettype($path)); + throw new \InvalidArgumentException($mess); } if (!ctype_print($path)) { $mess = 'Path can NOT have non-printable characters or be empty'; + throw new \DomainException($mess); } @@ -466,13 +337,15 @@ class DauxHelper $parts = []; if (!preg_match($regExp, $path, $parts)) { $mess = sprintf('Path is NOT valid, was given %s', $path); + throw new \DomainException($mess); } return '' !== $parts['root']; } - public static function getAbsolutePath($path) { + public static function getAbsolutePath($path) + { if (DauxHelper::isAbsolutePath($path)) { return $path; } @@ -480,45 +353,58 @@ class DauxHelper return getcwd() . '/' . $path; } - /** - * @param string|null $path - * @param string $basedir - * @param string $var The constant name to check - * @param "dir"|"file" $type - * @return false|null|string - */ - public static function findLocation($path, $basedir, $var, $type) { - // VFS, used only in tests - if (substr($path, 0, 6) == "vfs://") { - return $path; - } - - // When running through `daux --serve` we set an environment variable to know where we started from - $env = getenv($var); - if ($env && DauxHelper::is($env, $type)) { - return $env; - } - - // If Path is explicitly null, it's useless to go further - if ($path == null) { - return null; - } - - // Check if it's relative to the current directory or an absolute path - if (DauxHelper::is($path, $type)) { - return DauxHelper::getAbsolutePath($path); - } - - // Check if it exists relative to Daux's root - $newPath = $basedir . DIRECTORY_SEPARATOR . $path; - if (DauxHelper::is($newPath, $type)) { - return $newPath; - } - - return false; - } - - public static function is($path, $type) { + public static function is($path, $type) + { return ($type == 'dir') ? is_dir($path) : file_exists($path); } + + /** + * @param Config $config + * @param string $url + * + * @throws LinkNotFoundException + * + * @return Entry + */ + public static function resolveInternalFile($config, $url) + { + $triedAbsolute = false; + + // Legacy absolute paths could start with + // "!" In this case we will try to find + // the file starting at the root + if ($url[0] == '!' || $url[0] == '/') { + $url = ltrim($url, '!/'); + + if ($file = DauxHelper::getFile($config->getTree(), $url)) { + return $file; + } + + $triedAbsolute = true; + } + + // Seems it's not an absolute path or not found, + // so we'll continue with the current folder + if ($file = DauxHelper::getFile($config->getCurrentPage()->getParent(), $url)) { + return $file; + } + + // If we didn't already try it, we'll + // do a pass starting at the root + if (!$triedAbsolute && $file = DauxHelper::getFile($config->getTree(), $url)) { + return $file; + } + + throw new LinkNotFoundException("Could not locate file '$url'"); + } + + public static function isValidUrl($url) + { + return !empty($url) && $url[0] != '#'; + } + + public static function isExternalUrl($url) + { + return preg_match('#^(?:[a-z]+:)?//|^mailto:#', $url); + } } diff --git a/libs/Format/Base/ContentPage.php b/libs/Format/Base/ContentPage.php index 7641085..4af078e 100644 --- a/libs/Format/Base/ContentPage.php +++ b/libs/Format/Base/ContentPage.php @@ -14,7 +14,7 @@ abstract class ContentPage extends SimplePage /** * @var Config */ - protected $params; + protected $config; /** * @var ContentType @@ -38,9 +38,17 @@ abstract class ContentPage extends SimplePage return $this->file; } - public function setParams(Config $params) + public function setConfig(Config $config) { - $this->params = $params; + $this->config = $config; + } + + /** + * @deprecated use setConfig instead + */ + public function setParams(Config $config) + { + $this->setConfig($config); } /** @@ -65,11 +73,11 @@ abstract class ContentPage extends SimplePage return $this->getPureContent(); } - public static function fromFile(Content $file, $params, ContentType $contentType) + public static function fromFile(Content $file, $config, ContentType $contentType) { $page = new static($file->getTitle(), $file->getContent()); $page->setFile($file); - $page->setParams($params); + $page->setConfig($config); $page->setContentType($contentType); return $page; diff --git a/libs/Format/Base/EmbedImages.php b/libs/Format/Base/EmbedImages.php index f729e7e..ffef74b 100644 --- a/libs/Format/Base/EmbedImages.php +++ b/libs/Format/Base/EmbedImages.php @@ -3,7 +3,7 @@ * Created by IntelliJ IDEA. * User: onigoetz * Date: 06/11/15 - * Time: 20:27 + * Time: 20:27. */ namespace Todaymade\Daux\Format\Base; @@ -25,7 +25,7 @@ class EmbedImages { return preg_replace_callback( "/]*src=['\"]([^\"]*)['\"][^>]*>/", - function($matches) use ($file, $callback) { + function ($matches) use ($file, $callback) { if ($result = $this->findImage($matches[1], $matches[0], $file, $callback)) { return $result; } @@ -67,7 +67,6 @@ class EmbedImages //Get any file corresponding to the right one $file = DauxHelper::getFile($this->tree, $url); - if ($file === false) { return false; } diff --git a/libs/Format/Base/Generator.php b/libs/Format/Base/Generator.php index e499309..c29e426 100644 --- a/libs/Format/Base/Generator.php +++ b/libs/Format/Base/Generator.php @@ -6,15 +6,11 @@ use Todaymade\Daux\Daux; interface Generator { - /** - * @param Daux $daux - */ public function __construct(Daux $daux); /** - * @param InputInterface $input - * @param OutputInterface $output * @param int $width + * * @return mixed */ public function generateAll(InputInterface $input, OutputInterface $output, $width); diff --git a/libs/Format/Base/LiveGenerator.php b/libs/Format/Base/LiveGenerator.php index 97e14c6..4e364e3 100644 --- a/libs/Format/Base/LiveGenerator.php +++ b/libs/Format/Base/LiveGenerator.php @@ -6,9 +6,7 @@ use Todaymade\Daux\Tree\Entry; interface LiveGenerator extends Generator { /** - * @param Entry $node - * @param Config $params * @return \Todaymade\Daux\Format\Base\Page */ - public function generateOne(Entry $node, Config $params); + public function generateOne(Entry $node, Config $config); } diff --git a/libs/Format/Base/Page.php b/libs/Format/Base/Page.php index a7fd4c9..130418f 100644 --- a/libs/Format/Base/Page.php +++ b/libs/Format/Base/Page.php @@ -3,14 +3,14 @@ interface Page { /** - * Get the converted content, without any template + * Get the converted content, without any template. * * @return string */ public function getPureContent(); /** - * Get the full content + * Get the full content. * * @return mixed */ diff --git a/libs/Format/Confluence/Api.php b/libs/Format/Confluence/Api.php index 81d1c38..77f1b47 100644 --- a/libs/Format/Confluence/Api.php +++ b/libs/Format/Confluence/Api.php @@ -24,7 +24,8 @@ class Api } /** - * This method is public due to test purposes + * This method is public due to test purposes. + * * @return Client */ public function getClient() @@ -39,9 +40,8 @@ class Api /** * The standard error message from guzzle is quite poor in informations, - * this will give little bit more sense to it and return it + * this will give little bit more sense to it and return it. * - * @param BadResponseException $e * @return \Exception */ protected function handleError(BadResponseException $e) @@ -101,10 +101,11 @@ class Api } /** - * Get a list of pages + * Get a list of pages. * * @param int $rootPage * @param bool $recursive + * * @return array */ public function getList($rootPage, $recursive = false) @@ -153,6 +154,7 @@ class Api * @param int $parent_id * @param string $title * @param string $content + * * @return int */ public function createPage($parent_id, $title, $content) @@ -218,8 +220,13 @@ class Api public function showSourceCode($css, $lineNumber, $column) { $lines = preg_split("/\r?\n/", $css); + + if ($lines === false) { + return $css; + } + $start = max($lineNumber - 3, 0); - $end = min($lineNumber + 2, count($lines)); + $end = min($lineNumber + 2, count($lines)); $maxWidth = strlen("$end"); @@ -227,12 +234,11 @@ class Api $prepared = []; foreach ($filtered as $index => $line) { - $number = $start + 1 + $index; $gutter = substr(' ' . (' ' . $number), -$maxWidth) . ' | '; if ($number == $lineNumber) { - $spacing = str_repeat(" ", strlen($gutter) + $column - 2); + $spacing = str_repeat(' ', strlen($gutter) + $column - 2); $prepared[] = '>' . $gutter . $line . "\n " . $spacing . '^'; } else { $prepared[] = ' ' . $gutter . $line; @@ -243,9 +249,10 @@ class Api } /** - * Delete a page + * Delete a page. * * @param int $page_id + * * @return mixed */ public function deletePage($page_id) @@ -263,6 +270,7 @@ class Api // this name is uploaded try { $url = "content/$id/child/attachment?filename=" . urlencode($attachment['filename']); + return json_decode($this->getClient()->get($url)->getBody(), true); } catch (BadResponseException $e) { throw $this->handleError($e); @@ -313,9 +321,9 @@ class Api // If the attachment is already uploaded, // the update URL is different if (count($result['results'])) { - if ($this->getFileSize($attachment) == $result['results'][0]['extensions']['fileSize']) { - $write(" ( An attachment of the same size already exists, skipping. )"); + $write(' ( An attachment of the same size already exists, skipping. )'); + return; } diff --git a/libs/Format/Confluence/Config.php b/libs/Format/Confluence/Config.php new file mode 100644 index 0000000..351a03d --- /dev/null +++ b/libs/Format/Confluence/Config.php @@ -0,0 +1,80 @@ +hasValue('delete')) { + return $this->getValue('delete'); + } + + return false; + } + + public function getUpdateThreshold() + { + return $this->hasValue('update_threshold') ? $this->getValue('update_threshold') : 2; + } + + public function getPrefix() + { + return $this->getValue('prefix'); + } + + public function getBaseUrl() + { + return $this->getValue('base_url'); + } + + public function getUser() + { + return $this->getValue('user'); + } + + public function getPassword() + { + return $this->getValue('pass'); + } + + public function getSpaceId() + { + return $this->getValue('space_id'); + } + + public function hasAncestorId() + { + return $this->hasValue('ancestor_id'); + } + + public function getAncestorId() + { + return $this->getValue('ancestor_id'); + } + + public function setAncestorId($value) + { + $this->setValue('ancestor_id', $value); + } + + public function hasRootId() + { + return $this->hasValue('root_id'); + } + + public function getRootId() + { + return $this->getValue('root_id'); + } + + public function hasHeader() + { + return $this->hasValue('header'); + } + + public function getHeader() + { + return $this->getValue('header'); + } +} diff --git a/libs/Format/Confluence/ContentPage.php b/libs/Format/Confluence/ContentPage.php index abddf52..7a0ec9d 100644 --- a/libs/Format/Confluence/ContentPage.php +++ b/libs/Format/Confluence/ContentPage.php @@ -15,17 +15,16 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage //Embed images // We do it after generation so we can catch the images that were in html already - $content = (new EmbedImages($this->params['tree'])) + $content = (new EmbedImages($this->config->getTree())) ->embed( $content, $this->file, - function($src, array $attributes, Entry $file) { - + function ($src, array $attributes, Entry $file) { //Add the attachment for later upload if ($file instanceof Raw) { $filename = basename($file->getPath()); $this->attachments[$filename] = ['filename' => $filename, 'file' => $file]; - } else if ($file instanceof ComputedRaw) { + } elseif ($file instanceof ComputedRaw) { $filename = $file->getUri(); $this->attachments[$filename] = ['filename' => $filename, 'content' => $file->getContent()]; } else { @@ -36,20 +35,20 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage } ); - $intro = ''; - if (array_key_exists('confluence', $this->params) && array_key_exists('header', $this->params['confluence']) && !empty($this->params['confluence']['header'])) { - $intro = '' . $this->params['confluence']['header'] . ''; + if ($this->config->getConfluenceConfiguration()->hasHeader()) { + $intro = '' . $this->config->getConfluenceConfiguration()->getHeader() . ''; } return $intro . $content; } /** - * Create an image tag for the specified filename + * Create an image tag for the specified filename. * * @param string $filename * @param array $attributes + * * @return string */ private function createImageTag($filename, $attributes) @@ -61,7 +60,7 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage $re = '/float:\s*?(left|right);?/'; if (preg_match($re, $value, $matches)) { $img .= ' ac:align="' . $matches[1] . '"'; - $value = preg_replace($re, "", $value, 1); + $value = preg_replace($re, '', $value, 1); } } diff --git a/libs/Format/Confluence/ContentTypes/Markdown/CodeRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/CodeRenderer.php index 2e738f2..d87c212 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/CodeRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/CodeRenderer.php @@ -5,10 +5,9 @@ use League\CommonMark\HtmlElement; abstract class CodeRenderer implements BlockRendererInterface { - public function escapeCDATA($content) { - return str_replace("]]>", "]]]]>", $content); + return str_replace(']]>', ']]]]>', $content); } public function getHTMLElement($body, $language) diff --git a/libs/Format/Confluence/ContentTypes/Markdown/CommonMarkConverter.php b/libs/Format/Confluence/ContentTypes/Markdown/CommonMarkConverter.php index 39ae5f1..0a066da 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/CommonMarkConverter.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/CommonMarkConverter.php @@ -1,7 +1,10 @@ addBlockRenderer('Todaymade\Daux\ContentTypes\Markdown\TableOfContents', new TOCRenderer()); + $environment->addBlockRenderer(TableOfContents::class, new TOCRenderer()); //Add code renderer - $environment->addBlockRenderer('FencedCode', new FencedCodeRenderer()); - $environment->addBlockRenderer('IndentedCode', new IndentedCodeRenderer()); + $environment->addBlockRenderer(BlockElement\FencedCode::class, new FencedCodeRenderer()); + $environment->addBlockRenderer(BlockElement\IndentedCode::class, new IndentedCodeRenderer()); - $environment->addInlineRenderer('Image', new ImageRenderer()); + $environment->addInlineRenderer(InlineElement\Image::class, new ImageRenderer()); } } diff --git a/libs/Format/Confluence/ContentTypes/Markdown/ContentType.php b/libs/Format/Confluence/ContentTypes/Markdown/ContentType.php index e1f2410..d671938 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/ContentType.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/ContentType.php @@ -1,12 +1,9 @@ config = $config; - $this->converter = new CommonMarkConverter(['daux' => $config]); + return new CommonMarkConverter(['daux' => $this->config]); } } diff --git a/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php index 5d50682..68d1f9f 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php @@ -36,8 +36,6 @@ class FencedCodeRenderer extends CodeRenderer protected $known_conversions = ['html' => 'html/xml', 'xml' => 'html/xml', 'js' => 'javascript']; /** - * @param AbstractBlock $block - * @param HtmlRendererInterface $htmlRenderer * @param bool $inTightList * * @return HtmlElement|string @@ -48,18 +46,18 @@ class FencedCodeRenderer extends CodeRenderer throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block)); } - $language = $this->getLanguage($block->getInfoWords(), $htmlRenderer); + $language = $this->getLanguage($block->getInfoWords()); return $this->getHTMLElement($block->getStringContent(), $language); } - public function getLanguage($infoWords, ElementRendererInterface $htmlRenderer) + public function getLanguage($infoWords) { if (count($infoWords) === 0 || strlen($infoWords[0]) === 0) { return false; } - $language = Xml::escape($infoWords[0], true); + $language = Xml::escape($infoWords[0]); if (array_key_exists($language, $this->known_conversions)) { $language = $this->known_conversions[$language]; diff --git a/libs/Format/Confluence/ContentTypes/Markdown/ImageRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/ImageRenderer.php index a135565..67d523a 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/ImageRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/ImageRenderer.php @@ -4,12 +4,29 @@ use League\CommonMark\ElementRendererInterface; use League\CommonMark\HtmlElement; use League\CommonMark\Inline\Element\AbstractInline; use League\CommonMark\Inline\Element\Image; +use League\CommonMark\Inline\Renderer\InlineRendererInterface; +use League\CommonMark\Util\ConfigurationAwareInterface; +use League\CommonMark\Util\ConfigurationInterface; -class ImageRenderer extends \League\CommonMark\Inline\Renderer\ImageRenderer +class ImageRenderer implements InlineRendererInterface, ConfigurationAwareInterface { + /** + * @var ConfigurationInterface + */ + protected $config; + + /** + * @var \League\CommonMark\Inline\Renderer\ImageRenderer + */ + protected $parent; + + public function __construct() + { + $this->parent = new \League\CommonMark\Inline\Renderer\ImageRenderer(); + } + /** * @param Image $inline - * @param ElementRendererInterface $htmlRenderer * * @return HtmlElement */ @@ -28,6 +45,11 @@ class ImageRenderer extends \League\CommonMark\Inline\Renderer\ImageRenderer ); } - return parent::render($inline, $htmlRenderer); + return $this->parent->render($inline, $htmlRenderer); + } + + public function setConfiguration(ConfigurationInterface $configuration) + { + $this->parent->setConfiguration($configuration); } } diff --git a/libs/Format/Confluence/ContentTypes/Markdown/IndentedCodeRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/IndentedCodeRenderer.php index 5e3cb09..576fd6a 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/IndentedCodeRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/IndentedCodeRenderer.php @@ -8,8 +8,6 @@ use League\CommonMark\HtmlElement; class IndentedCodeRenderer extends CodeRenderer { /** - * @param AbstractBlock $block - * @param HtmlRendererInterface $htmlRenderer * @param bool $inTightList * * @return HtmlElement @@ -20,6 +18,6 @@ class IndentedCodeRenderer extends CodeRenderer throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block)); } - return $this->getHTMLElement($block->getStringContent(), ""); + return $this->getHTMLElement($block->getStringContent(), ''); } } diff --git a/libs/Format/Confluence/ContentTypes/Markdown/LinkRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/LinkRenderer.php index 42217d0..06590b1 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/LinkRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/LinkRenderer.php @@ -4,26 +4,19 @@ use League\CommonMark\ElementRendererInterface; use League\CommonMark\HtmlElement; use League\CommonMark\Inline\Element\AbstractInline; use League\CommonMark\Inline\Element\Link; +use Todaymade\Daux\DauxHelper; class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer { /** * @param AbstractInline|Link $inline - * @param ElementRendererInterface $htmlRenderer * * @return HtmlElement */ public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer) { - // This can't be in the method type as - // the method is an abstract and should - // have the same interface - if (!$inline instanceof Link) { - throw new \RuntimeException( - 'Wrong type passed to ' . __CLASS__ . '::' . __METHOD__ . - " the expected type was 'League\\CommonMark\\Inline\\Element\\Link' but '" . - get_class($inline) . "' was provided" - ); + if (!($inline instanceof Link)) { + throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline)); } // Default handling @@ -33,19 +26,29 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer // empty urls, anchors and absolute urls // should not go through the url resolver - if (!$this->isValidUrl($url) || $this->isExternalUrl($url)) { + if (!DauxHelper::isValidUrl($url) || DauxHelper::isExternalUrl($url)) { return $element; } - //Internal links - $file = $this->resolveInternalFile($url); + // if there's a hash component in the url, ensure we + // don't put that part through the resolver. + $urlAndHash = explode('#', $url); + $url = $urlAndHash[0]; - $link_props = [ + //Internal links + $file = DauxHelper::resolveInternalFile($this->daux, $url); + + $link_props = []; + if (isset($urlAndHash[1])) { + $link_props["ac:anchor"] = $urlAndHash[1]; + } + + $page_props = [ 'ri:content-title' => trim(trim($this->daux['confluence']['prefix']) . ' ' . $file->getTitle()), 'ri:space-key' => $this->daux['confluence']['space_id'], ]; - $page = strval(new HtmlElement('ri:page', $link_props, '', true)); + $page = strval(new HtmlElement('ri:page', $page_props, '', true)); $children = $htmlRenderer->renderInlines($inline->children()); if (strpos($children, '<') !== false) { $children = '' . $children . ''; @@ -53,6 +56,6 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer $children = ''; } - return new HtmlElement('ac:link', [], $page . $children); + return new HtmlElement('ac:link', $link_props, $page . $children); } } diff --git a/libs/Format/Confluence/ContentTypes/Markdown/TOCRenderer.php b/libs/Format/Confluence/ContentTypes/Markdown/TOCRenderer.php index 9e5ee90..6d2a3ef 100644 --- a/libs/Format/Confluence/ContentTypes/Markdown/TOCRenderer.php +++ b/libs/Format/Confluence/ContentTypes/Markdown/TOCRenderer.php @@ -3,11 +3,16 @@ use League\CommonMark\Block\Element\AbstractBlock; use League\CommonMark\Block\Renderer\BlockRendererInterface; use League\CommonMark\ElementRendererInterface; +use Todaymade\Daux\ContentTypes\Markdown\TableOfContents; class TOCRenderer implements BlockRendererInterface { public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, $inTightList = false) { + if (!($block instanceof TableOfContents)) { + throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block)); + } + return ''; } } diff --git a/libs/Format/Confluence/Generator.php b/libs/Format/Confluence/Generator.php index 0c70c23..e425ac3 100644 --- a/libs/Format/Confluence/Generator.php +++ b/libs/Format/Confluence/Generator.php @@ -2,7 +2,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -use Todaymade\Daux\Config; +use Todaymade\Daux\Config as GlobalConfig; use Todaymade\Daux\Console\RunAction; use Todaymade\Daux\Daux; use Todaymade\Daux\Tree\Content; @@ -18,9 +18,6 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator /** @var Daux */ protected $daux; - /** - * @param Daux $daux - */ public function __construct(Daux $daux) { $this->daux = $daux; @@ -30,7 +27,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator public function checkConfiguration() { - $config = $this->daux->getParams(); + $config = $this->daux->getConfig(); $confluence = $config->getConfluenceConfiguration(); if ($confluence == null) { @@ -40,7 +37,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $mandatory = ['space_id', 'base_url', 'user', 'pass', 'prefix']; $errors = []; foreach ($mandatory as $key) { - if (!array_key_exists($key, $confluence)) { + if (!$confluence->hasValue($key)) { $errors[] = $key; } } @@ -49,7 +46,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator throw new \RuntimeException("The following options are mandatory for confluence : '" . implode("', '", $errors) . "'"); } - if (!array_key_exists('ancestor_id', $confluence) && !array_key_exists('root_id', $confluence)) { + if (!$confluence->hasAncestorId() && !$confluence->hasRootId()) { throw new \RuntimeException("You must specify an 'ancestor_id' or a 'root_id' for confluence."); } } @@ -60,7 +57,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator public function getContentTypes() { return [ - new ContentTypes\Markdown\ContentType($this->daux->getParams()), + new ContentTypes\Markdown\ContentType($this->daux->getConfig()), ]; } @@ -69,10 +66,10 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator */ public function generateAll(InputInterface $input, OutputInterface $output, $width) { - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); - $confluence = $params['confluence']; - $this->prefix = trim($confluence['prefix']) . ' '; + $confluence = $config->getConfluenceConfiguration(); + $this->prefix = trim($confluence->getPrefix()) . ' '; if ($this->prefix == ' ') { $this->prefix = ''; } @@ -80,9 +77,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $tree = $this->runAction( 'Generating Tree ...', $width, - function() use ($params) { - $tree = $this->generateRecursive($this->daux->tree, $params); - $tree['title'] = $this->prefix . $params['title']; + function () use ($config) { + $tree = $this->generateRecursive($this->daux->tree, $config); + $tree['title'] = $this->prefix . $config->getTitle(); return $tree; } @@ -96,31 +93,31 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $publisher->publish($tree); } - private function generateRecursive(Directory $tree, Config $params, $base_url = '') + private function generateRecursive(Directory $tree, GlobalConfig $config, $base_url = '') { $final = ['title' => $this->prefix . $tree->getTitle()]; - $params['base_url'] = $params['base_page'] = $base_url; + $config['base_url'] = $base_url; - $params['image'] = str_replace('', $base_url, $params['image']); + $config->setImage(str_replace('', $base_url, $config->getImage())); if ($base_url !== '') { - $params['entry_page'] = $tree->getFirstPage(); + $config->setEntryPage($tree->getFirstPage()); } foreach ($tree->getEntries() as $key => $node) { if ($node instanceof Directory) { $final['children'][$this->prefix . $node->getTitle()] = $this->generateRecursive( $node, - $params, + $config, '../' . $base_url ); } elseif ($node instanceof Content) { - $params['request'] = $node->getUrl(); + $config->setRequest($node->getUrl()); $contentType = $this->daux->getContentTypeHandler()->getType($node); $data = [ 'title' => $this->prefix . $node->getTitle(), 'file' => $node, - 'page' => ContentPage::fromFile($node, $params, $contentType), + 'page' => ContentPage::fromFile($node, $config, $contentType), ]; if ($key == 'index.html') { diff --git a/libs/Format/Confluence/Publisher.php b/libs/Format/Confluence/Publisher.php index 94a4832..1c699c8 100644 --- a/libs/Format/Confluence/Publisher.php +++ b/libs/Format/Confluence/Publisher.php @@ -7,16 +7,6 @@ class Publisher { use RunAction; - /** - * @var Api - */ - protected $client; - - /** - * @var array - */ - protected $confluence; - /** * @var int terminal width */ @@ -27,15 +17,25 @@ class Publisher */ public $output; + /** + * @var Api + */ + protected $client; + + /** + * @var Config + */ + protected $confluence; + /** * @param $confluence */ - public function __construct($confluence) + public function __construct(Config $confluence) { $this->confluence = $confluence; - $this->client = new Api($confluence['base_url'], $confluence['user'], $confluence['pass']); - $this->client->setSpace($confluence['space_id']); + $this->client = new Api($confluence->getBaseUrl(), $confluence->getUser(), $confluence->getPassword()); + $this->client->setSpace($confluence->getSpaceId()); } public function run($title, $closure) @@ -62,24 +62,23 @@ class Publisher ); $published = $this->run( - "Create placeholder pages...", + 'Create placeholder pages...', function () use ($tree, $published) { - return $this->createRecursive($this->confluence['ancestor_id'], $tree, $published); + return $this->createRecursive($this->confluence->getAncestorId(), $tree, $published); } ); $this->output->writeLn('Publishing updates...'); - $published = $this->updateRecursive($this->confluence['ancestor_id'], $tree, $published); + $published = $this->updateRecursive($this->confluence->getAncestorId(), $tree, $published); - $shouldDelete = array_key_exists('delete', $this->confluence) && $this->confluence['delete']; - $delete = new PublisherDelete($this->output, $shouldDelete, $this->client); + $delete = new PublisherDelete($this->output, $this->confluence->shouldAutoDeleteOrphanedPages(), $this->client); $delete->handle($published); } protected function getRootPage($tree) { - if (array_key_exists('ancestor_id', $this->confluence)) { - $pages = $this->client->getList($this->confluence['ancestor_id']); + if ($this->confluence->hasAncestorId()) { + $pages = $this->client->getList($this->confluence->getAncestorId()); foreach ($pages as $page) { if ($page['title'] == $tree['title']) { return $page; @@ -87,9 +86,10 @@ class Publisher } } - if (array_key_exists('root_id', $this->confluence)) { - $published = $this->client->getPage($this->confluence['root_id']); - $this->confluence['ancestor_id'] = $published['ancestor_id']; + if ($this->confluence->hasRootId()) { + $published = $this->client->getPage($this->confluence->getRootId()); + $this->confluence->setAncestorId($published['ancestor_id']); + return $published; } @@ -178,7 +178,7 @@ class Publisher protected function updatePage($parent_id, $entry, $published) { - $updateThreshold = array_key_exists('update_threshold', $this->confluence) ? $this->confluence['update_threshold'] : 2; + $updateThreshold = $this->confluence->getUpdateThreshold(); $this->run( '- ' . PublisherUtilities::niceTitle($entry['file']->getUrl()), diff --git a/libs/Format/Confluence/PublisherDelete.php b/libs/Format/Confluence/PublisherDelete.php index b3a94a6..5879cc3 100644 --- a/libs/Format/Confluence/PublisherDelete.php +++ b/libs/Format/Confluence/PublisherDelete.php @@ -13,7 +13,7 @@ class PublisherDelete protected $deletable; /** - * @var boolean should delete ? + * @var bool should delete ? */ protected $delete; @@ -22,13 +22,12 @@ class PublisherDelete */ protected $client; - public function __construct($output, $delete, $client) + public function __construct($output, bool $delete, $client) { $this->output = $output; $this->delete = $delete; $this->client = $client; - $this->deletable = []; } @@ -55,13 +54,13 @@ class PublisherDelete if ($this->delete) { $this->doDelete(); - } else { $this->displayDeletable(); } } - protected function doDelete() { + protected function doDelete() + { $this->output->writeLn('Deleting obsolete pages...'); foreach ($this->deletable as $id => $title) { $this->output->writeLn("- $title"); @@ -69,10 +68,11 @@ class PublisherDelete } } - protected function displayDeletable() { + protected function displayDeletable() + { $this->output->writeLn('Listing obsolete pages...'); - $this->output->writeLn("> The following pages will not be deleted, but just listed for information."); - $this->output->writeLn("> If you want to delete these pages, you need to set the --delete flag on the command."); + $this->output->writeLn('> The following pages will not be deleted, but just listed for information.'); + $this->output->writeLn('> If you want to delete these pages, you need to set the --delete flag on the command.'); foreach ($this->deletable as $id => $title) { $this->output->writeLn("- $title"); } diff --git a/libs/Format/HTML/Config.php b/libs/Format/HTML/Config.php index affd476..cac9528 100644 --- a/libs/Format/HTML/Config.php +++ b/libs/Format/HTML/Config.php @@ -10,27 +10,182 @@ class Config extends BaseConfig return [ 'name' => 'GitHub', - 'basepath' => (strpos($url, 'https://github.com/') === 0 ? '' : 'https://github.com/') . trim($url, '/') + 'basepath' => (strpos($url, 'https://github.com/') === 0 ? '' : 'https://github.com/') . trim($url, '/'), ]; } public function getEditOn() { - if (array_key_exists('edit_on', $this)) { - if (is_string($this['edit_on'])) { - return $this->prepareGithubUrl($this['edit_on']); - } else { - - $this['edit_on']['basepath'] = rtrim($this['edit_on']['basepath'], '/'); - - return $this['edit_on']; + if ($this->hasValue('edit_on')) { + $edit_on = $this->getValue('edit_on'); + if (is_string($edit_on)) { + return $this->prepareGithubUrl($edit_on); } + $edit_on['basepath'] = rtrim($edit_on['basepath'], '/'); + + return $edit_on; } - if (array_key_exists('edit_on_github', $this)) { - return $this->prepareGithubUrl($this['edit_on_github']); + if ($this->hasValue('edit_on_github')) { + return $this->prepareGithubUrl($this->getValue('edit_on_github')); } return null; } + + public function hasSearch() + { + return $this->hasValue('search') && $this->getValue('search'); + } + + public function showDateModified() + { + return $this->hasValue('date_modified') && $this->getValue('date_modified'); + } + + public function showPreviousNextLinks() + { + if ($this->hasValue('jump_buttons')) { + return $this->getValue('jump_buttons'); + } + + return true; + } + + public function showCodeToggle() + { + if ($this->hasValue('toggle_code')) { + return $this->getValue('toggle_code'); + } + + return true; + } + + public function hasAutomaticTableOfContents(): bool + { + return $this->hasValue('auto_toc') && $this->getValue('auto_toc'); + } + + public function hasGoogleAnalytics() + { + return $this->hasValue('google_analytics') && $this->getValue('google_analytics'); + } + + public function getGoogleAnalyticsId() + { + return $this->getValue('google_analytics'); + } + + public function hasPlausibleAnalyticsDomain() + { + return $this->hasValue('plausible_domain') && $this->getValue('plausible_domain'); + } + + public function getPlausibleAnalyticsDomain() + { + return $this->getValue('plausible_domain'); + } + + public function hasPiwikAnalytics() + { + return $this->getValue('piwik_analytics') && $this->hasValue('piwik_analytics_id'); + } + + public function getPiwikAnalyticsId() + { + return $this->getValue('piwik_analytics_id'); + } + + public function getPiwikAnalyticsUrl() + { + return $this->getValue('piwik_analytics'); + } + + public function hasPoweredBy() + { + return $this->hasValue('powered_by') && !empty($this->getValue('powered_by')); + } + + public function getPoweredBy() + { + return $this->getValue('powered_by'); + } + + public function hasTwitterHandles() + { + return $this->hasValue('twitter') && !empty($this->getValue('twitter')); + } + + public function getTwitterHandles() + { + return $this->getValue('twitter'); + } + + public function hasLinks() + { + return $this->hasValue('links') && !empty($this->getValue('links')); + } + + public function getLinks() + { + return $this->getValue('links'); + } + + public function hasRepository() + { + return $this->hasValue('repo') && !empty($this->getValue('repo')); + } + + public function getRepository() + { + return $this->getValue('repo'); + } + + public function hasButtons() + { + return $this->hasValue('buttons') && !empty($this->getValue('buttons')); + } + + public function getButtons() + { + return $this->getValue('buttons'); + } + + public function hasLandingPage() + { + if ($this->hasValue('auto_landing')) { + return $this->getValue('auto_landing'); + } + + return true; + } + + public function hasBreadcrumbs() + { + if ($this->hasValue('breadcrumbs')) { + return $this->getValue('breadcrumbs'); + } + + return true; + } + + public function getBreadcrumbsSeparator() + { + return $this->getValue('breadcrumb_separator'); + } + + public function getTheme() + { + return $this->getValue('theme'); + } + + public function hasThemeVariant() + { + return $this->hasValue('theme-variant') && !empty($this->getValue('theme-variant')); + } + + public function getThemeVariant() + { + return $this->getValue('theme-variant'); + } } diff --git a/libs/Format/HTML/ContentPage.php b/libs/Format/HTML/ContentPage.php index 5ad705b..aebab03 100644 --- a/libs/Format/HTML/ContentPage.php +++ b/libs/Format/HTML/ContentPage.php @@ -4,27 +4,34 @@ use Todaymade\Daux\Tree\Root; class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage { + /** + * @var Template + */ + public $templateRenderer; + /** + * @var string + */ private $language; + + /** + * @var bool + */ private $homepage; - private function isHomepage() + private function isHomepage(): bool { // If the current page isn't the index, no chance it is the landing page if ($this->file->getParent()->getIndexPage() != $this->file) { return false; } - // If the direct parent is root, this is the homage + // If the direct parent is root, this is the homepage return $this->file->getParent() instanceof Root; } - private function isLanding() { - // If we don't have the auto_landing parameter, we don't want any homepage - if (array_key_exists('auto_landing', $this->params['html']) && !$this->params['html']['auto_landing']) { - return false; - } - - return $this->homepage; + private function isLanding(): bool + { + return $this->config->getHTML()->hasLandingPage() && $this->homepage; } private function initialize() @@ -32,7 +39,7 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage $this->homepage = $this->isHomepage(); $this->language = ''; - if ($this->params->isMultilanguage() && count($this->file->getParents())) { + if ($this->config->isMultilanguage() && count($this->file->getParents())) { $language_dir = $this->file->getParents()[0]; $this->language = $language_dir->getName(); } @@ -41,6 +48,7 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage /** * @param \Todaymade\Daux\Tree\Directory[] $parents * @param bool $multilanguage + * * @return array */ private function getBreadcrumbTrail($parents, $multilanguage) @@ -62,16 +70,16 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage protected function generatePage() { $this->initialize(); - $params = $this->params; + $config = $this->config; $entry_page = []; if ($this->homepage) { - if ($params->isMultilanguage()) { - foreach ($params['languages'] as $key => $name) { - $entry_page[$name] = $params['base_page'] . $params['entry_page'][$key]->getUrl(); + if ($config->isMultilanguage()) { + foreach ($config->getLanguages() as $key => $name) { + $entry_page[$name] = $config->getBasePage() . $config->getEntryPage()[$key]->getUrl(); } } else { - $entry_page['__VIEW_DOCUMENTATION__'] = $params['base_page'] . $params['entry_page']->getUrl(); + $entry_page['__VIEW_DOCUMENTATION__'] = $config->getBasePage() . $config->getEntryPage()->getUrl(); } } @@ -85,32 +93,32 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage 'relative_path' => $this->file->getRelativePath(), 'modified_time' => filemtime($this->file->getPath()), 'markdown' => $this->content, - 'request' => $params['request'], + 'request' => $config->getRequest(), 'content' => $this->getPureContent(), - 'breadcrumbs' => $params['html']['breadcrumbs'], + 'breadcrumbs' => $config->getHTML()->hasBreadcrumbs(), 'prev' => $this->file->getPrevious(), 'next' => $this->file->getNext(), - 'attributes' => $this->file->getAttribute() + 'attributes' => $this->file->getAttribute(), ]; if ($page['breadcrumbs']) { - $page['breadcrumb_trail'] = $this->getBreadcrumbTrail($this->file->getParents(), $params->isMultilanguage()); - $page['breadcrumb_separator'] = $params['html']['breadcrumb_separator']; + $page['breadcrumb_trail'] = $this->getBreadcrumbTrail($this->file->getParents(), $config->isMultilanguage()); + $page['breadcrumb_separator'] = $this->config->getHTML()->getBreadcrumbsSeparator(); if ($this->homepage) { $page['breadcrumb_trail'] = [['title' => $this->file->getTitle(), 'url' => '']]; } } - $context = ['page' => $page, 'params' => $params]; + $context = ['page' => $page, 'config' => $config]; - $template = "theme::content"; + $template = 'theme::content'; if ($this->isLanding()) { - $template = "theme::home"; + $template = 'theme::home'; } if (array_key_exists('template', $page['attributes'])) { - $template = "theme::" . $page['attributes']['template']; + $template = 'theme::' . $page['attributes']['template']; } return $this->templateRenderer->render($template, $context); diff --git a/libs/Format/HTML/ContentTypes/Markdown/CommonMarkConverter.php b/libs/Format/HTML/ContentTypes/Markdown/CommonMarkConverter.php index 96d8f37..df7ad5c 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/CommonMarkConverter.php +++ b/libs/Format/HTML/ContentTypes/Markdown/CommonMarkConverter.php @@ -1,7 +1,11 @@ addBlockRenderer('FencedCode', new FencedCodeRenderer()); + $environment->addBlockRenderer(BlockElement\FencedCode::class, new FencedCodeRenderer()); - $environment->addDocumentProcessor(new TOC\Processor($config)); - $environment->addBlockRenderer('Todaymade\Daux\ContentTypes\Markdown\TableOfContents', new TOC\Renderer($config)); + $processor = new TOC\Processor($config); + $environment->addEventListener(DocumentParsedEvent::class, [$processor, 'onDocumentParsed']); + $environment->addBlockRenderer(TableOfContents::class, new TOC\Renderer($config)); + + $environment->addInlineRenderer(InlineElement\Image::class, new ImageRenderer($config)); } } diff --git a/libs/Format/HTML/ContentTypes/Markdown/ContentType.php b/libs/Format/HTML/ContentTypes/Markdown/ContentType.php index 96930eb..e25f1cc 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/ContentType.php +++ b/libs/Format/HTML/ContentTypes/Markdown/ContentType.php @@ -1,12 +1,9 @@ config = $config; - $this->converter = new CommonMarkConverter(['daux' => $config]); + return new CommonMarkConverter(['daux' => $this->config]); } } diff --git a/libs/Format/HTML/ContentTypes/Markdown/FencedCodeRenderer.php b/libs/Format/HTML/ContentTypes/Markdown/FencedCodeRenderer.php index 44f0d0a..7da0ecf 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/FencedCodeRenderer.php +++ b/libs/Format/HTML/ContentTypes/Markdown/FencedCodeRenderer.php @@ -10,13 +10,17 @@ use League\CommonMark\Util\Xml; class FencedCodeRenderer implements BlockRendererInterface { - function __construct() { + /** + * @var Highlighter + */ + private $hl; + + public function __construct() + { $this->hl = new Highlighter(); } /** - * @param AbstractBlock $block - * @param HtmlRendererInterface $htmlRenderer * @param bool $inTightList * * @return HtmlElement|string @@ -43,7 +47,7 @@ class FencedCodeRenderer implements BlockRendererInterface $highlighted = $this->hl->highlight($language, $content); $content = $highlighted->value; $attrs['class'] .= 'hljs ' . $highlighted->language; - } catch (Exception $e) { + } catch (\Exception $e) { $attrs['class'] .= 'language-' . $language; } } @@ -65,6 +69,6 @@ class FencedCodeRenderer implements BlockRendererInterface return false; } - return Xml::escape($infoWords[0], true); + return Xml::escape($infoWords[0]); } } diff --git a/libs/Format/HTML/ContentTypes/Markdown/ImageRenderer.php b/libs/Format/HTML/ContentTypes/Markdown/ImageRenderer.php new file mode 100644 index 0000000..11b0950 --- /dev/null +++ b/libs/Format/HTML/ContentTypes/Markdown/ImageRenderer.php @@ -0,0 +1,95 @@ +daux = $daux; + $this->parent = new \League\CommonMark\Inline\Renderer\ImageRenderer(); + } + + /** + * Relative URLs can be done using either the folder with + * number prefix or the final name (with prefix stripped). + * This ensures that we always use the final name when generating. + * + * @param mixed $url + * + * @throws LinkNotFoundException + */ + protected function getCleanUrl($url) + { + // empty urls and anchors should + // not go through the url resolver + if (!DauxHelper::isValidUrl($url)) { + return $url; + } + + // Absolute urls, shouldn't either + if (DauxHelper::isExternalUrl($url)) { + return $url; + } + + try { + $file = DauxHelper::resolveInternalFile($this->daux, $url); + + return DauxHelper::getRelativePath($this->daux->getCurrentPage()->getUrl(), $file->getUrl()); + } catch (LinkNotFoundException $e) { + if ($this->daux->isStatic()) { + throw $e; + } + } + + return $url; + } + + /** + * @param Image $inline + * + * @throws LinkNotFoundException + * + * @return HtmlElement + */ + public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer) + { + if (!($inline instanceof Image)) { + throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline)); + } + + $inline->setUrl($this->getCleanUrl($inline->getUrl())); + + return $this->parent->render($inline, $htmlRenderer); + } + + public function setConfiguration(ConfigurationInterface $configuration) + { + $this->config = $configuration; + $this->parent->setConfiguration($configuration); + } +} diff --git a/libs/Format/HTML/ContentTypes/Markdown/TOC/Entry.php b/libs/Format/HTML/ContentTypes/Markdown/TOC/Entry.php index ca2bbf4..cabce76 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/TOC/Entry.php +++ b/libs/Format/HTML/ContentTypes/Markdown/TOC/Entry.php @@ -6,7 +6,7 @@ class Entry { protected $content; protected $level; - protected $parent = null; + protected $parent; protected $children = []; public function __construct(Heading $content) @@ -56,7 +56,6 @@ class Entry } /** - * @param Entry $parent * @param bool $addChild */ public function setParent(Entry $parent, $addChild = true) @@ -67,9 +66,6 @@ class Entry } } - /** - * @param Entry $child - */ public function addChild(Entry $child) { $child->setParent($this, false); diff --git a/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php b/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php index 1989d87..a0265b5 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php +++ b/libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php @@ -7,16 +7,20 @@ 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\Event\DocumentParsedEvent; 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\ContentTypes\Markdown\TableOfContents; +use Todaymade\Daux\DauxHelper; -class Processor implements DocumentProcessorInterface +class Processor { + /** + * @var Config + */ protected $config; public function __construct(Config $config) @@ -24,18 +28,9 @@ class Processor implements DocumentProcessorInterface $this->config = $config; } - public function hasAutoTOC() - { - return array_key_exists('html', $this->config) && array_key_exists('auto_toc', $this->config['html']) && $this->config['html']['auto_toc']; - } - - /** - * @param Document $document - * - * @return void - */ - public function processDocument(Document $document) + public function onDocumentParsed(DocumentParsedEvent $event) { + $document = $event->getDocument(); /** @var TableOfContents[] $tocs */ $tocs = []; @@ -48,6 +43,7 @@ class Processor implements DocumentProcessorInterface if ($node instanceof TableOfContents && !$event->isEntering()) { $tocs[] = $node; + continue; } @@ -59,7 +55,7 @@ class Processor implements DocumentProcessorInterface $headings[] = new Entry($node); } - if (count($headings) && (count($tocs) || $this->hasAutoTOC())) { + if (count($headings) && (count($tocs) || $this->config->getHTML()->hasAutomaticTableOfContents())) { $generated = $this->generate($headings); if (count($tocs)) { @@ -72,43 +68,27 @@ class Processor implements DocumentProcessorInterface } } - /** - * Get an escaped version of the link - * @param string $url - * @return string - */ - protected function escaped($url) { - $url = trim($url); - $url = preg_replace('~[^\\pL0-9_]+~u', '-', $url); - $url = trim($url, "-"); - $url = iconv("utf-8", "ASCII//TRANSLIT//IGNORE", $url); - $url = preg_replace('~[^-a-zA-Z0-9_]+~', '', $url); - - return $url; - } - - protected function getUniqueId(Document $document, $proposed) { - if ($proposed == "page_") { - $proposed = "page_section_" . (count($document->heading_ids) + 1); + protected function getUniqueId(Document $document, $proposed) + { + if ($proposed == 'page_') { + $proposed = 'page_section_' . (count($document->heading_ids) + 1); } // Quick path, it's a unique ID if (!in_array($proposed, $document->heading_ids)) { $document->heading_ids[] = $proposed; + return $proposed; } $extension = 1; // Initialize the variable at one, so on the first iteration we have 2 do { - $extension++; + ++$extension; } while (in_array("$proposed-$extension", $document->heading_ids)); return "$proposed-$extension"; } - /** - * @param Heading $node - */ protected function ensureHeadingHasId(Document $document, Heading $node) { // If the node has an ID, no need to generate it, just check it's unique @@ -139,13 +119,14 @@ class Processor implements DocumentProcessorInterface } } - $node->data['attributes']['id'] = $this->getUniqueId($document,'page_'. $this->escaped($text)); + $node->data['attributes']['id'] = $this->getUniqueId($document, 'page_' . DauxHelper::slug($text)); } /** - * Make a tree of the list of headings + * Make a tree of the list of headings. * * @param Entry[] $headings + * * @return RootEntry */ public function generate($headings) @@ -161,19 +142,21 @@ class Processor implements DocumentProcessorInterface $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; //} } @@ -183,6 +166,7 @@ class Processor implements DocumentProcessorInterface /** * @param Entry[] $entries + * * @return ListBlock */ protected function render(array $entries) @@ -234,7 +218,6 @@ class Processor implements DocumentProcessorInterface } /** - * @param Heading $node * @return Node[] */ protected function cloneChildren(Heading $node) diff --git a/libs/Format/HTML/ContentTypes/Markdown/TOC/Renderer.php b/libs/Format/HTML/ContentTypes/Markdown/TOC/Renderer.php index 7ad8c98..6100779 100644 --- a/libs/Format/HTML/ContentTypes/Markdown/TOC/Renderer.php +++ b/libs/Format/HTML/ContentTypes/Markdown/TOC/Renderer.php @@ -4,9 +4,15 @@ use League\CommonMark\Block\Element\AbstractBlock; use League\CommonMark\Block\Renderer\BlockRendererInterface; use League\CommonMark\ElementRendererInterface; use Todaymade\Daux\Config; +use Todaymade\Daux\ContentTypes\Markdown\TableOfContents; class Renderer implements BlockRendererInterface { + /** + * @var Config + */ + private $config; + public function __construct(Config $config) { $this->config = $config; @@ -14,7 +20,12 @@ class Renderer implements BlockRendererInterface public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, $inTightList = false) { + if (!($block instanceof TableOfContents)) { + throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block)); + } + $content = $htmlRenderer->renderBlocks($block->children()); + return $this->config->templateRenderer ->getEngine($this->config) ->render('theme::partials/table_of_contents', ['content' => $content]); diff --git a/libs/Format/HTML/Generator.php b/libs/Format/HTML/Generator.php index 3a8c14e..b239177 100755 --- a/libs/Format/HTML/Generator.php +++ b/libs/Format/HTML/Generator.php @@ -2,7 +2,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -use Todaymade\Daux\Config; +use Todaymade\Daux\Config as GlobalConfig; use Todaymade\Daux\Console\RunAction; use Todaymade\Daux\Daux; use Todaymade\Daux\DauxHelper; @@ -16,23 +16,24 @@ use Todaymade\Daux\Tree\Raw; class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator { - use RunAction, HTMLUtils; + use RunAction; + use HTMLUtils; /** @var Daux */ protected $daux; + /** @var Template */ + protected $templateRenderer; + protected $indexed_pages = []; - /** - * @param Daux $daux - */ public function __construct(Daux $daux) { - $params = $daux->getParams(); + $config = $daux->getConfig(); $this->daux = $daux; - $this->templateRenderer = new Template($params); - $params->templateRenderer = $this->templateRenderer; + $this->templateRenderer = new Template($config); + $config->templateRenderer = $this->templateRenderer; } /** @@ -41,7 +42,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator public function getContentTypes() { return [ - 'markdown' => new ContentType($this->daux->getParams()), + 'markdown' => new ContentType($this->daux->getConfig()), ]; } @@ -49,38 +50,34 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator { $destination = $input->getOption('destination'); - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); if (is_null($destination)) { - $destination = $this->daux->local_base . DIRECTORY_SEPARATOR . 'static'; + $destination = $config->getLocalBase() . DIRECTORY_SEPARATOR . 'static'; } $this->runAction( 'Copying Static assets ...', $width, - function() use ($destination, $params) { + function () use ($destination, $config) { $this->ensureEmptyDestination($destination); - $this->copyThemes($destination, $params->getThemesPath()); + $this->copyThemes($destination, $config->getThemesPath()); } ); $output->writeLn('Generating ...'); - if (!array_key_exists('search', $params['html']) || !$params['html']['search']) { - $params['html']['search'] = $input->getOption('search'); - } - - $this->generateRecursive($this->daux->tree, $destination, $params, $output, $width, $params['html']['search']); + $this->generateRecursive($this->daux->tree, $destination, $config, $output, $width, $config->getHTML()->hasSearch()); GeneratorHelper::copyRecursive( - $this->daux->local_base . DIRECTORY_SEPARATOR . 'daux_libraries' . DIRECTORY_SEPARATOR, + $config->getLocalBase() . DIRECTORY_SEPARATOR . 'daux_libraries' . DIRECTORY_SEPARATOR, $destination . DIRECTORY_SEPARATOR . 'daux_libraries' ); - if ($params['html']['search']) { + if ($config->getHTML()->hasSearch()) { file_put_contents( - $destination . DIRECTORY_SEPARATOR . 'daux_search_index.json', - json_encode(['pages' => $this->indexed_pages]) + $destination . DIRECTORY_SEPARATOR . 'daux_search_index.js', + 'load_search_index(' . json_encode(['pages' => $this->indexed_pages]) . ');' ); if (json_last_error()) { @@ -94,9 +91,10 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator * 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 + * modified from: http://nadeausoftware.com/articles/2007/09/php_tip_how_strip_html_tags_web_page. * * @param string $text + * * @return string */ private function sanitize($text) @@ -134,44 +132,41 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator // Sometimes strings are detected as invalid UTF-8 and json_encode can't treat them // iconv can fix those strings - $text = iconv('UTF-8', 'UTF-8//IGNORE', $text); - - return $text; + return iconv('UTF-8', 'UTF-8//IGNORE', $text); } /** - * Recursively generate the documentation + * Recursively generate the documentation. * - * @param Directory $tree * @param string $output_dir - * @param \Todaymade\Daux\Config $params * @param OutputInterface $output * @param int $width * @param bool $index_pages * @param string $base_url + * * @throws \Exception */ - private function generateRecursive(Directory $tree, $output_dir, $params, $output, $width, $index_pages, $base_url = '') + private function generateRecursive(Directory $tree, $output_dir, GlobalConfig $config, $output, $width, $index_pages, $base_url = '') { - DauxHelper::rebaseConfiguration($params, $base_url); + DauxHelper::rebaseConfiguration($config, $base_url); - if ($base_url !== '' && empty($params['entry_page'])) { - $params['entry_page'] = $tree->getFirstPage(); + if ($base_url !== '' && !$config->hasEntryPage()) { + $config->setEntryPage($tree->getFirstPage()); } foreach ($tree->getEntries() as $key => $node) { 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, $index_pages, '../' . $base_url); + $this->generateRecursive($node, $new_output_dir, $config, $output, $width, $index_pages, '../' . $base_url); - // Rebase configuration again as $params is a shared object - DauxHelper::rebaseConfiguration($params, $base_url); + // Rebase configuration again as $config is a shared object + DauxHelper::rebaseConfiguration($config, $base_url); } else { $this->runAction( '- ' . $node->getUrl(), $width, - function() use ($node, $output_dir, $key, $params, $index_pages) { + function () use ($node, $output_dir, $key, $config, $index_pages) { if ($node instanceof Raw) { copy($node->getPath(), $output_dir . DIRECTORY_SEPARATOR . $key); @@ -180,13 +175,13 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator $this->daux->tree->setActiveNode($node); - $generated = $this->generateOne($node, $params); + $generated = $this->generateOne($node, $config); file_put_contents($output_dir . DIRECTORY_SEPARATOR . $key, $generated->getContent()); if ($index_pages) { $this->indexed_pages[] = [ 'title' => $node->getTitle(), 'text' => $this->sanitize($generated->getPureContent()), - 'tags' => '', + 'tags' => '', 'url' => $node->getUrl(), ]; } @@ -197,11 +192,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator } /** - * @param Entry $node - * @param Config $params * @return \Todaymade\Daux\Format\Base\Page */ - public function generateOne(Entry $node, Config $params) + public function generateOne(Entry $node, GlobalConfig $config) { if ($node instanceof Raw) { return new RawPage($node->getPath()); @@ -211,9 +204,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator, LiveGenerator return new ComputedRawPage($node); } - $params['request'] = $node->getUrl(); + $config->setRequest($node->getUrl()); - $contentPage = ContentPage::fromFile($node, $params, $this->daux->getContentTypeHandler()->getType($node)); + $contentPage = ContentPage::fromFile($node, $config, $this->daux->getContentTypeHandler()->getType($node)); $contentPage->templateRenderer = $this->templateRenderer; return $contentPage; diff --git a/libs/Format/HTML/HTMLUtils.php b/libs/Format/HTML/HTMLUtils.php index 0c960be..49664ad 100644 --- a/libs/Format/HTML/HTMLUtils.php +++ b/libs/Format/HTML/HTMLUtils.php @@ -2,7 +2,8 @@ use Todaymade\Daux\GeneratorHelper; -trait HTMLUtils { +trait HTMLUtils +{ public function ensureEmptyDestination($destination) { if (is_dir($destination)) { @@ -13,7 +14,7 @@ trait HTMLUtils { } /** - * Copy all files from $local to $destination + * Copy all files from $local to $destination. * * @param string $destination * @param string $local_base @@ -26,4 +27,4 @@ trait HTMLUtils { $destination . DIRECTORY_SEPARATOR . 'themes' ); } -} \ No newline at end of file +} diff --git a/libs/Format/HTML/Template.php b/libs/Format/HTML/Template.php index 2d133a0..ab3318a 100644 --- a/libs/Format/HTML/Template.php +++ b/libs/Format/HTML/Template.php @@ -4,7 +4,7 @@ namespace Todaymade\Daux\Format\HTML; use League\Plates\Engine; use Symfony\Component\Console\Output\OutputInterface; -use Todaymade\Daux\Config; +use Todaymade\Daux\Config as GlobalConfig; use Todaymade\Daux\Daux; use Todaymade\Daux\Tree\Content; use Todaymade\Daux\Tree\Directory; @@ -13,25 +13,25 @@ class Template { protected $engine; - protected $params; + protected $config; /** * @param string $base * @param string $theme */ - public function __construct(Config $params) + public function __construct(GlobalConfig $config) { - $this->params = $params; + $this->config = $config; } - public function getEngine(Config $params) + public function getEngine(GlobalConfig $config) { if ($this->engine) { return $this->engine; } - $base = $params['templates']; - $theme = $params['theme']['templates']; + $base = $config->getTemplates(); + $theme = $config->getTheme()->getTemplates(); // Use internal templates if no templates // dir exists in the working directory @@ -55,19 +55,20 @@ class Template /** * @param string $name - * @param array $data + * * @return string */ public function render($name, array $data = []) { - $engine = $this->getEngine($data['params']); + $engine = $this->getEngine($data['config']); $engine->addData([ - 'base_url' => $data['params']['base_url'], - 'base_page' => $data['params']['base_page'], + 'base_url' => $data['config']->getBaseUrl(), + 'base_page' => $data['config']->getBasePage(), 'page' => $data['page'], - 'params' => $data['params'], - 'tree' => $data['params']['tree'], + 'params' => $data['config'], // legacy name for config + 'config' => $data['config'], + 'tree' => $data['config']['tree'], ]); Daux::writeln("Rendering template '$name'", OutputInterface::VERBOSITY_VERBOSE); @@ -84,7 +85,7 @@ class Template }); $engine->registerFunction('translate', function ($key) { - $language = $this->params['language']; + $language = $this->config->getLanguage(); if (isset($this->engine->getData('page')['page'])) { $page = $this->engine->getData('page'); @@ -93,14 +94,12 @@ class Template } } - if (array_key_exists($language, $this->params['strings'])) { - if (array_key_exists($key, $this->params['strings'][$language])) { - return $this->params['strings'][$language][$key]; - } + if ($this->config->hasTranslationKey($language, $key)) { + return $this->config->getTranslationKey($language, $key); } - if (array_key_exists($key, $this->params['strings']['en'])) { - return $this->params['strings']['en'][$key]; + if ($this->config->hasTranslationKey('en', $key)) { + return $this->config->getTranslationKey('en', $key); } return "Unknown key $key"; @@ -197,6 +196,7 @@ class Template /** * @param string $separator + * * @return string */ private function getSeparator($separator) diff --git a/libs/Format/HTML/Theme.php b/libs/Format/HTML/Theme.php new file mode 100644 index 0000000..6060921 --- /dev/null +++ b/libs/Format/HTML/Theme.php @@ -0,0 +1,31 @@ +getValue('fonts'); + } + + public function getCSS() + { + return $this->getValue('css'); + } + + public function getJS() + { + return $this->getValue('js'); + } + + public function getFavicon() + { + return $this->getValue('favicon'); + } + + public function getTemplates() + { + return $this->getValue('templates'); + } +} diff --git a/libs/Format/HTMLFile/Book.php b/libs/Format/HTMLFile/Book.php index 8e0ed21..5023625 100644 --- a/libs/Format/HTMLFile/Book.php +++ b/libs/Format/HTMLFile/Book.php @@ -1,6 +1,5 @@ getUrl()); + return 'file_' . str_replace('/', '_', $page->getUrl()); } protected function buildNavigation(Directory $tree) @@ -38,7 +37,7 @@ class Book $nav[] = [ 'title' => $node->getTitle(), - 'href' => "#" . $this->getPageUrl($node), + 'href' => '#' . $this->getPageUrl($node), ]; } elseif ($node instanceof Directory) { if (!$node->hasContent()) { @@ -49,7 +48,7 @@ class Book $nav[] = [ 'title' => $node->getTitle(), - 'href' => "#" . $this->getPageUrl($page_index), + 'href' => '#' . $this->getPageUrl($page_index), 'children' => $this->buildNavigation($node), ]; } @@ -89,7 +88,7 @@ class Book protected function generateCover() { - return "
    " . + return '
    ' . "

    {$this->cover['title']}

    " . "

    {$this->cover['subject']} by {$this->cover['author']}

    " . '
     
    '; diff --git a/libs/Format/HTMLFile/ContentPage.php b/libs/Format/HTMLFile/ContentPage.php index e9825f6..277579a 100644 --- a/libs/Format/HTMLFile/ContentPage.php +++ b/libs/Format/HTMLFile/ContentPage.php @@ -11,23 +11,23 @@ class ContentPage extends \Todaymade\Daux\Format\Base\ContentPage { $content = parent::generatePage(); - //Embed images + // Embed images // We do it after generation so we can catch the images that were in html already - $content = (new EmbedImages($this->params['tree'])) + return (new EmbedImages($this->config->getTree())) ->embed( $content, $this->file, - function($src, array $attributes, Raw $file) { - $content = base64_encode(file_get_contents($file->getPath())); + function ($src, array $attributes, Raw $file) { + // TODO :: ignore absolute paths + $content = base64_encode(file_get_contents($file->getPath())); $attr = ''; foreach ($attributes as $name => $value) { $attr .= ' ' . $name . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"'; } + // TODO :: handle other formats than PNG as well return ""; } ); - - return $content; } } diff --git a/libs/Format/HTMLFile/ContentTypes/Markdown/CommonMarkConverter.php b/libs/Format/HTMLFile/ContentTypes/Markdown/CommonMarkConverter.php index cf97727..b362310 100644 --- a/libs/Format/HTMLFile/ContentTypes/Markdown/CommonMarkConverter.php +++ b/libs/Format/HTMLFile/ContentTypes/Markdown/CommonMarkConverter.php @@ -1,13 +1,11 @@ getConfig('daux')); } } diff --git a/libs/Format/HTMLFile/ContentTypes/Markdown/ContentType.php b/libs/Format/HTMLFile/ContentTypes/Markdown/ContentType.php index 00e2157..e66eb03 100644 --- a/libs/Format/HTMLFile/ContentTypes/Markdown/ContentType.php +++ b/libs/Format/HTMLFile/ContentTypes/Markdown/ContentType.php @@ -1,12 +1,9 @@ config = $config; - $this->converter = new CommonMarkConverter(['daux' => $config]); + return new CommonMarkConverter(['daux' => $this->config]); } } diff --git a/libs/Format/HTMLFile/ContentTypes/Markdown/LinkRenderer.php b/libs/Format/HTMLFile/ContentTypes/Markdown/LinkRenderer.php index f4ccc67..e552ca8 100644 --- a/libs/Format/HTMLFile/ContentTypes/Markdown/LinkRenderer.php +++ b/libs/Format/HTMLFile/ContentTypes/Markdown/LinkRenderer.php @@ -4,30 +4,22 @@ use League\CommonMark\ElementRendererInterface; use League\CommonMark\HtmlElement; use League\CommonMark\Inline\Element\AbstractInline; use League\CommonMark\Inline\Element\Link; -use Todaymade\Daux\Config; use Todaymade\Daux\DauxHelper; use Todaymade\Daux\Exception\LinkNotFoundException; -use Todaymade\Daux\Tree\Entry; class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer { /** * @param AbstractInline|Link $inline - * @param ElementRendererInterface $htmlRenderer - * @return HtmlElement + * * @throws LinkNotFoundException + * + * @return HtmlElement */ public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer) { - // This can't be in the method type as - // the method is an abstract and should - // have the same interface - if (!$inline instanceof Link) { - throw new \RuntimeException( - 'Wrong type passed to ' . __CLASS__ . '::' . __METHOD__ . - " the expected type was 'League\\CommonMark\\Inline\\Element\\Link' but '" . - get_class($inline) . "' was provided" - ); + if (!($inline instanceof Link)) { + throw new \InvalidArgumentException('Incompatible inline type: ' . \get_class($inline)); } $element = parent::render($inline, $htmlRenderer); @@ -36,12 +28,12 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer // empty urls and anchors should // not go through the url resolver - if (!$this->isValidUrl($url)) { + if (!DauxHelper::isValidUrl($url)) { return $element; } // Absolute urls, shouldn't either - if ($this->isExternalUrl($url)) { + if (DauxHelper::isExternalUrl($url)) { $element->setAttribute('class', 'Link--external'); return $element; @@ -51,12 +43,12 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer $urlAndHash = explode('#', $url); if (isset($urlAndHash[1])) { $element->setAttribute('href', '#' . $urlAndHash[1]); - + return $element; } try { - $file = $this->resolveInternalFile($url); + $file = DauxHelper::resolveInternalFile($this->daux, $url); $url = $file->getUrl(); } catch (LinkNotFoundException $e) { if ($this->daux->isStatic()) { @@ -71,4 +63,4 @@ class LinkRenderer extends \Todaymade\Daux\ContentTypes\Markdown\LinkRenderer return $element; } -} \ No newline at end of file +} diff --git a/libs/Format/HTMLFile/Generator.php b/libs/Format/HTMLFile/Generator.php index 4d4f27b..14bfaf0 100644 --- a/libs/Format/HTMLFile/Generator.php +++ b/libs/Format/HTMLFile/Generator.php @@ -4,27 +4,28 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Todaymade\Daux\Console\RunAction; use Todaymade\Daux\Daux; -use Todaymade\Daux\Format\HTML\Template; use Todaymade\Daux\Format\HTML\HTMLUtils; +use Todaymade\Daux\Format\HTML\Template; use Todaymade\Daux\Format\HTMLFile\ContentTypes\Markdown\ContentType; class Generator implements \Todaymade\Daux\Format\Base\Generator { - use RunAction, HTMLUtils; + use RunAction; + use HTMLUtils; /** @var Daux */ protected $daux; - /** - * @param Daux $daux - */ + /** @var Template */ + protected $templateRenderer; + public function __construct(Daux $daux) { - $params = $daux->getParams(); + $config = $daux->getConfig(); $this->daux = $daux; - $this->templateRenderer = new Template($params); - $params->templateRenderer = $this->templateRenderer; + $this->templateRenderer = new Template($config); + $config->templateRenderer = $this->templateRenderer; } /** @@ -33,7 +34,7 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator public function getContentTypes() { return [ - 'markdown' => new ContentType($this->daux->getParams()), + 'markdown' => new ContentType($this->daux->getConfig()), ]; } @@ -44,23 +45,23 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator { $destination = $input->getOption('destination'); - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); if (is_null($destination)) { - $destination = $this->daux->local_base . DIRECTORY_SEPARATOR . 'static'; + $destination = $config->getLocalBase() . DIRECTORY_SEPARATOR . 'static'; } $this->runAction( 'Cleaning destination folder ...', $width, - function() use ($destination, $params) { + function () use ($destination) { $this->ensureEmptyDestination($destination); } ); $data = [ - 'author' => $params['author'], - 'title' => $params['title'], - 'subject' => $params['tagline'] + 'author' => $config->getAuthor(), + 'title' => $config->getTitle(), + 'subject' => $config->getTagline(), ]; $book = new Book($this->daux->tree, $data); @@ -70,9 +71,9 @@ class Generator implements \Todaymade\Daux\Format\Base\Generator $this->runAction( 'Generating ' . $current->getTitle(), $width, - function () use ($book, $current, $params) { + function () use ($book, $current, $config) { $contentType = $this->daux->getContentTypeHandler()->getType($current); - $content = ContentPage::fromFile($current, $params, $contentType); + $content = ContentPage::fromFile($current, $config, $contentType); $content->templateRenderer = $this->templateRenderer; $content = $content->getContent(); $book->addPage($current, $content); diff --git a/libs/FormatDate.php b/libs/FormatDate.php index 464e812..b853c78 100644 --- a/libs/FormatDate.php +++ b/libs/FormatDate.php @@ -4,13 +4,14 @@ use IntlDateFormatter; class FormatDate { - public static function format($params, $date) { - $locale = $params['language']; + public static function format($config, $date) + { + $locale = $config->getLanguage(); $datetype = IntlDateFormatter::LONG; $timetype = IntlDateFormatter::SHORT; $timezone = null; - if (!extension_loaded("intl")) { + if (!extension_loaded('intl')) { $locale = 'en'; $timezone = 'GMT'; } @@ -19,4 +20,4 @@ class FormatDate return $formatter->format($date); } -} \ No newline at end of file +} diff --git a/libs/GeneratorHelper.php b/libs/GeneratorHelper.php index 4e87580..6219109 100755 --- a/libs/GeneratorHelper.php +++ b/libs/GeneratorHelper.php @@ -5,7 +5,7 @@ use RuntimeException; class GeneratorHelper { /** - * Remove a directory recursively + * Remove a directory recursively. * * @param string $dir */ @@ -26,7 +26,7 @@ class GeneratorHelper } /** - * Copy files recursively + * Copy files recursively. * * @param string $source * @param string $destination @@ -39,7 +39,7 @@ class GeneratorHelper $dir = opendir($source); - if (!$dir) { + if ($dir === false) { throw new RuntimeException("Cannot copy '$source' to '$destination'"); } diff --git a/libs/Processor.php b/libs/Processor.php index 122a732..96d006e 100644 --- a/libs/Processor.php +++ b/libs/Processor.php @@ -22,8 +22,6 @@ class Processor protected $width; /** - * @param Daux $daux - * @param OutputInterface $output * @param int $width */ public function __construct(Daux $daux, OutputInterface $output, $width) @@ -37,10 +35,8 @@ class Processor * With this connection point, you can transform * the tree as you want, move pages, modify * pages and even add new ones. - * - * @param Root $root */ - public function manipulateTree(/** @scrutinizer ignore-unused */ Root $root) + public function manipulateTree(/* @scrutinizer ignore-unused */ Root $root) { } @@ -48,10 +44,8 @@ class Processor * This connection point provides * a way to extend the Markdown * parser and renderer. - * - * @param Environment $environment */ - public function extendCommonMarkEnvironment(/** @scrutinizer ignore-unused */ Environment $environment) + public function extendCommonMarkEnvironment(/* @scrutinizer ignore-unused */ Environment $environment) { } diff --git a/libs/Server/ErrorPage.php b/libs/Server/ErrorPage.php index f9084d3..c6c81dd 100644 --- a/libs/Server/ErrorPage.php +++ b/libs/Server/ErrorPage.php @@ -12,17 +12,17 @@ class ErrorPage extends SimplePage /** * @var \Todaymade\Daux\Config */ - private $params; + private $config; /** * @param string $title * @param string $content - * @param \Todaymade\Daux\Config $params + * @param \Todaymade\Daux\Config $config */ - public function __construct($title, $content, $params) + public function __construct($title, $content, $config) { parent::__construct($title, $content); - $this->params = $params; + $this->config = $config; } /** @@ -30,15 +30,15 @@ class ErrorPage extends SimplePage */ protected function generatePage() { - $params = $this->params; + $config = $this->config; $page = [ 'title' => $this->title, 'content' => $this->getPureContent(), 'language' => '', ]; - $template = new Template($params); + $template = new Template($config); - return $template->render('error', ['page' => $page, 'params' => $params]); + return $template->render('error', ['page' => $page, 'config' => $config]); } } diff --git a/libs/Server/ExtensionMimeTypeGuesser.php b/libs/Server/ExtensionMimeTypeGuesser.php index 1dff5d8..e1de672 100644 --- a/libs/Server/ExtensionMimeTypeGuesser.php +++ b/libs/Server/ExtensionMimeTypeGuesser.php @@ -1,29 +1,12 @@ guess($path); + $extension = pathinfo($path, PATHINFO_EXTENSION); + + if ($extension == 'css') { + return 'text/css'; + } + + if ($extension == 'js') { + return 'application/javascript'; + } + + return null; } } diff --git a/libs/Server/Server.php b/libs/Server/Server.php index 6f3c726..f6af68a 100755 --- a/libs/Server/Server.php +++ b/libs/Server/Server.php @@ -1,10 +1,11 @@ daux = $daux; + + $this->request = Request::createFromGlobals(); + $this->base_url = $this->request->getHttpHost() . $this->request->getBaseUrl() . '/'; + } + /** - * Serve the documentation + * Serve the documentation. * * @throws Exception */ public static function serve() { - $output = new NullOutput(); + $verbosity = getenv('DAUX_VERBOSITY'); + $output = new ConsoleOutput($verbosity); - $daux = new Daux(Daux::LIVE_MODE, $output); - $daux->initializeConfiguration(); + $configFile = getenv('DAUX_CONFIG'); + if ($configFile) { + $config = ConfigBuilder::fromFile($configFile); + } else { + $config = ConfigBuilder::withMode(Daux::LIVE_MODE)->build(); + } + + $daux = new Daux($config, $output); $class = $daux->getProcessorClass(); if (!empty($class)) { $daux->setProcessor(new $class($daux, $output, 0)); } - // Set this critical configuration - // for the tree generation - $daux->getParams()['index_key'] = 'index'; - // Improve the tree with a processor $daux->generateTree(); @@ -53,30 +65,24 @@ class Server try { $page = $server->handle(); } catch (NotFoundException $e) { - $page = new ErrorPage('An error occured', $e->getMessage(), $daux->getParams()); + $page = new ErrorPage('An error occured', $e->getMessage(), $daux->getConfig()); } $server->createResponse($page)->prepare($server->request)->send(); } - public function __construct(Daux $daux) - { - $this->daux = $daux; - - $this->request = Request::createFromGlobals(); - $this->base_url = $this->request->getHttpHost() . $this->request->getBaseUrl() . "/"; - } - /** * Create a temporary file with the file suffix, for mime type detection. * * @param string $postfix + * * @return string */ - private function getTemporaryFile($postfix) { + private function getTemporaryFile($postfix) + { $sysFileName = tempnam(sys_get_temp_dir(), 'daux'); if ($sysFileName === false) { - throw new \RuntimeException("Could not create temporary file"); + throw new \RuntimeException('Could not create temporary file'); } $newFileName = $sysFileName . $postfix; @@ -88,15 +94,16 @@ class Server return $newFileName; } - throw new \RuntimeException("Could not create temporary file"); + throw new \RuntimeException('Could not create temporary file'); } /** - * @param Page $page * @return Response */ - public function createResponse(Page $page) { - + public function createResponse(Page $page) + { + // Add a custom MimeType guesser in case the default ones are not available + // This makes sure that at least CSS and JS work fine. $mimeTypes = MimeTypes::getDefault(); $mimeTypes->registerGuesser(new ExtensionMimeTypeGuesser()); @@ -107,6 +114,7 @@ class Server if ($page instanceof ComputedRawPage) { $file = $this->getTemporaryFile($page->getFilename()); file_put_contents($file, $page->getContent()); + return new BinaryFileResponse($file); } @@ -116,32 +124,26 @@ class Server /** * @return \Todaymade\Daux\Config */ - public function getParams() + public function getConfig() { - $params = $this->daux->getParams(); + $config = $this->daux->getConfig(); - DauxHelper::rebaseConfiguration($params, '//' . $this->base_url); - $params['base_page'] = '//' . $this->base_url; - if (!$this->daux->options['live']['clean_urls']) { - $params['base_page'] .= 'index.php/'; - } + DauxHelper::rebaseConfiguration($config, '//' . $this->base_url); - // Text search would be too slow on live server - $params['html']['search'] = false; - - return $params; + return $config; } /** - * Handle an incoming request + * Handle an incoming request. * - * @return \Todaymade\Daux\Format\Base\Page * @throws Exception * @throws NotFoundException + * + * @return \Todaymade\Daux\Format\Base\Page */ public function handle() { - $this->params = $this->getParams(); + $this->config = $this->getConfig(); $request = substr($this->request->getRequestUri(), strlen($this->request->getBaseUrl()) + 1); @@ -157,27 +159,31 @@ class Server } /** - * Handle a request on custom themes + * Handle a request on custom themes. * * @param string $request - * @return \Todaymade\Daux\Format\Base\Page + * * @throws NotFoundException + * + * @return \Todaymade\Daux\Format\Base\Page */ public function serveTheme($request) { - $file = $this->getParams()->getThemesPath() . $request; + $file = $this->getConfig()->getThemesPath() . $request; if (file_exists($file)) { return new RawPage($file); } - throw new NotFoundException; + throw new NotFoundException(); } /** * @param string $request - * @return \Todaymade\Daux\Format\Base\Page + * * @throws NotFoundException + * + * @return \Todaymade\Daux\Format\Base\Page */ private function getPage($request) { @@ -197,6 +203,6 @@ class Server ); } - return $this->daux->getGenerator()->generateOne($file, $this->params); + return $this->daux->getGenerator()->generateOne($file, $this->config); } } diff --git a/libs/Tree/Builder.php b/libs/Tree/Builder.php index 82772fd..487122c 100644 --- a/libs/Tree/Builder.php +++ b/libs/Tree/Builder.php @@ -14,7 +14,7 @@ class Builder '.DS_Store', 'Thumbs.db', ]; - protected static function isIgnored(\SplFileInfo $file, $ignore) + protected static function isIgnored(SplFileInfo $file, $ignore) { $filename = $file->getFilename(); @@ -34,9 +34,10 @@ class Builder } /** - * Get name for a file + * Get name for a file. * * @param string $path + * * @return string */ protected static function getName($path) @@ -52,14 +53,16 @@ class Builder } /** - * Build the initial tree + * Build the initial tree. * * @param Directory $node * @param array $ignore */ public static function build($node, $ignore) { - if (($it = new \FilesystemIterator($node->getPath())) == false) { + try { + $it = new \FilesystemIterator($node->getPath()); + } catch (\UnexpectedValueException $e) { return; } @@ -94,8 +97,6 @@ class Builder } /** - * @param Directory $parent - * @param SplFileInfo $file * @return Content|Raw */ public static function createContent(Directory $parent, SplFileInfo $file) @@ -104,7 +105,7 @@ class Builder $config = $parent->getConfig(); - if (!in_array($file->getExtension(), $config['valid_content_extensions'])) { + if (!in_array($file->getExtension(), $config->getValidContentExtensions())) { $uri = $file->getFilename(); $entry = new Raw($parent, $uri, $file); @@ -122,7 +123,7 @@ class Builder $entry = new Content($parent, $uri, $file); - if ($entry->getUri() == $config['index_key']) { + if ($entry->getUri() == $config->getIndexKey()) { if ($parent instanceof Root) { $entry->setTitle($config->getTitle()); } else { @@ -139,6 +140,7 @@ class Builder /** * @param string $filename + * * @return string */ public static function removeSortingInformations($filename) @@ -152,8 +154,8 @@ class Builder } /** - * @param Directory $parent * @param string $title + * * @return Directory */ public static function getOrCreateDir(Directory $parent, $title) @@ -171,8 +173,8 @@ class Builder } /** - * @param Directory $parent * @param string $path + * * @return ContentAbstract */ public static function getOrCreatePage(Directory $parent, $path) @@ -184,7 +186,7 @@ class Builder $path .= '.md'; } - $raw = !in_array($extension, $parent->getConfig()['valid_content_extensions']); + $raw = !in_array($extension, $parent->getConfig()->getValidContentExtensions()); $title = $uri = $path; if (!$raw) { @@ -212,11 +214,10 @@ class Builder } /** - * Sort the tree recursively - * - * @param Directory $current + * Sort the tree recursively. */ - public static function sortTree(Directory $current) { + public static function sortTree(Directory $current) + { $current->sort(); foreach ($current->getEntries() as $entry) { if ($entry instanceof Directory) { @@ -226,10 +227,10 @@ class Builder } /** - * Calculate next and previous for all pages + * Calculate next and previous for all pages. * - * @param Directory $current * @param null|Content $prev + * * @return null|Content */ public static function finalizeTree(Directory $current, $prev = null) @@ -249,5 +250,4 @@ class Builder return $prev; } - } diff --git a/libs/Tree/Content.php b/libs/Tree/Content.php index 7259e16..762bc76 100644 --- a/libs/Tree/Content.php +++ b/libs/Tree/Content.php @@ -24,8 +24,8 @@ class Content extends ContentAbstract { if ($this->manuallySetContent) { $content = $this->content; - } else if (!$this->getPath()) { - throw new RuntimeException("Empty content"); + } elseif (!$this->getPath()) { + throw new RuntimeException('Empty content'); } else { $content = file_get_contents($this->getPath()); } @@ -40,10 +40,7 @@ class Content extends ContentAbstract return $frontMatter->parse($content); } - /** - * @return string - */ - public function getContent() + public function getContent(): string { if ($this->attributes === null) { $this->parseAttributes(); @@ -52,10 +49,7 @@ class Content extends ContentAbstract return $this->content; } - /** - * @param string $content - */ - public function setContent($content) + public function setContent(string $content): void { $this->manuallySetContent = true; $this->content = $content; @@ -64,15 +58,12 @@ class Content extends ContentAbstract /** * @return Content */ - public function getPrevious() + public function getPrevious(): ?Content { return $this->previous; } - /** - * @param Content $previous - */ - public function setPrevious($previous) + public function setPrevious(Content $previous) { $this->previous = $previous; } @@ -80,15 +71,12 @@ class Content extends ContentAbstract /** * @return Content */ - public function getNext() + public function getNext(): ?Content { return $this->next; } - /** - * @param Content $next - */ - public function setNext($next) + public function setNext(Content $next) { $this->next = $next; } @@ -102,7 +90,7 @@ class Content extends ContentAbstract return $this->name == 'index' || $this->name == '_index'; } - public function getTitle() + public function getTitle(): string { if ($title = $this->getAttribute('title')) { return $title; @@ -130,10 +118,11 @@ class Content extends ContentAbstract } /** - * Get one or all attributes for the content + * Get one or all attributes for the content. * - * @param string|null $key - * @return array|mixed|null + * @param null|string $key + * + * @return null|array|mixed */ public function getAttribute($key = null) { diff --git a/libs/Tree/ContentAbstract.php b/libs/Tree/ContentAbstract.php index 6636645..8c0590e 100644 --- a/libs/Tree/ContentAbstract.php +++ b/libs/Tree/ContentAbstract.php @@ -5,18 +5,12 @@ abstract class ContentAbstract extends Entry /** @var string */ protected $content; - /** - * @return string - */ - public function getContent() + public function getContent(): string { return $this->content; } - /** - * @param string $content - */ - public function setContent($content) + public function setContent(string $content): void { $this->content = $content; } diff --git a/libs/Tree/Directory.php b/libs/Tree/Directory.php index 958f1d6..aa10117 100644 --- a/libs/Tree/Directory.php +++ b/libs/Tree/Directory.php @@ -2,6 +2,7 @@ use ArrayIterator; use RuntimeException; +use Todaymade\Daux\Config; class Directory extends Entry implements \ArrayAccess, \IteratorAggregate { @@ -25,14 +26,25 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate ]; foreach ($this->children as $key => $entry) { + // In case of generated pages, the name might be empty. + // Thus we are falling back to other solutions, otherwise the page would disappear from the tree. $name = $entry->getName(); - if ($name == 'index' || $name == '_index') { - $buckets['index'][$key] = $entry; - continue; + if (!$name) { + $name = $entry->getTitle(); } if (!$name) { + $name = $key; + } + + if (!$name) { + continue; + } + + if ($name == 'index' || $name == '_index') { + $buckets['index'][$key] = $entry; + continue; } @@ -40,10 +52,12 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate if (is_numeric($name[1])) { $exploded = explode('_', $name); $buckets['down_numeric'][abs(substr($exploded[0], 1))][$key] = $entry; + continue; } $buckets['down'][$key] = $entry; + continue; } @@ -51,16 +65,19 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate if (is_numeric($name[1])) { $exploded = explode('_', $name); $buckets['up_numeric'][abs(substr($exploded[0], 1))][$key] = $entry; + continue; } $buckets['up'][$key] = $entry; + continue; } if (is_numeric($name[0])) { $exploded = explode('_', $name); $buckets['numeric'][abs($exploded[0])][$key] = $entry; + continue; } @@ -84,7 +101,7 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate private function sortBucket($bucket, $final) { - uasort($bucket, function(Entry $a, Entry $b) { + uasort($bucket, function (Entry $a, Entry $b) { return strcasecmp($a->getName(), $b->getName()); }); @@ -103,20 +120,17 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate return $this->children; } - public function addChild(Entry $entry) + public function addChild(Entry $entry): void { $this->children[$entry->getUri()] = $entry; } - public function removeChild(Entry $entry) + public function removeChild(Entry $entry): void { unset($this->children[$entry->getUri()]); } - /** - * @return \Todaymade\Daux\Config - */ - public function getConfig() + public function getConfig(): Config { if (!$this->parent) { throw new \RuntimeException('Could not retrieve configuration. Are you sure that your tree has a Root ?'); @@ -125,8 +139,9 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate return $this->parent->getConfig(); } - public function getLocalIndexPage() { - $index_key = $this->getConfig()['index_key']; + public function getLocalIndexPage() + { + $index_key = $this->getConfig()->getIndexKey(); if (isset($this->children[$index_key])) { return $this->children[$index_key]; @@ -135,15 +150,12 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate return false; } - /** - * @return Content|null - */ - public function getIndexPage() + public function getIndexPage(): ?Content { - $index_key = $this->getConfig()['index_key']; + $indexPage = $this->getLocalIndexPage(); - if ($this->getLocalIndexPage()) { - return $this->getLocalIndexPage(); + if ($indexPage instanceof Content) { + return $indexPage; } if ($this->getConfig()->shouldInheritIndex() && $first_page = $this->seekFirstPage()) { @@ -154,14 +166,13 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate } /** - * Seek the first available page from descendants - * @return Content|null + * Seek the first available page from descendants. */ - public function seekFirstPage() + public function seekFirstPage(): ?Content { if ($this instanceof self) { - $index_key = $this->getConfig()['index_key']; - if (isset($this->children[$index_key])) { + $index_key = $this->getConfig()->getIndexKey(); + if (isset($this->children[$index_key]) && $this->children[$index_key] instanceof Content) { return $this->children[$index_key]; } foreach ($this->children as $node_key => $node) { @@ -179,10 +190,7 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate return null; } - /** - * @return Content|null - */ - public function getFirstPage() + public function getFirstPage(): ?Content { if ($this->first_page) { return $this->first_page; @@ -214,26 +222,22 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate return null; } - /** - * @param Content $first_page - */ - public function setFirstPage($first_page) + public function setFirstPage(Content $first_page) { $this->first_page = $first_page; } /** * Used when creating the navigation. - * Hides folders without showable content - * - * @return bool + * Hides folders without showable content. */ - public function hasContent() + public function hasContent(): bool { foreach ($this->getEntries() as $node) { if ($node instanceof Content) { return true; - } elseif ($node instanceof self) { + } + if ($node instanceof self) { if ($node->hasContent()) { return true; } @@ -258,19 +262,23 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate } /** - * Whether a offset exists - * @param mixed $offset An offset to check for. - * @return bool true on success or false on failure. + * Whether a offset exists. + * + * @param mixed $offset an offset to check for + * + * @return bool true on success or false on failure */ - public function offsetExists($offset) + public function offsetExists($offset): bool { return array_key_exists($offset, $this->children); } /** - * Offset to retrieve - * @param mixed $offset The offset to retrieve. - * @return Entry Can return all value types. + * Offset to retrieve. + * + * @param mixed $offset the offset to retrieve + * + * @return Entry can return all value types */ public function offsetGet($offset) { @@ -278,10 +286,10 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate } /** - * Offset to set - * @param mixed $offset The offset to assign the value to. - * @param Entry $value The value to set. - * @return void + * Offset to set. + * + * @param mixed $offset the offset to assign the value to + * @param Entry $value the value to set */ public function offsetSet($offset, $value) { @@ -293,9 +301,9 @@ class Directory extends Entry implements \ArrayAccess, \IteratorAggregate } /** - * Offset to unset + * Offset to unset. + * * @param string $offset the offset to unset - * @return void */ public function offsetUnset($offset) { diff --git a/libs/Tree/Entry.php b/libs/Tree/Entry.php index 7543041..50a9060 100644 --- a/libs/Tree/Entry.php +++ b/libs/Tree/Entry.php @@ -23,7 +23,6 @@ abstract class Entry protected $path; /** - * @param Directory $parent * @param string $uri * @param SplFileInfo $info */ @@ -81,15 +80,12 @@ abstract class Entry /** * @return string */ - public function getTitle() + public function getTitle(): ?string { return $this->title; } - /** - * @param string $title - */ - public function setTitle($title) + public function setTitle(string $title) { $this->title = $title; } @@ -97,13 +93,13 @@ abstract class Entry /** * @return Directory */ - public function getParent() + public function getParent(): ?Directory { return $this->parent; } /** - * Return all parents starting with the root + * Return all parents starting with the root. * * @return Directory[] */ @@ -118,9 +114,6 @@ abstract class Entry return $parents; } - /** - * @param Directory $parent - */ protected function setParent(Directory $parent) { if ($this->parent) { @@ -134,17 +127,15 @@ abstract class Entry /** * @return string */ - public function getPath() + public function getPath(): ?string { return $this->path; } /** - * Get the path to the file from the root of the documentation - * - * @return string + * Get the path to the file from the root of the documentation. */ - public function getRelativePath() + public function getRelativePath(): string { $root = $this; while ($root->getParent() != null) { @@ -154,18 +145,12 @@ abstract class Entry return substr($this->path, strlen($root->getPath()) + 1); } - /** - * @return SplFileInfo - */ - public function getFileinfo() + public function getFileinfo(): SplFileInfo { return $this->info; } - /** - * @return string - */ - public function getUrl() + public function getUrl(): string { $url = ''; @@ -190,7 +175,8 @@ abstract class Entry ]; } - public function isHotPath(Entry $node = null) { + public function isHotPath(Entry $node = null) + { return $this->parent->isHotPath($node ?: $this); } } diff --git a/libs/Tree/Root.php b/libs/Tree/Root.php index b286ade..7c2dc04 100644 --- a/libs/Tree/Root.php +++ b/libs/Tree/Root.php @@ -11,7 +11,7 @@ class Root extends Directory protected $activeNode; /** - * The root doesn't have a parent + * The root doesn't have a parent. */ public function __construct(Config $config) { @@ -21,23 +21,18 @@ class Root extends Directory $this->path = $config->getDocumentationDirectory(); } - /** - * @return Config - */ - public function getConfig() + public function getConfig(): Config { return $this->config; } - /** - * @param Config $config - */ - public function setConfig($config) + public function setConfig(Config $config) { $this->config = $config; } - public function isHotPath(Entry $node = null) { + public function isHotPath(Entry $node = null): bool + { if ($node == null) { return true; } @@ -51,7 +46,7 @@ class Root extends Directory } foreach ($this->activeNode->getParents() as $parent) { - if ($node == $parent) { + if ($node === $parent) { return true; } } @@ -59,7 +54,8 @@ class Root extends Directory return false; } - public function setActiveNode(Entry $node) { + public function setActiveNode(Entry $node) + { $this->activeNode = $node; } } diff --git a/libs/bootstrap.php b/libs/bootstrap.php index 8e5b669..26b020d 100644 --- a/libs/bootstrap.php +++ b/libs/bootstrap.php @@ -1,6 +1,7 @@ setPsr4("Todaymade\\Daux\\Extension\\", $ext); + $loader->setPsr4('Todaymade\\Daux\\Extension\\', $ext); } diff --git a/package.json b/package.json index d6ae45b..c09feb3 100644 --- a/package.json +++ b/package.json @@ -8,12 +8,14 @@ "@swissquote/crafty-preset-postcss": "^1.8.0", "@swissquote/crafty-runner-gulp": "^1.8.0", "@swissquote/crafty-runner-rollup": "^1.8.0", - "flexsearch": "^0.6.30", - "preact": "^10.0.0-rc.3" + "flexsearch": "^0.6.32", + "postcss-page-break": "^2.0.0", + "preact": "^10.0.5" }, "scripts": { "build": "crafty run", "watch": "crafty watch", + "lint:js": "crafty jsLint --fix src/js/**/*.js", "lint:css": "crafty cssLint --fix --preset recommended themes/daux_singlepage/scss/*.scss themes/daux/scss/*.scss" } } diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..baa87b7 --- /dev/null +++ b/renovate.json @@ -0,0 +1,8 @@ +{ + "extends": [ + "config:base", + "group:allNonMajor", + ":preserveSemverRanges", + "schedule:weekends" + ] +} diff --git a/scripts/fix_report.php b/scripts/fix_report.php new file mode 100644 index 0000000..4f568d5 --- /dev/null +++ b/scripts/fix_report.php @@ -0,0 +1,52 @@ +loadXML($report); + +function hasDataSetTestCase(DomNode $node) { + foreach ($node->childNodes as $child) { + if ($child->nodeName === "testcase" && strpos($child->attributes->getNamedItem("name")->textContent, "with data set #" ) !== false) { + return $child; + } + } + + return false; +} + +function drillDownTestSuite(DomDocument $document, DomNode $node) { + if ($dataset = hasDataSetTestCase($node)) { + $childAttributes = $dataset->attributes; + $nodeAttributes= $node->attributes; + + $case = $document->createElement('testcase'); + $case->setAttribute('name', $childAttributes->getNamedItem('name')->textContent); + $case->setAttribute('class', $childAttributes->getNamedItem('class')->textContent); + $case->setAttribute('classname', $childAttributes->getNamedItem('classname')->textContent); + $case->setAttribute('file', $childAttributes->getNamedItem('file')->textContent); + $case->setAttribute('line', $childAttributes->getNamedItem('line')->textContent); + $case->setAttribute('assertions', $nodeAttributes->getNamedItem('assertions')->textContent); + $case->setAttribute('time', $nodeAttributes->getNamedItem('time')->textContent); + + $node->parentNode->replaceChild($case, $node); + return true; + } + + /** @var DomNode $child */ + for ($i=0; $i< $node->childNodes->length; $i++) { + $child = $node->childNodes->item($i); + if ($child->localName === "testsuite") { + if (drillDownTestSuite($document, $child)) { + $i--; + } + } + } + + return false; +} + +drillDownTestSuite($doc, $doc->firstChild); + +file_put_contents(dirname(__DIR__) . "/test-report.xml", $doc->saveXML()); +echo "Done\n"; diff --git a/scripts/fix_reports.sh b/scripts/fix_reports.sh new file mode 100755 index 0000000..90ab60c --- /dev/null +++ b/scripts/fix_reports.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# https://community.sonarsource.com/t/code-coverage-doesnt-work-with-github-action/16747/5 +echo "fix code coverage paths" +sed -i 's/\/home\/runner\/work\/daux.io\/daux.io\//\/github\/workspace\//g' coverage.clover + +php scripts/fix_report.php diff --git a/scripts/install_tools.sh b/scripts/install_tools.sh new file mode 100755 index 0000000..b9e4fe0 --- /dev/null +++ b/scripts/install_tools.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +if [ ! -d build ]; then + mkdir build; +fi + +echo "-- Install phpunit" +curl -sSLo build/phpunit https://phar.phpunit.de/phpunit-8.phar +chmod +x build/phpunit + +echo "-- Install php-cs-fixer" +curl -sSLo build/php-cs-fixer https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.16.3/php-cs-fixer.phar +chmod +x build/php-cs-fixer diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..f818211 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,10 @@ +sonar.projectKey=dauxio_daux.io +sonar.organization=daux +sonar.projectName=Daux.io + +sonar.sources=. +sonar.exclusions=vendor/**,tests/** +sonar.test.inclusions=tests/** + +sonar.php.coverage.reportPaths=coverage.clover +sonar.php.tests.reportPath=test-report.xml diff --git a/src/css/theme_daux/_components.scss b/src/css/theme_daux/_components.scss index 98cae53..6537068 100644 --- a/src/css/theme_daux/_components.scss +++ b/src/css/theme_daux/_components.scss @@ -35,7 +35,7 @@ Components display: inline-block; text-align: center; vertical-align: middle; - touch-action: manipulation; + touch-action: manipulation; // stylelint-disable-line plugin/no-unsupported-browser-features cursor: pointer; background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214 border: 1px solid transparent; @@ -99,7 +99,8 @@ Components } /* stylelint-disable-next-line selector-class-pattern */ -.no-js .CodeToggler { +.no-js .CodeToggler, +.CodeToggler--hidden { display: none; } @@ -249,7 +250,6 @@ Components display: inline-block; vertical-align: top; - zoom: 1; position: relative; height: 20px; @@ -264,7 +264,6 @@ Components .Twitter__button__label { display: inline-block; vertical-align: top; - zoom: 1; margin-left: 3px; white-space: nowrap; @@ -301,7 +300,7 @@ Components &:focus { border-color: var(--search-field-hover-border-color); - outline: 0; + outline: 0; // stylelint-disable-line plugin/no-unsupported-browser-features } } @@ -311,6 +310,7 @@ Components top: 9px; width: 16px; height: 16px; + cursor: pointer; } } @@ -477,7 +477,3 @@ ul.TableOfContents { border-color: var(--checkbox-disabled-tick-color); } } - -.Hidden { - display: none; -} diff --git a/src/css/theme_daux/_fonts.scss b/src/css/theme_daux/_fonts.scss index 755d61f..4ff70fd 100644 --- a/src/css/theme_daux/_fonts.scss +++ b/src/css/theme_daux/_fonts.scss @@ -20,6 +20,7 @@ url("../fonts/robotoslab-light.woff") format("woff"), url("../fonts/robotoslab-light.ttf") format("truetype"), url("../fonts/robotoslab-light.svg#roboto_slablight") format("svg"); + // stylelint-disable-next-line plugin/no-unsupported-browser-features unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } @@ -36,6 +37,7 @@ url("../fonts/robotoslab-regular.woff") format("woff"), url("../fonts/robotoslab-regular.ttf") format("truetype"), url("../fonts/robotoslab-regular.svg#roboto_slabregular") format("svg"); + // stylelint-disable-next-line plugin/no-unsupported-browser-features unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } @@ -51,6 +53,7 @@ url("../fonts/robotoslab-bold.woff") format("woff"), url("../fonts/robotoslab-bold.ttf") format("truetype"), url("../fonts/robotoslab-bold.svg#roboto_slabbold") format("svg"); + // stylelint-disable-next-line plugin/no-unsupported-browser-features unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } diff --git a/src/css/theme_daux/_mixins.scss b/src/css/theme_daux/_mixins.scss index 6ced5e5..aea126e 100644 --- a/src/css/theme_daux/_mixins.scss +++ b/src/css/theme_daux/_mixins.scss @@ -4,7 +4,7 @@ Mixins @mixin kill-background-image { background-image: none; - filter: none; + filter: none; // stylelint-disable-line plugin/no-unsupported-browser-features } @mixin kill-box-shadow { diff --git a/src/css/theme_daux/_print.scss b/src/css/theme_daux/_print.scss index e93d21b..ec193ed 100644 --- a/src/css/theme_daux/_print.scss +++ b/src/css/theme_daux/_print.scss @@ -11,19 +11,19 @@ h3, h4, h5, h6 { - page-break-after: avoid; - page-break-before: auto; + break-after: avoid; // stylelint-disable-line plugin/no-unsupported-browser-features + break-before: auto; // stylelint-disable-line plugin/no-unsupported-browser-features } pre, blockquote { border: 1px solid #999; font-style: italic; - page-break-inside: avoid; + break-inside: avoid; // stylelint-disable-line plugin/no-unsupported-browser-features } img { - page-break-inside: avoid; + break-inside: avoid; // stylelint-disable-line plugin/no-unsupported-browser-features border: 0; /* Some browsers like to show a border around images. Switch it off */ } @@ -50,7 +50,7 @@ q { .PageBreak { display: block; - page-break-before: always; + break-before: always; // stylelint-disable-line plugin/no-unsupported-browser-features } .NoPrint { diff --git a/src/css/theme_daux/_structure.scss b/src/css/theme_daux/_structure.scss index 12bf5f2..c4d4c3b 100644 --- a/src/css/theme_daux/_structure.scss +++ b/src/css/theme_daux/_structure.scss @@ -148,3 +148,13 @@ body { // 860 == screen-width of 1200 - sidebar - margin max-width: 860px; } + +.u-visuallyHidden { + position: absolute !important; + height: 1px; + width: 1px; + overflow: hidden; + clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ + clip: rect(1px, 1px, 1px, 1px); + white-space: nowrap; /* added line */ +} diff --git a/src/css/theme_daux/_typography.scss b/src/css/theme_daux/_typography.scss index bbbcb7a..9743c12 100644 --- a/src/css/theme_daux/_typography.scss +++ b/src/css/theme_daux/_typography.scss @@ -6,8 +6,8 @@ body { line-height: 1.5; font-family: var(--font-family-text); - font-feature-settings: "kern" 1; - font-kerning: normal; + font-feature-settings: "kern" 1; // stylelint-disable-line plugin/no-unsupported-browser-features + font-kerning: normal; // stylelint-disable-line plugin/no-unsupported-browser-features -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } @@ -189,8 +189,7 @@ h6 { img { max-width: 100%; - display: block; - margin: 0 auto; + display: inline-block; } code { diff --git a/src/css/theme_daux_singlepage/_fonts.scss b/src/css/theme_daux_singlepage/_fonts.scss index 755d61f..4ff70fd 100644 --- a/src/css/theme_daux_singlepage/_fonts.scss +++ b/src/css/theme_daux_singlepage/_fonts.scss @@ -20,6 +20,7 @@ url("../fonts/robotoslab-light.woff") format("woff"), url("../fonts/robotoslab-light.ttf") format("truetype"), url("../fonts/robotoslab-light.svg#roboto_slablight") format("svg"); + // stylelint-disable-next-line plugin/no-unsupported-browser-features unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } @@ -36,6 +37,7 @@ url("../fonts/robotoslab-regular.woff") format("woff"), url("../fonts/robotoslab-regular.ttf") format("truetype"), url("../fonts/robotoslab-regular.svg#roboto_slabregular") format("svg"); + // stylelint-disable-next-line plugin/no-unsupported-browser-features unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } @@ -51,6 +53,7 @@ url("../fonts/robotoslab-bold.woff") format("woff"), url("../fonts/robotoslab-bold.ttf") format("truetype"), url("../fonts/robotoslab-bold.svg#roboto_slabbold") format("svg"); + // stylelint-disable-next-line plugin/no-unsupported-browser-features unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; } diff --git a/src/css/theme_daux_singlepage/_print.scss b/src/css/theme_daux_singlepage/_print.scss index 9599166..bce61b2 100755 --- a/src/css/theme_daux_singlepage/_print.scss +++ b/src/css/theme_daux_singlepage/_print.scss @@ -11,19 +11,19 @@ h3, h4, h5, h6 { - page-break-after: avoid; - page-break-before: auto; + break-after: avoid; // stylelint-disable-line plugin/no-unsupported-browser-features + break-before: auto; // stylelint-disable-line plugin/no-unsupported-browser-features } pre, blockquote { border: 1px solid #999; font-style: italic; - page-break-inside: avoid; + break-inside: avoid; // stylelint-disable-line plugin/no-unsupported-browser-features } img { - page-break-inside: avoid; + break-inside: avoid; // stylelint-disable-line plugin/no-unsupported-browser-features border: 0; /* Some browsers like to show a border around images. Switch it off */ } @@ -50,7 +50,7 @@ q { .PageBreak { display: block; - page-break-before: always; + break-before: always; // stylelint-disable-line plugin/no-unsupported-browser-features } .NoPrint { diff --git a/src/css/theme_daux_singlepage/main.scss b/src/css/theme_daux_singlepage/main.scss index a22208d..3f98c9f 100755 --- a/src/css/theme_daux_singlepage/main.scss +++ b/src/css/theme_daux_singlepage/main.scss @@ -15,7 +15,7 @@ body { } body { - text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility; // stylelint-disable-line plugin/no-unsupported-browser-features -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-family: var(--font-family-text); diff --git a/src/js/search/index.js b/src/js/search/index.js index 2922a0c..6277a2e 100644 --- a/src/js/search/index.js +++ b/src/js/search/index.js @@ -23,6 +23,7 @@ class SearchEngine { constructor(options) { this.settings = { field: document.getElementById("search_input"), + form: document.getElementById("search_form"), show: 10, showURL: true, showTitleCount: true, @@ -30,7 +31,7 @@ class SearchEngine { descriptiveWords: 25, highlightTerms: true, highlightEveryTerm: false, - contentLocation: "daux_search_index.json", + contentLocation: "daux_search_index.js", ...options }; @@ -41,30 +42,37 @@ class SearchEngine { loadData() { if (!this.loadingPromise) { - this.loadingPromise = fetch( - this.settings.base_url + this.settings.contentLocation - ) - .then(data => data.json()) - .then(json => { - this.searchIndex = new FlexSearch({ - doc: { - id: "url", - field: ["title", "text", "tags"] - } - }); + // We do this as jsonp instead of an XHR or fetch request + // to be compatible with usage from filesystem + const po = document.createElement("script"); + po.type = "text/javascript"; + po.async = true; + po.src = this.settings.base_url + this.settings.contentLocation; + const s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(po, s); - let pages = json.pages; - - // Only keep the pages related to the current language - if (window.searchLanguage) { - const pagePrefix = `${window.searchLanguage}/`; - pages = pages.filter( - item => item.url.indexOf(pagePrefix) === 0 - ); + this.loadingPromise = new Promise(resolve => { + window.load_search_index = data => resolve(data); + }).then(json => { + this.searchIndex = new FlexSearch({ + doc: { + id: "url", + field: ["title", "text", "tags"] } - - this.searchIndex.add(pages); }); + + let pages = json.pages; + + // Only keep the pages related to the current language + if (window.searchLanguage) { + const pagePrefix = `${window.searchLanguage}/`; + pages = pages.filter( + item => item.url.indexOf(pagePrefix) === 0 + ); + } + + this.searchIndex.add(pages); + }); } return this.loadingPromise; @@ -89,6 +97,13 @@ class SearchEngine { }); } }); + + this.settings.form.addEventListener("submit", event => { + event.preventDefault(); + this.loadData().then(() => { + this.displaySearch(); + }); + }); } keyUpHandler = e => { diff --git a/src/js/theme_daux/code_toggle.js b/src/js/theme_daux/code_toggle.js index b302e7f..cd230f1 100644 --- a/src/js/theme_daux/code_toggle.js +++ b/src/js/theme_daux/code_toggle.js @@ -1,11 +1,10 @@ -const codeBlocks = document.querySelectorAll(".s-content pre"); -const toggleCodeSection = document.querySelector(".CodeToggler"); +import { ready } from "./utils"; const LOCAL_STORAGE_KEY = "daux_code_blocks_hidden"; -function setCodeBlockStyle(hidden) { +function setCodeBlockStyle(codeBlocks, hidden) { for (let a = 0; a < codeBlocks.length; a++) { - codeBlocks[a].classList.toggle("Hidden", hidden); + codeBlocks[a].classList.toggle("CodeToggler--hidden", hidden); } try { localStorage.setItem(LOCAL_STORAGE_KEY, hidden); @@ -14,7 +13,7 @@ function setCodeBlockStyle(hidden) { } } -function enableToggler() { +function enableToggler(toggleCodeSection, codeBlocks) { const toggleCodeBlockBtnSet = toggleCodeSection.querySelector( ".CodeToggler__button--main" ); // available when floating is disabled @@ -22,7 +21,7 @@ function enableToggler() { toggleCodeBlockBtnSet.addEventListener( "change", ev => { - setCodeBlockStyle(!ev.target.checked); + setCodeBlockStyle(codeBlocks, !ev.target.checked); }, false ); @@ -38,7 +37,7 @@ function enableToggler() { } if (hidden) { - setCodeBlockStyle(!!hidden); + setCodeBlockStyle(codeBlocks, !!hidden); toggleCodeBlockBtnSet.checked = !hidden; } } catch (e) { @@ -46,10 +45,17 @@ function enableToggler() { } } -if (toggleCodeSection) { - if (codeBlocks.length) { - enableToggler(); - } else { - toggleCodeSection.classList.add("Hidden"); +ready(() => { + const codeBlocks = document.querySelectorAll(".s-content pre"); + const toggleCodeSection = document.querySelector(".CodeToggler"); + + if (!toggleCodeSection) { + return; } -} + + if (codeBlocks.length) { + enableToggler(toggleCodeSection, codeBlocks); + } else { + toggleCodeSection.classList.add("CodeToggler--hidden"); + } +}); diff --git a/src/js/theme_daux/hamburger.js b/src/js/theme_daux/hamburger.js index 45b0663..5aee5c3 100644 --- a/src/js/theme_daux/hamburger.js +++ b/src/js/theme_daux/hamburger.js @@ -1,18 +1,22 @@ -const trigger = document.querySelector(".Collapsible__trigger"); +import { ready } from "./utils"; -if (trigger) { - const content = document.querySelector(".Collapsible__content"); +ready(() => { + const trigger = document.querySelector(".Collapsible__trigger"); - trigger.addEventListener("click", ev => { - if (content.classList.contains("Collapsible__content--open")) { - content.style.height = 0; - content.classList.remove("Collapsible__content--open"); - trigger.setAttribute("aria-expanded", "false"); - } else { - trigger.setAttribute("aria-expanded", "true"); - content.style.transitionDuration = "150ms"; - content.style.height = `${content.scrollHeight}px`; - content.classList.add("Collapsible__content--open"); - } - }); -} + if (trigger) { + const content = document.querySelector(".Collapsible__content"); + + trigger.addEventListener("click", ev => { + if (content.classList.contains("Collapsible__content--open")) { + content.style.height = 0; + content.classList.remove("Collapsible__content--open"); + trigger.setAttribute("aria-expanded", "false"); + } else { + trigger.setAttribute("aria-expanded", "true"); + content.style.transitionDuration = "150ms"; + content.style.height = `${content.scrollHeight}px`; + content.classList.add("Collapsible__content--open"); + } + }); + } +}); diff --git a/src/js/theme_daux/highlight.js b/src/js/theme_daux/highlight.js index a0c8ef3..0de2622 100644 --- a/src/js/theme_daux/highlight.js +++ b/src/js/theme_daux/highlight.js @@ -1,12 +1,16 @@ -const codeBlocks = document.querySelectorAll("pre > code:not(.hljs)"); -if (codeBlocks.length) { - const head = document.getElementsByTagName("head")[0], - script = document.createElement("script"); - script.type = "text/javascript"; - script.async = true; - script.src = `${window.base_url}daux_libraries/highlight.pack.js`; - script.onload = function(src) { - [].forEach.call(codeBlocks, window.hljs.highlightBlock); - }; - head.appendChild(script); -} +import { ready } from "./utils"; + +ready(() => { + const codeBlocks = document.querySelectorAll("pre > code:not(.hljs)"); + if (codeBlocks.length) { + const head = document.getElementsByTagName("head")[0], + script = document.createElement("script"); + script.type = "text/javascript"; + script.async = true; + script.src = `${window.base_url}daux_libraries/highlight.pack.js`; + script.onload = function(src) { + [].forEach.call(codeBlocks, window.hljs.highlightBlock); + }; + head.appendChild(script); + } +}); diff --git a/src/js/theme_daux/menu.js b/src/js/theme_daux/menu.js index 06a4948..de0b067 100644 --- a/src/js/theme_daux/menu.js +++ b/src/js/theme_daux/menu.js @@ -1,3 +1,5 @@ +import { ready } from "./utils"; + /** * After the transition finishes set the height to auto so child * menus can expand properly. @@ -56,24 +58,28 @@ function toggleSubMenu(ev) { } } -const navItems = document.querySelectorAll( - ".Nav__item.has-children i.Nav__arrow" -); +ready(() => { + const navItems = document.querySelectorAll( + ".Nav__item.has-children i.Nav__arrow" + ); -// Go in reverse here because on page load the child nav items need to be -// opened first before their parents so the height on the parents can be -// calculated properly. -for (let i = navItems.length - 1, target; i >= 0; i--) { - target = navItems[i]; - target.addEventListener("click", toggleSubMenu); + // Go in reverse here because on page load the child nav items need to be + // opened first before their parents so the height on the parents can be + // calculated properly. + for (let i = navItems.length - 1, target; i >= 0; i--) { + target = navItems[i]; + target.addEventListener("click", toggleSubMenu); - if (target.parentNode.parentNode.classList.contains("Nav__item--open")) { - toggleSubMenu({ target }); + if ( + target.parentNode.parentNode.classList.contains("Nav__item--open") + ) { + toggleSubMenu({ target }); + } } -} -// Some navigations just have sub-pages without having a page by themselves -const ajNav = document.querySelectorAll(".Nav__item__link--nopage"); -for (const navItem of ajNav) { - navItem.addEventListener("click", toggleSubMenu); -} + // Some navigations just have sub-pages without having a page by themselves + const ajNav = document.querySelectorAll(".Nav__item__link--nopage"); + for (const navItem of ajNav) { + navItem.addEventListener("click", toggleSubMenu); + } +}); diff --git a/src/js/theme_daux/utils.js b/src/js/theme_daux/utils.js new file mode 100644 index 0000000..6a1d97c --- /dev/null +++ b/src/js/theme_daux/utils.js @@ -0,0 +1,9 @@ +/* eslint-disable @swissquote/swissquote/import/prefer-default-export */ + +export function ready(fn) { + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", fn); + } else { + fn(); + } +} diff --git a/templates/content.php b/templates/content.php index c710bec..862f139 100644 --- a/templates/content.php +++ b/templates/content.php @@ -3,13 +3,13 @@
    + $hasPrevNext = (!empty($page['prev']) || !empty($page['next'])); + if ($hasPrevNext && $config->getHTML()->showPreviousNextLinks()) { + ?> + } ?> diff --git a/templates/home.php b/templates/home.php index e253793..9145158 100755 --- a/templates/home.php +++ b/templates/home.php @@ -4,31 +4,32 @@
    - ' . $params['tagline'] . '' : '' ?> + hasTagline()) ? '

    ' . $config->getTagline() . '

    ' : '' ?>
    - ' : '' ?> + hasImage()) ? '' . $config->getTitle() . '' : '' ?>
    - ' . $this->translate("View_on_github") . ''; - } + getHTML()->hasRepository()) { ?> + + translate("View_on_github") ?> + + translate("View_documentation"); foreach ($page['entry_page'] as $key => $node) { echo '' . str_replace("__VIEW_DOCUMENTATION__", $view_doc, $key) . ''; } - if(isset($params['html']['buttons']) && is_array($params['html']['buttons'])) { - foreach ($params['html']['buttons'] as $name => $link ) { + if ($config->getHTML()->hasButtons()) { + foreach ($config->getHTML()->getButtons() as $name => $link) { echo '' . $name . ''; } } @@ -50,18 +51,18 @@
    - + getHTML()->hasLinks()) { ?> - + getHTML()->hasTwitterHandles()) { ?> diff --git a/templates/layout/00_layout.php b/templates/layout/00_layout.php index 4aa7d8d..82ebd5b 100755 --- a/templates/layout/00_layout.php +++ b/templates/layout/00_layout.php @@ -1,26 +1,33 @@ - + - <?= $page['title']; ?> <?= ($page['title'] != $params['title'])? '- ' . $params['title'] : "" ?> - getTitle()) ? '- ' . $config->getTitle() : "" ?> +\n"; - } elseif (array_key_exists('tagline', $params)) { - echo " \n"; + $meta['description'] = $page['attributes']['description']; + } elseif ($config->hasTagline()) { + $meta['description'] = $config->getTagLine(); } if (array_key_exists('attributes', $page) && array_key_exists('keywords', $page['attributes'])) { - echo " \n"; + $meta['keywords'] = $page['attributes']['keywords']; } if (array_key_exists('attributes', $page) && array_key_exists('author', $page['attributes'])) { - echo " \n"; - } elseif (array_key_exists('author', $params)) { - echo " \n"; + $meta['author'] = $page['attributes']['author']; + } elseif ($config->hasAuthor()) { + $meta['author'] = $config->getAuthor(); + } + + foreach ($meta as $name => $content) { + echo " \n"; } ?> - + @@ -28,43 +35,40 @@ - "; - } ?> + getTheme()->getFonts() as $font) { ?> + + - "; - } ?> - - - - + getTheme()->getCSS() as $css) { ?> + section('content'); ?> insert('theme::partials/google_analytics', ['analytics' => $params['html']['google_analytics'], 'host' => array_key_exists('host', $params) ? $params['host'] : '']); + if ($config->getHTML()->hasGoogleAnalytics()) { + $this->insert('theme::partials/google_analytics', ['analytics' => $config->getHTML()->getGoogleAnalyticsId(), 'host' => $config->hasHost() ? $config->getHost() : '']); } - if ($params['html']['piwik_analytics']) { - $this->insert('theme::partials/piwik_analytics', ['url' => $params['html']['piwik_analytics'], 'id' => $params['html']['piwik_analytics_id']]); + if ($config->getHTML()->hasPiwikAnalytics()) { + $this->insert('theme::partials/piwik_analytics', ['url' => $config->getHTML()->getPiwikAnalyticsUrl(), 'id' => $config->getHTML()->getPiwikAnalyticsId()]); + } + if ($config->getHTML()->hasPlausibleAnalyticsDomain()) { + $this->insert('theme::partials/plausible_analytics', ['domain' => $config->getHTML()->getPlausibleAnalyticsDomain()]); } ?> - '; - } ?> + getTheme()->getJS() as $js) { ?> + + insert('theme::partials/search_script', ['page' => $page, 'base_url' => $base_url]); ?> - diff --git a/templates/layout/05_page.php b/templates/layout/05_page.php index 3273e12..e3c8998 100755 --- a/templates/layout/05_page.php +++ b/templates/layout/05_page.php @@ -7,7 +7,7 @@ - insert('theme::partials/navbar_content', ['params' => $params]); ?> + insert('theme::partials/navbar_content'); ?> diff --git a/templates/partials/google_analytics.php b/templates/partials/google_analytics.php index 2f6328b..2f9a47f 100644 --- a/templates/partials/google_analytics.php +++ b/templates/partials/google_analytics.php @@ -1,9 +1,6 @@ + diff --git a/templates/partials/navbar_content.php b/templates/partials/navbar_content.php index 36e5874..fe55859 100755 --- a/templates/partials/navbar_content.php +++ b/templates/partials/navbar_content.php @@ -1,11 +1,31 @@ - + +getTitle(); ?> - - +getHTML()->hasSearch()) { ?> + diff --git a/templates/partials/plausible_analytics.php b/templates/partials/plausible_analytics.php new file mode 100644 index 0000000..6141716 --- /dev/null +++ b/templates/partials/plausible_analytics.php @@ -0,0 +1 @@ + diff --git a/templates/partials/search_script.php b/templates/partials/search_script.php index 6f6b428..0950891 100644 --- a/templates/partials/search_script.php +++ b/templates/partials/search_script.php @@ -1,4 +1,9 @@ - + +getHTML()->hasSearch()) { ?>