Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

39 add option to only show specific lines #44

Merged
merged 13 commits into from
Oct 26, 2023
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
16 changes: 15 additions & 1 deletion resources/code-renderer.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,25 @@ pre[class*="language-"] {

.line-numbers .line-numbers-rows {
background-color: #f0f0f0;
margin: -1em 0;
margin: -1.15em 0;
malberts marked this conversation as resolved.
Show resolved Hide resolved
padding: 1em 0;
border-right: 1px solid #eaecf0;
}

.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;
}
47 changes: 47 additions & 0 deletions resources/code-specific-lines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Prism.hooks.add( 'complete', function ( env ) {
var showLineRanges = env.element.parentElement.getAttribute( 'data-show-lines' );

if (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 ) );
}
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could go into a nice pure-function with full unit-test coverage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modified


var tokenList = env.element.querySelector( '.token' ).innerHTML.split( /\n(?!$)/g );

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

if ( lineNumbersActive ) {
var lineNumberRows = env.element.querySelectorAll( '.line-numbers-rows span' );
}

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

if ( lineNumbersActive ) {
lineNumberRows[index].classList.add( 'hide-line' );
}
}
});

env.element.querySelector( '.token' ).innerHTML = tokenList.join( '' );
}
});
5 changes: 5 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 = false
) {
}
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->showSpecificLines;
malberts marked this conversation as resolved.
Show resolved Hide resolved
}

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

if ( $this->showEditButton == true ) {
Expand Down
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 = false
) {
}
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 = false
) {
}
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
10 changes: 5 additions & 5 deletions tests/Integration/Domain/CodeRendererTest.php
malberts marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,35 @@ 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 ) )->render( 'print( "Hello world" );', '' )
( new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '' ) )->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 ) )->render( 'console.log( "Hello world" as string );', '' )
( new CodeRenderer( language: 'typescript', showLineNumbers: true, showSpecificLines: '' ) )->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 ) )->render( '<script>alert( "HAX" );</script>', '' )
( new CodeRenderer( language: 'html', showLineNumbers: false, showSpecificLines: '' ) )->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 ) )->render( '<script>alert( "HAX" );</script>', '' )
( new CodeRenderer( language: 'javascript', showLineNumbers: false, showSpecificLines: '' ) )->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 ) )->render( '</code></pre>FOO', '' )
( new CodeRenderer( language: 'html', showLineNumbers: false, showSpecificLines: '' ) )->render( '</code></pre>FOO', '' )
);
}

Expand Down
23 changes: 14 additions & 9 deletions tests/Unit/Domain/WikiContentRendererFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,59 +20,64 @@ public function testMarkdownFileAndConfigWithoutLanguageCreatesMarkdownRenderer(
new RendererConfig(
fileExtension: 'md',
language: '',
showLineNumbers: false
showLineNumbers: false,
showSpecificLines: ''
)
)
);
}

public function testConfigWithoutLanguageCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'php', showLineNumbers: false ),
new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '' ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'php',
language: '',
showLineNumbers: false
showLineNumbers: false,
showSpecificLines: ''
)
)
);
}

public function testConfigWithLanguageCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'php', showLineNumbers: false ),
new CodeRenderer( language: 'php', showLineNumbers: false, showSpecificLines: '' ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'php',
language: 'php',
showLineNumbers: false
showLineNumbers: false,
showSpecificLines: ''
)
)
);
}

public function testConfigWithLanguageAndLineNumbersCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'php', showLineNumbers: true ),
new CodeRenderer( language: 'php', showLineNumbers: true, showSpecificLines: '' ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'php',
language: 'php',
showLineNumbers: true
showLineNumbers: true,
showSpecificLines: ''
)
)
);
}

public function testConfigWithMarkdownLanguageCreatesCodeRenderer(): void {
$this->assertEquals(
new CodeRenderer( language: 'md', showLineNumbers: false ),
new CodeRenderer( language: 'md', showLineNumbers: false, showSpecificLines: '' ),
( new WikiContentRendererFactory() )->createContentRenderer(
new RendererConfig(
fileExtension: 'md',
language: 'md',
showLineNumbers: false
showLineNumbers: false,
showSpecificLines: ''
)
)
);
Expand Down
3 changes: 2 additions & 1 deletion tests/Unit/UseCases/Embed/EmbedUseCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ private function createRequest( string $fileUrl ): EmbedRequest {
return new EmbedRequest(
fileUrl: $fileUrl,
language: '',
showLineNumbers: false
showLineNumbers: false,
showSpecificLines: ''
);
}

Expand Down
Loading