มอดูล:FormatProofread
หน้าตา
เอกสารการใช้งานสำหรับมอดูลนี้อาจสร้างขึ้นที่ มอดูล:FormatProofread/doc
local p = {}
--[=[
(example of input text)
มาตรา ๕ ให้รัฐมนตรีว่าการกระทรวงมหาดไทยรักษาการตามพระราชบัญญัตินี้ และให้...
กฎกระทรวงนั้น เมื่อได้ประกาศในราชกิจจานุเบกษาแล้ว ให้ใช้บังคับได้
ลักษณะ ๑
การใช้รถ
หมวด ๑
ลักษณะของรถที่ใช้ในทาง
มาตรา ๖ ห้ามมิให้ผู้ใดนำรถที่มีสภาพไม่มั่นคงแข็งแรง หรืออาจเกิดอันตราย หรืออาจทำให้...
รถที่ใช้ในทางเดินรถ ผู้ขับขี่ต้องจัดให้มีเครื่องยนตร์ เครื่องอุปกรณ์และหรือส่วนควบที่...
สภาพของรถที่อาจทำให้เสื่อมเสียสุขภาพอนามัยตามวรรคหนึ่งและวิธีการทดสอบ ให้เป็นไปตามหลักเกณฑ์และวิธีการที่กำหนดในกฎกระทรวง
...
...
มาตรา ๔๙ เมื่อได้รับสัญญาณขอแซงขึ้นหน้าจากรถคันที่อยู่ข้างหลัง ผู้ขับขี่ซึ่ง...
หมวด ๓
การออกรถ การเลี้ยวรถและการกลับรถ
มาตรา ๕๐ การขับรถออกจากที่จอด ถ้ามีรถจอดหรือมีสิ่งกีดขวางอยู่ข้างหน้า ผู้ขับขี่ต้อง...
มาตรา ๕๑ การเลี้ยวรถ ให้ปฏิบัติดังนี้
(๑) ถ้าจะเลี้ยวซ้าย
(ก) ในกรณีที่ไม่ได้แบ่งช่องเดินรถไว้ ให้ผู้ขับขี่ขับรถชิดทางเดินรถด้านซ้าย
(ข) ในกรณีที่มีการแบ่งช่องเดินรถไว้ และมีเครื่องหมายจราจรแสดงให้เลี้ยวซ้ายได้ ให้ผู้ขับขี่...
(ค) ในกรณีที่มีช่องเดินรถประจำทางอยู่ทางเดินรถด้านซ้ายสุด ให้ผู้ขับขี่...
(๒) ถ้าจะเลี้ยวขวา
(ก) สำหรับทางเดินรถที่ไม่ได้แบ่งช่องเดินรถไว้ ให้ผู้ขับขี่...
...
(๓) ถ้าจะเลี้ยวอ้อมวงเวียนหรือเกาะที่สร้างไว้ ให้ผู้ขับขี่ขับรถอ้อมไปทางซ้ายของวงเวียนหรือเกาะนั้น
ในกรณีตาม (๑) และ (๒) ผู้ขับขี่ต้อง...
มาตรา ๕๒ ในทางเดินรถที่สวนกันได้ ห้ามมิให้ผู้ขับขี่กลับรถในเมื่อมีรถอื่นสวน หรือตามมาในระยะไม่น้อยกว่าหนึ่งร้อยห้าสิบเมตร
ถ้าการกลับรถในทางเดินรถที่สวนกันได้จะเป็นการกีดขวางการจราจร ห้ามมิให้ผู้ขับขี่กลับรถในทางเดินรถนั้น
--]=]
--[=[
Example:
To expand "abc{{t1|a1|b1|c1}}def{{t2|a2|p2=b2}}{{t3}}xyz" do the following,
expandTemplates(mw.getCurrentFrame(), {
'abc',
{ 't1', {'a1', 'b1', 'c1'} },
'def',
{ 't2', {'a2', ['p2']='b2'} },
{ 't3', {} },
'xyz',
} )
--]=]
local function expandTemplates(frame, t)
local r = ''
for i, v in ipairs(t) do
if type(v)=='table' then
r = r..frame:expandTemplate{title=v[1], args=v[2]}
else
r = r..v
end
end
return r
end
-- p == { multiline, pattern, section name, number of lines following matched line,
-- function (matchResult, { line1, line2, ... }, state, frame)
-- }
local function multiline(v, p, state, frame)
--if state.section ~= nil then
-- if state.section ~= p[3] then return false end
-- state.section = nil; return p[5](state.sectionVal)
--end
--if state.section == p[3] then state.section = nil; return p[5](state.sectionVal, v, frame) end
if state.section == p[3] then
table.insert(state.sectionLine, v)
if #state.sectionLine < p[4] then return nil end
state.section = nil; return p[5](state.sectionVal, state.sectionLine, state, frame)
end
if state.section ~= nil then return false end
--local c = gsub(v, p, state) -- result is string or false
--if c then return nil end
--return c
--local c = {mw.ustring.match(v, p[2])}
-- "not x" is faster than "x == nil"
----if c[1] == nil then return false end
----state.section = p[3]; state.sectionVal = c; state.sectionLine = {}; return nil
--if c[1] then
-- state.section = p[3]; state.sectionVal = c; state.sectionLine = {}; return nil
--end
if type(p[2]) ~= 'table' then p[2] = { p[2] } end
for _, p2 in ipairs(p[2]) do
-- c[1] is string or nil
local c = {mw.ustring.match(v, p2)}
if c[1] then
state.section = p[3]; state.sectionVal = c; state.sectionLine = {}
state.pattern = pat
return nil
end
end
return false
end
-- This is deprecated, as it seem too complex
-- p == { section, pattern, section name, function (matchResult, v, state, frame) }
local function section(v, p, state, frame)
return multiline(v, { p[1], p[2], p[3], 1, function (matchResult, line, state, frame)
return p[4](matchResult, line[1], state, frame)
end }, state, frame)
end
-- p == { gsub, mw.ustring.gsub's 2nd, func(state, frame, gsub's captured var ...), mw.ustring.gsub's 4th parameter }
local function gsub(v, p, state, frame)
if type(p[2]) ~= 'table' then p[2] = { p[2] } end
for _, p2 in ipairs(p[2]) do
state.pattern = p2
--local r, c = mw.ustring.gsub(v, p2, p[3], p[4])
local r, c = mw.ustring.gsub(v, p2, function (...) return p[3](state, frame, ...) end, p[4])
--return r, c > 0
if c > 0 then return r end
end
return false
end
-- p == { del, pattern }
local function del(v, p, state, frame)
if mw.ustring.match(v, p[2]) then return nil end
return false
end
-- For passed as named template parameter that is going to be preprocessed.
-- Since input text is assumed to has already been preprocessed, so '{', '}', and '<' are escaped
-- to prevent them to be preprocessed. '[' is escaped to handle the case like '{{t1|a1=[[a}}
--
-- Example: frame:preprocess('{{t1|a1='..escapeNamedTemplateParameter(s)..'}}')
--
-- Note: This does not convert '=' to '{{=}}'
--
local function escapeNamedTemplateParameter(s)
return s:gsub('[{}<[]', '%1<!---->'):gsub('|', '{{!}}')
end
local escN = escapeNamedTemplateParameter
-- Suitable for passed as unnamed template parameter that is going to be preprocessed,
-- as it also convert '=' to '{{=}}'
--
-- Example: frame:preprocess('{{t1|'..escapeTemplateParameter(s)..'}}')
--
local function escapeTemplateParameter(s)
return s:gsub('[{}<[]', '%1<!---->'):gsub('[|=]', {['|']='{{!}}', ['=']='{{=}}'})
end
local esc = escapeTemplateParameter
local pat = {
['ราชกิจจานุเบกษา']={
['กฎหมาย']={
--[=[
-- in: ลักษณะ ๑
การใช้รถ
-- out1: {{ก|{{รมมจ|ลักษณะ ๑|การใช้รถ}}}}
{{เส้นตรง|7em}}
-- out2: {{ก|{{รมมจ|ลักษณะ ๑|{{u|การใช้รถ}}}}}}
--
-- in: หมวด ๑
ลักษณะของรถที่ใช้ในทาง
-- out1: {{กม|หม|๑|ลักษณะของรถที่ใช้ในทาง}}
{{เส้นตรง|7em}}
-- out2: {{กม|หม|๑|{{u|ลักษณะของรถที่ใช้ในทาง}}}}
--]=]
--[=[
{ section, {
'^(\n?)(ลักษณะ) +([๐-๙]+) *\n?$',
'^(\n?)(หมวด) +([๐-๙]+) *\n?$',
}, 'section', function (match, v, state, frame)
local enclose = state.p[5][match[2]]
if frame.args.u:len()>0 then
----v = '{{ก|{{รมมจ|ลักษณะ '..match[3]..'|'..mw.text.tag('u', {}, esc(v))..'}}}}'
--v = '{{ก|{{รมมจ|ลักษณะ '..match[3]..'|{{u|'..esc(v)..'}}}}}}'
v = enclose[1]..match[3]..'|{{u|'..esc(v)..'}}'..enclose[2]
else
--v = '{{ก|{{รมมจ|ลักษณะ '..match[2]..'|'..esc(v)..'}}}}\n{{เส้นตรง|7em}}'
v = enclose[1]..match[3]..'|'..esc(v)..enclose[2]..'\n{{เส้นตรง|7em}}'
end
return match[1]..frame:preprocess(v)
end, {
-- this table can be accessed as state.p[5]
['ลักษณะ'] = { '{{ก|{{รมมจ|ลักษณะ ', '}}}}' },
['หมวด'] = { '{{กม|หม|', '}}' },
}
},
--]=]
{ multiline, {
'^(\n?)(ลักษณะ) +([๐-๙]+) *\n?$',
'^(\n?)(หมวด) +([๐-๙]+) *\n?$',
}, 'section', 1, function (match, line, state, frame)
local enclose = state.p[6][match[2]]
if frame.args.u:len()>0 then
-- result of tag "<u>" processing showing that none of these functions do escape
-- the '<' nor '>' character,
-- mw.logObject(mw.getCurrentFrame():extensionTag('u', 'z</u>z2<u>z3'))
-- "<u>z</u>z2<u>z3</u>"
-- mw.logObject(mw.getCurrentFrame():callParserFunction('#tag:u', 'z</u>z2<u>z3'))
-- "<u>z</u>z2<u>z3</u>"
-- mw.logObject(mw.getCurrentFrame():preprocess('{{#tag:u|z</u>z2<u>z3}}'))
-- "<u>z</u>z2<u>z3</u>"
-- mw.logObject(mw.text.tag('u', {}, 'z</u>z2<u>z3'))
-- "<u>z</u>z2<u>z3</u>"
----line = '{{ก|{{รมมจ|ลักษณะ '..match[3]..'|'..mw.text.tag('u', {}, esc(line[1]))..'}}}}'
--line = '{{ก|{{รมมจ|ลักษณะ '..match[3]..'|{{u|'..esc(line[1])..'}}}}}}'
line = enclose[1]..match[3]..'|{{u|'..esc(line[1])..'}}'..enclose[2]
else
--line = '{{ก|{{รมมจ|ลักษณะ '..match[2]..'|'..esc(line[1])..'}}}}\n{{เส้นตรง|7em}}'
line = enclose[1]..match[3]..'|'..esc(line[1])..enclose[2]..'\n{{เส้นตรง|7em}}'
end
return match[1]..frame:preprocess(line)
end, {
-- this table can be accessed as state.p[6]
['ลักษณะ'] = { '{{ก|{{รมมจ|ลักษณะ ', '}}}}' },
['หมวด'] = { '{{กม|{{{หม|หม1}}}|', '}}' },
}
},
--[=[
-- in: ผู้รับสนองพระบรมราชโองการ
พลเอก เกรียงศักดิ์ ชมะนันทน์
นายกรัฐมนตรี
-- out:
{{กซ|{{รมมจ|ผู้รับสนองพระบรมราชโองการ|พลเอก เกรียงศักดิ์ ชมะนันทน์|นายกรัฐมนตรี}}|center}}
--
-- in: ผู้รับสนองพระราชโองการ
พลเอก ประยุทธ์ จันทร์โอชา
นายกรัฐมนตรี
-- out:
{{รมมจ|ผู้รับสนองพระราชโองการ|พลเอก ประยุทธ์ จันทร์โอชา|นายกรัฐมนตรี}}|center}}
--]=]
{ multiline, {
'^(\n?)(ผู้รับสนองพระบรมราชโองการ)\n?$',
'^(\n?)(ผู้รับสนองพระราชโองการ)\n?$',
}, 'ผู้รับสนองพระบรมราชโองการ', 2,
function (match, line, state, frame)
local p = ''; if state.i > 1 then p = '\n' end
return p..frame:preprocess(
'{{กซ|{{รมมจ|'..match[2]..'|'..esc(line[1])..'|'..esc(line[2])..'}}|center}}'
)
end
},
-- in: มาตรา ๕๑ การเลี้ยวรถ ให้ปฏิบัติดังนี้
-- out: {{กม|ม|๕๑}}การเลี้ยวรถ ให้ปฏิบัติดังนี้
-- * not use '^(\n*)...', since there never be more than one consecutive '\n'
{ gsub, '^(\n?)มาตรา +([๐-๙]+) +', function (state, frame, p, n)
-- expandTemplate() should be more efficient than preprocess()
-- however from experiment in Module:User:Ans/PerformanceTest,
-- * preprocess() with nowiki() is 4 times faster than expandTemplate(),
-- * preprocess() is 4 times faster than preprocess() witth nowiki()
--return p..frame:preprocess('{{กม|ม|'..n..'}}')
--return p..frame:preprocess('{{กม|'..esc(frame.args['ม'])..'|'..n..'}}')
return p..frame:preprocess('{{กม|{{{ม|ม1}}}|'..n..'}}')
--return p..mw.getCurrentFrame():expandTemplate{title='กม', args={'ม', n}}
end, 1 },
--[=[
--
-- ไม่รวมจัดรูปแบบพวกมาตราแก้ไขเพิ่มเติม เช่น "มาตรา ๒๘/๑๕" หรือ "มาตรา ๒๙ ทวิ"
-- เพราะ มาตราพวกนี้ใน ราชกิจจานุเบกษา จะอยู่ในเครื่องหมายคำพูดอีกที เช่น
--
-- มาตรา ๔ ให้เพิ่มความต่อไปนี้เป็นมาตรา ๓๒/๑ มาตรา ๓๒/๒ และมาตรา ๓๒/๓ แห่งพระราชบัญญัติลิขสิทธิ์ พ.ศ. ๒๕๓๗
-- "มาตรา ๓๒/๑ การจำหน่ายต้นฉบับหรือสำเนางานอันมีลิขสิทธิ์โดย...
-- มาตรา ๓๒/๒ การกระทำแก่งานอันมีลิขสิทธิ์ที่ทำหรือได้มาโดยชอบ..."
--
-- แต่หากต้องการจัดรูปแบบมาตราประเภท "มาตรา ๒๘/๑๕" เข้าไปด้วย ให้ uncomment code ด้านล่างนี้
-- (ส่วนมาตราประเภท "มาตรา ๒๙ ทวิ" ยังจัดรูปแบบอัตโนมัติไม่ได้)
--]=]
-- in: มาตรา ๒๘/๑๕ ...
-- out: {{กม|ม|๒๘/๑๕}}...
--{ gsub, '^(\n?)มาตรา +([๐-๙]+/[๐-๙]+) +', function (state, frame, p, n)
-- return p..frame:preprocess('{{กม|{{{ม|ม1}}}|'..n..'}}')
--end, 1 },
-- in: (๑) ถ้าจะเลี้ยวซ้าย
-- out: {{กม|วล|๑}}ถ้าจะเลี้ยวซ้าย
{ gsub, '^(\n?)%(([๐-๙]+)%) *', function (state, frame, p, n)
-- expandTemplate() should be more efficient than preprocess()
-- however from experiment in Module:User:Ans/PerformanceTest,
-- * preprocess() with nowiki() is 4 times faster than expandTemplate(),
-- * preprocess() is 4 times faster than preprocess() witth nowiki()
return p..frame:preprocess('{{กม|วล|'..n..'}}')
--return p..mw.getCurrentFrame():expandTemplate{title='กม', args={'วล', n}}
end, 1 },
-- in: (๑/๑) ...
-- out: {{กม|วล|๑/๑}}...
--{ gsub, '^(\n?)%(([๐-๙]+/[๐-๙]+)%) *', function (state, frame, p, n)
-- return p..frame:expandTemplate{title='กม', args={'วล', n}}
--end, 1},
-- in: (ก) ในกรณีที่ไม่ได้แบ่งช่องเดินรถไว้ ให้ผู้ขับขี่ขับรถชิดทางเดินรถด้านซ้าย
-- out: {{ชว}}{{กม|วล|ก}}ในกรณีที่ไม่ได้แบ่งช่องเดินรถไว้ ให้ผู้ขับขี่ขับรถชิดทางเดินรถด้านซ้าย
{ gsub, '^(\n?)%(([ก-ฮ]+)%) *', function (state, frame, p, n)
-- expandTemplate() should be more efficient than preprocess(),
-- however from experiment in Module:User:Ans/PerformanceTest,
-- * preprocess() with nowiki() is 10 times faster than expandTemplate(),
-- * preprocess() is 2 times faster than preprocess() witth nowiki()
return p..frame:preprocess('{{ชว}}{{กม|วล|'..n..'}}')
--return p..mw.getCurrentFrame():preprocess('{{ชว}}{{กม|วล|'..mw.text.nowiki(n)..'}}')
--return p..
-- mw.getCurrentFrame():expandTemplate{title='ชว', args={}}..
-- mw.getCurrentFrame():expandTemplate{title='กม', args={'วล', n}}
--return p..
-- expandTemplates(mw.getCurrentFrame(), { {'ชว',{}}, { 'กม',{'วล', n}} })
end, 1 },
-- in: หมายเหตุ:- เหตุผลในการประกาศใช้พระราชบัญญัติฉบับนี้ คือ ...
-- out:
----{{กม|มห0|เหตุผลในการประกาศใช้พระราชบัญญัติฉบับนี้ คือ ...}}
--
-- in: หมายเหตุ :- เหตุผลในการประกาศใช้พระราชบัญญัติฉบับนี้ คือ ...
-- out:
----{{กม|มห|เหตุผลในการประกาศใช้พระราชบัญญัติฉบับนี้ คือ ...}}
{ gsub, '^(\n?)หมายเหตุ( ?):%- (.*)$', function (state, frame, p, z, s)
if state.i > 1 then p = '\n----' else p = '' end
if z == '' then z = '0' else z = '' end
return p..frame:preprocess('{{กม|มห'..z..'|'..esc(s)..'}}')
end, 1 },
-- remove blank line
--{ del, '^\n? *\n?$' },
--{ del, '^\n?[ \n]*\n?$' },
{ del, '^[ \n]*$' },
}
}
}
--[[
------------------------------------------------------------------------------------
-- ipairsAtOffset
-- This is an iterator for arrays. It can be used like ipairs, but with
-- specified i as first index to iterate. i is an offset from 1
--
------------------------------------------------------------------------------------
--]]
local function ipairsAtOffset(t, i)
local f, s, i0 = ipairs(t)
return f, s, i0+i
end
local function format(pat, frame, iterFunc, iterStatic, iterVar)
local r, state = {}, {}
-- not work, if "..." is referenced, arg will be nil
--local text; for i, v in ... do arg[3], text = i, v; break end
local text
for i, v in iterFunc, iterStatic, iterVar do iterVar, text = i, v; break end
local patIter = {ipairs(pat)}
for i, v in ipairs(mw.text.split(text, '\n\n', true)) do
state.i = i; for _, p in unpack(patIter) do
state.p = p
--local c = p[1](v, p, state, frame, iterFunc, iterStatic, iterVar)
local r, c = pcall(p[1], v, p, state, frame, iterFunc, iterStatic, iterVar)
-- "r == false" is 65-75% slower than "not r" (tested by [[Module:User:Ans/PerformanceTest]]
if not r then v = frame:preprocess('{{error|'..esc(c)..'}}')..v;
mw.logObject(c, 'c'); mw.logObject(_, '_'); mw.logObject(p, 'p')
break end
-- result could be,
-- * string: insert entry
-- * nil: skip entry
-- * false: not match
--if c then v = c; break end
--if c == nil then v = c; break end
if c ~= false then v = c; break end
end
if v then table.insert(r, v) end
end
return table.concat(r, '\n\n')
end
p['ราชกิจจานุเบกษา'] = function (frame)
local args = frame.args
-- these cannot be used to change result of frame:preprocess('{{{u}}}') nor
-- frame:expandTemplate {title=..., args=frame.args}
if not args.u then args.u = '' end
if not args['ม'] then args['ม'] = 'ม1' end
if not args['หม'] then args['หม'] = 'หม1' end
--local r = mw.text.split(frame.args[1], '\n\n', true)
--for i, v in ipairs(r) do
-- --r[i] = mw.ustring.gsub(v, '^(\n*)มาตรา +([๐-๙]+) +', frame:preprocess('%1{{กม|ม|%2}}'), 1)
-- --r[i] = frame:preprocess(mw.ustring.gsub(v, '^(\n*)มาตรา +([๐-๙]+) +', '%1{{กม|ม|%2}}', 1))
-- --r[i] = mw.ustring.gsub(v, '^(\n*)มาตรา +([๐-๙]+) +', function (p, n)
-- -- --return p..frame:preprocess('{{กม|ม|'..n..'}}')
-- -- return p..frame:expandTemplate{title='กม', args={'ม', n}}
-- --end, 1)
-- for j, p in ipairs(pat['ราชกิจจานุเบกษา']['กฎหมาย']) do
-- local c;
-- r[i], c = mw.ustring.gsub(v, p[1], p[2], p[3])
-- if c > 0 then break end
-- end
--end
--return table.concat(r, '\n\n')
return format(pat['ราชกิจจานุเบกษา'][frame.args[1]], frame, ipairsAtOffset(frame.args, 1))
end
return p