Merge pull request #15 from ueberdosis/feature/parse-code-blocks

Add language support to Code Block’s parseDOM function
This commit is contained in:
Philipp Kühn
2020-09-30 19:21:17 +02:00
committed by GitHub
6 changed files with 44 additions and 8 deletions

View File

@@ -3,6 +3,7 @@ module.exports = {
'@babel/preset-env',
],
plugins: [
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
],
}

View File

@@ -69,6 +69,16 @@ context('/api/extensions/code-block', () => {
})
})
it('should parse the language from a HTML code block', () => {
cy.get('.ProseMirror').then(([{ editor }]) => {
editor.setContent('<pre><code class="language-css">body { display: none; }</code></pre>')
cy.get('.ProseMirror')
.find('pre>code.language-css')
.should('have.length', 1)
})
})
it('should make a code block for js', () => {
cy.get('.ProseMirror').then(([{ editor }]) => {
editor.clearContent()

View File

@@ -17,9 +17,10 @@ yarn add @tiptap/extension-code-block
```
## Settings
| Option | Type | Default | Description |
| ------ | ------ | ------- | -------------------------------------------- |
| class | string | | Add a custom class to the rendered HTML tag. |
| Option | Type | Default | Description |
| ------------------- | ------ | --------- | ---------------------------------------------------------------- |
| class | string | | Add a custom class to the rendered HTML tag. |
| languageClassPrefix | string | language- | Adds a prefix to language classes that are applied to code tags. |
## Commands
| Command | Options | Description |

View File

@@ -21,6 +21,7 @@
"reset": "yarn clean:packages && rm -rf ./**/.cache && rm -rf ./**/node_modules && rm -rf ./yarn.lock && yarn install"
},
"devDependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.11.0",
"@babel/preset-env": "^7.11.5",
"@types/prosemirror-commands": "^1.0.3",

View File

@@ -1,6 +1,10 @@
import { Command, Node } from '@tiptap/core'
import { textblockTypeInputRule } from 'prosemirror-inputrules'
export interface CodeBlockOptions {
languageClassPrefix: string,
}
export type CodeBlockCommand = () => Command
declare module '@tiptap/core/src/Editor' {
@@ -11,9 +15,12 @@ declare module '@tiptap/core/src/Editor' {
export const inputRegex = /^```(?<language>[a-z]*)? $/
export default new Node()
export default new Node<CodeBlockOptions>()
.name('code_block')
.schema(() => ({
.defaults({
languageClassPrefix: 'language-',
})
.schema(({ options }) => ({
attrs: {
language: {
default: null,
@@ -26,9 +33,25 @@ export default new Node()
defining: true,
draggable: false,
parseDOM: [
{ tag: 'pre', preserveWhitespace: 'full' },
{
tag: 'pre',
preserveWhitespace: 'full',
getAttrs(node) {
const classAttribute = (node as Element).firstElementChild?.getAttribute('class')
if (!classAttribute) {
return null
}
const regexLanguageClassPrefix = new RegExp(`^(${options.languageClassPrefix})`)
return { language: classAttribute.replace(regexLanguageClassPrefix, '') }
},
},
],
toDOM: node => ['pre', ['code', { class: node.attrs.language && `language-${node.attrs.language}` }, 0]],
toDOM: node => ['pre', ['code', {
class: node.attrs.language && options.languageClassPrefix + node.attrs.language,
}, 0]],
}))
.commands(({ name }) => ({
codeBlock: attrs => ({ commands }) => {

View File

@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "esnext",
"target": "es2019",
"module": "esnext",
"strict": true,
"jsx": "preserve",