mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-27 10:02:59 +08:00
Merge branch 'develop' into feature/custom-datetime-format
This commit is contained in:
commit
f640c9212e
104
README.md
104
README.md
@ -4,15 +4,47 @@
|
||||
|
||||
[English](./README.md) | [Chinese](./docs/README-ZH_CN.md) | [Russian](./docs/README.ru.md) | [Japanese](./docs/README.ja.md) | [Italian](./docs/README.it.md) | [Spanish](./docs/README.es.md)
|
||||
|
||||
TriliumNext Notes is an open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
|
||||
TriliumNext Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
|
||||
|
||||
See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview:
|
||||
|
||||
<a href="https://triliumnext.github.io/Docs/Wiki/screenshot-tour"><img src="./docs/app.png" alt="Trilium Screenshot" width="1000"></a>
|
||||
|
||||
## 🎁 Features
|
||||
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Rich WYSIWYG note editor including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
|
||||
* Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax highlighting
|
||||
* Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* UI available in English, German, Spanish, French, Romanian, and Chinese (simplified and traditional)
|
||||
* Direct [OpenID and TOTP integration](.docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/Multi-Factor%20Authentication.md") for more secure login
|
||||
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server
|
||||
* there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting)
|
||||
* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet
|
||||
* Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with per-note granularity
|
||||
* Sketching diagrams, based on [Excalidraw](https://excalidraw.com/) (note type "canvas")
|
||||
* [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing notes and their relations
|
||||
* Mind maps, based on [Mind Elixir](https://docs.mind-elixir.com/)
|
||||
* [Geo maps](./docs/User%20Guide/User%20Guide/Note%20Types/Geo%20Map.md) with location pins and GPX tracks
|
||||
* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for smartphones and tablets
|
||||
* Built-in [dark theme](https://triliumnext.github.io/Docs/Wiki/themes), support for user themes
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown)
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy saving of web content
|
||||
* Customizable UI (sidebar buttons, user-defined widgets, ...)
|
||||
|
||||
✨ Check out the following third-party resources/communities for more TriliumNext related goodies:
|
||||
|
||||
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more.
|
||||
- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more.
|
||||
|
||||
## ⚠️ Why TriliumNext?
|
||||
|
||||
[The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620)
|
||||
[The original Trilium project is in maintenance mode](https://github.com/zadam/trilium/issues/4620).
|
||||
|
||||
### Migrating from Trilium?
|
||||
|
||||
@ -20,7 +52,7 @@ There are no special migration steps to migrate from a zadam/Trilium instance to
|
||||
|
||||
Versions up to and including [v0.90.4](https://github.com/TriliumNext/Notes/releases/tag/v0.90.4) are compatible with the latest zadam/trilium version of [v0.63.7](https://github.com/zadam/trilium/releases/tag/v0.63.7). Any later versions of TriliumNext have their sync versions incremented.
|
||||
|
||||
## Documentation
|
||||
## 📖 Documentation
|
||||
|
||||
We're currently in the progress of moving the documentation to in-app (hit the `F1` key within Trilium). As a result, there may be some missing parts until we've completed the migration. If you'd prefer to navigate through the documentation within GitHub, you can navigate the [User Guide](./docs/User%20Guide/User%20Guide/) documentation.
|
||||
|
||||
@ -29,55 +61,40 @@ Below are some quick links for your convenience to navigate the documentation:
|
||||
- [Docker installation](./docs/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.md)
|
||||
- [Upgrading TriliumNext](./docs/User%20Guide/User%20Guide/Installation%20%26%20Setup/Upgrading%20TriliumNext.md)
|
||||
- [Concepts and Features - Note](./docs/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes.md)
|
||||
- [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge)
|
||||
|
||||
Until we finish reorganizing the documentation, you may also want to [browse the old documentation](https://triliumnext.github.io/Docs).
|
||||
|
||||
## 💬 Discuss with us
|
||||
|
||||
Feel free to join our official conversations. We would love to hear what features, suggestions, or issues you may have!
|
||||
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions)
|
||||
- [Matrix](https://matrix.to/#/#triliumnext:matrix.org) (For synchronous discussions.)
|
||||
- The `General` Matrix room is also bridged to [XMPP](xmpp:discuss@trilium.thisgreat.party?join)
|
||||
- [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For Asynchronous discussions)
|
||||
- [Wiki](https://triliumnext.github.io/Docs/) (For common how-to questions and user guides)
|
||||
|
||||
## 🎁 Features
|
||||
|
||||
* Notes can be arranged into arbitrarily deep tree. Single note can be placed into multiple places in the tree (see [cloning](https://triliumnext.github.io/Docs/Wiki/cloning-notes))
|
||||
* Rich WYSIWYG note editing including e.g. tables, images and [math](https://triliumnext.github.io/Docs/Wiki/text-notes) with markdown [autoformat](https://triliumnext.github.io/Docs/Wiki/text-notes#autoformat)
|
||||
* Support for editing [notes with source code](https://triliumnext.github.io/Docs/Wiki/code-notes), including syntax highlighting
|
||||
* Fast and easy [navigation between notes](https://triliumnext.github.io/Docs/Wiki/note-navigation), full text search and [note hoisting](https://triliumnext.github.io/Docs/Wiki/note-hoisting)
|
||||
* Seamless [note versioning](https://triliumnext.github.io/Docs/Wiki/note-revisions)
|
||||
* Note [attributes](https://triliumnext.github.io/Docs/Wiki/attributes) can be used for note organization, querying and advanced [scripting](https://triliumnext.github.io/Docs/Wiki/scripts)
|
||||
* Direct OpenID and TOTP integration for more secure login
|
||||
* [Synchronization](https://triliumnext.github.io/Docs/Wiki/synchronization) with self-hosted sync server
|
||||
* there's a [3rd party service for hosting synchronisation server](https://trilium.cc/paid-hosting)
|
||||
* [Sharing](https://triliumnext.github.io/Docs/Wiki/sharing) (publishing) notes to public internet
|
||||
* Strong [note encryption](https://triliumnext.github.io/Docs/Wiki/protected-notes) with per-note granularity
|
||||
* Sketching diagrams with built-in Excalidraw (note type "canvas")
|
||||
* [Relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map) and [link maps](https://triliumnext.github.io/Docs/Wiki/link-map) for visualizing notes and their relations
|
||||
* [Scripting](https://triliumnext.github.io/Docs/Wiki/scripts) - see [Advanced showcases](https://triliumnext.github.io/Docs/Wiki/advanced-showcases)
|
||||
* [REST API](https://triliumnext.github.io/Docs/Wiki/etapi) for automation
|
||||
* Scales well in both usability and performance upwards of 100 000 notes
|
||||
* Touch optimized [mobile frontend](https://triliumnext.github.io/Docs/Wiki/mobile-frontend) for smartphones and tablets
|
||||
* [Night theme](https://triliumnext.github.io/Docs/Wiki/themes)
|
||||
* [Evernote](https://triliumnext.github.io/Docs/Wiki/evernote-import) and [Markdown import & export](https://triliumnext.github.io/Docs/Wiki/markdown)
|
||||
* [Web Clipper](https://triliumnext.github.io/Docs/Wiki/web-clipper) for easy saving of web content
|
||||
|
||||
✨ Check out the following third-party resources/communities for more TriliumNext related goodies:
|
||||
|
||||
- [awesome-trilium](https://github.com/Nriver/awesome-trilium) for 3rd party themes, scripts, plugins and more.
|
||||
- [TriliumRocks!](https://trilium.rocks/) for tutorials, guides, and much more.
|
||||
- [Github Discussions](https://github.com/TriliumNext/Notes/discussions) (For asynchronous discussions.)
|
||||
- [Github Issues](https://github.com/TriliumNext/Notes/issues) (For bug reports and feature requests.)
|
||||
|
||||
## 🏗 Installation
|
||||
|
||||
### Desktop
|
||||
### Windows / MacOS
|
||||
|
||||
To use TriliumNext on your desktop machine (Linux, MacOS, and Windows) you have a few options:
|
||||
Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the `trilium` executable.
|
||||
|
||||
* Download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the `trilium` executable.
|
||||
* Access TriliumNext via the web interface of a server installation (see below)
|
||||
* Currently only the latest versions of Chrome & Firefox are supported (and tested).
|
||||
* TriliumNext is also provided as a Flatpak, but not yet published on FlatHub.
|
||||
### Linux
|
||||
|
||||
If your distribution is listed in the table below, use your distribution's package.
|
||||
|
||||
[](https://repology.org/project/trilium-next-desktop/versions)
|
||||
|
||||
You may also download the binary release for your platform from the [latest release page](https://github.com/TriliumNext/Notes/releases/latest), unzip the package and run the `trilium` executable.
|
||||
|
||||
TriliumNext is also provided as a Flatpak, but not yet published on FlatHub.
|
||||
|
||||
### Browser (any OS)
|
||||
|
||||
If you use a server installation (see below), you can directly access the web interface (which is almost identical to the desktop app).
|
||||
|
||||
Currently only the latest versions of Chrome & Firefox are supported (and tested).
|
||||
|
||||
### Mobile
|
||||
|
||||
@ -91,11 +108,6 @@ See issue https://github.com/TriliumNext/Notes/issues/72 for more information on
|
||||
|
||||
To install TriliumNext on your own server (including via Docker from [Dockerhub](https://hub.docker.com/r/triliumnext/notes)) follow [the server installation docs](https://triliumnext.github.io/Docs/Wiki/server-installation).
|
||||
|
||||
## 📝 Documentation
|
||||
|
||||
[See wiki for complete list of documentation pages.](https://triliumnext.github.io/Docs)
|
||||
|
||||
You can also read [Patterns of personal knowledge base](https://triliumnext.github.io/Docs/Wiki/patterns-of-personal-knowledge) to get some inspiration on how you might use TriliumNext.
|
||||
|
||||
## 💻 Contribute
|
||||
|
||||
@ -150,4 +162,6 @@ Support for the TriliumNext organization will be possible in the near future. Fo
|
||||
|
||||
## 🔑 License
|
||||
|
||||
Copyright 2017-2025 zadam, Elian Doran, and other contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
@ -38,9 +38,9 @@
|
||||
"@playwright/test": "1.52.0",
|
||||
"@stylistic/eslint-plugin": "4.2.0",
|
||||
"@types/express": "5.0.1",
|
||||
"@types/node": "22.15.18",
|
||||
"@types/node": "22.15.19",
|
||||
"@types/yargs": "17.0.33",
|
||||
"@vitest/coverage-v8": "3.1.3",
|
||||
"@vitest/coverage-v8": "3.1.4",
|
||||
"eslint": "9.27.0",
|
||||
"eslint-plugin-simple-import-sort": "12.1.1",
|
||||
"esm": "3.2.25",
|
||||
|
@ -31,7 +31,7 @@
|
||||
"draggabilly": "3.0.0",
|
||||
"force-graph": "1.49.6",
|
||||
"globals": "16.1.0",
|
||||
"i18next": "25.1.3",
|
||||
"i18next": "25.2.0",
|
||||
"i18next-http-backend": "3.0.2",
|
||||
"jquery": "3.7.1",
|
||||
"jquery-hotkeys": "0.2.2",
|
||||
@ -41,7 +41,7 @@
|
||||
"leaflet": "1.9.4",
|
||||
"leaflet-gpx": "2.2.0",
|
||||
"mark.js": "8.11.1",
|
||||
"marked": "15.0.11",
|
||||
"marked": "15.0.12",
|
||||
"mermaid": "11.6.0",
|
||||
"mind-elixir": "4.5.2",
|
||||
"panzoom": "9.4.3",
|
||||
@ -55,7 +55,7 @@
|
||||
"@ckeditor/ckeditor5-inspector": "4.1.0",
|
||||
"@types/bootstrap": "5.2.10",
|
||||
"@types/jquery": "3.5.32",
|
||||
"@types/leaflet": "1.9.17",
|
||||
"@types/leaflet": "1.9.18",
|
||||
"@types/leaflet-gpx": "1.3.7",
|
||||
"@types/react": "19.1.4",
|
||||
"@types/react-dom": "19.1.5",
|
||||
|
@ -283,6 +283,9 @@ export type CommandMappings = {
|
||||
type EventMappings = {
|
||||
initialRenderComplete: {};
|
||||
frocaReloaded: {};
|
||||
setLeftPaneVisibility: {
|
||||
leftPaneVisible: boolean | null;
|
||||
}
|
||||
protectedSessionStarted: {};
|
||||
notesReloaded: {
|
||||
noteIds: string[];
|
||||
|
@ -78,15 +78,15 @@ export default class RootCommandExecutor extends Component {
|
||||
}
|
||||
|
||||
hideLeftPaneCommand() {
|
||||
options.save(`leftPaneVisible`, "false");
|
||||
appContext.triggerEvent("setLeftPaneVisibility", { leftPaneVisible: false });
|
||||
}
|
||||
|
||||
showLeftPaneCommand() {
|
||||
options.save(`leftPaneVisible`, "true");
|
||||
appContext.triggerEvent("setLeftPaneVisibility", { leftPaneVisible: true });
|
||||
}
|
||||
|
||||
toggleLeftPaneCommand() {
|
||||
options.toggle("leftPaneVisible");
|
||||
appContext.triggerEvent("setLeftPaneVisibility", { leftPaneVisible: null });
|
||||
}
|
||||
|
||||
async showBackendLogCommand() {
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* highlight.js terraform syntax highlighting definition
|
||||
*
|
||||
* @see https://github.com/highlightjs/highlight.js
|
||||
*
|
||||
* :TODO:
|
||||
*
|
||||
* @package: highlightjs-terraform
|
||||
* @author: Nikos Tsirmirakis <nikos.tsirmirakis@winopsdba.com>
|
||||
* @since: 2019-03-20
|
||||
*
|
||||
* Description: Terraform (HCL) language definition
|
||||
* Category: scripting
|
||||
*/
|
||||
|
||||
var module = module ? module : {}; // shim for browser use
|
||||
|
||||
function hljsDefineTerraform(hljs) {
|
||||
var NUMBERS = {
|
||||
className: 'number',
|
||||
begin: '\\b\\d+(\\.\\d+)?',
|
||||
relevance: 0
|
||||
};
|
||||
var STRINGS = {
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"',
|
||||
contains: [{
|
||||
className: 'variable',
|
||||
begin: '\\${',
|
||||
end: '\\}',
|
||||
relevance: 9,
|
||||
contains: [{
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"'
|
||||
}, {
|
||||
className: 'meta',
|
||||
begin: '[A-Za-z_0-9]*' + '\\(',
|
||||
end: '\\)',
|
||||
contains: [
|
||||
NUMBERS, {
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"',
|
||||
contains: [{
|
||||
className: 'variable',
|
||||
begin: '\\${',
|
||||
end: '\\}',
|
||||
contains: [{
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"',
|
||||
contains: [{
|
||||
className: 'variable',
|
||||
begin: '\\${',
|
||||
end: '\\}'
|
||||
}]
|
||||
}, {
|
||||
className: 'meta',
|
||||
begin: '[A-Za-z_0-9]*' + '\\(',
|
||||
end: '\\)'
|
||||
}]
|
||||
}]
|
||||
},
|
||||
'self']
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
return {
|
||||
aliases: ['tf', 'hcl'],
|
||||
keywords: 'resource variable provider output locals module data terraform|10',
|
||||
literal: 'false true null',
|
||||
contains: [
|
||||
hljs.COMMENT('\\#', '$'),
|
||||
NUMBERS,
|
||||
STRINGS
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
hljs.registerLanguage('terraform', hljsDefineTerraform);
|
@ -12,10 +12,10 @@ import FAttachment from "../entities/fattachment.js";
|
||||
import imageContextMenuService from "../menus/image_context_menu.js";
|
||||
import { applySingleBlockSyntaxHighlight, applySyntaxHighlight } from "./syntax_highlight.js";
|
||||
import { loadElkIfNeeded, postprocessMermaidSvg } from "./mermaid.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js";
|
||||
import renderDoc from "./doc_renderer.js";
|
||||
import { t } from "../services/i18n.js";
|
||||
import WheelZoom from 'vanilla-js-wheel-zoom';
|
||||
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
|
||||
|
||||
let idCounter = 1;
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
import mimeTypesService from "./mime_types.js";
|
||||
import optionsService from "./options.js";
|
||||
import { getStylesheetUrl } from "./syntax_highlight.js";
|
||||
|
||||
export interface Library {
|
||||
js?: string[] | (() => string[]);
|
||||
css?: string[];
|
||||
@ -12,32 +8,6 @@ const KATEX: Library = {
|
||||
css: ["node_modules/katex/dist/katex.min.css"]
|
||||
};
|
||||
|
||||
const HIGHLIGHT_JS: Library = {
|
||||
js: () => {
|
||||
const mimeTypes = mimeTypesService.getMimeTypes();
|
||||
const scriptsToLoad = new Set<string>();
|
||||
scriptsToLoad.add("node_modules/@highlightjs/cdn-assets/highlight.min.js");
|
||||
for (const mimeType of mimeTypes) {
|
||||
const id = mimeType.highlightJs;
|
||||
if (!mimeType.enabled || !id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mimeType.highlightJsSource === "libraries") {
|
||||
scriptsToLoad.add(`libraries/highlightjs/${id}.js`);
|
||||
} else {
|
||||
// Built-in module.
|
||||
scriptsToLoad.add(`node_modules/@highlightjs/cdn-assets/languages/${id}.min.js`);
|
||||
}
|
||||
}
|
||||
|
||||
const currentTheme = String(optionsService.get("codeBlockTheme"));
|
||||
loadHighlightingTheme(currentTheme);
|
||||
|
||||
return Array.from(scriptsToLoad);
|
||||
}
|
||||
};
|
||||
|
||||
async function requireLibrary(library: Library) {
|
||||
if (library.css) {
|
||||
library.css.map((cssUrl) => requireCss(cssUrl));
|
||||
@ -91,36 +61,8 @@ async function requireCss(url: string, prependAssetPath = true) {
|
||||
}
|
||||
}
|
||||
|
||||
let highlightingThemeEl: JQuery<HTMLElement> | null = null;
|
||||
function loadHighlightingTheme(theme: string) {
|
||||
if (!theme) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (theme === "none") {
|
||||
// Deactivate the theme.
|
||||
if (highlightingThemeEl) {
|
||||
highlightingThemeEl.remove();
|
||||
highlightingThemeEl = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!highlightingThemeEl) {
|
||||
highlightingThemeEl = $(`<link rel="stylesheet" type="text/css" />`);
|
||||
$("head").append(highlightingThemeEl);
|
||||
}
|
||||
|
||||
const url = getStylesheetUrl(theme);
|
||||
if (url) {
|
||||
highlightingThemeEl.attr("href", url);
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
requireCss,
|
||||
requireLibrary,
|
||||
loadHighlightingTheme,
|
||||
KATEX,
|
||||
HIGHLIGHT_JS
|
||||
KATEX
|
||||
};
|
||||
|
@ -1,223 +0,0 @@
|
||||
// TODO: deduplicate with /src/services/import/mime_type_definitions.ts
|
||||
|
||||
/**
|
||||
* A pseudo-MIME type which is used in the editor to automatically determine the language used in code blocks via heuristics.
|
||||
*/
|
||||
export const MIME_TYPE_AUTO = "text-x-trilium-auto";
|
||||
|
||||
export interface MimeTypeDefinition {
|
||||
default?: boolean;
|
||||
title: string;
|
||||
mime: string;
|
||||
/** The name of the language/mime type as defined by highlight.js (or one of the aliases), in order to be used for syntax highlighting such as inside code blocks. */
|
||||
highlightJs?: string;
|
||||
/** If specified, will load the corresponding highlight.js file from the `libraries/highlightjs/${id}.js` instead of `node_modules/@highlightjs/cdn-assets/languages/${id}.min.js`. */
|
||||
highlightJsSource?: "libraries";
|
||||
/** If specified, will load the corresponding highlight file from the given path instead of `node_modules`. */
|
||||
codeMirrorSource?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* For highlight.js-supported languages, see https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md.
|
||||
*/
|
||||
|
||||
export const MIME_TYPES_DICT: readonly MimeTypeDefinition[] = Object.freeze([
|
||||
{ title: "Plain text", mime: "text/plain", highlightJs: "plaintext", default: true },
|
||||
|
||||
// Keep sorted alphabetically.
|
||||
{ title: "APL", mime: "text/apl" },
|
||||
{ title: "ASN.1", mime: "text/x-ttcn-asn" },
|
||||
{ title: "ASP.NET", mime: "application/x-aspx" },
|
||||
{ title: "Asterisk", mime: "text/x-asterisk" },
|
||||
{ title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos", codeMirrorSource: "libraries/codemirror/batch.js" },
|
||||
{ title: "Brainfuck", mime: "text/x-brainfuck", highlightJs: "brainfuck" },
|
||||
{ title: "C", mime: "text/x-csrc", highlightJs: "c", default: true },
|
||||
{ title: "C#", mime: "text/x-csharp", highlightJs: "csharp", default: true },
|
||||
{ title: "C++", mime: "text/x-c++src", highlightJs: "cpp", default: true },
|
||||
{ title: "Clojure", mime: "text/x-clojure", highlightJs: "clojure" },
|
||||
{ title: "ClojureScript", mime: "text/x-clojurescript" },
|
||||
{ title: "Closure Stylesheets (GSS)", mime: "text/x-gss" },
|
||||
{ title: "CMake", mime: "text/x-cmake", highlightJs: "cmake" },
|
||||
{ title: "Cobol", mime: "text/x-cobol" },
|
||||
{ title: "CoffeeScript", mime: "text/coffeescript", highlightJs: "coffeescript" },
|
||||
{ title: "Common Lisp", mime: "text/x-common-lisp", highlightJs: "lisp" },
|
||||
{ title: "CQL", mime: "text/x-cassandra" },
|
||||
{ title: "Crystal", mime: "text/x-crystal", highlightJs: "crystal" },
|
||||
{ title: "CSS", mime: "text/css", highlightJs: "css", default: true },
|
||||
{ title: "Cypher", mime: "application/x-cypher-query" },
|
||||
{ title: "Cython", mime: "text/x-cython" },
|
||||
{ title: "D", mime: "text/x-d", highlightJs: "d" },
|
||||
{ title: "Dart", mime: "application/dart", highlightJs: "dart" },
|
||||
{ title: "diff", mime: "text/x-diff", highlightJs: "diff" },
|
||||
{ title: "Django", mime: "text/x-django", highlightJs: "django" },
|
||||
{ title: "Dockerfile", mime: "text/x-dockerfile", highlightJs: "dockerfile" },
|
||||
{ title: "DTD", mime: "application/xml-dtd" },
|
||||
{ title: "Dylan", mime: "text/x-dylan" },
|
||||
{ title: "EBNF", mime: "text/x-ebnf", highlightJs: "ebnf" },
|
||||
{ title: "ECL", mime: "text/x-ecl" },
|
||||
{ title: "edn", mime: "application/edn" },
|
||||
{ title: "Eiffel", mime: "text/x-eiffel" },
|
||||
{ title: "Elm", mime: "text/x-elm", highlightJs: "elm" },
|
||||
{ title: "Embedded Javascript", mime: "application/x-ejs" },
|
||||
{ title: "Embedded Ruby", mime: "application/x-erb", highlightJs: "erb" },
|
||||
{ title: "Erlang", mime: "text/x-erlang", highlightJs: "erlang" },
|
||||
{ title: "Esper", mime: "text/x-esper" },
|
||||
{ title: "F#", mime: "text/x-fsharp", highlightJs: "fsharp" },
|
||||
{ title: "Factor", mime: "text/x-factor" },
|
||||
{ title: "FCL", mime: "text/x-fcl" },
|
||||
{ title: "Forth", mime: "text/x-forth" },
|
||||
{ title: "Fortran", mime: "text/x-fortran", highlightJs: "fortran" },
|
||||
{ title: "Gas", mime: "text/x-gas" },
|
||||
{ title: "GDScript (Godot)", mime: "text/x-gdscript" },
|
||||
{ title: "Gherkin", mime: "text/x-feature", highlightJs: "gherkin" },
|
||||
{ title: "GitHub Flavored Markdown", mime: "text/x-gfm", highlightJs: "markdown" },
|
||||
{ title: "Go", mime: "text/x-go", highlightJs: "go", default: true },
|
||||
{ title: "Groovy", mime: "text/x-groovy", highlightJs: "groovy", default: true },
|
||||
{ title: "HAML", mime: "text/x-haml", highlightJs: "haml" },
|
||||
{ title: "Haskell (Literate)", mime: "text/x-literate-haskell" },
|
||||
{ title: "Haskell", mime: "text/x-haskell", highlightJs: "haskell", default: true },
|
||||
{ title: "Haxe", mime: "text/x-haxe", highlightJs: "haxe" },
|
||||
{ title: "HTML", mime: "text/html", highlightJs: "xml", default: true },
|
||||
{ title: "HTTP", mime: "message/http", highlightJs: "http", default: true },
|
||||
{ title: "HXML", mime: "text/x-hxml" },
|
||||
{ title: "IDL", mime: "text/x-idl" },
|
||||
{ title: "Java Server Pages", mime: "application/x-jsp", highlightJs: "java" },
|
||||
{ title: "Java", mime: "text/x-java", highlightJs: "java", default: true },
|
||||
{ title: "Jinja2", mime: "text/jinja2" },
|
||||
{ title: "JS backend", mime: "application/javascript;env=backend", highlightJs: "javascript", default: true },
|
||||
{ title: "JS frontend", mime: "application/javascript;env=frontend", highlightJs: "javascript", default: true },
|
||||
{ title: "JSON-LD", mime: "application/ld+json", highlightJs: "json" },
|
||||
{ title: "JSON", mime: "application/json", highlightJs: "json", default: true },
|
||||
{ title: "JSX", mime: "text/jsx", highlightJs: "javascript" },
|
||||
{ title: "Julia", mime: "text/x-julia", highlightJs: "julia" },
|
||||
{ title: "Kotlin", mime: "text/x-kotlin", highlightJs: "kotlin", default: true },
|
||||
{ title: "LaTeX", mime: "text/x-latex", highlightJs: "latex" },
|
||||
{ title: "LESS", mime: "text/x-less", highlightJs: "less" },
|
||||
{ title: "LiveScript", mime: "text/x-livescript", highlightJs: "livescript" },
|
||||
{ title: "Lua", mime: "text/x-lua", highlightJs: "lua" },
|
||||
{ title: "MariaDB SQL", mime: "text/x-mariadb", highlightJs: "sql" },
|
||||
{ title: "Markdown", mime: "text/x-markdown", highlightJs: "markdown", default: true },
|
||||
{ title: "Mathematica", mime: "text/x-mathematica", highlightJs: "mathematica" },
|
||||
{ title: "mbox", mime: "application/mbox" },
|
||||
{ title: "MIPS Assembler", mime: "text/x-asm-mips", highlightJs: "mipsasm" },
|
||||
{ title: "mIRC", mime: "text/mirc" },
|
||||
{ title: "Modelica", mime: "text/x-modelica" },
|
||||
{ title: "MS SQL", mime: "text/x-mssql", highlightJs: "sql" },
|
||||
{ title: "mscgen", mime: "text/x-mscgen" },
|
||||
{ title: "msgenny", mime: "text/x-msgenny" },
|
||||
{ title: "MUMPS", mime: "text/x-mumps" },
|
||||
{ title: "MySQL", mime: "text/x-mysql", highlightJs: "sql" },
|
||||
{ title: "Nix", mime: "text/x-nix", highlightJs: "nix" },
|
||||
{ title: "Nginx", mime: "text/x-nginx-conf", highlightJs: "nginx" },
|
||||
{ title: "NSIS", mime: "text/x-nsis", highlightJs: "nsis" },
|
||||
{ title: "NTriples", mime: "application/n-triples" },
|
||||
{ title: "Objective-C", mime: "text/x-objectivec", highlightJs: "objectivec" },
|
||||
{ title: "OCaml", mime: "text/x-ocaml", highlightJs: "ocaml" },
|
||||
{ title: "Octave", mime: "text/x-octave" },
|
||||
{ title: "Oz", mime: "text/x-oz" },
|
||||
{ title: "Pascal", mime: "text/x-pascal", highlightJs: "delphi" },
|
||||
{ title: "PEG.js", mime: "null" },
|
||||
{ title: "Perl", mime: "text/x-perl", default: true },
|
||||
{ title: "PGP", mime: "application/pgp" },
|
||||
{ title: "PHP", mime: "text/x-php", default: true, highlightJs: "php" },
|
||||
{ title: "Pig", mime: "text/x-pig" },
|
||||
{ title: "PLSQL", mime: "text/x-plsql", highlightJs: "sql" },
|
||||
{ title: "PostgreSQL", mime: "text/x-pgsql", highlightJs: "pgsql" },
|
||||
{ title: "PowerShell", mime: "application/x-powershell", highlightJs: "powershell" },
|
||||
{ title: "Properties files", mime: "text/x-properties", highlightJs: "properties" },
|
||||
{ title: "ProtoBuf", mime: "text/x-protobuf", highlightJs: "protobuf" },
|
||||
{ title: "Pug", mime: "text/x-pug" },
|
||||
{ title: "Puppet", mime: "text/x-puppet", highlightJs: "puppet" },
|
||||
{ title: "Python", mime: "text/x-python", highlightJs: "python", default: true },
|
||||
{ title: "Q", mime: "text/x-q", highlightJs: "q" },
|
||||
{ title: "R", mime: "text/x-rsrc", highlightJs: "r" },
|
||||
{ title: "reStructuredText", mime: "text/x-rst" },
|
||||
{ title: "RPM Changes", mime: "text/x-rpm-changes" },
|
||||
{ title: "RPM Spec", mime: "text/x-rpm-spec" },
|
||||
{ title: "Ruby", mime: "text/x-ruby", highlightJs: "ruby", default: true },
|
||||
{ title: "Rust", mime: "text/x-rustsrc", highlightJs: "rust" },
|
||||
{ title: "SAS", mime: "text/x-sas", highlightJs: "sas" },
|
||||
{ title: "Sass", mime: "text/x-sass", highlightJs: "scss" },
|
||||
{ title: "Scala", mime: "text/x-scala" },
|
||||
{ title: "Scheme", mime: "text/x-scheme" },
|
||||
{ title: "SCSS", mime: "text/x-scss", highlightJs: "scss" },
|
||||
{ title: "Shell (bash)", mime: "text/x-sh", highlightJs: "bash", default: true },
|
||||
{ title: "Sieve", mime: "application/sieve" },
|
||||
{ title: "Slim", mime: "text/x-slim" },
|
||||
{ title: "Smalltalk", mime: "text/x-stsrc", highlightJs: "smalltalk" },
|
||||
{ title: "Smarty", mime: "text/x-smarty" },
|
||||
{ title: "SML", mime: "text/x-sml", highlightJs: "sml" },
|
||||
{ title: "Solr", mime: "text/x-solr" },
|
||||
{ title: "Soy", mime: "text/x-soy" },
|
||||
{ title: "SPARQL", mime: "application/sparql-query" },
|
||||
{ title: "Spreadsheet", mime: "text/x-spreadsheet" },
|
||||
{ title: "SQL", mime: "text/x-sql", highlightJs: "sql", default: true },
|
||||
{ title: "SQLite (Trilium)", mime: "text/x-sqlite;schema=trilium", highlightJs: "sql", default: true },
|
||||
{ title: "SQLite", mime: "text/x-sqlite", highlightJs: "sql" },
|
||||
{ title: "Squirrel", mime: "text/x-squirrel" },
|
||||
{ title: "sTeX", mime: "text/x-stex" },
|
||||
{ title: "Stylus", mime: "text/x-styl", highlightJs: "stylus" },
|
||||
{ title: "Swift", mime: "text/x-swift", default: true },
|
||||
{ title: "SystemVerilog", mime: "text/x-systemverilog" },
|
||||
{ title: "Tcl", mime: "text/x-tcl", highlightJs: "tcl" },
|
||||
{ title: "Terraform (HCL)", mime: "text/x-hcl", highlightJs: "terraform", highlightJsSource: "libraries", codeMirrorSource: "libraries/codemirror/hcl.js" },
|
||||
{ title: "Textile", mime: "text/x-textile" },
|
||||
{ title: "TiddlyWiki ", mime: "text/x-tiddlywiki" },
|
||||
{ title: "Tiki wiki", mime: "text/tiki" },
|
||||
{ title: "TOML", mime: "text/x-toml", highlightJs: "ini" },
|
||||
{ title: "Tornado", mime: "text/x-tornado" },
|
||||
{ title: "troff", mime: "text/troff" },
|
||||
{ title: "TTCN_CFG", mime: "text/x-ttcn-cfg" },
|
||||
{ title: "TTCN", mime: "text/x-ttcn" },
|
||||
{ title: "Turtle", mime: "text/turtle" },
|
||||
{ title: "Twig", mime: "text/x-twig", highlightJs: "twig" },
|
||||
{ title: "TypeScript-JSX", mime: "text/typescript-jsx", highlightJs: "typescript" },
|
||||
{ title: "TypeScript", mime: "application/typescript", highlightJs: "typescript" },
|
||||
{ title: "VB.NET", mime: "text/x-vb", highlightJs: "vbnet" },
|
||||
{ title: "VBScript", mime: "text/vbscript", highlightJs: "vbscript" },
|
||||
{ title: "Velocity", mime: "text/velocity" },
|
||||
{ title: "Verilog", mime: "text/x-verilog", highlightJs: "verilog" },
|
||||
{ title: "VHDL", mime: "text/x-vhdl", highlightJs: "vhdl" },
|
||||
{ title: "Vue.js Component", mime: "text/x-vue" },
|
||||
{ title: "Web IDL", mime: "text/x-webidl" },
|
||||
{ title: "XML", mime: "text/xml", highlightJs: "xml", default: true },
|
||||
{ title: "XQuery", mime: "application/xquery", highlightJs: "xquery" },
|
||||
{ title: "xu", mime: "text/x-xu" },
|
||||
{ title: "Yacas", mime: "text/x-yacas" },
|
||||
{ title: "YAML", mime: "text/x-yaml", highlightJs: "yaml", default: true },
|
||||
{ title: "Z80", mime: "text/x-z80" }
|
||||
]);
|
||||
|
||||
/**
|
||||
* Given a MIME type in the usual format (e.g. `text/csrc`), it returns a MIME type that can be passed down to the CKEditor
|
||||
* code plugin.
|
||||
*
|
||||
* @param mimeType The MIME type to normalize, in the usual format (e.g. `text/c-src`).
|
||||
* @returns the normalized MIME type (e.g. `text-c-src`).
|
||||
*/
|
||||
export function normalizeMimeTypeForCKEditor(mimeType: string) {
|
||||
return mimeType.toLowerCase().replace(/[\W_]+/g, "-");
|
||||
}
|
||||
|
||||
let byHighlightJsNameMappings: Record<string, MimeTypeDefinition> | null = null;
|
||||
|
||||
/**
|
||||
* Given a Highlight.js language tag (e.g. `css`), it returns a corresponding {@link MimeTypeDefinition} if found.
|
||||
*
|
||||
* If there are multiple {@link MimeTypeDefinition}s for the language tag, then only the first one is retrieved. For example for `javascript`, the "JS frontend" mime type is returned.
|
||||
*
|
||||
* @param highlightJsName a language tag.
|
||||
* @returns the corresponding {@link MimeTypeDefinition} if found, or `undefined` otherwise.
|
||||
*/
|
||||
export function getMimeTypeFromHighlightJs(highlightJsName: string) {
|
||||
if (!byHighlightJsNameMappings) {
|
||||
byHighlightJsNameMappings = {};
|
||||
for (const mimeType of MIME_TYPES_DICT) {
|
||||
if (mimeType.highlightJs && !byHighlightJsNameMappings[mimeType.highlightJs]) {
|
||||
byHighlightJsNameMappings[mimeType.highlightJs] = mimeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return byHighlightJsNameMappings[highlightJsName];
|
||||
}
|
@ -1,13 +1,6 @@
|
||||
import { MIME_TYPE_AUTO, MIME_TYPES_DICT, normalizeMimeTypeForCKEditor, type MimeTypeDefinition } from "./mime_type_definitions.js";
|
||||
import { normalizeMimeTypeForCKEditor, type MimeType, MIME_TYPE_AUTO, MIME_TYPES_DICT } from "@triliumnext/commons";
|
||||
import options from "./options.js";
|
||||
|
||||
interface MimeType extends MimeTypeDefinition {
|
||||
/**
|
||||
* True if this mime type was enabled by the user in the "Available MIME types in the dropdown" option in the Code Notes settings.
|
||||
*/
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
let mimeTypes: MimeType[] | null = null;
|
||||
|
||||
function loadMimeTypes() {
|
||||
@ -45,8 +38,8 @@ export function getHighlightJsNameForMime(mimeType: string) {
|
||||
for (const mimeType of mimeTypes) {
|
||||
// The mime stored by CKEditor is text-x-csrc instead of text/x-csrc so we keep this format for faster lookup.
|
||||
const normalizedMime = normalizeMimeTypeForCKEditor(mimeType.mime);
|
||||
if (mimeType.highlightJs) {
|
||||
mimeToHighlightJsMapping[normalizedMime] = mimeType.highlightJs;
|
||||
if (mimeType.mdLanguageCode) {
|
||||
mimeToHighlightJsMapping[normalizedMime] = mimeType.mdLanguageCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,11 @@ import Split from "split.js"
|
||||
|
||||
export const DEFAULT_GUTTER_SIZE = 5;
|
||||
|
||||
let leftPaneWidth: number;
|
||||
let reservedPx: number;
|
||||
let layoutOrientation: string;
|
||||
let leftInstance: ReturnType<typeof Split> | null;
|
||||
let rightPaneWidth: number;
|
||||
let rightInstance: ReturnType<typeof Split> | null;
|
||||
|
||||
function setupLeftPaneResizer(leftPaneVisible: boolean) {
|
||||
@ -14,27 +18,34 @@ function setupLeftPaneResizer(leftPaneVisible: boolean) {
|
||||
|
||||
$("#left-pane").toggle(leftPaneVisible);
|
||||
|
||||
layoutOrientation = layoutOrientation ?? options.get("layoutOrientation");
|
||||
reservedPx = reservedPx ?? (layoutOrientation === "vertical" ? ($("#launcher-pane").outerWidth() || 0) : 0);
|
||||
// Window resizing causes `window.innerWidth` to change, so `reservedWidth` needs to be recalculated each time.
|
||||
const reservedWidth = reservedPx / window.innerWidth * 100;
|
||||
if (!leftPaneVisible) {
|
||||
$("#rest-pane").css("width", "100%");
|
||||
|
||||
$("#rest-pane").css("width", layoutOrientation === "vertical" ? `${100 - reservedWidth}%` : "100%");
|
||||
return;
|
||||
}
|
||||
|
||||
let leftPaneWidth = options.getInt("leftPaneWidth");
|
||||
leftPaneWidth = leftPaneWidth ?? (options.getInt("leftPaneWidth") ?? 0);
|
||||
if (!leftPaneWidth || leftPaneWidth < 5) {
|
||||
leftPaneWidth = 5;
|
||||
}
|
||||
|
||||
const restPaneWidth = 100 - leftPaneWidth - reservedWidth;
|
||||
if (leftPaneVisible) {
|
||||
// Delayed initialization ensures that all DOM elements are fully rendered and part of the layout,
|
||||
// preventing Split.js from retrieving incorrect dimensions due to #left-pane not being rendered yet,
|
||||
// which would cause the minSize setting to have no effect.
|
||||
requestAnimationFrame(() => {
|
||||
leftInstance = Split(["#left-pane", "#rest-pane"], {
|
||||
sizes: [leftPaneWidth, 100 - leftPaneWidth],
|
||||
sizes: [leftPaneWidth, restPaneWidth],
|
||||
gutterSize: DEFAULT_GUTTER_SIZE,
|
||||
minSize: [150, 300],
|
||||
onDragEnd: (sizes) => options.save("leftPaneWidth", Math.round(sizes[0]))
|
||||
onDragEnd: (sizes) => {
|
||||
leftPaneWidth = Math.round(sizes[0]);
|
||||
options.save("leftPaneWidth", Math.round(sizes[0]));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -54,7 +65,7 @@ function setupRightPaneResizer() {
|
||||
return;
|
||||
}
|
||||
|
||||
let rightPaneWidth = options.getInt("rightPaneWidth");
|
||||
rightPaneWidth = rightPaneWidth ?? (options.getInt("rightPaneWidth") ?? 0);
|
||||
if (!rightPaneWidth || rightPaneWidth < 5) {
|
||||
rightPaneWidth = 5;
|
||||
}
|
||||
@ -63,8 +74,11 @@ function setupRightPaneResizer() {
|
||||
rightInstance = Split(["#center-pane", "#right-pane"], {
|
||||
sizes: [100 - rightPaneWidth, rightPaneWidth],
|
||||
gutterSize: DEFAULT_GUTTER_SIZE,
|
||||
minSize: [ 300, 180 ],
|
||||
onDragEnd: (sizes) => options.save("rightPaneWidth", Math.round(sizes[1]))
|
||||
minSize: [300, 180],
|
||||
onDragEnd: (sizes) => {
|
||||
rightPaneWidth = Math.round(sizes[1]);
|
||||
options.save("rightPaneWidth", Math.round(sizes[1]));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,8 @@
|
||||
import library_loader from "./library_loader.js";
|
||||
import { ensureMimeTypes, highlight, highlightAuto, loadTheme, Themes } from "@triliumnext/highlightjs";
|
||||
import mime_types from "./mime_types.js";
|
||||
import options from "./options.js";
|
||||
|
||||
export function getStylesheetUrl(theme: string) {
|
||||
if (!theme) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const defaultPrefix = "default:";
|
||||
if (theme.startsWith(defaultPrefix)) {
|
||||
return `${window.glob.assetPath}/node_modules/@highlightjs/cdn-assets/styles/${theme.substr(defaultPrefix.length)}.min.css`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
let highlightingLoaded = false;
|
||||
|
||||
/**
|
||||
* Identifies all the code blocks (as `pre code`) under the specified hierarchy and uses the highlight.js library to obtain the highlighted text which is then applied on to the code blocks.
|
||||
@ -25,6 +14,8 @@ export async function applySyntaxHighlight($container: JQuery<HTMLElement>) {
|
||||
return;
|
||||
}
|
||||
|
||||
await ensureMimeTypesForHighlighting();
|
||||
|
||||
const codeBlocks = $container.find("pre code");
|
||||
for (const codeBlock of codeBlocks) {
|
||||
const normalizedMimeType = extractLanguageFromClassList(codeBlock);
|
||||
@ -43,20 +34,13 @@ export async function applySingleBlockSyntaxHighlight($codeBlock: JQuery<HTMLEle
|
||||
$codeBlock.parent().toggleClass("hljs");
|
||||
const text = $codeBlock.text();
|
||||
|
||||
if (!window.hljs) {
|
||||
await library_loader.requireLibrary(library_loader.HIGHLIGHT_JS);
|
||||
}
|
||||
|
||||
let highlightedText = null;
|
||||
if (normalizedMimeType === mime_types.MIME_TYPE_AUTO) {
|
||||
highlightedText = hljs.highlightAuto(text);
|
||||
await ensureMimeTypesForHighlighting();
|
||||
highlightedText = highlightAuto(text);
|
||||
} else if (normalizedMimeType) {
|
||||
const language = mime_types.getHighlightJsNameForMime(normalizedMimeType);
|
||||
if (language) {
|
||||
highlightedText = hljs.highlight(text, { language });
|
||||
} else {
|
||||
console.warn(`Unknown mime type: ${normalizedMimeType}.`);
|
||||
}
|
||||
await ensureMimeTypesForHighlighting();
|
||||
highlightedText = highlight(text, { language: normalizedMimeType });
|
||||
}
|
||||
|
||||
if (highlightedText) {
|
||||
@ -64,6 +48,35 @@ export async function applySingleBlockSyntaxHighlight($codeBlock: JQuery<HTMLEle
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureMimeTypesForHighlighting() {
|
||||
if (highlightingLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load theme.
|
||||
const currentThemeName = String(options.get("codeBlockTheme"));
|
||||
loadHighlightingTheme(currentThemeName);
|
||||
|
||||
// Load mime types.
|
||||
const mimeTypes = mime_types.getMimeTypes();
|
||||
await ensureMimeTypes(mimeTypes);
|
||||
|
||||
highlightingLoaded = true;
|
||||
}
|
||||
|
||||
export function loadHighlightingTheme(themeName: string) {
|
||||
const themePrefix = "default:";
|
||||
let theme = null;
|
||||
if (themeName.includes(themePrefix)) {
|
||||
theme = Themes[themeName.substring(themePrefix.length)];
|
||||
}
|
||||
if (!theme) {
|
||||
theme = Themes.default;
|
||||
}
|
||||
|
||||
loadTheme(theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether syntax highlighting should be enabled for code blocks, by querying the value of the `codeblockTheme` option.
|
||||
* @returns whether syntax highlighting should be enabled for code blocks.
|
||||
|
@ -127,6 +127,7 @@ body.layout-horizontal > .horizontal {
|
||||
--launcher-pane-button-gap: var(--launcher-pane-vert-button-gap);
|
||||
|
||||
width: var(--launcher-pane-size) !important;
|
||||
min-width: var(--launcher-pane-size) !important;
|
||||
padding-bottom: var(--launcher-pane-button-gap);
|
||||
}
|
||||
|
||||
|
@ -1621,7 +1621,10 @@
|
||||
"color-scheme": "颜色方案"
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "自动换行"
|
||||
"word_wrapping": "自动换行",
|
||||
"theme_none": "无语法高亮",
|
||||
"theme_group_light": "浅色主题",
|
||||
"theme_group_dark": "深色主题"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "格式化"
|
||||
|
@ -1573,7 +1573,10 @@
|
||||
"color-scheme": "Farbschema"
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "Wortumbruch"
|
||||
"word_wrapping": "Wortumbruch",
|
||||
"theme_none": "Keine Syntax-Hervorhebung",
|
||||
"theme_group_light": "Helle Themen",
|
||||
"theme_group_dark": "Dunkle Themen"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "Format"
|
||||
|
@ -1827,7 +1827,10 @@
|
||||
"color-scheme": "Color Scheme"
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "Word wrapping"
|
||||
"word_wrapping": "Word wrapping",
|
||||
"theme_none": "No syntax highlighting",
|
||||
"theme_group_light": "Light themes",
|
||||
"theme_group_dark": "Dark themes"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "Formatting"
|
||||
|
@ -1589,7 +1589,10 @@
|
||||
"color-scheme": "Esquema de color"
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "Ajuste de palabras"
|
||||
"word_wrapping": "Ajuste de palabras",
|
||||
"theme_none": "Sin resaltado de sintaxis",
|
||||
"theme_group_light": "Temas claros",
|
||||
"theme_group_dark": "Temas oscuros"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "Formato"
|
||||
|
@ -1579,7 +1579,10 @@
|
||||
"color-scheme": "Jeu de couleurs"
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "Saut à la ligne automatique suivant la largeur"
|
||||
"word_wrapping": "Saut à la ligne automatique suivant la largeur",
|
||||
"theme_none": "Pas de coloration syntaxique",
|
||||
"theme_group_light": "Thèmes clairs",
|
||||
"theme_group_dark": "Thèmes sombres"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "Mise en forme"
|
||||
|
@ -1,5 +1,10 @@
|
||||
{
|
||||
"revisions": {
|
||||
"delete_button": ""
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "Sem destaque de sintaxe",
|
||||
"theme_group_light": "Temas claros",
|
||||
"theme_group_dark": "Temas escuros"
|
||||
}
|
||||
}
|
||||
|
@ -1585,7 +1585,10 @@
|
||||
"description": "Controlează evidențierea de sintaxă pentru blocurile de cod în interiorul notițelor text, notițele de tip cod nu vor fi afectate de aceste setări."
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "Încadrare text"
|
||||
"word_wrapping": "Încadrare text",
|
||||
"theme_none": "Fără evidențiere de sintaxă",
|
||||
"theme_group_dark": "Teme întunecate",
|
||||
"theme_group_light": "Teme luminoase"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "Formatare"
|
||||
|
@ -1519,7 +1519,10 @@
|
||||
"color-scheme": "顏色方案"
|
||||
},
|
||||
"code_block": {
|
||||
"word_wrapping": "自動換行"
|
||||
"word_wrapping": "自動換行",
|
||||
"theme_none": "無格式高亮",
|
||||
"theme_group_light": "淺色主題",
|
||||
"theme_group_dark": "深色主題"
|
||||
},
|
||||
"classic_editor_toolbar": {
|
||||
"title": "格式化"
|
||||
|
7
apps/client/src/types.d.ts
vendored
7
apps/client/src/types.d.ts
vendored
@ -124,13 +124,6 @@ declare global {
|
||||
var __non_webpack_require__: RequireMethod | undefined;
|
||||
|
||||
// Libraries
|
||||
// TODO: Replace once library loader is replaced with webpack.
|
||||
var hljs: {
|
||||
highlightAuto(text: string);
|
||||
highlight(text: string, {
|
||||
language: string
|
||||
});
|
||||
};
|
||||
var renderMathInElement: (element: HTMLElement, options: {
|
||||
trust: boolean;
|
||||
}) => void;
|
||||
|
@ -53,10 +53,6 @@ const TPL = /*html*/`
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.update-to-latest-version-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.global-menu .zoom-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
@ -235,7 +231,7 @@ const TPL = /*html*/`
|
||||
${t("global_menu.about")}
|
||||
</li>
|
||||
|
||||
<li class="dropdown-item update-to-latest-version-button" data-trigger-command="downloadLatestVersion">
|
||||
<li class="dropdown-item update-to-latest-version-button" style="display: none;" data-trigger-command="downloadLatestVersion">
|
||||
<span class="bx bx-sync"></span>
|
||||
|
||||
<span class="version-text"></span>
|
||||
|
@ -19,10 +19,10 @@ export default class LeftPaneToggleWidget extends CommandButtonWidget {
|
||||
return "bx-sidebar";
|
||||
}
|
||||
|
||||
return options.is("leftPaneVisible") ? "bx-chevrons-left" : "bx-chevrons-right";
|
||||
return this.currentLeftPaneVisible ? "bx-chevrons-left" : "bx-chevrons-right";
|
||||
};
|
||||
|
||||
this.settings.title = () => (options.is("leftPaneVisible") ? t("left_pane_toggle.hide_panel") : t("left_pane_toggle.show_panel"));
|
||||
this.settings.title = () => (this.currentLeftPaneVisible ? t("left_pane_toggle.hide_panel") : t("left_pane_toggle.show_panel"));
|
||||
|
||||
this.settings.command = () => (this.currentLeftPaneVisible ? "hideLeftPane" : "showLeftPane");
|
||||
|
||||
@ -32,16 +32,12 @@ export default class LeftPaneToggleWidget extends CommandButtonWidget {
|
||||
}
|
||||
|
||||
refreshIcon() {
|
||||
if (document.hasFocus() || this.currentLeftPaneVisible === true) {
|
||||
super.refreshIcon();
|
||||
splitService.setupLeftPaneResizer(this.currentLeftPaneVisible);
|
||||
}
|
||||
super.refreshIcon();
|
||||
splitService.setupLeftPaneResizer(this.currentLeftPaneVisible);
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||
if (loadResults.isOptionReloaded("leftPaneVisible") && document.hasFocus()) {
|
||||
this.currentLeftPaneVisible = options.is("leftPaneVisible");
|
||||
this.refreshIcon();
|
||||
}
|
||||
|
||||
setLeftPaneVisibilityEvent({ leftPaneVisible }: EventData<"setLeftPaneVisibility">) {
|
||||
this.currentLeftPaneVisible = leftPaneVisible ?? !this.currentLeftPaneVisible;
|
||||
this.refreshIcon();
|
||||
}
|
||||
}
|
||||
|
@ -4,28 +4,33 @@ import appContext, { type EventData } from "../../components/app_context.js";
|
||||
import type Component from "../../components/component.js";
|
||||
|
||||
export default class LeftPaneContainer extends FlexContainer<Component> {
|
||||
private currentLeftPaneVisible: boolean;
|
||||
|
||||
constructor() {
|
||||
super("column");
|
||||
|
||||
this.currentLeftPaneVisible = options.is("leftPaneVisible");
|
||||
|
||||
this.id("left-pane");
|
||||
this.css("height", "100%");
|
||||
this.collapsible();
|
||||
}
|
||||
|
||||
isEnabled() {
|
||||
return super.isEnabled() && options.is("leftPaneVisible");
|
||||
return super.isEnabled() && this.currentLeftPaneVisible;
|
||||
}
|
||||
|
||||
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
|
||||
if (loadResults.isOptionReloaded("leftPaneVisible") && document.hasFocus()) {
|
||||
const visible = this.isEnabled();
|
||||
this.toggleInt(visible);
|
||||
setLeftPaneVisibilityEvent({ leftPaneVisible }: EventData<"setLeftPaneVisibility">) {
|
||||
this.currentLeftPaneVisible = leftPaneVisible ?? !this.currentLeftPaneVisible;
|
||||
const visible = this.isEnabled();
|
||||
this.toggleInt(visible);
|
||||
|
||||
if (visible) {
|
||||
this.triggerEvent("focusTree", {});
|
||||
} else {
|
||||
this.triggerEvent("focusOnDetail", { ntxId: appContext.tabManager.getActiveContext()?.ntxId });
|
||||
}
|
||||
if (visible) {
|
||||
this.triggerEvent("focusTree", {});
|
||||
} else {
|
||||
this.triggerEvent("focusOnDetail", { ntxId: appContext.tabManager.getActiveContext()?.ntxId });
|
||||
}
|
||||
|
||||
options.save("leftPaneVisible", this.currentLeftPaneVisible.toString());
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,10 @@ import NoteContextAwareWidget from "./note_context_aware_widget.js";
|
||||
import protectedSessionHolder from "../services/protected_session_holder.js";
|
||||
import SpacedUpdate from "../services/spaced_update.js";
|
||||
import server from "../services/server.js";
|
||||
import libraryLoader from "../services/library_loader.js";
|
||||
import appContext, { type CommandListenerData, type EventData } from "../components/app_context.js";
|
||||
import keyboardActionsService from "../services/keyboard_actions.js";
|
||||
import noteCreateService from "../services/note_create.js";
|
||||
import attributeService from "../services/attributes.js";
|
||||
import attributeRenderer from "../services/attribute_renderer.js";
|
||||
|
||||
import EmptyTypeWidget from "./type_widgets/empty.js";
|
||||
import EditableTextTypeWidget from "./type_widgets/editable_text.js";
|
||||
@ -30,7 +28,6 @@ import ContentWidgetTypeWidget from "./type_widgets/content_widget.js";
|
||||
import AttachmentListTypeWidget from "./type_widgets/attachment_list.js";
|
||||
import AttachmentDetailTypeWidget from "./type_widgets/attachment_detail.js";
|
||||
import MindMapWidget from "./type_widgets/mind_map.js";
|
||||
import { getStylesheetUrl, isSyntaxHighlightEnabled } from "../services/syntax_highlight.js";
|
||||
import GeoMapTypeWidget from "./type_widgets/geo_map.js";
|
||||
import utils from "../services/utils.js";
|
||||
import type { NoteType } from "../entities/fnote.js";
|
||||
|
@ -1,9 +1,8 @@
|
||||
import library_loader from "../../../services/library_loader.js";
|
||||
import { ALLOWED_PROTOCOLS } from "../../../services/link.js";
|
||||
import { MIME_TYPE_AUTO } from "../../../services/mime_type_definitions.js";
|
||||
import { MIME_TYPE_AUTO } from "@triliumnext/commons";
|
||||
import { getHighlightJsNameForMime } from "../../../services/mime_types.js";
|
||||
import options from "../../../services/options.js";
|
||||
import { isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
|
||||
import { ensureMimeTypesForHighlighting, isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
|
||||
import utils from "../../../services/utils.js";
|
||||
import emojiDefinitionsUrl from "@triliumnext/ckeditor5/emoji_definitions/en.json?external";
|
||||
|
||||
@ -104,9 +103,9 @@ export function buildConfig() {
|
||||
definitionsUrl: emojiDefinitionsUrl
|
||||
},
|
||||
syntaxHighlighting: {
|
||||
async loadHighlightJs() {
|
||||
await library_loader.requireLibrary(library_loader.HIGHLIGHT_JS);
|
||||
return hljs;
|
||||
loadHighlightJs: async () => {
|
||||
await ensureMimeTypesForHighlighting();
|
||||
return await import("@triliumnext/highlightjs");
|
||||
},
|
||||
mapLanguageName: getHighlightJsNameForMime,
|
||||
defaultMimeType: MIME_TYPE_AUTO,
|
||||
|
@ -12,13 +12,13 @@ import appContext, { type CommandListenerData, type EventData } from "../../comp
|
||||
import dialogService from "../../services/dialog.js";
|
||||
import options from "../../services/options.js";
|
||||
import toast from "../../services/toast.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "../../services/mime_type_definitions.js";
|
||||
import { buildSelectedBackgroundColor } from "../../components/touch_bar.js";
|
||||
import { buildConfig, buildToolbarConfig } from "./ckeditor/config.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import { getMermaidConfig } from "../../services/mermaid.js";
|
||||
import { PopupEditor, ClassicEditor, EditorWatchdog, type CKTextEditor, type MentionFeed, type WatchdogConfig } from "@triliumnext/ckeditor5";
|
||||
import "@triliumnext/ckeditor5/index.css";
|
||||
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
|
||||
|
||||
const ENABLE_INSPECTOR = false;
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
import type { OptionMap } from "@triliumnext/commons";
|
||||
import { normalizeMimeTypeForCKEditor, type OptionMap } from "@triliumnext/commons";
|
||||
import { t } from "../../../../services/i18n.js";
|
||||
import library_loader from "../../../../services/library_loader.js";
|
||||
import server from "../../../../services/server.js";
|
||||
import OptionsWidget from "../options_widget.js";
|
||||
import { ensureMimeTypesForHighlighting, loadHighlightingTheme } from "../../../../services/syntax_highlight.js";
|
||||
import { Themes, type Theme } from "@triliumnext/highlightjs";
|
||||
|
||||
const SAMPLE_LANGUAGE = "javascript";
|
||||
const SAMPLE_LANGUAGE = normalizeMimeTypeForCKEditor("application/javascript;env=frontend");
|
||||
const SAMPLE_CODE = `\
|
||||
const n = 10;
|
||||
greet(n); // Print "Hello World" for n times
|
||||
@ -55,14 +56,6 @@ const TPL = /*html*/`
|
||||
</div>
|
||||
`;
|
||||
|
||||
// TODO: Deduplicate
|
||||
interface Theme {
|
||||
title: string;
|
||||
val: string;
|
||||
}
|
||||
|
||||
type Response = Record<string, Theme[]>;
|
||||
|
||||
/**
|
||||
* Contains appearance settings for code blocks within text notes, such as the theme for the syntax highlighter.
|
||||
*/
|
||||
@ -75,9 +68,31 @@ export default class CodeBlockOptions extends OptionsWidget {
|
||||
doRender() {
|
||||
this.$widget = $(TPL);
|
||||
this.$themeSelect = this.$widget.find(".theme-select");
|
||||
|
||||
// Populate the list of themes.
|
||||
const themeGroups = groupThemesByLightOrDark();
|
||||
for (const [key, themes] of Object.entries(themeGroups)) {
|
||||
const $group = key ? $("<optgroup>").attr("label", key) : null;
|
||||
|
||||
for (const theme of themes) {
|
||||
const option = $("<option>")
|
||||
.attr("value", theme.val)
|
||||
.text(theme.title);
|
||||
|
||||
if ($group) {
|
||||
$group.append(option);
|
||||
} else {
|
||||
this.$themeSelect.append(option);
|
||||
}
|
||||
}
|
||||
if ($group) {
|
||||
this.$themeSelect.append($group);
|
||||
}
|
||||
}
|
||||
|
||||
this.$themeSelect.on("change", async () => {
|
||||
const newTheme = String(this.$themeSelect.val());
|
||||
library_loader.loadHighlightingTheme(newTheme);
|
||||
loadHighlightingTheme(newTheme);
|
||||
await server.put(`options/codeBlockTheme/${newTheme}`);
|
||||
});
|
||||
|
||||
@ -91,11 +106,14 @@ export default class CodeBlockOptions extends OptionsWidget {
|
||||
#setupPreview(shouldEnableSyntaxHighlight: boolean) {
|
||||
const text = SAMPLE_CODE;
|
||||
if (shouldEnableSyntaxHighlight) {
|
||||
library_loader.requireLibrary(library_loader.HIGHLIGHT_JS).then(() => {
|
||||
import("@triliumnext/highlightjs").then(async (hljs) => {
|
||||
await ensureMimeTypesForHighlighting();
|
||||
const highlightedText = hljs.highlight(text, {
|
||||
language: SAMPLE_LANGUAGE
|
||||
});
|
||||
this.$sampleEl.html(highlightedText.value);
|
||||
if (highlightedText) {
|
||||
this.$sampleEl.html(highlightedText.value);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$sampleEl.text(text);
|
||||
@ -103,25 +121,6 @@ export default class CodeBlockOptions extends OptionsWidget {
|
||||
}
|
||||
|
||||
async optionsLoaded(options: OptionMap) {
|
||||
const themeGroups = await server.get<Response>("options/codeblock-themes");
|
||||
this.$themeSelect.empty();
|
||||
|
||||
for (const [key, themes] of Object.entries(themeGroups)) {
|
||||
const $group = key ? $("<optgroup>").attr("label", key) : null;
|
||||
|
||||
for (const theme of themes) {
|
||||
const option = $("<option>").attr("value", theme.val).text(theme.title);
|
||||
|
||||
if ($group) {
|
||||
$group.append(option);
|
||||
} else {
|
||||
this.$themeSelect.append(option);
|
||||
}
|
||||
}
|
||||
if ($group) {
|
||||
this.$themeSelect.append($group);
|
||||
}
|
||||
}
|
||||
this.$themeSelect.val(options.codeBlockTheme);
|
||||
this.setCheckboxState(this.$wordWrap, options.codeBlockWordWrap);
|
||||
this.$widget.closest(".note-detail-printable").toggleClass("word-wrap", options.codeBlockWordWrap === "true");
|
||||
@ -129,3 +128,38 @@ export default class CodeBlockOptions extends OptionsWidget {
|
||||
this.#setupPreview(options.codeBlockTheme !== "none");
|
||||
}
|
||||
}
|
||||
|
||||
interface ThemeData {
|
||||
val: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
function groupThemesByLightOrDark() {
|
||||
const darkThemes: ThemeData[] = [];
|
||||
const lightThemes: ThemeData[] = [];
|
||||
|
||||
for (const [ id, theme ] of Object.entries(Themes)) {
|
||||
const data: ThemeData = {
|
||||
val: "default:" + id,
|
||||
title: theme.name
|
||||
};
|
||||
|
||||
if (theme.name.includes("Dark")) {
|
||||
darkThemes.push(data);
|
||||
} else {
|
||||
lightThemes.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
const output: Record<string, ThemeData[]> = {
|
||||
"": [
|
||||
{
|
||||
val: "none",
|
||||
title: t("code_block.theme_none")
|
||||
}
|
||||
]
|
||||
};
|
||||
output[t("code_block.theme_group_light")] = lightThemes;
|
||||
output[t("code_block.theme_group_dark")] = darkThemes;
|
||||
return output;
|
||||
}
|
||||
|
@ -34,6 +34,9 @@
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../packages/highlightjs/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/codemirror/tsconfig.lib.json"
|
||||
},
|
||||
|
@ -3,6 +3,9 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../packages/highlightjs"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/codemirror"
|
||||
},
|
||||
|
@ -80,6 +80,7 @@ module.exports = composePlugins(
|
||||
}))
|
||||
}));
|
||||
|
||||
inlineCss(config);
|
||||
inlineSvg(config);
|
||||
externalJson(config);
|
||||
|
||||
@ -103,6 +104,17 @@ function inlineSvg(config) {
|
||||
});
|
||||
}
|
||||
|
||||
function inlineCss(config) {
|
||||
if (!config.module?.rules) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Alter Nx's asset rule to avoid inlining SVG if they have ?raw prepended.
|
||||
console.log(config.module.rules.map((r) => r.test.toString()));
|
||||
const existingRule = config.module.rules.find((r) => r.test.toString().startsWith("/\\.css"));
|
||||
existingRule.resourceQuery = { not: [/raw/] };
|
||||
}
|
||||
|
||||
function externalJson(config) {
|
||||
if (!config.module?.rules) {
|
||||
return;
|
||||
|
@ -67,8 +67,5 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/diff": "^7.0.2"
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,7 @@
|
||||
"electron-dl": "4.0.0",
|
||||
"electron-squirrel-startup": "1.0.1",
|
||||
"jquery.fancytree": "2.38.5",
|
||||
"jquery-hotkeys": "0.2.2",
|
||||
"@highlightjs/cdn-assets": "11.11.1"
|
||||
"jquery-hotkeys": "0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/electron-squirrel-startup": "1.0.2",
|
||||
|
@ -6,8 +6,7 @@
|
||||
"dependencies": {
|
||||
"better-sqlite3": "11.10.0",
|
||||
"jquery.fancytree": "2.38.5",
|
||||
"jquery-hotkeys": "0.2.2",
|
||||
"@highlightjs/cdn-assets": "11.11.1"
|
||||
"jquery-hotkeys": "0.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/remote": "2.1.2",
|
||||
@ -83,7 +82,7 @@
|
||||
"html2plaintext": "2.1.4",
|
||||
"http-proxy-agent": "7.0.2",
|
||||
"https-proxy-agent": "7.0.6",
|
||||
"i18next": "25.1.3",
|
||||
"i18next": "25.2.0",
|
||||
"i18next-fs-backend": "2.6.0",
|
||||
"image-type": "5.2.0",
|
||||
"ini": "5.0.0",
|
||||
@ -92,9 +91,9 @@
|
||||
"jimp": "1.6.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"jsdom": "26.1.0",
|
||||
"marked": "15.0.11",
|
||||
"marked": "15.0.12",
|
||||
"mime-types": "3.0.1",
|
||||
"multer": "1.4.5-lts.2",
|
||||
"multer": "2.0.0",
|
||||
"normalize-strings": "1.1.1",
|
||||
"ollama": "0.5.15",
|
||||
"openai": "4.100.0",
|
||||
|
@ -193,11 +193,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "搜索:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "无语法高亮",
|
||||
"theme_group_light": "浅色主题",
|
||||
"theme_group_dark": "深色主题"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "同步服务器主机未配置。请先配置同步。",
|
||||
"successful": "同步服务器握手成功,同步已开始。"
|
||||
|
@ -185,11 +185,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "Suche:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "Keine Syntax-Hervorhebung",
|
||||
"theme_group_light": "Helle Themen",
|
||||
"theme_group_dark": "Dunkle Themen"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "Der Synchronisations-Server-Host ist nicht konfiguriert. Bitte konfiguriere zuerst die Synchronisation.",
|
||||
"successful": "Die Server-Verbindung wurde erfolgreich hergestellt, die Synchronisation wurde gestartet."
|
||||
|
@ -193,11 +193,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "Search:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "No syntax highlighting",
|
||||
"theme_group_light": "Light themes",
|
||||
"theme_group_dark": "Dark themes"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "Sync server host is not configured. Please configure sync first.",
|
||||
"successful": "Sync server handshake has been successful, sync has been started."
|
||||
|
@ -189,11 +189,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "Buscar:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "Sin resaltado de sintaxis",
|
||||
"theme_group_light": "Temas claros",
|
||||
"theme_group_dark": "Temas oscuros"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "El servidor de sincronización no está configurado. Por favor configure primero la sincronización.",
|
||||
"successful": "El protocolo de enlace del servidor de sincronización ha sido exitoso, la sincronización ha comenzado."
|
||||
|
@ -189,11 +189,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "Recherche :"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "Pas de coloration syntaxique",
|
||||
"theme_group_light": "Thèmes clairs",
|
||||
"theme_group_dark": "Thèmes sombres"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "L'hôte du serveur de synchronisation n'est pas configuré. Veuillez d'abord configurer la synchronisation.",
|
||||
"successful": "L'établissement de liaison du serveur de synchronisation a été réussi, la synchronisation a été démarrée."
|
||||
|
@ -186,11 +186,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "Pesquisar:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "Sem destaque de sintaxe",
|
||||
"theme_group_light": "Temas claros",
|
||||
"theme_group_dark": "Temas escuros"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "O host do servidor de sincronização não está configurado. Por favor, configure a sincronização primeiro.",
|
||||
"successful": "A comunicação com o servidor de sincronização foi bem-sucedida, a sincronização foi iniciada."
|
||||
|
@ -189,11 +189,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "Căutare:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "Fără evidențiere de sintaxă",
|
||||
"theme_group_dark": "Teme întunecate",
|
||||
"theme_group_light": "Teme luminoase"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "Calea către serverul de sincronizare nu este configurată. Configurați sincronizarea înainte.",
|
||||
"successful": "Comunicarea cu serverul de sincronizare a avut loc cu succes, s-a început sincronizarea."
|
||||
|
@ -185,11 +185,6 @@
|
||||
"special_notes": {
|
||||
"search_prefix": "搜尋:"
|
||||
},
|
||||
"code_block": {
|
||||
"theme_none": "無格式高亮",
|
||||
"theme_group_light": "淺色主題",
|
||||
"theme_group_dark": "深色主題"
|
||||
},
|
||||
"test_sync": {
|
||||
"not-configured": "並未設定同步伺服器主機,請先設定同步",
|
||||
"successful": "成功與同步伺服器握手,現在開始同步"
|
||||
|
@ -6,7 +6,6 @@ import searchService from "../../services/search/services/search.js";
|
||||
import ValidationError from "../../errors/validation_error.js";
|
||||
import type { Request } from "express";
|
||||
import { changeLanguage, getLocales } from "../../services/i18n.js";
|
||||
import { listSyntaxHighlightingThemes } from "../../services/code_block_theme.js";
|
||||
import type { OptionNames } from "@triliumnext/commons";
|
||||
|
||||
// options allowed to be updated directly in the Options dialog
|
||||
@ -191,10 +190,6 @@ function getUserThemes() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getSyntaxHighlightingThemes() {
|
||||
return listSyntaxHighlightingThemes();
|
||||
}
|
||||
|
||||
function getSupportedLocales() {
|
||||
return getLocales();
|
||||
}
|
||||
@ -211,6 +206,5 @@ export default {
|
||||
updateOption,
|
||||
updateOptions,
|
||||
getUserThemes,
|
||||
getSyntaxHighlightingThemes,
|
||||
getSupportedLocales
|
||||
};
|
||||
|
@ -90,8 +90,6 @@ async function register(app: express.Application) {
|
||||
app.use(`/${assetPath}/node_modules/normalize.css/`, persistentCacheStatic(path.join(nodeModulesDir, "normalize.css/")));
|
||||
|
||||
app.use(`/${assetPath}/node_modules/jquery.fancytree/dist/`, persistentCacheStatic(path.join(nodeModulesDir, "jquery.fancytree/dist/")));
|
||||
|
||||
app.use(`/${assetPath}/node_modules/@highlightjs/cdn-assets/`, persistentCacheStatic(path.join(nodeModulesDir, "@highlightjs/cdn-assets/")));
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -217,7 +217,6 @@ function register(app: express.Application) {
|
||||
apiRoute(PUT, "/api/options/:name/:value*", optionsApiRoute.updateOption);
|
||||
apiRoute(PUT, "/api/options", optionsApiRoute.updateOptions);
|
||||
apiRoute(GET, "/api/options/user-themes", optionsApiRoute.getUserThemes);
|
||||
apiRoute(GET, "/api/options/codeblock-themes", optionsApiRoute.getSyntaxHighlightingThemes);
|
||||
apiRoute(GET, "/api/options/locales", optionsApiRoute.getSupportedLocales);
|
||||
|
||||
apiRoute(PST, "/api/password/change", passwordApiRoute.changePassword);
|
||||
|
@ -1,22 +0,0 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { readThemesFromFileSystem } from "./code_block_theme.js";
|
||||
|
||||
import themeNames from "./code_block_theme_names.json" with { type: "json" };
|
||||
import path = require("path");
|
||||
|
||||
describe("Code block theme", () => {
|
||||
it("all themes are mapped", () => {
|
||||
const themes = readThemesFromFileSystem(path.join(__dirname, "../../node_modules/@highlightjs/cdn-assets/styles"));
|
||||
|
||||
const mappedThemeNames = new Set(Object.values(themeNames));
|
||||
const unmappedThemeNames = new Set<string>();
|
||||
|
||||
for (const theme of themes) {
|
||||
if (!mappedThemeNames.has(theme.title)) {
|
||||
unmappedThemeNames.add(theme.title);
|
||||
}
|
||||
}
|
||||
|
||||
expect(unmappedThemeNames.size, `Unmapped themes: ${Array.from(unmappedThemeNames).join(", ")}`).toBe(0);
|
||||
});
|
||||
});
|
@ -1,107 +0,0 @@
|
||||
/**
|
||||
* @module
|
||||
*
|
||||
* Manages the server-side functionality of the code blocks feature, mostly for obtaining the available themes for syntax highlighting.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import themeNames from "./code_block_theme_names.json" with { type: "json" };
|
||||
import { t } from "i18next";
|
||||
import { join } from "path";
|
||||
import { isDev, isElectron, getResourceDir } from "./utils.js";
|
||||
|
||||
/**
|
||||
* Represents a color scheme for the code block syntax highlight.
|
||||
*/
|
||||
interface ColorTheme {
|
||||
/** The ID of the color scheme which should be stored in the options. */
|
||||
val: string;
|
||||
/** A user-friendly name of the theme. The name is already localized. */
|
||||
title: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the supported syntax highlighting themes for code blocks, in groups.
|
||||
*
|
||||
* The return value is an object where the keys represent groups in their human-readable name (e.g. "Light theme")
|
||||
* and the values are an array containing the information about every theme. There is also a special group with no
|
||||
* title (empty string) which should be displayed at the top of the listing pages, without a group.
|
||||
*
|
||||
* @returns the supported themes, grouped.
|
||||
*/
|
||||
export function listSyntaxHighlightingThemes() {
|
||||
const path = getStylesDirectory();
|
||||
const systemThemes = readThemesFromFileSystem(path);
|
||||
|
||||
return {
|
||||
"": [
|
||||
{
|
||||
val: "none",
|
||||
title: t("code_block.theme_none")
|
||||
}
|
||||
],
|
||||
...groupThemesByLightOrDark(systemThemes)
|
||||
};
|
||||
}
|
||||
|
||||
export function getStylesDirectory() {
|
||||
if (isElectron && !isDev) {
|
||||
return join(getResourceDir(), "styles");
|
||||
} else if (!isDev) {
|
||||
return join(getResourceDir(), "node_modules/@highlightjs/cdn-assets/styles");
|
||||
} else {
|
||||
return join(__dirname, "../node_modules/@highlightjs/cdn-assets/styles");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all the predefined themes by listing all minified CSSes from a given directory.
|
||||
*
|
||||
* The theme names are mapped against a known list in order to provide more descriptive names such as "Visual Studio 2015 (Dark)" instead of "vs2015".
|
||||
*
|
||||
* @param path the path to read from. Usually this is the highlight.js `styles` directory.
|
||||
* @returns the list of themes.
|
||||
*/
|
||||
export function readThemesFromFileSystem(path: string): ColorTheme[] {
|
||||
return fs
|
||||
.readdirSync(path)
|
||||
.filter((el) => el.endsWith(".min.css"))
|
||||
.map((name) => {
|
||||
const nameWithoutExtension = name.replace(".min.css", "");
|
||||
let title = nameWithoutExtension.replace(/-/g, " ");
|
||||
|
||||
if (title in themeNames) {
|
||||
title = (themeNames as Record<string, string>)[title];
|
||||
}
|
||||
|
||||
return {
|
||||
val: `default:${nameWithoutExtension}`,
|
||||
title: title
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Groups a list of themes by dark or light themes. This is done simply by checking whether "Dark" is present in the given theme, otherwise it's considered a light theme.
|
||||
* This generally only works if the theme has a known human-readable name (see {@link #readThemesFromFileSystem()})
|
||||
*
|
||||
* @param listOfThemes the list of themes to be grouped.
|
||||
* @returns the grouped themes by light or dark.
|
||||
*/
|
||||
function groupThemesByLightOrDark(listOfThemes: ColorTheme[]) {
|
||||
const darkThemes = [];
|
||||
const lightThemes = [];
|
||||
|
||||
for (const theme of listOfThemes) {
|
||||
if (theme.title.includes("Dark")) {
|
||||
darkThemes.push(theme);
|
||||
} else {
|
||||
lightThemes.push(theme);
|
||||
}
|
||||
}
|
||||
|
||||
const output: Record<string, ColorTheme[]> = {};
|
||||
output[t("code_block.theme_group_light")] = lightThemes;
|
||||
output[t("code_block.theme_group_dark")] = darkThemes;
|
||||
return output;
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
{
|
||||
"1c light": "1C (Light)",
|
||||
"a11y dark": "a11y (Dark)",
|
||||
"a11y light": "a11y (Light)",
|
||||
"agate": "Agate (Dark)",
|
||||
"an old hope": "An Old Hope (Dark)",
|
||||
"androidstudio": "Android Studio (Dark)",
|
||||
"arduino light": "Arduino (Light)",
|
||||
"arta": "Arta (Dark)",
|
||||
"ascetic": "Ascetic (Light)",
|
||||
"atom one dark reasonable": "Atom One with ReasonML support (Dark)",
|
||||
"atom one dark": "Atom One (Dark)",
|
||||
"atom one light": "Atom One (Light)",
|
||||
"brown paper": "Brown Paper (Light)",
|
||||
"codepen embed": "CodePen Embed (Dark)",
|
||||
"color brewer": "Color Brewer (Light)",
|
||||
"cybertopia cherry": "Cybertopia Cherry (Dark)",
|
||||
"cybertopia dimmer": "Cybertopia Dimmer (Dark)",
|
||||
"cybertopia icecap": "Cybertopia Icecap (Dark)",
|
||||
"cybertopia saturated": "Cybertopia Saturated (Dark)",
|
||||
"dark": "Dark",
|
||||
"default": "Original highlight.js Theme (Light)",
|
||||
"devibeans": "devibeans (Dark)",
|
||||
"docco": "Docco (Light)",
|
||||
"far": "FAR (Dark)",
|
||||
"felipec": "FelipeC (Dark)",
|
||||
"foundation": "Foundation 4 Docs (Light)",
|
||||
"github dark dimmed": "GitHub Dimmed (Dark)",
|
||||
"github dark": "GitHub (Dark)",
|
||||
"github": "GitHub (Light)",
|
||||
"gml": "GML (Dark)",
|
||||
"googlecode": "Google Code (Light)",
|
||||
"gradient dark": "Gradient (Dark)",
|
||||
"gradient light": "Gradient (Light)",
|
||||
"grayscale": "Grayscale (Light)",
|
||||
"hybrid": "hybrid (Dark)",
|
||||
"idea": "Idea (Light)",
|
||||
"intellij light": "IntelliJ (Light)",
|
||||
"ir black": "IR Black (Dark)",
|
||||
"isbl editor dark": "ISBL Editor (Dark)",
|
||||
"isbl editor light": "ISBL Editor (Light)",
|
||||
"kimbie dark": "Kimbie (Dark)",
|
||||
"kimbie light": "Kimbie (Light)",
|
||||
"lightfair": "Lightfair (Light)",
|
||||
"lioshi": "Lioshi (Dark)",
|
||||
"magula": "Magula (Light)",
|
||||
"mono blue": "Mono Blue (Light)",
|
||||
"monokai sublime": "Monokai Sublime (Dark)",
|
||||
"monokai": "Monokai (Dark)",
|
||||
"night owl": "Night Owl (Dark)",
|
||||
"nnfx dark": "NNFX (Dark)",
|
||||
"nnfx light": "NNFX (Light)",
|
||||
"nord": "Nord (Dark)",
|
||||
"obsidian": "Obsidian (Dark)",
|
||||
"panda syntax dark": "Panda (Dark)",
|
||||
"panda syntax light": "Panda (Light)",
|
||||
"paraiso dark": "Paraiso (Dark)",
|
||||
"paraiso light": "Paraiso (Light)",
|
||||
"pojoaque": "Pojoaque (Dark)",
|
||||
"purebasic": "PureBasic (Light)",
|
||||
"qtcreator dark": "Qt Creator (Dark)",
|
||||
"qtcreator light": "Qt Creator (Light)",
|
||||
"rainbow": "Rainbow (Dark)",
|
||||
"routeros": "RouterOS Script (Light)",
|
||||
"rose pine dawn": "Rose Pine Dawn (Light)",
|
||||
"rose pine moon": "Rose Pine Moon (Dark)",
|
||||
"rose pine": "Rose Pine (Dark)",
|
||||
"school book": "School Book (Light)",
|
||||
"shades of purple": "Shades of Purple (Dark)",
|
||||
"srcery": "Srcery (Dark)",
|
||||
"stackoverflow dark": "Stack Overflow (Dark)",
|
||||
"stackoverflow light": "Stack Overflow (Light)",
|
||||
"sunburst": "Sunburst (Dark)",
|
||||
"tokyo night dark": "Tokyo Night (Dark)",
|
||||
"tokyo night light": "Tokyo Night (Light)",
|
||||
"tomorrow night blue": "Tomorrow Night Blue (Dark)",
|
||||
"tomorrow night bright": "Tomorrow Night Bright (Dark)",
|
||||
"vs": "Visual Studio (Light)",
|
||||
"vs2015": "Visual Studio 2015 (Dark)",
|
||||
"xcode": "Xcode (Light)",
|
||||
"xt256": "xt256 (Dark)"
|
||||
}
|
@ -1,6 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import { parse, Renderer, type Tokens } from "marked";
|
||||
import htmlSanitizer from "../html_sanitizer.js";
|
||||
import importUtils from "./utils.js";
|
||||
import { getMimeTypeFromMarkdownName, MIME_TYPE_AUTO } from "@triliumnext/commons";
|
||||
import { ADMONITION_TYPE_MAPPINGS } from "../export/markdown.js";
|
||||
import utils from "../utils.js";
|
||||
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
|
||||
|
||||
/**
|
||||
* Keep renderer code up to date with https://github.com/markedjs/marked/blob/master/src/Renderer.ts.
|
||||
@ -123,14 +129,6 @@ class CustomMarkdownRenderer extends Renderer {
|
||||
|
||||
}
|
||||
|
||||
const renderer = new CustomMarkdownRenderer({ async: false });
|
||||
|
||||
import htmlSanitizer from "../html_sanitizer.js";
|
||||
import importUtils from "./utils.js";
|
||||
import { getMimeTypeFromHighlightJs, MIME_TYPE_AUTO, normalizeMimeTypeForCKEditor } from "./mime_type_definitions.js";
|
||||
import { ADMONITION_TYPE_MAPPINGS } from "../export/markdown.js";
|
||||
import utils from "../utils.js";
|
||||
|
||||
function renderToHtml(content: string, title: string) {
|
||||
// Double-escape slashes in math expression because they are otherwise consumed by the parser somewhere.
|
||||
content = content.replaceAll("\\$", "\\\\$");
|
||||
@ -158,15 +156,17 @@ function renderToHtml(content: string, title: string) {
|
||||
|
||||
function getNormalizedMimeFromMarkdownLanguage(language: string | undefined) {
|
||||
if (language) {
|
||||
const highlightJsName = getMimeTypeFromHighlightJs(language);
|
||||
if (highlightJsName) {
|
||||
return normalizeMimeTypeForCKEditor(highlightJsName.mime);
|
||||
const mimeDefinition = getMimeTypeFromMarkdownName(language);
|
||||
if (mimeDefinition) {
|
||||
return normalizeMimeTypeForCKEditor(mimeDefinition.mime);
|
||||
}
|
||||
}
|
||||
|
||||
return MIME_TYPE_AUTO;
|
||||
}
|
||||
|
||||
const renderer = new CustomMarkdownRenderer({ async: false });
|
||||
|
||||
export default {
|
||||
renderToHtml
|
||||
};
|
||||
|
@ -1,223 +0,0 @@
|
||||
// TODO: deduplicate with /src/public/app/services/mime_type_definitions.ts
|
||||
|
||||
/**
|
||||
* A pseudo-MIME type which is used in the editor to automatically determine the language used in code blocks via heuristics.
|
||||
*/
|
||||
export const MIME_TYPE_AUTO = "text-x-trilium-auto";
|
||||
|
||||
export interface MimeTypeDefinition {
|
||||
default?: boolean;
|
||||
title: string;
|
||||
mime: string;
|
||||
/** The name of the language/mime type as defined by highlight.js (or one of the aliases), in order to be used for syntax highlighting such as inside code blocks. */
|
||||
highlightJs?: string;
|
||||
/** If specified, will load the corresponding highlight.js file from the `libraries/highlightjs/${id}.js` instead of `node_modules/@highlightjs/cdn-assets/languages/${id}.min.js`. */
|
||||
highlightJsSource?: "libraries";
|
||||
/** If specified, will load the corresponding highlight file from the given path instead of `node_modules`. */
|
||||
codeMirrorSource?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* For highlight.js-supported languages, see https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md.
|
||||
*/
|
||||
|
||||
export const MIME_TYPES_DICT: readonly MimeTypeDefinition[] = Object.freeze([
|
||||
{ title: "Plain text", mime: "text/plain", highlightJs: "plaintext", default: true },
|
||||
|
||||
// Keep sorted alphabetically.
|
||||
{ title: "APL", mime: "text/apl" },
|
||||
{ title: "ASN.1", mime: "text/x-ttcn-asn" },
|
||||
{ title: "ASP.NET", mime: "application/x-aspx" },
|
||||
{ title: "Asterisk", mime: "text/x-asterisk" },
|
||||
{ title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos", codeMirrorSource: "libraries/codemirror/batch.js" },
|
||||
{ title: "Brainfuck", mime: "text/x-brainfuck", highlightJs: "brainfuck" },
|
||||
{ title: "C", mime: "text/x-csrc", highlightJs: "c", default: true },
|
||||
{ title: "C#", mime: "text/x-csharp", highlightJs: "csharp", default: true },
|
||||
{ title: "C++", mime: "text/x-c++src", highlightJs: "cpp", default: true },
|
||||
{ title: "Clojure", mime: "text/x-clojure", highlightJs: "clojure" },
|
||||
{ title: "ClojureScript", mime: "text/x-clojurescript" },
|
||||
{ title: "Closure Stylesheets (GSS)", mime: "text/x-gss" },
|
||||
{ title: "CMake", mime: "text/x-cmake", highlightJs: "cmake" },
|
||||
{ title: "Cobol", mime: "text/x-cobol" },
|
||||
{ title: "CoffeeScript", mime: "text/coffeescript", highlightJs: "coffeescript" },
|
||||
{ title: "Common Lisp", mime: "text/x-common-lisp", highlightJs: "lisp" },
|
||||
{ title: "CQL", mime: "text/x-cassandra" },
|
||||
{ title: "Crystal", mime: "text/x-crystal", highlightJs: "crystal" },
|
||||
{ title: "CSS", mime: "text/css", highlightJs: "css", default: true },
|
||||
{ title: "Cypher", mime: "application/x-cypher-query" },
|
||||
{ title: "Cython", mime: "text/x-cython" },
|
||||
{ title: "D", mime: "text/x-d", highlightJs: "d" },
|
||||
{ title: "Dart", mime: "application/dart", highlightJs: "dart" },
|
||||
{ title: "diff", mime: "text/x-diff", highlightJs: "diff" },
|
||||
{ title: "Django", mime: "text/x-django", highlightJs: "django" },
|
||||
{ title: "Dockerfile", mime: "text/x-dockerfile", highlightJs: "dockerfile" },
|
||||
{ title: "DTD", mime: "application/xml-dtd" },
|
||||
{ title: "Dylan", mime: "text/x-dylan" },
|
||||
{ title: "EBNF", mime: "text/x-ebnf", highlightJs: "ebnf" },
|
||||
{ title: "ECL", mime: "text/x-ecl" },
|
||||
{ title: "edn", mime: "application/edn" },
|
||||
{ title: "Eiffel", mime: "text/x-eiffel" },
|
||||
{ title: "Elm", mime: "text/x-elm", highlightJs: "elm" },
|
||||
{ title: "Embedded Javascript", mime: "application/x-ejs" },
|
||||
{ title: "Embedded Ruby", mime: "application/x-erb", highlightJs: "erb" },
|
||||
{ title: "Erlang", mime: "text/x-erlang", highlightJs: "erlang" },
|
||||
{ title: "Esper", mime: "text/x-esper" },
|
||||
{ title: "F#", mime: "text/x-fsharp", highlightJs: "fsharp" },
|
||||
{ title: "Factor", mime: "text/x-factor" },
|
||||
{ title: "FCL", mime: "text/x-fcl" },
|
||||
{ title: "Forth", mime: "text/x-forth" },
|
||||
{ title: "Fortran", mime: "text/x-fortran", highlightJs: "fortran" },
|
||||
{ title: "Gas", mime: "text/x-gas" },
|
||||
{ title: "GDScript (Godot)", mime: "text/x-gdscript" },
|
||||
{ title: "Gherkin", mime: "text/x-feature", highlightJs: "gherkin" },
|
||||
{ title: "GitHub Flavored Markdown", mime: "text/x-gfm", highlightJs: "markdown" },
|
||||
{ title: "Go", mime: "text/x-go", highlightJs: "go", default: true },
|
||||
{ title: "Groovy", mime: "text/x-groovy", highlightJs: "groovy", default: true },
|
||||
{ title: "HAML", mime: "text/x-haml", highlightJs: "haml" },
|
||||
{ title: "Haskell (Literate)", mime: "text/x-literate-haskell" },
|
||||
{ title: "Haskell", mime: "text/x-haskell", highlightJs: "haskell", default: true },
|
||||
{ title: "Haxe", mime: "text/x-haxe", highlightJs: "haxe" },
|
||||
{ title: "HTML", mime: "text/html", highlightJs: "xml", default: true },
|
||||
{ title: "HTTP", mime: "message/http", highlightJs: "http", default: true },
|
||||
{ title: "HXML", mime: "text/x-hxml" },
|
||||
{ title: "IDL", mime: "text/x-idl" },
|
||||
{ title: "Java Server Pages", mime: "application/x-jsp", highlightJs: "java" },
|
||||
{ title: "Java", mime: "text/x-java", highlightJs: "java", default: true },
|
||||
{ title: "Jinja2", mime: "text/jinja2" },
|
||||
{ title: "JS backend", mime: "application/javascript;env=backend", highlightJs: "javascript", default: true },
|
||||
{ title: "JS frontend", mime: "application/javascript;env=frontend", highlightJs: "javascript", default: true },
|
||||
{ title: "JSON-LD", mime: "application/ld+json", highlightJs: "json" },
|
||||
{ title: "JSON", mime: "application/json", highlightJs: "json", default: true },
|
||||
{ title: "JSX", mime: "text/jsx", highlightJs: "javascript" },
|
||||
{ title: "Julia", mime: "text/x-julia", highlightJs: "julia" },
|
||||
{ title: "Kotlin", mime: "text/x-kotlin", highlightJs: "kotlin", default: true },
|
||||
{ title: "LaTeX", mime: "text/x-latex", highlightJs: "latex" },
|
||||
{ title: "LESS", mime: "text/x-less", highlightJs: "less" },
|
||||
{ title: "LiveScript", mime: "text/x-livescript", highlightJs: "livescript" },
|
||||
{ title: "Lua", mime: "text/x-lua", highlightJs: "lua" },
|
||||
{ title: "MariaDB SQL", mime: "text/x-mariadb", highlightJs: "sql" },
|
||||
{ title: "Markdown", mime: "text/x-markdown", highlightJs: "markdown", default: true },
|
||||
{ title: "Mathematica", mime: "text/x-mathematica", highlightJs: "mathematica" },
|
||||
{ title: "mbox", mime: "application/mbox" },
|
||||
{ title: "MIPS Assembler", mime: "text/x-asm-mips", highlightJs: "mips" },
|
||||
{ title: "mIRC", mime: "text/mirc" },
|
||||
{ title: "Modelica", mime: "text/x-modelica" },
|
||||
{ title: "MS SQL", mime: "text/x-mssql", highlightJs: "sql" },
|
||||
{ title: "mscgen", mime: "text/x-mscgen" },
|
||||
{ title: "msgenny", mime: "text/x-msgenny" },
|
||||
{ title: "MUMPS", mime: "text/x-mumps" },
|
||||
{ title: "MySQL", mime: "text/x-mysql", highlightJs: "sql" },
|
||||
{ title: "Nix", mime: "text/x-nix", highlightJs: "nix" },
|
||||
{ title: "Nginx", mime: "text/x-nginx-conf", highlightJs: "nginx" },
|
||||
{ title: "NSIS", mime: "text/x-nsis", highlightJs: "nsis" },
|
||||
{ title: "NTriples", mime: "application/n-triples" },
|
||||
{ title: "Objective-C", mime: "text/x-objectivec", highlightJs: "objectivec" },
|
||||
{ title: "OCaml", mime: "text/x-ocaml", highlightJs: "ocaml" },
|
||||
{ title: "Octave", mime: "text/x-octave" },
|
||||
{ title: "Oz", mime: "text/x-oz" },
|
||||
{ title: "Pascal", mime: "text/x-pascal", highlightJs: "delphi" },
|
||||
{ title: "PEG.js", mime: "null" },
|
||||
{ title: "Perl", mime: "text/x-perl", default: true },
|
||||
{ title: "PGP", mime: "application/pgp" },
|
||||
{ title: "PHP", mime: "text/x-php", default: true },
|
||||
{ title: "Pig", mime: "text/x-pig" },
|
||||
{ title: "PLSQL", mime: "text/x-plsql", highlightJs: "sql" },
|
||||
{ title: "PostgreSQL", mime: "text/x-pgsql", highlightJs: "pgsql" },
|
||||
{ title: "PowerShell", mime: "application/x-powershell", highlightJs: "powershell" },
|
||||
{ title: "Properties files", mime: "text/x-properties", highlightJs: "properties" },
|
||||
{ title: "ProtoBuf", mime: "text/x-protobuf", highlightJs: "protobuf" },
|
||||
{ title: "Pug", mime: "text/x-pug" },
|
||||
{ title: "Puppet", mime: "text/x-puppet", highlightJs: "puppet" },
|
||||
{ title: "Python", mime: "text/x-python", highlightJs: "python", default: true },
|
||||
{ title: "Q", mime: "text/x-q", highlightJs: "q" },
|
||||
{ title: "R", mime: "text/x-rsrc", highlightJs: "r" },
|
||||
{ title: "reStructuredText", mime: "text/x-rst" },
|
||||
{ title: "RPM Changes", mime: "text/x-rpm-changes" },
|
||||
{ title: "RPM Spec", mime: "text/x-rpm-spec" },
|
||||
{ title: "Ruby", mime: "text/x-ruby", highlightJs: "ruby", default: true },
|
||||
{ title: "Rust", mime: "text/x-rustsrc", highlightJs: "rust" },
|
||||
{ title: "SAS", mime: "text/x-sas", highlightJs: "sas" },
|
||||
{ title: "Sass", mime: "text/x-sass" },
|
||||
{ title: "Scala", mime: "text/x-scala" },
|
||||
{ title: "Scheme", mime: "text/x-scheme" },
|
||||
{ title: "SCSS", mime: "text/x-scss", highlightJs: "scss" },
|
||||
{ title: "Shell (bash)", mime: "text/x-sh", highlightJs: "bash", default: true },
|
||||
{ title: "Sieve", mime: "application/sieve" },
|
||||
{ title: "Slim", mime: "text/x-slim" },
|
||||
{ title: "Smalltalk", mime: "text/x-stsrc", highlightJs: "smalltalk" },
|
||||
{ title: "Smarty", mime: "text/x-smarty" },
|
||||
{ title: "SML", mime: "text/x-sml", highlightJs: "sml" },
|
||||
{ title: "Solr", mime: "text/x-solr" },
|
||||
{ title: "Soy", mime: "text/x-soy" },
|
||||
{ title: "SPARQL", mime: "application/sparql-query" },
|
||||
{ title: "Spreadsheet", mime: "text/x-spreadsheet" },
|
||||
{ title: "SQL", mime: "text/x-sql", highlightJs: "sql", default: true },
|
||||
{ title: "SQLite (Trilium)", mime: "text/x-sqlite;schema=trilium", highlightJs: "sql", default: true },
|
||||
{ title: "SQLite", mime: "text/x-sqlite", highlightJs: "sql" },
|
||||
{ title: "Squirrel", mime: "text/x-squirrel" },
|
||||
{ title: "sTeX", mime: "text/x-stex" },
|
||||
{ title: "Stylus", mime: "text/x-styl", highlightJs: "stylus" },
|
||||
{ title: "Swift", mime: "text/x-swift", default: true },
|
||||
{ title: "SystemVerilog", mime: "text/x-systemverilog" },
|
||||
{ title: "Tcl", mime: "text/x-tcl", highlightJs: "tcl" },
|
||||
{ title: "Terraform (HCL)", mime: "text/x-hcl", highlightJs: "terraform", highlightJsSource: "libraries", codeMirrorSource: "libraries/codemirror/hcl.js" },
|
||||
{ title: "Textile", mime: "text/x-textile" },
|
||||
{ title: "TiddlyWiki ", mime: "text/x-tiddlywiki" },
|
||||
{ title: "Tiki wiki", mime: "text/tiki" },
|
||||
{ title: "TOML", mime: "text/x-toml", highlightJs: "ini" },
|
||||
{ title: "Tornado", mime: "text/x-tornado" },
|
||||
{ title: "troff", mime: "text/troff" },
|
||||
{ title: "TTCN_CFG", mime: "text/x-ttcn-cfg" },
|
||||
{ title: "TTCN", mime: "text/x-ttcn" },
|
||||
{ title: "Turtle", mime: "text/turtle" },
|
||||
{ title: "Twig", mime: "text/x-twig", highlightJs: "twig" },
|
||||
{ title: "TypeScript-JSX", mime: "text/typescript-jsx" },
|
||||
{ title: "TypeScript", mime: "application/typescript", highlightJs: "typescript" },
|
||||
{ title: "VB.NET", mime: "text/x-vb", highlightJs: "vbnet" },
|
||||
{ title: "VBScript", mime: "text/vbscript", highlightJs: "vbscript" },
|
||||
{ title: "Velocity", mime: "text/velocity" },
|
||||
{ title: "Verilog", mime: "text/x-verilog", highlightJs: "verilog" },
|
||||
{ title: "VHDL", mime: "text/x-vhdl", highlightJs: "vhdl" },
|
||||
{ title: "Vue.js Component", mime: "text/x-vue" },
|
||||
{ title: "Web IDL", mime: "text/x-webidl" },
|
||||
{ title: "XML", mime: "text/xml", highlightJs: "xml", default: true },
|
||||
{ title: "XQuery", mime: "application/xquery", highlightJs: "xquery" },
|
||||
{ title: "xu", mime: "text/x-xu" },
|
||||
{ title: "Yacas", mime: "text/x-yacas" },
|
||||
{ title: "YAML", mime: "text/x-yaml", highlightJs: "yaml", default: true },
|
||||
{ title: "Z80", mime: "text/x-z80" }
|
||||
]);
|
||||
|
||||
/**
|
||||
* Given a MIME type in the usual format (e.g. `text/csrc`), it returns a MIME type that can be passed down to the CKEditor
|
||||
* code plugin.
|
||||
*
|
||||
* @param mimeType The MIME type to normalize, in the usual format (e.g. `text/c-src`).
|
||||
* @returns the normalized MIME type (e.g. `text-c-src`).
|
||||
*/
|
||||
export function normalizeMimeTypeForCKEditor(mimeType: string) {
|
||||
return mimeType.toLowerCase().replace(/[\W_]+/g, "-");
|
||||
}
|
||||
|
||||
let byHighlightJsNameMappings: Record<string, MimeTypeDefinition> | null = null;
|
||||
|
||||
/**
|
||||
* Given a Highlight.js language tag (e.g. `css`), it returns a corresponding {@link MimeTypeDefinition} if found.
|
||||
*
|
||||
* If there are multiple {@link MimeTypeDefinition}s for the language tag, then only the first one is retrieved. For example for `javascript`, the "JS frontend" mime type is returned.
|
||||
*
|
||||
* @param highlightJsName a language tag.
|
||||
* @returns the corresponding {@link MimeTypeDefinition} if found, or `undefined` otherwise.
|
||||
*/
|
||||
export function getMimeTypeFromHighlightJs(highlightJsName: string) {
|
||||
if (!byHighlightJsNameMappings) {
|
||||
byHighlightJsNameMappings = {};
|
||||
for (const mimeType of MIME_TYPES_DICT) {
|
||||
if (mimeType.highlightJs && !byHighlightJsNameMappings[mimeType.highlightJs]) {
|
||||
byHighlightJsNameMappings[mimeType.highlightJs] = mimeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return byHighlightJsNameMappings[highlightJsName];
|
||||
}
|
@ -22,7 +22,6 @@ function buildFilesToCopy() {
|
||||
"autocomplete.js/dist",
|
||||
"normalize.css/normalize.css",
|
||||
"jquery.fancytree/dist",
|
||||
"@highlightjs/cdn-assets",
|
||||
|
||||
// Required as they are native dependencies and cannot be well bundled.
|
||||
"better-sqlite3",
|
||||
|
@ -21,6 +21,7 @@
|
||||
* [Inconsistent Find and Replace Behavior in Large Code Notes](https://github.com/TriliumNext/Notes/issues/1826) by @SiriusXT
|
||||
* [Incorrect import of multiple inline math](https://github.com/TriliumNext/Notes/pull/1906) by @SiriusXT
|
||||
* [Random EPERM: operation not permitted on Windows](https://github.com/TriliumNext/Notes/issues/249)
|
||||
* [The update button is sometimes blank](https://github.com/TriliumNext/Notes/pull/1975) by @SiriusXT
|
||||
|
||||
## ✨ Improvements
|
||||
|
||||
@ -32,10 +33,25 @@
|
||||
* [Make it show which node triggered the event when right-clicking on tree](https://github.com/TriliumNext/Notes/pull/1861) by @SiriusXT
|
||||
* [Only expand/collapse the left pane of the focused window](https://github.com/TriliumNext/Notes/pull/1905) by @SiriusXT
|
||||
* Code notes:
|
||||
* Added the GDScript (Godot) language.
|
||||
* Added the GDScript (Godot) language for both code notes and code blocks in text notes.
|
||||
* Added the Nix language (and also in code blocks for text notes).
|
||||
* Added an indentation marker.
|
||||
* Note: syntax highlighting for some languages (mostly HTML-template languages such as EJS, JSP) is no longer supported due to lack of upstream support. If this is a problem, feel free to report an issue and we can see what can be done about it.
|
||||
* Syntax highlighting in code blocks for text notes:
|
||||
* Added support for Cypher.
|
||||
* Added support for XML-DTD.
|
||||
* Added support for Jinja2.
|
||||
* Added support for ClojureScript.
|
||||
* Added support for Perl.
|
||||
* Added support for Scala.
|
||||
* Added support for Scheme.
|
||||
* Added support for Swift.
|
||||
* Added support for SystemVerilog.
|
||||
* Added support for mIRC.
|
||||
* Added support for Cobol.
|
||||
* Added support for Dylan.
|
||||
* Added support for RPM Specfile.
|
||||
* Added support for TCCN3.
|
||||
* Mermaid diagrams: basic syntax highlight (not all diagram types are supported) and code folding.
|
||||
* Slight organization in Appearance settings: code block themes are now in "Text Notes", added a "Related settings" section in Appearance.
|
||||
* [Added support for opening and activating a note in a new tab using Ctrl+Shift+click on notes in the launcher pane, note tree, or note images](https://github.com/TriliumNext/Notes/pull/1854) by @SiriusXT
|
||||
@ -49,6 +65,7 @@
|
||||
* Documented the new text note features: bookmarks and emojis.
|
||||
* Add documentation links and updated pnpm commands to README by @perfectra1n
|
||||
* Add documentation around setting the various environment variables to control upload size limit by @perfectra1n
|
||||
* README improvements by @FliegendeWurst
|
||||
|
||||
## 🌍 Internationalization
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
"@swc/helpers": "~0.5.11",
|
||||
"@triliumnext/server": "workspace:*",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/node": "22.15.18",
|
||||
"@types/node": "22.15.19",
|
||||
"@vitest/coverage-v8": "^3.0.5",
|
||||
"@vitest/ui": "^3.0.0",
|
||||
"chalk": "5.4.1",
|
||||
|
@ -173,14 +173,6 @@ export default class SyntaxHighlighting extends Plugin {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the corresponding language for the given mimetype.
|
||||
const highlightJsLanguage = this.config.mapLanguageName(mimeType);
|
||||
|
||||
if (mimeType !== this.config.defaultMimeType && !highlightJsLanguage) {
|
||||
console.warn(`Unsupported highlight.js for mime type ${mimeType}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't highlight if the code is too big, as the typing performance will be highly degraded.
|
||||
if (codeBlock.childCount >= HIGHLIGHT_MAX_BLOCK_COUNT) {
|
||||
return;
|
||||
@ -230,8 +222,13 @@ export default class SyntaxHighlighting extends Plugin {
|
||||
if (mimeType === this.config.defaultMimeType) {
|
||||
highlightRes = this.hljs.highlightAuto(text);
|
||||
} else {
|
||||
highlightRes = this.hljs.highlight(text, { language: highlightJsLanguage });
|
||||
highlightRes = this.hljs.highlight(text, { language: mimeType });
|
||||
}
|
||||
|
||||
if (!highlightRes) {
|
||||
return;
|
||||
}
|
||||
|
||||
dbg("text\n" + text);
|
||||
dbg("html\n" + highlightRes.value);
|
||||
|
||||
|
@ -3,4 +3,5 @@ export * from "./lib/options_interface.js";
|
||||
export * from "./lib/keyboard_actions_interface.js";
|
||||
export * from "./lib/hidden_subtree.js";
|
||||
export * from "./lib/rows.js";
|
||||
export * from "./lib/test-utils.js"
|
||||
export * from "./lib/test-utils.js";
|
||||
export * from "./lib/mime_type.js";
|
||||
|
226
packages/commons/src/lib/mime_type.ts
Normal file
226
packages/commons/src/lib/mime_type.ts
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* A pseudo-MIME type which is used in the editor to automatically determine the language used in code blocks via heuristics.
|
||||
*/
|
||||
export const MIME_TYPE_AUTO = "text-x-trilium-auto";
|
||||
|
||||
export interface MimeTypeDefinition {
|
||||
default?: boolean;
|
||||
title: string;
|
||||
mime: string;
|
||||
/** The name of the language/mime type as defined by highlight.js (or one of the aliases), in order to be used for syntax highlighting such as inside code blocks. */
|
||||
mdLanguageCode?: string;
|
||||
/** If specified, will load the corresponding highlight file from the given path instead of `node_modules`. */
|
||||
codeMirrorSource?: string;
|
||||
}
|
||||
|
||||
export interface MimeType extends MimeTypeDefinition {
|
||||
/**
|
||||
* True if this mime type was enabled by the user in the "Available MIME types in the dropdown" option in the Code Notes settings.
|
||||
*/
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a MIME type in the usual format (e.g. `text/csrc`), it returns a MIME type that can be passed down to the CKEditor
|
||||
* code plugin.
|
||||
*
|
||||
* @param mimeType The MIME type to normalize, in the usual format (e.g. `text/c-src`).
|
||||
* @returns the normalized MIME type (e.g. `text-c-src`).
|
||||
*/
|
||||
export function normalizeMimeTypeForCKEditor(mimeType: string) {
|
||||
return mimeType.toLowerCase().replace(/[\W_]+/g, "-");
|
||||
}
|
||||
|
||||
/**
|
||||
* For highlight.js-supported languages, see https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md.
|
||||
*/
|
||||
|
||||
export const MIME_TYPES_DICT: readonly MimeTypeDefinition[] = Object.freeze([
|
||||
{ title: "Plain text", mime: "text/plain", mdLanguageCode: "plaintext", default: true },
|
||||
|
||||
// Keep sorted alphabetically.
|
||||
{ title: "APL", mime: "text/apl" },
|
||||
{ title: "ASN.1", mime: "text/x-ttcn-asn" },
|
||||
{ title: "ASP.NET", mime: "application/x-aspx" },
|
||||
{ title: "Asterisk", mime: "text/x-asterisk" },
|
||||
{ title: "Batch file (DOS)", mime: "application/x-bat", highlightJs: "dos", codeMirrorSource: "libraries/codemirror/batch.js" },
|
||||
{ title: "Brainfuck", mime: "text/x-brainfuck", mdLanguageCode: "brainfuck" },
|
||||
{ title: "C", mime: "text/x-csrc", mdLanguageCode: "c", default: true },
|
||||
{ title: "C#", mime: "text/x-csharp", mdLanguageCode: "csharp", default: true },
|
||||
{ title: "C++", mime: "text/x-c++src", mdLanguageCode: "cpp", default: true },
|
||||
{ title: "Clojure", mime: "text/x-clojure", mdLanguageCode: "clojure" },
|
||||
{ title: "ClojureScript", mime: "text/x-clojurescript" },
|
||||
{ title: "Closure Stylesheets (GSS)", mime: "text/x-gss" },
|
||||
{ title: "CMake", mime: "text/x-cmake", mdLanguageCode: "cmake" },
|
||||
{ title: "Cobol", mime: "text/x-cobol" },
|
||||
{ title: "CoffeeScript", mime: "text/coffeescript", mdLanguageCode: "coffeescript" },
|
||||
{ title: "Common Lisp", mime: "text/x-common-lisp", mdLanguageCode: "lisp" },
|
||||
{ title: "CQL", mime: "text/x-cassandra" },
|
||||
{ title: "Crystal", mime: "text/x-crystal", mdLanguageCode: "crystal" },
|
||||
{ title: "CSS", mime: "text/css", mdLanguageCode: "css", default: true },
|
||||
{ title: "Cypher", mime: "application/x-cypher-query" },
|
||||
{ title: "Cython", mime: "text/x-cython" },
|
||||
{ title: "D", mime: "text/x-d", mdLanguageCode: "d" },
|
||||
{ title: "Dart", mime: "application/dart", mdLanguageCode: "dart" },
|
||||
{ title: "diff", mime: "text/x-diff", mdLanguageCode: "diff" },
|
||||
{ title: "Django", mime: "text/x-django", mdLanguageCode: "django" },
|
||||
{ title: "Dockerfile", mime: "text/x-dockerfile", mdLanguageCode: "dockerfile" },
|
||||
{ title: "DTD", mime: "application/xml-dtd" },
|
||||
{ title: "Dylan", mime: "text/x-dylan" },
|
||||
{ title: "EBNF", mime: "text/x-ebnf", mdLanguageCode: "ebnf" },
|
||||
{ title: "ECL", mime: "text/x-ecl" },
|
||||
{ title: "edn", mime: "application/edn" },
|
||||
{ title: "Eiffel", mime: "text/x-eiffel" },
|
||||
{ title: "Elm", mime: "text/x-elm", mdLanguageCode: "elm" },
|
||||
{ title: "Embedded Javascript", mime: "application/x-ejs" },
|
||||
{ title: "Embedded Ruby", mime: "application/x-erb", mdLanguageCode: "erb" },
|
||||
{ title: "Erlang", mime: "text/x-erlang", mdLanguageCode: "erlang" },
|
||||
{ title: "Esper", mime: "text/x-esper" },
|
||||
{ title: "F#", mime: "text/x-fsharp", mdLanguageCode: "fsharp" },
|
||||
{ title: "Factor", mime: "text/x-factor" },
|
||||
{ title: "FCL", mime: "text/x-fcl" },
|
||||
{ title: "Forth", mime: "text/x-forth" },
|
||||
{ title: "Fortran", mime: "text/x-fortran", mdLanguageCode: "fortran" },
|
||||
{ title: "Gas", mime: "text/x-gas" },
|
||||
{ title: "GDScript (Godot)", mime: "text/x-gdscript" },
|
||||
{ title: "Gherkin", mime: "text/x-feature", mdLanguageCode: "gherkin" },
|
||||
{ title: "GitHub Flavored Markdown", mime: "text/x-gfm", mdLanguageCode: "markdown" },
|
||||
{ title: "Go", mime: "text/x-go", mdLanguageCode: "go", default: true },
|
||||
{ title: "Groovy", mime: "text/x-groovy", mdLanguageCode: "groovy", default: true },
|
||||
{ title: "HAML", mime: "text/x-haml", mdLanguageCode: "haml" },
|
||||
{ title: "Haskell (Literate)", mime: "text/x-literate-haskell" },
|
||||
{ title: "Haskell", mime: "text/x-haskell", mdLanguageCode: "haskell", default: true },
|
||||
{ title: "Haxe", mime: "text/x-haxe", mdLanguageCode: "haxe" },
|
||||
{ title: "HTML", mime: "text/html", mdLanguageCode: "xml", default: true },
|
||||
{ title: "HTTP", mime: "message/http", mdLanguageCode: "http", default: true },
|
||||
{ title: "HXML", mime: "text/x-hxml" },
|
||||
{ title: "IDL", mime: "text/x-idl" },
|
||||
{ title: "Java Server Pages", mime: "application/x-jsp", mdLanguageCode: "java" },
|
||||
{ title: "Java", mime: "text/x-java", mdLanguageCode: "java", default: true },
|
||||
{ title: "Jinja2", mime: "text/jinja2" },
|
||||
{ title: "JS backend", mime: "application/javascript;env=backend", mdLanguageCode: "javascript", default: true },
|
||||
{ title: "JS frontend", mime: "application/javascript;env=frontend", mdLanguageCode: "javascript", default: true },
|
||||
{ title: "JSON-LD", mime: "application/ld+json", mdLanguageCode: "json" },
|
||||
{ title: "JSON", mime: "application/json", mdLanguageCode: "json", default: true },
|
||||
{ title: "JSX", mime: "text/jsx", mdLanguageCode: "javascript" },
|
||||
{ title: "Julia", mime: "text/x-julia", mdLanguageCode: "julia" },
|
||||
{ title: "Kotlin", mime: "text/x-kotlin", mdLanguageCode: "kotlin", default: true },
|
||||
{ title: "LaTeX", mime: "text/x-latex", mdLanguageCode: "latex" },
|
||||
{ title: "LESS", mime: "text/x-less", mdLanguageCode: "less" },
|
||||
{ title: "LiveScript", mime: "text/x-livescript", mdLanguageCode: "livescript" },
|
||||
{ title: "Lua", mime: "text/x-lua", mdLanguageCode: "lua" },
|
||||
{ title: "MariaDB SQL", mime: "text/x-mariadb", mdLanguageCode: "sql" },
|
||||
{ title: "Markdown", mime: "text/x-markdown", mdLanguageCode: "markdown", default: true },
|
||||
{ title: "Mathematica", mime: "text/x-mathematica", mdLanguageCode: "mathematica" },
|
||||
{ title: "mbox", mime: "application/mbox" },
|
||||
{ title: "MIPS Assembler", mime: "text/x-asm-mips", mdLanguageCode: "mips" },
|
||||
{ title: "mIRC", mime: "text/mirc" },
|
||||
{ title: "Modelica", mime: "text/x-modelica" },
|
||||
{ title: "MS SQL", mime: "text/x-mssql", mdLanguageCode: "sql" },
|
||||
{ title: "mscgen", mime: "text/x-mscgen" },
|
||||
{ title: "msgenny", mime: "text/x-msgenny" },
|
||||
{ title: "MUMPS", mime: "text/x-mumps" },
|
||||
{ title: "MySQL", mime: "text/x-mysql", mdLanguageCode: "sql" },
|
||||
{ title: "Nix", mime: "text/x-nix", mdLanguageCode: "nix" },
|
||||
{ title: "Nginx", mime: "text/x-nginx-conf", mdLanguageCode: "nginx" },
|
||||
{ title: "NSIS", mime: "text/x-nsis", mdLanguageCode: "nsis" },
|
||||
{ title: "NTriples", mime: "application/n-triples" },
|
||||
{ title: "Objective-C", mime: "text/x-objectivec", mdLanguageCode: "objectivec" },
|
||||
{ title: "OCaml", mime: "text/x-ocaml", mdLanguageCode: "ocaml" },
|
||||
{ title: "Octave", mime: "text/x-octave" },
|
||||
{ title: "Oz", mime: "text/x-oz" },
|
||||
{ title: "Pascal", mime: "text/x-pascal", mdLanguageCode: "delphi" },
|
||||
{ title: "PEG.js", mime: "null" },
|
||||
{ title: "Perl", mime: "text/x-perl", default: true },
|
||||
{ title: "PGP", mime: "application/pgp" },
|
||||
{ title: "PHP", mime: "text/x-php", default: true },
|
||||
{ title: "Pig", mime: "text/x-pig" },
|
||||
{ title: "PLSQL", mime: "text/x-plsql", mdLanguageCode: "sql" },
|
||||
{ title: "PostgreSQL", mime: "text/x-pgsql", mdLanguageCode: "pgsql" },
|
||||
{ title: "PowerShell", mime: "application/x-powershell", mdLanguageCode: "powershell" },
|
||||
{ title: "Properties files", mime: "text/x-properties", mdLanguageCode: "properties" },
|
||||
{ title: "ProtoBuf", mime: "text/x-protobuf", mdLanguageCode: "protobuf" },
|
||||
{ title: "Pug", mime: "text/x-pug" },
|
||||
{ title: "Puppet", mime: "text/x-puppet", mdLanguageCode: "puppet" },
|
||||
{ title: "Python", mime: "text/x-python", mdLanguageCode: "python", default: true },
|
||||
{ title: "Q", mime: "text/x-q", mdLanguageCode: "q" },
|
||||
{ title: "R", mime: "text/x-rsrc", mdLanguageCode: "r" },
|
||||
{ title: "reStructuredText", mime: "text/x-rst" },
|
||||
{ title: "RPM Changes", mime: "text/x-rpm-changes" },
|
||||
{ title: "RPM Spec", mime: "text/x-rpm-spec" },
|
||||
{ title: "Ruby", mime: "text/x-ruby", mdLanguageCode: "ruby", default: true },
|
||||
{ title: "Rust", mime: "text/x-rustsrc", mdLanguageCode: "rust" },
|
||||
{ title: "SAS", mime: "text/x-sas", mdLanguageCode: "sas" },
|
||||
{ title: "Sass", mime: "text/x-sass" },
|
||||
{ title: "Scala", mime: "text/x-scala" },
|
||||
{ title: "Scheme", mime: "text/x-scheme" },
|
||||
{ title: "SCSS", mime: "text/x-scss", mdLanguageCode: "scss" },
|
||||
{ title: "Shell (bash)", mime: "text/x-sh", mdLanguageCode: "bash", default: true },
|
||||
{ title: "Sieve", mime: "application/sieve" },
|
||||
{ title: "Slim", mime: "text/x-slim" },
|
||||
{ title: "Smalltalk", mime: "text/x-stsrc", mdLanguageCode: "smalltalk" },
|
||||
{ title: "Smarty", mime: "text/x-smarty" },
|
||||
{ title: "SML", mime: "text/x-sml", mdLanguageCode: "sml" },
|
||||
{ title: "Solr", mime: "text/x-solr" },
|
||||
{ title: "Soy", mime: "text/x-soy" },
|
||||
{ title: "SPARQL", mime: "application/sparql-query" },
|
||||
{ title: "Spreadsheet", mime: "text/x-spreadsheet" },
|
||||
{ title: "SQL", mime: "text/x-sql", mdLanguageCode: "sql", default: true },
|
||||
{ title: "SQLite (Trilium)", mime: "text/x-sqlite;schema=trilium", mdLanguageCode: "sql", default: true },
|
||||
{ title: "SQLite", mime: "text/x-sqlite", mdLanguageCode: "sql" },
|
||||
{ title: "Squirrel", mime: "text/x-squirrel" },
|
||||
{ title: "sTeX", mime: "text/x-stex" },
|
||||
{ title: "Stylus", mime: "text/x-styl", mdLanguageCode: "stylus" },
|
||||
{ title: "Swift", mime: "text/x-swift", default: true },
|
||||
{ title: "SystemVerilog", mime: "text/x-systemverilog" },
|
||||
{ title: "Tcl", mime: "text/x-tcl", mdLanguageCode: "tcl" },
|
||||
{ title: "Terraform (HCL)", mime: "text/x-hcl", highlightJs: "terraform", highlightJsSource: "libraries", codeMirrorSource: "libraries/codemirror/hcl.js" },
|
||||
{ title: "Textile", mime: "text/x-textile" },
|
||||
{ title: "TiddlyWiki ", mime: "text/x-tiddlywiki" },
|
||||
{ title: "Tiki wiki", mime: "text/tiki" },
|
||||
{ title: "TOML", mime: "text/x-toml", mdLanguageCode: "ini" },
|
||||
{ title: "Tornado", mime: "text/x-tornado" },
|
||||
{ title: "troff", mime: "text/troff" },
|
||||
{ title: "TTCN_CFG", mime: "text/x-ttcn-cfg" },
|
||||
{ title: "TTCN", mime: "text/x-ttcn" },
|
||||
{ title: "Turtle", mime: "text/turtle" },
|
||||
{ title: "Twig", mime: "text/x-twig", mdLanguageCode: "twig" },
|
||||
{ title: "TypeScript-JSX", mime: "text/typescript-jsx" },
|
||||
{ title: "TypeScript", mime: "application/typescript", mdLanguageCode: "typescript" },
|
||||
{ title: "VB.NET", mime: "text/x-vb", mdLanguageCode: "vbnet" },
|
||||
{ title: "VBScript", mime: "text/vbscript", mdLanguageCode: "vbscript" },
|
||||
{ title: "Velocity", mime: "text/velocity" },
|
||||
{ title: "Verilog", mime: "text/x-verilog", mdLanguageCode: "verilog" },
|
||||
{ title: "VHDL", mime: "text/x-vhdl", mdLanguageCode: "vhdl" },
|
||||
{ title: "Vue.js Component", mime: "text/x-vue" },
|
||||
{ title: "Web IDL", mime: "text/x-webidl" },
|
||||
{ title: "XML", mime: "text/xml", mdLanguageCode: "xml", default: true },
|
||||
{ title: "XQuery", mime: "application/xquery", mdLanguageCode: "xquery" },
|
||||
{ title: "xu", mime: "text/x-xu" },
|
||||
{ title: "Yacas", mime: "text/x-yacas" },
|
||||
{ title: "YAML", mime: "text/x-yaml", mdLanguageCode: "yaml", default: true },
|
||||
{ title: "Z80", mime: "text/x-z80" }
|
||||
]);
|
||||
|
||||
let byMarkdownNameMappings: Record<string, MimeTypeDefinition> | null = null;
|
||||
|
||||
/**
|
||||
* Given a Markdown language tag (e.g. `css`), it returns a corresponding {@link MimeTypeDefinition} if found.
|
||||
*
|
||||
* If there are multiple {@link MimeTypeDefinition}s for the language tag, then only the first one is retrieved. For example for `javascript`, the "JS frontend" mime type is returned.
|
||||
*
|
||||
* @param mdLanguageCode a language tag.
|
||||
* @returns the corresponding {@link MimeTypeDefinition} if found, or `undefined` otherwise.
|
||||
*/
|
||||
export function getMimeTypeFromMarkdownName(mdLanguageCode: string) {
|
||||
if (!byMarkdownNameMappings) {
|
||||
byMarkdownNameMappings = {};
|
||||
for (const mimeType of MIME_TYPES_DICT) {
|
||||
if (mimeType.mdLanguageCode && !byMarkdownNameMappings[mimeType.mdLanguageCode]) {
|
||||
byMarkdownNameMappings[mimeType.mdLanguageCode] = mimeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return byMarkdownNameMappings[mdLanguageCode];
|
||||
}
|
@ -2,22 +2,18 @@
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/packages/commons',
|
||||
plugins: [],
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
test: {
|
||||
'watch': false,
|
||||
'globals': true,
|
||||
'environment': "node",
|
||||
'include': ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
||||
'reporters': ["default"],
|
||||
'coverage': {
|
||||
'reportsDirectory': './test-output/vitest/coverage',
|
||||
'provider': 'v8' as const,
|
||||
}
|
||||
},
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/packages/commons',
|
||||
plugins: [],
|
||||
test: {
|
||||
'watch': false,
|
||||
'globals': true,
|
||||
'environment': "node",
|
||||
'include': ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
||||
'reporters': ["default"],
|
||||
'coverage': {
|
||||
'reportsDirectory': './test-output/vitest/coverage',
|
||||
'provider': 'v8' as const,
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
11
packages/highlightjs/README.md
Normal file
11
packages/highlightjs/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# highlightjs
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build highlightjs` to build the library.
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test highlightjs` to execute the unit tests via [Vitest](https://vitest.dev/).
|
24
packages/highlightjs/eslint.config.mjs
Normal file
24
packages/highlightjs/eslint.config.mjs
Normal file
@ -0,0 +1,24 @@
|
||||
import baseConfig from "../../eslint.config.mjs";
|
||||
|
||||
export default [
|
||||
...baseConfig,
|
||||
{
|
||||
"files": [
|
||||
"**/*.json"
|
||||
],
|
||||
"rules": {
|
||||
"@nx/dependency-checks": [
|
||||
"error",
|
||||
{
|
||||
"ignoredFiles": [
|
||||
"{projectRoot}/eslint.config.{js,cjs,mjs}",
|
||||
"{projectRoot}/vite.config.{js,ts,mjs,mts}"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"languageOptions": {
|
||||
"parser": (await import('jsonc-eslint-parser'))
|
||||
}
|
||||
}
|
||||
];
|
28
packages/highlightjs/package.json
Normal file
28
packages/highlightjs/package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "@triliumnext/highlightjs",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"nx": {
|
||||
"name": "highlightjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@exercism/highlightjs-gdscript": "0.0.1",
|
||||
"@triliumnext/commons": "workspace:*",
|
||||
"highlight.js": "11.11.1",
|
||||
"highlightjs-cobol": "0.3.3",
|
||||
"highlightjs-cypher": "1.2.0"
|
||||
}
|
||||
}
|
67
packages/highlightjs/src/index.ts
Normal file
67
packages/highlightjs/src/index.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import hljs from "../node_modules/highlight.js/es/core.js";
|
||||
import { normalizeMimeTypeForCKEditor, type MimeType } from "@triliumnext/commons";
|
||||
import syntaxDefinitions from "./syntax_highlighting.js";
|
||||
import { type Theme } from "./themes.js";
|
||||
import { type HighlightOptions } from "highlight.js";
|
||||
|
||||
export { default as Themes, type Theme } from "./themes.js";
|
||||
|
||||
const registeredMimeTypes = new Set<string>();
|
||||
const unsupportedMimeTypes = new Set<string>();
|
||||
let highlightingThemeEl: HTMLStyleElement | null = null;
|
||||
|
||||
export async function ensureMimeTypes(mimeTypes: MimeType[]) {
|
||||
for (const mimeType of mimeTypes) {
|
||||
if (!mimeType.enabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const mime = normalizeMimeTypeForCKEditor(mimeType.mime);
|
||||
if (registeredMimeTypes.has(mime)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
registeredMimeTypes.add(mime);
|
||||
const loader = syntaxDefinitions[mime];
|
||||
if (!loader) {
|
||||
unsupportedMimeTypes.add(mime);
|
||||
continue;
|
||||
}
|
||||
|
||||
const language = (await loader()).default;
|
||||
hljs.registerLanguage(mime, language);
|
||||
}
|
||||
}
|
||||
|
||||
export function highlight(code: string, options: HighlightOptions) {
|
||||
if (unsupportedMimeTypes.has(options.language)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!registeredMimeTypes.has(options.language)) {
|
||||
console.warn(`Unable to find highlighting for ${options.language}.`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return hljs.highlight(code, options);
|
||||
}
|
||||
|
||||
export async function loadTheme(theme: "none" | Theme) {
|
||||
if (theme === "none") {
|
||||
if (highlightingThemeEl) {
|
||||
highlightingThemeEl.remove();
|
||||
highlightingThemeEl = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!highlightingThemeEl) {
|
||||
highlightingThemeEl = document.createElement("style");
|
||||
document.querySelector("head")?.append(highlightingThemeEl);
|
||||
}
|
||||
|
||||
const themeCss = (await theme.load()).default as string;
|
||||
highlightingThemeEl.textContent = themeCss;
|
||||
}
|
||||
|
||||
export const { highlightAuto } = hljs;
|
76
packages/highlightjs/src/languages/dylan.ts
Normal file
76
packages/highlightjs/src/languages/dylan.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import type { HLJSApi, Language, Mode } from "highlight.js";
|
||||
|
||||
/*
|
||||
* highlight.js Dylan syntax highlighting definition
|
||||
*
|
||||
* Source: https://github.com/highlightjs/highlightjs-dylan/blob/master/src/dylan.js
|
||||
*
|
||||
* @see https://github.com/highlightjs/highlight.js
|
||||
* @see https://opendylan.org/
|
||||
*
|
||||
* :TODO:
|
||||
*
|
||||
* @package: highlightjs-dylan
|
||||
* @author: Peter Hull <peterhull90@gmail.com>
|
||||
* @since: 2019-04-08
|
||||
*
|
||||
* Description: Dylan language definition
|
||||
* Category: functional
|
||||
*/
|
||||
|
||||
export default function(hljs: HLJSApi): Language {
|
||||
const DYLAN_CORE_WORDS = ["define", "end", "handler", "let", "local", "macro", "otherwise"];
|
||||
const DYLAN_BEGIN_WORDS = ["begin", "block", "case", "for", "if", "method",
|
||||
"select", "unless", "until", "while"
|
||||
];
|
||||
const DYLAN_FUNCTION_WORDS: string[] = [];
|
||||
const DYLAN_DEFINE_BODY_WORDS = ["class", "library", "method", "module"];
|
||||
const DYLAN_DEFINE_LIST_WORDS = ["constant", "variable", "domain"];
|
||||
const DYLAN_RESERVED_WORDS = ([] as string[]).concat(DYLAN_CORE_WORDS,
|
||||
DYLAN_BEGIN_WORDS,
|
||||
DYLAN_FUNCTION_WORDS,
|
||||
DYLAN_DEFINE_BODY_WORDS.map(function(word) {
|
||||
return word + '|2';
|
||||
}),
|
||||
DYLAN_DEFINE_LIST_WORDS
|
||||
);
|
||||
const DYLAN_HASH_WORDS = ["#t", "#f", "#next", "#rest", "#key", "#all-keys", "#include"];
|
||||
const DYLAN_WORD = '[a-z\-+\*/^=#!%$_><@\?~][a-z0-9\-+\*/^=#!%$_><@\?~]*';
|
||||
const KEYWORDS = {
|
||||
$pattern: DYLAN_WORD,
|
||||
literal: DYLAN_HASH_WORDS.join(" "),
|
||||
keyword: DYLAN_RESERVED_WORDS.join(" ")
|
||||
};
|
||||
const DYLAN_CODE = {
|
||||
case_insensitive: true,
|
||||
className: 'dylan',
|
||||
keywords: KEYWORDS,
|
||||
contains: [{
|
||||
className: 'class',
|
||||
begin: '<' + DYLAN_WORD + '>',
|
||||
relevance: 0
|
||||
},
|
||||
{
|
||||
className: 'symbol',
|
||||
begin: '#' + DYLAN_WORD
|
||||
},
|
||||
{
|
||||
className: 'symbol',
|
||||
begin: DYLAN_WORD + ':',
|
||||
relevance: 0
|
||||
},
|
||||
{
|
||||
className: 'string',
|
||||
begin: '\'\\\\?.',
|
||||
end: '\'',
|
||||
illegal: '.'
|
||||
},
|
||||
hljs.C_NUMBER_MODE,
|
||||
hljs.QUOTE_STRING_MODE,
|
||||
hljs.C_LINE_COMMENT_MODE,
|
||||
hljs.C_BLOCK_COMMENT_MODE
|
||||
]
|
||||
};
|
||||
|
||||
return DYLAN_CODE;
|
||||
};
|
253
packages/highlightjs/src/languages/mirc.ts
Normal file
253
packages/highlightjs/src/languages/mirc.ts
Normal file
@ -0,0 +1,253 @@
|
||||
import type { HLJSApi, Language, Mode } from "highlight.js";
|
||||
|
||||
/**
|
||||
* highlight.js mIRC Scripting Language syntax highlighting definition
|
||||
*
|
||||
* Source: https://github.com/highlightjs/highlightjs-mirc/blob/master/mirc.js
|
||||
*
|
||||
* @see https://github.com/isagalaev/highlight.js
|
||||
*
|
||||
* @package: highlightjs-mirc
|
||||
* @author: Kedyn Macedonio <mkedyn@gmail.com>
|
||||
* @author: Sven Roelse <acvxqs@icloud.com>
|
||||
*/
|
||||
|
||||
export default function hljsDefineMIRC(hljs: HLJSApi): Language {
|
||||
const COMMENT_DOC = {
|
||||
className: 'comment',
|
||||
begin: /^\x20*\/\*\*\s+/,
|
||||
end: /^\x20*\*\//,
|
||||
contains: [
|
||||
{
|
||||
className: 'doctag',
|
||||
begin: /@\w+/
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const COMMENT_BLOCK = {
|
||||
className: 'comment',
|
||||
begin: /^\x20*\/\*/,
|
||||
end: /^\x20*\*\//
|
||||
};
|
||||
|
||||
const COMMENT_LINE = {
|
||||
className: 'comment',
|
||||
begin: /(^\x20*|}\x20+|\x20+\|\x20+);/,
|
||||
end: /(\x20+\|\x20+.+|$)/,
|
||||
excludeEnd: true
|
||||
};
|
||||
|
||||
const VARIABLES = {
|
||||
className: 'variable',
|
||||
begin: /%[^\s,\)]+/
|
||||
};
|
||||
|
||||
const IDENTIFIERS = [
|
||||
{
|
||||
className: 'literal',
|
||||
begin: /\$\$?(true|false|null)\b/,
|
||||
},
|
||||
{
|
||||
className: 'built_in',
|
||||
begin: /\$\$?(\!|0|(?:[1-9](?:\d+)?-?(?:\d+)?|\?\d+)|\+|\?|(?:abook|abs|acos|active(cid|wid)?|adate|address|addtok(cs)?|agent(name|stat|ver)?|alias|and|anick|ansi2mirc|aop|appactive|appstate|asc(time)?|asin|atan2?|auto|avoice|away(msg|time)?|banmask|banlist|base|beta|bfind|bindip|bitoff|biton|bits|bnick|bvar|bytes|calc|caller|cancel|cb|cd|ceil|chan(modes|nel|types)?|chat|chr|cid|clevel|click|cmdbox|cmdline|cnick|color|com(call|chan|char|err|pact|press|val)?|cosh?|count(cs)?|crc?|creq|crlf|ctimer?|ctrlenter|date|day(light)?|dbuh|dbuw|dcc(ignore|port)|dde(name)?|debug|decode|decompress|deltok|devent|dialog|did(reg|tok|wm)?|dir=|disk|dlevel|dll(call)?|dname|dns|dqwindow|duration|ebeeps|editbox|email(addr)?|encode|envvar|error|eval(next)?|event(id|params)?|exist(s|ing)|feof|ferr|fgetc|file(=|name)?|filtered|finddirn?|findfilen?|findtok(cs)?|fline|floor|font|fopen|fread|fromeditbox|fserve|full(address|date|name|screen)|get(dir|dot|tok)?|gmt|group|halted|hash|height|hfile=?|hfind|hget|highlight|hmac|hmatch|hnick|host|hotline(pos)?|hotlink|hotp|hregex|hypot|iaddress|ial(chan)?|ibl|idle|iel|ifmatch2?|ignore|iif|iil|inellipse|ini(topic)?|in(midi|mode|mp3|paste|poly|put|(round)rect|song|stok|t(ersect)?|wave|who)|ip(type)?|iql|is(alias|bit|dde|dir|file|id|lower|tok(cs)?|upper|utf)|key(char|rpt|val)|knick|lactive(cid|wid)?|left(win|wincid|winwid)?|len|level|lf|lines?|link|lock(ed)?|lof|log(10|dir|stamp(fmt)?)?|long(fn|ip)|lower|ltimer|maddress|mask|match(key|tok(cs)?)|maxlen(s|m|l)|md5|menu(bar|context|type)?|me|mid(idir)?|mircdir|mircexe|mircini|mk(log)?fn|mknickfn|mnick|mode(first|last|spl)?|mouse|mp3|msfile|msgstamp|msgtags|naddress|network|newnick|nhnick|nick(mode)?|no(file|path|pnick|qt|tags|tify|t)?|numeric|numtok|nvnick|ok|online(server|total)?|onpoly|opnick|ord?|os|parms|parse(line|type|utf)|passivedcc|pic?|play|pnick|portable|portfree|pos(cs)?|prefix|prop|protect|puttok|qt|query|r(address|ands?)?|raw(bytes|msg)|read(ini|n)?|reg(br|errstr|ex|ml(ex)?|sub(ex)?)|rem(ote|move(cs)?|tok(cs)?)|replace(cs|xcs|x)?|reptok(cs)?|result|rgb|right|rnick|round|samepath|scid|scon|script(dir([^\s\(),><:"|?*]+)?|line)?|sdir|send|server(ip|target)?|sfile|sha1|sha(256|384|512)|shortfn|show|signal|sinh?|site|sline|snick(s)?|snotify|sock(br|err|name)?|sorttok(cs)?|sound|speak|sqrt|sreq|ssl(certsha1|certsha256)?|ssl((lib)?dll)?|ssl(ready|version)|starting|status|str(ipped|ip)?|style|submenu|switchbar|sysdir|tanh?|target|tempfn|ticks|time(out|stamp(fmt)?r|zone)?|tips?|titlebar|token|toolbar|topic|totp|treebar|trust|ulevel|ulist|unsafe|upper|uptime|url|usermode|utf(de|en)code|v1|v2|var|vc|vcmd(stat|ver)?|version|vnick|vol|wavdir|wid(th)?|wild(site|tok(cs)?)|window|wrap|xor|yes|zip)\b)/
|
||||
}
|
||||
];
|
||||
|
||||
const COMMANDS = {
|
||||
className: 'built_in',
|
||||
begin: /\b(\/)?([!.]{1,2})?(abook|ajinvite|alias|aline|ame|amsg|anick|aop|auser|autojoin|avoice|away|background|ban|bcopy|beep|bindip|bread|breplace|bset|btrunc|bunset|bwrite|channel|clear(all)?|cline|clipboard|close|cnick|color|colour|com(close|list|open|reg)|copy|creq|ctcp(reply|s)?|dcc(server)?|dde(server)?|debug|dec|describe|dialog|did(tok)?|disable|disconnect|dlevel|dline|dll|dns|dqwindow|draw(copy|dot|fill|line|pic|rect|replace|rot|save|scroll|size|text)|ebeeps|echo|editbox|emailaddr|enable|events|exit|fclose|filter|findtext|finger|firewall|flash|flist|flood|flush|flushini|fnord|font|fopen|fseek|fsend|fserve|fullname|fupdate|fwrite|ghide|gload|gmove|gopts|gplay|gpoint|gqreq|groups|gshow|gsize|gstop|gtalk|gunload|guser|hadd|hdec|hdel|help|hfree|hinc|hload|hmake|hop|hotlink|hsave|ial(clear|mark)?|identd|ignore|iline|inc|iuser|join|leave|linesep|links|list|load(buf)?|localinfo|log|logview|mdi|me|menubar|mkdir|mnick|mode|msg|noop|notice|notify|omsg|onotice|parseline|part|partall|pdcc|perform|play|playctrl|pop|privmsg|protect|proxy|pvoice|qme|qmsg|query|queryrn|quit|raw|registration|reload|remini|remote|remove|rename|renwin|reseterror|resetidle|rlevel|rline|rmdir|run|ruser|save(buf|ini)?|say|scid|scon|server|set(layer)?|showmirc|signal|sline|sock(accept|close|list|listen|mark|open|pause|read|rename|udp|write)|sound|speak|splay|sreq|strip|switchbar|timer([^\x20]+)?|timestamp|tips?|titlebar|tnick|tokenize|toolbar|tray|treebar|ulist|unload|unset(all)?|updatenl|url|uwho|var|vc(add|md|rem)|vmsg|vnotice|vol|wall(chops|voices)|window|winhelp|write(ini)?|xyzzy)\b/,
|
||||
}
|
||||
|
||||
const ALIAS_DECLARATION = {
|
||||
className: 'function',
|
||||
begin: /^alias(\x20+-l)?\x20+[^\s]+/,
|
||||
returnBegin: true,
|
||||
contains: [
|
||||
{
|
||||
className: 'type',
|
||||
begin: /^alias/
|
||||
},
|
||||
{
|
||||
className: 'symbol',
|
||||
begin: /\x20+-l/
|
||||
},
|
||||
{
|
||||
className: 'title',
|
||||
begin: /\x20+[^\s]+/,
|
||||
endsParent: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const DIALOG = {
|
||||
className: 'code',
|
||||
begin: /^dialog(\x20+-l)?\x20+[^\x20]+\x20+{$/,
|
||||
end: /^}$/,
|
||||
returnBegin: true,
|
||||
contains: [
|
||||
{
|
||||
className: 'built_in',
|
||||
begin: /^dialog(\x20+-l)?\x20+[^\x20]+\x20+/,
|
||||
end: /{$/,
|
||||
excludeEnd: true,
|
||||
returnBegin: true,
|
||||
contains: [
|
||||
{
|
||||
className: 'symbol',
|
||||
begin: /\x20+-l/,
|
||||
},
|
||||
{
|
||||
className: 'title',
|
||||
begin: /\x20+[^\x20]+\x20+/,
|
||||
end: /{$/,
|
||||
excludeEnd: true,
|
||||
endsParent: true,
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
className: 'keyword',
|
||||
begin: /^\x20+(title|icon|size|option|text|edit|button|check|radio|box|scroll|list|combo|link|tab|menu|item)\x20+/
|
||||
},
|
||||
hljs.QUOTE_STRING_MODE,
|
||||
hljs.NUMBER_MODE,
|
||||
COMMENT_BLOCK,
|
||||
COMMENT_LINE,
|
||||
VARIABLES,
|
||||
IDENTIFIERS[0],
|
||||
IDENTIFIERS[1]
|
||||
]
|
||||
};
|
||||
|
||||
const MENU = {
|
||||
className: 'code',
|
||||
begin: /^menu\x20+[^\x20]+\x20*/,
|
||||
end: /{/,
|
||||
returnBegin: true,
|
||||
excludeEnd: true,
|
||||
contains: [
|
||||
{
|
||||
className: 'built_in',
|
||||
begin: /^menu\b/,
|
||||
end: /\x20+/,
|
||||
excludeEnd: true
|
||||
},
|
||||
{
|
||||
className: 'title',
|
||||
begin: /[^\s]+\x20*/,
|
||||
endsParent: true
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const GROUPS = {
|
||||
className: 'symbol',
|
||||
begin: /^#[^\s]+\x20+(on|off|end)$/
|
||||
}
|
||||
|
||||
const EVENTS1 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:(action|notice|text):[^:]+:(\?|#[^:]*|\*):/
|
||||
};
|
||||
|
||||
const EVENTS2 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:(active|input|tabcomp):(\*|#[^:]*|\?|=|!|@[^:]*):/
|
||||
};
|
||||
|
||||
|
||||
const EVENTS3 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:(agent|appactive|(dis)?connect(fail)?|dns|exit|(un)?load|(midi|mp3|play|wave)end|nick|nosound|u?notify|ping|pong|quit|start|usermode):/
|
||||
};
|
||||
|
||||
const EVENTS4 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:((un)?ban|(de)?help|(de|server)?op|(de)?owner|(de)?voice|invite|join|kick|(server)?mode|part|rawmode|topic):(?:\*|#[^:]*):/
|
||||
};
|
||||
|
||||
const EVENTS5 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:(chat|ctcpreply|error|file(rcvd|sent)|(get|send)fail|logon|serv|signal|snotice|sock(close|listen|open|read|write)|udpread|vcmd|wallops):[^:]+:/
|
||||
};
|
||||
|
||||
const EVENTS6 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:close:(\*|\?|=|!|@[^:]*):/
|
||||
};
|
||||
|
||||
const EVENTS7 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:dccserver:(chat|send|fserve):/
|
||||
};
|
||||
|
||||
const EVENTS8 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:dialog:[^:]+:(init|close|edit|sclick|dclick|menu|scroll|mouse|rclick|drop|\*):[\d\-,\*]+:/
|
||||
};
|
||||
|
||||
const EVENTS9 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:hotlink:[^:]+:(?:\*|#[^:]*|\?|=|!|@[^:]*):/
|
||||
};
|
||||
|
||||
const EVENTS10 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:key(down|up):(\*|@[^:]*):(\*|\d+(,\d+)*):/
|
||||
};
|
||||
|
||||
const EVENTS11 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:open:(\*|\?|=|!|@[^:]*):[^:]+:/
|
||||
};
|
||||
|
||||
const EVENTS12 = {
|
||||
className: 'built_in',
|
||||
begin: /^on\x20+(me:)?[^:\x20]+:parseline:(\*|in|out):[^:]+:/
|
||||
};
|
||||
|
||||
const EVENTS13 = {
|
||||
className: 'built_in',
|
||||
begin: /^raw\x20+(me:)?[^:\x20]+:[^:]+:/
|
||||
};
|
||||
|
||||
const EVENTS14 = {
|
||||
className: 'built_in',
|
||||
begin: /^ctcp\x20+(me:)?[^:\x20]+:[^:]+:(\*|#.*|\?):/
|
||||
};
|
||||
|
||||
return {
|
||||
aliases: ['mrc'],
|
||||
keywords: 'if elseif else while break continue halt haltdef goto return returnex',
|
||||
case_insensitive: true,
|
||||
contains: [
|
||||
COMMENT_DOC,
|
||||
COMMENT_BLOCK,
|
||||
COMMENT_LINE,
|
||||
hljs.NUMBER_MODE,
|
||||
ALIAS_DECLARATION,
|
||||
DIALOG,
|
||||
MENU,
|
||||
GROUPS,
|
||||
EVENTS1,
|
||||
EVENTS2,
|
||||
EVENTS3,
|
||||
EVENTS4,
|
||||
EVENTS5,
|
||||
EVENTS6,
|
||||
EVENTS7,
|
||||
EVENTS8,
|
||||
EVENTS9,
|
||||
EVENTS10,
|
||||
EVENTS11,
|
||||
EVENTS12,
|
||||
EVENTS13,
|
||||
EVENTS14,
|
||||
VARIABLES,
|
||||
IDENTIFIERS[0],
|
||||
IDENTIFIERS[1],
|
||||
COMMANDS
|
||||
]
|
||||
};
|
||||
}
|
71
packages/highlightjs/src/languages/rpm-specfile.ts
Normal file
71
packages/highlightjs/src/languages/rpm-specfile.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import type { HLJSApi, Language, Mode } from "highlight.js";
|
||||
|
||||
/**
|
||||
* highlight.js RPM spec file syntax highlighting definition
|
||||
*
|
||||
* Source: https://github.com/highlightjs/highlightjs-rpm-specfile
|
||||
*
|
||||
* @see https://github.com/highlightjs/highlight.js
|
||||
*
|
||||
* @package highlightjs-rpm-specfile
|
||||
* @author Ryan Lerch <rlerch@redhat.com>, Neal Gompa <ngompa13@gmail.com>
|
||||
* @since 2019-07-08
|
||||
* @license magnet:?xt=urn:btih:c80d50af7d3db9be66a4d0a86db0286e4fd33292&dn=bsd-3-clause.txt BSD-3-Clause
|
||||
*
|
||||
* Language: rpm-specfile
|
||||
* Description: RPM Specfile
|
||||
* Author: Ryan Lerch <rlerch@redhat.com>
|
||||
* Contributors: Neal Gompa <ngompa13@gmail.com>
|
||||
* Category: config
|
||||
* Requires: bash.js
|
||||
* Website: https://rpm.org/
|
||||
**/
|
||||
|
||||
export default function hljsDefineRpmSpecfile(hljs: HLJSApi): Language {
|
||||
return {
|
||||
aliases: ['rpm', 'spec', 'rpm-spec', 'specfile'],
|
||||
contains: [
|
||||
hljs.COMMENT('%dnl', '$'),
|
||||
hljs.HASH_COMMENT_MODE,
|
||||
hljs.APOS_STRING_MODE,
|
||||
hljs.QUOTE_STRING_MODE,
|
||||
{
|
||||
className: "type",
|
||||
begin: /^(Name|BuildRequires|Version|Release|Epoch|Summary|Group|License|Packager|Vendor|Icon|URL|Distribution|Prefix|Patch[0-9]*|Source[0-9]*|Requires\(?[a-z]*\)?|[a-z]+Req|Obsoletes|Recommends|Suggests|Supplements|Enhances|Provides|Conflicts|RemovePathPostfixes|Build[a-z]+|[a-z]+Arch|Auto[a-z]+)(:)/,
|
||||
},
|
||||
{
|
||||
className: "keyword",
|
||||
begin: /(%)(?:package|prep|generate_buildrequires|sourcelist|patchlist|build|description|install|verifyscript|clean|changelog|check|pre[a-z]*|post[a-z]*|trigger[a-z]*|files)/,
|
||||
},
|
||||
{
|
||||
className: "link",
|
||||
begin: /(%)(if|ifarch|ifnarch|ifos|ifnos|elif|elifarch|elifos|else|endif)/,
|
||||
},
|
||||
{
|
||||
className: "link",
|
||||
begin: /%\{_/,
|
||||
end: /}/,
|
||||
},
|
||||
{
|
||||
className: "symbol",
|
||||
begin: /%\{\?/,
|
||||
end: /}/,
|
||||
},
|
||||
{
|
||||
className: "link font-weight-bold",
|
||||
begin: /%\{/,
|
||||
end: /}/,
|
||||
},
|
||||
{
|
||||
className: "link font-weight-bold",
|
||||
begin: /%/,
|
||||
end: /[ \t\n]/
|
||||
},
|
||||
{
|
||||
className: "symbol font-weight-bold",
|
||||
begin: /^\* (Mon|Tue|Wed|Thu|Fri|Sat|Sun)/,
|
||||
end: /$/,
|
||||
},
|
||||
]
|
||||
};
|
||||
}
|
96
packages/highlightjs/src/languages/terraform.ts
Normal file
96
packages/highlightjs/src/languages/terraform.ts
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* highlight.js terraform syntax highlighting definition
|
||||
*
|
||||
* @see https://github.com/highlightjs/highlight.js
|
||||
*
|
||||
* :TODO:
|
||||
*
|
||||
* @package: highlightjs-terraform
|
||||
* @author: Nikos Tsirmirakis <nikos.tsirmirakis@winopsdba.com>
|
||||
* @since: 2019-03-20
|
||||
*
|
||||
* Description: Terraform (HCL) language definition
|
||||
* Category: scripting
|
||||
*/
|
||||
|
||||
import type { HLJSApi, Language, Mode } from "highlight.js";
|
||||
|
||||
export default function hljsDefineTerraform(hljs: HLJSApi): Language {
|
||||
const NUMBERS: Mode = {
|
||||
className: 'number',
|
||||
begin: '\\b\\d+(\\.\\d+)?',
|
||||
relevance: 0
|
||||
};
|
||||
const STRINGS: Mode = {
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"',
|
||||
contains: [{
|
||||
className: 'variable',
|
||||
begin: '\\${',
|
||||
end: '\\}',
|
||||
relevance: 9,
|
||||
contains: [{
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"'
|
||||
}, {
|
||||
className: 'meta',
|
||||
begin: '[A-Za-z_0-9]*' + '\\(',
|
||||
end: '\\)',
|
||||
contains: [
|
||||
NUMBERS, {
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"',
|
||||
contains: [{
|
||||
className: 'variable',
|
||||
begin: '\\${',
|
||||
end: '\\}',
|
||||
contains: [{
|
||||
className: 'string',
|
||||
begin: '"',
|
||||
end: '"',
|
||||
contains: [{
|
||||
className: 'variable',
|
||||
begin: '\\${',
|
||||
end: '\\}'
|
||||
}]
|
||||
}, {
|
||||
className: 'meta',
|
||||
begin: '[A-Za-z_0-9]*' + '\\(',
|
||||
end: '\\)'
|
||||
}]
|
||||
}]
|
||||
},
|
||||
'self' as const]
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
return {
|
||||
aliases: ['tf', 'hcl'],
|
||||
keywords: {
|
||||
keyword: [
|
||||
"resource",
|
||||
"variable",
|
||||
"provider",
|
||||
"output",
|
||||
"locals",
|
||||
"module",
|
||||
"data",
|
||||
"terraform|10"
|
||||
],
|
||||
literal: [
|
||||
"false",
|
||||
"true",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
contains: [
|
||||
hljs.COMMENT('\\#', '$'),
|
||||
NUMBERS,
|
||||
STRINGS
|
||||
]
|
||||
}
|
||||
}
|
343
packages/highlightjs/src/languages/ttcn3.ts
Normal file
343
packages/highlightjs/src/languages/ttcn3.ts
Normal file
@ -0,0 +1,343 @@
|
||||
import type { HLJSApi, Language, Mode } from "highlight.js";
|
||||
|
||||
/* vim:set ts=2 sw=2 et: */
|
||||
|
||||
/*
|
||||
Source: https://gitea.osmocom.org/ttcn3/highlightjs-ttcn3/src/branch/master/ttcn3.js
|
||||
|
||||
Language: TTCN-3
|
||||
Description: TTCN-3 is a domain specific programming language used particularly (but not only) in the telecom domain.
|
||||
Website: http://www.ttcn-3.org/
|
||||
Category: common, protocols
|
||||
Spec: ETSI ES 201 873-1 V4.15.1
|
||||
Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de>
|
||||
*/
|
||||
|
||||
export default function(hljs: HLJSApi): Language {
|
||||
const RESERVED_WORDS = [ /* table A.3 */
|
||||
'action',
|
||||
'activate',
|
||||
'address',
|
||||
'alive',
|
||||
'all',
|
||||
'alt',
|
||||
'altstep',
|
||||
'and',
|
||||
'and4b',
|
||||
'any',
|
||||
'anytype',
|
||||
'bitstring',
|
||||
'boolean',
|
||||
'break',
|
||||
'case',
|
||||
'call',
|
||||
'catch',
|
||||
'char',
|
||||
'charstring',
|
||||
'check',
|
||||
'clear',
|
||||
'complement',
|
||||
'component',
|
||||
'connect',
|
||||
'const',
|
||||
'continue',
|
||||
'control',
|
||||
'create',
|
||||
'deactivate',
|
||||
'decmatch',
|
||||
'default',
|
||||
'disconnect',
|
||||
'display',
|
||||
'do',
|
||||
'done',
|
||||
'else',
|
||||
'encode',
|
||||
'enumerated',
|
||||
'error',
|
||||
'except',
|
||||
'exception',
|
||||
'execute',
|
||||
'extends',
|
||||
'extension',
|
||||
'external',
|
||||
'fail',
|
||||
'false',
|
||||
'float',
|
||||
'for',
|
||||
'friend',
|
||||
'from',
|
||||
'function',
|
||||
'getverdict',
|
||||
'getcall',
|
||||
'getreply',
|
||||
'goto',
|
||||
'group',
|
||||
'halt',
|
||||
'hexstring',
|
||||
'if',
|
||||
'ifpresent',
|
||||
'import',
|
||||
'in',
|
||||
'inconc',
|
||||
'infinity',
|
||||
'inout',
|
||||
'integer',
|
||||
'interleave',
|
||||
'isbound',
|
||||
'ischosen',
|
||||
'ispresent',
|
||||
'isvalue',
|
||||
'kill',
|
||||
'killed',
|
||||
'label',
|
||||
'language',
|
||||
'length',
|
||||
'log',
|
||||
'map',
|
||||
'match',
|
||||
'message',
|
||||
'mixed',
|
||||
'mod',
|
||||
'modifies',
|
||||
'module',
|
||||
'modulepar',
|
||||
'mtc',
|
||||
'noblock',
|
||||
'none',
|
||||
'not',
|
||||
'not_a_number',
|
||||
'not4b',
|
||||
'nowait',
|
||||
'null',
|
||||
'octetstring',
|
||||
'of',
|
||||
'omit',
|
||||
'on',
|
||||
'optional',
|
||||
'or',
|
||||
'or4b',
|
||||
'out',
|
||||
'override',
|
||||
'param',
|
||||
'pass',
|
||||
'pattern',
|
||||
'permutation',
|
||||
'port',
|
||||
'present',
|
||||
'private',
|
||||
'procedure',
|
||||
'public',
|
||||
'raise',
|
||||
'read',
|
||||
'receive',
|
||||
'record',
|
||||
'recursive',
|
||||
'rem',
|
||||
'repeat',
|
||||
'reply',
|
||||
'return',
|
||||
'running',
|
||||
'runs',
|
||||
'select',
|
||||
'self',
|
||||
'send',
|
||||
'sender',
|
||||
'set',
|
||||
'setencode',
|
||||
'setverdict',
|
||||
'signature',
|
||||
'start',
|
||||
'stop',
|
||||
'subset',
|
||||
'superset',
|
||||
'system',
|
||||
'template',
|
||||
'testcase',
|
||||
'timeout',
|
||||
'timer',
|
||||
'to',
|
||||
'trigger',
|
||||
'true',
|
||||
'type',
|
||||
'union',
|
||||
'universal',
|
||||
'unmap',
|
||||
'value',
|
||||
'valueof',
|
||||
'var',
|
||||
'variant',
|
||||
'verdicttype',
|
||||
'while',
|
||||
'with',
|
||||
'xor',
|
||||
'xor4b',
|
||||
];
|
||||
|
||||
const BUILT_INS = [
|
||||
'action',
|
||||
'activate',
|
||||
'any2unistr',
|
||||
'bit2hex',
|
||||
'bit2int',
|
||||
'bit2oct',
|
||||
'bit2str',
|
||||
'call',
|
||||
'catch',
|
||||
'char2int',
|
||||
'char2oct',
|
||||
'check',
|
||||
'clear',
|
||||
'complement',
|
||||
'connect',
|
||||
'create',
|
||||
'deactivate',
|
||||
'decmatch',
|
||||
'decvalue',
|
||||
'decvalue_o',
|
||||
'decvalue_unichar',
|
||||
'disconnect',
|
||||
'encode',
|
||||
'encvalue',
|
||||
'encvalue_o',
|
||||
'encvalue_unichar',
|
||||
'enum2int',
|
||||
'execute',
|
||||
'float2int',
|
||||
'get_stringencoding',
|
||||
'getcall',
|
||||
'getreply',
|
||||
'getverdict',
|
||||
'halt',
|
||||
'hex2bit',
|
||||
'hex2int',
|
||||
'hex2oct',
|
||||
'hex2str',
|
||||
'hostid',
|
||||
'int2bit',
|
||||
'int2char',
|
||||
'int2enum',
|
||||
'int2float',
|
||||
'int2hex',
|
||||
'int2oct',
|
||||
'int2str',
|
||||
'int2unichar',
|
||||
'isbound',
|
||||
'ischosen',
|
||||
'ispresent',
|
||||
'istemplatekind',
|
||||
'isvalue',
|
||||
'kill',
|
||||
'killed',
|
||||
'length',
|
||||
'lengthof',
|
||||
'log',
|
||||
'map',
|
||||
'match',
|
||||
'oct2bit',
|
||||
'oct2char',
|
||||
'oct2hex',
|
||||
'oct2int',
|
||||
'oct2str',
|
||||
'oct2unichar',
|
||||
'raise',
|
||||
'receive',
|
||||
'record',
|
||||
'regexp',
|
||||
'remove_bom',
|
||||
'replace',
|
||||
'reply',
|
||||
'rnd',
|
||||
'running',
|
||||
'send',
|
||||
'setencode',
|
||||
'setverdict',
|
||||
'sizeof',
|
||||
'start',
|
||||
'stop',
|
||||
'str2float',
|
||||
'str2hex',
|
||||
'str2int',
|
||||
'str2oct',
|
||||
'substr',
|
||||
'testcasename',
|
||||
'timeout',
|
||||
'trigger',
|
||||
'unichar2int',
|
||||
'unichar2oct',
|
||||
'unmap',
|
||||
'value',
|
||||
'valueof',
|
||||
];
|
||||
|
||||
const LITERALS = [
|
||||
'error',
|
||||
'fail',
|
||||
'false',
|
||||
'inconc',
|
||||
'infinity',
|
||||
'none',
|
||||
'null',
|
||||
'omit',
|
||||
'pass',
|
||||
'true',
|
||||
];
|
||||
|
||||
const TYPES = [
|
||||
'address',
|
||||
'anytype',
|
||||
'bitstring',
|
||||
'boolean',
|
||||
'charstring',
|
||||
'default',
|
||||
'float',
|
||||
'hexstring',
|
||||
'integer',
|
||||
'octetstring',
|
||||
'universal',
|
||||
'universal charstring',
|
||||
'verdicttype',
|
||||
];
|
||||
|
||||
const KEYWORDS = {
|
||||
keyword: RESERVED_WORDS,
|
||||
built_in: BUILT_INS,
|
||||
literal: LITERALS,
|
||||
type: TYPES,
|
||||
};
|
||||
|
||||
const STRING = {
|
||||
className: 'string',
|
||||
variants: [
|
||||
{ /* octstring */
|
||||
match: /'([a-fA-F0-9]{2}|\?|\*)*'O/,
|
||||
relevance: 10,
|
||||
},
|
||||
{ /* hexstring */
|
||||
match: /'[a-fA-F0-9\?\*]*'H/,
|
||||
relevance: 10,
|
||||
},
|
||||
{ /* bitstring */
|
||||
match: /'[01\?\*]*'B/,
|
||||
relevance: 10,
|
||||
},
|
||||
hljs.APOS_STRING_MODE,
|
||||
hljs.QUOTE_STRING_MODE,
|
||||
],
|
||||
};
|
||||
|
||||
return {
|
||||
name: 'TTCN-3',
|
||||
aliases: [
|
||||
'ttcn',
|
||||
'ttcn3',
|
||||
'ttcnpp',
|
||||
],
|
||||
keywords: KEYWORDS,
|
||||
illegal: '(\\*=|\\+=|-=)',
|
||||
contains: [
|
||||
hljs.C_BLOCK_COMMENT_MODE,
|
||||
hljs.C_LINE_COMMENT_MODE,
|
||||
STRING,
|
||||
]
|
||||
};
|
||||
}
|
20
packages/highlightjs/src/syntax_highlighting.spec.ts
Normal file
20
packages/highlightjs/src/syntax_highlighting.spec.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { describe, it } from "vitest";
|
||||
import definitions from "./syntax_highlighting.js";
|
||||
import hljs from "highlight.js";
|
||||
|
||||
describe("Syntax highlighting definitions", () => {
|
||||
it("every entry is readable", async () => {
|
||||
for (const [ mime, loader ] of Object.entries(definitions)) {
|
||||
if (loader === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const language = (await loader()).default;
|
||||
|
||||
hljs.registerLanguage(mime, language);
|
||||
hljs.highlight("Hello world", {
|
||||
language: mime
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
178
packages/highlightjs/src/syntax_highlighting.ts
Normal file
178
packages/highlightjs/src/syntax_highlighting.ts
Normal file
@ -0,0 +1,178 @@
|
||||
import { normalizeMimeTypeForCKEditor } from "@triliumnext/commons";
|
||||
import type { LanguageFn } from "highlight.js";
|
||||
|
||||
type MimeRecord = Record<string, (() => Promise<{ default: LanguageFn}>) | null>;
|
||||
|
||||
const byMimeType: MimeRecord = {
|
||||
"text/plain": () => import("highlight.js/lib/languages/plaintext"),
|
||||
"application/dart": () => import("highlight.js/lib/languages/dart"),
|
||||
"application/edn": () => import("highlight.js/lib/languages/clojure"),
|
||||
"application/javascript;env=backend": () => import("highlight.js/lib/languages/javascript"),
|
||||
"application/javascript;env=frontend": () => import("highlight.js/lib/languages/javascript"),
|
||||
"application/json": () => import("highlight.js/lib/languages/json"),
|
||||
"application/ld+json": () => import("highlight.js/lib/languages/json"),
|
||||
"application/mbox": null,
|
||||
"application/n-triples": null,
|
||||
"application/pgp": null,
|
||||
"application/sieve": null,
|
||||
"application/sparql-query": null,
|
||||
"application/typescript": () => import("highlight.js/lib/languages/typescript"),
|
||||
"application/x-aspx": null,
|
||||
"application/x-bat": () => import("highlight.js/lib/languages/dos"),
|
||||
"application/x-cypher-query": () => import("highlightjs-cypher"),
|
||||
"application/x-ejs": null,
|
||||
"application/x-erb": () => import("highlight.js/lib/languages/erb"),
|
||||
"application/x-jsp": () => import("highlight.js/lib/languages/java"),
|
||||
"application/x-powershell": () => import("highlight.js/lib/languages/powershell"),
|
||||
"application/xml-dtd": () => import("highlight.js/lib/languages/xml"),
|
||||
"application/xquery": () => import("highlight.js/lib/languages/xquery"),
|
||||
"message/http": () => import("highlight.js/lib/languages/http"),
|
||||
"text/apl": null,
|
||||
"text/coffeescript": () => import("highlight.js/lib/languages/coffeescript"),
|
||||
"text/css": () => import("highlight.js/lib/languages/css"),
|
||||
"text/html": () => import("highlight.js/lib/languages/xml"),
|
||||
"text/jinja2": () => import("highlight.js/lib/languages/django"),
|
||||
"text/jsx": () => import("highlight.js/lib/languages/javascript"),
|
||||
"text/mirc": () => import("./languages/mirc.js"),
|
||||
"text/tiki": null,
|
||||
"text/troff": null,
|
||||
"text/turtle": null,
|
||||
"text/typescript-jsx": () => import("highlight.js/lib/languages/typescript"),
|
||||
"text/vbscript": () => import("highlight.js/lib/languages/vbscript"),
|
||||
"text/velocity": null,
|
||||
"text/vnd.mermaid": null,
|
||||
"text/mermaid": null,
|
||||
"text/x-asm-mips": () => import("highlight.js/lib/languages/mipsasm"),
|
||||
"text/x-asterisk": null,
|
||||
"text/x-brainfuck": () => import("highlight.js/lib/languages/brainfuck"),
|
||||
"text/x-c++src": () => import("highlight.js/lib/languages/cpp"),
|
||||
"text/x-cassandra": null,
|
||||
"text/x-clojure": () => import("highlight.js/lib/languages/clojure"),
|
||||
"text/x-clojurescript": () => import("highlight.js/lib/languages/clojure"),
|
||||
"text/x-cmake": () => import("highlight.js/lib/languages/cmake"),
|
||||
"text/x-cobol": () => import("highlightjs-cobol"),
|
||||
"text/x-common-lisp": () => import("highlight.js/lib/languages/lisp"),
|
||||
"text/x-crystal": () => import("highlight.js/lib/languages/crystal"),
|
||||
"text/x-csharp": () => import("highlight.js/lib/languages/csharp"),
|
||||
"text/x-csrc": () => import("highlight.js/lib/languages/c"),
|
||||
"text/x-cython": null,
|
||||
"text/x-d": () => import("highlight.js/lib/languages/d"),
|
||||
"text/x-diff": () => import("highlight.js/lib/languages/diff"),
|
||||
"text/x-django": () => import("highlight.js/lib/languages/django"),
|
||||
"text/x-dockerfile": () => import("highlight.js/lib/languages/dockerfile"),
|
||||
"text/x-dylan": () => import("./languages/dylan.js"),
|
||||
"text/x-ebnf": () => import("highlight.js/lib/languages/ebnf"),
|
||||
"text/x-ecl": null,
|
||||
"text/x-eiffel": null,
|
||||
"text/x-elm": () => import("highlight.js/lib/languages/elm"),
|
||||
"text/x-erlang": () => import("highlight.js/lib/languages/erlang"),
|
||||
"text/x-esper": null,
|
||||
"text/x-factor": null,
|
||||
"text/x-fcl": null,
|
||||
"text/x-feature": () => import("highlight.js/lib/languages/gherkin"),
|
||||
"text/x-forth": null,
|
||||
"text/x-fortran": () => import("highlight.js/lib/languages/fortran"),
|
||||
"text/x-fsharp": () => import("highlight.js/lib/languages/fsharp"),
|
||||
"text/x-gas": null,
|
||||
"text/x-gdscript": () => import("@exercism/highlightjs-gdscript"),
|
||||
"text/x-gfm": () => import("highlight.js/lib/languages/markdown"),
|
||||
"text/x-go": () => import("highlight.js/lib/languages/go"),
|
||||
"text/x-groovy": () => import("highlight.js/lib/languages/groovy"),
|
||||
"text/x-gss": null,
|
||||
"text/x-haml": () => import("highlight.js/lib/languages/haml"),
|
||||
"text/x-haskell": () => import("highlight.js/lib/languages/haskell"),
|
||||
"text/x-haxe": () => import("highlight.js/lib/languages/haxe"),
|
||||
"text/x-hcl": () => import("./languages/terraform.js"),
|
||||
"text/x-hxml": null,
|
||||
"text/x-idl": null,
|
||||
"text/x-java": () => import("highlight.js/lib/languages/java"),
|
||||
"text/x-julia": () => import("highlight.js/lib/languages/julia"),
|
||||
"text/x-kotlin": () => import("highlight.js/lib/languages/kotlin"),
|
||||
"text/x-latex": () => import("highlight.js/lib/languages/latex"),
|
||||
"text/x-less": () => import("highlight.js/lib/languages/less"),
|
||||
"text/x-literate-haskell": null,
|
||||
"text/x-livescript": () => import("highlight.js/lib/languages/livescript"),
|
||||
"text/x-lua": () => import("highlight.js/lib/languages/lua"),
|
||||
"text/x-mariadb": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-markdown": () => import("highlight.js/lib/languages/markdown"),
|
||||
"text/x-mathematica": () => import("highlight.js/lib/languages/mathematica"),
|
||||
"text/x-modelica": null,
|
||||
"text/x-mscgen": null,
|
||||
"text/x-msgenny": null,
|
||||
"text/x-mssql": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-mumps": null,
|
||||
"text/x-mysql": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-nix": () => import("highlight.js/lib/languages/nix"),
|
||||
"text/x-nginx-conf": () => import("highlight.js/lib/languages/nginx"),
|
||||
"text/x-nsis": () => import("highlight.js/lib/languages/nsis"),
|
||||
"text/x-objectivec": () => import("highlight.js/lib/languages/objectivec"),
|
||||
"text/x-ocaml": () => import("highlight.js/lib/languages/ocaml"),
|
||||
"text/x-octave": null,
|
||||
"text/x-oz": null,
|
||||
"text/x-pascal": () => import("highlight.js/lib/languages/delphi"),
|
||||
"text/x-perl": () => import("highlight.js/lib/languages/perl"),
|
||||
"text/x-pgsql": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-php": () => import("highlight.js/lib/languages/php"),
|
||||
"text/x-pig": null,
|
||||
"text/x-plsql": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-properties": () => import("highlight.js/lib/languages/properties"),
|
||||
"text/x-protobuf": () => import("highlight.js/lib/languages/protobuf"),
|
||||
"text/x-pug": null,
|
||||
"text/x-puppet": () => import("highlight.js/lib/languages/puppet"),
|
||||
"text/x-python": () => import("highlight.js/lib/languages/python"),
|
||||
"text/x-q": () => import("highlight.js/lib/languages/q"),
|
||||
"text/x-rpm-changes": null,
|
||||
"text/x-rpm-spec": () => import("./languages/rpm-specfile.js"),
|
||||
"text/x-rsrc": () => import("highlight.js/lib/languages/r"),
|
||||
"text/x-rst": null,
|
||||
"text/x-ruby": () => import("highlight.js/lib/languages/ruby"),
|
||||
"text/x-rustsrc": () => import("highlight.js/lib/languages/rust"),
|
||||
"text/x-sas": () => import("highlight.js/lib/languages/sas"),
|
||||
"text/x-sass": () => import("highlight.js/lib/languages/scss"),
|
||||
"text/x-scala": () => import("highlight.js/lib/languages/scala"),
|
||||
"text/x-scheme": () => import("highlight.js/lib/languages/scheme"),
|
||||
"text/x-scss": () => import("highlight.js/lib/languages/scss"),
|
||||
"text/x-sh": () => import("highlight.js/lib/languages/bash"),
|
||||
"text/x-slim": null,
|
||||
"text/x-smarty": null,
|
||||
"text/x-sml": () => import("highlight.js/lib/languages/sml"),
|
||||
"text/x-solr": null,
|
||||
"text/x-soy": null,
|
||||
"text/x-spreadsheet": null,
|
||||
"text/x-sql": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-sqlite;schema=trilium": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-sqlite": () => import("highlight.js/lib/languages/sql"),
|
||||
"text/x-squirrel": null,
|
||||
"text/x-stex": null,
|
||||
"text/x-stsrc": () => import("highlight.js/lib/languages/smalltalk"),
|
||||
"text/x-styl": () => import("highlight.js/lib/languages/stylus"),
|
||||
"text/x-swift": () => import("highlight.js/lib/languages/swift"),
|
||||
"text/x-systemverilog": () => import("highlight.js/lib/languages/verilog"),
|
||||
"text/x-tcl": () => import("highlight.js/lib/languages/tcl"),
|
||||
"text/x-textile": null,
|
||||
"text/x-tiddlywiki": null,
|
||||
"text/x-toml": () => import("highlight.js/lib/languages/ini"),
|
||||
"text/x-tornado": null,
|
||||
"text/x-ttcn-asn": null,
|
||||
"text/x-ttcn-cfg": null,
|
||||
"text/x-ttcn": () => import("./languages/ttcn3.js"),
|
||||
"text/x-twig": () => import("highlight.js/lib/languages/twig"),
|
||||
"text/x-vb": () => import("highlight.js/lib/languages/vbnet"),
|
||||
"text/x-verilog": () => import("highlight.js/lib/languages/verilog"),
|
||||
"text/x-vhdl": () => import("highlight.js/lib/languages/vhdl"),
|
||||
"text/x-vue": null,
|
||||
"text/x-webidl": null,
|
||||
"text/x-xu": null,
|
||||
"text/x-yacas": null,
|
||||
"text/x-yaml": () => import("highlight.js/lib/languages/yaml"),
|
||||
"text/x-z80": null,
|
||||
"text/xml": () => import("highlight.js/lib/languages/xml"),
|
||||
}
|
||||
|
||||
const normalizedByMimeType: MimeRecord = {};
|
||||
for (const [mimeType, loader] of Object.entries(byMimeType)) {
|
||||
const normalizedMimeType = normalizeMimeTypeForCKEditor(mimeType);
|
||||
normalizedByMimeType[normalizedMimeType] = loader;
|
||||
}
|
||||
|
||||
export default normalizedByMimeType;
|
10
packages/highlightjs/src/themes.spec.ts
Normal file
10
packages/highlightjs/src/themes.spec.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import themeDefinitions from "./themes.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
describe("Themes", () => {
|
||||
it("all IDs don't contain spaces", () => {
|
||||
for (const id of Object.keys(themeDefinitions)) {
|
||||
expect(id).not.toMatch(/\s/);
|
||||
}
|
||||
});
|
||||
});
|
329
packages/highlightjs/src/themes.ts
Normal file
329
packages/highlightjs/src/themes.ts
Normal file
@ -0,0 +1,329 @@
|
||||
export interface Theme {
|
||||
name: string;
|
||||
load: () => Promise<{ default: typeof import("*.css", { with: { "resolution-mode": "import" } }); }>;
|
||||
}
|
||||
|
||||
const themeDefinitions: Record<string, Theme> = {
|
||||
"1c-light": {
|
||||
name: "1C (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/1c-light.css?raw")
|
||||
},
|
||||
"a11y-dark": {
|
||||
name: "a11y (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/a11y-dark.css?raw")
|
||||
},
|
||||
"a11y-light": {
|
||||
name: "a11y (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/a11y-light.css?raw")
|
||||
},
|
||||
"agate": {
|
||||
name: "Agate (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/agate.css?raw")
|
||||
},
|
||||
"an-old-hope": {
|
||||
name: "An Old Hope (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/an-old-hope.css?raw")
|
||||
},
|
||||
"androidstudio": {
|
||||
name: "Android Studio (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/androidstudio.css?raw")
|
||||
},
|
||||
"arduino-light": {
|
||||
name: "Arduino (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/arduino-light.css?raw")
|
||||
},
|
||||
"arta": {
|
||||
name: "Arta (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/arta.css?raw")
|
||||
},
|
||||
"ascetic": {
|
||||
name: "Ascetic (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/ascetic.css?raw")
|
||||
},
|
||||
"atom-one-dark-reasonable": {
|
||||
name: "Atom One with ReasonML support (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/atom-one-dark-reasonable.css?raw")
|
||||
},
|
||||
"atom-one-dark": {
|
||||
name: "Atom One (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/atom-one-dark.css?raw")
|
||||
},
|
||||
"atom-one-light": {
|
||||
name: "Atom One (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/atom-one-light.css?raw")
|
||||
},
|
||||
"brown-paper": {
|
||||
name: "Brown Paper (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/brown-paper.css?raw")
|
||||
},
|
||||
"codepen-embed": {
|
||||
name: "CodePen Embed (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/codepen-embed.css?raw")
|
||||
},
|
||||
"color-brewer": {
|
||||
name: "Color Brewer (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/color-brewer.css?raw")
|
||||
},
|
||||
"cybertopia-cherry": {
|
||||
name: "Cybertopia Cherry (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/cybertopia-cherry.css?raw")
|
||||
},
|
||||
"cybertopia-dimmer": {
|
||||
name: "Cybertopia Dimmer (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/cybertopia-dimmer.css?raw")
|
||||
},
|
||||
"cybertopia-icecap": {
|
||||
name: "Cybertopia Icecap (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/cybertopia-icecap.css?raw")
|
||||
},
|
||||
"cybertopia-saturated": {
|
||||
name: "Cybertopia Saturated (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/cybertopia-saturated.css?raw")
|
||||
},
|
||||
"dark": {
|
||||
name: "Dark",
|
||||
load: () => import("../node_modules/highlight.js/styles/dark.css?raw")
|
||||
},
|
||||
"default": {
|
||||
name: "Original highlight.js Theme (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/default.css?raw")
|
||||
},
|
||||
"devibeans": {
|
||||
name: "devibeans (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/devibeans.css?raw")
|
||||
},
|
||||
"docco": {
|
||||
name: "Docco (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/docco.css?raw")
|
||||
},
|
||||
"far": {
|
||||
name: "FAR (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/far.css?raw")
|
||||
},
|
||||
"felipec": {
|
||||
name: "FelipeC (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/felipec.css?raw")
|
||||
},
|
||||
"foundation": {
|
||||
name: "Foundation 4 Docs (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/foundation.css?raw")
|
||||
},
|
||||
"github-dark-dimmed": {
|
||||
name: "GitHub Dimmed (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/github-dark-dimmed.css?raw")
|
||||
},
|
||||
"github-dark": {
|
||||
name: "GitHub (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/github-dark.css?raw")
|
||||
},
|
||||
"github": {
|
||||
name: "GitHub (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/github.css?raw")
|
||||
},
|
||||
"gml": {
|
||||
name: "GML (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/gml.css?raw")
|
||||
},
|
||||
"googlecode": {
|
||||
name: "Google Code (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/googlecode.css?raw")
|
||||
},
|
||||
"gradient-dark": {
|
||||
name: "Gradient (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/gradient-dark.css?raw")
|
||||
},
|
||||
"gradient-light": {
|
||||
name: "Gradient (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/gradient-light.css?raw")
|
||||
},
|
||||
"grayscale": {
|
||||
name: "Grayscale (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/grayscale.css?raw")
|
||||
},
|
||||
"hybrid": {
|
||||
name: "hybrid (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/hybrid.css?raw")
|
||||
},
|
||||
"idea": {
|
||||
name: "Idea (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/idea.css?raw")
|
||||
},
|
||||
"intellij-light": {
|
||||
name: "IntelliJ (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/intellij-light.css?raw")
|
||||
},
|
||||
"ir-black": {
|
||||
name: "IR Black (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/ir-black.css?raw")
|
||||
},
|
||||
"isbl-editor-dark": {
|
||||
name: "ISBL Editor (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/isbl-editor-dark.css?raw")
|
||||
},
|
||||
"isbl-editor-light": {
|
||||
name: "ISBL Editor (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/isbl-editor-light.css?raw")
|
||||
},
|
||||
"kimbie-dark": {
|
||||
name: "Kimbie (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/kimbie-dark.css?raw")
|
||||
},
|
||||
"kimbie-light": {
|
||||
name: "Kimbie (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/kimbie-light.css?raw")
|
||||
},
|
||||
"lightfair": {
|
||||
name: "Lightfair (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/lightfair.css?raw")
|
||||
},
|
||||
"lioshi": {
|
||||
name: "Lioshi (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/lioshi.css?raw")
|
||||
},
|
||||
"magula": {
|
||||
name: "Magula (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/magula.css?raw")
|
||||
},
|
||||
"mono-blue": {
|
||||
name: "Mono Blue (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/mono-blue.css?raw")
|
||||
},
|
||||
"monokai-sublime": {
|
||||
name: "Monokai Sublime (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/monokai-sublime.css?raw")
|
||||
},
|
||||
"monokai": {
|
||||
name: "Monokai (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/monokai.css?raw")
|
||||
},
|
||||
"night-owl": {
|
||||
name: "Night Owl (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/night-owl.css?raw")
|
||||
},
|
||||
"nnfx-dark": {
|
||||
name: "NNFX (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/nnfx-dark.css?raw")
|
||||
},
|
||||
"nnfx-light": {
|
||||
name: "NNFX (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/nnfx-light.css?raw")
|
||||
},
|
||||
"nord": {
|
||||
name: "Nord (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/nord.css?raw")
|
||||
},
|
||||
"obsidian": {
|
||||
name: "Obsidian (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/obsidian.css?raw")
|
||||
},
|
||||
"panda-syntax-dark": {
|
||||
name: "Panda (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/panda-syntax-dark.css?raw")
|
||||
},
|
||||
"panda-syntax-light": {
|
||||
name: "Panda (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/panda-syntax-light.css?raw")
|
||||
},
|
||||
"paraiso-dark": {
|
||||
name: "Paraiso (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/paraiso-dark.css?raw")
|
||||
},
|
||||
"paraiso-light": {
|
||||
name: "Paraiso (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/paraiso-light.css?raw")
|
||||
},
|
||||
"pojoaque": {
|
||||
name: "Pojoaque (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/pojoaque.css?raw")
|
||||
},
|
||||
"purebasic": {
|
||||
name: "PureBasic (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/purebasic.css?raw")
|
||||
},
|
||||
"qtcreator-dark": {
|
||||
name: "Qt Creator (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/qtcreator-dark.css?raw")
|
||||
},
|
||||
"qtcreator-light": {
|
||||
name: "Qt Creator (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/qtcreator-light.css?raw")
|
||||
},
|
||||
"rainbow": {
|
||||
name: "Rainbow (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/rainbow.css?raw")
|
||||
},
|
||||
"routeros": {
|
||||
name: "RouterOS Script (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/routeros.css?raw")
|
||||
},
|
||||
"rose-pine-dawn": {
|
||||
name: "Rose Pine Dawn (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/rose-pine-dawn.css?raw")
|
||||
},
|
||||
"rose-pine-moon": {
|
||||
name: "Rose Pine Moon (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/rose-pine-moon.css?raw")
|
||||
},
|
||||
"rose-pine": {
|
||||
name: "Rose Pine (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/rose-pine.css?raw")
|
||||
},
|
||||
"school-book": {
|
||||
name: "School Book (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/school-book.css?raw")
|
||||
},
|
||||
"shades-of-purple": {
|
||||
name: "Shades of Purple (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/shades-of-purple.css?raw")
|
||||
},
|
||||
"srcery": {
|
||||
name: "Srcery (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/srcery.css?raw")
|
||||
},
|
||||
"stackoverflow-dark": {
|
||||
name: "Stack Overflow (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/stackoverflow-dark.css?raw")
|
||||
},
|
||||
"stackoverflow-light": {
|
||||
name: "Stack Overflow (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/stackoverflow-light.css?raw")
|
||||
},
|
||||
"sunburst": {
|
||||
name: "Sunburst (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/sunburst.css?raw")
|
||||
},
|
||||
"tokyo-night-dark": {
|
||||
name: "Tokyo Night (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/tokyo-night-dark.css?raw")
|
||||
},
|
||||
"tokyo-night-light": {
|
||||
name: "Tokyo Night (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/tokyo-night-light.css?raw")
|
||||
},
|
||||
"tomorrow-night-blue": {
|
||||
name: "Tomorrow Night Blue (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/tomorrow-night-blue.css?raw")
|
||||
},
|
||||
"tomorrow-night-bright": {
|
||||
name: "Tomorrow Night Bright (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/tomorrow-night-bright.css?raw")
|
||||
},
|
||||
"vs": {
|
||||
name: "Visual Studio (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/vs.css?raw")
|
||||
},
|
||||
"vs2015": {
|
||||
name: "Visual Studio 2015 (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/vs2015.css?raw")
|
||||
},
|
||||
"xcode": {
|
||||
name: "Xcode (Light)",
|
||||
load: () => import("../node_modules/highlight.js/styles/xcode.css?raw")
|
||||
},
|
||||
"xt256": {
|
||||
name: "xt256 (Dark)",
|
||||
load: () => import("../node_modules/highlight.js/styles/xt256.css?raw")
|
||||
}
|
||||
}
|
||||
|
||||
export default themeDefinitions;
|
11
packages/highlightjs/src/types.d.ts
vendored
Normal file
11
packages/highlightjs/src/types.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
declare module '@exercism/highlightjs-gdscript' {
|
||||
import { LanguageFn } from "highlight.js";
|
||||
const defineLanguage: LanguageFn;
|
||||
export default defineLanguage;
|
||||
}
|
||||
|
||||
declare module 'highlightjs-cypher' {
|
||||
import { LanguageFn } from "highlight.js";
|
||||
const defineLanguage: LanguageFn;
|
||||
export default defineLanguage;
|
||||
}
|
16
packages/highlightjs/tsconfig.json
Normal file
16
packages/highlightjs/tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../commons"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
39
packages/highlightjs/tsconfig.lib.json
Normal file
39
packages/highlightjs/tsconfig.lib.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"rootDir": "src",
|
||||
"outDir": "dist",
|
||||
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo",
|
||||
"emitDeclarationOnly": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"types": [
|
||||
"node",
|
||||
"vite/client"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../commons/tsconfig.lib.json"
|
||||
}
|
||||
],
|
||||
"exclude": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx"
|
||||
]
|
||||
}
|
36
packages/highlightjs/tsconfig.spec.json
Normal file
36
packages/highlightjs/tsconfig.spec.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/vitest",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
],
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
42
packages/highlightjs/vite.config.ts
Normal file
42
packages/highlightjs/vite.config.ts
Normal file
@ -0,0 +1,42 @@
|
||||
|
||||
import { defineConfig } from 'vite';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import * as path from 'path';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/packages/highlightjs',
|
||||
plugins: [dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') }),],
|
||||
build: {
|
||||
outDir: './dist',
|
||||
emptyOutDir: true,
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
lib: {
|
||||
// Could also be a dictionary or array of multiple entry points.
|
||||
entry: 'src/index.ts',
|
||||
name: 'highlightjs',
|
||||
fileName: 'index',
|
||||
// Change this to the formats you want to support.
|
||||
// Don't forget to update your package.json as well.
|
||||
formats: ['es' as const]
|
||||
},
|
||||
rollupOptions: {
|
||||
// External packages that should not be bundled into your library.
|
||||
external: []
|
||||
},
|
||||
},
|
||||
test: {
|
||||
'watch': false,
|
||||
'globals': true,
|
||||
'environment': "happy-dom",
|
||||
'include': ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
||||
'reporters': ["default"],
|
||||
'coverage': {
|
||||
'reportsDirectory': './test-output/vitest/coverage',
|
||||
'provider': 'v8' as const,
|
||||
}
|
||||
},
|
||||
}));
|
1156
pnpm-lock.yaml
generated
1156
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -53,6 +53,9 @@
|
||||
},
|
||||
{
|
||||
"path": "./packages/codemirror"
|
||||
},
|
||||
{
|
||||
"path": "./packages/highlightjs"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user