Wiktionary
thwiktionary
https://th.wiktionary.org/wiki/%E0%B8%A7%E0%B8%B4%E0%B8%81%E0%B8%B4%E0%B8%9E%E0%B8%88%E0%B8%99%E0%B8%B2%E0%B8%99%E0%B8%B8%E0%B8%81%E0%B8%A3%E0%B8%A1:%E0%B8%AB%E0%B8%99%E0%B9%89%E0%B8%B2%E0%B8%AB%E0%B8%A5%E0%B8%B1%E0%B8%81
MediaWiki 1.46.0-wmf.26
case-sensitive
สื่อ
พิเศษ
พูดคุย
ผู้ใช้
คุยกับผู้ใช้
วิกิพจนานุกรม
คุยเรื่องวิกิพจนานุกรม
ไฟล์
คุยเรื่องไฟล์
มีเดียวิกิ
คุยเรื่องมีเดียวิกิ
แม่แบบ
คุยเรื่องแม่แบบ
วิธีใช้
คุยเรื่องวิธีใช้
หมวดหมู่
คุยเรื่องหมวดหมู่
ภาคผนวก
คุยเรื่องภาคผนวก
ดัชนี
คุยเรื่องดัชนี
สัมผัส
คุยเรื่องสัมผัส
อรรถาภิธาน
คุยเรื่องอรรถาภิธาน
TimedText
TimedText talk
มอดูล
คุยเรื่องมอดูล
Event
Event talk
शाक
0
6671
5722535
2188689
2026-05-05T04:02:36Z
OctraBot
3198
เก็บกวาด
5722535
wikitext
text/x-wiki
== ภาษาฮินดี ==
=== รากศัพท์ ===
{{bor+|hi|sa|शाक}}; {{doublet|hi|साग}}
=== การออกเสียง ===
* {{hi-IPA}}
=== คำนาม ===
{{hi-noun|m}}
# [[ผัก]]
#: {{syn|hi|सब्ज़ी|साग|भाजी}}
# [[สมุนไพร]]
==== การผันรูป ====
{{hi-ndecl|<M>}}
==== คำเกี่ยวข้อง ====
{{col2|hi|शाकाहारी}}
=== อ้างอิง ===
* {{R:hi:McGregor}}
hi8xkm8jjr6hssli43ru98iqfciwm3j
การ
0
9046
5722486
5714759
2026-05-05T01:07:12Z
OctraBot
3198
/* รากศัพท์ */
5722486
wikitext
text/x-wiki
{{also/auto}}
== ภาษาไทย ==
=== รากศัพท์ ===
{{bor+|th|sa|कार||ทำ, ผู้ทำ}} หรือ{{bor|th|pi|การ||ทำ, ผู้ทำ}}
=== การออกเสียง ===
{{th-pron|กาน}}
=== คำนาม ===
{{th-noun}}
# [[งาน]], [[สิ่ง]][[หรือ]][[เรื่อง]][[ที่]][[ทำ]], [[มัก]][[ใช้]][[เข้า]][[คู่]][[กับ]][[คำ]] งาน
#: {{ux|th|การงาน}}
#: {{ux|th|เป็นการเป็นงาน}}
#: {{ux|th|ได้การได้งาน}}
==== ลูกคำ ====
{{col4|th
|ช้าเป็นการ นานเป็นคุณ
}}
=== อุปสรรค ===
{{head|th|อุปสรรค}}
# [[ถ้า]][[อยู่]][[หน้า]][[นาม]] [[หมาย]][[ความ]][[ว่า]] เรื่อง, [[ธุระ]], [[หน้าที่]]
#: {{ux|th|การบ้าน}}
#: {{ux|th|การครัว}}
#: {{ux|th|การคลัง}}
#: {{ux|th|การเมือง}}
# ถ้าอยู่หน้า[[กริยา]] ทำกริยา[[ให้]][[เป็น]][[อาการนาม]]
#: {{ux|th|การกิน}}
#: {{ux|th|การเดิน}}
== ภาษาเขมรเหนือ ==
=== รากศัพท์ ===
เทียบ{{cog|km|ការ}}, {{cog|th|การ}}
=== การออกเสียง ===
* {{IPA|kxm|/kaːr/}}
=== คำนาม ===
{{kxm-noun}}
# การ, งาน
# [[งาน]][[แต่งงาน]]
== ภาษาคำเมือง ==
=== การออกเสียง ===
* {{IPA|nod|/kaːn˨˦/|a=เชียงใหม่}}
=== คำนาม ===
{{nod-noun|tl=1}}
# {{alternative form of|nod|ᨠᩣ᩠ᩁ}}
== ภาษาบาลี ==
=== รากศัพท์ ===
{{suffix|pi|กรฺ|-ณ}}
=== รูปแบบอื่น ===
{{pi-alt}}
=== คำนาม ===
{{pi-noun|m}}
# [[การทำ]]
=== การผัน ===
{{pi-decl-noun|g=m}}
ftl9bqypvfq3eys8bodj5f613szw0os
5722487
5722486
2026-05-05T01:08:47Z
OctraBot
3198
/* รากศัพท์ */
5722487
wikitext
text/x-wiki
{{also/auto}}
== ภาษาไทย ==
=== รากศัพท์ ===
{{bor+|th|sa|कार||การทำ, ผู้ทำ}} หรือ{{bor|th|pi|การ||การทำ, ผู้ทำ}}
=== การออกเสียง ===
{{th-pron|กาน}}
=== คำนาม ===
{{th-noun}}
# [[งาน]], [[สิ่ง]][[หรือ]][[เรื่อง]][[ที่]][[ทำ]], [[มัก]][[ใช้]][[เข้า]][[คู่]][[กับ]][[คำ]] งาน
#: {{ux|th|การงาน}}
#: {{ux|th|เป็นการเป็นงาน}}
#: {{ux|th|ได้การได้งาน}}
==== ลูกคำ ====
{{col4|th
|ช้าเป็นการ นานเป็นคุณ
}}
=== อุปสรรค ===
{{head|th|อุปสรรค}}
# [[ถ้า]][[อยู่]][[หน้า]][[นาม]] [[หมาย]][[ความ]][[ว่า]] เรื่อง, [[ธุระ]], [[หน้าที่]]
#: {{ux|th|การบ้าน}}
#: {{ux|th|การครัว}}
#: {{ux|th|การคลัง}}
#: {{ux|th|การเมือง}}
# ถ้าอยู่หน้า[[กริยา]] ทำกริยา[[ให้]][[เป็น]][[อาการนาม]]
#: {{ux|th|การกิน}}
#: {{ux|th|การเดิน}}
== ภาษาเขมรเหนือ ==
=== รากศัพท์ ===
เทียบ{{cog|km|ការ}}, {{cog|th|การ}}
=== การออกเสียง ===
* {{IPA|kxm|/kaːr/}}
=== คำนาม ===
{{kxm-noun}}
# การ, งาน
# [[งาน]][[แต่งงาน]]
== ภาษาคำเมือง ==
=== การออกเสียง ===
* {{IPA|nod|/kaːn˨˦/|a=เชียงใหม่}}
=== คำนาม ===
{{nod-noun|tl=1}}
# {{alternative form of|nod|ᨠᩣ᩠ᩁ}}
== ภาษาบาลี ==
=== รากศัพท์ ===
{{suffix|pi|กรฺ|-ณ}}
=== รูปแบบอื่น ===
{{pi-alt}}
=== คำนาม ===
{{pi-noun|m}}
# [[การทำ]]
=== การผัน ===
{{pi-decl-noun|g=m}}
n19819wbciw5yaaycwcgu38q9u1brrd
5722488
5722487
2026-05-05T01:10:22Z
OctraBot
3198
/* รากศัพท์ */
5722488
wikitext
text/x-wiki
{{also/auto}}
== ภาษาไทย ==
=== รากศัพท์ ===
{{bor+|th|sa|कार||การทำ, ผู้ทำ}} หรือ{{bor|th|pi|การ||การทำ}}
=== การออกเสียง ===
{{th-pron|กาน}}
=== คำนาม ===
{{th-noun}}
# [[งาน]], [[สิ่ง]][[หรือ]][[เรื่อง]][[ที่]][[ทำ]], [[มัก]][[ใช้]][[เข้า]][[คู่]][[กับ]][[คำ]] งาน
#: {{ux|th|การงาน}}
#: {{ux|th|เป็นการเป็นงาน}}
#: {{ux|th|ได้การได้งาน}}
==== ลูกคำ ====
{{col4|th
|ช้าเป็นการ นานเป็นคุณ
}}
=== อุปสรรค ===
{{head|th|อุปสรรค}}
# [[ถ้า]][[อยู่]][[หน้า]][[นาม]] [[หมาย]][[ความ]][[ว่า]] เรื่อง, [[ธุระ]], [[หน้าที่]]
#: {{ux|th|การบ้าน}}
#: {{ux|th|การครัว}}
#: {{ux|th|การคลัง}}
#: {{ux|th|การเมือง}}
# ถ้าอยู่หน้า[[กริยา]] ทำกริยา[[ให้]][[เป็น]][[อาการนาม]]
#: {{ux|th|การกิน}}
#: {{ux|th|การเดิน}}
== ภาษาเขมรเหนือ ==
=== รากศัพท์ ===
เทียบ{{cog|km|ការ}}, {{cog|th|การ}}
=== การออกเสียง ===
* {{IPA|kxm|/kaːr/}}
=== คำนาม ===
{{kxm-noun}}
# การ, งาน
# [[งาน]][[แต่งงาน]]
== ภาษาคำเมือง ==
=== การออกเสียง ===
* {{IPA|nod|/kaːn˨˦/|a=เชียงใหม่}}
=== คำนาม ===
{{nod-noun|tl=1}}
# {{alternative form of|nod|ᨠᩣ᩠ᩁ}}
== ภาษาบาลี ==
=== รากศัพท์ ===
{{suffix|pi|กรฺ|-ณ}}
=== รูปแบบอื่น ===
{{pi-alt}}
=== คำนาม ===
{{pi-noun|m}}
# [[การทำ]]
=== การผัน ===
{{pi-decl-noun|g=m}}
b3jej1ob6zgo62ju4wuhc987t26d0to
ประดับ
0
17575
5722549
5686281
2026-05-05T10:42:11Z
OctraBot
3198
/* คำพ้องความ */
5722549
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
จาก{{der|th|okz|ប្រតាប}}, {{m|okz|ប្រតាប្ប}}, {{m|okz|ប្រតប្ប|gloss=ทำให้เป็นระเบียบ}}, ซึ่งแผลงมาจาก {{m|okz|*តាប៑|gloss=เป็นระเบียบ}}; ร่วมเชื้อสายกับ{{cog|km|ប្រដាប់}}, {{cog|lo|ປະດັບ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-ดับ}}
=== คำกริยา ===
{{th-verb}}
# [[ตกแต่ง]][[ให้]][[งาม]][[ด้วย]][[สิ่ง]][[ต่าง]] ๆ [[มี]][[สร้อย]] [[แหวน]] [[เป็นต้น]]
#: {{ux|th|ประดับเหรียญตรา}}
#: {{ux|th|ประดับอาคารสถานที่}}
#: {{ux|th|ประดับโคมไฟ}}
# {{lb|th|โดยปริยาย}} [[ประกอบ]], [[เพิ่ม]]
#: {{ux|th|ประดับบารมี}}
==== คำพ้องความ ====
* [[ตกแต่ง]]
* [[ขจิต]]
* [[ประดับประดา]]
==== ลูกคำ ====
{{col|th|ข้าวประดับดิน|เครื่องประดับ|จตุรงคประดับ|ดวงเดือนประดับดาว|ดาวประดับ|ตรีประดับ|ทวาตรึงประดับ|ทวารประดับ|ประดับประดา|ไม้ประดับ|ราตรีประดับดาว|ประดับยนต์|ใบประดับ|เกล็ดประดับ}}
cqrwqn1cjiz3wy9d03y7nircxywaujx
ส่วนลด
0
18546
5722479
1493500
2026-05-04T16:25:42Z
~2026-26910-48
18958
/* ภาษาไทย */
5722479
wikitext
text/x-wiki
==ภาษาไทย==
สูบเทบ
===การออกเสียง===
* ส่วน-ลด
=== คำนาม ===
{{th-noun}}
# ส่วนที่[[หัก]]จากจำนวน[[เงิน]]ที่เก็บมาได้ หรือจากจำนวนที่ซื้อหรือที่ใช้ตาม[[ส่วน]]ที่กำหนดไว้
cmspgs8frv8zu1trhqviw5ctyr5ziu7
5722482
5722479
2026-05-05T01:01:09Z
OctraBot
3198
เก็บกวาด
5722482
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
{{com+|th|ส่วน|ลด}}
=== การออกเสียง ===
{{th-pron|ส่วน-ลด}}
=== คำนาม ===
{{th-noun}}
# [[ส่วน]][[ที่]][[หัก]][[จาก]][[จำนวน]][[เงิน]]ที่[[เก็บ]][[มา]][[ได้]] [[หรือ]]จากจำนวนที่[[ซื้อ]]หรือที่[[ใช้]][[ตาม]]ส่วนที่[[กำหนด]][[ไว้]]
s97cfq3cuozvq0zkaznj99z5gc088fz
ประกอบ
0
26068
5722550
2189024
2026-05-05T10:50:49Z
OctraBot
3198
/* ลูกคำ */
5722550
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
เทียบ{{cog|km|ផ្គួប}}, {{cog|mnw|ဗ္ဂပ်}} / {{m|mnw|ဗဂပ်}}; เป็นไปได้ว่าเกี่ยวข้องกับ {{m|th|ประกบ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-กอบ}}
=== คำกริยา ===
{{th-verb}}
# {{lb|th|สกรรม}} เอา[[ชิ้นส่วน]]ต่าง ๆ มารวมหรือ[[คุม]]กันเข้าเป็น[[รูปร่าง]]ตามที่ต้องการ
#: {{ux|th|'''ประกอบ'''รถยนต์}}
# {{lb|th|สกรรม}} [[ทำ]]
#: {{ux|th|'''ประกอบ'''อาชีพ}}
#: {{ux|th|'''ประกอบ'''ธุรกิจ}}
# {{lb|th|สกรรม}} [[ประสม]]หรือ[[ปรุง]]เป็นอันหนึ่งอันเดียวกัน
#: {{ux|th|'''ประกอบ'''ยา}}
#: {{ux|th|'''ประกอบ'''อาหาร}}
# {{lb|th|สกรรม}} [[เสริม]], [[เพิ่มเติม]]
#: {{ux|th|อธิบาย'''ประกอบ'''}}
==== คำพ้องความ ====
{{col4|th|กอปร}}
==== ลูกคำ ====
{{col|th|เขตประกอบการเสรี|ตัวประกอบ|ประกอบด้วย|ประกอบอาหาร|พระราชบัญญัติประกอบรัฐธรรมนูญ|ภาพประกอบ|เรือประกอบ|สถานประกอบการ|สมประกอบ|ส่วนประกอบ|สารประกอบ|องค์ประกอบ|จำนวนประกอบ|มุมประกอบ|ผู้ประกอบการ}}
ajg8xhmtp3yy33kxk1asp2stzqfzuun
5722551
5722550
2026-05-05T10:53:54Z
OctraBot
3198
/* ลูกคำ */
5722551
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
เทียบ{{cog|km|ផ្គួប}}, {{cog|mnw|ဗ္ဂပ်}} / {{m|mnw|ဗဂပ်}}; เป็นไปได้ว่าเกี่ยวข้องกับ {{m|th|ประกบ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-กอบ}}
=== คำกริยา ===
{{th-verb}}
# {{lb|th|สกรรม}} เอา[[ชิ้นส่วน]]ต่าง ๆ มารวมหรือ[[คุม]]กันเข้าเป็น[[รูปร่าง]]ตามที่ต้องการ
#: {{ux|th|'''ประกอบ'''รถยนต์}}
# {{lb|th|สกรรม}} [[ทำ]]
#: {{ux|th|'''ประกอบ'''อาชีพ}}
#: {{ux|th|'''ประกอบ'''ธุรกิจ}}
# {{lb|th|สกรรม}} [[ประสม]]หรือ[[ปรุง]]เป็นอันหนึ่งอันเดียวกัน
#: {{ux|th|'''ประกอบ'''ยา}}
#: {{ux|th|'''ประกอบ'''อาหาร}}
# {{lb|th|สกรรม}} [[เสริม]], [[เพิ่มเติม]]
#: {{ux|th|อธิบาย'''ประกอบ'''}}
==== คำพ้องความ ====
{{col4|th|กอปร}}
==== ลูกคำ ====
{{col|th|เขตประกอบการเสรี|ตัวประกอบ|ประกอบด้วย|ประกอบอาหาร|พระราชบัญญัติประกอบรัฐธรรมนูญ|ภาพประกอบ|เรือประกอบ|สถานประกอบการ|สมประกอบ|ส่วนประกอบ|สารประกอบ|องค์ประกอบ|จำนวนประกอบ|มุมประกอบ|ผู้ประกอบการ|ด้านประกอบมุมฉาก}}
rcxb67it6l1bor4wywfo2m5p1c9nkwj
คุยกับผู้ใช้:Bandita A
3
30582
5722480
1097443
2026-05-05T00:32:44Z
Kadı
15341
Kadı ย้ายหน้า [[คุยกับผู้ใช้:Banthitar A.]] ไปยัง [[คุยกับผู้ใช้:Bandita A]]: ย้ายหน้าอัตโนมัติขณะเปลี่ยนชื่อผู้ใช้ "[[Special:CentralAuth/Banthitar A.|Banthitar A.]]" เป็น "[[Special:CentralAuth/Bandita A|Bandita A]]"
131967
wikitext
text/x-wiki
{{Template:Welcome|realName=|name=Banthitar}}
-- [[ผู้ใช้:New user message|New user message]] ([[คุยกับผู้ใช้:New user message|พูดคุย]]) 12:27, 31 ธันวาคม 2555 (ICT)
kfj1o4hrtp76mqryug304ctkg4ouvwv
มอดูล:category tree/หัวข้อ/การสื่อสาร
828
44557
5722531
5632867
2026-05-05T03:56:27Z
OctraBot
3198
5722531
Scribunto
text/plain
local labels = {}
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-- FIXME: Lookup langs in the language list.
for _, lang_etc in ipairs {
"อาหรับ", "อารามายา", "จีน", "กรีก", "อังกฤษ", "เยอรมัน", "ญี่ปุ่น", "ละติน", "เกาหลี", "โอกินาวะ",
"โปรตุเกส", "สันสกฤต", "สเปน", "ทมิฬ", "เวียดนาม"
} do
if type(lang_etc) ~= "table" then
lang_etc = {lang_etc}
end
local lang, desc = unpack(lang_etc)
desc = desc or ("[[:หมวดหมู่:ภาษา%s|ภาษา%s]]"):format(lang, lang)
labels["ภาษา" .. lang .. " (หัวข้อ)"] = {
type = "related-to",
description = "=" .. desc,
parents = {"ชื่อภาษา"},
}
end
labels["การสื่อสาร"] = {
type = "related-to",
description = "default",
parents = {"หัวข้อทั้งหมด"},
}
labels["communication"] = labels["การสื่อสาร"]
labels["ชุดตัวอักษร"] = {
type = "name",
description = "default",
parents = {"ระบบการเขียน"},
}
labels["alphabets"] = labels["ชุดตัวอักษร"]
labels["artificial languages"] = { -- distinguish from "cat:constructed languages" family category
type = "name",
description = "={{w|constructed language}}s",
parents = {"ชื่อภาษา"},
}
labels["ภาษาท่าทาง"] = {
type = "related-to",
description = "default",
parents = {"ภาษา (หัวข้อ)", "การสื่อสารโดยไม่ใช้คำพูด"},
}
labels["body language"] = labels["ภาษาท่าทาง"]
labels["broadcasting"] = {
type = "related-to",
description = "default",
parents = {"สื่อ", "โทรคมนาคม"},
}
labels["Chinese character components"] = {
type = "set",
description = "=[[Chinese character]] [[component]]s",
parents = {"ตัวอักษร สัญลักษณ์ และเครื่องหมายวรรคตอน"},
}
labels["diacritical marks"] = {
type = "set",
description = "default",
parents = {"ตัวอักษร สัญลักษณ์ และเครื่องหมายวรรคตอน"},
}
labels["ภาษาถิ่น"] = {
type = "set",
description = "default",
parents = {"ภาษา (หัวข้อ)"},
}
labels["dialects"] = labels["ภาษาถิ่น"]
labels["dictation"] = {
type = "related-to",
description = "default",
parents = {"การสื่อสาร"},
}
labels["จารึกศาสตร์"] = {
type = "related-to",
description = "default",
parents = {"อักขรวิทยาโบราณ", "การเขียน"},
}
labels["epigraphy"] = labels["จารึกศาสตร์"]
labels["ภาษาสูญแล้ว"] = {
type = "name",
description = "default",
parents = {"ชื่อภาษา"},
}
labels["extinct languages"] = labels["ภาษาสูญแล้ว"]
labels["facial expressions"] = {
type = "set",
description = "default",
parents = {"การสื่อสารโดยไม่ใช้คำพูด", "หน้า"},
}
labels["ภาพพจน์ (หัวข้อ)"] = {
type = "set",
description = "=[[figure of speech|figures of speech]]",
parents = {"วาทศาสตร์"},
}
labels["figures of speech"] = labels["ภาพพจน์ (หัวข้อ)"]
labels["ธง"] = {
type = "related-to,name,type",
description = "default",
parents = {"การสื่อสาร"},
}
labels["flags"] = labels["ธง"]
labels["ภาษาเฉพาะวงการ"] = {
type = "related-to",
description = "default",
parents = {"ภาษา (หัวข้อ)"},
}
labels["jargon"] = labels["ภาษาเฉพาะวงการ"]
labels["Han characters"] = {
type = "related-to",
description = "default",
parents = {"ระบบการเขียน"},
}
labels["ภาษา (หัวข้อ)"] = {
type = "related-to",
description = "default",
parents = {"การสื่อสาร"},
}
labels["language"] = labels["ภาษา (หัวข้อ)"]
labels["กลุ่มภาษา (หัวข้อ)"] = {
type = "name",
description = "=[[language family|language families]], both accepted and controversial",
parents = {"ภาษา (หัวข้อ)", "ชื่อ (หัวข้อ)"},
}
labels["language families"] = labels["กลุ่มภาษา (หัวข้อ)"]
labels["ชื่อภาษา"] = {
type = "name",
description = "default",
parents = {"ภาษา (หัวข้อ)", "ชื่อ (หัวข้อ)"},
}
labels["languages"] = labels["ชื่อภาษา"]
labels["ตัวอักษร สัญลักษณ์ และเครื่องหมายวรรคตอน"] = {
type = "set",
description = "=[[letter]]s, [[symbol]]s, and [[punctuation]]",
parents = {"อักขรวิธี"},
}
labels["letters, symbols, and punctuation"] = labels["ตัวอักษร สัญลักษณ์ และเครื่องหมายวรรคตอน"]
labels["เหตุผลวิบัติ"] = {
type = "set",
description = "=[[logical fallacy|logical fallacies]], clearly defined errors in reasoning used to support or refute an argument",
additional = "{{also|หมวดหมู่:{{{langcode}}}:อคติ}}",
parents = {"วาทศาสตร์", "ตรรกศาสตร์"},
}
labels["logical fallacies"] = labels["เหตุผลวิบัติ"]
labels["สื่อ"] = {
type = "related-to",
description = "default",
parents = {"การสื่อสาร"},
}
labels["media"] = labels["สื่อ"]
labels["โทรศัพท์เคลื่อนที่"] = {
type = "related-to,set",
description = "default",
parents = {"โทรศัพท์"},
}
labels["mobile phones"] = labels["โทรศัพท์เคลื่อนที่"]
labels["การสื่อสารโดยไม่ใช้คำพูด"] = {
type = "related-to",
description = "default",
parents = {"การสื่อสาร"},
}
labels["nonverbal communication"] = labels["การสื่อสารโดยไม่ใช้คำพูด"]
labels["อักขรวิธี"] = {
type = "related-to",
description = "default",
parents = {"การเขียน"},
}
labels["orthography"] = labels["อักขรวิธี"]
labels["อักขรวิทยาโบราณ"] = {
type = "related-to",
description = "default",
parents = {"การเขียน"},
}
labels["palaeography"] = labels["อักขรวิทยาโบราณ"]
labels["ไปรษณีย์"] = {
type = "related-to",
description = "=[[post#Noun|post]] or [[mail#Noun|mail]]",
parents = {"การสื่อสาร"},
}
labels["post"] = labels["ไปรษณีย์"]
labels["postal abbreviations"] = {
type = "name",
description = "default",
parents = {"ไปรษณีย์"},
}
labels["public relations"] = {
type = "related-to",
description = "default no singularize",
parents = {"การสื่อสาร"},
}
labels["เครื่องหมายวรรคตอน (หัวข้อ)"] = {
type = "set",
description = "default",
parents = {"ตัวอักษร สัญลักษณ์ และเครื่องหมายวรรคตอน"},
}
labels["punctuation marks"] = labels["เครื่องหมายวรรคตอน (หัวข้อ)"]
labels["วิทยุ"] = {
type = "related-to",
description = "default",
parents = {"โทรคมนาคม"},
}
labels["radio"] = labels["วิทยุ"]
labels["วาทศาสตร์"] = {
type = "related-to",
description = "default",
parents = {"ภาษา (หัวข้อ)"},
}
labels["rhetoric"] = labels["วาทศาสตร์"]
labels["ภาษามือ"] = {
type = "name",
description = "default",
parents = {"ชื่อภาษา"},
}
labels["sign languages"] = labels["ภาษามือ"]
labels["ป้าย"] = {
type = "related-to,name,type",
description = "default",
parents = {"การสื่อสาร"},
}
labels["signs"] = labels["ป้าย"]
labels["สังคมภาษณ์"] = {
type = "name",
description = "default",
parents = {"ภาษา (หัวข้อ)"},
}
labels["sociolects"] = labels["สังคมภาษณ์"]
labels["สัญลักษณ์ (หัวข้อ)"] = {
type = "set",
description = "=[[symbol]]s, especially [[mathematical]] and [[scientific]] symbols",
additional = "Most symbols have equivalent meanings in many languages and can therefore be found in [[:หมวดหมู่:สัญลักษณ์ภาษาร่วม]].",
parents = {"ตัวอักษร สัญลักษณ์ และเครื่องหมายวรรคตอน"},
}
labels["symbols"] = labels["สัญลักษณ์ (หัวข้อ)"]
labels["การพูด"] = {
type = "related-to",
description = "default",
parents = {"ภาษา (หัวข้อ)", "พฤติกรรมมนุษย์"},
}
labels["talking"] = labels["การพูด"]
labels["โทรคมนาคม"] = {
type = "related-to",
description = "default no singularize",
parents = {"การสื่อสาร", "เทคโนโลยี"},
}
labels["telecommunications"] = labels["โทรคมนาคม"]
labels["โทรเลข"] = {
type = "related-to",
description = "default",
parents = {"โทรคมนาคม", "อิเล็กทรอนิกส์"},
wpcat = true,
commonscat = true,
}
labels["telegraphy"] = labels["โทรเลข"]
labels["โทรศัพท์"] = {
type = "related-to",
description = "default",
parents = {"โทรคมนาคม", "อิเล็กทรอนิกส์"},
}
labels["telephony"] = labels["โทรศัพท์"]
labels["การส่งข้อความ"] = {
type = "related-to",
description = "default",
parents = {"โทรคมนาคม"},
}
labels["texting"] = labels["การส่งข้อความ"]
labels["textual division"] = {
type = "related-to",
description = "default",
parents = {"การเขียน"},
}
labels["การเรียงพิมพ์"] = { -- เข้าใจง่ายกว่า "การจัดตัวอักษร"
type = "related-to",
description = "default",
parents = {"การเขียน", "การพิมพ์"},
}
labels["typography"] = labels["การเรียงพิมพ์"]
labels["การเขียน"] = {
type = "related-to",
description = "default",
parents = {"ภาษา (หัวข้อ)", "พฤติกรรมมนุษย์"},
}
labels["writing"] = labels["การเขียน"]
labels["ระบบการเขียน"] = {
type = "set",
description = "default",
parents = {"การเขียน"},
}
labels["writing systems"] = labels["ระบบการเขียน"]
return labels
hbp5fvuleelf1ww3xs9nu0zzlplpube
รับรอง
0
46367
5722557
2674212
2026-05-05T11:17:01Z
OctraBot
3198
/* คำกริยา */
5722557
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
{{com|th|รับ|รอง}}
=== การออกเสียง ===
{{th-pron|รับ-รอง}}
=== คำกริยา ===
{{th-verb|~}}
# [[รับประกัน]]
#: {{ux|th|รับรองว่าเป็นของแท้}}
# [[ต้อนรับ]]
#: {{ux|th|รับรองแขกเมือง}}
==== ลูกคำ ====
{{col|th|title=รับประกัน|ใบรับรอง|หนังสือรับรอง|ไปรษณีย์รับรอง|ผู้รับรอง|รับรองเพื่อแก้หน้า|หนังสือรับรองการทำประโยชน์|คำรับรอง}}
{{col|th|title=ต้อนรับ|บ้านรับรอง|ค่ารับรอง}}
==== คำแปลภาษาอื่น ====
{{trans-top|รับประกัน}}
* ไทลื้อ: {{t+|khb|ᦂᦻᧈᦉᧁᧈ}}
* ลาว: {{t+|lo|ຮັບຮອງ}}
{{trans-bottom}}
fy27e5a42iqud4nczav5n8ad3n2enuz
5722558
5722557
2026-05-05T11:17:27Z
OctraBot
3198
/* ลูกคำ */
5722558
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
{{com|th|รับ|รอง}}
=== การออกเสียง ===
{{th-pron|รับ-รอง}}
=== คำกริยา ===
{{th-verb|~}}
# [[รับประกัน]]
#: {{ux|th|รับรองว่าเป็นของแท้}}
# [[ต้อนรับ]]
#: {{ux|th|รับรองแขกเมือง}}
==== ลูกคำ ====
{{col|th|title=รับประกัน|ใบรับรอง|หนังสือรับรอง|ไปรษณีย์รับรอง|ผู้รับรอง|รับรองเพื่อแก้หน้า|หนังสือรับรองการทำประโยชน์|คำรับรอง}}
{{col|th|title=ต้อนรับ|บ้านรับรอง|ค่ารับรอง|ห้องรับรอง}}
==== คำแปลภาษาอื่น ====
{{trans-top|รับประกัน}}
* ไทลื้อ: {{t+|khb|ᦂᦻᧈᦉᧁᧈ}}
* ลาว: {{t+|lo|ຮັບຮອງ}}
{{trans-bottom}}
9xx8nwm5dj1xwgo3yldsel1z5gsudch
ประกัน
0
46398
5722553
2025363
2026-05-05T11:07:48Z
OctraBot
3198
/* คำนาม */
5722553
wikitext
text/x-wiki
== ภาษาไทย ==
===รากศัพท์===
{{bor+|th|km|ប្រកាន់}}; เทียบ{{cog|okz|ផ្កន៑}}; ร่วมเชื้อสายกับ{{cog|lo|ປະກັນ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-กัน}}
=== คำกริยา ===
{{th-verb}}
# [[รับรอง]][[ว่า]][[จะ]][[รับผิด]][[ใน]][[ความเสียหาย]][[ที่]][[เกิด]][[ขึ้น]]
# รับรองว่าจะ[[มี]][[หรือ]][[ไม่]]มี[[เหตุการณ์]][[นั้น]] ๆ
==== คำแปลภาษาอื่น ====
{{trans-top|รับรองว่าจะมีหรือไม่มีเหตุการณ์นั้น ๆ}}
* จีน:
*: จีนกลาง: {{t+|cmn|確保}}, {{t+|cmn|确保|tr=quèbǎo}}
* ไทลื้อ: {{t|khb|ᦁᦱᦙᦃᦱᧄᧈ}}
* ลาว: {{t|lo|ປະກັນ}}
* อังกฤษ: {{t|en|ensure|tr=เอ็นฌุร์}}
{{trans-bottom}}
=== คำนาม ===
{{th-noun}}
# [[หลักทรัพย์]]ที่[[ให้]][[ไว้]][[เป็น]][[เครื่อง]]รับรอง
==== ลูกคำ ====
{{col|th|ประกันภัย|ประกันสังคม|ค้ำประกัน|จัดประกัน|เจ้าหนี้มีประกัน|ประกันชีวิต|ประกันวินาศภัย|ตัวประกัน|นายประกัน|ประกันเชิงลา|ผัดวันประกันพรุ่ง|รับประกัน|ประกันทัณฑ์บน|หลักประกัน|เอาหัวเป็นประกัน|ประกันราคา|ประกันตัว|ประกันสุขภาพ|ผู้รับประกัน|ผู้เอาประกัน}}
6fei9cehoe712jlsoskbz0kos06nnum
5722554
5722553
2026-05-05T11:10:37Z
OctraBot
3198
/* ลูกคำ */
5722554
wikitext
text/x-wiki
== ภาษาไทย ==
===รากศัพท์===
{{bor+|th|km|ប្រកាន់}}; เทียบ{{cog|okz|ផ្កន៑}}; ร่วมเชื้อสายกับ{{cog|lo|ປະກັນ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-กัน}}
=== คำกริยา ===
{{th-verb}}
# [[รับรอง]][[ว่า]][[จะ]][[รับผิด]][[ใน]][[ความเสียหาย]][[ที่]][[เกิด]][[ขึ้น]]
# รับรองว่าจะ[[มี]][[หรือ]][[ไม่]]มี[[เหตุการณ์]][[นั้น]] ๆ
==== คำแปลภาษาอื่น ====
{{trans-top|รับรองว่าจะมีหรือไม่มีเหตุการณ์นั้น ๆ}}
* จีน:
*: จีนกลาง: {{t+|cmn|確保}}, {{t+|cmn|确保|tr=quèbǎo}}
* ไทลื้อ: {{t|khb|ᦁᦱᦙᦃᦱᧄᧈ}}
* ลาว: {{t|lo|ປະກັນ}}
* อังกฤษ: {{t|en|ensure|tr=เอ็นฌุร์}}
{{trans-bottom}}
=== คำนาม ===
{{th-noun}}
# [[หลักทรัพย์]]ที่[[ให้]][[ไว้]][[เป็น]][[เครื่อง]]รับรอง
==== ลูกคำ ====
{{col|th|ประกันภัย|ประกันสังคม|ค้ำประกัน|จัดประกัน|เจ้าหนี้มีประกัน|ประกันชีวิต|ประกันวินาศภัย|ตัวประกัน|นายประกัน|ประกันเชิงลา|ผัดวันประกันพรุ่ง|รับประกัน|ประกันทัณฑ์บน|หลักประกัน|เอาหัวเป็นประกัน|ประกันราคา|ประกันตัว|ประกันสุขภาพ|ผู้รับประกัน|ผู้เอาประกัน|เบี้ยประกัน}}
47s2czwllabegq9pqw8h5ahla9cqwqr
5722555
5722554
2026-05-05T11:12:21Z
OctraBot
3198
/* ลูกคำ */
5722555
wikitext
text/x-wiki
== ภาษาไทย ==
===รากศัพท์===
{{bor+|th|km|ប្រកាន់}}; เทียบ{{cog|okz|ផ្កន៑}}; ร่วมเชื้อสายกับ{{cog|lo|ປະກັນ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-กัน}}
=== คำกริยา ===
{{th-verb}}
# [[รับรอง]][[ว่า]][[จะ]][[รับผิด]][[ใน]][[ความเสียหาย]][[ที่]][[เกิด]][[ขึ้น]]
# รับรองว่าจะ[[มี]][[หรือ]][[ไม่]]มี[[เหตุการณ์]][[นั้น]] ๆ
==== คำแปลภาษาอื่น ====
{{trans-top|รับรองว่าจะมีหรือไม่มีเหตุการณ์นั้น ๆ}}
* จีน:
*: จีนกลาง: {{t+|cmn|確保}}, {{t+|cmn|确保|tr=quèbǎo}}
* ไทลื้อ: {{t|khb|ᦁᦱᦙᦃᦱᧄᧈ}}
* ลาว: {{t|lo|ປະກັນ}}
* อังกฤษ: {{t|en|ensure|tr=เอ็นฌุร์}}
{{trans-bottom}}
=== คำนาม ===
{{th-noun}}
# [[หลักทรัพย์]]ที่[[ให้]][[ไว้]][[เป็น]][[เครื่อง]]รับรอง
==== ลูกคำ ====
{{col|th|ประกันภัย|ประกันสังคม|ค้ำประกัน|จัดประกัน|เจ้าหนี้มีประกัน|ประกันชีวิต|ประกันวินาศภัย|ตัวประกัน|นายประกัน|ประกันเชิงลา|ผัดวันประกันพรุ่ง|รับประกัน|ประกันทัณฑ์บน|หลักประกัน|เอาหัวเป็นประกัน|ประกันราคา|ประกันตัว|ประกันสุขภาพ|ผู้รับประกัน|ผู้เอาประกัน|เบี้ยประกัน|ประกันภัยชดเชยรายได้}}
cply0nj7n244q74dnsn3aekykfl3bf2
5722556
5722555
2026-05-05T11:12:35Z
OctraBot
3198
/* ลูกคำ */
5722556
wikitext
text/x-wiki
== ภาษาไทย ==
===รากศัพท์===
{{bor+|th|km|ប្រកាន់}}; เทียบ{{cog|okz|ផ្កន៑}}; ร่วมเชื้อสายกับ{{cog|lo|ປະກັນ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-กัน}}
=== คำกริยา ===
{{th-verb}}
# [[รับรอง]][[ว่า]][[จะ]][[รับผิด]][[ใน]][[ความเสียหาย]][[ที่]][[เกิด]][[ขึ้น]]
# รับรองว่าจะ[[มี]][[หรือ]][[ไม่]]มี[[เหตุการณ์]][[นั้น]] ๆ
==== คำแปลภาษาอื่น ====
{{trans-top|รับรองว่าจะมีหรือไม่มีเหตุการณ์นั้น ๆ}}
* จีน:
*: จีนกลาง: {{t+|cmn|確保}}, {{t+|cmn|确保|tr=quèbǎo}}
* ไทลื้อ: {{t|khb|ᦁᦱᦙᦃᦱᧄᧈ}}
* ลาว: {{t|lo|ປະກັນ}}
* อังกฤษ: {{t|en|ensure|tr=เอ็นฌุร์}}
{{trans-bottom}}
=== คำนาม ===
{{th-noun}}
# [[หลักทรัพย์]]ที่[[ให้]][[ไว้]][[เป็น]][[เครื่อง]]รับรอง
==== ลูกคำ ====
{{col|th|ประกันภัย|ประกันสังคม|ค้ำประกัน|จัดประกัน|เจ้าหนี้มีประกัน|ประกันชีวิต|ประกันวินาศภัย|ตัวประกัน|นายประกัน|ประกันเชิงลา|ผัดวันประกันพรุ่ง|รับประกัน|ประกันทัณฑ์บน|หลักประกัน|เอาหัวเป็นประกัน|ประกันราคา|ประกันตัว|ประกันสุขภาพ|ผู้รับประกัน|ผู้เอาประกัน|เบี้ยประกัน|ประกันชดเชยรายได้}}
4yy1pxyi84kbt3wg0ohqkyi8pgymafo
มอดูล:category tree/รากศัพท์
828
50724
5722507
5720513
2026-05-05T01:48:36Z
OctraBot
3198
5722507
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local en_utilities_module = "Module:en-utilities"
local m_str_utils = require("Module:string utilities")
local add_indefinite_article = require(en_utilities_module).add_indefinite_article
local full_link = require("Module:links").full_link
local get_lang_by_name = require("Module:languages").getByCanonicalName
local insert = table.insert
local pattern_escape = m_str_utils.pattern_escape
local plain_gsub = m_str_utils.plain_gsub
local pluralize_pos = require("Module:headword").pluralize_pos
local pos_lemma_or_nonlemma = require("Module:headword").pos_lemma_or_nonlemma
local serial_comma_join = require("Module:table").serialCommaJoin
local tag_text = require("Module:script utilities").tag_text
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ศัพท์แบ่งตามรากศัพท์"] = {
description = "{{{langname}}} terms categorized by their etymologies.",
umbrella_parents = "มูลฐาน",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["terms by etymology"] = labels["ศัพท์แบ่งตามรากศัพท์"]
labels["AABB-type reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] in an AABB pattern.",
breadcrumb = "AABB-type",
parents = {"คำซ้ำ"},
}
labels["apophonic reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] with only a change in a vowel sound.",
breadcrumb = "apophonic",
parents = {"คำซ้ำ"},
}
labels["การผันรูปย้อนกลับ"] = {
description = "{{{langname}}} terms formed by reversing a supposed regular formation, removing part of an older term.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["back-formations"] = labels["การผันรูปย้อนกลับ"]
labels["คำหลอม"] = {
description = "{{{langname}}} terms formed by combinations of other words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["blends"] = labels["คำหลอม"]
labels["ศัพท์ที่ยืมมา"] = {
description = "{{{langname}}} terms that are loanwords, i.e. words that were directly incorporated from another language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["borrowed terms"] = labels["ศัพท์ที่ยืมมา"]
labels["catachreses"] = {
description = "{{{langname}}} terms derived from misuses or misapplications of other terms.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่บัญญัติ"] = {
description = "{{{langname}}} terms coined by an identifiable person, organization or other such entity.",
parents = {"terms attributed to a specific source"},
umbrella_parents = {name = "terms attributed to a specific source", is_label = true, sort = " "},
}
labels["coinages"] = labels["ศัพท์ที่บัญญัติ"]
labels["coordinated pairs"] = {
description = "Terms in {{{langname}}} consisting of a pair of terms joined by a [[coordinating conjunction]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated triples"] = {
description = "Terms in {{{langname}}} consisting of three terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quadruples"] = {
description = "Terms in {{{langname}}} consisting of four terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quintuples"] = {
description = "Terms in {{{langname}}} consisting of five terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากคำนาม"] = {
description = "{{{langname}}} terms derived from a noun.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["denominals"] = labels["denominals"]
labels["ศัพท์ที่รับมาจากคำกริยา"] = {
description = "{{{langname}}} terms derived from a verb.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["deverbals"] = labels["deverbals"]
labels["ศัพท์ที่ร่วมราก"] = {
description = "{{{langname}}} terms that trace their etymology from ultimately the same source as other terms in the same language, but by different routes, and often with subtly or substantially different meanings.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["doublets"] = labels["ศัพท์ที่ร่วมราก"]
labels["elongated forms"] = {
description = "{{{langname}}} terms where one or more letters or sounds is repeated for emphasis or effect.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากชื่อบุคคล"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["eponyms"] = labels["ศัพท์ที่รับมาจากชื่อบุคคล"]
labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"] = {
description = "{{{langname}}} terms that originate from [[trademark]]s, [[brand]]s and company names which have become [[genericized]]; that is, fallen into common usage in the target market's [[vernacular]], even when referring to other competing brands.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "เครื่องหมายการค้า"},
}
labels["genericized trademarks"] = labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"]
labels["ghost words"] = {
description = "{{{langname}}} terms that were originally erroneous or fictitious, published in a reference work as if they were genuine as a result of typographical error, misreading, or misinterpretation, or as [[:w:Fictitious entry|fictitious entries]], jokes, or hoaxes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["gramograms"] = {
description = "{{{langname}}} [[gramogram]]s – terms that are partially or completely spelled with [[homophone|homophonous]] letters.",
parents = {"rebuses"},
}
labels["haplological words"] = {
description = "{{{langname}}} words that underwent [[haplology]]: thus, their origin involved a loss or omission of a repeated sequence of sounds.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["homophonic translations"] = {
description = "{{{langname}}} terms that were borrowed by matching the etymon phonetically, without regard for the sense; compare [[phono-semantic matching]] and [[Hobson-Jobson]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["hybridisms"] = {
description = "{{{langname}}} terms formed by elements of different linguistic origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบทอด"] = {
description = "{{{langname}}} terms that were inherited from an earlier stage of the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["inherited terms"] = labels["ศัพท์ที่สืบทอด"]
labels["internationalisms"] = {
description = "{{{langname}}} loanwords which also exist in many other languages with the same or similar etymology.",
additional = "Terms should be here preferably only if the immediate source language is not known for certain. Entries are added into this category by [[Template:internationalism]]; see it for more information.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["legal doublets"] = {
description = "{{{langname}}} legal [[doublet]]s – a legal doublet is a standardized phrase commonly use in legal documents, proceedings etc. which includes two words that are near synonyms.",
parents = {"coordinated pairs"},
}
labels["legal triplets"] = {
description = "{{{langname}}} legal [[triplet]]s – a legal triplet is a standardized phrase commonly use in legal documents, proceedings etc which includes three words that are near synonyms.",
parents = {"coordinated triples"},
}
labels["LLM coinages"] = {
description = "{{{langname}}} terms that have been coined by {{w|large language models}} rather than humans.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["merisms"] = {
description = "{{{langname}}} [[merism]]s – terms that are [[coordinate]]s that, combined, are a synonym for a totality.",
parents = {"coordinated pairs"},
}
labels["metonyms"] = {
description = "{{{langname}}} terms whose origin involves calling a thing or concept not by its own name, but by the name of something intimately associated with that thing or concept.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["นวศัพท์"] = {
description = "{{{langname}}} terms that have been only recently acknowledged.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["neologisms"] = labels["นวศัพท์"]
labels["nonce terms"] = {
description = "{{{langname}}} terms that have been invented for a single occasion.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["number homophones"] = {
description = "{{{langname}}} terms that are partially or completely spelled with [[homophone|homophonous]] numbers.",
parents = {"rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["numerical contractions"] = {
description = "{{{langname}}} numerical contractions. In these, the number either denotes omitted characters ({{m+|en|globalization}} → {{m|en|g11n}}) or duplication ({{m+|kne|Kankanaey}} → {{m|kne|Kan2aey}}).",
parents = {"contractions", "rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["ศัพท์ที่เลียนเสียงธรรมชาติ"] = {
description = "{{{langname}}} terms that were coined to sound like what they represent.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["onomatopoeias"] = labels["ศัพท์ที่เลียนเสียงธรรมชาติ"]
labels["piecewise doublets"] = {
description = "{{{langname}}} terms that are [[ภาคผนวก:อภิธานศัพท์#piecewise doublet|piecewise doublets]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
--[=[ thwikt don't use specific terms below
for _, ism_and_langname in ipairs({
{"anglicisms", "English"},
{"Arabisms", "Arabic"},
{"Gallicisms", "French"},
{"Germanisms", "German"},
{"Hispanisms", "Spanish"},
{"Italianisms", "Italian"},
{"Latinisms", "Latin"},
{"Japonisms", "Japanese"},
}) do
local ism, langname = unpack(ism_and_langname)
labels["pseudo-" .. ism] = {
description = "{{{langname}}} terms that appear to be " .. langname .. ", but are not used or have an unrelated meaning in " .. langname .. " itself.",
parents = {"pseudo-loans"},
umbrella_parents = {name = "pseudo-loans", is_label = true, sort = " "},
}
end
--]=]
labels["rebracketings"] = {
description = "{{{langname}}} terms that have interacted with another word in such a way that the boundary between the words has been modified.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["rebuses"] = {
description = "{{{langname}}} [[rebus]]es – terms that are partially or completely represented by images, symbols or numbers, often as a form of wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบสร้าง"] = {
description = "{{{langname}}} terms that are not directly attested, but have been reconstructed through other evidence.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["reconstructed terms"] = labels["ศัพท์ที่สืบสร้าง"]
labels["reduplicated coordinated pairs"] = {
description = "{{{langname}}} reduplicated coordinated pairs.",
breadcrumb = "reduplicated",
parents = {"coordinated pairs", "คำซ้ำ"},
}
labels["reduplicated coordinated triples"] = {
description = "{{{langname}}} reduplicated coordinated triples.",
breadcrumb = "reduplicated",
parents = {"coordinated triples", "คำซ้ำ"},
}
labels["reduplicated coordinated quadruples"] = {
description = "{{{langname}}} reduplicated coordinated quadruples.",
breadcrumb = "reduplicated",
parents = {"coordinated quadruples", "คำซ้ำ"},
}
labels["reduplicated coordinated quintuples"] = {
description = "{{{langname}}} reduplicated coordinated quintuples.",
breadcrumb = "reduplicated",
parents = {"coordinated quintuples", "คำซ้ำ"},
}
labels["คำซ้ำ"] = {
description = "{{{langname}}} terms that underwent [[reduplication]], so their origin involved a repetition of roots or stems.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["reduplications"] = labels["คำซ้ำ"]
labels["retronyms"] = {
description = "{{{langname}}} terms that serve as new unique names for older objects or concepts whose previous names became ambiguous.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ราก"] = {
description = "Basic morphemes from which {{{langname}}} words are formed.",
parents = {"หน่วยคำ"},
}
labels["roots"] = labels["ราก"]
labels["Sanskritic formations"] = {
description = "{{{langname}}} terms coined from [[tatsama]] [[word]]s and/or [[affix]]es.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่รับมาจากภาษาสันสกฤต"},
}
labels["sound-symbolic terms"] = {
description = "{{{langname}}} terms that use {{w|sound symbolism}} to express ideas but which are not necessarily strictly speaking [[onomatopoeic]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelled-out initialisms"] = {
description = "{{{langname}}} initialisms in which the letter names are spelled out.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelling pronunciations"] = {
description = "{{{langname}}} terms whose pronunciation was historically or presently affected by their spelling.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["คำผวน"] = {
description = "{{{langname}}} terms in which the initial sounds of component parts have been exchanged, as in \"crook and nanny\" for \"nook and cranny\".",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spoonerisms"] = labels["คำผวน"]
labels["taxonomic eponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people, used for [[taxonomy]].",
parents = {"ศัพท์ที่รับมาจากชื่อบุคคล"},
}
labels["terms attributed to a specific source"] = {
description = "{{{langname}}} terms coined by an identifiable person or deriving from a known work.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms coined ex nihilo"] = {
description = "{{{langname}}} terms fabricated ''[[ex nihilo]]'', i.e. made up entirely rather than being derived from an existing source.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms containing fossilized case endings"] = {
description = "{{{langname}}} terms which preserve case morphology which is no longer analyzable within the contemporary grammatical system or which has been entirely lost from the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from area codes"] = {
description = "{{{langname}}} terms derived from [[area code]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"] = {
description = "{{{langname}}} terms derived from the shape of letters. This can include terms derived from the shape of any letter in any alphabet.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from the shape of letters"] = labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"]
labels["ศัพท์แบ่งตามราก"] = {
description = "{{{langname}}} terms categorized by the root they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์", {name = "ราก", sort = " "}},
}
labels["terms by root"] = labels["ศัพท์แบ่งตามราก"]
labels["ศัพท์แบ่งตามคำ"] = {
description = "{{{langname}}} terms categorized by the word they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms by word"] = labels["ศัพท์แบ่งตามคำ"]
labels["ศัพท์ที่รับมาจากบันเทิงคดี"] = {
description = "{{{langname}}} terms that originate from works of [[fiction]].",
breadcrumb = "บันเทิงคดี",
parents = {{name = "terms attributed to a specific source", sort = "บันเทิงคดี"}},
}
labels["terms derived from fiction"] = labels["ศัพท์ที่รับมาจากบันเทิงคดี"]
for _, data in ipairs {
{source="Dickensian works", desc="the works of [[w:Charles Dickens|Charles Dickens]]", topic_parent="Charles Dickens"},
{source="ดีซีคอมิกส์", desc="[[w:ดีซีคอมิกส์|ดีซีคอมิกส์]]"},
{source="โดราเอมอน", desc="[[w:Fujiko F. Fujio|Fujiko F. Fujio]]'s ''[[w:โดราเอมอน|โดราเอมอน]]''", displaytitle="''โดราเอมอน''"},
{source="ดรากอนบอล", desc="[[w:Akira Toriyama|Akira Toriyama]]'s ''[[w:ดรากอนบอล|ดรากอนบอล]]''", displaytitle="''ดรากอนบอล''"},
{source="ดักเบิร์กและเมาส์ตัน", desc="[[w:The Walt Disney Company|Disney]]'s [[w:Duck universe|Duckburg]] and [[w:Mickey Mouse universe|Mouseton]] universe",
topic_parent="ดิสนีย์"},
{source="ฟิวเจอรามา", desc="the animated television series ''{{w|ฟิวเจอรามา}}''", displaytitle = "''ฟิวเจอรามา''"},
{source="แฮร์รี่ พอตเตอร์", desc="the ''[[w:แฮร์รี่ พอตเตอร์|แฮร์รี่ พอตเตอร์]]'' series", displaytitle="''แฮร์รี่ พอตเตอร์''",
topic_parent="แฮร์รี่ พอตเตอร์"},
{source="Looney Tunes and Merrie Melodies", desc="''{{w|Looney Tunes}}'' and/or ''{{w|Merrie Melodies}}'', by {{w|Warner Bros. Animation}}", displaytitle = "''Looney Tunes'' and ''Merrie Melodies''"},
{source="หนึ่งเก้าแปดสี่", desc="[[w:George Orwell|George Orwell]]'s ''[[w:Nineteen Eighty-Four|Nineteen Eighty-Four]]''",
displaytitle="''หนึ่งเก้าแปดสี่''"},
{source="Seinfeld", desc="the American television sitcom ''{{w|Seinfeld}}'' (1989–1998)", displaytitle="''Seinfeld''"},
{source="Seussian works", desc="the works of [[w:Dr. Seuss|Dr. Seuss]]"},
{source="South Park", desc="the animated television series ''[[w:South Park|South Park]]''", displaytitle="''South Park''"},
{source="สตาร์ เทรค", desc="''[[w:สตาร์ เทรค|สตาร์ เทรค]]''", displaytitle="''สตาร์ เทรค''", topic_parent="สตาร์ เทรค"},
{source="สตาร์ วอร์ส", desc="''[[w:สตาร์ วอร์ส|สตาร์ วอร์ส]]''", displaytitle="''สตาร์ วอร์ส''", topic_parent="สตาร์ วอร์ส"},
{source="เดอะซิมป์สันส์", desc="''[[w:เดอะซิมป์สันส์|เดอะซิมป์สันส์]]''", displaytitle="''เดอะซิมป์สันส์''", topic_parent="เดอะซิมป์สันส์", sort="ซิมป์สันส์"},
{source="ปกรณัมของโทลคีน", desc="the [[legendarium]] of [[w:เจ. อาร์. อาร์. โทลคีน|เจ. อาร์. อาร์. โทลคีน]]", topic_parent="เจ. อาร์. อาร์. โทลคีน"},
} do
local parents = {{name = "ศัพท์ที่รับมาจากบันเทิงคดี", sort = data.sort or data.source}}
local umbrella_parents = {"หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"}
if data.topic_parent then
insert(parents, {name = "{{{langcode}}}:" .. data.topic_parent, raw = true})
insert(umbrella_parents, {name = data.topic_parent, raw = true})
end
labels["ศัพท์ที่รับมาจาก" .. data.source] = {
description = "{{{langname}}} terms that originate from " .. data.desc .. ".",
breadcrumb = data.displaytitle or data.source,
parents = parents,
umbrella = {
parents = umbrella_parents,
displaytitle = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle .. "แบ่งตามภาษา" or nil,
breadcrumb = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle,
},
displaytitle = data.displaytitle and "ศัพท์{{{langcat}}}ที่รับมาจาก" .. data.displaytitle or nil,
}
end
labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"] = {
description = "{{{langname}}} terms derived from Greek mythology which have acquired an idiomatic meaning.",
breadcrumb = "ประมวลเรื่องปรัมปรากรีก",
parents = {{name = "terms attributed to a specific source", sort = "ประมวลเรื่องปรัมปรากรีก"}},
}
labels["terms derived from Greek mythology"] = labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"]
labels["ศัพท์ที่รับมาจากอาชีพ"] = {
description = "{{{langname}}} terms derived from names of occupations.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from occupations"] = labels["ศัพท์ที่รับมาจากอาชีพ"]
labels["ศัพท์ที่รับมาจากภาษาอื่น"] = {
description = "{{{langname}}} terms that originate from other languages.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from other languages"] = labels["ศัพท์ที่รับมาจากภาษาอื่น"]
labels["ศัพท์ที่รับมาจากไบเบิล"] = {
description = "{{{langname}}} terms that originate from the [[Bible]].",
breadcrumb = {name = "ไบเบิล", nocap = true},
parents = {{name = "terms attributed to a specific source", sort = "ไบเบิล"}},
}
labels["terms derived from the Bible"] = labels["ศัพท์ที่รับมาจากไบเบิล"]
labels["ศัพท์ที่รับมาจากนิทานอีสป"] = {
description = "{{{langname}}} terms that originate from [[Aesop]]'s Fables.",
breadcrumb = "นิทานอีสป",
parents = {{name = "terms attributed to a specific source", sort = "นิทานอีสป"}},
}
labels["terms derived from Aesop's Fables"] = labels["ศัพท์ที่รับมาจากนิทานอีสป"]
labels["terms derived from toponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious places.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived through romanized wordplay"] = {
description = "{{{langname}}} terms derived through romanized wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms making reference to character shapes"] = {
description = "{{{langname}}} terms making reference to character shapes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากกีฬา"] = {
description = "{{{langname}}} terms that originate from sports.",
breadcrumb = "กีฬา",
parents = {{name = "terms attributed to a specific source", sort = "กีฬา"}},
}
labels["terms derived from sport"] = labels["ศัพท์ที่รับมาจากกีฬา"]
labels["ศัพท์ที่รับมาจากเบสบอล"] = {
description = "{{{langname}}} terms that originate from baseball.",
breadcrumb = "เบสบอล",
parents = {{name = "ศัพท์ที่รับมาจากกีฬา", sort = "เบสบอล"}},
}
labels["terms derived from baseball"] = labels["ศัพท์ที่รับมาจากเบสบอล"]
labels["terms with Indo-Aryan extensions"] = {
description = "{{{langname}}} terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with lemma and non-lemma form etymologies"] = {
description = "{{{langname}}} terms consisting of both a lemma and non-lemma form, of different origins.",
breadcrumb = "lemma and non-lemma form",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple etymologies"] = {
description = "{{{langname}}} terms that are derived from multiple origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with multiple lemma etymologies"] = {
description = "{{{langname}}} lemmas that are derived from multiple origins.",
breadcrumb = "multiple lemmas",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple non-lemma form etymologies"] = {
description = "{{{langname}}} non-lemma forms that are derived from multiple origins.",
breadcrumb = "multiple non-lemma forms",
parents = {"terms with multiple etymologies"},
}
labels["ศัพท์ที่ไม่ทราบรากศัพท์"] = {
description = "{{{langname}}} terms whose etymologies have not yet been established.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "ไม่ทราบรากศัพท์"}},
}
labels["terms with unknown etymologies"] = labels["ศัพท์ที่ไม่ทราบรากศัพท์"]
labels["univerbations"] = {
description = "{{{langname}}} terms that result from the agglutination of two or more words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["words derived through corruption"] = {
description = "{{{langname}}} words that result from a non-specific or sporadic change.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "corruption"}},
}
labels["words derived through metathesis"] = {
description = "{{{langname}}} words that were created through [[metathesis]] from another word.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "metathesis"}},
}
labels["words that have undergone semantic shift"] = {
description = "{{{langname}}} words that show senses explained by [[semantic shift]].",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "semantic shift"}},
}
labels["words that have undergone semantic broadening"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[broadening]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic broadening"}},
}
labels["words that have undergone semantic narrowing"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[narrowing]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic narrowing"}},
}
labels["words that have undergone amelioration"] = {
description = "{{{langname}}} words that have gained a positive [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "amelioration"}},
}
labels["words that have undergone pejoration"] = {
description = "{{{langname}}} words that have gained a negative [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "pejoration"}},
}
labels["terms with origins in folklore"] = {
description = "{{{langname}}} terms that have an etymology rooted in folklore.",
breadcrumb = "Folklore",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "folklore"}, {name = "{{{langcode}}}:Folklore", raw = true}},
umbrella_parents = {{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", raw = true}, {name = "Folklore", raw = true, sort = " "}}
}
-- Add 'umbrella_parents' key if not already present.
for _, data in pairs(labels) do
-- NOTE: umbrella.parents overrides umbrella_parents if both are given.
if not data.umbrella_parents then
data.umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to terms categorized by their etymologies, such as types of compounds or borrowings.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์แบ่งตามรากศัพท์", is_label = true, sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to borrowed terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่ยืมมา", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to inherited terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่สืบทอด", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Indo-Aryan extensions"] = {
description = "Umbrella categories covering terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Multiple etymology subcategories by language"] = {
description = "Umbrella categories covering topics related to terms with multiple etymologies.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["ศัพท์ที่ยืมกลับไปยังภาษาเดิม"] = {
description = "Categories with terms in specific languages that were borrowed from a second language that previously borrowed the term from the first language.",
additional = "A well-known example is {{m+|en|salaryman}}, a term borrowed from Japanese which in turn was borrowed from the English words [[salary]] and [[man]].\n\n{{{umbrella_msg}}}",
parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_source(source_name, allow_family, name_type)
local source = get_lang_by_name(source_name, nil, true, allow_family)
if source == nil then
return nil
end
-- Check that the source name matches the expected form (e.g. getCanonicalName, getDisplayForm etc).
if source[name_type](source) == source_name then
return source
end
end
local function get_source_and_type_desc(source, term_type)
if source:getCode() == "ine-pro" and term_type:find("^roots?$") then
return "[[w:Proto-Indo-European root|Proto-Indo-European " .. term_type .. "]]"
end
return "[[w:" .. source:getWikipediaArticle() .. "|" .. source:getCanonicalName() .. "]] " .. term_type
end
local function get_source_and_source_desc(source_name)
-- HACK! Map 'taxonomic names', as generated by [[Module:etymology]], back to its canonical name
-- before calling getByCanonicalName(). We need a more general solution here.
local source_desc
if source_name == "taxonomic names" then
source_name = "taxonomic name"
source_desc = "[[w:taxonomic nomenclature|taxonomic names]]"
end
local source = get_source(source_name, true, "getCanonicalName") --th
if source == nil then
return
end
source_desc = source_desc or source:makeCategoryLink()
if source:hasType("family") then
source_desc = "one of the " .. source_desc
end
return source, source_desc
end
-----------------------------------------------------------------------------
------------------------------- word handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE word word' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
local function lang_is_semitic(lang)
return lang:inFamily("sem")
end
insert(handlers, function(data)
local labelpref, word_and_id = data.label:match("^(terms belonging to the word )(.+)$")
if not word_and_id then
return
end
local word, id = word_and_id:match("^(.+) %((.-)%)$")
if not word then
word = word_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local word_desc = is_semitic and "[[w:Semitic word|word]]" or "word"
local parents = {}
if id then
insert(parents, {name = labelpref .. word, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามคำ", sort = word_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style words)
local word_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(word, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(word_no_prefix_suffix, not_separator_c, ""))
local linked_word = data.lang and full_link({ term = word, lang = data.lang, gloss = id, id = id }, "term") or word
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter words", sort = word_and_id})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, word, tag_text(word, lang, nil, "term"))
end
local breadcrumb = tag_text(word, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. word_desc .. " " .. linked_word .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^terms by (.+) word$")
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian word]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source:getDisplayForm())
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "word") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
-----------------------------------------------------------------------------
------------------------------- Root handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE root ROOT' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
-- Handler for e.g. [[:Category:Yola terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Russian terms derived from the Proto-Indo-European word *swé]], and corresponding umbrella
-- categories [[:Category:Terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Terms derived from the Proto-Indo-European word *swé]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(handlers, function(data)
local source_name, term_type, term_and_id
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name, term_and_id = data.label:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+) (.+)$")
if source_name then
term_type = tt
break
end
end
if not source_name then
return
end
local term, id = term_and_id:match("^(.+) %((.-)%)$")
if not term then
term = term_and_id
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {
{
name = "ศัพท์แบ่งตาม" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
local umbrella_parents = {
{
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
if id then
insert(parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
sort = " "
})
insert(umbrella_parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
is_label = true,
sort = " "
})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, term, tag_text(term, source, nil, "term"))
end
local breadcrumb = tag_text(term, source, nil, "term") .. (id and " (" .. id .. ")" or "")
local term_page, alt_form
if term_type == "root" and lang_is_semitic(source) then
term_page = ("ภาคผนวก:ราก%s/%s"):format(source:getCanonicalName(), term)
alt_form = term
else
term_page = term
end
return {
description = "{{{langname}}} terms that originate ultimately from the " .. get_source_and_type_desc(source, term_type) .. " " .. full_link({
term = term_page,
alt = alt_form,
lang = source,
gloss = id,
id = id
}, "term") .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
no_by_language = true,
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = umbrella_parents,
}
}
end)
insert(handlers, function(data)
local labelpref, root_and_id = data.label:match("^(terms belonging to the root )(.+)$")
if not root_and_id then
return
end
local root, id = root_and_id:match("^(.+) %((.-)%)$")
if not root then
root = root_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local root_desc = is_semitic and "[[w:Semitic root|root]]" or "root"
local parents = {}
if id then
insert(parents, {name = labelpref .. root, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามราก", sort = root_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style roots)
local root_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(root, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(root_no_prefix_suffix, not_separator_c, ""))
local root_page, alt_form
if is_semitic then
root_page = ("ภาคผนวก:ราก%s/%s"):format(data.lang:getCanonicalName(), root)
alt_form = root
else
root_page = root
end
local linked_root = data.lang and full_link(
{ term = root_page, alt = alt_form, lang = data.lang, gloss = id, id = id }, "term") or root_page
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter roots", sort = root_and_id})
end
-- Italicize the root/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, root, tag_text(root, lang, nil, "term"))
end
local breadcrumb = tag_text(root, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. root_desc .. " " .. linked_root .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์แบ่งตามราก(.+)$")
if not source_name or source_name == "ศัพท์" then --th; excludes falsily detect ศัพท์แบ่งตามรากศัพท์
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian root]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source_name)
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "root") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
insert(handlers, function(data)
local root_shape, post, additional = data.label:match("^(.+)([ -])shaped roots$")
if not root_shape then
return
elseif data.lang and data.lang:getCode() == "ine-pro" then
additional = [=[
* '''e''' stands for the vowel of the root.
* '''C''' stands for any stop or ''s''.
* '''R''' stands for any resonant.
* '''H''' stands for any laryngeal.
* '''M''' stands for ''m'' or ''w'', when followed by a resonant.
* '''s''' stands for ''s'', when next to a stop.]=]
end
if root_shape == "irregularly" and post == " " then
return {
breadcrumb = "irregular",
description = "{{{langname}}} roots with a shape that violates the {{w|Proto-Indo-European root#Shape of a root|known rules on root shapes}}.",
additional = additional,
parents = {{name = "roots by shape", sort = "*"}},
umbrella = false,
}
elseif post == " " then
return
end
return {
breadcrumb = root_shape,
description = "{{{langname}}} roots with the shape ''" .. root_shape .. "''.",
additional = additional,
parents = {{name = "roots by shape", sort = root_shape}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
-------------------- Derived/inherited/borrowed handlers --------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form "LANG terms derived from SOURCE", where SOURCE is a language, etymology language
-- or family (e.g. "Indo-European languages"), along with corresponding umbrella categories of the form
-- "Terms derived from SOURCE".
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์ที่รับมาจากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่รับมาจากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- Compute description.
local desc = "{{{langname}}} terms that originate from " .. source_desc .. "."
local additional
if source:hasType("family") then
additional = "This category should, ideally, contain only other categories. Entries can be categorized here, too, when the proper subcategory is unclear. " ..
"If you know the exact language from which an entry categorized here is derived, please edit its respective entry."
end
-- Compute parents.
local derived_from_variety_of_self = false
local parent
local sortkey = source:getDisplayForm()
if source:hasType("etymology-only") then
-- By default, `parent` is the source's parent.
parent = source:getParent()
-- Check if the source is a variety (or subvariety) of the language.
if data.lang and source:hasParent(data.lang) then
derived_from_variety_of_self = true
end
-- If the language is the direct parent of the source or the parent is "und", then we use the family of the source as `parent` instead.
if data.lang and (parent:getCode() == data.lang:getCode() or parent:getCode() == "und") then
parent = source:getFamily()
end
-- Regular language or family.
else
local fam = source:getFamily()
if fam then
parent = fam
end
end
-- If `parent` does not exist, is the same as `source`, or would be "isolate languages" or "not a family", then we discard it.
if (not parent) or parent:getCode() == source:getCode() or parent:getCode() == "qfa-iso" or parent:getCode() == "qfa-not" or
parent:getCode() == "qfa-unc" then
parent = nil
derived_from_variety_of_self = false
-- Otherwise, get the display form.
else
parent = parent:getDisplayForm()
end
parent = parent and "ศัพท์ที่รับมาจาก" .. parent or "ศัพท์ที่รับมาจากภาษาอื่น"
local parents = {{name = parent, sort = sortkey}}
if derived_from_variety_of_self then
insert(parents, "Category:Categories for terms in a language derived from a term in a subvariety of that language")
end
-- Compute umbrella parents.
local cat_name = source:getCode() == "mul-tax" and "Taxonomic names" or source:getCategoryName()
-- If the source is etymology-only, its category will be handled by the lect handler in
-- [[Module:category tree/ภาษณ์]]. If it has a nonstandard name like 'Kölsch' (i.e. not a name like
-- 'American English' that has a language name in it), the lect handler won't handle it unless we tell it to do so
-- through the following call; this is an optimization to avoid expensive processing work on all manner of randomly
-- named categories.
if source:hasType("etymology-only") then
require("Module:category tree/ภาษณ์").export.register_likely_lect_parent_cat(cat_name)
end
local umbrella_parents = {
(source:hasType("family") or source:getCode() == "mul-tax") and {name = cat_name, raw = true, sort = " "} or
{name = cat_name, raw = true, sort = "terms derived from"}
}
-- Without the following, the breadcrumb trail for e.g. [[Category:Javanese terms derived from French]] looks like
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages »
-- Indo-European languages » Italic languages » Romance languages » Italo-Western Romance languages »
-- Western Romance languages » Gallo-Romance languages » Gallo-Rhaetian languages » Oïl languages » French
-- To reduce the length, we truncate the "languages" part of the breadcrumbs as long as this does not create
-- ambiguity (i.e. unless there is a language with the same name as the family). Hence, for the Category
-- [[Category:Javanese terms derived from Arabic]], we end up with
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages » Afroasiatic »
-- Semitic » West Semitic » Central Semitic » Arabic languages » Arabic
-- because "Arabic" is ambiguous between family and language (and script, for that matter).
local breadcrumb = source_name
if source:hasType("family") and breadcrumb:find("กลุ่มภาษา") then
local truncated_breadcrumb = breadcrumb:gsub("กลุ่มภาษา", "")
if not get_lang_by_name(truncated_breadcrumb, nil, "allow etym") then
breadcrumb = truncated_breadcrumb
end
end
return {
description = desc,
additional = additional,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
description = "Categories with terms that originate from " .. source_desc .. ".",
parents = umbrella_parents,
},
}
end)
-- Handler for categories of the form "LANG terms inherited/borrowed from SOURCE", where SOURCE is a language,
-- etymology language or family (e.g. "Indo-European languages"). Also handles umbrella categories of the form
-- "Terms inherited/borrowed from SOURCE".
local function inherited_borrowed_handler(etymtype)
return function(data)
local source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
return {
description = "{{{langname}}} terms " .. etymtype .. " from " .. source_desc .. ".",
breadcrumb = source_name,
parents = {
{name = "ศัพท์ที่" .. etymtype, sort = source_name},
{name = "ศัพท์ที่รับมาจาก" .. (source:hasType("family") and "กลุ่มภาษา" or "ภาษา") .. source_name, sort = " "}
},
umbrella = {
parents = {
{ name = "ศัพท์ที่รับมาจากภาษา" .. source_name, is_label = true, sort = " " },
etymtype == "inherited" and
{ name = "หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา", sort = source_name }
-- There are several types of borrowings mixed into the following holding category,
-- so keep these ones sorted under 'Terms borrowed from SOURCE_NAME' instead of just
-- 'SOURCE_NAME'.
or "หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
end
table.insert(handlers, inherited_borrowed_handler("ยืมมา"))
table.insert(handlers, inherited_borrowed_handler("สืบทอด"))
-----------------------------------------------------------------------------
------------------------ Borrowing subtype handlers -------------------------
-----------------------------------------------------------------------------
-- General handler for specific borrowing subtypes, such as learned borrowings, calques and phono-semantic matchings.
local function borrowing_subtype_handler(dest, source_name, parent_cat, spec)
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- normally uses of UNKNOWN should not show up to the end user
local dest_name = dest and dest:getCanonicalName() or "UNKNOWN"
local additional, umbrella_additional
if spec.additional then
if dest then
additional = spec.additional(source, dest)
else
umbrella_additional = spec.umbrella_additional(source)
end
else
if not spec.categorizing_templates then
error("Internal error: Must specify either `categorizing_templates` or the combination of `additional` and `umbrella_additional` in each borrowing subtype spec")
end
local extra_templates = {}
local extra_template_text
for i, template in ipairs(spec.categorizing_templates) do
if i > 1 then
insert(extra_templates, ("{{tl|%s|...}}"):format(template))
end
end
if #extra_templates > 0 then
extra_template_text = (" (or %s, using the same syntax)"):format(
serial_comma_join(extra_templates, {conj = "or"}))
else
extra_template_text = ""
end
if dest then
additional = ("To categorize a term into this category, use {{tl|%s|%s|%s|<var>source_term</var>}}%s, " ..
"where <code><var>source_term</var></code> is the %s term that the term in question " ..
"was borrowed from."):format(
spec.categorizing_templates[1], dest:getCode(), source:getCode(), extra_template_text, source_name)
else
umbrella_additional = ("To categorize a term into a language-specific subcategory, use " ..
"{{tl|%s|<var>destcode</var>|%s|<var>source_term</var>}}%s, where <code><var>destcode</var></code> " ..
"is the language code of the language in question (see [[Wiktionary:List of languages]]), and " ..
"<code><var>source_term</var></code> is the %s term that the term in question was " ..
"borrowed from."):format(spec.categorizing_templates[1], source:getCode(), extra_template_text, source_name)
end
end
return {
description = "{{{langname}}} " .. spec.from_source_desc:gsub("SOURCE", source_desc):gsub("DEST", dest_name),
additional = additional,
breadcrumb = source_name,
parents = {
{ name = parent_cat, sort = source_name },
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, sort = " " },
},
umbrella = {
additional = umbrella_additional,
parents = {
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, is_label = true, sort = " " },
"หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
-- Specs describing types of borrowings.
-- `from_source_desc` is the English description used in categories of the form "LANGUAGE BORTYPE from SOURCE",
-- e.g. "Arabic semantic loans from English". "SOURCE" in the description is replaced by the source language.
-- `umbrella_desc` is the English description used in categories of the form "LANGUAGE BORTYPE", e.g.
-- "Arabic semantic loans". This is an umbrella category grouping all the source-language-specific categories.
-- `uses_subtype_handler`, if true, means that the handler for "LANGUAGE BORTYPE from SOURCE" categories is
-- implemented by a generic "TYPE borrowings" handler (at the bottom of this section), so we don't need to
-- create a BORTYPE-specific handler.
-- `umbrella_parent`, if given, is the parent category of the umbrella categories of the form "LANGUAGE BORTYPE".
-- By default it is "borrowed terms". Some borrowing types replace this with "terms by etymology". (FIXME:
-- Review whether this is correct.)
-- `label_pattern`, if given, is a Lua pattern that matches the category name minus the language at the beginning.
-- It should have one capture, which is the source language. An example is "^terms partially calqued from (.+)$".
-- If omitted, it is generated from BORTYPE.
-- `categorizing_templates`, if given, is the list of templates that categorize into this category. They are assumed to
-- follow the syntax of {{bor}}. The first template in the list should be the preferred alias. The specified
-- templates are used to form the `additional` text displayed on the language-specific category page and
-- corresponding umbrella category page describing how to categorize into the category in question. In more complex
-- cases, you can omit this field and instead supply the `additional` and `umbrella_additional` fields (as is done
-- with adapted borrowings). You must either specify `categorizing_templates` or the combination of `additional` and
-- `umbrella_additional`.
-- `additional`, if given, is a function of two arguments (source and destination language objects) that will generate
-- the `additional` text displayed on the language-specific category page that describes how to categorize into the
-- category in question. This is an alternative to specifying `categorizing_templates`, used in more complex cases
-- (currently, with adapted borrowings).
-- `umbrella_additional`, if given, is a function of one argument (source language object) that will generate the
-- `additional` text displayed on the umbrella category page that describes how to categorize into the category in
-- question. This is an alternative to specifying `categorizing_templates`, used in more complex cases (currently,
-- with adapted borrowings).
local borrowing_specs = {
["ศัพท์ที่ยืมโดยเรียนรู้"] = {
from_source_desc = "terms that are learned [[loanword]]s from SOURCE, that is, terms that were directly incorporated from SOURCE instead of through normal language contact.",
umbrella_desc = "terms that are learned [[loanword]]s, that is, terms that were directly incorporated from another language instead of through normal language contact.",
uses_subtype_handler = true,
categorizing_templates = {"lbor", "learned borrowing"},
},
["ศัพท์ที่ยืมโดยกึ่งเรียนรู้"] = {
from_source_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s from SOURCE, that is, terms borrowed from SOURCE (a [[classical language]]) into DEST (a modern language) and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
umbrella_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s, that is, terms borrowed from a [[classical language]] into a modern language and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
uses_subtype_handler = true,
categorizing_templates = {"slbor", "semi-learned borrowing"},
},
["ศัพท์ที่ยืมอักขรวิธี"] = {
from_source_desc = "orthographic loans from SOURCE, i.e. terms that were borrowed from SOURCE in their script forms, not their pronunciations.",
umbrella_desc = "orthographic loans, i.e. terms that were borrowed in their script forms, not their pronunciations.",
uses_subtype_handler = true,
categorizing_templates = {"obor", "orthographic borrowing"},
},
["ศัพท์ที่ยืมโดยไม่ดัดแปลง"] = {
from_source_desc = "[[loanword]]s from SOURCE that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of DEST.",
umbrella_desc = "[[loanword]]s that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of the target language.",
uses_subtype_handler = true,
categorizing_templates = {"ubor", "unadapted borrowing"},
},
["ศัพท์ที่ยืมโดยดัดแปลง"] = {
from_source_desc = "[[loanwords]] from SOURCE formed with the addition of an affix to conform the term to the normal morphology of DEST.",
umbrella_desc = "[[loanword]]s formed with the addition of an affix to conform the term to the normal morphology of the target language.",
uses_subtype_handler = true,
additional = function(source, dest)
return ("To categorize a term into this category, use {{tl|af|%s|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|%s|3=type=abor|4=...}}, using the same syntax), where <code><var>source_term</var></code> is " ..
"the %s term that the term in question was borrowed from and <code><var>affix</var></code> " ..
"is the %s affix used to adapt the %s term. An example is " ..
"{{m+|pl|adresować||to address}}, which would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate " ..
"that is was formed from {{m+|fr|adresser}} with the addition of the Polish verb-forming affix " ..
"{{m|pl|-ować}}."):format(dest:getCode(), source:getCode(), dest:getCode(), source:getCanonicalName(), dest:getCanonicalName(),
source:getCanonicalName())
end,
umbrella_additional = function(source)
return ("To categorize a term into a language-specific subcategory, use {{tl|af|<var>destcode</var>|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|<var>destcode</var>|3=type=abor|4=...}}, using the same syntax), where " ..
"<code><var>destcode</var></code> is the language code of the target language in question (see " ..
"[[Wiktionary:List of languages]]); <code><var>source_term</var></code> is the %s term " ..
"that the term in question was borrowed from; and <code><var>affix</var></code> is the target-language " ..
"affix used to adapt the %s term. An example is {{m+|pl|adresować||to address}}, which " ..
"would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate that is was formed from " ..
"{{m+|fr|adresser}} with the addition of the Polish verb-forming affix {{m|pl|-ować}}."):format(
source:getCode(), source:getCanonicalName(), source:getCanonicalName())
end,
},
["ศัพท์ที่ยืมความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]] from SOURCE, i.e. terms one or more of whose definitions was borrowed from a term in SOURCE.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]], i.e. terms one or more of whose definitions was borrowed from a term in another language.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
categorizing_templates = {"sl", "semantic loan"},
},
["ศัพท์ที่แปลตรงตัวบางส่วน"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#partial calque|partially calqued]] from SOURCE, i.e. terms formed partly by piece-by-piece translations of SOURCE terms and partly by direct borrowing.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#partial calque|partial calques]], i.e. terms formed partly by piece-by-piece translations of terms from other languages and partly by direct borrowing.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวบางส่วนจากภาษา(.+)$",
categorizing_templates = {"pcal", "pclq", "partial calque"},
},
["ศัพท์ที่แปลตรงตัว"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#calque|calqued]] from SOURCE, i.e. terms formed by piece-by-piece translations of SOURCE terms.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#calque|calques]], i.e. terms formed by piece-by-piece translations of terms from other languages.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวจากภาษา(.+)$",
categorizing_templates = {"cal", "clq", "calque"},
},
["ศัพท์ที่เข้าคู่เสียง-ความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]] from SOURCE, i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]], i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
categorizing_templates = {"psm", "phono-semantic matching"},
},
["ศัพท์ที่ยืมเทียม"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]] from SOURCE, i.e. terms that appear to be SOURCE, but are not used or have an unrelated meaning in SOURCE itself.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]], i.e. terms that appear to be derived from another language, but are not used or have an unrelated meaning in that language itself.",
categorizing_templates = {"pl", "pseudo-loan"},
},
}
for bortype, spec in pairs(borrowing_specs) do
labels[bortype] = {
description = "{{{langname}}} " .. spec.umbrella_desc,
parents = {spec.umbrella_parent or "ศัพท์ที่ยืมมา"},
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
if not spec.uses_subtype_handler then
-- If the label pattern isn't specifically given, generate it from the `bortype`; but make sure to
-- escape hyphens in the pattern.
local label_pattern = spec.label_pattern or "^" .. pattern_escape(bortype) .. "จากภาษา(.+)$"
insert(handlers, function(data)
local source_name = data.label:match(label_pattern)
if source_name then
return borrowing_subtype_handler(data.lang, source_name, bortype, spec)
end
end)
end
end
insert(handlers, function(data)
local borrowing_type, source_name = data.label:match("^(ศัพท์ที่ยืม.+)จากภาษา(.+)$")
if borrowing_type then
local spec = borrowing_specs[borrowing_type]
return borrowing_subtype_handler(data.lang, source_name, borrowing_type, spec)
end
end)
-----------------------------------------------------------------------------
---------------------- Indo-Aryan extension handlers ------------------------
-----------------------------------------------------------------------------
-- FIXME: Put this in a family-specific module.
insert(handlers, function(data)
local labelpref, extension = data.label:match("^(terms extended with Indo%-Aryan )(.+)$")
if not extension then
return
end
local lang_inc_ash = require("Module:languages").getByCode("inc-ash")
local linked_term = full_link({lang = lang_inc_ash, term = extension}, "term")
local tagged_term = tag_text(extension, lang_inc_ash, nil, "term")
return {
description = "{{{langname}}} terms extended with the [[Indo-Aryan]] [[pleonastic]] affix " .. linked_term .. ".",
displaytitle = "{{{langname}}} " .. labelpref .. tagged_term,
breadcrumb = tagged_term,
parents = {{name = "terms with Indo-Aryan extensions", sort = extension}},
umbrella = {
no_by_language = true,
parents = "Indo-Aryan extensions",
displaytitle = "Terms extended with Indo-Aryan " .. tagged_term,
}
}
end)
-----------------------------------------------------------------------------
---------------------------- Coined-by handlers -----------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local coiner = data.label:match("^terms coined by (.+)$")
if not coiner then
return
end
-- Sort by last name per request from [[User:Metaknowledge]]
local last_name = umatch(coiner, ".-%s(%S+)$")
return {
description = "{{{langname}}} terms coined by " .. coiner .. ".",
breadcrumb = coiner,
parents = {{
name = "coinages",
sort = last_name and last_name .. ", " .. coiner or coiner,
}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
------------------------ Multiple etymology handlers ------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local pos = data.label:match("^terms with multiple (.+) etymologies$")
if not pos then
return
end
local plpos = pluralize_pos(pos)
local postype = pos_lemma_or_nonlemma(plpos)
if not postype then
return
end
return {
description = "{{{langname}}} " .. plpos .. " that are derived from multiple origins.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = "multiple " .. plpos,
parents = {{
name = "terms with multiple " .. postype .. " etymologies",
sort = pos,
}},
}
end)
insert(handlers, function(data)
local pos1, pos2 = data.label:match("^terms with (.+) and (.+) etymologies$")
if not pos1 then
return
end
local pos1type = pos_lemma_or_nonlemma(pluralize_pos(pos1))
local pos2type = pos_lemma_or_nonlemma(pluralize_pos(pos2))
if not (pos1type and pos2type) then
return
end
return {
description = "{{{langname}}} terms consisting of " .. add_indefinite_article(pos1) .." of one origin and " ..
add_indefinite_article(pos2) .. " of a different origin.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = pos1 .. " and " .. pos2,
parents = {{
name = pos1type == pos2type and "terms with multiple " .. pos1type .. " etymologies" or
"terms with lemma and non-lemma form etymologies",
sort = pos1 .. " and " .. pos2,
}},
}
end)
-----------------------------------------------------------------------------
--------------------------- Borrowed-back handlers --------------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form e.g. [[:Category:English terms borrowed back into English]]. We need to use a handler
-- because the category's language occurs inside the label itself. For the same reason, the umbrella category has a
-- nonstandard name "Terms borrowed back into the same language", so we handle it as a regular parent and disable the
-- built-in umbrella mechanism.
insert(handlers, function(data)
local lang = data.lang
if not lang then
return
end
local source_name = data.label:match("^terms borrowed back into (.+)$")
if not (source_name and source_name == lang:getDisplayForm()) then
return
end
return {
description = "{{{langname}}} terms that were borrowed from another language that originally borrowed the term from " .. source_name .. ".",
parents = {"ศัพท์แบ่งตามรากศัพท์", "borrowed terms", {
name = "Terms borrowed back into the same language",
raw = true,
sort = "{{{langname}}}"
}},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
end)
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for umbrella metacategories of the form e.g. [[:Category:Terms derived from Proto-Indo-Iranian roots]]
-- and [[:Category:Terms derived from Proto-Indo-European words]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(raw_handlers, function(data)
local source_name, terms_type
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name = data.category:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+)$")
if source_name then
terms_type = tt
break
end
end
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
return {
description = "Umbrella categories covering terms derived from particular " .. get_source_and_type_desc(source, terms_type) .. ".",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{ name = terms_type == "ราก" and "ราก" or "คำหลัก", is_label = true, lang = source:getCode(), sort = " " },
{ name = "ศัพท์ที่รับมาจาก" .. source_name, is_label = true, sort = " " .. terms_type },
},
}
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}
qp7fba7p3nxdrf08rr4685f243z4g6l
5722508
5722507
2026-05-05T01:49:25Z
OctraBot
3198
5722508
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local en_utilities_module = "Module:en-utilities"
local m_str_utils = require("Module:string utilities")
local add_indefinite_article = require(en_utilities_module).add_indefinite_article
local full_link = require("Module:links").full_link
local get_lang_by_name = require("Module:languages").getByCanonicalName
local insert = table.insert
local pattern_escape = m_str_utils.pattern_escape
local plain_gsub = m_str_utils.plain_gsub
local pluralize_pos = require("Module:headword").pluralize_pos
local pos_lemma_or_nonlemma = require("Module:headword").pos_lemma_or_nonlemma
local serial_comma_join = require("Module:table").serialCommaJoin
local tag_text = require("Module:script utilities").tag_text
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ศัพท์แบ่งตามรากศัพท์"] = {
description = "{{{langname}}} terms categorized by their etymologies.",
umbrella_parents = "มูลฐาน",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["terms by etymology"] = labels["ศัพท์แบ่งตามรากศัพท์"]
labels["AABB-type reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] in an AABB pattern.",
breadcrumb = "AABB-type",
parents = {"คำซ้ำ"},
}
labels["apophonic reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] with only a change in a vowel sound.",
breadcrumb = "apophonic",
parents = {"คำซ้ำ"},
}
labels["การผันรูปย้อนกลับ"] = {
description = "{{{langname}}} terms formed by reversing a supposed regular formation, removing part of an older term.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["back-formations"] = labels["การผันรูปย้อนกลับ"]
labels["คำหลอม"] = {
description = "{{{langname}}} terms formed by combinations of other words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["blends"] = labels["คำหลอม"]
labels["ศัพท์ที่ยืมมา"] = {
description = "{{{langname}}} terms that are loanwords, i.e. words that were directly incorporated from another language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["borrowed terms"] = labels["ศัพท์ที่ยืมมา"]
labels["catachreses"] = {
description = "{{{langname}}} terms derived from misuses or misapplications of other terms.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่บัญญัติ"] = {
description = "{{{langname}}} terms coined by an identifiable person, organization or other such entity.",
parents = {"terms attributed to a specific source"},
umbrella_parents = {name = "terms attributed to a specific source", is_label = true, sort = " "},
}
labels["coinages"] = labels["ศัพท์ที่บัญญัติ"]
labels["coordinated pairs"] = {
description = "Terms in {{{langname}}} consisting of a pair of terms joined by a [[coordinating conjunction]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated triples"] = {
description = "Terms in {{{langname}}} consisting of three terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quadruples"] = {
description = "Terms in {{{langname}}} consisting of four terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quintuples"] = {
description = "Terms in {{{langname}}} consisting of five terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากคำนาม"] = {
description = "{{{langname}}} terms derived from a noun.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["denominals"] = labels["ศัพท์ที่รับมาจากคำนาม"]
labels["ศัพท์ที่รับมาจากคำกริยา"] = {
description = "{{{langname}}} terms derived from a verb.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["deverbals"] = labels["ศัพท์ที่รับมาจากคำกริยา"]
labels["ศัพท์ที่ร่วมราก"] = {
description = "{{{langname}}} terms that trace their etymology from ultimately the same source as other terms in the same language, but by different routes, and often with subtly or substantially different meanings.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["doublets"] = labels["ศัพท์ที่ร่วมราก"]
labels["elongated forms"] = {
description = "{{{langname}}} terms where one or more letters or sounds is repeated for emphasis or effect.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากชื่อบุคคล"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["eponyms"] = labels["ศัพท์ที่รับมาจากชื่อบุคคล"]
labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"] = {
description = "{{{langname}}} terms that originate from [[trademark]]s, [[brand]]s and company names which have become [[genericized]]; that is, fallen into common usage in the target market's [[vernacular]], even when referring to other competing brands.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "เครื่องหมายการค้า"},
}
labels["genericized trademarks"] = labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"]
labels["ghost words"] = {
description = "{{{langname}}} terms that were originally erroneous or fictitious, published in a reference work as if they were genuine as a result of typographical error, misreading, or misinterpretation, or as [[:w:Fictitious entry|fictitious entries]], jokes, or hoaxes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["gramograms"] = {
description = "{{{langname}}} [[gramogram]]s – terms that are partially or completely spelled with [[homophone|homophonous]] letters.",
parents = {"rebuses"},
}
labels["haplological words"] = {
description = "{{{langname}}} words that underwent [[haplology]]: thus, their origin involved a loss or omission of a repeated sequence of sounds.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["homophonic translations"] = {
description = "{{{langname}}} terms that were borrowed by matching the etymon phonetically, without regard for the sense; compare [[phono-semantic matching]] and [[Hobson-Jobson]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["hybridisms"] = {
description = "{{{langname}}} terms formed by elements of different linguistic origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบทอด"] = {
description = "{{{langname}}} terms that were inherited from an earlier stage of the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["inherited terms"] = labels["ศัพท์ที่สืบทอด"]
labels["internationalisms"] = {
description = "{{{langname}}} loanwords which also exist in many other languages with the same or similar etymology.",
additional = "Terms should be here preferably only if the immediate source language is not known for certain. Entries are added into this category by [[Template:internationalism]]; see it for more information.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["legal doublets"] = {
description = "{{{langname}}} legal [[doublet]]s – a legal doublet is a standardized phrase commonly use in legal documents, proceedings etc. which includes two words that are near synonyms.",
parents = {"coordinated pairs"},
}
labels["legal triplets"] = {
description = "{{{langname}}} legal [[triplet]]s – a legal triplet is a standardized phrase commonly use in legal documents, proceedings etc which includes three words that are near synonyms.",
parents = {"coordinated triples"},
}
labels["LLM coinages"] = {
description = "{{{langname}}} terms that have been coined by {{w|large language models}} rather than humans.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["merisms"] = {
description = "{{{langname}}} [[merism]]s – terms that are [[coordinate]]s that, combined, are a synonym for a totality.",
parents = {"coordinated pairs"},
}
labels["metonyms"] = {
description = "{{{langname}}} terms whose origin involves calling a thing or concept not by its own name, but by the name of something intimately associated with that thing or concept.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["นวศัพท์"] = {
description = "{{{langname}}} terms that have been only recently acknowledged.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["neologisms"] = labels["นวศัพท์"]
labels["nonce terms"] = {
description = "{{{langname}}} terms that have been invented for a single occasion.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["number homophones"] = {
description = "{{{langname}}} terms that are partially or completely spelled with [[homophone|homophonous]] numbers.",
parents = {"rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["numerical contractions"] = {
description = "{{{langname}}} numerical contractions. In these, the number either denotes omitted characters ({{m+|en|globalization}} → {{m|en|g11n}}) or duplication ({{m+|kne|Kankanaey}} → {{m|kne|Kan2aey}}).",
parents = {"contractions", "rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["ศัพท์ที่เลียนเสียงธรรมชาติ"] = {
description = "{{{langname}}} terms that were coined to sound like what they represent.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["onomatopoeias"] = labels["ศัพท์ที่เลียนเสียงธรรมชาติ"]
labels["piecewise doublets"] = {
description = "{{{langname}}} terms that are [[ภาคผนวก:อภิธานศัพท์#piecewise doublet|piecewise doublets]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
--[=[ thwikt don't use specific terms below
for _, ism_and_langname in ipairs({
{"anglicisms", "English"},
{"Arabisms", "Arabic"},
{"Gallicisms", "French"},
{"Germanisms", "German"},
{"Hispanisms", "Spanish"},
{"Italianisms", "Italian"},
{"Latinisms", "Latin"},
{"Japonisms", "Japanese"},
}) do
local ism, langname = unpack(ism_and_langname)
labels["pseudo-" .. ism] = {
description = "{{{langname}}} terms that appear to be " .. langname .. ", but are not used or have an unrelated meaning in " .. langname .. " itself.",
parents = {"pseudo-loans"},
umbrella_parents = {name = "pseudo-loans", is_label = true, sort = " "},
}
end
--]=]
labels["rebracketings"] = {
description = "{{{langname}}} terms that have interacted with another word in such a way that the boundary between the words has been modified.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["rebuses"] = {
description = "{{{langname}}} [[rebus]]es – terms that are partially or completely represented by images, symbols or numbers, often as a form of wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบสร้าง"] = {
description = "{{{langname}}} terms that are not directly attested, but have been reconstructed through other evidence.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["reconstructed terms"] = labels["ศัพท์ที่สืบสร้าง"]
labels["reduplicated coordinated pairs"] = {
description = "{{{langname}}} reduplicated coordinated pairs.",
breadcrumb = "reduplicated",
parents = {"coordinated pairs", "คำซ้ำ"},
}
labels["reduplicated coordinated triples"] = {
description = "{{{langname}}} reduplicated coordinated triples.",
breadcrumb = "reduplicated",
parents = {"coordinated triples", "คำซ้ำ"},
}
labels["reduplicated coordinated quadruples"] = {
description = "{{{langname}}} reduplicated coordinated quadruples.",
breadcrumb = "reduplicated",
parents = {"coordinated quadruples", "คำซ้ำ"},
}
labels["reduplicated coordinated quintuples"] = {
description = "{{{langname}}} reduplicated coordinated quintuples.",
breadcrumb = "reduplicated",
parents = {"coordinated quintuples", "คำซ้ำ"},
}
labels["คำซ้ำ"] = {
description = "{{{langname}}} terms that underwent [[reduplication]], so their origin involved a repetition of roots or stems.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["reduplications"] = labels["คำซ้ำ"]
labels["retronyms"] = {
description = "{{{langname}}} terms that serve as new unique names for older objects or concepts whose previous names became ambiguous.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ราก"] = {
description = "Basic morphemes from which {{{langname}}} words are formed.",
parents = {"หน่วยคำ"},
}
labels["roots"] = labels["ราก"]
labels["Sanskritic formations"] = {
description = "{{{langname}}} terms coined from [[tatsama]] [[word]]s and/or [[affix]]es.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่รับมาจากภาษาสันสกฤต"},
}
labels["sound-symbolic terms"] = {
description = "{{{langname}}} terms that use {{w|sound symbolism}} to express ideas but which are not necessarily strictly speaking [[onomatopoeic]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelled-out initialisms"] = {
description = "{{{langname}}} initialisms in which the letter names are spelled out.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelling pronunciations"] = {
description = "{{{langname}}} terms whose pronunciation was historically or presently affected by their spelling.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["คำผวน"] = {
description = "{{{langname}}} terms in which the initial sounds of component parts have been exchanged, as in \"crook and nanny\" for \"nook and cranny\".",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spoonerisms"] = labels["คำผวน"]
labels["taxonomic eponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people, used for [[taxonomy]].",
parents = {"ศัพท์ที่รับมาจากชื่อบุคคล"},
}
labels["terms attributed to a specific source"] = {
description = "{{{langname}}} terms coined by an identifiable person or deriving from a known work.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms coined ex nihilo"] = {
description = "{{{langname}}} terms fabricated ''[[ex nihilo]]'', i.e. made up entirely rather than being derived from an existing source.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms containing fossilized case endings"] = {
description = "{{{langname}}} terms which preserve case morphology which is no longer analyzable within the contemporary grammatical system or which has been entirely lost from the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from area codes"] = {
description = "{{{langname}}} terms derived from [[area code]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"] = {
description = "{{{langname}}} terms derived from the shape of letters. This can include terms derived from the shape of any letter in any alphabet.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from the shape of letters"] = labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"]
labels["ศัพท์แบ่งตามราก"] = {
description = "{{{langname}}} terms categorized by the root they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์", {name = "ราก", sort = " "}},
}
labels["terms by root"] = labels["ศัพท์แบ่งตามราก"]
labels["ศัพท์แบ่งตามคำ"] = {
description = "{{{langname}}} terms categorized by the word they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms by word"] = labels["ศัพท์แบ่งตามคำ"]
labels["ศัพท์ที่รับมาจากบันเทิงคดี"] = {
description = "{{{langname}}} terms that originate from works of [[fiction]].",
breadcrumb = "บันเทิงคดี",
parents = {{name = "terms attributed to a specific source", sort = "บันเทิงคดี"}},
}
labels["terms derived from fiction"] = labels["ศัพท์ที่รับมาจากบันเทิงคดี"]
for _, data in ipairs {
{source="Dickensian works", desc="the works of [[w:Charles Dickens|Charles Dickens]]", topic_parent="Charles Dickens"},
{source="ดีซีคอมิกส์", desc="[[w:ดีซีคอมิกส์|ดีซีคอมิกส์]]"},
{source="โดราเอมอน", desc="[[w:Fujiko F. Fujio|Fujiko F. Fujio]]'s ''[[w:โดราเอมอน|โดราเอมอน]]''", displaytitle="''โดราเอมอน''"},
{source="ดรากอนบอล", desc="[[w:Akira Toriyama|Akira Toriyama]]'s ''[[w:ดรากอนบอล|ดรากอนบอล]]''", displaytitle="''ดรากอนบอล''"},
{source="ดักเบิร์กและเมาส์ตัน", desc="[[w:The Walt Disney Company|Disney]]'s [[w:Duck universe|Duckburg]] and [[w:Mickey Mouse universe|Mouseton]] universe",
topic_parent="ดิสนีย์"},
{source="ฟิวเจอรามา", desc="the animated television series ''{{w|ฟิวเจอรามา}}''", displaytitle = "''ฟิวเจอรามา''"},
{source="แฮร์รี่ พอตเตอร์", desc="the ''[[w:แฮร์รี่ พอตเตอร์|แฮร์รี่ พอตเตอร์]]'' series", displaytitle="''แฮร์รี่ พอตเตอร์''",
topic_parent="แฮร์รี่ พอตเตอร์"},
{source="Looney Tunes and Merrie Melodies", desc="''{{w|Looney Tunes}}'' and/or ''{{w|Merrie Melodies}}'', by {{w|Warner Bros. Animation}}", displaytitle = "''Looney Tunes'' and ''Merrie Melodies''"},
{source="หนึ่งเก้าแปดสี่", desc="[[w:George Orwell|George Orwell]]'s ''[[w:Nineteen Eighty-Four|Nineteen Eighty-Four]]''",
displaytitle="''หนึ่งเก้าแปดสี่''"},
{source="Seinfeld", desc="the American television sitcom ''{{w|Seinfeld}}'' (1989–1998)", displaytitle="''Seinfeld''"},
{source="Seussian works", desc="the works of [[w:Dr. Seuss|Dr. Seuss]]"},
{source="South Park", desc="the animated television series ''[[w:South Park|South Park]]''", displaytitle="''South Park''"},
{source="สตาร์ เทรค", desc="''[[w:สตาร์ เทรค|สตาร์ เทรค]]''", displaytitle="''สตาร์ เทรค''", topic_parent="สตาร์ เทรค"},
{source="สตาร์ วอร์ส", desc="''[[w:สตาร์ วอร์ส|สตาร์ วอร์ส]]''", displaytitle="''สตาร์ วอร์ส''", topic_parent="สตาร์ วอร์ส"},
{source="เดอะซิมป์สันส์", desc="''[[w:เดอะซิมป์สันส์|เดอะซิมป์สันส์]]''", displaytitle="''เดอะซิมป์สันส์''", topic_parent="เดอะซิมป์สันส์", sort="ซิมป์สันส์"},
{source="ปกรณัมของโทลคีน", desc="the [[legendarium]] of [[w:เจ. อาร์. อาร์. โทลคีน|เจ. อาร์. อาร์. โทลคีน]]", topic_parent="เจ. อาร์. อาร์. โทลคีน"},
} do
local parents = {{name = "ศัพท์ที่รับมาจากบันเทิงคดี", sort = data.sort or data.source}}
local umbrella_parents = {"หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"}
if data.topic_parent then
insert(parents, {name = "{{{langcode}}}:" .. data.topic_parent, raw = true})
insert(umbrella_parents, {name = data.topic_parent, raw = true})
end
labels["ศัพท์ที่รับมาจาก" .. data.source] = {
description = "{{{langname}}} terms that originate from " .. data.desc .. ".",
breadcrumb = data.displaytitle or data.source,
parents = parents,
umbrella = {
parents = umbrella_parents,
displaytitle = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle .. "แบ่งตามภาษา" or nil,
breadcrumb = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle,
},
displaytitle = data.displaytitle and "ศัพท์{{{langcat}}}ที่รับมาจาก" .. data.displaytitle or nil,
}
end
labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"] = {
description = "{{{langname}}} terms derived from Greek mythology which have acquired an idiomatic meaning.",
breadcrumb = "ประมวลเรื่องปรัมปรากรีก",
parents = {{name = "terms attributed to a specific source", sort = "ประมวลเรื่องปรัมปรากรีก"}},
}
labels["terms derived from Greek mythology"] = labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"]
labels["ศัพท์ที่รับมาจากอาชีพ"] = {
description = "{{{langname}}} terms derived from names of occupations.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from occupations"] = labels["ศัพท์ที่รับมาจากอาชีพ"]
labels["ศัพท์ที่รับมาจากภาษาอื่น"] = {
description = "{{{langname}}} terms that originate from other languages.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from other languages"] = labels["ศัพท์ที่รับมาจากภาษาอื่น"]
labels["ศัพท์ที่รับมาจากไบเบิล"] = {
description = "{{{langname}}} terms that originate from the [[Bible]].",
breadcrumb = {name = "ไบเบิล", nocap = true},
parents = {{name = "terms attributed to a specific source", sort = "ไบเบิล"}},
}
labels["terms derived from the Bible"] = labels["ศัพท์ที่รับมาจากไบเบิล"]
labels["ศัพท์ที่รับมาจากนิทานอีสป"] = {
description = "{{{langname}}} terms that originate from [[Aesop]]'s Fables.",
breadcrumb = "นิทานอีสป",
parents = {{name = "terms attributed to a specific source", sort = "นิทานอีสป"}},
}
labels["terms derived from Aesop's Fables"] = labels["ศัพท์ที่รับมาจากนิทานอีสป"]
labels["terms derived from toponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious places.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived through romanized wordplay"] = {
description = "{{{langname}}} terms derived through romanized wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms making reference to character shapes"] = {
description = "{{{langname}}} terms making reference to character shapes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากกีฬา"] = {
description = "{{{langname}}} terms that originate from sports.",
breadcrumb = "กีฬา",
parents = {{name = "terms attributed to a specific source", sort = "กีฬา"}},
}
labels["terms derived from sport"] = labels["ศัพท์ที่รับมาจากกีฬา"]
labels["ศัพท์ที่รับมาจากเบสบอล"] = {
description = "{{{langname}}} terms that originate from baseball.",
breadcrumb = "เบสบอล",
parents = {{name = "ศัพท์ที่รับมาจากกีฬา", sort = "เบสบอล"}},
}
labels["terms derived from baseball"] = labels["ศัพท์ที่รับมาจากเบสบอล"]
labels["terms with Indo-Aryan extensions"] = {
description = "{{{langname}}} terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with lemma and non-lemma form etymologies"] = {
description = "{{{langname}}} terms consisting of both a lemma and non-lemma form, of different origins.",
breadcrumb = "lemma and non-lemma form",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple etymologies"] = {
description = "{{{langname}}} terms that are derived from multiple origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with multiple lemma etymologies"] = {
description = "{{{langname}}} lemmas that are derived from multiple origins.",
breadcrumb = "multiple lemmas",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple non-lemma form etymologies"] = {
description = "{{{langname}}} non-lemma forms that are derived from multiple origins.",
breadcrumb = "multiple non-lemma forms",
parents = {"terms with multiple etymologies"},
}
labels["ศัพท์ที่ไม่ทราบรากศัพท์"] = {
description = "{{{langname}}} terms whose etymologies have not yet been established.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "ไม่ทราบรากศัพท์"}},
}
labels["terms with unknown etymologies"] = labels["ศัพท์ที่ไม่ทราบรากศัพท์"]
labels["univerbations"] = {
description = "{{{langname}}} terms that result from the agglutination of two or more words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["words derived through corruption"] = {
description = "{{{langname}}} words that result from a non-specific or sporadic change.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "corruption"}},
}
labels["words derived through metathesis"] = {
description = "{{{langname}}} words that were created through [[metathesis]] from another word.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "metathesis"}},
}
labels["words that have undergone semantic shift"] = {
description = "{{{langname}}} words that show senses explained by [[semantic shift]].",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "semantic shift"}},
}
labels["words that have undergone semantic broadening"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[broadening]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic broadening"}},
}
labels["words that have undergone semantic narrowing"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[narrowing]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic narrowing"}},
}
labels["words that have undergone amelioration"] = {
description = "{{{langname}}} words that have gained a positive [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "amelioration"}},
}
labels["words that have undergone pejoration"] = {
description = "{{{langname}}} words that have gained a negative [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "pejoration"}},
}
labels["terms with origins in folklore"] = {
description = "{{{langname}}} terms that have an etymology rooted in folklore.",
breadcrumb = "Folklore",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "folklore"}, {name = "{{{langcode}}}:Folklore", raw = true}},
umbrella_parents = {{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", raw = true}, {name = "Folklore", raw = true, sort = " "}}
}
-- Add 'umbrella_parents' key if not already present.
for _, data in pairs(labels) do
-- NOTE: umbrella.parents overrides umbrella_parents if both are given.
if not data.umbrella_parents then
data.umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to terms categorized by their etymologies, such as types of compounds or borrowings.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์แบ่งตามรากศัพท์", is_label = true, sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to borrowed terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่ยืมมา", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to inherited terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่สืบทอด", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Indo-Aryan extensions"] = {
description = "Umbrella categories covering terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Multiple etymology subcategories by language"] = {
description = "Umbrella categories covering topics related to terms with multiple etymologies.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["ศัพท์ที่ยืมกลับไปยังภาษาเดิม"] = {
description = "Categories with terms in specific languages that were borrowed from a second language that previously borrowed the term from the first language.",
additional = "A well-known example is {{m+|en|salaryman}}, a term borrowed from Japanese which in turn was borrowed from the English words [[salary]] and [[man]].\n\n{{{umbrella_msg}}}",
parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_source(source_name, allow_family, name_type)
local source = get_lang_by_name(source_name, nil, true, allow_family)
if source == nil then
return nil
end
-- Check that the source name matches the expected form (e.g. getCanonicalName, getDisplayForm etc).
if source[name_type](source) == source_name then
return source
end
end
local function get_source_and_type_desc(source, term_type)
if source:getCode() == "ine-pro" and term_type:find("^roots?$") then
return "[[w:Proto-Indo-European root|Proto-Indo-European " .. term_type .. "]]"
end
return "[[w:" .. source:getWikipediaArticle() .. "|" .. source:getCanonicalName() .. "]] " .. term_type
end
local function get_source_and_source_desc(source_name)
-- HACK! Map 'taxonomic names', as generated by [[Module:etymology]], back to its canonical name
-- before calling getByCanonicalName(). We need a more general solution here.
local source_desc
if source_name == "taxonomic names" then
source_name = "taxonomic name"
source_desc = "[[w:taxonomic nomenclature|taxonomic names]]"
end
local source = get_source(source_name, true, "getCanonicalName") --th
if source == nil then
return
end
source_desc = source_desc or source:makeCategoryLink()
if source:hasType("family") then
source_desc = "one of the " .. source_desc
end
return source, source_desc
end
-----------------------------------------------------------------------------
------------------------------- word handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE word word' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
local function lang_is_semitic(lang)
return lang:inFamily("sem")
end
insert(handlers, function(data)
local labelpref, word_and_id = data.label:match("^(terms belonging to the word )(.+)$")
if not word_and_id then
return
end
local word, id = word_and_id:match("^(.+) %((.-)%)$")
if not word then
word = word_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local word_desc = is_semitic and "[[w:Semitic word|word]]" or "word"
local parents = {}
if id then
insert(parents, {name = labelpref .. word, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามคำ", sort = word_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style words)
local word_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(word, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(word_no_prefix_suffix, not_separator_c, ""))
local linked_word = data.lang and full_link({ term = word, lang = data.lang, gloss = id, id = id }, "term") or word
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter words", sort = word_and_id})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, word, tag_text(word, lang, nil, "term"))
end
local breadcrumb = tag_text(word, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. word_desc .. " " .. linked_word .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^terms by (.+) word$")
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian word]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source:getDisplayForm())
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "word") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
-----------------------------------------------------------------------------
------------------------------- Root handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE root ROOT' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
-- Handler for e.g. [[:Category:Yola terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Russian terms derived from the Proto-Indo-European word *swé]], and corresponding umbrella
-- categories [[:Category:Terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Terms derived from the Proto-Indo-European word *swé]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(handlers, function(data)
local source_name, term_type, term_and_id
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name, term_and_id = data.label:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+) (.+)$")
if source_name then
term_type = tt
break
end
end
if not source_name then
return
end
local term, id = term_and_id:match("^(.+) %((.-)%)$")
if not term then
term = term_and_id
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {
{
name = "ศัพท์แบ่งตาม" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
local umbrella_parents = {
{
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
if id then
insert(parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
sort = " "
})
insert(umbrella_parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
is_label = true,
sort = " "
})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, term, tag_text(term, source, nil, "term"))
end
local breadcrumb = tag_text(term, source, nil, "term") .. (id and " (" .. id .. ")" or "")
local term_page, alt_form
if term_type == "root" and lang_is_semitic(source) then
term_page = ("ภาคผนวก:ราก%s/%s"):format(source:getCanonicalName(), term)
alt_form = term
else
term_page = term
end
return {
description = "{{{langname}}} terms that originate ultimately from the " .. get_source_and_type_desc(source, term_type) .. " " .. full_link({
term = term_page,
alt = alt_form,
lang = source,
gloss = id,
id = id
}, "term") .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
no_by_language = true,
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = umbrella_parents,
}
}
end)
insert(handlers, function(data)
local labelpref, root_and_id = data.label:match("^(terms belonging to the root )(.+)$")
if not root_and_id then
return
end
local root, id = root_and_id:match("^(.+) %((.-)%)$")
if not root then
root = root_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local root_desc = is_semitic and "[[w:Semitic root|root]]" or "root"
local parents = {}
if id then
insert(parents, {name = labelpref .. root, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามราก", sort = root_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style roots)
local root_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(root, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(root_no_prefix_suffix, not_separator_c, ""))
local root_page, alt_form
if is_semitic then
root_page = ("ภาคผนวก:ราก%s/%s"):format(data.lang:getCanonicalName(), root)
alt_form = root
else
root_page = root
end
local linked_root = data.lang and full_link(
{ term = root_page, alt = alt_form, lang = data.lang, gloss = id, id = id }, "term") or root_page
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter roots", sort = root_and_id})
end
-- Italicize the root/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, root, tag_text(root, lang, nil, "term"))
end
local breadcrumb = tag_text(root, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. root_desc .. " " .. linked_root .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์แบ่งตามราก(.+)$")
if not source_name or source_name == "ศัพท์" then --th; excludes falsily detect ศัพท์แบ่งตามรากศัพท์
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian root]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source_name)
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "root") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
insert(handlers, function(data)
local root_shape, post, additional = data.label:match("^(.+)([ -])shaped roots$")
if not root_shape then
return
elseif data.lang and data.lang:getCode() == "ine-pro" then
additional = [=[
* '''e''' stands for the vowel of the root.
* '''C''' stands for any stop or ''s''.
* '''R''' stands for any resonant.
* '''H''' stands for any laryngeal.
* '''M''' stands for ''m'' or ''w'', when followed by a resonant.
* '''s''' stands for ''s'', when next to a stop.]=]
end
if root_shape == "irregularly" and post == " " then
return {
breadcrumb = "irregular",
description = "{{{langname}}} roots with a shape that violates the {{w|Proto-Indo-European root#Shape of a root|known rules on root shapes}}.",
additional = additional,
parents = {{name = "roots by shape", sort = "*"}},
umbrella = false,
}
elseif post == " " then
return
end
return {
breadcrumb = root_shape,
description = "{{{langname}}} roots with the shape ''" .. root_shape .. "''.",
additional = additional,
parents = {{name = "roots by shape", sort = root_shape}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
-------------------- Derived/inherited/borrowed handlers --------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form "LANG terms derived from SOURCE", where SOURCE is a language, etymology language
-- or family (e.g. "Indo-European languages"), along with corresponding umbrella categories of the form
-- "Terms derived from SOURCE".
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์ที่รับมาจากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่รับมาจากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- Compute description.
local desc = "{{{langname}}} terms that originate from " .. source_desc .. "."
local additional
if source:hasType("family") then
additional = "This category should, ideally, contain only other categories. Entries can be categorized here, too, when the proper subcategory is unclear. " ..
"If you know the exact language from which an entry categorized here is derived, please edit its respective entry."
end
-- Compute parents.
local derived_from_variety_of_self = false
local parent
local sortkey = source:getDisplayForm()
if source:hasType("etymology-only") then
-- By default, `parent` is the source's parent.
parent = source:getParent()
-- Check if the source is a variety (or subvariety) of the language.
if data.lang and source:hasParent(data.lang) then
derived_from_variety_of_self = true
end
-- If the language is the direct parent of the source or the parent is "und", then we use the family of the source as `parent` instead.
if data.lang and (parent:getCode() == data.lang:getCode() or parent:getCode() == "und") then
parent = source:getFamily()
end
-- Regular language or family.
else
local fam = source:getFamily()
if fam then
parent = fam
end
end
-- If `parent` does not exist, is the same as `source`, or would be "isolate languages" or "not a family", then we discard it.
if (not parent) or parent:getCode() == source:getCode() or parent:getCode() == "qfa-iso" or parent:getCode() == "qfa-not" or
parent:getCode() == "qfa-unc" then
parent = nil
derived_from_variety_of_self = false
-- Otherwise, get the display form.
else
parent = parent:getDisplayForm()
end
parent = parent and "ศัพท์ที่รับมาจาก" .. parent or "ศัพท์ที่รับมาจากภาษาอื่น"
local parents = {{name = parent, sort = sortkey}}
if derived_from_variety_of_self then
insert(parents, "Category:Categories for terms in a language derived from a term in a subvariety of that language")
end
-- Compute umbrella parents.
local cat_name = source:getCode() == "mul-tax" and "Taxonomic names" or source:getCategoryName()
-- If the source is etymology-only, its category will be handled by the lect handler in
-- [[Module:category tree/ภาษณ์]]. If it has a nonstandard name like 'Kölsch' (i.e. not a name like
-- 'American English' that has a language name in it), the lect handler won't handle it unless we tell it to do so
-- through the following call; this is an optimization to avoid expensive processing work on all manner of randomly
-- named categories.
if source:hasType("etymology-only") then
require("Module:category tree/ภาษณ์").export.register_likely_lect_parent_cat(cat_name)
end
local umbrella_parents = {
(source:hasType("family") or source:getCode() == "mul-tax") and {name = cat_name, raw = true, sort = " "} or
{name = cat_name, raw = true, sort = "terms derived from"}
}
-- Without the following, the breadcrumb trail for e.g. [[Category:Javanese terms derived from French]] looks like
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages »
-- Indo-European languages » Italic languages » Romance languages » Italo-Western Romance languages »
-- Western Romance languages » Gallo-Romance languages » Gallo-Rhaetian languages » Oïl languages » French
-- To reduce the length, we truncate the "languages" part of the breadcrumbs as long as this does not create
-- ambiguity (i.e. unless there is a language with the same name as the family). Hence, for the Category
-- [[Category:Javanese terms derived from Arabic]], we end up with
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages » Afroasiatic »
-- Semitic » West Semitic » Central Semitic » Arabic languages » Arabic
-- because "Arabic" is ambiguous between family and language (and script, for that matter).
local breadcrumb = source_name
if source:hasType("family") and breadcrumb:find("กลุ่มภาษา") then
local truncated_breadcrumb = breadcrumb:gsub("กลุ่มภาษา", "")
if not get_lang_by_name(truncated_breadcrumb, nil, "allow etym") then
breadcrumb = truncated_breadcrumb
end
end
return {
description = desc,
additional = additional,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
description = "Categories with terms that originate from " .. source_desc .. ".",
parents = umbrella_parents,
},
}
end)
-- Handler for categories of the form "LANG terms inherited/borrowed from SOURCE", where SOURCE is a language,
-- etymology language or family (e.g. "Indo-European languages"). Also handles umbrella categories of the form
-- "Terms inherited/borrowed from SOURCE".
local function inherited_borrowed_handler(etymtype)
return function(data)
local source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
return {
description = "{{{langname}}} terms " .. etymtype .. " from " .. source_desc .. ".",
breadcrumb = source_name,
parents = {
{name = "ศัพท์ที่" .. etymtype, sort = source_name},
{name = "ศัพท์ที่รับมาจาก" .. (source:hasType("family") and "กลุ่มภาษา" or "ภาษา") .. source_name, sort = " "}
},
umbrella = {
parents = {
{ name = "ศัพท์ที่รับมาจากภาษา" .. source_name, is_label = true, sort = " " },
etymtype == "inherited" and
{ name = "หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา", sort = source_name }
-- There are several types of borrowings mixed into the following holding category,
-- so keep these ones sorted under 'Terms borrowed from SOURCE_NAME' instead of just
-- 'SOURCE_NAME'.
or "หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
end
table.insert(handlers, inherited_borrowed_handler("ยืมมา"))
table.insert(handlers, inherited_borrowed_handler("สืบทอด"))
-----------------------------------------------------------------------------
------------------------ Borrowing subtype handlers -------------------------
-----------------------------------------------------------------------------
-- General handler for specific borrowing subtypes, such as learned borrowings, calques and phono-semantic matchings.
local function borrowing_subtype_handler(dest, source_name, parent_cat, spec)
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- normally uses of UNKNOWN should not show up to the end user
local dest_name = dest and dest:getCanonicalName() or "UNKNOWN"
local additional, umbrella_additional
if spec.additional then
if dest then
additional = spec.additional(source, dest)
else
umbrella_additional = spec.umbrella_additional(source)
end
else
if not spec.categorizing_templates then
error("Internal error: Must specify either `categorizing_templates` or the combination of `additional` and `umbrella_additional` in each borrowing subtype spec")
end
local extra_templates = {}
local extra_template_text
for i, template in ipairs(spec.categorizing_templates) do
if i > 1 then
insert(extra_templates, ("{{tl|%s|...}}"):format(template))
end
end
if #extra_templates > 0 then
extra_template_text = (" (or %s, using the same syntax)"):format(
serial_comma_join(extra_templates, {conj = "or"}))
else
extra_template_text = ""
end
if dest then
additional = ("To categorize a term into this category, use {{tl|%s|%s|%s|<var>source_term</var>}}%s, " ..
"where <code><var>source_term</var></code> is the %s term that the term in question " ..
"was borrowed from."):format(
spec.categorizing_templates[1], dest:getCode(), source:getCode(), extra_template_text, source_name)
else
umbrella_additional = ("To categorize a term into a language-specific subcategory, use " ..
"{{tl|%s|<var>destcode</var>|%s|<var>source_term</var>}}%s, where <code><var>destcode</var></code> " ..
"is the language code of the language in question (see [[Wiktionary:List of languages]]), and " ..
"<code><var>source_term</var></code> is the %s term that the term in question was " ..
"borrowed from."):format(spec.categorizing_templates[1], source:getCode(), extra_template_text, source_name)
end
end
return {
description = "{{{langname}}} " .. spec.from_source_desc:gsub("SOURCE", source_desc):gsub("DEST", dest_name),
additional = additional,
breadcrumb = source_name,
parents = {
{ name = parent_cat, sort = source_name },
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, sort = " " },
},
umbrella = {
additional = umbrella_additional,
parents = {
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, is_label = true, sort = " " },
"หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
-- Specs describing types of borrowings.
-- `from_source_desc` is the English description used in categories of the form "LANGUAGE BORTYPE from SOURCE",
-- e.g. "Arabic semantic loans from English". "SOURCE" in the description is replaced by the source language.
-- `umbrella_desc` is the English description used in categories of the form "LANGUAGE BORTYPE", e.g.
-- "Arabic semantic loans". This is an umbrella category grouping all the source-language-specific categories.
-- `uses_subtype_handler`, if true, means that the handler for "LANGUAGE BORTYPE from SOURCE" categories is
-- implemented by a generic "TYPE borrowings" handler (at the bottom of this section), so we don't need to
-- create a BORTYPE-specific handler.
-- `umbrella_parent`, if given, is the parent category of the umbrella categories of the form "LANGUAGE BORTYPE".
-- By default it is "borrowed terms". Some borrowing types replace this with "terms by etymology". (FIXME:
-- Review whether this is correct.)
-- `label_pattern`, if given, is a Lua pattern that matches the category name minus the language at the beginning.
-- It should have one capture, which is the source language. An example is "^terms partially calqued from (.+)$".
-- If omitted, it is generated from BORTYPE.
-- `categorizing_templates`, if given, is the list of templates that categorize into this category. They are assumed to
-- follow the syntax of {{bor}}. The first template in the list should be the preferred alias. The specified
-- templates are used to form the `additional` text displayed on the language-specific category page and
-- corresponding umbrella category page describing how to categorize into the category in question. In more complex
-- cases, you can omit this field and instead supply the `additional` and `umbrella_additional` fields (as is done
-- with adapted borrowings). You must either specify `categorizing_templates` or the combination of `additional` and
-- `umbrella_additional`.
-- `additional`, if given, is a function of two arguments (source and destination language objects) that will generate
-- the `additional` text displayed on the language-specific category page that describes how to categorize into the
-- category in question. This is an alternative to specifying `categorizing_templates`, used in more complex cases
-- (currently, with adapted borrowings).
-- `umbrella_additional`, if given, is a function of one argument (source language object) that will generate the
-- `additional` text displayed on the umbrella category page that describes how to categorize into the category in
-- question. This is an alternative to specifying `categorizing_templates`, used in more complex cases (currently,
-- with adapted borrowings).
local borrowing_specs = {
["ศัพท์ที่ยืมโดยเรียนรู้"] = {
from_source_desc = "terms that are learned [[loanword]]s from SOURCE, that is, terms that were directly incorporated from SOURCE instead of through normal language contact.",
umbrella_desc = "terms that are learned [[loanword]]s, that is, terms that were directly incorporated from another language instead of through normal language contact.",
uses_subtype_handler = true,
categorizing_templates = {"lbor", "learned borrowing"},
},
["ศัพท์ที่ยืมโดยกึ่งเรียนรู้"] = {
from_source_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s from SOURCE, that is, terms borrowed from SOURCE (a [[classical language]]) into DEST (a modern language) and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
umbrella_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s, that is, terms borrowed from a [[classical language]] into a modern language and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
uses_subtype_handler = true,
categorizing_templates = {"slbor", "semi-learned borrowing"},
},
["ศัพท์ที่ยืมอักขรวิธี"] = {
from_source_desc = "orthographic loans from SOURCE, i.e. terms that were borrowed from SOURCE in their script forms, not their pronunciations.",
umbrella_desc = "orthographic loans, i.e. terms that were borrowed in their script forms, not their pronunciations.",
uses_subtype_handler = true,
categorizing_templates = {"obor", "orthographic borrowing"},
},
["ศัพท์ที่ยืมโดยไม่ดัดแปลง"] = {
from_source_desc = "[[loanword]]s from SOURCE that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of DEST.",
umbrella_desc = "[[loanword]]s that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of the target language.",
uses_subtype_handler = true,
categorizing_templates = {"ubor", "unadapted borrowing"},
},
["ศัพท์ที่ยืมโดยดัดแปลง"] = {
from_source_desc = "[[loanwords]] from SOURCE formed with the addition of an affix to conform the term to the normal morphology of DEST.",
umbrella_desc = "[[loanword]]s formed with the addition of an affix to conform the term to the normal morphology of the target language.",
uses_subtype_handler = true,
additional = function(source, dest)
return ("To categorize a term into this category, use {{tl|af|%s|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|%s|3=type=abor|4=...}}, using the same syntax), where <code><var>source_term</var></code> is " ..
"the %s term that the term in question was borrowed from and <code><var>affix</var></code> " ..
"is the %s affix used to adapt the %s term. An example is " ..
"{{m+|pl|adresować||to address}}, which would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate " ..
"that is was formed from {{m+|fr|adresser}} with the addition of the Polish verb-forming affix " ..
"{{m|pl|-ować}}."):format(dest:getCode(), source:getCode(), dest:getCode(), source:getCanonicalName(), dest:getCanonicalName(),
source:getCanonicalName())
end,
umbrella_additional = function(source)
return ("To categorize a term into a language-specific subcategory, use {{tl|af|<var>destcode</var>|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|<var>destcode</var>|3=type=abor|4=...}}, using the same syntax), where " ..
"<code><var>destcode</var></code> is the language code of the target language in question (see " ..
"[[Wiktionary:List of languages]]); <code><var>source_term</var></code> is the %s term " ..
"that the term in question was borrowed from; and <code><var>affix</var></code> is the target-language " ..
"affix used to adapt the %s term. An example is {{m+|pl|adresować||to address}}, which " ..
"would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate that is was formed from " ..
"{{m+|fr|adresser}} with the addition of the Polish verb-forming affix {{m|pl|-ować}}."):format(
source:getCode(), source:getCanonicalName(), source:getCanonicalName())
end,
},
["ศัพท์ที่ยืมความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]] from SOURCE, i.e. terms one or more of whose definitions was borrowed from a term in SOURCE.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]], i.e. terms one or more of whose definitions was borrowed from a term in another language.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
categorizing_templates = {"sl", "semantic loan"},
},
["ศัพท์ที่แปลตรงตัวบางส่วน"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#partial calque|partially calqued]] from SOURCE, i.e. terms formed partly by piece-by-piece translations of SOURCE terms and partly by direct borrowing.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#partial calque|partial calques]], i.e. terms formed partly by piece-by-piece translations of terms from other languages and partly by direct borrowing.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวบางส่วนจากภาษา(.+)$",
categorizing_templates = {"pcal", "pclq", "partial calque"},
},
["ศัพท์ที่แปลตรงตัว"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#calque|calqued]] from SOURCE, i.e. terms formed by piece-by-piece translations of SOURCE terms.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#calque|calques]], i.e. terms formed by piece-by-piece translations of terms from other languages.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวจากภาษา(.+)$",
categorizing_templates = {"cal", "clq", "calque"},
},
["ศัพท์ที่เข้าคู่เสียง-ความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]] from SOURCE, i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]], i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
categorizing_templates = {"psm", "phono-semantic matching"},
},
["ศัพท์ที่ยืมเทียม"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]] from SOURCE, i.e. terms that appear to be SOURCE, but are not used or have an unrelated meaning in SOURCE itself.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]], i.e. terms that appear to be derived from another language, but are not used or have an unrelated meaning in that language itself.",
categorizing_templates = {"pl", "pseudo-loan"},
},
}
for bortype, spec in pairs(borrowing_specs) do
labels[bortype] = {
description = "{{{langname}}} " .. spec.umbrella_desc,
parents = {spec.umbrella_parent or "ศัพท์ที่ยืมมา"},
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
if not spec.uses_subtype_handler then
-- If the label pattern isn't specifically given, generate it from the `bortype`; but make sure to
-- escape hyphens in the pattern.
local label_pattern = spec.label_pattern or "^" .. pattern_escape(bortype) .. "จากภาษา(.+)$"
insert(handlers, function(data)
local source_name = data.label:match(label_pattern)
if source_name then
return borrowing_subtype_handler(data.lang, source_name, bortype, spec)
end
end)
end
end
insert(handlers, function(data)
local borrowing_type, source_name = data.label:match("^(ศัพท์ที่ยืม.+)จากภาษา(.+)$")
if borrowing_type then
local spec = borrowing_specs[borrowing_type]
return borrowing_subtype_handler(data.lang, source_name, borrowing_type, spec)
end
end)
-----------------------------------------------------------------------------
---------------------- Indo-Aryan extension handlers ------------------------
-----------------------------------------------------------------------------
-- FIXME: Put this in a family-specific module.
insert(handlers, function(data)
local labelpref, extension = data.label:match("^(terms extended with Indo%-Aryan )(.+)$")
if not extension then
return
end
local lang_inc_ash = require("Module:languages").getByCode("inc-ash")
local linked_term = full_link({lang = lang_inc_ash, term = extension}, "term")
local tagged_term = tag_text(extension, lang_inc_ash, nil, "term")
return {
description = "{{{langname}}} terms extended with the [[Indo-Aryan]] [[pleonastic]] affix " .. linked_term .. ".",
displaytitle = "{{{langname}}} " .. labelpref .. tagged_term,
breadcrumb = tagged_term,
parents = {{name = "terms with Indo-Aryan extensions", sort = extension}},
umbrella = {
no_by_language = true,
parents = "Indo-Aryan extensions",
displaytitle = "Terms extended with Indo-Aryan " .. tagged_term,
}
}
end)
-----------------------------------------------------------------------------
---------------------------- Coined-by handlers -----------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local coiner = data.label:match("^terms coined by (.+)$")
if not coiner then
return
end
-- Sort by last name per request from [[User:Metaknowledge]]
local last_name = umatch(coiner, ".-%s(%S+)$")
return {
description = "{{{langname}}} terms coined by " .. coiner .. ".",
breadcrumb = coiner,
parents = {{
name = "coinages",
sort = last_name and last_name .. ", " .. coiner or coiner,
}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
------------------------ Multiple etymology handlers ------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local pos = data.label:match("^terms with multiple (.+) etymologies$")
if not pos then
return
end
local plpos = pluralize_pos(pos)
local postype = pos_lemma_or_nonlemma(plpos)
if not postype then
return
end
return {
description = "{{{langname}}} " .. plpos .. " that are derived from multiple origins.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = "multiple " .. plpos,
parents = {{
name = "terms with multiple " .. postype .. " etymologies",
sort = pos,
}},
}
end)
insert(handlers, function(data)
local pos1, pos2 = data.label:match("^terms with (.+) and (.+) etymologies$")
if not pos1 then
return
end
local pos1type = pos_lemma_or_nonlemma(pluralize_pos(pos1))
local pos2type = pos_lemma_or_nonlemma(pluralize_pos(pos2))
if not (pos1type and pos2type) then
return
end
return {
description = "{{{langname}}} terms consisting of " .. add_indefinite_article(pos1) .." of one origin and " ..
add_indefinite_article(pos2) .. " of a different origin.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = pos1 .. " and " .. pos2,
parents = {{
name = pos1type == pos2type and "terms with multiple " .. pos1type .. " etymologies" or
"terms with lemma and non-lemma form etymologies",
sort = pos1 .. " and " .. pos2,
}},
}
end)
-----------------------------------------------------------------------------
--------------------------- Borrowed-back handlers --------------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form e.g. [[:Category:English terms borrowed back into English]]. We need to use a handler
-- because the category's language occurs inside the label itself. For the same reason, the umbrella category has a
-- nonstandard name "Terms borrowed back into the same language", so we handle it as a regular parent and disable the
-- built-in umbrella mechanism.
insert(handlers, function(data)
local lang = data.lang
if not lang then
return
end
local source_name = data.label:match("^terms borrowed back into (.+)$")
if not (source_name and source_name == lang:getDisplayForm()) then
return
end
return {
description = "{{{langname}}} terms that were borrowed from another language that originally borrowed the term from " .. source_name .. ".",
parents = {"ศัพท์แบ่งตามรากศัพท์", "borrowed terms", {
name = "Terms borrowed back into the same language",
raw = true,
sort = "{{{langname}}}"
}},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
end)
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for umbrella metacategories of the form e.g. [[:Category:Terms derived from Proto-Indo-Iranian roots]]
-- and [[:Category:Terms derived from Proto-Indo-European words]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(raw_handlers, function(data)
local source_name, terms_type
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name = data.category:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+)$")
if source_name then
terms_type = tt
break
end
end
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
return {
description = "Umbrella categories covering terms derived from particular " .. get_source_and_type_desc(source, terms_type) .. ".",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{ name = terms_type == "ราก" and "ราก" or "คำหลัก", is_label = true, lang = source:getCode(), sort = " " },
{ name = "ศัพท์ที่รับมาจาก" .. source_name, is_label = true, sort = " " .. terms_type },
},
}
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}
e9gr0gdn65yo8tmv6d8ogc15thta0hx
5722509
5722508
2026-05-05T02:19:27Z
OctraBot
3198
5722509
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local en_utilities_module = "Module:en-utilities"
local m_str_utils = require("Module:string utilities")
local add_indefinite_article = require(en_utilities_module).add_indefinite_article
local full_link = require("Module:links").full_link
local get_lang_by_name = require("Module:languages").getByCanonicalName
local insert = table.insert
local pattern_escape = m_str_utils.pattern_escape
local plain_gsub = m_str_utils.plain_gsub
local pluralize_pos = require("Module:headword").pluralize_pos
local pos_lemma_or_nonlemma = require("Module:headword").pos_lemma_or_nonlemma
local serial_comma_join = require("Module:table").serialCommaJoin
local tag_text = require("Module:script utilities").tag_text
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ศัพท์แบ่งตามรากศัพท์"] = {
description = "{{{langname}}} terms categorized by their etymologies.",
umbrella_parents = "มูลฐาน",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["terms by etymology"] = labels["ศัพท์แบ่งตามรากศัพท์"]
labels["AABB-type reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] in an AABB pattern.",
breadcrumb = "AABB-type",
parents = {"คำซ้ำ"},
}
labels["apophonic reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] with only a change in a vowel sound.",
breadcrumb = "apophonic",
parents = {"คำซ้ำ"},
}
labels["ศัพท์ที่ผันรูปย้อนกลับ"] = {
description = "{{{langname}}} terms formed by reversing a supposed regular formation, removing part of an older term.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["back-formations"] = labels["ศัพท์ที่ผันรูปย้อนกลับ"]
labels["คำหลอม"] = {
description = "{{{langname}}} terms formed by combinations of other words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["blends"] = labels["คำหลอม"]
labels["ศัพท์ที่ยืมมา"] = {
description = "{{{langname}}} terms that are loanwords, i.e. words that were directly incorporated from another language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["borrowed terms"] = labels["ศัพท์ที่ยืมมา"]
labels["catachreses"] = {
description = "{{{langname}}} terms derived from misuses or misapplications of other terms.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่บัญญัติ"] = {
description = "{{{langname}}} terms coined by an identifiable person, organization or other such entity.",
parents = {"terms attributed to a specific source"},
umbrella_parents = {name = "terms attributed to a specific source", is_label = true, sort = " "},
}
labels["coinages"] = labels["ศัพท์ที่บัญญัติ"]
labels["coordinated pairs"] = {
description = "Terms in {{{langname}}} consisting of a pair of terms joined by a [[coordinating conjunction]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated triples"] = {
description = "Terms in {{{langname}}} consisting of three terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quadruples"] = {
description = "Terms in {{{langname}}} consisting of four terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quintuples"] = {
description = "Terms in {{{langname}}} consisting of five terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากคำนาม"] = {
description = "{{{langname}}} terms derived from a noun.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["denominals"] = labels["ศัพท์ที่รับมาจากคำนาม"]
labels["ศัพท์ที่รับมาจากคำกริยา"] = {
description = "{{{langname}}} terms derived from a verb.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["deverbals"] = labels["ศัพท์ที่รับมาจากคำกริยา"]
labels["ศัพท์ที่ร่วมราก"] = {
description = "{{{langname}}} terms that trace their etymology from ultimately the same source as other terms in the same language, but by different routes, and often with subtly or substantially different meanings.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["doublets"] = labels["ศัพท์ที่ร่วมราก"]
labels["elongated forms"] = {
description = "{{{langname}}} terms where one or more letters or sounds is repeated for emphasis or effect.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากชื่อบุคคล"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["eponyms"] = labels["ศัพท์ที่รับมาจากชื่อบุคคล"]
labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"] = {
description = "{{{langname}}} terms that originate from [[trademark]]s, [[brand]]s and company names which have become [[genericized]]; that is, fallen into common usage in the target market's [[vernacular]], even when referring to other competing brands.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "เครื่องหมายการค้า"},
}
labels["genericized trademarks"] = labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"]
labels["ghost words"] = {
description = "{{{langname}}} terms that were originally erroneous or fictitious, published in a reference work as if they were genuine as a result of typographical error, misreading, or misinterpretation, or as [[:w:Fictitious entry|fictitious entries]], jokes, or hoaxes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["gramograms"] = {
description = "{{{langname}}} [[gramogram]]s – terms that are partially or completely spelled with [[homophone|homophonous]] letters.",
parents = {"rebuses"},
}
labels["haplological words"] = {
description = "{{{langname}}} words that underwent [[haplology]]: thus, their origin involved a loss or omission of a repeated sequence of sounds.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["homophonic translations"] = {
description = "{{{langname}}} terms that were borrowed by matching the etymon phonetically, without regard for the sense; compare [[phono-semantic matching]] and [[Hobson-Jobson]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["hybridisms"] = {
description = "{{{langname}}} terms formed by elements of different linguistic origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบทอด"] = {
description = "{{{langname}}} terms that were inherited from an earlier stage of the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["inherited terms"] = labels["ศัพท์ที่สืบทอด"]
labels["internationalisms"] = {
description = "{{{langname}}} loanwords which also exist in many other languages with the same or similar etymology.",
additional = "Terms should be here preferably only if the immediate source language is not known for certain. Entries are added into this category by [[Template:internationalism]]; see it for more information.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["legal doublets"] = {
description = "{{{langname}}} legal [[doublet]]s – a legal doublet is a standardized phrase commonly use in legal documents, proceedings etc. which includes two words that are near synonyms.",
parents = {"coordinated pairs"},
}
labels["legal triplets"] = {
description = "{{{langname}}} legal [[triplet]]s – a legal triplet is a standardized phrase commonly use in legal documents, proceedings etc which includes three words that are near synonyms.",
parents = {"coordinated triples"},
}
labels["LLM coinages"] = {
description = "{{{langname}}} terms that have been coined by {{w|large language models}} rather than humans.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["merisms"] = {
description = "{{{langname}}} [[merism]]s – terms that are [[coordinate]]s that, combined, are a synonym for a totality.",
parents = {"coordinated pairs"},
}
labels["metonyms"] = {
description = "{{{langname}}} terms whose origin involves calling a thing or concept not by its own name, but by the name of something intimately associated with that thing or concept.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["นวศัพท์"] = {
description = "{{{langname}}} terms that have been only recently acknowledged.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["neologisms"] = labels["นวศัพท์"]
labels["nonce terms"] = {
description = "{{{langname}}} terms that have been invented for a single occasion.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["number homophones"] = {
description = "{{{langname}}} terms that are partially or completely spelled with [[homophone|homophonous]] numbers.",
parents = {"rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["numerical contractions"] = {
description = "{{{langname}}} numerical contractions. In these, the number either denotes omitted characters ({{m+|en|globalization}} → {{m|en|g11n}}) or duplication ({{m+|kne|Kankanaey}} → {{m|kne|Kan2aey}}).",
parents = {"contractions", "rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["ศัพท์ที่เลียนเสียงธรรมชาติ"] = {
description = "{{{langname}}} terms that were coined to sound like what they represent.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["onomatopoeias"] = labels["ศัพท์ที่เลียนเสียงธรรมชาติ"]
labels["piecewise doublets"] = {
description = "{{{langname}}} terms that are [[ภาคผนวก:อภิธานศัพท์#piecewise doublet|piecewise doublets]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
--[=[ thwikt don't use specific terms below
for _, ism_and_langname in ipairs({
{"anglicisms", "English"},
{"Arabisms", "Arabic"},
{"Gallicisms", "French"},
{"Germanisms", "German"},
{"Hispanisms", "Spanish"},
{"Italianisms", "Italian"},
{"Latinisms", "Latin"},
{"Japonisms", "Japanese"},
}) do
local ism, langname = unpack(ism_and_langname)
labels["pseudo-" .. ism] = {
description = "{{{langname}}} terms that appear to be " .. langname .. ", but are not used or have an unrelated meaning in " .. langname .. " itself.",
parents = {"pseudo-loans"},
umbrella_parents = {name = "pseudo-loans", is_label = true, sort = " "},
}
end
--]=]
labels["rebracketings"] = {
description = "{{{langname}}} terms that have interacted with another word in such a way that the boundary between the words has been modified.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["rebuses"] = {
description = "{{{langname}}} [[rebus]]es – terms that are partially or completely represented by images, symbols or numbers, often as a form of wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบสร้าง"] = {
description = "{{{langname}}} terms that are not directly attested, but have been reconstructed through other evidence.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["reconstructed terms"] = labels["ศัพท์ที่สืบสร้าง"]
labels["reduplicated coordinated pairs"] = {
description = "{{{langname}}} reduplicated coordinated pairs.",
breadcrumb = "reduplicated",
parents = {"coordinated pairs", "คำซ้ำ"},
}
labels["reduplicated coordinated triples"] = {
description = "{{{langname}}} reduplicated coordinated triples.",
breadcrumb = "reduplicated",
parents = {"coordinated triples", "คำซ้ำ"},
}
labels["reduplicated coordinated quadruples"] = {
description = "{{{langname}}} reduplicated coordinated quadruples.",
breadcrumb = "reduplicated",
parents = {"coordinated quadruples", "คำซ้ำ"},
}
labels["reduplicated coordinated quintuples"] = {
description = "{{{langname}}} reduplicated coordinated quintuples.",
breadcrumb = "reduplicated",
parents = {"coordinated quintuples", "คำซ้ำ"},
}
labels["คำซ้ำ"] = {
description = "{{{langname}}} terms that underwent [[reduplication]], so their origin involved a repetition of roots or stems.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["reduplications"] = labels["คำซ้ำ"]
labels["retronyms"] = {
description = "{{{langname}}} terms that serve as new unique names for older objects or concepts whose previous names became ambiguous.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ราก"] = {
description = "Basic morphemes from which {{{langname}}} words are formed.",
parents = {"หน่วยคำ"},
}
labels["roots"] = labels["ราก"]
labels["Sanskritic formations"] = {
description = "{{{langname}}} terms coined from [[tatsama]] [[word]]s and/or [[affix]]es.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่รับมาจากภาษาสันสกฤต"},
}
labels["sound-symbolic terms"] = {
description = "{{{langname}}} terms that use {{w|sound symbolism}} to express ideas but which are not necessarily strictly speaking [[onomatopoeic]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelled-out initialisms"] = {
description = "{{{langname}}} initialisms in which the letter names are spelled out.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelling pronunciations"] = {
description = "{{{langname}}} terms whose pronunciation was historically or presently affected by their spelling.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["คำผวน"] = {
description = "{{{langname}}} terms in which the initial sounds of component parts have been exchanged, as in \"crook and nanny\" for \"nook and cranny\".",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spoonerisms"] = labels["คำผวน"]
labels["taxonomic eponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people, used for [[taxonomy]].",
parents = {"ศัพท์ที่รับมาจากชื่อบุคคล"},
}
labels["terms attributed to a specific source"] = {
description = "{{{langname}}} terms coined by an identifiable person or deriving from a known work.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms coined ex nihilo"] = {
description = "{{{langname}}} terms fabricated ''[[ex nihilo]]'', i.e. made up entirely rather than being derived from an existing source.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms containing fossilized case endings"] = {
description = "{{{langname}}} terms which preserve case morphology which is no longer analyzable within the contemporary grammatical system or which has been entirely lost from the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from area codes"] = {
description = "{{{langname}}} terms derived from [[area code]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"] = {
description = "{{{langname}}} terms derived from the shape of letters. This can include terms derived from the shape of any letter in any alphabet.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from the shape of letters"] = labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"]
labels["ศัพท์แบ่งตามราก"] = {
description = "{{{langname}}} terms categorized by the root they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์", {name = "ราก", sort = " "}},
}
labels["terms by root"] = labels["ศัพท์แบ่งตามราก"]
labels["ศัพท์แบ่งตามคำ"] = {
description = "{{{langname}}} terms categorized by the word they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms by word"] = labels["ศัพท์แบ่งตามคำ"]
labels["ศัพท์ที่รับมาจากบันเทิงคดี"] = {
description = "{{{langname}}} terms that originate from works of [[fiction]].",
breadcrumb = "บันเทิงคดี",
parents = {{name = "terms attributed to a specific source", sort = "บันเทิงคดี"}},
}
labels["terms derived from fiction"] = labels["ศัพท์ที่รับมาจากบันเทิงคดี"]
for _, data in ipairs {
{source="Dickensian works", desc="the works of [[w:Charles Dickens|Charles Dickens]]", topic_parent="Charles Dickens"},
{source="ดีซีคอมิกส์", desc="[[w:ดีซีคอมิกส์|ดีซีคอมิกส์]]"},
{source="โดราเอมอน", desc="[[w:Fujiko F. Fujio|Fujiko F. Fujio]]'s ''[[w:โดราเอมอน|โดราเอมอน]]''", displaytitle="''โดราเอมอน''"},
{source="ดรากอนบอล", desc="[[w:Akira Toriyama|Akira Toriyama]]'s ''[[w:ดรากอนบอล|ดรากอนบอล]]''", displaytitle="''ดรากอนบอล''"},
{source="ดักเบิร์กและเมาส์ตัน", desc="[[w:The Walt Disney Company|Disney]]'s [[w:Duck universe|Duckburg]] and [[w:Mickey Mouse universe|Mouseton]] universe",
topic_parent="ดิสนีย์"},
{source="ฟิวเจอรามา", desc="the animated television series ''{{w|ฟิวเจอรามา}}''", displaytitle = "''ฟิวเจอรามา''"},
{source="แฮร์รี่ พอตเตอร์", desc="the ''[[w:แฮร์รี่ พอตเตอร์|แฮร์รี่ พอตเตอร์]]'' series", displaytitle="''แฮร์รี่ พอตเตอร์''",
topic_parent="แฮร์รี่ พอตเตอร์"},
{source="Looney Tunes and Merrie Melodies", desc="''{{w|Looney Tunes}}'' and/or ''{{w|Merrie Melodies}}'', by {{w|Warner Bros. Animation}}", displaytitle = "''Looney Tunes'' and ''Merrie Melodies''"},
{source="หนึ่งเก้าแปดสี่", desc="[[w:George Orwell|George Orwell]]'s ''[[w:Nineteen Eighty-Four|Nineteen Eighty-Four]]''",
displaytitle="''หนึ่งเก้าแปดสี่''"},
{source="Seinfeld", desc="the American television sitcom ''{{w|Seinfeld}}'' (1989–1998)", displaytitle="''Seinfeld''"},
{source="Seussian works", desc="the works of [[w:Dr. Seuss|Dr. Seuss]]"},
{source="South Park", desc="the animated television series ''[[w:South Park|South Park]]''", displaytitle="''South Park''"},
{source="สตาร์ เทรค", desc="''[[w:สตาร์ เทรค|สตาร์ เทรค]]''", displaytitle="''สตาร์ เทรค''", topic_parent="สตาร์ เทรค"},
{source="สตาร์ วอร์ส", desc="''[[w:สตาร์ วอร์ส|สตาร์ วอร์ส]]''", displaytitle="''สตาร์ วอร์ส''", topic_parent="สตาร์ วอร์ส"},
{source="เดอะซิมป์สันส์", desc="''[[w:เดอะซิมป์สันส์|เดอะซิมป์สันส์]]''", displaytitle="''เดอะซิมป์สันส์''", topic_parent="เดอะซิมป์สันส์", sort="ซิมป์สันส์"},
{source="ปกรณัมของโทลคีน", desc="the [[legendarium]] of [[w:เจ. อาร์. อาร์. โทลคีน|เจ. อาร์. อาร์. โทลคีน]]", topic_parent="เจ. อาร์. อาร์. โทลคีน"},
} do
local parents = {{name = "ศัพท์ที่รับมาจากบันเทิงคดี", sort = data.sort or data.source}}
local umbrella_parents = {"หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"}
if data.topic_parent then
insert(parents, {name = "{{{langcode}}}:" .. data.topic_parent, raw = true})
insert(umbrella_parents, {name = data.topic_parent, raw = true})
end
labels["ศัพท์ที่รับมาจาก" .. data.source] = {
description = "{{{langname}}} terms that originate from " .. data.desc .. ".",
breadcrumb = data.displaytitle or data.source,
parents = parents,
umbrella = {
parents = umbrella_parents,
displaytitle = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle .. "แบ่งตามภาษา" or nil,
breadcrumb = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle,
},
displaytitle = data.displaytitle and "ศัพท์{{{langcat}}}ที่รับมาจาก" .. data.displaytitle or nil,
}
end
labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"] = {
description = "{{{langname}}} terms derived from Greek mythology which have acquired an idiomatic meaning.",
breadcrumb = "ประมวลเรื่องปรัมปรากรีก",
parents = {{name = "terms attributed to a specific source", sort = "ประมวลเรื่องปรัมปรากรีก"}},
}
labels["terms derived from Greek mythology"] = labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"]
labels["ศัพท์ที่รับมาจากอาชีพ"] = {
description = "{{{langname}}} terms derived from names of occupations.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from occupations"] = labels["ศัพท์ที่รับมาจากอาชีพ"]
labels["ศัพท์ที่รับมาจากภาษาอื่น"] = {
description = "{{{langname}}} terms that originate from other languages.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from other languages"] = labels["ศัพท์ที่รับมาจากภาษาอื่น"]
labels["ศัพท์ที่รับมาจากไบเบิล"] = {
description = "{{{langname}}} terms that originate from the [[Bible]].",
breadcrumb = {name = "ไบเบิล", nocap = true},
parents = {{name = "terms attributed to a specific source", sort = "ไบเบิล"}},
}
labels["terms derived from the Bible"] = labels["ศัพท์ที่รับมาจากไบเบิล"]
labels["ศัพท์ที่รับมาจากนิทานอีสป"] = {
description = "{{{langname}}} terms that originate from [[Aesop]]'s Fables.",
breadcrumb = "นิทานอีสป",
parents = {{name = "terms attributed to a specific source", sort = "นิทานอีสป"}},
}
labels["terms derived from Aesop's Fables"] = labels["ศัพท์ที่รับมาจากนิทานอีสป"]
labels["terms derived from toponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious places.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived through romanized wordplay"] = {
description = "{{{langname}}} terms derived through romanized wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms making reference to character shapes"] = {
description = "{{{langname}}} terms making reference to character shapes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากกีฬา"] = {
description = "{{{langname}}} terms that originate from sports.",
breadcrumb = "กีฬา",
parents = {{name = "terms attributed to a specific source", sort = "กีฬา"}},
}
labels["terms derived from sport"] = labels["ศัพท์ที่รับมาจากกีฬา"]
labels["ศัพท์ที่รับมาจากเบสบอล"] = {
description = "{{{langname}}} terms that originate from baseball.",
breadcrumb = "เบสบอล",
parents = {{name = "ศัพท์ที่รับมาจากกีฬา", sort = "เบสบอล"}},
}
labels["terms derived from baseball"] = labels["ศัพท์ที่รับมาจากเบสบอล"]
labels["terms with Indo-Aryan extensions"] = {
description = "{{{langname}}} terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with lemma and non-lemma form etymologies"] = {
description = "{{{langname}}} terms consisting of both a lemma and non-lemma form, of different origins.",
breadcrumb = "lemma and non-lemma form",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple etymologies"] = {
description = "{{{langname}}} terms that are derived from multiple origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with multiple lemma etymologies"] = {
description = "{{{langname}}} lemmas that are derived from multiple origins.",
breadcrumb = "multiple lemmas",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple non-lemma form etymologies"] = {
description = "{{{langname}}} non-lemma forms that are derived from multiple origins.",
breadcrumb = "multiple non-lemma forms",
parents = {"terms with multiple etymologies"},
}
labels["ศัพท์ที่ไม่ทราบรากศัพท์"] = {
description = "{{{langname}}} terms whose etymologies have not yet been established.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "ไม่ทราบรากศัพท์"}},
}
labels["terms with unknown etymologies"] = labels["ศัพท์ที่ไม่ทราบรากศัพท์"]
labels["univerbations"] = {
description = "{{{langname}}} terms that result from the agglutination of two or more words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["words derived through corruption"] = {
description = "{{{langname}}} words that result from a non-specific or sporadic change.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "corruption"}},
}
labels["words derived through metathesis"] = {
description = "{{{langname}}} words that were created through [[metathesis]] from another word.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "metathesis"}},
}
labels["words that have undergone semantic shift"] = {
description = "{{{langname}}} words that show senses explained by [[semantic shift]].",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "semantic shift"}},
}
labels["words that have undergone semantic broadening"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[broadening]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic broadening"}},
}
labels["words that have undergone semantic narrowing"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[narrowing]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic narrowing"}},
}
labels["words that have undergone amelioration"] = {
description = "{{{langname}}} words that have gained a positive [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "amelioration"}},
}
labels["words that have undergone pejoration"] = {
description = "{{{langname}}} words that have gained a negative [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "pejoration"}},
}
labels["terms with origins in folklore"] = {
description = "{{{langname}}} terms that have an etymology rooted in folklore.",
breadcrumb = "Folklore",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "folklore"}, {name = "{{{langcode}}}:Folklore", raw = true}},
umbrella_parents = {{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", raw = true}, {name = "Folklore", raw = true, sort = " "}}
}
-- Add 'umbrella_parents' key if not already present.
for _, data in pairs(labels) do
-- NOTE: umbrella.parents overrides umbrella_parents if both are given.
if not data.umbrella_parents then
data.umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to terms categorized by their etymologies, such as types of compounds or borrowings.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์แบ่งตามรากศัพท์", is_label = true, sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to borrowed terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่ยืมมา", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to inherited terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่สืบทอด", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Indo-Aryan extensions"] = {
description = "Umbrella categories covering terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Multiple etymology subcategories by language"] = {
description = "Umbrella categories covering topics related to terms with multiple etymologies.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["ศัพท์ที่ยืมกลับไปยังภาษาเดิม"] = {
description = "Categories with terms in specific languages that were borrowed from a second language that previously borrowed the term from the first language.",
additional = "A well-known example is {{m+|en|salaryman}}, a term borrowed from Japanese which in turn was borrowed from the English words [[salary]] and [[man]].\n\n{{{umbrella_msg}}}",
parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_source(source_name, allow_family, name_type)
local source = get_lang_by_name(source_name, nil, true, allow_family)
if source == nil then
return nil
end
-- Check that the source name matches the expected form (e.g. getCanonicalName, getDisplayForm etc).
if source[name_type](source) == source_name then
return source
end
end
local function get_source_and_type_desc(source, term_type)
if source:getCode() == "ine-pro" and term_type:find("^roots?$") then
return "[[w:Proto-Indo-European root|Proto-Indo-European " .. term_type .. "]]"
end
return "[[w:" .. source:getWikipediaArticle() .. "|" .. source:getCanonicalName() .. "]] " .. term_type
end
local function get_source_and_source_desc(source_name)
-- HACK! Map 'taxonomic names', as generated by [[Module:etymology]], back to its canonical name
-- before calling getByCanonicalName(). We need a more general solution here.
local source_desc
if source_name == "taxonomic names" then
source_name = "taxonomic name"
source_desc = "[[w:taxonomic nomenclature|taxonomic names]]"
end
local source = get_source(source_name, true, "getCanonicalName") --th
if source == nil then
return
end
source_desc = source_desc or source:makeCategoryLink()
if source:hasType("family") then
source_desc = "one of the " .. source_desc
end
return source, source_desc
end
-----------------------------------------------------------------------------
------------------------------- word handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE word word' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
local function lang_is_semitic(lang)
return lang:inFamily("sem")
end
insert(handlers, function(data)
local labelpref, word_and_id = data.label:match("^(terms belonging to the word )(.+)$")
if not word_and_id then
return
end
local word, id = word_and_id:match("^(.+) %((.-)%)$")
if not word then
word = word_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local word_desc = is_semitic and "[[w:Semitic word|word]]" or "word"
local parents = {}
if id then
insert(parents, {name = labelpref .. word, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามคำ", sort = word_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style words)
local word_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(word, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(word_no_prefix_suffix, not_separator_c, ""))
local linked_word = data.lang and full_link({ term = word, lang = data.lang, gloss = id, id = id }, "term") or word
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter words", sort = word_and_id})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, word, tag_text(word, lang, nil, "term"))
end
local breadcrumb = tag_text(word, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. word_desc .. " " .. linked_word .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^terms by (.+) word$")
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian word]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source:getDisplayForm())
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "word") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
-----------------------------------------------------------------------------
------------------------------- Root handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE root ROOT' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
-- Handler for e.g. [[:Category:Yola terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Russian terms derived from the Proto-Indo-European word *swé]], and corresponding umbrella
-- categories [[:Category:Terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Terms derived from the Proto-Indo-European word *swé]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(handlers, function(data)
local source_name, term_type, term_and_id
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name, term_and_id = data.label:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+) (.+)$")
if source_name then
term_type = tt
break
end
end
if not source_name then
return
end
local term, id = term_and_id:match("^(.+) %((.-)%)$")
if not term then
term = term_and_id
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {
{
name = "ศัพท์แบ่งตาม" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
local umbrella_parents = {
{
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
if id then
insert(parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
sort = " "
})
insert(umbrella_parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
is_label = true,
sort = " "
})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, term, tag_text(term, source, nil, "term"))
end
local breadcrumb = tag_text(term, source, nil, "term") .. (id and " (" .. id .. ")" or "")
local term_page, alt_form
if term_type == "root" and lang_is_semitic(source) then
term_page = ("ภาคผนวก:ราก%s/%s"):format(source:getCanonicalName(), term)
alt_form = term
else
term_page = term
end
return {
description = "{{{langname}}} terms that originate ultimately from the " .. get_source_and_type_desc(source, term_type) .. " " .. full_link({
term = term_page,
alt = alt_form,
lang = source,
gloss = id,
id = id
}, "term") .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
no_by_language = true,
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = umbrella_parents,
}
}
end)
insert(handlers, function(data)
local labelpref, root_and_id = data.label:match("^(terms belonging to the root )(.+)$")
if not root_and_id then
return
end
local root, id = root_and_id:match("^(.+) %((.-)%)$")
if not root then
root = root_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local root_desc = is_semitic and "[[w:Semitic root|root]]" or "root"
local parents = {}
if id then
insert(parents, {name = labelpref .. root, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามราก", sort = root_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style roots)
local root_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(root, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(root_no_prefix_suffix, not_separator_c, ""))
local root_page, alt_form
if is_semitic then
root_page = ("ภาคผนวก:ราก%s/%s"):format(data.lang:getCanonicalName(), root)
alt_form = root
else
root_page = root
end
local linked_root = data.lang and full_link(
{ term = root_page, alt = alt_form, lang = data.lang, gloss = id, id = id }, "term") or root_page
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter roots", sort = root_and_id})
end
-- Italicize the root/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, root, tag_text(root, lang, nil, "term"))
end
local breadcrumb = tag_text(root, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. root_desc .. " " .. linked_root .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์แบ่งตามราก(.+)$")
if not source_name or source_name == "ศัพท์" then --th; excludes falsily detect ศัพท์แบ่งตามรากศัพท์
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian root]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source_name)
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "root") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
insert(handlers, function(data)
local root_shape, post, additional = data.label:match("^(.+)([ -])shaped roots$")
if not root_shape then
return
elseif data.lang and data.lang:getCode() == "ine-pro" then
additional = [=[
* '''e''' stands for the vowel of the root.
* '''C''' stands for any stop or ''s''.
* '''R''' stands for any resonant.
* '''H''' stands for any laryngeal.
* '''M''' stands for ''m'' or ''w'', when followed by a resonant.
* '''s''' stands for ''s'', when next to a stop.]=]
end
if root_shape == "irregularly" and post == " " then
return {
breadcrumb = "irregular",
description = "{{{langname}}} roots with a shape that violates the {{w|Proto-Indo-European root#Shape of a root|known rules on root shapes}}.",
additional = additional,
parents = {{name = "roots by shape", sort = "*"}},
umbrella = false,
}
elseif post == " " then
return
end
return {
breadcrumb = root_shape,
description = "{{{langname}}} roots with the shape ''" .. root_shape .. "''.",
additional = additional,
parents = {{name = "roots by shape", sort = root_shape}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
-------------------- Derived/inherited/borrowed handlers --------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form "LANG terms derived from SOURCE", where SOURCE is a language, etymology language
-- or family (e.g. "Indo-European languages"), along with corresponding umbrella categories of the form
-- "Terms derived from SOURCE".
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์ที่รับมาจากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่รับมาจากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- Compute description.
local desc = "{{{langname}}} terms that originate from " .. source_desc .. "."
local additional
if source:hasType("family") then
additional = "This category should, ideally, contain only other categories. Entries can be categorized here, too, when the proper subcategory is unclear. " ..
"If you know the exact language from which an entry categorized here is derived, please edit its respective entry."
end
-- Compute parents.
local derived_from_variety_of_self = false
local parent
local sortkey = source:getDisplayForm()
if source:hasType("etymology-only") then
-- By default, `parent` is the source's parent.
parent = source:getParent()
-- Check if the source is a variety (or subvariety) of the language.
if data.lang and source:hasParent(data.lang) then
derived_from_variety_of_self = true
end
-- If the language is the direct parent of the source or the parent is "und", then we use the family of the source as `parent` instead.
if data.lang and (parent:getCode() == data.lang:getCode() or parent:getCode() == "und") then
parent = source:getFamily()
end
-- Regular language or family.
else
local fam = source:getFamily()
if fam then
parent = fam
end
end
-- If `parent` does not exist, is the same as `source`, or would be "isolate languages" or "not a family", then we discard it.
if (not parent) or parent:getCode() == source:getCode() or parent:getCode() == "qfa-iso" or parent:getCode() == "qfa-not" or
parent:getCode() == "qfa-unc" then
parent = nil
derived_from_variety_of_self = false
-- Otherwise, get the display form.
else
parent = parent:getDisplayForm()
end
parent = parent and "ศัพท์ที่รับมาจาก" .. parent or "ศัพท์ที่รับมาจากภาษาอื่น"
local parents = {{name = parent, sort = sortkey}}
if derived_from_variety_of_self then
insert(parents, "Category:Categories for terms in a language derived from a term in a subvariety of that language")
end
-- Compute umbrella parents.
local cat_name = source:getCode() == "mul-tax" and "Taxonomic names" or source:getCategoryName()
-- If the source is etymology-only, its category will be handled by the lect handler in
-- [[Module:category tree/ภาษณ์]]. If it has a nonstandard name like 'Kölsch' (i.e. not a name like
-- 'American English' that has a language name in it), the lect handler won't handle it unless we tell it to do so
-- through the following call; this is an optimization to avoid expensive processing work on all manner of randomly
-- named categories.
if source:hasType("etymology-only") then
require("Module:category tree/ภาษณ์").export.register_likely_lect_parent_cat(cat_name)
end
local umbrella_parents = {
(source:hasType("family") or source:getCode() == "mul-tax") and {name = cat_name, raw = true, sort = " "} or
{name = cat_name, raw = true, sort = "terms derived from"}
}
-- Without the following, the breadcrumb trail for e.g. [[Category:Javanese terms derived from French]] looks like
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages »
-- Indo-European languages » Italic languages » Romance languages » Italo-Western Romance languages »
-- Western Romance languages » Gallo-Romance languages » Gallo-Rhaetian languages » Oïl languages » French
-- To reduce the length, we truncate the "languages" part of the breadcrumbs as long as this does not create
-- ambiguity (i.e. unless there is a language with the same name as the family). Hence, for the Category
-- [[Category:Javanese terms derived from Arabic]], we end up with
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages » Afroasiatic »
-- Semitic » West Semitic » Central Semitic » Arabic languages » Arabic
-- because "Arabic" is ambiguous between family and language (and script, for that matter).
local breadcrumb = source_name
if source:hasType("family") and breadcrumb:find("กลุ่มภาษา") then
local truncated_breadcrumb = breadcrumb:gsub("กลุ่มภาษา", "")
if not get_lang_by_name(truncated_breadcrumb, nil, "allow etym") then
breadcrumb = truncated_breadcrumb
end
end
return {
description = desc,
additional = additional,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
description = "Categories with terms that originate from " .. source_desc .. ".",
parents = umbrella_parents,
},
}
end)
-- Handler for categories of the form "LANG terms inherited/borrowed from SOURCE", where SOURCE is a language,
-- etymology language or family (e.g. "Indo-European languages"). Also handles umbrella categories of the form
-- "Terms inherited/borrowed from SOURCE".
local function inherited_borrowed_handler(etymtype)
return function(data)
local source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
return {
description = "{{{langname}}} terms " .. etymtype .. " from " .. source_desc .. ".",
breadcrumb = source_name,
parents = {
{name = "ศัพท์ที่" .. etymtype, sort = source_name},
{name = "ศัพท์ที่รับมาจาก" .. (source:hasType("family") and "กลุ่มภาษา" or "ภาษา") .. source_name, sort = " "}
},
umbrella = {
parents = {
{ name = "ศัพท์ที่รับมาจากภาษา" .. source_name, is_label = true, sort = " " },
etymtype == "inherited" and
{ name = "หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา", sort = source_name }
-- There are several types of borrowings mixed into the following holding category,
-- so keep these ones sorted under 'Terms borrowed from SOURCE_NAME' instead of just
-- 'SOURCE_NAME'.
or "หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
end
table.insert(handlers, inherited_borrowed_handler("ยืมมา"))
table.insert(handlers, inherited_borrowed_handler("สืบทอด"))
-----------------------------------------------------------------------------
------------------------ Borrowing subtype handlers -------------------------
-----------------------------------------------------------------------------
-- General handler for specific borrowing subtypes, such as learned borrowings, calques and phono-semantic matchings.
local function borrowing_subtype_handler(dest, source_name, parent_cat, spec)
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- normally uses of UNKNOWN should not show up to the end user
local dest_name = dest and dest:getCanonicalName() or "UNKNOWN"
local additional, umbrella_additional
if spec.additional then
if dest then
additional = spec.additional(source, dest)
else
umbrella_additional = spec.umbrella_additional(source)
end
else
if not spec.categorizing_templates then
error("Internal error: Must specify either `categorizing_templates` or the combination of `additional` and `umbrella_additional` in each borrowing subtype spec")
end
local extra_templates = {}
local extra_template_text
for i, template in ipairs(spec.categorizing_templates) do
if i > 1 then
insert(extra_templates, ("{{tl|%s|...}}"):format(template))
end
end
if #extra_templates > 0 then
extra_template_text = (" (or %s, using the same syntax)"):format(
serial_comma_join(extra_templates, {conj = "or"}))
else
extra_template_text = ""
end
if dest then
additional = ("To categorize a term into this category, use {{tl|%s|%s|%s|<var>source_term</var>}}%s, " ..
"where <code><var>source_term</var></code> is the %s term that the term in question " ..
"was borrowed from."):format(
spec.categorizing_templates[1], dest:getCode(), source:getCode(), extra_template_text, source_name)
else
umbrella_additional = ("To categorize a term into a language-specific subcategory, use " ..
"{{tl|%s|<var>destcode</var>|%s|<var>source_term</var>}}%s, where <code><var>destcode</var></code> " ..
"is the language code of the language in question (see [[Wiktionary:List of languages]]), and " ..
"<code><var>source_term</var></code> is the %s term that the term in question was " ..
"borrowed from."):format(spec.categorizing_templates[1], source:getCode(), extra_template_text, source_name)
end
end
return {
description = "{{{langname}}} " .. spec.from_source_desc:gsub("SOURCE", source_desc):gsub("DEST", dest_name),
additional = additional,
breadcrumb = source_name,
parents = {
{ name = parent_cat, sort = source_name },
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, sort = " " },
},
umbrella = {
additional = umbrella_additional,
parents = {
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, is_label = true, sort = " " },
"หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
-- Specs describing types of borrowings.
-- `from_source_desc` is the English description used in categories of the form "LANGUAGE BORTYPE from SOURCE",
-- e.g. "Arabic semantic loans from English". "SOURCE" in the description is replaced by the source language.
-- `umbrella_desc` is the English description used in categories of the form "LANGUAGE BORTYPE", e.g.
-- "Arabic semantic loans". This is an umbrella category grouping all the source-language-specific categories.
-- `uses_subtype_handler`, if true, means that the handler for "LANGUAGE BORTYPE from SOURCE" categories is
-- implemented by a generic "TYPE borrowings" handler (at the bottom of this section), so we don't need to
-- create a BORTYPE-specific handler.
-- `umbrella_parent`, if given, is the parent category of the umbrella categories of the form "LANGUAGE BORTYPE".
-- By default it is "borrowed terms". Some borrowing types replace this with "terms by etymology". (FIXME:
-- Review whether this is correct.)
-- `label_pattern`, if given, is a Lua pattern that matches the category name minus the language at the beginning.
-- It should have one capture, which is the source language. An example is "^terms partially calqued from (.+)$".
-- If omitted, it is generated from BORTYPE.
-- `categorizing_templates`, if given, is the list of templates that categorize into this category. They are assumed to
-- follow the syntax of {{bor}}. The first template in the list should be the preferred alias. The specified
-- templates are used to form the `additional` text displayed on the language-specific category page and
-- corresponding umbrella category page describing how to categorize into the category in question. In more complex
-- cases, you can omit this field and instead supply the `additional` and `umbrella_additional` fields (as is done
-- with adapted borrowings). You must either specify `categorizing_templates` or the combination of `additional` and
-- `umbrella_additional`.
-- `additional`, if given, is a function of two arguments (source and destination language objects) that will generate
-- the `additional` text displayed on the language-specific category page that describes how to categorize into the
-- category in question. This is an alternative to specifying `categorizing_templates`, used in more complex cases
-- (currently, with adapted borrowings).
-- `umbrella_additional`, if given, is a function of one argument (source language object) that will generate the
-- `additional` text displayed on the umbrella category page that describes how to categorize into the category in
-- question. This is an alternative to specifying `categorizing_templates`, used in more complex cases (currently,
-- with adapted borrowings).
local borrowing_specs = {
["ศัพท์ที่ยืมโดยเรียนรู้"] = {
from_source_desc = "terms that are learned [[loanword]]s from SOURCE, that is, terms that were directly incorporated from SOURCE instead of through normal language contact.",
umbrella_desc = "terms that are learned [[loanword]]s, that is, terms that were directly incorporated from another language instead of through normal language contact.",
uses_subtype_handler = true,
categorizing_templates = {"lbor", "learned borrowing"},
},
["ศัพท์ที่ยืมโดยกึ่งเรียนรู้"] = {
from_source_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s from SOURCE, that is, terms borrowed from SOURCE (a [[classical language]]) into DEST (a modern language) and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
umbrella_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s, that is, terms borrowed from a [[classical language]] into a modern language and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
uses_subtype_handler = true,
categorizing_templates = {"slbor", "semi-learned borrowing"},
},
["ศัพท์ที่ยืมอักขรวิธี"] = {
from_source_desc = "orthographic loans from SOURCE, i.e. terms that were borrowed from SOURCE in their script forms, not their pronunciations.",
umbrella_desc = "orthographic loans, i.e. terms that were borrowed in their script forms, not their pronunciations.",
uses_subtype_handler = true,
categorizing_templates = {"obor", "orthographic borrowing"},
},
["ศัพท์ที่ยืมโดยไม่ดัดแปลง"] = {
from_source_desc = "[[loanword]]s from SOURCE that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of DEST.",
umbrella_desc = "[[loanword]]s that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of the target language.",
uses_subtype_handler = true,
categorizing_templates = {"ubor", "unadapted borrowing"},
},
["ศัพท์ที่ยืมโดยดัดแปลง"] = {
from_source_desc = "[[loanwords]] from SOURCE formed with the addition of an affix to conform the term to the normal morphology of DEST.",
umbrella_desc = "[[loanword]]s formed with the addition of an affix to conform the term to the normal morphology of the target language.",
uses_subtype_handler = true,
additional = function(source, dest)
return ("To categorize a term into this category, use {{tl|af|%s|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|%s|3=type=abor|4=...}}, using the same syntax), where <code><var>source_term</var></code> is " ..
"the %s term that the term in question was borrowed from and <code><var>affix</var></code> " ..
"is the %s affix used to adapt the %s term. An example is " ..
"{{m+|pl|adresować||to address}}, which would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate " ..
"that is was formed from {{m+|fr|adresser}} with the addition of the Polish verb-forming affix " ..
"{{m|pl|-ować}}."):format(dest:getCode(), source:getCode(), dest:getCode(), source:getCanonicalName(), dest:getCanonicalName(),
source:getCanonicalName())
end,
umbrella_additional = function(source)
return ("To categorize a term into a language-specific subcategory, use {{tl|af|<var>destcode</var>|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|<var>destcode</var>|3=type=abor|4=...}}, using the same syntax), where " ..
"<code><var>destcode</var></code> is the language code of the target language in question (see " ..
"[[Wiktionary:List of languages]]); <code><var>source_term</var></code> is the %s term " ..
"that the term in question was borrowed from; and <code><var>affix</var></code> is the target-language " ..
"affix used to adapt the %s term. An example is {{m+|pl|adresować||to address}}, which " ..
"would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate that is was formed from " ..
"{{m+|fr|adresser}} with the addition of the Polish verb-forming affix {{m|pl|-ować}}."):format(
source:getCode(), source:getCanonicalName(), source:getCanonicalName())
end,
},
["ศัพท์ที่ยืมความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]] from SOURCE, i.e. terms one or more of whose definitions was borrowed from a term in SOURCE.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]], i.e. terms one or more of whose definitions was borrowed from a term in another language.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
categorizing_templates = {"sl", "semantic loan"},
},
["ศัพท์ที่แปลตรงตัวบางส่วน"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#partial calque|partially calqued]] from SOURCE, i.e. terms formed partly by piece-by-piece translations of SOURCE terms and partly by direct borrowing.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#partial calque|partial calques]], i.e. terms formed partly by piece-by-piece translations of terms from other languages and partly by direct borrowing.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวบางส่วนจากภาษา(.+)$",
categorizing_templates = {"pcal", "pclq", "partial calque"},
},
["ศัพท์ที่แปลตรงตัว"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#calque|calqued]] from SOURCE, i.e. terms formed by piece-by-piece translations of SOURCE terms.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#calque|calques]], i.e. terms formed by piece-by-piece translations of terms from other languages.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวจากภาษา(.+)$",
categorizing_templates = {"cal", "clq", "calque"},
},
["ศัพท์ที่เข้าคู่เสียง-ความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]] from SOURCE, i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]], i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
categorizing_templates = {"psm", "phono-semantic matching"},
},
["ศัพท์ที่ยืมเทียม"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]] from SOURCE, i.e. terms that appear to be SOURCE, but are not used or have an unrelated meaning in SOURCE itself.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]], i.e. terms that appear to be derived from another language, but are not used or have an unrelated meaning in that language itself.",
categorizing_templates = {"pl", "pseudo-loan"},
},
}
for bortype, spec in pairs(borrowing_specs) do
labels[bortype] = {
description = "{{{langname}}} " .. spec.umbrella_desc,
parents = {spec.umbrella_parent or "ศัพท์ที่ยืมมา"},
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
if not spec.uses_subtype_handler then
-- If the label pattern isn't specifically given, generate it from the `bortype`; but make sure to
-- escape hyphens in the pattern.
local label_pattern = spec.label_pattern or "^" .. pattern_escape(bortype) .. "จากภาษา(.+)$"
insert(handlers, function(data)
local source_name = data.label:match(label_pattern)
if source_name then
return borrowing_subtype_handler(data.lang, source_name, bortype, spec)
end
end)
end
end
insert(handlers, function(data)
local borrowing_type, source_name = data.label:match("^(ศัพท์ที่ยืม.+)จากภาษา(.+)$")
if borrowing_type then
local spec = borrowing_specs[borrowing_type]
return borrowing_subtype_handler(data.lang, source_name, borrowing_type, spec)
end
end)
-----------------------------------------------------------------------------
---------------------- Indo-Aryan extension handlers ------------------------
-----------------------------------------------------------------------------
-- FIXME: Put this in a family-specific module.
insert(handlers, function(data)
local labelpref, extension = data.label:match("^(terms extended with Indo%-Aryan )(.+)$")
if not extension then
return
end
local lang_inc_ash = require("Module:languages").getByCode("inc-ash")
local linked_term = full_link({lang = lang_inc_ash, term = extension}, "term")
local tagged_term = tag_text(extension, lang_inc_ash, nil, "term")
return {
description = "{{{langname}}} terms extended with the [[Indo-Aryan]] [[pleonastic]] affix " .. linked_term .. ".",
displaytitle = "{{{langname}}} " .. labelpref .. tagged_term,
breadcrumb = tagged_term,
parents = {{name = "terms with Indo-Aryan extensions", sort = extension}},
umbrella = {
no_by_language = true,
parents = "Indo-Aryan extensions",
displaytitle = "Terms extended with Indo-Aryan " .. tagged_term,
}
}
end)
-----------------------------------------------------------------------------
---------------------------- Coined-by handlers -----------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local coiner = data.label:match("^terms coined by (.+)$")
if not coiner then
return
end
-- Sort by last name per request from [[User:Metaknowledge]]
local last_name = umatch(coiner, ".-%s(%S+)$")
return {
description = "{{{langname}}} terms coined by " .. coiner .. ".",
breadcrumb = coiner,
parents = {{
name = "coinages",
sort = last_name and last_name .. ", " .. coiner or coiner,
}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
------------------------ Multiple etymology handlers ------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local pos = data.label:match("^terms with multiple (.+) etymologies$")
if not pos then
return
end
local plpos = pluralize_pos(pos)
local postype = pos_lemma_or_nonlemma(plpos)
if not postype then
return
end
return {
description = "{{{langname}}} " .. plpos .. " that are derived from multiple origins.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = "multiple " .. plpos,
parents = {{
name = "terms with multiple " .. postype .. " etymologies",
sort = pos,
}},
}
end)
insert(handlers, function(data)
local pos1, pos2 = data.label:match("^terms with (.+) and (.+) etymologies$")
if not pos1 then
return
end
local pos1type = pos_lemma_or_nonlemma(pluralize_pos(pos1))
local pos2type = pos_lemma_or_nonlemma(pluralize_pos(pos2))
if not (pos1type and pos2type) then
return
end
return {
description = "{{{langname}}} terms consisting of " .. add_indefinite_article(pos1) .." of one origin and " ..
add_indefinite_article(pos2) .. " of a different origin.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = pos1 .. " and " .. pos2,
parents = {{
name = pos1type == pos2type and "terms with multiple " .. pos1type .. " etymologies" or
"terms with lemma and non-lemma form etymologies",
sort = pos1 .. " and " .. pos2,
}},
}
end)
-----------------------------------------------------------------------------
--------------------------- Borrowed-back handlers --------------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form e.g. [[:Category:English terms borrowed back into English]]. We need to use a handler
-- because the category's language occurs inside the label itself. For the same reason, the umbrella category has a
-- nonstandard name "Terms borrowed back into the same language", so we handle it as a regular parent and disable the
-- built-in umbrella mechanism.
insert(handlers, function(data)
local lang = data.lang
if not lang then
return
end
local source_name = data.label:match("^terms borrowed back into (.+)$")
if not (source_name and source_name == lang:getDisplayForm()) then
return
end
return {
description = "{{{langname}}} terms that were borrowed from another language that originally borrowed the term from " .. source_name .. ".",
parents = {"ศัพท์แบ่งตามรากศัพท์", "borrowed terms", {
name = "Terms borrowed back into the same language",
raw = true,
sort = "{{{langname}}}"
}},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
end)
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for umbrella metacategories of the form e.g. [[:Category:Terms derived from Proto-Indo-Iranian roots]]
-- and [[:Category:Terms derived from Proto-Indo-European words]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(raw_handlers, function(data)
local source_name, terms_type
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name = data.category:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+)$")
if source_name then
terms_type = tt
break
end
end
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
return {
description = "Umbrella categories covering terms derived from particular " .. get_source_and_type_desc(source, terms_type) .. ".",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{ name = terms_type == "ราก" and "ราก" or "คำหลัก", is_label = true, lang = source:getCode(), sort = " " },
{ name = "ศัพท์ที่รับมาจาก" .. source_name, is_label = true, sort = " " .. terms_type },
},
}
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}
215fo9musxyhseluw3vjg6ovgwn2g11
5722521
5722509
2026-05-05T02:37:40Z
OctraBot
3198
5722521
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local en_utilities_module = "Module:en-utilities"
local m_str_utils = require("Module:string utilities")
local add_indefinite_article = require(en_utilities_module).add_indefinite_article
local full_link = require("Module:links").full_link
local get_lang_by_name = require("Module:languages").getByCanonicalName
local insert = table.insert
local pattern_escape = m_str_utils.pattern_escape
local plain_gsub = m_str_utils.plain_gsub
local pluralize_pos = require("Module:headword").pluralize_pos
local pos_lemma_or_nonlemma = require("Module:headword").pos_lemma_or_nonlemma
local serial_comma_join = require("Module:table").serialCommaJoin
local tag_text = require("Module:script utilities").tag_text
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ศัพท์แบ่งตามรากศัพท์"] = {
description = "{{{langname}}} terms categorized by their etymologies.",
umbrella_parents = "มูลฐาน",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["terms by etymology"] = labels["ศัพท์แบ่งตามรากศัพท์"]
labels["AABB-type reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] in an AABB pattern.",
breadcrumb = "AABB-type",
parents = {"คำซ้ำ"},
}
labels["apophonic reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] with only a change in a vowel sound.",
breadcrumb = "apophonic",
parents = {"คำซ้ำ"},
}
labels["ศัพท์ที่ผันรูปย้อนกลับ"] = {
description = "{{{langname}}} terms formed by reversing a supposed regular formation, removing part of an older term.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["back-formations"] = labels["ศัพท์ที่ผันรูปย้อนกลับ"]
labels["คำหลอม"] = {
description = "{{{langname}}} terms formed by combinations of other words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["blends"] = labels["คำหลอม"]
labels["ศัพท์ที่ยืมมา"] = {
description = "{{{langname}}} terms that are loanwords, i.e. words that were directly incorporated from another language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["borrowed terms"] = labels["ศัพท์ที่ยืมมา"]
labels["catachreses"] = {
description = "{{{langname}}} terms derived from misuses or misapplications of other terms.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่บัญญัติ"] = {
description = "{{{langname}}} terms coined by an identifiable person, organization or other such entity.",
parents = {"terms attributed to a specific source"},
umbrella_parents = {name = "terms attributed to a specific source", is_label = true, sort = " "},
}
labels["coinages"] = labels["ศัพท์ที่บัญญัติ"]
labels["coordinated pairs"] = {
description = "Terms in {{{langname}}} consisting of a pair of terms joined by a [[coordinating conjunction]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated triples"] = {
description = "Terms in {{{langname}}} consisting of three terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quadruples"] = {
description = "Terms in {{{langname}}} consisting of four terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quintuples"] = {
description = "Terms in {{{langname}}} consisting of five terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากคำนาม"] = {
description = "{{{langname}}} terms derived from a noun.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["denominals"] = labels["ศัพท์ที่รับมาจากคำนาม"]
labels["ศัพท์ที่รับมาจากคำกริยา"] = {
description = "{{{langname}}} terms derived from a verb.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["deverbals"] = labels["ศัพท์ที่รับมาจากคำกริยา"]
labels["ศัพท์ที่ร่วมราก"] = {
description = "{{{langname}}} terms that trace their etymology from ultimately the same source as other terms in the same language, but by different routes, and often with subtly or substantially different meanings.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["doublets"] = labels["ศัพท์ที่ร่วมราก"]
labels["elongated forms"] = {
description = "{{{langname}}} terms where one or more letters or sounds is repeated for emphasis or effect.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากชื่อบุคคล"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["eponyms"] = labels["ศัพท์ที่รับมาจากชื่อบุคคล"]
labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"] = {
description = "{{{langname}}} terms that originate from [[trademark]]s, [[brand]]s and company names which have become [[genericized]]; that is, fallen into common usage in the target market's [[vernacular]], even when referring to other competing brands.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "เครื่องหมายการค้า"},
}
labels["genericized trademarks"] = labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"]
labels["ghost words"] = {
description = "{{{langname}}} terms that were originally erroneous or fictitious, published in a reference work as if they were genuine as a result of typographical error, misreading, or misinterpretation, or as [[:w:Fictitious entry|fictitious entries]], jokes, or hoaxes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["gramograms"] = {
description = "{{{langname}}} [[gramogram]]s – terms that are partially or completely spelled with [[homophone|homophonous]] letters.",
parents = {"rebuses"},
}
labels["haplological words"] = {
description = "{{{langname}}} words that underwent [[haplology]]: thus, their origin involved a loss or omission of a repeated sequence of sounds.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["homophonic translations"] = {
description = "{{{langname}}} terms that were borrowed by matching the etymon phonetically, without regard for the sense; compare [[phono-semantic matching]] and [[Hobson-Jobson]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["hybridisms"] = {
description = "{{{langname}}} terms formed by elements of different linguistic origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบทอด"] = {
description = "{{{langname}}} terms that were inherited from an earlier stage of the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["inherited terms"] = labels["ศัพท์ที่สืบทอด"]
labels["internationalisms"] = {
description = "{{{langname}}} loanwords which also exist in many other languages with the same or similar etymology.",
additional = "Terms should be here preferably only if the immediate source language is not known for certain. Entries are added into this category by [[Template:internationalism]]; see it for more information.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["legal doublets"] = {
description = "{{{langname}}} legal [[doublet]]s – a legal doublet is a standardized phrase commonly use in legal documents, proceedings etc. which includes two words that are near synonyms.",
parents = {"coordinated pairs"},
}
labels["legal triplets"] = {
description = "{{{langname}}} legal [[triplet]]s – a legal triplet is a standardized phrase commonly use in legal documents, proceedings etc which includes three words that are near synonyms.",
parents = {"coordinated triples"},
}
labels["LLM coinages"] = {
description = "{{{langname}}} terms that have been coined by {{w|large language models}} rather than humans.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["merisms"] = {
description = "{{{langname}}} [[merism]]s – terms that are [[coordinate]]s that, combined, are a synonym for a totality.",
parents = {"coordinated pairs"},
}
labels["metonyms"] = {
description = "{{{langname}}} terms whose origin involves calling a thing or concept not by its own name, but by the name of something intimately associated with that thing or concept.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["นวศัพท์"] = {
description = "{{{langname}}} terms that have been only recently acknowledged.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["neologisms"] = labels["นวศัพท์"]
labels["nonce terms"] = {
description = "{{{langname}}} terms that have been invented for a single occasion.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["number homophones"] = {
description = "{{{langname}}} terms that are partially or completely spelled with [[homophone|homophonous]] numbers.",
parents = {"rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["numerical contractions"] = {
description = "{{{langname}}} numerical contractions. In these, the number either denotes omitted characters ({{m+|en|globalization}} → {{m|en|g11n}}) or duplication ({{m+|kne|Kankanaey}} → {{m|kne|Kan2aey}}).",
parents = {"contractions", "rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["ศัพท์ที่เลียนเสียงธรรมชาติ"] = {
description = "{{{langname}}} terms that were coined to sound like what they represent.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["onomatopoeias"] = labels["ศัพท์ที่เลียนเสียงธรรมชาติ"]
labels["piecewise doublets"] = {
description = "{{{langname}}} terms that are [[ภาคผนวก:อภิธานศัพท์#piecewise doublet|piecewise doublets]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
--[=[ thwikt don't use specific terms below
for _, ism_and_langname in ipairs({
{"anglicisms", "English"},
{"Arabisms", "Arabic"},
{"Gallicisms", "French"},
{"Germanisms", "German"},
{"Hispanisms", "Spanish"},
{"Italianisms", "Italian"},
{"Latinisms", "Latin"},
{"Japonisms", "Japanese"},
}) do
local ism, langname = unpack(ism_and_langname)
labels["pseudo-" .. ism] = {
description = "{{{langname}}} terms that appear to be " .. langname .. ", but are not used or have an unrelated meaning in " .. langname .. " itself.",
parents = {"pseudo-loans"},
umbrella_parents = {name = "pseudo-loans", is_label = true, sort = " "},
}
end
--]=]
labels["rebracketings"] = {
description = "{{{langname}}} terms that have interacted with another word in such a way that the boundary between the words has been modified.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["rebuses"] = {
description = "{{{langname}}} [[rebus]]es – terms that are partially or completely represented by images, symbols or numbers, often as a form of wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบสร้าง"] = {
description = "{{{langname}}} terms that are not directly attested, but have been reconstructed through other evidence.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["reconstructed terms"] = labels["ศัพท์ที่สืบสร้าง"]
labels["reduplicated coordinated pairs"] = {
description = "{{{langname}}} reduplicated coordinated pairs.",
breadcrumb = "reduplicated",
parents = {"coordinated pairs", "คำซ้ำ"},
}
labels["reduplicated coordinated triples"] = {
description = "{{{langname}}} reduplicated coordinated triples.",
breadcrumb = "reduplicated",
parents = {"coordinated triples", "คำซ้ำ"},
}
labels["reduplicated coordinated quadruples"] = {
description = "{{{langname}}} reduplicated coordinated quadruples.",
breadcrumb = "reduplicated",
parents = {"coordinated quadruples", "คำซ้ำ"},
}
labels["reduplicated coordinated quintuples"] = {
description = "{{{langname}}} reduplicated coordinated quintuples.",
breadcrumb = "reduplicated",
parents = {"coordinated quintuples", "คำซ้ำ"},
}
labels["คำซ้ำ"] = {
description = "{{{langname}}} terms that underwent [[reduplication]], so their origin involved a repetition of roots or stems.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["reduplications"] = labels["คำซ้ำ"]
labels["retronyms"] = {
description = "{{{langname}}} terms that serve as new unique names for older objects or concepts whose previous names became ambiguous.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ราก"] = {
description = "Basic morphemes from which {{{langname}}} words are formed.",
parents = {"หน่วยคำ"},
}
labels["roots"] = labels["ราก"]
labels["Sanskritic formations"] = {
description = "{{{langname}}} terms coined from [[tatsama]] [[word]]s and/or [[affix]]es.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่รับมาจากภาษาสันสกฤต"},
}
labels["sound-symbolic terms"] = {
description = "{{{langname}}} terms that use {{w|sound symbolism}} to express ideas but which are not necessarily strictly speaking [[onomatopoeic]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelled-out initialisms"] = {
description = "{{{langname}}} initialisms in which the letter names are spelled out.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelling pronunciations"] = {
description = "{{{langname}}} terms whose pronunciation was historically or presently affected by their spelling.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["คำผวน"] = {
description = "{{{langname}}} terms in which the initial sounds of component parts have been exchanged, as in \"crook and nanny\" for \"nook and cranny\".",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spoonerisms"] = labels["คำผวน"]
labels["taxonomic eponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people, used for [[taxonomy]].",
parents = {"ศัพท์ที่รับมาจากชื่อบุคคล"},
}
labels["terms attributed to a specific source"] = {
description = "{{{langname}}} terms coined by an identifiable person or deriving from a known work.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms coined ex nihilo"] = {
description = "{{{langname}}} terms fabricated ''[[ex nihilo]]'', i.e. made up entirely rather than being derived from an existing source.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms containing fossilized case endings"] = {
description = "{{{langname}}} terms which preserve case morphology which is no longer analyzable within the contemporary grammatical system or which has been entirely lost from the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from area codes"] = {
description = "{{{langname}}} terms derived from [[area code]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"] = {
description = "{{{langname}}} terms derived from the shape of letters. This can include terms derived from the shape of any letter in any alphabet.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from the shape of letters"] = labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"]
labels["ศัพท์แบ่งตามราก"] = {
description = "{{{langname}}} terms categorized by the root they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์", {name = "ราก", sort = " "}},
}
labels["terms by root"] = labels["ศัพท์แบ่งตามราก"]
labels["ศัพท์แบ่งตามคำ"] = {
description = "{{{langname}}} terms categorized by the word they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms by word"] = labels["ศัพท์แบ่งตามคำ"]
labels["ศัพท์ที่รับมาจากบันเทิงคดี"] = {
description = "{{{langname}}} terms that originate from works of [[fiction]].",
breadcrumb = "บันเทิงคดี",
parents = {{name = "terms attributed to a specific source", sort = "บันเทิงคดี"}},
}
labels["terms derived from fiction"] = labels["ศัพท์ที่รับมาจากบันเทิงคดี"]
for _, data in ipairs {
{source="Dickensian works", desc="the works of [[w:Charles Dickens|Charles Dickens]]", topic_parent="Charles Dickens"},
{source="ดีซีคอมิกส์", desc="[[w:ดีซีคอมิกส์|ดีซีคอมิกส์]]"},
{source="โดราเอมอน", desc="[[w:Fujiko F. Fujio|Fujiko F. Fujio]]'s ''[[w:โดราเอมอน|โดราเอมอน]]''", displaytitle="''โดราเอมอน''"},
{source="ดรากอนบอล", desc="[[w:Akira Toriyama|Akira Toriyama]]'s ''[[w:ดรากอนบอล|ดรากอนบอล]]''", displaytitle="''ดรากอนบอล''"},
{source="ดักเบิร์กและเมาส์ตัน", desc="[[w:The Walt Disney Company|Disney]]'s [[w:Duck universe|Duckburg]] and [[w:Mickey Mouse universe|Mouseton]] universe",
topic_parent="ดิสนีย์"},
{source="ฟิวเจอรามา", desc="the animated television series ''{{w|ฟิวเจอรามา}}''", displaytitle = "''ฟิวเจอรามา''"},
{source="แฮร์รี่ พอตเตอร์", desc="the ''[[w:แฮร์รี่ พอตเตอร์|แฮร์รี่ พอตเตอร์]]'' series", displaytitle="''แฮร์รี่ พอตเตอร์''",
topic_parent="แฮร์รี่ พอตเตอร์"},
{source="Looney Tunes and Merrie Melodies", desc="''{{w|Looney Tunes}}'' and/or ''{{w|Merrie Melodies}}'', by {{w|Warner Bros. Animation}}", displaytitle = "''Looney Tunes'' and ''Merrie Melodies''"},
{source="หนึ่งเก้าแปดสี่", desc="[[w:George Orwell|George Orwell]]'s ''[[w:Nineteen Eighty-Four|Nineteen Eighty-Four]]''",
displaytitle="''หนึ่งเก้าแปดสี่''"},
{source="Seinfeld", desc="the American television sitcom ''{{w|Seinfeld}}'' (1989–1998)", displaytitle="''Seinfeld''"},
{source="Seussian works", desc="the works of [[w:Dr. Seuss|Dr. Seuss]]"},
{source="South Park", desc="the animated television series ''[[w:South Park|South Park]]''", displaytitle="''South Park''"},
{source="สตาร์ เทรค", desc="''[[w:สตาร์ เทรค|สตาร์ เทรค]]''", displaytitle="''สตาร์ เทรค''", topic_parent="สตาร์ เทรค"},
{source="สตาร์ วอร์ส", desc="''[[w:สตาร์ วอร์ส|สตาร์ วอร์ส]]''", displaytitle="''สตาร์ วอร์ส''", topic_parent="สตาร์ วอร์ส"},
{source="เดอะซิมป์สันส์", desc="''[[w:เดอะซิมป์สันส์|เดอะซิมป์สันส์]]''", displaytitle="''เดอะซิมป์สันส์''", topic_parent="เดอะซิมป์สันส์", sort="ซิมป์สันส์"},
{source="ปกรณัมของโทลคีน", desc="the [[legendarium]] of [[w:เจ. อาร์. อาร์. โทลคีน|เจ. อาร์. อาร์. โทลคีน]]", topic_parent="เจ. อาร์. อาร์. โทลคีน"},
} do
local parents = {{name = "ศัพท์ที่รับมาจากบันเทิงคดี", sort = data.sort or data.source}}
local umbrella_parents = {"หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"}
if data.topic_parent then
insert(parents, {name = "{{{langcode}}}:" .. data.topic_parent, raw = true})
insert(umbrella_parents, {name = data.topic_parent, raw = true})
end
labels["ศัพท์ที่รับมาจาก" .. data.source] = {
description = "{{{langname}}} terms that originate from " .. data.desc .. ".",
breadcrumb = data.displaytitle or data.source,
parents = parents,
umbrella = {
parents = umbrella_parents,
displaytitle = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle .. "แบ่งตามภาษา" or nil,
breadcrumb = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle,
},
displaytitle = data.displaytitle and "ศัพท์{{{langcat}}}ที่รับมาจาก" .. data.displaytitle or nil,
}
end
labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"] = {
description = "{{{langname}}} terms derived from Greek mythology which have acquired an idiomatic meaning.",
breadcrumb = "ประมวลเรื่องปรัมปรากรีก",
parents = {{name = "terms attributed to a specific source", sort = "ประมวลเรื่องปรัมปรากรีก"}},
}
labels["terms derived from Greek mythology"] = labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"]
labels["ศัพท์ที่รับมาจากอาชีพ"] = {
description = "{{{langname}}} terms derived from names of occupations.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from occupations"] = labels["ศัพท์ที่รับมาจากอาชีพ"]
labels["ศัพท์ที่รับมาจากภาษาอื่น"] = {
description = "{{{langname}}} terms that originate from other languages.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from other languages"] = labels["ศัพท์ที่รับมาจากภาษาอื่น"]
labels["ศัพท์ที่รับมาจากไบเบิล"] = {
description = "{{{langname}}} terms that originate from the [[Bible]].",
breadcrumb = {name = "ไบเบิล", nocap = true},
parents = {{name = "terms attributed to a specific source", sort = "ไบเบิล"}},
}
labels["terms derived from the Bible"] = labels["ศัพท์ที่รับมาจากไบเบิล"]
labels["ศัพท์ที่รับมาจากนิทานอีสป"] = {
description = "{{{langname}}} terms that originate from [[Aesop]]'s Fables.",
breadcrumb = "นิทานอีสป",
parents = {{name = "terms attributed to a specific source", sort = "นิทานอีสป"}},
}
labels["terms derived from Aesop's Fables"] = labels["ศัพท์ที่รับมาจากนิทานอีสป"]
labels["terms derived from toponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious places.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived through romanized wordplay"] = {
description = "{{{langname}}} terms derived through romanized wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms making reference to character shapes"] = {
description = "{{{langname}}} terms making reference to character shapes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากกีฬา"] = {
description = "{{{langname}}} terms that originate from sports.",
breadcrumb = "กีฬา",
parents = {{name = "terms attributed to a specific source", sort = "กีฬา"}},
}
labels["terms derived from sport"] = labels["ศัพท์ที่รับมาจากกีฬา"]
labels["ศัพท์ที่รับมาจากเบสบอล"] = {
description = "{{{langname}}} terms that originate from baseball.",
breadcrumb = "เบสบอล",
parents = {{name = "ศัพท์ที่รับมาจากกีฬา", sort = "เบสบอล"}},
}
labels["terms derived from baseball"] = labels["ศัพท์ที่รับมาจากเบสบอล"]
labels["terms with Indo-Aryan extensions"] = {
description = "{{{langname}}} terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with lemma and non-lemma form etymologies"] = {
description = "{{{langname}}} terms consisting of both a lemma and non-lemma form, of different origins.",
breadcrumb = "lemma and non-lemma form",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple etymologies"] = {
description = "{{{langname}}} terms that are derived from multiple origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with multiple lemma etymologies"] = {
description = "{{{langname}}} lemmas that are derived from multiple origins.",
breadcrumb = "multiple lemmas",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple non-lemma form etymologies"] = {
description = "{{{langname}}} non-lemma forms that are derived from multiple origins.",
breadcrumb = "multiple non-lemma forms",
parents = {"terms with multiple etymologies"},
}
labels["ศัพท์ที่ไม่ทราบรากศัพท์"] = {
description = "{{{langname}}} terms whose etymologies have not yet been established.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "ไม่ทราบรากศัพท์"}},
}
labels["terms with unknown etymologies"] = labels["ศัพท์ที่ไม่ทราบรากศัพท์"]
labels["univerbations"] = {
description = "{{{langname}}} terms that result from the agglutination of two or more words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["words derived through corruption"] = {
description = "{{{langname}}} words that result from a non-specific or sporadic change.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "corruption"}},
}
labels["words derived through metathesis"] = {
description = "{{{langname}}} words that were created through [[metathesis]] from another word.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "metathesis"}},
}
labels["words that have undergone semantic shift"] = {
description = "{{{langname}}} words that show senses explained by [[semantic shift]].",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "semantic shift"}},
}
labels["words that have undergone semantic broadening"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[broadening]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic broadening"}},
}
labels["words that have undergone semantic narrowing"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[narrowing]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic narrowing"}},
}
labels["words that have undergone amelioration"] = {
description = "{{{langname}}} words that have gained a positive [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "amelioration"}},
}
labels["words that have undergone pejoration"] = {
description = "{{{langname}}} words that have gained a negative [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "pejoration"}},
}
labels["terms with origins in folklore"] = {
description = "{{{langname}}} terms that have an etymology rooted in folklore.",
breadcrumb = "Folklore",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "folklore"}, {name = "{{{langcode}}}:Folklore", raw = true}},
umbrella_parents = {{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", raw = true}, {name = "Folklore", raw = true, sort = " "}}
}
-- Add 'umbrella_parents' key if not already present.
for _, data in pairs(labels) do
-- NOTE: umbrella.parents overrides umbrella_parents if both are given.
if not data.umbrella_parents then
data.umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to terms categorized by their etymologies, such as types of compounds or borrowings.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์แบ่งตามรากศัพท์", is_label = true, sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to borrowed terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่ยืมมา", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to inherited terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่สืบทอด", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Indo-Aryan extensions"] = {
description = "Umbrella categories covering terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Multiple etymology subcategories by language"] = {
description = "Umbrella categories covering topics related to terms with multiple etymologies.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["ศัพท์ที่ยืมกลับไปยังภาษาเดิม"] = {
description = "Categories with terms in specific languages that were borrowed from a second language that previously borrowed the term from the first language.",
additional = "A well-known example is {{m+|en|salaryman}}, a term borrowed from Japanese which in turn was borrowed from the English words [[salary]] and [[man]].\n\n{{{umbrella_msg}}}",
parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_source(source_name, allow_family, name_type)
local source = get_lang_by_name(source_name, nil, true, allow_family)
if source == nil then
return nil
end
-- Check that the source name matches the expected form (e.g. getCanonicalName, getDisplayForm etc).
if source[name_type](source) == source_name then
return source
end
end
local function get_source_and_type_desc(source, term_type)
if source:getCode() == "ine-pro" and term_type:find("^roots?$") then
return "[[w:Proto-Indo-European root|Proto-Indo-European " .. term_type .. "]]"
end
return "[[w:" .. source:getWikipediaArticle() .. "|" .. source:getCanonicalName() .. "]] " .. term_type
end
local function get_source_and_source_desc(source_name)
-- HACK! Map 'taxonomic names', as generated by [[Module:etymology]], back to its canonical name
-- before calling getByCanonicalName(). We need a more general solution here.
local source_desc
if source_name == "taxonomic names" then
source_name = "taxonomic name"
source_desc = "[[w:taxonomic nomenclature|taxonomic names]]"
end
local source = get_source(source_name, true, "getCanonicalName") --th
if source == nil then
return
end
source_desc = source_desc or source:makeCategoryLink()
if source:hasType("family") then
source_desc = "one of the " .. source_desc
end
return source, source_desc
end
-----------------------------------------------------------------------------
------------------------------- word handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE word word' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
local function lang_is_semitic(lang)
return lang:inFamily("sem")
end
insert(handlers, function(data)
local labelpref, word_and_id = data.label:match("^(terms belonging to the word )(.+)$")
if not word_and_id then
return
end
local word, id = word_and_id:match("^(.+) %((.-)%)$")
if not word then
word = word_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local word_desc = is_semitic and "[[w:Semitic word|word]]" or "word"
local parents = {}
if id then
insert(parents, {name = labelpref .. word, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามคำ", sort = word_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style words)
local word_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(word, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(word_no_prefix_suffix, not_separator_c, ""))
local linked_word = data.lang and full_link({ term = word, lang = data.lang, gloss = id, id = id }, "term") or word
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter words", sort = word_and_id})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, word, tag_text(word, lang, nil, "term"))
end
local breadcrumb = tag_text(word, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. word_desc .. " " .. linked_word .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^terms by (.+) word$")
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian word]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source:getDisplayForm())
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "word") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
-----------------------------------------------------------------------------
------------------------------- Root handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE root ROOT' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
-- Handler for e.g. [[:Category:Yola terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Russian terms derived from the Proto-Indo-European word *swé]], and corresponding umbrella
-- categories [[:Category:Terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Terms derived from the Proto-Indo-European word *swé]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(handlers, function(data)
local source_name, term_type, term_and_id
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name, term_and_id = data.label:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+) (.+)$")
if source_name then
term_type = tt
break
end
end
if not source_name then
return
end
local term, id = term_and_id:match("^(.+) %((.-)%)$")
if not term then
term = term_and_id
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {
{
name = "ศัพท์แบ่งตาม" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
local umbrella_parents = {
{
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
if id then
insert(parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
sort = " "
})
insert(umbrella_parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
is_label = true,
sort = " "
})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, term, tag_text(term, source, nil, "term"))
end
local breadcrumb = tag_text(term, source, nil, "term") .. (id and " (" .. id .. ")" or "")
local term_page, alt_form
if term_type == "root" and lang_is_semitic(source) then
term_page = ("ภาคผนวก:ราก%s/%s"):format(source:getCanonicalName(), term)
alt_form = term
else
term_page = term
end
return {
description = "{{{langname}}} terms that originate ultimately from the " .. get_source_and_type_desc(source, term_type) .. " " .. full_link({
term = term_page,
alt = alt_form,
lang = source,
gloss = id,
id = id
}, "term") .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
no_by_language = true,
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = umbrella_parents,
}
}
end)
insert(handlers, function(data)
local labelpref, root_and_id = data.label:match("^(terms belonging to the root )(.+)$")
if not root_and_id then
return
end
local root, id = root_and_id:match("^(.+) %((.-)%)$")
if not root then
root = root_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local root_desc = is_semitic and "[[w:Semitic root|root]]" or "root"
local parents = {}
if id then
insert(parents, {name = labelpref .. root, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามราก", sort = root_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style roots)
local root_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(root, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(root_no_prefix_suffix, not_separator_c, ""))
local root_page, alt_form
if is_semitic then
root_page = ("ภาคผนวก:ราก%s/%s"):format(data.lang:getCanonicalName(), root)
alt_form = root
else
root_page = root
end
local linked_root = data.lang and full_link(
{ term = root_page, alt = alt_form, lang = data.lang, gloss = id, id = id }, "term") or root_page
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter roots", sort = root_and_id})
end
-- Italicize the root/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, root, tag_text(root, lang, nil, "term"))
end
local breadcrumb = tag_text(root, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. root_desc .. " " .. linked_root .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์แบ่งตามราก(.+)$")
if not source_name or source_name == "ศัพท์" then --th; excludes falsily detect ศัพท์แบ่งตามรากศัพท์
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian root]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source_name)
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "root") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
insert(handlers, function(data)
local root_shape, post, additional = data.label:match("^(.+)([ -])shaped roots$")
if not root_shape then
return
elseif data.lang and data.lang:getCode() == "ine-pro" then
additional = [=[
* '''e''' stands for the vowel of the root.
* '''C''' stands for any stop or ''s''.
* '''R''' stands for any resonant.
* '''H''' stands for any laryngeal.
* '''M''' stands for ''m'' or ''w'', when followed by a resonant.
* '''s''' stands for ''s'', when next to a stop.]=]
end
if root_shape == "irregularly" and post == " " then
return {
breadcrumb = "irregular",
description = "{{{langname}}} roots with a shape that violates the {{w|Proto-Indo-European root#Shape of a root|known rules on root shapes}}.",
additional = additional,
parents = {{name = "roots by shape", sort = "*"}},
umbrella = false,
}
elseif post == " " then
return
end
return {
breadcrumb = root_shape,
description = "{{{langname}}} roots with the shape ''" .. root_shape .. "''.",
additional = additional,
parents = {{name = "roots by shape", sort = root_shape}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
-------------------- Derived/inherited/borrowed handlers --------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form "LANG terms derived from SOURCE", where SOURCE is a language, etymology language
-- or family (e.g. "Indo-European languages"), along with corresponding umbrella categories of the form
-- "Terms derived from SOURCE".
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์ที่รับมาจากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่รับมาจากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- Compute description.
local desc = "{{{langname}}} terms that originate from " .. source_desc .. "."
local additional
if source:hasType("family") then
additional = "This category should, ideally, contain only other categories. Entries can be categorized here, too, when the proper subcategory is unclear. " ..
"If you know the exact language from which an entry categorized here is derived, please edit its respective entry."
end
-- Compute parents.
local derived_from_variety_of_self = false
local parent
local sortkey = source:getDisplayForm()
if source:hasType("etymology-only") then
-- By default, `parent` is the source's parent.
parent = source:getParent()
-- Check if the source is a variety (or subvariety) of the language.
if data.lang and source:hasParent(data.lang) then
derived_from_variety_of_self = true
end
-- If the language is the direct parent of the source or the parent is "und", then we use the family of the source as `parent` instead.
if data.lang and (parent:getCode() == data.lang:getCode() or parent:getCode() == "und") then
parent = source:getFamily()
end
-- Regular language or family.
else
local fam = source:getFamily()
if fam then
parent = fam
end
end
-- If `parent` does not exist, is the same as `source`, or would be "isolate languages" or "not a family", then we discard it.
if (not parent) or parent:getCode() == source:getCode() or parent:getCode() == "qfa-iso" or parent:getCode() == "qfa-not" or
parent:getCode() == "qfa-unc" then
parent = nil
derived_from_variety_of_self = false
-- Otherwise, get the display form.
else
parent = parent:getDisplayForm()
end
parent = parent and "ศัพท์ที่รับมาจาก" .. parent or "ศัพท์ที่รับมาจากภาษาอื่น"
local parents = {{name = parent, sort = sortkey}}
if derived_from_variety_of_self then
insert(parents, "Category:Categories for terms in a language derived from a term in a subvariety of that language")
end
-- Compute umbrella parents.
local cat_name = source:getCode() == "mul-tax" and "Taxonomic names" or source:getCategoryName()
-- If the source is etymology-only, its category will be handled by the lect handler in
-- [[Module:category tree/ภาษณ์]]. If it has a nonstandard name like 'Kölsch' (i.e. not a name like
-- 'American English' that has a language name in it), the lect handler won't handle it unless we tell it to do so
-- through the following call; this is an optimization to avoid expensive processing work on all manner of randomly
-- named categories.
if source:hasType("etymology-only") then
require("Module:category tree/ภาษณ์").export.register_likely_lect_parent_cat(cat_name)
end
local umbrella_parents = {
(source:hasType("family") or source:getCode() == "mul-tax") and {name = cat_name, raw = true, sort = " "} or
{name = cat_name, raw = true, sort = "terms derived from"}
}
-- Without the following, the breadcrumb trail for e.g. [[Category:Javanese terms derived from French]] looks like
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages »
-- Indo-European languages » Italic languages » Romance languages » Italo-Western Romance languages »
-- Western Romance languages » Gallo-Romance languages » Gallo-Rhaetian languages » Oïl languages » French
-- To reduce the length, we truncate the "languages" part of the breadcrumbs as long as this does not create
-- ambiguity (i.e. unless there is a language with the same name as the family). Hence, for the Category
-- [[Category:Javanese terms derived from Arabic]], we end up with
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages » Afroasiatic »
-- Semitic » West Semitic » Central Semitic » Arabic languages » Arabic
-- because "Arabic" is ambiguous between family and language (and script, for that matter).
local breadcrumb = source_name
if source:hasType("family") and breadcrumb:find("กลุ่มภาษา") then
local truncated_breadcrumb = breadcrumb:gsub("กลุ่มภาษา", "")
if not get_lang_by_name(truncated_breadcrumb, nil, "allow etym") then
breadcrumb = truncated_breadcrumb
end
end
return {
description = desc,
additional = additional,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
description = "Categories with terms that originate from " .. source_desc .. ".",
parents = umbrella_parents,
},
}
end)
-- Handler for categories of the form "LANG terms inherited/borrowed from SOURCE", where SOURCE is a language,
-- etymology language or family (e.g. "Indo-European languages"). Also handles umbrella categories of the form
-- "Terms inherited/borrowed from SOURCE".
local function inherited_borrowed_handler(etymtype)
return function(data)
local source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
return {
description = "{{{langname}}} terms " .. etymtype .. " from " .. source_desc .. ".",
breadcrumb = source_name,
parents = {
{name = "ศัพท์ที่" .. etymtype, sort = source_name},
{name = "ศัพท์ที่รับมาจาก" .. (source:hasType("family") and "กลุ่มภาษา" or "ภาษา") .. source_name, sort = " "}
},
umbrella = {
parents = {
{ name = "ศัพท์ที่รับมาจากภาษา" .. source_name, is_label = true, sort = " " },
etymtype == "inherited" and
{ name = "หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา", sort = source_name }
-- There are several types of borrowings mixed into the following holding category,
-- so keep these ones sorted under 'Terms borrowed from SOURCE_NAME' instead of just
-- 'SOURCE_NAME'.
or "หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
end
table.insert(handlers, inherited_borrowed_handler("ยืมมา"))
table.insert(handlers, inherited_borrowed_handler("สืบทอด"))
-----------------------------------------------------------------------------
------------------------ Borrowing subtype handlers -------------------------
-----------------------------------------------------------------------------
-- General handler for specific borrowing subtypes, such as learned borrowings, calques and phono-semantic matchings.
local function borrowing_subtype_handler(dest, source_name, parent_cat, spec)
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- normally uses of UNKNOWN should not show up to the end user
local dest_name = dest and dest:getCanonicalName() or "UNKNOWN"
local additional, umbrella_additional
if spec.additional then
if dest then
additional = spec.additional(source, dest)
else
umbrella_additional = spec.umbrella_additional(source)
end
else
if not spec.categorizing_templates then
error("Internal error: Must specify either `categorizing_templates` or the combination of `additional` and `umbrella_additional` in each borrowing subtype spec")
end
local extra_templates = {}
local extra_template_text
for i, template in ipairs(spec.categorizing_templates) do
if i > 1 then
insert(extra_templates, ("{{tl|%s|...}}"):format(template))
end
end
if #extra_templates > 0 then
extra_template_text = (" (or %s, using the same syntax)"):format(
serial_comma_join(extra_templates, {conj = "or"}))
else
extra_template_text = ""
end
if dest then
additional = ("To categorize a term into this category, use {{tl|%s|%s|%s|<var>source_term</var>}}%s, " ..
"where <code><var>source_term</var></code> is the %s term that the term in question " ..
"was borrowed from."):format(
spec.categorizing_templates[1], dest:getCode(), source:getCode(), extra_template_text, source_name)
else
umbrella_additional = ("To categorize a term into a language-specific subcategory, use " ..
"{{tl|%s|<var>destcode</var>|%s|<var>source_term</var>}}%s, where <code><var>destcode</var></code> " ..
"is the language code of the language in question (see [[Wiktionary:List of languages]]), and " ..
"<code><var>source_term</var></code> is the %s term that the term in question was " ..
"borrowed from."):format(spec.categorizing_templates[1], source:getCode(), extra_template_text, source_name)
end
end
return {
description = "{{{langname}}} " .. spec.from_source_desc:gsub("SOURCE", source_desc):gsub("DEST", dest_name),
additional = additional,
breadcrumb = source_name,
parents = {
{ name = parent_cat, sort = source_name },
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, sort = " " },
},
umbrella = {
additional = umbrella_additional,
parents = {
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, is_label = true, sort = " " },
"หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
-- Specs describing types of borrowings.
-- `from_source_desc` is the English description used in categories of the form "LANGUAGE BORTYPE from SOURCE",
-- e.g. "Arabic semantic loans from English". "SOURCE" in the description is replaced by the source language.
-- `umbrella_desc` is the English description used in categories of the form "LANGUAGE BORTYPE", e.g.
-- "Arabic semantic loans". This is an umbrella category grouping all the source-language-specific categories.
-- `uses_subtype_handler`, if true, means that the handler for "LANGUAGE BORTYPE from SOURCE" categories is
-- implemented by a generic "TYPE borrowings" handler (at the bottom of this section), so we don't need to
-- create a BORTYPE-specific handler.
-- `umbrella_parent`, if given, is the parent category of the umbrella categories of the form "LANGUAGE BORTYPE".
-- By default it is "borrowed terms". Some borrowing types replace this with "terms by etymology". (FIXME:
-- Review whether this is correct.)
-- `label_pattern`, if given, is a Lua pattern that matches the category name minus the language at the beginning.
-- It should have one capture, which is the source language. An example is "^terms partially calqued from (.+)$".
-- If omitted, it is generated from BORTYPE.
-- `categorizing_templates`, if given, is the list of templates that categorize into this category. They are assumed to
-- follow the syntax of {{bor}}. The first template in the list should be the preferred alias. The specified
-- templates are used to form the `additional` text displayed on the language-specific category page and
-- corresponding umbrella category page describing how to categorize into the category in question. In more complex
-- cases, you can omit this field and instead supply the `additional` and `umbrella_additional` fields (as is done
-- with adapted borrowings). You must either specify `categorizing_templates` or the combination of `additional` and
-- `umbrella_additional`.
-- `additional`, if given, is a function of two arguments (source and destination language objects) that will generate
-- the `additional` text displayed on the language-specific category page that describes how to categorize into the
-- category in question. This is an alternative to specifying `categorizing_templates`, used in more complex cases
-- (currently, with adapted borrowings).
-- `umbrella_additional`, if given, is a function of one argument (source language object) that will generate the
-- `additional` text displayed on the umbrella category page that describes how to categorize into the category in
-- question. This is an alternative to specifying `categorizing_templates`, used in more complex cases (currently,
-- with adapted borrowings).
local borrowing_specs = {
["ศัพท์ที่ยืมโดยเรียนรู้"] = {
from_source_desc = "terms that are learned [[loanword]]s from SOURCE, that is, terms that were directly incorporated from SOURCE instead of through normal language contact.",
umbrella_desc = "terms that are learned [[loanword]]s, that is, terms that were directly incorporated from another language instead of through normal language contact.",
uses_subtype_handler = true,
categorizing_templates = {"lbor", "learned borrowing"},
},
["ศัพท์ที่ยืมโดยกึ่งเรียนรู้"] = {
from_source_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s from SOURCE, that is, terms borrowed from SOURCE (a [[classical language]]) into DEST (a modern language) and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
umbrella_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s, that is, terms borrowed from a [[classical language]] into a modern language and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
uses_subtype_handler = true,
categorizing_templates = {"slbor", "semi-learned borrowing"},
},
["ศัพท์ที่ยืมอักขรวิธี"] = {
from_source_desc = "orthographic loans from SOURCE, i.e. terms that were borrowed from SOURCE in their script forms, not their pronunciations.",
umbrella_desc = "orthographic loans, i.e. terms that were borrowed in their script forms, not their pronunciations.",
uses_subtype_handler = true,
categorizing_templates = {"obor", "orthographic borrowing"},
},
["ศัพท์ที่ยืมโดยไม่ดัดแปลง"] = {
from_source_desc = "[[loanword]]s from SOURCE that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of DEST.",
umbrella_desc = "[[loanword]]s that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of the target language.",
uses_subtype_handler = true,
categorizing_templates = {"ubor", "unadapted borrowing"},
},
["ศัพท์ที่ยืมโดยดัดแปลง"] = {
from_source_desc = "[[loanwords]] from SOURCE formed with the addition of an affix to conform the term to the normal morphology of DEST.",
umbrella_desc = "[[loanword]]s formed with the addition of an affix to conform the term to the normal morphology of the target language.",
uses_subtype_handler = true,
additional = function(source, dest)
return ("To categorize a term into this category, use {{tl|af|%s|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|%s|3=type=abor|4=...}}, using the same syntax), where <code><var>source_term</var></code> is " ..
"the %s term that the term in question was borrowed from and <code><var>affix</var></code> " ..
"is the %s affix used to adapt the %s term. An example is " ..
"{{m+|pl|adresować||to address}}, which would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate " ..
"that is was formed from {{m+|fr|adresser}} with the addition of the Polish verb-forming affix " ..
"{{m|pl|-ować}}."):format(dest:getCode(), source:getCode(), dest:getCode(), source:getCanonicalName(), dest:getCanonicalName(),
source:getCanonicalName())
end,
umbrella_additional = function(source)
return ("To categorize a term into a language-specific subcategory, use {{tl|af|<var>destcode</var>|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|<var>destcode</var>|3=type=abor|4=...}}, using the same syntax), where " ..
"<code><var>destcode</var></code> is the language code of the target language in question (see " ..
"[[Wiktionary:List of languages]]); <code><var>source_term</var></code> is the %s term " ..
"that the term in question was borrowed from; and <code><var>affix</var></code> is the target-language " ..
"affix used to adapt the %s term. An example is {{m+|pl|adresować||to address}}, which " ..
"would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate that is was formed from " ..
"{{m+|fr|adresser}} with the addition of the Polish verb-forming affix {{m|pl|-ować}}."):format(
source:getCode(), source:getCanonicalName(), source:getCanonicalName())
end,
},
["ศัพท์ที่ยืมความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]] from SOURCE, i.e. terms one or more of whose definitions was borrowed from a term in SOURCE.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]], i.e. terms one or more of whose definitions was borrowed from a term in another language.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
categorizing_templates = {"sl", "semantic loan"},
},
["ศัพท์ที่แปลตรงตัวบางส่วน"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#partial calque|partially calqued]] from SOURCE, i.e. terms formed partly by piece-by-piece translations of SOURCE terms and partly by direct borrowing.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#partial calque|partial calques]], i.e. terms formed partly by piece-by-piece translations of terms from other languages and partly by direct borrowing.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวบางส่วนจากภาษา(.+)$",
categorizing_templates = {"pcal", "pclq", "partial calque"},
},
["ศัพท์ที่แปลตรงตัว"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#calque|calqued]] from SOURCE, i.e. terms formed by piece-by-piece translations of SOURCE terms.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#calque|calques]], i.e. terms formed by piece-by-piece translations of terms from other languages.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวจากภาษา(.+)$",
categorizing_templates = {"cal", "clq", "calque"},
},
["ศัพท์ที่เข้าคู่เสียง-ความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]] from SOURCE, i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]], i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
categorizing_templates = {"psm", "phono-semantic matching"},
},
["ศัพท์ที่ยืมเทียม"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]] from SOURCE, i.e. terms that appear to be SOURCE, but are not used or have an unrelated meaning in SOURCE itself.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]], i.e. terms that appear to be derived from another language, but are not used or have an unrelated meaning in that language itself.",
categorizing_templates = {"pl", "pseudo-loan"},
},
}
for bortype, spec in pairs(borrowing_specs) do
labels[bortype] = {
description = "{{{langname}}} " .. spec.umbrella_desc,
parents = {spec.umbrella_parent or "ศัพท์ที่ยืมมา"},
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
if not spec.uses_subtype_handler then
-- If the label pattern isn't specifically given, generate it from the `bortype`; but make sure to
-- escape hyphens in the pattern.
local label_pattern = spec.label_pattern or "^" .. pattern_escape(bortype) .. "จากภาษา(.+)$"
insert(handlers, function(data)
local source_name = data.label:match(label_pattern)
if source_name then
return borrowing_subtype_handler(data.lang, source_name, bortype, spec)
end
end)
end
end
insert(handlers, function(data)
local borrowing_type, source_name = data.label:match("^(ศัพท์ที่ยืม.+)จากภาษา(.+)$")
if borrowing_type then
local spec = borrowing_specs[borrowing_type]
return borrowing_subtype_handler(data.lang, source_name, borrowing_type, spec)
end
end)
-----------------------------------------------------------------------------
---------------------- Indo-Aryan extension handlers ------------------------
-----------------------------------------------------------------------------
-- FIXME: Put this in a family-specific module.
insert(handlers, function(data)
local labelpref, extension = data.label:match("^(terms extended with Indo%-Aryan )(.+)$")
if not extension then
return
end
local lang_inc_ash = require("Module:languages").getByCode("inc-ash")
local linked_term = full_link({lang = lang_inc_ash, term = extension}, "term")
local tagged_term = tag_text(extension, lang_inc_ash, nil, "term")
return {
description = "{{{langname}}} terms extended with the [[Indo-Aryan]] [[pleonastic]] affix " .. linked_term .. ".",
displaytitle = "{{{langname}}} " .. labelpref .. tagged_term,
breadcrumb = tagged_term,
parents = {{name = "terms with Indo-Aryan extensions", sort = extension}},
umbrella = {
no_by_language = true,
parents = "Indo-Aryan extensions",
displaytitle = "Terms extended with Indo-Aryan " .. tagged_term,
}
}
end)
-----------------------------------------------------------------------------
---------------------------- Coined-by handlers -----------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local coiner = data.label:match("^terms coined by (.+)$")
if not coiner then
return
end
-- Sort by last name per request from [[User:Metaknowledge]]
local last_name = umatch(coiner, ".-%s(%S+)$")
return {
description = "{{{langname}}} terms coined by " .. coiner .. ".",
breadcrumb = coiner,
parents = {{
name = "coinages",
sort = last_name and last_name .. ", " .. coiner or coiner,
}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
------------------------ Multiple etymology handlers ------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local pos = data.label:match("^terms with multiple (.+) etymologies$")
if not pos then
return
end
local plpos = pluralize_pos(pos)
local postype = pos_lemma_or_nonlemma(plpos)
if not postype then
return
end
return {
description = "{{{langname}}} " .. plpos .. " that are derived from multiple origins.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = "multiple " .. plpos,
parents = {{
name = "terms with multiple " .. postype .. " etymologies",
sort = pos,
}},
}
end)
insert(handlers, function(data)
local pos1, pos2 = data.label:match("^terms with (.+) and (.+) etymologies$")
if not pos1 then
return
end
local pos1type = pos_lemma_or_nonlemma(pluralize_pos(pos1))
local pos2type = pos_lemma_or_nonlemma(pluralize_pos(pos2))
if not (pos1type and pos2type) then
return
end
return {
description = "{{{langname}}} terms consisting of " .. add_indefinite_article(pos1) .." of one origin and " ..
add_indefinite_article(pos2) .. " of a different origin.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = pos1 .. " and " .. pos2,
parents = {{
name = pos1type == pos2type and "terms with multiple " .. pos1type .. " etymologies" or
"terms with lemma and non-lemma form etymologies",
sort = pos1 .. " and " .. pos2,
}},
}
end)
-----------------------------------------------------------------------------
--------------------------- Borrowed-back handlers --------------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form e.g. [[:Category:English terms borrowed back into English]]. We need to use a handler
-- because the category's language occurs inside the label itself. For the same reason, the umbrella category has a
-- nonstandard name "Terms borrowed back into the same language", so we handle it as a regular parent and disable the
-- built-in umbrella mechanism.
insert(handlers, function(data)
local lang = data.lang
if not lang then
return
end
local source_name = data.label:match("^terms borrowed back into (.+)$")
if not (source_name and source_name == lang:getDisplayForm()) then
return
end
return {
description = "{{{langname}}} terms that were borrowed from another language that originally borrowed the term from " .. source_name .. ".",
parents = {"ศัพท์แบ่งตามรากศัพท์", "borrowed terms", {
name = "ศัพท์ที่ยืมกลับไปยังภาษาเดิม",
raw = true,
sort = "{{{langname}}}"
}},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
end)
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for umbrella metacategories of the form e.g. [[:Category:Terms derived from Proto-Indo-Iranian roots]]
-- and [[:Category:Terms derived from Proto-Indo-European words]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(raw_handlers, function(data)
local source_name, terms_type
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name = data.category:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+)$")
if source_name then
terms_type = tt
break
end
end
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
return {
description = "Umbrella categories covering terms derived from particular " .. get_source_and_type_desc(source, terms_type) .. ".",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{ name = terms_type == "ราก" and "ราก" or "คำหลัก", is_label = true, lang = source:getCode(), sort = " " },
{ name = "ศัพท์ที่รับมาจาก" .. source_name, is_label = true, sort = " " .. terms_type },
},
}
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}
ipyr7fkw54ncsashjc4jab5sbce329p
5722522
5722521
2026-05-05T02:46:29Z
OctraBot
3198
5722522
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local en_utilities_module = "Module:en-utilities"
local m_str_utils = require("Module:string utilities")
local add_indefinite_article = require(en_utilities_module).add_indefinite_article
local full_link = require("Module:links").full_link
local get_lang_by_name = require("Module:languages").getByCanonicalName
local insert = table.insert
local pattern_escape = m_str_utils.pattern_escape
local plain_gsub = m_str_utils.plain_gsub
local pluralize_pos = require("Module:headword").pluralize_pos
local pos_lemma_or_nonlemma = require("Module:headword").pos_lemma_or_nonlemma
local serial_comma_join = require("Module:table").serialCommaJoin
local tag_text = require("Module:script utilities").tag_text
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ศัพท์แบ่งตามรากศัพท์"] = {
description = "{{{langname}}} terms categorized by their etymologies.",
umbrella_parents = "มูลฐาน",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["terms by etymology"] = labels["ศัพท์แบ่งตามรากศัพท์"]
labels["AABB-type reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] in an AABB pattern.",
breadcrumb = "AABB-type",
parents = {"คำซ้ำ"},
}
labels["apophonic reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] with only a change in a vowel sound.",
breadcrumb = "apophonic",
parents = {"คำซ้ำ"},
}
labels["ศัพท์ที่ผันรูปย้อนกลับ"] = {
description = "{{{langname}}} terms formed by reversing a supposed regular formation, removing part of an older term.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["back-formations"] = labels["ศัพท์ที่ผันรูปย้อนกลับ"]
labels["คำหลอม"] = {
description = "{{{langname}}} terms formed by combinations of other words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["blends"] = labels["คำหลอม"]
labels["ศัพท์ที่ยืมมา"] = {
description = "{{{langname}}} terms that are loanwords, i.e. words that were directly incorporated from another language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["borrowed terms"] = labels["ศัพท์ที่ยืมมา"]
labels["catachreses"] = {
description = "{{{langname}}} terms derived from misuses or misapplications of other terms.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่บัญญัติ"] = {
description = "{{{langname}}} terms coined by an identifiable person, organization or other such entity.",
parents = {"terms attributed to a specific source"},
umbrella_parents = {name = "terms attributed to a specific source", is_label = true, sort = " "},
}
labels["coinages"] = labels["ศัพท์ที่บัญญัติ"]
labels["coordinated pairs"] = {
description = "Terms in {{{langname}}} consisting of a pair of terms joined by a [[coordinating conjunction]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated triples"] = {
description = "Terms in {{{langname}}} consisting of three terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quadruples"] = {
description = "Terms in {{{langname}}} consisting of four terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quintuples"] = {
description = "Terms in {{{langname}}} consisting of five terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากคำนาม"] = {
description = "{{{langname}}} terms derived from a noun.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["denominals"] = labels["ศัพท์ที่รับมาจากคำนาม"]
labels["ศัพท์ที่รับมาจากคำกริยา"] = {
description = "{{{langname}}} terms derived from a verb.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["deverbals"] = labels["ศัพท์ที่รับมาจากคำกริยา"]
labels["ศัพท์ที่ร่วมราก"] = {
description = "{{{langname}}} terms that trace their etymology from ultimately the same source as other terms in the same language, but by different routes, and often with subtly or substantially different meanings.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["doublets"] = labels["ศัพท์ที่ร่วมราก"]
labels["elongated forms"] = {
description = "{{{langname}}} terms where one or more letters or sounds is repeated for emphasis or effect.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากชื่อบุคคล"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["eponyms"] = labels["ศัพท์ที่รับมาจากชื่อบุคคล"]
labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"] = {
description = "{{{langname}}} terms that originate from [[trademark]]s, [[brand]]s and company names which have become [[genericized]]; that is, fallen into common usage in the target market's [[vernacular]], even when referring to other competing brands.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "เครื่องหมายการค้า"},
}
labels["genericized trademarks"] = labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"]
labels["ghost words"] = {
description = "{{{langname}}} terms that were originally erroneous or fictitious, published in a reference work as if they were genuine as a result of typographical error, misreading, or misinterpretation, or as [[:w:Fictitious entry|fictitious entries]], jokes, or hoaxes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["gramograms"] = {
description = "{{{langname}}} [[gramogram]]s – terms that are partially or completely spelled with [[homophone|homophonous]] letters.",
parents = {"rebuses"},
}
labels["haplological words"] = {
description = "{{{langname}}} words that underwent [[haplology]]: thus, their origin involved a loss or omission of a repeated sequence of sounds.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["homophonic translations"] = {
description = "{{{langname}}} terms that were borrowed by matching the etymon phonetically, without regard for the sense; compare [[phono-semantic matching]] and [[Hobson-Jobson]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["hybridisms"] = {
description = "{{{langname}}} terms formed by elements of different linguistic origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบทอด"] = {
description = "{{{langname}}} terms that were inherited from an earlier stage of the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["inherited terms"] = labels["ศัพท์ที่สืบทอด"]
labels["internationalisms"] = {
description = "{{{langname}}} loanwords which also exist in many other languages with the same or similar etymology.",
additional = "Terms should be here preferably only if the immediate source language is not known for certain. Entries are added into this category by [[Template:internationalism]]; see it for more information.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["legal doublets"] = {
description = "{{{langname}}} legal [[doublet]]s – a legal doublet is a standardized phrase commonly use in legal documents, proceedings etc. which includes two words that are near synonyms.",
parents = {"coordinated pairs"},
}
labels["legal triplets"] = {
description = "{{{langname}}} legal [[triplet]]s – a legal triplet is a standardized phrase commonly use in legal documents, proceedings etc which includes three words that are near synonyms.",
parents = {"coordinated triples"},
}
labels["LLM coinages"] = {
description = "{{{langname}}} terms that have been coined by {{w|large language models}} rather than humans.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["merisms"] = {
description = "{{{langname}}} [[merism]]s – terms that are [[coordinate]]s that, combined, are a synonym for a totality.",
parents = {"coordinated pairs"},
}
labels["metonyms"] = {
description = "{{{langname}}} terms whose origin involves calling a thing or concept not by its own name, but by the name of something intimately associated with that thing or concept.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["นวศัพท์"] = {
description = "{{{langname}}} terms that have been only recently acknowledged.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["neologisms"] = labels["นวศัพท์"]
labels["nonce terms"] = {
description = "{{{langname}}} terms that have been invented for a single occasion.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["number homophones"] = {
description = "{{{langname}}} terms that are partially or completely spelled with [[homophone|homophonous]] numbers.",
parents = {"rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["numerical contractions"] = {
description = "{{{langname}}} numerical contractions. In these, the number either denotes omitted characters ({{m+|en|globalization}} → {{m|en|g11n}}) or duplication ({{m+|kne|Kankanaey}} → {{m|kne|Kan2aey}}).",
parents = {"contractions", "rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["ศัพท์ที่เลียนเสียงธรรมชาติ"] = {
description = "{{{langname}}} terms that were coined to sound like what they represent.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["onomatopoeias"] = labels["ศัพท์ที่เลียนเสียงธรรมชาติ"]
labels["piecewise doublets"] = {
description = "{{{langname}}} terms that are [[ภาคผนวก:อภิธานศัพท์#piecewise doublet|piecewise doublets]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
--[=[ thwikt don't use specific terms below
for _, ism_and_langname in ipairs({
{"anglicisms", "English"},
{"Arabisms", "Arabic"},
{"Gallicisms", "French"},
{"Germanisms", "German"},
{"Hispanisms", "Spanish"},
{"Italianisms", "Italian"},
{"Latinisms", "Latin"},
{"Japonisms", "Japanese"},
}) do
local ism, langname = unpack(ism_and_langname)
labels["pseudo-" .. ism] = {
description = "{{{langname}}} terms that appear to be " .. langname .. ", but are not used or have an unrelated meaning in " .. langname .. " itself.",
parents = {"pseudo-loans"},
umbrella_parents = {name = "pseudo-loans", is_label = true, sort = " "},
}
end
--]=]
labels["rebracketings"] = {
description = "{{{langname}}} terms that have interacted with another word in such a way that the boundary between the words has been modified.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["rebuses"] = {
description = "{{{langname}}} [[rebus]]es – terms that are partially or completely represented by images, symbols or numbers, often as a form of wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบสร้าง"] = {
description = "{{{langname}}} terms that are not directly attested, but have been reconstructed through other evidence.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["reconstructed terms"] = labels["ศัพท์ที่สืบสร้าง"]
labels["reduplicated coordinated pairs"] = {
description = "{{{langname}}} reduplicated coordinated pairs.",
breadcrumb = "reduplicated",
parents = {"coordinated pairs", "คำซ้ำ"},
}
labels["reduplicated coordinated triples"] = {
description = "{{{langname}}} reduplicated coordinated triples.",
breadcrumb = "reduplicated",
parents = {"coordinated triples", "คำซ้ำ"},
}
labels["reduplicated coordinated quadruples"] = {
description = "{{{langname}}} reduplicated coordinated quadruples.",
breadcrumb = "reduplicated",
parents = {"coordinated quadruples", "คำซ้ำ"},
}
labels["reduplicated coordinated quintuples"] = {
description = "{{{langname}}} reduplicated coordinated quintuples.",
breadcrumb = "reduplicated",
parents = {"coordinated quintuples", "คำซ้ำ"},
}
labels["คำซ้ำ"] = {
description = "{{{langname}}} terms that underwent [[reduplication]], so their origin involved a repetition of roots or stems.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["reduplications"] = labels["คำซ้ำ"]
labels["retronyms"] = {
description = "{{{langname}}} terms that serve as new unique names for older objects or concepts whose previous names became ambiguous.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ราก"] = {
description = "Basic morphemes from which {{{langname}}} words are formed.",
parents = {"หน่วยคำ"},
}
labels["roots"] = labels["ราก"]
labels["Sanskritic formations"] = {
description = "{{{langname}}} terms coined from [[tatsama]] [[word]]s and/or [[affix]]es.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่รับมาจากภาษาสันสกฤต"},
}
labels["sound-symbolic terms"] = {
description = "{{{langname}}} terms that use {{w|sound symbolism}} to express ideas but which are not necessarily strictly speaking [[onomatopoeic]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelled-out initialisms"] = {
description = "{{{langname}}} initialisms in which the letter names are spelled out.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelling pronunciations"] = {
description = "{{{langname}}} terms whose pronunciation was historically or presently affected by their spelling.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["คำผวน"] = {
description = "{{{langname}}} terms in which the initial sounds of component parts have been exchanged, as in \"crook and nanny\" for \"nook and cranny\".",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spoonerisms"] = labels["คำผวน"]
labels["taxonomic eponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people, used for [[taxonomy]].",
parents = {"ศัพท์ที่รับมาจากชื่อบุคคล"},
}
labels["terms attributed to a specific source"] = {
description = "{{{langname}}} terms coined by an identifiable person or deriving from a known work.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms coined ex nihilo"] = {
description = "{{{langname}}} terms fabricated ''[[ex nihilo]]'', i.e. made up entirely rather than being derived from an existing source.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms containing fossilized case endings"] = {
description = "{{{langname}}} terms which preserve case morphology which is no longer analyzable within the contemporary grammatical system or which has been entirely lost from the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from area codes"] = {
description = "{{{langname}}} terms derived from [[area code]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"] = {
description = "{{{langname}}} terms derived from the shape of letters. This can include terms derived from the shape of any letter in any alphabet.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from the shape of letters"] = labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"]
labels["ศัพท์แบ่งตามราก"] = {
description = "{{{langname}}} terms categorized by the root they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์", {name = "ราก", sort = " "}},
}
labels["terms by root"] = labels["ศัพท์แบ่งตามราก"]
labels["ศัพท์แบ่งตามคำ"] = {
description = "{{{langname}}} terms categorized by the word they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms by word"] = labels["ศัพท์แบ่งตามคำ"]
labels["ศัพท์ที่รับมาจากบันเทิงคดี"] = {
description = "{{{langname}}} terms that originate from works of [[fiction]].",
breadcrumb = "บันเทิงคดี",
parents = {{name = "terms attributed to a specific source", sort = "บันเทิงคดี"}},
}
labels["terms derived from fiction"] = labels["ศัพท์ที่รับมาจากบันเทิงคดี"]
for _, data in ipairs {
{source="Dickensian works", desc="the works of [[w:Charles Dickens|Charles Dickens]]", topic_parent="Charles Dickens"},
{source="ดีซีคอมิกส์", desc="[[w:ดีซีคอมิกส์|ดีซีคอมิกส์]]"},
{source="โดราเอมอน", desc="[[w:Fujiko F. Fujio|Fujiko F. Fujio]]'s ''[[w:โดราเอมอน|โดราเอมอน]]''", displaytitle="''โดราเอมอน''"},
{source="ดรากอนบอล", desc="[[w:Akira Toriyama|Akira Toriyama]]'s ''[[w:ดรากอนบอล|ดรากอนบอล]]''", displaytitle="''ดรากอนบอล''"},
{source="ดักเบิร์กและเมาส์ตัน", desc="[[w:The Walt Disney Company|Disney]]'s [[w:Duck universe|Duckburg]] and [[w:Mickey Mouse universe|Mouseton]] universe",
topic_parent="ดิสนีย์"},
{source="ฟิวเจอรามา", desc="the animated television series ''{{w|ฟิวเจอรามา}}''", displaytitle = "''ฟิวเจอรามา''"},
{source="แฮร์รี่ พอตเตอร์", desc="the ''[[w:แฮร์รี่ พอตเตอร์|แฮร์รี่ พอตเตอร์]]'' series", displaytitle="''แฮร์รี่ พอตเตอร์''",
topic_parent="แฮร์รี่ พอตเตอร์"},
{source="Looney Tunes and Merrie Melodies", desc="''{{w|Looney Tunes}}'' and/or ''{{w|Merrie Melodies}}'', by {{w|Warner Bros. Animation}}", displaytitle = "''Looney Tunes'' and ''Merrie Melodies''"},
{source="หนึ่งเก้าแปดสี่", desc="[[w:George Orwell|George Orwell]]'s ''[[w:Nineteen Eighty-Four|Nineteen Eighty-Four]]''",
displaytitle="''หนึ่งเก้าแปดสี่''"},
{source="Seinfeld", desc="the American television sitcom ''{{w|Seinfeld}}'' (1989–1998)", displaytitle="''Seinfeld''"},
{source="Seussian works", desc="the works of [[w:Dr. Seuss|Dr. Seuss]]"},
{source="South Park", desc="the animated television series ''[[w:South Park|South Park]]''", displaytitle="''South Park''"},
{source="สตาร์ เทรค", desc="''[[w:สตาร์ เทรค|สตาร์ เทรค]]''", displaytitle="''สตาร์ เทรค''", topic_parent="สตาร์ เทรค"},
{source="สตาร์ วอร์ส", desc="''[[w:สตาร์ วอร์ส|สตาร์ วอร์ส]]''", displaytitle="''สตาร์ วอร์ส''", topic_parent="สตาร์ วอร์ส"},
{source="เดอะซิมป์สันส์", desc="''[[w:เดอะซิมป์สันส์|เดอะซิมป์สันส์]]''", displaytitle="''เดอะซิมป์สันส์''", topic_parent="เดอะซิมป์สันส์", sort="ซิมป์สันส์"},
{source="ปกรณัมของโทลคีน", desc="the [[legendarium]] of [[w:เจ. อาร์. อาร์. โทลคีน|เจ. อาร์. อาร์. โทลคีน]]", topic_parent="เจ. อาร์. อาร์. โทลคีน"},
} do
local parents = {{name = "ศัพท์ที่รับมาจากบันเทิงคดี", sort = data.sort or data.source}}
local umbrella_parents = {"หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"}
if data.topic_parent then
insert(parents, {name = "{{{langcode}}}:" .. data.topic_parent, raw = true})
insert(umbrella_parents, {name = data.topic_parent, raw = true})
end
labels["ศัพท์ที่รับมาจาก" .. data.source] = {
description = "{{{langname}}} terms that originate from " .. data.desc .. ".",
breadcrumb = data.displaytitle or data.source,
parents = parents,
umbrella = {
parents = umbrella_parents,
displaytitle = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle .. "แบ่งตามภาษา" or nil,
breadcrumb = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle,
},
displaytitle = data.displaytitle and "ศัพท์{{{langcat}}}ที่รับมาจาก" .. data.displaytitle or nil,
}
end
labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"] = {
description = "{{{langname}}} terms derived from Greek mythology which have acquired an idiomatic meaning.",
breadcrumb = "ประมวลเรื่องปรัมปรากรีก",
parents = {{name = "terms attributed to a specific source", sort = "ประมวลเรื่องปรัมปรากรีก"}},
}
labels["terms derived from Greek mythology"] = labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"]
labels["ศัพท์ที่รับมาจากอาชีพ"] = {
description = "{{{langname}}} terms derived from names of occupations.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from occupations"] = labels["ศัพท์ที่รับมาจากอาชีพ"]
labels["ศัพท์ที่รับมาจากภาษาอื่น"] = {
description = "{{{langname}}} terms that originate from other languages.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from other languages"] = labels["ศัพท์ที่รับมาจากภาษาอื่น"]
labels["ศัพท์ที่รับมาจากไบเบิล"] = {
description = "{{{langname}}} terms that originate from the [[Bible]].",
breadcrumb = {name = "ไบเบิล", nocap = true},
parents = {{name = "terms attributed to a specific source", sort = "ไบเบิล"}},
}
labels["terms derived from the Bible"] = labels["ศัพท์ที่รับมาจากไบเบิล"]
labels["ศัพท์ที่รับมาจากนิทานอีสป"] = {
description = "{{{langname}}} terms that originate from [[Aesop]]'s Fables.",
breadcrumb = "นิทานอีสป",
parents = {{name = "terms attributed to a specific source", sort = "นิทานอีสป"}},
}
labels["terms derived from Aesop's Fables"] = labels["ศัพท์ที่รับมาจากนิทานอีสป"]
labels["terms derived from toponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious places.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived through romanized wordplay"] = {
description = "{{{langname}}} terms derived through romanized wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms making reference to character shapes"] = {
description = "{{{langname}}} terms making reference to character shapes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากกีฬา"] = {
description = "{{{langname}}} terms that originate from sports.",
breadcrumb = "กีฬา",
parents = {{name = "terms attributed to a specific source", sort = "กีฬา"}},
}
labels["terms derived from sport"] = labels["ศัพท์ที่รับมาจากกีฬา"]
labels["ศัพท์ที่รับมาจากเบสบอล"] = {
description = "{{{langname}}} terms that originate from baseball.",
breadcrumb = "เบสบอล",
parents = {{name = "ศัพท์ที่รับมาจากกีฬา", sort = "เบสบอล"}},
}
labels["terms derived from baseball"] = labels["ศัพท์ที่รับมาจากเบสบอล"]
labels["terms with Indo-Aryan extensions"] = {
description = "{{{langname}}} terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with lemma and non-lemma form etymologies"] = {
description = "{{{langname}}} terms consisting of both a lemma and non-lemma form, of different origins.",
breadcrumb = "lemma and non-lemma form",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple etymologies"] = {
description = "{{{langname}}} terms that are derived from multiple origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with multiple lemma etymologies"] = {
description = "{{{langname}}} lemmas that are derived from multiple origins.",
breadcrumb = "multiple lemmas",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple non-lemma form etymologies"] = {
description = "{{{langname}}} non-lemma forms that are derived from multiple origins.",
breadcrumb = "multiple non-lemma forms",
parents = {"terms with multiple etymologies"},
}
labels["ศัพท์ที่ไม่ทราบรากศัพท์"] = {
description = "{{{langname}}} terms whose etymologies have not yet been established.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "ไม่ทราบรากศัพท์"}},
}
labels["terms with unknown etymologies"] = labels["ศัพท์ที่ไม่ทราบรากศัพท์"]
labels["univerbations"] = {
description = "{{{langname}}} terms that result from the agglutination of two or more words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["words derived through corruption"] = {
description = "{{{langname}}} words that result from a non-specific or sporadic change.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "corruption"}},
}
labels["words derived through metathesis"] = {
description = "{{{langname}}} words that were created through [[metathesis]] from another word.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "metathesis"}},
}
labels["words that have undergone semantic shift"] = {
description = "{{{langname}}} words that show senses explained by [[semantic shift]].",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "semantic shift"}},
}
labels["words that have undergone semantic broadening"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[broadening]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic broadening"}},
}
labels["words that have undergone semantic narrowing"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[narrowing]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic narrowing"}},
}
labels["words that have undergone amelioration"] = {
description = "{{{langname}}} words that have gained a positive [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "amelioration"}},
}
labels["words that have undergone pejoration"] = {
description = "{{{langname}}} words that have gained a negative [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "pejoration"}},
}
labels["terms with origins in folklore"] = {
description = "{{{langname}}} terms that have an etymology rooted in folklore.",
breadcrumb = "Folklore",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "folklore"}, {name = "{{{langcode}}}:Folklore", raw = true}},
umbrella_parents = {{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", raw = true}, {name = "Folklore", raw = true, sort = " "}}
}
-- Add 'umbrella_parents' key if not already present.
for _, data in pairs(labels) do
-- NOTE: umbrella.parents overrides umbrella_parents if both are given.
if not data.umbrella_parents then
data.umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to terms categorized by their etymologies, such as types of compounds or borrowings.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์แบ่งตามรากศัพท์", is_label = true, sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to borrowed terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่ยืมมา", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to inherited terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่สืบทอด", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Indo-Aryan extensions"] = {
description = "Umbrella categories covering terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Multiple etymology subcategories by language"] = {
description = "Umbrella categories covering topics related to terms with multiple etymologies.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["ศัพท์ที่ยืมกลับไปยังภาษาเดิม"] = {
description = "Categories with terms in specific languages that were borrowed from a second language that previously borrowed the term from the first language.",
additional = "A well-known example is {{m+|en|salaryman}}, a term borrowed from Japanese which in turn was borrowed from the English words [[salary]] and [[man]].\n\n{{{umbrella_msg}}}",
parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_source(source_name, allow_family, name_type)
local source = get_lang_by_name(source_name, nil, true, allow_family)
if source == nil then
return nil
end
-- Check that the source name matches the expected form (e.g. getCanonicalName, getDisplayForm etc).
if source[name_type](source) == source_name then
return source
end
end
local function get_source_and_type_desc(source, term_type)
if source:getCode() == "ine-pro" and term_type:find("^roots?$") then
return "[[w:Proto-Indo-European root|Proto-Indo-European " .. term_type .. "]]"
end
return "[[w:" .. source:getWikipediaArticle() .. "|" .. source:getCanonicalName() .. "]] " .. term_type
end
local function get_source_and_source_desc(source_name)
-- HACK! Map 'taxonomic names', as generated by [[Module:etymology]], back to its canonical name
-- before calling getByCanonicalName(). We need a more general solution here.
local source_desc
if source_name == "taxonomic names" then
source_name = "taxonomic name"
source_desc = "[[w:taxonomic nomenclature|taxonomic names]]"
end
local source = get_source(source_name, true, "getCanonicalName") --th
if source == nil then
return
end
source_desc = source_desc or source:makeCategoryLink()
if source:hasType("family") then
source_desc = "one of the " .. source_desc
end
return source, source_desc
end
-----------------------------------------------------------------------------
------------------------------- word handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE word word' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
local function lang_is_semitic(lang)
return lang:inFamily("sem")
end
insert(handlers, function(data)
local labelpref, word_and_id = data.label:match("^(terms belonging to the word )(.+)$")
if not word_and_id then
return
end
local word, id = word_and_id:match("^(.+) %((.-)%)$")
if not word then
word = word_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local word_desc = is_semitic and "[[w:Semitic word|word]]" or "word"
local parents = {}
if id then
insert(parents, {name = labelpref .. word, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามคำ", sort = word_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style words)
local word_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(word, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(word_no_prefix_suffix, not_separator_c, ""))
local linked_word = data.lang and full_link({ term = word, lang = data.lang, gloss = id, id = id }, "term") or word
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter words", sort = word_and_id})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, word, tag_text(word, lang, nil, "term"))
end
local breadcrumb = tag_text(word, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. word_desc .. " " .. linked_word .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^terms by (.+) word$")
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian word]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source:getDisplayForm())
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "word") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
-----------------------------------------------------------------------------
------------------------------- Root handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE root ROOT' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
-- Handler for e.g. [[:Category:Yola terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Russian terms derived from the Proto-Indo-European word *swé]], and corresponding umbrella
-- categories [[:Category:Terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Terms derived from the Proto-Indo-European word *swé]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(handlers, function(data)
local source_name, term_type, term_and_id
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name, term_and_id = data.label:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+) (.+)$")
if source_name then
term_type = tt
break
end
end
if not source_name then
return
end
local term, id = term_and_id:match("^(.+) %((.-)%)$")
if not term then
term = term_and_id
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {
{
name = "ศัพท์แบ่งตาม" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
local umbrella_parents = {
{
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
if id then
insert(parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
sort = " "
})
insert(umbrella_parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
is_label = true,
sort = " "
})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, term, tag_text(term, source, nil, "term"))
end
local breadcrumb = tag_text(term, source, nil, "term") .. (id and " (" .. id .. ")" or "")
local term_page, alt_form
if term_type == "root" and lang_is_semitic(source) then
term_page = ("ภาคผนวก:ราก%s/%s"):format(source:getCanonicalName(), term)
alt_form = term
else
term_page = term
end
return {
description = "{{{langname}}} terms that originate ultimately from the " .. get_source_and_type_desc(source, term_type) .. " " .. full_link({
term = term_page,
alt = alt_form,
lang = source,
gloss = id,
id = id
}, "term") .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
no_by_language = true,
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = umbrella_parents,
}
}
end)
insert(handlers, function(data)
local labelpref, root_and_id = data.label:match("^(terms belonging to the root )(.+)$")
if not root_and_id then
return
end
local root, id = root_and_id:match("^(.+) %((.-)%)$")
if not root then
root = root_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local root_desc = is_semitic and "[[w:Semitic root|root]]" or "root"
local parents = {}
if id then
insert(parents, {name = labelpref .. root, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามราก", sort = root_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style roots)
local root_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(root, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(root_no_prefix_suffix, not_separator_c, ""))
local root_page, alt_form
if is_semitic then
root_page = ("ภาคผนวก:ราก%s/%s"):format(data.lang:getCanonicalName(), root)
alt_form = root
else
root_page = root
end
local linked_root = data.lang and full_link(
{ term = root_page, alt = alt_form, lang = data.lang, gloss = id, id = id }, "term") or root_page
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter roots", sort = root_and_id})
end
-- Italicize the root/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, root, tag_text(root, lang, nil, "term"))
end
local breadcrumb = tag_text(root, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. root_desc .. " " .. linked_root .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์แบ่งตามราก(.+)$")
if not source_name or source_name == "ศัพท์" then --th; excludes falsily detect ศัพท์แบ่งตามรากศัพท์
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian root]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source_name)
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "root") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
insert(handlers, function(data)
local root_shape, post, additional = data.label:match("^(.+)([ -])shaped roots$")
if not root_shape then
return
elseif data.lang and data.lang:getCode() == "ine-pro" then
additional = [=[
* '''e''' stands for the vowel of the root.
* '''C''' stands for any stop or ''s''.
* '''R''' stands for any resonant.
* '''H''' stands for any laryngeal.
* '''M''' stands for ''m'' or ''w'', when followed by a resonant.
* '''s''' stands for ''s'', when next to a stop.]=]
end
if root_shape == "irregularly" and post == " " then
return {
breadcrumb = "irregular",
description = "{{{langname}}} roots with a shape that violates the {{w|Proto-Indo-European root#Shape of a root|known rules on root shapes}}.",
additional = additional,
parents = {{name = "roots by shape", sort = "*"}},
umbrella = false,
}
elseif post == " " then
return
end
return {
breadcrumb = root_shape,
description = "{{{langname}}} roots with the shape ''" .. root_shape .. "''.",
additional = additional,
parents = {{name = "roots by shape", sort = root_shape}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
-------------------- Derived/inherited/borrowed handlers --------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form "LANG terms derived from SOURCE", where SOURCE is a language, etymology language
-- or family (e.g. "Indo-European languages"), along with corresponding umbrella categories of the form
-- "Terms derived from SOURCE".
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์ที่รับมาจากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่รับมาจากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- Compute description.
local desc = "{{{langname}}} terms that originate from " .. source_desc .. "."
local additional
if source:hasType("family") then
additional = "This category should, ideally, contain only other categories. Entries can be categorized here, too, when the proper subcategory is unclear. " ..
"If you know the exact language from which an entry categorized here is derived, please edit its respective entry."
end
-- Compute parents.
local derived_from_variety_of_self = false
local parent
local sortkey = source:getDisplayForm()
if source:hasType("etymology-only") then
-- By default, `parent` is the source's parent.
parent = source:getParent()
-- Check if the source is a variety (or subvariety) of the language.
if data.lang and source:hasParent(data.lang) then
derived_from_variety_of_self = true
end
-- If the language is the direct parent of the source or the parent is "und", then we use the family of the source as `parent` instead.
if data.lang and (parent:getCode() == data.lang:getCode() or parent:getCode() == "und") then
parent = source:getFamily()
end
-- Regular language or family.
else
local fam = source:getFamily()
if fam then
parent = fam
end
end
-- If `parent` does not exist, is the same as `source`, or would be "isolate languages" or "not a family", then we discard it.
if (not parent) or parent:getCode() == source:getCode() or parent:getCode() == "qfa-iso" or parent:getCode() == "qfa-not" or
parent:getCode() == "qfa-unc" then
parent = nil
derived_from_variety_of_self = false
-- Otherwise, get the display form.
else
parent = parent:getDisplayForm()
end
parent = parent and "ศัพท์ที่รับมาจาก" .. parent or "ศัพท์ที่รับมาจากภาษาอื่น"
local parents = {{name = parent, sort = sortkey}}
if derived_from_variety_of_self then
insert(parents, "Category:Categories for terms in a language derived from a term in a subvariety of that language")
end
-- Compute umbrella parents.
local cat_name = source:getCode() == "mul-tax" and "Taxonomic names" or source:getCategoryName()
-- If the source is etymology-only, its category will be handled by the lect handler in
-- [[Module:category tree/ภาษณ์]]. If it has a nonstandard name like 'Kölsch' (i.e. not a name like
-- 'American English' that has a language name in it), the lect handler won't handle it unless we tell it to do so
-- through the following call; this is an optimization to avoid expensive processing work on all manner of randomly
-- named categories.
if source:hasType("etymology-only") then
require("Module:category tree/ภาษณ์").export.register_likely_lect_parent_cat(cat_name)
end
local umbrella_parents = {
(source:hasType("family") or source:getCode() == "mul-tax") and {name = cat_name, raw = true, sort = " "} or
{name = cat_name, raw = true, sort = "terms derived from"}
}
-- Without the following, the breadcrumb trail for e.g. [[Category:Javanese terms derived from French]] looks like
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages »
-- Indo-European languages » Italic languages » Romance languages » Italo-Western Romance languages »
-- Western Romance languages » Gallo-Romance languages » Gallo-Rhaetian languages » Oïl languages » French
-- To reduce the length, we truncate the "languages" part of the breadcrumbs as long as this does not create
-- ambiguity (i.e. unless there is a language with the same name as the family). Hence, for the Category
-- [[Category:Javanese terms derived from Arabic]], we end up with
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages » Afroasiatic »
-- Semitic » West Semitic » Central Semitic » Arabic languages » Arabic
-- because "Arabic" is ambiguous between family and language (and script, for that matter).
local breadcrumb = source_name
if source:hasType("family") and breadcrumb:find("กลุ่มภาษา") then
local truncated_breadcrumb = breadcrumb:gsub("กลุ่มภาษา", "")
if not get_lang_by_name(truncated_breadcrumb, nil, "allow etym") then
breadcrumb = truncated_breadcrumb
end
end
return {
description = desc,
additional = additional,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
description = "Categories with terms that originate from " .. source_desc .. ".",
parents = umbrella_parents,
},
}
end)
-- Handler for categories of the form "LANG terms inherited/borrowed from SOURCE", where SOURCE is a language,
-- etymology language or family (e.g. "Indo-European languages"). Also handles umbrella categories of the form
-- "Terms inherited/borrowed from SOURCE".
local function inherited_borrowed_handler(etymtype)
return function(data)
local source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
return {
description = "{{{langname}}} terms " .. etymtype .. " from " .. source_desc .. ".",
breadcrumb = source_name,
parents = {
{name = "ศัพท์ที่" .. etymtype, sort = source_name},
{name = "ศัพท์ที่รับมาจาก" .. (source:hasType("family") and "กลุ่มภาษา" or "ภาษา") .. source_name, sort = " "}
},
umbrella = {
parents = {
{ name = "ศัพท์ที่รับมาจากภาษา" .. source_name, is_label = true, sort = " " },
etymtype == "inherited" and
{ name = "หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา", sort = source_name }
-- There are several types of borrowings mixed into the following holding category,
-- so keep these ones sorted under 'Terms borrowed from SOURCE_NAME' instead of just
-- 'SOURCE_NAME'.
or "หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
end
table.insert(handlers, inherited_borrowed_handler("ยืมมา"))
table.insert(handlers, inherited_borrowed_handler("สืบทอด"))
-----------------------------------------------------------------------------
------------------------ Borrowing subtype handlers -------------------------
-----------------------------------------------------------------------------
-- General handler for specific borrowing subtypes, such as learned borrowings, calques and phono-semantic matchings.
local function borrowing_subtype_handler(dest, source_name, parent_cat, spec)
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- normally uses of UNKNOWN should not show up to the end user
local dest_name = dest and dest:getCanonicalName() or "UNKNOWN"
local additional, umbrella_additional
if spec.additional then
if dest then
additional = spec.additional(source, dest)
else
umbrella_additional = spec.umbrella_additional(source)
end
else
if not spec.categorizing_templates then
error("Internal error: Must specify either `categorizing_templates` or the combination of `additional` and `umbrella_additional` in each borrowing subtype spec")
end
local extra_templates = {}
local extra_template_text
for i, template in ipairs(spec.categorizing_templates) do
if i > 1 then
insert(extra_templates, ("{{tl|%s|...}}"):format(template))
end
end
if #extra_templates > 0 then
extra_template_text = (" (or %s, using the same syntax)"):format(
serial_comma_join(extra_templates, {conj = "or"}))
else
extra_template_text = ""
end
if dest then
additional = ("To categorize a term into this category, use {{tl|%s|%s|%s|<var>source_term</var>}}%s, " ..
"where <code><var>source_term</var></code> is the %s term that the term in question " ..
"was borrowed from."):format(
spec.categorizing_templates[1], dest:getCode(), source:getCode(), extra_template_text, source_name)
else
umbrella_additional = ("To categorize a term into a language-specific subcategory, use " ..
"{{tl|%s|<var>destcode</var>|%s|<var>source_term</var>}}%s, where <code><var>destcode</var></code> " ..
"is the language code of the language in question (see [[Wiktionary:List of languages]]), and " ..
"<code><var>source_term</var></code> is the %s term that the term in question was " ..
"borrowed from."):format(spec.categorizing_templates[1], source:getCode(), extra_template_text, source_name)
end
end
return {
description = "{{{langname}}} " .. spec.from_source_desc:gsub("SOURCE", source_desc):gsub("DEST", dest_name),
additional = additional,
breadcrumb = source_name,
parents = {
{ name = parent_cat, sort = source_name },
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, sort = " " },
},
umbrella = {
additional = umbrella_additional,
parents = {
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, is_label = true, sort = " " },
"หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
-- Specs describing types of borrowings.
-- `from_source_desc` is the English description used in categories of the form "LANGUAGE BORTYPE from SOURCE",
-- e.g. "Arabic semantic loans from English". "SOURCE" in the description is replaced by the source language.
-- `umbrella_desc` is the English description used in categories of the form "LANGUAGE BORTYPE", e.g.
-- "Arabic semantic loans". This is an umbrella category grouping all the source-language-specific categories.
-- `uses_subtype_handler`, if true, means that the handler for "LANGUAGE BORTYPE from SOURCE" categories is
-- implemented by a generic "TYPE borrowings" handler (at the bottom of this section), so we don't need to
-- create a BORTYPE-specific handler.
-- `umbrella_parent`, if given, is the parent category of the umbrella categories of the form "LANGUAGE BORTYPE".
-- By default it is "borrowed terms". Some borrowing types replace this with "terms by etymology". (FIXME:
-- Review whether this is correct.)
-- `label_pattern`, if given, is a Lua pattern that matches the category name minus the language at the beginning.
-- It should have one capture, which is the source language. An example is "^terms partially calqued from (.+)$".
-- If omitted, it is generated from BORTYPE.
-- `categorizing_templates`, if given, is the list of templates that categorize into this category. They are assumed to
-- follow the syntax of {{bor}}. The first template in the list should be the preferred alias. The specified
-- templates are used to form the `additional` text displayed on the language-specific category page and
-- corresponding umbrella category page describing how to categorize into the category in question. In more complex
-- cases, you can omit this field and instead supply the `additional` and `umbrella_additional` fields (as is done
-- with adapted borrowings). You must either specify `categorizing_templates` or the combination of `additional` and
-- `umbrella_additional`.
-- `additional`, if given, is a function of two arguments (source and destination language objects) that will generate
-- the `additional` text displayed on the language-specific category page that describes how to categorize into the
-- category in question. This is an alternative to specifying `categorizing_templates`, used in more complex cases
-- (currently, with adapted borrowings).
-- `umbrella_additional`, if given, is a function of one argument (source language object) that will generate the
-- `additional` text displayed on the umbrella category page that describes how to categorize into the category in
-- question. This is an alternative to specifying `categorizing_templates`, used in more complex cases (currently,
-- with adapted borrowings).
local borrowing_specs = {
["ศัพท์ที่ยืมโดยเรียนรู้"] = {
from_source_desc = "terms that are learned [[loanword]]s from SOURCE, that is, terms that were directly incorporated from SOURCE instead of through normal language contact.",
umbrella_desc = "terms that are learned [[loanword]]s, that is, terms that were directly incorporated from another language instead of through normal language contact.",
uses_subtype_handler = true,
categorizing_templates = {"lbor", "learned borrowing"},
},
["ศัพท์ที่ยืมโดยกึ่งเรียนรู้"] = {
from_source_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s from SOURCE, that is, terms borrowed from SOURCE (a [[classical language]]) into DEST (a modern language) and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
umbrella_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s, that is, terms borrowed from a [[classical language]] into a modern language and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
uses_subtype_handler = true,
categorizing_templates = {"slbor", "semi-learned borrowing"},
},
["ศัพท์ที่ยืมอักขรวิธี"] = {
from_source_desc = "orthographic loans from SOURCE, i.e. terms that were borrowed from SOURCE in their script forms, not their pronunciations.",
umbrella_desc = "orthographic loans, i.e. terms that were borrowed in their script forms, not their pronunciations.",
uses_subtype_handler = true,
categorizing_templates = {"obor", "orthographic borrowing"},
},
["ศัพท์ที่ยืมโดยไม่ดัดแปลง"] = {
from_source_desc = "[[loanword]]s from SOURCE that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of DEST.",
umbrella_desc = "[[loanword]]s that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of the target language.",
uses_subtype_handler = true,
categorizing_templates = {"ubor", "unadapted borrowing"},
},
["ศัพท์ที่ยืมโดยดัดแปลง"] = {
from_source_desc = "[[loanwords]] from SOURCE formed with the addition of an affix to conform the term to the normal morphology of DEST.",
umbrella_desc = "[[loanword]]s formed with the addition of an affix to conform the term to the normal morphology of the target language.",
uses_subtype_handler = true,
additional = function(source, dest)
return ("To categorize a term into this category, use {{tl|af|%s|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|%s|3=type=abor|4=...}}, using the same syntax), where <code><var>source_term</var></code> is " ..
"the %s term that the term in question was borrowed from and <code><var>affix</var></code> " ..
"is the %s affix used to adapt the %s term. An example is " ..
"{{m+|pl|adresować||to address}}, which would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate " ..
"that is was formed from {{m+|fr|adresser}} with the addition of the Polish verb-forming affix " ..
"{{m|pl|-ować}}."):format(dest:getCode(), source:getCode(), dest:getCode(), source:getCanonicalName(), dest:getCanonicalName(),
source:getCanonicalName())
end,
umbrella_additional = function(source)
return ("To categorize a term into a language-specific subcategory, use {{tl|af|<var>destcode</var>|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|<var>destcode</var>|3=type=abor|4=...}}, using the same syntax), where " ..
"<code><var>destcode</var></code> is the language code of the target language in question (see " ..
"[[Wiktionary:List of languages]]); <code><var>source_term</var></code> is the %s term " ..
"that the term in question was borrowed from; and <code><var>affix</var></code> is the target-language " ..
"affix used to adapt the %s term. An example is {{m+|pl|adresować||to address}}, which " ..
"would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate that is was formed from " ..
"{{m+|fr|adresser}} with the addition of the Polish verb-forming affix {{m|pl|-ować}}."):format(
source:getCode(), source:getCanonicalName(), source:getCanonicalName())
end,
},
["ศัพท์ที่ยืมความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]] from SOURCE, i.e. terms one or more of whose definitions was borrowed from a term in SOURCE.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]], i.e. terms one or more of whose definitions was borrowed from a term in another language.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
categorizing_templates = {"sl", "semantic loan"},
},
["ศัพท์ที่แปลตรงตัวบางส่วน"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#partial calque|partially calqued]] from SOURCE, i.e. terms formed partly by piece-by-piece translations of SOURCE terms and partly by direct borrowing.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#partial calque|partial calques]], i.e. terms formed partly by piece-by-piece translations of terms from other languages and partly by direct borrowing.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวบางส่วนจากภาษา(.+)$",
categorizing_templates = {"pcal", "pclq", "partial calque"},
},
["ศัพท์ที่แปลตรงตัว"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#calque|calqued]] from SOURCE, i.e. terms formed by piece-by-piece translations of SOURCE terms.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#calque|calques]], i.e. terms formed by piece-by-piece translations of terms from other languages.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวจากภาษา(.+)$",
categorizing_templates = {"cal", "clq", "calque"},
},
["ศัพท์ที่เข้าคู่เสียง-ความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]] from SOURCE, i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]], i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
categorizing_templates = {"psm", "phono-semantic matching"},
},
["ศัพท์ที่ยืมเทียม"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]] from SOURCE, i.e. terms that appear to be SOURCE, but are not used or have an unrelated meaning in SOURCE itself.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]], i.e. terms that appear to be derived from another language, but are not used or have an unrelated meaning in that language itself.",
categorizing_templates = {"pl", "pseudo-loan"},
},
}
for bortype, spec in pairs(borrowing_specs) do
labels[bortype] = {
description = "{{{langname}}} " .. spec.umbrella_desc,
parents = {spec.umbrella_parent or "ศัพท์ที่ยืมมา"},
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
if not spec.uses_subtype_handler then
-- If the label pattern isn't specifically given, generate it from the `bortype`; but make sure to
-- escape hyphens in the pattern.
local label_pattern = spec.label_pattern or "^" .. pattern_escape(bortype) .. "จากภาษา(.+)$"
insert(handlers, function(data)
local source_name = data.label:match(label_pattern)
if source_name then
return borrowing_subtype_handler(data.lang, source_name, bortype, spec)
end
end)
end
end
insert(handlers, function(data)
local borrowing_type, source_name = data.label:match("^(ศัพท์ที่ยืม.+)จากภาษา(.+)$")
if borrowing_type then
local spec = borrowing_specs[borrowing_type]
return borrowing_subtype_handler(data.lang, source_name, borrowing_type, spec)
end
end)
-----------------------------------------------------------------------------
---------------------- Indo-Aryan extension handlers ------------------------
-----------------------------------------------------------------------------
-- FIXME: Put this in a family-specific module.
insert(handlers, function(data)
local labelpref, extension = data.label:match("^(terms extended with Indo%-Aryan )(.+)$")
if not extension then
return
end
local lang_inc_ash = require("Module:languages").getByCode("inc-ash")
local linked_term = full_link({lang = lang_inc_ash, term = extension}, "term")
local tagged_term = tag_text(extension, lang_inc_ash, nil, "term")
return {
description = "{{{langname}}} terms extended with the [[Indo-Aryan]] [[pleonastic]] affix " .. linked_term .. ".",
displaytitle = "{{{langname}}} " .. labelpref .. tagged_term,
breadcrumb = tagged_term,
parents = {{name = "terms with Indo-Aryan extensions", sort = extension}},
umbrella = {
no_by_language = true,
parents = "Indo-Aryan extensions",
displaytitle = "Terms extended with Indo-Aryan " .. tagged_term,
}
}
end)
-----------------------------------------------------------------------------
---------------------------- Coined-by handlers -----------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local coiner = data.label:match("^terms coined by (.+)$")
if not coiner then
return
end
-- Sort by last name per request from [[User:Metaknowledge]]
local last_name = umatch(coiner, ".-%s(%S+)$")
return {
description = "{{{langname}}} terms coined by " .. coiner .. ".",
breadcrumb = coiner,
parents = {{
name = "coinages",
sort = last_name and last_name .. ", " .. coiner or coiner,
}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
------------------------ Multiple etymology handlers ------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local pos = data.label:match("^terms with multiple (.+) etymologies$")
if not pos then
return
end
local plpos = pluralize_pos(pos)
local postype = pos_lemma_or_nonlemma(plpos)
if not postype then
return
end
return {
description = "{{{langname}}} " .. plpos .. " that are derived from multiple origins.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = "multiple " .. plpos,
parents = {{
name = "terms with multiple " .. postype .. " etymologies",
sort = pos,
}},
}
end)
insert(handlers, function(data)
local pos1, pos2 = data.label:match("^terms with (.+) and (.+) etymologies$")
if not pos1 then
return
end
local pos1type = pos_lemma_or_nonlemma(pluralize_pos(pos1))
local pos2type = pos_lemma_or_nonlemma(pluralize_pos(pos2))
if not (pos1type and pos2type) then
return
end
return {
description = "{{{langname}}} terms consisting of " .. add_indefinite_article(pos1) .." of one origin and " ..
add_indefinite_article(pos2) .. " of a different origin.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = pos1 .. " and " .. pos2,
parents = {{
name = pos1type == pos2type and "terms with multiple " .. pos1type .. " etymologies" or
"terms with lemma and non-lemma form etymologies",
sort = pos1 .. " and " .. pos2,
}},
}
end)
-----------------------------------------------------------------------------
--------------------------- Borrowed-back handlers --------------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form e.g. [[:Category:English terms borrowed back into English]]. We need to use a handler
-- because the category's language occurs inside the label itself. For the same reason, the umbrella category has a
-- nonstandard name "Terms borrowed back into the same language", so we handle it as a regular parent and disable the
-- built-in umbrella mechanism.
insert(handlers, function(data)
local lang = data.lang
if not lang then
return
end
local source_name = data.label:match("^terms borrowed back into (.+)$")
if not (source_name and source_name == lang:getDisplayForm()) then
return
end
return {
description = "{{{langname}}} terms that were borrowed from another language that originally borrowed the term from " .. source_name .. ".",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่ยืมมา", {
name = "ศัพท์ที่ยืมกลับไปยังภาษาเดิม",
raw = true,
sort = "{{{langname}}}"
}},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
end)
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for umbrella metacategories of the form e.g. [[:Category:Terms derived from Proto-Indo-Iranian roots]]
-- and [[:Category:Terms derived from Proto-Indo-European words]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(raw_handlers, function(data)
local source_name, terms_type
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name = data.category:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+)$")
if source_name then
terms_type = tt
break
end
end
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
return {
description = "Umbrella categories covering terms derived from particular " .. get_source_and_type_desc(source, terms_type) .. ".",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{ name = terms_type == "ราก" and "ราก" or "คำหลัก", is_label = true, lang = source:getCode(), sort = " " },
{ name = "ศัพท์ที่รับมาจาก" .. source_name, is_label = true, sort = " " .. terms_type },
},
}
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}
7efyavorctnylx1ow4b52f0le3veazu
5722523
5722522
2026-05-05T02:48:46Z
OctraBot
3198
5722523
Scribunto
text/plain
local labels = {}
local raw_categories = {}
local handlers = {}
local raw_handlers = {}
local en_utilities_module = "Module:en-utilities"
local m_str_utils = require("Module:string utilities")
local add_indefinite_article = require(en_utilities_module).add_indefinite_article
local full_link = require("Module:links").full_link
local get_lang_by_name = require("Module:languages").getByCanonicalName
local insert = table.insert
local pattern_escape = m_str_utils.pattern_escape
local plain_gsub = m_str_utils.plain_gsub
local pluralize_pos = require("Module:headword").pluralize_pos
local pos_lemma_or_nonlemma = require("Module:headword").pos_lemma_or_nonlemma
local serial_comma_join = require("Module:table").serialCommaJoin
local tag_text = require("Module:script utilities").tag_text
local umatch = mw.ustring.match
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
-----------------------------------------------------------------------------
-- --
-- LABELS --
-- --
-----------------------------------------------------------------------------
labels["ศัพท์แบ่งตามรากศัพท์"] = {
description = "{{{langname}}} terms categorized by their etymologies.",
umbrella_parents = "มูลฐาน",
parents = {{name = "{{{langcat}}}", raw = true}},
}
labels["terms by etymology"] = labels["ศัพท์แบ่งตามรากศัพท์"]
labels["AABB-type reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] in an AABB pattern.",
breadcrumb = "AABB-type",
parents = {"คำซ้ำ"},
}
labels["apophonic reduplications"] = {
description = "{{{langname}}} terms that underwent [[reduplication]] with only a change in a vowel sound.",
breadcrumb = "apophonic",
parents = {"คำซ้ำ"},
}
labels["ศัพท์ที่ผันรูปย้อนกลับ"] = {
description = "{{{langname}}} terms formed by reversing a supposed regular formation, removing part of an older term.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["back-formations"] = labels["ศัพท์ที่ผันรูปย้อนกลับ"]
labels["คำหลอม"] = {
description = "{{{langname}}} terms formed by combinations of other words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["blends"] = labels["คำหลอม"]
labels["ศัพท์ที่ยืมมา"] = {
description = "{{{langname}}} terms that are loanwords, i.e. words that were directly incorporated from another language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["borrowed terms"] = labels["ศัพท์ที่ยืมมา"]
labels["catachreses"] = {
description = "{{{langname}}} terms derived from misuses or misapplications of other terms.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่บัญญัติ"] = {
description = "{{{langname}}} terms coined by an identifiable person, organization or other such entity.",
parents = {"terms attributed to a specific source"},
umbrella_parents = {name = "terms attributed to a specific source", is_label = true, sort = " "},
}
labels["coinages"] = labels["ศัพท์ที่บัญญัติ"]
labels["coordinated pairs"] = {
description = "Terms in {{{langname}}} consisting of a pair of terms joined by a [[coordinating conjunction]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated triples"] = {
description = "Terms in {{{langname}}} consisting of three terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quadruples"] = {
description = "Terms in {{{langname}}} consisting of four terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["coordinated quintuples"] = {
description = "Terms in {{{langname}}} consisting of five terms joined by one or more [[coordinating conjunction]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากคำนาม"] = {
description = "{{{langname}}} terms derived from a noun.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["denominals"] = labels["ศัพท์ที่รับมาจากคำนาม"]
labels["ศัพท์ที่รับมาจากคำกริยา"] = {
description = "{{{langname}}} terms derived from a verb.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["deverbals"] = labels["ศัพท์ที่รับมาจากคำกริยา"]
labels["ศัพท์ที่ร่วมราก"] = {
description = "{{{langname}}} terms that trace their etymology from ultimately the same source as other terms in the same language, but by different routes, and often with subtly or substantially different meanings.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["doublets"] = labels["ศัพท์ที่ร่วมราก"]
labels["elongated forms"] = {
description = "{{{langname}}} terms where one or more letters or sounds is repeated for emphasis or effect.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากชื่อบุคคล"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["eponyms"] = labels["ศัพท์ที่รับมาจากชื่อบุคคล"]
labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"] = {
description = "{{{langname}}} terms that originate from [[trademark]]s, [[brand]]s and company names which have become [[genericized]]; that is, fallen into common usage in the target market's [[vernacular]], even when referring to other competing brands.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "เครื่องหมายการค้า"},
}
labels["genericized trademarks"] = labels["ศัพท์ที่รับมาจากเครื่องหมายการค้า"]
labels["ghost words"] = {
description = "{{{langname}}} terms that were originally erroneous or fictitious, published in a reference work as if they were genuine as a result of typographical error, misreading, or misinterpretation, or as [[:w:Fictitious entry|fictitious entries]], jokes, or hoaxes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["gramograms"] = {
description = "{{{langname}}} [[gramogram]]s – terms that are partially or completely spelled with [[homophone|homophonous]] letters.",
parents = {"rebuses"},
}
labels["haplological words"] = {
description = "{{{langname}}} words that underwent [[haplology]]: thus, their origin involved a loss or omission of a repeated sequence of sounds.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["homophonic translations"] = {
description = "{{{langname}}} terms that were borrowed by matching the etymon phonetically, without regard for the sense; compare [[phono-semantic matching]] and [[Hobson-Jobson]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["hybridisms"] = {
description = "{{{langname}}} terms formed by elements of different linguistic origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบทอด"] = {
description = "{{{langname}}} terms that were inherited from an earlier stage of the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["inherited terms"] = labels["ศัพท์ที่สืบทอด"]
labels["internationalisms"] = {
description = "{{{langname}}} loanwords which also exist in many other languages with the same or similar etymology.",
additional = "Terms should be here preferably only if the immediate source language is not known for certain. Entries are added into this category by [[Template:internationalism]]; see it for more information.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["legal doublets"] = {
description = "{{{langname}}} legal [[doublet]]s – a legal doublet is a standardized phrase commonly use in legal documents, proceedings etc. which includes two words that are near synonyms.",
parents = {"coordinated pairs"},
}
labels["legal triplets"] = {
description = "{{{langname}}} legal [[triplet]]s – a legal triplet is a standardized phrase commonly use in legal documents, proceedings etc which includes three words that are near synonyms.",
parents = {"coordinated triples"},
}
labels["LLM coinages"] = {
description = "{{{langname}}} terms that have been coined by {{w|large language models}} rather than humans.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["merisms"] = {
description = "{{{langname}}} [[merism]]s – terms that are [[coordinate]]s that, combined, are a synonym for a totality.",
parents = {"coordinated pairs"},
}
labels["metonyms"] = {
description = "{{{langname}}} terms whose origin involves calling a thing or concept not by its own name, but by the name of something intimately associated with that thing or concept.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["นวศัพท์"] = {
description = "{{{langname}}} terms that have been only recently acknowledged.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["neologisms"] = labels["นวศัพท์"]
labels["nonce terms"] = {
description = "{{{langname}}} terms that have been invented for a single occasion.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["number homophones"] = {
description = "{{{langname}}} terms that are partially or completely spelled with [[homophone|homophonous]] numbers.",
parents = {"rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["numerical contractions"] = {
description = "{{{langname}}} numerical contractions. In these, the number either denotes omitted characters ({{m+|en|globalization}} → {{m|en|g11n}}) or duplication ({{m+|kne|Kankanaey}} → {{m|kne|Kan2aey}}).",
parents = {"contractions", "rebuses", "ศัพท์ที่สะกดด้วยตัวเลข"},
}
labels["ศัพท์ที่เลียนเสียงธรรมชาติ"] = {
description = "{{{langname}}} terms that were coined to sound like what they represent.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["onomatopoeias"] = labels["ศัพท์ที่เลียนเสียงธรรมชาติ"]
labels["piecewise doublets"] = {
description = "{{{langname}}} terms that are [[ภาคผนวก:อภิธานศัพท์#piecewise doublet|piecewise doublets]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
--[=[ thwikt don't use specific terms below
for _, ism_and_langname in ipairs({
{"anglicisms", "English"},
{"Arabisms", "Arabic"},
{"Gallicisms", "French"},
{"Germanisms", "German"},
{"Hispanisms", "Spanish"},
{"Italianisms", "Italian"},
{"Latinisms", "Latin"},
{"Japonisms", "Japanese"},
}) do
local ism, langname = unpack(ism_and_langname)
labels["pseudo-" .. ism] = {
description = "{{{langname}}} terms that appear to be " .. langname .. ", but are not used or have an unrelated meaning in " .. langname .. " itself.",
parents = {"pseudo-loans"},
umbrella_parents = {name = "pseudo-loans", is_label = true, sort = " "},
}
end
--]=]
labels["rebracketings"] = {
description = "{{{langname}}} terms that have interacted with another word in such a way that the boundary between the words has been modified.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["rebuses"] = {
description = "{{{langname}}} [[rebus]]es – terms that are partially or completely represented by images, symbols or numbers, often as a form of wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่สืบสร้าง"] = {
description = "{{{langname}}} terms that are not directly attested, but have been reconstructed through other evidence.",
parents = {"ศัพท์แบ่งตามรากศัพท์"}
}
labels["reconstructed terms"] = labels["ศัพท์ที่สืบสร้าง"]
labels["reduplicated coordinated pairs"] = {
description = "{{{langname}}} reduplicated coordinated pairs.",
breadcrumb = "reduplicated",
parents = {"coordinated pairs", "คำซ้ำ"},
}
labels["reduplicated coordinated triples"] = {
description = "{{{langname}}} reduplicated coordinated triples.",
breadcrumb = "reduplicated",
parents = {"coordinated triples", "คำซ้ำ"},
}
labels["reduplicated coordinated quadruples"] = {
description = "{{{langname}}} reduplicated coordinated quadruples.",
breadcrumb = "reduplicated",
parents = {"coordinated quadruples", "คำซ้ำ"},
}
labels["reduplicated coordinated quintuples"] = {
description = "{{{langname}}} reduplicated coordinated quintuples.",
breadcrumb = "reduplicated",
parents = {"coordinated quintuples", "คำซ้ำ"},
}
labels["คำซ้ำ"] = {
description = "{{{langname}}} terms that underwent [[reduplication]], so their origin involved a repetition of roots or stems.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["reduplications"] = labels["คำซ้ำ"]
labels["retronyms"] = {
description = "{{{langname}}} terms that serve as new unique names for older objects or concepts whose previous names became ambiguous.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ราก"] = {
description = "Basic morphemes from which {{{langname}}} words are formed.",
parents = {"หน่วยคำ"},
}
labels["roots"] = labels["ราก"]
labels["Sanskritic formations"] = {
description = "{{{langname}}} terms coined from [[tatsama]] [[word]]s and/or [[affix]]es.",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่รับมาจากภาษาสันสกฤต"},
}
labels["sound-symbolic terms"] = {
description = "{{{langname}}} terms that use {{w|sound symbolism}} to express ideas but which are not necessarily strictly speaking [[onomatopoeic]].",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelled-out initialisms"] = {
description = "{{{langname}}} initialisms in which the letter names are spelled out.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spelling pronunciations"] = {
description = "{{{langname}}} terms whose pronunciation was historically or presently affected by their spelling.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["คำผวน"] = {
description = "{{{langname}}} terms in which the initial sounds of component parts have been exchanged, as in \"crook and nanny\" for \"nook and cranny\".",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["spoonerisms"] = labels["คำผวน"]
labels["taxonomic eponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious people, used for [[taxonomy]].",
parents = {"ศัพท์ที่รับมาจากชื่อบุคคล"},
}
labels["terms attributed to a specific source"] = {
description = "{{{langname}}} terms coined by an identifiable person or deriving from a known work.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms coined ex nihilo"] = {
description = "{{{langname}}} terms fabricated ''[[ex nihilo]]'', i.e. made up entirely rather than being derived from an existing source.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms containing fossilized case endings"] = {
description = "{{{langname}}} terms which preserve case morphology which is no longer analyzable within the contemporary grammatical system or which has been entirely lost from the language.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from area codes"] = {
description = "{{{langname}}} terms derived from [[area code]]s.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"] = {
description = "{{{langname}}} terms derived from the shape of letters. This can include terms derived from the shape of any letter in any alphabet.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from the shape of letters"] = labels["ศัพท์ที่รับมาจากรูปร่างตัวอักษร"]
labels["ศัพท์แบ่งตามราก"] = {
description = "{{{langname}}} terms categorized by the root they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์", {name = "ราก", sort = " "}},
}
labels["terms by root"] = labels["ศัพท์แบ่งตามราก"]
labels["ศัพท์แบ่งตามคำ"] = {
description = "{{{langname}}} terms categorized by the word they originate from.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms by word"] = labels["ศัพท์แบ่งตามคำ"]
labels["ศัพท์ที่รับมาจากบันเทิงคดี"] = {
description = "{{{langname}}} terms that originate from works of [[fiction]].",
breadcrumb = "บันเทิงคดี",
parents = {{name = "terms attributed to a specific source", sort = "บันเทิงคดี"}},
}
labels["terms derived from fiction"] = labels["ศัพท์ที่รับมาจากบันเทิงคดี"]
for _, data in ipairs {
{source="Dickensian works", desc="the works of [[w:Charles Dickens|Charles Dickens]]", topic_parent="Charles Dickens"},
{source="ดีซีคอมิกส์", desc="[[w:ดีซีคอมิกส์|ดีซีคอมิกส์]]"},
{source="โดราเอมอน", desc="[[w:Fujiko F. Fujio|Fujiko F. Fujio]]'s ''[[w:โดราเอมอน|โดราเอมอน]]''", displaytitle="''โดราเอมอน''"},
{source="ดรากอนบอล", desc="[[w:Akira Toriyama|Akira Toriyama]]'s ''[[w:ดรากอนบอล|ดรากอนบอล]]''", displaytitle="''ดรากอนบอล''"},
{source="ดักเบิร์กและเมาส์ตัน", desc="[[w:The Walt Disney Company|Disney]]'s [[w:Duck universe|Duckburg]] and [[w:Mickey Mouse universe|Mouseton]] universe",
topic_parent="ดิสนีย์"},
{source="ฟิวเจอรามา", desc="the animated television series ''{{w|ฟิวเจอรามา}}''", displaytitle = "''ฟิวเจอรามา''"},
{source="แฮร์รี่ พอตเตอร์", desc="the ''[[w:แฮร์รี่ พอตเตอร์|แฮร์รี่ พอตเตอร์]]'' series", displaytitle="''แฮร์รี่ พอตเตอร์''",
topic_parent="แฮร์รี่ พอตเตอร์"},
{source="Looney Tunes and Merrie Melodies", desc="''{{w|Looney Tunes}}'' and/or ''{{w|Merrie Melodies}}'', by {{w|Warner Bros. Animation}}", displaytitle = "''Looney Tunes'' and ''Merrie Melodies''"},
{source="หนึ่งเก้าแปดสี่", desc="[[w:George Orwell|George Orwell]]'s ''[[w:Nineteen Eighty-Four|Nineteen Eighty-Four]]''",
displaytitle="''หนึ่งเก้าแปดสี่''"},
{source="Seinfeld", desc="the American television sitcom ''{{w|Seinfeld}}'' (1989–1998)", displaytitle="''Seinfeld''"},
{source="Seussian works", desc="the works of [[w:Dr. Seuss|Dr. Seuss]]"},
{source="South Park", desc="the animated television series ''[[w:South Park|South Park]]''", displaytitle="''South Park''"},
{source="สตาร์ เทรค", desc="''[[w:สตาร์ เทรค|สตาร์ เทรค]]''", displaytitle="''สตาร์ เทรค''", topic_parent="สตาร์ เทรค"},
{source="สตาร์ วอร์ส", desc="''[[w:สตาร์ วอร์ส|สตาร์ วอร์ส]]''", displaytitle="''สตาร์ วอร์ส''", topic_parent="สตาร์ วอร์ส"},
{source="เดอะซิมป์สันส์", desc="''[[w:เดอะซิมป์สันส์|เดอะซิมป์สันส์]]''", displaytitle="''เดอะซิมป์สันส์''", topic_parent="เดอะซิมป์สันส์", sort="ซิมป์สันส์"},
{source="ปกรณัมของโทลคีน", desc="the [[legendarium]] of [[w:เจ. อาร์. อาร์. โทลคีน|เจ. อาร์. อาร์. โทลคีน]]", topic_parent="เจ. อาร์. อาร์. โทลคีน"},
} do
local parents = {{name = "ศัพท์ที่รับมาจากบันเทิงคดี", sort = data.sort or data.source}}
local umbrella_parents = {"หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"}
if data.topic_parent then
insert(parents, {name = "{{{langcode}}}:" .. data.topic_parent, raw = true})
insert(umbrella_parents, {name = data.topic_parent, raw = true})
end
labels["ศัพท์ที่รับมาจาก" .. data.source] = {
description = "{{{langname}}} terms that originate from " .. data.desc .. ".",
breadcrumb = data.displaytitle or data.source,
parents = parents,
umbrella = {
parents = umbrella_parents,
displaytitle = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle .. "แบ่งตามภาษา" or nil,
breadcrumb = data.displaytitle and "ศัพท์ที่รับมาจาก" .. data.displaytitle,
},
displaytitle = data.displaytitle and "ศัพท์{{{langcat}}}ที่รับมาจาก" .. data.displaytitle or nil,
}
end
labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"] = {
description = "{{{langname}}} terms derived from Greek mythology which have acquired an idiomatic meaning.",
breadcrumb = "ประมวลเรื่องปรัมปรากรีก",
parents = {{name = "terms attributed to a specific source", sort = "ประมวลเรื่องปรัมปรากรีก"}},
}
labels["terms derived from Greek mythology"] = labels["ศัพท์ที่รับมาจากประมวลเรื่องปรัมปรากรีก"]
labels["ศัพท์ที่รับมาจากอาชีพ"] = {
description = "{{{langname}}} terms derived from names of occupations.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from occupations"] = labels["ศัพท์ที่รับมาจากอาชีพ"]
labels["ศัพท์ที่รับมาจากภาษาอื่น"] = {
description = "{{{langname}}} terms that originate from other languages.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived from other languages"] = labels["ศัพท์ที่รับมาจากภาษาอื่น"]
labels["ศัพท์ที่รับมาจากไบเบิล"] = {
description = "{{{langname}}} terms that originate from the [[Bible]].",
breadcrumb = {name = "ไบเบิล", nocap = true},
parents = {{name = "terms attributed to a specific source", sort = "ไบเบิล"}},
}
labels["terms derived from the Bible"] = labels["ศัพท์ที่รับมาจากไบเบิล"]
labels["ศัพท์ที่รับมาจากนิทานอีสป"] = {
description = "{{{langname}}} terms that originate from [[Aesop]]'s Fables.",
breadcrumb = "นิทานอีสป",
parents = {{name = "terms attributed to a specific source", sort = "นิทานอีสป"}},
}
labels["terms derived from Aesop's Fables"] = labels["ศัพท์ที่รับมาจากนิทานอีสป"]
labels["terms derived from toponyms"] = {
description = "{{{langname}}} terms derived from names of real or fictitious places.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms derived through romanized wordplay"] = {
description = "{{{langname}}} terms derived through romanized wordplay.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms making reference to character shapes"] = {
description = "{{{langname}}} terms making reference to character shapes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["ศัพท์ที่รับมาจากกีฬา"] = {
description = "{{{langname}}} terms that originate from sports.",
breadcrumb = "กีฬา",
parents = {{name = "terms attributed to a specific source", sort = "กีฬา"}},
}
labels["terms derived from sport"] = labels["ศัพท์ที่รับมาจากกีฬา"]
labels["ศัพท์ที่รับมาจากเบสบอล"] = {
description = "{{{langname}}} terms that originate from baseball.",
breadcrumb = "เบสบอล",
parents = {{name = "ศัพท์ที่รับมาจากกีฬา", sort = "เบสบอล"}},
}
labels["terms derived from baseball"] = labels["ศัพท์ที่รับมาจากเบสบอล"]
labels["terms with Indo-Aryan extensions"] = {
description = "{{{langname}}} terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with lemma and non-lemma form etymologies"] = {
description = "{{{langname}}} terms consisting of both a lemma and non-lemma form, of different origins.",
breadcrumb = "lemma and non-lemma form",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple etymologies"] = {
description = "{{{langname}}} terms that are derived from multiple origins.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["terms with multiple lemma etymologies"] = {
description = "{{{langname}}} lemmas that are derived from multiple origins.",
breadcrumb = "multiple lemmas",
parents = {"terms with multiple etymologies"},
}
labels["terms with multiple non-lemma form etymologies"] = {
description = "{{{langname}}} non-lemma forms that are derived from multiple origins.",
breadcrumb = "multiple non-lemma forms",
parents = {"terms with multiple etymologies"},
}
labels["ศัพท์ที่ไม่ทราบรากศัพท์"] = {
description = "{{{langname}}} terms whose etymologies have not yet been established.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "ไม่ทราบรากศัพท์"}},
}
labels["terms with unknown etymologies"] = labels["ศัพท์ที่ไม่ทราบรากศัพท์"]
labels["univerbations"] = {
description = "{{{langname}}} terms that result from the agglutination of two or more words.",
parents = {"ศัพท์แบ่งตามรากศัพท์"},
}
labels["words derived through corruption"] = {
description = "{{{langname}}} words that result from a non-specific or sporadic change.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "corruption"}},
}
labels["words derived through metathesis"] = {
description = "{{{langname}}} words that were created through [[metathesis]] from another word.",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "metathesis"}},
}
labels["words that have undergone semantic shift"] = {
description = "{{{langname}}} words that show senses explained by [[semantic shift]].",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "semantic shift"}},
}
labels["words that have undergone semantic broadening"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[broadening]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic broadening"}},
}
labels["words that have undergone semantic narrowing"] = {
description = "{{{langname}}} words that show senses explained by [[semantic]] [[narrowing]].",
parents = {{name = "words that have undergone semantic shift", sort = "semantic narrowing"}},
}
labels["words that have undergone amelioration"] = {
description = "{{{langname}}} words that have gained a positive [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "amelioration"}},
}
labels["words that have undergone pejoration"] = {
description = "{{{langname}}} words that have gained a negative [[connotation]] over time.",
parents = {{name = "words that have undergone semantic shift", sort = "pejoration"}},
}
labels["terms with origins in folklore"] = {
description = "{{{langname}}} terms that have an etymology rooted in folklore.",
breadcrumb = "Folklore",
parents = {{name = "ศัพท์แบ่งตามรากศัพท์", sort = "folklore"}, {name = "{{{langcode}}}:Folklore", raw = true}},
umbrella_parents = {{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", raw = true}, {name = "Folklore", raw = true, sort = " "}}
}
-- Add 'umbrella_parents' key if not already present.
for _, data in pairs(labels) do
-- NOTE: umbrella.parents overrides umbrella_parents if both are given.
if not data.umbrella_parents then
data.umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"
end
end
-----------------------------------------------------------------------------
-- --
-- RAW CATEGORIES --
-- --
-----------------------------------------------------------------------------
raw_categories["หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to terms categorized by their etymologies, such as types of compounds or borrowings.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์แบ่งตามรากศัพท์", is_label = true, sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to borrowed terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่ยืมมา", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา"] = {
description = "Umbrella categories covering topics related to inherited terms.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "ศัพท์ที่สืบทอด", is_label = true, sort = " "},
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Indo-Aryan extensions"] = {
description = "Umbrella categories covering terms extended with particular [[Indo-Aryan]] [[pleonastic]] affixes.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["Multiple etymology subcategories by language"] = {
description = "Umbrella categories covering topics related to terms with multiple etymologies.",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{name = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา", sort = " "},
},
}
raw_categories["ศัพท์ที่ยืมกลับไปยังภาษาเดิม"] = {
description = "Categories with terms in specific languages that were borrowed from a second language that previously borrowed the term from the first language.",
additional = "A well-known example is {{m+|en|salaryman}}, a term borrowed from Japanese which in turn was borrowed from the English words [[salary]] and [[man]].\n\n{{{umbrella_msg}}}",
parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
-----------------------------------------------------------------------------
-- --
-- HANDLERS --
-- --
-----------------------------------------------------------------------------
local function get_source(source_name, allow_family, name_type)
local source = get_lang_by_name(source_name, nil, true, allow_family)
if source == nil then
return nil
end
-- Check that the source name matches the expected form (e.g. getCanonicalName, getDisplayForm etc).
if source[name_type](source) == source_name then
return source
end
end
local function get_source_and_type_desc(source, term_type)
if source:getCode() == "ine-pro" and term_type:find("^roots?$") then
return "[[w:Proto-Indo-European root|Proto-Indo-European " .. term_type .. "]]"
end
return "[[w:" .. source:getWikipediaArticle() .. "|" .. source:getCanonicalName() .. "]] " .. term_type
end
local function get_source_and_source_desc(source_name)
-- HACK! Map 'taxonomic names', as generated by [[Module:etymology]], back to its canonical name
-- before calling getByCanonicalName(). We need a more general solution here.
local source_desc
if source_name == "taxonomic names" then
source_name = "taxonomic name"
source_desc = "[[w:taxonomic nomenclature|taxonomic names]]"
end
local source = get_source(source_name, true, "getCanonicalName") --th
if source == nil then
return
end
source_desc = source_desc or source:makeCategoryLink()
if source:hasType("family") then
source_desc = "one of the " .. source_desc
end
return source, source_desc
end
-----------------------------------------------------------------------------
------------------------------- word handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE word word' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
local function lang_is_semitic(lang)
return lang:inFamily("sem")
end
insert(handlers, function(data)
local labelpref, word_and_id = data.label:match("^(terms belonging to the word )(.+)$")
if not word_and_id then
return
end
local word, id = word_and_id:match("^(.+) %((.-)%)$")
if not word then
word = word_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local word_desc = is_semitic and "[[w:Semitic word|word]]" or "word"
local parents = {}
if id then
insert(parents, {name = labelpref .. word, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามคำ", sort = word_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style words)
local word_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(word, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(word_no_prefix_suffix, not_separator_c, ""))
local linked_word = data.lang and full_link({ term = word, lang = data.lang, gloss = id, id = id }, "term") or word
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter words", sort = word_and_id})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, word, tag_text(word, lang, nil, "term"))
end
local breadcrumb = tag_text(word, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. word_desc .. " " .. linked_word .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^terms by (.+) word$")
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian word]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source:getDisplayForm())
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "word") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
-----------------------------------------------------------------------------
------------------------------- Root handlers -------------------------------
-----------------------------------------------------------------------------
-- Handlers for 'terms derived from the SOURCE root ROOT' must go *BEFORE* the
-- more general 'terms derived from SOURCE' handler.
-- Handler for e.g. [[:Category:Yola terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Russian terms derived from the Proto-Indo-European word *swé]], and corresponding umbrella
-- categories [[:Category:Terms derived from the Proto-Indo-European root *h₂el- (grow)]] and
-- [[:Category:Terms derived from the Proto-Indo-European word *swé]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(handlers, function(data)
local source_name, term_type, term_and_id
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name, term_and_id = data.label:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+) (.+)$")
if source_name then
term_type = tt
break
end
end
if not source_name then
return
end
local term, id = term_and_id:match("^(.+) %((.-)%)$")
if not term then
term = term_and_id
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {
{
name = "ศัพท์แบ่งตาม" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
local umbrella_parents = {
{
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type,
sort = (source:makeSortKey(term)),
}
}
if id then
insert(parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
sort = " "
})
insert(umbrella_parents, {
name = "ศัพท์ที่รับมาจาก" .. source_name .. term_type .. " " .. term,
is_label = true,
sort = " "
})
end
-- Italicize the word/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, term, tag_text(term, source, nil, "term"))
end
local breadcrumb = tag_text(term, source, nil, "term") .. (id and " (" .. id .. ")" or "")
local term_page, alt_form
if term_type == "root" and lang_is_semitic(source) then
term_page = ("ภาคผนวก:ราก%s/%s"):format(source:getCanonicalName(), term)
alt_form = term
else
term_page = term
end
return {
description = "{{{langname}}} terms that originate ultimately from the " .. get_source_and_type_desc(source, term_type) .. " " .. full_link({
term = term_page,
alt = alt_form,
lang = source,
gloss = id,
id = id
}, "term") .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
no_by_language = true,
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = umbrella_parents,
}
}
end)
insert(handlers, function(data)
local labelpref, root_and_id = data.label:match("^(terms belonging to the root )(.+)$")
if not root_and_id then
return
end
local root, id = root_and_id:match("^(.+) %((.-)%)$")
if not root then
root = root_and_id
end
local is_semitic = lang_is_semitic(data.lang)
local root_desc = is_semitic and "[[w:Semitic root|root]]" or "root"
local parents = {}
if id then
insert(parents, {name = labelpref .. root, sort = id})
end
insert(parents, {name = "ศัพท์แบ่งตามราก", sort = root_and_id})
local separators = "־ %-"
local separator_c = "[" .. separators .. "]"
local not_separator_c = "[^" .. separators .. "]"
-- remove any leading or trailing separators (e.g. in PIE-style roots)
local root_no_prefix_suffix =
mw.ustring.gsub(mw.ustring.gsub(root, separator_c .. "$", ""), "^" .. separator_c, "")
local num_sep = mw.ustring.len(mw.ustring.gsub(root_no_prefix_suffix, not_separator_c, ""))
local root_page, alt_form
if is_semitic then
root_page = ("ภาคผนวก:ราก%s/%s"):format(data.lang:getCanonicalName(), root)
alt_form = root
else
root_page = root
end
local linked_root = data.lang and full_link(
{ term = root_page, alt = alt_form, lang = data.lang, gloss = id, id = id }, "term") or root_page
if num_sep > 0 then
insert(parents, {name = "" .. (num_sep + 1) .. "-letter roots", sort = root_and_id})
end
-- Italicize the root/word in the title.
local function displaytitle(title, lang)
return plain_gsub(title, root, tag_text(root, lang, nil, "term"))
end
local breadcrumb = tag_text(root, data.lang, nil, "term") .. (id and " (" .. id .. ")" or "")
return {
description = "{{{langname}}} terms that belong to the " .. root_desc .. " " .. linked_root .. ".",
displaytitle = displaytitle,
breadcrumb = breadcrumb,
parents = parents,
umbrella = false,
}
end)
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์แบ่งตามราก(.+)$")
if not source_name or source_name == "ศัพท์" then --th; excludes falsily detect ศัพท์แบ่งตามรากศัพท์
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
local parents = {"ศัพท์แบ่งตามรากศัพท์"}
-- In [[:Category:Proto-Indo-Iranian terms by Proto-Indo-Iranian root]],
-- don't add parent [[:Category:Proto-Indo-Iranian terms derived from Proto-Indo-Iranian]].
if not data.lang or data.lang:getCode() ~= source:getCode() then
insert(parents, "ศัพท์ที่รับมาจากภาษา" .. source_name)
end
return {
description = "{{{langname}}} terms categorized by the " .. get_source_and_type_desc(source, "root") .. " they originate from.",
parents = parents,
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
end)
insert(handlers, function(data)
local root_shape, post, additional = data.label:match("^(.+)([ -])shaped roots$")
if not root_shape then
return
elseif data.lang and data.lang:getCode() == "ine-pro" then
additional = [=[
* '''e''' stands for the vowel of the root.
* '''C''' stands for any stop or ''s''.
* '''R''' stands for any resonant.
* '''H''' stands for any laryngeal.
* '''M''' stands for ''m'' or ''w'', when followed by a resonant.
* '''s''' stands for ''s'', when next to a stop.]=]
end
if root_shape == "irregularly" and post == " " then
return {
breadcrumb = "irregular",
description = "{{{langname}}} roots with a shape that violates the {{w|Proto-Indo-European root#Shape of a root|known rules on root shapes}}.",
additional = additional,
parents = {{name = "roots by shape", sort = "*"}},
umbrella = false,
}
elseif post == " " then
return
end
return {
breadcrumb = root_shape,
description = "{{{langname}}} roots with the shape ''" .. root_shape .. "''.",
additional = additional,
parents = {{name = "roots by shape", sort = root_shape}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
-------------------- Derived/inherited/borrowed handlers --------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form "LANG terms derived from SOURCE", where SOURCE is a language, etymology language
-- or family (e.g. "Indo-European languages"), along with corresponding umbrella categories of the form
-- "Terms derived from SOURCE".
insert(handlers, function(data)
local source_name = data.label:match("^ศัพท์ที่รับมาจากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่รับมาจากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- Compute description.
local desc = "{{{langname}}} terms that originate from " .. source_desc .. "."
local additional
if source:hasType("family") then
additional = "This category should, ideally, contain only other categories. Entries can be categorized here, too, when the proper subcategory is unclear. " ..
"If you know the exact language from which an entry categorized here is derived, please edit its respective entry."
end
-- Compute parents.
local derived_from_variety_of_self = false
local parent
local sortkey = source:getDisplayForm()
if source:hasType("etymology-only") then
-- By default, `parent` is the source's parent.
parent = source:getParent()
-- Check if the source is a variety (or subvariety) of the language.
if data.lang and source:hasParent(data.lang) then
derived_from_variety_of_self = true
end
-- If the language is the direct parent of the source or the parent is "und", then we use the family of the source as `parent` instead.
if data.lang and (parent:getCode() == data.lang:getCode() or parent:getCode() == "und") then
parent = source:getFamily()
end
-- Regular language or family.
else
local fam = source:getFamily()
if fam then
parent = fam
end
end
-- If `parent` does not exist, is the same as `source`, or would be "isolate languages" or "not a family", then we discard it.
if (not parent) or parent:getCode() == source:getCode() or parent:getCode() == "qfa-iso" or parent:getCode() == "qfa-not" or
parent:getCode() == "qfa-unc" then
parent = nil
derived_from_variety_of_self = false
-- Otherwise, get the display form.
else
parent = parent:getDisplayForm()
end
parent = parent and "ศัพท์ที่รับมาจาก" .. parent or "ศัพท์ที่รับมาจากภาษาอื่น"
local parents = {{name = parent, sort = sortkey}}
if derived_from_variety_of_self then
insert(parents, "Category:Categories for terms in a language derived from a term in a subvariety of that language")
end
-- Compute umbrella parents.
local cat_name = source:getCode() == "mul-tax" and "Taxonomic names" or source:getCategoryName()
-- If the source is etymology-only, its category will be handled by the lect handler in
-- [[Module:category tree/ภาษณ์]]. If it has a nonstandard name like 'Kölsch' (i.e. not a name like
-- 'American English' that has a language name in it), the lect handler won't handle it unless we tell it to do so
-- through the following call; this is an optimization to avoid expensive processing work on all manner of randomly
-- named categories.
if source:hasType("etymology-only") then
require("Module:category tree/ภาษณ์").export.register_likely_lect_parent_cat(cat_name)
end
local umbrella_parents = {
(source:hasType("family") or source:getCode() == "mul-tax") and {name = cat_name, raw = true, sort = " "} or
{name = cat_name, raw = true, sort = "terms derived from"}
}
-- Without the following, the breadcrumb trail for e.g. [[Category:Javanese terms derived from French]] looks like
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages »
-- Indo-European languages » Italic languages » Romance languages » Italo-Western Romance languages »
-- Western Romance languages » Gallo-Romance languages » Gallo-Rhaetian languages » Oïl languages » French
-- To reduce the length, we truncate the "languages" part of the breadcrumbs as long as this does not create
-- ambiguity (i.e. unless there is a language with the same name as the family). Hence, for the Category
-- [[Category:Javanese terms derived from Arabic]], we end up with
-- Fundamental » All languages » Javanese » Terms by etymology » Terms derived from other languages » Afroasiatic »
-- Semitic » West Semitic » Central Semitic » Arabic languages » Arabic
-- because "Arabic" is ambiguous between family and language (and script, for that matter).
local breadcrumb = source_name
if source:hasType("family") and breadcrumb:find("กลุ่มภาษา") then
local truncated_breadcrumb = breadcrumb:gsub("กลุ่มภาษา", "")
if not get_lang_by_name(truncated_breadcrumb, nil, "allow etym") then
breadcrumb = truncated_breadcrumb
end
end
return {
description = desc,
additional = additional,
breadcrumb = breadcrumb,
parents = parents,
umbrella = {
description = "Categories with terms that originate from " .. source_desc .. ".",
parents = umbrella_parents,
},
}
end)
-- Handler for categories of the form "LANG terms inherited/borrowed from SOURCE", where SOURCE is a language,
-- etymology language or family (e.g. "Indo-European languages"). Also handles umbrella categories of the form
-- "Terms inherited/borrowed from SOURCE".
local function inherited_borrowed_handler(etymtype)
return function(data)
local source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากภาษา(.+)$")
if not source_name then
source_name = data.label:match("^ศัพท์ที่" .. etymtype .. "จากกลุ่มภาษา(.+)$") --th; try again with family
if not source_name then
return
end
end
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
return {
description = "{{{langname}}} terms " .. etymtype .. " from " .. source_desc .. ".",
breadcrumb = source_name,
parents = {
{name = "ศัพท์ที่" .. etymtype, sort = source_name},
{name = "ศัพท์ที่รับมาจาก" .. (source:hasType("family") and "กลุ่มภาษา" or "ภาษา") .. source_name, sort = " "}
},
umbrella = {
parents = {
{ name = "ศัพท์ที่รับมาจากภาษา" .. source_name, is_label = true, sort = " " },
etymtype == "inherited" and
{ name = "หมวดหมู่ย่อยของศัพท์ที่สืบทอดแบ่งตามภาษา", sort = source_name }
-- There are several types of borrowings mixed into the following holding category,
-- so keep these ones sorted under 'Terms borrowed from SOURCE_NAME' instead of just
-- 'SOURCE_NAME'.
or "หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
end
table.insert(handlers, inherited_borrowed_handler("ยืมมา"))
table.insert(handlers, inherited_borrowed_handler("สืบทอด"))
-----------------------------------------------------------------------------
------------------------ Borrowing subtype handlers -------------------------
-----------------------------------------------------------------------------
-- General handler for specific borrowing subtypes, such as learned borrowings, calques and phono-semantic matchings.
local function borrowing_subtype_handler(dest, source_name, parent_cat, spec)
local source, source_desc = get_source_and_source_desc(source_name)
if not source then
return
end
-- normally uses of UNKNOWN should not show up to the end user
local dest_name = dest and dest:getCanonicalName() or "UNKNOWN"
local additional, umbrella_additional
if spec.additional then
if dest then
additional = spec.additional(source, dest)
else
umbrella_additional = spec.umbrella_additional(source)
end
else
if not spec.categorizing_templates then
error("Internal error: Must specify either `categorizing_templates` or the combination of `additional` and `umbrella_additional` in each borrowing subtype spec")
end
local extra_templates = {}
local extra_template_text
for i, template in ipairs(spec.categorizing_templates) do
if i > 1 then
insert(extra_templates, ("{{tl|%s|...}}"):format(template))
end
end
if #extra_templates > 0 then
extra_template_text = (" (or %s, using the same syntax)"):format(
serial_comma_join(extra_templates, {conj = "or"}))
else
extra_template_text = ""
end
if dest then
additional = ("To categorize a term into this category, use {{tl|%s|%s|%s|<var>source_term</var>}}%s, " ..
"where <code><var>source_term</var></code> is the %s term that the term in question " ..
"was borrowed from."):format(
spec.categorizing_templates[1], dest:getCode(), source:getCode(), extra_template_text, source_name)
else
umbrella_additional = ("To categorize a term into a language-specific subcategory, use " ..
"{{tl|%s|<var>destcode</var>|%s|<var>source_term</var>}}%s, where <code><var>destcode</var></code> " ..
"is the language code of the language in question (see [[Wiktionary:List of languages]]), and " ..
"<code><var>source_term</var></code> is the %s term that the term in question was " ..
"borrowed from."):format(spec.categorizing_templates[1], source:getCode(), extra_template_text, source_name)
end
end
return {
description = "{{{langname}}} " .. spec.from_source_desc:gsub("SOURCE", source_desc):gsub("DEST", dest_name),
additional = additional,
breadcrumb = source_name,
parents = {
{ name = parent_cat, sort = source_name },
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, sort = " " },
},
umbrella = {
additional = umbrella_additional,
parents = {
{ name = "ศัพท์ที่ยืมมาจากภาษา" .. source_name, is_label = true, sort = " " },
"หมวดหมู่ย่อยของศัพท์ที่ยืมมาแบ่งตามภาษา",
}
},
}
end
-- Specs describing types of borrowings.
-- `from_source_desc` is the English description used in categories of the form "LANGUAGE BORTYPE from SOURCE",
-- e.g. "Arabic semantic loans from English". "SOURCE" in the description is replaced by the source language.
-- `umbrella_desc` is the English description used in categories of the form "LANGUAGE BORTYPE", e.g.
-- "Arabic semantic loans". This is an umbrella category grouping all the source-language-specific categories.
-- `uses_subtype_handler`, if true, means that the handler for "LANGUAGE BORTYPE from SOURCE" categories is
-- implemented by a generic "TYPE borrowings" handler (at the bottom of this section), so we don't need to
-- create a BORTYPE-specific handler.
-- `umbrella_parent`, if given, is the parent category of the umbrella categories of the form "LANGUAGE BORTYPE".
-- By default it is "borrowed terms". Some borrowing types replace this with "terms by etymology". (FIXME:
-- Review whether this is correct.)
-- `label_pattern`, if given, is a Lua pattern that matches the category name minus the language at the beginning.
-- It should have one capture, which is the source language. An example is "^terms partially calqued from (.+)$".
-- If omitted, it is generated from BORTYPE.
-- `categorizing_templates`, if given, is the list of templates that categorize into this category. They are assumed to
-- follow the syntax of {{bor}}. The first template in the list should be the preferred alias. The specified
-- templates are used to form the `additional` text displayed on the language-specific category page and
-- corresponding umbrella category page describing how to categorize into the category in question. In more complex
-- cases, you can omit this field and instead supply the `additional` and `umbrella_additional` fields (as is done
-- with adapted borrowings). You must either specify `categorizing_templates` or the combination of `additional` and
-- `umbrella_additional`.
-- `additional`, if given, is a function of two arguments (source and destination language objects) that will generate
-- the `additional` text displayed on the language-specific category page that describes how to categorize into the
-- category in question. This is an alternative to specifying `categorizing_templates`, used in more complex cases
-- (currently, with adapted borrowings).
-- `umbrella_additional`, if given, is a function of one argument (source language object) that will generate the
-- `additional` text displayed on the umbrella category page that describes how to categorize into the category in
-- question. This is an alternative to specifying `categorizing_templates`, used in more complex cases (currently,
-- with adapted borrowings).
local borrowing_specs = {
["ศัพท์ที่ยืมโดยเรียนรู้"] = {
from_source_desc = "terms that are learned [[loanword]]s from SOURCE, that is, terms that were directly incorporated from SOURCE instead of through normal language contact.",
umbrella_desc = "terms that are learned [[loanword]]s, that is, terms that were directly incorporated from another language instead of through normal language contact.",
uses_subtype_handler = true,
categorizing_templates = {"lbor", "learned borrowing"},
},
["ศัพท์ที่ยืมโดยกึ่งเรียนรู้"] = {
from_source_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s from SOURCE, that is, terms borrowed from SOURCE (a [[classical language]]) into DEST (a modern language) and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
umbrella_desc = "terms that are [[semi-learned borrowing|semi-learned]] [[loanword]]s, that is, terms borrowed from a [[classical language]] into a modern language and partly reshaped based on later [[sound change]]s or by analogy with [[inherit]]ed terms in the language.",
uses_subtype_handler = true,
categorizing_templates = {"slbor", "semi-learned borrowing"},
},
["ศัพท์ที่ยืมอักขรวิธี"] = {
from_source_desc = "orthographic loans from SOURCE, i.e. terms that were borrowed from SOURCE in their script forms, not their pronunciations.",
umbrella_desc = "orthographic loans, i.e. terms that were borrowed in their script forms, not their pronunciations.",
uses_subtype_handler = true,
categorizing_templates = {"obor", "orthographic borrowing"},
},
["ศัพท์ที่ยืมโดยไม่ดัดแปลง"] = {
from_source_desc = "[[loanword]]s from SOURCE that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of DEST.",
umbrella_desc = "[[loanword]]s that have not been conformed to the morpho-syntactic, phonological and/or phonotactical rules of the target language.",
uses_subtype_handler = true,
categorizing_templates = {"ubor", "unadapted borrowing"},
},
["ศัพท์ที่ยืมโดยดัดแปลง"] = {
from_source_desc = "[[loanwords]] from SOURCE formed with the addition of an affix to conform the term to the normal morphology of DEST.",
umbrella_desc = "[[loanword]]s formed with the addition of an affix to conform the term to the normal morphology of the target language.",
uses_subtype_handler = true,
additional = function(source, dest)
return ("To categorize a term into this category, use {{tl|af|%s|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|%s|3=type=abor|4=...}}, using the same syntax), where <code><var>source_term</var></code> is " ..
"the %s term that the term in question was borrowed from and <code><var>affix</var></code> " ..
"is the %s affix used to adapt the %s term. An example is " ..
"{{m+|pl|adresować||to address}}, which would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate " ..
"that is was formed from {{m+|fr|adresser}} with the addition of the Polish verb-forming affix " ..
"{{m|pl|-ować}}."):format(dest:getCode(), source:getCode(), dest:getCode(), source:getCanonicalName(), dest:getCanonicalName(),
source:getCanonicalName())
end,
umbrella_additional = function(source)
return ("To categorize a term into a language-specific subcategory, use {{tl|af|<var>destcode</var>|3=type=adap|4=%s:<var>source_term</var>|5=-<var>affix</var>}} " ..
"(or {{tl|af|<var>destcode</var>|3=type=abor|4=...}}, using the same syntax), where " ..
"<code><var>destcode</var></code> is the language code of the target language in question (see " ..
"[[Wiktionary:List of languages]]); <code><var>source_term</var></code> is the %s term " ..
"that the term in question was borrowed from; and <code><var>affix</var></code> is the target-language " ..
"affix used to adapt the %s term. An example is {{m+|pl|adresować||to address}}, which " ..
"would use {{tl|af|pl|3=type=adap|4=fr:adresser|5=-ować}} to indicate that is was formed from " ..
"{{m+|fr|adresser}} with the addition of the Polish verb-forming affix {{m|pl|-ować}}."):format(
source:getCode(), source:getCanonicalName(), source:getCanonicalName())
end,
},
["ศัพท์ที่ยืมความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]] from SOURCE, i.e. terms one or more of whose definitions was borrowed from a term in SOURCE.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#semantic loan|semantic loans]], i.e. terms one or more of whose definitions was borrowed from a term in another language.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
categorizing_templates = {"sl", "semantic loan"},
},
["ศัพท์ที่แปลตรงตัวบางส่วน"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#partial calque|partially calqued]] from SOURCE, i.e. terms formed partly by piece-by-piece translations of SOURCE terms and partly by direct borrowing.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#partial calque|partial calques]], i.e. terms formed partly by piece-by-piece translations of terms from other languages and partly by direct borrowing.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวบางส่วนจากภาษา(.+)$",
categorizing_templates = {"pcal", "pclq", "partial calque"},
},
["ศัพท์ที่แปลตรงตัว"] = {
from_source_desc = "terms that were [[ภาคผนวก:อภิธานศัพท์#calque|calqued]] from SOURCE, i.e. terms formed by piece-by-piece translations of SOURCE terms.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#calque|calques]], i.e. terms formed by piece-by-piece translations of terms from other languages.",
umbrella_parent = "ศัพท์แบ่งตามรากศัพท์",
label_pattern = "^ศัพท์ที่แปลตรงตัวจากภาษา(.+)$",
categorizing_templates = {"cal", "clq", "calque"},
},
["ศัพท์ที่เข้าคู่เสียง-ความหมาย"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]] from SOURCE, i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#phono-semantic matching|phono-semantic matchings]], i.e. terms that were borrowed by matching the etymon phonetically and semantically.",
categorizing_templates = {"psm", "phono-semantic matching"},
},
["ศัพท์ที่ยืมเทียม"] = {
from_source_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]] from SOURCE, i.e. terms that appear to be SOURCE, but are not used or have an unrelated meaning in SOURCE itself.",
umbrella_desc = "[[ภาคผนวก:อภิธานศัพท์#pseudo-loan|pseudo-loans]], i.e. terms that appear to be derived from another language, but are not used or have an unrelated meaning in that language itself.",
categorizing_templates = {"pl", "pseudo-loan"},
},
}
for bortype, spec in pairs(borrowing_specs) do
labels[bortype] = {
description = "{{{langname}}} " .. spec.umbrella_desc,
parents = {spec.umbrella_parent or "ศัพท์ที่ยืมมา"},
umbrella_parents = "หมวดหมู่ย่อยของศัพท์แบ่งตามรากศัพท์แบ่งตามภาษา",
}
if not spec.uses_subtype_handler then
-- If the label pattern isn't specifically given, generate it from the `bortype`; but make sure to
-- escape hyphens in the pattern.
local label_pattern = spec.label_pattern or "^" .. pattern_escape(bortype) .. "จากภาษา(.+)$"
insert(handlers, function(data)
local source_name = data.label:match(label_pattern)
if source_name then
return borrowing_subtype_handler(data.lang, source_name, bortype, spec)
end
end)
end
end
insert(handlers, function(data)
local borrowing_type, source_name = data.label:match("^(ศัพท์ที่ยืม.+)จากภาษา(.+)$")
if borrowing_type then
local spec = borrowing_specs[borrowing_type]
return borrowing_subtype_handler(data.lang, source_name, borrowing_type, spec)
end
end)
-----------------------------------------------------------------------------
---------------------- Indo-Aryan extension handlers ------------------------
-----------------------------------------------------------------------------
-- FIXME: Put this in a family-specific module.
insert(handlers, function(data)
local labelpref, extension = data.label:match("^(terms extended with Indo%-Aryan )(.+)$")
if not extension then
return
end
local lang_inc_ash = require("Module:languages").getByCode("inc-ash")
local linked_term = full_link({lang = lang_inc_ash, term = extension}, "term")
local tagged_term = tag_text(extension, lang_inc_ash, nil, "term")
return {
description = "{{{langname}}} terms extended with the [[Indo-Aryan]] [[pleonastic]] affix " .. linked_term .. ".",
displaytitle = "{{{langname}}} " .. labelpref .. tagged_term,
breadcrumb = tagged_term,
parents = {{name = "terms with Indo-Aryan extensions", sort = extension}},
umbrella = {
no_by_language = true,
parents = "Indo-Aryan extensions",
displaytitle = "Terms extended with Indo-Aryan " .. tagged_term,
}
}
end)
-----------------------------------------------------------------------------
---------------------------- Coined-by handlers -----------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local coiner = data.label:match("^terms coined by (.+)$")
if not coiner then
return
end
-- Sort by last name per request from [[User:Metaknowledge]]
local last_name = umatch(coiner, ".-%s(%S+)$")
return {
description = "{{{langname}}} terms coined by " .. coiner .. ".",
breadcrumb = coiner,
parents = {{
name = "coinages",
sort = last_name and last_name .. ", " .. coiner or coiner,
}},
umbrella = false,
}
end)
-----------------------------------------------------------------------------
------------------------ Multiple etymology handlers ------------------------
-----------------------------------------------------------------------------
insert(handlers, function(data)
local pos = data.label:match("^terms with multiple (.+) etymologies$")
if not pos then
return
end
local plpos = pluralize_pos(pos)
local postype = pos_lemma_or_nonlemma(plpos)
if not postype then
return
end
return {
description = "{{{langname}}} " .. plpos .. " that are derived from multiple origins.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = "multiple " .. plpos,
parents = {{
name = "terms with multiple " .. postype .. " etymologies",
sort = pos,
}},
}
end)
insert(handlers, function(data)
local pos1, pos2 = data.label:match("^terms with (.+) and (.+) etymologies$")
if not pos1 then
return
end
local pos1type = pos_lemma_or_nonlemma(pluralize_pos(pos1))
local pos2type = pos_lemma_or_nonlemma(pluralize_pos(pos2))
if not (pos1type and pos2type) then
return
end
return {
description = "{{{langname}}} terms consisting of " .. add_indefinite_article(pos1) .." of one origin and " ..
add_indefinite_article(pos2) .. " of a different origin.",
umbrella_parents = "Multiple etymology subcategories by language",
breadcrumb = pos1 .. " and " .. pos2,
parents = {{
name = pos1type == pos2type and "terms with multiple " .. pos1type .. " etymologies" or
"terms with lemma and non-lemma form etymologies",
sort = pos1 .. " and " .. pos2,
}},
}
end)
-----------------------------------------------------------------------------
--------------------------- Borrowed-back handlers --------------------------
-----------------------------------------------------------------------------
-- Handler for categories of the form e.g. [[:Category:English terms borrowed back into English]]. We need to use a handler
-- because the category's language occurs inside the label itself. For the same reason, the umbrella category has a
-- nonstandard name "Terms borrowed back into the same language", so we handle it as a regular parent and disable the
-- built-in umbrella mechanism.
insert(handlers, function(data)
local lang = data.lang
if not lang then
return
end
local source_name = data.label:match("^ศัพท์ที่ยืมกลับไปยังภาษา(.+)$")
if not (source_name and source_name == lang:getDisplayForm() and source_name ~= "เดิม") then -- excludes "ภาษาเดิม"
return
end
return {
description = "{{{langname}}} terms that were borrowed from another language that originally borrowed the term from " .. source_name .. ".",
parents = {"ศัพท์แบ่งตามรากศัพท์", "ศัพท์ที่ยืมมา", {
name = "ศัพท์ที่ยืมกลับไปยังภาษาเดิม",
raw = true,
sort = "{{{langname}}}"
}},
umbrella = false, -- Umbrella has a nonstandard name so we treat it as a raw category
}
end)
-----------------------------------------------------------------------------
-- --
-- RAW HANDLERS --
-- --
-----------------------------------------------------------------------------
-- Handler for umbrella metacategories of the form e.g. [[:Category:Terms derived from Proto-Indo-Iranian roots]]
-- and [[:Category:Terms derived from Proto-Indo-European words]]. Replaces the former
-- [[Module:category tree/PIE root cat]], [[Module:category tree/root cat]] and [[Template:PIE word cat]].
insert(raw_handlers, function(data)
local source_name, terms_type
for _, tt in ipairs{"ราก", "คำ", "ศัพท์"} do
source_name = data.category:match("^ศัพท์ที่รับมาจาก" .. tt .. "(.+)$")
if source_name then
terms_type = tt
break
end
end
if not source_name then
return
end
local source = get_source(source_name, false, "getCanonicalName")
if not source then
return
end
return {
description = "Umbrella categories covering terms derived from particular " .. get_source_and_type_desc(source, terms_type) .. ".",
additional = "{{{umbrella_meta_msg}}}",
parents = {
"หมวดหมู่ใหญ่รวมหัวข้อ",
{ name = terms_type == "ราก" and "ราก" or "คำหลัก", is_label = true, lang = source:getCode(), sort = " " },
{ name = "ศัพท์ที่รับมาจาก" .. source_name, is_label = true, sort = " " .. terms_type },
},
}
end)
return {LABELS = labels, RAW_CATEGORIES = raw_categories, HANDLERS = handlers, RAW_HANDLERS = raw_handlers}
q7gw7yckargztpg2qoozjaw5uf2c3ns
ประดิษฐ์
0
149918
5722547
1882647
2026-05-05T10:29:53Z
OctraBot
3198
/* คำคุณศัพท์ */
5722547
wikitext
text/x-wiki
{{also/auto}}
== ภาษาไทย ==
=== รูปแบบอื่น ===
* {{alt|th|ประดิษฐ}}
=== รากศัพท์ ===
{{bor+|th|sa|प्रतिष्ठ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-ดิด}}
=== คำกริยา ===
{{th-verb}}
# [[ตั้ง]][[ขึ้น]], [[จัด]][[ทำ]]ขึ้น, [[คิด]]ทำขึ้น, [[สร้าง]]ขึ้น, [[แต่ง]]ขึ้น
=== คำคุณศัพท์ ===
{{th-adj|-}}
# [[ที่]]จัดทำขึ้น[[ให้]][[เหมือน]][[ของ]][[จริง]]
#: {{ux|th|ดอกไม้ประดิษฐ์}}
# ที่คิดทำขึ้น[[ไม่]]เหมือน[[ธรรมชาติ]]
#: {{ux|th|ลายประดิษฐ์}}
==== ลูกคำ ====
{{col|th|เบญจางคประดิษฐ์|ยั้งคิดประดิษฐ์รำ|นักประดิษฐ์|สิ่งประดิษฐ์|ปัญญาประดิษฐ์|ภาษาประดิษฐ์|ปืนไทยประดิษฐ์|ฟ้าประดิษฐ์}}
6h526a7i8nuxcgmwixl1pcf9p3lmpv0
5722548
5722547
2026-05-05T10:32:17Z
OctraBot
3198
/* ลูกคำ */
5722548
wikitext
text/x-wiki
{{also/auto}}
== ภาษาไทย ==
=== รูปแบบอื่น ===
* {{alt|th|ประดิษฐ}}
=== รากศัพท์ ===
{{bor+|th|sa|प्रतिष्ठ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-ดิด}}
=== คำกริยา ===
{{th-verb}}
# [[ตั้ง]][[ขึ้น]], [[จัด]][[ทำ]]ขึ้น, [[คิด]]ทำขึ้น, [[สร้าง]]ขึ้น, [[แต่ง]]ขึ้น
=== คำคุณศัพท์ ===
{{th-adj|-}}
# [[ที่]]จัดทำขึ้น[[ให้]][[เหมือน]][[ของ]][[จริง]]
#: {{ux|th|ดอกไม้ประดิษฐ์}}
# ที่คิดทำขึ้น[[ไม่]]เหมือน[[ธรรมชาติ]]
#: {{ux|th|ลายประดิษฐ์}}
==== ลูกคำ ====
{{col|th|เบญจางคประดิษฐ์|ยั้งคิดประดิษฐ์รำ|นักประดิษฐ์|สิ่งประดิษฐ์|ปัญญาประดิษฐ์|ภาษาประดิษฐ์|ปืนไทยประดิษฐ์|ฟ้าประดิษฐ์|บุคลิกประดิษฐ์|รอยประดิษฐ์|วัจนประดิษฐ์|สมองประดิษฐ์}}
obrd9tmc68toe1rcmjlwo2gf97kbccm
ประดิษฐ
0
149920
5722546
5030814
2026-05-05T10:26:32Z
OctraBot
3198
/* คำคุณศัพท์ */
5722546
wikitext
text/x-wiki
{{also/auto}}
== ภาษาไทย ==
=== รากศัพท์ ===
{{bor+|th|sa|प्रतिष्ठ}}
=== การออกเสียง ===
{{th-pron|ปฺระ-ดิด-ถะ-}}
=== คำคุณศัพท์ ===
{{th-adj|-}}
# {{alternative form of|th|ประดิษฐ์}}
==== ลูกคำ ====
{{col|th|ประดิษฐกรรม}}
<!--ประดิษฐาน ไม่ได้มาจาก ประดิษฐ+ฐาน-->
1whnn5fssk07lhz73a3z22sj5ejid5s
हस्तमैथुन
0
211654
5722540
1274888
2026-05-05T04:33:58Z
OctraBot
3198
/* ภาษาฮินดี */ เก็บกวาด
5722540
wikitext
text/x-wiki
== ภาษาฮินดี ==
{{wp|hi:}}
=== รากศัพท์ ===
จาก{{com|hi|हस्त|मैथुन}}
=== การออกเสียง ===
* {{hi-IPA|हस्त-मैथुन}}
=== คำนาม ===
{{hi-noun|m}}
# [[อัตกาม]], [[การ]][[สำเร็จ]][[ความ]][[ใคร่]][[ด้วย]][[ตัว]][[เอง]]
==== การผันรูป ====
{{hi-ndecl|//हस्त्मैथुन<M>}}
==== ลูกคำ ====
* {{l|hi|हस्तमैथुन करना}}
{{topics|hi|Sex}}
iu1i5nm1fk25mjicfflgx9mou9w0lhy
ᨶᩣ᩠ᨿ
0
231259
5722544
5718736
2026-05-05T09:31:23Z
Ai Ku Karng
17824
/* ภาษาคำเมือง */
5722544
wikitext
text/x-wiki
== ภาษาคำเมือง ==
=== รูปแบบอื่น ===
{{nod-alt|~=นาย}}
=== รากศัพท์ ===
ร่วมเชื้อสายกับ{{cog|khb|ᦓᦻ}}, {{cog|th|นาย}}
=== การออกเสียง ===
* {{IPA|nod|/naːj˧˧/|a=เชียงใหม่}}
=== คำนาม ===
{{nod-noun}}
# [[นาย]]
5grkdqvhhn8cdif1c18h7wqbg31p4ax
มอดูล:hi-IPA
828
233725
5722541
1953589
2026-05-05T04:43:32Z
OctraBot
3198
5722541
Scribunto
text/plain
local export = {}
local lang = require("Module:languages").getByCode("hi")
local sc = require("Module:scripts").getByCode("Deva")
local m_IPA = require("Module:IPA")
local m_a = require("Module:accent qualifier")
local m_str_utils = require("Module:string utilities")
local find = m_str_utils.find
local gcodepoint = m_str_utils.gcodepoint
local gmatch = m_str_utils.gmatch
local gsub = m_str_utils.gsub
local u = m_str_utils.char
local correspondences = {
["ṅ"] = "ŋ", ["g"] = "ɡ",
["c"] = "t͡ʃ", ["j"] = "d͡ʒ",
["ṭ"] = "ʈ", ["ḍ"] = "ɖ", ["ṇ"] = "ɳ",
["t"] = "t̪", ["d"] = "d̪",
["y"] = "j", ["r"] = "ɾ", ["v"] = "ʋ",
["ś"] = "ʃ", ["ṣ"] = "ʂ", ["ź"] = "ʒ", ["ž"] = "ʒ", ["h"] = "ɦ",
["ṛ"] = "ɽ", ["ẓ"] = "ʒ", ["ḷ"] = "l", ["ḻ"] = "l", ["ġ"] = "ɣ", ["q"] = "q", ["x"] = "x", ["ṉ"] = "n", ["ṟ"] = "ɾ",
["a"] = "ə", ["ā"] = "ɑː", ["i"] = "ɪ",
["ī"] = "iː", ["o"] = "oː", ["e"] = "eː",
["u"] = "ʊ", ["ū"] = "uː", ["ŏ"] = "ɔ", ["ĕ"] = "æ",
["ẽ"] = "ẽː", ["ũ"] = "ʊ̃", ["õ"] = "õː", ["ã"] = "ə̃", ["ā̃"] = "ɑ̃ː", ["ĩ"] = "ɪ̃", ["ī̃"] = "ĩː",
["ॐ"] = "oːm", ["ḥ"] = "(ɦ)", ["'"] = "(ʔ)",
}
local perso_arabic = {
["x"] = "kh", ["ġ"] = "g", ["q"] = "k", ["ź"] = "z", ["z"] = "j", ["f"] = "ph", ["'"] = "",
}
local urdu = {
["ṣ"] = "ʃ", ["ṇ"] = "n",
}
local deccani = {
["q"] = "x",
}
local lengthen = {
["a"] = "ā", ["i"] = "ī", ["u"] = "ū",
}
local vowels = "aāiīuūoǒŏěĕʊɪɔɔ̃ɛeæãā̃ẽĩī̃õũū̃ː"
local vowel = "[aāiīuūoǒŏěĕʊɪɔɔ̃ɛeæãā̃ẽĩī̃õũū̃]ː?"
local weak_h = "([gjdḍbṛnm])h"
local aspirate = "([kctṭp])"
local syllabify_pattern = "([" .. vowels .. "]̃?)([^" .. vowels .. "%.%-]+)([" .. vowels .. "]̃?)"
local function find_consonants(text)
local current = ""
local cons = {}
for cc in gcodepoint(text .. " ") do
local ch = u(cc)
if find(current .. ch, "^[kgṅcjñṭḍṇtdnpbmyrlvśṣshqxġzžḻṛṟfθṉḥ]$") or find(current .. ch, "^[kgcjṭḍtdpbṛ]h$") then
current = current .. ch
else
table.insert(cons, current)
current = ch
end
end
return cons
end
local function syllabify(text)
for count = 1, 2 do
text = gsub(text, syllabify_pattern, function(a, b, c)
b_set = find_consonants(b)
table.insert(b_set, #b_set > 1 and 2 or 1, ".")
return a .. table.concat(b_set) .. c
end)
text = gsub(text, "(" .. vowel .. ")(?=" .. vowel .. ")", "%1.")
end
for count = 1, 2 do
text = gsub(text, "(" .. vowel .. ")(" .. vowel .. ")", "%1.%2")
end
-- syllabification corrections
-- ([^.]) is added in front, just in case one of the (unlikely) clusters
-- would occur after a blank space (temporarily reformatted as '..')
text = gsub(text, '([^.])%.([kqgcjṭḍtdpb])(h?)([kqgcjṭḍtdpbxġfnɳmsśzź])', '%1%2%3.%4')
text = gsub(text, '([^.])%.([qgcjṭḍtdpb])(h?)ṣ', '%1%2%3.ṣ')
text = gsub(text, '([^.])%.khṣ', '%1kh.ṣ') -- not kṣ/क्ष
text = gsub(text, '([^.])%.([xġfnɳmzźyrlv])([kqgcjṭḍtdpbxġfnɳmsśṣzźh])', '%1%2.%3')
text = gsub(text, '([^.])%.([sśṣ])([gjḍdbġsśṣzźh])', '%1%2.%3')
return text
end
local identical = "knlsfzθ"
for character in gmatch(identical, ".") do
correspondences[character] = character
end
local function transliterate(text)
--return (lang:transliterate(text))
return lang:transliterate(text, nil, "hi-translit-Latn")
end
function export.link(term)
return require("Module:links").full_link{ term = term, lang = lang, sc = sc }
end
function export.toIPA(text, style)
text = gsub(text, '॰', '-')
local translit = text
if lang:findBestScript(text):isTransliterated() then
translit = transliterate(text)
end
if not translit then
error('The term "' .. text .. '" could not be transliterated.')
end
if style == "nonpersianized" then
translit = gsub(translit, "[xġqźzf']", perso_arabic)
end
if style == "dakhini" then
translit = gsub(translit, "[q]", deccani)
end
-- force final schwa for Hindi
translit = gsub(translit, "a~$", "ə")
if style == "desanskritize" then
translit = gsub(translit, "(...)ə$", "%1ɑ(ː)")
translit = gsub(translit, "[ṣṇ]", urdu)
end
-- vowels
translit = gsub(translit, "͠", "̃")
translit = gsub(translit, 'a(̃?)i', 'ɛ%1ː')
translit = gsub(translit, 'a(̃?)u', 'ɔ%1ː')
translit = gsub(translit, "%-$", "")
translit = gsub(translit, "^%-", "")
translit = gsub(translit, "ŕ$", "r")
translit = gsub(translit, "ŕ(" .. vowel .. ")", "r%1")
translit = gsub(translit, "ŕ", "ri")
translit = gsub(translit, 'jñ', 'gy')
translit = gsub(translit, ",", "")
translit = gsub(translit, " ", "..")
translit = syllabify(translit)
translit = gsub(translit, "%.ː", "ː.")
translit = gsub(translit, "%.̃", "̃")
translit = gsub(translit, aspirate .. "h", '%1ʰ')
translit = gsub(translit, weak_h, '%1ʱ')
local result = gsub(translit, ".", correspondences)
-- remove final schwa (Pandey, 2014)
-- actually weaken
result = gsub(result, "(...)ə$", "%1ᵊ")
result = gsub(result, "(...)ə ", "%1ᵊ ")
result = gsub(result, "(...)ə%.?%-", "%1ᵊ-")
-- formatting
result = gsub(result, "%.?%-", ".")
result = gsub(result, "%.%.", " ")
result = gsub(result, "ː̃", "̃ː")
result = gsub(result, "ː%.̃", "̃ː.")
result = gsub(result, "%.$", "")
-- ñ
result = gsub(result, "ñ", "n")
-- i and u lengthening
result = gsub(result, "ʊ(̃?)(ɦ?)$", "u%1ː%2")
result = gsub(result, "ɪ(̃?)(ɦ?)$", "i%1ː%2")
-- deaffricate first affricate in geminates
result = gsub(result, "t͡ʃ(%.?)t͡ʃ", "t̪%1t͡ʃ")
result = gsub(result, "d͡ʒ(%.?)d͡ʒ", "d̪%1d͡ʒ")
-- silent h in 'lh-', 'vh-' (Ohala 1983, p.45)
result = gsub(result, "^([lʋ])ɦ", "%1")
result = gsub(result, "([ .])([lʋ])ɦ", "%1%2")
result = gsub(result, "ɛː(%.?)j", function(a)
local res = "ə̯i"
res = res .. a .. "j"
return res
end)
result = gsub(result, "ɔː(%.?)ʋ", function(a)
local res = "ə̯u"
res = res .. a .. "ʋ"
return res
end)
return result
end
function export.narrow_IPA(ipa)
-- what /ɑ/ and /ə/ really are
ipa = gsub(ipa, 'ɑ', 'ä')
ipa = gsub(ipa, 'ə', 'ɐ')
-- uvular /x/, /ɣ/ ??
-- ipa = gsub(ipa, 'x', 'χ')
-- ipa = gsub(ipa, 'ɣ', 'ʁ')
-- retroflex s rules
ipa = gsub(ipa, 'ʂ(%.?)([^ʈɖ.])', 'ʃ%1%2')
ipa = gsub(ipa, 'ʂ$', 'ʃ')
-- nasal allophones
ipa = gsub(ipa, 'ŋ(%.?)([qχʁ])', 'ɴ%1%2')
ipa = gsub(ipa, 'n%.j', 'ɲ.j')
ipa = gsub(ipa, '[nɳ](%.?)ʃ', 'ɲ%1ʃ') -- this nasal is likely more front than before /j/, but not doing a too narrow transcription seems preferable
ipa = gsub(ipa, 'n(%.?)([td])̪', 'n̪%1%2̪')
ipa = gsub(ipa, 'm(%.?)f', 'ɱ%1f')
-- nasals induce nasalization
ipa = gsub(ipa, '([ɐäɪiʊueɛoɔæ])(ː?)([nɳɲŋɴmɱ])', '%1̃%2%3')
-- cc, jj
ipa = gsub(ipa, 't̪(%.?)t͡ʃ', 't̚%1t͡ʃ')
ipa = gsub(ipa, 'd̪(%.?)d͡ʒ', 'd̚%1d͡ʒ')
-- syllable boundary consonants
ipa = gsub(ipa, '([kɡ])%.([kɡ])', '%1̚.%2')
ipa = gsub(ipa, '([ʈɖ])%.([ʈɖ])', '%1̚.%2')
ipa = gsub(ipa, '([td]̪?)%.([tdn])', '%1̚.%2')
ipa = gsub(ipa, '([pb])%.([pb])', '%1̚.%2')
-- aspiration rules
ipa = gsub(ipa, 'ɐɦ([%. ])', 'ɛɦ%1')
ipa = gsub(ipa, 'ɐɦ$', 'ɛɦ')
ipa = gsub(ipa, 'ɐ%.ɦɐ', 'ɛ.ɦɛ')
ipa = gsub(ipa, 'ɐ%(ɦ%)', 'ɛ(ɦ)')
ipa = gsub(ipa, 'ʊɦ%.', 'ɔɦ.')
ipa = gsub(ipa, 'ʊ%.ɦɐ', 'ɔ.ɦɔ')
ipa = gsub(ipa, 'ɐ%.ɦʊ', 'ɔ.ɦɔ')
ipa = gsub(ipa, '([ɐäɪiʊueɛoɔæ])(̃?)(ː?)ɦ', '%1%2%3ʱ')
-- v/w
ipa = gsub(ipa, '([kɡŋtdɲʈɖɳnpbm]̪?%.?)ʋ', '%1w')
-- geminate /ɾ/ is trill
ipa = gsub(ipa, "ɾ%.ɾ", "r.r")
-- for onomatopeic words ending on -र्र
ipa = gsub(ipa, "ɾɾ", "rː")
-- final geminates often pronounced as singletons
ipa = gsub(ipa, "([kɡʈɖɳtdnpbml]̪?)%1", "%1(ː)")
-- final cc, jj
ipa = gsub(ipa, "t̚t͡ʃ", "(t̚)t͡ʃ")
ipa = gsub(ipa, "d̚d͡ʒ", "(d̚)d͡ʒ")
ipa = gsub(ipa, "ɪ%.j", "i.j")
ipa = gsub(ipa, " ", "‿")
return ipa
end
function export.make(frame)
local args = frame:getParent().args
local pagetitle = mw.loadData("Module:headword/data").pagename
local p, results = {}, {}, {}
if args[1] then
for index, item in ipairs(args) do
table.insert(p, (item ~= "") and item or nil)
end
else
p = { pagetitle }
end
for _, Hindi in ipairs(p) do
local persianized = export.toIPA(Hindi, "persianized")
local nonpersianized = export.toIPA(Hindi, "nonpersianized")
table.insert(results, { pron = "/" .. persianized .. "/" })
local narrow = export.narrow_IPA(persianized)
if narrow ~= persianized then table.insert(results, { pron = "[" .. narrow .. "]" }) end
if persianized ~= nonpersianized then
table.insert(results, { pron = "/" .. nonpersianized .. "/" })
local narrow = export.narrow_IPA(nonpersianized)
if narrow ~= nonpersianized then table.insert(results, { pron = "[" .. narrow .. "]" }) end
end
end
return m_a.format_qualifiers(lang, {"ฮินดีมาตรฐาน"}) .. " " .. m_IPA.format_IPA_full { lang = lang, items = results }
end
function export.make_ur(frame)
local args = frame:getParent().args
local pagetitle = mw.loadData("Module:headword/data").pagename
local lang = require("Module:languages").getByCode("ur")
local sc = require("Module:scripts").getByCode("ur-Arab")
local p, results = {}, {}, {}
if args[1] then
for index, item in ipairs(args) do
table.insert(p, (item ~= "") and item or nil)
end
else
error("No transliterations given.")
end
for _, Urdu in ipairs(p) do
Urdu = lang:transliterate(Urdu) or Urdu
local desanskritize = export.toIPA(Urdu, "desanskritize")
table.insert(results, { pron = "/" .. desanskritize .. "/" })
end
return m_a.format_qualifiers(lang, {"อูรดู"}) .. ' ' .. m_IPA.format_IPA_full { lang = lang, items = results }
end
function export.make_deccani(frame)
local args = frame:getParent().args
local pagetitle = mw.loadData("Module:headword/data").pagename
local lang = require("Module:languages").getByCode("ur")
local sc = require("Module:scripts").getByCode("ur-Arab")
local p, results = {}, {}, {}
if args[1] then
for index, item in ipairs(args) do
table.insert(p, (item ~= "") and item or nil)
end
else
error("No transliterations given.")
end
for _, Urdu in ipairs(p) do
local dakhini = export.toIPA(Urdu, "dakhini")
table.insert(results, { pron = "/" .. dakhini .. "/" })
end
return m_a.format_qualifiers(lang, {"ทักขินี"}) .. ' ' .. m_IPA.format_IPA_full { lang = lang, items = results }
end
return export
h6aym55fdteb96tf2xwbi5faxl40qp4
มอดูล:labels/data/regional
828
261903
5722532
4733497
2026-05-05T03:57:29Z
OctraBot
3198
5722532
Scribunto
text/plain
local labels = {}
------------------------------------------ Generic ------------------------------------------
--not sure where to put this
labels["คลาสสิก"] = {
aliases = {"Classical", "classical"},
-- "ca", "fa", "id", la", "zh" handled in lang-specific module
langs = {"ar", "az", "ja", "jv", "kum", "ms", "quc", "sa", "tl"},
special_display = "[[<canonical_name>คลาสสิก]]",
regional_categories = true,
}
labels["จารึก"] = {
aliases = {"Epigraphic", "epigraphic"},
langs = {"grc", "pgd", "pra", "sa"},
special_display = "[[w:จารึกศาสตร์|<canonical_name>จารึก]]",
regional_categories = true,
}
labels["ภูมิภาค"] = {
aliases = {"เฉพาะภูมิภาค", "ภาษาเฉพาะภูมิภาค", "regional", "regionally"}, -- ภาษาถิ่น ซ้ำกับ dialect
display = "ภาษาเฉพาะภูมิภาค",
regional_categories = true,
}
------------------------------------------ Places ------------------------------------------
labels["Anatri"] = {
aliases = {"Lower Chuvash"},
langs = {"cv"}, -- e.g. вот "fire" vs the Upper Chuvash / literary standard вут
Wikipedia = true,
regional_categories = true,
}
labels["ออสเตรเลีย"] = {
aliases = {"AU", "Australian", "Australia"},
-- "de", "en", "mt", "zh" handled in lang-specific modules
langs = {"el", "it", "ko", "ru"},
Wikipedia = true,
regional_categories = true,
}
labels["Black Isle"] = {
langs = {"sco"}, -- conceivably also en, gd, perhaps enm, but -sche could only find sco
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Bogor"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
labels["บราซิล"] = {
aliases = {"Brazilian", "Brazil"},
-- "pt" handled in lang-specific module
langs = {"ja", "mch", "vec", "yi"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Brebes"] = {
aliases = {"Brebian"},
langs = {},
Wikipedia = "Brebes Regency",
regional_categories = true,
}
labels["Britain"] = {
aliases = {"Brit", "British", "Great Britain"},
-- "en", "zh" handled in lang-specific module
langs = {"bn", "ur", "vi"},
Wikipedia = "Great Britain",
regional_categories = "British",
}
labels["Bukovina"] = {
aliases = {"Bucovina", "Bukovinian", "Bukowina"},
langs = {"pl", "ro", "uk"},
Wikipedia = true,
regional_categories = "Bukovinian",
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Burundi"] = {
aliases = {"Burundian"},
langs = {},
Wikipedia = true,
regional_categories = "Burundian",
}
labels["แคนาดา"] = {
aliases = {"Canadian", "Canada"},
-- "en", "fr", "zh" handled in lang-specific module
langs = {"gd", "haa", "is", "ko", "ru", "tli", "uk", "vi"},
Wikipedia = true,
regional_categories = true,
}
labels["จีน"] = {
aliases = {"China"},
-- "en", "ko" handled in lang-specific module
langs = {"ja", "khb", "kk", "mhx", "mn", "ug"},
Wikipedia = true,
regional_categories = true,
}
labels["Congo"] = {
aliases = {"Democratic Republic of the Congo", "Democratic Republic of Congo", "DR Congo", "Congo-Kinshasa", "Republic of the Congo", "Republic of Congo", "Congo-Brazzaville", "Congolese"}, -- these could be split if need be
-- "fr" handled in lang-specific module
langs = {"avu", "yom"},
Wikipedia = true,
regional_categories = "Congolese",
}
labels["ไซปรัส"] = {
aliases = {"cypriot", "Cypriot", "Cyprus"},
-- "tr" handled in lang-specific module
langs = {"ar", "el"},
Wikipedia = true,
regional_categories = true,
}
labels["Dobruja"] = {
aliases = {"Dobrogea", "Dobrujan"},
langs = {"crh", "ro"},
Wikipedia = true,
regional_categories = "Dobrujan",
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Durban"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
labels["ยุโรป"] = {
aliases = {"Europe", "European"},
-- "en", "es", "fr", "pt" handled in lang-specific module
langs = {"ur"},
Wikipedia = true,
regional_categories = true,
}
labels["ฝรั่งเศส"] = {
aliases = {"French", "French"},
-- "fr", "zh" handled in lang-specific module
langs = {"la", "lad", "nrf", "vi", "yi"},
Wikipedia = true,
regional_categories = true,
}
labels["อินเดีย"] = {
aliases = {"Indian", "India"},
-- "en", "pa", "pt" handled in lang-specific module
langs = {"bn", "dv", "fa", "ml", "ta", "ur"},
Wikipedia = true,
regional_categories = true,
}
labels["อินโดนีเซีย"] = {
aliases = {"Indonesian", "Indonesia"},
-- "en", "zh" handled in lang-specific module
langs = {"id", "jv", "ms", "nl"},
Wikipedia = true,
regional_categories = true,
}
labels["อิสราเอล"] = {
aliases = {"Israeli", "Israel"},
-- "en" handled in lang-specific module
langs = {"ajp", "ar", "he", "ru", "yi"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Kalix"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
-- FIXME: Move to Uyghur label data module
labels["คาซักสถาน"] = {
aliases = {"Kazakhstani", "Kazakh", "Kazakhstan"},
langs = {"ug"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Kemaliye"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Kitti"] = {
langs = {},
Wikipedia = "Kitti, Federated States of Micronesia",
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Kukkuzi"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Lucknow"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Luleå"] = {
aliases = {"Lulea"},
langs = {},
Wikipedia = true,
regional_categories = true,
}
labels["Lviv"] = {
aliases = {"Lvov", "Lwow", "Lwów"},
langs = {"pl", "uk"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Muş"] = {
aliases = {"Mush"},
langs = {},
Wikipedia = true,
regional_categories = true,
}
labels["พม่า"] = {
aliases = {"เมียนมา", "Myanmarese", "Burma", "Burmese", "Myanmar"},
-- "en", "my", "zh" handled in lang-specific module; FIXME: move ksw and mnw to lang-specific modules
langs = {"ksw", "mnw"},
Wikipedia = true,
regional_categories = true,
}
labels["ไนจีเรีย"] = {
aliases = {"Nigerian", "Nigeria"},
-- "en" handled in lang-specific module
langs = {"ar", "ff", "guw", "ha", "yo"},
Wikipedia = true,
regional_categories = true,
}
labels["ปาเลสไตน์"] = {
aliases = {"Palestinian", "Palestine"},
-- "en" handled in lang-specific module
langs = {"ajp", "ar", "arc"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Priangan"] = {
langs = {},
Wikipedia = "Parahyangan",
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Rome"] = {
aliases = {"Roma", "Romano"},
langs = {},
Wikipedia = true,
regional_categories = "Roman",
}
labels["Scania"] = {
aliases = {"Scanian", "Skanian", "Skåne"},
langs = {"gmq-oda", "sv"},
Wikipedia = true,
regional_categories = "Scanian",
}
-- Silesia German, Silesia Polish; for differentiation between sli "Silesian East Central German"
-- don't add Silesian as alias
labels["Silesia"] = {
langs = {"de", "pl"},
Wikipedia = true,
}
labels["เซาท์แอฟริกา"] = {
aliases = {"แอฟริกาใต้", "South African", "South Africa"},
-- "de", "en", "pt" handled in lang-specific module
langs = {"af", "nl", "st", "te", "yi", "zu"},
Wikipedia = true,
regional_categories = true,
}
labels["สเปน"] = {
aliases = {"Spanish", "ES", "Spain"},
-- "ca", "es" handled in lang-specific module
langs = {"la"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Surati"] = {
langs = {},
Wikipedia = "Surat district",
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Surgut"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
labels["Suriname"] = {
aliases = {"Surinamese"},
langs = {"car", "hns", "jv", "nl"},
Wikipedia = true,
regional_categories = "Surinamese",
}
labels["ไทย"] = {
aliases = {"Thai", "Thailand"},
-- "en", "zh" handled in lang-specific module
langs = {"khb", "mnw", "th"},
Wikipedia = true,
regional_categories = true,
}
labels["UK"] = {
aliases = {"United Kingdom"},
-- "en", "zh" handled in lang-specific module
langs = {"bn", "ur", "vi"},
Wikipedia = "United Kingdom",
regional_categories = "British",
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Old Ukrainian"] = {
langs = {},
Wikipedia = true,
plain_categories = true,
}
labels["สหรัฐอเมริกา"] = {
aliases = {"สหรัฐ", "อเมริกา", "U.S.", "United States", "United States of America", "USA", "America", "American", "US"}, -- America/American: should these be aliases of 'North America'?
-- DO NOT include "es" here, otherwise {{lb|es|American}} will categorize in [[:Category:American Spanish]]; see [[:Category:United States Spanish]].
-- "de", "en", "pt", "zh" handled in lang-specific module
langs = {"hi", "is", "it", "ja", "ko", "nl", "ru", "tli", "ur", "vi", "yi"},
Wikipedia = "United States",
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Vilhelmina"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
labels["Viryal"] = {
aliases = {"Upper Chuvash"},
langs = {"cv"},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Wallonia"] = {
aliases = {"Wallonian"},
langs = {},
Wikipedia = true,
regional_categories = "Wallonian",
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Special Region of Yogyakarta"] = {
aliases = {"SR Yogyakarta"},
langs = {},
Wikipedia = true,
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Zakarpattia"] = {
langs = {},
Wikipedia = "Zakarpattia Oblast",
regional_categories = true,
}
-- WARNING: No existing languages or categories associated with label; add to `langs` as needed
labels["Zululand"] = {
langs = {},
Wikipedia = true,
regional_categories = true,
}
------------------------------------------ Chinese romanizations ------------------------------------------
labels["ฮั่นยฺหวี่พินอิน"] = {
aliases = {"พินอิน", "Hanyu pinyin", "Pinyin", "pinyin", "Hanyu Pinyin"},
Wikidata = "Q42222",
plain_categories = true,
}
labels["Postal Romanization"] = {
aliases = {"Postal romanization", "postal romanization", "Postal", "postal"},
Wikidata = "Q151868",
plain_categories = true,
}
labels["Tongyong Pinyin"] = {
aliases = {"Tongyong pinyin"},
Wikidata = "Q700739",
plain_categories = true,
}
labels["Wade–Giles"] = {
aliases = {"Wade-Giles"},
Wikidata = "Q208442",
plain_categories = true,
}
return require("Module:labels").finalize_data(labels)
4cp644sug0wmknndzf1njiqxhehbi48
มอดูล:hi-noun
828
287870
5722536
2765144
2026-05-05T04:09:15Z
OctraBot
3198
5722536
Scribunto
text/plain
local export = {}
--[=[
Authorship: Ben Wing <benwing2>
]=]
--[=[
TERMINOLOGY:
-- "slot" = A particular combination of case/number.
Example slot names for nouns are "dir_s" (direct singular) and
"voc_p" (vocative plural). Each slot is filled with zero or more forms.
-- "form" = The declined Hindi form representing the value of a given slot.
-- "lemma" = The dictionary form of a given Hindi term. Generally the direct
masculine singular, but may occasionally be another form if the direct
masculine singular is missing.
]=]
local lang = require("Module:languages").getByCode("hi")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_string_utilities = require("Module:string utilities")
local iut = require("Module:inflection utilities")
local put = require("Module:parse utilities")
local m_para = require("Module:parameters")
local com = require("Module:hi-common")
local u = require("Module:string/char")
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rgmatch = mw.ustring.gmatch
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local usub = mw.ustring.sub
local uupper = mw.ustring.upper
local ulower = mw.ustring.lower
-- vowel diacritics; don't display nicely on their own
local M = u(0x0901)
local N = u(0x0902)
local MN_c = "[" .. M .. N .. "]"
local H = u(0x0903)
local AA = u(0x093e)
local E = u(0x0947)
local EN = E .. N
local I = u(0x093f)
local II = u(0x0940)
local O = u(0x094b)
local ON = O .. N
local U = u(0x0941)
local UU = u(0x0942)
local R = u(0x0943)
local VIRAMA = u(0x094d)
local TILDE = u(0x0303)
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
local retval, nsubs = rsubn(term, foo, bar)
return retval, nsubs > 0
end
local noun_slots = {
dir_s = "dir|s",
obl_s = "obl|s",
voc_s = "voc|s",
dir_p = "dir|p",
obl_p = "obl|p",
voc_p = "voc|p",
}
local noun_slots_with_linked = m_table.shallowCopy(noun_slots)
noun_slots_with_linked["dir_s_linked"] = "dir|s"
noun_slots_with_linked["dir_p_linked"] = "dir|p"
local input_params_to_slots_both = {
[1] = "dir_s",
[2] = "dir_p",
[3] = "obl_s",
[4] = "obl_p",
[5] = "voc_s",
[6] = "voc_p",
}
local input_params_to_slots_sg = {
[1] = "dir_s",
[2] = "obl_s",
[3] = "voc_s",
}
local input_params_to_slots_pl = {
[1] = "dir_p",
[2] = "obl_p",
[3] = "voc_p",
}
local cases = {
dir = true,
obl = true,
voc = true,
}
local function skip_slot(number, slot)
return number == "sg" and rfind(slot, "_p$") or
number == "pl" and rfind(slot, "_s$")
end
local function add(base, stem, translit_stem, slot, ending, footnotes)
if skip_slot(base.number, slot) then
return
end
com.add_form(base, stem, translit_stem, slot, ending, footnotes)
end
local function process_slot_overrides(base)
for slot, overrides in pairs(base.overrides) do
if skip_slot(base.number, slot) then
error("Override specified for invalid slot '" .. slot .. "' due to '" .. base.number .. "' number restriction")
end
base.forms[slot] = nil
for _, override in ipairs(overrides) do
for _, value in ipairs(override.values) do
local form = value.form
local tr = com.transliterate_respelling(value.phon_form)
local combined_notes = iut.combine_footnotes(base.footnotes, value.footnotes)
assert(override.full)
if form ~= "" then
iut.insert_form(base.forms, slot, {form = form, translit = tr, footnotes = combined_notes})
end
end
end
end
end
local function add_decl(base, stem, translit_stem, dir_s, obl_s, voc_s, dir_p, obl_p, voc_p,
footnotes
)
if not stem then
stem = base.lemma
translit_stem = base.lemma_translit
end
local plstem, pl_translit_stem = stem, translit_stem
if base.plstem then
plstem = base.plstem
pl_translit_stem = base.pl_translit_stem
end
add(base, stem, translit_stem, "dir_s", dir_s, footnotes)
add(base, stem, translit_stem, "obl_s", obl_s, footnotes)
add(base, stem, translit_stem, "voc_s", voc_s, footnotes)
add(base, plstem, pl_translit_stem, "dir_p", dir_p, footnotes)
add(base, plstem, pl_translit_stem, "obl_p", obl_p, footnotes)
add(base, plstem, pl_translit_stem, "voc_p", voc_p, footnotes)
end
local function handle_derived_slots_and_overrides(base)
process_slot_overrides(base)
-- Compute linked versions of potential lemma slots, for use in {{hi-noun}}.
-- We substitute the original lemma (before removing links) for forms that
-- are the same as the lemma, if the original lemma has links.
for _, slot in ipairs({"dir_s", "dir_p"}) do
iut.insert_forms(base.forms, slot .. "_linked", iut.map_forms(base.forms[slot], function(form)
if form == base.orig_lemma_no_links and rfind(base.orig_lemma, "%[%[") then
return base.orig_lemma
else
return form
end
end))
end
end
local function fetch_final_mn(base)
local mn = rmatch(base.lemma, "(" .. MN_c .. ")$")
if not mn then
error("Internal error: Lemma " .. base.lemma .. " should end in nasal vowel")
end
return mn
end
local decls = {}
local declprops = {}
decls["c-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", ON, O)
end
declprops["c-m"] = {
desc = "masc cons-stem",
cat = "masculine consonant-stem ~",
}
decls["c-f"] = function(base)
add_decl(base, nil, nil, "", "", "", EN, ON, O)
end
declprops["c-f"] = {
desc = "fem cons-stem",
cat = "feminine consonant-stem ~",
}
decls["ā-m"] = function(base)
if rfind(base.lemma, "या$") then
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "ए", "ए", "ए", "यों", "यो")
add_decl(base, stem, translit_stem, nil, "ये", "ये", "ये")
else
local stem, translit_stem = com.strip_ending(base, AA)
add_decl(base, stem, translit_stem, AA, E, E, E, ON, O)
end
end
-- E.g. तेंदुआ "leopard"
decls["ind-ā-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "आ")
add_decl(base, stem, translit_stem, "आ", "ए", "ए", "ए", "ओं", "ओ")
end
decls["unmarked-ā-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
declprops["unmarked-ā-m"] = {
desc = "masc unmarked ā-stem",
cat = "masculine unmarked ā-stem ~",
}
-- No need for ind-unmarked-ā-m because declension is "unmarked", i.e. all endings
-- are added after the vowel.
-- E.g. रेस्तराँ "restaurant"
decls["unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, AA .. "ओं", AA .. "ओं")
end
declprops["unmarked-ān-m"] = {
desc = "masc unmarked ā̃-stem",
cat = "masculine unmarked ā̃-stem ~",
}
decls["ind-unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "आओं", "आओं")
end
declprops["ind-unmarked-ān-m"] = {
desc = "masc ind unmarked ā̃-stem",
cat = "masculine independent unmarked ā̃-stem ~",
}
-- E.g. ख़ानसामाँ "butler, cook"
decls["ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, EN, EN, EN, ON, ON)
end
-- E.g. कुआँ "well"
decls["ind-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, "एँ", "एँ", "एँ", "ओं", "ओं")
end
decls["ā-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
-- No need for ind-ā-f because declension is "unmarked", i.e. all endings
-- are added after the vowel.
decls["ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, AA .. "एँ", AA .. "ओं", AA .. "ओं")
end
decls["ind-ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "आएँ", "आओं", "आओं")
end
decls["i-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "यों", "यो")
end
decls["i-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "याँ", "यों", "यो")
end
-- E.g. प्रधान मंत्री "prime minister"
decls["ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, II, I .. "यों", I .. "यो")
end
-- E.g. भाई "brother"
decls["ind-ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "ई", "इयों", "इयो")
end
decls["īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, II .. N, I .. "यों", I .. "यों")
end
decls["ind-īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "ईं", "इयों", "इयों")
end
decls["ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, I .. "याँ", I .. "यों", I .. "यो")
end
-- E.g. दवाई "medicine", डोई "wooden ladle", तेंदुई "female leopard", मिठाई "sweet, dessert"
decls["ind-ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "इयाँ", "इयों", "इयो")
end
decls["īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, I .. "याँ", I .. "यों", I .. "यों")
end
decls["ind-īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "इयाँ", "इयों", "इयों")
end
decls["iyā-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "या", "या", "याँ", "यों", "यो")
end
decls["iyān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "या" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "यों", "यों")
end
decls["o-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, O)
add_decl(base, stem, translit_stem, O, O, O, O, ON, O)
end
decls["on-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, ON)
add_decl(base, stem, translit_stem, ON, ON, ON, ON, ON, ON)
end
decls["u-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
decls["u-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
decls["ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, UU, U .. "ओं", U .. "ओ")
end
decls["ind-ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "ऊ", "उओं", "उओ")
end
decls["ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, U .. "ओं", U .. "ओं")
end
decls["ind-ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "उओं", "उओं")
end
decls["ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, U .. "एँ", U .. "ओं", U .. "ओ")
end
decls["ind-ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "उएँ", "उओं", "उओ")
end
-- E.g. जूँ "louse"
decls["ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, U .. "एँ", U .. "ओं", U .. "ओं")
end
decls["ind-ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "उएँ", "उओं", "उओं")
end
decls["r-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
-- E.g. प्रातः "morning"
decls["h-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, H)
add_decl(base, stem, translit_stem, H, H, H, H, ON, O)
end
decls["indecl"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "", "")
end
declprops["indecl"] = {
desc = "indecl",
cat = "indeclinable ~",
}
decls["adj"] = function(base, stress)
local adj_alternant_multiword_spec = require("Module:hi-adjective").do_generate_forms(
{base.lemma .. "//" .. base.lemma_translit}
)
local function copy(from_slot, to_slot)
base.forms[to_slot] = adj_alternant_multiword_spec.forms[from_slot]
end
if base.number ~= "pl" then
copy("dir_m_s", "dir_s")
copy("obl_m_s", "obl_s")
copy("voc_m_s", "voc_s")
end
if base.number ~= "sg" then
copy("dir_m_p", "dir_p")
copy("obl_m_p", "obl_p")
copy("voc_m_p", "voc_p")
end
end
declprops["adj"] = {
desc = "adj",
cat = "adjectival ~",
}
local function fetch_footnotes(separated_group)
local footnotes
for j = 2, #separated_group - 1, 2 do
if separated_group[j + 1] ~= "" then
error("Extraneous text after bracketed footnotes: '" .. table.concat(separated_group) .. "'")
end
if not footnotes then
footnotes = {}
end
table.insert(footnotes, separated_group[j])
end
return footnotes
end
--[=[
Parse a single override spec and return two values: the slot the override applies to,
and an object describing the override spec. The input is actually a list where the footnotes have been separated out. For example, given the spec 'oblpl:हज़ारों:हज़ारहा[rare]',
the input will be a list {"oblpl:हज़ारों:हज़ारहा", "[rare]", ""}. The object returned for
this example looks like this:
{
full = true,
values = {
{
form = "हज़ारों"
},
{
form = "हज़ारहा",
footnotes = {"[rare]"}
}
}
}
]=]
local function parse_override(segments)
local retval = {values = {}}
local part = segments[1]
local offset = 4
local case = usub(part, 1, 3)
if cases[case] then
-- ok
else
error("Internal error: unrecognized case in override: '" .. table.concat(segments) .. "'")
end
local rest = usub(part, offset)
local slot
if rfind(rest, "^pl") then
rest = rsub(rest, "^pl", "")
slot = case .. "_p"
else
slot = case .. "_s"
end
if rfind(rest, "^:") then
retval.full = true
rest = rsub(rest, "^:", "")
else
error("Suffix overrides not currently supported: " .. part)
end
segments[1] = rest
local colon_separated_groups = put.split_alternating_runs(segments, ":")
for i, colon_separated_group in ipairs(colon_separated_groups) do
local value = {}
local form = colon_separated_group[1]
if form == "" then
error("Use - to indicate an empty ending for slot '" .. slot .. "': '" .. table.concat(segments .. "'"))
elseif form == "-" then
value.form = ""
else
value.form, value.phon_form = com.split_term_respelling(form)
end
value.footnotes = fetch_footnotes(colon_separated_group)
table.insert(retval.values, value)
end
return slot, retval
end
--[=[
Parse an indicator spec (text consisting of angle brackets and zero or more
dot-separated indicators within them). Return value is an object of the form
{
overrides = {
SLOT = {OVERRIDE, OVERRIDE, ...}, -- as returned by parse_override()
...
},
forms = {}, -- forms for a single spec alternant; see `forms` below
footnotes = {"FOOTNOTE", "FOOTNOTE", ...}, -- may be missing
explicit_gender = "GENDER", -- "M", "F"; may be missing
number = "NUMBER", -- "sg", "pl"; may be missing
adj = true, -- may be missing
indecl = true, -- may be missing
unmarked = true, -- may be missing
iya = true, -- may be missing
plstem = "PLSTEM", -- may be missing
pl_phon_stem = "PLSTEM-PHONETIC-RESPELLING", -- as specified by the user; may be missing
pl_translit_stem = "PLSTEM-TRANSLIT", -- translit of pl_phon_stem (if present) or plstem; may be missing
-- The following additional fields are added by other functions:
orig_lemma = "ORIGINAL-LEMMA", -- as given by the user or taken from pagename
orig_lemma_no_links = "ORIGINAL-LEMMA-NO-LINKS", -- links removed
lemma = "LEMMA", -- `orig_lemma_no_links`, converted to singular form if plural
phon_lemma = "LEMMA-PHONETIC-RESPELLING", -- as specified by the user; may be missing
lemma_translit = "LEMMA-TRANSLIT", -- translit of phon_lemma (if present) or lemma
forms = {
SLOT = {
{
form = "FORM",
footnotes = {"FOOTNOTE", "FOOTNOTE", ...} -- may be missing
},
...
},
...
},
decl = "DECL", -- declension, e.g. "ind-ūn-f"
}
]=]
local function parse_indicator_spec(angle_bracket_spec)
local inside = rmatch(angle_bracket_spec, "^<(.*)>$")
assert(inside)
local base = {overrides = {}, forms = {}}
if inside ~= "" then
local segments = put.parse_balanced_segment_run(inside, "[", "]")
local dot_separated_groups = put.split_alternating_runs(segments, "%.")
for i, dot_separated_group in ipairs(dot_separated_groups) do
local part = dot_separated_group[1]
local case_prefix = usub(part, 1, 3)
if cases[case_prefix] then
local slot, override = parse_override(dot_separated_group)
if base.overrides[slot] then
table.insert(base.overrides[slot], override)
else
base.overrides[slot] = {override}
end
elseif part == "" then
if #dot_separated_group == 1 then
error("Blank indicator: '" .. inside .. "'")
end
base.footnotes = fetch_footnotes(dot_separated_group)
elseif #dot_separated_group > 1 then
error("Footnotes only allowed with slot overrides or by themselves: '" .. table.concat(dot_separated_group) .. "'")
elseif part == "M" or part == "F" then
if base.explicit_gender then
error("Can't specify gender twice: '" .. inside .. "'")
end
base.explicit_gender = part
elseif part == "sg" or part == "pl" then
if base.number then
error("Can't specify number twice: '" .. inside .. "'")
end
base.number = part
elseif part == "+" then
if base.adj then
error("Can't specify '+' twice: '" .. inside .. "'")
end
base.adj = true
elseif part == "$" then
if base.indecl then
error("Can't specify '$' twice: '" .. inside .. "'")
end
base.indecl = true
elseif part == "unmarked" then
if base.unmarked then
error("Can't specify 'unmarked' twice: '" .. inside .. "'")
end
base.unmarked = true
elseif part == "iyā" then
if base.iya then
error("Can't specify 'iyā' twice: '" .. inside .. "'")
end
base.iya = true
elseif rfind(part, "^plstem:") then
if base.plstem then
error("Can't specify plural stem twice: '" .. inside .. "'")
end
base.plstem, base.pl_phon_stem = com.split_term_respelling(rsub(part, "^plstem:", ""))
base.pl_translit_stem = com.transliterate_respelling(base.pl_phon_stem) or (lang:transliterate(base.plstem))
else
error("Unrecognized indicator '" .. part .. "': '" .. inside .. "'")
end
end
end
return base
end
local function set_defaults_and_check_bad_indicators(base)
-- Set default values.
if not base.adj and not base.indecl then
base.number = base.number or "both"
end
base.gender = base.explicit_gender
if base.iya then
if base.adj then
error("Can't specify both '+' and 'iya'")
end
if base.gender == "M" then
error("Can't specify M gender with 'iyā' indicator")
end
if not rfind(base.lemma, I .. "याँ?$") and not rfind(base.lemma, "-इयाँ?$") then
error("With 'iyā' indicator, lemma must end in " .. I .. "या or " .. I .. "याँ: " .. base.lemma)
end
base.gender = "F"
end
if base.unmarked then
if base.adj then
error("Can't specify both '+' and 'unmarked'")
end
if base.iya then
error("Can't specify both 'iya' and 'unmarked'")
end
if base.gender == "F" then
error("Can't specify F gender with 'unmarked' indicator")
end
base.gender = "M"
end
if rfind(base.lemma, "[" .. O .. H .. R .. "]$") then
if base.gender == "F" then
error("Can't specify F gender with lemma ending in " .. O .. ", " .. H .. " or " .. R .. ": " .. base.lemma)
end
base.gender = "M"
end
if not base.gender and not base.adj and not base.indecl then
error("Unless lemma is in " .. O .. ", " .. H .. " or " .. R .. " or 'iya', 'unmarked' or '$' specified, gender must be given: " .. base.lemma)
end
if base.adj and base.indecl then
error("Can't specify both '+' and '$' on the same lemma " .. base.lemma)
end
end
-- For a plural-only lemma, synthesize a likely singular lemma. It doesn't have to be
-- theoretically correct as long as it generates all the correct plural forms.
local function synthesize_singular_lemma(base)
if not base.gender then
error("For plural-only lemma, need to specify the gender: '" .. base.lemma .. "'")
end
if base.gender == "M" then
if rfind(base.lemma, E .. "$") then
local stem, translit_stem = com.strip_ending(base, E)
base.lemma = stem .. AA
base.lemma_translit = translit_stem .. "ā"
return
end
if rfind(base.lemma, "ए$") then
-- FIXME, what about -iyā -> -ie?
local stem, translit_stem = com.strip_ending(base, "ए")
base.lemma = stem .. "अ"
base.lemma_translit = translit_stem .. "ā"
return
end
local ending = rmatch(base.lemma, "(" .. E .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. AA .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. "अ" .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
-- Otherwise, singular same as plural and lemma is already correct.
else
assert(base.gender == "F")
local function add_dir_p_override()
-- Add an override to force the direct plural to match. This is needed below
-- in case the lemma ends in anusvara instead of chandrabindu (because the
-- declension functions generate a direct plural with chandrabindu) and also
-- when the direct plural is the same as the singular.
if not base.overrides.dir_p then
base.overrides.dir_p = {}
end
table.insert(base.overrides.dir_p, {full = true, values = {{form = base.lemma, phon_form = base.lemma_translit}}})
end
local ending = rmatch(base.lemma, "(" .. EN .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(या " .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
-- This may or may not produce the "right" singular but regardless,
-- the plural will be correct, which is all that matters.
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
-- We seem to have an endingless plural, e.g. औलाद. Add an override to the dir_p slot
-- to force this form.
add_dir_p_override()
end
end
-- For an adjectival lemma, synthesize the masc singular form.
local function synthesize_adj_lemma(base)
if not rfind(base.lemma, "[अ" .. AA .. "]" .. MN_c .. "?$") then
error("Unrecognized adjectival lemma: " .. base.lemma)
end
base.gender = "M"
base.decl = "adj"
end
-- Determine the declension based on the lemma and gender. The declension is
-- set in base.decl.
local function determine_declension(base)
if base.decl then
return
end
assert(not base.adj)
if base.indecl then
base.decl = "indecl"
elseif base.gender == "M" then
if base.unmarked then
if rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "unmarked-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "unmarked-ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-unmarked-ān-m"
else
error("With 'unmarked' indicator, lemma must end in " .. AA .. ", " .. AA .. M .. ", " ..
AA .. N .. ", आ, आँ: or आं " .. base.lemma)
end
elseif rfind(base.lemma, AA .. "$") then
base.decl = "ā-m"
elseif rfind(base.lemma, "आ$") then
base.decl = "ind-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-m"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-m"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-m"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-m"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-m"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-m"
elseif rfind(base.lemma, O .. "$") then
base.decl = "o-m"
elseif rfind(base.lemma, O .. N .. "$") then
base.decl = "on-m"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-m"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-m"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-m"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-m"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-m"
elseif rfind(base.lemma, R .. "$") then
base.decl = "r-m"
elseif rfind(base.lemma, H .. "$") then
base.decl = "h-m"
else
base.decl = "c-m"
end
else
assert(base.gender == "F")
if base.iya then
if rfind(base.lemma, MN_c .. "$") then
base.decl = "iyān-f"
else
base.decl = "iyā-f"
end
elseif rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "ā-f"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-f"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-f"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-f"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-f"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-f"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-f"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-f"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-f"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-f"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-f"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-f"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-f"
else
base.decl = "c-f"
end
end
end
local function detect_indicator_spec(base)
set_defaults_and_check_bad_indicators(base)
if base.adj then
synthesize_adj_lemma(base)
else
if base.number == "pl" then
synthesize_singular_lemma(base)
end
determine_declension(base)
end
end
local function detect_all_indicator_specs(alternant_multiword_spec)
iut.map_word_specs(alternant_multiword_spec, function(base)
detect_indicator_spec(base)
end)
end
local propagate_multiword_properties
local function propagate_alternant_properties(alternant_spec, property, mixed_value, nouns_only)
local seen_property
for _, multiword_spec in ipairs(alternant_spec.alternants) do
propagate_multiword_properties(multiword_spec, property, mixed_value, nouns_only)
if seen_property == nil then
seen_property = multiword_spec[property]
elseif multiword_spec[property] and seen_property ~= multiword_spec[property] then
seen_property = mixed_value
end
end
alternant_spec[property] = seen_property
end
propagate_multiword_properties = function(multiword_spec, property, mixed_value, nouns_only)
local seen_property = nil
local last_seen_nounal_pos = 0
local word_specs = multiword_spec.alternant_or_word_specs or multiword_spec.word_specs
for i = 1, #word_specs do
local is_nounal
if word_specs[i].alternants then
propagate_alternant_properties(word_specs[i], property, mixed_value)
is_nounal = not not word_specs[i][property]
elseif nouns_only then
is_nounal = not word_specs[i].adj and not word_specs[i].indecl
else
is_nounal = not not word_specs[i][property]
end
if is_nounal then
if not word_specs[i][property] then
error("Internal error: noun-type word spec without " .. property .. " set")
end
for j = last_seen_nounal_pos + 1, i - 1 do
word_specs[j][property] = word_specs[j][property] or word_specs[i][property]
end
last_seen_nounal_pos = i
if seen_property == nil then
seen_property = word_specs[i][property]
elseif seen_property ~= word_specs[i][property] then
seen_property = mixed_value
end
end
end
if last_seen_nounal_pos > 0 then
for i = last_seen_nounal_pos + 1, #word_specs do
word_specs[i][property] = word_specs[i][property] or word_specs[last_seen_nounal_pos][property]
end
end
multiword_spec[property] = seen_property
end
local function propagate_properties_downward(alternant_multiword_spec, property, default_propval)
local propval1 = alternant_multiword_spec[property] or default_propval
for _, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
local propval2 = alternant_or_word_spec[property] or propval1
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
local propval3 = multiword_spec[property] or propval2
for _, word_spec in ipairs(multiword_spec.word_specs) do
local propval4 = word_spec[property] or propval3
if propval4 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
word_spec[property] = propval4
end
end
else
if propval2 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
alternant_or_word_spec[property] = propval2
end
end
end
--[=[
Propagate `property` (one of "animacy", "gender" or "number") from nouns to adjacent
adjectives. We proceed as follows:
1. We assume the properties in question are already set on all nouns. This should happen
in set_defaults_and_check_bad_indicators().
2. We first propagate properties upwards and sideways. We recurse downwards from the top.
When we encounter a multiword spec, we proceed left to right looking for a noun.
When we find a noun, we fetch its property (recursing if the noun is an alternant),
and propagate it to any adjectives to its left, up to the next noun to the left.
When we have processed the last noun, we also propagate its property value to any
adjectives to the right (to handle e.g. [[пустальга звычайная]] "common kestrel", where
the adjective польовий should inherit the 'animal' animacy of лунь). Finally, we set
the property value for the multiword spec itself by combining all the non-nil
properties of the individual elements. If all non-nil properties have the same value,
the result is that value, otherwise it is `mixed_value` (which is "mixed" for animacy
and gender, but "both" for number).
3. When we encounter an alternant spec in this process, we recursively process each
alternant (which is a multiword spec) using the previous step, and combine any
non-nil properties we encounter the same way as for multiword specs.
4. The effect of steps 2 and 3 is to set the property of each alternant and multiword
spec based on its children or its neighbors.
]=]
local function propagate_properties(alternant_multiword_spec, property, default_propval, mixed_value)
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, "nouns only")
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, false)
propagate_properties_downward(alternant_multiword_spec, property, default_propval)
end
-- Find the first noun in a multiword expression and set alternant_multiword_spec.first_noun
-- to the index of that noun. Also find the first adjective and set alternant_multiword_spec.first_adj
-- similarly. If there is a first noun, we use its properties to determine the overall expression's
-- properties; otherwise we use the first adjective's properties, otherwise the first word's properties.
-- If the "word" located this way is not an alternant spec, we just use its properties directly, otherwise
-- we use the properties of the first noun (or failing that the first adjective, or failing that the
-- first word) in each alternative alternant in the alternant spec. For this reason, we need to set the
-- the .first_noun of and .first_adj of each multiword expression embedded in the first noun alternant spec,
-- and the .first_adj of each multiword expression in each adjective alternant spec leading up to the
-- first noun alternant spec.
local function determine_noun_status(alternant_multiword_spec)
for i, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
if alternant_or_word_spec.alternants then
local alternant_type
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
for j, word_spec in ipairs(multiword_spec.word_specs) do
if not word_spec.indecl then
if not word_spec.adj then
multiword_spec.first_noun = j
alternant_type = "noun"
break
elseif not multiword_spec.first_adj then
multiword_spec.first_adj = j
if not alternant_type then
alternant_type = "adj"
end
end
end
end
end
if alternant_type == "noun" then
alternant_multiword_spec.first_noun = i
return
elseif alternant_type == "adj" and not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
elseif not alternant_or_word_spec.indecl then
if not alternant_or_word_spec.adj then
alternant_multiword_spec.first_noun = i
return
elseif not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
end
end
end
local function decline_noun(base)
if not decls[base.decl] then
error("Internal error: Unrecognized declension type '" .. base.decl .. "'")
end
decls[base.decl](base)
handle_derived_slots_and_overrides(base)
end
local function process_manual_overrides(forms, args, number)
local params_to_slots_map =
number == "sg" and input_params_to_slots_sg or
number == "pl" and input_params_to_slots_pl or
input_params_to_slots_both
for param, slot in pairs(params_to_slots_map) do
if args[param] then
forms[slot] = nil
if args[param] ~= "-" and args[param] ~= "—" then
for _, form in ipairs(rsplit(args[param], "%s*,%s*")) do
local hi, phon = com.split_term_respelling(form)
local tr = phon and com.transliterate_respelling(phon) or nil
iut.insert_form(forms, slot, {form=form, translit=tr})
end
end
end
end
end
local function compute_category_and_desc(base)
local props = declprops[base.decl]
if props then
return props.cat, props.desc
end
local rest, gender = rmatch(base.decl, "^(.+)%-([mf])$")
if not gender then
error("Internal error: Don't know how to parse decl '" .. base.decl .. "'")
end
local cat_gender = gender == "m" and "masculine" or "feminine"
local desc_gender = gender == "m" and "masc" or "fem"
local ind, stem = rmatch(rest, "^(ind%-)(.*)$")
if not ind then
stem = rest
end
stem = rsub(stem, "n$", TILDE)
if ind then
return cat_gender .. " independent " .. stem .. "-stem ~", desc_gender .. " ind " .. stem .. "-stem"
else
return cat_gender .. " " .. stem .. "-stem ~", desc_gender .. " " .. stem .. "-stem"
end
end
-- Compute the categories to add the noun to, as well as the annotation to display in the
-- declension title bar. We combine the code to do these functions as both categories and
-- title bar contain similar information.
local function compute_categories_and_annotation(alternant_multiword_spec)
local cats = {}
local function insert(cattype)
cattype = rsub(cattype, "~", alternant_multiword_spec.pos)
m_table.insertIfNot(cats, "Hindi " .. cattype)
end
if alternant_multiword_spec.number == "sg" then
insert("uncountable ~")
elseif alternant_multiword_spec.number == "pl" then
insert("pluralia tantum")
end
local annotation
if alternant_multiword_spec.manual then
alternant_multiword_spec.annotation =
alternant_multiword_spec.number == "sg" and "sg-only" or
alternant_multiword_spec.number == "pl" and "pl-only" or
""
else
local annparts = {}
local decldescs = {}
local function do_word_spec(base)
local cat, desc = compute_category_and_desc(base)
insert(cat)
m_table.insertIfNot(decldescs, desc)
if base.plstem then
insert("~ with irregular plural stem")
end
if (lang:transliterate(base.lemma)) ~= base.lemma_translit then
insert("~ with phonetic respelling")
end
end
local key_entry = alternant_multiword_spec.first_noun or alternant_multiword_spec.first_adj or 1
if #alternant_multiword_spec.alternant_or_word_specs >= key_entry then
local alternant_or_word_spec = alternant_multiword_spec.alternant_or_word_specs[key_entry]
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
key_entry = multiword_spec.first_noun or multiword_spec.first_adj or 1
if #multiword_spec.word_specs >= key_entry then
do_word_spec(multiword_spec.word_specs[key_entry])
end
end
else
do_word_spec(alternant_or_word_spec)
end
end
if alternant_multiword_spec.number ~= "both" then
table.insert(annparts, alternant_multiword_spec.number == "sg" and "sg-only" or "pl-only")
end
if #decldescs == 0 then
table.insert(annparts, "indecl")
else
table.insert(annparts, table.concat(decldescs, " // "))
end
alternant_multiword_spec.annotation = table.concat(annparts, " ")
if #decldescs > 1 then
insert("~ with multiple declensions")
end
end
alternant_multiword_spec.categories = cats
end
local function show_forms(alternant_multiword_spec)
local lemmas = alternant_multiword_spec.forms.dir_s or alternant_multiword_spec.forms.dir_p or {}
local props = {
lemmas = lemmas,
slot_table = noun_slots_with_linked,
lang = lang,
include_translit = true,
-- Explicit additional top-level footnotes only occur with {{hi-ndecl-manual}} and variants.
footnotes = alternant_multiword_spec.footnotes,
allow_footnote_symbols = not not alternant_multiword_spec.footnotes,
}
iut.show_forms(alternant_multiword_spec.forms, props)
end
local function make_table(alternant_multiword_spec)
local forms = alternant_multiword_spec.forms
local table_top = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = '{title}{annotation}',
palette = 'blue',
tall = 'yes',
class = 'tr-alongside',
}
}
local table_bottom = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-bottom',
args = {
notes = forms.footnote or nil,
}
}
local table_spec_both = table_top .. [=[
!
! เอกพจน์
! พหูพจน์
|-
! การกตรง
| {dir_s}
| {dir_p}
|-
! การกอ้อม
| {obl_s}
| {obl_p}
|-
! สัมโพธนการก
| {voc_s}
| {voc_p}
]=] .. table_bottom
local table_spec_sg = table_top .. [=[
!
! เอกพจน์
|-
! การกตรง
| {dir_s}
|-
! การกอ้อม
| {obl_s}
|-
! สัมโพธนการก
| {voc_s}
]=] .. table_bottom
local table_spec_pl = table_top .. [=[
!
! พหูพจน์
|-
! การกตรง
| {dir_p}
|-
! การกอ้อม
| {obl_p}
|-
! สัมโพธนการก
| {voc_p}
]=] .. table_bottom
if alternant_multiword_spec.title then
forms.title = alternant_multiword_spec.title
else
forms.title = '<span class="nowrap">Declension of <i lang="hi" class="Deva">' .. forms.lemma .. '</i></span>'
end
local annotation = alternant_multiword_spec.annotation
if annotation == "" then
forms.annotation = ""
else
forms.annotation = ' <span class="nowrap" style="font-size: smaller;">(' .. annotation .. ")</span>"
end
local table_spec =
alternant_multiword_spec.number == "sg" and table_spec_sg or
alternant_multiword_spec.number == "pl" and table_spec_pl or
table_spec_both
forms.notes_clause = forms.footnote ~= "" and forms.footnote or ""
return m_string_utilities.format(table_spec, forms)
end
local function compute_headword_genders(alternant_multiword_spec)
local genders = {}
local number
if alternant_multiword_spec.number == "pl" then
number = "-p"
else
number = ""
end
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.gender == "M" then
m_table.insertIfNot(genders, "m" .. number)
elseif base.gender == "F" then
m_table.insertIfNot(genders, "f" .. number)
else
error("Internal error: Unrecognized gender '" ..
(base.gender or "nil") .. "'")
end
end)
return genders
end
-- Externally callable function to parse and decline a noun given user-specified arguments.
-- Return value is WORD_SPEC, an object where the declined forms are in `WORD_SPEC.forms`
-- for each slot. If there are no values for a slot, the slot key will be missing. The value
-- for a given slot is a list of objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms(parent_args, pos, from_headword, def)
local params = {
[1] = {required = true, default = "दुनिया<iyā>"},
footnote = {list = true},
title = true,
pagename = true,
json = {type = "boolean"},
}
if from_headword then
params["lemma"] = {list = true}
params["g"] = {list = true}
params["f"] = {list = true}
params["m"] = {list = true}
params["id"] = true
end
local args = m_para.process(parent_args, params)
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
lang = lang,
transliterate_respelling = com.transliterate_respelling,
allow_blank_lemma = true,
}
local alternant_multiword_spec = iut.parse_inflected_text(args[1], parse_props)
alternant_multiword_spec.title = args.title
alternant_multiword_spec.footnotes = args.footnote
alternant_multiword_spec.pos = pos or "nouns"
alternant_multiword_spec.args = args
alternant_multiword_spec.pagename = args.pagename
com.normalize_all_lemmas(alternant_multiword_spec, "always transliterate")
detect_all_indicator_specs(alternant_multiword_spec)
propagate_properties(alternant_multiword_spec, "number", "both", "both")
-- The default of "M" should apply only to plural adjectives, where it doesn't matter.
-- FIXME: This may be wrong for Hindi.
propagate_properties(alternant_multiword_spec, "gender", "M", "mixed")
determine_noun_status(alternant_multiword_spec)
local inflect_props = {
skip_slot = function(slot)
return skip_slot(alternant_multiword_spec.number, slot)
end,
slot_table = noun_slots_with_linked,
lang = lang,
inflect_word_spec = decline_noun,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
com.remove_redundant_translit(alternant_multiword_spec)
compute_categories_and_annotation(alternant_multiword_spec)
alternant_multiword_spec.genders = compute_headword_genders(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Externally callable function to parse and decline a noun where all forms
-- are given manually. Return value is WORD_SPEC, an object where the declined
-- forms are in `WORD_SPEC.forms` for each slot. If there are no values for a
-- slot, the slot key will be missing. The value for a given slot is a list of
-- objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms_manual(parent_args, number, pos, from_headword, def)
if number ~= "sg" and number ~= "pl" and number ~= "both" then
error("Internal error: number (arg 1) must be 'sg', 'pl' or 'both': '" .. number .. "'")
end
local params = {
footnote = {list = true},
title = true,
json = {type = "boolean"},
}
if number == "both" then
params[1] = {required = true, default = "तारीख़"}
params[2] = {required = true, default = "तवारीख़"}
params[3] = {required = true, default = "तारीख़"}
params[4] = {required = true, default = "तवारीख़ों"}
params[5] = {required = true, default = "तारीख़"}
params[6] = {required = true, default = "तवारीख़ो"}
elseif number == "sg" then
params[1] = {required = true, default = "अदला-बदला"}
params[2] = {required = true, default = "अदले-बदले"}
params[3] = {required = true, default = "अदले-बदले"}
else
params[1] = {required = true, default = "लोग"}
params[2] = {required = true, default = "लोगों"}
params[3] = {required = true, default = "लोगो"}
end
local args = m_para.process(parent_args, params)
local alternant_multiword_spec = {
title = args.title,
footnotes = args.footnote,
forms = {},
number = number,
pos = pos or "nouns",
manual = true,
}
process_manual_overrides(alternant_multiword_spec.forms, args, alternant_multiword_spec.number)
compute_categories_and_annotation(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Entry point for {{hi-ndecl}}. Template-callable function to parse and decline a noun given
-- user-specified arguments and generate a displayable table of the declined forms.
function export.show(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms(parent_args)
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
-- Entry point for {{hi-ndecl-manual}}, {{hi-ndecl-manual-sg}} and {{hi-ndecl-manual-pl}}.
-- Template-callable function to parse and decline a noun given manually-specified inflections
-- and generate a displayable table of the declined forms.
function export.show_manual(frame)
local iparams = {
[1] = {required = true},
}
local iargs = m_para.process(frame.args, iparams)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms_manual(parent_args, iargs[1])
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
return export
pjvy7qgan16911vlzwgu97zzde4g4kl
5722537
5722536
2026-05-05T04:10:15Z
OctraBot
3198
5722537
Scribunto
text/plain
local export = {}
--[=[
Authorship: Ben Wing <benwing2>
]=]
--[=[
TERMINOLOGY:
-- "slot" = A particular combination of case/number.
Example slot names for nouns are "dir_s" (direct singular) and
"voc_p" (vocative plural). Each slot is filled with zero or more forms.
-- "form" = The declined Hindi form representing the value of a given slot.
-- "lemma" = The dictionary form of a given Hindi term. Generally the direct
masculine singular, but may occasionally be another form if the direct
masculine singular is missing.
]=]
local lang = require("Module:languages").getByCode("hi")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_string_utilities = require("Module:string utilities")
local iut = require("Module:inflection utilities")
local put = require("Module:parse utilities")
local m_para = require("Module:parameters")
local com = require("Module:hi-common")
local u = require("Module:string/char")
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rgmatch = mw.ustring.gmatch
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local usub = mw.ustring.sub
local uupper = mw.ustring.upper
local ulower = mw.ustring.lower
-- vowel diacritics; don't display nicely on their own
local M = u(0x0901)
local N = u(0x0902)
local MN_c = "[" .. M .. N .. "]"
local H = u(0x0903)
local AA = u(0x093e)
local E = u(0x0947)
local EN = E .. N
local I = u(0x093f)
local II = u(0x0940)
local O = u(0x094b)
local ON = O .. N
local U = u(0x0941)
local UU = u(0x0942)
local R = u(0x0943)
local VIRAMA = u(0x094d)
local TILDE = u(0x0303)
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
local retval, nsubs = rsubn(term, foo, bar)
return retval, nsubs > 0
end
local noun_slots = {
dir_s = "dir|s",
obl_s = "obl|s",
voc_s = "voc|s",
dir_p = "dir|p",
obl_p = "obl|p",
voc_p = "voc|p",
}
local noun_slots_with_linked = m_table.shallowCopy(noun_slots)
noun_slots_with_linked["dir_s_linked"] = "dir|s"
noun_slots_with_linked["dir_p_linked"] = "dir|p"
local input_params_to_slots_both = {
[1] = "dir_s",
[2] = "dir_p",
[3] = "obl_s",
[4] = "obl_p",
[5] = "voc_s",
[6] = "voc_p",
}
local input_params_to_slots_sg = {
[1] = "dir_s",
[2] = "obl_s",
[3] = "voc_s",
}
local input_params_to_slots_pl = {
[1] = "dir_p",
[2] = "obl_p",
[3] = "voc_p",
}
local cases = {
dir = true,
obl = true,
voc = true,
}
local function skip_slot(number, slot)
return number == "sg" and rfind(slot, "_p$") or
number == "pl" and rfind(slot, "_s$")
end
local function add(base, stem, translit_stem, slot, ending, footnotes)
if skip_slot(base.number, slot) then
return
end
com.add_form(base, stem, translit_stem, slot, ending, footnotes)
end
local function process_slot_overrides(base)
for slot, overrides in pairs(base.overrides) do
if skip_slot(base.number, slot) then
error("Override specified for invalid slot '" .. slot .. "' due to '" .. base.number .. "' number restriction")
end
base.forms[slot] = nil
for _, override in ipairs(overrides) do
for _, value in ipairs(override.values) do
local form = value.form
local tr = com.transliterate_respelling(value.phon_form)
local combined_notes = iut.combine_footnotes(base.footnotes, value.footnotes)
assert(override.full)
if form ~= "" then
iut.insert_form(base.forms, slot, {form = form, translit = tr, footnotes = combined_notes})
end
end
end
end
end
local function add_decl(base, stem, translit_stem, dir_s, obl_s, voc_s, dir_p, obl_p, voc_p,
footnotes
)
if not stem then
stem = base.lemma
translit_stem = base.lemma_translit
end
local plstem, pl_translit_stem = stem, translit_stem
if base.plstem then
plstem = base.plstem
pl_translit_stem = base.pl_translit_stem
end
add(base, stem, translit_stem, "dir_s", dir_s, footnotes)
add(base, stem, translit_stem, "obl_s", obl_s, footnotes)
add(base, stem, translit_stem, "voc_s", voc_s, footnotes)
add(base, plstem, pl_translit_stem, "dir_p", dir_p, footnotes)
add(base, plstem, pl_translit_stem, "obl_p", obl_p, footnotes)
add(base, plstem, pl_translit_stem, "voc_p", voc_p, footnotes)
end
local function handle_derived_slots_and_overrides(base)
process_slot_overrides(base)
-- Compute linked versions of potential lemma slots, for use in {{hi-noun}}.
-- We substitute the original lemma (before removing links) for forms that
-- are the same as the lemma, if the original lemma has links.
for _, slot in ipairs({"dir_s", "dir_p"}) do
iut.insert_forms(base.forms, slot .. "_linked", iut.map_forms(base.forms[slot], function(form)
if form == base.orig_lemma_no_links and rfind(base.orig_lemma, "%[%[") then
return base.orig_lemma
else
return form
end
end))
end
end
local function fetch_final_mn(base)
local mn = rmatch(base.lemma, "(" .. MN_c .. ")$")
if not mn then
error("Internal error: Lemma " .. base.lemma .. " should end in nasal vowel")
end
return mn
end
local decls = {}
local declprops = {}
decls["c-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", ON, O)
end
declprops["c-m"] = {
desc = "masc cons-stem",
cat = "masculine consonant-stem ~",
}
decls["c-f"] = function(base)
add_decl(base, nil, nil, "", "", "", EN, ON, O)
end
declprops["c-f"] = {
desc = "fem cons-stem",
cat = "feminine consonant-stem ~",
}
decls["ā-m"] = function(base)
if rfind(base.lemma, "या$") then
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "ए", "ए", "ए", "यों", "यो")
add_decl(base, stem, translit_stem, nil, "ये", "ये", "ये")
else
local stem, translit_stem = com.strip_ending(base, AA)
add_decl(base, stem, translit_stem, AA, E, E, E, ON, O)
end
end
-- E.g. तेंदुआ "leopard"
decls["ind-ā-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "आ")
add_decl(base, stem, translit_stem, "आ", "ए", "ए", "ए", "ओं", "ओ")
end
decls["unmarked-ā-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
declprops["unmarked-ā-m"] = {
desc = "masc unmarked ā-stem",
cat = "masculine unmarked ā-stem ~",
}
-- No need for ind-unmarked-ā-m because declension is "unmarked", i.e. all endings
-- are added after the vowel.
-- E.g. रेस्तराँ "restaurant"
decls["unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, AA .. "ओं", AA .. "ओं")
end
declprops["unmarked-ān-m"] = {
desc = "masc unmarked ā̃-stem",
cat = "masculine unmarked ā̃-stem ~",
}
decls["ind-unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "आओं", "आओं")
end
declprops["ind-unmarked-ān-m"] = {
desc = "masc ind unmarked ā̃-stem",
cat = "masculine independent unmarked ā̃-stem ~",
}
-- E.g. ख़ानसामाँ "butler, cook"
decls["ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, EN, EN, EN, ON, ON)
end
-- E.g. कुआँ "well"
decls["ind-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, "एँ", "एँ", "एँ", "ओं", "ओं")
end
decls["ā-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
-- No need for ind-ā-f because declension is "unmarked", i.e. all endings
-- are added after the vowel.
decls["ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, AA .. "एँ", AA .. "ओं", AA .. "ओं")
end
decls["ind-ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "आएँ", "आओं", "आओं")
end
decls["i-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "यों", "यो")
end
decls["i-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "याँ", "यों", "यो")
end
-- E.g. प्रधान मंत्री "prime minister"
decls["ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, II, I .. "यों", I .. "यो")
end
-- E.g. भाई "brother"
decls["ind-ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "ई", "इयों", "इयो")
end
decls["īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, II .. N, I .. "यों", I .. "यों")
end
decls["ind-īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "ईं", "इयों", "इयों")
end
decls["ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, I .. "याँ", I .. "यों", I .. "यो")
end
-- E.g. दवाई "medicine", डोई "wooden ladle", तेंदुई "female leopard", मिठाई "sweet, dessert"
decls["ind-ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "इयाँ", "इयों", "इयो")
end
decls["īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, I .. "याँ", I .. "यों", I .. "यों")
end
decls["ind-īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "इयाँ", "इयों", "इयों")
end
decls["iyā-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "या", "या", "याँ", "यों", "यो")
end
decls["iyān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "या" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "यों", "यों")
end
decls["o-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, O)
add_decl(base, stem, translit_stem, O, O, O, O, ON, O)
end
decls["on-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, ON)
add_decl(base, stem, translit_stem, ON, ON, ON, ON, ON, ON)
end
decls["u-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
decls["u-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
decls["ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, UU, U .. "ओं", U .. "ओ")
end
decls["ind-ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "ऊ", "उओं", "उओ")
end
decls["ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, U .. "ओं", U .. "ओं")
end
decls["ind-ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "उओं", "उओं")
end
decls["ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, U .. "एँ", U .. "ओं", U .. "ओ")
end
decls["ind-ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "उएँ", "उओं", "उओ")
end
-- E.g. जूँ "louse"
decls["ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, U .. "एँ", U .. "ओं", U .. "ओं")
end
decls["ind-ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "उएँ", "उओं", "उओं")
end
decls["r-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
-- E.g. प्रातः "morning"
decls["h-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, H)
add_decl(base, stem, translit_stem, H, H, H, H, ON, O)
end
decls["indecl"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "", "")
end
declprops["indecl"] = {
desc = "indecl",
cat = "indeclinable ~",
}
decls["adj"] = function(base, stress)
local adj_alternant_multiword_spec = require("Module:hi-adjective").do_generate_forms(
{base.lemma .. "//" .. base.lemma_translit}
)
local function copy(from_slot, to_slot)
base.forms[to_slot] = adj_alternant_multiword_spec.forms[from_slot]
end
if base.number ~= "pl" then
copy("dir_m_s", "dir_s")
copy("obl_m_s", "obl_s")
copy("voc_m_s", "voc_s")
end
if base.number ~= "sg" then
copy("dir_m_p", "dir_p")
copy("obl_m_p", "obl_p")
copy("voc_m_p", "voc_p")
end
end
declprops["adj"] = {
desc = "adj",
cat = "adjectival ~",
}
local function fetch_footnotes(separated_group)
local footnotes
for j = 2, #separated_group - 1, 2 do
if separated_group[j + 1] ~= "" then
error("Extraneous text after bracketed footnotes: '" .. table.concat(separated_group) .. "'")
end
if not footnotes then
footnotes = {}
end
table.insert(footnotes, separated_group[j])
end
return footnotes
end
--[=[
Parse a single override spec and return two values: the slot the override applies to,
and an object describing the override spec. The input is actually a list where the footnotes have been separated out. For example, given the spec 'oblpl:हज़ारों:हज़ारहा[rare]',
the input will be a list {"oblpl:हज़ारों:हज़ारहा", "[rare]", ""}. The object returned for
this example looks like this:
{
full = true,
values = {
{
form = "हज़ारों"
},
{
form = "हज़ारहा",
footnotes = {"[rare]"}
}
}
}
]=]
local function parse_override(segments)
local retval = {values = {}}
local part = segments[1]
local offset = 4
local case = usub(part, 1, 3)
if cases[case] then
-- ok
else
error("Internal error: unrecognized case in override: '" .. table.concat(segments) .. "'")
end
local rest = usub(part, offset)
local slot
if rfind(rest, "^pl") then
rest = rsub(rest, "^pl", "")
slot = case .. "_p"
else
slot = case .. "_s"
end
if rfind(rest, "^:") then
retval.full = true
rest = rsub(rest, "^:", "")
else
error("Suffix overrides not currently supported: " .. part)
end
segments[1] = rest
local colon_separated_groups = put.split_alternating_runs(segments, ":")
for i, colon_separated_group in ipairs(colon_separated_groups) do
local value = {}
local form = colon_separated_group[1]
if form == "" then
error("Use - to indicate an empty ending for slot '" .. slot .. "': '" .. table.concat(segments .. "'"))
elseif form == "-" then
value.form = ""
else
value.form, value.phon_form = com.split_term_respelling(form)
end
value.footnotes = fetch_footnotes(colon_separated_group)
table.insert(retval.values, value)
end
return slot, retval
end
--[=[
Parse an indicator spec (text consisting of angle brackets and zero or more
dot-separated indicators within them). Return value is an object of the form
{
overrides = {
SLOT = {OVERRIDE, OVERRIDE, ...}, -- as returned by parse_override()
...
},
forms = {}, -- forms for a single spec alternant; see `forms` below
footnotes = {"FOOTNOTE", "FOOTNOTE", ...}, -- may be missing
explicit_gender = "GENDER", -- "M", "F"; may be missing
number = "NUMBER", -- "sg", "pl"; may be missing
adj = true, -- may be missing
indecl = true, -- may be missing
unmarked = true, -- may be missing
iya = true, -- may be missing
plstem = "PLSTEM", -- may be missing
pl_phon_stem = "PLSTEM-PHONETIC-RESPELLING", -- as specified by the user; may be missing
pl_translit_stem = "PLSTEM-TRANSLIT", -- translit of pl_phon_stem (if present) or plstem; may be missing
-- The following additional fields are added by other functions:
orig_lemma = "ORIGINAL-LEMMA", -- as given by the user or taken from pagename
orig_lemma_no_links = "ORIGINAL-LEMMA-NO-LINKS", -- links removed
lemma = "LEMMA", -- `orig_lemma_no_links`, converted to singular form if plural
phon_lemma = "LEMMA-PHONETIC-RESPELLING", -- as specified by the user; may be missing
lemma_translit = "LEMMA-TRANSLIT", -- translit of phon_lemma (if present) or lemma
forms = {
SLOT = {
{
form = "FORM",
footnotes = {"FOOTNOTE", "FOOTNOTE", ...} -- may be missing
},
...
},
...
},
decl = "DECL", -- declension, e.g. "ind-ūn-f"
}
]=]
local function parse_indicator_spec(angle_bracket_spec)
local inside = rmatch(angle_bracket_spec, "^<(.*)>$")
assert(inside)
local base = {overrides = {}, forms = {}}
if inside ~= "" then
local segments = put.parse_balanced_segment_run(inside, "[", "]")
local dot_separated_groups = put.split_alternating_runs(segments, "%.")
for i, dot_separated_group in ipairs(dot_separated_groups) do
local part = dot_separated_group[1]
local case_prefix = usub(part, 1, 3)
if cases[case_prefix] then
local slot, override = parse_override(dot_separated_group)
if base.overrides[slot] then
table.insert(base.overrides[slot], override)
else
base.overrides[slot] = {override}
end
elseif part == "" then
if #dot_separated_group == 1 then
error("Blank indicator: '" .. inside .. "'")
end
base.footnotes = fetch_footnotes(dot_separated_group)
elseif #dot_separated_group > 1 then
error("Footnotes only allowed with slot overrides or by themselves: '" .. table.concat(dot_separated_group) .. "'")
elseif part == "M" or part == "F" then
if base.explicit_gender then
error("Can't specify gender twice: '" .. inside .. "'")
end
base.explicit_gender = part
elseif part == "sg" or part == "pl" then
if base.number then
error("Can't specify number twice: '" .. inside .. "'")
end
base.number = part
elseif part == "+" then
if base.adj then
error("Can't specify '+' twice: '" .. inside .. "'")
end
base.adj = true
elseif part == "$" then
if base.indecl then
error("Can't specify '$' twice: '" .. inside .. "'")
end
base.indecl = true
elseif part == "unmarked" then
if base.unmarked then
error("Can't specify 'unmarked' twice: '" .. inside .. "'")
end
base.unmarked = true
elseif part == "iyā" then
if base.iya then
error("Can't specify 'iyā' twice: '" .. inside .. "'")
end
base.iya = true
elseif rfind(part, "^plstem:") then
if base.plstem then
error("Can't specify plural stem twice: '" .. inside .. "'")
end
base.plstem, base.pl_phon_stem = com.split_term_respelling(rsub(part, "^plstem:", ""))
base.pl_translit_stem = com.transliterate_respelling(base.pl_phon_stem) or (lang:transliterate(base.plstem))
else
error("Unrecognized indicator '" .. part .. "': '" .. inside .. "'")
end
end
end
return base
end
local function set_defaults_and_check_bad_indicators(base)
-- Set default values.
if not base.adj and not base.indecl then
base.number = base.number or "both"
end
base.gender = base.explicit_gender
if base.iya then
if base.adj then
error("Can't specify both '+' and 'iya'")
end
if base.gender == "M" then
error("Can't specify M gender with 'iyā' indicator")
end
if not rfind(base.lemma, I .. "याँ?$") and not rfind(base.lemma, "-इयाँ?$") then
error("With 'iyā' indicator, lemma must end in " .. I .. "या or " .. I .. "याँ: " .. base.lemma)
end
base.gender = "F"
end
if base.unmarked then
if base.adj then
error("Can't specify both '+' and 'unmarked'")
end
if base.iya then
error("Can't specify both 'iya' and 'unmarked'")
end
if base.gender == "F" then
error("Can't specify F gender with 'unmarked' indicator")
end
base.gender = "M"
end
if rfind(base.lemma, "[" .. O .. H .. R .. "]$") then
if base.gender == "F" then
error("Can't specify F gender with lemma ending in " .. O .. ", " .. H .. " or " .. R .. ": " .. base.lemma)
end
base.gender = "M"
end
if not base.gender and not base.adj and not base.indecl then
error("Unless lemma is in " .. O .. ", " .. H .. " or " .. R .. " or 'iya', 'unmarked' or '$' specified, gender must be given: " .. base.lemma)
end
if base.adj and base.indecl then
error("Can't specify both '+' and '$' on the same lemma " .. base.lemma)
end
end
-- For a plural-only lemma, synthesize a likely singular lemma. It doesn't have to be
-- theoretically correct as long as it generates all the correct plural forms.
local function synthesize_singular_lemma(base)
if not base.gender then
error("For plural-only lemma, need to specify the gender: '" .. base.lemma .. "'")
end
if base.gender == "M" then
if rfind(base.lemma, E .. "$") then
local stem, translit_stem = com.strip_ending(base, E)
base.lemma = stem .. AA
base.lemma_translit = translit_stem .. "ā"
return
end
if rfind(base.lemma, "ए$") then
-- FIXME, what about -iyā -> -ie?
local stem, translit_stem = com.strip_ending(base, "ए")
base.lemma = stem .. "अ"
base.lemma_translit = translit_stem .. "ā"
return
end
local ending = rmatch(base.lemma, "(" .. E .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. AA .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. "अ" .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
-- Otherwise, singular same as plural and lemma is already correct.
else
assert(base.gender == "F")
local function add_dir_p_override()
-- Add an override to force the direct plural to match. This is needed below
-- in case the lemma ends in anusvara instead of chandrabindu (because the
-- declension functions generate a direct plural with chandrabindu) and also
-- when the direct plural is the same as the singular.
if not base.overrides.dir_p then
base.overrides.dir_p = {}
end
table.insert(base.overrides.dir_p, {full = true, values = {{form = base.lemma, phon_form = base.lemma_translit}}})
end
local ending = rmatch(base.lemma, "(" .. EN .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(या " .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
-- This may or may not produce the "right" singular but regardless,
-- the plural will be correct, which is all that matters.
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
-- We seem to have an endingless plural, e.g. औलाद. Add an override to the dir_p slot
-- to force this form.
add_dir_p_override()
end
end
-- For an adjectival lemma, synthesize the masc singular form.
local function synthesize_adj_lemma(base)
if not rfind(base.lemma, "[अ" .. AA .. "]" .. MN_c .. "?$") then
error("Unrecognized adjectival lemma: " .. base.lemma)
end
base.gender = "M"
base.decl = "adj"
end
-- Determine the declension based on the lemma and gender. The declension is
-- set in base.decl.
local function determine_declension(base)
if base.decl then
return
end
assert(not base.adj)
if base.indecl then
base.decl = "indecl"
elseif base.gender == "M" then
if base.unmarked then
if rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "unmarked-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "unmarked-ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-unmarked-ān-m"
else
error("With 'unmarked' indicator, lemma must end in " .. AA .. ", " .. AA .. M .. ", " ..
AA .. N .. ", आ, आँ: or आं " .. base.lemma)
end
elseif rfind(base.lemma, AA .. "$") then
base.decl = "ā-m"
elseif rfind(base.lemma, "आ$") then
base.decl = "ind-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-m"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-m"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-m"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-m"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-m"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-m"
elseif rfind(base.lemma, O .. "$") then
base.decl = "o-m"
elseif rfind(base.lemma, O .. N .. "$") then
base.decl = "on-m"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-m"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-m"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-m"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-m"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-m"
elseif rfind(base.lemma, R .. "$") then
base.decl = "r-m"
elseif rfind(base.lemma, H .. "$") then
base.decl = "h-m"
else
base.decl = "c-m"
end
else
assert(base.gender == "F")
if base.iya then
if rfind(base.lemma, MN_c .. "$") then
base.decl = "iyān-f"
else
base.decl = "iyā-f"
end
elseif rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "ā-f"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-f"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-f"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-f"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-f"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-f"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-f"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-f"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-f"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-f"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-f"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-f"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-f"
else
base.decl = "c-f"
end
end
end
local function detect_indicator_spec(base)
set_defaults_and_check_bad_indicators(base)
if base.adj then
synthesize_adj_lemma(base)
else
if base.number == "pl" then
synthesize_singular_lemma(base)
end
determine_declension(base)
end
end
local function detect_all_indicator_specs(alternant_multiword_spec)
iut.map_word_specs(alternant_multiword_spec, function(base)
detect_indicator_spec(base)
end)
end
local propagate_multiword_properties
local function propagate_alternant_properties(alternant_spec, property, mixed_value, nouns_only)
local seen_property
for _, multiword_spec in ipairs(alternant_spec.alternants) do
propagate_multiword_properties(multiword_spec, property, mixed_value, nouns_only)
if seen_property == nil then
seen_property = multiword_spec[property]
elseif multiword_spec[property] and seen_property ~= multiword_spec[property] then
seen_property = mixed_value
end
end
alternant_spec[property] = seen_property
end
propagate_multiword_properties = function(multiword_spec, property, mixed_value, nouns_only)
local seen_property = nil
local last_seen_nounal_pos = 0
local word_specs = multiword_spec.alternant_or_word_specs or multiword_spec.word_specs
for i = 1, #word_specs do
local is_nounal
if word_specs[i].alternants then
propagate_alternant_properties(word_specs[i], property, mixed_value)
is_nounal = not not word_specs[i][property]
elseif nouns_only then
is_nounal = not word_specs[i].adj and not word_specs[i].indecl
else
is_nounal = not not word_specs[i][property]
end
if is_nounal then
if not word_specs[i][property] then
error("Internal error: noun-type word spec without " .. property .. " set")
end
for j = last_seen_nounal_pos + 1, i - 1 do
word_specs[j][property] = word_specs[j][property] or word_specs[i][property]
end
last_seen_nounal_pos = i
if seen_property == nil then
seen_property = word_specs[i][property]
elseif seen_property ~= word_specs[i][property] then
seen_property = mixed_value
end
end
end
if last_seen_nounal_pos > 0 then
for i = last_seen_nounal_pos + 1, #word_specs do
word_specs[i][property] = word_specs[i][property] or word_specs[last_seen_nounal_pos][property]
end
end
multiword_spec[property] = seen_property
end
local function propagate_properties_downward(alternant_multiword_spec, property, default_propval)
local propval1 = alternant_multiword_spec[property] or default_propval
for _, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
local propval2 = alternant_or_word_spec[property] or propval1
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
local propval3 = multiword_spec[property] or propval2
for _, word_spec in ipairs(multiword_spec.word_specs) do
local propval4 = word_spec[property] or propval3
if propval4 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
word_spec[property] = propval4
end
end
else
if propval2 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
alternant_or_word_spec[property] = propval2
end
end
end
--[=[
Propagate `property` (one of "animacy", "gender" or "number") from nouns to adjacent
adjectives. We proceed as follows:
1. We assume the properties in question are already set on all nouns. This should happen
in set_defaults_and_check_bad_indicators().
2. We first propagate properties upwards and sideways. We recurse downwards from the top.
When we encounter a multiword spec, we proceed left to right looking for a noun.
When we find a noun, we fetch its property (recursing if the noun is an alternant),
and propagate it to any adjectives to its left, up to the next noun to the left.
When we have processed the last noun, we also propagate its property value to any
adjectives to the right (to handle e.g. [[пустальга звычайная]] "common kestrel", where
the adjective польовий should inherit the 'animal' animacy of лунь). Finally, we set
the property value for the multiword spec itself by combining all the non-nil
properties of the individual elements. If all non-nil properties have the same value,
the result is that value, otherwise it is `mixed_value` (which is "mixed" for animacy
and gender, but "both" for number).
3. When we encounter an alternant spec in this process, we recursively process each
alternant (which is a multiword spec) using the previous step, and combine any
non-nil properties we encounter the same way as for multiword specs.
4. The effect of steps 2 and 3 is to set the property of each alternant and multiword
spec based on its children or its neighbors.
]=]
local function propagate_properties(alternant_multiword_spec, property, default_propval, mixed_value)
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, "nouns only")
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, false)
propagate_properties_downward(alternant_multiword_spec, property, default_propval)
end
-- Find the first noun in a multiword expression and set alternant_multiword_spec.first_noun
-- to the index of that noun. Also find the first adjective and set alternant_multiword_spec.first_adj
-- similarly. If there is a first noun, we use its properties to determine the overall expression's
-- properties; otherwise we use the first adjective's properties, otherwise the first word's properties.
-- If the "word" located this way is not an alternant spec, we just use its properties directly, otherwise
-- we use the properties of the first noun (or failing that the first adjective, or failing that the
-- first word) in each alternative alternant in the alternant spec. For this reason, we need to set the
-- the .first_noun of and .first_adj of each multiword expression embedded in the first noun alternant spec,
-- and the .first_adj of each multiword expression in each adjective alternant spec leading up to the
-- first noun alternant spec.
local function determine_noun_status(alternant_multiword_spec)
for i, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
if alternant_or_word_spec.alternants then
local alternant_type
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
for j, word_spec in ipairs(multiword_spec.word_specs) do
if not word_spec.indecl then
if not word_spec.adj then
multiword_spec.first_noun = j
alternant_type = "noun"
break
elseif not multiword_spec.first_adj then
multiword_spec.first_adj = j
if not alternant_type then
alternant_type = "adj"
end
end
end
end
end
if alternant_type == "noun" then
alternant_multiword_spec.first_noun = i
return
elseif alternant_type == "adj" and not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
elseif not alternant_or_word_spec.indecl then
if not alternant_or_word_spec.adj then
alternant_multiword_spec.first_noun = i
return
elseif not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
end
end
end
local function decline_noun(base)
if not decls[base.decl] then
error("Internal error: Unrecognized declension type '" .. base.decl .. "'")
end
decls[base.decl](base)
handle_derived_slots_and_overrides(base)
end
local function process_manual_overrides(forms, args, number)
local params_to_slots_map =
number == "sg" and input_params_to_slots_sg or
number == "pl" and input_params_to_slots_pl or
input_params_to_slots_both
for param, slot in pairs(params_to_slots_map) do
if args[param] then
forms[slot] = nil
if args[param] ~= "-" and args[param] ~= "—" then
for _, form in ipairs(rsplit(args[param], "%s*,%s*")) do
local hi, phon = com.split_term_respelling(form)
local tr = phon and com.transliterate_respelling(phon) or nil
iut.insert_form(forms, slot, {form=form, translit=tr})
end
end
end
end
end
local function compute_category_and_desc(base)
local props = declprops[base.decl]
if props then
return props.cat, props.desc
end
local rest, gender = rmatch(base.decl, "^(.+)%-([mf])$")
if not gender then
error("Internal error: Don't know how to parse decl '" .. base.decl .. "'")
end
local cat_gender = gender == "m" and "masculine" or "feminine"
local desc_gender = gender == "m" and "masc" or "fem"
local ind, stem = rmatch(rest, "^(ind%-)(.*)$")
if not ind then
stem = rest
end
stem = rsub(stem, "n$", TILDE)
if ind then
return cat_gender .. " independent " .. stem .. "-stem ~", desc_gender .. " ind " .. stem .. "-stem"
else
return cat_gender .. " " .. stem .. "-stem ~", desc_gender .. " " .. stem .. "-stem"
end
end
-- Compute the categories to add the noun to, as well as the annotation to display in the
-- declension title bar. We combine the code to do these functions as both categories and
-- title bar contain similar information.
local function compute_categories_and_annotation(alternant_multiword_spec)
local cats = {}
local function insert(cattype)
cattype = rsub(cattype, "~", alternant_multiword_spec.pos)
m_table.insertIfNot(cats, "Hindi " .. cattype)
end
if alternant_multiword_spec.number == "sg" then
insert("uncountable ~")
elseif alternant_multiword_spec.number == "pl" then
insert("pluralia tantum")
end
local annotation
if alternant_multiword_spec.manual then
alternant_multiword_spec.annotation =
alternant_multiword_spec.number == "sg" and "sg-only" or
alternant_multiword_spec.number == "pl" and "pl-only" or
""
else
local annparts = {}
local decldescs = {}
local function do_word_spec(base)
local cat, desc = compute_category_and_desc(base)
insert(cat)
m_table.insertIfNot(decldescs, desc)
if base.plstem then
insert("~ with irregular plural stem")
end
if (lang:transliterate(base.lemma)) ~= base.lemma_translit then
insert("~ with phonetic respelling")
end
end
local key_entry = alternant_multiword_spec.first_noun or alternant_multiword_spec.first_adj or 1
if #alternant_multiword_spec.alternant_or_word_specs >= key_entry then
local alternant_or_word_spec = alternant_multiword_spec.alternant_or_word_specs[key_entry]
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
key_entry = multiword_spec.first_noun or multiword_spec.first_adj or 1
if #multiword_spec.word_specs >= key_entry then
do_word_spec(multiword_spec.word_specs[key_entry])
end
end
else
do_word_spec(alternant_or_word_spec)
end
end
if alternant_multiword_spec.number ~= "both" then
table.insert(annparts, alternant_multiword_spec.number == "sg" and "sg-only" or "pl-only")
end
if #decldescs == 0 then
table.insert(annparts, "indecl")
else
table.insert(annparts, table.concat(decldescs, " // "))
end
alternant_multiword_spec.annotation = table.concat(annparts, " ")
if #decldescs > 1 then
insert("~ with multiple declensions")
end
end
alternant_multiword_spec.categories = cats
end
local function show_forms(alternant_multiword_spec)
local lemmas = alternant_multiword_spec.forms.dir_s or alternant_multiword_spec.forms.dir_p or {}
local props = {
lemmas = lemmas,
slot_table = noun_slots_with_linked,
lang = lang,
include_translit = true,
-- Explicit additional top-level footnotes only occur with {{hi-ndecl-manual}} and variants.
footnotes = alternant_multiword_spec.footnotes,
allow_footnote_symbols = not not alternant_multiword_spec.footnotes,
}
iut.show_forms(alternant_multiword_spec.forms, props)
end
local function make_table(alternant_multiword_spec)
local forms = alternant_multiword_spec.forms
local table_top = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = '{title}{annotation}',
palette = 'blue',
tall = 'yes',
class = 'tr-alongside',
}
}
local table_bottom = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-bottom',
args = {
notes = forms.footnote or nil,
}
}
local table_spec_both = table_top .. [=[
!
! เอกพจน์
! พหูพจน์
|-
! การกตรง
| {dir_s}
| {dir_p}
|-
! การกอ้อม
| {obl_s}
| {obl_p}
|-
! สัมโพธนการก
| {voc_s}
| {voc_p}
]=] .. table_bottom
local table_spec_sg = table_top .. [=[
!
! เอกพจน์
|-
! การกตรง
| {dir_s}
|-
! การกอ้อม
| {obl_s}
|-
! สัมโพธนการก
| {voc_s}
]=] .. table_bottom
local table_spec_pl = table_top .. [=[
!
! พหูพจน์
|-
! การกตรง
| {dir_p}
|-
! การกอ้อม
| {obl_p}
|-
! สัมโพธนการก
| {voc_p}
]=] .. table_bottom
if alternant_multiword_spec.title then
forms.title = alternant_multiword_spec.title
else
forms.title = '<span class="nowrap">การผันรูปของ <i lang="hi" class="Deva">' .. forms.lemma .. '</i></span>'
end
local annotation = alternant_multiword_spec.annotation
if annotation == "" then
forms.annotation = ""
else
forms.annotation = ' <span class="nowrap" style="font-size: smaller;">(' .. annotation .. ")</span>"
end
local table_spec =
alternant_multiword_spec.number == "sg" and table_spec_sg or
alternant_multiword_spec.number == "pl" and table_spec_pl or
table_spec_both
forms.notes_clause = forms.footnote ~= "" and forms.footnote or ""
return m_string_utilities.format(table_spec, forms)
end
local function compute_headword_genders(alternant_multiword_spec)
local genders = {}
local number
if alternant_multiword_spec.number == "pl" then
number = "-p"
else
number = ""
end
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.gender == "M" then
m_table.insertIfNot(genders, "m" .. number)
elseif base.gender == "F" then
m_table.insertIfNot(genders, "f" .. number)
else
error("Internal error: Unrecognized gender '" ..
(base.gender or "nil") .. "'")
end
end)
return genders
end
-- Externally callable function to parse and decline a noun given user-specified arguments.
-- Return value is WORD_SPEC, an object where the declined forms are in `WORD_SPEC.forms`
-- for each slot. If there are no values for a slot, the slot key will be missing. The value
-- for a given slot is a list of objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms(parent_args, pos, from_headword, def)
local params = {
[1] = {required = true, default = "दुनिया<iyā>"},
footnote = {list = true},
title = true,
pagename = true,
json = {type = "boolean"},
}
if from_headword then
params["lemma"] = {list = true}
params["g"] = {list = true}
params["f"] = {list = true}
params["m"] = {list = true}
params["id"] = true
end
local args = m_para.process(parent_args, params)
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
lang = lang,
transliterate_respelling = com.transliterate_respelling,
allow_blank_lemma = true,
}
local alternant_multiword_spec = iut.parse_inflected_text(args[1], parse_props)
alternant_multiword_spec.title = args.title
alternant_multiword_spec.footnotes = args.footnote
alternant_multiword_spec.pos = pos or "nouns"
alternant_multiword_spec.args = args
alternant_multiword_spec.pagename = args.pagename
com.normalize_all_lemmas(alternant_multiword_spec, "always transliterate")
detect_all_indicator_specs(alternant_multiword_spec)
propagate_properties(alternant_multiword_spec, "number", "both", "both")
-- The default of "M" should apply only to plural adjectives, where it doesn't matter.
-- FIXME: This may be wrong for Hindi.
propagate_properties(alternant_multiword_spec, "gender", "M", "mixed")
determine_noun_status(alternant_multiword_spec)
local inflect_props = {
skip_slot = function(slot)
return skip_slot(alternant_multiword_spec.number, slot)
end,
slot_table = noun_slots_with_linked,
lang = lang,
inflect_word_spec = decline_noun,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
com.remove_redundant_translit(alternant_multiword_spec)
compute_categories_and_annotation(alternant_multiword_spec)
alternant_multiword_spec.genders = compute_headword_genders(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Externally callable function to parse and decline a noun where all forms
-- are given manually. Return value is WORD_SPEC, an object where the declined
-- forms are in `WORD_SPEC.forms` for each slot. If there are no values for a
-- slot, the slot key will be missing. The value for a given slot is a list of
-- objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms_manual(parent_args, number, pos, from_headword, def)
if number ~= "sg" and number ~= "pl" and number ~= "both" then
error("Internal error: number (arg 1) must be 'sg', 'pl' or 'both': '" .. number .. "'")
end
local params = {
footnote = {list = true},
title = true,
json = {type = "boolean"},
}
if number == "both" then
params[1] = {required = true, default = "तारीख़"}
params[2] = {required = true, default = "तवारीख़"}
params[3] = {required = true, default = "तारीख़"}
params[4] = {required = true, default = "तवारीख़ों"}
params[5] = {required = true, default = "तारीख़"}
params[6] = {required = true, default = "तवारीख़ो"}
elseif number == "sg" then
params[1] = {required = true, default = "अदला-बदला"}
params[2] = {required = true, default = "अदले-बदले"}
params[3] = {required = true, default = "अदले-बदले"}
else
params[1] = {required = true, default = "लोग"}
params[2] = {required = true, default = "लोगों"}
params[3] = {required = true, default = "लोगो"}
end
local args = m_para.process(parent_args, params)
local alternant_multiword_spec = {
title = args.title,
footnotes = args.footnote,
forms = {},
number = number,
pos = pos or "nouns",
manual = true,
}
process_manual_overrides(alternant_multiword_spec.forms, args, alternant_multiword_spec.number)
compute_categories_and_annotation(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Entry point for {{hi-ndecl}}. Template-callable function to parse and decline a noun given
-- user-specified arguments and generate a displayable table of the declined forms.
function export.show(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms(parent_args)
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
-- Entry point for {{hi-ndecl-manual}}, {{hi-ndecl-manual-sg}} and {{hi-ndecl-manual-pl}}.
-- Template-callable function to parse and decline a noun given manually-specified inflections
-- and generate a displayable table of the declined forms.
function export.show_manual(frame)
local iparams = {
[1] = {required = true},
}
local iargs = m_para.process(frame.args, iparams)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms_manual(parent_args, iargs[1])
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
return export
1qq370khnjrpcaizomhkxjp21p7scp8
5722538
5722537
2026-05-05T04:12:18Z
OctraBot
3198
5722538
Scribunto
text/plain
local export = {}
--[=[
Authorship: Ben Wing <benwing2>
]=]
--[=[
TERMINOLOGY:
-- "slot" = A particular combination of case/number.
Example slot names for nouns are "dir_s" (direct singular) and
"voc_p" (vocative plural). Each slot is filled with zero or more forms.
-- "form" = The declined Hindi form representing the value of a given slot.
-- "lemma" = The dictionary form of a given Hindi term. Generally the direct
masculine singular, but may occasionally be another form if the direct
masculine singular is missing.
]=]
local lang = require("Module:languages").getByCode("hi")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_string_utilities = require("Module:string utilities")
local iut = require("Module:inflection utilities")
local put = require("Module:parse utilities")
local m_para = require("Module:parameters")
local com = require("Module:hi-common")
local u = require("Module:string/char")
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rgmatch = mw.ustring.gmatch
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local usub = mw.ustring.sub
local uupper = mw.ustring.upper
local ulower = mw.ustring.lower
-- vowel diacritics; don't display nicely on their own
local M = u(0x0901)
local N = u(0x0902)
local MN_c = "[" .. M .. N .. "]"
local H = u(0x0903)
local AA = u(0x093e)
local E = u(0x0947)
local EN = E .. N
local I = u(0x093f)
local II = u(0x0940)
local O = u(0x094b)
local ON = O .. N
local U = u(0x0941)
local UU = u(0x0942)
local R = u(0x0943)
local VIRAMA = u(0x094d)
local TILDE = u(0x0303)
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
local retval, nsubs = rsubn(term, foo, bar)
return retval, nsubs > 0
end
local noun_slots = {
dir_s = "dir|s",
obl_s = "obl|s",
voc_s = "voc|s",
dir_p = "dir|p",
obl_p = "obl|p",
voc_p = "voc|p",
}
local noun_slots_with_linked = m_table.shallowCopy(noun_slots)
noun_slots_with_linked["dir_s_linked"] = "dir|s"
noun_slots_with_linked["dir_p_linked"] = "dir|p"
local input_params_to_slots_both = {
[1] = "dir_s",
[2] = "dir_p",
[3] = "obl_s",
[4] = "obl_p",
[5] = "voc_s",
[6] = "voc_p",
}
local input_params_to_slots_sg = {
[1] = "dir_s",
[2] = "obl_s",
[3] = "voc_s",
}
local input_params_to_slots_pl = {
[1] = "dir_p",
[2] = "obl_p",
[3] = "voc_p",
}
local cases = {
dir = true,
obl = true,
voc = true,
}
local function skip_slot(number, slot)
return number == "sg" and rfind(slot, "_p$") or
number == "pl" and rfind(slot, "_s$")
end
local function add(base, stem, translit_stem, slot, ending, footnotes)
if skip_slot(base.number, slot) then
return
end
com.add_form(base, stem, translit_stem, slot, ending, footnotes)
end
local function process_slot_overrides(base)
for slot, overrides in pairs(base.overrides) do
if skip_slot(base.number, slot) then
error("Override specified for invalid slot '" .. slot .. "' due to '" .. base.number .. "' number restriction")
end
base.forms[slot] = nil
for _, override in ipairs(overrides) do
for _, value in ipairs(override.values) do
local form = value.form
local tr = com.transliterate_respelling(value.phon_form)
local combined_notes = iut.combine_footnotes(base.footnotes, value.footnotes)
assert(override.full)
if form ~= "" then
iut.insert_form(base.forms, slot, {form = form, translit = tr, footnotes = combined_notes})
end
end
end
end
end
local function add_decl(base, stem, translit_stem, dir_s, obl_s, voc_s, dir_p, obl_p, voc_p,
footnotes
)
if not stem then
stem = base.lemma
translit_stem = base.lemma_translit
end
local plstem, pl_translit_stem = stem, translit_stem
if base.plstem then
plstem = base.plstem
pl_translit_stem = base.pl_translit_stem
end
add(base, stem, translit_stem, "dir_s", dir_s, footnotes)
add(base, stem, translit_stem, "obl_s", obl_s, footnotes)
add(base, stem, translit_stem, "voc_s", voc_s, footnotes)
add(base, plstem, pl_translit_stem, "dir_p", dir_p, footnotes)
add(base, plstem, pl_translit_stem, "obl_p", obl_p, footnotes)
add(base, plstem, pl_translit_stem, "voc_p", voc_p, footnotes)
end
local function handle_derived_slots_and_overrides(base)
process_slot_overrides(base)
-- Compute linked versions of potential lemma slots, for use in {{hi-noun}}.
-- We substitute the original lemma (before removing links) for forms that
-- are the same as the lemma, if the original lemma has links.
for _, slot in ipairs({"dir_s", "dir_p"}) do
iut.insert_forms(base.forms, slot .. "_linked", iut.map_forms(base.forms[slot], function(form)
if form == base.orig_lemma_no_links and rfind(base.orig_lemma, "%[%[") then
return base.orig_lemma
else
return form
end
end))
end
end
local function fetch_final_mn(base)
local mn = rmatch(base.lemma, "(" .. MN_c .. ")$")
if not mn then
error("Internal error: Lemma " .. base.lemma .. " should end in nasal vowel")
end
return mn
end
local decls = {}
local declprops = {}
decls["c-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", ON, O)
end
declprops["c-m"] = {
desc = "masc cons-stem",
cat = "masculine consonant-stem ~",
}
decls["c-f"] = function(base)
add_decl(base, nil, nil, "", "", "", EN, ON, O)
end
declprops["c-f"] = {
desc = "fem cons-stem",
cat = "feminine consonant-stem ~",
}
decls["ā-m"] = function(base)
if rfind(base.lemma, "या$") then
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "ए", "ए", "ए", "यों", "यो")
add_decl(base, stem, translit_stem, nil, "ये", "ये", "ये")
else
local stem, translit_stem = com.strip_ending(base, AA)
add_decl(base, stem, translit_stem, AA, E, E, E, ON, O)
end
end
-- E.g. तेंदुआ "leopard"
decls["ind-ā-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "आ")
add_decl(base, stem, translit_stem, "आ", "ए", "ए", "ए", "ओं", "ओ")
end
decls["unmarked-ā-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
declprops["unmarked-ā-m"] = {
desc = "masc unmarked ā-stem",
cat = "masculine unmarked ā-stem ~",
}
-- No need for ind-unmarked-ā-m because declension is "unmarked", i.e. all endings
-- are added after the vowel.
-- E.g. रेस्तराँ "restaurant"
decls["unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, AA .. "ओं", AA .. "ओं")
end
declprops["unmarked-ān-m"] = {
desc = "masc unmarked ā̃-stem",
cat = "masculine unmarked ā̃-stem ~",
}
decls["ind-unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "आओं", "आओं")
end
declprops["ind-unmarked-ān-m"] = {
desc = "masc ind unmarked ā̃-stem",
cat = "masculine independent unmarked ā̃-stem ~",
}
-- E.g. ख़ानसामाँ "butler, cook"
decls["ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, EN, EN, EN, ON, ON)
end
-- E.g. कुआँ "well"
decls["ind-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, "एँ", "एँ", "एँ", "ओं", "ओं")
end
decls["ā-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
-- No need for ind-ā-f because declension is "unmarked", i.e. all endings
-- are added after the vowel.
decls["ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, AA .. "एँ", AA .. "ओं", AA .. "ओं")
end
decls["ind-ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "आएँ", "आओं", "आओं")
end
decls["i-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "यों", "यो")
end
decls["i-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "याँ", "यों", "यो")
end
-- E.g. प्रधान मंत्री "prime minister"
decls["ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, II, I .. "यों", I .. "यो")
end
-- E.g. भाई "brother"
decls["ind-ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "ई", "इयों", "इयो")
end
decls["īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, II .. N, I .. "यों", I .. "यों")
end
decls["ind-īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "ईं", "इयों", "इयों")
end
decls["ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, I .. "याँ", I .. "यों", I .. "यो")
end
-- E.g. दवाई "medicine", डोई "wooden ladle", तेंदुई "female leopard", मिठाई "sweet, dessert"
decls["ind-ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "इयाँ", "इयों", "इयो")
end
decls["īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, I .. "याँ", I .. "यों", I .. "यों")
end
decls["ind-īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "इयाँ", "इयों", "इयों")
end
decls["iyā-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "या", "या", "याँ", "यों", "यो")
end
decls["iyān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "या" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "यों", "यों")
end
decls["o-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, O)
add_decl(base, stem, translit_stem, O, O, O, O, ON, O)
end
decls["on-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, ON)
add_decl(base, stem, translit_stem, ON, ON, ON, ON, ON, ON)
end
decls["u-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
decls["u-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
decls["ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, UU, U .. "ओं", U .. "ओ")
end
decls["ind-ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "ऊ", "उओं", "उओ")
end
decls["ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, U .. "ओं", U .. "ओं")
end
decls["ind-ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "उओं", "उओं")
end
decls["ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, U .. "एँ", U .. "ओं", U .. "ओ")
end
decls["ind-ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "उएँ", "उओं", "उओ")
end
-- E.g. जूँ "louse"
decls["ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, U .. "एँ", U .. "ओं", U .. "ओं")
end
decls["ind-ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "उएँ", "उओं", "उओं")
end
decls["r-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
-- E.g. प्रातः "morning"
decls["h-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, H)
add_decl(base, stem, translit_stem, H, H, H, H, ON, O)
end
decls["indecl"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "", "")
end
declprops["indecl"] = {
desc = "indecl",
cat = "indeclinable ~",
}
decls["adj"] = function(base, stress)
local adj_alternant_multiword_spec = require("Module:hi-adjective").do_generate_forms(
{base.lemma .. "//" .. base.lemma_translit}
)
local function copy(from_slot, to_slot)
base.forms[to_slot] = adj_alternant_multiword_spec.forms[from_slot]
end
if base.number ~= "pl" then
copy("dir_m_s", "dir_s")
copy("obl_m_s", "obl_s")
copy("voc_m_s", "voc_s")
end
if base.number ~= "sg" then
copy("dir_m_p", "dir_p")
copy("obl_m_p", "obl_p")
copy("voc_m_p", "voc_p")
end
end
declprops["adj"] = {
desc = "adj",
cat = "adjectival ~",
}
local function fetch_footnotes(separated_group)
local footnotes
for j = 2, #separated_group - 1, 2 do
if separated_group[j + 1] ~= "" then
error("Extraneous text after bracketed footnotes: '" .. table.concat(separated_group) .. "'")
end
if not footnotes then
footnotes = {}
end
table.insert(footnotes, separated_group[j])
end
return footnotes
end
--[=[
Parse a single override spec and return two values: the slot the override applies to,
and an object describing the override spec. The input is actually a list where the footnotes have been separated out. For example, given the spec 'oblpl:हज़ारों:हज़ारहा[rare]',
the input will be a list {"oblpl:हज़ारों:हज़ारहा", "[rare]", ""}. The object returned for
this example looks like this:
{
full = true,
values = {
{
form = "हज़ारों"
},
{
form = "हज़ारहा",
footnotes = {"[rare]"}
}
}
}
]=]
local function parse_override(segments)
local retval = {values = {}}
local part = segments[1]
local offset = 4
local case = usub(part, 1, 3)
if cases[case] then
-- ok
else
error("Internal error: unrecognized case in override: '" .. table.concat(segments) .. "'")
end
local rest = usub(part, offset)
local slot
if rfind(rest, "^pl") then
rest = rsub(rest, "^pl", "")
slot = case .. "_p"
else
slot = case .. "_s"
end
if rfind(rest, "^:") then
retval.full = true
rest = rsub(rest, "^:", "")
else
error("Suffix overrides not currently supported: " .. part)
end
segments[1] = rest
local colon_separated_groups = put.split_alternating_runs(segments, ":")
for i, colon_separated_group in ipairs(colon_separated_groups) do
local value = {}
local form = colon_separated_group[1]
if form == "" then
error("Use - to indicate an empty ending for slot '" .. slot .. "': '" .. table.concat(segments .. "'"))
elseif form == "-" then
value.form = ""
else
value.form, value.phon_form = com.split_term_respelling(form)
end
value.footnotes = fetch_footnotes(colon_separated_group)
table.insert(retval.values, value)
end
return slot, retval
end
--[=[
Parse an indicator spec (text consisting of angle brackets and zero or more
dot-separated indicators within them). Return value is an object of the form
{
overrides = {
SLOT = {OVERRIDE, OVERRIDE, ...}, -- as returned by parse_override()
...
},
forms = {}, -- forms for a single spec alternant; see `forms` below
footnotes = {"FOOTNOTE", "FOOTNOTE", ...}, -- may be missing
explicit_gender = "GENDER", -- "M", "F"; may be missing
number = "NUMBER", -- "sg", "pl"; may be missing
adj = true, -- may be missing
indecl = true, -- may be missing
unmarked = true, -- may be missing
iya = true, -- may be missing
plstem = "PLSTEM", -- may be missing
pl_phon_stem = "PLSTEM-PHONETIC-RESPELLING", -- as specified by the user; may be missing
pl_translit_stem = "PLSTEM-TRANSLIT", -- translit of pl_phon_stem (if present) or plstem; may be missing
-- The following additional fields are added by other functions:
orig_lemma = "ORIGINAL-LEMMA", -- as given by the user or taken from pagename
orig_lemma_no_links = "ORIGINAL-LEMMA-NO-LINKS", -- links removed
lemma = "LEMMA", -- `orig_lemma_no_links`, converted to singular form if plural
phon_lemma = "LEMMA-PHONETIC-RESPELLING", -- as specified by the user; may be missing
lemma_translit = "LEMMA-TRANSLIT", -- translit of phon_lemma (if present) or lemma
forms = {
SLOT = {
{
form = "FORM",
footnotes = {"FOOTNOTE", "FOOTNOTE", ...} -- may be missing
},
...
},
...
},
decl = "DECL", -- declension, e.g. "ind-ūn-f"
}
]=]
local function parse_indicator_spec(angle_bracket_spec)
local inside = rmatch(angle_bracket_spec, "^<(.*)>$")
assert(inside)
local base = {overrides = {}, forms = {}}
if inside ~= "" then
local segments = put.parse_balanced_segment_run(inside, "[", "]")
local dot_separated_groups = put.split_alternating_runs(segments, "%.")
for i, dot_separated_group in ipairs(dot_separated_groups) do
local part = dot_separated_group[1]
local case_prefix = usub(part, 1, 3)
if cases[case_prefix] then
local slot, override = parse_override(dot_separated_group)
if base.overrides[slot] then
table.insert(base.overrides[slot], override)
else
base.overrides[slot] = {override}
end
elseif part == "" then
if #dot_separated_group == 1 then
error("Blank indicator: '" .. inside .. "'")
end
base.footnotes = fetch_footnotes(dot_separated_group)
elseif #dot_separated_group > 1 then
error("Footnotes only allowed with slot overrides or by themselves: '" .. table.concat(dot_separated_group) .. "'")
elseif part == "M" or part == "F" then
if base.explicit_gender then
error("Can't specify gender twice: '" .. inside .. "'")
end
base.explicit_gender = part
elseif part == "sg" or part == "pl" then
if base.number then
error("Can't specify number twice: '" .. inside .. "'")
end
base.number = part
elseif part == "+" then
if base.adj then
error("Can't specify '+' twice: '" .. inside .. "'")
end
base.adj = true
elseif part == "$" then
if base.indecl then
error("Can't specify '$' twice: '" .. inside .. "'")
end
base.indecl = true
elseif part == "unmarked" then
if base.unmarked then
error("Can't specify 'unmarked' twice: '" .. inside .. "'")
end
base.unmarked = true
elseif part == "iyā" then
if base.iya then
error("Can't specify 'iyā' twice: '" .. inside .. "'")
end
base.iya = true
elseif rfind(part, "^plstem:") then
if base.plstem then
error("Can't specify plural stem twice: '" .. inside .. "'")
end
base.plstem, base.pl_phon_stem = com.split_term_respelling(rsub(part, "^plstem:", ""))
base.pl_translit_stem = com.transliterate_respelling(base.pl_phon_stem) or (lang:transliterate(base.plstem))
else
error("Unrecognized indicator '" .. part .. "': '" .. inside .. "'")
end
end
end
return base
end
local function set_defaults_and_check_bad_indicators(base)
-- Set default values.
if not base.adj and not base.indecl then
base.number = base.number or "both"
end
base.gender = base.explicit_gender
if base.iya then
if base.adj then
error("Can't specify both '+' and 'iya'")
end
if base.gender == "M" then
error("Can't specify M gender with 'iyā' indicator")
end
if not rfind(base.lemma, I .. "याँ?$") and not rfind(base.lemma, "-इयाँ?$") then
error("With 'iyā' indicator, lemma must end in " .. I .. "या or " .. I .. "याँ: " .. base.lemma)
end
base.gender = "F"
end
if base.unmarked then
if base.adj then
error("Can't specify both '+' and 'unmarked'")
end
if base.iya then
error("Can't specify both 'iya' and 'unmarked'")
end
if base.gender == "F" then
error("Can't specify F gender with 'unmarked' indicator")
end
base.gender = "M"
end
if rfind(base.lemma, "[" .. O .. H .. R .. "]$") then
if base.gender == "F" then
error("Can't specify F gender with lemma ending in " .. O .. ", " .. H .. " or " .. R .. ": " .. base.lemma)
end
base.gender = "M"
end
if not base.gender and not base.adj and not base.indecl then
error("Unless lemma is in " .. O .. ", " .. H .. " or " .. R .. " or 'iya', 'unmarked' or '$' specified, gender must be given: " .. base.lemma)
end
if base.adj and base.indecl then
error("Can't specify both '+' and '$' on the same lemma " .. base.lemma)
end
end
-- For a plural-only lemma, synthesize a likely singular lemma. It doesn't have to be
-- theoretically correct as long as it generates all the correct plural forms.
local function synthesize_singular_lemma(base)
if not base.gender then
error("For plural-only lemma, need to specify the gender: '" .. base.lemma .. "'")
end
if base.gender == "M" then
if rfind(base.lemma, E .. "$") then
local stem, translit_stem = com.strip_ending(base, E)
base.lemma = stem .. AA
base.lemma_translit = translit_stem .. "ā"
return
end
if rfind(base.lemma, "ए$") then
-- FIXME, what about -iyā -> -ie?
local stem, translit_stem = com.strip_ending(base, "ए")
base.lemma = stem .. "अ"
base.lemma_translit = translit_stem .. "ā"
return
end
local ending = rmatch(base.lemma, "(" .. E .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. AA .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. "अ" .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
-- Otherwise, singular same as plural and lemma is already correct.
else
assert(base.gender == "F")
local function add_dir_p_override()
-- Add an override to force the direct plural to match. This is needed below
-- in case the lemma ends in anusvara instead of chandrabindu (because the
-- declension functions generate a direct plural with chandrabindu) and also
-- when the direct plural is the same as the singular.
if not base.overrides.dir_p then
base.overrides.dir_p = {}
end
table.insert(base.overrides.dir_p, {full = true, values = {{form = base.lemma, phon_form = base.lemma_translit}}})
end
local ending = rmatch(base.lemma, "(" .. EN .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(या " .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
-- This may or may not produce the "right" singular but regardless,
-- the plural will be correct, which is all that matters.
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
-- We seem to have an endingless plural, e.g. औलाद. Add an override to the dir_p slot
-- to force this form.
add_dir_p_override()
end
end
-- For an adjectival lemma, synthesize the masc singular form.
local function synthesize_adj_lemma(base)
if not rfind(base.lemma, "[अ" .. AA .. "]" .. MN_c .. "?$") then
error("Unrecognized adjectival lemma: " .. base.lemma)
end
base.gender = "M"
base.decl = "adj"
end
-- Determine the declension based on the lemma and gender. The declension is
-- set in base.decl.
local function determine_declension(base)
if base.decl then
return
end
assert(not base.adj)
if base.indecl then
base.decl = "indecl"
elseif base.gender == "M" then
if base.unmarked then
if rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "unmarked-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "unmarked-ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-unmarked-ān-m"
else
error("With 'unmarked' indicator, lemma must end in " .. AA .. ", " .. AA .. M .. ", " ..
AA .. N .. ", आ, आँ: or आं " .. base.lemma)
end
elseif rfind(base.lemma, AA .. "$") then
base.decl = "ā-m"
elseif rfind(base.lemma, "आ$") then
base.decl = "ind-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-m"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-m"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-m"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-m"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-m"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-m"
elseif rfind(base.lemma, O .. "$") then
base.decl = "o-m"
elseif rfind(base.lemma, O .. N .. "$") then
base.decl = "on-m"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-m"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-m"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-m"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-m"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-m"
elseif rfind(base.lemma, R .. "$") then
base.decl = "r-m"
elseif rfind(base.lemma, H .. "$") then
base.decl = "h-m"
else
base.decl = "c-m"
end
else
assert(base.gender == "F")
if base.iya then
if rfind(base.lemma, MN_c .. "$") then
base.decl = "iyān-f"
else
base.decl = "iyā-f"
end
elseif rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "ā-f"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-f"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-f"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-f"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-f"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-f"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-f"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-f"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-f"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-f"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-f"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-f"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-f"
else
base.decl = "c-f"
end
end
end
local function detect_indicator_spec(base)
set_defaults_and_check_bad_indicators(base)
if base.adj then
synthesize_adj_lemma(base)
else
if base.number == "pl" then
synthesize_singular_lemma(base)
end
determine_declension(base)
end
end
local function detect_all_indicator_specs(alternant_multiword_spec)
iut.map_word_specs(alternant_multiword_spec, function(base)
detect_indicator_spec(base)
end)
end
local propagate_multiword_properties
local function propagate_alternant_properties(alternant_spec, property, mixed_value, nouns_only)
local seen_property
for _, multiword_spec in ipairs(alternant_spec.alternants) do
propagate_multiword_properties(multiword_spec, property, mixed_value, nouns_only)
if seen_property == nil then
seen_property = multiword_spec[property]
elseif multiword_spec[property] and seen_property ~= multiword_spec[property] then
seen_property = mixed_value
end
end
alternant_spec[property] = seen_property
end
propagate_multiword_properties = function(multiword_spec, property, mixed_value, nouns_only)
local seen_property = nil
local last_seen_nounal_pos = 0
local word_specs = multiword_spec.alternant_or_word_specs or multiword_spec.word_specs
for i = 1, #word_specs do
local is_nounal
if word_specs[i].alternants then
propagate_alternant_properties(word_specs[i], property, mixed_value)
is_nounal = not not word_specs[i][property]
elseif nouns_only then
is_nounal = not word_specs[i].adj and not word_specs[i].indecl
else
is_nounal = not not word_specs[i][property]
end
if is_nounal then
if not word_specs[i][property] then
error("Internal error: noun-type word spec without " .. property .. " set")
end
for j = last_seen_nounal_pos + 1, i - 1 do
word_specs[j][property] = word_specs[j][property] or word_specs[i][property]
end
last_seen_nounal_pos = i
if seen_property == nil then
seen_property = word_specs[i][property]
elseif seen_property ~= word_specs[i][property] then
seen_property = mixed_value
end
end
end
if last_seen_nounal_pos > 0 then
for i = last_seen_nounal_pos + 1, #word_specs do
word_specs[i][property] = word_specs[i][property] or word_specs[last_seen_nounal_pos][property]
end
end
multiword_spec[property] = seen_property
end
local function propagate_properties_downward(alternant_multiword_spec, property, default_propval)
local propval1 = alternant_multiword_spec[property] or default_propval
for _, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
local propval2 = alternant_or_word_spec[property] or propval1
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
local propval3 = multiword_spec[property] or propval2
for _, word_spec in ipairs(multiword_spec.word_specs) do
local propval4 = word_spec[property] or propval3
if propval4 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
word_spec[property] = propval4
end
end
else
if propval2 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
alternant_or_word_spec[property] = propval2
end
end
end
--[=[
Propagate `property` (one of "animacy", "gender" or "number") from nouns to adjacent
adjectives. We proceed as follows:
1. We assume the properties in question are already set on all nouns. This should happen
in set_defaults_and_check_bad_indicators().
2. We first propagate properties upwards and sideways. We recurse downwards from the top.
When we encounter a multiword spec, we proceed left to right looking for a noun.
When we find a noun, we fetch its property (recursing if the noun is an alternant),
and propagate it to any adjectives to its left, up to the next noun to the left.
When we have processed the last noun, we also propagate its property value to any
adjectives to the right (to handle e.g. [[пустальга звычайная]] "common kestrel", where
the adjective польовий should inherit the 'animal' animacy of лунь). Finally, we set
the property value for the multiword spec itself by combining all the non-nil
properties of the individual elements. If all non-nil properties have the same value,
the result is that value, otherwise it is `mixed_value` (which is "mixed" for animacy
and gender, but "both" for number).
3. When we encounter an alternant spec in this process, we recursively process each
alternant (which is a multiword spec) using the previous step, and combine any
non-nil properties we encounter the same way as for multiword specs.
4. The effect of steps 2 and 3 is to set the property of each alternant and multiword
spec based on its children or its neighbors.
]=]
local function propagate_properties(alternant_multiword_spec, property, default_propval, mixed_value)
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, "nouns only")
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, false)
propagate_properties_downward(alternant_multiword_spec, property, default_propval)
end
-- Find the first noun in a multiword expression and set alternant_multiword_spec.first_noun
-- to the index of that noun. Also find the first adjective and set alternant_multiword_spec.first_adj
-- similarly. If there is a first noun, we use its properties to determine the overall expression's
-- properties; otherwise we use the first adjective's properties, otherwise the first word's properties.
-- If the "word" located this way is not an alternant spec, we just use its properties directly, otherwise
-- we use the properties of the first noun (or failing that the first adjective, or failing that the
-- first word) in each alternative alternant in the alternant spec. For this reason, we need to set the
-- the .first_noun of and .first_adj of each multiword expression embedded in the first noun alternant spec,
-- and the .first_adj of each multiword expression in each adjective alternant spec leading up to the
-- first noun alternant spec.
local function determine_noun_status(alternant_multiword_spec)
for i, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
if alternant_or_word_spec.alternants then
local alternant_type
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
for j, word_spec in ipairs(multiword_spec.word_specs) do
if not word_spec.indecl then
if not word_spec.adj then
multiword_spec.first_noun = j
alternant_type = "noun"
break
elseif not multiword_spec.first_adj then
multiword_spec.first_adj = j
if not alternant_type then
alternant_type = "adj"
end
end
end
end
end
if alternant_type == "noun" then
alternant_multiword_spec.first_noun = i
return
elseif alternant_type == "adj" and not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
elseif not alternant_or_word_spec.indecl then
if not alternant_or_word_spec.adj then
alternant_multiword_spec.first_noun = i
return
elseif not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
end
end
end
local function decline_noun(base)
if not decls[base.decl] then
error("Internal error: Unrecognized declension type '" .. base.decl .. "'")
end
decls[base.decl](base)
handle_derived_slots_and_overrides(base)
end
local function process_manual_overrides(forms, args, number)
local params_to_slots_map =
number == "sg" and input_params_to_slots_sg or
number == "pl" and input_params_to_slots_pl or
input_params_to_slots_both
for param, slot in pairs(params_to_slots_map) do
if args[param] then
forms[slot] = nil
if args[param] ~= "-" and args[param] ~= "—" then
for _, form in ipairs(rsplit(args[param], "%s*,%s*")) do
local hi, phon = com.split_term_respelling(form)
local tr = phon and com.transliterate_respelling(phon) or nil
iut.insert_form(forms, slot, {form=form, translit=tr})
end
end
end
end
end
local function compute_category_and_desc(base)
local props = declprops[base.decl]
if props then
return props.cat, props.desc
end
local rest, gender = rmatch(base.decl, "^(.+)%-([mf])$")
if not gender then
error("Internal error: Don't know how to parse decl '" .. base.decl .. "'")
end
local cat_gender = gender == "m" and "masculine" or "feminine"
local desc_gender = gender == "m" and "เพศชาย" or "เพศหญิง"
local ind, stem = rmatch(rest, "^(ind%-)(.*)$")
if not ind then
stem = rest
end
stem = rsub(stem, "n$", TILDE)
if ind then
return cat_gender .. " independent " .. stem .. "-stem ~", desc_gender .. " ind " .. stem .. "-stem"
else
return cat_gender .. " " .. stem .. "-stem ~", desc_gender .. " " .. stem .. "-stem"
end
end
-- Compute the categories to add the noun to, as well as the annotation to display in the
-- declension title bar. We combine the code to do these functions as both categories and
-- title bar contain similar information.
local function compute_categories_and_annotation(alternant_multiword_spec)
local cats = {}
local function insert(cattype)
cattype = rsub(cattype, "~", alternant_multiword_spec.pos)
m_table.insertIfNot(cats, "Hindi " .. cattype)
end
if alternant_multiword_spec.number == "sg" then
insert("uncountable ~")
elseif alternant_multiword_spec.number == "pl" then
insert("pluralia tantum")
end
local annotation
if alternant_multiword_spec.manual then
alternant_multiword_spec.annotation =
alternant_multiword_spec.number == "sg" and "sg-only" or
alternant_multiword_spec.number == "pl" and "pl-only" or
""
else
local annparts = {}
local decldescs = {}
local function do_word_spec(base)
local cat, desc = compute_category_and_desc(base)
insert(cat)
m_table.insertIfNot(decldescs, desc)
if base.plstem then
insert("~ with irregular plural stem")
end
if (lang:transliterate(base.lemma)) ~= base.lemma_translit then
insert("~ with phonetic respelling")
end
end
local key_entry = alternant_multiword_spec.first_noun or alternant_multiword_spec.first_adj or 1
if #alternant_multiword_spec.alternant_or_word_specs >= key_entry then
local alternant_or_word_spec = alternant_multiword_spec.alternant_or_word_specs[key_entry]
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
key_entry = multiword_spec.first_noun or multiword_spec.first_adj or 1
if #multiword_spec.word_specs >= key_entry then
do_word_spec(multiword_spec.word_specs[key_entry])
end
end
else
do_word_spec(alternant_or_word_spec)
end
end
if alternant_multiword_spec.number ~= "both" then
table.insert(annparts, alternant_multiword_spec.number == "sg" and "sg-only" or "pl-only")
end
if #decldescs == 0 then
table.insert(annparts, "indecl")
else
table.insert(annparts, table.concat(decldescs, " // "))
end
alternant_multiword_spec.annotation = table.concat(annparts, " ")
if #decldescs > 1 then
insert("~ with multiple declensions")
end
end
alternant_multiword_spec.categories = cats
end
local function show_forms(alternant_multiword_spec)
local lemmas = alternant_multiword_spec.forms.dir_s or alternant_multiword_spec.forms.dir_p or {}
local props = {
lemmas = lemmas,
slot_table = noun_slots_with_linked,
lang = lang,
include_translit = true,
-- Explicit additional top-level footnotes only occur with {{hi-ndecl-manual}} and variants.
footnotes = alternant_multiword_spec.footnotes,
allow_footnote_symbols = not not alternant_multiword_spec.footnotes,
}
iut.show_forms(alternant_multiword_spec.forms, props)
end
local function make_table(alternant_multiword_spec)
local forms = alternant_multiword_spec.forms
local table_top = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = '{title}{annotation}',
palette = 'blue',
tall = 'yes',
class = 'tr-alongside',
}
}
local table_bottom = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-bottom',
args = {
notes = forms.footnote or nil,
}
}
local table_spec_both = table_top .. [=[
!
! เอกพจน์
! พหูพจน์
|-
! การกตรง
| {dir_s}
| {dir_p}
|-
! การกอ้อม
| {obl_s}
| {obl_p}
|-
! สัมโพธนการก
| {voc_s}
| {voc_p}
]=] .. table_bottom
local table_spec_sg = table_top .. [=[
!
! เอกพจน์
|-
! การกตรง
| {dir_s}
|-
! การกอ้อม
| {obl_s}
|-
! สัมโพธนการก
| {voc_s}
]=] .. table_bottom
local table_spec_pl = table_top .. [=[
!
! พหูพจน์
|-
! การกตรง
| {dir_p}
|-
! การกอ้อม
| {obl_p}
|-
! สัมโพธนการก
| {voc_p}
]=] .. table_bottom
if alternant_multiword_spec.title then
forms.title = alternant_multiword_spec.title
else
forms.title = '<span class="nowrap">การผันรูปของ <i lang="hi" class="Deva">' .. forms.lemma .. '</i></span>'
end
local annotation = alternant_multiword_spec.annotation
if annotation == "" then
forms.annotation = ""
else
forms.annotation = ' <span class="nowrap" style="font-size: smaller;">(' .. annotation .. ")</span>"
end
local table_spec =
alternant_multiword_spec.number == "sg" and table_spec_sg or
alternant_multiword_spec.number == "pl" and table_spec_pl or
table_spec_both
forms.notes_clause = forms.footnote ~= "" and forms.footnote or ""
return m_string_utilities.format(table_spec, forms)
end
local function compute_headword_genders(alternant_multiword_spec)
local genders = {}
local number
if alternant_multiword_spec.number == "pl" then
number = "-p"
else
number = ""
end
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.gender == "M" then
m_table.insertIfNot(genders, "m" .. number)
elseif base.gender == "F" then
m_table.insertIfNot(genders, "f" .. number)
else
error("Internal error: Unrecognized gender '" ..
(base.gender or "nil") .. "'")
end
end)
return genders
end
-- Externally callable function to parse and decline a noun given user-specified arguments.
-- Return value is WORD_SPEC, an object where the declined forms are in `WORD_SPEC.forms`
-- for each slot. If there are no values for a slot, the slot key will be missing. The value
-- for a given slot is a list of objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms(parent_args, pos, from_headword, def)
local params = {
[1] = {required = true, default = "दुनिया<iyā>"},
footnote = {list = true},
title = true,
pagename = true,
json = {type = "boolean"},
}
if from_headword then
params["lemma"] = {list = true}
params["g"] = {list = true}
params["f"] = {list = true}
params["m"] = {list = true}
params["id"] = true
end
local args = m_para.process(parent_args, params)
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
lang = lang,
transliterate_respelling = com.transliterate_respelling,
allow_blank_lemma = true,
}
local alternant_multiword_spec = iut.parse_inflected_text(args[1], parse_props)
alternant_multiword_spec.title = args.title
alternant_multiword_spec.footnotes = args.footnote
alternant_multiword_spec.pos = pos or "nouns"
alternant_multiword_spec.args = args
alternant_multiword_spec.pagename = args.pagename
com.normalize_all_lemmas(alternant_multiword_spec, "always transliterate")
detect_all_indicator_specs(alternant_multiword_spec)
propagate_properties(alternant_multiword_spec, "number", "both", "both")
-- The default of "M" should apply only to plural adjectives, where it doesn't matter.
-- FIXME: This may be wrong for Hindi.
propagate_properties(alternant_multiword_spec, "gender", "M", "mixed")
determine_noun_status(alternant_multiword_spec)
local inflect_props = {
skip_slot = function(slot)
return skip_slot(alternant_multiword_spec.number, slot)
end,
slot_table = noun_slots_with_linked,
lang = lang,
inflect_word_spec = decline_noun,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
com.remove_redundant_translit(alternant_multiword_spec)
compute_categories_and_annotation(alternant_multiword_spec)
alternant_multiword_spec.genders = compute_headword_genders(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Externally callable function to parse and decline a noun where all forms
-- are given manually. Return value is WORD_SPEC, an object where the declined
-- forms are in `WORD_SPEC.forms` for each slot. If there are no values for a
-- slot, the slot key will be missing. The value for a given slot is a list of
-- objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms_manual(parent_args, number, pos, from_headword, def)
if number ~= "sg" and number ~= "pl" and number ~= "both" then
error("Internal error: number (arg 1) must be 'sg', 'pl' or 'both': '" .. number .. "'")
end
local params = {
footnote = {list = true},
title = true,
json = {type = "boolean"},
}
if number == "both" then
params[1] = {required = true, default = "तारीख़"}
params[2] = {required = true, default = "तवारीख़"}
params[3] = {required = true, default = "तारीख़"}
params[4] = {required = true, default = "तवारीख़ों"}
params[5] = {required = true, default = "तारीख़"}
params[6] = {required = true, default = "तवारीख़ो"}
elseif number == "sg" then
params[1] = {required = true, default = "अदला-बदला"}
params[2] = {required = true, default = "अदले-बदले"}
params[3] = {required = true, default = "अदले-बदले"}
else
params[1] = {required = true, default = "लोग"}
params[2] = {required = true, default = "लोगों"}
params[3] = {required = true, default = "लोगो"}
end
local args = m_para.process(parent_args, params)
local alternant_multiword_spec = {
title = args.title,
footnotes = args.footnote,
forms = {},
number = number,
pos = pos or "nouns",
manual = true,
}
process_manual_overrides(alternant_multiword_spec.forms, args, alternant_multiword_spec.number)
compute_categories_and_annotation(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Entry point for {{hi-ndecl}}. Template-callable function to parse and decline a noun given
-- user-specified arguments and generate a displayable table of the declined forms.
function export.show(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms(parent_args)
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
-- Entry point for {{hi-ndecl-manual}}, {{hi-ndecl-manual-sg}} and {{hi-ndecl-manual-pl}}.
-- Template-callable function to parse and decline a noun given manually-specified inflections
-- and generate a displayable table of the declined forms.
function export.show_manual(frame)
local iparams = {
[1] = {required = true},
}
local iargs = m_para.process(frame.args, iparams)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms_manual(parent_args, iargs[1])
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
return export
fhqf0gv2dduwnlihi0xfa4bt2nknsmq
5722539
5722538
2026-05-05T04:18:58Z
OctraBot
3198
5722539
Scribunto
text/plain
local export = {}
--[=[
Authorship: Ben Wing <benwing2>
]=]
--[=[
TERMINOLOGY:
-- "slot" = A particular combination of case/number.
Example slot names for nouns are "dir_s" (direct singular) and
"voc_p" (vocative plural). Each slot is filled with zero or more forms.
-- "form" = The declined Hindi form representing the value of a given slot.
-- "lemma" = The dictionary form of a given Hindi term. Generally the direct
masculine singular, but may occasionally be another form if the direct
masculine singular is missing.
]=]
local lang = require("Module:languages").getByCode("hi")
local m_table = require("Module:table")
local m_links = require("Module:links")
local m_string_utilities = require("Module:string utilities")
local iut = require("Module:inflection utilities")
local put = require("Module:parse utilities")
local m_para = require("Module:parameters")
local com = require("Module:hi-common")
local u = require("Module:string/char")
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rgmatch = mw.ustring.gmatch
local rsubn = mw.ustring.gsub
local ulen = mw.ustring.len
local usub = mw.ustring.sub
local uupper = mw.ustring.upper
local ulower = mw.ustring.lower
-- vowel diacritics; don't display nicely on their own
local M = u(0x0901)
local N = u(0x0902)
local MN_c = "[" .. M .. N .. "]"
local H = u(0x0903)
local AA = u(0x093e)
local E = u(0x0947)
local EN = E .. N
local I = u(0x093f)
local II = u(0x0940)
local O = u(0x094b)
local ON = O .. N
local U = u(0x0941)
local UU = u(0x0942)
local R = u(0x0943)
local VIRAMA = u(0x094d)
local TILDE = u(0x0303)
-- version of rsubn() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
-- version of rsubn() that returns a 2nd argument boolean indicating whether
-- a substitution was made.
local function rsubb(term, foo, bar)
local retval, nsubs = rsubn(term, foo, bar)
return retval, nsubs > 0
end
local noun_slots = {
dir_s = "dir|s",
obl_s = "obl|s",
voc_s = "voc|s",
dir_p = "dir|p",
obl_p = "obl|p",
voc_p = "voc|p",
}
local noun_slots_with_linked = m_table.shallowCopy(noun_slots)
noun_slots_with_linked["dir_s_linked"] = "dir|s"
noun_slots_with_linked["dir_p_linked"] = "dir|p"
local input_params_to_slots_both = {
[1] = "dir_s",
[2] = "dir_p",
[3] = "obl_s",
[4] = "obl_p",
[5] = "voc_s",
[6] = "voc_p",
}
local input_params_to_slots_sg = {
[1] = "dir_s",
[2] = "obl_s",
[3] = "voc_s",
}
local input_params_to_slots_pl = {
[1] = "dir_p",
[2] = "obl_p",
[3] = "voc_p",
}
local cases = {
dir = true,
obl = true,
voc = true,
}
local function skip_slot(number, slot)
return number == "sg" and rfind(slot, "_p$") or
number == "pl" and rfind(slot, "_s$")
end
local function add(base, stem, translit_stem, slot, ending, footnotes)
if skip_slot(base.number, slot) then
return
end
com.add_form(base, stem, translit_stem, slot, ending, footnotes)
end
local function process_slot_overrides(base)
for slot, overrides in pairs(base.overrides) do
if skip_slot(base.number, slot) then
error("Override specified for invalid slot '" .. slot .. "' due to '" .. base.number .. "' number restriction")
end
base.forms[slot] = nil
for _, override in ipairs(overrides) do
for _, value in ipairs(override.values) do
local form = value.form
local tr = com.transliterate_respelling(value.phon_form)
local combined_notes = iut.combine_footnotes(base.footnotes, value.footnotes)
assert(override.full)
if form ~= "" then
iut.insert_form(base.forms, slot, {form = form, translit = tr, footnotes = combined_notes})
end
end
end
end
end
local function add_decl(base, stem, translit_stem, dir_s, obl_s, voc_s, dir_p, obl_p, voc_p,
footnotes
)
if not stem then
stem = base.lemma
translit_stem = base.lemma_translit
end
local plstem, pl_translit_stem = stem, translit_stem
if base.plstem then
plstem = base.plstem
pl_translit_stem = base.pl_translit_stem
end
add(base, stem, translit_stem, "dir_s", dir_s, footnotes)
add(base, stem, translit_stem, "obl_s", obl_s, footnotes)
add(base, stem, translit_stem, "voc_s", voc_s, footnotes)
add(base, plstem, pl_translit_stem, "dir_p", dir_p, footnotes)
add(base, plstem, pl_translit_stem, "obl_p", obl_p, footnotes)
add(base, plstem, pl_translit_stem, "voc_p", voc_p, footnotes)
end
local function handle_derived_slots_and_overrides(base)
process_slot_overrides(base)
-- Compute linked versions of potential lemma slots, for use in {{hi-noun}}.
-- We substitute the original lemma (before removing links) for forms that
-- are the same as the lemma, if the original lemma has links.
for _, slot in ipairs({"dir_s", "dir_p"}) do
iut.insert_forms(base.forms, slot .. "_linked", iut.map_forms(base.forms[slot], function(form)
if form == base.orig_lemma_no_links and rfind(base.orig_lemma, "%[%[") then
return base.orig_lemma
else
return form
end
end))
end
end
local function fetch_final_mn(base)
local mn = rmatch(base.lemma, "(" .. MN_c .. ")$")
if not mn then
error("Internal error: Lemma " .. base.lemma .. " should end in nasal vowel")
end
return mn
end
local decls = {}
local declprops = {}
decls["c-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", ON, O)
end
declprops["c-m"] = {
desc = "masc cons-stem",
cat = "masculine consonant-stem ~",
}
decls["c-f"] = function(base)
add_decl(base, nil, nil, "", "", "", EN, ON, O)
end
declprops["c-f"] = {
desc = "fem cons-stem",
cat = "feminine consonant-stem ~",
}
decls["ā-m"] = function(base)
if rfind(base.lemma, "या$") then
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "ए", "ए", "ए", "यों", "यो")
add_decl(base, stem, translit_stem, nil, "ये", "ये", "ये")
else
local stem, translit_stem = com.strip_ending(base, AA)
add_decl(base, stem, translit_stem, AA, E, E, E, ON, O)
end
end
-- E.g. तेंदुआ "leopard"
decls["ind-ā-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "आ")
add_decl(base, stem, translit_stem, "आ", "ए", "ए", "ए", "ओं", "ओ")
end
decls["unmarked-ā-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
declprops["unmarked-ā-m"] = {
desc = "masc unmarked ā-stem",
cat = "masculine unmarked ā-stem ~",
}
-- No need for ind-unmarked-ā-m because declension is "unmarked", i.e. all endings
-- are added after the vowel.
-- E.g. रेस्तराँ "restaurant"
decls["unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, AA .. "ओं", AA .. "ओं")
end
declprops["unmarked-ān-m"] = {
desc = "masc unmarked ā̃-stem",
cat = "masculine unmarked ā̃-stem ~",
}
decls["ind-unmarked-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "आओं", "आओं")
end
declprops["ind-unmarked-ān-m"] = {
desc = "masc ind unmarked ā̃-stem",
cat = "masculine independent unmarked ā̃-stem ~",
}
-- E.g. ख़ानसामाँ "butler, cook"
decls["ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, EN, EN, EN, ON, ON)
end
-- E.g. कुआँ "well"
decls["ind-ān-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, "एँ", "एँ", "एँ", "ओं", "ओं")
end
decls["ā-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
-- No need for ind-ā-f because declension is "unmarked", i.e. all endings
-- are added after the vowel.
decls["ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = AA .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, AA .. "एँ", AA .. "ओं", AA .. "ओं")
end
decls["ind-ān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "आ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "आएँ", "आओं", "आओं")
end
decls["i-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "यों", "यो")
end
decls["i-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "याँ", "यों", "यो")
end
-- E.g. प्रधान मंत्री "prime minister"
decls["ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, II, I .. "यों", I .. "यो")
end
-- E.g. भाई "brother"
decls["ind-ī-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "ई", "इयों", "इयो")
end
decls["īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, II .. N, I .. "यों", I .. "यों")
end
decls["ind-īn-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "ईं", "इयों", "इयों")
end
decls["ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II)
add_decl(base, stem, translit_stem, II, II, II, I .. "याँ", I .. "यों", I .. "यो")
end
-- E.g. दवाई "medicine", डोई "wooden ladle", तेंदुई "female leopard", मिठाई "sweet, dessert"
decls["ind-ī-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ई")
add_decl(base, stem, translit_stem, "ई", "ई", "ई", "इयाँ", "इयों", "इयो")
end
decls["īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, II .. N)
add_decl(base, stem, translit_stem, II .. N, II .. N, II .. N, I .. "याँ", I .. "यों", I .. "यों")
end
decls["ind-īn-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ईं")
add_decl(base, stem, translit_stem, "ईं", "ईं", "ईं", "इयाँ", "इयों", "इयों")
end
decls["iyā-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "या")
add_decl(base, stem, translit_stem, "या", "या", "या", "याँ", "यों", "यो")
end
decls["iyān-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "या" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "यों", "यों")
end
decls["o-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, O)
add_decl(base, stem, translit_stem, O, O, O, O, ON, O)
end
decls["on-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, ON)
add_decl(base, stem, translit_stem, ON, ON, ON, ON, ON, ON)
end
decls["u-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
decls["u-f"] = function(base)
add_decl(base, nil, nil, "", "", "", "एँ", "ओं", "ओ")
end
decls["ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, UU, U .. "ओं", U .. "ओ")
end
decls["ind-ū-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "ऊ", "उओं", "उओ")
end
decls["ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, U .. "ओं", U .. "ओं")
end
decls["ind-ūn-m"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, ending, "उओं", "उओं")
end
decls["ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, UU)
add_decl(base, stem, translit_stem, UU, UU, UU, U .. "एँ", U .. "ओं", U .. "ओ")
end
decls["ind-ū-f"] = function(base)
local stem, translit_stem = com.strip_ending(base, "ऊ")
add_decl(base, stem, translit_stem, "ऊ", "ऊ", "ऊ", "उएँ", "उओं", "उओ")
end
-- E.g. जूँ "louse"
decls["ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = UU .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, U .. "एँ", U .. "ओं", U .. "ओं")
end
decls["ind-ūn-f"] = function(base)
local mn = fetch_final_mn(base)
local ending = "ऊ" .. mn
local stem, translit_stem = com.strip_ending(base, ending)
add_decl(base, stem, translit_stem, ending, ending, ending, "उएँ", "उओं", "उओं")
end
decls["r-m"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "ओं", "ओ")
end
-- E.g. प्रातः "morning"
decls["h-m"] = function(base)
local stem, translit_stem = com.strip_ending(base, H)
add_decl(base, stem, translit_stem, H, H, H, H, ON, O)
end
decls["indecl"] = function(base)
add_decl(base, nil, nil, "", "", "", "", "", "")
end
declprops["indecl"] = {
desc = "indecl",
cat = "indeclinable ~",
}
decls["adj"] = function(base, stress)
local adj_alternant_multiword_spec = require("Module:hi-adjective").do_generate_forms(
{base.lemma .. "//" .. base.lemma_translit}
)
local function copy(from_slot, to_slot)
base.forms[to_slot] = adj_alternant_multiword_spec.forms[from_slot]
end
if base.number ~= "pl" then
copy("dir_m_s", "dir_s")
copy("obl_m_s", "obl_s")
copy("voc_m_s", "voc_s")
end
if base.number ~= "sg" then
copy("dir_m_p", "dir_p")
copy("obl_m_p", "obl_p")
copy("voc_m_p", "voc_p")
end
end
declprops["adj"] = {
desc = "adj",
cat = "adjectival ~",
}
local function fetch_footnotes(separated_group)
local footnotes
for j = 2, #separated_group - 1, 2 do
if separated_group[j + 1] ~= "" then
error("Extraneous text after bracketed footnotes: '" .. table.concat(separated_group) .. "'")
end
if not footnotes then
footnotes = {}
end
table.insert(footnotes, separated_group[j])
end
return footnotes
end
--[=[
Parse a single override spec and return two values: the slot the override applies to,
and an object describing the override spec. The input is actually a list where the footnotes have been separated out. For example, given the spec 'oblpl:हज़ारों:हज़ारहा[rare]',
the input will be a list {"oblpl:हज़ारों:हज़ारहा", "[rare]", ""}. The object returned for
this example looks like this:
{
full = true,
values = {
{
form = "हज़ारों"
},
{
form = "हज़ारहा",
footnotes = {"[rare]"}
}
}
}
]=]
local function parse_override(segments)
local retval = {values = {}}
local part = segments[1]
local offset = 4
local case = usub(part, 1, 3)
if cases[case] then
-- ok
else
error("Internal error: unrecognized case in override: '" .. table.concat(segments) .. "'")
end
local rest = usub(part, offset)
local slot
if rfind(rest, "^pl") then
rest = rsub(rest, "^pl", "")
slot = case .. "_p"
else
slot = case .. "_s"
end
if rfind(rest, "^:") then
retval.full = true
rest = rsub(rest, "^:", "")
else
error("Suffix overrides not currently supported: " .. part)
end
segments[1] = rest
local colon_separated_groups = put.split_alternating_runs(segments, ":")
for i, colon_separated_group in ipairs(colon_separated_groups) do
local value = {}
local form = colon_separated_group[1]
if form == "" then
error("Use - to indicate an empty ending for slot '" .. slot .. "': '" .. table.concat(segments .. "'"))
elseif form == "-" then
value.form = ""
else
value.form, value.phon_form = com.split_term_respelling(form)
end
value.footnotes = fetch_footnotes(colon_separated_group)
table.insert(retval.values, value)
end
return slot, retval
end
--[=[
Parse an indicator spec (text consisting of angle brackets and zero or more
dot-separated indicators within them). Return value is an object of the form
{
overrides = {
SLOT = {OVERRIDE, OVERRIDE, ...}, -- as returned by parse_override()
...
},
forms = {}, -- forms for a single spec alternant; see `forms` below
footnotes = {"FOOTNOTE", "FOOTNOTE", ...}, -- may be missing
explicit_gender = "GENDER", -- "M", "F"; may be missing
number = "NUMBER", -- "sg", "pl"; may be missing
adj = true, -- may be missing
indecl = true, -- may be missing
unmarked = true, -- may be missing
iya = true, -- may be missing
plstem = "PLSTEM", -- may be missing
pl_phon_stem = "PLSTEM-PHONETIC-RESPELLING", -- as specified by the user; may be missing
pl_translit_stem = "PLSTEM-TRANSLIT", -- translit of pl_phon_stem (if present) or plstem; may be missing
-- The following additional fields are added by other functions:
orig_lemma = "ORIGINAL-LEMMA", -- as given by the user or taken from pagename
orig_lemma_no_links = "ORIGINAL-LEMMA-NO-LINKS", -- links removed
lemma = "LEMMA", -- `orig_lemma_no_links`, converted to singular form if plural
phon_lemma = "LEMMA-PHONETIC-RESPELLING", -- as specified by the user; may be missing
lemma_translit = "LEMMA-TRANSLIT", -- translit of phon_lemma (if present) or lemma
forms = {
SLOT = {
{
form = "FORM",
footnotes = {"FOOTNOTE", "FOOTNOTE", ...} -- may be missing
},
...
},
...
},
decl = "DECL", -- declension, e.g. "ind-ūn-f"
}
]=]
local function parse_indicator_spec(angle_bracket_spec)
local inside = rmatch(angle_bracket_spec, "^<(.*)>$")
assert(inside)
local base = {overrides = {}, forms = {}}
if inside ~= "" then
local segments = put.parse_balanced_segment_run(inside, "[", "]")
local dot_separated_groups = put.split_alternating_runs(segments, "%.")
for i, dot_separated_group in ipairs(dot_separated_groups) do
local part = dot_separated_group[1]
local case_prefix = usub(part, 1, 3)
if cases[case_prefix] then
local slot, override = parse_override(dot_separated_group)
if base.overrides[slot] then
table.insert(base.overrides[slot], override)
else
base.overrides[slot] = {override}
end
elseif part == "" then
if #dot_separated_group == 1 then
error("Blank indicator: '" .. inside .. "'")
end
base.footnotes = fetch_footnotes(dot_separated_group)
elseif #dot_separated_group > 1 then
error("Footnotes only allowed with slot overrides or by themselves: '" .. table.concat(dot_separated_group) .. "'")
elseif part == "M" or part == "F" then
if base.explicit_gender then
error("Can't specify gender twice: '" .. inside .. "'")
end
base.explicit_gender = part
elseif part == "sg" or part == "pl" then
if base.number then
error("Can't specify number twice: '" .. inside .. "'")
end
base.number = part
elseif part == "+" then
if base.adj then
error("Can't specify '+' twice: '" .. inside .. "'")
end
base.adj = true
elseif part == "$" then
if base.indecl then
error("Can't specify '$' twice: '" .. inside .. "'")
end
base.indecl = true
elseif part == "unmarked" then
if base.unmarked then
error("Can't specify 'unmarked' twice: '" .. inside .. "'")
end
base.unmarked = true
elseif part == "iyā" then
if base.iya then
error("Can't specify 'iyā' twice: '" .. inside .. "'")
end
base.iya = true
elseif rfind(part, "^plstem:") then
if base.plstem then
error("Can't specify plural stem twice: '" .. inside .. "'")
end
base.plstem, base.pl_phon_stem = com.split_term_respelling(rsub(part, "^plstem:", ""))
base.pl_translit_stem = com.transliterate_respelling(base.pl_phon_stem) or (lang:transliterate(base.plstem))
else
error("Unrecognized indicator '" .. part .. "': '" .. inside .. "'")
end
end
end
return base
end
local function set_defaults_and_check_bad_indicators(base)
-- Set default values.
if not base.adj and not base.indecl then
base.number = base.number or "both"
end
base.gender = base.explicit_gender
if base.iya then
if base.adj then
error("Can't specify both '+' and 'iya'")
end
if base.gender == "M" then
error("Can't specify M gender with 'iyā' indicator")
end
if not rfind(base.lemma, I .. "याँ?$") and not rfind(base.lemma, "-इयाँ?$") then
error("With 'iyā' indicator, lemma must end in " .. I .. "या or " .. I .. "याँ: " .. base.lemma)
end
base.gender = "F"
end
if base.unmarked then
if base.adj then
error("Can't specify both '+' and 'unmarked'")
end
if base.iya then
error("Can't specify both 'iya' and 'unmarked'")
end
if base.gender == "F" then
error("Can't specify F gender with 'unmarked' indicator")
end
base.gender = "M"
end
if rfind(base.lemma, "[" .. O .. H .. R .. "]$") then
if base.gender == "F" then
error("Can't specify F gender with lemma ending in " .. O .. ", " .. H .. " or " .. R .. ": " .. base.lemma)
end
base.gender = "M"
end
if not base.gender and not base.adj and not base.indecl then
error("Unless lemma is in " .. O .. ", " .. H .. " or " .. R .. " or 'iya', 'unmarked' or '$' specified, gender must be given: " .. base.lemma)
end
if base.adj and base.indecl then
error("Can't specify both '+' and '$' on the same lemma " .. base.lemma)
end
end
-- For a plural-only lemma, synthesize a likely singular lemma. It doesn't have to be
-- theoretically correct as long as it generates all the correct plural forms.
local function synthesize_singular_lemma(base)
if not base.gender then
error("For plural-only lemma, need to specify the gender: '" .. base.lemma .. "'")
end
if base.gender == "M" then
if rfind(base.lemma, E .. "$") then
local stem, translit_stem = com.strip_ending(base, E)
base.lemma = stem .. AA
base.lemma_translit = translit_stem .. "ā"
return
end
if rfind(base.lemma, "ए$") then
-- FIXME, what about -iyā -> -ie?
local stem, translit_stem = com.strip_ending(base, "ए")
base.lemma = stem .. "अ"
base.lemma_translit = translit_stem .. "ā"
return
end
local ending = rmatch(base.lemma, "(" .. E .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. AA .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem .. "अ" .. M
base.lemma_translit = translit_stem .. "ā̃"
return
end
-- Otherwise, singular same as plural and lemma is already correct.
else
assert(base.gender == "F")
local function add_dir_p_override()
-- Add an override to force the direct plural to match. This is needed below
-- in case the lemma ends in anusvara instead of chandrabindu (because the
-- declension functions generate a direct plural with chandrabindu) and also
-- when the direct plural is the same as the singular.
if not base.overrides.dir_p then
base.overrides.dir_p = {}
end
table.insert(base.overrides.dir_p, {full = true, values = {{form = base.lemma, phon_form = base.lemma_translit}}})
end
local ending = rmatch(base.lemma, "(" .. EN .. ")$")
if ending then
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(ए" .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
local ending = rmatch(base.lemma, "(या " .. MN_c .. ")$")
if ending then
add_dir_p_override() -- in case lemma ends in anusvara
-- This may or may not produce the "right" singular but regardless,
-- the plural will be correct, which is all that matters.
local stem, translit_stem = com.strip_ending(base, ending)
base.lemma = stem
base.lemma_translit = translit_stem
return
end
-- We seem to have an endingless plural, e.g. औलाद. Add an override to the dir_p slot
-- to force this form.
add_dir_p_override()
end
end
-- For an adjectival lemma, synthesize the masc singular form.
local function synthesize_adj_lemma(base)
if not rfind(base.lemma, "[अ" .. AA .. "]" .. MN_c .. "?$") then
error("Unrecognized adjectival lemma: " .. base.lemma)
end
base.gender = "M"
base.decl = "adj"
end
-- Determine the declension based on the lemma and gender. The declension is
-- set in base.decl.
local function determine_declension(base)
if base.decl then
return
end
assert(not base.adj)
if base.indecl then
base.decl = "indecl"
elseif base.gender == "M" then
if base.unmarked then
if rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "unmarked-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "unmarked-ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-unmarked-ān-m"
else
error("With 'unmarked' indicator, lemma must end in " .. AA .. ", " .. AA .. M .. ", " ..
AA .. N .. ", आ, आँ: or आं " .. base.lemma)
end
elseif rfind(base.lemma, AA .. "$") then
base.decl = "ā-m"
elseif rfind(base.lemma, "आ$") then
base.decl = "ind-ā-m"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-m"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-m"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-m"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-m"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-m"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-m"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-m"
elseif rfind(base.lemma, O .. "$") then
base.decl = "o-m"
elseif rfind(base.lemma, O .. N .. "$") then
base.decl = "on-m"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-m"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-m"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-m"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-m"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-m"
elseif rfind(base.lemma, R .. "$") then
base.decl = "r-m"
elseif rfind(base.lemma, H .. "$") then
base.decl = "h-m"
else
base.decl = "c-m"
end
else
assert(base.gender == "F")
if base.iya then
if rfind(base.lemma, MN_c .. "$") then
base.decl = "iyān-f"
else
base.decl = "iyā-f"
end
elseif rfind(base.lemma, AA .. "$") or rfind(base.lemma, "आ$") then
base.decl = "ā-f"
elseif rfind(base.lemma, AA .. MN_c .. "$") then
base.decl = "ān-f"
elseif rfind(base.lemma, "आ" .. MN_c .. "$") then
base.decl = "ind-ān-f"
elseif rfind(base.lemma, I .. "$") then
base.decl = "i-f"
elseif rfind(base.lemma, II .. "$") then
base.decl = "ī-f"
elseif rfind(base.lemma, "ई$") then
base.decl = "ind-ī-f"
elseif rfind(base.lemma, II .. N .. "$") then
base.decl = "īn-f"
elseif rfind(base.lemma, "ईं$") then
base.decl = "ind-īn-f"
elseif rfind(base.lemma, U .. "$") then
base.decl = "u-f"
elseif rfind(base.lemma, UU .. "$") then
base.decl = "ū-f"
elseif rfind(base.lemma, "ऊ$") then
base.decl = "ind-ū-f"
elseif rfind(base.lemma, UU .. MN_c .. "$") then
base.decl = "ūn-f"
elseif rfind(base.lemma, "ऊ" .. MN_c .. "$") then
base.decl = "ind-ūn-f"
else
base.decl = "c-f"
end
end
end
local function detect_indicator_spec(base)
set_defaults_and_check_bad_indicators(base)
if base.adj then
synthesize_adj_lemma(base)
else
if base.number == "pl" then
synthesize_singular_lemma(base)
end
determine_declension(base)
end
end
local function detect_all_indicator_specs(alternant_multiword_spec)
iut.map_word_specs(alternant_multiword_spec, function(base)
detect_indicator_spec(base)
end)
end
local propagate_multiword_properties
local function propagate_alternant_properties(alternant_spec, property, mixed_value, nouns_only)
local seen_property
for _, multiword_spec in ipairs(alternant_spec.alternants) do
propagate_multiword_properties(multiword_spec, property, mixed_value, nouns_only)
if seen_property == nil then
seen_property = multiword_spec[property]
elseif multiword_spec[property] and seen_property ~= multiword_spec[property] then
seen_property = mixed_value
end
end
alternant_spec[property] = seen_property
end
propagate_multiword_properties = function(multiword_spec, property, mixed_value, nouns_only)
local seen_property = nil
local last_seen_nounal_pos = 0
local word_specs = multiword_spec.alternant_or_word_specs or multiword_spec.word_specs
for i = 1, #word_specs do
local is_nounal
if word_specs[i].alternants then
propagate_alternant_properties(word_specs[i], property, mixed_value)
is_nounal = not not word_specs[i][property]
elseif nouns_only then
is_nounal = not word_specs[i].adj and not word_specs[i].indecl
else
is_nounal = not not word_specs[i][property]
end
if is_nounal then
if not word_specs[i][property] then
error("Internal error: noun-type word spec without " .. property .. " set")
end
for j = last_seen_nounal_pos + 1, i - 1 do
word_specs[j][property] = word_specs[j][property] or word_specs[i][property]
end
last_seen_nounal_pos = i
if seen_property == nil then
seen_property = word_specs[i][property]
elseif seen_property ~= word_specs[i][property] then
seen_property = mixed_value
end
end
end
if last_seen_nounal_pos > 0 then
for i = last_seen_nounal_pos + 1, #word_specs do
word_specs[i][property] = word_specs[i][property] or word_specs[last_seen_nounal_pos][property]
end
end
multiword_spec[property] = seen_property
end
local function propagate_properties_downward(alternant_multiword_spec, property, default_propval)
local propval1 = alternant_multiword_spec[property] or default_propval
for _, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
local propval2 = alternant_or_word_spec[property] or propval1
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
local propval3 = multiword_spec[property] or propval2
for _, word_spec in ipairs(multiword_spec.word_specs) do
local propval4 = word_spec[property] or propval3
if propval4 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
word_spec[property] = propval4
end
end
else
if propval2 == "mixed" then
error("Attempt to assign mixed " .. property .. " to word")
end
alternant_or_word_spec[property] = propval2
end
end
end
--[=[
Propagate `property` (one of "animacy", "gender" or "number") from nouns to adjacent
adjectives. We proceed as follows:
1. We assume the properties in question are already set on all nouns. This should happen
in set_defaults_and_check_bad_indicators().
2. We first propagate properties upwards and sideways. We recurse downwards from the top.
When we encounter a multiword spec, we proceed left to right looking for a noun.
When we find a noun, we fetch its property (recursing if the noun is an alternant),
and propagate it to any adjectives to its left, up to the next noun to the left.
When we have processed the last noun, we also propagate its property value to any
adjectives to the right (to handle e.g. [[пустальга звычайная]] "common kestrel", where
the adjective польовий should inherit the 'animal' animacy of лунь). Finally, we set
the property value for the multiword spec itself by combining all the non-nil
properties of the individual elements. If all non-nil properties have the same value,
the result is that value, otherwise it is `mixed_value` (which is "mixed" for animacy
and gender, but "both" for number).
3. When we encounter an alternant spec in this process, we recursively process each
alternant (which is a multiword spec) using the previous step, and combine any
non-nil properties we encounter the same way as for multiword specs.
4. The effect of steps 2 and 3 is to set the property of each alternant and multiword
spec based on its children or its neighbors.
]=]
local function propagate_properties(alternant_multiword_spec, property, default_propval, mixed_value)
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, "nouns only")
propagate_multiword_properties(alternant_multiword_spec, property, mixed_value, false)
propagate_properties_downward(alternant_multiword_spec, property, default_propval)
end
-- Find the first noun in a multiword expression and set alternant_multiword_spec.first_noun
-- to the index of that noun. Also find the first adjective and set alternant_multiword_spec.first_adj
-- similarly. If there is a first noun, we use its properties to determine the overall expression's
-- properties; otherwise we use the first adjective's properties, otherwise the first word's properties.
-- If the "word" located this way is not an alternant spec, we just use its properties directly, otherwise
-- we use the properties of the first noun (or failing that the first adjective, or failing that the
-- first word) in each alternative alternant in the alternant spec. For this reason, we need to set the
-- the .first_noun of and .first_adj of each multiword expression embedded in the first noun alternant spec,
-- and the .first_adj of each multiword expression in each adjective alternant spec leading up to the
-- first noun alternant spec.
local function determine_noun_status(alternant_multiword_spec)
for i, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
if alternant_or_word_spec.alternants then
local alternant_type
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
for j, word_spec in ipairs(multiword_spec.word_specs) do
if not word_spec.indecl then
if not word_spec.adj then
multiword_spec.first_noun = j
alternant_type = "noun"
break
elseif not multiword_spec.first_adj then
multiword_spec.first_adj = j
if not alternant_type then
alternant_type = "adj"
end
end
end
end
end
if alternant_type == "noun" then
alternant_multiword_spec.first_noun = i
return
elseif alternant_type == "adj" and not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
elseif not alternant_or_word_spec.indecl then
if not alternant_or_word_spec.adj then
alternant_multiword_spec.first_noun = i
return
elseif not alternant_multiword_spec.first_adj then
alternant_multiword_spec.first_adj = i
end
end
end
end
local function decline_noun(base)
if not decls[base.decl] then
error("Internal error: Unrecognized declension type '" .. base.decl .. "'")
end
decls[base.decl](base)
handle_derived_slots_and_overrides(base)
end
local function process_manual_overrides(forms, args, number)
local params_to_slots_map =
number == "sg" and input_params_to_slots_sg or
number == "pl" and input_params_to_slots_pl or
input_params_to_slots_both
for param, slot in pairs(params_to_slots_map) do
if args[param] then
forms[slot] = nil
if args[param] ~= "-" and args[param] ~= "—" then
for _, form in ipairs(rsplit(args[param], "%s*,%s*")) do
local hi, phon = com.split_term_respelling(form)
local tr = phon and com.transliterate_respelling(phon) or nil
iut.insert_form(forms, slot, {form=form, translit=tr})
end
end
end
end
end
local function compute_category_and_desc(base)
local props = declprops[base.decl]
if props then
return props.cat, props.desc
end
local rest, gender = rmatch(base.decl, "^(.+)%-([mf])$")
if not gender then
error("Internal error: Don't know how to parse decl '" .. base.decl .. "'")
end
local cat_gender = gender == "m" and "masculine" or "feminine"
local desc_gender = gender == "m" and "เพศชาย" or "เพศหญิง"
local ind, stem = rmatch(rest, "^(ind%-)(.*)$")
if not ind then
stem = rest
end
stem = rsub(stem, "n$", TILDE)
if ind then
return cat_gender .. " independent " .. stem .. "-stem ~", desc_gender .. " ind " .. stem .. " การันต์"
else
return cat_gender .. " " .. stem .. "-stem ~", desc_gender .. " " .. stem .. " การันต์"
end
end
-- Compute the categories to add the noun to, as well as the annotation to display in the
-- declension title bar. We combine the code to do these functions as both categories and
-- title bar contain similar information.
local function compute_categories_and_annotation(alternant_multiword_spec)
local cats = {}
local function insert(cattype)
cattype = rsub(cattype, "~", alternant_multiword_spec.pos)
m_table.insertIfNot(cats, "Hindi " .. cattype)
end
if alternant_multiword_spec.number == "sg" then
insert("uncountable ~")
elseif alternant_multiword_spec.number == "pl" then
insert("pluralia tantum")
end
local annotation
if alternant_multiword_spec.manual then
alternant_multiword_spec.annotation =
alternant_multiword_spec.number == "sg" and "sg-only" or
alternant_multiword_spec.number == "pl" and "pl-only" or
""
else
local annparts = {}
local decldescs = {}
local function do_word_spec(base)
local cat, desc = compute_category_and_desc(base)
insert(cat)
m_table.insertIfNot(decldescs, desc)
if base.plstem then
insert("~ with irregular plural stem")
end
if (lang:transliterate(base.lemma)) ~= base.lemma_translit then
insert("~ with phonetic respelling")
end
end
local key_entry = alternant_multiword_spec.first_noun or alternant_multiword_spec.first_adj or 1
if #alternant_multiword_spec.alternant_or_word_specs >= key_entry then
local alternant_or_word_spec = alternant_multiword_spec.alternant_or_word_specs[key_entry]
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
key_entry = multiword_spec.first_noun or multiword_spec.first_adj or 1
if #multiword_spec.word_specs >= key_entry then
do_word_spec(multiword_spec.word_specs[key_entry])
end
end
else
do_word_spec(alternant_or_word_spec)
end
end
if alternant_multiword_spec.number ~= "both" then
table.insert(annparts, alternant_multiword_spec.number == "sg" and "sg-only" or "pl-only")
end
if #decldescs == 0 then
table.insert(annparts, "indecl")
else
table.insert(annparts, table.concat(decldescs, " // "))
end
alternant_multiword_spec.annotation = table.concat(annparts, " ")
if #decldescs > 1 then
insert("~ with multiple declensions")
end
end
alternant_multiword_spec.categories = cats
end
local function show_forms(alternant_multiword_spec)
local lemmas = alternant_multiword_spec.forms.dir_s or alternant_multiword_spec.forms.dir_p or {}
local props = {
lemmas = lemmas,
slot_table = noun_slots_with_linked,
lang = lang,
include_translit = true,
-- Explicit additional top-level footnotes only occur with {{hi-ndecl-manual}} and variants.
footnotes = alternant_multiword_spec.footnotes,
allow_footnote_symbols = not not alternant_multiword_spec.footnotes,
}
iut.show_forms(alternant_multiword_spec.forms, props)
end
local function make_table(alternant_multiword_spec)
local forms = alternant_multiword_spec.forms
local table_top = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-top',
args = {
title = '{title}{annotation}',
palette = 'blue',
tall = 'yes',
class = 'tr-alongside',
}
}
local table_bottom = mw.getCurrentFrame():expandTemplate{
title = 'inflection-table-bottom',
args = {
notes = forms.footnote or nil,
}
}
local table_spec_both = table_top .. [=[
!
! เอกพจน์
! พหูพจน์
|-
! การกตรง
| {dir_s}
| {dir_p}
|-
! การกอ้อม
| {obl_s}
| {obl_p}
|-
! สัมโพธนการก
| {voc_s}
| {voc_p}
]=] .. table_bottom
local table_spec_sg = table_top .. [=[
!
! เอกพจน์
|-
! การกตรง
| {dir_s}
|-
! การกอ้อม
| {obl_s}
|-
! สัมโพธนการก
| {voc_s}
]=] .. table_bottom
local table_spec_pl = table_top .. [=[
!
! พหูพจน์
|-
! การกตรง
| {dir_p}
|-
! การกอ้อม
| {obl_p}
|-
! สัมโพธนการก
| {voc_p}
]=] .. table_bottom
if alternant_multiword_spec.title then
forms.title = alternant_multiword_spec.title
else
forms.title = '<span class="nowrap">การผันรูปของ <i lang="hi" class="Deva">' .. forms.lemma .. '</i></span>'
end
local annotation = alternant_multiword_spec.annotation
if annotation == "" then
forms.annotation = ""
else
forms.annotation = ' <span class="nowrap" style="font-size: smaller;">(' .. annotation .. ")</span>"
end
local table_spec =
alternant_multiword_spec.number == "sg" and table_spec_sg or
alternant_multiword_spec.number == "pl" and table_spec_pl or
table_spec_both
forms.notes_clause = forms.footnote ~= "" and forms.footnote or ""
return m_string_utilities.format(table_spec, forms)
end
local function compute_headword_genders(alternant_multiword_spec)
local genders = {}
local number
if alternant_multiword_spec.number == "pl" then
number = "-p"
else
number = ""
end
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.gender == "M" then
m_table.insertIfNot(genders, "m" .. number)
elseif base.gender == "F" then
m_table.insertIfNot(genders, "f" .. number)
else
error("Internal error: Unrecognized gender '" ..
(base.gender or "nil") .. "'")
end
end)
return genders
end
-- Externally callable function to parse and decline a noun given user-specified arguments.
-- Return value is WORD_SPEC, an object where the declined forms are in `WORD_SPEC.forms`
-- for each slot. If there are no values for a slot, the slot key will be missing. The value
-- for a given slot is a list of objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms(parent_args, pos, from_headword, def)
local params = {
[1] = {required = true, default = "दुनिया<iyā>"},
footnote = {list = true},
title = true,
pagename = true,
json = {type = "boolean"},
}
if from_headword then
params["lemma"] = {list = true}
params["g"] = {list = true}
params["f"] = {list = true}
params["m"] = {list = true}
params["id"] = true
end
local args = m_para.process(parent_args, params)
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
lang = lang,
transliterate_respelling = com.transliterate_respelling,
allow_blank_lemma = true,
}
local alternant_multiword_spec = iut.parse_inflected_text(args[1], parse_props)
alternant_multiword_spec.title = args.title
alternant_multiword_spec.footnotes = args.footnote
alternant_multiword_spec.pos = pos or "nouns"
alternant_multiword_spec.args = args
alternant_multiword_spec.pagename = args.pagename
com.normalize_all_lemmas(alternant_multiword_spec, "always transliterate")
detect_all_indicator_specs(alternant_multiword_spec)
propagate_properties(alternant_multiword_spec, "number", "both", "both")
-- The default of "M" should apply only to plural adjectives, where it doesn't matter.
-- FIXME: This may be wrong for Hindi.
propagate_properties(alternant_multiword_spec, "gender", "M", "mixed")
determine_noun_status(alternant_multiword_spec)
local inflect_props = {
skip_slot = function(slot)
return skip_slot(alternant_multiword_spec.number, slot)
end,
slot_table = noun_slots_with_linked,
lang = lang,
inflect_word_spec = decline_noun,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
com.remove_redundant_translit(alternant_multiword_spec)
compute_categories_and_annotation(alternant_multiword_spec)
alternant_multiword_spec.genders = compute_headword_genders(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Externally callable function to parse and decline a noun where all forms
-- are given manually. Return value is WORD_SPEC, an object where the declined
-- forms are in `WORD_SPEC.forms` for each slot. If there are no values for a
-- slot, the slot key will be missing. The value for a given slot is a list of
-- objects {form=FORM, translit=TRANSLIT, footnotes=FOOTNOTES}.
function export.do_generate_forms_manual(parent_args, number, pos, from_headword, def)
if number ~= "sg" and number ~= "pl" and number ~= "both" then
error("Internal error: number (arg 1) must be 'sg', 'pl' or 'both': '" .. number .. "'")
end
local params = {
footnote = {list = true},
title = true,
json = {type = "boolean"},
}
if number == "both" then
params[1] = {required = true, default = "तारीख़"}
params[2] = {required = true, default = "तवारीख़"}
params[3] = {required = true, default = "तारीख़"}
params[4] = {required = true, default = "तवारीख़ों"}
params[5] = {required = true, default = "तारीख़"}
params[6] = {required = true, default = "तवारीख़ो"}
elseif number == "sg" then
params[1] = {required = true, default = "अदला-बदला"}
params[2] = {required = true, default = "अदले-बदले"}
params[3] = {required = true, default = "अदले-बदले"}
else
params[1] = {required = true, default = "लोग"}
params[2] = {required = true, default = "लोगों"}
params[3] = {required = true, default = "लोगो"}
end
local args = m_para.process(parent_args, params)
local alternant_multiword_spec = {
title = args.title,
footnotes = args.footnote,
forms = {},
number = number,
pos = pos or "nouns",
manual = true,
}
process_manual_overrides(alternant_multiword_spec.forms, args, alternant_multiword_spec.number)
compute_categories_and_annotation(alternant_multiword_spec)
if args.json then
return require("Module:JSON").toJSON(alternant_multiword_spec)
end
return alternant_multiword_spec
end
-- Entry point for {{hi-ndecl}}. Template-callable function to parse and decline a noun given
-- user-specified arguments and generate a displayable table of the declined forms.
function export.show(frame)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms(parent_args)
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
-- Entry point for {{hi-ndecl-manual}}, {{hi-ndecl-manual-sg}} and {{hi-ndecl-manual-pl}}.
-- Template-callable function to parse and decline a noun given manually-specified inflections
-- and generate a displayable table of the declined forms.
function export.show_manual(frame)
local iparams = {
[1] = {required = true},
}
local iargs = m_para.process(frame.args, iparams)
local parent_args = frame:getParent().args
local alternant_multiword_spec = export.do_generate_forms_manual(parent_args, iargs[1])
if type(alternant_multiword_spec) == "string" then -- json=1 specified
return alternant_multiword_spec
end
show_forms(alternant_multiword_spec)
return make_table(alternant_multiword_spec) .. require("Module:utilities").format_categories(alternant_multiword_spec.categories, lang)
end
return export
tp3c1a9b02iqw60rff821wd11721mv5
ไทยแลนด์
0
292223
5722524
4755485
2026-05-05T02:52:48Z
OctraBot
3198
5722524
wikitext
text/x-wiki
== ภาษาไทย ==
{{wp}}
=== รากศัพท์ ===
{{bor+|th|en|Thailand}} โดยส่วนแรก {{bor|th|th|ไทย}} ถูกนำมาใช้
=== การออกเสียง ===
{{th-pron|ไท-แลน}}
=== คำวิสามานยนาม ===
{{th-proper noun}}
# {{lb|th|ไม่ทางการ}} [[ประเทศไทย]]
{{topics|th|ไทย}}
dfmctt62la4mx0ib185oo1nrt3zun7v
5722525
5722524
2026-05-05T02:53:01Z
OctraBot
3198
/* รากศัพท์ */
5722525
wikitext
text/x-wiki
== ภาษาไทย ==
{{wp}}
=== รากศัพท์ ===
{{bor+|th|en|Thailand}}, โดยส่วนแรก {{bor|th|th|ไทย}} ถูกนำมาใช้
=== การออกเสียง ===
{{th-pron|ไท-แลน}}
=== คำวิสามานยนาม ===
{{th-proper noun}}
# {{lb|th|ไม่ทางการ}} [[ประเทศไทย]]
{{topics|th|ไทย}}
jino13pka6c7jtsrp81rgukiizb6pnc
แม่แบบ:hi-IPA/documentation
10
301917
5722542
1515972
2026-05-05T04:44:45Z
OctraBot
3198
5722542
wikitext
text/x-wiki
{{documentation subpage}}
Hindi IPA pronunciation template, using [[Module:hi-IPA]] as a backend.
To force a schwa to appear, use an asterisk.
<includeonly>
[[หมวดหมู่:แม่แบบการออกเสียงภาษาฮินดี|IPA]]
</includeonly>
iri05dleiogt09akerl51p8j4tqkymp
ประกวด
0
310637
5722552
1577556
2026-05-05T10:57:13Z
OctraBot
3198
/* ภาษาไทย */ เก็บกวาด
5722552
wikitext
text/x-wiki
== ภาษาไทย ==
=== การออกเสียง ===
{{th-pron|ปฺระ-กวด}}
=== คำกริยา ===
{{th-verb}}
# [[แข่งขัน]][[เพื่อ]][[เลือก]][[เฟ้น]][[เอา]][[ดี]] [[โดย]][[มี]][[การตัดสิน]]
=== คำนาม ===
{{th-noun}}
# [[การแข่งขัน]]เพื่อเลือกเฟ้นเอาดี โดยมีการตัดสิน
==== ลูกคำ ====
{{col|th|ประกวดประขัน|ประกวดราคา}}
dkhxvgxabm9wyrekeejuqxrrnlx1uc8
มอดูล:labels/data/lang
828
311851
5722534
5722418
2026-05-05T04:01:09Z
OctraBot
3198
5722534
Scribunto
text/plain
-- Table listing all of the languages with lang-specific labels modules.
local langs_with_lang_specific_modules = {
--["ab"] = true,
--["ady"] = true,
--["ae"] = true,
--["af"] = true,
--["afb"] = true,
--["aii"] = true,
--["ain"] = true,
--["ajp"] = true,
--["ak"] = true,
--["akk"] = true,
--["amf"] = true,
--["an"] = true,
--["ang"] = true,
--["apc"] = true,
["ar"] = true,
--["arc"] = true,
--["arq"] = true,
--["arz"] = true,
--["as"] = true,
--["av"] = true,
--["az"] = true,
--["bar"] = true,
--["bcl"] = true,
--["be"] = true,
--["bg"] = true,
--["bho"] = true,
--["bn"] = true,
--["br"] = true,
--["byk"] = true,
["ca"] = true,
--["car"] = true,
--["cbk"] = true,
--["ceb"] = true,
--["cel-pro"] = true,
--["ch"] = true,
--["cho"] = true,
--["chr"] = true,
--["cim"] = true,
--["ckb"] = true,
--["cop"] = true,
--["cpg"] = true,
--["cpi"] = true,
--["crh"] = true,
--["cs"] = true,
--["csb"] = true,
--["cu"] = true,
--["cy"] = true,
--["da"] = true,
--["dcc"] = true,
["de"] = true,
--["dlm"] = true,
--["dnj"] = true,
--["dum"] = true,
--["egl"] = true,
--["egy"] = true,
--["el"] = true,
["en"] = true,
--["enm"] = true,
["es"] = true,
--["et"] = true,
--["eu"] = true,
--["evn"] = true,
--["fa"] = true,
--["fax"] = true,
--["ff"] = true,
--["fi"] = true,
--["fo"] = true,
["fr"] = true,
--["fro"] = true,
--["frp"] = true,
--["frr"] = true,
--["fy"] = true,
["ga"] = true,
--["gd"] = true,
--["gem-pro"] = true,
--["gl"] = true,
--["gmq-oda"] = true,
--["gmq-pro"] = true,
--["gmw-bgh"] = true,
--["gmw-cfr"] = true,
--["gmw-ecg"] = true,
--["gmw-pro"] = true,
--["gmw-rfr"] = true,
--["gmy"] = true,
--["gn"] = true,
--["goh"] = true,
--["grc"] = true,
--["grk-ita"] = true,
--["gsw"] = true,
--["gu"] = true,
--["guw"] = true,
--["ha"] = true,
--["haa"] = true,
--["haw"] = true,
--["he"] = true,
--["hi"] = true,
--["hit"] = true,
--["hrx"] = true,
--["hsb"] = true,
--["ht"] = true,
--["hu"] = true,
["hy"] = true,
--["id"] = true,
--["inc-apa"] = true,
--["inc-ash"] = true,
--["inc-ohi"] = true,
--["it"] = true,
--["iu"] = true,
--["izh"] = true,
["ja"] = true,
--["jje"] = true,
--["jut"] = true,
--["jv"] = true,
--["ka"] = true,
--["kca-eas"] = true,
--["kca-nor"] = true,
--["kca-sou"] = true,
--["kea"] = true,
--["kix"] = true,
--["kls"] = true,
--["kmr"] = true,
--["kn"] = true,
--["kne"] = true,
["ko"] = true,
--["kok"] = true,
--["kpv"] = true,
--["krc"] = true,
--["krl"] = true,
--["kw"] = true,
--["ilo"] = true,
--["la"] = true,
--["lad"] = true,
--["li"] = true,
--["lis"] = true,
--["lmo"] = true,
--["lrl"] = true,
--["lv"] = true,
--["lzz"] = true,
--["mak"] = true,
--["mch"] = true,
--["mco"] = true,
--["mh"] = true,
--["mhd"] = true,
--["mic"] = true,
--["mk"] = true,
--["mlm"] = true,
--["mn"] = true,
--["mns-cen"] = true,
--["mns-nor"] = true,
--["mns-sou"] = true,
--["moh"] = true,
--["mr"] = true,
["ms"] = true,
--["mt"] = true,
--["mul"] = true,
--["mus"] = true,
--["mvi"] = true,
--["my"] = true,
--["nap"] = true,
--["nb"] = true,
--["nds-de"] = true,
--["nds-nl"] = true,
--["new"] = true,
--["nhn"] = true,
--["nhx"] = true,
--["niv"] = true,
--["nl"] = true,
--["nn"] = true,
--["non"] = true,
--["nrf"] = true,
--["nrn"] = true,
--["oc"] = true,
--["oj"] = true,
--["oko"] = true,
--["okz"] = true,
--["onb"] = true,
--["os"] = true,
--["osc"] = true,
--["ota"] = true,
--["otk"] = true,
--["pa"] = true,
--["pam"] = true,
--["paw"] = true,
--["peh"] = true,
--["phl"] = true,
["pl"] = true,
--["pnt"] = true,
--["poz-pro"] = true,
--["pra"] = true,
--["ps"] = true,
["pt"] = true,
--["qu"] = true,
--["qwc"] = true,
--["qwm"] = true,
--["rgn"] = true,
--["rm"] = true,
--["rmc"] = true,
--["rml"] = true,
--["rmn"] = true,
--["rmy"] = true,
--["ro"] = true,
--["roa-ona"] = true,
--["roa-opt"] = true,
--["rom"] = true,
--["ru"] = true,
--["rue"] = true,
--["rw"] = true,
--["rys"] = true,
--["ryu"] = true,
["sa"] = true,
--["sc"] = true,
--["scl"] = true,
--["scn"] = true,
--["sco"] = true,
--["se"] = true,
--["sel-sou"] = true,
["sh"] = true,
--["sjd"] = true,
--["sk"] = true,
--["skr"] = true,
--["sl"] = true,
--["sla-pro"] = true,
--["smi-pro"] = true,
--["sn"] = true,
--["sq"] = true,
--["srn"] = true,
--["su"] = true,
--["sux"] = true,
--["sv"] = true,
["sw"] = true,
--["szl"] = true,
--["ta"] = true,
--["te"] = true,
--["tet"] = true,
["th"] = true,
--["tkr"] = true,
--["tl"] = true,
--["tmh"] = true,
--["tpw"] = true,
--["tr"] = true,
--["trk-pro"] = true,
--["tsg"] = true,
--["tt"] = true,
--["udi"] = true,
--["udm"] = true,
--["uk"] = true,
--["ur"] = true,
--["urj-fin-pro"] = true,
--["uz"] = true,
--["war"] = true,
--["vec"] = true,
["vi"] = true,
--["xcl"] = true,
--["xh"] = true,
--["xme-ker"] = true,
--["xmf"] = true,
--["xnn"] = true,
--["xqa"] = true,
--["xum"] = true,
--["ycr"] = true,
--["yi"] = true,
--["yo"] = true,
--["yok-bvy"] = true,
--["yok-dly"] = true,
--["yok-kry"] = true,
--["yok-nvy"] = true,
--["yok-svy"] = true,
--["yok-tky"] = true,
--["yrk"] = true,
--["yrl"] = true,
--["za"] = true,
["zh"] = true,
--["zle-ono"] = true,
--["zle-ort"] = true,
--["zlw-ocs"] = true,
--["zlw-opl"] = true,
--["zlw-osk"] = true,
--["zlw-slv"] = true,
--["zu"] = true,
}
return {
langs_with_lang_specific_modules = langs_with_lang_specific_modules,
}
39fiidv4sajf0w2hccjyirxmst4zc7q
หมวดหมู่:ศัพท์ภาษาฮีบรูที่ผันรูปย้อนกลับ
14
332023
5722515
1766474
2026-05-05T02:30:06Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาฮีบรู]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาฮีบรูที่การผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766474
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
5722516
5722515
2026-05-05T02:32:00Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:ศัพท์ภาษาฮีบรูที่การผันรูปย้อนกลับ]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาฮีบรูที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766474
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาดัตช์ที่ผันรูปย้อนกลับ
14
332024
5722511
1766475
2026-05-05T02:21:13Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาดัตช์]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาดัตช์ที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766475
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาฮังการีที่ผันรูปย้อนกลับ
14
332025
5722514
1766476
2026-05-05T02:25:42Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาฮังการี]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาฮังการีที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766476
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาอังกฤษที่ผันรูปย้อนกลับ
14
332026
5722513
1766477
2026-05-05T02:22:03Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาอังกฤษ]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาอังกฤษที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766477
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาเอสเปรันโตที่ผันรูปย้อนกลับ
14
332027
5722518
1766478
2026-05-05T02:32:58Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาเอสเปรันโต]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาเอสเปรันโตที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766478
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาเยอรมันที่ผันรูปย้อนกลับ
14
332028
5722517
1766479
2026-05-05T02:32:38Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาเยอรมัน]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาเยอรมันที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766479
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาไทยที่ผันรูปย้อนกลับ
14
332029
5722519
1766480
2026-05-05T02:33:23Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาไทย]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาไทยที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766480
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ที่ผันรูปย้อนกลับแบ่งตามภาษา
14
332030
5722520
1766481
2026-05-05T02:33:47Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับแบ่งตามภาษา]] ไปยัง [[หมวดหมู่:ศัพท์ที่ผันรูปย้อนกลับแบ่งตามภาษา]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766481
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาญี่ปุ่นที่ผันรูปย้อนกลับ
14
332031
5722510
1766482
2026-05-05T02:20:45Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาญี่ปุ่น]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาญี่ปุ่นที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766482
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
หมวดหมู่:ศัพท์ภาษาสเปนที่ผันรูปย้อนกลับ
14
332032
5722512
1766483
2026-05-05T02:21:39Z
OctraBot
3198
OctraBot ย้ายหน้า [[หมวดหมู่:การผันรูปย้อนกลับภาษาสเปน]] ไปยัง [[หมวดหมู่:ศัพท์ภาษาสเปนที่ผันรูปย้อนกลับ]] โดยไม่สร้างหน้าเปลี่ยนทางตามมา
1766483
wikitext
text/x-wiki
{{auto cat}}
eomzlm5v4j7ond1phrju7cnue91g5qx
สันนิษฐาน
0
1858004
5722484
4933780
2026-05-05T01:01:54Z
OctraBot
3198
/* การออกเสียง */
5722484
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
{{der+|th|pi|สนฺนิฏฐาน}}
=== การออกเสียง ===
{{th-pron|สัน-นิด-ถาน}}
=== คำกริยา ===
{{th-verb}}
# [[ลง]][[ความเห็น]][[เป็น]][[การคาด]][[คะเน]][[ไว้]][[ก่อน]]
s7iqny78yk6591l859fu2htxiyuof2t
คุยกับผู้ใช้:Banthitar A.
3
2331048
5722481
2026-05-05T00:32:44Z
Kadı
15341
Kadı ย้ายหน้า [[คุยกับผู้ใช้:Banthitar A.]] ไปยัง [[คุยกับผู้ใช้:Bandita A]]: ย้ายหน้าอัตโนมัติขณะเปลี่ยนชื่อผู้ใช้ "[[Special:CentralAuth/Banthitar A.|Banthitar A.]]" เป็น "[[Special:CentralAuth/Bandita A|Bandita A]]"
5722481
wikitext
text/x-wiki
#เปลี่ยนทาง [[คุยกับผู้ใช้:Bandita A]]
cer9ntu8hmu56l6bekgq2zcs9va9hkg
การสันนิษฐาน
0
2331049
5722483
2026-05-05T01:01:40Z
OctraBot
3198
สร้างคำอัตโนมัติ
5722483
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
{{prefix|th|การ|สันนิษฐาน}}
=== การออกเสียง ===
{{th-pron|กาน-สัน-นิด-ฐาน}}
=== คำนาม ===
{{th-noun}}
# {{abstract noun of|th|สันนิษฐาน}}
f9r75crzm1qbjzoccw8jhto6abletw8
5722485
5722483
2026-05-05T01:01:57Z
OctraBot
3198
/* การออกเสียง */
5722485
wikitext
text/x-wiki
== ภาษาไทย ==
=== รากศัพท์ ===
{{prefix|th|การ|สันนิษฐาน}}
=== การออกเสียง ===
{{th-pron|กาน-สัน-นิด-ถาน}}
=== คำนาม ===
{{th-noun}}
# {{abstract noun of|th|สันนิษฐาน}}
b54uil5q8886hxq1ks7ylg0nzwynhi5
deinterjectional
0
2331050
5722489
2026-05-05T01:12:10Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722489
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
จาก{{confix|en|de|interjection|al|gloss1=จาก}}
=== คำคุณศัพท์ ===
{{examples|[[helloing]], [[heave-hoing]], [[LOLed]], [[amening]], [[hallelujahing]], [[yoohooing]]}}
{{en-adj|-}}
# {{lb|en|grammar}} ที่รับมาจาก[[คำอุทาน]]
#: {{cot|en|denominal|deverbal|deadjectival|denumeral|depronominal}}<!-- https://books.google.hu/books?id=YJClCwAAQBAJ&pg=PT1035 https://jurnal.uns.ac.id/icalc/article/download/16112/12952 http://www.languagesgulper.com/eng/Lithuanian.html -->
o44x650ayqljb8pynsopg9ygajkfqoz
depronominal
0
2331051
5722490
2026-05-05T01:12:56Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722490
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
จาก{{prefix|en|de|pronominal|gloss1=จาก}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar}} ที่รับมาจาก[[คำสรรพนาม]]
#: {{cot|en|denominal|deverbal|deadjectival|denumeral|deinterjectional}}<!-- https://books.google.hu/books?id=YJClCwAAQBAJ&pg=PT1035 https://jurnal.uns.ac.id/icalc/article/download/16112/12952 http://www.languagesgulper.com/eng/Lithuanian.html -->
2w6rq89htwptu10by2uougppd6h99fl
deadjectival
0
2331052
5722491
2026-05-05T01:13:51Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722491
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== รูปแบบอื่น ===
* {{gloss|คำย่อ}}: {{l|en|deadj.}}
=== รากศัพท์ ===
จาก{{prefix|en|de|adjectival|gloss1=จาก}}<ref>{{R:OED2|entry=de-adjectival|pos=a|id=00058081}}</ref>
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar}} ที่รับมาจาก[[คำคุณศัพท์]]
#: {{cot|en|denominal|deverbal|denumeral|depronominal|deinterjectional}}
=== คำนาม ===
{{examples|[[weak]] (adj) → [[weaken]] (verb)<br>[[large]] (adj) → [[enlarge]] (verb)<br>[[tidy]] (adj) → [[tidiness]] (noun)<br>[[passive]] (adj) → [[passivity]] (noun)}}
{{en-noun}}
# {{lb|en|grammar}} คำที่รับมาจากคำคุณศัพท์
#: {{cot|en|denominal|deverbal}}
=== อ้างอิง ===
<references/>
5y9i3d7j69v2pkrbwite8h43sucge0k
5722492
5722491
2026-05-05T01:14:03Z
OctraBot
3198
/* คำนาม */
5722492
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== รูปแบบอื่น ===
* {{gloss|คำย่อ}}: {{l|en|deadj.}}
=== รากศัพท์ ===
จาก{{prefix|en|de|adjectival|gloss1=จาก}}<ref>{{R:OED2|entry=de-adjectival|pos=a|id=00058081}}</ref>
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar}} ที่รับมาจาก[[คำคุณศัพท์]]
#: {{cot|en|denominal|deverbal|denumeral|depronominal|deinterjectional}}
=== คำนาม ===
{{examples|[[weak]] (adj) → [[weaken]] (verb)<br>[[large]] (adj) → [[enlarge]] (verb)<br>[[tidy]] (adj) → [[tidiness]] (noun)<br>[[passive]] (adj) → [[passivity]] (noun)}}
{{en-noun}}
# {{lb|en|grammar}} [[คำ]]ที่รับมาจากคำคุณศัพท์
#: {{cot|en|denominal|deverbal}}
=== อ้างอิง ===
<references/>
47v5b7sh0cq5plj9egkfqf3mxtbnfc4
deverbal
0
2331053
5722493
2026-05-05T01:18:50Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722493
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
{{wp|en:}}
=== รากศัพท์ ===
จาก{{confix|en|de|verb|al}}
=== การออกเสียง ===
* {{enPR|dē-vûr'''′'''bəl}}
* {{IPA|en|/diːˈvɜː.bəl/|a=RP,AuE}}
** {{audio|en|LL-Q1860 (eng)-Vealhurl-deverbal.wav|a=Southern England}}
* {{IPA|en|/diˈvɜɹ.bəl/|a=GenAm,CanE}}
* {{IPA|en|/diːˈvøː.bəl/|a=NZE}}
* {{IPA|en|/diˈvɛɹ.bəl/|a=ScE}}
* {{IPA|en|/ɖiːˈvɜːʳ.bal/|a=InE}}
* {{hyph|en|de|ver|bal}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar|linguistics}} ที่รับมาจาก[[คำกริยา]]
#: {{cot|en|denominal|deadjectival|denumeral|depronominal|deinterjectional}}
==== ลูกคำ ====
{{col|en|deverbally
}}
=== คำนาม ===
{{en-noun}}
{{examples|en
|example=''see'' [[:หมวดหมู่:English deverbals]]
}}
# {{lb|en|grammar|linguistics}} [[คำ]]ที่รับมาจาก[[คำกริยา]], โดยเฉพาะหมายถึง[[คำนาม]]/คำเสมือนนามที่เกี่ยวกับคำกริยานั้น
#: {{syn|en|deverbal noun|q2=rare|deverbative}}
#: {{hypo|en|verbal noun}}
#: {{cot|en|denominal}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|deverbal, deverbative}}
=== คำสลับอักษร ===
* {{anagrams|en|a=abdeelrv|verbaled}}
== ภาษาโรมาเนีย ==
=== รากศัพท์ ===
{{bor+|ro|fr|déverbal}}
=== คำคุณศัพท์ ===
{{ro-adj}}
# [[คำ]]ที่รับมาจาก[[คำกริยา]]
==== การผันรูป ====
{{ro-decl-adj}}
ey9vqn5daan4jn89nnsuxunf7azs38p
5722494
5722493
2026-05-05T01:18:59Z
OctraBot
3198
เรียงลำดับหัวเรื่องภาษา
5722494
wikitext
text/x-wiki
== ภาษาโรมาเนีย ==
=== รากศัพท์ ===
{{bor+|ro|fr|déverbal}}
=== คำคุณศัพท์ ===
{{ro-adj}}
# [[คำ]]ที่รับมาจาก[[คำกริยา]]
==== การผันรูป ====
{{ro-decl-adj}}
== ภาษาอังกฤษ ==
{{wp|en:}}
=== รากศัพท์ ===
จาก{{confix|en|de|verb|al}}
=== การออกเสียง ===
* {{enPR|dē-vûr'''′'''bəl}}
* {{IPA|en|/diːˈvɜː.bəl/|a=RP,AuE}}
** {{audio|en|LL-Q1860 (eng)-Vealhurl-deverbal.wav|a=Southern England}}
* {{IPA|en|/diˈvɜɹ.bəl/|a=GenAm,CanE}}
* {{IPA|en|/diːˈvøː.bəl/|a=NZE}}
* {{IPA|en|/diˈvɛɹ.bəl/|a=ScE}}
* {{IPA|en|/ɖiːˈvɜːʳ.bal/|a=InE}}
* {{hyph|en|de|ver|bal}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar|linguistics}} ที่รับมาจาก[[คำกริยา]]
#: {{cot|en|denominal|deadjectival|denumeral|depronominal|deinterjectional}}
==== ลูกคำ ====
{{col|en|deverbally
}}
=== คำนาม ===
{{en-noun}}
{{examples|en
|example=''see'' [[:หมวดหมู่:English deverbals]]
}}
# {{lb|en|grammar|linguistics}} [[คำ]]ที่รับมาจาก[[คำกริยา]], โดยเฉพาะหมายถึง[[คำนาม]]/คำเสมือนนามที่เกี่ยวกับคำกริยานั้น
#: {{syn|en|deverbal noun|q2=rare|deverbative}}
#: {{hypo|en|verbal noun}}
#: {{cot|en|denominal}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|deverbal, deverbative}}
=== คำสลับอักษร ===
* {{anagrams|en|a=abdeelrv|verbaled}}
sxacdehpovkb396uqcn3396wb4ivnjx
5722495
5722494
2026-05-05T01:19:38Z
OctraBot
3198
/* คำนาม */
5722495
wikitext
text/x-wiki
== ภาษาโรมาเนีย ==
=== รากศัพท์ ===
{{bor+|ro|fr|déverbal}}
=== คำคุณศัพท์ ===
{{ro-adj}}
# [[คำ]]ที่รับมาจาก[[คำกริยา]]
==== การผันรูป ====
{{ro-decl-adj}}
== ภาษาอังกฤษ ==
{{wp|en:}}
=== รากศัพท์ ===
จาก{{confix|en|de|verb|al}}
=== การออกเสียง ===
* {{enPR|dē-vûr'''′'''bəl}}
* {{IPA|en|/diːˈvɜː.bəl/|a=RP,AuE}}
** {{audio|en|LL-Q1860 (eng)-Vealhurl-deverbal.wav|a=Southern England}}
* {{IPA|en|/diˈvɜɹ.bəl/|a=GenAm,CanE}}
* {{IPA|en|/diːˈvøː.bəl/|a=NZE}}
* {{IPA|en|/diˈvɛɹ.bəl/|a=ScE}}
* {{IPA|en|/ɖiːˈvɜːʳ.bal/|a=InE}}
* {{hyph|en|de|ver|bal}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar|linguistics}} ที่รับมาจาก[[คำกริยา]]
#: {{cot|en|denominal|deadjectival|denumeral|depronominal|deinterjectional}}
==== ลูกคำ ====
{{col|en|deverbally
}}
=== คำนาม ===
{{en-noun}}
{{examples|en
|example=''see'' [[:หมวดหมู่:English deverbals]]
}}
# {{lb|en|grammar|linguistics}} [[คำ]]ที่รับมาจากคำกริยา, โดยเฉพาะหมายถึง[[คำนาม]]/คำเสมือนนามที่เกี่ยวกับคำกริยานั้น
#: {{syn|en|deverbal noun|q2=rare|deverbative}}
#: {{hypo|en|verbal noun}}
#: {{cot|en|denominal}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|deverbal, deverbative}}
=== คำสลับอักษร ===
* {{anagrams|en|a=abdeelrv|verbaled}}
sv0w8v510w80gk8826wknge93trjs6d
5722505
5722495
2026-05-05T01:41:33Z
OctraBot
3198
/* คำนาม */
5722505
wikitext
text/x-wiki
== ภาษาโรมาเนีย ==
=== รากศัพท์ ===
{{bor+|ro|fr|déverbal}}
=== คำคุณศัพท์ ===
{{ro-adj}}
# [[คำ]]ที่รับมาจาก[[คำกริยา]]
==== การผันรูป ====
{{ro-decl-adj}}
== ภาษาอังกฤษ ==
{{wp|en:}}
=== รากศัพท์ ===
จาก{{confix|en|de|verb|al}}
=== การออกเสียง ===
* {{enPR|dē-vûr'''′'''bəl}}
* {{IPA|en|/diːˈvɜː.bəl/|a=RP,AuE}}
** {{audio|en|LL-Q1860 (eng)-Vealhurl-deverbal.wav|a=Southern England}}
* {{IPA|en|/diˈvɜɹ.bəl/|a=GenAm,CanE}}
* {{IPA|en|/diːˈvøː.bəl/|a=NZE}}
* {{IPA|en|/diˈvɛɹ.bəl/|a=ScE}}
* {{IPA|en|/ɖiːˈvɜːʳ.bal/|a=InE}}
* {{hyph|en|de|ver|bal}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar|linguistics}} ที่รับมาจาก[[คำกริยา]]
#: {{cot|en|denominal|deadjectival|denumeral|depronominal|deinterjectional}}
==== ลูกคำ ====
{{col|en|deverbally
}}
=== คำนาม ===
{{en-noun}}
{{examples|en
|example=''see'' [[:หมวดหมู่:English deverbals]]
}}
# {{lb|en|grammar|linguistics}} [[คำ]]ที่รับมาจากคำกริยา, โดยเฉพาะหมายถึง[[คำนาม]]/วลีนามที่เกี่ยวกับคำกริยานั้น
#: {{syn|en|deverbal noun|q2=rare|deverbative}}
#: {{hypo|en|verbal noun}}
#: {{cot|en|denominal}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|deverbal, deverbative}}
=== คำสลับอักษร ===
* {{anagrams|en|a=abdeelrv|verbaled}}
8ow9v877vb18pli2b3bus6x7f0d3pre
5722506
5722505
2026-05-05T01:45:25Z
OctraBot
3198
/* คำนาม */
5722506
wikitext
text/x-wiki
== ภาษาโรมาเนีย ==
=== รากศัพท์ ===
{{bor+|ro|fr|déverbal}}
=== คำคุณศัพท์ ===
{{ro-adj}}
# [[คำ]]ที่รับมาจาก[[คำกริยา]]
==== การผันรูป ====
{{ro-decl-adj}}
== ภาษาอังกฤษ ==
{{wp|en:}}
=== รากศัพท์ ===
จาก{{confix|en|de|verb|al}}
=== การออกเสียง ===
* {{enPR|dē-vûr'''′'''bəl}}
* {{IPA|en|/diːˈvɜː.bəl/|a=RP,AuE}}
** {{audio|en|LL-Q1860 (eng)-Vealhurl-deverbal.wav|a=Southern England}}
* {{IPA|en|/diˈvɜɹ.bəl/|a=GenAm,CanE}}
* {{IPA|en|/diːˈvøː.bəl/|a=NZE}}
* {{IPA|en|/diˈvɛɹ.bəl/|a=ScE}}
* {{IPA|en|/ɖiːˈvɜːʳ.bal/|a=InE}}
* {{hyph|en|de|ver|bal}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar|linguistics}} ที่รับมาจาก[[คำกริยา]]
#: {{cot|en|denominal|deadjectival|denumeral|depronominal|deinterjectional}}
==== ลูกคำ ====
{{col|en|deverbally
}}
=== คำนาม ===
{{en-noun}}
{{examples|en
|example=''ดูที่'' [[:หมวดหมู่:ศัพท์ภาษาอังกฤษที่รับมาจากคำกริยา]]
}}
# {{lb|en|grammar|linguistics}} [[คำ]]ที่รับมาจากคำกริยา, โดยเฉพาะหมายถึง[[คำนาม]]/วลีนามที่เกี่ยวกับคำกริยานั้น
#: {{syn|en|deverbal noun|q2=rare|deverbative}}
#: {{hypo|en|verbal noun}}
#: {{cot|en|denominal}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|deverbal, deverbative}}
=== คำสลับอักษร ===
* {{anagrams|en|a=abdeelrv|verbaled}}
avtnmo5tyh7u4r4hr2r1qmjf74kbdw7
deverbal noun
0
2331054
5722496
2026-05-05T01:20:26Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722496
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== คำนาม ===
{{en-noun}}
# {{synonym of|en|deverbal}}
i79s4a2dgjjad9ct0tngw7m7c4w0y05
deverbale
0
2331055
5722497
2026-05-05T01:21:39Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722497
wikitext
text/x-wiki
== ภาษาอิตาลี ==
=== การออกเสียง ===
{{it-pr}}
=== คำคุณศัพท์ ===
{{it-adj}}
# {{lb|it|grammar}} ที่รับมาจาก[[คำกริยา]]
=== คำนาม ===
{{it-noun|m}}
# [[คำ]]ที่รับมาจากคำกริยา, โดยเฉพาะหมายถึง[[คำนาม]]/คำเสมือนนามที่เกี่ยวกับคำกริยานั้น
1jdc8dmxvlaelf4capd8ibh5xp1apdk
deverbal nouns
0
2331056
5722498
2026-05-05T01:22:33Z
OctraBot
3198
เก็บกวาด
5722498
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== คำนาม ===
{{head|en|รูปนาม}}
# {{plural of|en|deverbal noun}}
5g53ykb84qapk033c7fh08jrpy01dxx
denumeral
0
2331057
5722499
2026-05-05T01:23:51Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722499
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
จาก{{prefix|en|de|numeral|gloss1=จาก}}
=== คำคุณศัพท์ ===
{{examples|[[86ing]], [[69ing]], [[404ing]], [[911ing]], [[5150ing]]}}
{{en-adj|-}}
# {{lb|en|grammar}} ที่รับมาจาก[[เลข]]
#: {{cot|en|denominal|deverbal|deadjectival|depronominal|deinterjectional}}<!-- https://books.google.hu/books?id=YJClCwAAQBAJ&pg=PT1035 https://jurnal.uns.ac.id/icalc/article/download/16112/12952 http://www.languagesgulper.com/eng/Lithuanian.html -->
=== คำสลับอักษร ===
* {{anagrams|en|a=adeelmnru|undermeal}}
mhkavpihls800s2i7tjszrga3qlrdoo
denominal
0
2331058
5722500
2026-05-05T01:28:37Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด
5722500
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
{{etymon|en|:af|de-|nominal|tree=1|text=+}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|grammar|linguistics}} ที่รับมาจาก[[คำนาม]]
#: {{syn|en|denominative|desubstantival}}
#: {{cot|en|deverbal|deadjectival|denumeral|depronominal|deinterjectional}}
==== ลูกคำ ====
{{col|en|denominally
|non-denominal}}
=== คำนาม ===
{{en-noun}}
# {{lb|en|grammar|linguistics}} [[คำ]]ที่รับมาจากคำนามหรือ[[คำคุณศัพท์]], โดยบ่อยครั้งจะเป็น[[คำกริยา]]
#: {{syn|en|denominative}}
#: {{cot|en|deverbal}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|denominal, denominative}}
=== คำสลับอักษร ===
* {{anagrams|en|a=adeilmnno|almondine|mandoline|melanonid|nonmedial}}
h7bne56dvnxp5ysksdc6du4mfzn38cz
denominative
0
2331059
5722501
2026-05-05T01:32:58Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด เรียงลำดับหัวเรื่องภาษา
5722501
wikitext
text/x-wiki
== ภาษาละติน ==
=== คำคุณศัพท์ ===
{{head|la|รูปคุณศัพท์|head=dēnōminātīve}}
# {{inflection of|la|dēnōminātīvus||voc|m|s}}
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
{{etymon|en|:bor|la-lat:dēnōminātīvus|tree=1}}
จาก{{bor|en|la-lat|dēnōminātīvus}}, a [[calque]] of {{der|en|grc|παρώνυμος|t=derivative}}. It originally had the meaning “derived”,<ref>{{R:OED Online|title=denominative|code=50001|part of speech=adj. and n|date=November 2016}}</ref> but in its grammatical sense, it has developed the meaning “from a noun”, perhaps a reinterpretation of the Latin morphemes that it consists of: the preposition {{m|la|dē|t=from}} and the stem of {{m|la|nōmen|t=name, noun}}.
=== การออกเสียง ===
* {{IPA|en|/di-ˈnä-mə-nə-tiv/|a=GA}}
** {{audio|en|LL-Q1860 (eng)-Yangolin-denominative.wav|a=GA}}
* {{audio|en|LL-Q1860 (eng)-Vealhurl-denominative.wav|a=Southern England}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# ที่เป็น[[ชื่อ]]
#* {{quote-text|en|year=1885|author=William Philo Clark|title=The Indian Sign Language|page=283
|passage=From the fact that this was the most noticeable feature in their costume, the name came naturally to be the '''denominative''' term of the tribe.}}
# ที่มีหรือสามารถมีชื่อเรียกหรือชื่อที่เฉพาะเจาะจง; สามารถระบุชื่อได้
#* {{quote-text|en|year=1678|author=J. Hawkins|title=Cocker's Arithm.|section=ii. 29
|passage=The least <!--i.e. smallest--> '''denominative''' part of time is a second.}}
# {{lb|en|grammar}} ที่รับมาจาก[[คำนาม]]หรือ[[คำคุณศัพท์]]
#: {{syn|en|denominal}}
==== ลูกคำ ====
{{col|en|denominatively}}
=== คำนาม ===
{{en-noun}}
# {{lb|en|grammar}} [[คำ]]ที่รับมาจากคำนามหรือ[[คำคุณศัพท์]], โดยบ่อยครั้งจะเป็น[[คำกริยา]]
#: {{syn|en|denominal}}
==== อ้างอิง ====
<references />
=== ดูเพิ่ม ===
* {{l|en|deadjective}}, {{l|en|denominal}}, {{l|en|desubstantive}}, {{l|en|deverbal}}, {{l|en|deverbative}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|denominative, denominal}}
{{C|en|ไวยากรณ์}}
== ภาษาอิตาลี ==
=== คำคุณศัพท์ ===
{{head|it|รูปคุณศัพท์|g=f-p}}
# {{feminine plural of|it|denominativo}}
eow6mpyzxd7u5a7ktadk4wnw8yizx4q
5722502
5722501
2026-05-05T01:33:20Z
OctraBot
3198
/* คำนาม */
5722502
wikitext
text/x-wiki
== ภาษาละติน ==
=== คำคุณศัพท์ ===
{{head|la|รูปคุณศัพท์|head=dēnōminātīve}}
# {{inflection of|la|dēnōminātīvus||voc|m|s}}
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
{{etymon|en|:bor|la-lat:dēnōminātīvus|tree=1}}
จาก{{bor|en|la-lat|dēnōminātīvus}}, a [[calque]] of {{der|en|grc|παρώνυμος|t=derivative}}. It originally had the meaning “derived”,<ref>{{R:OED Online|title=denominative|code=50001|part of speech=adj. and n|date=November 2016}}</ref> but in its grammatical sense, it has developed the meaning “from a noun”, perhaps a reinterpretation of the Latin morphemes that it consists of: the preposition {{m|la|dē|t=from}} and the stem of {{m|la|nōmen|t=name, noun}}.
=== การออกเสียง ===
* {{IPA|en|/di-ˈnä-mə-nə-tiv/|a=GA}}
** {{audio|en|LL-Q1860 (eng)-Yangolin-denominative.wav|a=GA}}
* {{audio|en|LL-Q1860 (eng)-Vealhurl-denominative.wav|a=Southern England}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# ที่เป็น[[ชื่อ]]
#* {{quote-text|en|year=1885|author=William Philo Clark|title=The Indian Sign Language|page=283
|passage=From the fact that this was the most noticeable feature in their costume, the name came naturally to be the '''denominative''' term of the tribe.}}
# ที่มีหรือสามารถมีชื่อเรียกหรือชื่อที่เฉพาะเจาะจง; สามารถระบุชื่อได้
#* {{quote-text|en|year=1678|author=J. Hawkins|title=Cocker's Arithm.|section=ii. 29
|passage=The least <!--i.e. smallest--> '''denominative''' part of time is a second.}}
# {{lb|en|grammar}} ที่รับมาจาก[[คำนาม]]หรือ[[คำคุณศัพท์]]
#: {{syn|en|denominal}}
==== ลูกคำ ====
{{col|en|denominatively}}
=== คำนาม ===
{{en-noun}}
# {{lb|en|grammar}} [[คำ]]ที่รับมาจากคำนามหรือคำคุณศัพท์, โดยบ่อยครั้งจะเป็น[[คำกริยา]]
#: {{syn|en|denominal}}
==== อ้างอิง ====
<references />
=== ดูเพิ่ม ===
* {{l|en|deadjective}}, {{l|en|denominal}}, {{l|en|desubstantive}}, {{l|en|deverbal}}, {{l|en|deverbative}}
=== อ่านเพิ่ม ===
* {{R:OneLook}}
* {{R:GNV|denominative, denominal}}
{{C|en|ไวยากรณ์}}
== ภาษาอิตาลี ==
=== คำคุณศัพท์ ===
{{head|it|รูปคุณศัพท์|g=f-p}}
# {{feminine plural of|it|denominativo}}
r8tdf0pkym0rjw4b5utcabnyw3ith15
deverbative
0
2331060
5722503
2026-05-05T01:34:49Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด เรียงลำดับหัวเรื่องภาษา
5722503
wikitext
text/x-wiki
== ภาษาเยอรมัน ==
=== การออกเสียง ===
* {{audio|de|De-deverbative.ogg|a=<<Germany>> (<<Berlin>>)}}
=== คำคุณศัพท์ ===
{{head|de|รูปคุณศัพท์}}
# {{de-adj form of|deverbativ}}
== ภาษาอังกฤษ ==
=== รากศัพท์ ===
จาก{{affix|en|de-|verb|-ative}}
=== การออกเสียง ===
* {{enPR|dē-vûr'''′'''bə-tĭv}}
* {{IPA|en|/diːˈvɜː.bə.tɪv/|a=RP,AuE}}
* {{IPA|en|/diˈvɜɹ.bə.tɪv/|a=GenAm,CanE}}
* {{IPA|en|/diːˈvøː.bə.təv/|a=NZE}}
* {{IPA|en|/diˈvɛɹ.bə.tɪv/|a=ScE}}
* {{IPA|en|/ɖiːˈvɜːʳ.ba.ʈiv/|a=InE}}
* {{hyph|en|de|ver|ba|tive}}
=== คำคุณศัพท์ ===
{{en-adj|-}}
# {{lb|en|linguistics|grammar|rare}} ที่รับมาจาก[[คำกริยา]]
=== คำนาม ===
{{en-noun}}
# {{lb|en|linguistics|grammar|rare}} [[คำ]]หรือส่วนหนึ่งของคำที่รับมาจากคำกริยา
==== คำพ้องความ ====
* {{l|en|deverbal}} {{qual|สามัญมากกว่า}}
==== คำแปลภาษาอื่น ====
{{trans-see|deverbal}}
=== ดูเพิ่ม ===
* {{l|en|denominal}}
* {{l|en|denominative}}
6nelrsb88loes55mr52e1aeqvrgr3ov
deverbatives
0
2331061
5722504
2026-05-05T01:35:06Z
OctraBot
3198
นำเข้าจาก enwikt เก็บกวาด เรียงลำดับหัวเรื่องภาษา
5722504
wikitext
text/x-wiki
== ภาษาเยอรมัน ==
=== การออกเสียง ===
* {{audio|de|De-deverbatives.ogg|a=<<Germany>> (<<Berlin>>)}}
=== คำคุณศัพท์ ===
{{head|de|รูปคุณศัพท์}}
# {{de-adj form of|deverbativ}}
== ภาษาอังกฤษ ==
=== คำนาม ===
{{head|en|รูปนาม}}
# {{plural of|en|deverbative}}
ku9x36e33hn4e24eltoslfh7rdh788q
มอดูล:labels/data/lang/sa
828
2331062
5722526
2026-05-05T03:32:01Z
OctraBot
3198
สร้างหน้าด้วย "local labels = {} labels["Buddhist Hybrid Sanskrit"] = { aliases = {"BHS"}, Wikipedia = true, plain_categories = true, } labels["Epic Sanskrit"] = { aliases = {"Epic"}, Wikipedia = "Indian epic poetry#Sanskrit epics", plain_categories = true, } labels["Classical Sanskrit"] = { Wikipedia = true, } labels["Epigraphic Sanskrit"] = { Wikipedia = "Epigraphy", plain_categories = true, } labels["New Sanskrit"] = { aliases = {"Neo-Sanskrit"},..."
5722526
Scribunto
text/plain
local labels = {}
labels["Buddhist Hybrid Sanskrit"] = {
aliases = {"BHS"},
Wikipedia = true,
plain_categories = true,
}
labels["Epic Sanskrit"] = {
aliases = {"Epic"},
Wikipedia = "Indian epic poetry#Sanskrit epics",
plain_categories = true,
}
labels["Classical Sanskrit"] = {
Wikipedia = true,
}
labels["Epigraphic Sanskrit"] = {
Wikipedia = "Epigraphy",
plain_categories = true,
}
labels["New Sanskrit"] = {
aliases = {"Neo-Sanskrit"},
Wikipedia = "Sanskrit revival",
plain_categories = true,
}
labels["Later Sanskrit"] = {
aliases = {"Later-Sanskrit", "later Sanskrit", "later-Sanskrit", "Later", "later"},
display = "[[later|Later]] [[Sanskrit]]",
plain_categories = true,
}
labels["พระเวท"] = {
aliases = {"เวท", "Vedic", "Veda", "Vedic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตพระเวท",
regional_categories = true,
}
labels["ฤคเวท"] = {
aliases = {"Rigvedic", "RV", "Rigveda", "Rig Veda", "Rigvedic Sanskrit"},
Wikipedia = "ฤคเวท",
regional_categories = true,
}
labels["ยชุรเวท"] = {
aliases = {"Yajurvedic", "YV", "Yajurveda", "Yajur Veda", "Yajurvedic Sanskrit"},
Wikipedia = "ยชุรเวท",
}
labels["สามเวท"] = {
aliases = {"Samavedic", "SV", "Samaveda", "Sama Veda", "Samavedic Sanskrit"},
Wikipedia = "สามเวท",
}
labels["อถรรพเวท"] = {
aliases = {"Atharvavedic", "AV", "Atharvaveda", "Atharva Veda", "Atharvavedic Sanskrit"},
Wikipedia = "อถรรพเวท",
}
return require("Module:labels").finalize_data(labels)
4ntx48y2utnk5l8dnm8awo0t4ms5cmj
5722527
5722526
2026-05-05T03:43:36Z
OctraBot
3198
5722527
Scribunto
text/plain
local labels = {}
labels["Buddhist Hybrid Sanskrit"] = {
aliases = {"BHS"},
Wikipedia = true,
plain_categories = true,
}
labels["Epic Sanskrit"] = {
aliases = {"Epic"},
Wikipedia = "Indian epic poetry#Sanskrit epics",
plain_categories = true,
}
labels["คลาสสิก"] = {
aliases = {"สันสกฤตคลาสสิก", "classical", "Classical Sanskrit"},
Wikipedia = "ภาษาสันสกฤตคลาสสิก",
}
labels["Epigraphic Sanskrit"] = {
Wikipedia = "Epigraphy",
plain_categories = true,
}
labels["New Sanskrit"] = {
aliases = {"Neo-Sanskrit"},
Wikipedia = "Sanskrit revival",
plain_categories = true,
}
labels["Later Sanskrit"] = {
aliases = {"Later-Sanskrit", "later Sanskrit", "later-Sanskrit", "Later", "later"},
display = "[[later|Later]] [[Sanskrit]]",
plain_categories = true,
}
labels["พระเวท"] = {
aliases = {"เวท", "สันสกฤตพระเวท", "Vedic", "Veda", "Vedic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตพระเวท",
regional_categories = true,
}
labels["ฤคเวท"] = {
aliases = {"Rigvedic", "RV", "Rigveda", "Rig Veda", "Rigvedic Sanskrit"},
Wikipedia = "ฤคเวท",
regional_categories = true,
}
labels["ยชุรเวท"] = {
aliases = {"Yajurvedic", "YV", "Yajurveda", "Yajur Veda", "Yajurvedic Sanskrit"},
Wikipedia = "ยชุรเวท",
}
labels["สามเวท"] = {
aliases = {"Samavedic", "SV", "Samaveda", "Sama Veda", "Samavedic Sanskrit"},
Wikipedia = "สามเวท",
}
labels["อถรรพเวท"] = {
aliases = {"Atharvavedic", "AV", "Atharvaveda", "Atharva Veda", "Atharvavedic Sanskrit"},
Wikipedia = "อถรรพเวท",
}
return require("Module:labels").finalize_data(labels)
rrlfrrgiu9dtwxry742oeb5a7jy61qe
5722528
5722527
2026-05-05T03:47:13Z
OctraBot
3198
5722528
Scribunto
text/plain
local labels = {}
labels["Buddhist Hybrid Sanskrit"] = {
aliases = {"BHS"},
Wikipedia = true,
plain_categories = true,
}
labels["มหากาพย์"] = {
aliases = {"สันสกฤตมหากาพย์", "Epic", "Epic", "Epic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตมหากาพย์",
plain_categories = true,
}
labels["คลาสสิก"] = {
aliases = {"สันสกฤตคลาสสิก", "classical", "Classical", "Classical Sanskrit"},
Wikipedia = "ภาษาสันสกฤตคลาสสิก",
}
labels["Epigraphic Sanskrit"] = {
Wikipedia = "Epigraphy",
plain_categories = true,
}
labels["New Sanskrit"] = {
aliases = {"Neo-Sanskrit"},
Wikipedia = "Sanskrit revival",
plain_categories = true,
}
labels["Later Sanskrit"] = {
aliases = {"Later-Sanskrit", "later Sanskrit", "later-Sanskrit", "Later", "later"},
display = "[[later|Later]] [[Sanskrit]]",
plain_categories = true,
}
labels["พระเวท"] = {
aliases = {"เวท", "สันสกฤตพระเวท", "Vedic", "Veda", "Vedic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตพระเวท",
regional_categories = true,
}
labels["ฤคเวท"] = {
aliases = {"Rigvedic", "RV", "Rigveda", "Rig Veda", "Rigvedic Sanskrit"},
Wikipedia = "ฤคเวท",
regional_categories = true,
}
labels["ยชุรเวท"] = {
aliases = {"Yajurvedic", "YV", "Yajurveda", "Yajur Veda", "Yajurvedic Sanskrit"},
Wikipedia = "ยชุรเวท",
}
labels["สามเวท"] = {
aliases = {"Samavedic", "SV", "Samaveda", "Sama Veda", "Samavedic Sanskrit"},
Wikipedia = "สามเวท",
}
labels["อถรรพเวท"] = {
aliases = {"Atharvavedic", "AV", "Atharvaveda", "Atharva Veda", "Atharvavedic Sanskrit"},
Wikipedia = "อถรรพเวท",
}
return require("Module:labels").finalize_data(labels)
6gclytiwoaulw2ij19fi6ugmivksxja
5722529
5722528
2026-05-05T03:47:24Z
OctraBot
3198
5722529
Scribunto
text/plain
local labels = {}
labels["Buddhist Hybrid Sanskrit"] = {
aliases = {"BHS"},
Wikipedia = true,
plain_categories = true,
}
labels["มหากาพย์"] = {
aliases = {"สันสกฤตมหากาพย์", "epic", "Epic", "Epic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตมหากาพย์",
plain_categories = true,
}
labels["คลาสสิก"] = {
aliases = {"สันสกฤตคลาสสิก", "classical", "Classical", "Classical Sanskrit"},
Wikipedia = "ภาษาสันสกฤตคลาสสิก",
}
labels["Epigraphic Sanskrit"] = {
Wikipedia = "Epigraphy",
plain_categories = true,
}
labels["New Sanskrit"] = {
aliases = {"Neo-Sanskrit"},
Wikipedia = "Sanskrit revival",
plain_categories = true,
}
labels["Later Sanskrit"] = {
aliases = {"Later-Sanskrit", "later Sanskrit", "later-Sanskrit", "Later", "later"},
display = "[[later|Later]] [[Sanskrit]]",
plain_categories = true,
}
labels["พระเวท"] = {
aliases = {"เวท", "สันสกฤตพระเวท", "Vedic", "Veda", "Vedic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตพระเวท",
regional_categories = true,
}
labels["ฤคเวท"] = {
aliases = {"Rigvedic", "RV", "Rigveda", "Rig Veda", "Rigvedic Sanskrit"},
Wikipedia = "ฤคเวท",
regional_categories = true,
}
labels["ยชุรเวท"] = {
aliases = {"Yajurvedic", "YV", "Yajurveda", "Yajur Veda", "Yajurvedic Sanskrit"},
Wikipedia = "ยชุรเวท",
}
labels["สามเวท"] = {
aliases = {"Samavedic", "SV", "Samaveda", "Sama Veda", "Samavedic Sanskrit"},
Wikipedia = "สามเวท",
}
labels["อถรรพเวท"] = {
aliases = {"Atharvavedic", "AV", "Atharvaveda", "Atharva Veda", "Atharvavedic Sanskrit"},
Wikipedia = "อถรรพเวท",
}
return require("Module:labels").finalize_data(labels)
31okiw6rkqvvltt6s8wtlc0j5m3188f
5722530
5722529
2026-05-05T03:50:51Z
OctraBot
3198
5722530
Scribunto
text/plain
local labels = {}
labels["Buddhist Hybrid Sanskrit"] = {
aliases = {"BHS"},
Wikipedia = true,
plain_categories = true,
}
labels["มหากาพย์"] = {
aliases = {"สันสกฤตมหากาพย์", "epic", "Epic", "Epic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตมหากาพย์",
plain_categories = true,
}
labels["คลาสสิก"] = {
aliases = {"สันสกฤตคลาสสิก", "classical", "Classical", "Classical Sanskrit"},
Wikipedia = "ภาษาสันสกฤตคลาสสิก",
}
labels["จารึก"] = {
aliases = {"สันสกฤตจารึก", "epigraphic", "Epigraphic", "Epigraphic Sanskrit"},
Wikipedia = "จารึกศาสตร์ภาษาสันสกฤต",
plain_categories = true,
}
labels["New Sanskrit"] = {
aliases = {"Neo-Sanskrit"},
Wikipedia = "Sanskrit revival",
plain_categories = true,
}
labels["Later Sanskrit"] = {
aliases = {"Later-Sanskrit", "later Sanskrit", "later-Sanskrit", "Later", "later"},
display = "[[later|Later]] [[Sanskrit]]",
plain_categories = true,
}
labels["พระเวท"] = {
aliases = {"เวท", "สันสกฤตพระเวท", "Vedic", "Veda", "Vedic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตพระเวท",
regional_categories = true,
}
labels["ฤคเวท"] = {
aliases = {"Rigvedic", "RV", "Rigveda", "Rig Veda", "Rigvedic Sanskrit"},
Wikipedia = "ฤคเวท",
regional_categories = true,
}
labels["ยชุรเวท"] = {
aliases = {"Yajurvedic", "YV", "Yajurveda", "Yajur Veda", "Yajurvedic Sanskrit"},
Wikipedia = "ยชุรเวท",
}
labels["สามเวท"] = {
aliases = {"Samavedic", "SV", "Samaveda", "Sama Veda", "Samavedic Sanskrit"},
Wikipedia = "สามเวท",
}
labels["อถรรพเวท"] = {
aliases = {"Atharvavedic", "AV", "Atharvaveda", "Atharva Veda", "Atharvavedic Sanskrit"},
Wikipedia = "อถรรพเวท",
}
return require("Module:labels").finalize_data(labels)
pp6ldeocacwdbmegmxky7tq8io1jg3o
5722533
5722530
2026-05-05T04:00:09Z
OctraBot
3198
5722533
Scribunto
text/plain
local labels = {}
labels["Buddhist Hybrid Sanskrit"] = {
aliases = {"BHS"},
Wikipedia = true,
plain_categories = true,
}
labels["มหากาพย์"] = {
aliases = {"สันสกฤตมหากาพย์", "epic", "Epic", "Epic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตมหากาพย์",
plain_categories = true,
}
labels["สันสกฤตคลาสสิก"] = { -- classical/คลาสสิก มีแล้วใน regional
aliases = {"Classical Sanskrit"},
Wikipedia = "ภาษาสันสกฤตคลาสสิก",
}
labels["สันสกฤตจารึก"] = { -- epigraphic/จารึก มีแล้วใน regional
aliases = {"Epigraphic Sanskrit"},
Wikipedia = "จารึกศาสตร์ภาษาสันสกฤต",
plain_categories = true,
}
labels["New Sanskrit"] = {
aliases = {"Neo-Sanskrit"},
Wikipedia = "Sanskrit revival",
plain_categories = true,
}
labels["Later Sanskrit"] = {
aliases = {"Later-Sanskrit", "later Sanskrit", "later-Sanskrit", "Later", "later"},
display = "[[later|Later]] [[Sanskrit]]",
plain_categories = true,
}
labels["พระเวท"] = {
aliases = {"เวท", "สันสกฤตพระเวท", "Vedic", "Veda", "Vedic Sanskrit"},
Wikipedia = "ภาษาสันสกฤตพระเวท",
regional_categories = true,
}
labels["ฤคเวท"] = {
aliases = {"Rigvedic", "RV", "Rigveda", "Rig Veda", "Rigvedic Sanskrit"},
Wikipedia = "ฤคเวท",
regional_categories = true,
}
labels["ยชุรเวท"] = {
aliases = {"Yajurvedic", "YV", "Yajurveda", "Yajur Veda", "Yajurvedic Sanskrit"},
Wikipedia = "ยชุรเวท",
}
labels["สามเวท"] = {
aliases = {"Samavedic", "SV", "Samaveda", "Sama Veda", "Samavedic Sanskrit"},
Wikipedia = "สามเวท",
}
labels["อถรรพเวท"] = {
aliases = {"Atharvavedic", "AV", "Atharvaveda", "Atharva Veda", "Atharvavedic Sanskrit"},
Wikipedia = "อถรรพเวท",
}
return require("Module:labels").finalize_data(labels)
bo6v17stg109zq69sy2ufuboycpp0d4
คุยกับผู้ใช้:Ballardmaize
3
2331063
5722543
2026-05-05T05:09:42Z
New user message
2698
เพิ่ม[[Template:Welcome|สารต้อนรับ]]ในหน้าคุยของผู้ใช้ใหม่
5722543
wikitext
text/x-wiki
{{Template:Welcome|realName=|name=Ballardmaize}}
-- [[ผู้ใช้:New user message|New user message]] ([[คุยกับผู้ใช้:New user message|คุย]]) 12:09, 5 พฤษภาคม 2569 (+07)
3wucs6fcislhzboivpb61zawbhj969h
คุยกับผู้ใช้:Redmin
3
2331064
5722545
2026-05-05T09:41:56Z
New user message
2698
เพิ่ม[[Template:Welcome|สารต้อนรับ]]ในหน้าคุยของผู้ใช้ใหม่
5722545
wikitext
text/x-wiki
{{Template:Welcome|realName=|name=Redmin}}
-- [[ผู้ใช้:New user message|New user message]] ([[คุยกับผู้ใช้:New user message|คุย]]) 16:41, 5 พฤษภาคม 2569 (+07)
kl8mwbog4jfzf6ubmg46kaeedmml5ww