Development of zero foundation exclusive Markdown online editor

Posted by worldofcarp on Thu, 24 Feb 2022 07:27:02 +0100

Development of zero foundation exclusive Markdown online editor

Online case

Markdown is also a markup language, which is similar to HTML and has nothing to do with CSS. The display styles of markdown editors (Typora, etc.) we usually use and see are displayed after being converted to HTML and CSS with built-in styles;

Nowadays, the way of Markdown writing + HTML presentation is no longer limited to client writing, but is increasingly favored by various websites, especially blog / forum websites, such as nuggets community, CSDN, blog Garden, etc; What these websites have in common is that they provide the function of writing and editing articles online, and basically follow the Markdown writing + HTML display mode;

1. Markdown and HTML

1) Name difference

The full name of HTML is hypertext markup language (Hypertext Markup Language), which focuses on the word markup and translates it into markup;

In contrast, markdown is just the opposite of markup, so we can understand that markdown means anti markup for the time being;

2) Functional difference

HTML focuses on the display of content, including form, style, format, etc; For a page user, as long as the page display is beautiful enough, he will not pay attention to the simplicity or complexity of the source code; Simple HTML can display the basic styles of content, such as h1, h2 ·······································································.

Markdown pays more attention to the writing methods and rules of content (source code). Simple and efficient writing and rules enable users to get twice the result with half the effort; Therefore, the main users of markdown are content generators, such as document writers.

2. Markdown to HTML

In fact, the principle of converting Markdown (all later expressed in MD) into HTML is not difficult. It is essentially the conversion of strings. For example, if you recognize the MD content of # primary title, it is judged as starting with ## plus space and ending with newline, and the corresponding HTML string content of < H1 > primary title < / H1 > is generated. Of course, in fact, the transformation of all formats is far more complex than what I described. For example, the principle and production drawings of nuclear bombs have long been made public, but there are only a few countries that can build nuclear bombs.

Now there are many Markdown to HTML libraries, so we can also save making wheels and directly stand on the shoulders of giants for our development; The implementation of MD online editor described in this paper uses the technology Vite+Vue3+TypeScript+markedjs

First look at the result map: (online editing + saving + changing theme, etc.)

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-wmjmaath-1645683473228) (/ users / Haolian / library / Application Support / typora user images / image-20220224114821238. PNG)]

1)marked.js

Back to this article, after simple research, I finally chose to use marked.js Convert Markdown to HTML; It is installed and used in the same way as most node libraries:

// install
npm install marked
// Lead in (ES module)
import { marked } from "marked";
// Use mdStr: markdown text data, html: converted html format text data
let html = marked.parse(mdStr)

2) Markdown to HTML presentation

1. Define md2html function

// mdParser.ts
import { marked } from "marked";

export async function md2html(mdStr: string) {
    let html = await marked.parse(mdStr)
    return html;
}

2. Online HTML content rendering (v-html)

Convert MD to HTML through marked, and then bind the converted htmlValue to the defined div through v-html. A simple MD to HTML online rendering page is realized;

// mdEditor.vue
<template>
  ···
	<div class="markdown-body" id="markdown" v-html="htmlValue"></div>
</template>

<script lang='ts'>
  ···
  import { md2html } from '../utils/mdParser';
  ···
  
  export default defineComponent({
    setup() {
      ···
      let mdValue = ref<string>('');
    	let htmlValue = ref<string>('');
      ···
      htmlValue.value = await md2html(mdValue.value);
      return {
        htmlValue
      }
    }
  })
</script>

3) MD online editing and HTML real-time rendering

  • Divide the page area: MD editing area (implemented by textarea) and HTML rendering area (v-html);
  • Monitor the data changes in the MD editing area and update the HTML rendering area in real time;
// mdEditor.vue
<template>
  ···
					<div class="editor-area">
                ···
                    <div class="m-text">
                        <a-textarea
                            id="text-area"
                            class="m-textarea boxshadow"
                            v-model:value="mdValue"
                            style="padding: 10px"
                        />
                    </div>
          
                ····
                    <div class="m-lr boxshadow">
                        <div class="markdown-body" id="markdown" v-html="htmlValue"></div>
                    </div>
               ···
        </div>
	···
