Module:Kangxi radical

require('strict')

local p = {}

function p.find(t, srch) -- search by value
   for k, _ in ipairs(t) do
	  if t[k] == srch then return k; end
   end
end

local labels = { -- ten per line
   "one", "line", "dot", "slash", "second", "hook", "two", "lid", "man", "legs",
   "enter", "eight", "down box", "cover", "ice", "table", "open box", "knife", "power", "wrap",
   "spoon", "right open box", "hiding enclosure", "ten", "divination", "seal", "cliff", "private", "again", "mouth",
   "enclosure", "earth", "scholar", "go", "go slowly", "evening", "big", "woman", "child", "roof",
   "inch", "small", "lame", "corpse", "sprout", "mountain", "river", "work", "oneself", "turban",
   "dry", "short thread", "dotted cliff", "long stride", "two hands", "shoot", "bow", "snout", "bristle", "step",
   "heart", "halberd", "door", "hand", "branch", "rap", "script", "dipper", "axe", "square",
   "not", "sun", "say", "moon", "tree", "lack", "stop", "death", "weapon", "do not",
   "compare", "fur", "clan", "steam", "water", "fire", "claw", "father", "double x", "half tree trunk",
   "slice", "fang", "cow", "dog", "profound", "jade", "melon", "tile", "sweet", "life",
   "use", "field", "bolt of cloth", "sickness", "dotted tent", "white", "skin", "dish", "eye", "spear",
   "arrow", "stone", "spirit", "track", "grain", "cave", "stand", "bamboo", "rice", "silk",
   "jar", "net", "sheep", "feather", "old", "and", "plow", "ear", "brush", "meat",
   "minister", "self", "arrive", "mortar", "tongue", "oppose", "boat", "stopping", "color", "grass",
   "tiger", "insect", "blood", "walk enclosure", "clothes", "west", "see", "horn", "speech", "valley",
   "bean", "pig", "badger", "shell", "red", "run", "foot", "body", "cart", "bitter",
   "morning", "walk", "city", "wine", "distinguish", "village", "gold", "long", "gate", "mound",
   "slave", "short tailed bird", "rain", "blue", "wrong", "face", "leather", "tanned leather", "leek", "sound",
   "leaf", "wind", "fly", "eat", "head", "fragrant", "horse", "bone", "tall", "hair",
   "fight", "sacrificial wine", "cauldron", "ghost", "fish", "bird", "salt", "deer", "wheat", "hemp",
   "yellow", "millet", "black", "embroidery", "frog", "tripod", "drum", "rat", "nose", "even",
   "tooth", "dragon", "turtle", "flute",
}

