tiptap 中文文档

tiptap CodeBlockLowlight 代码高亮

使用 CodeBlockLowlight  代码高亮扩展,你可以在文档中显示源代码而不被浏览器解析,代码包裹在HTML标记的 precode 标签中,并且可以让代码高亮

Install 安装

npm install lowlight @tiptap/extension-code-block-lowlight

Settings 配置

lowlight 导入lowlight插件给扩展。

import { lowlight } from 'lowlight/lib/core'

CodeBlockLowlight.configure({
  lowlight,
})

languageClassPrefix 代码样式class的前缀。

CodeBlockLowlight.configure({
  languageClassPrefix: 'language-',
})

defaultLanguage 设置默认语言比如javascript、html。

CodeBlockLowlight.configure({
  defaultLanguage: 'plaintext',
})

HTMLAttributes 自定义标签对应的HTML属性。

CodeBlockLowlight.configure({
  HTMLAttributes: {
    class: 'my-custom-class',
  },
})

Commands 命令

setCodeBlock 将选中内容转换为代码块。

editor.commands.setCodeBlock()

toggleCodeBlock 将选中内容切换为代码块或取消代码块。

editor.commands.toggleCodeBlock()

Shortcuts 快捷键

Windows/Linux Control Alt C
macOS Cmd Alt C

源代码

CodeBlockLowlight 源代码

在线例子

vue 在线例子

CodeBlockLowlight 例子

  • Vue 例子

  • React 例子

<template>
  <div v-if="editor">
    <button @click="editor.chain().focus().toggleCodeBlock().run()" :class="{ 'is-active': editor.isActive('codeBlock') }">
      toggleCodeBlock
    </button>
    <button @click="editor.chain().focus().setCodeBlock().run()" :disabled="editor.isActive('codeBlock')">
      setCodeBlock
    </button>
    <editor-content :editor="editor" />
  </div>
</template>
<script>
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { Editor, EditorContent } from '@tiptap/vue-3'
import css from 'highlight.js/lib/languages/css'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import html from 'highlight.js/lib/languages/xml'
// load all highlight.js languages
import { lowlight } from 'lowlight'

lowlight.registerLanguage('html', html)
lowlight.registerLanguage('css', css)
lowlight.registerLanguage('js', js)
lowlight.registerLanguage('ts', ts)

export default {
  components: {
    EditorContent,
  },
  data() {
    return {
      editor: null,
    }
  },
  mounted() {
    this.editor = new Editor({
      extensions: [
        Document,
        Paragraph,
        Text,
        CodeBlockLowlight.configure({
          lowlight,
        }),
      ],
      content: `
        <p>
          That’s a boring paragraph followed by a fenced code block:
        </p>
        <pre><code>for (var i=1; i <= 20; i++)
{
  if (i % 15 == 0)
    console.log("FizzBuzz");
  else if (i % 3 == 0)
    console.log("Fizz");
  else if (i % 5 == 0)
    console.log("Buzz");
  else
    console.log(i);
}</code></pre>
        <p>
          Press Command/Ctrl + Enter to leave the fenced code block and continue typing in boring paragraphs.
        </p>
      `,
    })
  },

  beforeUnmount() {
    this.editor.destroy()
  },
}
</script>
<style>
/* Basic editor styles */
.ProseMirror {
  > * + * {
    margin-top: 0.75em;
  }
  pre {
    background: #0D0D0D;
    color: #FFF;
    font-family: 'JetBrainsMono', monospace;
    padding: 0.75rem 1rem;
    border-radius: 0.5rem;
    code {
      color: inherit;
      padding: 0;
      background: none;
      font-size: 0.8rem;
    }
    .hljs-comment,
    .hljs-quote {
      color: #616161;
    }
    .hljs-variable,
    .hljs-template-variable,
    .hljs-attribute,
    .hljs-tag,
    .hljs-name,
    .hljs-regexp,
    .hljs-link,
    .hljs-name,
    .hljs-selector-id,
    .hljs-selector-class {
      color: #F98181;
    }
    .hljs-number,
    .hljs-meta,
    .hljs-built_in,
    .hljs-builtin-name,
    .hljs-literal,
    .hljs-type,
    .hljs-params {
      color: #FBBC88;
    }
    .hljs-string,
    .hljs-symbol,
    .hljs-bullet {
      color: #B9F18D;
    }
    .hljs-title,
    .hljs-section {
      color: #FAF594;
    }
    .hljs-keyword,
    .hljs-selector-tag {
      color: #70CFF8;
    }
    .hljs-emphasis {
      font-style: italic;
    }
    .hljs-strong {
      font-weight: 700;
    }
  }
}
</style>
// load specific languages only
// import { lowlight } from 'lowlight/lib/core'
// import javascript from 'highlight.js/lib/languages/javascript'
// lowlight.registerLanguage('javascript', javascript)
import './styles.scss'

