Skip to content

Instantly share code, notes, and snippets.

@zr-tex8r
Created July 31, 2019 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zr-tex8r/ddaf5bb2f91d9df1be46e10ffa700fc3 to your computer and use it in GitHub Desktop.
Save zr-tex8r/ddaf5bb2f91d9df1be46e10ffa700fc3 to your computer and use it in GitHub Desktop.
Pandoc:“Markdownはデカイ文字を書くのに便利”的なフィルタ
-- biggggg.lua
--
-- @copyright 2019 Takayuki YATO (aka. "ZR")
-- GitHub: https://github.com/zr-tex8r
-- Twitter: @zr_tex8r
-- This program is distributed under the MIT License.
--
local filter_name = 'biggggg'
---------------------------------------- 設定
--- デバッグログを出すか
local show_log = false
--- 拡大倍率
local BIG_BASE = 1.2
local LATEX_PROLOGUE = [==[
\makeatletter
\@ifundefined{scalefont}{\DeclareRobustCommand\scalefont[1]{%
\dimen@\f@size\p@ \dimen@=#1\dimen@
\fontsize\dimen@\dimen@\selectfont}}{}
\@ifundefined{textsmall}{\DeclareRobustCommand\textsmall[1]{%
{\scalefont{0.8333}#1}}}{}
\makeatother
]==]
---------------------------------------- 補助
local insert, remove = table.insert, table.remove
--- デバッグログを出力する.
local function log(fmt, ...)
if not show_log then return end
io.stderr:write(filter_name..': '..fmt:format(...).."\n")
end
local function fformat(prec, val)
local s = ('%.'..tostring(prec)..'f'):format(val)
return s:gsub('0+$', ''):gsub('%.$', '')
end
---------------------------------------- フィルタ用補助
--- 出力フォーマットがサポート対象であるか.
-- @return 真偽値
local function is_format_supported()
return FORMAT == 'latex' or FORMAT == 'html'
end
--- 拡大用のクラス名について, その段階値を返す.
-- @return 段階値 (拡大用クラス以外ならnil)
local function scale_value(cls)
if cls == 'Small' then return cls end
if cls == 'smal' then return -0.5 end
local big = cls:match('^bi(g+)$')
if big then return #big end
local small = cls:match('^smal(l+)$')
if small then return - #small end
return nil
end
--- 段階値からマークアップへの変換.
-- @return 前側のマークアップの文字列
-- @return 後側のマークアップの文字列
local function scale_markup(scl)
if FORMAT == 'latex' then
if scl == 'Small' then
return '\\textsmall{', '}'
end
local val = fformat(4, BIG_BASE ^ scl)
return '{\\scalefont{'..val..'}', '}'
elseif FORMAT == 'html' then
if scl == 'Small' then
return '<small>', '</small>'
end
local val = fformat(2, 100 * BIG_BASE ^ scl)
return '<span style="font-size:'..val..'%">', '</span>'
else assert(false)
end
end
--- span要素のクラス群の中から拡大に関する情報を取り出す.
-- @return 段階値 (拡大用クラス不指定ならnil)
-- @return 拡大用以外のクラスの列 (不指定ならnil)
local function scan_bigg_classes(span)
local gscl, oclss, clss = 0, {}, span.classes
for _, cls in ipairs(clss) do
local t = scale_value(cls)
if type(t) == 'string' then gscl = t
elseif type(t) == 'number' then
if type(gscl) == 'number' then gscl = gscl + t end
else insert(oclss, cls)
end
end
if #clss == #oclss then return nil end
return gscl, oclss
end
---------------------------------------- フェーズ'mainproc'
-- Span要素に対する処理.
local function mainproc_Span(span)
local scl, clss = scan_bigg_classes(span)
if not scl then return end
log("bigg span: scale=%s", scl)
-- 内容の前後にマークアップのRawInlineを追加する
local mb, ma = scale_markup(scl)
if mb then
insert(span.content, 1, pandoc.RawInline(FORMAT, mb))
end
if ma then
insert(span.content, pandoc.RawInline(FORMAT, ma))
end
span.classes = clss
return {span}
end
-- 文書全体に対する処理.
local function mainproc_Pandoc(doc)
if FORMAT == 'latex' then
insert(doc.blocks, 1,
pandoc.RawBlock(FORMAT, LATEX_PROLOGUE))
return doc
end
end
---------------------------------------- フィルタ定義
if is_format_supported() then
return {
{-- フェーズmainproc
Span = mainproc_Span;
Pandoc = mainproc_Pandoc;
};
}
else log("format '%s' in not supported", FORMAT)
end
---------------------------------------- おしまい
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment