Passed
Push — dougall-pheobe-database-map-fi... ( ...2d7731 )
by
unknown
22:10
created

MarkdownNeon::consumeNeonPlugin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
ccs 0
cts 7
cp 0
crap 2
1
<?php
2
/**
3
 * @link http://www.newicon.net/neon
4
 * @copyright Copyright (c) 2017 Newicon Ltd
5
 * @license http://www.newicon.net/neon/license/
6
 * @author Steve O'Brien <[email protected]> 06/10/2017
7
 * @package neon
8
 */
9
10
namespace neon\core\view;
11
12
use cebe\markdown\GithubMarkdown;
13
use neon\core\helpers\Str;
14
use neon\dev\widgets\NeonFiddle;
15
16
/**
17
 * Class MarkdownNeon
18
 * Adds neon specific elements to markdown
19
 * For example we may wish to include components via tags in a markdown way for eaxmple
20
 * {componentName}
21
 * Or documentation tips
22
 *
23
 * {{tip}}
24
 * Documentation tip
25
 * {/tip}}
26
 *
27
 * {{NeonFiddle}}
28
 *
29
 * {/NeonFiddle}}
30
 *
31
 * It would also be good to be able to run code (when in debug / dev mode) that would show the code that was run
32
 * in the documentation and print the results nicely too.  Perhaps:
33
 *
34
 * ~~~code
35
 *
36
 * ~~~
37
 *
38
 * @package neon\core\view
39
 */
40
class MarkdownNeon extends GithubMarkdown
41
{
42
	public $enableNewlines = true;
43
44
	public $neonPluginOpenTag = ['<!', '>'];
45
	public $neonPluginCloseTag = '</!>';
46
47
	/**
48
	 * Store an array of tags to render widgets store th tag text without delimiters
49
	 * for example:
50
	 * ```php
51
	 * [
52
	 *     'myPlugin' => ['class' => 'neon\my\class']
53
	 * ]
54
	 * ```
55
	 * @var array
56
	 */
57
	public $registeredWidgets = [];
58
59
	protected function identifyNeonPlugin($line, $lines, $current)
0 ignored issues
show
Unused Code introduced by
The parameter $current is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

59
	protected function identifyNeonPlugin($line, $lines, /** @scrutinizer ignore-unused */ $current)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $lines is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

59
	protected function identifyNeonPlugin($line, /** @scrutinizer ignore-unused */ $lines, $current)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
60
	{
61
		$openDelimiter = $this->neonPluginOpenTag[0];
62
		//if (Str::startsWith($line, $openDelimiter))
63
		if (strncmp($line, $openDelimiter, strlen($openDelimiter)) === 0) {
64
			return true;
65
		}
66
		return false;
67
	}
68
69
	protected function consumeNeonPlugin($lines, $current)
70
	{
71
		// create block array
72
		$block = ['neonPlugin'];
73
74
		$block['plugin']  = $this->_getPluginNameFromLines($lines, $current);
75
		$block['attributes']  = $this->_getPluginAttributesFromLines($lines, $current);
76
		$block['content'] = $this->_getPluginContentFromLines($lines, $current, $endLine);
77
78
		return [$block, $endLine];
79
	}
80
81
	protected function renderNeonPlugin($block)
82
	{
83
		$plugin = $block['plugin'];
84
		$content = implode("\n",$block['content']);
85
		$attributes = $block['attributes'];
86
		if (class_exists($plugin))
87
			return $plugin::widget(array_merge($attributes, ['content' => $content]));
88
		return '<div class="alert alert-danger">unknown plugin: &quot;' .  $plugin . '&quot;</div>';
89
	}
90
91
	protected function _getPluginAttributesFromLines($lines, $current)
92
	{
93
		list ($openDelimiter, $closeDelimiter) = $this->neonPluginOpenTag;
94
		$content = [];
95
		// consume all lines until the $closingTag is found
96
		for ($i = $current, $count = count($lines); $i < $count; $i++) {
97
98
			$line = $lines[$i];
99
			// stop consuming lines if we find the closing tag
100
			if (strpos($line, $closeDelimiter) !== false) {
101
				$content[] = $line;
102
				break;
103
			}
104
			$content[] = $line;
105
		}
106
		// remove tag and open delimiter from first and last lines
107
		$plugin = $this->_getPluginNameFromLines($lines, $current);
108
		$lastLine = \count($content)-1;
109
		$content[0] = Str::replaceFirst($openDelimiter, '', $content[0]);
110
		$content[0] = Str::replaceFirst($plugin, '', $content[0]);
111
		$content[$lastLine] = Str::replaceLast($closeDelimiter, '', $content[$lastLine]);
112
113
		$attrs = implode(' ', $content);
114
		// xml part
115
		$xml = simplexml_load_string("<attr $attrs></attr>");
116
		$attributes = [];
117
		foreach($xml[0]->attributes() as $a => $b) {
118
			$attributes[$a] = (string) $b;
119
		}
120
		return $attributes;
121
	}
122
123
	/**
124
	 * Get the plugin name without delimiters
125
	 *
126
	 * @param string $line - the line which contains the plugin tag
127
	 * @param int $current - the current line position
128
	 * @return String - the plugin name
129
	 */
130
	private function _getPluginNameFromLines($lines, $current)
131
	{
132
		$line = rtrim($lines[$current]);
133
		list ($openDelimiter, $closeDelimiter) = $this->neonPluginOpenTag;
134
		$tag = trim(substr($line, \strlen($openDelimiter)));
135
		// remove the closing delimiter if it has one
136
		$tagLine = str_replace($closeDelimiter, '', $tag);
137
		return explode(' ', $tagLine)[0];
138
	}
139
140
	/**
141
	 * @param array $lines
142
	 * @param int $current the current line to start from (the line with the detected plugin tag)
143
	 * @param int $i - the end line number
144
	 * @return array - array of lines that should be sent to this plugin
145
	 */
146
	private function _getPluginContentFromLines(array $lines, $current, &$i)
147
	{
148
		$closingTag = $this->neonPluginCloseTag;
149
		$content = [];
150
		// consume all lines until the $closingTag is found
151
		for ($i = $current + 1, $count = count($lines); $i < $count; $i++) {
152
			$line = $lines[$i];
153
			// stop consuming lines if we find the closing tag
154
			if (strpos($line, $closingTag) !== false)
155
				break;
156
			$content[] = $line;
157
		}
158
		return $content;
159
	}
160
161
	protected function _getLinesBetween($lines, $current, $startTag, $endTag)
0 ignored issues
show
Unused Code introduced by
The parameter $current is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

161
	protected function _getLinesBetween($lines, /** @scrutinizer ignore-unused */ $current, $startTag, $endTag)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $startTag is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

161
	protected function _getLinesBetween($lines, $current, /** @scrutinizer ignore-unused */ $startTag, $endTag)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $endTag is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

161
	protected function _getLinesBetween($lines, $current, $startTag, /** @scrutinizer ignore-unused */ $endTag)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $lines is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

161
	protected function _getLinesBetween(/** @scrutinizer ignore-unused */ $lines, $current, $startTag, $endTag)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
162
	{
163
164
	}
165
166
167
}