Module:zh-forms: difference between revisions

From Wiktionary, the free dictionary
Jump to navigation Jump to search
Content deleted Content added
reduce Lua memory usage ever so slightly
move some data to a data submodule
Line 3: Line 3:
local links = require("Module:links")
local links = require("Module:links")
local lang = require("Module:languages")
local lang = require("Module:languages")
local m_data = require("Module:zh-forms/data")
local find = mw.ustring.find
local find = mw.ustring.find
local gsub = mw.ustring.gsub
local gsub = mw.ustring.gsub
Line 13: Line 14:
["both"] = "Hani",
["both"] = "Hani",
}
}

local chars_variant_both = 'しめ溼裡うらぐん羣床ゆかまもるまもる污汚ためためにせにせ炮砲麵麪やかまし諠嘩譁鄰となりせん綫眾しゅ'
local chars_variant_one = 'たい輓遊あいだ'
-- result of comparing the utf32-cn.map and utf32-tw.map files that are at https://github.com/adobe-fonts/source-han-sans/tree/release/Resources
local chars_unified = "⺽⼊⼋⼔⼣⼥⼾⽍⽐⽕⽚⽛⽠⽡⽰⽱⽳⽶⽼⽾⽿⾆⾇⾌⾝⾠⾣⾬⾮⾵⾷⾻⾿⿁⿅⿆⿇⿈⿋⿌⿏⿓⿔㑤㑦㒈㒖㒯㒼㓁㓲㕙㕯㕹㖗㖘㖨㖿㗛㗳㗾㙂㙇㙈㙎㙳㚚㚥㚪㚬㚰㚱㚵㚹㚼㛁㛃㛄㛅㛇㛈㛓㛔㛖㛡㛢㛥㛦㛵㜁㜃㜈㜊㜍㜜㜟㜣㜬㜰㜲㜳㝢㝬㞹㞾㟲㟴㟸㠗㠙㡵㢣㤆㤯㥤㥯㦀㦑㦙㦤㦾㧬㧻㨘㩞㩧㪖㫵㫶㫽㬚㬫㬹㮕㮡㮴㯄㯳㯴㱔㱕㲋㴬㴲㵆㵌㵝㵟㵢㵩㵪㵵㶈㶥㶭㶴㶿㷆㷇㷉㷌㷓㷧㷨㷫㷳㷴㷷㷼㷽㸆㸏㹃㺖㺲㻇㻐㻑㻖㻗㻢㻧㻫㻬㻰㻳㻴㻺㼀㽹㿀㿍㿭㿺䀝䁓䁘䁟䁥䁯䂨䃈䃺䄃䄒䄲䅮䅼䅿䆲䆻䆿䇛䇭䇯䇹䈑䈣䉀䉠䉪䊌䊔䊢䌊䌫䍃䎑䎗䎚䎺䎼䏁䏙䏟䏭䏰䏲䐁䐂䐓䐗䐤䐥䐭䑛䑺䒟䒠䒢䒰䒷䒽䓀䓃䓅䓎䓝䓞䓟䓡䓤䓩䓪䓫䓬䓲䓴䔃䔄䔉䔋䔖䔛䔝䔧䔮䔳䔶䔻䔽䔿䕃䕑䕒䕕䕘䕜䕢䕪䕭䕷䕸䕺䕾䖎䖓䖛䖣䖳䗚䘆䘵䙺䚄䛷䜓䜘䜶䞦䟴䟿䠴䠷䡱䢛䢭䢮䣐䣭䣮䣳䣺䤆䤑䤫䥲䧔䧩䨏䨝䨤䨵䩮䪤䪩䫿䬙䬠䬷䮐䯊䯒䯛䰁䰠䶉ななうし丕丰まる丽乖じょう乜也乬乸乿亃亇些亟亡あきら亲亹仈今仞令以仮仱仳仹任份伀伋伍伙伨伬伶伾佌てい佒佘佞佢佤佬佲佴佺佽佾侂ただし侈例さむらい侑侒わび侞侫こう侴侵侹侺侻俀しゅん俏保俞俟おさむ俳俺俿倇倏倓倕候倜倥倧倩やまと倯倰倱倷倻偀偃偈偊偌へん偕偛偞偠偡偢偤偨偫偰偶偷傀傁傂傅傒傜傝傞傦傲傺傻僄僇僈僋僎像僐僔僙僠僣僪僭僯僳僸儆儋儍儒はかな儠儦儳充兝入ぜん兪八こう兮冀冇冏かぶと冞冢决冴ひや冹冽すご凊凋しのげ凐凝凞凭凼刃分列ぶんれつ刢刱刵刹剁削ぜん剕剜剡剨剩剪剭わり剺剽劀劄劋劐劖劘つとむいさむ勓勘つの勠勥匊匎匑匒匕化きたさじ匜匧匪匴ひき匼匽匾匿卌博しるしおろし卼厎厖厜厞厦うまや厫厬げん及反叛叟叭名吒吜ぎん吡吩吪含吸吾呀呁ほけてい呎呝呢呤呧周呰呱呲呶呸咎咓咠咡咤咧咨咪咫咴咹咾哆哎哤哨哮哸哾唃唅唆唇唉唌唥唬唳唴唵唷唼唾啁啃ついばめしょう啌啖啡啨啾啿喁善喈喉ちょう喍喏喓喝喟喢喨喩喭喰喳喴喵喺喻喼喿嗂しゃがれ嗅嗋嗏嗐嗒嗓嗕嗖嗗嗘嗜嗞嗟嗡嗢嗤嗬嗲嗵嗷嗸嗼嗾嘅嘌嘐嘒嘛嘝嘬くちばし噀噂噃噆噉噊噏噒噗噙噡噢噤器噪噬噱噳噶噺噾噿嚁嚃嚄嚅嚆嚒嚓嚘嚟嚭嚯嚱嚵嚹嚾嚿囃囖囟囡囧囮囹囿圀圈圊圛圾坂坅均坋坌坒块坭坯坱坴坺坻坼坽たれ垔垛垞垵垹埁ほこり埆埈埏埐埕埝埥埦埩埭埵埶埽埾堉堎堒堔堗堙堞堠堡堣堧堨堩堪堬堰堶塈塉塌塑塔塕塛塣塭塳塶塺墁墂墈墉墍墒墓墚墟墡墣墦墫墯墴おう壉壒壖壣みずのえ壾壿夅変夌复夎夏夑夒夔夕がい夗夙夤夬ひさし奃奄奆奈ちぎり奓奕奘奚奜奝奠奥奫奱おんなやつ奵奶奷奸她奻こう奾奿妀妁如妃妄妅妉妊妍妎妏妐妒妓妔妖妗妘みょう妚妞妟妠妡妢妣妤妥妦妧妨妭妮妯妰妱妲妴妵妶妸いもうと妺妻妼妽わらわ妿姀姁姃姄姅姆姇姈姊はじめ姌姎姏姐しゅうと姒姓姖姘姚姛きょう姝姞姠姡姣姤うば姨姩ひめひめ姭姮姯姰姱姲姳姴姵姶姷姸姹姺姻姼姽姾姿すがた娀威娂娃娉娊娋娌娍娏しゃば娒娓娕娖娗娘娚娜娞娟娠娡娣娤娥娧娩娪娫娬娭娮娰娳娵娶娷娸娹娼娽娾婀婂婃婄婅婆婇婈婉婊婌婍婐婑婒婓婔婕婖婗婘婙こん婛婝婞婟婠婢婤婥婧婨婩婪婫婮婰婱婷婹婺婻婼婽婾婿媂媃媄媆媊媋媌媎媏媐媑媒媓媔媕媖媗媙こびひめ媝媞媟媠媡媢媤媥媦媩媫媬媱媲媳媴媵媶媷媸媹媺媻媾嫀嫁あによめ嫃嫄嫆嫇嫉嫊いや嫍嫎嫏嫑嫓嫕嫖嫘嫙嫚嫛嫜嫝嫞嫟嫠嫡嫣嫤嫦嫨嫩嫪嫫嫬嫭嫮嫯嫲嫳嫴嫶嫷嫸嫹嫽嫾嬁うれし嬍嬎嬏嬑嬓嬔嬕嬖嬗嬚嬛嬞嬟嬠嬥嬧嬨嬫嬬嬯嬲嬴嬼嬽嬿孀孁孅孈孊孍孏孝孥孬孮孶孷孺孽宅やすむねあてなだめがいえんよい宸寈ぐう寖寙寞察寤寥寨寱寲寺尃射じょうみこと尐尜むくいぬ尳尺あま屄屎くず屔屝ぞくくつ屧屳屸屹屺屻屼屾岆岈岉岋岌岍岏岐岑岒岓岔岞岟岠岣岤岥そわ岫岬岭岮岯岰岵岶岷岺岻峂峆峈峋峌峏峐峑峒峓峔峖峗峘峙峛峟峥峨峪峬峭峮ほう峱峵峸峹たかし峿崆たかし崋崌さき崏崕崚崛崝崞崣崤崥崦崧崨崯崰崲崳崴崷崸崹崺崼崾崿嵁嵃嵆嵈嵉嵊嵋嵎嵑嵕嵖嵞嵢嵣嵥嵧嵨嵫嵬嵯嵰嵱嵲嵳嵴嵹嵺嵻嶀嶂嶅嶆しま嶍嶒嶓嶕嶙嶜嶝嶞嶟嶫嶬嶯嶰嶱嶵嶶嶷巁巂巇巉巌たかし巏巕しゅう巟巡きょたつみ帍帑帗帘帚帟帤帨帩帮幋幔幕まんまく幞幡幧幨幪幭幯幰かそけ庀庇庈庌庐底庛庤庨庬庮庱あんかんいさお庹廆廋廌廒廖廘廛廨廰廲延异弅弈弊弎弚たゆ弡弤わたるいしゆみ弭弰彉彐彔彗彘彛つねあや彯彶彸彽彾待徎徖徘徟循徭ほろ徯忍忘忙忛忞忣忪かい忴念忸忿怇怌怏怒怓怜怟怣きゅう怨怩怵恀恁恃恅恉こいおそれじょ恝恢ほしいまま恬恮恷恾悁悄悆悉悛悜さとるゆう您悰悱悲悷悸悾惃惄情惆惋惌惔惗惘惰惵惹惼惾愀愁愈愉愍愎愒愖愚愝感愧愮愲愶すなお慀慅慌慓慕慜慝慠慢慥慦慧慨慰慵慷憀憈憋憌憝憟憡憨いこい憯憰憳憺憼憾懂懅懆懈懊懋懚懡懦懩懮懵懻懿戜戠戡戢戤戥戫戮戳戺戽戾ぼうひらた扂扃扆扇扈扉扊扒たく扡扨扭扮扱扲扳批扽承こじ抐抓抭抳抵拆拎拐こばめ拔拖拟拰拴拶拸拻ゆび挈按挓挖挨振挰挷挻挼捌捎捐捑捔捘捛捥捩捶捸捺捻捼捿掅掋掍排掕掖掞探せっひかえ掩掫きく掮掯掰揂そろい揄揆もめ描插揓揕揖揗揙揝揟揠揩揪揬揭揯揱揲揳揶揸揻搋搏搓搔搘搚搜搡搢搦搧搫搬搭搮搰搲搳搽搿摎摓摛摝摠摡摦摮摰摱摴摸摹摽撍撒撖撗撘撙撚撤撬播撮撯撰撱撼擂みさお擎擏とりこ擖擙擛擢擦擨擩擭擵擸擿攁攃攇攉攊攍攐攗攟攠攥攭敉敖きょう敜敢散けいじき斐斒斖料斛斟斢斥しんほどこせ旍旎ぞく旒旓旚旛旞旡すんですんでむね旲昀昄昅こん昈昋昐昑昝映昤昵晏晗晙晨晭晴晵晷晼暆暍暚暛暡暨暩暪暬くれ暵暹暽曁曌曔曘曚曜曣曤曰曷曼かえさい朁朂朅有朎朔ちん朘朙もち朠朡朦朳朵朼杋李あんず杒杗杝条もく杧杰杲杳杻松ばん极枃枇枌枍枔枘枲柂柃柅柋柍某柒染やわら柜柝柢查柧柭柰柴柸柼とちせん栔栗栘栚栠栥栨栩栮栯栳栵栾桀桇案桉桌くわ桝桭桯桵桷梁梄梆梊梋梐梒梠梢梣梤梦梨梫梭梳梴梵棇棈棍棎棐棑棕棙棠棣はねず棦棨棪森棯棰棱棷棸棻棼棽わん椂椃椄椆ぶな椌椓椕椖もみじ椰椸さわら椻楀楂楄楆楈楉楌楑楔楘楛楜楡ならゆずりはかじ楬楲楶楷ひさぎ楺概榆榍えのき榑榗榙榛榣榤かや榨榩榭榰榹榻榽榾槂槃槆槉槊槌槎槐槢槥槦槬槱槲槴槷槸槺槾樆樇樊といぶな樚樛樝模樥樧樶樽橀橁橄橆そり橉橎橏橐橓橕橖橘橠橡橩橪橾檃檌檎檐檑檓檕檖檗檞檠檤檦檧檨檫檬檱檴檶檽櫆櫊櫋櫌櫐櫔櫘櫙櫜櫡櫶欂欃欅欈欉欚次欦欻款歁歃歅歇歈歋歑歔歙歠此歫歭歹死歾殁殂殃殄殆殈殉こと殌殍殎殏殑殔殕殖殗殙殛殟殠殣殥殦殧殪殶毇毉毌どく毓比毖毗毚毞毣毦毯毳毹毻毼毾氁氄氉氐氓氛氝氡氨氪氮氯氰氹汃汆汍汐汒汝汩汭汮汲汳汵汾沉沊沘沜沢沭沲沶沿泒泚泜泠どろ泬泰泱洃きよし洖洚洝洤洧洬洯洰洱洲洳洺りゅう浚浛浧浱浵浸浻浽しょう涊涍よだれ涓涔涗涘えき涳涴涵涶涹涿淆淍淓淕淗淙淝淞あわいん淭淯淰深淲混淹淼淽渄きよし渜渝みぞ渣渫渭渮渳渴渵渶渼渿湀湇湉湑湒湓湔湖湚湛湝湠湤湥湨湫湮湱湸溉溍溗溙溚溛溞溠溥溦溧けい溭溯溱溲溴溺溻溽溾滃滊滍滐滑滕滘たき滢滫滮滶滹滺滼滽漂漆漈漉漏漒漓漘漠漤漥漫漭漮漻潃潏潒潖潗潘せん潝潠潢潲潳潸潾澂澈澉澊澓澕澞澡澥澨澪澯澲澳澵澸澹澻澽濈濍濡濢濦濩濭濮濯濷濸瀀瀁瀊瀌瀍瀖瀗瀛瀞瀡瀪瀵瀷瀺瀿灀灆灊灌灐灖灜灞灥火灮灯はい灵灶灷灸灹灺灼灾灿炁炂炃炄炅炆炉炊炍えん炏炐炑炒炔炕炖炘炙炚炟炠炡炢炥炦炧炩炫炬炭炮炯炱炳炴炵炷炸炻炼炽炾烀烄烇烈烊烋烎烐烑烓烔烕烗烘烙烚烜烞けむり烠烡烢烤烯烰烵烶烷烸烺烻烼烽烾烿焀焂焅焆焈焊焋焌焍焐焓焗焙焚焜焝焞焠焢焣焥焩焫焮焯焰焱焲焳焴焵しか焾煀煁煃煅煆煊煋煌煎煐煓煚煜煝煞煠煡煣煤煨煪煫煲煳煵煶煷煸煺煻煽煾熀熄熆熇熊熎熐熑熔熖熘熛熜熝熠熢熣熤熥熧熨熩熪熬熭熯熳熴熵熷熸熺熿燂もえ燅燇燊燋燎燏燑燔つばめ燚燛燝燠燢燥ひうち燫燮燱燲燸燹爀爂ばく爇爉爊爎爔爙爚爝爟爢爤爦爨爪爬爹牄片ばん牉牌牏牒牖牗きば牚牝牣牷とく牻牾犑犕犗犘犚犟犣犥犦犩犪犮犽狃狄狉狊狋きつね狑狔狖狫狴狷狻狿猇猋猏猐猑猒猜猢猣猦ねこ猰猱猲猴猵猷猹猺猾獀獉獌ばく獒獚獝獡獦獬獴獶獾獿玡玢玤玦玪玭れい玼珊珛珝珡珤珥珫はん珵琀琄琇琉琊琌琛みがく琤琥琨琬琭琮琰琲きん琵琶びわ琷瑀瑎瑏瑐瑚あきら瑜瑟瑥瑧瑨瑮瑰瑳瑵瑹瑿璁璃璆璈璍璘璚璜璞璠璥璨璩璪璭璱璲璷璺璻瓀瓁瓂瓋瓗瓘瓜瓝瓞瓟瓠瓡瓢べん瓤瓥かわら瓧瓨瓩瓪瓬瓮瓰瓱瓲瓴瓵瓶瓷瓸瓻瓽瓾瓿甀甂しきがわら甄甅甇甈甋甍甏甐こしき甓甔甗甚甜甝甪甯甿畇畈畑畟畤ばん畬畯畹疄疏疑疕疝疢疪きず疷疾痈痊痏痑痚痜痝痞痟痠痥痦たん痱痵痷痿瘃瘈瘊瘔瘙瘛瘝瘟やせ瘢瘣瘥瘦瘩瘭瘯瘳瘵瘼癀癑癓癗癙癚みずのと皂皆皈皉皊皣皤皫しわ皻盆盉盎盔盝盦盩盭盲盳盷盻盼眅県眢眯眳眵眹睃睄睈睊睒睕睖睙睛睡むつみ睩睭睮睽睿瞂瞃瞄瞅瞈瞍瞎瞙瞝瞟瞢まどか瞮瞰瞲瞴瞵瞻瞾矂矅矋矌矏矐矔のぶ矜矝矞矣矦矩矮矱矺矽矾砉砏砐砑砒とぎ砨砮砱砹硂硝硥硫硭确硹硺硻硾硿碀碃碆碉碌わん碟碡碣碤碥碳碴碶磃磆磇磈磉磋磍磎いわ磓磔磗磘磝磡すり磭磲磷磺磻磼磿礇礌礜礞礡礤礭礯礳礴礵礶示祂祓祗祟祡祤ひょうさい祲祳祾禁禂禃みそぎ禋禑禖禙禝禠禢禤禭禲禷禸禹禺离禽しゅう秅秋秎秕秜秠秡秢しん秧秪秫秬秶秺うつり稄稆ほどやや稑稔稠稦稨稯稰稷稽穄穈穊穋穔穟穥穮穲あな穵究穸穹そら穻穾穿窀突窂窃窄窅窆窇窈窉窊窋窌窏窐窑窒窔うつろあなぐらまど窘窙窛窞くつ窠窢窣窨窫窬窲窳窴窷窸窹窼窽窾窿竁竂かまど竆竛りゅう竣竫竭竷竺竻竽竾竿ざお笀笄笅笆きゅう笉笊たかんな笌笍笎笏笐笑笒笓笔笘しょうふえむち笟笠笢笣笤笥笧笨笩笪笫第笭笮笯笰笱笲笳笴笵笸ささ笻筀筃筅筇筈とう筊筋筌筎いかだかたみ筑筒こたえ筕策筘筠筡筢筤筥筦筨おさ筭筮筰筱筲筳むしろ筶筷筻箄箅箈箊箌たが箎箐箑箓はく箖算箘箙箚箛箜箝かん箢箤箬箭箮箯ばこ箲箴箵箷箾篁篅篆へん篊篌篎篏篐篕篙篚篜篝篟篡篣篥へら篧篨篪篫篬篰篱篲篴篷篹篺篼篾簁簃簄簅簆簇簉簋簌簎簏簐簕簙簛簟簠簦簧簨簩簪簬簭簰簳簼簿籀籂籄籇籈籉籊籍籓籖籗籝籥籦籧籰まい籴籵籸籹籺类籽籾籿粀きろめーとる粄粅粈粉粊粌みりめーとる粑粒粔粕粖粗ねば粞粟粡粢粣粥粨粱つばらうるち粴粶いき粼粽せい粿糂糄糅糇糈のり糋糌糍糎糑糒糔糕とう糗糙糚糜糟糠そうこう糢糨糪糬糭糯糱糵けい紁紫紷紻絉絒絜絮綔綗綩綮緪緳縃縏縔縥縻繁繄繇繌繺纂纛缷缸缹缺缿罀罁罅罉罐罔罕罛罥罨罪罱罻罽羃羉羌羒羚羝羞羡羧羭羮羯羰羳羸あつもの羺羻羼羽羾羿翀翁翂翃翅翇翉翊翋翌翍翎翏翐翑翔翕翗翛翝翞翟みどり翡翢翣翥翦翧翨翩翪翭翯翰翱翲かげ翴翵翷翸こぼしつばさ翾耀老耄おいぼれ耆耋耍耎耒耔こう耖耗耘耙耛耜耞耟耠耤耥耦耨耩耪耭耯耰耱耳耴耵耶耷耹耻耼耽耾耿聃聄聆聇聈聊聏聐聑聒联聕聘聚聛聜聝聡聢聣聤聦聧聬聭聱聸肁肂肄はじめ肈肋はだ肏肒肓肕肖ひじ肙肚肛肜きも肟股肣肥かた肪肫肭肮肯肱そだてさかな肵肶肷肸はい肼肽胂胃胄胅きも胇胈胍胎胏胔胕胖胗胘胙胚胛胜胝胞胠胡たね胥胦胩胬胭胯胰胱胲胳どう胵胶むね胹胺胻胼のう脀脂もろ脉脊脌脎脒脔脖脘あし脝脞脟脡脢脤脧脩脬脭脯脰脲脷脺脽脾腃腄腆腇腈腊腋腌腍腏腑腒腓腔腕腙腚腛腞腠腤なまぐさ腧腩腭腮腯腰けん腲腴腶腷はらせん腼腿膀膂膄膆膇膈膉膊膌膍あぶら膗膘膙膛まくひざ膟膣膥膦膨膪膬膰膲膳膵膺膻膼しり臁臂臃臄臅臆臇臊臌臑臒臛臞臬しゅう臱臲致臻臿舋したねぶ舑舔舚舛しゅん舝舞舠舡舢舥舦舨こう舫般舭舯舲舳舴舵舶舷はやぶねせん舺舼舽舾舿艀艂艄艅艇艉艋艎艏艐艑艒艓艔艕艖艗そう艚艞艟艡艥艨艩艬艹艺艻艽もぐさ艿芀芃芄芇芊いも芍芎芏芐芑芒芓芔芘芙芚芛しば芟芠芡芢芣芤あくたあし芧芨芩芪芫芬芭芮しん芰花よし芴芶芷芸せり芺芼芾芿苀苂苃苄苊苏苐苑苒苓こけ苕苗苘苙苛苜つと苟苠苡苢苣苤わか苨苪とま苬苭苮苯苰英ふき苴苶苷苹いちご苻苽苾苿茀茁しげ范茄ちがや茆茇茈茉茋茌茖茗茚茛あかね茝茞茢茤茥茧いばら茩茪茫茬茭茯茱茳茴茵ちゃ茷茸茹茺茼茽荀荂荃荄荅荇荈草荌荎荏荐荑荒荓荔荖荗荢荵荶荷荸荺おぎ荼荽荾荿莃莅莆莇莈莉莌莍莎莏莑莒いちご莔莕莘莙むしろ莛莜莝莞つぼみ莠莣莥莦たばこ莩莪莫莬莰莽莾莿菀菁菂菃かん菆菇菈菉きくきん菍菎菏菔菖菘菙菛さい菝菞うさぎ菠菡菢菤菥菧菨菩菪菫菬菭菮菰ひし菲菳菵菶菷菹菺菻菼菽菾菿萁萃萄萅萆萉萋萌萍萎萏萐萑萒萓萔萖萘萛萜めぐむ萡萣はぎ萫萭萮萰かや萳萶萷萸萹萺萻萼落萾萿葀葂葃葄葅葆葇葈葊葋葌葍葎葐葑葓葔葕葖ちょ葘葙葚葛葜葞葟葡葢董葥葧葨葩葪葫そうかや葮葰ねぎ葲葳葴葵葶葸葹葺葽葾葿蒀蒂蒄蒆蒈蒎蒏蒐蒑蒖蒗蒘蒙蒚蒛ひる蒝蒟蒠蒡蒢蒣蒤蒧蒨蒩蒪蒫蒬蒮蒯蒰蒱蒲蒴蒸蒹蒺蒻蒽蒾蒿蓁蓂蓄蓅蓇蓉蓊蓌めどぎ蓎蓏蓐蓑蓒蓓蓔蓖蓗蓚蓛蓞蓢蓤蓨蓩蓪蓫よもぎ蓰蓱蓳蓶蓷蓸蓹蓺蓻蓼蓾蓿しとみ蔂蔃蔅蔇蔈蔉蔊蔋蔌蔍蔏蔐蔑蔒づる蔖蔗蔙蔚蔛蔜蔝蔟蔡蔤蔧蔨蔩蔫蔬蔰蔳蔸蔻蔽蕀蕂しげる蕅蕇蕈蕉しべ蕌蕍蕔蕖ふき蕙蕛蕜蕞蕠蕣蕤蕥蕦蕧わらび蕫蕬蕮蕯蕰蕱蕵蕶蕸蕹蕺蕻蕼蕾薁薂薃薄薅薇薍薎薏薐薓薕その薚薛薜薝薞薡薢薣らっきょう薧薨たきぎいもかおる薳薶薷薸とう薽薿藀藁藂藃藄藅藆藈藊藋ぞう藐藑藒藕藗藙あかざ藞藟藠藡藢藤藦藨はん藫藮藯藱藲藸藽藿蘁蘅蘉蘌蘍蘏蘑蘔ひこばえ蘗蘘蘙蘛蘜蘠蘣蘥蘦蘧蘨蘩蘪蘮蘯蘲蘳蘶蘸蘹蘻蘼蘾虀虂虃虆虇虈虋虌虍とらしいたげ虒虓けん虙虞虠虡虢虣虤虥虨虩虪虱虴虻蚇蚋蚌蚍蚐蚗蚙蚜蚡蚣のみ蚩蚳蚷蚸蚽蛂蛉蛌蛖蛚蛩蛪蛷蛸蜃蜄蜈蜌蜎蜑蜒蜙蜚蜣蜧蜩蜰蜲蜹蜻蜿蝂蝆蝎蝑蝓蝔蝘蝙蝚蝛蝤蝧蝬まむし蝳蝴蝵蝶蝹蝺螁螆螇螉螋螌螏螑螓螔螖螚螛螝螥螩螪螫螭螯螰螱螲螵螶蟃ぶと蟉蟋蟌蟒蟓蟕蟝蟠蟤蟥蟨蟮かに蟼蟾蠂蠃蠄蠓蠕蠖蠗蠛蠡蠤蠥蠬蠮蠵蠸衁衄衈衪衯衱衲おくみふすまえり袀袂袊袕袘袚袛袲袶袽きれ裎裐裒裔裖裗裘裞裧裬裯裴裵裶裹裺裻褉褊褋褐褒褓褕褗褙褞褟褡褢しとね褦褧褨褩褪褫褬褮褰褵褶褹褼褽褾襁襐襑襔襙襚襜えり襥襦襮襷襺要覅覆覑覝覣覮覾角觓觖觗觙觚觛觜觟觠觡觢解觤觥触觧觨觩觫觬觭觮觰觱觲觳觺觼觾觿訾訿詙詹誝諿謒謕謤謦謧謪謷謽譃譒譕譗譝譢譥警譪さん讈谻谽谾豁豂豃豋豌豖ぶた豟象豦豫豯豱豽貁貐貔貕貘賲贀贌起赹赺赽趆趍趐趑趓趔趜趢趣趥趦趪趮趯趴趹趻趿跅跉跋跐跚跜距跢跧跫跱跺踂踃踆踍踒踗踘踙踛踜踠踥踭踸踻踽蹀蹁蹂蹅蹆蹉蹊蹋蹐蹗蹙蹨蹩蹯蹲蹷蹸みずかき躁躆躇躌躐躔躞躠躤躨躬躮むくろからだ躲躹躺躼躽軁軉軠軡軶輎轋轜轝べんたつはずかしめ辴辶辷辸边つじこみ达辿迁迂まで迅迆迉迊迋迌迍迎迏运きん迒迓かえし迕迖迗迚迠迡迢迣迤迥迦迨すすむさこ迭迮じゅつ迵迶迷迸迹迺迼追迾迿退すさおく适逃逄逅ぎゃく逋逌逍透逐逑递途逖逗どおり逛逜逝逞そくづくり逡逢逤逭逮逯逳逴逵逶逷逸逼逽逾遁とげ遄遆ぐう遌遍遏遐遑遒どう遖遘遚遛遝遢遣遤遧遨遫遬遭遮遳遴遵遹遻遽遾避邀邂邃邅邆邈邋邍邙邦よこしま邳邶てい邿郁郔郘郢郩郪郬郮郯郰郺郾鄀鄁鄃鄄鄅鄋鄏鄑鄘ひな鄚鄝鄠鄤鄯鄵鄸鄹鄾鄿酀酁酃酄酅酉酊酋しゃくはい酎酏酐酑しゅ酓酕酗酘酙酚酜酞酟酠酡酢たけなわ酤酥酨酩酪酬酮酯酰酲酳酴酵酶こくさん酹酺酼醀醁醂醄醅あつしよい醊醋醌醍醎醏醐醑醒醓醙醚醛醝醠醡ひしお醥醨醩醪醭醮醯醰醴醵醷醹醺醽醾釂釄釉釐釶釸鈭鉯銇銎銤銮銵鋄鋆鋑鋷鋺錓錖錴錵錹錼鍻鎀鎁鎎鎏鎐鎜鎟鎥鏅鏊鏎鏖鏠鏬鏮鏶鏼鏿鐌鐭鐰鐷鑃鑅鑗鑝鑧鑬鑶镇闀闙阤阪阰阺阾陁陊降陏陖陛陫陬陱陲陵陾隁隃隅隇隋ずい隗隙隞隡隧隩隳隶雂雅しゅうやとい雕雗雘雚雟雡雩雪雯雱雴雵れいかみなり雸雹雺雽雿需霂霃霄霅霆震霈霉霋霍霎霏霐霒霓霖霘霙霛霜霝霞霟霠霡霤霥霦霨霩霪霫霬霮霯霰霱露霴霵霶霸霹霺霾霿靀靁靃靇靊靋あおやすし靘靛靟靠靡靲くつ靸靹鞅鞍鞓鞗さや鞙鞚きく鞢鞣鞨鞳鞶韂韄韖韰韵韺韽頀頨顈顟顲飊飌食飡飧飬飹飺餇餐餙餥餮饂饏饓饔饕饖馛馜馠馡馣馤馥馧かおる馫馿えき駌駖騆驆驧骨骪骫骬骭骮骰骱骳骴骵骶骷むくろ骹骺骻骼骿髀髁髂髃髄髆髇髊髍髑髓髗髢髬髭髶髾鬃鬇鬋鬌鬏鬐鬔鬕かずらたてがみ鬫鬯鬳鬵鬷鬻おに鬽鬾鬿魀さきがけたましい魃魄魆魈魊魋魌魍魐魑魒魔魕魖魙魤魲魿鯓鯜鯳鱱鱳鱶鳹鴄いかる鵦鶈鶐鶜鶧鶸鶾鷈鷝鷡鷬鸒鸔鹿麀麁麂麃麄麅麆麇麈麉麊麋麌麍麎麑ふもと麔麕麖麘麙麚麛麜麝麟麠麢麭麶あさ麾麿黀黁黅黆黇黈きびはじむ黏黐黓黔黖默黚黜黝黟黢黤黥黦黫黭黮黰黳黵黹黺黻黼鼘鼙鼛鼜鼞鼠鼢鼣鼤鼥鼦鼧鼨鼩鼪鼫いたち鼭鼮鼯鼰鼱鼳鼵鼶鼷鼸鼹齀齂齃齄齅齇齓齛齢齫龒龗龘龟龣龤鿛鿢鿣鿤鿦鿨鿫𠂊𠘑𠣽𠪚𠭤𠮟𠹭𡌶𡐓𡑒𡪯𢆕𢕭𢯽𢹂𣊟𣕚𣗎𣜿𣳾𤺍𥕢𥕵𥧌𥴊𥻗𥻘𥼲𥾵𦉪𦍌𦐂𦗪𦙀𦤇𦥑𦪧𦰡𧄍𧗐𧪄𧿨𨅺𨥉𨨩𨸶𩍉𪊲𫶔𭅞𭗐𭴼𮡜𱁬"


