opentui-markdown-render 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +27 -0
- package/README.md +223 -2
- package/bin/otmd.tsx +99 -0
- package/native/Cargo.lock +3708 -0
- package/native/Cargo.toml +28 -0
- package/native/build.rs +3 -0
- package/native/src/lib.rs +880 -0
- package/package.json +67 -4
- package/prebuilds/linux-x64-gnu/opentui_markdown_render.node +4 -0
- package/src/app.tsx +180 -0
- package/src/cli.ts +63 -0
- package/src/config/index.ts +46 -0
- package/src/config/load.ts +337 -0
- package/src/config/resolve.ts +36 -0
- package/src/config/theme.ts +110 -0
- package/src/config/types.ts +105 -0
- package/src/core/document.ts +44 -0
- package/src/core/frame.ts +144 -0
- package/src/core/image.ts +9 -0
- package/src/core/index.ts +6 -0
- package/src/core/layout.ts +27 -0
- package/src/core/math.ts +170 -0
- package/src/core/parse.ts +208 -0
- package/src/core/tables.ts +58 -0
- package/src/graphics.ts +85 -0
- package/src/headings.ts +77 -0
- package/src/index.ts +107 -0
- package/src/math/index.ts +86 -0
- package/src/math/native.ts +39 -0
- package/src/math/renderer.ts +84 -0
- package/src/math/validate.ts +44 -0
- package/src/media.tsx +267 -0
- package/src/merman/class/dagre-layout.ts +171 -0
- package/src/merman/class/diagram.ts +8 -0
- package/src/merman/class/drawing.ts +343 -0
- package/src/merman/class/labels.ts +38 -0
- package/src/merman/class/layout.ts +531 -0
- package/src/merman/class/parser.ts +308 -0
- package/src/merman/class/render-grid.ts +18 -0
- package/src/merman/class/style.ts +27 -0
- package/src/merman/class/types.ts +57 -0
- package/src/merman/core/canvas.ts +228 -0
- package/src/merman/core/color/style.ts +56 -0
- package/src/merman/core/drawing.ts +307 -0
- package/src/merman/core/geometry.ts +347 -0
- package/src/merman/core/mermaid.ts +38 -0
- package/src/merman/core/render-grid.ts +51 -0
- package/src/merman/core/spatial.ts +243 -0
- package/src/merman/core/text-lines.ts +32 -0
- package/src/merman/core/text.ts +44 -0
- package/src/merman/detect.ts +19 -0
- package/src/merman/diagnostics.ts +16 -0
- package/src/merman/diagram.ts +268 -0
- package/src/merman/flowchart/drawing.ts +433 -0
- package/src/merman/flowchart/labels.ts +144 -0
- package/src/merman/flowchart/layout.ts +1057 -0
- package/src/merman/flowchart/options.ts +12 -0
- package/src/merman/flowchart/parser.ts +477 -0
- package/src/merman/flowchart/render.ts +10 -0
- package/src/merman/flowchart/routing.ts +1429 -0
- package/src/merman/flowchart/style.ts +79 -0
- package/src/merman/flowchart/types.ts +63 -0
- package/src/merman/gantt/diagram.ts +8 -0
- package/src/merman/gantt/drawing.ts +193 -0
- package/src/merman/gantt/parser.ts +198 -0
- package/src/merman/gantt/render-grid.ts +17 -0
- package/src/merman/gantt/style.ts +36 -0
- package/src/merman/gantt/types.ts +45 -0
- package/src/merman/gitgraph/diagram.ts +8 -0
- package/src/merman/gitgraph/drawing.ts +234 -0
- package/src/merman/gitgraph/parser.ts +234 -0
- package/src/merman/gitgraph/render-grid.ts +17 -0
- package/src/merman/gitgraph/style.ts +37 -0
- package/src/merman/gitgraph/types.ts +36 -0
- package/src/merman/palette.ts +60 -0
- package/src/merman/sequence/diagram.ts +8 -0
- package/src/merman/sequence/drawing.ts +288 -0
- package/src/merman/sequence/options.ts +8 -0
- package/src/merman/sequence/parser.ts +303 -0
- package/src/merman/sequence/placement.ts +692 -0
- package/src/merman/sequence/render-grid.ts +22 -0
- package/src/merman/sequence/style.ts +81 -0
- package/src/merman/sequence/types.ts +74 -0
- package/src/merman/state/diagram.ts +8 -0
- package/src/merman/state/drawing.ts +363 -0
- package/src/merman/state/endpoint.ts +15 -0
- package/src/merman/state/layout.ts +1134 -0
- package/src/merman/state/note.ts +59 -0
- package/src/merman/state/options.ts +11 -0
- package/src/merman/state/parser.ts +245 -0
- package/src/merman/state/render-grid.ts +22 -0
- package/src/merman/state/routing.ts +1522 -0
- package/src/merman/state/search.ts +103 -0
- package/src/merman/state/style.ts +52 -0
- package/src/merman/state/types.ts +63 -0
- package/src/merman/state/visible-model.ts +77 -0
- package/src/merman/timeline/diagram.ts +8 -0
- package/src/merman/timeline/drawing.ts +109 -0
- package/src/merman/timeline/parser.ts +119 -0
- package/src/merman/timeline/render-grid.ts +17 -0
- package/src/merman/timeline/style.ts +36 -0
- package/src/merman/timeline/types.ts +31 -0
- package/src/merman.ts +3 -0
- package/src/statusline.tsx +183 -0
- package/src/theme/colors.ts +11 -0
- package/src/theme/defaults.ts +190 -0
- package/src/theme/index.ts +7 -0
- package/src/theme/load.ts +39 -0
- package/src/theme/resolve.ts +167 -0
- package/src/theme/syntax.ts +96 -0
- package/src/theme/types.ts +151 -0
- package/src/view/code.tsx +27 -0
- package/src/view/document-slots.ts +111 -0
- package/src/view/document-table.tsx +98 -0
- package/src/view/document.tsx +195 -0
- package/src/view/frame.tsx +83 -0
- package/src/view/inline-flow.tsx +113 -0
- package/src/view/inline-layout.ts +149 -0
- package/src/view/inline-math.ts +42 -0
- package/src/view/inline-style.ts +103 -0
- package/src/view/math.tsx +85 -0
- package/src/view/mermaid.tsx +128 -0
- package/src/view/table.ts +100 -0
- package/themes/dark.json +32 -0
- package/themes/example.jsonc +98 -0
- package/themes/light.json +32 -0
- package/themes/solarized-dark.json +32 -0
- package/themes/solarized-light.json +32 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createEffect, createMemo, Show, type Accessor } from "solid-js"
|
|
2
|
+
import { type MouseEvent, type TextRenderable } from "@opentui/core"
|
|
3
|
+
import { measureMermaidDiagram, type PreparedDiagram } from "../merman/diagram"
|
|
4
|
+
import { detectMermaidDiagram } from "../merman/detect"
|
|
5
|
+
import { MermaidSyntaxError } from "../merman/diagnostics"
|
|
6
|
+
import { DiagramCanvasSizeError } from "../merman/core/canvas"
|
|
7
|
+
import { resolveOpenCodeDiagramPalette } from "../merman/palette"
|
|
8
|
+
import type { Theme } from "../theme/types"
|
|
9
|
+
import type { MermaidConfig } from "../config/types"
|
|
10
|
+
import { defaultHeadingStyles, type HeadingStyles } from "../headings"
|
|
11
|
+
import { CodeBlock } from "./code"
|
|
12
|
+
|
|
13
|
+
export type MermaidDiagramViewProps = {
|
|
14
|
+
source: string
|
|
15
|
+
theme: Theme
|
|
16
|
+
columns: number
|
|
17
|
+
mermaidOptions?: MermaidConfig
|
|
18
|
+
headings?: HeadingStyles
|
|
19
|
+
onDiagnostic?: (diagnostic: { level: "error"; message: string }) => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function DiagramText(props: { prepared: Accessor<PreparedDiagram> }) {
|
|
23
|
+
let ref: TextRenderable | undefined
|
|
24
|
+
let dragX: number | undefined
|
|
25
|
+
createEffect(() => {
|
|
26
|
+
if (!ref) return
|
|
27
|
+
const prepared = props.prepared()
|
|
28
|
+
ref.content = prepared.text
|
|
29
|
+
ref.height = prepared.height
|
|
30
|
+
ref.width = "100%"
|
|
31
|
+
ref.wrapMode = "none"
|
|
32
|
+
ref.selectable = false
|
|
33
|
+
ref.marginTop = 1
|
|
34
|
+
})
|
|
35
|
+
return <text ref={(renderable) => {
|
|
36
|
+
ref = renderable
|
|
37
|
+
if (!ref) return
|
|
38
|
+
ref.onMouseDown = (event: MouseEvent) => {
|
|
39
|
+
if (event.button !== 0) return
|
|
40
|
+
ref?.ctx.clearSelection()
|
|
41
|
+
dragX = event.x
|
|
42
|
+
event.preventDefault()
|
|
43
|
+
event.stopPropagation()
|
|
44
|
+
}
|
|
45
|
+
ref.onMouseDrag = (event: MouseEvent) => {
|
|
46
|
+
if (dragX === undefined) return
|
|
47
|
+
const dx = event.x - dragX
|
|
48
|
+
dragX = event.x
|
|
49
|
+
if (ref && dx) ref.scrollX -= dx
|
|
50
|
+
event.preventDefault()
|
|
51
|
+
event.stopPropagation()
|
|
52
|
+
}
|
|
53
|
+
ref.onMouseDragEnd = () => { dragX = undefined }
|
|
54
|
+
ref.onMouseUp = () => { dragX = undefined }
|
|
55
|
+
ref.onMouseScroll = (event: MouseEvent) => {
|
|
56
|
+
const direction = event.scroll?.direction
|
|
57
|
+
if (direction !== "left" && direction !== "right") return
|
|
58
|
+
event.preventDefault()
|
|
59
|
+
event.stopPropagation()
|
|
60
|
+
}
|
|
61
|
+
}} />
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function MermaidDiagramView(props: MermaidDiagramViewProps) {
|
|
65
|
+
let lastGood: PreparedDiagram | undefined
|
|
66
|
+
const prepared = createMemo(() => {
|
|
67
|
+
const source = props.source
|
|
68
|
+
const kind = detectMermaidDiagram(source)
|
|
69
|
+
if (kind && lastGood && lastGood.kind !== kind) lastGood = undefined
|
|
70
|
+
const options = {
|
|
71
|
+
compact: props.mermaidOptions?.compact,
|
|
72
|
+
classLayout: props.mermaidOptions?.classLayout,
|
|
73
|
+
layoutMaxWidth: Math.min(props.mermaidOptions?.layoutMaxWidth ?? 120, Math.max(1, props.columns)),
|
|
74
|
+
colors: resolveOpenCodeDiagramPalette(props.theme),
|
|
75
|
+
palette: props.theme.palette,
|
|
76
|
+
}
|
|
77
|
+
const restore = () => {
|
|
78
|
+
if (!lastGood) return undefined
|
|
79
|
+
try {
|
|
80
|
+
// Reprepare with the current width and palette, never display an old
|
|
81
|
+
// StyledText raster carrying stale colors or geometry.
|
|
82
|
+
return measureMermaidDiagram(lastGood.source, options)
|
|
83
|
+
} catch {
|
|
84
|
+
return undefined
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const result = measureMermaidDiagram(source, options)
|
|
89
|
+
if (result && result.height > 0) {
|
|
90
|
+
lastGood = result
|
|
91
|
+
return result
|
|
92
|
+
}
|
|
93
|
+
if (lastGood && (!kind || lastGood.kind === kind)) {
|
|
94
|
+
return restore()
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error instanceof MermaidSyntaxError && lastGood && lastGood.kind === kind) {
|
|
98
|
+
return restore()
|
|
99
|
+
}
|
|
100
|
+
if (error instanceof MermaidSyntaxError && kind) {
|
|
101
|
+
const lines = source.split("\n")
|
|
102
|
+
if (error.lineNumber > 2 && !lines.slice(error.lineNumber).some((line) => line.trim())) {
|
|
103
|
+
try {
|
|
104
|
+
const result = measureMermaidDiagram(lines.slice(0, error.lineNumber - 1).join("\n"), options)
|
|
105
|
+
if (result?.height) {
|
|
106
|
+
lastGood = result
|
|
107
|
+
return result
|
|
108
|
+
}
|
|
109
|
+
} catch (prefixError) {
|
|
110
|
+
if (!(prefixError instanceof MermaidSyntaxError || prefixError instanceof DiagramCanvasSizeError)) {
|
|
111
|
+
props.onDiagnostic?.({ level: "error", message: prefixError instanceof Error ? prefixError.message : String(prefixError) })
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!(error instanceof MermaidSyntaxError || error instanceof DiagramCanvasSizeError)) {
|
|
117
|
+
props.onDiagnostic?.({ level: "error", message: error instanceof Error ? error.message : String(error) })
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return undefined
|
|
121
|
+
})
|
|
122
|
+
return <box width="100%" flexDirection="column" flexShrink={0}>
|
|
123
|
+
<Show when={prepared()} fallback={<CodeBlock content={props.source} language="mermaid"
|
|
124
|
+
theme={props.theme} headings={props.headings ?? defaultHeadingStyles} />}>
|
|
125
|
+
{(value) => <DiagramText prepared={value} />}
|
|
126
|
+
</Show>
|
|
127
|
+
</box>
|
|
128
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BoxRenderable,
|
|
3
|
+
TextTableRenderable,
|
|
4
|
+
type MouseEvent,
|
|
5
|
+
type RenderContext,
|
|
6
|
+
} from "@opentui/core"
|
|
7
|
+
|
|
8
|
+
// In content mode a table keeps its natural columns even when its layout box is
|
|
9
|
+
// narrower, so its drawn width can be larger than `table.width`. The layout
|
|
10
|
+
// itself knows the drawn width; fall back to the box when the field is gone.
|
|
11
|
+
function tableWidth(table: TextTableRenderable): number {
|
|
12
|
+
const layout = (
|
|
13
|
+
table as unknown as { computeLayout?: (maxWidth?: number) => { tableWidth?: number } | undefined }
|
|
14
|
+
).computeLayout?.(undefined)
|
|
15
|
+
const width = layout?.tableWidth
|
|
16
|
+
if (typeof width === "number" && Number.isFinite(width) && width > 0) return Math.round(width)
|
|
17
|
+
return Number.isFinite(table.width) ? Math.round(table.width) : 0
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// OpenTUI's table draws itself into the bounds it is given, so a table wider
|
|
21
|
+
// than the document is clipped by the terminal. The wrapper keeps the table at
|
|
22
|
+
// its natural width and moves it sideways, the same way a Mermaid diagram is
|
|
23
|
+
// panned. A table that actually needs the scroller gives up cell selection:
|
|
24
|
+
// otherwise a drag would select text instead of panning.
|
|
25
|
+
export class ScrollableTableRenderable extends BoxRenderable {
|
|
26
|
+
protected readonly table: TextTableRenderable
|
|
27
|
+
protected offset = 0
|
|
28
|
+
protected panEnabled = true
|
|
29
|
+
private dragX: number | undefined
|
|
30
|
+
|
|
31
|
+
constructor(ctx: RenderContext, table: TextTableRenderable) {
|
|
32
|
+
super(ctx, {
|
|
33
|
+
width: "100%",
|
|
34
|
+
flexDirection: "row",
|
|
35
|
+
flexShrink: 0,
|
|
36
|
+
overflow: "hidden",
|
|
37
|
+
})
|
|
38
|
+
this.table = table
|
|
39
|
+
table.flexShrink = 0
|
|
40
|
+
this.add(table)
|
|
41
|
+
this.onMouseDown = (event: MouseEvent) => {
|
|
42
|
+
if (event.button !== 0) return
|
|
43
|
+
this.dragX = event.x
|
|
44
|
+
}
|
|
45
|
+
this.onMouseDrag = (event: MouseEvent) => {
|
|
46
|
+
if (this.dragX === undefined || !this.panEnabled) return
|
|
47
|
+
const dx = event.x - this.dragX
|
|
48
|
+
this.dragX = event.x
|
|
49
|
+
if (!dx || !this.overflows()) return
|
|
50
|
+
event.preventDefault()
|
|
51
|
+
event.stopPropagation()
|
|
52
|
+
this.scrollBy(-dx)
|
|
53
|
+
}
|
|
54
|
+
this.onMouseDragEnd = () => {
|
|
55
|
+
this.dragX = undefined
|
|
56
|
+
}
|
|
57
|
+
this.onMouseUp = () => {
|
|
58
|
+
this.dragX = undefined
|
|
59
|
+
}
|
|
60
|
+
// A vertical wheel is left to the host: the document scroll box owns it.
|
|
61
|
+
this.onMouseScroll = (event: MouseEvent) => {
|
|
62
|
+
const direction = event.scroll?.direction
|
|
63
|
+
if (!this.panEnabled || (direction !== "left" && direction !== "right")) return
|
|
64
|
+
if (!this.overflows()) return
|
|
65
|
+
event.preventDefault()
|
|
66
|
+
event.stopPropagation()
|
|
67
|
+
this.scrollBy(direction === "left" ? -2 : 2)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// A table that fits keeps cell selection; only a table that has to scroll
|
|
72
|
+
// gives its drag to the scroller.
|
|
73
|
+
protected override onResize(width: number, _height: number) {
|
|
74
|
+
super.onResize(width, _height)
|
|
75
|
+
this.syncOverflowState(width)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
protected syncOverflowState(width = this.width) {
|
|
79
|
+
// A Solid custom renderable receives props before Yoga assigns its first
|
|
80
|
+
// width. Measuring the table at that point can poison the layout cache.
|
|
81
|
+
if (!Number.isFinite(width) || width <= 0) return
|
|
82
|
+
const viewport = Math.round(width)
|
|
83
|
+
const max = Math.max(0, tableWidth(this.table) - viewport)
|
|
84
|
+
this.offset = this.panEnabled ? Math.min(this.offset, max) : 0
|
|
85
|
+
this.table.marginLeft = -this.offset
|
|
86
|
+
this.table.selectable = !this.panEnabled || max === 0
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private overflows(width = this.width) {
|
|
90
|
+
const viewportWidth = Number.isFinite(width) ? Math.round(width) : 0
|
|
91
|
+
return tableWidth(this.table) > viewportWidth
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private scrollBy(delta: number) {
|
|
95
|
+
const viewportWidth = Number.isFinite(this.width) ? Math.round(this.width) : 0
|
|
96
|
+
const max = Math.max(0, tableWidth(this.table) - viewportWidth)
|
|
97
|
+
this.offset = Math.max(0, Math.min(max, this.offset + delta))
|
|
98
|
+
this.table.marginLeft = -this.offset
|
|
99
|
+
}
|
|
100
|
+
}
|
package/themes/dark.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mode": "dark",
|
|
3
|
+
"accent": "#58a6ff",
|
|
4
|
+
"categorical": ["#58a6ff", "#d2a8ff", "#3fb950", "#d29922", "#f85149", "#ffa657"],
|
|
5
|
+
"text": {
|
|
6
|
+
"base": "#e6edf3",
|
|
7
|
+
"muted": "#8b949e",
|
|
8
|
+
"feedback": { "error": "#f85149", "warning": "#d29922", "success": "#3fb950", "info": "#58a6ff" },
|
|
9
|
+
"action": { "primary": { "focused": "#58a6ff" } }
|
|
10
|
+
},
|
|
11
|
+
"background": { "base": "#0d1117" },
|
|
12
|
+
"border": { "base": "#30363d" },
|
|
13
|
+
"frame": { "border": "#30363d", "title": "#8b949e" },
|
|
14
|
+
"markdown": {
|
|
15
|
+
"text": "#e6edf3", "heading": "#d2a8ff",
|
|
16
|
+
"heading1": "#58a6ff", "heading2": "#d2a8ff", "heading3": "#d2a8ff",
|
|
17
|
+
"heading4": "#8b949e", "heading5": "#8b949e", "heading6": "#8b949e",
|
|
18
|
+
"link": "#58a6ff", "linkText": "#58a6ff", "code": "#ffa657",
|
|
19
|
+
"blockQuote": "#8b949e", "emphasis": "#e6edf3", "strong": "#e6edf3",
|
|
20
|
+
"horizontalRule": "#30363d", "listItem": "#e6edf3", "listEnumeration": "#e6edf3",
|
|
21
|
+
"image": "#58a6ff", "imageText": "#58a6ff", "codeBlock": "#e6edf3"
|
|
22
|
+
},
|
|
23
|
+
"syntax": {
|
|
24
|
+
"comment": "#8b949e", "keyword": "#ff7b72", "function": "#d2a8ff",
|
|
25
|
+
"variable": "#ffa657", "string": "#a5d6ff", "number": "#79c0ff",
|
|
26
|
+
"type": "#ffa657", "operator": "#ff7b72", "punctuation": "#c9d1d9"
|
|
27
|
+
},
|
|
28
|
+
"diff": {
|
|
29
|
+
"text": { "added": "#3fb950", "removed": "#f85149", "context": "#8b949e" },
|
|
30
|
+
"background": { "added": "#12261e", "removed": "#25171c", "context": "#161b22" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
// The semantic mode controls contrast-sensitive derived colours.
|
|
3
|
+
"mode": "dark",
|
|
4
|
+
|
|
5
|
+
// Optional fixed Mermaid diagram palette. Omit it to derive diagram colours.
|
|
6
|
+
"palette": [
|
|
7
|
+
"#58a6ff", "#d2a8ff", "#3fb950", "#d29922", "#f85149", "#ffa657"
|
|
8
|
+
],
|
|
9
|
+
|
|
10
|
+
// Main accent and the categorical colours used by diagrams and UI elements.
|
|
11
|
+
"accent": "#58a6ff",
|
|
12
|
+
"categorical": ["#58a6ff", "#d2a8ff", "#3fb950", "#d29922", "#f85149", "#ffa657"],
|
|
13
|
+
|
|
14
|
+
"text": {
|
|
15
|
+
"base": "#e6edf3",
|
|
16
|
+
"muted": "#8b949e",
|
|
17
|
+
"feedback": {
|
|
18
|
+
"error": "#f85149",
|
|
19
|
+
"warning": "#d29922",
|
|
20
|
+
"success": "#3fb950",
|
|
21
|
+
"info": "#58a6ff"
|
|
22
|
+
},
|
|
23
|
+
"action": {
|
|
24
|
+
"primary": {
|
|
25
|
+
"focused": "#58a6ff"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
"background": {
|
|
31
|
+
"base": "#0d1117"
|
|
32
|
+
},
|
|
33
|
+
"border": {
|
|
34
|
+
"base": "#30363d"
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Frame and statusline are optional in the resolved API; these examples show
|
|
38
|
+
// the complete file shape and can be adjusted independently.
|
|
39
|
+
"frame": {
|
|
40
|
+
"border": "#30363d",
|
|
41
|
+
"title": "#8b949e"
|
|
42
|
+
},
|
|
43
|
+
"statusline": {
|
|
44
|
+
"background": "#161b22",
|
|
45
|
+
"foreground": "#e6edf3",
|
|
46
|
+
"title": "#58a6ff",
|
|
47
|
+
"muted": "#8b949e",
|
|
48
|
+
"border": "#58a6ff"
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
"markdown": {
|
|
52
|
+
"text": "#e6edf3",
|
|
53
|
+
"heading": "#d2a8ff",
|
|
54
|
+
"heading1": "#58a6ff",
|
|
55
|
+
"heading2": "#d2a8ff",
|
|
56
|
+
"heading3": "#d2a8ff",
|
|
57
|
+
"heading4": "#8b949e",
|
|
58
|
+
"heading5": "#8b949e",
|
|
59
|
+
"heading6": "#8b949e",
|
|
60
|
+
"link": "#58a6ff",
|
|
61
|
+
"linkText": "#58a6ff",
|
|
62
|
+
"code": "#ffa657",
|
|
63
|
+
"blockQuote": "#8b949e",
|
|
64
|
+
"emphasis": "#e6edf3",
|
|
65
|
+
"strong": "#e6edf3",
|
|
66
|
+
"horizontalRule": "#30363d",
|
|
67
|
+
"listItem": "#e6edf3",
|
|
68
|
+
"listEnumeration": "#e6edf3",
|
|
69
|
+
"image": "#58a6ff",
|
|
70
|
+
"imageText": "#58a6ff",
|
|
71
|
+
"codeBlock": "#e6edf3"
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
"syntax": {
|
|
75
|
+
"comment": "#8b949e",
|
|
76
|
+
"keyword": "#ff7b72",
|
|
77
|
+
"function": "#d2a8ff",
|
|
78
|
+
"variable": "#ffa657",
|
|
79
|
+
"string": "#a5d6ff",
|
|
80
|
+
"number": "#79c0ff",
|
|
81
|
+
"type": "#ffa657",
|
|
82
|
+
"operator": "#ff7b72",
|
|
83
|
+
"punctuation": "#c9d1d9"
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
"diff": {
|
|
87
|
+
"text": {
|
|
88
|
+
"added": "#3fb950",
|
|
89
|
+
"removed": "#f85149",
|
|
90
|
+
"context": "#8b949e"
|
|
91
|
+
},
|
|
92
|
+
"background": {
|
|
93
|
+
"added": "#12261e",
|
|
94
|
+
"removed": "#25171c",
|
|
95
|
+
"context": "#161b22"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mode": "light",
|
|
3
|
+
"accent": "#0969da",
|
|
4
|
+
"categorical": ["#0969da", "#8250df", "#1a7f37", "#9a6700", "#cf222e", "#bc4c00"],
|
|
5
|
+
"text": {
|
|
6
|
+
"base": "#1f2328",
|
|
7
|
+
"muted": "#59636e",
|
|
8
|
+
"feedback": { "error": "#cf222e", "warning": "#9a6700", "success": "#1a7f37", "info": "#0969da" },
|
|
9
|
+
"action": { "primary": { "focused": "#0969da" } }
|
|
10
|
+
},
|
|
11
|
+
"background": { "base": "#ffffff" },
|
|
12
|
+
"border": { "base": "#8c959f" },
|
|
13
|
+
"frame": { "border": "#8c959f", "title": "#59636e" },
|
|
14
|
+
"markdown": {
|
|
15
|
+
"text": "#1f2328", "heading": "#8250df",
|
|
16
|
+
"heading1": "#0969da", "heading2": "#8250df", "heading3": "#8250df",
|
|
17
|
+
"heading4": "#6f42c1", "heading5": "#3d444d", "heading6": "#3d444d",
|
|
18
|
+
"link": "#0969da", "linkText": "#0969da", "code": "#953800",
|
|
19
|
+
"blockQuote": "#59636e", "emphasis": "#1f2328", "strong": "#1f2328",
|
|
20
|
+
"horizontalRule": "#d1d9e0", "listItem": "#1f2328", "listEnumeration": "#1f2328",
|
|
21
|
+
"image": "#0969da", "imageText": "#0969da", "codeBlock": "#1f2328"
|
|
22
|
+
},
|
|
23
|
+
"syntax": {
|
|
24
|
+
"comment": "#59636e", "keyword": "#cf222e", "function": "#8250df",
|
|
25
|
+
"variable": "#1f2328", "string": "#0a3069", "number": "#0550ae",
|
|
26
|
+
"type": "#0550ae", "operator": "#0550ae", "punctuation": "#1f2328"
|
|
27
|
+
},
|
|
28
|
+
"diff": {
|
|
29
|
+
"text": { "added": "#1a7f37", "removed": "#cf222e", "context": "#59636e" },
|
|
30
|
+
"background": { "added": "#dafbe1", "removed": "#ffebe9", "context": "#f6f8fa" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mode": "dark",
|
|
3
|
+
"palette": ["#002b36", "#073642", "#586e75", "#657b83", "#839496", "#93a1a1", "#eee8d5", "#fdf6e3", "#b58900", "#cb4b16", "#dc322f", "#d33682", "#6c71c4", "#268bd2", "#2aa198", "#859900"],
|
|
4
|
+
"accent": "#268bd2",
|
|
5
|
+
"categorical": ["#268bd2", "#6c71c4", "#859900", "#b58900", "#dc322f", "#cb4b16"],
|
|
6
|
+
"text": {
|
|
7
|
+
"base": "#93a1a1", "muted": "#839496",
|
|
8
|
+
"feedback": { "error": "#dc322f", "warning": "#b58900", "success": "#859900", "info": "#268bd2" },
|
|
9
|
+
"action": { "primary": { "focused": "#268bd2" } }
|
|
10
|
+
},
|
|
11
|
+
"background": { "base": "#002b36" },
|
|
12
|
+
"border": { "base": "#586e75" },
|
|
13
|
+
"frame": { "border": "#586e75", "title": "#93a1a1" },
|
|
14
|
+
"markdown": {
|
|
15
|
+
"text": "#93a1a1", "heading": "#268bd2",
|
|
16
|
+
"heading1": "#268bd2", "heading2": "#268bd2", "heading3": "#268bd2",
|
|
17
|
+
"heading4": "#268bd2", "heading5": "#268bd2", "heading6": "#268bd2",
|
|
18
|
+
"link": "#268bd2", "linkText": "#268bd2", "code": "#cb4b16",
|
|
19
|
+
"blockQuote": "#839496", "emphasis": "#93a1a1", "strong": "#93a1a1",
|
|
20
|
+
"horizontalRule": "#586e75", "listItem": "#93a1a1", "listEnumeration": "#93a1a1",
|
|
21
|
+
"image": "#268bd2", "imageText": "#268bd2", "codeBlock": "#93a1a1"
|
|
22
|
+
},
|
|
23
|
+
"syntax": {
|
|
24
|
+
"comment": "#839496", "keyword": "#dc322f", "function": "#6c71c4",
|
|
25
|
+
"variable": "#93a1a1", "string": "#2aa198", "number": "#d33682",
|
|
26
|
+
"type": "#b58900", "operator": "#268bd2", "punctuation": "#93a1a1"
|
|
27
|
+
},
|
|
28
|
+
"diff": {
|
|
29
|
+
"text": { "added": "#859900", "removed": "#dc322f", "context": "#839496" },
|
|
30
|
+
"background": { "added": "#073642", "removed": "#073642", "context": "#073642" }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mode": "light",
|
|
3
|
+
"palette": ["#002b36", "#073642", "#586e75", "#657b83", "#839496", "#93a1a1", "#eee8d5", "#fdf6e3", "#b58900", "#cb4b16", "#dc322f", "#d33682", "#6c71c4", "#268bd2", "#2aa198", "#859900"],
|
|
4
|
+
"accent": "#268bd2",
|
|
5
|
+
"categorical": ["#268bd2", "#6c71c4", "#859900", "#b58900", "#dc322f", "#cb4b16"],
|
|
6
|
+
"text": {
|
|
7
|
+
"base": "#586e75", "muted": "#657b83",
|
|
8
|
+
"feedback": { "error": "#dc322f", "warning": "#b58900", "success": "#859900", "info": "#268bd2" },
|
|
9
|
+
"action": { "primary": { "focused": "#268bd2" } }
|
|
10
|
+
},
|
|
11
|
+
"background": { "base": "#fdf6e3" },
|
|
12
|
+
"border": { "base": "#657b83" },
|
|
13
|
+
"frame": { "border": "#657b83", "title": "#586e75" },
|
|
14
|
+
"markdown": {
|
|
15
|
+
"text": "#586e75", "heading": "#268bd2",
|
|
16
|
+
"heading1": "#268bd2", "heading2": "#268bd2", "heading3": "#268bd2",
|
|
17
|
+
"heading4": "#268bd2", "heading5": "#268bd2", "heading6": "#268bd2",
|
|
18
|
+
"link": "#268bd2", "linkText": "#268bd2", "code": "#cb4b16",
|
|
19
|
+
"blockQuote": "#657b83", "emphasis": "#586e75", "strong": "#586e75",
|
|
20
|
+
"horizontalRule": "#657b83", "listItem": "#586e75", "listEnumeration": "#586e75",
|
|
21
|
+
"image": "#268bd2", "imageText": "#268bd2", "codeBlock": "#586e75"
|
|
22
|
+
},
|
|
23
|
+
"syntax": {
|
|
24
|
+
"comment": "#657b83", "keyword": "#dc322f", "function": "#6c71c4",
|
|
25
|
+
"variable": "#586e75", "string": "#2aa198", "number": "#d33682",
|
|
26
|
+
"type": "#b58900", "operator": "#268bd2", "punctuation": "#586e75"
|
|
27
|
+
},
|
|
28
|
+
"diff": {
|
|
29
|
+
"text": { "added": "#859900", "removed": "#dc322f", "context": "#657b83" },
|
|
30
|
+
"background": { "added": "#eee8d5", "removed": "#eee8d5", "context": "#eee8d5" }
|
|
31
|
+
}
|
|
32
|
+
}
|