You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.6 KiB
88 lines
2.6 KiB
4 years ago
|
import { Injectable } from '@angular/core';
|
||
|
import * as hljs from 'highlight.js';
|
||
|
|
||
|
@Injectable({
|
||
|
providedIn: 'root'
|
||
|
})
|
||
|
export class TreoHighlightService
|
||
|
{
|
||
|
/**
|
||
|
* Constructor
|
||
|
*/
|
||
|
constructor()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
// -----------------------------------------------------------------------------------------------------
|
||
|
// @ Private methods
|
||
|
// -----------------------------------------------------------------------------------------------------
|
||
|
|
||
|
/**
|
||
|
* Remove the empty lines around the code block
|
||
|
* and re-align the indentation based on the first
|
||
|
* non-whitespace indented character
|
||
|
*
|
||
|
* @param code
|
||
|
* @private
|
||
|
*/
|
||
|
private _format(code: string): string
|
||
|
{
|
||
|
let firstCharIndentation: number | null = null;
|
||
|
|
||
|
// Split the code into lines and store the lines
|
||
|
const lines = code.split('\n');
|
||
|
|
||
|
// Trim the empty lines around the code block
|
||
|
while ( lines.length && lines[0].trim() === '' )
|
||
|
{
|
||
|
lines.shift();
|
||
|
}
|
||
|
|
||
|
while ( lines.length && lines[lines.length - 1].trim() === '' )
|
||
|
{
|
||
|
lines.pop();
|
||
|
}
|
||
|
|
||
|
// Iterate through the lines to figure out the first
|
||
|
// non-whitespace character indentation
|
||
|
lines.forEach((line) => {
|
||
|
|
||
|
// Skip the line if its length is zero
|
||
|
if ( line.length === 0 )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// We look at all the lines to find the smallest indentation
|
||
|
// of the first non-whitespace char since the first ever line
|
||
|
// is not necessarily has to be the line with the smallest
|
||
|
// non-whitespace char indentation
|
||
|
firstCharIndentation = firstCharIndentation === null ?
|
||
|
line.search(/\S|$/) :
|
||
|
Math.min(line.search(/\S|$/), firstCharIndentation);
|
||
|
});
|
||
|
|
||
|
// Iterate through the lines one more time, remove the extra
|
||
|
// indentation, join them together and return it
|
||
|
return lines.map((line) => {
|
||
|
return line.substring(firstCharIndentation);
|
||
|
}).join('\n');
|
||
|
}
|
||
|
|
||
|
// -----------------------------------------------------------------------------------------------------
|
||
|
// @ Public methods
|
||
|
// -----------------------------------------------------------------------------------------------------
|
||
|
|
||
|
/**
|
||
|
* Highlight
|
||
|
*/
|
||
|
highlight(code: string, language: string): string
|
||
|
{
|
||
|
// Format the code
|
||
|
code = this._format(code);
|
||
|
|
||
|
// Highlight and return the code
|
||
|
return hljs.highlight(language, code).value;
|
||
|
}
|
||
|
}
|