Skip to content

Commit

Permalink
39 add option to only show specific lines (#44)
Browse files Browse the repository at this point in the history
* Front-end side of working done

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Fix

* Completed

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Fix

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Changes

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Fixed for other Language Code Files

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Test Addition

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Reversion

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Normalization of Variable

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Changes

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

* Fixes

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>

---------

Signed-off-by: Muhammad Yousuf Fazal <[email protected]>
  • Loading branch information
myousuffazal authored Oct 26, 2023
1 parent 8810d2d commit 25df96d
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 11 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Example:
Parameters:
* `lang`: (Optional) One of the [supported languages]. Only necessary if the language is not detected from the file extension.
* `line`: (Optional) Show line numbers.
* `specificLines`: (Optional) Show only specific lines. Can be a single line number or a range separated with a hyphen (-). Multiple line numbers or ranges can be separated by commas.

Examples:

Expand All @@ -74,6 +75,11 @@ Render PHP file with line numbers:
{{#embed:https://example.com/fluffy/kittens.php|lang=php|line}}
```

Render PHP file with specific lines:
```
{{#embed:https://example.com/fluffy/kittens.php|lang=php|specificLines=1-3,8}}
```

### Refreshing external content

To refresh all the pages containing one of the parser functions added by this extension, run
Expand Down
3 changes: 2 additions & 1 deletion extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
"es6": true,
"scripts": [
"prism/prism.js",
"bitbucket-edit.js"
"bitbucket-edit.js",
"code-specific-lines.js"
]
},
"ext.external-content.code-renderer.styles": {
Expand Down
14 changes: 14 additions & 0 deletions resources/code-renderer.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,17 @@ pre[class*="language-"] {
.line-numbers-rows > span::before {
color: #72777d;
}

.hide-line {
display: none;
}

.line-numbers-rows .hide-line,
.line-numbers-rows .hide-line:before {
display: block;
height: 0px;
font-size: 1px;
background: #f0f0f0 !important;
color: #f0f0f0 !important;
text-shadow: none;
}
78 changes: 78 additions & 0 deletions resources/code-specific-lines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
Prism.hooks.add( 'complete', function( env ) {
var showLineRanges = env.element.parentElement.getAttribute( 'data-show-lines' );

if (showLineRanges) {
var showLines = showLines( showLineRanges );

var tokenList = tokenList( env.element.innerHTML, showLines );

var lineNumbersActive = Prism.util.isActive( env.element, 'line-numbers' );

if ( lineNumbersActive ) {
var lineNumberList = lineNumberList( env.element.querySelectorAll( '.line-numbers-rows span' ), showLines );

env.element.innerHTML = tokenList.join( '' ) + '<span aria-hidden="true" class="line-numbers-rows">' + lineNumberList.join( '' ) + '</span>';
}
else {
env.element.innerHTML = tokenList.join( '' );
}
}

function showLines( showLineRanges ) {
var showLines = [];

showLineRanges.replace( /\s+/g, '' ).split( ',' ).filter( Boolean ).forEach( function( currentRange ) {
if (currentRange.includes( '-' )) {
var range = currentRange.split( '-' );

if ( range[0] > range[1] ) {
[range[0], range[1]] = [range[1], range[0]];
}

for ( var counter = range[0]; counter <= range[1]; counter++ ) {
showLines.push( Number( counter ) );
}
}
else {
showLines.push( Number( currentRange ) );
}
});

return showLines;
}

function tokenList( HTML, showLines ) {
var tokenList = HTML.split( /\n(?!$)/g );
var tokenCount = tokenList.length;
const regex = /(<span aria-hidden="true" class="line-numbers-rows">(.*<\/span>))/gm;

tokenList.forEach( function( value, index ) {
if ( index === tokenCount - 1 ) {
value = value.replace (regex, '' );
}

if ( showLines.includes ( index + 1 ) ) {
tokenList[index] += '\n';
}
else {
tokenList[index] = '<span class="hide-line">' + value + '</span>';
}
});

return tokenList;
}

function lineNumberList( lineNumberRows, showLines ) {
var lineNumberList = [];

lineNumberRows.forEach( function( value, index ) {
if ( !showLines.includes( index + 1 ) ) {
lineNumberRows[index].classList.add( 'hide-line' );
}

lineNumberList[index] = lineNumberRows[index].outerHTML;
});

return lineNumberList;
}
});
22 changes: 22 additions & 0 deletions src/Domain/ContentRenderer/CodeRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class CodeRenderer implements ContentRenderer {
public function __construct(
private string $language,
private bool $showLineNumbers,
private string $showSpecificLines,
private bool $showEditButton
) {
}
Expand Down Expand Up @@ -56,6 +57,10 @@ private function getWrapperAttributes( string $contentUrl ): array {

$attributes['class'] = $this->getWrapperClasses();

if ( !empty( $this->showSpecificLines ) ) {
$attributes['data-show-lines'] = $this->lineNormalizer( $this->showSpecificLines );
}

$attributes['data-toolbar-order'] = 'copy-to-clipboard';

if ( $this->showEditButton ) {
Expand All @@ -66,4 +71,21 @@ private function getWrapperAttributes( string $contentUrl ): array {
return $attributes;
}

/**
* @return string
*/
private function lineNormalizer( string $lines ) {
$exploded = explode( ',', preg_replace( '/\s+/', '', $lines ) );

$ranges = array_filter( $exploded, static function( $value ): bool {
if ( preg_match( '/^\d+$/', $value ) || preg_match( '/^(\d+)-(\d+)$/', $value ) ) {
return true;
}
else {
return false;
}
} );

return implode( ',', $ranges );
}
}
1 change: 1 addition & 0 deletions src/Domain/ContentRenderer/RendererConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public function __construct(
public string $fileExtension,
public string $language,
public bool $showLineNumbers,
public string $showSpecificLines,
public bool $showEditButton
) {
}
Expand Down
2 changes: 2 additions & 0 deletions src/Domain/WikiContentRendererFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public function createContentRenderer( RendererConfig $config ): ContentRenderer
return new CodeRenderer(
language: $config->language,
showLineNumbers: $config->showLineNumbers,
showSpecificLines: $config->showSpecificLines,
showEditButton: $config->showEditButton
);
}
Expand All @@ -27,6 +28,7 @@ public function createContentRenderer( RendererConfig $config ): ContentRenderer
return new CodeRenderer(
language: $config->fileExtension, // TODO: Use an extension-to-language map, although common extensions already work.
showLineNumbers: $config->showLineNumbers,
showSpecificLines: $config->showSpecificLines,
showEditButton: $config->showEditButton

);
Expand Down
1 change: 1 addition & 0 deletions src/UseCases/Embed/EmbedRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public function __construct(
public string $fileUrl,
public ?string $language,
public ?bool $showLineNumbers,
public ?string $showSpecificLines,
public bool $showEditButton
) {
}
Expand Down
2 changes: 2 additions & 0 deletions src/UseCases/Embed/EmbedRequestBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ public static function argumentsToRequest( array $arguments, bool $showEditButto

$language = $normalizedArguments['lang'] ?? null;
$line = $normalizedArguments['line'] ?? null;
$specificLines = $normalizedArguments['specificLines'] ?? null;

return new EmbedRequest(
fileUrl: $arguments[0],
language: is_string( $language ) ? $language : null,
showLineNumbers: is_bool( $line ) ? $line : null,
showSpecificLines: is_string( $specificLines ) ? $specificLines : null,
showEditButton: $showEditButton
);
}
Expand Down
1 change: 1 addition & 0 deletions src/UseCases/Embed/EmbedUseCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ private function createRendererConfig( EmbedRequest $request ): RendererConfig {
),
language: $request->language ?? '',
showLineNumbers: $request->showLineNumbers ?? false,
showSpecificLines: $request->showSpecificLines ?? '',
showEditButton: $request->showEditButton
);
}
Expand Down
30 changes: 24 additions & 6 deletions tests/Integration/Domain/CodeRendererTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,42 +15,60 @@ class CodeRendererTest extends TestCase {
public function testRendersSimplePhpWithoutLineNumbers(): void {
$this->assertSame(
'<pre class="external-content" data-toolbar-order="copy-to-clipboard"><code class="language-php">print( "Hello world" );</code></pre>',
( new CodeRenderer( language: 'php', showLineNumbers: false, showEditButton: false ) )->render( 'print( "Hello world" );', '' )
( new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '', showEditButton: false ) )->render( 'print( "Hello world" );', '' )
);
}

public function testRendersSimpleTypescriptWithLineNumbers(): void {
$this->assertSame(
'<pre class="external-content line-numbers" data-toolbar-order="copy-to-clipboard"><code class="language-typescript">console.log( "Hello world" as string );</code></pre>',
( new CodeRenderer( language: 'typescript', showLineNumbers: true, showEditButton: false ) )->render( 'console.log( "Hello world" as string );', '' )
( new CodeRenderer( language: 'typescript', showLineNumbers: true, showSpecificLines: '', showEditButton: false ) )->render( 'console.log( "Hello world" as string );', '' )
);
}

public function testRendersEscapedHtml(): void {
$this->assertSame(
'<pre class="external-content" data-toolbar-order="copy-to-clipboard"><code class="language-html">&lt;script>alert( "HAX" );&lt;/script></code></pre>',
( new CodeRenderer( language: 'html', showLineNumbers: false, showEditButton: false ) )->render( '<script>alert( "HAX" );</script>', '' )
( new CodeRenderer( language: 'html', showLineNumbers: false, showSpecificLines: '', showEditButton: false ) )->render( '<script>alert( "HAX" );</script>', '' )
);
}

public function testRendersEscapedHtmlWithWrongLanguage(): void {
$this->assertSame(
'<pre class="external-content" data-toolbar-order="copy-to-clipboard"><code class="language-javascript">&lt;script>alert( "HAX" );&lt;/script></code></pre>',
( new CodeRenderer( language: 'javascript', showLineNumbers: false, showEditButton: false ) )->render( '<script>alert( "HAX" );</script>', '' )
( new CodeRenderer( language: 'javascript', showLineNumbers: false, showSpecificLines: '', showEditButton: false ) )->render( '<script>alert( "HAX" );</script>', '' )
);
}

public function testRendersEscapedPartialHtml(): void {
$this->assertSame(
'<pre class="external-content" data-toolbar-order="copy-to-clipboard"><code class="language-html">&lt;/code>&lt;/pre>FOO</code></pre>',
( new CodeRenderer( language: 'html', showLineNumbers: false, showEditButton: false ) )->render( '</code></pre>FOO', '' )
( new CodeRenderer( language: 'html', showLineNumbers: false, showSpecificLines: '', showEditButton: false ) )->render( '</code></pre>FOO', '' )
);
}

public function testRendersShowEditButton(): void {
$this->assertSame(
'<pre class="external-content" data-toolbar-order="bitbucket-edit,copy-to-clipboard" data-src="http://bitbucket:7990/projects/TEST/repos/test/browse/test.php"><code class="language-php">&lt;/code>&lt;/pre>FOO</code></pre>',
( new CodeRenderer( language: 'php', showLineNumbers: false, showEditButton: true ) )->render( '</code></pre>FOO', 'http://bitbucket:7990/projects/TEST/repos/test/browse/test.php' )
( new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '', showEditButton: true ) )->render( '</code></pre>FOO', 'http://bitbucket:7990/projects/TEST/repos/test/browse/test.php' )
);
}

public function testRendersSpecificLineNumbers(): void {
$this->assertSame(
'<pre class="external-content line-numbers" data-show-lines="2-3,5" data-toolbar-order="copy-to-clipboard"><code class="language-php">&lt;?php
$a = "Hello";
$b = "World";
print( $a . " " . $b );
?></code></pre>',
( new CodeRenderer( language: 'php', showLineNumbers: true, showSpecificLines: '2-3,5', showEditButton: false ) )->render(
'<?php
$a = "Hello";
$b = "World";
print( $a . " " . $b );
?>', '' )
);
}

Expand Down
13 changes: 9 additions & 4 deletions tests/Unit/Domain/WikiContentRendererFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function testMarkdownFileAndConfigWithoutLanguageCreatesMarkdownRenderer(
fileExtension: 'md',
language: '',
showLineNumbers: false,
showSpecificLines: '',
showEditButton: false
)
)
Expand All @@ -29,12 +30,13 @@ public function testMarkdownFileAndConfigWithoutLanguageCreatesMarkdownRenderer(

public function testConfigWithoutLanguageCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'php', showLineNumbers: false, showEditButton: false ),
new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '', showEditButton: false ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'php',
language: '',
showLineNumbers: false,
showSpecificLines: '',
showEditButton: false
)
)
Expand All @@ -43,12 +45,13 @@ public function testConfigWithoutLanguageCreatesCodeRenderer(): void {

public function testConfigWithLanguageCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'php', showLineNumbers: false, showEditButton: false ),
new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '', showEditButton: false ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'php',
language: 'php',
showLineNumbers: false,
showSpecificLines: '',
showEditButton: false
)
)
Expand All @@ -57,12 +60,13 @@ public function testConfigWithLanguageCreatesCodeRenderer(): void {

public function testConfigWithLanguageAndLineNumbersCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'php', showLineNumbers: true, showEditButton: false ),
new CodeRenderer( language: 'php', showLineNumbers: true, showSpecificLines: '', showEditButton: false ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'php',
language: 'php',
showLineNumbers: true,
showSpecificLines: '',
showEditButton: false
)
)
Expand All @@ -71,12 +75,13 @@ public function testConfigWithLanguageAndLineNumbersCreatesCodeRenderer(): void

public function testConfigWithMarkdownLanguageCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'md', showLineNumbers: false, showEditButton: false ),
new CodeRenderer( language: 'md', showLineNumbers: false, showSpecificLines: '', showEditButton: false ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'md',
language: 'md',
showLineNumbers: false,
showSpecificLines: '',
showEditButton: false
)
)
Expand Down
1 change: 1 addition & 0 deletions tests/Unit/UseCases/Embed/EmbedUseCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ private function createRequest( string $fileUrl ): EmbedRequest {
fileUrl: $fileUrl,
language: '',
showLineNumbers: false,
showSpecificLines: '',
showEditButton: false
);
}
Expand Down

0 comments on commit 25df96d

Please sign in to comment.