@@ -106,6 +106,16 @@ $(function() {
|
||||
});
|
||||
});
|
||||
|
||||
$('.markdown-body :header').prepend(function() {
|
||||
$(this).prepend('<a class="anchor" href="#'+$(this).attr('id')+'"><i class="fas fa-link"></i>');
|
||||
});
|
||||
|
||||
$('.markdown-body :header').hover(function(){
|
||||
$(this).find('a.anchor').show();
|
||||
}, function(){
|
||||
$(this).find('a.anchor').hide();
|
||||
});
|
||||
|
||||
/*
|
||||
$('input').iCheck({
|
||||
checkboxClass: 'icheckbox_square-blue',
|
||||
|
||||
@@ -37,3 +37,4 @@ footer.main-footer {
|
||||
@import 'calendar';
|
||||
@import 'dashboard';
|
||||
@import 'navbar';
|
||||
@import 'documentation';
|
||||
|
||||
25
assets/sass/documentation.scss
Normal file
25
assets/sass/documentation.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
.markdown-body {
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
a.anchor {
|
||||
float: left;
|
||||
font-size: 0.5em;
|
||||
margin-left: -1em;
|
||||
padding-top: 0.5em;
|
||||
color: $text-color;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
.markdown-body {
|
||||
padding-left: 25px;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
}
|
||||
|
||||
/* The filter form is available on most pages above the datatable */
|
||||
@media (min-width: 768px) {
|
||||
@media (min-width: $screen-sm-min) {
|
||||
.toolbar {
|
||||
form.navbar-form {
|
||||
font-size: $font-size-base;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"build/app.js": "/build/app.js?3dadf2331143d4cac84f",
|
||||
"build/app.css": "/build/app.css?6501689dff217d14b179e3049295343e",
|
||||
"build/app.js": "/build/app.js?d823754f6c3293656052",
|
||||
"build/app.css": "/build/app.css?979d88ed847886068fcf3eb0bc3de545",
|
||||
"build/images/blue@2x.png": "/build/images/blue@2x.png?2694acfd",
|
||||
"build/images/blue.png": "/build/images/blue.png?96f8a905",
|
||||
"build/fonts/fa-solid-900.woff2": "/build/fonts/fa-solid-900.woff2?e8a92a29",
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
use Parsedown as MarkdownParser;
|
||||
|
||||
/**
|
||||
* A simple class to parse markdown syntax and return HTML.
|
||||
*/
|
||||
@@ -26,7 +24,7 @@ class Markdown
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->parser = new MarkdownParser();
|
||||
$this->parser = new ParsedownExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
68
src/Utils/ParsedownExtension.php
Normal file
68
src/Utils/ParsedownExtension.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
/**
|
||||
* This Class extends the default Parsedown Class for custom methods.
|
||||
*/
|
||||
class ParsedownExtension extends \Parsedown
|
||||
{
|
||||
private $ids = [];
|
||||
|
||||
protected function blockHeader($line)
|
||||
{
|
||||
$block = parent::blockHeader($line);
|
||||
|
||||
$text = $block['element']['text'];
|
||||
$id = $this->getIDfromText($text);
|
||||
|
||||
// add id-attribute
|
||||
$block['element']['attributes'] = [
|
||||
'id' => $id
|
||||
];
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
/**
|
||||
* github-action for creating ids:
|
||||
*
|
||||
* - It downcases the header string
|
||||
* - remove anything that is not a letter, number, space or hyphen
|
||||
* - changes any space to a hyphen.
|
||||
* - If that is not unique, add "-1", "-2", "-3",... to make it unique
|
||||
*
|
||||
* @param $text
|
||||
* @return string
|
||||
*/
|
||||
private function getIDfromText($text)
|
||||
{
|
||||
$text = strtolower($text);
|
||||
|
||||
$text = preg_replace('/[^A-Za-z0-9\-\ ]/', '', $text);
|
||||
$text = strtr($text, [' ' => '-']);
|
||||
|
||||
if (isset($this->ids[$text])) {
|
||||
$i = 0;
|
||||
$numberedText = $text . '-1';
|
||||
|
||||
while (isset($this->ids[$numberedText])) {
|
||||
$i++;
|
||||
$numberedText = $text . '-' . $i;
|
||||
}
|
||||
|
||||
$text = $numberedText;
|
||||
}
|
||||
|
||||
$this->ids[$text] = '';
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
<a href="{{ path('help') }}">{{ 'action.back'|trans }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="box-body">
|
||||
<div class="box-body markdown-body">
|
||||
{{ documentation|md2html|replace(replacer)|raw }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,7 +25,7 @@ class HelpControllerTest extends ControllerBaseTest
|
||||
$client = $this->getClientForAuthenticatedUser();
|
||||
$this->request($client, '/help/');
|
||||
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||
$this->assertContains('<h1>Kimai documentation</h1>', $client->getResponse()->getContent());
|
||||
$this->assertContains('<h1 id="kimai-documentation">Kimai documentation</h1>', $client->getResponse()->getContent());
|
||||
$this->assertContains('<a href="configurations">', $client->getResponse()->getContent());
|
||||
$this->assertContains('<a href="developers">', $client->getResponse()->getContent());
|
||||
$this->assertContains('<a href="users">', $client->getResponse()->getContent());
|
||||
|
||||
@@ -31,7 +31,7 @@ class MarkdownExtensionTest extends TestCase
|
||||
{
|
||||
$sut = new MarkdownExtension(new Markdown());
|
||||
$this->assertEquals('<p><em>test</em></p>', $sut->markdownToHtml('*test*'));
|
||||
$this->assertEquals('<h1>foobar</h1>', $sut->markdownToHtml('# foobar'));
|
||||
$this->assertEquals('<h1 id="foobar">foobar</h1>', $sut->markdownToHtml('# foobar'));
|
||||
}
|
||||
|
||||
public function testTimesheetContent()
|
||||
|
||||
@@ -21,6 +21,6 @@ class MarkdownTest extends TestCase
|
||||
{
|
||||
$sut = new Markdown();
|
||||
$this->assertEquals('<p><em>test</em></p>', $sut->toHtml('*test*'));
|
||||
$this->assertEquals('<h1>foobar</h1>', $sut->toHtml('# foobar'));
|
||||
$this->assertEquals('<h1 id="foobar">foobar</h1>', $sut->toHtml('# foobar'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user