更新R包后,使用bookdown时出现编译失败问题请教
dapengde tctcab 那就告诉你们一个花钱买不到的绝招吧。blogdown 的文件名和短链接(slug)都是可以通过自定义函数生成的,如果要汉字自动转拼音的话,可作如下设置:
options(blogdown.filename.pre_processor = function(x) {
pinyin::py(x, sep = '-', dic = pinyin::pydic('toneless'))
})
然后插件 New Post 里敲汉字就会自动出来拼音文件名和短链接:
然而 pinyin::py()
有个不太合理的地方,就是把字符串拆成单个字符之后转换,然后再(默认)用下划线拼接起来,如“你好abc”会被转成“ni-hao-a-b-c”,我觉得转成“ni-hao-abc”更合理一些,不过这个实现起来会稍微费劲一点点。另外感觉这函数跑起来略慢,似乎有提速的可能,看哪位壮士有空细究帮忙吧。
- 已编辑
有空开始研究了一下这个包,从我的1200+条标题转换记录来0.5秒 看还是挺快的啊
但是准确率堪忧…@dapengde 怎么回事
pinyin::py("我喜欢旅游", dic= pinyin::pydic("toneless"))
#> 我喜欢旅游
#> "wo_chi_huan_lv_liu"
pinyin::py("我受不了了",dic= pinyin::pydic("toneless"))
#> 我受不了了
#> "wo_dao_bu_le_le"
<sup>Created on 2019-10-18 by the reprex package (v0.3.0)</sup>
@yihui 我看了一下,貌似需要在py_single
函数中的 strsplit
函数考虑一下连续的字母或数字就不拆开,应该写一点正则可以解决这个问题 @dapengde 仅供参考
https://github.com/pzhaonet/pinyin/blob/7b05b06b11ab06ddf1678d48c35abb4d4b47ecc0/R/py.R#L28
- 已编辑
yihui 我的老天,这黑科技太牛了,然而藏得也太深了,搜啊搜只在 blogdown 的 NEWS 里搜到一条:
pinyin 包跑起来略慢,原因可能是因为下面这一句,把 py()
和 pydic()
两个函数合成一句的缘故:
pinyin::py(x, sep = '-', dic = pinyin::pydic('toneless'))
慢在 pydic()
,它用来载入字典,然而一劳永逸,载入之后,每次转换时只需执行 py()
函数就快了。例如:
require(pinyin)
mydic <- pydic("toneless")
py("我喜欢旅游", dic= mydic)
py("我受不了了", dic= mydic)
肯定比
pinyin::py("我喜欢旅游", dic= pinyin::pydic("toneless"))
pinyin::py("我受不了了", dic= pinyin::pydic("toneless"))
快很多。
历史上,pinyin 经过了一次提速。提速前,用的方法是简单粗暴的文本查找替换。有一天,有个用户要转换大量的汉字,发现这样太慢,就给我提出了两个改进方案:一个是把拼音库转成 environment,另一个是并行计算。我采纳了第一个,所以才有了 pydic()
函数,目的就是把原来的文本拼音库转成 environment。
tctcab 准确率堪忧的原因是没有解决多音字的问题。因为现在是逐字在拼音库里找一个字的拼音,它没法根据上下文(字)判断受不了了
里的两个了
的读音区别,所以默认从库里选择第一个。也可以把所有读音都在结果里列出来,但是就是不会智能选择正确的那个。默认拼音库里的多音字很多,有些音从来没见过。可以换个拼音库 (dic = 'pinyin2'
),内含常用读音:
mydic <- pydic(method = 'toneless', dic = 'pinyin2')
py("我喜欢旅游", dic= mydic)
我喜欢旅游
"wo_xi_huan_lv_you"
然而这仍然没解决 我受不了了
的问题。目前只能凑合用了。
我看了一下别的软件,好像也没能解决这个问题。例如<http://xh.5156edu.com/conversion.html> 和 <https://zhongwenzhuanpinyin.51240.com/>。
Cloud2016
a-b-c
这个问题当时我考虑过,一度想挽起袖子给解决了,后来懒兵一犯,得过且过了。
pinyin 包是刚学会写包时写的,生涩得很,目的是够用,在不得已的一些场合(例如 bookdown 的中文章节 ID,例如操作系统不支持中文文件名等)里把汉字替换成字母而已。现在回头去看,要改的地方很多,连文档都没好好写,无奈没有那个精力了,可预见的未来也没有时间去改进。哪位好汉有时间的话就接过去吧。
对了,它还可以把汉字转换成五笔码和四角号码,例如:
dic_wb98 <- 'https://github.com/pzhaonet/pinyin/raw/master/inst2/wubi98.txt'
mywb98 <- load_dic(dic_file = dic_wb98)
py("春眠不觉晓,处处闻啼鸟", sep = '_', dic = mywb98)
也支持用户自定义字典。反正本质就是个批量查找替换。可以开开脑洞,看看它还能做什么。
@dapengde @yihui 我早些时候发了一个帖特意提及那些隐藏的功能选项 但是没有人跟帖。其实后来我知道,要想翻出来这些价值几个亿的东西,就要去搜大神们的 repo,比如上面这例子搜 option 或者 options 应该能搞出来 <https://github.com/rstudio/blogdown/search?q=option&unscoped_q=option>
- 已编辑
我发现你的一个不好的习惯就是老是想把好多功能塞进同一个包里。比如现在拼音输入完全是中文输入主流,五笔和四角号码都差不多淘汰了,塞进去有点奇怪。更何况包名是pinyin,不是wubi或者sijiaohaoma。
我觉得先把一件事情做好做到极致的扎实 再去想怎么锦上添花吧
中文转拼音我看来是非常有价值的工作,丢掉可惜。看看这个爆栈网的问题,八个答案了没一个好用的
====
同样上次那个sinx包在另一个帖里也吐槽过,三十多个依赖简直想把你吊起来打一顿…初衷挺好,收集有意思的留言跟fortune一样打出来。结果塞进一堆唐诗宋词金庸语录养生记录,还做了花哨的Tshirt,还塞了个cowsay包进去,我几次尝试拿砍刀大刀阔斧地清理一番最后都生理性抗拒地做不下去了…
- 已编辑
tctcab 做精之后再锦上添花,谁不想啊,却是不能。pinyin 包只要解决多音字问题,就完美了,然而卡在这一步已经很久,无计可施。
五笔和四角的功能是用户后来要求的。我的本意是既然默认字库 'pinyin' 和备选字库 'pinyin2' 仍然不完善,那就允许用户自定义字库。刚好有用户提出五笔和四角的需求(这个用户做汉字方向的字型研究用),就以此为例,做为自定义字库的示范。当然,为了突出拼音的 c 位,五笔和四角这两个字库都没有安装到包里,而是用的时候才下载。
pinyin 包开发过程里的故事详见:<https://openr.pzhao.org/zh/tags/pinyin/>。 我不是要彻底丢掉,而是先放一放。最近一两年生活工作有大变动,忙不过来。另外,我一直希望有人参与进来一起做。openr 一直期待新成员。自己做起来比较无趣。
sinx 包确实依赖太多了。这个属于玩嗨没收住。只要把 cowsay 砍去,我估计能少一半依赖。我也是生理性抗拒地懒得修改。
tctcab 刚开始开发包的人都容易这样,乱七八糟的东西都塞在一个包里。比如在我的第一个 R 包 animation 中,我最初就把毫无关系的 formatR::tidy_source()
塞在里面了,过了很久才把它移出去。所以后来我就建议初试开发 R 包的人先折腾几个不太重要的包,踩过一些常见的坑、养成一些克制的习惯之后再开发重要的包。
dapengde 加载字典你可以用懒加载的方式,这样就只需要加载一次了。大意如此(核心是那个双箭头):
lazy_dic = local({
res = list()
function(dic = c('p1', 'p2')) {
dic = match.arg(dic)
if (!is.null(res[[dic]])) return(res[[dic]])
res[[dic]] <<- {
Sys.sleep(5)
'这里是耗费时间的加载字典过程'
}
res[[dic]]
}
})
lazy_dic('p1') # 慢
lazy_dic('p1') # 快
lazy_dic('p2') # 慢
lazy_dic('p2') # 快
Cloud2016 这些价值几个亿的东西我在没遇到非常合适的应用案例之前一般先不会叫唤(写代码容易,一到写文档就犯懒了)。我放在包里面只是我隐约感觉它们会有用。现在才终于找到 blogdown.filename.pre_processor
选项的一个完美应用场景了。
yihui 这个双箭头 <<- 我记得在且仅在你的博客里见过,一搜果然:
我觉得这黑科技是在往华山剑宗的道路上一路狂奔……