Module:GHS phrases/sandbox
Appearance
![]() | This is the module sandbox page for Module:GHS phrases (diff). See also the companion subpage for test cases (run). |
![]() | This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This module depends on the following other modules: |
- Implements templates {{GHS phrases}} (talk) (tests), {{H-phrases}} and {{P-phrases}}.
List all phrases
List of H-phrases
Code | Phrase |
---|---|
H200 | Unstable explosive |
H201 | Explosive: mass explosion hazard |
H202 | Explosive: severe projection hazard |
H203 | Explosive: fire, blast or projection hazard |
H204 | Fire or projection hazard |
H205 | May mass explode in fire |
H206 | Fire, blast or projection hazard: increased risk of explosion if desensitizing agent is reduced |
H207 | Fire or projection hazard; increased risk of explosion if desensitizing agent is reduced |
H208 | Fire hazard; increased risk of explosion if desensitizing agent is reduced |
H209 | Explosive |
H210 | Very explosive |
H211 | May be sensitive |
H220 | Extremely flammable gas |
H221 | Flammable gas |
H222 | Extremely flammable material |
H223 | Flammable material |
H224 | Extremely flammable liquid and vapour |
H225 | Highly flammable liquid and vapour |
H226 | Flammable liquid and vapour |
H227 | Combustible liquid |
H228 | Flammable solid |
H229 | Pressurized container: may burst if heated |
H230 | May react explosively even in the absence of air |
H231 | May react explosively even in the absence of air at elevated pressure and/or temperature |
H232 | May ignite spontaneously if exposed to air |
H240 | Heating may cause an explosion |
H241 | Heating may cause a fire or explosion |
H242 | Heating may cause a fire |
H250 | Catches fire spontaneously if exposed to air |
H251 | Self-heating: may catch fire |
H252 | Self-heating in large quantities: may catch fire |
H260 | In contact with water releases flammable gases which may ignite spontaneously |
H261 | In contact with water releases flammable gas |
H270 | May cause or intensify fire: oxidizer |
H271 | May cause fire or explosion: strong oxidizer |
H272 | May intensify fire: oxidizer |
H280 | Contains gas under pressure: may explode if heated |
H281 | Contains refrigerated gas: may cause cryogenic burns or injury |
H282 | Extremely flammable chemical under pressure: May explode if heated |
H283 | Flammable chemical under pressure: May explode if heated |
H284 | Chemical under pressure: May explode if heated |
H290 | May be corrosive to metals |
H300 | Fatal if swallowed |
H300+H310 | Fatal if swallowed or in contact with skin |
H300+H310+H330 | Fatal if swallowed, in contact with skin or if inhaled |
H300+H330 | Fatal if swallowed or if inhaled |
H301 | Toxic if swallowed |
H301+H311 | Toxic if swallowed or in contact with skin |
H301+H311+H331 | Toxic if swallowed, in contact with skin or if inhaled |
H301+H331 | Toxic if swallowed or if inhaled |
H302 | Harmful if swallowed |
H302+H312 | Harmful if swallowed or in contact with skin |
H302+H312+H332 | Harmful if swallowed, in contact with skin or if inhaled |
H302+H332 | Harmful if swallowed or inhaled |
H303 | May be harmful if swallowed |
H303+H313 | May be harmful if swallowed or in contact with skin |
H303+H313+H333 | May be harmful if swallowed, in contact with skin or if inhaled |
H303+H333 | May be harmful if swallowed or if inhaled |
H304 | May be fatal if swallowed and enters airways |
H305 | May be harmful if swallowed and enters airways |
H310 | Fatal in contact with skin |
H310+H330 | Fatal in contact with skin or if inhaled |
H311 | Toxic in contact with skin |
H311+H331 | Toxic in contact with skin or if inhaled |
H312 | Harmful in contact with skin |
H312+H332 | Harmful in contact with skin or if inhaled |
H313 | May be harmful in contact with skin |
H313+H333 | May be harmful in contact with skin or if inhaled |
H314 | Causes severe skin burns and eye damage |
H315 | Causes skin irritation |
H315+H320 | Causes skin and eye irritation |
H316 | Causes mild skin irritation |
H317 | May cause an allergic skin reaction |
H318 | Causes serious eye damage |
H319 | Causes serious eye irritation |
H320 | Causes eye irritation |
H330 | Fatal if inhaled |
H331 | Toxic if inhaled |
H332 | Harmful if inhaled |
H333 | May be harmful if inhaled |
H334 | May cause allergy or asthma symptoms of breathing difficulties if inhaled |
H335 | May cause respiratory irritation |
H336 | May cause drowsiness or dizziness |
H340 | May cause genetic defects |
H341 | Suspected of causing genetic defects |
H350 | May cause cancer |
H350i | May cause cancer by inhalation |
H351 | Suspected of causing cancer |
H360 | May damage fertility or the unborn child |
H360D | May damage the unborn child |
H360Df | May damage the unborn child. Suspected of damaging fertility. |
H360F | May damage fertility |
H360FD | May damage fertility. May damage the unborn child. |
H360Fd | May damage fertility. Suspected of damaging the unborn child. |
H361 | Suspected of damaging fertility or the unborn child |
H361d | Suspected of damaging the unborn child |
H361f | Suspected of damaging fertility |
H361fd | Suspected of damaging fertility. Suspected of damaging the unborn child. |
H362 | May cause harm to breast-fed children |
H370 | Causes damage to organs |
H371 | May cause damage to organs |
H372 | Causes damage to organs through prolonged or repeated exposure |
H373 | May cause damage to organs through prolonged or repeated exposure |
H400 | Very toxic to aquatic life |
H401 | Toxic to aquatic life |
H402 | Harmful to aquatic life |
H410 | Very toxic to aquatic life with long lasting effects |
H411 | Toxic to aquatic life with long lasting effects |
H412 | Harmful to aquatic life with long lasting effects |
H413 | May cause long lasting harmful effects to aquatic life |
H420 | Harms public health and the environment by destroying ozone in the upper atmosphere |
H441 | Very toxic to terrestrial invertebrates |
List of P-phrases
Code | Phrase |
---|---|
P103 | Read label before use. |
P201 | Obtain special instructions before use. |
P202 | Do not handle until all safety precautions have been read and understood. |
P203 | Obtain, read and follow all safety instructions before use. |
P210 | Keep away from heat, hot surfaces, sparks, open flames and other ignition sources. No smoking. |
P211 | Do not spray on an open flame or other ignition source. |
P212 | Avoid heating under confinement or reduction of the desensitized agent. |
P220 | Keep/Store away from clothing/.../combustible materials. |
P221 | Take any precaution to avoid mixing with combustibles. |
P222 | Do not allow contact with air. |
P223 | Do not allow contact with water. |
P230 | Keep wetted with ... |
P231 | Handle and store contents under inert gas/... |
P231+P232 | Handle and store contents under inert gas. Protect from moisture |
P232 | Protect from moisture. |
P233 | Keep container tightly closed. |
P234 | Keep only in original container/packaging. |
P235 | Keep cool. |
P235+P410 | Keep cool. Protect from sunlight. |
P236 | Keep only in original packaging; division .. in the transport configuraion. |
P240 | Ground and bond container and receiving equipment. |
P241 | Use explosion-proof electrical/ventilating/light/.../equipment. |
P242 | Use only non-sparking tools. |
P243 | Take precautionary measures to prevent static discharges. |
P244 | Keep valves and fittings free from grease and oil |
P250 | Do not subject to grinding/shock/.../friction. |
P251 | Pressurized container – Do not pierce or burn, even after use. |
P260 | Do not breathe dust/fume/gas/mist/vapours/spray. |
P261 | Avoid breathing dust/fume/gas/mist/vapours/spray. |
P262 | Do not get in eyes, on skin, or on clothing. |
P263 | Avoid contact during pregnancy and while nursing. |
P264 | Wash ... thoroughly after handling. |
P264+P265 | Wash ... thoroughly after handling. Do not touch eyes. |
P265 | Do not touch eyes. |
P270 | Do not eat, drink or smoke when using this product. |
P271 | Use only outdoors or in a well-ventilated area. |
P272 | Contaminated work clothing should not be allowed out of the workplace. |
P273 | Avoid release to the environment. |
P280 | Wear protective gloves/protective clothing/eye protection/face protection. |
P281 | Use personal protective equipment as required. |
P282 | Wear cold insulating gloves and either face shield or eye protection. |
P283 | Wear fire resistant or flame retardant clothing. |
P284 | Wear respiratory protection. |
P285 | In case of inadequate ventilation wear respiratory protection. |
P301 | IF SWALLOWED: |
P301+P310 | IF SWALLOWED: Immediately call a POISON CENTER or doctor/physician. |
P301+P310+P330 | IF SWALLOWED: Immediately call a POISON CENTER or doctor/physician. Rinse mouth. |
P301+P312 | IF SWALLOWED: Call a POISON CENTER or doctor/physician if you feel unwell. |
P301+P312+P330 | IF SWALLOWED: Call a POISON CENTER or doctor/physician if you feel unwell. Rinse mouth. |
P301+P316 | IF SWALLOWED: Get immediate emergency medical help. |
P301+P317 | IF SWALLOWED: IF SWALLOWED: Get medical help. |
P301+P330+P331 | IF SWALLOWED: Rinse mouth. Do NOT induce vomiting. |
P302 | IF ON SKIN: |
P302+P312 | IF ON SKIN: Call a POISON CENTER or doctor/physician if you feel unwell. |
P302+P317 | IF ON SKIN: Get medical help. |
P302+P334 | IF ON SKIN: Immerse in cool water or wrap in wet bandages. |
P302+P335+P334 | IF ON SKIN: Brush off loose particles from skin. Immerse in cool water or wrap in wet bandages. |
P302+P350 | IF ON SKIN: Gently wash with soap and water. |
P302+P352 | IF ON SKIN: Wash with soap and water. |
P302+P352+P312 | IF ON SKIN: Wash with soap and water. Call a POISON CENTER or doctor/physician if you feel unwell. |
P302+P353 | IF ON SKIN: Rinse skin with water [or shower]. |
P302+P361+P354 | IF ON SKIN: Take off Immediately all contaminated clothing. Immediately rinse with water for several minutes. |
P303 | IF ON SKIN (or hair): |
P303+P361+P353 | IF ON SKIN (or hair): Remove/Take off immediately all contaminated clothing. Rinse skin with water [or shower]. |
P303+P361+P353+P315 | IF ON SKIN (or hair): Remove/Take off immediately all contaminated clothing. Rinse skin with water [or shower]. Get immediate medical advice/attention. |
P304 | IF INHALED: |
P304+P312 | IF INHALED: Call a POISON CENTER or doctor/physician if you feel unwell. |
P304+P317 | IF INHALED: Get medical help. |
P304+P340 | IF INHALED: Remove victim to fresh air and keep at rest in a position comfortable for breathing. |
P304+P340+P310 | IF INHALED: Remove victim to fresh air and keep at rest in a position comfortable for breathing. Immediately call a POISON CENTER or doctor/physician. |
P304+P340+P311 | IF INHALED: Remove victim to fresh air and keep at rest in a position comfortable for breathing. Call a POISON CENTER or doctor/physician. |
P304+P340+P312 | IF INHALED: Remove victim to fresh air and keep at rest in a position comfortable for breathing. Call a POISON CENTER or doctor/physician if you feel unwell. |
P304+P340+P315 | IF INHALED: Remove victim to fresh air and keep at rest in a position comfortable for breathing. Get immediate medical advice/attention. |
P304+P341 | IF INHALED: If breathing is difficult, remove victim to fresh air and keep at rest in a position comfortable for breathing. |
P305 | IF IN EYES: |
P305+P351+P338+P310 | IF IN EYES: Rinse continuously with water for several minutes. Remove contact lenses if present and easy to do. Continue rinsing. Immediately call a POISON CENTER or doctor/physician. |
P305+P351+P338+P315 | IF IN EYES: Rinse cautiously with water for several minutes. Remove contact lenses if present and easy to do. Continue rinsing. Get immediate medical advice/attention. |
P305+P354+P338 | IF IN EYES: Immediately rinse with water for several minutes. Remove contact lenses if present and easy to do. Continue rinsing. |
P306 | IF ON CLOTHING: |
P306+P360 | IF ON CLOTHING: Rinse immediately contaminated clothing and skin with plenty of water before removing clothes. |
P307 | IF exposed: |
P307+P311 | IF exposed: Call a POISON CENTER or doctor/physician. |
P308 | IF exposed or concerned: |
P308+P310 | IF exposed or concerned: Immediately call a POISON CENTER or doctor/physician. |
P308+P311 | IF exposed or concerned: Call a POISON CENTER or doctor/physician. |
P308+P313 | IF exposed or concerned: Get medical advice/attention. |
P308+P316 | IF exposed or concerned: Get emergency medical help immediately. |
P308+P360 | IF ON CLOTHING: Rinse Immediately contaminated CLOTHING and SKIN with plenty of water before removing clothes. |
P309 | IF exposed or you feel unwell: |
P309+P311 | IF exposed or you feel unwell: Call a POISON CENTER or doctor/physician. |
P310 | Immediately call a POISON CENTER or doctor/physician. |
P311 | Call a POISON CENTER or doctor/physician. |
P312 | Call a POISON CENTER or doctor/physician if you feel unwell. |
P313 | Get medical advice/attention. |
P314 | Get Medical advice/attention if you feel unwell. |
P315 | Get immediate medical advice/attention. |
P316 | Get immediate emergency medical help. |
P317 | Get emergency medical help. |
P318 | If exposed or concerned, get medical advice. |
P319 | Get medical help if you feel unwell. |
P320 | Specific treatment is urgent (see ... on this label). |
P321 | Specific treatment (see ... on this label). |
P322 | Specific measures (see ... on this label). |
P330 | Rinse mouth. |
P331 | Do NOT induce vomiting. |
P332 | If skin irritation occurs: |
P332+P313 | If skin irritation occurs: Get medical advice/attention. |
P332+P317 | If skin irritation occurs: Get medical help. |
P333 | If skin irritation or a rash occurs: |
P333+P313 | If skin irritation or a rash occurs: Get medical advice/attention. |
P333+P317 | If skin irritation or rash occurs: Get medical help. |
P334 | Immerse in cool water [or wrap in wet bandages]. |
P335 | Brush off loose particles from skin. |
P335+P334 | Brush off loose particles from skin. Immerse in cool water/wrap in wet bandages. |
P336 | Thaw frosted parts with lukewarm water. Do not rub affected areas. |
P336+P315 | Thaw frosted parts with lukewarm water. Do not rub affected area. Get immediate medical advice/attention. |
P336+P317 | Immediately thaw frosted parts with lukewarm water. Do not rub affected area. Get medical help. |
P337 | If eye irritation persists: |
P337+P313 | If eye irritation persists: Get medical advice/attention. |
P337+P317 | If eye irritation persists: Get medical help. |
P338 | Remove contact lenses if present and easy to do. Continue rinsing. |
P340 | Remove victim to fresh air and keep at rest in a position comfortable for breathing. |
P341 | If breathing is difficult, remove victim to fresh air and keep at rest in a position comfortable for breathing. |
P342 | If experiencing respiratory symptoms: |
P342+P311 | If experiencing respiratory symptoms: Call a POISON CENTER or doctor/physician. |
P342+P316 | If experiencing respiratory symptoms: Get emergence medical help immediately. |
P350 | Gently wash with soap and water. |
P351 | Rinse cautiously with water for several minutes. |
P352 | Wash with plenty of water. |
P353 | Rinse skin with water [or shower]. |
P354 | Immediately rinse with water for several minutes. |
P360 | Rinse immediately contaminated clothing and skin with plenty of water before removing clothes. |
P361 | Remove/Take off immediately all contaminated clothing. |
P361+P364 | Take off immediately all contaminated clothing and wash it before reuse. |
P362 | Take off contaminated clothing. |
P362+P364 | Take off contaminated clothing and wash it before reuse. |
P363 | Wash contaminated clothing before reuse. |
P364 | And wash it before reuse. |
P370 | In case of fire: |
P370+P372+P380+P373 | In case of fire: Explosion risk. Evacuate area. DO NOT fight fire when fire reaches explosives. |
P370+P376 | In case of fire: Stop leak if safe to do so. |
P370+P378 | In case of fire: Use ... to extinguish. |
P370+P380 | In case of fire: Evacuate area. |
P370+P380+P375 | In case of fire: Evacuate area. Fight fire remotely due to the risk of explosion. |
P370+P380+P375+P378 | In case of fire: Evacuate area. Fight fire remotely due to the risk of explosion. Use ... to extinguish. |
P371 | In case of major fire and large quantities: |
P371+P380+P375 | In case of major fire and large quantities: Evacuate area. Fight fire remotely due to the risk of explosion. |
P372 | Explosion risk. |
P373 | DO NOT fight fire when fire reaches explosives. |
P374 | Fight fire with normal precautions from a reasonable distance. |
P375 | Fight fire remotely due to the risk of explosion. |
P376 | Stop leak if safe to do so. |
P377 | Leaking gas fire – do not extinguish unless leak can be stopped safely. |
P378 | Use ... to extinguish. |
P380 | Evacuate area. |
P381 | In case of leakage, eliminate all ignition sources. |
P390 | Absorb spillage to prevent material damage. |
P391 | Collect spillage. |
P401 | Store in accordance with ... |
P402 | Store in a dry place. |
P402+P404 | Store in a dry place. Store in a closed container. |
P403 | Store in a well ventilated place. |
P403+P233 | Store in a well ventilated place. Keep container tightly closed. |
P403+P235 | Store in a well ventilated place. Keep cool. |
P404 | Store in a closed container. |
P405 | Store locked up. |
P406 | Store in a corrosive resistant/... container with a resistant inner liner. |
P407 | Maintain air gap between stacks or pallets. |
P410 | Protect from sunlight. |
P410+P403 | Protect from sunlight. Store in a well ventilated place. |
P410+P412 | Protect from sunlight. Do not expose to temperatures exceeding 50 ºC/122 ºF. |
P411 | Store at temperatures not exceeding ... ºC/... ºF. |
P411+P235 | Store at temperatures not exceeding ... ºC/... ºF. Keep cool. |
P412 | Do not expose to temperatures exceeding 50 ºC/122 ºF. |
P413 | Store bulk masses greater than ... kg/... lbs at temperatures not exceeding ... °C/... °F. |
P420 | Store separately/away from other materials. |
P422 | Store contents under ... |
P501 | Dispose of contents/container to ... |
P502 | Refer to manufacturer or supplier for information on recovery or recycling. |
P503 | Refer to manufacturer/supplier... for information on disposal/recovery/recycling. |
List formats
|listtype=abbr
(default)- P201, P302+P334, P502
Listtype options
|
---|
|
Full abbr list
Complete H, P lists (H200, H201, H202, ...)
|
---|
As of 31 May 2023:
|
Features
Hide Doubles
Repeated phrase codes are hidden:
{{GHS phrases|H400|H401|H401|H401}}
→ H400, H401
Omit Rules
|omit=true
(default)
Omit Rules: when the keep ID is present, do not show the omit ID phrase
|
{{GHS phrases|H314|H318}}
→ H314
All module functions
module function | template | note |
---|---|---|
main |
{{GHS phrases}} {{H-phrases}} {{P-phrases}} |
|setid=H, P preset
|
listAll |
{{GHS phrases/inline}} | equals main + |listtype=inline
|
numberOfPhrases |
{{GHS phrases/number of phrases}} | |
listAll |
{{GHS phrases/list all}} | |
listOmitRules |
{{GHS phrases/list omit rules}} | documentation only; no |setid=
|
Tracking
- First Help page: Template:GHS phrases (including documentation)
- Category:GHS errors (0) (includes: "unknown parameter used")
- Category:GHS warnings (2)
See also
- Main article: Globally Harmonized System of Classification and Labelling of Chemicals (GHS);
- {{Chembox}}, {{Chembox Hazards}}
- Source: "Globally Harmonized System of Classification and Labelling of Chemicals" (pdf). 2021. Annex 3: Codification of Statements and Pictograms (pp 268–385).
- ^ a b "Globally Harmonized System of Classification and Labelling of Chemicals" (pdf). 2021. Annex 3: Codification of Statements and Pictograms (pp 268–385).
-- START MERGE PH TABLES 28-11-2021
-- removed dead/DEV code into /sandbox2 2021-12-28
-- ERR11+13 together? 'X'
--------------------------------------------------------------------------------
-- Module:GHS phrases
--
-- main: reads GHS parameters (arguments like "H301", "P401")
-- and returns for each (listtype='abbr'):
-- phraseCode visible; formal phrase text as <abbr title="...">
-- setid = H, P or ''
-- phraseCode = e.g. "H201", "P231+P234"
-- phrase text read from array tables in [[Module:GHS phrases/data]]
--
-- Implements: [[Template:GHS phrases]]
-- Helppage: [[Template:GHS phrases]]
-- Error category: [[Category:GHS errors]], [[Category:GHS warnings]] (mainspace pages only)
-- todo longer term: reorg cats unde GHStrackiung; all msg prefic "GHS"; add cat:Notes;
--
-- Also:
-- listAll(), numberOfPhrases(), listOmitRules(),
-- listtype, omit
--------------------------------------------------------------------------------
require('Module:No globals')
local r = {} -- "r" for return, so no confusion with setid P
local GHSdata = mw.loadData('Module:GHS phrases/data/sandbox') -- -- todo /sandbox here
local getArgs = require('Module:Arguments').getArgs
local tTools = require('Module:TableTools')
local yesno = require('Module:Yesno')
local tArgName = {} -- named parameters (setid, omit, listtype)
local tTailPreviewMsgs = {} -- tail: Preview messages, added after the inline output
local tTailCats = {} -- tail: Categories, added after the inline output
local isDebug = true
--------------------------------------------------------------------------------
-- label H-phrases or P-phrases
--------------------------------------------------------------------------------
local function PHlabel()
if tArgName.useSetid == '' then
return 'GHS--phrases'
else
return tArgName.useSetid .. '-phrases'
end
end
--------------------------------------------------------------------------------
-- wlHelpPage
--
-- Formats page as [[Helppage#Section|Label]]
-- by default, sLabel == sSection ( |label = #section (#anchor) )
--------------------------------------------------------------------------------
local function wlHelpPage(sSection, sLabel)
local sHelpPage = 'Template:GHS phrases'
if sLabel == nil then sLabel = sSection end
if (sLabel or '') == '' then
sLabel = ''
else
sLabel = '|' .. sLabel
end
if (sSection or '') == '' then
sSection = ''
else
sSection = '#' .. sSection
end
return '[[' .. sHelpPage .. sSection .. sLabel .. ']]'
end
--------------------------------------------------------------------------------
-- wlInlineTag
--
-- class="noprint Inline-Template Template-Fact" is c/p from meta Template:Fix. No TSTYLES (Dec2021)
-- Returns <sup>[?]</sup> with wikilink to [[helppage#section|errormessage]]
--------------------------------------------------------------------------------
local function wlInlineTag(sMsgTxt)
local sMsg
-- span css title with the linked [?] text, as label in wikilink: [[targetpage#section|spantitlelabel]]
local sSection = PHlabel()
local spanCssTitle = '<span title=\"' .. PHlabel() .. ': ' .. sMsgTxt .. '\">?</span>'
sMsg = '<sup><span class="noprint Inline-Template Template-Fact">[<i>'
.. wlHelpPage(sSection, spanCssTitle)
.. '</i>]</span></sup>'
return sMsg
end
--------------------------------------------------------------------------------
-- formatInMono
--
-- Use mono font-family (from: Template:Mono)
--------------------------------------------------------------------------------
local function formatInMono(s)
if yesno(s == '', false) or false then -- do not return an empty span
return ''
else
return '<span class="monospaced" style="font-family: monospace;">' .. s .. '</span>'
end
end
--------------------------------------------------------------------------------
-- addPreviewMsg
--------------------------------------------------------------------------------
local function addPreviewMsg(sMsg)
local previewWarn = require('Module:If preview')._warning
if sMsg == '' then
else
if isDebug then
table.insert(tTailPreviewMsgs, sMsg .. '|')
else
table.insert(tTailPreviewMsgs, previewWarn({sMsg}))
end
end
return sMsg
end
--------------------------------------------------------------------------------
-- addErrorCategory
--
-- Formats as [[Category:GHS errors|catsort]]
-- or '' when in other namespace.
-- sCatsort option using: H, P, _
--------------------------------------------------------------------------------
local function addErrorCategory(sCatsort)
local pagetype = require('Module:Pagetype').main
if sCatsort == nil then sCatsort = tArgName.useSetid end
local wlErrCat = ''
if pagetype() == 'article' then -- mainspace only
if sCatsort == '' then
wlErrCat = '[[Category:GHS errors]]'
else
wlErrCat = '[[Category:GHS errors|' .. sCatsort .. ']]'
end
else
if isDebug then
wlErrCat = '[[:Category:GHS errors|CAT:' .. sCatsort .. ']]'
else
return
end
end
table.insert(tTailCats, wlErrCat)
return
end
--------------------------------------------------------------------------------
-- addWarningCategory
--
-- Formats as [[Category:GHS warnings|catsort]]
-- mainspace only, or '' when in other namespace.
-- sCatsort warning options used: D, O, - (Double, Omit, Hyphen)
--------------------------------------------------------------------------------
local function addWarningCategory(sCatsort)
local pagetype = require('Module:Pagetype').main
--debug so do here / move into if-clause
if sCatsort == nil then sCatsort = tArgName.setid end
local wlWarnCat = ''
if pagetype() == 'article' then -- mainspace only
if sCatsort == '' then
wlWarnCat = '[[Category:GHS warnings]]'
else
wlWarnCat = '[[Category:GHS warnings|' .. sCatsort .. ']]'
end
else
if isDebug then
wlWarnCat = '[[:Category:GHS warnings|CAT:warn-' .. sCatsort .. ']]|'
else
return ''
end
end
table.insert(tTailCats, wlWarnCat)
return
end
--------------------------------------------------------------------------------
-- reportMsgAndTrack (errormessage,)
--
--------------------------------------------------------------------------------
local function reportMsgAndTrack(errID, sSetID, sPhraseCode)
-- ERR11 = setid BAD like 'X'
-- ERR13 = no setid
-- ERR21 = code has no setid
-- ERR22 = code not found in list
-- ERR24 = OmitRule
-- ERR25 = Double
-- NOTE31 = hyphen used
local isWarning = false
local sPrevMsg = ''
local sCatSort = 'ε' -- lc epsilon = errID unexpected / absent
local sInlineMsg = ''
if errID == 'ERR11' then
sPrevMsg = wlHelpPage('GHS setid') .. ': set id \'' .. sSetID .. '\' not known (\'H\' or \'P\' expected)'
sCatSort = 'I-unk'
elseif errID == 'ERR13' then
sPrevMsg = wlHelpPage('', 'GHS phrases') .. ': set id missing (please use: setid=H or P)'
sCatSort = 'I-missing'
elseif errID == 'ERR21' then
sInlineMsg = sPhraseCode .. wlInlineTag('\'' .. sPhraseCode .. '\' not found') -- adds the [?] tag; with wl and CSS title
sPrevMsg = wlHelpPage(PHlabel()) .. ': \'' .. sPhraseCode .. '\' not found'
sCatSort = PHlabel()
elseif errID == 'ERR22' then
sInlineMsg = sPhraseCode .. wlInlineTag('\'' .. sPhraseCode .. '\' not found') -- adds the [?] tag; with wl and CSS title
sPrevMsg = wlHelpPage(PHlabel()) .. ': \'' .. sPhraseCode .. '\' set id is not \'' .. tArgName.useSetid .. '\''
sCatSort = PHlabel()
elseif errID == 'ERR24' then
sInlineMsg = ''
isWarning = true
sCatSort = 'O'
elseif errID == 'ERR25' then
sInlineMsg = ''
isWarning = true
sCatSort = 'D'
elseif errID == "NOTE31" then
sInlineMsg = ''
isWarning = true
sCatSort = '-'
else
sPrevMsg = 'error unk'
sInlineMsg = errID .. ': error ID unk'
sCatSort = '?E'
end
local sDebugPrefix = ''
if isDebug then
sDebugPrefix = formatInMono('/' .. errID .. '$' .. tArgName.useSetid .. '/')
end
addPreviewMsg(sPrevMsg .. sDebugPrefix)
if isWarning then
addWarningCategory(sCatSort .. sDebugPrefix)
else
addErrorCategory(sCatSort .. sDebugPrefix)
end
return sInlineMsg
end
--------------------------------------------------------------------------------
-- showTailMsgAndCat
--
-- show table tTailPreviewMsgs
-- preview-messages and errorcat
-- all namespaces
--------------------------------------------------------------------------------
local function showTailMsgAndCat()
if isDebug then
else
if tTools.size(tTailPreviewMsgs) > 0 then
return table.concat(tTailPreviewMsgs, '') .. table.concat(tTailCats, '')
else
return ''
end
end
return table.concat(tTailPreviewMsgs, '') .. table.concat(tTailCats, '')
end
--------------------------------------------------------------------------------
-- applyHideDuplicates
--
-- returns edited table, with double Codes removed
-- adds warning with codes.
-- base table tArgsCodes is walked through by a iwalker that reads a singel code,
-- then a ikiller checks the upward part of the same table to delete all copies
-- ikiller starts at end of table, walks towards iwalker; then tArgsCodes is compressed
-- iwalker steps 1 up in the freshly compressed table
-- Used: iArgs is sorted, and order stays same. compress does not change that.
--------------------------------------------------------------------------------
local function applyHideDuplicates(tArgsCodes)
local iR, iK -- iR = reader, iK = killer; the iKiller works from the array end backward
local hit = false
iR = 1
while iR < #tArgsCodes do
iK = #tArgsCodes
while iK > iR do
if tArgsCodes[iK] == tArgsCodes[iR] then
hit = true
addPreviewMsg('Duplicate removed: ' .. tArgsCodes[iR])
table.remove(tArgsCodes, iK)
tTools.compressSparseArray(tArgsCodes)
end
iK = iK - 1
end
tTools.compressSparseArray(tArgsCodes)
iR = iR + 1
end
if hit then
reportMsgAndTrack('ERR25')
end
return tArgsCodes
end
--------------------------------------------------------------------------------
-- applyOmitRules
--
-- returns edited table, with Omit phraseCode's removed
-- Omit rule is per GHS_Rev9E_0.pdf (2021)
--------------------------------------------------------------------------------
local function applyOmitRules(tArgsCodes)
local tRules = GHSdata['tOmitRules']
local hit = false
for keep, omit in pairs(tRules) do
if tTools.inArray(tArgsCodes, omit) then
if tTools.inArray(tArgsCodes, keep) then
hit = true
for i, k in pairs(tArgsCodes) do
if k == omit then
table.remove(tArgsCodes, i)
end
end
addPreviewMsg(wlHelpPage('Omit Rules') .. ': keep ' .. keep .. ', omit ' .. omit)
end
end
end
if hit then
tTools.compressSparseArray(tArgsCodes)
reportMsgAndTrack('ERR24')
end
return tArgsCodes
end
--------------------------------------------------------------------------------
-- formatPhraseAbbr
--
-- format phraseCode and text, for abbr-form (infobox list form)
--------------------------------------------------------------------------------
local function formatPhraseAbbr(phraseCode, sPhrase)
return '<abbr class="abbr" title=" ' .. phraseCode .. ': ' .. sPhrase .. '">'
.. phraseCode
.. '</abbr>'
end
--------------------------------------------------------------------------------
-- formatPhraseInline
--
-- format phraseCode and text, for inline form (in sentence)
-- adds "quotes"
--------------------------------------------------------------------------------
local function formatPhraseInline(phraseCode, sPhrase)
return formatInMono(phraseCode) .. ': \"' .. sPhrase .. '\"'
end
--------------------------------------------------------------------------------
-- formatPhraseList
--
-- as inline, but no "quotes" added.
--------------------------------------------------------------------------------
local function formatPhraseList(phraseCode, sPhrase)
return formatInMono(phraseCode) .. ': ' .. sPhrase
end
--------------------------------------------------------------------------------
-- getHyphenNoGHS
--------------------------------------------------------------------------------
local function getHyphenNoGHS(tArgs)
local b
b = yesno(tArgs[1] == '-', false) or false
if b == true then
reportMsgAndTrack('NOTE31', nil,'-')
end
tArgName.bHyphenNoGHS = b
return b
end
--------------------------------------------------------------------------------
-- getSetID
--
-- Determines setid (expected either 'H', 'P' or '')
-- First route is: read |setid=
-- When |setid= is not set,
-- it looks for a first parameter that has an H of P prefix (in |P201|P202|...)
-- when not found, '' is retured
-- (then: try first hit in clean Code list from H330 or P330)
-- In one call, P and H numbers can *not* be mixed
-- so "|H201|P202|" will cause error "P202 not found" (... in H-list)
-- returns .useSetId
--------------------------------------------------------------------------------
local function getSetID(tArgs)
local setidArg = tArgs.setid or ''
local setidFromCodelist = ''
if setidArg == 'P' or setidArg == 'H' then
elseif setidArg == '' then
-- not defined, try reading from code list
setidFromCodelist = nil
for i, v in ipairs(tArgs) do
setidFromCodelist = mw.ustring.match(v, '^[PH]') or nil
if setidFromCodelist ~= nil then
break
end
end
if setidFromCodelist == nil then
setidFromCodelist = ''
end
else -- bad id like 'X' (nil not expected)
reportMsgAndTrack('ERR11', setidArg)
setidArg = '' -- no setid; ERR
end
tArgName.setid = setidArg
tArgName.setidFromCodelist = setidFromCodelist
if tArgName.setid == '' then
tArgName.useSetid = tArgName.setidFromCodelist
else
tArgName.useSetid = tArgName.setid
end
if tArgName.useSetid == '' then
if getHyphenNoGHS(tArgs) == true then
-- skip this report when hyphen
else
reportMsgAndTrack('ERR13')
end
end
if tArgName.useSetid == nil then
tArgName.useSetid = 'NiL'
end
return tArgName.useSetid
end
--------------------------------------------------------------------------------
-- getListType
--
-- Checks list format, including those from Module:List
--------------------------------------------------------------------------------
local function getListType(tArgs)
local listTypes = {
['abbr'] = true,
['inline'] = true,
['bulleted'] = true,
['unbulleted'] = true,
['horizontal'] = true,
['ordered'] = true,
['horizontal_ordered'] = true,
['horizontal ordered'] = true
}
local sListType = tArgs['listtype'] or 'abbr'
if sListType == '' or sListType == 'abbr' then
sListType = 'abbr'
elseif listTypes[sListType] == true then
if sListType == 'horizontal ordered' then
sListType = 'horizontal_ordered'
end
else
sListType = 'abbr'
end
tArgName.listtype = sListType
return
end
--------------------------------------------------------------------------------
-- getDoOmitRules
--------------------------------------------------------------------------------
local function getDoOmitRules(tArgs)
tArgName.omit = yesno(tArgs['omit'], true) or true
return tArgName.omit
end
--------------------------------------------------------------------------------
-- one option (Jan 2022):
-- format=plain - used in NumberOfPhrases
--------------------------------------------------------------------------------
local function getFormatSettings(tArgs)
if tArgs['format'] == 'plain' then
tArgName.format = 'plain'
else
tArgName.format = ''
end
return tArgName.format
end
--------------------------------------------------------------------------------
local function hyphenNoGHStext()
return GHSdata.tHyphenNoGHS['hyphen']
end
--------------------------------------------------------------------------------
-- normaliseCode
--
--
--------------------------------------------------------------------------------
local function normaliseCode(c)
local setid = tArgName.useSetid or ''
c = mw.text.decode(c)
c = mw.ustring.gsub(c, '[^%d%+A-Za-z]', '')
c = mw.ustring.gsub(c, '^(%d)', setid .. '%1')
c = mw.ustring.gsub(c, '%+(%d)', '+' .. setid .. '%1')
return c
end
--------------------------------------------------------------------------------
-- checkCodeFormat like X567
--------------------------------------------------------------------------------
local function checkCodeFormat(c)
local s = 'chk fmt: '
mw.ustring.gmatch(c, '[%+]?[PH]%d%d%d[A-Za-z]*')
for codeN in iterator do
s = s .. codeN .. '; '
end
return s
end
--------------------------------------------------------------------------------
-- prepareArgsAndCodes
--
-- 1. reads & checks named parameters (like setid)
-- 2. clean up & format phrase IDs (=unnamed parameters)
-- remove bad characters, create H/P pattern "H201", "P310+P302"
-- returns input Codes list (=unnnamed parameters): straight array, no nil's, sorted
--------------------------------------------------------------------------------
local function prepareArgsAndCodes(tArgs)
local tArgsCodes
-- read, normalise & store named args; add errnote
getSetID(tArgs)
getHyphenNoGHS(tArgs)
getListType(tArgs)
getDoOmitRules(tArgs)
getFormatSettings(tArgs)
tArgsCodes = tTools.compressSparseArray(tArgs) -- removes all named args
for i, v in ipairs(tArgsCodes) do
v = normaliseCode(v)
tArgsCodes[i] = v
end
table.sort(tArgsCodes)
return tArgsCodes
end
--------------------------------------------------------------------------------
-- listAll
--
-- Returns wikitable rows for each phrase id.
-- requires |setid=P/H
-- returns full list, all phrases, for a setid
-- 2-columns wikitable, sorted, sortable, anchor like "H201" for each
--------------------------------------------------------------------------------
function r.listAll(frame)
local tArgs = getArgs(frame)
local tL = {}
prepareArgsAndCodes(tArgs)
if tArgName.useSetid == '' then
-- -- todo test setid is required ERR11, ERR13
end
local tRead
tRead = GHSdata['GHSphrases']
-- ORDERED RANGE: t2 {i, code}
local t2 = {}
local sPattern = '^' .. tArgName.setid
for code, v in pairs(tRead) do
if string.match(code, sPattern) ~= nil then
table.insert(t2, code)
end
end
t2 = tTools.compressSparseArray(t2)
table.sort(t2) -- required, worls (unk why .sort(tRead) did not work / Nov 2021)
-- LIST: tL tablerows (i, code, phrase)
local sTR, v, sAnchor
-- i = array index, s = phrase code, v = phrase text
for i, s in ipairs(t2) do
v = tRead[s]
sAnchor = '<span class="anchor" id="' .. s .. '"/>'
sTR = '|- ' .. sAnchor .. '\n| datasortvalue="' .. i .. '" | <span style="font-family: monospace;">' .. s .. '</span> || ' .. v
table.insert(tL, sTR)
end
return table.concat(tL, '\n')
end
--------------------------------------------------------------------------------
-- numberOfPhrases
--
-- Documentation
-- requires |setid=H/P
-- Returns number of phrases, in format
-- "GHS H-phrases (123)"
--------------------------------------------------------------------------------
function r.numberOfPhrases(frame)
local tArgs = getArgs(frame)
local tC = {}
tArgs.setid = 'H' -- dummy
prepareArgsAndCodes(tArgs)
if tArgName.useSetid == '' then
-- setid is required
return showTailMsgAndCat()
end
tC = GHSdata['GHSphrases']
local iT = 0
if tArgName.useSetid == '' then
iT = tTools.size(tC) -- all H+P then
else
local sPat = '^' .. tArgName.useSetid
for c, phrase in pairs(tC) do
if string.match(c, sPat) ~= nil then
iT = iT + 1
end
end
end
local sResult
if tArgName.format == 'plain' then
sResult = tostring(iT)
else
sResult = 'GHS ' .. PHlabel() .. ' <span style="font-weight: normal;">(' .. tostring(iT) .. ')</span>'
end
return sResult .. showTailMsgAndCat()
end
--------------------------------------------------------------------------------
-- listOmitRules
-- tod: top text now external
-- self-documentation
-- does not usae frame args, does not require setid=H,P
--------------------------------------------------------------------------------
function r.listOmitRules()
local tRules = GHSdata['tOmitRules']
local tL = {}
local s
s = ''
for keep, omit in pairs(tRules) do
s = '• keep ' .. formatInMono(keep) .. ', omit ' .. formatInMono(omit)
table.insert(tL, s)
end
table.sort(tL)
return table.concat(tL, '<br/>')
end
--------------------------------------------------------------------------------
-- _main
--
-- processes setid (H, P) and phrase codes
-- error: setid not P, H
-- code not found
-- cannot mix H and P phrases
-- reads phrases from /data H or P phrases tables
-- formats phrase (abbreviation, abbr-title, phraseCode)
--------------------------------------------------------------------------------
function r._main(tArgs)
local tArgsCodes
tArgsCodes = prepareArgsAndCodes(tArgs)
if tArgName.useSetid == '' then
return showTailMsgAndCat()
end
if #tArgsCodes == 0 then -- no codes in; no text shown no error no warning
return showTailMsgAndCat()
end
if tArgName.bHyphenNoGHS then
return hyphenNoGHStext(tArgName.setid) .. showTailMsgAndCat()
end
tArgsCodes = applyHideDuplicates(tArgsCodes)
if tArgName.omit then
tArgsCodes = applyOmitRules(tArgsCodes)
end
local formatterF
if tArgName.listtype == 'abbr' then
formatterF = formatPhraseAbbr
elseif tArgName.listtype == 'inline' then
formatterF = formatPhraseInline
else --- Module:List options
formatterF = formatPhraseList
end
local tReadPhrases = {}
tReadPhrases = GHSdata['GHSphrases']
local sPhrase
local tR = {} -- Return table, to concat by listtype
local sSetPattern = '^' .. tArgName.useSetid
for i, code in ipairs(tArgsCodes) do
sPhrase = tReadPhrases[code]
if sPhrase == nil then
sPhrase = reportMsgAndTrack('ERR21', nil, code)
table.insert(tR, sPhrase)
elseif mw.ustring.match(code, sSetPattern) == nil then
sPhrase = reportMsgAndTrack('ERR22', tArgName.useSetid, code)
table.insert(tR, sPhrase)
else
table.insert(tR, formatterF(code, sPhrase))
end
end
if tArgName.listtype == 'abbr' then
return table.concat(tR, ', ') .. showTailMsgAndCat()
elseif tArgName.listtype == 'inline' then
return table.concat(tR, ', ') .. showTailMsgAndCat()
else
local mList = require('Module:List')
return mList[tArgName.listtype](tR) .. showTailMsgAndCat()
end
end
--------------------------------------------------------------------------------
-- main
--
-- handles template input frame, then calls generic _main() function
-- To be invoked from {{template}}
--------------------------------------------------------------------------------
function r.main(frame)
local tArgs = getArgs(frame)
return r._main(tArgs)
end
return r