HTML逆向生成Markdown -- Part 2

HTML逆向生成Markdown -- Part 2

接上一篇HTML逆向生成Markdown -- Part 1javascript

在前文的结尾,咱们已经将HTML文本处理为一个个虚拟DOM节点(JSON对象)了。java

为了方便以后的处理,新增长了两个表示结束标签的节点,以方便构建DOM树。数组

const result = [
    {
        tag: 'h2',
        type: 42,           // 不要在乎`type`属性,这是自定义的,42表明`h2`元素对应数字
        position: 1
    },
    {
        tag: 'textNode',
        type: 1,
        position: 3,
        content: '逆向解析HTMl'
    },
    {
        tag: 'h2',
        type: 42,
        position: 2
    },
    {
        tag: 'p',
        type: 6,
        position: 1
    },
    {
        tag: 'a',
        type: 2,
        position: 1,
        attr: {
            href: 'https://www.baidu.com'
        }
    },
    {
        tag: 'textNode',
        type: 1,
        position: 3,
        content: 'Markdown'
    },
    {
        tag: 'a',
        type: 2,
        position: 2
    },
    {
        tag: 'p',
        type: 6,
        position: 2
    },
]
复制代码

构建虚拟DOM树

咱们已经用position属性标识了开始/结尾标签和文本节点,咱们知道在开始和结束标签之间的节点都属于该节点的子节点。 以此类推,就表示出一颗DOM树了。 以上文的节点数组为输入咱们来尝试构建一个虚拟DOM树。post

  1. 第一个是h2标签且为开始标签
[
    {
        tag: 'h2',
        type: 42
    }
]
复制代码
  1. 第二个是文本节点
[
    {
        tag: 'h2',
        type: 42,
        child: [
            {
                tag: 'textNode',
                type: 1,
                content: '逆向解析HTMl'
            }
        ]
    }
]
复制代码
  1. 第三个是h2的结束标签,结束标签不会改变树的结构。结束标签表示以后的节点都不是该节点的子节点。(在代码层面上来讲就是回退到父节点上,以后在添加节点就是添加到父节点的子节点数组中
[
    {
        tag: 'h2',
        type: 42,
        child: [
            {
                tag: 'textNode',
                type: 1,
                content: '逆向解析HTMl'
            }
        ]
    }
]
复制代码
  1. 第四个是p的开始标签。由于h2已经结束了,因此p被添加到根节点上。
[
    {
        tag: 'h2',
        type: 42,
        child: [
            {
                tag: 'textNode',
                type: 1,
                content: '逆向解析HTMl'
            }
        ]
    },
    {
        tag: 'p',
        type: 6
    }
]
复制代码
  1. 第五个是a的开始标签,由于上一个是p的开始标签,因此a被添加到p的子节点中
[
    {
        tag: 'h2',
        type: 42,
        child: [
            {
                tag: 'textNode',
                type: 1,
                content: '逆向解析HTMl'
            }
        ]
    },
    {
        tag: 'p',
        type: 6,
        child: [
            {
                tag: 'a',
                type: 2,
                attr: {
                    href: 'https://www.baidu.com'
                }
            }
        ]
    }
]
复制代码
  1. 第六个是文本节点,同理被添加到a的子节点中。
[
    {
        tag: 'h2',
        type: 42,
        child: [
            {
                tag: 'textNode',
                type: 1,
                content: '逆向解析HTMl'
            }
        ]
    },
    {
        tag: 'p',
        type: 6,
        child: [
            {
                tag: 'a',
                type: 2,
                attr: {
                    href: 'https://www.baidu.com'
                },
                child: [
                    {
                        tag: 'textNode',
                        type: 1,
                        position: 3,
                        content: 'Markdown'
                    }
                ]
            }
        ]
    }
]
复制代码
  1. 以后的两个都是结束标签,树结构也不会发生变化。

最终,咱们获得的是这样一个DOM树结构:spa

const  result = [
    {
        tag: 'h2',
        type: 42,
        child: [
            {
                tag: 'textNode',
                type: 1,
                content: '逆向解析HTMl'
            }
        ]
    },
    {
        tag: 'p',
        type: 6,
        child: [
            {
                tag: 'a',
                type: 2,
                attr: {
                    href: 'https://www.baidu.com'
                },
                child: [
                    {
                        tag: 'textNode',
                        type: 1,
                        position: 3,
                        content: 'Markdown'
                    }
                ]
            }
        ]
    }
]
复制代码

到这一步,咱们已经将HTML文本转化成了虚拟DOM树。最后也是最关键的一步,就是分析DOM树,根据MD规则生成MD文本了。 能够说以前的三个步骤都是为了最后一步服务的。code

相关文章
相关标签/搜索