Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/services/i18n/locales/en/preferences.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,9 @@
},
"language": {
"label": "Language"
},
"markdown": {
"label": "Markdown",
"codeRenderer": "Code block Renderer"
}
}
6 changes: 5 additions & 1 deletion src/main/services/i18n/locales/en/special.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"Snippets with unsupported languages will be set to default Plain Text."
]
},
"htmlCssPreview": "Add fragments with HTML & CSS languages to view result."
"htmlCssPreview": "Add fragments with HTML & CSS languages to view result.",
"codeBlockRenderer": [
"When using Codemirror, the language to be set for the code block must correspond to one of the values of the",
"languages"
]
},
"success": {
"migrate": "DB successfully migrated."
Expand Down
4 changes: 4 additions & 0 deletions src/main/services/i18n/locales/ru/preferences.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,9 @@
},
"language": {
"label": "Язык"
},
"markdown": {
"label": "Markdown",
"codeRenderer": "Рендерер блоков кода"
}
}
6 changes: 5 additions & 1 deletion src/main/services/i18n/locales/ru/special.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
"Сниппеты с неподдерживаемыми языками будут установлены на стандартный простой текст."
]
},
"htmlCssPreview": "Добавьте фрагменты с языками HTML и CSS для просмотра результата."
"htmlCssPreview": "Добавьте фрагменты с языками HTML и CSS для просмотра результата.",
"codeBlockRenderer": [
"При использовании Codemirror, устанавливаемый язык для блока кода должен соответствовать одному из значений",
"языков"
]
},
"success": {
"migrate": "БД успешно перенесена."
Expand Down
3 changes: 2 additions & 1 deletion src/main/store/module/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export default new Store<PreferencesStore>({
width: 600
},
markdown: {
presentationScale: 1.3
presentationScale: 1.3,
codeRenderer: 'highlight.js'
},
language: 'en'
}
Expand Down
5 changes: 4 additions & 1 deletion src/renderer/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ const init = async () => {
appStore.sizes.sidebar = store.app.get('sidebarWidth')
appStore.sizes.snippetList = store.app.get('snippetListWidth')
appStore.screenshot = store.preferences.get('screenshot')
appStore.markdown = store.preferences.get('markdown')
appStore.markdown = {
...appStore.markdown,
...store.preferences.get('markdown')
}

snippetStore.sort = store.app.get('sort')

Expand Down
3 changes: 3 additions & 0 deletions src/renderer/assets/scss/markdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -951,5 +951,8 @@
pre {
background-color: rgba(0, 0, 0, 0.15);
}
.CodeMirror-gutter {
background-color: rgba(0, 0, 0, 0.03) !important;
}
}
}
9 changes: 9 additions & 0 deletions src/renderer/assets/scss/themes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -298,3 +298,12 @@

--color-tag-delete: var(--color-contrast-lower-alt3);
}

[data-theme^="dark"] {
a {
color: var(--color-contrast-medium);
&:hover {
color: var(--color-text);
}
}
}
82 changes: 71 additions & 11 deletions src/renderer/components/markdown/TheMarkdown.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="markdown markdown-body">
<PerfectScrollbar>
<div v-html="renderer" />
<div v-html="renderedHtml" />
</PerfectScrollbar>
</div>
</template>
Expand All @@ -11,11 +11,14 @@ import { useAppStore } from '@/store/app'
import { useSnippetStore } from '@/store/snippets'
import sanitizeHtml from 'sanitize-html'
import hljs from 'highlight.js'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue'
import { ipc, store } from '@/electron'
import { marked } from 'marked'
import mermaid from 'mermaid'
import { useHljsTheme } from '@/composable'
import { useCodemirror } from '@/composable/codemirror'

import { nanoid } from 'nanoid'

const isDev = import.meta.env.DEV

Expand All @@ -24,28 +27,51 @@ interface Props {
scale?: number
}

interface Editors {
id: string
value: string
lang: string
}

const props = withDefaults(defineProps<Props>(), {
scale: 1
})

const appStore = useAppStore()
const snippetStore = useSnippetStore()

const renderedHtml = ref()

const editors: Editors[] = []

const forceRefresh = ref()
const preTagBg = computed(() =>
appStore.isLightTheme ? '#fff' : 'var(--color-contrast-high)'
)
const fontFamily = computed(() => appStore.editor.fontFamily)