local variants = { -- five per line
   ["一"] = 1, ["乀"] = 2, ["乁"] = 2, ["丶"] = 3, ["丿"] = 4, ["zorro"] = 5, ["乙"] = 5, ["⺂"] = 5, ["⺃"] = 5, ["⺄"] = 5,
   ["亅"] = 6, ["二"] = 7, ["亠"] = 8, ["人"] = 9, ["亻"] = 9, ["𠂉"] = 9, ["person"] = 9, ["human"] = 9, ["儿"] = 10, ["兒"] = 10, ["児"] = 10,
   ["入"] = 11, ["丷"] = 12, ["八"] = 12,  ["冂"] = 13,  ["冖"] = 14, ["冫"] = 15, ["⺀"] = 15,
   ["几"] = 16, ["𠘧"] = 16, ["幾"] = 16, ["𠘨"] = 16, ["凵"] = 17, ["刀"] = 18, ["刂"] = 18, ["⺈"] = 18, ["力"] = 19, ["勹"] = 20,
   ["匕"] = 21, ["匚"] = 22, ["匸"] = 23, ["十"] = 24, ["卜"] = 25, ["⺊"] = 25, ["divine"] = 25,
   ["卩"] = 26, ["㔾"] = 26, ["厂"] = 27, ["⺁"] = 27, ["厶"] = 28, ["又"] = 29, ["口"] = 30,
   ["囗"] = 31, ["土"] = 32, ["士"] = 33, ["夂"] = 34, ["夊"] = 35, ["slowly"] = 35,
   ["夕"] = 36, ["大"] = 37, ["large"] = 37, ["女"] = 38, ["female"] = 38, ["子"] = 39, ["宀"] = 40,
   ["寸"] = 41, ["thumb"] = 41, ["小"] = 42, ["⺌"] = 42, ["⺍"] = 42, ["尢"] = 43, ["⺐"] = 43, ["⺎"] = 43, ["尸"] = 44, ["屮"] = 45,
   ["山"] = 46, ["hill"] = 46, ["巛"] = 47, ["巜"] = 47, ["川"] = 47, ["工"] = 48, ["己"] = 49, ["巾"] = 50,
   ["干"] = 51, ["⺓"] = 52, ["幺"] = 52, ["广"] = 53, ["廣"] = 53, ["広"] = 53, ["廴"] = 54, ["廾"] = 55,
   ["弋"] = 56, ["弓"] = 57, ["彐"] = 58, ["彑"] = 58, ["彡"] = 59, ["彳"] = 60,
   ["心"] = 61, ["忄"] = 61, ["㣺"] = 61, ["戈"] = 62, ["戶"] = 63, ["戸"] = 63, ["户"] = 63, ["手"] = 64, ["⺘"] = 64, ["扌"] = 64, ["支"] = 65,
   ["攴"] = 66, ["文"] = 67, ["斗"] = 68, ["斤"] = 69, ["方"] = 70,
   ["无"] = 71, ["無"] = 71, ["日"] = 72, ["⺜"] = 72, ["曰"] = 73, ["月"] = 74, ["⺝"] = 74, ["木"] = 75, ["wood"] = 75,
   ["欠"] = 76, ["止"] = 77, ["龰"] = 77, ["𣥂"] = 77, ["歺"] = 78, ["歹"] = 78, ["殳"] = 79, ["母"] = 80,
   ["比"] = 81, ["毛"] = 82, ["氏"] = 83, ["气"] = 84, ["氣"] = 84, ["air"] = 84, ["気"] = 84, ["水"] = 85, ["氵"] = 85, ["氺"] = 85,
   ["火"] = 86, ["灬"] = 86, ["paw"] = 87, ["nail"] = 87, ["爪"] = 87, ["⺥"] = 87, ["父"] = 88, ["爻"] = 89, ["xx"] = 89, ["爿"] = 90,
   ["片"] = 91, ["牙"] = 92, ["tooth"] = 92, ["牛"] = 93, ["牜"] = 93, ["𠂒"] = 93, ["bull"] = 93, ["犭"] = 94, ["犬"] = 94, ["玄"] = 95,
   ["玉"] = 96, ["𤣩"] = 96, ["瓜"] = 97, ["瓦"] = 98, ["甘"] = 99, ["生"] = 100,
   ["用"] = 101, ["田"] = 102, ["疋"] = 103, ["𤴔"] = 103, ["疒"] = 104, ["illness"] = 104, ["ill"] = 104, ["sick"] = 104, ["癶"] = 105,
   ["白"] = 106, ["皮"] = 107, ["皿"] = 108, ["目"] = 109, ["矛"] = 110,
   ["矢"] = 111, ["石"] = 112, ["示"] = 113, ["礻"] = 113, ["⺬"] = 113, ["禸"] = 114, ["禾"] = 115,
   ["穴"] = 116, ["立"] = 117, ["竹"] = 118, ["𥫗"] = 118, ["米"] = 119, ["糸"] = 120, ["丝"] = 120, ["糹"] = 120,
   ["缶"] = 121, ["网"] = 122, ["羊"] = 123, ["⺶"] = 123, ["羽"] = 124, ["老"] = 125,
   ["而"] = 126, ["耒"] = 127, ["耳"] = 128, ["聿"] = 129, ["肉"] = 130, ["⺼"] = 130,
   ["臣"] = 131, ["自"] = 132, ["至"] = 133, ["臼"] = 134, ["舌"] = 135,
   ["舛"] = 136, ["舟"] = 137, ["艮"] = 138, ["色"] = 139, ["colour"] = 139, ["艸"] = 140, ["艹"] = 140, ["䒑"] = 140,
   ["虍"] = 141, ["虫"] = 142, ["血"] = 143, ["行"] = 144, ["衣"] = 145, ["𧘇"] = 145, ["衤"] = 145,
   ["襾"] = 146, ["西"] = 146, ["見"] = 147, ["见"] = 147, ["⻅"] = 147,  ["角"] = 148, ["⻆"] = 148, ["言"] = 149, ["⻈"] = 149,  ["訁"] = 149,  ["谷"] = 150,
   ["豆"] = 151, ["豕"] = 152, ["豸"] = 153, ["貝"] = 154, ["贝"] = 154, ["赤"] = 155,
   ["走"] = 156, ["足"] = 157, ["𧾷"] = 157, ["身"] = 158, ["車"] = 159, ["车"] = 159, ["辛"] = 160,
   ["辰"] = 161, ["辵"] = 162, ["辶"] = 162, ["⻌"] = 162, ["⻍"] = 162, ["⻎"] = 162, ["邑"] = 163, ["⻏"] = 163, ["酉"] = 164, ["釆"] = 165,
   ["里"] = 166, ["金"] = 167, ["釒"] = 167, ["钅"] = 167, ["長"] = 168, ["长"] = 168, ["镸"] = 168, ["門"] = 169, ["⻔"] = 169, ["门"] = 169, ["阜"] = 170, ["⻖"] = 170,
   ["⾪"] = 171, ["隹"] = 172, ["雨"] = 173, ["⻗"] = 173, ["靑"] = 174, ["grue"] = 174, ["非"] = 175,
   ["面"] = 176, ["革"] = 177, ["韋"] = 178, ["韭"] = 179, ["音"] = 180,
   ["頁"] = 181, ["風"] = 182, ["风"] = 182, ["⻛"] = 182, ["飛"] = 183, ["飞"] = 183, ["食"] = 184, ["⻝"] = 184, ["飠"] = 184, ["𩙿"] = 184, ["饣"] = 184, ["首"] = 185,
   ["香"] = 186, ["馬"] = 187, ["马"] = 187, ["⻢"] = 187, ["🐎"] = 187,  ["骨"] = 188, ["⻣"] = 188, ["高"] = 189, ["髟"] = 190,
   ["鬥"] = 191,  ["鬯"] = 192, ["鬲"] = 193, ["鬼"] = 194, ["⻤"] = 194, ["魚"] = 195, ["鱼"] = 195, ["⻥"] = 195,
   ["鳥"] = 196, ["鸟"] = 196, ["⻦"] = 196, ["鹵"] = 197, ["卤"] = 197, ["⻧"] = 197, ["鹿"] = 198, ["麥"] = 199, ["麦"] = 199, ["⻨"] = 199, ["麻"] = 200,
   ["黃"] = 201, ["黄"] = 201, ["⻩"] = 201, ["黍"] = 202, ["黑"] = 203, ["黹"] = 204, ["黽"] = 205,  ["黾"] = 205,  ["⻪"] = 205,
   ["鼎"] = 206, ["鼓"] = 207, ["壴"] = 207, ["鼠"] = 208, ["鼻"] = 209, ["齊"] = 210, ["⻬"] = 210, ["齐"] = 210,
   ["齒"] = 211, ["齿"] = 211, ["⻮"] = 211, ["龍"] = 212, ["龙"] = 212,  ["⻰"] = 212, ["龜"] = 213, ["⻱"] = 213, ["龟"] = 213, ["⻳"] = 213,  ["龠"] = 214,
}