import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import { EditorContent, useEditor } from '@tiptap/react'
import css from 'highlight.js/lib/languages/css'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import html from 'highlight.js/lib/languages/xml'
// load all highlight.js languages
import { lowlight } from 'lowlight'
import React from 'react'

lowlight.registerLanguage('html', html)
lowlight.registerLanguage('css', css)
lowlight.registerLanguage('js', js)
lowlight.registerLanguage('ts', ts)

export default () => {
  const editor = useEditor({
    extensions: [
      Document,
      Paragraph,
      Text,
      CodeBlockLowlight.configure({
        lowlight,
      }),
    ],
    content: `
        <p>
          That’s a boring paragraph followed by a fenced code block:
        </p>
        <pre><code class="language-javascript">for (var i=1; i <= 20; i++)
{
  if (i % 15 == 0)
    console.log("FizzBuzz");
  else if (i % 3 == 0)
    console.log("Fizz");
  else if (i % 5 == 0)
    console.log("Buzz");
  else
    console.log(i);
}</code></pre>
        <p>
          Press Command/Ctrl + Enter to leave the fenced code block and continue typing in boring paragraphs.
        </p>
      `,
  })

  if (!editor) {
    return null
  }

  return (
    <>
      <button
        onClick={() => editor.chain().focus().toggleCodeBlock().run()}
        className={editor.isActive('codeBlock') ? 'is-active' : ''}
      >
        toggleCodeBlock
      </button>
      <button
        onClick={() => editor.chain().focus().setCodeBlock().run()}
        disabled={editor.isActive('codeBlock')}
      >
        setCodeBlock
      </button>


      <EditorContent editor={editor} />
    </>
  )
}

/* Basic editor styles */
/*
.ProseMirror {
  > * + * {
    margin-top: 0.75em;
  }

  pre {
    background: #0d0d0d;
    border-radius: 0.5rem;
    color: #fff;
    font-family: "JetBrainsMono", monospace;
    padding: 0.75rem 1rem;

    code {
      background: none;
      color: inherit;
      font-size: 0.8rem;
      padding: 0;
    }

    .hljs-comment,
    .hljs-quote {
      color: #616161;
    }

    .hljs-variable,
    .hljs-template-variable,
    .hljs-attribute,
    .hljs-tag,
    .hljs-name,
    .hljs-regexp,
    .hljs-link,
    .hljs-name,
    .hljs-selector-id,
    .hljs-selector-class {
      color: #f98181;
    }


    .hljs-number,
    .hljs-meta,
    .hljs-built_in,
    .hljs-builtin-name,
    .hljs-literal,
    .hljs-type,
    .hljs-params {
      color: #fbbc88;
    }

    .hljs-string,
    .hljs-symbol,
    .hljs-bullet {
      color: #b9f18d;
    }

    .hljs-title,
    .hljs-section {
      color: #faf594;
    }

    .hljs-keyword,
    .hljs-selector-tag {
      color: #70cff8;
    }

    .hljs-emphasis {
      font-style: italic;
    }

    .hljs-strong {
      font-weight: 700;
    }
  }
}
*/
Catalog
快速入门 Guide 向导 API 列表 tiptap 方法 tiptap 属性 titap 配置 commands 命令 nodes 节点 Blockquote 引用扩展 BulletList 无序序列扩展 CodeBlock 代码块扩展 CodeBlockLowlight 代码高亮 Document 节点 HardBreak 换行节点 Heading 标题节点 HorizontalRule 横线节点 Image 图片扩展 ListItem 节点 Mention 提及节点 OrderedList 有序列节点 Paragraph 段落节点 Table 表格扩展 TaskList 任务列表 TaskItem 任务列表项 Text 节点 marks 标记 extensions 扩展