Module:TagQS: Difference between revisions
From Neodyland Wiki
More actions
No edit summary |
No edit summary |
||
| (10 intermediate revisions by 2 users not shown) | |||
| Line 16: | Line 16: | ||
]] | ]] | ||
require(' | require('strict') -- used for debugging purposes as it detects cases of unintended global variables | ||
-- ================================================== | -- ================================================== | ||
| Line 22: | Line 22: | ||
-- ================================================== | -- ================================================== | ||
local p = {} | local p = {} | ||
function p.replaceUnlessQuoted(str, oldChar, newChar) | |||
-- String "str" has some sections that are in quotes and some that are not. | |||
-- Do replacements only in the text sections which are not in "" quotes. | |||
local quote = string.byte('"') | |||
local comma = string.byte(oldChar) | |||
local quoted = false | |||
for pos = 1, #str do | |||
if str:byte(pos) == quote then | |||
quoted = not quoted | |||
end | |||
if str:byte(pos) == comma and not quoted then | |||
str = str:sub(1,pos-1) .. newChar .. str:sub(pos+1, str:len()) | |||
end | |||
end | |||
return str | |||
end | |||
-- =========================================================================== | -- =========================================================================== | ||
| Line 27: | Line 44: | ||
-- =========================================================================== | -- =========================================================================== | ||
function p.createTag(field, property, value) | function p.createTag(field, property, value) | ||
return mw.ustring.format('<div style="display: none;">%s QS:%s,%s</div> | -- create tags to insert using "field" "property" and "value" strings. | ||
-- "field" is an unique label to distinguish it from other tags. | |||
-- "property" and "value" are actually in a format similar to the one expected by QuickStatements | |||
return mw.ustring.format('<div style="display: none;">%s QS:%s,%s</div>', field, property or 'P', value) | |||
end | end | ||
function p.changeField(text, old, new) | function p.changeField(text, old, new) | ||
-- replace "field" part of the tag. It is needed as sometimes template adding those tags does not | |||
-- know the meaning, which is known the the outside template. For example in | |||
-- "{{Book|translator={{Creator|wikidata=Q12345}}" the Creator template will create initial | |||
-- tag with the wikidata item and {{Book}} template will add label and property for "transaltor". | |||
local patrn = '%<div style="display: none;"%>'.. old ..' QS:([^%<]+)%</div%>' | local patrn = '%<div style="display: none;"%>'.. old ..' QS:([^%<]+)%</div%>' | ||
local repl = '<div style="display: none;">'.. new ..' QS:%1</div>' | local repl = '<div style="display: none;">'.. new ..' QS:%1</div>' | ||
return mw.ustring.gsub(text, patrn, repl) | return mw.ustring.gsub(text, patrn, repl) | ||
end | end | ||
function p.changeProperty(text, field, old, new) | function p.changeProperty(text, field, old, new) | ||
if not old then | -- replace "property" part of the tag. It is needed as sometimes template adding those tags does not | ||
-- know the meaning, which is known the the outside template. For example in | |||
-- "{{Book|translator={{Creator|wikidata=Q12345}}" the Creator template will create initial | |||
-- tag with the wikidata item and {{Book}} template will add label and property for "transaltor". | |||
if not old then -- string "old" is optional if nil than any property will be replaced | |||
old = '[^%,]+' | old = '[^%,]+' | ||
end | end | ||
local patrn = '%<div style="display: none;"%>' .. field .. ' QS:' .. old .. ',([^%<]+)%</div%>' | local patrn = '%<div style="display: none;"%>' .. field .. ' QS:' .. old .. ',([^%<]+)%</div%>' | ||
local repl = '<div style="display: none;">' .. field .. ' QS:' .. new .. ',%1</div>' | local repl = '<div style="display: none;">' .. field .. ' QS:' .. new .. ',%1</div>' | ||
return mw.ustring.gsub(text, patrn, repl) | |||
end | |||
function p.append2value(text, field, text2append) | |||
-- append "text" to the "value" part of the tag | |||
local patrn = '%<div style="display: none;"%>'.. field ..' QS:([^%<]+)%</div%>' | |||
local repl = '<div style="display: none;">' .. field ..' QS:%1,' .. text2append .. '</div>' | |||
return mw.ustring.gsub(text, patrn, repl) | return mw.ustring.gsub(text, patrn, repl) | ||
end | end | ||
function p.readTag(text, field) | function p.readTag(text, field) | ||
-- read a single tag | |||
local pat = '%<div style="display: none;"%>'..field..' QS:([^%<]+)%</div%>' | local pat = '%<div style="display: none;"%>'..field..' QS:([^%<]+)%</div%>' | ||
local qs = string.match(text, pat) -- find hidden tag with QS code | local qs = string.match(text, pat) -- find hidden tag with QS code | ||
local _, nMatch = string.gsub(text, pat, "") -- count matches | local _, nMatch = string.gsub(text, pat, "") -- count matches | ||
if qs and nMatch==1 then -- allow only single matches | if qs and nMatch==1 then -- allow only single matches | ||
return mw.ustring. | return p.replaceUnlessQuoted(qs, ',', '|') | ||
end | |||
end | |||
function p.readTags(text, field) | |||
-- read multiple tags and return array of them | |||
local pat = '%<div style="display: none;"%>'..field..' QS:([^%<]+)%</div%>' | |||
local ret = {} | |||
for qs in mw.ustring.gmatch(text, pat) do | |||
table.insert(ret, p.replaceUnlessQuoted(qs, ',', '|') ) | |||
end | end | ||
return ret | |||
end | |||
function p.hasTag(text, field) | |||
-- does the "text" has a tag with field "field", or if field=nil does it have any tags? | |||
return text~= p.removeTag(text, field) | |||
end | end | ||
function p.removeTag(text, field) | function p.removeTag(text, field) | ||
-- remove tags with field "field" from the string. Field =nil will replace all tags | |||
if not field then | if not field then | ||
field = '[^ ]+' | |||
end | end | ||
local patrn = '%<div style="display: none;"%>' .. field .. ' QS:[^%<]+%</div%>' | local patrn = '%<div style="display: none;"%>' .. field .. ' QS:[^%<]+%</div%>' | ||
Latest revision as of 14:05, 15 July 2024
This documentation is transcluded from Module:TagQS/doc.
--[[
_____ .___ .__ ___________ ________ _________
/ \ ____ __| _/_ __| | ____ /\ \__ ___/____ ____ \_____ \ / _____/
/ \ / \ / _ \ / __ | | \ | _/ __ \ \/ | | \__ \ / ___\ / / \ \ \_____ \
/ Y ( <_> ) /_/ | | / |_\ ___/ /\ | | / __ \_/ /_/ > \_/. \/ \
\____|__ /\____/\____ |____/|____/\___ > \/ |____| (____ /\___ /\_____\ \_/_______ /
\/ \/ \/ \//_____/ \__> \/
This module is intended for creating invisible tags which can be used to pass
language independent data from some templates to infoboxes. Those tags are often
used by templates like [Template:Artwork] to pass data to Wikidata
Authors and maintainers:
* User:Jarekt - original version
]]
require('strict') -- used for debugging purposes as it detects cases of unintended global variables
-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}
function p.replaceUnlessQuoted(str, oldChar, newChar)
-- String "str" has some sections that are in quotes and some that are not.
-- Do replacements only in the text sections which are not in "" quotes.
local quote = string.byte('"')
local comma = string.byte(oldChar)
local quoted = false
for pos = 1, #str do
if str:byte(pos) == quote then
quoted = not quoted
end
if str:byte(pos) == comma and not quoted then
str = str:sub(1,pos-1) .. newChar .. str:sub(pos+1, str:len())
end
end
return str
end
-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p.createTag(field, property, value)
-- create tags to insert using "field" "property" and "value" strings.
-- "field" is an unique label to distinguish it from other tags.
-- "property" and "value" are actually in a format similar to the one expected by QuickStatements
return mw.ustring.format('<div style="display: none;">%s QS:%s,%s</div>', field, property or 'P', value)
end
function p.changeField(text, old, new)
-- replace "field" part of the tag. It is needed as sometimes template adding those tags does not
-- know the meaning, which is known the the outside template. For example in
-- "{{Book|translator={{Creator|wikidata=Q12345}}" the Creator template will create initial
-- tag with the wikidata item and {{Book}} template will add label and property for "transaltor".
local patrn = '%<div style="display: none;"%>'.. old ..' QS:([^%<]+)%</div%>'
local repl = '<div style="display: none;">'.. new ..' QS:%1</div>'
return mw.ustring.gsub(text, patrn, repl)
end
function p.changeProperty(text, field, old, new)
-- replace "property" part of the tag. It is needed as sometimes template adding those tags does not
-- know the meaning, which is known the the outside template. For example in
-- "{{Book|translator={{Creator|wikidata=Q12345}}" the Creator template will create initial
-- tag with the wikidata item and {{Book}} template will add label and property for "transaltor".
if not old then -- string "old" is optional if nil than any property will be replaced
old = '[^%,]+'
end
local patrn = '%<div style="display: none;"%>' .. field .. ' QS:' .. old .. ',([^%<]+)%</div%>'
local repl = '<div style="display: none;">' .. field .. ' QS:' .. new .. ',%1</div>'
return mw.ustring.gsub(text, patrn, repl)
end
function p.append2value(text, field, text2append)
-- append "text" to the "value" part of the tag
local patrn = '%<div style="display: none;"%>'.. field ..' QS:([^%<]+)%</div%>'
local repl = '<div style="display: none;">' .. field ..' QS:%1,' .. text2append .. '</div>'
return mw.ustring.gsub(text, patrn, repl)
end
function p.readTag(text, field)
-- read a single tag
local pat = '%<div style="display: none;"%>'..field..' QS:([^%<]+)%</div%>'
local qs = string.match(text, pat) -- find hidden tag with QS code
local _, nMatch = string.gsub(text, pat, "") -- count matches
if qs and nMatch==1 then -- allow only single matches
return p.replaceUnlessQuoted(qs, ',', '|')
end
end
function p.readTags(text, field)
-- read multiple tags and return array of them
local pat = '%<div style="display: none;"%>'..field..' QS:([^%<]+)%</div%>'
local ret = {}
for qs in mw.ustring.gmatch(text, pat) do
table.insert(ret, p.replaceUnlessQuoted(qs, ',', '|') )
end
return ret
end
function p.hasTag(text, field)
-- does the "text" has a tag with field "field", or if field=nil does it have any tags?
return text~= p.removeTag(text, field)
end
function p.removeTag(text, field)
-- remove tags with field "field" from the string. Field =nil will replace all tags
if not field then
field = '[^ ]+'
end
local patrn = '%<div style="display: none;"%>' .. field .. ' QS:[^%<]+%</div%>'
return mw.ustring.gsub(text, patrn, '')
end
-- ===========================================================================
-- === Versions of the function to be called from template namespace
-- ===========================================================================
function p.CreateTag(frame)
return p.createTag(frame.args[1], frame.args[2], frame.args[3])
end
return p