Skip to content

Commit 4926dc9

Browse files
committed
Added the option to use multiple codes inside a codeblock.
Added the option to use multiple codes inside a codeblock by adding more `<code>` and `<desc>`-tags. Changed the Layout of the PHP-Files a little bit.
1 parent d69cccf commit 4926dc9

File tree

6 files changed

+108
-34
lines changed

6 files changed

+108
-34
lines changed

includes/MultiCodeBlock.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,45 @@ public static function onParserFirstCallInit( Parser &$parser ) {
2828
* @param Parser $parser The MediaWiki syntax parser
2929
* @param PPFrame $frame MediaWiki frame
3030
*/
31-
public static function renderMultiCodeBlock( string &$input, array &$args, Parser &$parser, PPFrame &$frame ) {
31+
public static function renderMultiCodeBlock( string $input, array $args, Parser $parser, PPFrame $frame ) {
3232
$out = $parser->getOutput();
3333
$out->addModuleStyles( [ 'ext.multicodeblock.styles' ] );
3434
$out->addModules( [ 'ext.multicodeblock.js' ] );
3535

3636
$code = findCodeBlocks($input);
3737

38-
$replaced = str_replace($code, '', $input);
38+
$replaced = str_replace($code, 'test', $input);
3939
$dom = getDOM($replaced);
4040

4141
$codevariants = $dom->getElementsbyTagName('codeblock');
42-
$descriptions = $dom->getElementsbyTagName('desc');
43-
42+
43+
$descriptions = [];
44+
foreach($codevariants as $codevariant) {
45+
array_push($descriptions, $codevariant->getElementsbyTagName('desc'));
46+
}
47+
$codeArr = [];
48+
foreach($codevariants as $codevariant) {
49+
array_push($codeArr, $codevariant->getElementsbyTagName('code'));
50+
}
51+
4452
$size = sizeof($codevariants);
4553
$return = "";
4654
$languages = array();
4755

4856
$h1 = new \Highlight\Highlighter();
4957

58+
$last = 0;
5059
for($i = 0; $i < $size; ++$i) {
51-
$desc = $descriptions->item($i);
60+
$length = sizeof($codeArr[$i]);
61+
$codeBlocks = array_slice($code, $last, $length);
62+
63+
$last += $length;
5264

53-
$codeblock = createCodeBlock($code[$i], $desc, $codevariants[$i]->getAttribute('lang'), $parser, $h1);
54-
$return .= '<div class="tab-content '.($i == 0 ? 'tc-active' : '').'" data-tab="'.$i.'">'.$codeblock[0].'</div>';
65+
$codeblock = createCodeBlock($codeBlocks, $descriptions[$i], $codevariants[$i]->getAttribute('lang'), $parser, $h1);
66+
$return .= createTab($codeblock[0], $i);
5567
array_push($languages, $codeblock[1]);
5668
}
5769

58-
return createFrame($languages, $return);
70+
return array(createFrame($languages, $return), 'markerType' => 'nowiki');
5971
}
6072
}

includes/MultiCodeBlockBuilder.php

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php
22
require_once __DIR__ . '/vendor/autoload.php';
33

4-
require_once 'Description.php';
5-
require_once 'Code.php';
4+
require_once 'class/Description.php';
5+
require_once 'class/Code.php';
6+
require_once 'class/LanguageBlock.php';
67

78
/**
89
* Returns the DOM-Parser with custom options and the HTML-Tree
@@ -23,6 +24,10 @@ function getDOM(&$content) {
2324
return $dom;
2425
}
2526

27+
function createTab(string &$code, int $index, string $extra = 'outer') {
28+
return '<div class="'.$extra.' tab-content '.($index == 0 ? 'tc-active' : '').'" data-tab="'.$index.'">'.$code.'</div>';
29+
}
30+
2631
/**
2732
* Returns the MultiCodeBlock as a whole.
2833
*
@@ -31,18 +36,17 @@ function getDOM(&$content) {
3136
*
3237
* @return string The whole MultiCodeBlock.
3338
*/
34-
function createFrame(array $lang, string &$code) {
39+
function createFrame(array $lang, string &$code, string $extra = 'outer', bool $addCopy = false) {
3540
$size = sizeof($lang);
3641
$copyIcon = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/></svg>';
3742

3843
$return = '<div class="multicodeblock">
39-
<div class="copy" title="Copy code to clipboard">'.$copyIcon.'<span class="tooltip">Failed to copy!</span>
40-
</div>
41-
<div class="tabs">
42-
<div class="tab-sidebar">
44+
'.($addCopy ? '<div class="copy" title="Copy code to clipboard">'.$copyIcon.'<span class="tooltip">Failed to copy!</span></div>': '').'
45+
<div class="'.$extra.' tabs">
46+
<div class="'.$extra.' tab-sidebar">
4347
';
4448
for($i = 0; $i < $size; $i++) {
45-
$return .= '<button class="tab-button '.($i == 0 ? 'tb-active' : '').'" data-for-tab="'.$i.'">'.$lang[$i].'</button>';
49+
$return .= '<button class="'.$extra.' tab-button '.($i == 0 ? 'tb-active' : '').'" data-for-tab="'.$i.'">'.$lang[$i].'</button>';
4650
}
4751
$return .= '</div>'.$code.'</div></div>';
4852

@@ -66,31 +70,46 @@ function replaceLang(string $lang) {
6670
/**
6771
* Returns a single codeblock
6872
*
69-
* @param DOMElement $codevariant The content of the `<codevariant>` element.
70-
* @param string $code The code inside the `<codevariant>` block.
71-
* @param DOMElement $description The content of the `<desc>` element.
72-
* @param Parser $parser The parser object by MediaWiki
73-
* @param Highlighter $h1 The highlighter object
73+
* @param string $codeTags The code inside the `<codevariant>` block.
74+
* @param DOMElement $descriptions The content of the `<desc>` element.
75+
* @param string $lang The language of the `<codevariant>`.
76+
* @param Parser $parser The parser object by MediaWiki.
77+
* @param Highlighter $h1 The highlighter object.
7478
*
7579
* @return array The codeblock as the first element and the language as the second element.
7680
*/
77-
function createCodeBlock(&$code, &$description, $lang, Parser &$parser, \Highlight\Highlighter &$h1) {
81+
function createCodeBlock(array &$codeTags, DOMNodeList &$descriptions, $lang, Parser &$parser, \Highlight\Highlighter &$h1) {
7882
if($lang == null) {
7983
return array('<span style="color: red; font-size: 700;">No Lang Attribute</span>', 'No lang');
8084
}
8185

8286
$lang = strtolower($lang);
8387

84-
$code = new Code($code, $lang);
85-
$desc = new Description($description);
86-
$highlight = $code->highlight($h1);
88+
$languageBlock = new LanguageBlock($codeTags, $descriptions, $lang);
89+
90+
$return = '';
91+
92+
$versions = [];
8793

88-
$isObject = true;
89-
if(!isset($highlight->value)) {
90-
$isObject = false;
94+
for($i = 0;$i < $languageBlock->size; ++$i) {
95+
if($languageBlock->code[$i] === null) {
96+
continue;
97+
}
98+
99+
$highlight = $languageBlock->code[$i]->highlight($h1);
100+
101+
$isObject = true;
102+
if(!isset($highlight->value)) {
103+
$isObject = false;
104+
}
105+
106+
array_push($versions, 'Version #'.($i + 1));
107+
$return .= createTab(combineCodeDescription(($isObject ? $highlight->value : $highlight), $languageBlock->getDescription($i), $parser), $i, 'inner');
91108
}
109+
110+
$return = createFrame($versions, $return, 'inner', true);
92111

93-
return array(combineCodeDescription(($isObject ? $highlight->value : $highlight), $desc, $parser), ($isObject ? replaceLang($highlight->language) : $lang));
112+
return array($return, replaceLang($lang));
94113
}
95114

96115
/**
@@ -102,7 +121,7 @@ function createCodeBlock(&$code, &$description, $lang, Parser &$parser, \Highlig
102121
*
103122
* @return string A combined version of the code and the description with the MediaWiki syntax.
104123
*/
105-
function combineCodeDescription(string $code, Description &$desc, Parser &$parser) {
124+
function &combineCodeDescription(string $code, Description &$desc, Parser &$parser) {
106125
$arr = explode("\n", $code);
107126
$size = sizeof($arr);
108127

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?php
2-
require_once __DIR__ . '/vendor/autoload.php';
2+
require_once __DIR__ . '/../vendor/autoload.php';
33

44
/**
55
* Stores the description of the code.

includes/class/LanguageBlock.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
class LanguageBlock {
3+
public array $code = [];
4+
public array $desc = [];
5+
6+
public int $size = 0;
7+
private int $sizeDescription = 0;
8+
9+
public function __construct(array &$codeblocks = null, &$descriptions = null, &$lang = null) {
10+
if($codeblocks === null || $descriptions === null || $lang === null)
11+
return;
12+
13+
$this->setLanguageBlock($codeblocks, $descriptions, $lang);
14+
}
15+
16+
public function setLanguageBlock(array &$codeblocks, &$descriptions, &$lang) {
17+
$sizeCode = 0;
18+
19+
foreach($codeblocks as $code) {
20+
array_push($this->code, new Code($code, $lang));
21+
++$sizeCode;
22+
}
23+
24+
$sizeDesc = 0;
25+
foreach($descriptions as $description) {
26+
array_push($this->desc, new Description($description));
27+
++$sizeDesc;
28+
}
29+
30+
$this->size = $sizeCode;
31+
$this->sizeDescription = $sizeDesc;
32+
}
33+
34+
public function &getDescription(int $index) {
35+
if($this->sizeDescription < ($index + 1)) {
36+
$descr = new Description();
37+
return $descr;
38+
}
39+
return $this->desc[$index];
40+
}
41+
}

resources/ext.multicodeblock/js/multicodeblock.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@ const tabButtons = document.getElementsByClassName('tab-button');
44
for (let i = 0; i < tabButtons.length; i++) {
55
tabButtons[i].addEventListener("click", () => {
66
const button = tabButtons[i];
7+
const outer = (button.classList.contains('outer') ? 'outer' : 'inner');
8+
79
const sidebar = button.parentElement;
810
const tabContainer = sidebar.parentElement;
911
const tabNumber = button.dataset.forTab;
10-
const activateTab = tabContainer.querySelector(`.tab-content[data-tab="${tabNumber}"]`);
12+
const activateTab = tabContainer.querySelector(`.${outer}.tab-content[data-tab="${tabNumber}"]`);
1113

1214
{
13-
const innerTabButtons = sidebar.getElementsByClassName('tab-button');
15+
const innerTabButtons = sidebar.getElementsByClassName(outer + ' tab-button');
1416
for (let i = 0; i < innerTabButtons.length; i++) {
1517
innerTabButtons[i].classList.remove('tb-active');
1618
}
1719
}
1820

1921
{
20-
const innerTabContents = tabContainer.getElementsByClassName('tab-content');
22+
const innerTabContents = tabContainer.getElementsByClassName(outer + ' tab-content');
2123
for (let i = 0; i < innerTabContents.length; i++) {
2224
innerTabContents[i].classList.remove('tc-active');
2325
}

0 commit comments

Comments
 (0)