Mô đun:Lucbat

Văn thư lưu trữ mở Wikisource
Tài liệu mô đun[xem] [sửa] [lịch sử] [làm mới]

The module that provides most of the logic for {{Lục bát}}.

Cách sử dụng[sửa]

{{#gọi:Lucbat|lucbat}}

Tham số
Tên tham số Giá trị cho phép Mặc định
đầu / start open / mở, stanza / khổ, follow / tiếp mở
cuối / end close / đóng, stanza / khổ, follow / tiếp đóng
dòng / line 6 / lục, 8 / bát lục

-- This is an module to implement "lucbat"
-- The aim here is to provide a poem syntax that's simple, but semantically
-- correct and able to handle things like export and line wrapping.
require('strict')

local p = {} --p stands for package

local getArgs = require('Module:Arguments').getArgs

-- return true if an item is in a given list
local function check_in_list(x, list)
	for k, v in pairs(list) do
		if x == v then
			return true
		end
	end
	return false
end

local function find_first_param(args, list)
	for k, v in pairs(list) do
		if args[v] ~= nil then
			return v
		end
	end
	return nil
end

local function normalise_single_arg(args, names, default, values)
	local name = find_first_param(args, names)
	if not name then
		return default
	end
	-- mw.log("name: " .. name)
	local value = args[name]
	for key, list in pairs(values) do
		if check_in_list(value, list) then
			return key
		end
	end
	error("Unknown argument value: '" .. name .. "=" .. value .. "'.")
end

local function normalise_arg(args)
	local result = {}
	local params = {
		['open'] = {"open", "mở"},
		['stanza'] = {"stanza","khổ"},
		['follow'] = {"follow", "tiếp"},
	}
	result['start'] = normalise_single_arg(args, {'đầu', 'start'}, 'open', params)

	params = {
		['close'] = {"close", "đóng"},
		['stanza'] = {"stanza", "khổ"},
		['follow'] = {"follow", "tiếp"},
	}
	result['end'] = normalise_single_arg(args, {'cuối', 'end'}, 'close', params)
	params = {
		['6'] = {'6', 'lục'},
		['8'] = {'8', 'bát'},
	}
	result['line'] = normalise_single_arg(args, {'dòng', 'line'}, '6', params)
	return result
end

--[=[
Construct a "luc bat poem"
]=]
function p.lucbat(frame)
	-- mw.log("begin...")
	local args = getArgs(frame)
	local params = normalise_arg(args)

	local isPageNs = mw.title.getCurrentTitle():inNamespace(104)
	-- in Page namespace, we always open a fresh environment and close it at the end
	local open = isPageNs or params['start'] == 'open'
	local close = isPageNs or params['end'] == 'close'
	local line8 = params['line'] == '8'

	-- Try not to blow up if called without an argument
	-- split()/trim() handle empty strings fine, but throw when fed nil
	local input = ''
	if args[1] ~= nil then
		input = args[1]
	end

	local lines = mw.text.split(mw.text.trim(input), "\r?\n", false)
	local s = ""

	if open then 
		s = s .. '<div class="ws-lucbat"'

		-- add an HTML and XML lang attributes if needed
		if args['lang'] ~= nil then
			s = s .. ' lang="' .. args['lang'] .. '"'
			s = s .. ' xml:lang="' .. args['lang'] .. '"'
		end

		-- set up the CSS style if needed
		local style = ""
		if args['align'] ~= nil and args['align'] ~= "" then
			style = style .. 'text-align:' .. args['align'] .. ';'
		end

		if args['style'] ~= nil and args['style'] ~= "" then
			style = style .. args['style']
		end

		if style ~= "" then
			s = s .. ' style="' .. style .. '"'
		end

		s = s .. ">"
	end

	local want_open_stanza = open or params['start'] == 'stanza'
	local want_close_stanza = close or params['end'] == 'stanza'

	-- hide the BR in a span so we can manipulate it with CSS cross-browser
	local linebreak = '<span class="ws-lucbat-break"><br/></span>'
	local span6 = '<span class="ws-lucbat-6">'
	local span8 = '<span class="ws-lucbat-8">'

	-- mw.log("start...")

	for k, line in pairs(lines) do
		mw.log(line)
		-- empty line -> close current stanza or a line break
		if mw.text.trim(line) == '' then
			if want_open_stanza then
				s = s .. linebreak
			else
				s = s .. '</div>'
				want_open_stanza = true
				line8 = false
			end
		else
			-- We have text, open stanza if needed
			if want_open_stanza then
				s = s .. '<div class="ws-lucbat-kho">'
				want_open_stanza = false
			end
			if line8 then
				s = s .. span8
			else
				s = s .. span6
			end
			s = s .. line .. '</span>' .. linebreak
			line8 = not line8
		end
	end

	if want_close_stanza and not want_open_stanza then
		s = s .. linebreak .. '</div>'
	end

	if close then
		s = s .. "</div>"
	end
	-- mw.log("end...")
	return s
	-- return '<div class="for-test">' .. input .. '</div>'
end

mw.log("loaded...")
return p