add code blocks syntax highlighting

This commit is contained in:
BearToCode 2023-05-07 22:05:12 +02:00
parent 6cbe0ef814
commit 1941478a80
27 changed files with 857 additions and 107 deletions

1
.npmrc
View file

@ -1 +1,2 @@
engine-strict=true
auto-install-peers=true

View file

@ -21,9 +21,11 @@
},
"type": "module",
"dependencies": {
"@cartamd/plugin-code": "workspace:^",
"@cartamd/plugin-emoji": "workspace:^",
"@cartamd/plugin-math": "workspace:^",
"@cartamd/plugin-slash": "workspace:^",
"@cartamd/plugin-emoji": "workspace:^",
"@speed-highlight/core": "^1.1.11",
"carta-md": "workspace:^",
"katex": "^0.16.7"
}

View file

@ -3,14 +3,19 @@
import { math } from '@cartamd/plugin-math';
import { slash } from '@cartamd/plugin-slash';
import { emoji } from '@cartamd/plugin-emoji';
import { code } from '@cartamd/plugin-code';
import 'carta-md/default-theme.css';
import 'highlight.js/scss/base16/tomorrow.scss';
import 'carta-md/light.css';
import '@cartamd/plugin-code/default.css';
import 'katex/dist/katex.css';
import '@cartamd/plugin-slash/default-theme.css';
import '@cartamd/plugin-emoji/default-theme.css';
const carta = new Carta({
extensions: [math(), slash(), emoji()]
extensions: [math(), slash(), emoji(), code()]
});
</script>
@ -43,7 +48,7 @@
font-variant-ligatures: normal;
}
:global(.carta-input) {
:global(.carta-input, code) {
font-family: 'Fira Code', monospace;
font-variant-ligatures: normal;
}

View file

@ -10,10 +10,8 @@
"svelte": "./dist/index.js",
"import": "./dist/index.js"
},
"./default-theme.css": {
"import": "./dist/default-theme.css",
"require": "./dist/default-theme.css"
}
"./default-theme.css": "./dist/default-theme.css",
"./light.css": "./dist/light.css"
},
"version": "0.1.6",
"scripts": {
@ -29,6 +27,7 @@
"@sveltejs/kit": "^1.0.0-next.587",
"@sveltejs/package": "^2.0.2",
"@types/marked": "^4.0.8",
"@types/prismjs": "^1.26.0",
"svelte-check": "^3.2.0",
"tslib": "^2.4.1",
"typescript": "^4.9.4",
@ -37,8 +36,8 @@
},
"type": "module",
"dependencies": {
"highlight.js": "^11.8.0",
"marked": "^4.3.0"
"marked": "^4.3.0",
"prismjs": "^1.29.0"
},
"peerDependencies": {
"svelte": "^3.54.0"

View file

@ -85,6 +85,7 @@
width: 100%;
height: 2rem;
display: flex;
flex-shrink: 0;
}
:global(.mode-split > *) {

View file

@ -9,7 +9,6 @@ import {
import { defaultIcons, type CartaIcon, type DefaultIconId } from './icons';
import { defaultPrefixes, type DefaultPrefixId, type Prefix } from './prefixes';
import type { SvelteComponentTyped } from 'svelte';
import hljs from 'highlight.js/lib/common';
/**
* Carta editor options.
@ -40,11 +39,6 @@ export interface CartaOptions {
* History (Undo/Redo) options.
*/
historyOptions?: Partial<CartaHistoryOptions>;
/**
* Code blocks syntax highlight using Prism.
* @defaults true
*/
codeHighlighting?: boolean;
}
/**
@ -147,16 +141,6 @@ export class Carta {
?.flatMap((ext) => ext.markedExtensions)
.filter((ext) => ext != null) as marked.MarkedExtension[] | undefined;
if (markedExtensions) marked.use(...markedExtensions);
// Code highlighting
if ((options?.codeHighlighting ?? true) == true)
marked.setOptions({
highlight: function (code, lang) {
if (hljs.getLanguage(lang)) return hljs.highlight(code, { language: lang }).value;
else return hljs.highlight(code, { language: 'text' }).value;
// Invalid language
}
});
}
/**
@ -164,8 +148,12 @@ export class Carta {
* @param markdown Markdown input.
* @returns Rendered html.
*/
public render(markdown: string): string {
return marked.parse(markdown);
public async render(markdown: string): Promise<string> {
return new Promise((resolve) => {
marked.parse(markdown, (e, val) => {
resolve(val);
});
});
}
/**

View file

@ -11,7 +11,7 @@
// On value updates
value = value;
debounce(() => {
renderedHtml = carta.render(value);
carta.render(value).then((rendered) => (renderedHtml = rendered));
}, carta.options?.rendererDebounce ?? 300)();
}
</script>

View file

@ -1,9 +1,8 @@
<script lang="ts">
import { onMount } from 'svelte';
import type { Carta } from '../carta';
import hljs from 'highlight.js/lib/core';
import markdown from 'highlight.js/lib/languages/markdown';
hljs.registerLanguage('markdown', markdown);
import Prism from 'prismjs';
import 'prismjs/components/prism-markdown.js';
export let carta: Carta;
export let value = '';
@ -24,7 +23,7 @@
};
const highlight = (val: string) => {
highlighted = hljs.highlight(val, { language: 'markdown', ignoreIllegals: true }).value;
highlighted = Prism.highlight(val, Prism.languages.markdown, 'language-markdown');
};
$: highlight(value);

View file

@ -0,0 +1,431 @@
/**
* One Light theme for prism.js
* Based on Atom's One Light theme: https://github.com/atom/atom/tree/master/packages/one-light-syntax
*/
/**
* One Light colours (accurate as of commit eb064bf on 19 Feb 2021)
* From colors.less
* --mono-1: hsl(230, 8%, 24%);
* --mono-2: hsl(230, 6%, 44%);
* --mono-3: hsl(230, 4%, 64%)
* --hue-1: hsl(198, 99%, 37%);
* --hue-2: hsl(221, 87%, 60%);
* --hue-3: hsl(301, 63%, 40%);
* --hue-4: hsl(119, 34%, 47%);
* --hue-5: hsl(5, 74%, 59%);
* --hue-5-2: hsl(344, 84%, 43%);
* --hue-6: hsl(35, 99%, 36%);
* --hue-6-2: hsl(35, 99%, 40%);
* --syntax-fg: hsl(230, 8%, 24%);
* --syntax-bg: hsl(230, 1%, 98%);
* --syntax-gutter: hsl(230, 1%, 62%);
* --syntax-guide: hsla(230, 8%, 24%, 0.2);
* --syntax-accent: hsl(230, 100%, 66%);
* From syntax-variables.less
* --syntax-selection-color: hsl(230, 1%, 90%);
* --syntax-gutter-background-color-selected: hsl(230, 1%, 90%);
* --syntax-cursor-line: hsla(230, 8%, 24%, 0.05);
*/
code[class*='language-'],
pre[class*='language-'] {
background: hsl(230, 1%, 98%);
color: hsl(230, 8%, 24%);
font-family: 'Fira Code', 'Fira Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
line-height: 1.5;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Selection */
code[class*='language-']::-moz-selection,
code[class*='language-'] *::-moz-selection,
pre[class*='language-'] *::-moz-selection {
background: hsl(230, 1%, 90%);
color: inherit;
}
code[class*='language-']::selection,
code[class*='language-'] *::selection,
pre[class*='language-'] *::selection {
background: hsl(230, 1%, 90%);
color: inherit;
}
/* Code blocks */
pre[class*='language-'] {
padding: 1em;
margin: 0.5em 0;
overflow: auto;
border-radius: 0.3em;
}
/* Inline code */
:not(pre) > code[class*='language-'] {
padding: 0.2em 0.3em;
border-radius: 0.3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.cdata {
color: hsl(230, 4%, 64%);
}
.token.doctype,
.token.punctuation,
.token.entity {
color: hsl(230, 8%, 24%);
}
.token.attr-name,
.token.class-name,
.token.boolean,
.token.constant,
.token.number,
.token.atrule {
color: hsl(35, 99%, 36%);
}
.token.keyword {
color: hsl(301, 63%, 40%);
}
.token.property,
.token.tag,
.token.symbol,
.token.deleted,
.token.important {
color: hsl(5, 74%, 59%);
}
.token.selector,
.token.string,
.token.char,
.token.builtin,
.token.inserted,
.token.regex,
.token.attr-value,
.token.attr-value > .token.punctuation {
color: hsl(119, 34%, 47%);
}
.token.variable,
.token.operator,
.token.function {
color: hsl(221, 87%, 60%);
}
.token.url {
color: hsl(198, 99%, 37%);
}
/* HTML overrides */
.token.attr-value > .token.punctuation.attr-equals,
.token.special-attr > .token.attr-value > .token.value.css {
color: hsl(230, 8%, 24%);
}
/* CSS overrides */
.language-css .token.selector {
color: hsl(5, 74%, 59%);
}
.language-css .token.property {
color: hsl(230, 8%, 24%);
}
.language-css .token.function,
.language-css .token.url > .token.function {
color: hsl(198, 99%, 37%);
}
.language-css .token.url > .token.string.url {
color: hsl(119, 34%, 47%);
}
.language-css .token.important,
.language-css .token.atrule .token.rule {
color: hsl(301, 63%, 40%);
}
/* JS overrides */
.language-javascript .token.operator {
color: hsl(301, 63%, 40%);
}
.language-javascript
.token.template-string
> .token.interpolation
> .token.interpolation-punctuation.punctuation {
color: hsl(344, 84%, 43%);
}
/* JSON overrides */
.language-json .token.operator {
color: hsl(230, 8%, 24%);
}
.language-json .token.null.keyword {
color: hsl(35, 99%, 36%);
}
/* MD overrides */
.language-markdown .token.url,
.language-markdown .token.url > .token.operator,
.language-markdown .token.url-reference.url > .token.string {
color: hsl(230, 8%, 24%);
}
.language-markdown .token.url > .token.content {
color: hsl(221, 87%, 60%);
}
.language-markdown .token.url > .token.url,
.language-markdown .token.url-reference.url {
color: hsl(198, 99%, 37%);
}
.language-markdown .token.blockquote.punctuation,
.language-markdown .token.hr.punctuation {
color: hsl(230, 4%, 64%);
font-style: italic;
}
.language-markdown .token.code-snippet {
color: hsl(119, 34%, 47%);
}
.language-markdown .token.bold .token.content {
color: hsl(35, 99%, 36%);
}
.language-markdown .token.italic .token.content {
color: hsl(301, 63%, 40%);
}
.language-markdown .token.strike .token.content,
.language-markdown .token.strike .token.punctuation,
.language-markdown .token.list.punctuation,
.language-markdown .token.title.important > .token.punctuation {
color: hsl(5, 74%, 59%);
}
/* General */
.token.bold {
font-weight: bold;
}
.token.comment,
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.token.namespace {
opacity: 0.8;
}
/* Plugin overrides */
/* Selectors should have higher specificity than those in the plugins' default stylesheets */
/* Show Invisibles plugin overrides */
.token.token.tab:not(:empty):before,
.token.token.cr:before,
.token.token.lf:before,
.token.token.space:before {
color: hsla(230, 8%, 24%, 0.2);
}
/* Toolbar plugin overrides */
/* Space out all buttons and move them away from the right edge of the code block */
div.code-toolbar > .toolbar.toolbar > .toolbar-item {
margin-right: 0.4em;
}
/* Styling the buttons */
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span {
background: hsl(230, 1%, 90%);
color: hsl(230, 6%, 44%);
padding: 0.1em 0.4em;
border-radius: 0.3em;
}
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus {
background: hsl(230, 1%, 78%); /* custom: darken(--syntax-bg, 20%) */
color: hsl(230, 8%, 24%);
}
/* Line Highlight plugin overrides */
/* The highlighted line itself */
.line-highlight.line-highlight {
background: hsla(230, 8%, 24%, 0.05);
}
/* Default line numbers in Line Highlight plugin */
.line-highlight.line-highlight:before,
.line-highlight.line-highlight[data-end]:after {
background: hsl(230, 1%, 90%);
color: hsl(230, 8%, 24%);
padding: 0.1em 0.6em;
border-radius: 0.3em;
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */
}
/* Hovering over a linkable line number (in the gutter area) */
/* Requires Line Numbers plugin as well */
pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before {
background-color: hsla(230, 8%, 24%, 0.05);
}
/* Line Numbers and Command Line plugins overrides */
/* Line separating gutter from coding area */
.line-numbers.line-numbers .line-numbers-rows,
.command-line .command-line-prompt {
border-right-color: hsla(230, 8%, 24%, 0.2);
}
/* Stuff in the gutter */
.line-numbers .line-numbers-rows > span:before,
.command-line .command-line-prompt > span:before {
color: hsl(230, 1%, 62%);
}
/* Match Braces plugin overrides */
/* Note: Outline colour is inherited from the braces */
.rainbow-braces .token.token.punctuation.brace-level-1,
.rainbow-braces .token.token.punctuation.brace-level-5,
.rainbow-braces .token.token.punctuation.brace-level-9 {
color: hsl(5, 74%, 59%);
}
.rainbow-braces .token.token.punctuation.brace-level-2,
.rainbow-braces .token.token.punctuation.brace-level-6,
.rainbow-braces .token.token.punctuation.brace-level-10 {
color: hsl(119, 34%, 47%);
}
.rainbow-braces .token.token.punctuation.brace-level-3,
.rainbow-braces .token.token.punctuation.brace-level-7,
.rainbow-braces .token.token.punctuation.brace-level-11 {
color: hsl(221, 87%, 60%);
}
.rainbow-braces .token.token.punctuation.brace-level-4,
.rainbow-braces .token.token.punctuation.brace-level-8,
.rainbow-braces .token.token.punctuation.brace-level-12 {
color: hsl(301, 63%, 40%);
}
/* Diff Highlight plugin overrides */
/* Taken from https://github.com/atom/github/blob/master/styles/variables.less */
pre.diff-highlight > code .token.token.deleted:not(.prefix),
pre > code.diff-highlight .token.token.deleted:not(.prefix) {
background-color: hsla(353, 100%, 66%, 0.15);
}
pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection {
background-color: hsla(353, 95%, 66%, 0.25);
}
pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection {
background-color: hsla(353, 95%, 66%, 0.25);
}
pre.diff-highlight > code .token.token.inserted:not(.prefix),
pre > code.diff-highlight .token.token.inserted:not(.prefix) {
background-color: hsla(137, 100%, 55%, 0.15);
}
pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection {
background-color: hsla(135, 73%, 55%, 0.25);
}
pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
background-color: hsla(135, 73%, 55%, 0.25);
}
/* Previewers plugin overrides */
/* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-light-ui */
/* Border around popup */
.prism-previewer.prism-previewer:before,
.prism-previewer-gradient.prism-previewer-gradient div {
border-color: hsl(0, 0, 95%);
}
/* Angle and time should remain as circles and are hence not included */
.prism-previewer-color.prism-previewer-color:before,
.prism-previewer-gradient.prism-previewer-gradient div,
.prism-previewer-easing.prism-previewer-easing:before {
border-radius: 0.3em;
}
/* Triangles pointing to the code */
.prism-previewer.prism-previewer:after {
border-top-color: hsl(0, 0, 95%);
}
.prism-previewer-flipped.prism-previewer-flipped.after {
border-bottom-color: hsl(0, 0, 95%);
}
/* Background colour within the popup */
.prism-previewer-angle.prism-previewer-angle:before,
.prism-previewer-time.prism-previewer-time:before,
.prism-previewer-easing.prism-previewer-easing {
background: hsl(0, 0%, 100%);
}
/* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */
/* For time, this is the alternate colour */
.prism-previewer-angle.prism-previewer-angle circle,
.prism-previewer-time.prism-previewer-time circle {
stroke: hsl(230, 8%, 24%);
stroke-opacity: 1;
}
/* Stroke colours of the handle, direction point, and vector itself */
.prism-previewer-easing.prism-previewer-easing circle,
.prism-previewer-easing.prism-previewer-easing path,
.prism-previewer-easing.prism-previewer-easing line {
stroke: hsl(230, 8%, 24%);
}
/* Fill colour of the handle */
.prism-previewer-easing.prism-previewer-easing circle {
fill: transparent;
}

View file

@ -3,7 +3,7 @@
import { Carta } from '$lib/internal/carta';
import '$lib/default-theme.css';
import 'highlight.js/scss/base16/tomorrow.scss';
import '$lib/light.css';
const carta = new Carta();
</script>

View file

@ -0,0 +1,33 @@
{
"name": "@cartamd/plugin-code",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/src/index.d.ts",
"exports": {
".": "./dist/index.js",
"./*.css": "./dist/*.css"
},
"scripts": {
"build": "vite build"
},
"devDependencies": {
"@types/marked": "^4.0.8",
"carta-md": "workspace:*",
"tslib": "^2.5.0",
"typescript": "^5.0.4",
"vite": "^4.3.2",
"vite-plugin-dts": "^2.3.0",
"vite-plugin-dynamic-import": "^1.3.4"
},
"peerDependencies": {
"carta-md": "^0.1.3",
"marked": "^4.3.0"
},
"files": [
"dist"
],
"version": "0.1.6",
"dependencies": {
"@speed-highlight/core": "^1.1.11"
}
}

View file

@ -0,0 +1,41 @@
@import 'default.css';
[class*='shj-lang-'] {
color: #f8f8f2;
background: #1a1a1c;
}
[class*='shj-lang-']:before {
color: #6f9aff;
}
.shj-syn-deleted,
.shj-syn-err,
.shj-syn-var {
color: #ff5261;
}
.shj-syn-section,
.shj-syn-kwd {
color: #ff7cc6;
}
.shj-syn-class {
color: #eab07c;
}
.shj-numbers,
.shj-syn-cmnt {
color: #7d828b;
}
.shj-syn-insert,
.shj-syn-type,
.shj-syn-func,
.shj-syn-bool {
color: #71d58a;
}
.shj-syn-num {
color: #b581fd;
}
.shj-syn-oper {
color: #80c6ff;
}
.shj-syn-str {
color: #4dacfa;
}

View file

@ -0,0 +1,108 @@
.carta-renderer code {
white-space: pre;
border-radius: 10px;
color: #112;
text-shadow: none;
/* line-height: 24px; */
box-sizing: border-box;
}
.carta-renderer code > div {
padding: 2px 20px;
max-width: min(100%, 100vw);
}
.shj-inline {
margin: 0;
padding: 2px 5px;
display: inline-block;
border-radius: 5px;
}
.carta-renderer code::selection,
.carta-renderer code ::selection {
background: #bdf5;
}
.carta-renderer code > div {
display: flex;
overflow: auto;
}
.carta-renderer code > div :last-child {
flex: 1;
outline: none;
}
.shj-numbers {
padding-left: 5px;
counter-reset: line;
}
.shj-numbers div {
padding-right: 5px;
}
.shj-numbers div::before {
color: #999;
display: block;
content: counter(line);
opacity: 0.5;
text-align: right;
margin-right: 5px;
counter-increment: line;
}
.shj-syn-cmnt {
font-style: italic;
}
.shj-syn-err,
.shj-syn-kwd {
color: #e16;
}
.shj-syn-num,
.shj-syn-class {
color: #f60;
}
.shj-numbers,
.shj-syn-cmnt {
color: #999;
}
.shj-syn-insert,
.shj-syn-str {
color: #7d8;
}
.shj-syn-bool {
color: #3bf;
}
.shj-syn-type,
.shj-syn-oper {
color: #5af;
}
.shj-syn-section,
.shj-syn-func {
color: #84f;
}
.shj-syn-deleted,
.shj-syn-var {
color: #f44;
}
.shj-oneline {
padding: 12px 10px;
}
.shj-lang-http.shj-oneline .shj-syn-kwd {
background: #25f;
color: #fff;
padding: 5px 7px;
border-radius: 5px;
}
.shj-multiline.shj-mode-header {
padding: 20px;
}
.shj-multiline.shj-mode-header:before {
content: attr(data-lang);
color: #58f;
display: block;
padding: 10px 20px;
background: #58f3;
border-radius: 5px;
margin-bottom: 20px;
}

View file

@ -0,0 +1,58 @@
import type { CartaExtension } from 'carta-md';
import { highlightText } from '@speed-highlight/core';
import { detectLanguage } from '@speed-highlight/core/detect.js';
interface CodeExtensionOptions {
/**
* Default language when none is provided.
*/
defaultLanguage?: string;
/**
* Whether to autodetect a language when none is provided.
* Overwritten by `defaultLanguage`.
*/
autoDetect?: string;
/**
* Line numbering.
* @defaults true.
*/
lineNumbering?: boolean;
}
/**
* Carta code highlighting plugin. Themes available at https://github.com/speed-highlight/core/tree/main/dist/themes.
*/
export const code = (options?: CodeExtensionOptions): CartaExtension => {
return {
markedExtensions: [
{
langPrefix: 'shj-lang-',
highlight(code, lang, cb) {
(async () => {
lang ||= options?.defaultLanguage ?? '';
if (lang) {
try {
const highlighted = await highlightText(code, lang, true, {
hideLineNumbers: options?.lineNumbering ?? false
});
cb && cb(undefined, highlighted);
return;
} catch (_) {
/* empty */
}
}
if (options?.autoDetect ?? true) {
const detected = detectLanguage(code);
const highlighted = await highlightText(code, detected, true, {
hideLineNumbers: !(options?.lineNumbering ?? true)
});
cb && cb(undefined, highlighted);
return;
}
cb && cb(undefined, 'basic');
})();
}
}
]
};
};

View file

@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"allowJs": true,
"strict": false,
"typeRoots": ["./node_modules/@types", "./typings"],
"baseUrl": "./",
"paths": {
"*": ["*", "./typings/*"]
}
},
"include": ["./src", "./typings/**/*.d.ts"],
"references": [{ "path": "../carta-md" }]
}

View file

@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler"
},
"include": ["vite.config.ts"]
}

