library-ts/browser/text/lexer/HighlightedHTML.ts

99 lines
2.6 KiB
TypeScript
Raw Normal View History

2025-03-08 08:16:54 +00:00
import { LexerEvent } from "./LexerEvent";
import { Lexer } from "./Lexer";
import { LexerQuery } from "./LexerQuery";
import { ElementType } from "../../dom/ElementType";
import { ElementAttribute } from "../../dom/ElementAttribute";
export class HighlightedHTML
{
static readonly codeToken = new ElementType( "code-token" );
static readonly type = new ElementAttribute( "type" );
static createLexerStyles( lexer:Lexer, prefixSelector:string = "", styles:string="" )
{
let matchers = lexer.matchers;
for ( let i = 0; i < matchers.length; i++ )
{
let matcher = matchers[ i ];
let hue = 360 - i / matchers.length * 360;
let style = `\n${prefixSelector}code-token-${matcher.type}{ color: hsl(${hue}, 60%, 60%)}`;
styles += style;
}
return styles;
}
static tokenize( query:LexerQuery )
{
let htmlTags = query.tokens.map(
t=>
{
if ( t.isDone || t.isError )
{
return "";
}
let rawValue = t.getMatch( query.source );
let textNode = document.createTextNode( rawValue );
let wrapper = document.createElement( "div" );
wrapper.appendChild( textNode );
let escapedText = wrapper.innerHTML;
return `<code-token-${t.type}>${escapedText}</code-token-${t.type}>`
}
);
return htmlTags.join( "" );
}
static auto( lexer:Lexer, query:LexerQuery )
{
let tokens = query.tokens;
let source = query.source;
let htmlTags = tokens.map(
t=>
{
let rawValue = t.getMatch( source );
let textNode = document.createTextNode( rawValue );
let wrapper = document.createElement( "div" );
wrapper.appendChild( textNode );
let escapedText = wrapper.innerHTML;
return `<code-token data-type="${t.type}">${escapedText}</code-token>`
}
);
let styles =
`
body
{
background-color: hsl(0,0%,10%);
}
pre
{
font-family: Ubuntu Mono;
}
`;
let matchers = lexer.matchers;
for ( let i = 0; i < matchers.length; i++ )
{
let matcher = matchers[ i ];
let hue = i / matchers.length * 360;
let style = `\ncode-token[data-type="${matcher.type}"]{ color: hsl(${hue}, 60%, 60%)}`;
styles += style;
}
let html = `<html><meta charset="utf-8"></meta><head><style>${styles}</style></head><body><pre>${htmlTags.join( "" )}</pre></body></html>`
return html;
}
}