ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Hugo 页面方法 WordCount:深入理解字数统计与 CJK 处理规则

Hugo 页面方法 WordCount:深入理解字数统计与 CJK 处理规则 Hugo 页面方法 WordCount深入理解字数统计与 CJK 处理规则【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoWordCount 是 Hugo 页面对象Page提供的一个模板方法用于返回当前页面内容的单词数量返回值类型为int。在文章列表展示字数、阅读时间估算、SEO 元信息生成等场景中它是ReadingTime等派生指标的基础数据来源。读完本文你将掌握 WordCount 的调用方式、底层计数算法、CJK中日韩语言的特殊处理规则以及它与FuzzyWordCount、ReadingTime之间的关联。基本用法在 Hugo 模板中WordCount 以PAGE.WordCount的签名暴露直接在页面上下文中调用即可{{ .WordCount }} → 103例如在文章列表中显示约 103 字{{ if gt .WordCount 0 }} span{{ .WordCount }} words/span {{ end }}精确计数与模糊计数WordCount 与 FuzzyWordCountHugo 提供了两个互补的字数统计方法方法说明示例.WordCount返回精确的单词数量{{ .WordCount }}→ 103.FuzzyWordCount将字数向上取整到最近的 100 的倍数{{ .FuzzyWordCount }}→ 200FuzzyWordCount的用途是生成更整齐的展示数字如约 500 字其实现逻辑可以在 hugolib/page__content.go 中看到if result.fuzzyWordCount 0 { result.fuzzyWordCount (result.wordCount 99) / 100 * 100 }即(wordCount 99) / 100 * 100对精确字数做向上取整到百位。需要精确数字时用WordCount需要展示友好的近似值时用FuzzyWordCount。两者的方法定义都位于 hugolib/page__content.gofunc (c *cachedContentScope) WordCount(ctx context.Context) int { ctx c.prepareContext(ctx) return c.mustContentPlain(ctx).wordCount } func (c *cachedContentScope) FuzzyWordCount(ctx context.Context) int { ctx c.prepareContext(ctx) return c.mustContentPlain(ctx).fuzzyWordCount }底层计数算法从源码结构看WordCount 并不是对渲染后的 HTML 直接计数而是基于**纯文本plain text**进行统计。contentPlainPlainWords结构体hugolib/page__content.go同时缓存了plain、plainWords、wordCount、fuzzyWordCount和readingTime这些指标共享同一次内容解析结果。在默认非 CJK场景下Hugo 调用helpers.TotalWords完成计数实现在 helpers/content.go// TotalWords counts instance of one or more consecutive white space // characters, as defined by unicode.IsSpace, in s. // This is a cheaper way of word counting than the obvious len(strings.Fields(s)). func TotalWords(s string) int { n : 0 inWord : false for _, r : range s { wasInWord : inWord inWord !unicode.IsSpace(r) if inWord !wasInWord { n } } return n }该算法以unicode.IsSpace定义的空白字符作为单词分隔符统计连续非空白字符段的数量比直接调用strings.Fields再取长度的方式开销更低。这也意味着纯英文/拉丁文本的计数符合直觉按空格等空白符分词对于中文、日文等不使用空格分词的语言直接按此算法会把整段连续汉字计为 1 个单词因此需要启用 CJK 规则。CJK 语言的特殊处理对于中日韩CJK语言内容原文档明确要求在项目配置中将hasCJKLanguage设置为true。启用后Hugo 会对包含 CJK 字符的页面应用 CJK 字数统计规则。如需在单个页面上覆盖此行为可在其 front matter 中设置isCJKLanguage字段。对应的计数逻辑位于 hugolib/page__content.goisCJKLanguage : cp.po.p.m.pageConfig.IsCJKLanguage if isCJKLanguage { result.wordCount 0 for _, word : range result.plainWords { runeCount : utf8.RuneCountInString(word) if len(word) runeCount { result.wordCount } else { result.wordCount runeCount } } } else { result.wordCount helpers.TotalWords(result.plain) }CJK 规则的核心是每个不含多字节字符的词计 1 个词包含多字节字符如 CJK 文字的词按字符rune数量计数。这样中文段落中的每个汉字都会被单独计数混排的中英文也能得到合理结果。全局配置hasCJKLanguagehasCJKLanguage是站点级配置项位于项目配置文件如hugo.toml中hasCJKLanguage true启用后Hugo 对站点内所有包含 CJK 字符的页面应用 CJK 计数规则。具体配置说明参见 config/allconfig 相关的加载逻辑。单页覆盖isCJKLanguage当站点全局启用了 CJK 规则但某个页面恰好是纯英文内容时可以在该页面的 front matter 中设置isCJKLanguage覆盖默认行为。该字段的解析逻辑在 hugolib/page__meta.gopcfg.IsCJKLanguage *isCJKLanguage ... pcfg.Params[iscjklanguage] pcfg.IsCJKLanguage示例某英文页面 front matter--- title: An English Post isCJKLanguage: false ---字段类型定义见 resources/page/pagemeta/page_frontmatter.go。对 ReadingTime 的连带影响CJK 规则不仅影响字数还会影响阅读时间的估算。在 hugolib/page__content.go 中if isCJKLanguage { result.readingTime (result.wordCount 499) / 500 } else { result.readingTime (result.wordCount 211) / 212 }即 CJK 内容按每分钟 500 字估算约每 500 字 1 分钟非 CJK 内容按每分钟约 212 词估算。因此配置hasCJKLanguage是否准确会同时影响WordCount与ReadingTime两个指标。测试用例验证仓库中的单元测试对上述规则做了完整的验证见 hugolib/page_test.go测试用例验证点TestWordCountWithAllCJKRunesWithoutHasCJKLanguage全 CJK 内容未启用 CJK 规则时计为 8TestWordCountWithAllCJKRunesHasCJKLanguage启用 CJK 规则后同样内容计为 15按字符计数TestWordCountWithMainEnglishWithCJKRunes中英混排内容启用 CJK 规则后计为 74TestWordCountWithIsCJKLanguageFalse单页isCJKLanguage: false覆盖后计为 75TestWordCount精确计数 483FuzzyWordCount为 500这些用例同时覆盖了 Markdown、HTML、Org 等多种内容格式印证了字数统计与渲染格式无关、只与最终纯文本相关。此外TestReadingTimeAndFuzzyWordCountBoundarieshugolib/page_test.go通过模板直接输出{{ .WordCount }}|{{ .FuzzyWordCount }}|{{ .ReadingTime }}验证了三个指标的一致性。调用链路小结从源码调用链看模板中{{ .WordCount }}的执行路径为pageContentOutput.WordCounthugolib/page__per_output.go委托给已渲染内容cachedContentScope.WordCounthugolib/page__content.go从内容缓存中取出wordCount缓存值在内容首次解析时由contentPlainPlainWords计算得到CJK 与否分别走上述两套算法。由于结果被缓存同一页面多次调用WordCount、FuzzyWordCount、ReadingTime不会产生重复解析开销。总结{{ .WordCount }}返回页面纯文本的精确单词数类型为int默认按空白符分词计数启用hasCJKLanguage后CJK 字符逐字计数更适合中文等无空格语言单页可用 front matter 的isCJKLanguage覆盖全局配置需要展示约 xx 字时使用{{ .FuzzyWordCount }}向上取整到 100 的倍数同一份纯文本解析结果同时支撑WordCount、FuzzyWordCount与ReadingTime理解其一即可理解三者。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表