ဝိၵ်ႇသျိၼ်ႇၼရီႇ 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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 "&mdash;" 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 "&#8592;&nbsp;" or direction == "next" and "&nbsp;&#8594;" 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, " &nbsp;&nbsp;&nbsp; ''" .. 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