Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Javascript】手把手教你自定义一个markdown编辑器 #67

Open
AwesomeDevin opened this issue Jan 20, 2022 · 0 comments
Open

Comments

@AwesomeDevin
Copy link
Owner

引言

markdown 是一种创作者通过输入简洁的文字便能够实现 自动排版 的排版语法,目前国内包括知乎、简书、掘金、v2ex,国外包括 stack overflow、github, 等各大内容创作平台都已经支持了 markdown 语法(当然也包括 jelly ),创作者也因为习惯了 markdown 语法,如果某个平台不支持 markdown 语法,那么必然会留下一个不好的印象,甚至可能被拉黑名单。
总而言之,拥有一个支持 markdown 语法的编辑器对于内容创作平台而言是尤为重要的。

那么,作为一个开发者来说,我们应该如何实现一个 markdown 编辑器呢?

主要做的事情有两部分:
1. 针对文本内容进行语法分析并自定义样式
2. 针对代码关键词需要高亮展示

一. 针对文本内容进行语法分析

1.1 markdown语法转html标签

就 markdown 语法而言,我们获取的输入值往往是:

# 这是标题
> 这是内容
#### 这是表格
表头1 | 表头2 | 表头3
------|-------|-------
内容1 | 内容2 | 内容3

这些输入值保存到数据库中到文本内容为:

# 这是标题↵> 这是内容↵#### 这是表格↵表头1 | 表头2 | 表头3↵------|-------|-------↵内容1 | 内容2 | 内容3

这里我们需要将对应markdown转变为浏览器可以识别的html标签:

  • # 文字处理为<h1>文字</h1>标签
  • > 文字处理为<blockquote><p>文字<p></blockquote>标签
  • xxx | xxx | xxx \n ---|---|---\n内容1 | 内容2 | 内容3处理为<table><thead><tbody><th><td>标签

这里推荐使用第三方库showdown,它是一个 JavascriptHTML的转换器,可以在客户端(在浏览器中)或服务器端(NodeJs )使用。

需要注意的是 showdown 无法识别特殊符号,在调用makeHtml()前,需要先将特殊符号处理为\n换行符。

text.replace(//g,'\n')

具体代码如下:

import showdown from 'showdown'
const converter = new showdown.Converter()
converter.setFlavor('github')
converter.makeHtml('# 这是标题↵> 这是内容↵#### 这是表格↵表头1 | 表头2 | 表头3↵------|-------|-------↵内容1 | 内容2 | 内容3'.replace(//g,'\n'))

最终得到 HTML 结构:

<h1 id="这是标题">这是标题</h1>
<blockquote>
  <p>这是内容</p>
</blockquote>
<h4 id="这是表格">这是表格</h4>
<table>
  <thead>
    <tr>
      <th id="表头1">表头1</th>
      <th id="表头2">表头2</th>
      <th id="表头3">表头3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>内容1</td>
      <td>内容2</td>
      <td>内容3</td>
    </tr>
  </tbody>
</table>
1.2 markdown语法自定义样式

使用标签选择器自定义样式

 blockquote {
    color: #7f8fa4;
    font-size: inherit;
    padding: 8px 24px;
    margin: 16px 0;
    border-left: 3px solid #eaeaea;
    p {
      margin: 0;
    }
  }
  table {
    thead {
      background: #292c34;
      color: #a9b0bd;
      th {
        border: 1px solid #292c34;
        border-right-color: #a9b0bd;
        padding: 10px 20px;
        box-sizing: border-box;
        &:nth-last-child(1) {
          border-color: #292c34;
        }
      }
    }
    tbody {
      td {
        border: 1px solid #292c34;
        padding: 10px 20px;
        box-sizing: border-box;
      }
    }
  }

实际效果:

二. 针对代码关键词需要高亮展示

2.1 提取代码块关键词

我们使用 markdown 语法展示代码时,往往会带上语言类型,如javascript:

转换效果如下:

<pre>
  <code class="javascript language-javascript">
    import showdown from 'showdown'
    const converter = new showdown.Converter()
    converter.setFlavor('github')
    converter.makeHtml('# 这是标题
        **这是加粗的文字**
        *这是斜体*'.replace(/
    /g,'\n'))</code>
</pre>

转换结果使用<pre><code>标签将整个代码块都给包裹在里面,并不能够区分代码块关键词(eg: 'import'、'class'),无法满足我们的需求。 这时便需要借助highlight.js来提取关键词,同时给对应关键词添加上className

2.2 highlight.js

highlight.js是一个 javascript 编写的语法高亮器,可以同时运行在浏览器跟服务端,不依赖任何框架,且具备自动检测语言功能。
highlightAll()方法可以自动识别页面上的

块,并自动检测语言。
识别结果:

&lt;pre&gt;&lt;code 
<span class="hljs-keyword">class</span>
=&quot;javascript language-javascript&quot;&gt;
<span class="hljs-keyword">import</span> 
showdown 
<span class="hljs-keyword">from</span> 
<span class="hljs-string">&#x27;showdown&#x27;</span>
const converter = 
<span class="hljs-built_in">new</span> 
showdown.Converter()
converter.setFlavor(
<span class="hljs-string">&#x27;github&#x27;</span>
)
converter.makeHtml(
<span class="hljs-string">&#x27;# 这是标题
**这是加粗的文字**
*这是斜体*&#x27;
</span>.replace(/
/g,
<span class="hljs-string">&#x27;\n&#x27;</span>))&lt;/code&gt;&lt;/pre&gt;

该库支持的语言种类繁多,包括gopythonjava等,详情可查看:
https://github.com/highlightjs/highlight.js/blob/main/SUPPORTED_LANGUAGES.md

2.3 代码高亮

代码高亮我们可以通过css自定义样式,也可以尝试引入hightlighth.js提供的官方样式(vscodeatomxcodegithub等)。

@import '../node_modules/highlight.js/styles/atom-one-dark.css';
2.4 代码高亮效果

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant