暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Go语言博客写作与文档解析

红牛编程 2018-11-20
433

项目练习,学以致用。转发或赞赏得视频。将赞赏或转发的截图发送给微信号: 540090808 (韩忠康) 即可获取视频。


1 文档存储2 markdown 文件格式3 文章对象4 文章对象构造方法

1 文档存储

/source/
目录,数据源目录,用于存放与文章相关的原始数据,例如 markdown 文件,文章内容使用的图像文件等。可能的子目录有 post
image
draft
等。

其中 /source/post/
目录用于存储创建的 markdown 文件,就是文章内容。写作的第一个步骤,就是在该目录中创建后缀为 .md
格式的文件,例如 /source/post/hello.md
。此处我们先手动创建,后面会使用定义一个命令来创建文章内容模板。

2 markdown 文件格式

文章内容分为两部分,文章元信息和文章内容。演示如下:

------
title: 第一篇博客
category: go
tag:
- markdown
- yaml
- go
------

## 摘要
在这里是文章摘要

<!-- more -->
## 标题 2
文章内容

### 标题 3
章节内容

元信息在文章开头,使用 ------(6个-) 来包裹。

元信息部分使用 YAML 格式,用于表示文章属性,例如标题,作者,分类,标签,封面图片,发布时间等。

内容使用 markdown 格式。

3 文章对象

定义 Post 结构体对象用于存储解析后的文章内容,结构体定义如下:

将 该结构体定义在 post 包中,就是 post.Post 是我们的文章类型。

/src/post/post.go

package post

// Post 文章结构体的结构
type Post struct {
  // 对应的文件名例如,hello.md
  file string
  // 标题
  Title string
  // 作者
  Author string
  // 封面图片
  Cover string
  // 分类
  Category string
  // 标签
  Tags []string
  // 发布时间
  Date string
  // 内容
  Content template.HTML
}

4 文章对象构造方法

为文章对象提供构造方法,用来解析文章内容,实例化文章对象,代码如下:

思路是:读取文件内容,使用正则剥离元信息和内容部分,通过 gopkg.in/yaml.v2
包解析元信息,通过 gopkg.in/russross/blackfriday.v2
包解析文章内容,最后实例化 Post 结构体对象。

/src/post/post.go

import (
  "errors"
  "gopkg.in/russross/blackfriday.v2"
  "gopkg.in/yaml.v2"
  "html/template"
  "io/ioutil"
  "regexp"
)

//构造方法
func New(f string) (*Post, error) {

  // 读取文件内容,得到切片
  content, err := ioutil.ReadFile(f)
  if nil != err {
    return nil, errors.New("文章读取失败")
  }

  // 拆解内容,获取元信息和内容主体部分,使用 regexp完成
  // 元信息:以6个-开头,匹配任意字符串(包括换行)的子模式,到6个-结束。
  pattern:=`(?s)^-{6}(.*)-{6}\s*(.*)$`
  reg, err := regexp.Compile(pattern)
  if nil != err {
    return nil, err
  }

  // 查找内容
  result := reg.FindAllStringSubmatch(string(content), -1)
  if len(result) < 1 {
    return nil, errors.New("文章解析失败")
  }
  mateInfo := result[0][1]
  contentBody := result[0][2]

  // 解析元信息 yaml
  var mates map[string]interface{}
  err = yaml.Unmarshal([]byte(mateInfo), &mates)
  if nil != err {
    return nil, err
  }

  // 转换到需要的类型。通过空接口的类型断言获取数据
  t, _ := mates["title"].(string)
  a, _ := mates["author"].(string)
  cov, _ := mates["cover"].(string)
  d, _ := mates["date"].(string)
  cat, _ := mates["category"].(string)
  var ts []string
  // 遍历每个tag重新赋值,转换为切片才能遍历
  for _, v :=range mates["tags"].([]interface{}) {
    ts = append(ts, v.(string))
  }

  // 解析 markdown 格式,生成 html 格式内容
  c := blackfriday.Run([]byte(contentBody))
  // 获取Post对象
  p := &Post {
    file: f,
    Title: t,
    Author: a,
    Cover: cov,
    Date: d,
    Category: cat,
    Tags: ts,
    Content:template.HTML(string(c)),
  }
  return p, nil
}

完!
原文出自:小韩说课


文章转载自红牛编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论