Hugo v0.6.x升级那些事儿

从去年九月开始,很长一段时间一直停留在Hugo v0.56,因为没搞明白Homebrew的回滚机制。自从托管给了zeit,在now.json的环境文件里完全可以自由控制版本,由此一发不可收拾,彻底放飞自我。想升就升,想降就降,不亦乐乎?

Hugo 0.6x有哪些重大升级

除却一些鸡零狗碎的升级外,Hugo 0.6x系统最大的变化即,跟着Gitea更换了一个GO语言的markdown parser,将原先的Blackfriday 换成了Goldmark ,基于CommonMark规范标准,支持GFM。

有网友做过测试,在CommonMark规范的前提下,4款Go实现的Markdown引擎Lute、goldmark、Blackfriday和golang-commonmark的性能差距不大 ,某种程度来讲,Blackfriday因为没有实现GFM,性能反倒看上去更好一些。

当初码云换CommonMark规范解析器时,罗列过有若干好处:

  • 标题#后面需要有空格才会正确渲染标题
  • 正确解析形如 Map<String, Collection<Object.toString» 的文本
  • 解决代码块标签前后没有空行导致不换行显示
  • 解决Readme中注释显示的问题
  • 解决 Html colspan、rowspan 标签无效的问题
  • 解决标题中不支持Code块的问题
  • 解决内容中不留空格无法加粗的问题
  • 支持–构建表格

当然也有不足之处,例如不再支持[TOC],因此建议在升级前好好研究下Hugo v0.6.x的新版Configure Markup

本主题升级过程中遇到的若干问题

代码块出现黑框背景、代码高亮异常

出现该问题的原因是v0.6.x版本以上的glodmark默认全局开启了Fenced Code Blocks高亮模式,与本主题的代码高亮插件highlightjs-line-numbers.js发生冲突。

 "markup": {
      "highlight": {
         "codeFences": false,//默认开启,如果你和我一样用了其它高亮插件,请选择false
         "guessSyntax": false,
         "hl_Lines": "",
         "lineNoStart": 1,
         "lineNos": false,
         "lineNumbersInTable": false,//默认开启,以防万一,建议关闭
         "noClasses": false,//默认开启,以防万一,建议关闭
         "style": "monokai",
         "tabWidth": 4
      }
   }

个别shortcode模板失效

附件模板在升级后变形失效
附件模板在升级后变形失效

在升级到0.6.0版本之后,出现了attachment等个别shortcode失效的情况,原因是非markdown语法的html的话预设会变成 <!-- raw HTML omitted -->。为此,Hugo官方0.6.0版的release中提到一项类似Blackfriday中 skipHTML的设置:

Also, if you have lots of inline HTML in your Markdown files, you may have to enable the unsafe mode:

   "goldmark": {
         "renderer": {
            "hardWraps": false,
            "unsafe": true,//默认是关闭,如果你应用了很多shortcode模板,建议开启
            "xHTML": false
         }
}

然鹅,并无卵用。于是,遍历了互联网终于找到了解决方案-在shortcode的模板代码首行中写入:

{{ $_hugo_config := `{ "version": 1 }` }}

这个办法之前在《hugo 0.55.0彩蛋版有哪些变化 》中提到过,没想「 蓦然回首,那人却在灯火阑珊处」。

默认无法以新标签页打开外链

在Blackfriday时代,可以设置外链默认以新标签页打开。为此,我还特意写过一篇《HUGO 如何默认以新建标签方式打开外链 》的文章,重点只有一条:

   "blackfriday": {
    	"hrefTargetBlank":true
    }

但Goldmark时代降临后,所有的外链只能在本页面跳转。对SEO来说,这是大忌,但我的考虑出发点仅仅是用户体验感不好。

Hugo v0.62.0及以上版本中, Goldmark有一项新功能Render Hooks,可以拓展markdown的行为清单,例如重新调整已上传的图像、以新标签打开外链等。需要做的仅仅是在layouts/_default/_markup目录中创建相应模板。标准目录结构如下:

layouts
└── _default
    └── _markup
        ├── render-image.html
        ├── render-image.rss.xml
        └── render-link.html

为了能够实现在新标签页面中打开外链的目的,可以在layouts/_default/_markup目录下创建一个名为render-link.html的新文件,文件内容为:

<a
  href = "{{.Destination | safeURL}}"
  {{  with  . Title  }}  title = "{{.}}" {{  end  }}
  {{  if  strings . HasPrefix  . Destination  " http "  }} target = "_blank"  rel = "noopener" {{  end  }} >
  {{.Text}} </a>

