模块:Citation/CS1/Utilities:修订间差异
外观
wikiw>Antigng |
小 导入1个版本 |
(没有差异)
| |
2025年6月21日 (六) 00:45的最新版本
-{H|zh-cn:账号; zh-tw:帳號;}--{H|账户=>zh-cn:账号; 账户=>zh-tw:帳號;}--{H|賬戶=>zh-cn:账号; 賬戶=>zh-tw:帳號;}--{H|賬號=>zh-cn:账号; 賬號=>zh-tw:帳號;}--{H|帐户=>zh-cn:账号; 帐户=>zh-tw:帳號;}--{H|帳戶=>zh-cn:账号;}--{H|帐号=>zh-cn:账号; 帐号=>zh-tw:帳號;}--{H|zh-cn:全域账号; zh-tw:全域帳號;}--{H|zh-cn:大量账号创建者; zh-tw:大量帳號建立者; zh-hk:大量帳號建立者;}--{H|zh-cn:高级; zh-tw:進階;}--{H|zh-cn:规范控制; zh-tw:權威控制;}--{H|zh-cn:封禁; zh-tw:封鎖; zh-hk:封鎖;}--{H|zh-cn:全域封禁; zh-tw:全域封鎖; zh-hk:全域封鎖;}--{H|zh-cn:更改; zh-tw:變更;}--{H|zh-cn:字符; zh-tw:字元;}--{H|zh-cn:著作权; zh-tw:著作權; zh-hk:版權; zh-mo:著作權;}--{H|版权=>zh-tw:著作權; 版权=>zh-mo:著作權;}--{H|版权信息=>zh-cn:著作权信息; 版权信息=>zh-sg:著作权信息; 版权信息=>zh-my:著作权信息; 版权信息=>zh-tw:著作權資訊; 版权信息=>zh-mo:著作權資訊;}--{H|zh-cn:创建; zh-tw:建立;}--{H|創建=>zh-tw:建立; 創建=>zh-hk:建立; 創建=>zh-mo:建立;}--{H|zh-cn:自定义; zh-tw:自訂;}--{H|自定義=>zh-hk:自訂; 自定義=>zh-tw:自訂;}--{H|自定=>zh-hk:自訂; 自定=>zh-tw:自訂;}--{H|zh-cn:默认; zh-tw:預設;}--{H|默認=>zh-tw:預設;}--{H|zh-hans: 扩展名; zh-hant: 副檔名;}--{H|文件扩展名 => zh-tw: 副檔名; 文件扩展名 => zh-hk: 副檔名; 文件扩展名 => zh-mo: 副檔名; }--{H|zh-hans: 扩展; zh-hant: 擴充功能;}--{H|扩充功能 => zh-cn: 扩展; 扩充功能 => zh-my: 扩展; 扩充功能 => zh-sg: 扩展;}--{H|擴充套件 => zh-cn: 扩展; 擴充套件 => zh-my: 扩展; 擴充套件 => zh-sg: 扩展;}--{H|擴展 => zh-tw: 擴充功能; 擴展 => zh-hk: 擴充功能; 擴展 => zh-mo: 擴充功能; }--{H|zh-cn:文件; zh-tw:檔案;}--{H|档案=>zh-cn:文件; 档案=>zh-sg:文件; 档案=>zh-my:文件;}--{H|zh-cn:文件名; zh-tw:檔案名稱;}--{H|zh-hans:机器用户; zh-tw:機器使用者; zh-hk:機械用戶;}--{H|zh-cn:脚注; zh-tw:註腳;}--{H|zh-cn:帮助:; zh-tw:說明:;}--{H|zh-cn:帮助讨论:; zh-tw:說明討論:;}--{H|zh-cn:导入; zh-tw:匯入;}--{H|汇入=>zh-cn:导入; 汇入=>zh-sg:导入; 汇入=>zh-my:导入;}--{H|導入=>zh-tw:匯入; 導入=>zh-hk:匯入; 導入=>zh-mo:匯入;}--{H|zh-cn:信息; zh-tw:資訊;}--{H|zh-hans:界面; zh-hant:介面;}--{H|zh-cn:界面管理员; zh-tw:介面管理員;}--{H|zh-cn:IP封禁豁免; zh-tw:IP封鎖豁免;}--{H|IP封禁例外=>zh-hans:IP封禁豁免; IP封禁例外=>zh-hant:IP封鎖豁免;}--{H|IP封鎖例外=>zh-hans:IP封禁豁免; IP封禁例外=>zh-hant:IP封鎖豁免;}--{H|zh-hans:换行符;zh-hant:換行字元;}--{H|zh:換行符;zh-hans:换行符;zh-hant:換行字元;}--{H|zh:换行字元;zh-hans:换行符;zh-hant:換行字元;}--{H|zh-cn:链接; zh-tw:連結;}--{H|连结=>zh-cn:链接; 连结=>zh-sg:链接; 连结=>zh-my:链接;}--{H|鏈接=>zh-tw:連結; 鏈接=>zh-hk:連結; 鏈接=>zh-mo:連結;}--{H|鏈結=>zh-tw:連結; 鏈結=>zh-hk:連結; 鏈結=>zh-mo:連結;}--{H|内链=>zh-tw:內部連結; 内链=>zh-hk:內部連結; 内链=>zh-mo:內部連結;}--{H|內鏈=>zh-tw:內部連結; 內鏈=>zh-hk:內部連結; 內鏈=>zh-mo:內部連結;}--{H|外链=>zh-tw:外部連結; 外链=>zh-hk:外部連結; 外链=>zh-mo:外部連結;}--{H|外鏈=>zh-tw:外部連結; 外鏈=>zh-hk:外部連結; 外鏈=>zh-mo:外部連結;}--{H|红链=>zh-tw:紅色連結; 红链=>zh-hk:紅色連結; 红链=>zh-mo:紅色連結;}--{H|紅鏈=>zh-tw:紅色連結; 紅鏈=>zh-hk:紅色連結; 紅鏈=>zh-mo:紅色連結;}--{H|绿链=>zh-tw:綠色連結; 绿链=>zh-hk:綠色連結; 绿链=>zh-mo:綠色連結;}--{H|綠鏈=>zh-tw:綠色連結; 綠鏈=>zh-hk:綠色連結; 綠鏈=>zh-mo:綠色連結;}--{H|蓝链=>zh-tw:藍色連結; 蓝链=>zh-hk:藍色連結; 蓝链=>zh-mo:藍色連結;}--{H|藍鏈=>zh-tw:藍色連結; 藍鏈=>zh-hk:藍色連結; 藍鏈=>zh-mo:藍色連結;}--{H|zh-cn:链入; zh-tw:連入;}--{H|鏈入=>zh-tw:連入;}--{H|zh-hans:日志详情; zh-hant:日誌明細;}--{H|zh-hans:登录; zh-hant:登入;}--{H|zh-hant:登出; zh-hans:退出;}--{H|退出登录 => zh-tw:登出; 退出登录 => zh-hk:登出; 退出登录 => zh-mo:登出; }--{H|zh-cn:模块; zh-tw:模組;}--{H|模组=>zh-cn:模块; 模组=>zh-sg:模块; 模组=>zh-my:模块;}--{H|zh-hans:模块文档; zh-hant:模組文件;}--{H|zh-hans:命名空间; zh-hant:命名空間;}--{H|名字空间=>zh-cn:命名空间; 名字空间=>zh-hk:命名空間; 名字空间=>zh-mo:命名空間; 名字空间=>zh-tw:命名空間; 名字空间=>zh-sg:命名空间; 名字空间=>zh-my:命名空间;}--{H|名字空間=>zh-cn:命名空间; 名字空間=>zh-hk:命名空間; 名字空間=>zh-mo:命名空間; 名字空間=>zh-tw:命名空間; 名字空間=>zh-sg:命名空间; 名字空間=>zh-my:命名空间;}--{H|zh-hans:布告板; zh-hant:布告板;}--{H|布告板=>zh-hk:佈告板; 布告板=>zh-mo:佈告板}--{H|佈告板=>zh-tw:布告板; 佈告板=>zh-hans:布告板}--{H|zh-cn:解析器函数; zh-hk:解析器函數; zh-tw:解析器函數;}--{H|zh-cn:参数设置; zh-tw:偏好設定; zh-hk:參數設置;}--{H|zh-hans:项目; zh-hant:專案; zh-tw:專案;}--{H|专案=>zh-cn:项目; 专案=>zh-sg:项目; 专案=>zh-my:项目; 专案=>zh-tw:專案;}--{H|計劃=>zh-cn:项目; 計劃=>zh-sg:项目; 計劃=>zh-my:项目; 計劃=>zh-tw:專案; 計劃=>zh-hk:專案; 計劃=>zh-mo:專案;}--{H|zh-hans:项目页面; zh-hant:專案頁面; zh-tw:專案頁面;}--{H|項目頁面=>zh-tw:計畫頁面; 項目頁面=>zh-hk:專案頁面; 項目=>zh-mo:專案頁面;}--{H|zh-hans:最近更改; zh-hant:近期變更;}--{H|zh-cn:重定向; zh-tw:重新導向;}--{H|zh-cn:重定向页; zh-tw:重新導向頁面;}--{H|重定向页面=>zh-tw:重新導向頁面; 重定向页面=>zh-hk:重新導向頁面; 重定向页面=>zh-mo:重新導向頁面;}--{H|zh-cn:举报; zh-tw:檢舉;}--{H|zh-cn:示例; zh-tw:範例;}--{H|皮肤=>zh-tw:外觀; 皮肤=>zh-hk:外觀; 皮肤=>zh-mo:外觀;}--{H|zh-hans:原始码; zh-hant:原始碼; zh-cn:源代码;}--{H|源代碼=>zh-hk:原始碼; 源代碼=>zh-mo:原始碼; 源代碼=>zh-tw:原始碼; 源代碼=>zh-sg:原始码; 源代碼=>zh-my:原始码;}--{H|源码=>zh-hk:原始碼; 源码=>zh-mo:原始碼; 源码=>zh-tw:原始碼; 源码=>zh-sg:原始码; 源码=>zh-my:原始码;}--{H|源碼=>zh-hk:原始碼; 源碼=>zh-mo:原始碼; 源碼=>zh-tw:原始碼; 源碼=>zh-sg:原始码; 源碼=>zh-my:原始码;}--{H|zh-cn:字符串; zh-tw:字串;}--{H|zh-hans:模板数据; zh-hant:模板資料; zh-tw:模板資料;}--{H|zh-hans:模板文档; zh-hant:模板文件;}--{H|zh-cn:通过; zh-tw:透過;}--{H|zh-cn:撤销; zh-tw:復原;}--{H|撤消=>zh-tw:復原; 撤消=>zh-hk:復原; 撤消=>zh-mo:復原;}--{H|zh-hans:用户; zh-hant:使用者; zh-tw:使用者; zh-hk:用戶;}--{H|zh-cn:用户组; zh-tw:使用者群組; zh-hk:用戶組;}--{H|用户名字空間=>zh-hk:用戶命名空間; 用户名字空間=>zh-mo:用戶命名空間; 用户名字空間=>zh-tw:使用者命名空間;}--{H|用戶名字空间=>zh-hk:用戶命名空間; 用戶名字空间=>zh-mo:用戶命名空間; 用戶名字空间=>zh-tw:使用者命名空間;}--{H|用戶名字空間=>zh-hk:用戶命名空間; 用戶名字空間=>zh-mo:用戶命名空間; 用戶名字空間=>zh-tw:使用者命名空間;}--{H|zh-cn:用户页; zh-tw:使用者頁面; zh-hk:用戶頁;}--{H|用户頁=>zh-tw:使用者頁面;}--{H|用戶页=>zh-tw:使用者頁面;}--{H|用户页面=>zh-tw:使用者頁面;}--{H|使用者頁=>zh-tw:使用者頁面;}--{H|使用者頁面=>zh-tw:使用者頁面;}--{H|用户权限 => zh-tw:使用者權限;用戶權限 => zh-tw:使用者權限;}--{H|用户权 => zh-tw:使用者權限;用戶權 => zh-tw:使用者權限;}--{H|zh-cn:用户框; zh-tw:使用者方塊; zh-hk:用戶框;}--{H|zh-hans:用户名; zh-hant:用戶名; zh-tw:使用者名稱;}--{H|用户名称=>zh-cn:用户名; 用户名称=>zh-my:用户名; 用户名称=>zh-sg:用户名; 用户名称=>zh-tw:使用者名稱;}--{H|用戶名稱=>zh-cn:用户名; 用戶名稱=>zh-my:用户名; 用戶名稱=>zh-sg:用户名; 用戶名稱=>zh-tw:使用者名稱;}--{H|zh-cn:查看; zh-tw:檢視;}--{H|zh-cn:可视化; zh-tw:視覺化;}--{H|zh-cn:监视列表; zh-tw:監視清單;}--{H|计算机=>zh-sg:电脑; 计算机=>zh-my:电脑; 计算机=>zh-tw:電腦; 计算机=>zh-hk:電腦; 计算机=>zh-mo:電腦;}--{H|計算機=>zh-sg:电脑; 計算機=>zh-my:电脑;}--{H|电子计算机=>zh-sg:电脑; 电子计算机=>zh-my:电脑; 电子计算机=>zh-tw:電腦; 电子计算机=>zh-hk:電腦; 电子计算机=>zh-mo:電腦;}--{H|zh-cn:链接; zh-tw:連結;}--{H|连结=>zh-cn:链接; 连结=>zh-sg:链接; 连结=>zh-my:链接;}--{H|zh-cn:链入; zh-tw:連入;}--{H|zh-cn:程序;zh-hk:程序;zh-tw:程式;}--{H|zh-cn:语法高亮; zh-tw:語法突顯;}--{H|語法凸顯=>zh-cn:语法高亮; 語法凸顯=>zh-sg:语法高亮; 語法凸顯=>zh-my:语法高亮;}--{H|语法高亮度=>zh-tw:語法突顯; 语法高亮度=>zh-hk:語法突顯; 语法高亮度=>zh-mo:語法突顯;}--{H|語法高亮度=>zh-tw:語法突顯; 語法高亮度=>zh-hk:語法突顯; 語法高亮度=>zh-mo:語法突顯;}--{H|zh-cn:可视化; zh-tw:視覺化;}--{H|紀錄=>zh-cn:记录}--{H|zh-cn:署名; zh-hk:署名; zh-tw:姓名標示; zh-sg:署名;}--{H|zh-hans:著作权; zh-hant:著作權; zh-hk:版權;}--{H|版权=>zh-cn:著作权; 版权=>zh-sg:著作权; 版权=>zh-my:著作权; 版权=>zh-tw:著作權; 版权=>zh-mo:著作權;}--{H|zh-hans:著作权信息;zh-hant:著作權資訊;zh-hk:版權資訊;}--{H|版权信息=>zh-cn:著作权信息; 版权信息=>zh-sg:著作权信息; 版权信息=>zh-my:著作权信息; 版权信息=>zh-tw:著作權資訊; 版权信息=>zh-mo:著作權資訊;}--{H|zh-cn:知识共享;zh-tw:創用CC;zh-hk:共享創意;}--{H|知识共享CC => zh-tw: 創用CC; 共享創意CC => zh-tw: 創用CC;}--{H|zh-cn:知识共享公共许可协议;zh-tw:創用CC公眾授權條款;zh-hk:共享創意公眾特許條款;}--{H|創用 CC 公眾授權條款=>zh-cn:知识共享公共许可协议;創用 CC 公眾授權條款=>zh-tw:創用 CC 公眾授權條款;創用 CC 公眾授權條款=>zh-hk:共享創意公眾特許條款;創用 CC 公眾授權條款=>zh-mo:共享創意公眾特許條款;}--{H|創用CC 公眾授權條款=>zh-cn:知识共享公共许可协议;創用CC 公眾授權條款=>zh-tw:創用CC 公眾授權條款;創用CC 公眾授權條款=>zh-hk:共享創意公眾特許條款;創用CC 公眾授權條款=>zh-mo:共享創意公眾特許條款;}--{H|創作共用公眾授權條款=>zh-cn:知识共享公共许可协议;創用共用公眾授權條款=>zh-tw:創用CC 公眾授權條款;創用共用公眾授權條款=>zh-hk:共享創意公眾特許條款;創用共用公眾授權條款=>zh-mo:共享創意公眾特許條款;}--{H|zh-cn:自由软件许可协议;zh-tw:自由軟體授權;zh-hk:自由軟體授權;}--{H|zh-cn:信息; zh-tw:資訊}--{H|授權=>zh-cn:授权; 授權=>zh-hk:授權; 授權=>zh-tw:授權;}--{H|授权=>zh-cn:授权; 授權=>zh-hk:授權; 授權=>zh-tw:授權;}--{H|特許=>zh-cn:許可; 特許=>zh-hk:特許; 特許=>zh-tw:授權;}--{H|許可=>zh-cn:许可; 許可=>zh-tw:授權; 許可=>zh-hk:特許;}--{H|许可=>zh-cn:许可; 许可=>zh-tw:授權; 许可=>zh-hk:特許;}--{H|zh-cn:许可条款; zh-tw:授權條款; zh-hk:特許條款;}--{H|授权条款=>zh-cn:许可证;授权条款=>zh-hk:特許條款;授权条款=>zh-mo:特許條款;}--{H|许可证=>zh-tw:授權條款;许可证=>zh-hk:特許條款;许可证=>zh-mo:特許條款;}--{H|許可證=>zh-tw:授權條款;許可證=>zh-hk:特許條款;許可證=>zh-mo:特許條款;}--{H|zh-cn:本地化; zh-tw:在地化; zh-hk:本地化; zh-sg:本地化;}--{H|zh-cn:禁止演绎; zh-hk:禁止衍生; zh-tw:禁止改作; zh-cn:禁止演绎;}--{H|zh-cn:发布; zh-tw:釋出;}--{H|zh-cn:相同方式共享; zh-hk:相同方式共享; zh-tw:相同方式分享; zh-sg:相同方式共享;}--{H|zh-hans:维护报告;zh-hant:維護報表}--{H|zh:未连接至项的页面;zh-hans:未连接至项的页面;zh-hant:頁面未連結至任何項目}--{H|未链接页面=>zh:未连接至项的页面;未链接页面=>zh-hans:未连接至项的页面;未链接页面=>zh-hant:頁面未連結至任何項目}--{H|zh-hans:页面列表;zh-hant:頁面清單}--{H|所有带前缀的页面=>zh:前缀索引;所有带前缀的页面=>zh-hans:前缀索引;所有带前缀的页面=>zh-hant:前缀索引}--{H|按詞頭查詢頁面=>zh:前缀索引;按詞頭查詢頁面=>zh-hans:前缀索引;按詞頭查詢頁面=>zh-hant:前缀索引}--{H|zh-cn:搜索; zh-tw:搜尋;}--{H|zh:全域用户账户重命名申请;zh-hans:全域用户账户重命名申请;zh-hant:全域使用者帳號重新命名請求}--{H|全域重命名申请=>zh:全域用户账户重命名申请;全域重命名申请=>zh-hans:全域用户账户重命名申请;全域重命名申请=>zh-hant:全域使用者帳號重新命名請求}--{H|zh:创建账户;zh-hans:创建账户;zh-hant:建立帳號}--{H|zh:登录;zh-hans:登录;zh-hant:登入}--{H|zh:统一登录状态;zh-hans:统一登录状态;zh-hant:帳號整合狀態}--{H|合并账户=>zh:统一登录状态;合并账户=>zh-hans:统一登录状态;合并账户=>zh-hant:帳號整合狀態}--{H|zh-hans:电子邮箱;zh-hant:電子郵件;}--{H|zh-hans:电邮联系;zh-hant:電郵聯絡用戶;zh-tw:電郵聯絡使用者;}--{H|zh-hans:参数设置;zh-hant:偏好設定;}--{H|偏好设定=>zh-hans:参数设置;偏好设定=>zh-cn:参数设置;偏好设定=>zh-my:参数设置;偏好设定=>zh-sg:参数设置;}--{H|參數設置=>zh-hant:偏好設定;參數設置=>zh-tw:偏好設定;參數設置=>zh-hk:偏好設定;參數設置=>zh-mo:偏好設定;}--{H|zh-hans:设置;zh-hant:設定;}--{H|设定=>zh-hans:设置;设定=>zh-cn:设置;设定=>zh-my:设置;设定=>zh-sg:设置;}--{H|設置=>zh-hant:設定;設置=>zh-tw:設定;設置=>zh-hk:設定;設置=>zh-mo:設定;}--{H|zh-hans:最近更改;zh-hant:近期變更;}--{H|近期变更=>zh-cn:最近更改;近期变更=>zh-my:最近更改;近期变更=>zh-sg:最近更改;}--{H|zh-hans:链入页面;zh-hant:連結至此的頁面;}--{H|链接至此的页面=>zh-cn:链入页面;链接至此的页面=>zh-my:链入页面;链接至此的页面=>zh-sg:链入页面;}--{H|连结至此的页面=>zh-cn:链入页面;连结至此的页面=>zh-my:链入页面;连结至此的页面=>zh-sg:链入页面;}--{H|鏈入頁面=>zh-tw:連結至此的頁面;鏈入頁面=>zh-hk:連結至此的頁面;鏈入頁面=>zh-mo:連結至此的頁面;}--{H|連入頁面=>zh-tw:連結至此的頁面;連入頁面=>zh-hk:連結至此的頁面;連入頁面=>zh-mo:連結至此的頁面;}--{H|zh-cn:档案馆; zh-tw:檔案館;}--{H|档案馆=>zh-cn:档案馆; 档案馆=>zh-sg:档案馆; 档案馆=>zh-my:档案馆;}--{H|zh-hans:方程式;zh-hant:方程式}--{H|zh-cn:全域禁制; zh-tw:全域禁制;}--{H|zh-cn:日志项目; zh-tw:日誌項目;}--{H|zh-hant:通過;zh-tw:通過;zh-hk:通過;zh-mo:通過;zh-hans:通过;zh-cn:通过;zh-sg:通过;zh-my:通过;}--{H|透過=>zh-hant:透過;zh-hans:通过;}--{H|使用者名稱稱=>zh-tw:使用者名稱;}--{H|使用者名稱命名空間 => zh-tw:使用者命名空間;}--{H|使用者權限限 => zh-tw:使用者權限;}--{H|用户名单 => zh-tw:使用者名單; 用戶名單 => zh-tw:使用者名單;}--{H|用户名單 => zh-tw:使用者名單; 用户名單 => zh-tw:使用者名單;}--{H|zh-hans:或许可以;zh-hant:或許可以}--{H|zh-hans:也许可以;zh-hant:也許可以}-
{{#lst:Module:Citation/CS1/doc|header}} 此页面包含Module:Citation/CS1会用到的常用函数和表。
{{#lst:Module:Citation/CS1/doc|module_components_table}}
--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]
local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration
--[[--------------------------< H Y P H E N _ T O _ D A S H >-------------------------------------------------
Converts a hyphen to a dash
]]
--
local function hyphen_to_dash( str )
if not is_set(str) or str:match( "[%[%]{}<>]" ) ~= nil then
return str;
end
return str:gsub( '-', '–' );
end
--[[--------------------------< I S _ S E T >------------------------------------------------------------------
Returns true if argument is set; false otherwise. Argument is 'set' when it exists (not nil) or when it is not an empty string.
This function is global because it is called from both this module and from Date validation
]]
function is_set( var )
return not (var == nil or var == '');
end
--[[--------------------------< F I R S T _ S E T >------------------------------------------------------------
Locates and returns the first set value in a table of values where the order established in the table,
left-to-right (or top-to-bottom), is the order in which the values are evaluated. Returns nil if none are set.
This version replaces the original 'for _, val in pairs do' and a similar version that used ipairs. With the pairs
version the order of evaluation could not be guaranteed. With the ipairs version, a nil value would terminate
the for-loop before it reached the actual end of the list.
]]
local function first_set (list, count)
local i = 1;
while i <= count do -- loop through all items in list
if is_set( list[i] ) then
return list[i]; -- return the first set list member
end
i = i + 1; -- point to next
end
end
--[[--------------------------< I N _ A R R A Y >--------------------------------------------------------------
Whether needle is in haystack
]]
local function in_array( needle, haystack )
if needle == nil then
return false;
end
for n,v in ipairs( haystack ) do
if v == needle then
return n;
end
end
return false;
end
--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------
Populates numbered arguments in a message string using an argument table.
]]
local function substitute( msg, args )
return args and mw.message.newRawMessage( msg, args ):plain() or msg;
end
--[[--------------------------< H A S _ A C C E P T _ A S _ W R I T T E N >------------------------------------
When <str> is wholly wrapped in accept-as-written markup, return <str> without markup and true; return <str> and false else
with allow_empty = false, <str> must have at least one character inside the markup
with allow_empty = true, <str> the markup frame can be empty like (()) to distinguish an empty template parameter from the specific condition "has no applicable value" in citation-context.
After further evaluation the two cases might be merged at a later stage, but should be kept separated for now.
]]
local function has_accept_as_written (str, allow_empty)
local count;
if true == allow_empty then
str, count = str:gsub ('^%(%((.*)%)%)$', '%1'); -- allows (()) to be an empty set
else
str, count = str:gsub ('^%(%((.+)%)%)$', '%1');
end
return str, 0 ~= count;
end
--[[--------------------------< S A F E _ F O R _ I T A L I C S >----------------------------------------------
Protects a string that will be wrapped in wiki italic markup '' ... ''
Note: We cannot use <i> for italics, as the expected behavior for italics specified by ''...'' in the title is that
they will be inverted (i.e. unitalicized) in the resulting references. In addition, <i> and '' tend to interact
poorly under Mediawiki's HTML tidy.
]]
local function safe_for_italics (str)
if not is_set (str) then return str end
if str:sub (1, 1) == "'" then str = "<span></span>" .. str; end
if str:sub (-1, -1) == "'" then str = str .. "<span></span>"; end
-- Remove newlines as they break italics.
return str:gsub ('\n', ' ');
end
--[[--------------------------< W R A P _ S T Y L E >----------------------------------------------------------
Applies styling to various parameters. Supplied string is wrapped using a message_list configuration taking one
argument; protects italic styled parameters. Additional text taken from citation_config.presentation - the reason
this function is similar to but separate from wrap_msg().
]]
local function wrap_style (key, str)
if not is_set (str) then
return '';
elseif in_array (key, cfg.presentation['_safe_for_italics']) then
str = safe_for_italics (str);
end
return substitute (cfg.presentation[key], str);
end
--[[--------------------------< M A K E _ S E P _ L I S T >------------------------------------------------------------
make a separated list of items using provided separators.
<sep_list> - typically '<comma><space>'
<sep_list_pair> - typically '<space>and<space>'
<sep_list_end> - typically '<comma><space>and<space>' or '<comma><space>&<space>'
defaults to cfg.presentation['sep_list'], cfg.presentation['sep_list_pair'], and cfg.presentation['sep_list_end']
if <sep_list_end> is specified, <sep_list> and <sep_list_pair> must also be supplied
]]
local function make_sep_list (count, list_seq, sep_list, sep_list_pair, sep_list_end)
local list = '';
if not sep_list then -- set the defaults
sep_list = cfg.presentation['sep_list'];
sep_list_pair = cfg.presentation['sep_list_pair'];
sep_list_end = cfg.presentation['sep_list_end'];
end
if 2 >= count then
list = table.concat (list_seq, sep_list_pair); -- insert separator between two items; returns list_seq[1] then only one item
elseif 2 < count then
list = table.concat (list_seq, sep_list, 1, count - 1); -- concatenate all but last item with plain list separator
list = table.concat ({list, list_seq[count]}, sep_list_end); -- concatenate last item onto end of <list> with final separator
end
return list;
end
--[[--------------------------< S A F E _ J O I N >------------------------------------------------------------
Joins a sequence of strings together while checking for duplicate separation characters.
]]
local function safe_join( tbl, duplicate_char )
--[[
Note: we use string functions here, rather than ustring functions.
This has considerably faster performance and should work correctly as
long as the duplicate_char is strict ASCII. The strings
in tbl may be ASCII or UTF8.
]]
local str = ''; -- the output string
local comp = ''; -- what does 'comp' mean?
local end_chr = '';
local trim;
for _, value in ipairs( tbl ) do
if value == nil then value = ''; end
if str == '' then -- if output string is empty
str = value; -- assign value to it (first time through the loop)
elseif value ~= '' then
if value:sub(1,1) == '<' then -- Special case of values enclosed in spans and other markup.
comp = value:gsub( "%b<>", "" ); -- remove html markup (<span>string</span> -> string)
else
comp = value;
end
-- typically duplicate_char is sepc
if comp:sub(1,1) == duplicate_char then -- is first charactier same as duplicate_char? why test first character?
-- Because individual string segments often (always?) begin with terminal punct for th
-- preceding segment: 'First element' .. 'sepc next element' .. etc?
trim = false;
end_chr = str:sub(-1,-1); -- get the last character of the output string
-- str = str .. "<HERE(enchr=" .. end_chr.. ")" -- debug stuff?
if end_chr == duplicate_char then -- if same as separator
str = str:sub(1,-2); -- remove it
elseif end_chr == "'" then -- if it might be wikimarkup
if str:sub(-3,-1) == duplicate_char .. "''" then -- if last three chars of str are sepc''
str = str:sub(1, -4) .. "''"; -- remove them and add back ''
elseif str:sub(-5,-1) == duplicate_char .. "]]''" then -- if last five chars of str are sepc]]''
trim = true; -- why? why do this and next differently from previous?
elseif str:sub(-4,-1) == duplicate_char .. "]''" then -- if last four chars of str are sepc]''
trim = true; -- same question
end
elseif end_chr == "]" then -- if it might be wikimarkup
if str:sub(-3,-1) == duplicate_char .. "]]" then -- if last three chars of str are sepc]] wikilink
trim = true;
elseif str:sub(-2,-1) == duplicate_char .. "]" then -- if last two chars of str are sepc] external link
trim = true;
elseif str:sub(-4,-1) == duplicate_char .. "'']" then -- normal case when |url=something & |title=Title.
trim = true;
end
elseif end_chr == " " then -- if last char of output string is a space
if str:sub(-2,-1) == duplicate_char .. " " then -- if last two chars of str are <sepc><space>
str = str:sub(1,-3); -- remove them both
end
end
if trim then
if value ~= comp then -- value does not equal comp when value contains html markup
local dup2 = duplicate_char;
if dup2:match( "%A" ) then dup2 = "%" .. dup2; end -- if duplicate_char not a letter then escape it
value = value:gsub( "(%b<>)" .. dup2, "%1", 1 ) -- remove duplicate_char if it follows html markup
else
value = value:sub( 2, -1 ); -- remove duplicate_char when it is first character
end
end
end
str = str .. value; --add it to the output string
end
end
return str;
end
--[[--------------------------< S T R I P _ A P O S T R O P H E _ M A R K U P >--------------------------------
Strip wiki italic and bold markup from argument so that it doesn't contaminate COinS metadata.
This function strips common patterns of apostrophe markup. We presume that editors who have taken the time to
markup a title have, as a result, provided valid markup. When they don't, some single apostrophes are left behind.
]]
local function strip_apostrophe_markup (argument)
if not is_set (argument) then return argument; end
while true do
if argument:match ("%'%'%'%'%'") then -- bold italic (5)
argument=argument:gsub("%'%'%'%'%'", ""); -- remove all instances of it
elseif argument:match ("%'%'%'%'") then -- italic start and end without content (4)
argument=argument:gsub("%'%'%'%'", "");
elseif argument:match ("%'%'%'") then -- bold (3)
argument=argument:gsub("%'%'%'", "");
elseif argument:match ("%'%'") then -- italic (2)
argument=argument:gsub("%'%'", "");
else
break;
end
end
return argument; -- done
end
--[[--------------------------< H A S _ I N V I S I B L E _ C H A R S >----------------------------------------
This function searches a parameter's value for nonprintable or invisible characters. The search stops at the
first match.
This function will detect the visible replacement character when it is part of the wikisource.
Detects but ignores nowiki and math stripmarkers. Also detects other named stripmarkers (gallery, math, pre, ref)
and identifies them with a slightly different error message. See also coins_cleanup().
Detects but ignores the character pattern that results from the transclusion of {{'}} templates.
Output of this function is an error message that identifies the character or the Unicode group, or the stripmarker
that was detected along with its position (or, for multi-byte characters, the position of its first byte) in the
parameter value.
]]
local function has_invisible_chars (param, v)
local position = ''; -- position of invisible char or starting position of stripmarker
local dummy; -- end of matching string; not used but required to hold end position when a capture is returned
local capture; -- used by stripmarker detection to hold name of the stripmarker
local i=1;
local stripmarker, apostrophe;
while cfg.invisible_chars[i] do
local char=cfg.invisible_chars[i][1] -- the character or group name
local pattern=cfg.invisible_chars[i][2] -- the pattern used to find it
position, dummy, capture = mw.ustring.find (v, pattern) -- see if the parameter value contains characters that match the pattern
if position then
if 'nowiki' == capture or 'math' == capture or -- nowiki and math stripmarkers (not an error condition)
('templatestyles' == capture) then -- templatestyles stripmarker allowed
stripmarker = true; -- set a flag
elseif true == stripmarker and 'delete' == char then -- because stripmakers begin and end with the delete char, assume that we've found one end of a stripmarker
position = nil; -- unset
elseif 'apostrophe' == char then -- apostrophe template uses ‍, hair space and zero-width space
apostrophe = true;
elseif true == apostrophe and in_array (char, {'zero width joiner', 'zero width space', 'hair space'}) then
position = nil; -- unset
else
local err_msg;
if capture then
err_msg = capture .. ' ' .. cfg.invisible_chars[i][3] or char;
else
err_msg = cfg.invisible_chars[i][3] or (char .. ' character');
end
return {err_msg, wrap_style ('parameter', param), position}; -- and done with this parameter
end
end
i=i+1; -- bump our index
end
end
--[[--------------------------< W R A P _ M S G >--------------------------------------------------------------
Applies additional message text to various parameter values. Supplied string is wrapped using a message_list
configuration taking one argument. Supports lower case text for {{citation}} templates. Additional text taken
from citation_config.messages - the reason this function is similar to but separate from wrap_style().
]]
local function wrap_msg (key, str, lower)
if not is_set (str) then
return '';
elseif in_array (key, cfg.messages['_safe_for_italics']) then
str = safe_for_italics (str);
end
if true == lower then
local msg;
msg = cfg.messages[key]:lower(); -- set the message to lower case before
return substitute (msg, str); -- including template text
else
return substitute (cfg.messages[key], str);
end
end
--[[--------------------------< K E R N _ Q U O T E S >--------------------------------------------------------
Apply kerning to open the space between the quote mark provided by the Module and a leading or trailing quote mark contained in a |title= or |chapter= parameter's value.
This function will positive kern either single or double quotes:
"'Unkerned title with leading and trailing single quote marks'"
" 'Kerned title with leading and trailing single quote marks' " (in real life the kerning isn't as wide as this example)
Double single quotes (italic or bold wikimarkup) are not kerned.
Call this function for chapter titles, for website titles, etc; not for book titles.
]]
local function kern_quotes (str)
local cap='';
local cap2='';
cap, cap2 = str:match ("^([\"\'])([^\'].+)"); -- match leading double or single quote but not double single quotes
if is_set (cap) then
str = wrap_style ('kern-left', {cap, cap2});
end
cap, cap2 = str:match ("^(.+[^\'])([\"\'])$")
if is_set (cap) then
str = wrap_style ('kern-right', {cap, cap2});
end
return str;
end
--[[--------------------------< P E N D _ S E P A R A T O R >--------------------------------------------------
]]
local function pend_separator (item, sepc, prepend)
if prepend then
return is_set (item) and sepc .. ' ' .. item or '';
else
return is_set (item) and item .. sepc .. ' ' or '';
end
end
--[[--------------------------< S E T _ S E L E C T E D _ M O D U L E S >--------------------------------------
Sets local cfg table to same (live or sandbox) as that used by the other modules.
]]
local function set_selected_modules (cfg_table_ptr)
cfg = cfg_table_ptr;
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
first_set = first_set, -- exported functions
has_accept_as_written = has_accept_as_written,
has_invisible_chars = has_invisible_chars,
hyphen_to_dash = hyphen_to_dash,
in_array = in_array,
is_set = is_set,
kern_quotes = kern_quotes,
make_sep_list = make_sep_list,
pend_separator = pend_separator,
safe_join = safe_join,
substitude = substitude,
strip_apostrophe_markup = strip_apostrophe_markup,
substitute = substitute,
wrap_style = wrap_style,
wrap_msg = wrap_msg,
set_selected_modules = set_selected_modules
}