text: import traverse from '../traverse'
  
  export default function parser(ast, themePrefix) {
    const result = []
  
    traverse(ast, {
      root: {
        enter(_, { tag, style }) {
          result.push(`<${tag} ${style}>`)
        },
        leave(_, { tag }) {
          result.push(`</${tag}>`)
        }
      },
  
      heading: {
        enter(_, { space, tag, style, getTagWithStyleByType }) {
          const { tag: aTag, style: aStyle } = getTagWithStyleByType('_link')
          const A = `<${aTag} ${aStyle}>`
  
          result.push(`${space}<${tag} ${style}>${A}`)
        },
        leave(_, { space, tag, getTagWithStyleByType }) {
          const { tag: aTag } = getTagWithStyleByType('_link')
  
          result.push(`${space}</${aTag}></${tag}>`)
        }
      },
  
      text: {
        enter(node, { space }) {
          const { value } = node
  
          result.push(`${space}${value}`)
        },
        leave(_, { space }) {
          result.push(`${space}`)
        }
      },
  
      blockquote: {
        enter(_, { space, tag, style, getTagWithStyleByType }) {
          const { tag: pTag, style: pStyle } = getTagWithStyleByType('link')
          const P = `<${pTag} ${pStyle}>`
  
          result.push(`${space}<${tag} ${style}>${P}`)
        },
        leave(_, { space, tag, getTagWithStyleByType }) {
          const { tag: pTag } = getTagWithStyleByType('link')
  
          result.push(`${space}</${pTag}></${tag}>`)
        },
      },
  
      paragraph: {
        enter(node, { space, style, tag }) {
          // 父级是checkbox类型时 应被 li 包裹
          if (typeof node.findParent().checked !== 'boolean') {
            result.push(`${space}<${tag} ${style}>`)
          }
        },
        leave(node, { space, tag }) {
          if (typeof node.findParent().checked !== 'boolean') {
            result.push(`${space}</${tag}>`)
          }
        }
      },
  
      inlineCode: {
        enter(node, { space, tag, style }) {
          const { value } = node
  
          result.push(`${space}<${tag} ${style}>${value}`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      code: {
        enter(node, { space, tag, style, getTagWithStyleByType }) {
          const { lang, value } = node
          const { tag: codeTag, style: codeStyle } = getTagWithStyleByType('inlineCode')
          const Code = `<${codeTag} ${codeStyle}>`
          const codeValue = value
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
  
          result.push(`${space}<${tag} ${style} lang="${lang}">${Code}${codeValue}`)
        },
        leave(_, { space, tag, getTagWithStyleByType }) {
          const { tag: codeTag } = getTagWithStyleByType('inlineCode')
  
          result.push(`${space}</${codeTag}></${tag}>`)
        }
      },
  
      link: {
        enter(node, { space, tag, style, getTagWithStyleByType }) {
          const { url } = node
          const { tag: aTag, style: aStyle } = getTagWithStyleByType('_link')
          const A = `<${aTag} ${aStyle} href="${url}">`
  
          result.push(`${space}<${tag} ${style}>${A}`)
        },
        leave(_, { space, getTagWithStyleByType }) {
          const { tag: aTag } = getTagWithStyleByType('_link')
  
          result.push(`${space}</${aTag}>`)
        }
      },
  
      list: {
        enter(_, { space, tag }) {
          result.push(`${space}<${tag}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      listItem: {
        enter(node, { space, tag, style, getTagWithStyleByType }) {
          const isCheckbox = typeof node.checked === 'boolean'
          const attrs = isCheckbox ? `type="checkbox" disabled ${node.checked ? 'checked' : ''}` : ''
  
          // checkbox 需要被 li 包裹
          let wrapper = ''
          if (isCheckbox) {
            const { tag: liTag, style: liStyle } = getTagWithStyleByType('__listItem_checkbox')
            wrapper = `<${liTag} ${liStyle}>`
          }
  
          result.push(`${space}${wrapper}<${tag} ${style} ${attrs}>`)
        },
        leave(node, { space, tag, getTagWithStyleByType }) {
          const isCheckbox = typeof node.checked === 'boolean'
  
          let wrapper = ''
          if (isCheckbox) {
            const { tag: liTag } = getTagWithStyleByType('__listItem_checkbox')
            wrapper = `</${liTag}>`
          }
  
          result.push(`${space}${wrapper}</${tag}>`)
        }
      },
  
      table: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      tableRow: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      tableCell: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      html(node, { space }) {
        const { value } = node
  
        result.push(`${space}${value}`)
      },
  
      emphasis: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      strong: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      delete: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
      
      thematicBreak: {
        enter(_, { space, tag, style }) {
          result.push(`${space}<${tag} ${style}>`)
        },
        leave(_, { space, tag }) {
          result.push(`${space}</${tag}>`)
        }
      },
  
      image: {
        enter(node, { space, tag, style, getTagWithStyleByType }) {
          const { url, alt } = node
  
          const { tag: imgTitleTag, style: imgTitleStyle } = getTagWithStyleByType('__imgTitle')
          const __imgTitle = `<${imgTitleTag} ${imgTitleStyle}>${alt}`
      
          result.push(`${space}<${tag} ${style} src="${url}" alt="${alt}">${__imgTitle}`)
        },
        leave(_, { space, tag, getTagWithStyleByType }) {
          const { tag: imgTitleTag } = getTagWithStyleByType('__imgTitle')
  
          result.push(`${space}</${imgTitleTag}></${tag}>`)
        }
      }
  
    }, themePrefix)
  
    return result.join('')
  }