function p.Kxr(frame)
   local getArgs = require('Module:Arguments').getArgs
   return p._Kxr(getArgs(frame))
end

local function utfEscape(hex)
   return	"&#" .. hex .. ";"
end

function p.toRadicalNumber(ch)
   local codepoint = mw.ustring.codepoint(ch)
   local result = nil

   if codepoint >= 0x2F00 and codepoint <= 0x2FD5 then result = codepoint - 0x2F00 + 1
   else result = variants[ch]
   end

   if not result then result = p.find(labels, ch); end
   return result
end

function p._Kxr(args)
   local num = nil
   local add_link = false
   local add_label = args["name"] ~= "no"
   local add_numero = false
   local use_variant = false

   local glyph = ""
   local label = ""
   local result = ""

   if tonumber(args[1]) then num = math.floor(tonumber(args[1]))
   else
	  num = p.toRadicalNumber(string.lower(args[1]))
	  if args["variant"] or args["v"] then use_variant = true; end
   end
   local unicode = 0x2F00 + num - 1

   if use_variant and mw.ustring.len(args[1]) == 1 then glyph = args[1]
   else glyph = utfEscape(unicode); end

   if args["l"] or args["link"] or args["links"] then add_link = true; end

   if add_label then
	  local label_style = "\"font-variant: small-caps; text-transform: lowercase\""
	  label = string.upper(labels[num])

	  if add_link then label = "[[Radical " .. num .. "|".. label .. "]]"; end
	  label = "&emsp13;<span style=" .. label_style ..  ">'" ..  label .. "'</span>"
   end

   result = "<span lang=\"und-Hani\">" .. glyph .. "</span>" .. label
   return result
end

return p