</template>

<script lang='ts'>
  ···
  import { md2html } from '../utils/mdParser';
  ···
  
  export default defineComponent({
    setup() {
      ···
      let mdValue = ref<string>('');
    	let htmlValue = ref<string>('');
      ···
      watch([mdValue], async () => {
        let md = await md2html(mdValue.value);
        htmlValue.value = md;
      });
      return {
        htmlValue,
        mdValue
      }
    }
  })
</script>

4) Replace MD theme

The theme is actually a series of CSS styles. I set CSS styles for various elements in MD to HTML respectively. Here I'm lazy and learn from them directly Nuggets Part of the theme; When you open the source code of the article, you can see that Nuggets has made a clear distinction between the MD area and all topics. It is found that the class in the MD area is written as markdown body, and the CSS style of relevant topics is directly placed under the dom, which is very convenient for us to learn from 😂

The specific reference is as follows:

  • Find the MD rendering area of the Nuggets article (red box);
  • Copy the style in the style label (green box);
  • The theme CSS style is stored in the database to facilitate acquisition, replacement and rendering;

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-slxwma6d-1645683473231) (/ users / Haolian / library / Application Support / typora user images / image-202202241320326. PNG)]

Of course, if you have time and energy, you can write the theme style directly. It's not advisable for me to learn (steal) like this!

The final success is shown in the figure below:

[the external link image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-bkinu2tv-1645683473232) (/ users / Haolian / library / Application Support / typera user images / image-2022022413275443. PNG)]

Direct code:

<template>
    				···
                <div class="m-b">
                    Select theme:
                    <a-select
                        style="margin-right: 10px; width: 200px"
                        v-model:value="selectTheme"
                        :options="options"
                    ></a-select>
                </div>
                ····
        <div class="editor-area">
            ···
                        <a-textarea
                            id="text-area"
                            class="m-textarea boxshadow"
                            v-model:value="mdValue"
                            style="padding: 10px"
                        />
                ···
                    <div class="m-lr boxshadow">
                        <div class="markdown-body" id="markdown" v-html="htmlValue"></div>
                    </div>
             ···
        </div>
    </a-card>
</template>

<script lang='ts'>
···
import { defineComponent, onMounted, reactive, ref, watch } from 'vue';
import { md2html } from '../utils/mdParser';
import { getAllTheme } from '../api/blog';
  
export default defineComponent({
    ···
    setup() {
  			···
        let mdValue = ref<string>('');
        let htmlValue = ref<string>('');
        let selectTheme = ref<string>('');
        let mdTitle = ref<string>('');
        let options = reactive<Array<{ value: string; label: string }>>([]);
  			···
				// Interface to get all theme styles
        const getTheme = async () => {
            const theme: any = await getAllTheme();
            theme.forEach((item) => {
                options.push({
                    label: item.theme,
                    value: item.style,
                });
            });
          	// The first topic is selected by default
            selectTheme.value = options[0].value;
        };
        onMounted(getTheme);
      	// Listen for changes in topics and md contents
        watch([mdValue, selectTheme], async () => {
            let md = await md2html(mdValue.value);
            htmlValue.value = selectTheme.value ? selectTheme.value + md : md;
        });
        return {
            selectTheme,
            options,
            mdValue,
            htmlValue,
            mdTitle,
            chnageType,
        };
    },
});
</script>

5) File save

Use here file-saver Save data in different formats. The specific use method is Baidu / Google. Just look at the document. It's very simple!

summary

It is not difficult to find from the above contents that it is not difficult to develop an MD online editor. On the one hand, it benefits from the powerful and comprehensive front-end ecology, and on the other hand, it benefits from the learning and reference of excellent projects. Otherwise, just writing a native MD parser is enough for us to drink a pot, and then customizing various themes requires all kinds of costs, These are enough to dissuade a large number of developers.

In the end, thanks to the times and will feed back to the times, you and I are all practitioners!

I've seen the end. If I think it's OK, I'll give you some advice, praise, collect and pay attention 😄, Code word unceasingly, insist on updating!

Personal homepage: http://www.wawow.xyz

Topics: Front-end html markdown