36
packages/plugin-code/typings/index.d.ts vendored Normal file
View file

@ -0,0 +1,36 @@
declare module '@speed-highlight/core' {
export type ShjLanguage = string;
export type ShjOptions = {
hideLineNumbers?: boolean;
};
/**
* @function highlightText
* @async
* Highlight a string passed as argument and return it
* @example
* elm.innerHTML = await highlightText(code, 'js');
* @param {String} src The code
* @param {ShjLanguage} lang The language of the code
* @param {Boolean} [multiline=true] If it is multiline, it will add a wrapper for the line numbering and header
* @param {ShjOptions} [opt={}] Customization options
* @returns {Promise<String>} The highlighted string
*/
export function highlightText(
src: string,
lang: ShjLanguage,
multiline?: boolean,
opt?: ShjOptions
): Promise<string>;
}
declare module '@speed-highlight/core/detect.js' {
/**
* @function detectLanguage
* Try to find the language the given code belong to
* @param {String} code The code
* @returns {ShjLanguage} The language of the code
*/
export function detectLanguage(code: string): ShjLanguage;
}

View file

@ -0,0 +1,23 @@
import { defineConfig } from 'vite';
import { resolve } from 'path';
import dts from 'vite-plugin-dts';
import dynamicImport from 'vite-plugin-dynamic-import';
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'plugin-code',
fileName: 'index'
}
},
plugins: [
dts(),
dynamicImport({
filter(id) {
if (id.includes('@speed-highlight/core')) return true;
}
})
]
});

View file

@ -31,14 +31,12 @@
"tslib": "^2.5.0",
"typescript": "^5.0.2",
"vite": "^4.3.2",
"vite-plugin-dts": "^2.3.0"
"vite-plugin-dts": "^2.3.0",
"node-emoji": "^1.11.0",
"bezier-easing": "^2.1.0"
},
"peerDependencies": {
"carta-md": "^0.1.6",
"marked": "^4.3.0"
},
"dependencies": {
"bezier-easing": "^2.1.0",
"node-emoji": "^1.11.0"
}
}

View file

@ -42,7 +42,7 @@
function handleKeyDown(e: KeyboardEvent) {
if (!carta.input) return;
if (visible) {
if (e.key === ' ' || (e.key === 'Backspace' && filter === '')) {
if (e.key === ' ' || ((e.key === 'Backspace' || e.key === 'Escape') && filter === '')) {
// Close
visible = false;
} else if (e.key === 'Enter') {

View file

@ -10,6 +10,9 @@ export default defineConfig({
entry: resolve(__dirname, 'src/lib/index.ts'),
name: 'plugin-emoji',
fileName: 'index'
},
rollupOptions: {
external: []
}
},
plugins: [svelte(), dts(), hmr()]

View file

@ -29,12 +29,10 @@
"tslib": "^2.5.0",
"typescript": "^5.0.2",
"vite": "^4.3.2",
"vite-plugin-dts": "^2.3.0"
"vite-plugin-dts": "^2.3.0",
"bezier-easing": "^2.1.0"
},
"peerDependencies": {
"carta-md": "^0.1.6"
},
"dependencies": {
"bezier-easing": "^2.1.0"
}
}

View file

@ -41,7 +41,7 @@
function handleKeyDown(e: KeyboardEvent) {
if (!carta.input) return;
if (visible) {
if (e.key === ' ' || (e.key === 'Backspace' && filter === '')) {
if (e.key === ' ' || ((e.key === 'Backspace' || e.key === 'Escape') && filter === '')) {
// Close
visible = false;
} else if (e.key === 'Enter') {

View file

@ -10,6 +10,9 @@ export default defineConfig({
entry: resolve(__dirname, 'src/lib/index.ts'),
name: 'plugin-slash',
fileName: 'index'
},
rollupOptions: {
external: []
}
},
plugins: [svelte(), dts(), hmr()]

View file

@ -3,6 +3,7 @@
{ "path": "carta-md" },
{ "path": "plugin-math" },
{ "path": "plugin-emoji" },
{ "path": "plugin-slash" }
{ "path": "plugin-slash" },
{ "path": "plugin-code" }
]
}

117
pnpm-lock.yaml generated
View file

@ -40,6 +40,9 @@ importers:
demo:
dependencies:
'@cartamd/plugin-code':
specifier: workspace:^
version: link:../packages/plugin-code
'@cartamd/plugin-emoji':
specifier: workspace:^
version: link:../packages/plugin-emoji
@ -49,6 +52,9 @@ importers:
'@cartamd/plugin-slash':
specifier: workspace:^
version: link:../packages/plugin-slash
'@speed-highlight/core':
specifier: ^1.1.11
version: 1.1.11
carta-md:
specifier: workspace:^
version: link:../packages/carta-md
@ -83,12 +89,12 @@ importers:
packages/carta-md:
dependencies:
highlight.js:
specifier: ^11.8.0
version: 11.8.0
marked:
specifier: ^4.3.0
version: 4.3.0
prismjs:
specifier: ^1.29.0
version: 1.29.0
svelte:
specifier: ^3.54.0
version: 3.55.1
@ -122,7 +128,38 @@ importers:
version: 5.0.1(typescript@4.9.4)
vite:
specifier: ^4.0.0
version: 4.3.3
version: 4.3.3(@types/node@18.16.3)
packages/plugin-code:
dependencies:
'@speed-highlight/core':
specifier: ^1.1.11
version: 1.1.11
marked:
specifier: ^4.3.0
version: 4.3.0
devDependencies:
'@types/marked':
specifier: ^4.0.8
version: 4.0.8
carta-md:
specifier: workspace:*
version: link:../carta-md
tslib:
specifier: ^2.5.0
version: 2.5.0
typescript:
specifier: ^5.0.4
version: 5.0.4
vite:
specifier: ^4.3.2
version: 4.3.3(@types/node@18.16.3)
vite-plugin-dts:
specifier: ^2.3.0
version: 2.3.0(@types/node@18.16.3)(vite@4.3.3)
vite-plugin-dynamic-import:
specifier: ^1.3.4
version: 1.3.4
packages/plugin-emoji:
dependencies:
@ -192,25 +229,6 @@ importers:
specifier: ^5.0.4
version: 5.0.4
packages/plugin-prism:
dependencies:
marked:
specifier: ^4.3.0
version: 4.3.0
prismjs:
specifier: ^1.29.0
version: 1.29.0
devDependencies:
'@types/marked':
specifier: ^4.0.8
version: 4.0.8
carta-md:
specifier: workspace:*
version: link:../carta-md
typescript:
specifier: ^5.0.4
version: 5.0.4
packages/plugin-slash:
dependencies:
bezier-easing:
@ -669,6 +687,10 @@ packages:
string-argv: 0.3.1
dev: true
/@speed-highlight/core@1.1.11:
resolution: {integrity: sha512-KtUCQahL7WjK8zKEhWwzBa/7t6wimmOF9BFS/gIbVE48BwNEK7NafOkwzfYRF7D6RjENsP2aJDZRANwHDncqnw==}
dev: false
/@sveltejs/adapter-auto@1.0.3(@sveltejs/kit@1.15.9):
resolution: {integrity: sha512-hc7O12YQqvZ1CD4fo1gMJuPzBZvuoG5kwxb2RRoz4fVoB8B2vuPO2cY751Ln0G6T/HMrAf8kCqw6Pg+wbxcstw==}
peerDependencies:
@ -710,7 +732,7 @@ packages:
svelte: 3.55.1
tiny-glob: 0.2.9
undici: 5.22.0
vite: 4.3.3
vite: 4.3.3(@types/node@18.16.3)
transitivePeerDependencies:
- supports-color
dev: true
@ -763,7 +785,7 @@ packages:
magic-string: 0.30.0
svelte: 3.55.1
svelte-hmr: 0.15.1(svelte@3.55.1)
vite: 4.3.3
vite: 4.3.3(@types/node@18.16.3)
vitefu: 0.2.4(vite@4.3.3)
transitivePeerDependencies:
- supports-color
@ -1367,6 +1389,10 @@ packages:
dev: true
optional: true
/es-module-lexer@1.2.1:
resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==}
dev: true
/es6-promise@3.3.1:
resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
dev: true
@ -1730,11 +1756,6 @@ packages:
function-bind: 1.1.1
dev: true
/highlight.js@11.8.0:
resolution: {integrity: sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==}
engines: {node: '>=12.0.0'}
dev: false
/human-signals@4.3.1:
resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==}
engines: {node: '>=14.18.0'}
@ -3270,36 +3291,12 @@ packages:
- supports-color
dev: true
/vite@4.3.3:
resolution: {integrity: sha512-MwFlLBO4udZXd+VBcezo3u8mC77YQk+ik+fbc0GZWGgzfbPP+8Kf0fldhARqvSYmtIWoAJ5BXPClUbMTlqFxrA==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
peerDependencies:
'@types/node': '>= 14'
less: '*'
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
/vite-plugin-dynamic-import@1.3.4:
resolution: {integrity: sha512-Emg0MSQMqkqLWPWBj6L9ErjnAOFInAjCB5LLl/t8BIZMjbwrrOP8x+Ni1Fs+nujYTBPhrLlfUZB64VvSqSEKCQ==}
dependencies:
esbuild: 0.17.18
postcss: 8.4.23
rollup: 3.21.2
optionalDependencies:
fsevents: 2.3.2
acorn: 8.8.2
es-module-lexer: 1.2.1
fast-glob: 3.2.12
dev: true
/vite@4.3.3(@types/node@18.16.3):
@ -3343,7 +3340,7 @@ packages:
vite:
optional: true
dependencies:
vite: 4.3.3
vite: 4.3.3(@types/node@18.16.3)
dev: true
/wcwidth@1.0.1:

View file

@ -9,4 +9,4 @@ export const execAsync = util.promisify(childProcess.exec);
/**
* List of all the packages.
*/
export const packages = ['carta-md', 'plugin-math', 'plugin-slash', 'plugin-emoji'];
export const packages = ['carta-md', 'plugin-math', 'plugin-slash', 'plugin-emoji', 'plugin-code'];