Anki 解决多种卡片模板导出网页:给插件修 BUG

近期使用 Anki 这个间隔重复记忆软件非常频繁,在里面积累了大量卡片。考虑到备考以及无法使用电子设备的情况,也考虑到将来分享笔记的需要,我找到了 Anki 2.1 可用的一个插件:Export deck to HTML

随便找了个模板,转换卡片类型单一、没有数学公式的牌组固然很好,但复杂一点的就出现问题了。

怎么办呢?首先我发现如果直接在模板里写死各种字段,若当前卡片没有找到这个字段,会出现提示 “## field … not found ##”

这个就是插件本身的问题了。正好 Anki 的插件是用 python 编写的,遂直接找源代码进行修改。

这个插件位于 C:\Users\用户名\AppData\Roaming\Anki2\addons21\1897277426\ExportDeckToHtml.py,我们搜索找到产生提示的子段

try:
    value = card.note()[field[2:-2]]
    key += value
except KeyError:
    value = '## field ' + field + ' not found ##'

直接改成

try:
    value = card.note()[field[2:-2]]
    key += value
except KeyError:
    value = ''

并且我发现在导出含图片的卡片时,出现了一些 bug,图片会把文字内容覆盖掉。查阅了插件的实现之后,我发现这又是插件写法的问题。 插件作者是用如下代码处理图片的:

pictures = re.findall(r'\<img src="(.*?)"', value)
if len(pictures):
    img_tmp = '<img src="%s">'
    value = ""
    for pic in pictures:
        full_img_path = join(
            collection_path, pic)
        img_tag = img_tmp % full_img_path
        value += img_tag
    key += value
    content += value
card_html = card_html.replace(field, value)

value 变量本来存着这个字段的所有信息,这样处理一下,value 当然就变成只剩图片了。

这段代码的原逻辑有点不好改,用处就是把 Anki 卡片里存的图片的相对路径,改成绝对路径。

作者可能也是对正则表达式不熟练,只能这样粗糙地处理。其实,只要把这一整段改成下面两句即可。

value = re.sub('(?<=\<img src=").*?(?=")', lambda matched : join(collection_path, matched.group(0)), value)
card_html = card_html.replace(field, value)

这样效果很完美。

然后在模板网页里用 javascript 和 css 简单处理一下表格的着色、数学公式的渲染、填空题的显示,即可完成。

<head>
    <meta charset="UTF-8">
    <script type="text/x-mathjax-config">
        MathJax = {
            tex: {
              inlineMath: [['$', '$'], ['\\(', '\\)']]
            },
            svg: {
              fontCache: 'global'
            }
          };
        </script>
        <script type="text/javascript" id="MathJax-script" async
          src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js">
        </script>
    <style>
        table {
            font-family: "Book Antiqua", "宋体";
            font-size: 13px;
            color: #000000;
            border-width: 1px;
            border-color: #000000;
            border-collapse: collapse;
            width: 100%;
        }
        @media print {
            tr:nth-child(odd){
                background-color: #dfdfdf ;
            }
        }    
        tr:nth-child(odd){
            background-color: #dfdfdf ;
        }
        td, th {
            border-width: 1px;
            padding: 8px;
            border-style: solid;
            border-color: #000000;
        }

        img {
            max-width: 50%;
            height: auto;
        }
    </style>
    <script>
        window.onload = function() {
            var bs = document.getElementsByTagName("span");
            for(var i = 0; i < bs.length; i++) {
                if(bs[i].style.backgroundColor != "") {
                var par = bs[i].parentNode;
                    bs[i].style.backgroundColor = par.style.backgroundColor;
                }
            }
            var texts = document.getElementsByTagName("td");
            for(var i = 0; i < texts.length; i++) {
                var text = texts[i].innerHTML;
                var rep = text.replace(/{{c[1-9]::(.*?)}}/g, "<p style=\"color: rgb(0, 0, 255); display: inline; text-decoration: underline; \">$1</p>");
                texts[i].innerHTML = rep;
            }
        }
    </script>
</head>

<body>
    <table>
        <tr>
            <td>{{正面}}{{文字}}{{Text}}</td>
            <td>{{背面}}{{背面额外}}</td>
        </tr>
    </table>
</body>

最后贴一张解决了上述各种坑点的效果图:

Joy © 2023 Powered by Jekyll and Theme by solid

今日诗词API Valine 评论管理 Github