-- Change one variant character to another variant character.
-- Change one variant character to another variant character.
Line 23: Line 19:
function export.change_to_variant(text)
function export.change_to_variant(text)
local count = 0
local count = 0
local text = mw.ustring.gsub(text, ('([%s])'):format(chars_variant_both), function(char)
local text = mw.ustring.gsub(text, ('([%s])'):format(m_data.chars_variant_both), function(char)
count = count + 1
count = count + 1
if (count > 1) then return '' end -- add |t2= manually, please
if (count > 1) then return '' end -- add |t2= manually, please
local this_char_index = mw.ustring.find(chars_variant_both, char)
local this_char_index = mw.ustring.find(m_data.chars_variant_both, char)
local first_or_second = (this_char_index % 2)
local first_or_second = (this_char_index % 2)
local other_char_index = this_char_index + (first_or_second == 1 and 1 or -1)
local other_char_index = this_char_index + (first_or_second == 1 and 1 or -1)
return mw.ustring.sub(chars_variant_both, other_char_index, other_char_index)
return mw.ustring.sub(m_data.chars_variant_both, other_char_index, other_char_index)
end)
end)
return (count == 1 and text or '')
return (count == 1 and text or '')
Line 74: Line 70:
-- automatically generate a |t2=
-- automatically generate a |t2=
insert_st(t, export.change_to_variant(t[1]))
insert_st(t, export.change_to_variant(t[1]))
elseif find(t[1], ('[%s]'):format(chars_variant_both .. chars_variant_one)) then
elseif find(t[1], ('[%s]'):format(m_data.chars_variant_both .. m_data.chars_variant_one)) then
require('Module:debug').track('zh-forms/entry possibly missing a variant form')
require('Module:debug').track('zh-forms/entry possibly missing a variant form')
end
end
Line 408: Line 404:
--This is not a complete list!
--This is not a complete list!
if #identity == 1 and find(chars_unified, '[' .. test_word .. ']') then
if #identity == 1 and find(m_data.chars_unified, '[' .. test_word .. ']') then
simp_note = '<sup><span class="explain" title="Using the same code point' .. (length>1 and 's' or '') .. ' as the traditional form due to Han unification. Without proper font support, it may be displayed as the same as the traditional form.">#</span></sup>'
simp_note = '<sup><span class="explain" title="Using the same code point' .. (length>1 and 's' or '') .. ' as the traditional form due to Han unification. Without proper font support, it may be displayed as the same as the traditional form.">#</span></sup>'
char_set['simp'] = char_set['trad']
char_set['simp'] = char_set['trad']

