mirror of
https://github.com/marktext/marktext.git
synced 2025-05-02 13:11:30 +08:00
feat: support solidity in codeblock and optimization of file icons (#2775)
* feat: support solidity in codeblock and optimization of file icons * feat: update file icons
This commit is contained in:
parent
c6d4368988
commit
8af9605e35
@ -36,6 +36,7 @@
|
||||
"@electron/remote": "^2.0.1",
|
||||
"@hfelix/electron-localshortcut": "^3.1.1",
|
||||
"@hfelix/electron-spellchecker": "^2.0.0",
|
||||
"@marktext/file-icons": "^1.0.4",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"arg": "^5.0.1",
|
||||
"axios": "0.22.0",
|
||||
@ -54,7 +55,6 @@
|
||||
"element-resize-detector": "^1.2.4",
|
||||
"element-ui": "^2.15.7",
|
||||
"execall": "^2.0.0",
|
||||
"file-icons-js": "1.0.3",
|
||||
"flowchart.js": "^1.17.0",
|
||||
"fontmanager-redux": "^1.1.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
import katex from 'katex'
|
||||
import prism, { loadedLanguages, transfromAliasToOrigin } from '../../../prism/'
|
||||
import 'katex/dist/contrib/mhchem.min.js'
|
||||
import prism, { loadedCache, transfromAliasToOrigin } from '../../../prism/'
|
||||
import { CLASS_OR_ID, DEVICE_MEMORY, PREVIEW_DOMPURIFY_CONFIG, HAS_TEXT_BLOCK_REG } from '../../../config'
|
||||
import { tokenizer } from '../../'
|
||||
import { snakeToCamel, sanitize, escapeHtml, getLongUniqueId, getImageInfo } from '../../../utils'
|
||||
@ -234,7 +234,7 @@ export default function renderLeafBlock (parent, block, activeBlocks, matches, u
|
||||
|
||||
// transfrom alias to original language
|
||||
const transformedLang = transfromAliasToOrigin([lang])[0]
|
||||
if (transformedLang && /\S/.test(code) && loadedCache.has(transformedLang)) {
|
||||
if (transformedLang && /\S/.test(code) && loadedLanguages.has(transformedLang)) {
|
||||
const wrapper = document.createElement('div')
|
||||
wrapper.classList.add(`language-${transformedLang}`)
|
||||
wrapper.innerHTML = code
|
||||
|
@ -1,7 +1,7 @@
|
||||
import Prism from 'prismjs'
|
||||
import { filter } from 'fuzzaldrin'
|
||||
import initLoadLanguage, { loadedCache, transfromAliasToOrigin } from './loadLanguage'
|
||||
import languages from './languages'
|
||||
import initLoadLanguage, { loadedLanguages, transfromAliasToOrigin } from './loadLanguage'
|
||||
import { languages } from 'prismjs/components.js'
|
||||
|
||||
const prism = Prism
|
||||
window.Prism = Prism
|
||||
@ -44,9 +44,8 @@ loadLanguage('yaml')
|
||||
export {
|
||||
search,
|
||||
loadLanguage,
|
||||
loadedCache,
|
||||
transfromAliasToOrigin,
|
||||
languages
|
||||
loadedLanguages,
|
||||
transfromAliasToOrigin
|
||||
}
|
||||
|
||||
export default prism
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,41 +1,19 @@
|
||||
import languages from './languages'
|
||||
let peerDependentsMap = null
|
||||
export const loadedCache = new Set(['markup', 'css', 'clike', 'javascript'])
|
||||
const prismComponentCache = new Map()
|
||||
import components from 'prismjs/components.js'
|
||||
import getLoader from 'prismjs/dependencies'
|
||||
import { getDefer } from '../utils'
|
||||
/**
|
||||
* The set of all languages which have been loaded using the below function.
|
||||
*
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
export const loadedLanguages = new Set(['markup', 'css', 'clike', 'javascript'])
|
||||
|
||||
function getPeerDependentsMap () {
|
||||
const peerDependentsMap = {}
|
||||
Object.keys(languages).forEach(function (language) {
|
||||
if (language === 'meta') {
|
||||
return false
|
||||
}
|
||||
if (languages[language].peerDependencies) {
|
||||
let peerDependencies = languages[language].peerDependencies
|
||||
if (!Array.isArray(peerDependencies)) {
|
||||
peerDependencies = [peerDependencies]
|
||||
}
|
||||
peerDependencies.forEach(function (peerDependency) {
|
||||
if (!peerDependentsMap[peerDependency]) {
|
||||
peerDependentsMap[peerDependency] = []
|
||||
}
|
||||
peerDependentsMap[peerDependency].push(language)
|
||||
})
|
||||
}
|
||||
})
|
||||
return peerDependentsMap
|
||||
}
|
||||
|
||||
function getPeerDependents (mainLanguage) {
|
||||
if (!peerDependentsMap) {
|
||||
peerDependentsMap = getPeerDependentsMap()
|
||||
}
|
||||
return peerDependentsMap[mainLanguage] || []
|
||||
}
|
||||
const { languages } = components
|
||||
|
||||
// Look for the origin languge by alias
|
||||
export const transfromAliasToOrigin = arr => {
|
||||
export const transfromAliasToOrigin = langs => {
|
||||
const result = []
|
||||
for (const lang of arr) {
|
||||
for (const lang of langs) {
|
||||
if (languages[lang]) {
|
||||
result.push(lang)
|
||||
} else {
|
||||
@ -59,76 +37,47 @@ export const transfromAliasToOrigin = arr => {
|
||||
}
|
||||
|
||||
function initLoadLanguage (Prism) {
|
||||
return async function loadLanguages (arr, withoutDependencies) {
|
||||
return async function loadLanguages (langs) {
|
||||
// If no argument is passed, load all components
|
||||
if (!arr) {
|
||||
arr = Object.keys(languages).filter(function (language) {
|
||||
return language !== 'meta'
|
||||
if (!langs) {
|
||||
langs = Object.keys(languages).filter(function (lang) {
|
||||
return lang !== 'meta'
|
||||
})
|
||||
}
|
||||
if (arr && !arr.length) {
|
||||
|
||||
if (langs && !langs.length) {
|
||||
return Promise.reject(new Error('The first parameter should be a list of load languages or single language.'))
|
||||
}
|
||||
|
||||
if (!Array.isArray(arr)) {
|
||||
arr = [arr]
|
||||
if (!Array.isArray(langs)) {
|
||||
langs = [langs]
|
||||
}
|
||||
|
||||
const promises = []
|
||||
const transformedLangs = transfromAliasToOrigin(arr)
|
||||
for (const language of transformedLangs) {
|
||||
// handle not existed
|
||||
if (!languages[language]) {
|
||||
promises.push(Promise.resolve({
|
||||
lang: language,
|
||||
// the user might have loaded languages via some other way or used `prism.js` which already includes some
|
||||
// we don't need to validate the ids because `getLoader` will ignore invalid ones
|
||||
const loaded = [...loadedLanguages, ...Object.keys(Prism.languages)]
|
||||
|
||||
getLoader(components, langs, loaded).load(async lang => {
|
||||
const defer = getDefer()
|
||||
promises.push(defer.promise)
|
||||
if (!(lang in components.languages)) {
|
||||
defer.resolve({
|
||||
lang,
|
||||
status: 'noexist'
|
||||
}))
|
||||
continue
|
||||
}
|
||||
// handle already cached
|
||||
if (loadedCache.has(language)) {
|
||||
promises.push(Promise.resolve({
|
||||
lang: language,
|
||||
status: 'cached'
|
||||
}))
|
||||
continue
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Load dependencies first
|
||||
if (!withoutDependencies && languages[language].require) {
|
||||
const results = await loadLanguages(languages[language].require)
|
||||
promises.push(...results)
|
||||
}
|
||||
delete Prism.languages[lang]
|
||||
|
||||
delete Prism.languages[language]
|
||||
if (!prismComponentCache.has(language)) {
|
||||
await import('prismjs/components/prism-' + language)
|
||||
prismComponentCache.set(language, Prism.languages[language])
|
||||
} else {
|
||||
Prism.languages[language] = prismComponentCache.get(language)
|
||||
}
|
||||
loadedCache.add(language)
|
||||
promises.push(Promise.resolve({
|
||||
status: 'loaded',
|
||||
lang: language
|
||||
}))
|
||||
|
||||
// Reload dependents
|
||||
const dependents = getPeerDependents(language).filter(function (dependent) {
|
||||
// If dependent language was already loaded,
|
||||
// we want to reload it.
|
||||
if (Prism.languages[dependent]) {
|
||||
delete Prism.languages[dependent]
|
||||
loadedCache.delete(dependent)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
await import('prismjs/components/prism-' + lang)
|
||||
defer.resolve({
|
||||
lang,
|
||||
status: loadedLanguages.has(lang) ? 'cached' : 'loaded'
|
||||
})
|
||||
if (dependents.length) {
|
||||
const results = await loadLanguages(dependents, true)
|
||||
promises.push(...results)
|
||||
}
|
||||
}
|
||||
loadedLanguages.add(lang)
|
||||
})
|
||||
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.ag-list-picker .item .icon-wrapper span:before {
|
||||
|
@ -48,19 +48,15 @@ class CodePicker extends BaseScrollFloat {
|
||||
const { renderArray, oldVnode, scrollElement, activeItem } = this
|
||||
let children = renderArray.map(item => {
|
||||
let iconClassNames
|
||||
if (item.ext && Array.isArray(item.ext)) {
|
||||
for (const ext of item.ext) {
|
||||
iconClassNames = fileIcons.getClassWithColor(`fackname.${ext}`)
|
||||
if (iconClassNames) break
|
||||
}
|
||||
} else if (item.name) {
|
||||
iconClassNames = fileIcons.getClassWithColor(item.name)
|
||||
|
||||
if (item.name) {
|
||||
iconClassNames = fileIcons.getClassByLanguage(item.name)
|
||||
}
|
||||
|
||||
// Because `markdown mode in Codemirror` don't have extensions.
|
||||
// if still can not get the className, add a common className 'atom-icon light-cyan'
|
||||
if (!iconClassNames) {
|
||||
iconClassNames = item.name === 'markdown' ? fileIcons.getClassWithColor('fackname.md') : 'atom-icon light-cyan'
|
||||
iconClassNames = item.name === 'markdown' ? fileIcons.getClassByName('fackname.md') : 'atom-icon light-cyan'
|
||||
}
|
||||
const iconSelector = 'span' + iconClassNames.split(/\s/).map(s => `.${s}`).join('')
|
||||
const icon = h('div.icon-wrapper', h(iconSelector))
|
||||
|
@ -1,5 +1,16 @@
|
||||
// Because the sidebar also use the file icons, So I put this file out of floatBox directory.
|
||||
import 'file-icons-js/css/style.css'
|
||||
import fileIcons from 'file-icons-js'
|
||||
import '@marktext/file-icons/build/index.css'
|
||||
import fileIcons from '@marktext/file-icons'
|
||||
|
||||
fileIcons.getClassByName = function (name) {
|
||||
const icon = fileIcons.matchName(name)
|
||||
|
||||
return icon ? icon.getClass(0, false) : null
|
||||
}
|
||||
fileIcons.getClassByLanguage = function (lang) {
|
||||
const icon = fileIcons.matchLanguage(lang)
|
||||
|
||||
return icon ? icon.getClass(0, false) : null
|
||||
}
|
||||
|
||||
export default fileIcons
|
||||
|
@ -412,3 +412,14 @@ export const collectFootnotes = (blocks) => {
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
export const getDefer = () => {
|
||||
const defer = {}
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
defer.resolve = resolve
|
||||
defer.reject = reject
|
||||
})
|
||||
defer.promise = promise
|
||||
|
||||
return defer
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
className () {
|
||||
let icon = fileIcons.getClassWithColor(this.name ? this.name : 'mock.md')
|
||||
let icon = fileIcons.getClassByName(this.name ? this.name : 'mock.md')
|
||||
if (!icon) {
|
||||
// Use fallback icon when the icon is unknown.
|
||||
icon = fileIcons.getClassWithColor('mock.md')
|
||||
icon = fileIcons.getClassByName('mock.md')
|
||||
}
|
||||
return icon.split(/\s/)
|
||||
}
|
||||
|
31
yarn.lock
31
yarn.lock
@ -1611,6 +1611,13 @@
|
||||
diff "^5.0.0"
|
||||
parse5-sax-parser "^6.0.1"
|
||||
|
||||
"@marktext/file-icons@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/@marktext/file-icons/-/file-icons-1.0.4.tgz#322ab75e3d4c872550819b70f7dbe56e51322239"
|
||||
integrity sha512-lVXig/OaF7JMPtxqd7InIraS1NcolXJBuBqlEet+Y8qgVsSns7DlNW876xo3Xywqf/hAuq1mQ4qjj/Gp97tcug==
|
||||
dependencies:
|
||||
file-icons "github:file-icons/atom"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.3":
|
||||
version "2.1.3"
|
||||
resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
|
||||
@ -2773,6 +2780,13 @@ atob@^2.1.2:
|
||||
resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
atom-fs@v0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.npmjs.org/atom-fs/-/atom-fs-0.2.1.tgz#650717ff1bfe2d10e3add5fa8f296875b68ce0e5"
|
||||
integrity sha512-H+09ux1pNAPUbJqyrZ7lA/CpNmKqZURrYc23QzDUG29A380EYEnzwW99Do5VlT8SmZtyapOMySFesndgvZZGWg==
|
||||
dependencies:
|
||||
mapped-disposable "^1.0.3"
|
||||
|
||||
atomically@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/atomically/-/atomically-1.7.0.tgz#c07a0458432ea6dbc9a3506fffa424b48bccaafe"
|
||||
@ -6531,10 +6545,14 @@ file-entry-cache@^6.0.1:
|
||||
dependencies:
|
||||
flat-cache "^3.0.4"
|
||||
|
||||
file-icons-js@1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/file-icons-js/-/file-icons-js-1.0.3.tgz#d0765dc1d86aba4b2d7664a39e4ef7af9f12c5af"
|
||||
integrity sha512-n4zoKEpMaAxBTUB7wtgrFBa4dM3b7mBLLA1VI/Q5Cdk/k2UA8S8oaxvnECp3QOzg0Dn+KKRzfIHF7qSdRkA65Q==
|
||||
"file-icons@github:file-icons/atom":
|
||||
version "2.1.47"
|
||||
resolved "https://codeload.github.com/file-icons/atom/tar.gz/66d57920f352fa5ed0c66f6fe86a98b2b3b8dac1"
|
||||
dependencies:
|
||||
atom-fs v0.2.1
|
||||
lru-cache "^5.1.1"
|
||||
mapped-disposable "^1.0.3"
|
||||
micromatch "^4.0.2"
|
||||
|
||||
file-loader@^6.2.0:
|
||||
version "6.2.0"
|
||||
@ -9321,6 +9339,11 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
mapped-disposable@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/mapped-disposable/-/mapped-disposable-1.0.3.tgz#3eaad0b20b174142ee80bd37f675bab200abd569"
|
||||
integrity sha512-DpYYRSZjNB6tOg8E4BZ+rNsKe4WxoptwM8+JqHi8R0buJgHLmrmAfJtv4lcqqO1esTtxaPx4FXOR54bPoS9qwg==
|
||||
|
||||
marked@^1.2.9:
|
||||
version "1.2.9"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.9.tgz#53786f8b05d4c01a2a5a76b7d1ec9943d29d72dc"
|
||||
|
Loading…
Reference in New Issue
Block a user