diff --git a/README.md b/README.md
index d40d55d..ad7fea7 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
",
"homepage": "https://www.proangular.com",
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index cd575d4..603bbbc 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -33,17 +33,32 @@ import { Component } from '@angular/core';
[useCache]="false"
>
+ SETTING THE CODE STYLE THEME
+
+ Select a "highlight.js" code theme to apply. Note: Only one theme can be
+ loaded on a single page at a time! The first theme to load will apply to
+ all gists on the page.
+
+
+
DISPLAYING ONE SPECIFIC FILE
Display only one specific file when your gist has many.
DISPLAYING MULTIPLE, SPECIFIC FILES
You can also display any number of specific files by name.
diff --git a/src/app/public/ngx-gist-theme.service.ts b/src/app/public/ngx-gist-theme.service.ts
index 3f3b1a3..783bbb2 100644
--- a/src/app/public/ngx-gist-theme.service.ts
+++ b/src/app/public/ngx-gist-theme.service.ts
@@ -6,27 +6,63 @@ export class NgxGistThemeService {
public constructor(@Inject(DOCUMENT) private readonly document: Document) {}
private importElMaterialTheme: HTMLLinkElement | null = null;
+ private importElHljsTheme: HTMLLinkElement | null = null;
- public setTheme(materialPrebuiltTheme: MaterialPrebuiltTheme): void {
- const themeId = 'material-theme-import';
- const currentEl = this.document.getElementById(themeId);
-
- if (currentEl) {
- this.document.removeChild(currentEl);
+ public setTheme({
+ materialTheme,
+ hilightJsTheme,
+ }: {
+ materialTheme?: MaterialPrebuiltTheme;
+ hilightJsTheme?: HighlightJsTheme;
+ } = {}): void {
+ if (!materialTheme && !hilightJsTheme) {
+ throw new Error('You must provide a theme.');
}
- if (this.importElMaterialTheme) {
- this.document.removeChild(this.importElMaterialTheme);
- }
+ const materialThemeId = 'material-theme-import';
+ const hljsThemeId = 'hljs-theme-import';
- this.importElMaterialTheme = this.document.createElement('link');
- this.importElMaterialTheme.href = `https://unpkg.com/@angular/material@14.1.0/prebuilt-themes/${materialPrebuiltTheme}.css`;
- this.importElMaterialTheme.media = 'screen,print';
- this.importElMaterialTheme.rel = 'stylesheet';
- this.importElMaterialTheme.type = 'text/css';
- this.importElMaterialTheme.id = themeId;
+ const materialThemeLinkEl = this.document.getElementById(materialThemeId);
+ if (materialThemeLinkEl && !hilightJsTheme) {
+ // Material theme aleady exists, return.
+ return;
+ }
- this.document.head.appendChild(this.importElMaterialTheme);
+ const hljsThemeLinkEl = this.document.getElementById(hljsThemeId);
+ if (hljsThemeLinkEl && hilightJsTheme === 'default' && !materialTheme) {
+ // Default theme already in use, return.
+ console.log('returned');
+ return;
+ } else if (
+ hljsThemeLinkEl &&
+ hilightJsTheme !== 'default' &&
+ !materialTheme
+ ) {
+ // Override previously used theme, but remove it first.
+ console.log('remove');
+ this.document.head.removeChild(hljsThemeLinkEl);
+ }
+ console.log('info: ', materialTheme, hilightJsTheme);
+ if (materialTheme) {
+ // !!! Update version when needed.
+ const version = '14.1.0';
+ const url = `@angular/material@${version}/prebuilt-themes/${materialTheme}.css`;
+ this.importElMaterialTheme = this.document.createElement('link');
+ this.importElMaterialTheme.href = `https://unpkg.com/${url}`;
+ this.importElMaterialTheme.rel = 'stylesheet';
+ this.importElMaterialTheme.id = materialThemeId;
+ this.document.head.appendChild(this.importElMaterialTheme);
+ } else if (hilightJsTheme) {
+ console.log('apply', hilightJsTheme);
+ // !!! Update version when needed.
+ const version = '11.6.0';
+ const url = `highlight.js@${version}/styles/${hilightJsTheme}.css`;
+ this.importElHljsTheme = this.document.createElement('link');
+ this.importElHljsTheme.href = `https://unpkg.com/${url}`;
+ this.importElHljsTheme.rel = 'stylesheet';
+ this.importElHljsTheme.id = hljsThemeId;
+ this.document.head.appendChild(this.importElHljsTheme);
+ }
}
}
@@ -35,3 +71,77 @@ export type MaterialPrebuiltTheme =
| 'indigo-pink'
| 'pink-bluegrey'
| 'purple-green';
+
+export type HighlightJsTheme =
+ | 'a11y-dark'
+ | 'a11y-light'
+ | 'agate'
+ | 'androidstudio'
+ | 'an-old-hope'
+ | 'arduino-light'
+ | 'arta'
+ | 'ascetic'
+ | 'atom-one-dark'
+ | 'atom-one-dark-reasonable'
+ | 'atom-one-light'
+ | 'brown-paper'
+ | 'codepen-embed'
+ | 'color-brewer'
+ | 'dark'
+ | 'default'
+ | 'devibeans'
+ | 'docco'
+ | 'far'
+ | 'felipec'
+ | 'foundation'
+ | 'github'
+ | 'github-dark'
+ | 'github-dark-dimmed'
+ | 'gml'
+ | 'googlecode'
+ | 'gradient-dark'
+ | 'gradient-light'
+ | 'grayscale'
+ | 'hybrid'
+ | 'idea'
+ | 'intellij-light'
+ | 'ir-black'
+ | 'isbl-editor-dark'
+ | 'isbl-editor-light'
+ | 'kimbie-dark'
+ | 'kimbie-light'
+ | 'lightfair'
+ | 'lioshi'
+ | 'magula'
+ | 'mono-blue'
+ | 'monokai'
+ | 'monokai-sublime'
+ | 'night-owl'
+ | 'nnfx-dark'
+ | 'nnfx-light'
+ | 'nord'
+ | 'obsidian'
+ | 'panda-syntax-dark'
+ | 'panda-syntax-light'
+ | 'paraiso-dark'
+ | 'paraiso-light'
+ | 'pojoaque'
+ | 'purebasic'
+ | 'qtcreator-dark'
+ | 'qtcreator-light'
+ | 'rainbow'
+ | 'routeros'
+ | 'school-book'
+ | 'shades-of-purple'
+ | 'srcery'
+ | 'stackoverflow-dark'
+ | 'stackoverflow-light'
+ | 'sunburst'
+ | 'tokyo-night-dark'
+ | 'tokyo-night-light'
+ | 'tomorrow-night-blue'
+ | 'tomorrow-night-bright'
+ | 'vs'
+ | 'vs2015'
+ | 'xcode'
+ | 'xt256';
diff --git a/src/app/public/ngx-gist.component.ts b/src/app/public/ngx-gist.component.ts
index f7c3f2e..8cb0860 100644
--- a/src/app/public/ngx-gist.component.ts
+++ b/src/app/public/ngx-gist.component.ts
@@ -2,13 +2,13 @@ import { NgxGistService } from './ngx-gist.service';
import { isNonEmptyValue } from './ngx-gist.utilities';
import { NgxGist } from './ngx-gist.model';
import { Component, Inject, Input, OnInit } from '@angular/core';
-import { Language } from 'highlight.js';
import { BehaviorSubject, filter, firstValueFrom, ReplaySubject } from 'rxjs';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { DOCUMENT } from '@angular/common';
import { NgxGistLineNumbersService } from './ngx-gist-line-numbers.service';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import {
+ HighlightJsTheme,
MaterialPrebuiltTheme,
NgxGistThemeService,
} from './ngx-gist-theme.service';
@@ -27,7 +27,7 @@ import {
[label]="file.filename"
>
-
@@ -57,14 +57,10 @@ export class NgxGistComponent implements OnInit {
public constructor(
@Inject(DOCUMENT) private readonly document: Document,
private readonly domSanitizer: DomSanitizer,
- private readonly ngxGistService: NgxGistService,
private readonly ngxGistLineNumbersService: NgxGistLineNumbersService,
+ private readonly ngxGistService: NgxGistService,
private readonly ngxGistThemeService: NgxGistThemeService,
) {}
-
- // TODO: Apply HighlightJs code theme.
- // @Input() public codeTheme?: unknown;
-
/**
* Display in the DOM only the selected filename(s) from the gists files array.
*
@@ -115,15 +111,14 @@ export class NgxGistComponent implements OnInit {
>(1);
public readonly gistIdChanges = this.gistIdSubject.asObservable();
/**
- * When defined, override automatic language detection [and styling] and
- * treat all gists as this lanuage.
+ * The `highlight.js` code theme to use and display.
*
- * Default: `undefined`
+ * Default: `'default'`
*
- * Tip: See supported language strings here:
- * https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md
+ * Note: Only _one_ theme can be loaded on a single page at a time! The first
+ * theme to load will apply to all gists on the page.
*/
- @Input() public languageName?: Language['name'];
+ @Input() public codeTheme: HighlightJsTheme = 'default';
/**
* Define a material core theme to apply. Ideally, you should already have
* your global material theme set at the root of your project so try to
@@ -153,12 +148,16 @@ export class NgxGistComponent implements OnInit {
@Input() public useCache = true;
public async ngOnInit(): Promise {
- this.setTheme();
+ // Load themes
+ this.setMaterialTheme();
+ this.setHljsTheme();
+ // Load line numbers
if (this.showLineNumbers) {
await this.ngxGistLineNumbersService.load();
}
+ // Load gist(s) async
this.gistIdChanges
.pipe(filter(isNonEmptyValue), untilDestroyed(this))
.subscribe(async (gistId) => {
@@ -189,11 +188,18 @@ export class NgxGistComponent implements OnInit {
}
}
- private setTheme(): void {
+ private setHljsTheme(): void {
+ if (!this.codeTheme) {
+ return;
+ }
+ this.ngxGistThemeService.setTheme({ hilightJsTheme: this.codeTheme });
+ }
+
+ private setMaterialTheme(): void {
if (!this.materialTheme) {
return;
}
- this.ngxGistThemeService.setTheme(this.materialTheme);
+ this.ngxGistThemeService.setTheme({ materialTheme: this.materialTheme });
}
public applyLineNumbers(highlightedConent: string): SafeHtml | null {
diff --git a/src/app/public/public.ts b/src/app/public/public.ts
index 3081920..da3764d 100644
--- a/src/app/public/public.ts
+++ b/src/app/public/public.ts
@@ -1,5 +1,9 @@
/** Public API Exports for Node Package */
+export {
+ HighlightJsTheme,
+ MaterialPrebuiltTheme,
+} from './ngx-gist-theme.service';
export * from './ngx-gist.component';
export * from './ngx-gist.model';
export * from './ngx-gist.module';
diff --git a/src/assets/images/demo-gist.gif b/src/assets/images/demo-gist.gif
new file mode 100644
index 0000000..9c5c755
Binary files /dev/null and b/src/assets/images/demo-gist.gif differ
diff --git a/src/styles.scss b/src/styles.scss
index 906298e..4316880 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -17,3 +17,5 @@ body {
margin: 0;
background-color: #faf9f6;
}
+
+@import "~highlight.js/styles/github.css";