Revision as of 05:42, 27 May 2022

New Chinese Character box, used by {{zh-forms}}.


local export = {}
local m_zh = require("Module:zh")
local links = require("Module:links")
local lang = require("Module:languages")
local m_data = require("Module:zh-forms/data")
local find = mw.ustring.find
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local len = mw.ustring.len

local sc = {
	["trad"] = "Hant",
	["simp"] = "Hans",
	["both"] = "Hani",
}

-- Change one variant character to another variant character.
-- Currently, only do so once. Return false if there is more than one character to change, or if there is no change.
function export.change_to_variant(text)
	local count = 0
	local text = mw.ustring.gsub(text, ('([%s])'):format(m_data.chars_variant_both), function(char)
		count = count + 1
		if (count > 1) then return '' end -- add |t2= manually, please
		local this_char_index = mw.ustring.find(m_data.chars_variant_both, char)
		local first_or_second = (this_char_index % 2)
		local other_char_index = this_char_index + (first_or_second == 1 and 1 or -1)
		return mw.ustring.sub(m_data.chars_variant_both, other_char_index, other_char_index)
	end)
	return (count == 1 and text or '')
end

function export.make(frame)
	local params = {
		[1] = { list = true, allow_holes = true, allow_empty = true },
		["s"] = { list = true },
		["t"] = { list = true },
		["ss"] = {}, ["ns"] = {}, ["alt"] = {}, ["type"] = {}, ["delink"] = {}, ["lit"] = {}, ["note"] = {}, ["gloss"] = {}
	}
	local args = require("Module:parameters").process(frame:getParent().args, params)
	local comp_type = args["type"]
	local s, t = {}, {}
	local annotation = {}
	if not frame:getParent().args["t"] then
		table.insert(t, 1, mw.title.getCurrentTitle().subpageText)
	end
		
	local PAGENAME = mw.title.getCurrentTitle().text
	local content = mw.title.new(PAGENAME):getContent()
	
	local function insert_st(set, text)
		table.insert(set, text)
	end
	
	for i = 1, #args.s do
		if (#args.s == 1) and PAGENAME == args.s[i] then error('Redundant text in |s=.') end
		insert_st(s, args.s[i])
	end
	for i = 1, #args.t do
		if (#args.t == 1) and PAGENAME == args.t[i] then error('Redundant text in |t=.') end
		insert_st(t, args.t[i])
	end
	
	-- temp tracking
	if #s == 0 and (gsub(t[1], '.', mw.loadData("Module:zh/data/ts").ts)) ~= t[1] then
		require('Module:debug').track('zh-forms/entry possibly missing a simplified form')
	end
	if #t == 1 then
		local to_variant = export.change_to_variant(t[1])
		if (to_variant ~= '') then
			-- automatically generate a |t2=
			insert_st(t, export.change_to_variant(t[1]))
		elseif find(t[1], ('[%s]'):format(m_data.chars_variant_both .. m_data.chars_variant_one)) then
			require('Module:debug').track('zh-forms/entry possibly missing a variant form')
		end
	end
	s.name = "simp"
	t.name = "trad"
	
	if #t ~= 1 and #s == 0 then
		table.insert(s, t[1])
	end

	local function asterisk(term, iscomp)
		if iscomp and len(t[1]) > 1 then return "" end
		if term == mw.title.getCurrentTitle().subpageText or not (mw.title.new(term) or {}).exists then return "" end
		local content = mw.title.new(term):getContent()
		content = gsub(content, "zh%-pron", "Ꙁ")
		content = gsub(content, "zh%-see", "Ꙁ")
		content = gsub(content, "[^Ꙁ]", "")
		return mw.ustring.len(content) > 1 and '<sup><span class="explain" title="This form has one or more other meanings.">*</span></sup>' or ''
	end

	local function var_fmt(length, color)
		return '\n|-\n! style="padding: 0.' .. (length > 8 and '3' or '5') ..
			'em;border: 1px solid #aaa;background: #' .. (color or 'E0FFFF') ..
			';font-weight: normal;font-size: smaller;" colspan="2" |'
	end
	
	local function char_gap(length, script, last)
		return '\n| style="padding: 0.' .. (length > 8 and '3' or '5') ..
			'em; background-color:white;' ..
			(last and 'border-right: 1px solid #aaa;border' .. (length ~= 1 and '-bottom' or '') .. ': 1px solid #aaa; '
				or 'border-bottom: 1px solid #aaa; ') ..
			'font-size:x-large" lang="zh-' .. sc[script] .. '" class="' .. sc[script] .. '" | '
	end
	
	local function header(length, var_count)
		return ((length > 3 or var_count * length > 5) and '{|' or '{| align=right') .. 
			' style="clear: right;margin: 1em;border-collapse: collapse;text-align: center"' ..
			(length ~= 1 and '\n|-\n! colspan=2|' or '')
	end
	
	local function gloss_fmt(word, colspan, length)
		return '\n! style="padding: 0.' .. (length > 8 and '3' or '5') ..
			'em;border: 1px solid #aaa;background:#F5F5DC;font-weight: normal;font-size: 85%; width:' ..
			(length <= 8 and (30 * word + 30) or (25 * word + 25)) .. 'px" colspan=' .. (colspan or 1)  ..'|'
	end

	local function form_fmt(text, length, script)
		local fmtd_text = {}
		for i,value in ipairs(text) do
			fmtd_text[i] = links.language_link({ lang = lang.getByCode("zh"), term = value }) .. asterisk(value, false)
		end
		return length ~= 1 and ((length > 8 and '' or '<span style="font-size:140%">') ..
			'(<span lang="zh-' .. sc[script] .. '" class="' .. sc[script] .. '">' .. table.concat(fmtd_text, "/") .. '</span>)' ..
			(length > 8 and '' or '</span>')) or ''
	end
	
	local function char_fmt(text, length, script)
		return (#text ~= 1 and (char_gap(length, script) .. table.concat(text, char_gap(length, script), 1, #text-1)) or '') .. char_gap(length, script, true) .. text[#text]
	end
	
	local test_word = t[1]
	local length = len(test_word)
	local word_division = {}
	local i = 1
	local decomposable

	if comp_type then
		for index in mw.text.gsplit(comp_type, "", true) do
			if find(mw.ustring.sub(test_word, i, i), '[,%-]') then
				table.insert(word_division, { i, i } )
				i = i + 1
			elseif mw.ustring.sub(test_word, i, i) == '…' then
				table.insert(word_division, { i, i + 1 } )
				i = i + 2
			end
			table.insert(word_division, { i, i + index - 1 } )
			i = i + index
		end
		if i - 1 ~= len(gsub(test_word, '…+$', '')) and not find(table.concat(t) .. table.concat(s), "[⿰⿱⿲⿳⿴⿵⿶⿷⿸⿹⿺⿻]") then
			error("'type' parameter does not match word length.")
		end
	else
		for i = 1, length do
			table.insert(word_division, { i, i } )
		end
		decomposable = len(gsub(test_word, '…+$', '')) > 2 and true or false
	end
	
	local delink = {}
	if args["delink"] then
		if args["delink"] == "y" then
			for del_index, _ in ipairs(word_division) do
				delink[del_index] = "yes"
			end
		else
			for position in mw.text.gsplit(args["delink"], ",") do
				delink[tonumber(position)] = "yes"
			end
		end
	end
	
	local char_set = { ['simp'] = {}, ['trad'] = {} }
	local identity = #s == 0 and {t} or {s,t}
	local uncreated = {}
	
	for _, id in ipairs(identity) do
		for i, position in ipairs(word_division) do
			local char_string = ""
			for j = 1, #id do
				local word_form = mw.ustring.sub(id[j], position[1], position[2])
				if not find(char_string, word_form) then
					char_string = (char_string ~= "" and (char_string .. '/') or "") .. word_form
				end
			end
			if not find(char_string, '[,%-]') then
				local hash = {}
				for thing in mw.text.gsplit(char_string, (delink[i] and "" or "/")) do
					table.insert(hash, links.language_link({ lang = lang.getByCode("zh"), term = thing }) .. asterisk(thing, true))
				end
				char_string = table.concat(hash, (delink[i] and "" or "/"))
			end
			table.insert(char_set[id.name], char_string)
		end
		for _, item in ipairs(id) do
			if not (mw.title.new(item) or {}).exists and item ~= mw.title.getCurrentTitle().subpageText then
				table.insert(uncreated, '"[[' .. item .. ']]"')
			end
		end
	end

	local scripts = { ['いち-鿿㐀-䶿﨎﨏﨑﨓﨔﨟﨡﨣﨤﨧-﨩𠀀-𪛟𪜀-𮯯𰀀-𱍏'] = 'Hani' , ['a-zA-ZāēīōūĀĒĪŌŪa-zA-Z'] = 'Latn', ['0-90-9'] = 'Numb', ['Ͱ-Ͽ'] = 'Grek' }
	local script = {}
	for range, script_name in pairs(scripts) do
		if find(test_word, '[' .. range .. ']') then
			table.insert(script, script_name)
		end
	end

	if find(t[1], "([^─…]+)%1") and args['gloss'] ~= '-' and len(t[1]) < 7 then
		if gsub(comp_type or "", "1", "") == "" then
			table.insert(annotation, '[[Category:Chinese reduplications]]')
		elseif find(t[1], "([^…][^…]+)%1") or find(table.concat(char_set['trad'], " "), "([^─…%[%]a-z]+)%1") then
			local evil
			for _, component in ipairs(char_set['trad']) do
				if len(component) > 1 then
					local comp_content = mw.title.new(links.remove_links(component)):getContent() or false
					if not comp_content or find(comp_content, "|gloss=-") or not find(comp_content, "==Chinese==") then
						evil = true
					end
				end
			end
			if not evil then table.insert(annotation, '[[Category:Chinese reduplications]]') end
		end
	end

	table.insert(annotation, #script > 1 and '[[Category:Chinese terms written in multiple scripts]]' or nil)
	table.insert(annotation, (decomposable and args['gloss'] ~= '-' and not args['note'] and not args['lit']) and '[[Category:Chinese entries with potentially decomposable titles]]' or nil)
	table.insert(annotation, (#uncreated > 0 and mw.title.getCurrentTitle().nsText == "") and '[[Category:Chinese terms with uncreated forms]]' .. 
		'<small class="attentionseeking">(' .. (#uncreated == 1 and 'This form' or 'These forms') ..
		' in the hanzi box ' .. (#uncreated == 1 and 'is' or 'are') .. ' uncreated: ' .. 
		table.concat(uncreated, ", ") .. '.)</small>' or nil)
	
	local ss = ""
	if args["ss"] then
		ss = var_fmt(length, 'FFFFE0') .. '[[w:Second round of simplified Chinese characters|2nd round simp.]]' .. mw.ustring.sub(char_gap(length, 'simp', true), 1, -45)
			.. '; padding-top: 10px; padding-bottom: 10px; border-right: 1px solid #aaa; border-bottom: 1px solid #aaa"'
			.. ' colspan="' .. #word_division .. '"|' .. m_zh.link(nil, nil, { args["ss"], tr = "-" }, mw.title.getCurrentTitle().subpageText)
	end
	
	local ns = ""
	if args["ns"] then
		ns = var_fmt(length, 'FFFFE0') .. 'nonstandard simp.' .. mw.ustring.sub(char_gap(length, 'simp', true), 1, -45)
			.. '; padding-top: 10px; padding-bottom: 10px; border-right: 1px solid #aaa; border-bottom: 1px solid #aaa"'
			.. ' colspan="' .. #word_division .. '"|' .. m_zh.link(nil, nil, { args["ns"], tr = "-" }, mw.title.getCurrentTitle().subpageText)
	end
	
	local altforms = ""
	if args["alt"] then
		local altform_list = {}
		for altform in mw.text.gsplit(args["alt"], ",") do
			local altdecomp = mw.text.split(altform, ":")
			local altdecomp2 = mw.text.split(altdecomp[1], "-")
			altdecomp3 = altdecomp2[2] and  ' <span style="font-size:70%"><i>' .. gsub(altdecomp2[2], "‡", frame:expandTemplate{
					title = "Template:zh-historical-dict",
					args = { type = "form", nocat = "1" }
				}) .. '</i></span>' or ''
			table.insert(altform_list, '<span style="white-space:nowrap;">' ..
				m_zh.link(nil, nil, { altdecomp2[1], tr = (altdecomp[2] or "-") }, mw.title.getCurrentTitle().subpageText) .. 
				altdecomp3 .. '</span>')
		end
		if #altform_list > 5 then
			altforms = '<div class="vsSwitcher" data-toggle-category="Chinese alternative forms"><span class="vsToggleElement">&nbsp;</span>' ..
				'<div class="vsShow">' .. table.concat(altform_list, "<br>", 1, 5) ..
				'</div><div class="vsHide">' .. table.concat(altform_list, "<br>") .. '</div></div>'
		else
			altforms = table.concat(altform_list, "<br>")
		end
		altforms = var_fmt(length, 'F0FFE0') .. 'alternative forms' .. mw.ustring.sub(char_gap(length, "trad", true), 1, -45)
			.. '; padding-top: 10px; padding-bottom: 10px; border-right: 1px solid #aaa; border-bottom: 1px solid #aaa"'
			.. ' colspan="' .. #word_division .. '"|' .. altforms
	end
	
	local anagram = ""
	if len(t[1]) == 2 and not find(t[1], "(.)%1") then
		local anagram_link = mw.ustring.sub(t[1], 2, 2) .. mw.ustring.sub(t[1], 1, 1)
		local anagram_content = mw.title.new(anagram_link):getContent() or false
		if anagram_content and find(anagram_content, "==Chinese==") then
			anagram = var_fmt(length, 'F0FFE0') .. 'anagram' .. mw.ustring.sub(char_gap(length, 'trad', true), 1, -45)
			.. '; padding-top: 10px; padding-bottom: 10px; border-right: 1px solid #aaa; border-bottom: 1px solid #aaa"'
			.. ' colspan="' .. #word_division .. '"|' .. m_zh.link(nil, nil, { anagram_link, tr = "-" }, mw.title.getCurrentTitle().subpageText)
		end
	end
	
	local literal = (args["lit"] or args["note"]) and '\n|-' .. 
		gloss_fmt(length, #word_division + 2, length) .. 
		(args["lit"] and '<i>Literally:</i> “' .. args["lit"] .. 
		(find(args["lit"], "%.$") and "”" or "”.") or args["note"]) or ""
	
	local gloss = {}
	if args['gloss'] == '-' then
		gloss = { gloss_fmt(length * 1.6, #word_division, length) .. '<i>phonetic</i>' }
	elseif length == 1 then
		gloss = {}--{ gloss_fmt(1.6, #word_division) .. '-' }
	else
		for i, position in ipairs(word_division) do
			local character = mw.ustring.sub(t[1], position[1], position[2])
			
			local gloss_text = args[1][i]
			-- Load glosses module if no gloss was supplied and the word is a single character.
			if not gloss_text and position[1] == position[2] then
				local glosses = mw.loadData("Module:zh/data/glosses")
				gloss_text = glosses.glosses[character] or ""
				gloss_text = gsub(gloss_text, "{{taxlink|([^{}]+)}}",
					function (taxlink_text)
						local taxlink_args, argi = {}, 1
						for arg in mw.text.gsplit(taxlink_text, "|") do
							local arg_split = mw.text.split(arg, "=")
							if arg_split[2] then
								taxlink_args[arg_split[1]] = arg_split[2]
							else
								taxlink_args[argi] = (arg ~= "" and arg or nil)
								argi = argi + 1
							end
						end
						local frame = mw.getCurrentFrame()
						return frame:expandTemplate{
							title = 'taxlink',
							args = taxlink_args
						}
					end)
				if gloss_text == "" and find(character, "^[いち-鿿㐀-䶿﨎﨏﨑﨓﨔﨟﨡﨣﨤﨧-﨩]+$") and not find(glosses.nonlemma, character) then
					require('Module:debug').track('zh-forms/no gloss found for Chinese character')
				end
			end
			if gloss_text == "-" then gloss_text = "''phonetic''" end
			if not gloss_text then
				gloss_text = ""
			end
			
			--[[
				To ensure that suffixes are not broken up between lines, like this:
				-
				ist
			]]
			if find(gloss_text, "-", nil, true) then
				local nonbreaking_hyphen = mw.ustring.char(0x2011)
				gloss_text = mw.ustring.gsub(gloss_text, "^%-", nonbreaking_hyphen)
				gloss_text = mw.ustring.gsub(gloss_text, "(%s)%-", "%1" .. nonbreaking_hyphen)
			end
		
			if gloss_text == "" and position[2] > position[1] then
				local senses = {}
				local content = mw.title.new(character):getContent() or false
				if content then
					gloss_text = m_zh.extract_gloss(content, false)
					if gloss_text == "" and find(character, "^[いち-鿿㐀-䶿﨎﨏﨑﨓﨔﨟﨡﨣﨤﨧-﨩]+$") then
						require('Module:debug').track('zh-forms/no gloss found but entry exists')
					end
					if not string.match(content, character) then
						require('Module:debug').track('zh-forms/compounds not mentioned in derived terms on the component pages')
					end
				else
					if gloss_text == "" and find(character, "^[いち-鿿㐀-䶿﨎﨏﨑﨓﨔﨟﨡﨣﨤﨧-﨩]+$") then
						table.insert(annotation, '[[Category:Chinese redlinks/zh-forms]]')
					end
				end
			end
			gloss_text = gsub(gloss_text, ";[^a-zA-Z0-9]+;", ";")
			gloss_text = gsub(gloss_text, ";[^a-zA-Z0-9]*$", "")
			gloss_text = gsub(gloss_text, ";+", ";")
			if len(gsub(gloss_text, '[^;]', '')) > 2 then
				gloss_text = '<div class="vsSwitcher" data-toggle-category="glosses"><span class="vsToggleElement">&nbsp;</span><div class="vsShow">' ..
					match(gloss_text, '^[^;]+;[^;]+;[^;]+') .. '</div><div class="vsHide">' .. gloss_text .. '</div></div>'
			end
			local word_length = match(character, '[,…%-]') and 0 or 
				(delink[i] and len(character) or len(character) * (len(gsub(char_set['trad'][i], '[^/]', '')) + 1))
			table.insert(gloss, gloss_fmt(word_length, 1, length) .. gloss_text)
		end
	end
	
	if content then
		local applicable_pos = { ["Noun"] = 1, ["Verb"] = 1, ["Adjective"] = 1, ["Adverb"] = 1, 
			["Definitions"] = 1, ["Pronunciation"] = 1 }
		local previous_level = 2
		local subheading_wanted
		--[=[
		-- Used under headers for Chinese varieties, for instance in [[āu-piah]]
		local Chinese_section = string.match(content, "\n==Chinese==\n(.-)\n==[^=]")
		if not Chinese_section then
			error("No Chinese section found.")
		end
		--]=]
		if length == 1 and not string.match(content, "===Definitions===") then
			require('Module:debug').track('zh-forms/no definitions section found')
		end
		if length == 1 and not string.match(content, "===Compounds===") and string.match(content, "zh-der") then
			require('Module:debug').track('zh-forms/derived terms probably needing renaming')
		end
		for equals, heading_text in string.gmatch(content, "\n(%=%=+)([^%=]+)%=%=+") do
			local current_level = #equals
			if subheading_wanted and current_level ~= previous_level + 1 then
				if applicable_pos[heading_text] then
					error("The heading \"===Etymology ''n''===\" or \"===Pronunciation ''n''===\" must be followed by a subheading one level lower.")
				end
			end
			previous_level = current_level
			subheading_wanted = string.find(heading_text, " [0-9]+") and true or false
		end
	end
	
	local simp_note = ""
    --This is not a complete list!
	
	if #identity == 1 and find(m_data.chars_unified, '[' .. test_word .. ']') then
		simp_note = '<sup><span class="explain" title="Using the same code point' .. (length>1 and 's' or '') .. ' as the traditional form due to Han unification. Without proper font support, it may be displayed as the same as the traditional form.">#</span></sup>'
		char_set['simp'] = char_set['trad']
	end
	
	return table.concat{
		header(length, math.max(#t, #s)), table.concat(gloss, ""),
		((#identity == 1 and simp_note == '') and
			(var_fmt(length) .. '[[Simplified Chinese|simp.]] and [[Traditional Chinese|trad.]]<br>' .. 
				form_fmt(t, length, 'both') .. char_fmt(char_set['trad'], length, 'both'))
		or
			 var_fmt(length) .. '[[Traditional Chinese|trad.]] ' .. 
			 	form_fmt(t, length, 'trad') .. char_fmt(char_set['trad'], length, 'trad') .. 

			(var_fmt(length) .. '[[Simplified Chinese|simp.]] ' .. simp_note ..
				form_fmt(#s == 0 and t or s, length, 'simp') .. char_fmt(char_set['simp'], length, 'simp'))

		), ss, ns, altforms, anagram, literal, '\n|}', table.concat(annotation)
	}
end

return export