如果你用了以下链接的书写格式

[Neist](https://nei.st/  "华人独立政见媒体流")

那么会被 渲染成这样的代码

 href= "Https://nei.st/"  Title= <a "华人独立政见媒体流"  Target= "_Blank"  Rel= "Noopener">
  Neist  </a>

效果如下:

Neist

添加Noopener标签可以阻止新标签利用JavaScript功能。同样,rel =“noreferrer”属性也可防止将引用者信息传递给新页面,增加隐私性。

部分代码换行失效

如前篇《重拾中州韵 》所言:

- [mritd的rime词库][l1]: 该版本比较精简基础,不包含五笔和双拼方案。
- [alswl的rime词库][l2]:最齐全的朙月拼音扩展词库,更新也非常及时。
- [JackChen007的rime词库][l3]: 包罗万象的一个词典仓库,有中古三拼、日语、粤语等多语种的输入解决方案

[l1]: https://github.com/mritd/rime
[l2]: https://github.com/alswl/Rime
[l3]: https://github.com/JackChen007/myRimeCfg

切换到Goldmark后,按《markdown链接的另一种写法 》写的末部markdown链接,全部没被加<br>

后置式markdown链接写法在升级后失效
后置式markdown链接写法在升级后失效

后来无意间发现,打开hardwraps即可。

   "goldmark": {
         "renderer": {
            "hardWraps": false,//默认是关闭,如果你和我一样有换行引发的排版问题,建议打开试试
            "unsafe": true,
            "xHTML": false
         }
}

这里涉及到一个hardwraps的作用:

Github对于GFM hardwraps有一段介绍:

The biggest difference that Github Flavored Markdown introduces is in the handling of linebreaks. With Standard Markdown you can hard wrap paragraphs of text and they will be combined into a single paragraph. We find this to be the cause of a huge number of unintentional formatting errors. GFM treats newlines in paragraph-like content as real line breaks, which is probably what you intended.

以下列代码为例:

Line one
Line two

Par two

如果设置开启hardwraps,则输出:

<p>Line one
<br>Line two</p>

<p>Par two</p>

如果设置关闭hardwraps,则输出:

<p>Line one Line two</p>

<p>Par two</p>

relref被删除并无实质影响

官方在Hugo v0.60.0的声明中有一条:

Hugo

Remove .Site.Ref/RelRef 69fd1c60

看完真真让人惊出一身冷汗,因为在以往的文章中有不少类似Ref/Relref的写法:

《[WebP部署那些事儿]({{< relref"20190404WebP部署那些事儿.md" >}})》

但实际生成的时候,并没有受到影响。官方文档中Ref/Relref那页 也活得好好的,并没有被删除的痕迹,看来受影响的只有.site前缀的Ref/Relref,虚惊一场。

两代脚注的渲染结果在css层面值得注意

根据goldmark 0.60的代码,Hugo脚注的渲染结果与上一代blackfriday相比,有局部改变

func (r *FootnoteHTMLRenderer) renderFootnoteBackLink(w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) {
  if entering {
    n := node.(*ast.FootnoteBackLink)
    is := strconv.Itoa(n.Index)
    _, _ = w.WriteString(`<a href="#fnref:`)
    _, _ = w.WriteString(is)
    _, _ = w.WriteString(`" class="footnote-backref" role="doc-backlink">`)
    _, _ = w.WriteString("&#8617;")
    _, _ = w.WriteString(`</a>`)
  }
  return gast.WalkContinue, nil
}

实测显示,blackfriday配置中footnoteAnchorPrefix, footnoteReturnLinkContents等参数都失效了,而且HTML渲染结果去掉了a锚点的rel=参数,加了个role=参数,这个倒没实质性影响,但在写css时要稍加留意。

前代注脚的通常被渲染成


<div class="footnotes" rel="footnote">
<hr>
<ol>
<li id="fn:1">text1</li>
<li id="fn:2">text2</li>
……
<li id="fn:N">text3</li>
</ol>
</div>

在Hugo v0.6.x后,则为

<section class="footnotes" role="doc-endnotes">
<hr><ol>
<li id="fn:1" role="doc-endnote">text1</li>
<li id="fn:2" role="doc-endnote">text2</li>
……
<li id="fn:N" role="doc-endnote">text3</li>
</ol>
</section>