ဝိၵ်ႇသျိၼ်ႇၼရီႇ
shnwiktionary
https://shn.wiktionary.org/wiki/%E1%80%9D%E1%80%AD%E1%81%B5%E1%80%BA%E1%82%87%E1%80%9E%E1%80%BB%E1%80%AD%E1%81%BC%E1%80%BA%E1%82%87%E1%81%BC%E1%80%9B%E1%80%AE%E1%82%87:%E1%81%BC%E1%82%83%E1%82%88%E1%82%81%E1%80%B0%E1%80%9D%E1%80%BA%E1%82%81%E1%82%85%E1%81%B5%E1%80%BA%E1%82%88
MediaWiki 1.46.0-wmf.26
case-sensitive
သိုဝ်ႇၶၢဝ်ႇ
ၶိုၵ်ႉတွၼ်း
ဢုပ်ႇၵုမ်
ၽူႈၸႂ်ႉတိုဝ်း
ဢုပ်ႇၵုမ် ၽူႈၸႂ်ႉတိုဝ်း
ဝိၵ်ႇသျိၼ်ႇၼရီႇ
လွင်ႈဢုပ်ႇဢူဝ်း ဝိၵ်ႇသျိၼ်ႇၼရီႇ
ၾၢႆႇ
ဢုပ်ႇၵုမ် ၾၢႆႇ
မီႇတီႇယႃႇဝီႇၶီႇ
ဢုပ်ႇၵုမ် မီႇတီႇယႃႇဝီႇၶီႇ
ထႅမ်းပလဵတ်ႉ
ဢုပ်ႇၵုမ် ထႅမ်းပလဵတ်ႉ
လွင်ႈၸွႆႈထႅမ်
ဢုပ်ႇၵုမ် လွင်ႈၸွႆႈထႅမ်
ပိူင်ထၢၼ်ႈ
ဢုပ်ႇၵုမ် ပိူင်ထၢၼ်ႈ
ၵိူၼ်ႇတူ
ဢုပ်ႇၵုမ် ၵိူၼ်ႇတူ
တွၼ်ႈၸပ်းႁၢင်
ဢုပ်ႇၵုမ် တွၼ်ႈၸပ်းႁၢင်
တူၼ်းၸၢပ်ႈလႅပ်ႈ
ဢုပ်ႇၵုမ် တူၼ်းၸၢပ်ႈလႅပ်ႈ
ၶိုၼ်းၵေႃႇသၢင်ႈ
ဢုပ်ႇၵုမ် ၶိုၼ်းၵေႃႇသၢင်ႈ
TimedText
TimedText talk
မေႃႇၵျူး
ဢုပ်ႇၵုမ် မေႃႇၵျူး
Event
Event talk
မေႃႇၵျူး:chemical element list/data/shn
828
54840
260386
2026-04-29T12:27:05Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "local export = {} export.elements = { [1] = { wplink = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ", name = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ" }, [2] = { wplink = "ႁီႇလီႇယႅမ်ႇ", name = "ႁီႇလီႇယႅမ်ႇ" }, [3] = { wplink = "လီႇထီႇယႅမ်ႇ", name = "လီႇထီႇယႅမ်ႇ" }, [4] = { wplink = "ပႄႇရီႇလီႇ..."
260386
Scribunto
text/plain
local export = {}
export.elements = {
[1] = { wplink = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ", name = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ" },
[2] = { wplink = "ႁီႇလီႇယႅမ်ႇ", name = "ႁီႇလီႇယႅမ်ႇ" },
[3] = { wplink = "လီႇထီႇယႅမ်ႇ", name = "လီႇထီႇယႅမ်ႇ" },
[4] = { wplink = "ပႄႇရီႇလီႇယႅမ်ႇ", name = "ပႄႇရီႇလီႇယႅမ်ႇ" },
[5] = { wplink = "ပူဝ်ႇရွၼ်ႇ", name = "ပူဝ်ႇရွၼ်ႇ" },
[6] = { wplink = "ၶႃႇပွၼ်ႇ", name = "ၶႃႇပွၼ်ႇ" },
[7] = { wplink = "ၼၢႆႇထရူဝ်ႇၵျိၼ်ႇ", name = "ၼၢႆႇထရူဝ်ႇၵျိၼ်ႇ" },
[8] = { wplink = "ဢွၵ်ႇသီႇၵျိၼ်ႇ", name = "ဢွၵ်ႇသီႇၵျိၼ်ႇ" },
[9] = { wplink = "ၾလူဝ်ႇရိၼ်း", name = "ၾလူဝ်ႇရိၼ်း" },
[10] = { wplink = "ၼီႇဢွၼ်ႇ", name = "ၼီႇဢွၼ်ႇ" },
[11] = { wplink = "သူဝ်ႇတီႇယႅမ်ႇ", name = "သူဝ်ႇတီႇယႅမ်ႇ" },
[12] = { wplink = "မႅၵ်ႉၼီးသီႇယႅမ်ႇ", name = "မႅၵ်ႉၼီးသီႇယႅမ်ႇ" },
[13] = { wplink = "ဢလူႇမီႇၼီႇယႅမ်ႇ", name = "ဢလူႇမီႇၼီႇယႅမ်ႇ" },
[14] = { wplink = "သီႇလီႇၵွၼ်ႇ", name = "သီႇလီႇၵွၼ်ႇ" },
[15] = { wplink = "ၽွတ်ႉသ်ၾေႃးရတ်ႉသ်", name = "ၽွတ်ႉသ်ၾေႃးရတ်ႉသ်" },
[16] = { wplink = "သပ်ႉၾႃႇ", name = "သပ်ႉၾႃႇ" },
[17] = { wplink = "ၶလူဝ်ႇရိၼ်း", name = "ၶလူဝ်ႇရိၼ်း" },
[18] = { wplink = "ဢႃႇၵွၼ်ႇ", name = "ဢႃႇၵွၼ်ႇ" },
[19] = { wplink = "ပူဝ်ႇတႅတ်ႉသီႇယႅမ်ႇ", name = "ပူဝ်ႇတႅတ်ႉသီႇယႅမ်ႇ" },
[20] = { wplink = "ၶႄႇလ်သီႇယႅမ်ႇ", name = "ၶႄႇလ်သီႇယႅမ်ႇ" },
[21] = { wplink = "သၵႅၼ်ႇတီႇယႅမ်ႇ", name = "သၵႅၼ်ႇတီႇယႅမ်ႇ" },
[22] = { wplink = "တၢႆႇထေႇၼီႇယႅမ်ႇ", name = "တၢႆႇထေႇၼီႇယႅမ်ႇ" },
[23] = { wplink = "ဝၼေးတီႇယႅမ်ႇ", name = "ဝၼေးတီႇယႅမ်ႇ" },
[24] = { wplink = "ၶရူဝ်ႇမီႇယႅမ်ႇ", name = "ၶရူဝ်ႇမီႇယႅမ်ႇ" },
[25] = { wplink = "မႅင်းၵၼီးသ်", name = "မႅင်းၵၼီးသ်" },
[26] = { wplink = "ဢၢႆႇယၼ်ႇ", name = "ဢၢႆႇယၼ်ႇ" },
[27] = { wplink = "ၵူဝ်ႇပေႃး", name = "ၵူဝ်ႇပေႃး" },
[28] = { wplink = "ၼိၵ်ႉၵႄႇ", name = "ၼိၵ်ႉၵႄႇ" },
[29] = { wplink = "ၶွပ်ႉပႃႇ", name = "ၶွပ်ႉပႃႇ" },
[30] = { wplink = "ၸိၼ်ႉၵ်", name = "ၸိၼ်ႉၵ်" },
[31] = { wplink = "ၵႄႇလီႇယႅမ်ႇ", name = "ၵႄႇလီႇယႅမ်ႇ" },
[32] = { wplink = "ၵျႃႇမေးၼီႇယႅမ်ႇ", name = "ၵျႃႇမေးၼီႇယႅမ်ႇ" },
[33] = { wplink = "ဢႃႇသၼိၵ်ႉ", name = "ဢႃႇသၼိၵ်ႉ" },
[34] = { wplink = "သီႇလီႇၼီႇယႅမ်ႇ", name = "သီႇလီႇၼီႇယႅမ်ႇ" },
[35] = { wplink = "ပရူဝ်ႇမိၼ်ႇ", name = "ပရူဝ်ႇမိၼ်ႇ" },
[36] = { wplink = "ၶရိပ်ႉတွၼ်ႇ", name = "ၶရိပ်ႉတွၼ်ႇ" },
[37] = { wplink = "ရူႇပီႇတီႇယႅမ်ႇ", name = "ရူႇပီႇတီႇယႅမ်ႇ" },
[38] = { wplink = "သထရွၼ်ႇတီႇယႅမ်ႇ", name = "သထရွၼ်ႇတီႇယႅမ်ႇ" },
[39] = { wplink = "ဢိတ်ႉထရီႇယႅမ်ႇ", name = "ဢိတ်ႉထရီႇယႅမ်ႇ" },
[40] = { wplink = "ၸိူဝ်ႇၶူဝ်ႇၼီႇယႅမ်ႇ", name = "ၸိူဝ်ႇၶူဝ်ႇၼီႇယႅမ်ႇ" },
[41] = { wplink = "ၼၢႆႇဢူဝ်ႇပီႇယႅမ်ႇ", name = "ၼၢႆႇဢူဝ်ႇပီႇယႅမ်ႇ" },
[42] = { wplink = "မူဝ်ႇလိပ်ႉတီႇၼႅမ်ႇ", name = "မူဝ်ႇလိပ်ႉတီႇၼႅမ်ႇ" },
[43] = { wplink = "ထႅတ်ႉၼီႇသျီႇယႅမ်ႇ", name = "ထႅတ်ႉၼီႇသျီႇယႅမ်ႇ" },
[44] = { wplink = "ရူႇထီးၼီႇယႅမ်ႇ", name = "ရူႇထီးၼီႇယႅမ်ႇ" },
[45] = { wplink = "ရူဝ်ႇတီႇယႅမ်ႇ", name = "ရူဝ်ႇတီႇယႅမ်ႇ" },
[46] = { wplink = "ပႄႇလေႇတီႇယႅမ်ႇ", name = "ပႄႇလေႇတီႇယႅမ်ႇ" },
[47] = { wplink = "သေးလ်ဝႃႇ", name = "သေးလ်ဝႃႇ" },
[48] = { wplink = "ၶႄႇတီႇယႅမ်ႇ", name = "ၶႄႇတီႇယႅမ်ႇ" },
[49] = { wplink = "ဢိၼ်ႇတီႇယႅမ်ႇ", name = "ဢိၼ်ႇတီႇယႅမ်ႇ" },
[50] = { wplink = "တိၼ်ႇ", name = "တိၼ်ႇ" },
[51] = { wplink = "ဢႅၼ်ႇတီႇမူဝ်ႇၼီႇ", name = "ဢႅၼ်ႇတီႇမူဝ်ႇၼီႇ" },
[52] = { wplink = "တႄႇလူႇရီႇယႅမ်ႇ", name = "တႄႇလူႇရီႇယႅမ်ႇ" },
[53] = { wplink = "ဢၢႆႇဢူဝ်ႇတိၼ်း", name = "ဢၢႆႇဢူဝ်ႇတိၼ်း" },
[54] = { wplink = "သီးၼွၼ်ႇ", name = "သီးၼွၼ်ႇ" },
[55] = { wplink = "သီးသီႇယႅမ်ႇ", name = "သီးသီႇယႅမ်ႇ" },
[56] = { wplink = "ပႄႇရီႇယႅမ်ႇ", name = "ပႄႇရီႇယႅမ်ႇ" },
[57] = { wplink = "လႅၼ်းထၼႅမ်ႇ", name = "လႅၼ်းထၼႅမ်ႇ" },
[58] = { wplink = "သီးရီႇယႅမ်ႇ", name = "သီးရီႇယႅမ်ႇ" },
[59] = { wplink = "ၽရႃႇသီႇယူဝ်ႇတီႇယႅမ်ႇ", name = "ၽရႃႇသီႇယူဝ်ႇတီႇယႅမ်ႇ" },
[60] = { wplink = "ၼီႇဢူဝ်ႇတီႇယႅမ်ႇ", name = "ၼီႇဢူဝ်ႇတီႇယႅမ်ႇ" },
[61] = { wplink = "ၽရူဝ်ႇမီးထီးယႅမ်ႇ", name = "ၽရူဝ်ႇမီးထီးယႅမ်ႇ" },
[62] = { wplink = "သႃႇမေးရီႇယႅမ်ႇ", name = "သႃႇမေးရီႇယႅမ်ႇ" },
[63] = { wplink = "ယူႇရူဝ်ႇပီႇယႅမ်ႇ", name = "ယူႇရူဝ်ႇပီႇယႅမ်ႇ" },
[64] = { wplink = "ၵတ်ႉတူဝ်ႇလီႇၼီႇယႅမ်ႇ", name = "ၵတ်ႉတူဝ်ႇလီႇၼီႇယႅမ်ႇ" },
[65] = { wplink = "ထႃႇပီႇယႅမ်ႇ", name = "ထႃႇပီႇယႅမ်ႇ" },
[66] = { wplink = "တၢႆးသ်ပရူဝ်ႇသီႇယႅမ်ႇ", name = "တၢႆးသ်ပရူဝ်ႇသီႇယႅမ်ႇ" },
[67] = { wplink = "ႁူဝ်းမီႇယႅမ်ႇ", name = "ႁူဝ်းမီႇယႅမ်ႇ" },
[68] = { wplink = "ဢႃးပီႇယႅမ်ႇ", name = "ဢႃးပီႇယႅမ်ႇ" },
[69] = { wplink = "ထူႇလီႇယႅမ်ႇ", name = "ထူႇလီႇယႅမ်ႇ" },
[70] = { wplink = "ဢိတ်ႉတႃႇပီႇယႅမ်ႇ", name = "ဢိတ်ႉတႃႇပီႇယႅမ်ႇ" },
[71] = { wplink = "လူႇထီးသျီႇယႅမ်ႇ", name = "လူႇထီးသျီႇယႅမ်ႇ" },
[72] = { wplink = "ႁႅပ်ႉၾ်ၼီႇယႅမ်ႇ", name = "ႁႅပ်ႉၾ်ၼီႇယႅမ်ႇ" },
[73] = { wplink = "တႅၼ်ႇတလႅမ်ႇ", name = "တႅၼ်ႇတလႅမ်ႇ" },
[74] = { wplink = "ထၢပ်ႉသ်တႅၼ်ႇ ", name = "ထၢပ်ႉသ်တႅၼ်ႇ " },
[75] = { wplink = "ရီးၼီႇယႅမ်ႇ", name = "ရီးၼီႇယႅမ်ႇ" },
[76] = { wplink = "ဢွတ်ႉသ်မီႇယႅမ်ႇ", name = "ဢွတ်ႉသ်မီႇယႅမ်ႇ" },
[77] = { wplink = "ဢီႇရီႇတီႇယႅမ်ႇ", name = "ဢီႇရီႇတီႇယႅမ်ႇ" },
[78] = { wplink = "ၽလႅတ်ႉတိၼ်ႇၼႅမ်ႇ", name = "ၽလႅတ်ႉတိၼ်ႇၼႅမ်ႇ" },
[79] = { wplink = "ၶမ်း", name = "ၶမ်း" },
[80] = { wplink = "မႃႇၵျူႇရီႇ (ၶူဝ်းထၢတ်ႈ)", name = "မႃႇၵျူႇရီႇ" },
[81] = { wplink = "တႅတ်ႉလီႇယႅမ်ႇ", name = "တႅတ်ႉလီႇယႅမ်ႇ" },
[82] = { wplink = "ၸိုၼ်း", name = "ၸိုၼ်း" },
[83] = { wplink = "ပိတ်ႉသ်မတ်ႉထ်", name = "ပိတ်ႉသ်မတ်ႉထ်" },
[84] = { wplink = "ၽူဝ်ႇလူဝ်ႇၼီႇယႅမ်ႇ", name = "ၽူဝ်ႇလူဝ်ႇၼီႇယႅမ်ႇ" },
[85] = { wplink = "ဢႅတ်ႉသ်တႃႇတီၼ်ႇ", name = "ဢႅတ်ႉသ်တႃႇတီၼ်ႇ" },
[86] = { wplink = "ရေးတွၼ်ႇ", name = "ရေးတွၼ်ႇ" },
[87] = { wplink = "ၾရၢၼ်ႇသျီႇယႅမ်ႇ", name = "ၾရၢၼ်ႇသျီႇယႅမ်ႇ" },
[88] = { wplink = "ရေးတီႇယႅမ်ႇ", name = "ရေးတီႇယႅမ်ႇ" },
[89] = { wplink = "ဢႅၵ်ႉတိၼ်ႇၼီႇယႅမ်ႇ", name = "ဢႅၵ်ႉတိၼ်ႇၼီႇယႅမ်ႇ" },
[90] = { wplink = "ထူဝ်ႇရီႇယႅမ်ႇ", name = "ထူဝ်ႇရီႇယႅမ်ႇ" },
[91] = { wplink = "ပရူဝ်ႇတႅၵ်ႉတိၼ်ႇၼီႇယႅမ်ႇ", name = "ပရူဝ်ႇတႅၵ်ႉတိၼ်ႇၼီႇယႅမ်ႇ" },
[92] = { wplink = "ယူႇရေးၼီႇယႅမ်ႇ", name = "ယူႇရေးၼီႇယႅမ်ႇ" },
[93] = { wplink = "ၼႅပ်ႉတုၼ်ႇၼီႇယႅမ်ႇ", name = "ၼႅပ်ႉတုၼ်ႇၼီႇယႅမ်ႇ" },
[94] = { wplink = "ၽလူႇတူဝ်ႇၼီႇယႅမ်ႇ", name = "ၽလူႇတူဝ်ႇၼီႇယႅမ်ႇ" },
[95] = { wplink = "ဢမႄႇရီႇသျီႇယႅမ်ႇ", name = "ဢမႄႇရီႇသျီႇယႅမ်ႇ" },
[96] = { wplink = "ၵျူႇရီႇယႅမ်ႇ", name = "ၵျူႇရီႇယႅမ်ႇ" },
[97] = { wplink = "ပႃႇၶီႇလီႇယႅမ်ႇ", name = "ပႃႇၶီႇလီႇယႅမ်ႇ" },
[98] = { wplink = "ၵႄႇလီႇၾူဝ်းၼီႇယႅမ်ႇ", name = "ၵႄႇလီႇၾူဝ်းၼီႇယႅမ်ႇ" },
[99] = { wplink = "ဢၢႆႇသတၢႆႇၼီႇယႅမ်ႇ", name = "ဢၢႆႇသတၢႆႇၼီႇယႅမ်ႇ" },
[100] = { wplink = "ၾႃႇမီႇယႅမ်ႇ", name = "ၾႃႇမီႇယႅမ်ႇ" },
[101] = { wplink = "မႅၼ်ႇတႄႇလီႇဝီႇယႅမ်ႇ", name = "မႅၼ်ႇတႄႇလီႇဝီႇယႅမ်ႇ" },
[102] = { wplink = "ၼူဝ်ႇပႄႇလီႇယႅမ်ႇ", name = "ၼူဝ်ႇပႄႇလီႇယႅမ်ႇ" },
[103] = { wplink = "လေႃးရႅၼ်းသျီႇယႅမ်ႇ", name = "လေႃးရႅၼ်းသျီႇယႅမ်ႇ" },
[104] = { wplink = "ရၢတ်ႉထႃႇၾူဝ်ႇတီႇယႅမ်ႇ", name = "ရၢတ်ႉထႃႇၾူဝ်ႇတီႇယႅမ်ႇ" },
[105] = { wplink = "တပ်ႉၼီႇယႅမ်ႇ", name = "တပ်ႉၼီႇယႅမ်ႇ" },
[106] = { wplink = "သီးပေႃးၵီႇယႅမ်ႇ", name = "သီးပေႃးၵီႇယႅမ်ႇ" },
[107] = { wplink = "ပူဝ်ႇရီႇယႅမ်ႇ", name = "ပူဝ်ႇရီႇယႅမ်ႇ" },
[108] = { wplink = "ႁႅတ်ႉသီႇယႅမ်ႇ", name = "ႁႅတ်ႉသီႇယႅမ်ႇ" },
[109] = { wplink = "မၢႆႉၼႄႇရီႇယႅမ်ႇ", name = "မၢႆႉၼႄႇရီႇယႅမ်ႇ" },
[110] = { wplink = "တၢၼ်းသတႅတ်ႉတီႇယႅမ်ႇ", name = "တၢၼ်းသတႅတ်ႉတီႇယႅမ်ႇ" },
[111] = { wplink = "ရႅၼ်ႉၵျႅၼ်ႇၼီႇယႅမ်ႇ", name = "ရႅၼ်ႉၵျႅၼ်ႇၼီႇယႅမ်ႇ" },
[112] = { wplink = "ၵူဝ်ႇပႃႇၼီႇသျီႇယႅမ်ႇ", name = "ၵူဝ်ႇပႃႇၼီႇသျီႇယႅမ်ႇ" },
[113] = { wplink = "ၼီႇႁူဝ်ႇၼီႇယႅမ်ႇ", name = "ၼီႇႁူဝ်ႇၼီႇယႅမ်ႇ" },
[114] = { wplink = "ၾလႄႇရူဝ်ႇဝီႇယႅမ်ႇ", name = "ၾလႄႇရူဝ်ႇဝီႇယႅမ်ႇ" },
[115] = { wplink = "မူဝ်ႇသၵူဝ်ႇဝီႇယႅမ်ႇ", name = "မူဝ်ႇသၵူဝ်ႇဝီႇယႅမ်ႇ" },
[116] = { wplink = "လိဝ်ႇၾႃႇမူဝ်ႇရီႇယႅမ်ႇ", name = "လိဝ်ႇၾႃႇမူဝ်ႇရီႇယႅမ်ႇ" },
[117] = { wplink = "တႅၼ်ႇၼႄႇသိၼ်း", name = "တႅၼ်ႇၼႄႇသိၼ်း" },
[118] = { wplink = "ဢူဝ်ႇၵႃႇၼႄႇသၼ်ႇ", name = "ဢူဝ်ႇၵႃႇၼႄႇသၼ်ႇ" },
}
export.systematic_naming = true
return export
cwzu64toc8yw5dgtrng1dgdx62cx6sx
ထႅမ်းပလဵတ်ႉ:chemical element box
10
54841
260387
2026-04-29T12:28:07Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "{{#invoke:chemical element list|show_box}}<noinclude>{{documentation}}</noinclude>"
260387
wikitext
text/x-wiki
{{#invoke:chemical element list|show_box}}<noinclude>{{documentation}}</noinclude>
j0ykbtt4d76o2kojarvondbmyxzfxfk
မေႃႇၵျူး:chemical element list
828
54842
260388
2026-04-29T12:29:15Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "local export = {} local M = require("Module:module loader").init({ require = { links = "Module:links", string_utilities = "Module:string utilities", table = "Module:table", qualifier = "Module:qualifier", gender_and_number = "Module:gender and number", parameters = "Module:parameters", }, loadData = { common_elements_data = "Module:chemical element list/data/common", }, }) local function common_e..."
260388
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "Name",
atomic_number_caption = "Atomic number %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "Period", full_label = "Period" },
{ key = "group", label = "Group", full_label = "Group" },
{ key = "block", label = "Block", full_label = "Block" },
{ key = "element_class", label = "Class", full_label = "Element class" },
},
previous = "Previous: ",
next = "Next: ",
appendix_list_title = "Chemical elements in %s",
header_appendix_link = "[[Appendix:%s|Chemical element]]",
header_generic = "[[chemical element|Chemical element]]",
wikipedia_footer_portal = "[[w:%s:|%s Wikipedia]]",
wikipedia_footer_article_on = "article on ",
edit_link_label = "edit",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "Alternative names",
collapsible_expand = "show",
collapsible_collapse = "hide",
classification_data_heading = "Classification data",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "Halogens",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "Halogens",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName()) .. " " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
}
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
jk40hl4wgx9qgm1gau32j2og3d9k8qk
260394
260388
2026-04-30T00:17:25Z
Saimawnkham
9
ဢၢပ်ႉတဵတ်ႉၶေႃႈမုၼ်း
260394
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "Period", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "Group", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "Block", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "Class", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် တီႈ ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "Halogens",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "Halogens",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName()) .. " " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
}
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
doetw3bn8ak0q79oljus7fz746kjp8c
260395
260394
2026-04-30T00:18:41Z
Saimawnkham
9
260395
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် တီႈ ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "Halogens",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "Halogens",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName()) .. " " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
}
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
0vm1gsj4myhtdjnork827hg6zic84bt
260396
260395
2026-04-30T00:28:34Z
Saimawnkham
9
260396
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "Halogens",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "Halogens",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. "တီႈ"
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
52kmegbvau0v3el0xiw5kao6o1pqgw7
260397
260396
2026-04-30T00:29:11Z
Saimawnkham
9
260397
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "Halogens",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "Halogens",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. "တီႈ" ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
qka7328w3z5syekw0jeosn6eocbvjaa
260398
260397
2026-04-30T00:29:51Z
Saimawnkham
9
260398
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "Halogens",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "Halogens",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. " တီႈ " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
5gobyzlkdt46voi9h9qnci5xpcfkmo9
260400
260398
2026-04-30T01:58:12Z
Saimawnkham
9
ဢၢပ်ႉတဵတ်ႉၶေႃႈမုၼ်း
260400
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("Period %d elements"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("Group %d elements"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add(upper(block_name) .. "-block elements")
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. " တီႈ " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "Chemical elements")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
69uvsaavv7g8u7djr0rnn36mfakq4yg
260401
260400
2026-04-30T02:02:43Z
Saimawnkham
9
ဢၢပ်ႉတဵတ်ႉၶေႃႈမုၼ်း
260401
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "-block",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("ထၢတ်ႈငဝ်ႈ ထႅဝ်ၼွၼ်း %d"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("ထၢတ်ႈငဝ်ႈ ထႅဝ်တင်ႈ %d"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add("ၸုမ်းထၢတ်ႈငဝ်ႈ-"..upper(block_name))
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "-block"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = normalized .. block_suffix
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. " တီႈ " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "ထၢတ်ႈငဝ်ႈ")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
rgf0eq6whop9dbsarjb5g54imgivl5h
260402
260401
2026-04-30T02:05:26Z
Saimawnkham
9
260402
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "ၸုမ်း-",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["halogen"] = {
label = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("ထၢတ်ႈငဝ်ႈ ထႅဝ်ၼွၼ်း %d"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("ထၢတ်ႈငဝ်ႈ ထႅဝ်တင်ႈ %d"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add("ၸုမ်းထၢတ်ႈငဝ်ႈ-"..upper(block_name))
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "ၸုမ်း-"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = block_suffix .. normalized
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. " တီႈ " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "ထၢတ်ႈငဝ်ႈ")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
18ymp5u8pbezry4ya6j3doicldiyast
260403
260402
2026-04-30T02:06:00Z
Saimawnkham
9
ဢၢပ်ႉတဵတ်ႉၶေႃႈမုၼ်း
260403
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
links = "Module:links",
string_utilities = "Module:string utilities",
table = "Module:table",
qualifier = "Module:qualifier",
gender_and_number = "Module:gender and number",
parameters = "Module:parameters",
},
loadData = {
common_elements_data = "Module:chemical element list/data/common",
},
})
local function common_element_row_with_symbol(atomic_number)
local el = M.common_elements_data and M.common_elements_data.elements
local row = el and el[atomic_number]
if type(row) == "table" and type(row.symbol) == "string" and row.symbol ~= "" then
return row
end
return nil
end
local concat = table.concat
local insert = table.insert
local lower = string.lower
local upper = string.upper
local UI_STRINGS = {
default_name_display = "ၸိုဝ်ႈ",
atomic_number_caption = "မၢႆဢတေႃးမိၵ်ႉ %s",
block_suffix = "ၸုမ်း-",
classification_fields = {
{ key = "period", label = "ထႅဝ်ၼွၼ်း", full_label = "ထႅဝ်ၼွၼ်း" },
{ key = "group", label = "ထႅဝ်တင်ႈ", full_label = "ထႅဝ်တင်ႈ" },
{ key = "block", label = "ၸုမ်း", full_label = "ၸုမ်းထၢတ်ႈၸွမ်းၸၼ်ႉႁႅင်း" },
{ key = "element_class", label = "မဵဝ်း", full_label = "မဵဝ်းထၢတ်ႈငဝ်ႈ" },
},
previous = "ပူၼ်ႉမႃး: ",
next = "တေမႃး: ",
appendix_list_title = "ထၢတ်ႈငဝ်ႈ တီႈ %s",
header_appendix_link = "[[Appendix:%s|ထၢတ်ႈငဝ်ႈ]]",
header_generic = "[[:en:chemical element|ထၢတ်ႈငဝ်ႈ]]",
wikipedia_footer_portal = "[[w:%s:|ဝီႇၶီႇၽီးတီးယႃး%s]]",
wikipedia_footer_article_on = "လိၵ်ႈႁွမ်တွမ် ",
edit_link_label = "ထတ်း",
legacy_systematic_name_label = "Former IUPAC systematic name",
alternative_names_heading = "ၸိုဝ်ႈတၢင်ႇဢၼ်",
collapsible_expand = "ၼႄ",
collapsible_collapse = "သိူင်ႇ",
classification_data_heading = "ၵၢၼ်ၸႅၵ်ႇမဵဝ်း ၶေႃႈမုၼ်း",
}
local default_name_types = {
{ key = "name", display = UI_STRINGS.default_name_display },
}
function export.get_data_module_name(langcode)
return "Module:chemical element list/data/" .. langcode
end
local function normalize_atomic_number(value)
if not value then
return nil
end
value = tostring(value):gsub(",", "")
if not value:find("^%d+$") then
return nil
end
return tostring(tonumber(value))
end
local function normalize_symbol(value)
if not value or value == "" then
return nil
end
local symbol = tostring(value)
return upper(symbol:sub(1, 1)) .. lower(symbol:sub(2))
end
local EXTENDED_DIGIT_DATA = {
["0"] = { symbol = "n", name = "nil" },
["1"] = { symbol = "u", name = "un" },
["2"] = { symbol = "b", name = "bi" },
["3"] = { symbol = "t", name = "tri" },
["4"] = { symbol = "q", name = "quad" },
["5"] = { symbol = "p", name = "pent" },
["6"] = { symbol = "h", name = "hex" },
["7"] = { symbol = "s", name = "sept" },
["8"] = { symbol = "o", name = "oct" },
["9"] = { symbol = "e", name = "enn" },
}
local DEFAULT_SYSTEMATIC_ELISIONS = {
{ "iium$", "ium" },
{ "ennnil", "ennil" },
}
local function build_systematic_maps(systematic_config)
local config = systematic_config or {}
local digit_data = config.digit_data
if type(digit_data) ~= "table" then
digit_data = {}
for digit, data in pairs(EXTENDED_DIGIT_DATA) do
digit_data[digit] = data
end
end
local symbol_digits = {}
local name_digits = {}
local symbol_reverse_digits = {}
for digit, data in pairs(digit_data) do
local symbol = data and data.symbol
local name = data and data.name
if symbol and name then
symbol_digits[digit] = symbol
name_digits[digit] = name
symbol_reverse_digits[symbol] = digit
end
end
return symbol_digits, name_digits, symbol_reverse_digits
end
local function build_systematic_symbol_from_number(atomic_number, systematic_config)
local symbol_digits = build_systematic_maps(systematic_config)
local symbol_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local symbol_part = symbol_digits[digit]
if not symbol_part then
return nil
end
insert(symbol_parts, symbol_part)
end
if #symbol_parts == 0 then
return nil
end
symbol_parts[1] = upper(symbol_parts[1])
return concat(symbol_parts)
end
local function get_extended_symbol(atomic_number, systematic_config)
return build_systematic_symbol_from_number(atomic_number, systematic_config)
end
local function build_systematic_name_from_number(atomic_number, systematic_config)
local _, name_digits = build_systematic_maps(systematic_config)
local name_parts = {}
for digit in tostring(atomic_number):gmatch("%d") do
local name_part = name_digits[digit]
if not name_part then
return nil
end
insert(name_parts, name_part)
end
if #name_parts == 0 then
return nil
end
local suffix = systematic_config and systematic_config.suffix or "ium"
local name = concat(name_parts) .. suffix
-- IUPAC elisions for temporary systematic names.
local elisions = systematic_config and systematic_config.elisions
if systematic_config and systematic_config.replace_default_elisions and type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
else
for _, rule in ipairs(DEFAULT_SYSTEMATIC_ELISIONS) do
local pattern = rule[1]
local repl = rule[2] or ""
name = name:gsub(pattern, repl)
end
if type(elisions) == "table" then
for _, rule in ipairs(elisions) do
local pattern = rule and rule[1]
local repl = rule and rule[2] or ""
if pattern then
name = name:gsub(pattern, repl)
end
end
end
end
return name
end
local function get_extended_name(atomic_number, systematic_config)
if common_element_row_with_symbol(atomic_number) then
return nil
end
return build_systematic_name_from_number(atomic_number, systematic_config)
end
local function parse_extended_symbol_to_number(symbol, systematic_config)
if type(symbol) ~= "string" or symbol == "" then
return nil
end
local _, _, symbol_reverse_digits = build_systematic_maps(systematic_config)
local digits = {}
for char in lower(symbol):gmatch(".") do
local digit = symbol_reverse_digits[char]
if not digit then
return nil
end
insert(digits, digit)
end
if #digits == 0 then
return nil
end
local normalized = normalize_atomic_number(concat(digits))
if not normalized then
return nil
end
local number = tonumber(normalized)
if not number or common_element_row_with_symbol(number) then
return nil
end
return normalized
end
local function parse_systematic_name_to_number(name, systematic_config)
if type(name) ~= "string" or name == "" then
return nil
end
local normalized_name = lower(name):gsub("[%s%-]", "")
for number = 1, 999 do
if not common_element_row_with_symbol(number) then
local ext = get_extended_name(number, systematic_config)
if ext and ext == normalized_name then
return tostring(number)
end
end
end
return nil
end
-- Legacy temporary IUPAC names/symbols (e.g. ununoctium/Uuo) should resolve
-- to official elements when those atomic numbers already exist in the dataset.
local function parse_legacy_systematic_alias_to_number(value, systematic_config)
if type(value) ~= "string" or value == "" then
return nil
end
local normalized_value = lower(value):gsub("[%s%-]", "")
for number = 100, 999 do
local name = build_systematic_name_from_number(number, systematic_config)
if name and lower(name) == normalized_value then
return tostring(number)
end
end
local normalized_symbol = normalize_symbol(value)
for number = 100, 999 do
local symbol = build_systematic_symbol_from_number(number, systematic_config)
if symbol and symbol == normalized_symbol then
return tostring(number)
end
end
return nil
end
local function get_systematic_config(m_data, langcode)
local systematic_naming = m_data and m_data.systematic_naming
if systematic_naming == true then
return {}
end
if type(systematic_naming) == "table" then
if systematic_naming.enabled == false then
return nil
end
return systematic_naming
end
return nil
end
function export.get_universal_symbol(atomic_number)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
local number = tonumber(normalized_number)
local row = common_element_row_with_symbol(number)
if row then
return row.symbol
end
return get_extended_symbol(number, nil)
end
function export.get_systematic_element_name(atomic_number, systematic_naming)
local normalized_number = normalize_atomic_number(atomic_number)
if not normalized_number then
return nil
end
return get_extended_name(tonumber(normalized_number), systematic_naming)
end
local function get_element_symbol(element, atomic_number)
local symbol = type(element) == "table" and normalize_symbol(element.symbol) or nil
if symbol then
return symbol
end
return export.get_universal_symbol(atomic_number)
end
-- Parse a form with modifiers.
function export.parse_form_and_modifiers(form_with_modifiers)
local formobj = {}
local form = form_with_modifiers
while true do
local new_form, angle_bracketed = form:match("^(.-)(%b<>)$")
if not new_form then
break
end
local prefix, content = angle_bracketed:match("^<(%w+):(.+)>$")
if not prefix then
break
end
if prefix == "tag" then
formobj.tag = formobj.tag or {}
insert(formobj.tag, content)
elseif prefix == "q" or prefix == "qq" or prefix == "tr" or prefix == "link" or prefix == "id" or prefix == "g" or prefix == "alt" then
if formobj[prefix] then
error(("Duplicate modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
formobj[prefix] = content
else
error(("Unrecognized modifier '%s' in data module form: %s"):format(prefix, form_with_modifiers))
end
form = new_form
end
formobj.form = form
return formobj
end
local function split_form_variants(form)
if type(form) ~= "string" then
return {}
end
if not form:find("//", nil, true) then
return { form }
end
local forms = M.links.split_on_slashes(form)
if type(forms) ~= "table" or #forms == 0 then
return { form }
end
return forms
end
local function form_matches_pagename(form, pagename, lang)
for _, variant in ipairs(split_form_variants(form)) do
if lang:stripDiacritics(M.links.remove_links(variant)) == pagename then
return true
end
end
return false
end
local function form_equals_pagename(formobj, pagename, lang)
if formobj.link == pagename then
return true
end
if form_matches_pagename(formobj.form, pagename, lang) then
return true
end
if formobj.alt and form_matches_pagename(formobj.alt, pagename, lang) then
return true
end
return false
end
local function get_symbol_to_number_map(m_data)
if type(m_data._symbol_to_number_cache) == "table" then
return m_data._symbol_to_number_cache
end
local map = {}
local explicit_map = m_data.symbol_to_number or m_data.symbols
if type(explicit_map) == "table" then
for symbol, number in pairs(explicit_map) do
local normalized_symbol = normalize_symbol(symbol)
local normalized_number = normalize_atomic_number(number)
if normalized_symbol and normalized_number then
map[normalized_symbol] = normalized_number
end
end
end
-- Auto-derive any missing mappings from the elements table.
for atomic_number, element in pairs(m_data.elements or {}) do
local normalized_number = normalize_atomic_number(atomic_number)
local symbol = get_element_symbol(element, normalized_number)
if normalized_number and symbol and not map[symbol] then
map[symbol] = normalized_number
end
end
m_data._symbol_to_number_cache = map
return map
end
local function resolve_element_data(m_data, atomic_number_or_symbol, systematic_config)
if not m_data or type(m_data.elements) ~= "table" then
return nil, nil, false
end
local normalized_number = normalize_atomic_number(atomic_number_or_symbol)
if normalized_number then
local data = m_data.elements[normalized_number] or m_data.elements[tonumber(normalized_number)]
if systematic_config and not data then
local number = tonumber(normalized_number)
local systematic_name = number and get_extended_name(number, systematic_config) or nil
if systematic_name then
data = {
name = systematic_name,
symbol = export.get_universal_symbol(number),
}
end
end
return normalized_number, data, false
end
local symbol_to_number = get_symbol_to_number_map(m_data)
local symbol = normalize_symbol(atomic_number_or_symbol)
local mapped_number = symbol and symbol_to_number[symbol] or nil
if mapped_number then
local normalized_mapped = normalize_atomic_number(mapped_number)
local data = normalized_mapped and
(m_data.elements[normalized_mapped] or m_data.elements[tonumber(normalized_mapped)]) or nil
return normalized_mapped, data, false
end
local extended_number = parse_extended_symbol_to_number(atomic_number_or_symbol, systematic_config)
if extended_number then
local data = m_data.elements[extended_number] or m_data.elements[tonumber(extended_number)]
if systematic_config and not data then
local number = tonumber(extended_number)
data = {
name = get_extended_name(number, systematic_config),
symbol = export.get_universal_symbol(number),
}
end
return extended_number, data, false
end
local legacy_number = parse_legacy_systematic_alias_to_number(atomic_number_or_symbol, systematic_config)
if legacy_number then
local data = m_data.elements[legacy_number] or m_data.elements[tonumber(legacy_number)]
return legacy_number, data, true
end
return nil, nil, false
end
local function merge_element_data(common_elements, atomic_number, element)
local common_entry = nil
local normalized_number = normalize_atomic_number(atomic_number)
if common_elements and normalized_number then
common_entry = common_elements[normalized_number] or common_elements[tonumber(normalized_number)]
end
if type(common_entry) ~= "table" then
return element
end
local merged = M.table.deepCopy(common_entry)
if type(element) == "table" then
for key, value in pairs(element) do
merged[key] = value
end
end
return merged
end
local function sorted_atomic_numbers(m_data)
local numbers = {}
for number, _ in pairs(m_data.elements or {}) do
local normalized = normalize_atomic_number(number)
if normalized then
insert(numbers, tonumber(normalized))
end
end
table.sort(numbers)
return numbers
end
local function get_next_and_prev_keys(m_data, current_atomic_number)
local current = tonumber(current_atomic_number)
if not current then
return nil, nil
end
local element = m_data.elements[current_atomic_number] or m_data.elements[current]
local next_number = element and element.next and normalize_atomic_number(element.next) or nil
local prev_number = element and element.prev and normalize_atomic_number(element.prev) or nil
if next_number and prev_number then
return next_number, prev_number
end
local numbers = sorted_atomic_numbers(m_data)
for i, number in ipairs(numbers) do
if number == current then
next_number = next_number or (numbers[i + 1] and tostring(numbers[i + 1]) or nil)
prev_number = prev_number or (numbers[i - 1] and tostring(numbers[i - 1]) or nil)
break
end
end
if not next_number then
next_number = tostring(current + 1)
end
if not prev_number and current > 1 then
prev_number = tostring(current - 1)
end
return next_number, prev_number
end
local ELEMENT_CLASS_TO_CATEGORIES = {
["alkali metal"] = {
label = "Alkali metals",
},
["alkaline earth metal"] = {
label = "Alkaline earth metals",
},
["transition metal"] = {
label = "Transition metals",
},
["post-transition metal"] = {
label = "Post-transition metals",
},
["lanthanide"] = {
label = "Lanthanide series chemical elements",
},
["actinide"] = {
label = "Actinide series chemical elements",
},
["metalloid"] = {
label = "Metalloids",
},
["ႁႄႇလူဝ်ႇၵျႅၼ်ႇ"] = {
label = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
},
["noble gas"] = {
label = "Noble gases",
},
["nonmetal"] = {
label = "Nonmetals",
},
}
local GROUP_TO_SUBCAT = {
[13] = "Boron group elements",
[14] = "Carbon group elements",
[15] = "Pnictogens",
[16] = "Chalcogens",
[17] = "ႁႄႇလူဝ်ႇၵျႅၼ်ႇ",
[18] = "Noble gases",
}
local function get_auto_subcategories(langcode, atomic_number, m_data)
local n = tonumber(atomic_number)
if not n then
return {}
end
local subcats = {}
local seen_subcats = {}
local function add(cat_name)
if not cat_name or seen_subcats[cat_name] then
return
end
seen_subcats[cat_name] = true
insert(subcats, ("[[Category:%s:%s]]"):format(langcode, cat_name))
end
-- Optional data-driven override, keyed by atomic number: { [8] = {"Chalcogens"} }.
local by_number = m_data and m_data.subcategories_by_atomic_number
if type(by_number) == "table" and type(by_number[n]) == "table" then
for _, cat_name in ipairs(by_number[n]) do
add(cat_name)
end
return subcats
end
local common_elements = M.common_elements_data and M.common_elements_data.elements or nil
local common_entry = common_elements and (common_elements[n] or common_elements[tostring(n)]) or nil
local added_from_common = false
if type(common_entry) == "table" then
local class_key = common_entry.element_class and lower(tostring(common_entry.element_class)) or nil
local class_map = class_key and ELEMENT_CLASS_TO_CATEGORIES[class_key] or nil
local class_label = class_map and class_map.label or nil
if class_label then
add(class_label)
added_from_common = true
end
local period_number = tonumber(common_entry.period)
if period_number then
add(("ထၢတ်ႈငဝ်ႈ ထႅဝ်ၼွၼ်း %d"):format(period_number))
added_from_common = true
end
local group_number = tonumber(common_entry.group)
if group_number then
add(("ထၢတ်ႈငဝ်ႈ ထႅဝ်တင်ႈ %d"):format(group_number))
added_from_common = true
end
local group_cat = group_number and GROUP_TO_SUBCAT[group_number] or nil
if group_cat then
add(group_cat)
added_from_common = true
end
local block_name = common_entry.block and lower(tostring(common_entry.block)) or nil
if block_name and block_name:match("^[spdf]$") then
add("ၸုမ်းထၢတ်ႈငဝ်ႈ-"..upper(block_name))
added_from_common = true
end
end
if added_from_common then
return subcats
end
return subcats
end
local function lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
local matches = {}
local seen_matches = {}
local function check_form(raw_form, atomic_number, name_type)
local formobj = export.parse_form_and_modifiers(raw_form)
if form_equals_pagename(formobj, pagename, lang) and (not requested_type or requested_type == name_type) then
local normalized_number = normalize_atomic_number(atomic_number)
if normalized_number then
local key = normalized_number .. "||" .. name_type
if not seen_matches[key] then
seen_matches[key] = true
insert(matches, { normalized_number, name_type })
end
end
end
end
for atomic_number, element in pairs(m_data.elements or {}) do
for _, name_type in ipairs(name_types) do
local key = name_type.key
local value = element[key]
if value then
if type(value) == "table" then
for _, form in ipairs(value) do
check_form(form, atomic_number, key)
end
else
check_form(value, atomic_number, key)
end
end
end
end
return matches
end
local function add_name_types(name_types, additional_types)
local types = M.table.deepCopy(name_types)
for _, additional_type in ipairs(additional_types) do
insert(types, additional_type)
end
return types
end
function export.get_name_types(m_data)
if m_data.additional_name_types then
return add_name_types(default_name_types, m_data.additional_name_types)
end
return default_name_types
end
function export.display_name_type(name_type)
if name_type.display then
return name_type.display
end
return name_type.key:gsub("^.", upper):gsub("_", " ")
end
function export.format_formobj(formobj, lang)
local left_q = formobj.q and M.qualifier.format_qualifier(formobj.q) .. " " or ""
local right_q = ((formobj.g and " " .. M.gender_and_number.format_genders(M.string_utilities.split(formobj.g, ",")) or "")
.. (formobj.qq and " " .. M.qualifier.format_qualifier(formobj.qq) or ""))
local term = formobj.link or formobj.form
local alt = formobj.alt
if not alt and formobj.link then
alt = formobj.form
end
return left_q .. M.links.full_link {
lang = lang,
term = term,
alt = alt,
tr = formobj.tr,
id = formobj.id,
} .. right_q
end
local function get_name_form_links(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local linked_forms = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(linked_forms, export.format_formobj(formobj, lang))
end
end
return linked_forms
end
local function get_name_form_displays(element, lang)
local forms = element and element.name
if not forms then
return {}
end
if type(forms) ~= "table" then
forms = { forms }
end
local displays = {}
for _, form in ipairs(forms) do
if type(form) == "string" then
local formobj = export.parse_form_and_modifiers(form)
insert(displays, {
formobj = formobj,
formatted = export.format_formobj(formobj, lang),
})
end
end
return displays
end
local function format_element_label(atomic_number, element, lang, pagename, primary_name_override,
resolved_via_legacy_systematic_alias)
local symbol = get_element_symbol(element, atomic_number) or "?"
local name_displays = get_name_form_displays(element, lang)
local primary_idx = 1
if pagename then
for idx, item in ipairs(name_displays) do
if form_equals_pagename(item.formobj, pagename, lang) then
primary_idx = idx
break
end
end
end
local primary_name = #name_displays > 0 and name_displays[primary_idx].formatted or "—"
if primary_name_override and primary_name_override ~= "" then
primary_name = primary_name_override
end
local alternative_names = {}
for idx, item in ipairs(name_displays) do
if primary_name_override and primary_name_override ~= "" then
insert(alternative_names, item.formatted)
elseif idx ~= primary_idx then
insert(alternative_names, item.formatted)
end
end
local legacy_note = ""
if resolved_via_legacy_systematic_alias then
legacy_note = ('<br/><span class="chemical-element-box-legacy-systematic">%s</span>'):format(
UI_STRINGS.legacy_systematic_name_label)
end
local atomic_caption = UI_STRINGS.atomic_number_caption:format(atomic_number)
return ('<span class="chemical-element-box-symbol"><b>%s</b></span><br/>'
.. '<span class="chemical-element-box-atomic-caption">%s</span><br/>'
.. '<span class="chemical-element-box-primary-name">%s</span>%s'):format(symbol, atomic_caption, primary_name,
legacy_note),
(#alternative_names > 0 and concat(alternative_names, ", ") or nil)
end
local function get_optional_classification_fields(element)
local block_suffix = UI_STRINGS.block_suffix or "ၸုမ်း-"
local out = {}
for _, field in ipairs(UI_STRINGS.classification_fields) do
local value = element and element[field.key]
if value ~= nil and value ~= "" then
if field.key == "block" then
local normalized = lower(tostring(value))
if normalized:match("^[spdfg]$") then
value = block_suffix .. normalized
end
end
insert(out, { label = field.label, full_label = field.full_label or field.label, value = tostring(value) })
end
end
return out
end
local function render_classification_fields(classification_fields)
if not classification_fields or #classification_fields == 0 then
return nil
end
local lines = {
'<table class="chemical-element-box-classification-table">',
}
for _, field in ipairs(classification_fields) do
insert(lines, "<tr>")
insert(lines,
('<th class="chemical-element-box-classification-th" title="%s">%s</th>'):format(field.full_label, field.label))
insert(lines, ('<td class="chemical-element-box-classification-td">%s</td>'):format(field.value))
insert(lines, "</tr>")
end
insert(lines, "</table>")
return concat(lines, "\n")
end
local function format_adjacent_display(lang, element, atomic_number, direction)
if not element then
return "—"
end
local linked_forms = get_name_form_links(element, lang)
local linked_name = #linked_forms > 0 and concat(linked_forms, ", ") or
(get_element_symbol(element, atomic_number) or "?")
local arrows = direction == "prev" and "← " or direction == "next" and " →" or ""
return ("<b>%s%s (%s)%s</b>"):format(
direction == "prev" and arrows or "",
linked_name,
get_element_symbol(element, atomic_number) or "?",
direction == "next" and arrows or ""
)
end
local function add_category(lines, langcode, sort_key)
insert(lines, ("[[Category:%s:%s]]"):format(langcode, sort_key))
end
local function common_has_element_row(elements, z_num)
if type(elements) ~= "table" or not z_num then
return false
end
return elements[z_num] ~= nil or elements[tostring(z_num)] ~= nil
end
local function include_hypothetical_element_category(atomic_number_num)
local els = M.common_elements_data and M.common_elements_data.elements
return not common_has_element_row(els, atomic_number_num)
end
-- Implementation of {{chemical element box}}.
function export.show_box(frame)
local params = {
[1] = { required = true, type = "language", default = "und" },
[2] = true, -- atomic number or symbol
pagename = true,
type = true,
symbol = true,
}
local args = M.parameters.process(frame:getParent().args, params, nil, "chemical element list", "show_box")
local lang = args[1]
local langcode = lang:getCode()
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local module_name = export.get_data_module_name(langcode)
local m_data = require(module_name)
if type(m_data.elements) ~= "table" then
error(("Module '%s' must export an `elements` table."):format(module_name))
end
local name_types = export.get_name_types(m_data)
local common_elements_data = M.common_elements_data and M.common_elements_data.elements or nil
local requested_type = args.type
local atomic_number = nil
local element = nil
local resolved_via_legacy_alias = false
local systematic_config = get_systematic_config(m_data, langcode)
if args[2] then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args[2], systematic_config)
elseif args.symbol then
atomic_number, element, resolved_via_legacy_alias = resolve_element_data(m_data, args.symbol, systematic_config)
end
if element and requested_type and not element[requested_type] then
error(("The name type '%s' for element %s is not found in [[%s]]."):format(requested_type, atomic_number,
module_name))
end
if not element then
local matches = lookup_element_by_form(lang, m_data, pagename, requested_type, name_types)
if #matches == 0 then
local title = mw.title.getCurrentTitle()
if langcode == "und" and title and title.nsText == "Template" then
local numbers = sorted_atomic_numbers(m_data)
if numbers[1] then
atomic_number = tostring(numbers[1])
element = m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]
end
end
if not element and systematic_config then
local systematic_number = parse_systematic_name_to_number(pagename, systematic_config)
if systematic_number then
atomic_number, element = resolve_element_data(m_data, systematic_number, systematic_config)
end
end
if not element then
local legacy_number = parse_legacy_systematic_alias_to_number(pagename, systematic_config)
if legacy_number then
atomic_number, element = resolve_element_data(m_data, legacy_number, systematic_config)
resolved_via_legacy_alias = element ~= nil
end
end
if not element then
error(("The page name '%s' does not match any known element in [[%s]]."):format(pagename, module_name))
end
else
local unique_numbers = {}
local number_list = {}
for _, match in ipairs(matches) do
local normalized_number = normalize_atomic_number(match[1])
if normalized_number and not unique_numbers[normalized_number] then
unique_numbers[normalized_number] = true
insert(number_list, normalized_number)
end
end
if #number_list > 1 then
error(("The page name '%s' matches multiple element entries in [[%s]] (atomic numbers: %s). Please specify 2= or symbol=.")
:format(
pagename, module_name, concat(number_list, ", ")))
end
local first_match = matches[1]
atomic_number = normalize_atomic_number(first_match[1])
element = atomic_number and (m_data.elements[atomic_number] or m_data.elements[tonumber(atomic_number)]) or
nil
requested_type = requested_type or first_match[2]
end
end
if not atomic_number or not element then
error("Unable to resolve current element entry.")
end
element = merge_element_data(common_elements_data, atomic_number, element)
local formatted_forms = {}
for _, name_type in ipairs(name_types) do
local forms = element[name_type.key]
if forms then
local forms_list = type(forms) == "table" and forms or { forms }
local formatted = {}
local pagename_among_forms = false
for _, form in ipairs(forms_list) do
local formobj = export.parse_form_and_modifiers(form)
insert(formatted, export.format_formobj(formobj, lang))
if not pagename_among_forms and form_equals_pagename(formobj, pagename, lang) then
pagename_among_forms = true
requested_type = requested_type or name_type.key
end
end
local displayed_type = export.display_name_type(name_type)
if pagename_among_forms then
displayed_type = "'''" .. displayed_type .. "'''"
end
insert(formatted_forms, " ''" .. displayed_type .. "'': " .. concat(formatted, ", "))
end
end
local next_number, prev_number = get_next_and_prev_keys(m_data, atomic_number)
local next_element = nil
local prev_element = nil
if next_number then
_, next_element = resolve_element_data(m_data, next_number, systematic_config)
end
if prev_number then
_, prev_element = resolve_element_data(m_data, prev_number, systematic_config)
end
local U = UI_STRINGS
local prev_display = UI_STRINGS.previous .. format_adjacent_display(lang, prev_element, prev_number, "prev")
local next_display = UI_STRINGS.next .. format_adjacent_display(lang, next_element, next_number, "next")
local primary_name_override = nil
if resolved_via_legacy_alias and type(pagename) == "string" and pagename ~= "" then
primary_name_override = export.format_formobj({ form = pagename }, lang)
end
local current_display, alternative_names_display = format_element_label(atomic_number, element, lang, pagename,
primary_name_override, resolved_via_legacy_alias)
local classification_fields = get_optional_classification_fields(element)
local classification_fields_display = render_classification_fields(classification_fields)
local appendix_name = UI_STRINGS.appendix_list_title:format(lang:getCanonicalName())
local appendix_title = mw.title.new(appendix_name, "Appendix")
local header_link = appendix_title and appendix_title:getContent()
and UI_STRINGS.header_appendix_link:format(appendix_name)
or UI_STRINGS.header_generic
local footer_line = nil
if element.wplink then
local wplink_langcode = lang:getCode()
footer_line = "| colspan=\"3\" class=\"chemical-element-box-footer\" | " ..
UI_STRINGS.wikipedia_footer_article_on ..
M.links.full_link {
lang = lang,
term = "w:" .. wplink_langcode .. ":" .. element.wplink,
alt = element.wplink,
} .. " တီႈ " ..
UI_STRINGS.wikipedia_footer_portal:format(wplink_langcode, lang:getCanonicalName())
end
local edit_link = ' <sup>(<span class="plainlinks chemical-element-box-edit-link">[' ..
tostring(mw.uri.fullUrl(module_name, { action = "edit" })) ..
" " .. UI_STRINGS.edit_link_label .. "]</span>)</sup>"
local lines = {
'{| class="chemical-element-box-wrapper chemical-element-box"',
"|-",
'! class="chemical-element-box-heading" | ' .. header_link .. edit_link,
"|-",
'| class="chemical-element-box-main" | ' .. current_display,
}
if alternative_names_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-alt-names" | <b>'
.. UI_STRINGS.alternative_names_heading .. "</b>: " .. alternative_names_display)
end
if classification_fields_display then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text chemical-element-box-classification-cell" | '
..
'<div class="mw-collapsible mw-collapsed" data-expandtext="' ..
UI_STRINGS.collapsible_expand .. '" data-collapsetext="' .. UI_STRINGS.collapsible_collapse .. '">'
.. '<div class="chemical-element-box-classification-title">' .. UI_STRINGS.classification_data_heading .. "</div>"
.. '<div class="mw-collapsible-content chemical-element-box-classification-body">'
.. classification_fields_display
.. "</div>"
.. "</div>")
end
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. prev_display)
insert(lines, "|-")
insert(lines, '| class="chemical-element-box-text" | ' .. next_display)
if footer_line then
insert(lines, "|-")
insert(lines,
'| class="chemical-element-box-text" | ' ..
footer_line:gsub('^| colspan="3" class="chemical%-element%-box%-footer" | ', ""))
end
insert(lines, "|}")
local atomic_number_num = tonumber(atomic_number)
local data_entry = m_data.elements[atomic_number] or (atomic_number_num and m_data.elements[atomic_number_num] or nil)
local is_systematic_fallback_element = systematic_config
and atomic_number_num
and not data_entry
and not common_element_row_with_symbol(atomic_number_num)
local title_obj = mw.title.getCurrentTitle()
if langcode ~= "und" and title_obj and title_obj.nsText ~= "Template" then
add_category(lines, langcode, "ထၢတ်ႈငဝ်ႈ")
if is_systematic_fallback_element or resolved_via_legacy_alias then
add_category(lines, langcode, "Systematic element names")
end
if is_systematic_fallback_element and include_hypothetical_element_category(atomic_number_num) then
add_category(lines, langcode, "Hypothetical chemical elements")
end
if not resolved_via_legacy_alias then
for _, subcat in ipairs(get_auto_subcategories(langcode, atomic_number, m_data)) do
insert(lines, subcat)
end
end
end
local wikitext = concat(lines, "\n")
local styles = frame:extensionTag("templatestyles", "", { src = "Template:chemical element box/style.css" })
return styles .. "\n" .. wikitext
end
return export
fr39kst6otfxa6ph5msbcvvar6rxgcp
မေႃႇၵျူး:chemical element list/data/common
828
54843
260389
2026-04-29T12:29:49Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "local export = {} -- Source (primary dataset): -- PubChem [Internet]. Bethesda (MD): National Library of Medicine (US), -- National Center for Biotechnology Information; 2004-. -- Periodic Table of Elements; [cited 2026 Apr. 24]. -- Available from: https://pubchem.ncbi.nlm.nih.gov/periodic-table/ export.elements = { [1] = { symbol = "H", period = 1, group = 1, block = "s", element_class = "nonmetal", }..."
260389
Scribunto
text/plain
local export = {}
-- Source (primary dataset):
-- PubChem [Internet]. Bethesda (MD): National Library of Medicine (US),
-- National Center for Biotechnology Information; 2004-.
-- Periodic Table of Elements; [cited 2026 Apr. 24].
-- Available from: https://pubchem.ncbi.nlm.nih.gov/periodic-table/
export.elements = {
[1] = {
symbol = "H",
period = 1,
group = 1,
block = "s",
element_class = "nonmetal",
},
[2] = {
symbol = "He",
period = 1,
group = 18,
block = "p",
element_class = "noble gas",
},
[3] = {
symbol = "Li",
period = 2,
group = 1,
block = "s",
element_class = "alkali metal",
},
[4] = {
symbol = "Be",
period = 2,
group = 2,
block = "s",
element_class = "alkaline earth metal",
},
[5] = {
symbol = "B",
period = 2,
group = 13,
block = "p",
element_class = "metalloid",
},
[6] = {
symbol = "C",
period = 2,
group = 14,
block = "p",
element_class = "nonmetal",
},
[7] = {
symbol = "N",
period = 2,
group = 15,
block = "p",
element_class = "nonmetal",
},
[8] = {
symbol = "O",
period = 2,
group = 16,
block = "p",
element_class = "nonmetal",
},
[9] = {
symbol = "F",
period = 2,
group = 17,
block = "p",
element_class = "halogen",
},
[10] = {
symbol = "Ne",
period = 2,
group = 18,
block = "p",
element_class = "noble gas",
},
[11] = {
symbol = "Na",
period = 3,
group = 1,
block = "s",
element_class = "alkali metal",
},
[12] = {
symbol = "Mg",
period = 3,
group = 2,
block = "s",
element_class = "alkaline earth metal",
},
[13] = {
symbol = "Al",
period = 3,
group = 13,
block = "p",
element_class = "post-transition metal",
},
[14] = {
symbol = "Si",
period = 3,
group = 14,
block = "p",
element_class = "metalloid",
},
[15] = {
symbol = "P",
period = 3,
group = 15,
block = "p",
element_class = "nonmetal",
},
[16] = {
symbol = "S",
period = 3,
group = 16,
block = "p",
element_class = "nonmetal",
},
[17] = {
symbol = "Cl",
period = 3,
group = 17,
block = "p",
element_class = "halogen",
},
[18] = {
symbol = "Ar",
period = 3,
group = 18,
block = "p",
element_class = "noble gas",
},
[19] = {
symbol = "K",
period = 4,
group = 1,
block = "s",
element_class = "alkali metal",
},
[20] = {
symbol = "Ca",
period = 4,
group = 2,
block = "s",
element_class = "alkaline earth metal",
},
[21] = {
symbol = "Sc",
period = 4,
group = 3,
block = "d",
element_class = "transition metal",
},
[22] = {
symbol = "Ti",
period = 4,
group = 4,
block = "d",
element_class = "transition metal",
},
[23] = {
symbol = "V",
period = 4,
group = 5,
block = "d",
element_class = "transition metal",
},
[24] = {
symbol = "Cr",
period = 4,
group = 6,
block = "d",
element_class = "transition metal",
},
[25] = {
symbol = "Mn",
period = 4,
group = 7,
block = "d",
element_class = "transition metal",
},
[26] = {
symbol = "Fe",
period = 4,
group = 8,
block = "d",
element_class = "transition metal",
},
[27] = {
symbol = "Co",
period = 4,
group = 9,
block = "d",
element_class = "transition metal",
},
[28] = {
symbol = "Ni",
period = 4,
group = 10,
block = "d",
element_class = "transition metal",
},
[29] = {
symbol = "Cu",
period = 4,
group = 11,
block = "d",
element_class = "transition metal",
},
[30] = {
symbol = "Zn",
period = 4,
group = 12,
block = "d",
element_class = "transition metal",
},
[31] = {
symbol = "Ga",
period = 4,
group = 13,
block = "p",
element_class = "post-transition metal",
},
[32] = {
symbol = "Ge",
period = 4,
group = 14,
block = "p",
element_class = "metalloid",
},
[33] = {
symbol = "As",
period = 4,
group = 15,
block = "p",
element_class = "metalloid",
},
[34] = {
symbol = "Se",
period = 4,
group = 16,
block = "p",
element_class = "nonmetal",
},
[35] = {
symbol = "Br",
period = 4,
group = 17,
block = "p",
element_class = "halogen",
},
[36] = {
symbol = "Kr",
period = 4,
group = 18,
block = "p",
element_class = "noble gas",
},
[37] = {
symbol = "Rb",
period = 5,
group = 1,
block = "s",
element_class = "alkali metal",
},
[38] = {
symbol = "Sr",
period = 5,
group = 2,
block = "s",
element_class = "alkaline earth metal",
},
[39] = {
symbol = "Y",
period = 5,
group = 3,
block = "d",
element_class = "transition metal",
},
[40] = {
symbol = "Zr",
period = 5,
group = 4,
block = "d",
element_class = "transition metal",
},
[41] = {
symbol = "Nb",
period = 5,
group = 5,
block = "d",
element_class = "transition metal",
},
[42] = {
symbol = "Mo",
period = 5,
group = 6,
block = "d",
element_class = "transition metal",
},
[43] = {
symbol = "Tc",
period = 5,
group = 7,
block = "d",
element_class = "transition metal",
natural_occurrence = "decay",
},
[44] = {
symbol = "Ru",
period = 5,
group = 8,
block = "d",
element_class = "transition metal",
},
[45] = {
symbol = "Rh",
period = 5,
group = 9,
block = "d",
element_class = "transition metal",
},
[46] = {
symbol = "Pd",
period = 5,
group = 10,
block = "d",
element_class = "transition metal",
},
[47] = {
symbol = "Ag",
period = 5,
group = 11,
block = "d",
element_class = "transition metal",
},
[48] = {
symbol = "Cd",
period = 5,
group = 12,
block = "d",
element_class = "transition metal",
},
[49] = {
symbol = "In",
period = 5,
group = 13,
block = "p",
element_class = "post-transition metal",
},
[50] = {
symbol = "Sn",
period = 5,
group = 14,
block = "p",
element_class = "post-transition metal",
},
[51] = {
symbol = "Sb",
period = 5,
group = 15,
block = "p",
element_class = "metalloid",
},
[52] = {
symbol = "Te",
period = 5,
group = 16,
block = "p",
element_class = "metalloid",
},
[53] = {
symbol = "I",
period = 5,
group = 17,
block = "p",
element_class = "halogen",
},
[54] = {
symbol = "Xe",
period = 5,
group = 18,
block = "p",
element_class = "noble gas",
},
[55] = {
symbol = "Cs",
period = 6,
group = 1,
block = "s",
element_class = "alkali metal",
},
[56] = {
symbol = "Ba",
period = 6,
group = 2,
block = "s",
element_class = "alkaline earth metal",
},
[57] = {
symbol = "La",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[58] = {
symbol = "Ce",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[59] = {
symbol = "Pr",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[60] = {
symbol = "Nd",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[61] = {
symbol = "Pm",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
natural_occurrence = "decay",
},
[62] = {
symbol = "Sm",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[63] = {
symbol = "Eu",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[64] = {
symbol = "Gd",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[65] = {
symbol = "Tb",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[66] = {
symbol = "Dy",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[67] = {
symbol = "Ho",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[68] = {
symbol = "Er",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[69] = {
symbol = "Tm",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[70] = {
symbol = "Yb",
period = 6,
group = 3,
block = "f",
element_class = "lanthanide",
},
[71] = {
symbol = "Lu",
period = 6,
group = 3,
block = "d",
element_class = "lanthanide",
},
[72] = {
symbol = "Hf",
period = 6,
group = 4,
block = "d",
element_class = "transition metal",
},
[73] = {
symbol = "Ta",
period = 6,
group = 5,
block = "d",
element_class = "transition metal",
},
[74] = {
symbol = "W",
period = 6,
group = 6,
block = "d",
element_class = "transition metal",
},
[75] = {
symbol = "Re",
period = 6,
group = 7,
block = "d",
element_class = "transition metal",
},
[76] = {
symbol = "Os",
period = 6,
group = 8,
block = "d",
element_class = "transition metal",
},
[77] = {
symbol = "Ir",
period = 6,
group = 9,
block = "d",
element_class = "transition metal",
},
[78] = {
symbol = "Pt",
period = 6,
group = 10,
block = "d",
element_class = "transition metal",
},
[79] = {
symbol = "Au",
period = 6,
group = 11,
block = "d",
element_class = "transition metal",
},
[80] = {
symbol = "Hg",
period = 6,
group = 12,
block = "d",
element_class = "transition metal",
},
[81] = {
symbol = "Tl",
period = 6,
group = 13,
block = "p",
element_class = "post-transition metal",
},
[82] = {
symbol = "Pb",
period = 6,
group = 14,
block = "p",
element_class = "post-transition metal",
},
[83] = {
symbol = "Bi",
period = 6,
group = 15,
block = "p",
element_class = "post-transition metal",
},
[84] = {
symbol = "Po",
period = 6,
group = 16,
block = "p",
element_class = "metalloid",
natural_occurrence = "decay",
},
[85] = {
symbol = "At",
period = 6,
group = 17,
block = "p",
element_class = "halogen",
natural_occurrence = "decay",
},
[86] = {
symbol = "Rn",
period = 6,
group = 18,
block = "p",
element_class = "noble gas",
natural_occurrence = "decay",
},
[87] = {
symbol = "Fr",
period = 7,
group = 1,
block = "s",
element_class = "alkali metal",
natural_occurrence = "decay",
},
[88] = {
symbol = "Ra",
period = 7,
group = 2,
block = "s",
element_class = "alkaline earth metal",
natural_occurrence = "decay",
},
[89] = {
symbol = "Ac",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "decay",
},
[90] = {
symbol = "Th",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
},
[91] = {
symbol = "Pa",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "decay",
},
[92] = {
symbol = "U",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
},
[93] = {
symbol = "Np",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "decay",
},
[94] = {
symbol = "Pu",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "decay",
},
[95] = {
symbol = "Am",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[96] = {
symbol = "Cm",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[97] = {
symbol = "Bk",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[98] = {
symbol = "Cf",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[99] = {
symbol = "Es",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[100] = {
symbol = "Fm",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[101] = {
symbol = "Md",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[102] = {
symbol = "No",
period = 7,
group = 3,
block = "f",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[103] = {
symbol = "Lr",
period = 7,
group = 3,
block = "d",
element_class = "actinide",
natural_occurrence = "synthetic",
},
[104] = {
symbol = "Rf",
period = 7,
group = 4,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[105] = {
symbol = "Db",
period = 7,
group = 5,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[106] = {
symbol = "Sg",
period = 7,
group = 6,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[107] = {
symbol = "Bh",
period = 7,
group = 7,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[108] = {
symbol = "Hs",
period = 7,
group = 8,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[109] = {
symbol = "Mt",
period = 7,
group = 9,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[110] = {
symbol = "Ds",
period = 7,
group = 10,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[111] = {
symbol = "Rg",
period = 7,
group = 11,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[112] = {
symbol = "Cn",
period = 7,
group = 12,
block = "d",
element_class = "transition metal",
natural_occurrence = "synthetic",
},
[113] = {
symbol = "Nh",
period = 7,
group = 13,
block = "p",
element_class = "post-transition metal",
natural_occurrence = "synthetic",
},
[114] = {
symbol = "Fl",
period = 7,
group = 14,
block = "p",
element_class = "post-transition metal",
natural_occurrence = "synthetic",
},
[115] = {
symbol = "Mc",
period = 7,
group = 15,
block = "p",
element_class = "post-transition metal",
natural_occurrence = "synthetic",
},
[116] = {
symbol = "Lv",
period = 7,
group = 16,
block = "p",
element_class = "post-transition metal",
natural_occurrence = "synthetic",
},
[117] = {
symbol = "Ts",
period = 7,
group = 17,
block = "p",
element_class = "halogen",
natural_occurrence = "synthetic",
},
[118] = {
symbol = "Og",
period = 7,
group = 18,
block = "p",
element_class = "noble gas",
natural_occurrence = "synthetic",
},
}
return export
t2pytoyc3vhj3xiqyr2okwvmdc2gg2n
မေႃႇၵျူး:chemical element list/data/und
828
54844
260390
2026-04-29T12:30:46Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "local export = {} export.elements = { [1] = { symbol = "H", wplink = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ", name = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ", }, } return export"
260390
Scribunto
text/plain
local export = {}
export.elements = {
[1] = {
symbol = "H",
wplink = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ",
name = "ႁၢႆႇတရူဝ်ႇၵျိၼ်ႇ",
},
}
return export
6qsbr3hse7x5aszbwii3p5bkr029xzg
260392
260390
2026-04-29T12:33:20Z
Saimawnkham
9
260392
Scribunto
text/plain
local export = {}
export.elements = {
[1] = {
symbol = "H",
wplink = "Hydrogen",
name = "hydrogen",
},
}
return export
d9hsttpa3m020sx27onooqdj5toiuuj
မေႃႇၵျူး:chemical element list/data/en
828
54845
260391
2026-04-29T12:32:19Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "local export = {} export.elements = { [1] = { wplink = "Hydrogen", name = "hydrogen" }, [2] = { wplink = "Helium", name = "helium" }, [3] = { wplink = "Lithium", name = "lithium" }, [4] = { wplink = "Beryllium", name = "beryllium" }, [5] = { wplink = "Boron", name = "boron" }, [6] = { wplink = "Carbon", name = "carbon" }, [7] = { wplink = "Nitrogen", name = "nitrogen" }, [8] = { wplink = "Oxygen", name = "o..."
260391
Scribunto
text/plain
local export = {}
export.elements = {
[1] = { wplink = "Hydrogen", name = "hydrogen" },
[2] = { wplink = "Helium", name = "helium" },
[3] = { wplink = "Lithium", name = "lithium" },
[4] = { wplink = "Beryllium", name = "beryllium" },
[5] = { wplink = "Boron", name = "boron" },
[6] = { wplink = "Carbon", name = "carbon" },
[7] = { wplink = "Nitrogen", name = "nitrogen" },
[8] = { wplink = "Oxygen", name = "oxygen" },
[9] = { wplink = "Fluorine", name = "fluorine" },
[10] = { wplink = "Neon", name = "neon" },
[11] = { wplink = "Sodium", name = "sodium" },
[12] = { wplink = "Magnesium", name = "magnesium" },
[13] = { wplink = "Aluminium", name = "aluminium" },
[14] = { wplink = "Silicon", name = "silicon" },
[15] = { wplink = "Phosphorus", name = "phosphorus" },
[16] = { wplink = "Sulfur", name = "sulfur" },
[17] = { wplink = "Chlorine", name = "chlorine" },
[18] = { wplink = "Argon", name = "argon" },
[19] = { wplink = "Potassium", name = "potassium" },
[20] = { wplink = "Calcium", name = "calcium" },
[21] = { wplink = "Scandium", name = "scandium" },
[22] = { wplink = "Titanium", name = "titanium" },
[23] = { wplink = "Vanadium", name = "vanadium" },
[24] = { wplink = "Chromium", name = "chromium" },
[25] = { wplink = "Manganese", name = "manganese" },
[26] = { wplink = "Iron", name = "iron" },
[27] = { wplink = "Cobalt", name = "cobalt" },
[28] = { wplink = "Nickel", name = "nickel" },
[29] = { wplink = "Copper", name = "copper" },
[30] = { wplink = "Zinc", name = "zinc" },
[31] = { wplink = "Gallium", name = "gallium" },
[32] = { wplink = "Germanium", name = "germanium" },
[33] = { wplink = "Arsenic", name = "arsenic" },
[34] = { wplink = "Selenium", name = "selenium" },
[35] = { wplink = "Bromine", name = "bromine" },
[36] = { wplink = "Krypton", name = "krypton" },
[37] = { wplink = "Rubidium", name = "rubidium" },
[38] = { wplink = "Strontium", name = "strontium" },
[39] = { wplink = "Yttrium", name = "yttrium" },
[40] = { wplink = "Zirconium", name = "zirconium" },
[41] = { wplink = "Niobium", name = "niobium" },
[42] = { wplink = "Molybdenum", name = "molybdenum" },
[43] = { wplink = "Technetium", name = "technetium" },
[44] = { wplink = "Ruthenium", name = "ruthenium" },
[45] = { wplink = "Rhodium", name = "rhodium" },
[46] = { wplink = "Palladium", name = "palladium" },
[47] = { wplink = "Silver", name = "silver" },
[48] = { wplink = "Cadmium", name = "cadmium" },
[49] = { wplink = "Indium", name = "indium" },
[50] = { wplink = "Tin", name = "tin" },
[51] = { wplink = "Antimony", name = "antimony" },
[52] = { wplink = "Tellurium", name = "tellurium" },
[53] = { wplink = "Iodine", name = "iodine" },
[54] = { wplink = "Xenon", name = "xenon" },
[55] = { wplink = "Caesium", name = "caesium" },
[56] = { wplink = "Barium", name = "barium" },
[57] = { wplink = "Lanthanum", name = "lanthanum" },
[58] = { wplink = "Cerium", name = "cerium" },
[59] = { wplink = "Praseodymium", name = "praseodymium" },
[60] = { wplink = "Neodymium", name = "neodymium" },
[61] = { wplink = "Promethium", name = "promethium" },
[62] = { wplink = "Samarium", name = "samarium" },
[63] = { wplink = "Europium", name = "europium" },
[64] = { wplink = "Gadolinium", name = "gadolinium" },
[65] = { wplink = "Terbium", name = "terbium" },
[66] = { wplink = "Dysprosium", name = "dysprosium" },
[67] = { wplink = "Holmium", name = "holmium" },
[68] = { wplink = "Erbium", name = "erbium" },
[69] = { wplink = "Thulium", name = "thulium" },
[70] = { wplink = "Ytterbium", name = "ytterbium" },
[71] = { wplink = "Lutetium", name = "lutetium" },
[72] = { wplink = "Hafnium", name = "hafnium" },
[73] = { wplink = "Tantalum", name = "tantalum" },
[74] = { wplink = "Tungsten", name = "tungsten" },
[75] = { wplink = "Rhenium", name = "rhenium" },
[76] = { wplink = "Osmium", name = "osmium" },
[77] = { wplink = "Iridium", name = "iridium" },
[78] = { wplink = "Platinum", name = "platinum" },
[79] = { wplink = "Gold", name = "gold" },
[80] = { wplink = "Mercury (element)", name = "mercury" },
[81] = { wplink = "Thallium", name = "thallium" },
[82] = { wplink = "Lead", name = "lead" },
[83] = { wplink = "Bismuth", name = "bismuth" },
[84] = { wplink = "Polonium", name = "polonium" },
[85] = { wplink = "Astatine", name = "astatine" },
[86] = { wplink = "Radon", name = "radon" },
[87] = { wplink = "Francium", name = "francium" },
[88] = { wplink = "Radium", name = "radium" },
[89] = { wplink = "Actinium", name = "actinium" },
[90] = { wplink = "Thorium", name = "thorium" },
[91] = { wplink = "Protactinium", name = "protactinium" },
[92] = { wplink = "Uranium", name = "uranium" },
[93] = { wplink = "Neptunium", name = "neptunium" },
[94] = { wplink = "Plutonium", name = "plutonium" },
[95] = { wplink = "Americium", name = "americium" },
[96] = { wplink = "Curium", name = "curium" },
[97] = { wplink = "Berkelium", name = "berkelium" },
[98] = { wplink = "Californium", name = "californium" },
[99] = { wplink = "Einsteinium", name = "einsteinium" },
[100] = { wplink = "Fermium", name = "fermium" },
[101] = { wplink = "Mendelevium", name = "mendelevium" },
[102] = { wplink = "Nobelium", name = "nobelium" },
[103] = { wplink = "Lawrencium", name = "lawrencium" },
[104] = { wplink = "Rutherfordium", name = "rutherfordium" },
[105] = { wplink = "Dubnium", name = "dubnium" },
[106] = { wplink = "Seaborgium", name = "seaborgium" },
[107] = { wplink = "Bohrium", name = "bohrium" },
[108] = { wplink = "Hassium", name = "hassium" },
[109] = { wplink = "Meitnerium", name = "meitnerium" },
[110] = { wplink = "Darmstadtium", name = "darmstadtium" },
[111] = { wplink = "Roentgenium", name = "roentgenium" },
[112] = { wplink = "Copernicium", name = "copernicium" },
[113] = { wplink = "Nihonium", name = "nihonium" },
[114] = { wplink = "Flerovium", name = "flerovium" },
[115] = { wplink = "Moscovium", name = "moscovium" },
[116] = { wplink = "Livermorium", name = "livermorium" },
[117] = { wplink = "Tennessine", name = "tennessine" },
[118] = { wplink = "Oganesson", name = "oganesson" },
}
export.systematic_naming = true
return export
gujm1ijsnzrcb9it08ho7r1vlwjvgkv
ထႅမ်းပလဵတ်ႉ:chemical element box/style.css
10
54846
260393
2026-04-29T12:33:39Z
Saimawnkham
9
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "table.chemical-element-box-wrapper.chemical-element-box { display: table; width: fit-content; max-width: 100%; margin: 0.5em 0; padding: 0; box-sizing: border-box; overflow-x: auto; position: relative; float: right; clear: right; text-align: center; border-collapse: collapse; border: 1px solid var(--border-color-base); min-width: 270px; background: var(--wikt-palette-white); color: var(--color-base);..."
260393
sanitized-css
text/css
table.chemical-element-box-wrapper.chemical-element-box {
display: table;
width: fit-content;
max-width: 100%;
margin: 0.5em 0;
padding: 0;
box-sizing: border-box;
overflow-x: auto;
position: relative;
float: right;
clear: right;
text-align: center;
border-collapse: collapse;
border: 1px solid var(--border-color-base);
min-width: 270px;
background: var(--wikt-palette-white);
color: var(--color-base);
}
@media all and (max-width: 639px) {
table.chemical-element-box-wrapper.chemical-element-box {
float: none !important;
width: 100% !important;
max-width: 100%;
overflow-x: auto;
}
}
.chemical-element-box-heading {
text-align: center !important;
font-size: 85%;
letter-spacing: 0.03em;
text-transform: uppercase;
border-bottom: 1px solid var(--border-color-base);
padding: 6px 10px;
}
.chemical-element-box-edit-link {
text-transform: initial;
}
.chemical-element-box-main {
text-align: center !important;
padding: 10px 12px 8px 12px;
vertical-align: middle;
}
.chemical-element-box-symbol {
font-size: 260%;
line-height: 1;
letter-spacing: 0.02em;
}
.chemical-element-box-atomic-caption {
font-size: 90%;
color: var(--wikt-palette-grey-50);
}
.chemical-element-box-primary-name {
font-size: 115%;
}
.chemical-element-box-legacy-systematic {
display: block;
margin-top: 0.35em;
font-size: 82%;
line-height: 1.25;
color: var(--wikt-palette-grey-50);
font-style: italic;
}
.chemical-element-box-text {
text-align: left !important;
border-top: 1px solid var(--border-color-base);
padding: 6px 10px;
}
.chemical-element-box-alt-names {
font-size: 90%;
line-height: 1.35;
}
.chemical-element-box-classification-cell {
font-size: 90%;
line-height: 1.4;
}
.chemical-element-box-classification-title {
font-weight: 600;
}
.chemical-element-box-classification-body {
margin-top: 4px;
}
.chemical-element-box-footer {
text-align: center;
}
.chemical-element-box-wrapper .chemical-element-box-classification-table {
width: 100%;
border-collapse: collapse;
font-size: 90%;
line-height: 1.2;
}
.chemical-element-box-wrapper .chemical-element-box-classification-th {
text-align: left;
font-weight: 600;
padding: 1px 6px 1px 0;
white-space: nowrap;
width: 1%;
}
.chemical-element-box-wrapper .chemical-element-box-classification-td {
text-align: right;
padding: 1px 0;
word-break: break-word;
}
j6n8b21cavff72sllrjulgakppy4mpx
chlorine
0
54847
260399
2026-04-30T01:50:16Z
Sai Myo Thura Kyaw
38
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "==ဢိင်းၵလဵတ်ႈ== {{chemical element box|en}} ===သဵင်ဢွၵ်ႇ=== * {{enPR|klôʹrēn|a=GA}}, {{IPA|en|/ˈklɔɹin/}} * {{enPR|klôʹrēn|a=RP}}, {{IPA|en|/ˈklɔːɹiːn/}} * {{audio|en|LL-Q1860 (eng)-Naomi Persephone Amethyst (NaomiAmethyst)-chlorine.wav|a=GA}} * {{audio|en|en-us-chlorine.ogg|a=US}} * {{IPA|en|a=Indic|/ˈkʰlorɪn/|/ˈkʰlɔrɪn/|/-in/}} * {{rhymes|en|ɔːɹiːn|..."
260399
wikitext
text/x-wiki
==ဢိင်းၵလဵတ်ႈ==
{{chemical element box|en}}
===သဵင်ဢွၵ်ႇ===
* {{enPR|klôʹrēn|a=GA}}, {{IPA|en|/ˈklɔɹin/}}
* {{enPR|klôʹrēn|a=RP}}, {{IPA|en|/ˈklɔːɹiːn/}}
* {{audio|en|LL-Q1860 (eng)-Naomi Persephone Amethyst (NaomiAmethyst)-chlorine.wav|a=GA}}
* {{audio|en|en-us-chlorine.ogg|a=US}}
* {{IPA|en|a=Indic|/ˈkʰlorɪn/|/ˈkʰlɔrɪn/|/-in/}}
* {{rhymes|en|ɔːɹiːn|s=2}}
* {{hyph|en|chlo|rine}}
===ႁိၵ်ႈ===
{{en-noun|-|s}}
# ထၢတ်ႈၶရူဝ်ႇရိင်း။
===ၽိုၼ်ဢိင်===
# {{VPS Ref}}
cqjh9y7vvtsu4w09210wx1xl1ye5ink
260405
260399
2026-04-30T02:37:42Z
Sai Myo Thura Kyaw
38
/* ႁိၵ်ႈ */
260405
wikitext
text/x-wiki
==ဢိင်းၵလဵတ်ႈ==
{{chemical element box|en}}
===သဵင်ဢွၵ်ႇ===
* {{enPR|klôʹrēn|a=GA}}, {{IPA|en|/ˈklɔɹin/}}
* {{enPR|klôʹrēn|a=RP}}, {{IPA|en|/ˈklɔːɹiːn/}}
* {{audio|en|LL-Q1860 (eng)-Naomi Persephone Amethyst (NaomiAmethyst)-chlorine.wav|a=GA}}
* {{audio|en|en-us-chlorine.ogg|a=US}}
* {{IPA|en|a=Indic|/ˈkʰlorɪn/|/ˈkʰlɔrɪn/|/-in/}}
* {{rhymes|en|ɔːɹiːn|s=2}}
* {{hyph|en|chlo|rine}}
===ႁိၵ်ႈ===
{{en-noun|-|s}}
# ထၢတ်ႈၶလူဝ်ႇရိၼ်း။
===ၽိုၼ်ဢိင်===
# {{VPS Ref}}
4zlkz1uhj6n24d7frcpgt0lguhjynv4
chlorines
0
54848
260404
2026-04-30T02:37:29Z
Sai Myo Thura Kyaw
38
ၵေႃႇသၢင်ႈၼႃႈလိၵ်ႈဝႆႉ တင်း "==ဢိင်းၵလဵတ်ႈ== ===ႁိၵ်ႈ=== {{head|en|ပိူင်ၽၢင်ႁိၵ်ႈ}} # {{plural of|en|chlorine}} (ဢႅတ်ႇတမ်ႇ ၶွင် ၶလူဝ်ႇရိၼ်း)"
260404
wikitext
text/x-wiki
==ဢိင်းၵလဵတ်ႈ==
===ႁိၵ်ႈ===
{{head|en|ပိူင်ၽၢင်ႁိၵ်ႈ}}
# {{plural of|en|chlorine}} (ဢႅတ်ႇတမ်ႇ ၶွင် ၶလူဝ်ႇရိၼ်း)
b2d6nmxen3gosoafp0xdqut6hyyp8th