Skip to content

Commit

Permalink
Merge pull request #448 from IgniteUI/dTsvetkov/add-tsx-highlight-sup…
Browse files Browse the repository at this point in the history
…port

Add tsx highlight support
  • Loading branch information
ChronosSF authored Sep 12, 2023
2 parents 648d243 + 585abde commit c204db1
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 8 deletions.
7 changes: 1 addition & 6 deletions src/app/services/code-view/code-view.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { ExplicitEditor, ICodeViewCSS, ICodeViewElements, ICodeViewEvents, ICodeViewFilesData, ICodeViewMembers, ICodeViewOptions } from '../../types';
import hljs from "highlight.js";
import localization from '../localization';
import util from '../utils';
const hljsRazor = require('highlightjs-cshtml-razor');
hljs.registerLanguage("cshtml-razor", hljsRazor);
import hljs from "../highlight-custom";


export class CodeView implements ICodeViewEvents, ICodeViewMembers {
Expand Down Expand Up @@ -112,9 +110,6 @@ export class CodeView implements ICodeViewEvents, ICodeViewMembers {
let language;

switch (f.fileExtension) {
case "tsx":
language = 'ts';
break;
case "js":
language = 'javascript';
break;
Expand Down
121 changes: 121 additions & 0 deletions src/app/services/highlight-custom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// highlight-custom.tsx
import hljs from 'highlight.js';
const hljsRazor = require('highlightjs-cshtml-razor');
hljs.registerLanguage("cshtml-razor", hljsRazor);

hljs.registerLanguage('tsx', function (hljs) {
const TSX_KEYWORDS = {
keyword:
// TypeScript Keywords
'render abstract any as async await boolean break case catch class continue const ' +
'constructor declare default delete do else enum export extends false ' +
'finally for from function get if implements import in infer instanceof ' +
'interface keyof let module namespace never new null number object ' +
'package private protected public readonly require global return set ' +
'static string super switch this throw true try typeof undefined ' +
'unique var void while with yield' +
// JSX Keywords
'JSX JSX.Element JSXElement JSXFragment JSXText JSXOpeningElement JSXClosingElement ' +
'JSXAttribute JSXSpreadAttribute JSXExpressionContainer JSXSpreadChild ' +
'JSXMemberExpression JSXNamespacedName JSXEmptyExpression JSXIdentifier ' +
'JSXSpreadAttribute JSXSpreadChild ' +
// React Keywords
'React.Component React ReactDOM createRoot ' +
// Additional TSX-related keywords
'Props State',
};

// TypeScript and JSX-related syntax definitions
const TSX_CONTAINS = [
hljs!.COMMENT(
// Single-line and multi-line comments
'/\\*\\*',
'\\*/',
{
relevance: 0,
contains: [
{
className: 'doctag',
begin: '@\\w+',
relevance: 0,
},
],
}
),
hljs!.C_LINE_COMMENT_MODE,
hljs!.C_BLOCK_COMMENT_MODE,
hljs!.APOS_STRING_MODE,
hljs!.QUOTE_STRING_MODE,
{
// Numbers
className: 'number',
variants: [
{ begin: '\\b(0[bB][01]+)' },
{ begin: '\\b(0[oO][0-7]+)' },
{ begin: hljs!.C_NUMBER_RE },
],
relevance: 0,
},
{
// TypeScript variable declarations
beginKeywords: 'let const',
end: '\\=',
endScope: 'keyword',
keywords: 'let const',
relevance: 10,
contains: [
{
className: 'variable',
begin: '[A-Za-z$_][0-9A-Za-z$_]*',
relevance: 0,
},
],
},
{
// JSX Elements
begin: '<',
end: '>',
subLanguage: 'xml',
contains: [
{
// JSX Self-Closing Tags
begin: '<',
end: '/>',
subLanguage: 'xml',
contains: [],
},
{
// JSX Opening Tags
begin: '<',
end: '>',
subLanguage: 'xml',
contains: [],
relevance: 0,
},
],
},
{
// Recognize ReactDOM.createRoot
className: 'built_in',
begin: 'ReactDOM\\.createRoot',
},
{
// Recognize React.Component
className: 'built_in',
begin: 'React\\.Component',
},
{
// Recognize JSX
className: 'type',
begin: 'JSX',
},
];

return {
aliases: ['tsx'],
keywords: TSX_KEYWORDS,
contains: TSX_CONTAINS,
};
});

export default hljs;
5 changes: 3 additions & 2 deletions src/app/services/rendering/article.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import util from "../utils";
import { RenderingService, HTMLHighlightedCodeElement, INavigationOptions } from "../../types";;
import anchors from 'anchor-js';
import hljs from "highlight.js";
import hljs from "../highlight-custom";
import type { IgniteUIPlatform} from '../../types';
import { onSampleIframeContentLoaded, onXPlatSampleIframeContentLoaded } from "../../handlers";
import { Router } from "../router";
Expand Down Expand Up @@ -156,7 +156,8 @@ export class ArticleRenderingService extends RenderingService {
hljs.highlightBlock(block);
const highlightedBlock = <HTMLHighlightedCodeElement>block;
block = (block as HTMLHighlightedCodeElement);
let $span: JQuery<HTMLSpanElement> = $(`<span class="hljs-lang-name">${highlightedBlock.result.language}</span>`);
const language = highlightedBlock.result && highlightedBlock.result.language ? highlightedBlock.result.language : block.className.split('-')[1];
let $span: JQuery<HTMLSpanElement> = $(`<span class="hljs-lang-name">${language}</span>`);
let $button: JQuery<HTMLButtonElement> = $('<button data-localize="hljs.copyCode" class="hljs-code-copy hidden"></button>');
let $codeContainer: JQuery<HTMLPreElement> = $(highlightedBlock).parent() as unknown as JQuery<HTMLPreElement>;
$codeContainer.append([$span, $button]);
Expand Down

0 comments on commit c204db1

Please sign in to comment.