跳转至

metapost用例

我的metapost用例。可能包含从各处抄来又忘记了出处的片段。

我主要的使用环境是ConTeXt,因此实际包含的是ConTeXt、luametafun(兼容metafun、metapost)、lua的代码,并尽可能在lua端处理,请注意分辨。

ConTeXt文档:

% 字体设置
\usetypescriptfile  [mscore]
\usebodyfont        [mschinese,18pt]

% 导入lua模块MPwordslink.lua
\startluacode
    require "MPwordslink"
\stopluacode

% 定义宏
\def\wordslink[#1,#2,#3]{
    \startMPcode
        lua.MP.wordslink(#1,#2,#3) ;
    \stopMPcode
}

\starttext


\startcolumns[n=3]
\wordslink["认","认识;认得;认不得;",                     "0.7"]
\wordslink["字","识字;认字;名字;生字;",                 "0.7"]
\wordslink["名","点名;几名;有名;名人;书名;",               "0.7"]
\wordslink["草","草地;花草;花花草草;草鱼;",             "0.7"]
\wordslink["自","自己;自个r;自学;不自在;自小;自来水;",    "0.7"]
\wordslink["读","读书;",                                   "0.7"]
\wordslink["鱼","小鱼;小鱼r;鱼头;",                      "0.7"]
\wordslink["鸟","小鸟;小鸟r;鸟叫;",                      "0.7"]
\stopcolumns

\stoptext

lua模块:

-- 保存为MPwordslink.lua

-- 依赖utf8.lua模块处理中文,见 https://gist.github.com/markandgo/5776124
-- 注意改名,以免跟系统模块冲突
local utf8 = require "m-utf8"
-- c: 字;s: "词语;词语;...";r:半径
function MP.wordslink(char,words,r) --lua.MP是给用户预留的命名空间,lua.mp则是系统自用的
    local function split (c, inputstr, sep)
        if sep == nil then
            sep = "%s*;%s*"
        end
        -- {{str:word, len:wordlength, match_num:c_num_in_the_word, head_or_tail:last_c's_position},..}
        local t={}
        for str in utf8.gmatch(inputstr, "[^"..sep.."]+") do
            local tbl = {}
            local match_num = 0
            for cc in utf8.gmatch(str,".") do
                table.insert(tbl, cc)
                if c == cc then match_num = match_num +1 end
            end
            local len = utf8.len(str)
            local head_or_tail = nil
            if tbl[1] == c then head_or_tail = 1 end
            if tbl[#tbl] == c then head_or_tail = 2 end
            --print(str, len, match_num, head_or_tail)
            -- 删除生字
            if match_num == 1 and head_or_tail then
                str = utf8.gsub(str, c, nil)
            end
            table.insert(t, {["str"]=str, ["len"]=len, ["match_num"]=match_num, ["head_or_tail"]=head_or_tail})
        end
        return t
    end
    local t = split(char, words)
    local rt = 360 / #t

    local code1 = [[
        input boxes;
        sp:=%s;
        circleit.n0("%s");
        n0.c = origin;
        drawboxed(n0);
        circleit.a("");
    ]]
    mp.fprint(code1, r, char)
    mp.fprint([[a.c = n0.c + (0, %s cm);]], r) --定位圆

    for i,data in ipairs(t) do
        local v = data["str"]
        v = utf8.gsub(v, "r", [[\low{儿}]])
        local len = data["len"]
        local ri = len/2*r --实际半径cm
        mp.fprint([[circleit.n%s(btex %s etex);]], i, v)
        mp.fprint([[n%s.c = (a.c + (0, %s cm)) rotated %s;]], i, ri, (-rt*(i-1)))
        mp.fprint([[drawboxed(n%s);]], i)
        if data["match_num"] >= 2 or data["head_or_tail"] == nil then --含两个以上生字,或生字不在头尾
            mp.fprint([[draw n0.c .. n%s.c cutbefore bpath.n0 cutafter bpath.n%s;]], i, i)
        elseif data["head_or_tail"] == 2 then --生字在尾
            mp.fprint([[drawarrow n%s.c .. n0.c cutafter bpath.n0 cutbefore bpath.n%s;]], i, i)
        elseif data["head_or_tail"] == 1 then --生字在头
            mp.fprint([[drawarrow n0.c .. n%s.c cutbefore bpath.n0 cutafter bpath.n%s;]], i, i)
        end
    end
end
return MP.wordslink

评论