const init = () => {
const renderer: marked.RendererObject = {
code (code: string, lang: string) {
if (lang === 'mermaid') {
return `<div class="mermaid">${code}</div><br>`
} else {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
return `<pre><code class="language-${lang}">${
hljs.highlight(code, { language }).value
}</code></pre>`
if (appStore.markdown.codeRenderer === 'highlight.js') {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'
return `<pre><code class="language-${lang}">${
hljs.highlight(code, { language }).value
}</code></pre>`
} else {
const id = nanoid(6)

editors.push({
id,
value: code,
lang
})

return `<div id="${id}"></div>`
}
}
},
link (href: string, title: string, text: string) {
Expand All @@ -69,10 +95,12 @@ const initMermaid = () => {

onMounted(() => {
initMermaid()
render()
})

const getRenderer = () => {
const render = () => {
const raw = marked.parse(props.value)

let html = sanitizeHtml(raw, {
allowedTags: [
'h1',
Expand Down Expand Up @@ -152,7 +180,8 @@ const getRenderer = () => {
'class',
'type',
'checked',
'disabled'
'disabled',
'id'
]
}
})
Expand All @@ -164,11 +193,9 @@ const getRenderer = () => {
? html.replace(re, `src="file://${path}/`)
: html.replace(re, `src="${path}/`)

return html
renderedHtml.value = html
}

const renderer = computed(() => getRenderer())

const openExternal = (e: Event) => {
const el = e.target as HTMLAnchorElement
e.preventDefault()
Expand Down Expand Up @@ -209,6 +236,24 @@ watch(
{ immediate: true }
)

watch(renderedHtml, () => {
nextTick(() => {
editors.forEach(i => {
useCodemirror(i.id, {
value: i.value,
mode: i.lang
})
})
})
})

watch(
() => props.value,
() => {
render()
}
)

init()

onMounted(() => {
Expand Down Expand Up @@ -238,5 +283,20 @@ window.addEventListener('resize', () => {
:deep(.ps) {
height: v-bind(height);
}
:deep(.CodeMirror) {
height: 100%;
padding: var(--spacing-xs);
font-size: 0.85em;
font-family: v-bind(fontFamily);
}
:deep(.CodeMirror-line) {
padding: 0 var(--spacing-sm);
&:first-child {
padding-top: var(--spacing-xs);
}
&:last-child {
padding-bottom: var(--spacing-xs);
}
}
}
</style>
53 changes: 53 additions & 0 deletions src/renderer/components/preferences/MarkdownPreferences.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<div class="language-preferences">
<AppForm>
<AppFormItem :label="i18n.t('preferences:markdown.codeRenderer')">
<AppSelect
v-model="renderer"
:options="rendererOptions"
/>
<template #desc>
{{ i18n.t('special:description.codeBlockRenderer.0') }}
<a
href="#"
@click="
onClickUrl(
'https://github.com/massCodeIO/massCode/blob/master/src/renderer/components/editor/languages.ts'
)
"
>{{ i18n.t('special:description.codeBlockRenderer.1') }}</a>.
</template>
</AppFormItem>
</AppForm>
</div>
</template>

<script setup lang="ts">
import { i18n, store } from '@/electron'
import { useAppStore } from '@/store/app'
import { computed } from 'vue'
import { onClickUrl } from '@/composable'

const appStore = useAppStore()

const renderer = computed({
get: () => appStore.markdown.codeRenderer,
set: v => {
appStore.markdown.codeRenderer = v
store.preferences.set('markdown', { ...appStore.markdown })
}
})

const rendererOptions = [
{
label: 'Codemirror',
value: 'codemirror'
},
{
label: 'Highlight.js',
value: 'highlight.js'
}
]
</script>

<style lang="scss" scoped></style>
16 changes: 16 additions & 0 deletions src/renderer/composable/codemirror.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { getThemeName } from '@/components/editor/themes'
import { useAppStore } from '@/store/app'
import type { EditorConfiguration } from 'codemirror'
import CodeMirror from 'codemirror'

export const useCodemirror = (elemId: string, options: EditorConfiguration) => {
const appStore = useAppStore()

CodeMirror(document.getElementById(elemId)!, {
...options,
theme: getThemeName(appStore.theme) || 'GitHub',
scrollbarStyle: 'null',
readOnly: true,
cursorBlinkRate: -1
})
}
5 changes: 5 additions & 0 deletions src/renderer/composable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,8 @@ export const checkForRemoteNotification = async () => {
checkAndShow()
}, 1000 * 60 * 180) // 3 часа
}

export const onClickUrl = (url: string) => {
ipc.invoke('main:open-url', url)
track('app/open-url', url)
}
3 changes: 2 additions & 1 deletion src/renderer/store/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const CODE_PREVIEW_DEFAULTS: CodePreviewSettings = {
}

const MARKDOWN_DEFAULTS: MarkdownSettings = {
presentationScale: 1.3
presentationScale: 1.3,
codeRenderer: 'highlight.js'
}

export const useAppStore = defineStore('app', {
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/views/Preferences.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
>
<EditorPreferences />
</AppMenuItem>
<AppMenuItem
:name="i18n.t('preferences:markdown.label')"
value="markdown"
>
<MarkdownPreferences />
</AppMenuItem>
<AppMenuItem
:name="i18n.t('preferences:appearance.label')"
value="appearance"
Expand Down
1 change: 1 addition & 0 deletions src/shared/types/main/store.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface AppStore {
}

export interface MarkdownSettings {
codeRenderer: 'codemirror' | 'highlight.js'
presentationScale: number
}

Expand Down