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.47.0-wmf.24
case-sensitive
สื่อ
พิเศษ
พูดคุย
ผู้ใช้
คุยกับผู้ใช้
วิกิพจนานุกรม
คุยเรื่องวิกิพจนานุกรม
ไฟล์
คุยเรื่องไฟล์
มีเดียวิกิ
คุยเรื่องมีเดียวิกิ
แม่แบบ
คุยเรื่องแม่แบบ
วิธีใช้
คุยเรื่องวิธีใช้
หมวดหมู่
คุยเรื่องหมวดหมู่
ภาคผนวก
คุยเรื่องภาคผนวก
ดัชนี
คุยเรื่องดัชนี
สัมผัส
คุยเรื่องสัมผัส
อรรถาภิธาน
คุยเรื่องอรรถาภิธาน
TimedText
TimedText talk
มอดูล
คุยเรื่องมอดูล
Event
Event talk
มอดูล:scripts/data
828
36356
5775306
5775295
2026-10-14T13:06:13Z
Octahedron80
267
5775306
Scribunto
text/plain
--[=[
When adding new scripts to this file, please don't forget to add
style definitons for the script in [[MediaWiki:Gadget-LanguagesAndScripts.css]].
]=]
local concat = table.concat
local insert = table.insert
local ipairs = ipairs
local next = next
local remove = table.remove
local select = select
local sort = table.sort
-- Loaded on demand, as it may not be needed (depending on the data).
local function u(...)
u = require("Module:string/char")
return u(...)
end
-- We can't use mw.loadData() on [[Module:languages/chars]] because [[Module:languages/data]] itself is sometimes loaded
-- using mw.loadData(), and calling mw.loadData() on [[Module:languages/chars]] will insert metatables into the
-- character tables, which the second mw.loadData() will choke on.
local m_chars = require("Module:languages/chars")
local c = m_chars.chars
local p = m_chars.puaChars
local cs = m_chars.chars_substitutions
------------------------------------------------------------------------------------
--
-- Helper functions
--
------------------------------------------------------------------------------------
-- Note: a[2] > b[2] means opens are sorted before closes if otherwise equal.
local function sort_ranges(a, b)
return a[1] < b[1] or a[1] == b[1] and a[2] > b[2]
end
-- Returns the union of two or more range tables.
local function union(...)
local ranges = {}
for i = 1, select("#", ...) do
local argt = select(i, ...)
for j, v in ipairs(argt) do
insert(ranges, {v, j % 2 == 1 and 1 or -1})
end
end
sort(ranges, sort_ranges)
local ret, i = {}, 0
for _, range in ipairs(ranges) do
i = i + range[2]
if i == 0 and range[2] == -1 then -- close
insert(ret, range[1])
elseif i == 1 and range[2] == 1 then -- open
if ret[#ret] and range[1] <= ret[#ret] + 1 then
remove(ret) -- merge adjacent ranges
else
insert(ret, range[1])
end
end
end
return ret
end
-- Adds the `characters` key, which is determined by a script's `ranges` table.
local function process_ranges(sc)
local ranges, chars = sc.ranges, {}
for i = 2, #ranges, 2 do
if ranges[i] == ranges[i - 1] then
insert(chars, u(ranges[i]))
else
insert(chars, u(ranges[i - 1]))
if ranges[i] > ranges[i - 1] + 1 then
insert(chars, "-")
end
insert(chars, u(ranges[i]))
end
end
sc.characters = concat(chars)
ranges.n = #ranges
return sc
end
local function handle_normalization_fixes(fixes)
local combiningClasses = fixes.combiningClasses
if combiningClasses then
local chars, i = {}, 0
for char in next, combiningClasses do
i = i + 1
chars[i] = char
end
fixes.combiningClassCharacters = concat(chars)
end
return fixes
end
------------------------------------------------------------------------------------
--
-- Data
--
------------------------------------------------------------------------------------
local m = {}
m["Adlm"] = process_ranges{
"อัดลัม",
19606346,
"alphabet",
aliases = {"Adlam"},
ranges = {
0x061F, 0x061F,
0x0640, 0x0640,
0x1E900, 0x1E94B,
0x1E950, 0x1E959,
0x1E95E, 0x1E95F,
},
capitalized = true,
direction = "rtl",
}
m["Afak"] = {
"อาฟากา",
382019,
"syllabary",
aliases = {"Afaka"},
-- Not in Unicode
}
m["Aghb"] = process_ranges{
"Caucasian Albanian",
2495716,
"alphabet",
ranges = {
0x10530, 0x10563,
0x1056F, 0x1056F,
},
}
m["Ahom"] = process_ranges{
"อาหม",
2839633,
"abugida",
aliases = {"อะหม", "Ahom"},
ranges = {
0x11700, 0x1171A,
0x1171D, 0x1172B,
0x11730, 0x11746,
},
}
m["Arab"] = process_ranges{
"อาหรับ",
1828555,
"abjad", -- more precisely, impure abjad
aliases = {"อารบิก", "อาระบิก", "Arabic"},
varieties = {{"ยาวี", "Jawi"}, {"Nastaliq", "Nastaleeq"}},
ranges = {
0x0600, 0x06FF,
0x0750, 0x077F,
0x0870, 0x088E,
0x0890, 0x0891,
0x0897, 0x08E1,
0x08E3, 0x08FF,
0xFB50, 0xFBC2,
0xFBD3, 0xFD8F,
0xFD92, 0xFDC7,
0xFDCF, 0xFDCF,
0xFDF0, 0xFDFF,
0xFE70, 0xFE74,
0xFE76, 0xFEFC,
0x102E0, 0x102FB,
0x10E60, 0x10E7E,
0x10EC2, 0x10EC4,
0x10EFC, 0x10EFF,
0x1EE00, 0x1EE03,
0x1EE05, 0x1EE1F,
0x1EE21, 0x1EE22,
0x1EE24, 0x1EE24,
0x1EE27, 0x1EE27,
0x1EE29, 0x1EE32,
0x1EE34, 0x1EE37,
0x1EE39, 0x1EE39,
0x1EE3B, 0x1EE3B,
0x1EE42, 0x1EE42,
0x1EE47, 0x1EE47,
0x1EE49, 0x1EE49,
0x1EE4B, 0x1EE4B,
0x1EE4D, 0x1EE4F,
0x1EE51, 0x1EE52,
0x1EE54, 0x1EE54,
0x1EE57, 0x1EE57,
0x1EE59, 0x1EE59,
0x1EE5B, 0x1EE5B,
0x1EE5D, 0x1EE5D,
0x1EE5F, 0x1EE5F,
0x1EE61, 0x1EE62,
0x1EE64, 0x1EE64,
0x1EE67, 0x1EE6A,
0x1EE6C, 0x1EE72,
0x1EE74, 0x1EE77,
0x1EE79, 0x1EE7C,
0x1EE7E, 0x1EE7E,
0x1EE80, 0x1EE89,
0x1EE8B, 0x1EE9B,
0x1EEA1, 0x1EEA3,
0x1EEA5, 0x1EEA9,
0x1EEAB, 0x1EEBB,
0x1EEF0, 0x1EEF1,
},
direction = "rtl",
normalizationFixes = handle_normalization_fixes{
from = {"ٳ"},
to = {"اٟ"}
},
}
m["fa-Arab"] = {
"อาหรับ",
744068,
m["Arab"][3],
aliases = m["Arab"].aliases,
ranges = m["Arab"].ranges,
characters = m["Arab"].characters,
other_names = {"เปอร์โซ-อาหรับ", "Perso-Arabic"},
direction = "rtl",
parent = "Arab",
normalizationFixes = m["Arab"].normalizationFixes,
}
m["kk-Arab"] = {
"อาหรับ",
90681452,
m["Arab"][3],
aliases = m["Arab"].aliases,
ranges = m["Arab"].ranges,
characters = m["Arab"].characters,
direction = "rtl",
parent = "Arab",
normalizationFixes = m["Arab"].normalizationFixes,
}
m["ks-Arab"] = m["fa-Arab"]
m["ku-Arab"] = m["fa-Arab"]
m["ms-Arab"] = m["kk-Arab"]
m["mzn-Arab"] = m["fa-Arab"]
m["ota-Arab"] = m["fa-Arab"]
m["pa-Arab"] = {
"ศาหมุขี",
133800,
m["Arab"][3],
aliases = {"Shahmukhi"},
ranges = m["Arab"].ranges,
characters = m["Arab"].characters,
other_names = {"อารบิก", "อาระบิก", "Arabic"},
direction = "rtl",
parent = "Arab",
normalizationFixes = m["Arab"].normalizationFixes,
}
m["ps-Arab"] = m["fa-Arab"]
m["sd-Arab"] = m["fa-Arab"]
m["tt-Arab"] = m["fa-Arab"]
m["ug-Arab"] = m["fa-Arab"]
m["ur-Arab"] = m["fa-Arab"]
-- Aran (Nastaliq) is subsumed into Arab
m["Armi"] = process_ranges{
"แอราเมอิกจักรวรรดิ",
26978,
"abjad",
aliases = {"Imperial Aramaic"},
ranges = {
0x10840, 0x10855,
0x10857, 0x1085F,
},
direction = "rtl",
}
m["Armn"] = process_ranges{
"อาร์มีเนีย",
11932,
"alphabet",
aliases = {"อาร์เมเนีย", "Armenian"},
ranges = {
0x0531, 0x0556,
0x0559, 0x058A,
0x058D, 0x058F,
0xFB13, 0xFB17,
},
capitalized = true,
translit = "Armn-translit",
}
m["Avst"] = process_ranges{
"อเวสตะ",
790681,
"alphabet",
aliases = {"Avestan"},
ranges = {
0x10B00, 0x10B35,
0x10B39, 0x10B3F,
},
direction = "rtl",
}
m["pal-Avst"] = {
"Pazend",
4925073,
m["Avst"][3],
aliases = m["Avst"].aliases,
ranges = m["Avst"].ranges,
characters = m["Avst"].characters,
direction = "rtl",
parent = "Avst",
}
m["Bali"] = process_ranges{
"บาหลี",
804984,
"abugida",
aliases = {"Balinese"},
ranges = {
0x1B00, 0x1B4C,
0x1B4E, 0x1B7F,
},
}
m["Bamu"] = process_ranges{
"บามุม",
806024,
"syllabary",
aliases = {"Bamum"},
ranges = {
0xA6A0, 0xA6F7,
0x16800, 0x16A38,
},
}
m["Bass"] = process_ranges{
"บัสซา",
810458,
"alphabet",
aliases = {"วาห์", "Bassa", "Bassa Vah", "Vah"},
ranges = {
0x16AD0, 0x16AED,
0x16AF0, 0x16AF5,
},
}
m["Batk"] = process_ranges{
"บาตัก",
51592,
"abugida",
aliases = {"Batak"},
ranges = {
0x1BC0, 0x1BF3,
0x1BFC, 0x1BFF,
},
}
m["Beng"] = process_ranges{
"เบงกอล",
756802,
"abugida",
aliases = {"เบงกาลี", "บังลา", "Bengali"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0980, 0x0983,
0x0985, 0x098C,
0x098F, 0x0990,
0x0993, 0x09A8,
0x09AA, 0x09B0,
0x09B2, 0x09B2,
0x09B6, 0x09B9,
0x09BC, 0x09C4,
0x09C7, 0x09C8,
0x09CB, 0x09CE,
0x09D7, 0x09D7,
0x09DC, 0x09DD,
0x09DF, 0x09E3,
0x09E6, 0x09EF,
0x09F2, 0x09FE,
0x1CD0, 0x1CD0,
0x1CD2, 0x1CD2,
0x1CD5, 0x1CD6,
0x1CD8, 0x1CD8,
0x1CE1, 0x1CE1,
0x1CEA, 0x1CEA,
0x1CED, 0x1CED,
0x1CF2, 0x1CF2,
0x1CF5, 0x1CF7,
0xA8F1, 0xA8F1,
},
normalizationFixes = handle_normalization_fixes{
from = {"অা", "ঋৃ", "ঌৢ"},
to = {"আ", "ৠ", "ৡ"}
},
}
m["as-Beng"] = process_ranges{
"อัสสัม",
191272,
m["Beng"][3],
other_names = {"เบงกอล-อัสสัม", "เบงกาลี-อัสสัม", "นาครีตะวันออก", "Assamese", "Bengali-Assamese", "Eastern Nagari"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0980, 0x0983,
0x0985, 0x098C,
0x098F, 0x0990,
0x0993, 0x09A8,
0x09AA, 0x09AF,
0x09B2, 0x09B2,
0x09B6, 0x09B9,
0x09BC, 0x09C4,
0x09C7, 0x09C8,
0x09CB, 0x09CE,
0x09D7, 0x09D7,
0x09DC, 0x09DD,
0x09DF, 0x09E3,
0x09E6, 0x09FE,
0x1CD0, 0x1CD0,
0x1CD2, 0x1CD2,
0x1CD5, 0x1CD6,
0x1CD8, 0x1CD8,
0x1CE1, 0x1CE1,
0x1CEA, 0x1CEA,
0x1CED, 0x1CED,
0x1CF2, 0x1CF2,
0x1CF5, 0x1CF7,
0xA8F1, 0xA8F1,
},
normalizationFixes = m["Beng"].normalizationFixes,
}
m["Bhks"] = process_ranges{
"ไภกษุกี",
17017839,
"abugida",
aliases = {"Bhaiksuki"},
ranges = {
0x11C00, 0x11C08,
0x11C0A, 0x11C36,
0x11C38, 0x11C45,
0x11C50, 0x11C6C,
},
}
m["Blis"] = {
"Blissymbolic",
609817,
"logography",
aliases = {"Blissymbols"},
-- Not in Unicode
}
m["Bopo"] = process_ranges{
"จู้อิน",
198269,
"semisyllabary",
aliases = {"จู้อินฝูเฮ่า", "ปอพอมอฟอ", "ปัวพัวมัวฟัว", "Zhuyin", "Zhuyin Fuhao", "Bopomofo"},
ranges = {
0x02EA, 0x02EB,
0x3001, 0x3003,
0x3008, 0x3011,
0x3013, 0x301F,
0x302A, 0x302D,
0x3030, 0x3030,
0x3037, 0x3037,
0x30FB, 0x30FB,
0x3105, 0x312F,
0x31A0, 0x31BF,
0xFE45, 0xFE46,
0xFF61, 0xFF65,
},
}
m["Brah"] = process_ranges{
"พราหมี",
185083,
"abugida",
aliases = {"พราหฺมี", "Brahmi"},
ranges = {
0x11000, 0x1104D,
0x11052, 0x11075,
0x1107F, 0x1107F,
},
normalizationFixes = handle_normalization_fixes{
from = {"𑀅𑀸", "𑀋𑀾", "𑀏𑁂"},
to = {"𑀆", "𑀌", "𑀐"}
},
translit = "Brah-translit",
}
m["Brai"] = process_ranges{
"เบรลล์",
79894,
"alphabet",
aliases = {"Braille"},
ranges = {
0x2800, 0x28FF,
},
}
m["Bugi"] = process_ranges{
"ลนตารา",
1074947,
"abugida",
aliases = {"บูกิส", "Lontara", "Buginese"},
ranges = {
0x1A00, 0x1A1B,
0x1A1E, 0x1A1F,
0xA9CF, 0xA9CF,
},
}
m["Buhd"] = process_ranges{
"บูฮิด",
1002969,
"abugida",
aliases = {"Buhid"},
ranges = {
0x1735, 0x1736,
0x1740, 0x1751,
0x1752, 0x1753,
},
}
m["Cakm"] = process_ranges{
"จักมา",
1059328,
"abugida",
aliases = {"Chakma"},
ranges = {
0x09E6, 0x09EF,
0x1040, 0x1049,
0x11100, 0x11134,
0x11136, 0x11147,
},
}
m["Cans"] = process_ranges{
"Canadian syllabic",
2479183,
"abugida",
ranges = {
0x1400, 0x167F,
0x18B0, 0x18F5,
0x11AB0, 0x11ABF,
},
}
m["Cari"] = process_ranges{
"คาเรีย",
1094567,
"alphabet",
aliases = {"Carian"},
ranges = {
0x102A0, 0x102D0,
},
}
m["Cham"] = process_ranges{
"จาม",
1060381,
"abugida",
aliases = {"Cham"},
ranges = {
0xAA00, 0xAA36,
0xAA40, 0xAA4D,
0xAA50, 0xAA59,
0xAA5C, 0xAA5F,
},
}
m["Cher"] = process_ranges{
"เชโรกี",
26549,
"syllabary",
aliases = {"Cherokee"},
ranges = {
0x13A0, 0x13F5,
0x13F8, 0x13FD,
0xAB70, 0xABBF,
},
}
m["Chis"] = {
"Chisoi",
123173777,
"abugida",
-- Not in Unicode
}
m["Chrs"] = process_ranges{
"ฆวารัซม์",
72386710,
"abjad",
aliases = {"โคแรสเมีย", "Khwarezmian", "Chorasmian"},
ranges = {
0x10FB0, 0x10FCB,
},
direction = "rtl",
}
m["Copt"] = process_ranges{
"คอปติก",
321083,
"alphabet",
aliases = {"Coptic"},
ranges = {
0x03E2, 0x03EF,
0x2C80, 0x2CF3,
0x2CF9, 0x2CFF,
0x102E0, 0x102FB,
},
capitalized = true,
}
m["Cpmn"] = process_ranges{
"Cypro-Minoan",
1751985,
"syllabary",
aliases = {"Cypro Minoan"},
ranges = {
0x10100, 0x10101,
0x12F90, 0x12FF2,
},
}
m["Cprt"] = process_ranges{
"ไซปรัส",
1757689,
"syllabary",
aliases = {"ไซเปรียท", "Cypriot"},
ranges = {
0x10100, 0x10102,
0x10107, 0x10133,
0x10137, 0x1013F,
0x10800, 0x10805,
0x10808, 0x10808,
0x1080A, 0x10835,
0x10837, 0x10838,
0x1083C, 0x1083C,
0x1083F, 0x1083F,
},
direction = "rtl",
}
m["Cyrl"] = process_ranges{
"ซีริลลิก",
8209,
"alphabet",
aliases = {"Cyrillic"},
ranges = {
0x0400, 0x052F,
0x1C80, 0x1C8A,
0x1D2B, 0x1D2B,
0x1D78, 0x1D78,
0x1DF8, 0x1DF8,
0x2DE0, 0x2DFF,
0x2E43, 0x2E43,
0xA640, 0xA69F,
0xFE2E, 0xFE2F,
0x1E030, 0x1E06D,
0x1E08F, 0x1E08F,
},
capitalized = true,
}
m["Cyrs"] = {
"ซีริลลิกเก่า",
442244,
m["Cyrl"][3],
aliases = {"ซีริลลิกช่วงต้น", "Old Cyrillic", "Early Cyrillic"},
ranges = m["Cyrl"].ranges,
characters = m["Cyrl"].characters,
capitalized = m["Cyrl"].capitalized,
wikipedia_article = "Early Cyrillic alphabet",
normalizationFixes = handle_normalization_fixes{
from = {"Ѹ", "ѹ"},
to = {"Ꙋ", "ꙋ"}
},
strip_diacritics = {remove_diacritics = cs.Cyrs_remove_diacritics},
sort_key = {
remove_diacritics = cs.Cyrs_remove_diacritics,
from = {
"ї", "оу", -- 2 chars
"[ґꙣєѕꙃꙅꙁіꙇђꙉѻꙩꙫꙭꙮꚙꚛꙋѡѿꙍѽꙑѣꙗѥꙕѧꙙѩꙝꙛѫѭѯѱѳѵҁ]"
},
to = {
"и" .. p[1], "у", {
["ґ"] = "г" .. p[1], ["ꙣ"] = "д" .. p[1], ["є"] = "е", ["ѕ"] = "ж" .. p[1], ["ꙃ"] = "ж" .. p[1],
["ꙅ"] = "ж" .. p[1], ["ꙁ"] = "з", ["і"] = "и" .. p[1], ["ꙇ"] = "и" .. p[1], ["ђ"] = "и" .. p[2],
["ꙉ"] = "и" .. p[2], ["ѻ"] = "о", ["ꙩ"] = "о", ["ꙫ"] = "о", ["ꙭ"] = "о",
["ꙮ"] = "о", ["ꚙ"] = "о", ["ꚛ"] = "о", ["ꙋ"] = "у", ["ѡ"] = "х" .. p[1],
["ѿ"] = "х" .. p[1], ["ꙍ"] = "х" .. p[1], ["ѽ"] = "х" .. p[1], ["ꙑ"] = "ы", ["ѣ"] = "ь" .. p[1],
["ꙗ"] = "ь" .. p[2], ["ѥ"] = "ь" .. p[3], ["ꙕ"] = "ю", ["ѧ"] = "я", ["ꙙ"] = "я",
["ѩ"] = "я" .. p[1], ["ꙝ"] = "я" .. p[1], ["ꙛ"] = "я" .. p[2], ["ѫ"] = "я" .. p[3], ["ѭ"] = "я" .. p[4],
["ѯ"] = "я" .. p[5], ["ѱ"] = "я" .. p[6], ["ѳ"] = "я" .. p[7], ["ѵ"] = "я" .. p[8], ["ҁ"] = "я" .. p[9],
}
},
}
}
m["Deva"] = process_ranges{
"เทวนาครี",
38592,
"abugida",
aliases = {"Devanagari"},
ranges = {
0x0900, 0x097F,
0x1CD0, 0x1CF6,
0x1CF8, 0x1CF9,
0x20F0, 0x20F0,
0xA830, 0xA839,
0xA8E0, 0xA8FF,
0x11B00, 0x11B09,
},
normalizationFixes = handle_normalization_fixes{
from = {"ॆॆ", "ेे", "ाॅ", "ाॆ", "ाꣿ", "ॊॆ", "ाे", "ाै", "ोे", "ाऺ", "ॖॖ", "अॅ", "अॆ", "अा", "एॅ", "एॆ", "एे", "एꣿ", "ऎॆ", "अॉ", "आॅ", "अॊ", "आॆ", "अो", "आे", "अौ", "आै", "ओे", "अऺ", "अऻ", "आऺ", "अाꣿ", "आꣿ", "ऒॆ", "अॖ", "अॗ", "ॶॖ", "्?ा"},
to = {"ꣿ", "ै", "ॉ", "ॊ", "ॏ", "ॏ", "ो", "ौ", "ौ", "ऻ", "ॗ", "ॲ", "ऄ", "आ", "ऍ", "ऎ", "ऐ", "ꣾ", "ꣾ", "ऑ", "ऑ", "ऒ", "ऒ", "ओ", "ओ", "औ", "औ", "औ", "ॳ", "ॴ", "ॴ", "ॵ", "ॵ", "ॵ", "ॶ", "ॷ", "ॷ"}
},
}
m["Diak"] = process_ranges{
"ดิเวส อกุรุ",
3307073,
"abugida",
aliases = {"ดิเวหิ อกุรุ", "Dhives Akuru", "Dhivehi Akuru", "Dives Akuru", "Divehi Akuru"},
ranges = {
0x11900, 0x11906,
0x11909, 0x11909,
0x1190C, 0x11913,
0x11915, 0x11916,
0x11918, 0x11935,
0x11937, 0x11938,
0x1193B, 0x11946,
0x11950, 0x11959,
},
}
m["Dogr"] = process_ranges{
"โฑครี",
72402987,
"abugida",
aliases = {"Dogri", "Dogra"},
ranges = {
0x0964, 0x096F,
0xA830, 0xA839,
0x11800, 0x1183B,
},
}
m["Dsrt"] = process_ranges{
"Deseret",
1200582,
"alphabet",
ranges = {
0x10400, 0x1044F,
},
capitalized = true,
}
m["Dupl"] = process_ranges{
"Duployan",
5316025,
"alphabet",
ranges = {
0x1BC00, 0x1BC6A,
0x1BC70, 0x1BC7C,
0x1BC80, 0x1BC88,
0x1BC90, 0x1BC99,
0x1BC9C, 0x1BCA3,
},
}
m["Egyd"] = {
"Demotic",
188519,
"abjad, logography",
-- Not in Unicode
}
m["Egyh"] = {
"Hieratic",
208111,
"abjad, logography",
-- Unified with Egyptian hieroglyphic in Unicode
}
m["Egyp"] = process_ranges{
"ไฮเออโรกลีฟอียิปต์",
132659,
"abjad, logography",
aliases = {"Egyptian hieroglyphic"},
ranges = {
0x13000, 0x13455,
0x13460, 0x143FA,
},
varieties = {"Hieratic"},
wikipedia_article = "ไฮเออโรกลีฟอียิปต์",
normalizationFixes = handle_normalization_fixes{
from = {"𓃁", "𓆖"},
to = {"𓃀𓂝", "𓆓𓏏𓇿"}
},
}
m["Elba"] = process_ranges{
"เอลบาซาน",
1036714,
"alphabet",
aliases = {"Elbasan"},
ranges = {
0x10500, 0x10527,
},
}
m["Elym"] = process_ranges{
"Elymaic",
60744423,
"abjad",
ranges = {
0x10FE0, 0x10FF6,
},
direction = "rtl",
}
m["Ethi"] = process_ranges{
"เอธิโอเปีย",
257634,
"abugida",
aliases = {"กืออึซ", "Ethiopic", "Ge'ez"},
ranges = {
0x1200, 0x1248,
0x124A, 0x124D,
0x1250, 0x1256,
0x1258, 0x1258,
0x125A, 0x125D,
0x1260, 0x1288,
0x128A, 0x128D,
0x1290, 0x12B0,
0x12B2, 0x12B5,
0x12B8, 0x12BE,
0x12C0, 0x12C0,
0x12C2, 0x12C5,
0x12C8, 0x12D6,
0x12D8, 0x1310,
0x1312, 0x1315,
0x1318, 0x135A,
0x135D, 0x137C,
0x1380, 0x1399,
0x2D80, 0x2D96,
0x2DA0, 0x2DA6,
0x2DA8, 0x2DAE,
0x2DB0, 0x2DB6,
0x2DB8, 0x2DBE,
0x2DC0, 0x2DC6,
0x2DC8, 0x2DCE,
0x2DD0, 0x2DD6,
0x2DD8, 0x2DDE,
0xAB01, 0xAB06,
0xAB09, 0xAB0E,
0xAB11, 0xAB16,
0xAB20, 0xAB26,
0xAB28, 0xAB2E,
0x1E7E0, 0x1E7E6,
0x1E7E8, 0x1E7EB,
0x1E7ED, 0x1E7EE,
0x1E7F0, 0x1E7FE,
},
sort_key = "Ethi-sortkey",
}
m["Gara"] = process_ranges{
"Garay",
3095302,
"alphabet",
capitalized = true,
direction = "rtl",
ranges = {
0x060C, 0x060C,
0x061B, 0x061B,
0x061F, 0x061F,
0x10D40, 0x10D65,
0x10D69, 0x10D85,
0x10D8E, 0x10D8F,
},
}
m["Geok"] = process_ranges{
"Khutsuri",
1090055,
"alphabet",
ranges = { -- Ⴀ-Ⴭ is Asomtavruli, ⴀ-ⴭ is Nuskhuri
0x10A0, 0x10C5,
0x10C7, 0x10C7,
0x10CD, 0x10CD,
0x10FB, 0x10FB,
0x2D00, 0x2D25,
0x2D27, 0x2D27,
0x2D2D, 0x2D2D,
},
varieties = {"Nuskhuri", "Asomtavruli"},
capitalized = true,
translit = "Geok-translit",
}
m["Geor"] = process_ranges{
"จอร์เจีย",
3317411,
"alphabet",
aliases = {"Georgian"},
ranges = { -- ა-ჿ is lowercase Mkhedruli; Ა-Ჿ is uppercase Mkhedruli (Mtavruli)
0x0589, 0x0589,
0x10D0, 0x10FF,
0x1C90, 0x1CBA,
0x1CBD, 0x1CBF,
},
varieties = {"Mkhedruli", "Mtavruli"},
capitalized = true,
translit = "Geor-translit",
}
m["Glag"] = process_ranges{
"กลาโกลิติก",
145625,
"alphabet",
aliases = {"Glagolitic"},
ranges = {
0x0484, 0x0484,
0x0487, 0x0487,
0x0589, 0x0589,
0x10FB, 0x10FB,
0x2C00, 0x2C5F,
0x2E43, 0x2E43,
0xA66F, 0xA66F,
0x1E000, 0x1E006,
0x1E008, 0x1E018,
0x1E01B, 0x1E021,
0x1E023, 0x1E024,
0x1E026, 0x1E02A,
},
capitalized = true,
}
m["Gong"] = process_ranges{
"คุญชลาโคณฑี",
18125340,
"abugida",
aliases = {"Gunjala Gondi"},
ranges = {
0x0964, 0x0965,
0x11D60, 0x11D65,
0x11D67, 0x11D68,
0x11D6A, 0x11D8E,
0x11D90, 0x11D91,
0x11D93, 0x11D98,
0x11DA0, 0x11DA9,
},
}
m["Gonm"] = process_ranges{
"มสรามโคณฑี",
16977603,
"abugida",
aliases = {"Masaram Gondi"},
ranges = {
0x0964, 0x0965,
0x11D00, 0x11D06,
0x11D08, 0x11D09,
0x11D0B, 0x11D36,
0x11D3A, 0x11D3A,
0x11D3C, 0x11D3D,
0x11D3F, 0x11D47,
0x11D50, 0x11D59,
},
}
m["Goth"] = process_ranges{
"กอท",
467784,
"alphabet",
aliases = {"กอทิก", "กอทิค", "กอธิก", "กอธิค", "โกทิก", "โกทิค", "โกธิก", "โกธิค", "Gothic"},
ranges = {
0x10330, 0x1034A,
},
wikipedia_article = "Gothic alphabet",
}
m["Gran"] = process_ranges{
"ครันถะ",
1119274,
"abugida",
aliases = {"Grantha"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0BE6, 0x0BF3,
0x1CD0, 0x1CD0,
0x1CD2, 0x1CD3,
0x1CF2, 0x1CF4,
0x1CF8, 0x1CF9,
0x20F0, 0x20F0,
0x11300, 0x11303,
0x11305, 0x1130C,
0x1130F, 0x11310,
0x11313, 0x11328,
0x1132A, 0x11330,
0x11332, 0x11333,
0x11335, 0x11339,
0x1133B, 0x11344,
0x11347, 0x11348,
0x1134B, 0x1134D,
0x11350, 0x11350,
0x11357, 0x11357,
0x1135D, 0x11363,
0x11366, 0x1136C,
0x11370, 0x11374,
0x11FD0, 0x11FD1,
0x11FD3, 0x11FD3,
},
}
m["Grek"] = process_ranges{
"กรีก",
8216,
"alphabet",
aliases = {"Greek"},
ranges = {
0x0341, 0x0341,
0x0374, 0x0375,
0x037E, 0x037E,
0x0384, 0x038A,
0x038C, 0x038C,
0x038E, 0x03A1,
0x03A3, 0x03D7,
0x03DA, 0x03DB,
0x03DE, 0x03E1,
0x03F0, 0x03F1,
0x03F4, 0x03F4,
0x03FC, 0x03FC,
0x1D26, 0x1D2A,
0x1D5D, 0x1D61,
0x1D66, 0x1D6A,
0x1DBF, 0x1DBF,
0x2126, 0x2127,
0x2129, 0x2129,
0x213C, 0x2140,
0xAB65, 0xAB65,
0x10140, 0x1018E,
0x101A0, 0x101A0,
0x1D200, 0x1D245,
},
capitalized = true,
display_text = cs["Grek-displaytext"],
strip_diacritics = cs["Grek-stripdiacritics"],
sort_key = {
remove_diacritics = "'ʼ;·`¨´῀" .. c.grave .. c.acute .. c.diaer .. c.caron .. c.turnedcommaabove .. c.commaabove .. c.revcommaabove .. c.macron .. c.breve .. c.diaerbelow .. c.brevebelow .. c.perispomeni .. c.ypogegrammeni .. c.RSQuo .. c.prime .. c.keraia .. c.lowerkeraia .. c.tonos .. c.coronis .. c.psili .. c.dasia,
from = {"ϝ", "ͷ", "ϛ", "ͱ", "ͺ", "ϳ", "ϻ", "[ϟϙ]", "[ςϲ]", "ͳ"},
to = {"ε" .. p[1], "ε" .. p[2], "ε" .. p[3], "ζ" .. p[1], "ι", "ι" .. p[1], "π" .. p[1], "π" .. p[2], "σ", "ϡ"},
},
}
m["Polyt"] = process_ranges{
"กรีก",
1475332,
m["Grek"][3],
aliases = m["Grek"].aliases,
ranges = union(m["Grek"].ranges, {
0x0340, 0x0340,
0x0342, 0x0345,
0x0370, 0x0373,
0x0376, 0x0377,
0x037A, 0x037D,
0x037F, 0x037F,
0x03D8, 0x03D9,
0x03DC, 0x03DD,
0x03F2, 0x03F3,
0x03F5, 0x03FB,
0x03FD, 0x03FF,
0x1F00, 0x1F15,
0x1F18, 0x1F1D,
0x1F20, 0x1F45,
0x1F48, 0x1F4D,
0x1F50, 0x1F57,
0x1F59, 0x1F59,
0x1F5B, 0x1F5B,
0x1F5D, 0x1F5D,
0x1F5F, 0x1F7D,
0x1F80, 0x1FB4,
0x1FB6, 0x1FC4,
0x1FC6, 0x1FD3,
0x1FD6, 0x1FDB,
0x1FDD, 0x1FEF,
0x1FF2, 0x1FF4,
0x1FF6, 0x1FFE,
}),
ietf_subtag = "Grek",
capitalized = m["Grek"].capitalized,
parent = "Grek",
display_text = m["Grek"].display_text,
strip_diacritics = "Polyt-stripdiacritics",
sort_key = m["Grek"].sort_key,
translit = "grc-translit",
}
m["Gujr"] = process_ranges{
"คุชราต",
733944,
"abugida",
aliases = {"คุชราตี", "Gujarati"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0A81, 0x0A83,
0x0A85, 0x0A8D,
0x0A8F, 0x0A91,
0x0A93, 0x0AA8,
0x0AAA, 0x0AB0,
0x0AB2, 0x0AB3,
0x0AB5, 0x0AB9,
0x0ABC, 0x0AC5,
0x0AC7, 0x0AC9,
0x0ACB, 0x0ACD,
0x0AD0, 0x0AD0,
0x0AE0, 0x0AE3,
0x0AE6, 0x0AF1,
0x0AF9, 0x0AFF,
0xA830, 0xA839,
},
normalizationFixes = handle_normalization_fixes{
from = {"ઓ", "અાૈ", "અા", "અૅ", "અે", "અૈ", "અૉ", "અો", "અૌ", "આૅ", "આૈ", "ૅા"},
to = {"અાૅ", "ઔ", "આ", "ઍ", "એ", "ઐ", "ઑ", "ઓ", "ઔ", "ઓ", "ઔ", "ૉ"}
},
}
m["Gukh"] = process_ranges{
"Khema",
110064239,
"abugida",
aliases = {"Gurung Khema", "Khema Phri", "Khema Lipi"},
ranges = {
0x0965, 0x0965,
0x16100, 0x16139,
},
}
m["Guru"] = process_ranges{
"คุรมุขี",
689894,
"abugida",
aliases = {"กูร์มูคี", "เกอร์มุกห์", "Gurmukhi"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0A01, 0x0A03,
0x0A05, 0x0A0A,
0x0A0F, 0x0A10,
0x0A13, 0x0A28,
0x0A2A, 0x0A30,
0x0A32, 0x0A33,
0x0A35, 0x0A36,
0x0A38, 0x0A39,
0x0A3C, 0x0A3C,
0x0A3E, 0x0A42,
0x0A47, 0x0A48,
0x0A4B, 0x0A4D,
0x0A51, 0x0A51,
0x0A59, 0x0A5C,
0x0A5E, 0x0A5E,
0x0A66, 0x0A76,
0xA830, 0xA839,
},
normalizationFixes = handle_normalization_fixes{
from = {"ਅਾ", "ਅੈ", "ਅੌ", "ੲਿ", "ੲੀ", "ੲੇ", "ੳੁ", "ੳੂ", "ੳੋ"},
to = {"ਆ", "ਐ", "ਔ", "ਇ", "ਈ", "ਏ", "ਉ", "ਊ", "ਓ"}
},
}
m["Hang"] = process_ranges{
"ฮันกึล",
8222,
"syllabary",
aliases = {"ฮังกึล", "Hangul", "Hangeul"},
ranges = {
0x1100, 0x11FF,
0x3001, 0x3003,
0x3008, 0x3011,
0x3013, 0x301F,
0x302E, 0x3030,
0x3037, 0x3037,
0x30FB, 0x30FB,
0x3131, 0x318E,
0x3200, 0x321E,
0x3260, 0x327E,
0xA960, 0xA97C,
0xAC00, 0xD7A3,
0xD7B0, 0xD7C6,
0xD7CB, 0xD7FB,
0xFE45, 0xFE46,
0xFF61, 0xFF65,
0xFFA0, 0xFFBE,
0xFFC2, 0xFFC7,
0xFFCA, 0xFFCF,
0xFFD2, 0xFFD7,
0xFFDA, 0xFFDC,
},
}
m["Hani"] = process_ranges{
"จีน",
8201,
"logography",
aliases = {"ฮั่น", "Han"},
ranges = {
0x2E80, 0x2E99,
0x2E9B, 0x2EF3,
0x2F00, 0x2FD5,
0x2FF0, 0x2FFF,
0x3001, 0x3003,
0x3005, 0x3011,
0x3013, 0x301F,
0x3021, 0x302D,
0x3030, 0x3030,
0x3037, 0x303F,
0x3190, 0x319F,
0x31C0, 0x31E5,
0x31EF, 0x31EF,
0x3220, 0x3247,
0x3280, 0x32B0,
0x32C0, 0x32CB,
0x30FB, 0x30FB,
0x32FF, 0x32FF,
0x3358, 0x3370,
0x337B, 0x337F,
0x33E0, 0x33FE,
0x3400, 0x4DBF,
0x4E00, 0x9FFF,
0xA700, 0xA707,
0xF900, 0xFA6D,
0xFA70, 0xFAD9,
0xFE45, 0xFE46,
0xFF61, 0xFF65,
0x16FE2, 0x16FE3,
0x16FF0, 0x16FF1,
0x1D360, 0x1D371,
0x1F250, 0x1F251,
0x20000, 0x2A6DF,
0x2A700, 0x2B739,
0x2B740, 0x2B81D,
0x2B820, 0x2CEA1,
0x2CEB0, 0x2EBE0,
0x2EBF0, 0x2EE5D,
0x2F800, 0x2FA1D,
0x30000, 0x3134A,
0x31350, 0x323AF,
},
varieties = {{"ฮั่นจื่อ", "Hanzi"}, {"คันจิ", "Kanji"}, {"ฮันจา", "Hanja"}, {"จื๋อโนม", "Chu Nom"}},
spaces = false,
}
m["Hans"] = {
"จีนตัวย่อ",
185614,
m["Hani"][3],
aliases = {"Simplified Han"},
ranges = m["Hani"].ranges,
characters = m["Hani"].characters,
spaces = m["Hani"].spaces,
parent = "Hani",
}
m["Hant"] = {
"จีนตัวเต็ม",
178528,
m["Hani"][3],
aliases = {"Traditional Han"},
ranges = m["Hani"].ranges,
characters = m["Hani"].characters,
spaces = m["Hani"].spaces,
parent = "Hani",
}
m["Hano"] = process_ranges{
"ฮานูโนโอ",
1584045,
"abugida",
aliases = {"Hanunoo", "Hanunó'o", "Hanuno'o"},
ranges = {
0x1720, 0x1736,
},
}
m["Hatr"] = process_ranges{
"Hatran",
20813038,
"abjad",
ranges = {
0x108E0, 0x108F2,
0x108F4, 0x108F5,
0x108FB, 0x108FF,
},
direction = "rtl",
}
m["Hebr"] = process_ranges{
"ฮีบรู",
33513,
"abjad", -- more precisely, impure abjad
aliases = {"Hebrew"},
ranges = {
0x0591, 0x05C7,
0x05D0, 0x05EA,
0x05EF, 0x05F4,
0x2135, 0x2138,
0xFB1D, 0xFB36,
0xFB38, 0xFB3C,
0xFB3E, 0xFB3E,
0xFB40, 0xFB41,
0xFB43, 0xFB44,
0xFB46, 0xFB4F,
},
direction = "rtl",
display_text = "Hebr-common",
sort_key = "Hebr-common",
strip_diacritics = "Hebr-common",
}
m["Hira"] = process_ranges{
"ฮิรางานะ",
48332,
"syllabary",
aliases = {"ฮิระงะนะ", "Hiragana"},
ranges = {
0x3001, 0x3003,
0x3008, 0x3011,
0x3013, 0x301F,
0x3030, 0x3035,
0x3037, 0x3037,
0x303C, 0x303D,
0x3041, 0x3096,
0x3099, 0x30A0,
0x30FB, 0x30FC,
0xFE45, 0xFE46,
0xFF61, 0xFF65,
0xFF70, 0xFF70,
0xFF9E, 0xFF9F,
0x1B001, 0x1B11F,
0x1B132, 0x1B132,
0x1B150, 0x1B152,
0x1F200, 0x1F200,
},
varieties = {{"เฮ็นไตงานะ", "Hentaigana"}},
spaces = false,
}
m["Hluw"] = process_ranges{
"ไฮเออโรกลีฟอานาโตเลีย",
521323,
"logography, syllabary",
aliases = {"Anatolian Hieroglyphs"},
ranges = {
0x14400, 0x14646,
},
wikipedia_article = "ไฮเออโรกลีฟอานาโตเลีย",
}
m["Hmng"] = process_ranges{
"Pahawh Hmong",
365954,
"semisyllabary",
aliases = {"ม้ง", "Hmong"},
ranges = {
0x16B00, 0x16B45,
0x16B50, 0x16B59,
0x16B5B, 0x16B61,
0x16B63, 0x16B77,
0x16B7D, 0x16B8F,
},
}
m["Hmnp"] = process_ranges{
"Nyiakeng Puachue Hmong",
33712499,
"alphabet",
ranges = {
0x1E100, 0x1E12C,
0x1E130, 0x1E13D,
0x1E140, 0x1E149,
0x1E14E, 0x1E14F,
},
}
m["Hung"] = process_ranges{
"ฮังการีเก่า",
446224,
"alphabet",
aliases = {"รูนฮังการี", "Old Hungarian", "Hungarian runic"},
ranges = {
0x10C80, 0x10CB2,
0x10CC0, 0x10CF2,
0x10CFA, 0x10CFF,
},
capitalized = true,
direction = "rtl",
}
m["Ibrnn"] = {
"ไอบีเรียตะวันออกเฉียงเหนือ",
1113155,
"semisyllabary",
aliases = {"Northeastern Iberian"},
ietf_subtag = "Zzzz",
-- Not in Unicode
}
m["Ibrns"] = {
"ไอบีเรียตะวันออกเฉียงใต้",
2305351,
"semisyllabary",
aliases = {"Southeastern Iberian"},
ietf_subtag = "Zzzz",
-- Not in Unicode
}
m["Image"] = {
-- To be used to avoid any formatting or link processing
"Image-rendered",
478798,
-- This should not have any characters listed
ietf_subtag = "Zyyy",
translit = false,
character_category = false, -- none
}
m["Inds"] = {
"สินธุ",
601388,
aliases = {"อินดัส", "Indus", "Harappan", "Indus Valley"},
}
m["Ipach"] = {
"สัทอักษรสากล",
21204,
aliases = {"International Phonetic Alphabet", "IPA"},
ietf_subtag = "Latn",
}
m["Ital"] = process_ranges{
"อิตาลิกเก่า",
4891256,
"alphabet",
aliases = {"Old Italic"},
ranges = {
0x10300, 0x10323,
0x1032D, 0x1032F,
},
translit = "Ital-translit",
}
m["Java"] = process_ranges{
"ชวา",
879704,
"abugida",
aliases = {"Javanese"},
ranges = {
0xA980, 0xA9CD,
0xA9CF, 0xA9D9,
0xA9DE, 0xA9DF,
},
}
m["Jurc"] = {
"จูร์เชน",
912240,
"logography",
aliases = {"Jurchen"},
spaces = false,
}
m["Kali"] = process_ranges{
"กะยา",
4919239,
"abugida",
aliases = {"Kayah Li"},
ranges = {
0xA900, 0xA92F,
},
}
m["Kana"] = process_ranges{
"คาตากานะ",
82946,
"syllabary",
aliases = {"คะตะกะนะ", "Katakana"},
ranges = {
0x3001, 0x3003,
0x3008, 0x3011,
0x3013, 0x301F,
0x3030, 0x3035,
0x3037, 0x3037,
0x303C, 0x303D,
0x3099, 0x309C,
0x30A0, 0x30FF,
0x31F0, 0x31FF,
0x32D0, 0x32FE,
0x3300, 0x3357,
0xFE45, 0xFE46,
0xFF61, 0xFF9F,
0x1AFF0, 0x1AFF3,
0x1AFF5, 0x1AFFB,
0x1AFFD, 0x1AFFE,
0x1B000, 0x1B000,
0x1B120, 0x1B122,
0x1B155, 0x1B155,
0x1B164, 0x1B167,
},
spaces = false,
}
m["Kawi"] = process_ranges{
"กวิ",
975802,
"abugida",
aliases = {"Kawi"},
ranges = {
0x11F00, 0x11F10,
0x11F12, 0x11F3A,
0x11F3E, 0x11F5A,
},
}
m["Khar"] = process_ranges{
"ขโรษฐี",
1161266,
"abugida",
aliases = {"Kharoshthi"},
ranges = {
0x10A00, 0x10A03,
0x10A05, 0x10A06,
0x10A0C, 0x10A13,
0x10A15, 0x10A17,
0x10A19, 0x10A35,
0x10A38, 0x10A3A,
0x10A3F, 0x10A48,
0x10A50, 0x10A58,
},
direction = "rtl",
}
m["Khmr"] = process_ranges{
"เขมร",
1054190,
"abugida",
aliases = {"Khmer"},
ranges = {
0x1780, 0x17DD,
0x17E0, 0x17E9,
0x17F0, 0x17F9,
0x19E0, 0x19FF,
},
spaces = false,
normalizationFixes = handle_normalization_fixes{
from = {"ឣ", "ឤ"},
to = {"អ", "អា"}
},
}
m["Khoj"] = process_ranges{
"Khojki",
1740656,
"abugida",
ranges = {
0x0AE6, 0x0AEF,
0xA830, 0xA839,
0x11200, 0x11211,
0x11213, 0x11241,
},
normalizationFixes = handle_normalization_fixes{
from = {"𑈀𑈬𑈱", "𑈀𑈬", "𑈀𑈱", "𑈀𑈳", "𑈁𑈱", "𑈆𑈬", "𑈬𑈰", "𑈬𑈱", "𑉀𑈮"},
to = {"𑈇", "𑈁", "𑈅", "𑈇", "𑈇", "𑈃", "𑈲", "𑈳", "𑈂"}
},
}
m["Khomt"] = {
"ขอมไทย",
13023788,
"abugida",
aliases = {"Khom Thai"},
-- Not in Unicode
}
m["Kitl"] = {
"คีตันใหญ่",
6401797,
"logography",
aliases = {"Khitan Large"},
spaces = false,
}
m["Kits"] = process_ranges{
"คีตันเล็ก",
6401800,
"logography, syllabary",
aliases = {"Khitan Small"},
ranges = {
0x16FE4, 0x16FE4,
0x18B00, 0x18CD5,
0x18CFF, 0x18CFF,
},
spaces = false,
}
m["Knda"] = process_ranges{
"กันนฑะ",
839666,
"abugida",
aliases = {"กันนาดา", "Kannada"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0C80, 0x0C8C,
0x0C8E, 0x0C90,
0x0C92, 0x0CA8,
0x0CAA, 0x0CB3,
0x0CB5, 0x0CB9,
0x0CBC, 0x0CC4,
0x0CC6, 0x0CC8,
0x0CCA, 0x0CCD,
0x0CD5, 0x0CD6,
0x0CDD, 0x0CDE,
0x0CE0, 0x0CE3,
0x0CE6, 0x0CEF,
0x0CF1, 0x0CF3,
0x1CD0, 0x1CD0,
0x1CD2, 0x1CD3,
0x1CDA, 0x1CDA,
0x1CF2, 0x1CF2,
0x1CF4, 0x1CF4,
0xA830, 0xA835,
},
normalizationFixes = handle_normalization_fixes{
from = {"ಉಾ", "ಋಾ", "ಒೌ"},
to = {"ಊ", "ೠ", "ಔ"}
},
translit = "Knda-translit",
}
m["Kpel"] = {
"Kpelle",
1586299,
"syllabary",
-- Not in Unicode
}
m["Krai"] = process_ranges{
"Kirat Rai",
123173834,
"abugida",
aliases = {"Rai", "Khambu Rai", "Rai Barṇamālā", "Kirat Khambu Rai"},
ranges = {
0x16D40, 0x16D79,
},
}
m["Kthi"] = process_ranges{
"ไกถี",
1253814,
"abugida",
aliases = {"Kaithi"},
ranges = {
0x0966, 0x096F,
0xA830, 0xA839,
0x11080, 0x110C2,
0x110CD, 0x110CD,
},
}
m["Kulit"] = {
"Kulitan",
6443044,
"abugida",
-- Not in Unicode
}
m["Lana"] = process_ranges{
"ไทธรรม",
1314503,
"abugida",
aliases = {"ธรรม", "ตัวเมือง", "ล้านนา", "Tai Tham", "Tham", "Tua Mueang", "Lanna"},
ranges = {
0x1A20, 0x1A5E,
0x1A60, 0x1A7C,
0x1A7F, 0x1A89,
0x1A90, 0x1A99,
0x1AA0, 0x1AAD,
},
spaces = false,
}
m["Laoo"] = process_ranges{
"ลาว",
1815229,
"abugida",
aliases = {"Lao"},
ranges = {
0x0E81, 0x0E82,
0x0E84, 0x0E84,
0x0E86, 0x0E8A,
0x0E8C, 0x0EA3,
0x0EA5, 0x0EA5,
0x0EA7, 0x0EBD,
0x0EC0, 0x0EC4,
0x0EC6, 0x0EC6,
0x0EC8, 0x0ECE,
0x0ED0, 0x0ED9,
0x0EDC, 0x0EDF,
},
spaces = false,
}
m["Latn"] = process_ranges{
"ละติน",
8229,
"alphabet",
aliases = {"ลาติน", "โรมัน", "Latin", "Roman"},
ranges = {
0x0041, 0x005A,
0x0061, 0x007A,
0x00AA, 0x00AA,
0x00BA, 0x00BA,
0x00C0, 0x00D6,
0x00D8, 0x00F6,
0x00F8, 0x02B8,
0x02C0, 0x02C1,
0x02E0, 0x02E4,
0x0363, 0x036F,
0x0485, 0x0486,
0x0951, 0x0952,
0x10FB, 0x10FB,
0x1D00, 0x1D25,
0x1D2C, 0x1D5C,
0x1D62, 0x1D65,
0x1D6B, 0x1D77,
0x1D79, 0x1DBE,
0x1DF8, 0x1DF8,
0x1E00, 0x1EFF,
0x202F, 0x202F,
0x2071, 0x2071,
0x207F, 0x207F,
0x2090, 0x209C,
0x20F0, 0x20F0,
0x2100, 0x2125,
0x2128, 0x2128,
0x212A, 0x2134,
0x2139, 0x213B,
0x2141, 0x214E,
0x2160, 0x2188,
0x2C60, 0x2C7F,
0xA700, 0xA707,
0xA722, 0xA787,
0xA78B, 0xA7CD,
0xA7D0, 0xA7D1,
0xA7D3, 0xA7D3,
0xA7D5, 0xA7DC,
0xA7F2, 0xA7FF,
0xA92E, 0xA92E,
0xAB30, 0xAB5A,
0xAB5C, 0xAB64,
0xAB66, 0xAB69,
0xFB00, 0xFB06,
0xFF21, 0xFF3A,
0xFF41, 0xFF5A,
0x10780, 0x10785,
0x10787, 0x107B0,
0x107B2, 0x107BA,
0x1DF00, 0x1DF1E,
0x1DF25, 0x1DF2A,
},
varieties = {{"รูมี", "Rumi"}, {"โรมาจิ", "โรมะจิ", "Romaji", "Rōmaji"}, "Romaja"},
capitalized = true,
translit = false,
}
m["Latf"] = {
"ฟรักทูร์",
148443,
m["Latn"][3],
aliases = {"Fraktur"},
ranges = m["Latn"].ranges,
characters = m["Latn"].characters,
other_names = {"แบล็กเลตเทอร์", "Blackletter"}, -- Blackletter is actually the parent "script"
capitalized = m["Latn"].capitalized,
translit = m["Latn"].translit,
parent = "Latn",
}
m["Latg"] = {
"แกลิก",
1432616,
m["Latn"][3],
aliases = {"Gaelic"},
ranges = m["Latn"].ranges,
characters = m["Latn"].characters,
other_names = {"ไอริช", "Irish"},
capitalized = m["Latn"].capitalized,
translit = m["Latn"].translit,
parent = "Latn",
}
m["pjt-Latn"] = {
"ละติน",
nil,
m["Latn"][3],
aliases = m["Latn"].aliases,
ranges = m["Latn"].ranges,
characters = m["Latn"].characters,
capitalized = m["Latn"].capitalized,
translit = m["Latn"].translit,
parent = "Latn",
}
m["Leke"] = {
"Leke",
19572613,
"abugida",
-- Not in Unicode
}
m["Lepc"] = process_ranges{
"เลปชา",
1481626,
"abugida",
aliases = {"Lepcha"},
ranges = {
0x1C00, 0x1C37,
0x1C3B, 0x1C49,
0x1C4D, 0x1C4F,
},
}
m["Limb"] = process_ranges{
"ลิมบู",
933796,
"abugida",
aliases = {"Limbu"},
ranges = {
0x0965, 0x0965,
0x1900, 0x191E,
0x1920, 0x192B,
0x1930, 0x193B,
0x1940, 0x1940,
0x1944, 0x194F,
},
}
m["Lina"] = process_ranges{
"ลิเนียร์เอ",
30972,
aliases = {"Linear A"},
ranges = {
0x10107, 0x10133,
0x10600, 0x10736,
0x10740, 0x10755,
0x10760, 0x10767,
},
}
m["Linb"] = process_ranges{
"ลิเนียร์บี",
190102,
aliases = {"Linear B"},
ranges = {
0x10000, 0x1000B,
0x1000D, 0x10026,
0x10028, 0x1003A,
0x1003C, 0x1003D,
0x1003F, 0x1004D,
0x10050, 0x1005D,
0x10080, 0x100FA,
0x10100, 0x10102,
0x10107, 0x10133,
0x10137, 0x1013F,
},
}
m["Lisu"] = process_ranges{
"ลีสู่",
1194621,
"alphabet",
aliases = {"ฟราเซอร์", "Lisu", "Fraser"},
ranges = {
0x300A, 0x300B,
0xA4D0, 0xA4FF,
0x11FB0, 0x11FB0,
},
normalizationFixes = handle_normalization_fixes{
from = {"['’]", "[.ꓸ][.ꓸ]", "[.ꓸ][,ꓹ]"},
to = {"ʼ", "ꓺ", "ꓻ"}
},
translit = "Lisu-translit",
sort_key = {
from = {"𑾰"},
to = {"ꓬ" .. p[1]}
},
}
m["Loma"] = {
"Loma",
13023816,
"syllabary",
-- Not in Unicode
}
m["Lyci"] = process_ranges{
"ลิเชีย",
913587,
"alphabet",
aliases = {"Lycian"},
ranges = {
0x10280, 0x1029C,
},
}
m["Lydi"] = process_ranges{
"ลิเดีย",
4261300,
"alphabet",
aliases = {"Lydian"},
ranges = {
0x10920, 0x10939,
0x1093F, 0x1093F,
},
direction = "rtl",
}
m["Mahj"] = process_ranges{
"มหาชนี",
6732850,
"abugida",
aliases = {"Mahajani"},
ranges = {
0x0964, 0x096F,
0xA830, 0xA839,
0x11150, 0x11176,
},
}
m["Maka"] = process_ranges{
"มากัซซาร์",
72947229,
"abugida",
aliases = {"มากาซาร์", "มากาซาร์เก่า", "Makasar", "Makassar", "Old Makasar"},
ranges = {
0x11EE0, 0x11EF8,
},
}
m["Mand"] = process_ranges{
"มันดาอิก",
1812130,
aliases = {"Mandaic", "Mandaean"},
ranges = {
0x0640, 0x0640,
0x0840, 0x085B,
0x085E, 0x085E,
},
direction = "rtl",
}
m["Mani"] = process_ranges{
"Manichaean",
3544702,
"abjad",
ranges = {
0x0640, 0x0640,
0x10AC0, 0x10AE6,
0x10AEB, 0x10AF6,
},
direction = "rtl",
translit = "Mani-translit",
}
m["Marc"] = process_ranges{
"Marchen",
72403709,
"abugida",
ranges = {
0x11C70, 0x11C8F,
0x11C92, 0x11CA7,
0x11CA9, 0x11CB6,
},
}
m["Maya"] = process_ranges{
"มายา",
211248,
aliases = {"มายัน", "Maya", "Maya hieroglyphic", "Mayan", "Mayan hieroglyphic"},
ranges = {
0x1D2E0, 0x1D2F3,
},
}
m["Medf"] = process_ranges{
"Medefaidrin",
1519764,
aliases = {"Oberi Okaime", "Oberi Ɔkaimɛ"},
ranges = {
0x16E40, 0x16E9A,
},
capitalized = true,
}
m["Mend"] = process_ranges{
"Mende",
951069,
aliases = {"Mende Kikakui"},
ranges = {
0x1E800, 0x1E8C4,
0x1E8C7, 0x1E8D6,
},
direction = "rtl",
}
m["Merc"] = process_ranges{
"Meroitic cursive",
73028124,
"abugida",
ranges = {
0x109A0, 0x109B7,
0x109BC, 0x109CF,
0x109D2, 0x109FF,
},
direction = "rtl",
}
m["Mero"] = process_ranges{
"Meroitic hieroglyphic",
73028623,
"abugida",
ranges = {
0x10980, 0x1099F,
},
direction = "rtl",
wikipedia_article = "Meroitic hieroglyphs",
}
m["Mlym"] = process_ranges{
"มลยาฬัม",
1164129,
"abugida",
aliases = {"มลยาลัม", "มาลายาลัม", "Malayalam"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0D00, 0x0D0C,
0x0D0E, 0x0D10,
0x0D12, 0x0D44,
0x0D46, 0x0D48,
0x0D4A, 0x0D4F,
0x0D54, 0x0D63,
0x0D66, 0x0D7F,
0x1CDA, 0x1CDA,
0x1CF2, 0x1CF2,
0xA830, 0xA832,
},
normalizationFixes = handle_normalization_fixes{
from = {"ഇൗ", "ഉൗ", "എെ", "ഒാ", "ഒൗ", "ക്", "ണ്", "ന്റ", "ന്", "മ്", "യ്", "ര്", "ല്", "ള്", "ഴ്", "െെ", "ൻ്റ"},
to = {"ഈ", "ഊ", "ഐ", "ഓ", "ഔ", "ൿ", "ൺ", "ൻറ", "ൻ", "ൔ", "ൕ", "ർ", "ൽ", "ൾ", "ൖ", "ൈ", "ന്റ"}
},
translit = "Mlym-translit",
}
m["Modi"] = process_ranges{
"โมฑี",
1703713,
"abugida",
aliases = {"Modi"},
ranges = {
0xA830, 0xA839,
0x11600, 0x11644,
0x11650, 0x11659,
},
normalizationFixes = handle_normalization_fixes{
from = {"𑘀𑘹", "𑘀𑘺", "𑘁𑘹", "𑘁𑘺"},
to = {"𑘊", "𑘋", "𑘌", "𑘍"}
},
}
do
local Mong_displaytext = {
from = {"([ᠨ-ᡂᡸ])ᠶ([ᠨ-ᡂᡸ])", "([ᠠ-ᡂᡸ])ᠸ([^᠋ᠠ-ᠧ])", "([ᠠ-ᡂᡸ])ᠸ$"},
to = {"%1ᠢ%2", "%1ᠧ%2", "%1ᠧ"}
}
m["Mong"] = process_ranges{
"มองโกเลีย",
1055705,
"alphabet",
aliases = {"Mongolian", "Mongol bichig", "Hudum Mongol bichig"},
ranges = {
0x1800, 0x1805,
0x180A, 0x1819,
0x1820, 0x1842,
0x1878, 0x1878,
0x1880, 0x1897,
0x18A6, 0x18A6,
0x18A9, 0x18A9,
0x200C, 0x200D,
0x202F, 0x202F,
0x3001, 0x3002,
0x3008, 0x300B,
0x11660, 0x11668,
},
direction = "vertical-ltr",
display_text = Mong_displaytext,
strip_diacritics = Mong_displaytext,
translit = "Mong-translit",
}
m["mnc-Mong"] = process_ranges{
"แมนจู",
122888,
m["Mong"][3],
aliases = {"Manchu"},
ranges = {
0x1801, 0x1801,
0x1804, 0x1804,
0x1808, 0x180F,
0x1820, 0x1820,
0x1823, 0x1823,
0x1828, 0x182A,
0x182E, 0x1830,
0x1834, 0x1838,
0x183A, 0x183A,
0x185D, 0x185D,
0x185F, 0x1861,
0x1864, 0x1869,
0x186C, 0x1871,
0x1873, 0x1877,
0x1880, 0x1888,
0x188F, 0x188F,
0x189A, 0x18A5,
0x18A8, 0x18A8,
0x18AA, 0x18AA,
0x200C, 0x200D,
0x202F, 0x202F,
},
direction = "vertical-ltr",
parent = "Mong",
translit = "mnc-translit",
}
m["sjo-Mong"] = process_ranges{
"ซิเบ",
113624153,
m["Mong"][3],
aliases = {"Xibe", "Sibe"},
ranges = {
0x1804, 0x1804,
0x1807, 0x1807,
0x180A, 0x180F,
0x1820, 0x1820,
0x1823, 0x1823,
0x1828, 0x1828,
0x182A, 0x182A,
0x182E, 0x1830,
0x1834, 0x1838,
0x183A, 0x183A,
0x185D, 0x1872,
0x200C, 0x200D,
0x202F, 0x202F,
},
direction = "vertical-ltr",
parent = "mnc-Mong",
}
m["xwo-Mong"] = process_ranges{
"Clear Script",
529085,
m["Mong"][3],
aliases = {"Todo", "Todo bichig"},
ranges = {
0x1800, 0x1801,
0x1804, 0x1806,
0x180A, 0x1820,
0x1828, 0x1828,
0x182F, 0x1831,
0x1834, 0x1834,
0x1837, 0x1838,
0x183A, 0x183B,
0x1840, 0x1840,
0x1843, 0x185C,
0x1880, 0x1887,
0x1889, 0x188F,
0x1894, 0x1894,
0x1896, 0x1899,
0x18A7, 0x18A7,
0x200C, 0x200D,
0x202F, 0x202F,
0x11669, 0x1166C,
},
direction = "vertical-ltr",
parent = "Mong",
translit = "xwo-translit",
}
end
m["Moon"] = {
"Moon",
918391,
"alphabet",
aliases = {"Moon System of Embossed Reading", "Moon type", "Moon writing", "Moon alphabet", "Moon code"},
-- Not in Unicode
}
m["Morse"] = {
"รหัสมอร์ส",
79897,
aliases = {"Morse code"},
ietf_subtag = "Zsym",
}
m["Mroo"] = process_ranges{
"มรู",
75919253,
aliases = {"มโร", "มรุง", "Mru", "Mro", "Mrung"},
ranges = {
0x16A40, 0x16A5E,
0x16A60, 0x16A69,
0x16A6E, 0x16A6F,
},
}
m["Mtei"] = process_ranges{
"มณีปุระ",
2981413,
"abugida",
aliases = {"ไมไตมะเยก", "มีไตมะเยก", "Manipuri", "Meitei Mayek", "Meetei Mayek"},
ranges = {
0xAAE0, 0xAAF6,
0xABC0, 0xABED,
0xABF0, 0xABF9,
},
}
m["Mult"] = process_ranges{
"Multani",
17047906,
"abugida",
ranges = {
0x0A66, 0x0A6F,
0x11280, 0x11286,
0x11288, 0x11288,
0x1128A, 0x1128D,
0x1128F, 0x1129D,
0x1129F, 0x112A9,
},
}
m["Music"] = process_ranges{
"สัญกรณ์ดนตรี",
233861,
"pictography",
aliases = {"Musical notation"},
ranges = {
0x2669, 0x266F,
0x1D100, 0x1D126,
0x1D129, 0x1D1EA,
},
ietf_subtag = "Zsym",
translit = false,
}
m["Mymr"] = process_ranges{
"พม่า",
43887939,
"abugida",
aliases = {"เมียนมา", "Burmese", "Myanmar"},
ranges = {
0x1000, 0x109F,
0xA92E, 0xA92E,
0xA9E0, 0xA9FE,
0xAA60, 0xAA7F,
0x116D0, 0x116E3,
},
spaces = false,
}
m["Nagm"] = process_ranges{
"Mundari Bani",
106917274,
"alphabet",
aliases = {"Nag Mundari"},
ranges = {
0x1E4D0, 0x1E4F9,
},
}
m["Nand"] = process_ranges{
"นันทินาครี",
6963324,
"abugida",
aliases = {"Nandinagari"},
ranges = {
0x0964, 0x0965,
0x0CE6, 0x0CEF,
0x1CE9, 0x1CE9,
0x1CF2, 0x1CF2,
0x1CFA, 0x1CFA,
0xA830, 0xA835,
0x119A0, 0x119A7,
0x119AA, 0x119D7,
0x119DA, 0x119E4,
},
}
m["Narb"] = process_ranges{
"Ancient North Arabian",
1472213,
"abjad",
aliases = {"Old North Arabian"},
ranges = {
0x10A80, 0x10A9F,
},
direction = "rtl",
translit = "Narb-translit",
}
m["Nbat"] = process_ranges{
"Nabataean",
855624,
"abjad",
aliases = {"Nabatean"},
ranges = {
0x10880, 0x1089E,
0x108A7, 0x108AF,
},
direction = "rtl",
}
m["Newa"] = process_ranges{
"Newa",
7237292,
"abugida",
aliases = {"Newar", "Newari", "Prachalit Nepal"},
ranges = {
0x11400, 0x1145B,
0x1145D, 0x11461,
},
}
m["Nkdb"] = {
"Dongba",
1190953,
"pictography",
aliases = {"Naxi Dongba", "Nakhi Dongba", "Tomba", "Tompa", "Mo-so"},
spaces = false,
-- Not in Unicode
}
m["Nkgb"] = {
"Geba",
731189,
"syllabary",
aliases = {"Nakhi Geba", "Naxi Geba"},
spaces = false,
-- Not in Unicode
}
m["Nkoo"] = process_ranges{
"N'Ko",
1062587,
"alphabet",
ranges = {
0x060C, 0x060C,
0x061B, 0x061B,
0x061F, 0x061F,
0x07C0, 0x07FA,
0x07FD, 0x07FF,
0xFD3E, 0xFD3F,
},
direction = "rtl",
}
m["None"] = {
"ไม่ระบุ",
nil,
aliases = {"unspecified"},
-- This should not have any characters listed
ietf_subtag = "Zyyy",
translit = false,
character_category = false, -- none
}
m["Nshu"] = process_ranges{
"Nüshu",
56436,
"syllabary",
aliases = {"Nushu"},
ranges = {
0x16FE1, 0x16FE1,
0x1B170, 0x1B2FB,
},
spaces = false,
}
m["Ogam"] = process_ranges{
"Ogham",
184661,
ranges = {
0x1680, 0x169C,
},
}
m["Olck"] = process_ranges{
"อ็อลจิกิ",
201688,
aliases = {"อ็อลเจะเม็ท", "อ็อล", "สันถาลี", "สันถัล", "Ol Chiki", "Ol Chemetʼ", "Ol", "Santali"},
ranges = {
0x1C50, 0x1C7F,
},
}
m["Onao"] = process_ranges{
"Ol Onal",
108607084,
"alphabet",
ranges = {
0x0964, 0x0965,
0x1E5D0, 0x1E5FA,
0x1E5FF, 0x1E5FF,
},
}
m["Orkh"] = process_ranges{
"Old Turkic",
5058305,
aliases = {"Orkhon runic"},
ranges = {
0x10C00, 0x10C48,
},
direction = "rtl",
translit = "Orkh-translit",
}
m["Orya"] = process_ranges{
"โอริยา",
1760127,
"abugida",
aliases = {"โอเดีย", "Oriya", "Odia"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0B01, 0x0B03,
0x0B05, 0x0B0C,
0x0B0F, 0x0B10,
0x0B13, 0x0B28,
0x0B2A, 0x0B30,
0x0B32, 0x0B33,
0x0B35, 0x0B39,
0x0B3C, 0x0B44,
0x0B47, 0x0B48,
0x0B4B, 0x0B4D,
0x0B55, 0x0B57,
0x0B5C, 0x0B5D,
0x0B5F, 0x0B63,
0x0B66, 0x0B77,
0x1CDA, 0x1CDA,
0x1CF2, 0x1CF2,
},
normalizationFixes = handle_normalization_fixes{
from = {"ଅା", "ଏୗ", "ଓୗ"},
to = {"ଆ", "ଐ", "ଔ"}
},
}
m["Osge"] = process_ranges{
"Osage",
7105529,
ranges = {
0x104B0, 0x104D3,
0x104D8, 0x104FB,
},
capitalized = true,
}
m["Osma"] = process_ranges{
"อุสมาน",
1377866,
aliases = {"Osmanya"},
ranges = {
0x10480, 0x1049D,
0x104A0, 0x104A9,
},
}
m["Ougr"] = process_ranges{
"อุยกูร์เก่า",
1998938,
"abjad, alphabet",
aliases = {"Old Uyghur"},
ranges = {
0x0640, 0x0640,
0x10AF2, 0x10AF2,
0x10F70, 0x10F89,
},
-- This should ideally be "vertical-ltr", but getting the CSS right is tricky because it's right-to-left horizontally, but left-to-right vertically. Currently, displaying it vertically causes it to display bottom-to-top.
direction = "rtl",
}
m["Palm"] = process_ranges{
"แพลไมรา",
17538100,
aliases = {"แพลไมรีน", "Palmyrene"},
ranges = {
0x10860, 0x1087F,
},
direction = "rtl",
}
m["Pauc"] = process_ranges{
"Pau Cin Hau",
25339852,
ranges = {
0x11AC0, 0x11AF8,
},
}
m["Pcun"] = {
"Proto-Cuneiform",
1650699,
"pictography",
-- Not in Unicode
}
m["Pelm"] = {
"Proto-Elamite",
56305763,
"pictography",
-- Not in Unicode
}
m["Perm"] = process_ranges{
"Old Permic",
147899,
ranges = {
0x0483, 0x0483,
0x10350, 0x1037A,
},
}
m["Phag"] = process_ranges{
"Phags-pa",
822836,
"abugida",
ranges = {
0x1802, 0x1803,
0x1805, 0x1805,
0x200C, 0x200D,
0x202F, 0x202F,
0x3002, 0x3002,
0xA840, 0xA877,
},
direction = "vertical-ltr",
}
m["Phli"] = process_ranges{
"ปาห์ลาวีจารึก",
24089793,
"abjad",
aliases = {"Inscriptional Pahlavi"},
ranges = {
0x10B60, 0x10B72,
0x10B78, 0x10B7F,
},
direction = "rtl",
}
m["Phlp"] = process_ranges{
"ปาห์ลาวีเพลงสดุดี",
7253954,
"abjad",
aliases = {"Psalter Pahlavi"},
ranges = {
0x0640, 0x0640,
0x10B80, 0x10B91,
0x10B99, 0x10B9C,
0x10BA9, 0x10BAF,
},
direction = "rtl",
}
m["Phlv"] = {
"ปาห์ลาวีคัมภีร์",
72403118,
"abjad",
aliases = {"ปาห์ลาวีหนังสือ", "Book Pahlavi"},
direction = "rtl",
wikipedia_article = "Pahlavi scripts#Book Pahlavi",
-- Not in Unicode
}
m["Phnx"] = process_ranges{
"ฟินิเชีย",
26752,
"abjad",
aliases = {"Phoenician"},
ranges = {
0x10900, 0x1091B,
0x1091F, 0x1091F,
},
direction = "rtl",
translit = "Phnx-translit",
}
m["Plrd"] = process_ranges{
"Pollard",
601734,
"abugida",
aliases = {"Miao"},
ranges = {
0x16F00, 0x16F4A,
0x16F4F, 0x16F87,
0x16F8F, 0x16F9F,
},
}
m["Prti"] = process_ranges{
"พาร์เทียจารึก",
13023804,
aliases = {"Inscriptional Parthian"},
ranges = {
0x10B40, 0x10B55,
0x10B58, 0x10B5F,
},
direction = "rtl",
}
m["Psin"] = {
"Proto-Sinaitic",
1065250,
"abjad",
direction = "rtl",
-- Not in Unicode
}
m["Ranj"] = {
"Ranjana",
2385276,
"abugida",
-- Not in Unicode
}
m["Rjng"] = process_ranges{
"Rejang",
2007960,
"abugida",
ranges = {
0xA930, 0xA953,
0xA95F, 0xA95F,
},
}
m["Rohg"] = process_ranges{
"ฮานิฟ",
21028705,
"alphabet",
aliases = {"ฮานีฟี", "Hanifi Rohingya", "Hanifi"},
ranges = {
0x060C, 0x060C,
0x061B, 0x061B,
0x061F, 0x061F,
0x0640, 0x0640,
0x06D4, 0x06D4,
0x10D00, 0x10D27,
0x10D30, 0x10D39,
},
direction = "rtl",
}
m["Roro"] = {
"Rongorongo",
209764,
-- Not in Unicode
}
m["Rumin"] = process_ranges{
"Rumi numerals",
nil,
ranges = {
0x10E60, 0x10E7E,
},
ietf_subtag = "Arab",
}
m["Runr"] = process_ranges{
"รูน",
82996,
"alphabet",
aliases = {"รูนิก", "Runic"},
ranges = {
0x16A0, 0x16EA,
0x16EE, 0x16F8,
},
}
do
local Samr_stripdiacritics = {
remove_diacritics = c.CGJ .. u(0x0816) .. "-" .. u(0x082D),
}
m["Samr"] = process_ranges{
"Samaritan",
1550930,
"abjad",
ranges = {
0x0800, 0x082D,
0x0830, 0x083E,
},
direction = "rtl",
strip_diacritics = Samr_stripdiacritics,
sort_key = Samr_stripdiacritics,
}
end
m["Sarb"] = process_ranges{
"Ancient South Arabian",
446074,
"abjad",
aliases = {"Old South Arabian"},
ranges = {
0x10A60, 0x10A7F,
},
direction = "rtl",
translit = "Sarb-translit",
}
m["Saur"] = process_ranges{
"Saurashtra",
3535165,
"abugida",
ranges = {
0xA880, 0xA8C5,
0xA8CE, 0xA8D9,
},
}
m["Semap"] = {
"สัญญาณธง",
250796,
"pictography",
aliases = {"flag semaphore"},
ietf_subtag = "Zsym",
}
m["Sgnw"] = process_ranges{
"SignWriting",
1497335,
"pictography",
aliases = {"Sutton SignWriting"},
ranges = {
0x1D800, 0x1DA8B,
0x1DA9B, 0x1DA9F,
0x1DAA1, 0x1DAAF,
},
translit = false,
}
m["Shaw"] = process_ranges{
"Shavian",
1970098,
aliases = {"Shaw"},
ranges = {
0x10450, 0x1047F,
},
}
m["Shrd"] = process_ranges{
"ศารทา",
2047117,
"abugida",
aliases = {"Sharada"},
ranges = {
0x0951, 0x0951,
0x1CD7, 0x1CD7,
0x1CD9, 0x1CD9,
0x1CDC, 0x1CDD,
0x1CE0, 0x1CE0,
0xA830, 0xA835,
0xA838, 0xA838,
0x11180, 0x111DF,
},
translit = "Shrd-translit",
}
m["Shui"] = {
"Sui",
752854,
"logography",
spaces = false,
-- Not in Unicode
}
m["Sidd"] = process_ranges{
"สิทธัม",
250379,
"abugida",
aliases = {"Siddham"},
ranges = {
0x11580, 0x115B5,
0x115B8, 0x115DD,
},
translit = "Sidd-translit",
}
m["Sidt"] = {
"Sidetic",
36659,
"alphabet",
direction = "rtl",
-- Not in Unicode
}
m["Sind"] = process_ranges{
"ขุทาพาที",
6402810,
"abugida",
aliases = {"ขุทาวาที", "Khudabadi", "Khudawadi"},
ranges = {
0x0964, 0x0965,
0xA830, 0xA839,
0x112B0, 0x112EA,
0x112F0, 0x112F9,
},
normalizationFixes = handle_normalization_fixes{
from = {"𑊰𑋠", "𑊰𑋥", "𑊰𑋦", "𑊰𑋧", "𑊰𑋨"},
to = {"𑊱", "𑊶", "𑊷", "𑊸", "𑊹"}
},
}
m["Sinh"] = process_ranges{
"สิงหล",
1574992,
"abugida",
aliases = {"Sinhalese", "Sinhala"},
ranges = {
0x0964, 0x0965,
0x0D81, 0x0D83,
0x0D85, 0x0D96,
0x0D9A, 0x0DB1,
0x0DB3, 0x0DBB,
0x0DBD, 0x0DBD,
0x0DC0, 0x0DC6,
0x0DCA, 0x0DCA,
0x0DCF, 0x0DD4,
0x0DD6, 0x0DD6,
0x0DD8, 0x0DDF,
0x0DE6, 0x0DEF,
0x0DF2, 0x0DF4,
0x1CF2, 0x1CF2,
0x111E1, 0x111F4,
},
normalizationFixes = handle_normalization_fixes{
from = {"අා", "අැ", "අෑ", "උෟ", "ඍෘ", "ඏෟ", "එ්", "එෙ", "ඔෟ", "ෘෘ"},
to = {"ආ", "ඇ", "ඈ", "ඌ", "ඎ", "ඐ", "ඒ", "ඓ", "ඖ", "ෲ"}
},
}
m["Sogd"] = process_ranges{
"ซอกเดีย",
578359,
"abjad",
aliases = {"Sogdian"},
ranges = {
0x0640, 0x0640,
0x10F30, 0x10F59,
},
direction = "rtl",
}
m["Sogo"] = process_ranges{
"ซอกเดียเก่า",
72403254,
"abjad",
aliases = {"Old Sogdian"},
ranges = {
0x10F00, 0x10F27,
},
direction = "rtl",
}
m["Sora"] = process_ranges{
"Sorang Sompeng",
7563292,
aliases = {"Sora Sompeng"},
ranges = {
0x110D0, 0x110E8,
0x110F0, 0x110F9,
},
}
m["Soyo"] = process_ranges{
"Soyombo",
8009382,
"abugida",
ranges = {
0x11A50, 0x11AA2,
},
}
m["Sund"] = process_ranges{
"ซุนดา",
51589,
"abugida",
aliases = {"Sundanese"},
ranges = {
0x1B80, 0x1BBF,
0x1CC0, 0x1CC7,
},
}
m["Sunu"] = process_ranges{
"Sunuwar",
109984965,
"alphabet",
ranges = {
0x11BC0, 0x11BE1,
0x11BF0, 0x11BF9,
},
}
m["Sylo"] = process_ranges{
"สิเลฏินาครี",
144128,
"abugida",
aliases = {"สิลอฏินาครี", "Syloti Nagri", "Sylheti Nagari"},
ranges = {
0x0964, 0x0965,
0x09E6, 0x09EF,
0xA800, 0xA82C,
},
}
m["Syrc"] = process_ranges{
"ซีรีแอก",
26567,
"abjad", -- more precisely, impure abjad
aliases = {"ซีเรียค", "Syriac"},
ranges = {
0x060C, 0x060C,
0x061B, 0x061C,
0x061F, 0x061F,
0x0640, 0x0640,
0x064B, 0x0655,
0x0670, 0x0670,
0x0700, 0x070D,
0x070F, 0x074A,
0x074D, 0x074F,
0x0860, 0x086A,
0x1DF8, 0x1DF8,
0x1DFA, 0x1DFA,
},
direction = "rtl",
}
-- Syre, Syrj, Syrn are apparently subsumed into Syrc; discuss if this causes issues
m["Tagb"] = process_ranges{
"ตักบันวา",
977444,
"abugida",
aliases = {"Tagbanwa"},
ranges = {
0x1735, 0x1736,
0x1760, 0x176C,
0x176E, 0x1770,
0x1772, 0x1773,
},
}
m["Takr"] = process_ranges{
"ฏากรี",
759202,
"abugida",
aliases = {"ตากรี", "Takri"},
ranges = {
0x0964, 0x0965,
0xA830, 0xA839,
0x11680, 0x116B9,
0x116C0, 0x116C9,
},
normalizationFixes = handle_normalization_fixes{
from = {"𑚀𑚭", "𑚀𑚴", "𑚀𑚵", "𑚆𑚲"},
to = {"𑚁", "𑚈", "𑚉", "𑚇"}
},
}
m["Tale"] = process_ranges{
"ไทใต้คง",
2566326,
"abugida",
aliases = {"ไทเหนือ", "ไทเหนือใหม่", "ไตเหลอ", "Tai Nüa", "Tai Nuea", "New Tai Nüa", "New Tai Nuea", "Dehong Dai", "Tai Dehong", "Tai Le"},
ranges = {
0x1040, 0x1049,
0x1950, 0x196D,
0x1970, 0x1974,
},
spaces = false,
}
m["Talu"] = process_ranges{
"ไทลื้อใหม่",
3498863,
"abugida",
aliases = {"New Tai Lue"},
ranges = {
0x1980, 0x19AB,
0x19B0, 0x19C9,
0x19D0, 0x19DA,
0x19DE, 0x19DF,
},
spaces = false,
}
m["Taml"] = process_ranges{
"ทมิฬ",
26803,
"abugida",
aliases = {"Tamil"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0B82, 0x0B83,
0x0B85, 0x0B8A,
0x0B8E, 0x0B90,
0x0B92, 0x0B95,
0x0B99, 0x0B9A,
0x0B9C, 0x0B9C,
0x0B9E, 0x0B9F,
0x0BA3, 0x0BA4,
0x0BA8, 0x0BAA,
0x0BAE, 0x0BB9,
0x0BBE, 0x0BC2,
0x0BC6, 0x0BC8,
0x0BCA, 0x0BCD,
0x0BD0, 0x0BD0,
0x0BD7, 0x0BD7,
0x0BE6, 0x0BFA,
0x1CDA, 0x1CDA,
0xA8F3, 0xA8F3,
0x11301, 0x11301,
0x11303, 0x11303,
0x1133B, 0x1133C,
0x11FC0, 0x11FF1,
0x11FFF, 0x11FFF,
},
normalizationFixes = handle_normalization_fixes{
from = {"அூ", "ஸ்ரீ"},
to = {"ஆ", "ஶ்ரீ"}
},
}
m["Tang"] = process_ranges{
"ตังกุต",
1373610,
"logography, syllabary",
aliases = {"Tangut"},
ranges = {
0x31EF, 0x31EF,
0x16FE0, 0x16FE0,
0x17000, 0x187F7,
0x18800, 0x18AFF,
0x18D00, 0x18D08,
},
spaces = false,
translit = "txg-translit",
}
m["Tavt"] = process_ranges{
"ไทเวียด",
11818517,
"abugida",
aliases = {"Tai Viet"},
ranges = {
0xAA80, 0xAAC2,
0xAADB, 0xAADF,
},
spaces = false,
}
m["Tayo"] = process_ranges{
"ลายตัย",
16306701,
"abugida",
aliases = {"ญ้อ", "ไทญ้อ", "Lai Tay", "Tai Yo"},
direction = "vertical-rtl",
ranges = {
0x1E6C0, 0x1E6DE,
0x1E6E0, 0x1E6F5,
0x1E6FE, 0x1E6FF,
},
spaces = false,
}
m["Telu"] = process_ranges{
"เตลูกู",
570450,
"abugida",
aliases = {"Telugu"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x0C00, 0x0C0C,
0x0C0E, 0x0C10,
0x0C12, 0x0C28,
0x0C2A, 0x0C39,
0x0C3C, 0x0C44,
0x0C46, 0x0C48,
0x0C4A, 0x0C4D,
0x0C55, 0x0C56,
0x0C58, 0x0C5A,
0x0C5D, 0x0C5D,
0x0C60, 0x0C63,
0x0C66, 0x0C6F,
0x0C77, 0x0C7F,
0x1CDA, 0x1CDA,
0x1CF2, 0x1CF2,
},
normalizationFixes = handle_normalization_fixes{
from = {"ఒౌ", "ఒౕ", "ిౕ", "ెౕ", "ొౕ"},
to = {"ఔ", "ఓ", "ీ", "ే", "ో"}
},
}
m["Teng"] = {
"เทงกวาร์",
473725,
aliases = {"Tengwar"},
}
m["Tfng"] = process_ranges{
"ทิฟินาค",
208503,
"abjad, alphabet",
aliases = {"Tifinagh"},
ranges = {
0x2D30, 0x2D67,
0x2D6F, 0x2D70,
0x2D7F, 0x2D7F,
},
other_names = {"ลิบีโค-เบอร์เบอร์", "เบอร์เบอร์", "Libyco-Berber", "Berber"}, -- per Wikipedia, Libyco-Berber is the parent
}
m["Tglg"] = process_ranges{
"ไบบายิน",
812124,
"abugida",
aliases = {"ตากาล็อก", "Baybayin", "Tagalog"},
varieties = {"Kur-itan"},
ranges = {
0x1700, 0x1715,
0x171F, 0x171F,
0x1735, 0x1736,
},
}
m["Thaa"] = process_ranges{
"ทานะ",
877906,
"abugida",
aliases = {"Thaana"},
ranges = {
0x060C, 0x060C,
0x061B, 0x061C,
0x061F, 0x061F,
0x0660, 0x0669,
0x0780, 0x07B1,
0xFDF2, 0xFDF2,
0xFDFD, 0xFDFD,
},
direction = "rtl",
}
m["Thai"] = process_ranges{
"ไทย",
236376,
"abugida",
aliases = {"Thai"},
ranges = {
0x0E01, 0x0E3A,
0x0E40, 0x0E5B,
},
spaces = false,
translit = false, --only for thwikt
}
do
local Tibt_displaytext = {
from = {"ༀ", "༌", "།།", "༚༚", "༚༝", "༝༚", "༝༝", "ཷ", "ཹ", "ེེ", "ོོ"},
to = {"ཨོཾ", "་", "༎", "༛", "༟", "࿎", "༞", "ྲཱྀ", "ླཱྀ", "ཻ", "ཽ"}
}
m["Tibt"] = process_ranges{
"ทิเบต",
46861,
"abugida",
aliases = {"Tibetan"},
ranges = {
0x0F00, 0x0F47,
0x0F49, 0x0F6C,
0x0F71, 0x0F97,
0x0F99, 0x0FBC,
0x0FBE, 0x0FCC,
0x0FCE, 0x0FD4,
0x0FD9, 0x0FDA,
0x3008, 0x300B,
},
normalizationFixes = handle_normalization_fixes{
combiningClasses = {["༹"] = 1},
from = {"ཷ", "ཹ"},
to = {"ྲཱྀ", "ླཱྀ"}
},
display_text = Tibt_displaytext,
strip_diacritics = Tibt_displaytext,
sort_key = "Tibt-sortkey",
translit = "Tibt-translit",
}
m["sit-tam-Tibt"] = {
"ตัมยิก",
109875213,
m["Tibt"][3],
-- There is no inheritance of properties currently implemented for scripts. Per [[User:Theknightwho]], this
-- is because it's tricky to do since there are several types of child scripts: those that are mere display
-- variants (like fa-Arab, kk-Arab), which should be eliminated in favor of CSS language selectors to
-- handle the font differences; those that are genuinely different scripts that happen to share the same
-- Unicode codepoints but have mostly different properties (e.g. Manchu vs. Mongolian); and those that are
-- somewhere in between (like Tamyig vs. Tibetan). As a result, we currently have to manually specify
-- which properties we want inherited as follows.
aliases = {"Tamyig"},
ranges = m["Tibt"].ranges,
characters = m["Tibt"].characters,
parent = "Tibt",
normalizationFixes = m["Tibt"].normalizationFixes,
display_text = m["Tibt"].display_text,
strip_diacritics = m["Tibt"].strip_diacritics,
sort_key = m["Tibt"].sort_key,
translit = m["Tibt"].translit,
}
end
m["Tirh"] = process_ranges{
"ติรหุตา",
1765752,
"abugida",
aliases = {"Tirhuta"},
ranges = {
0x0951, 0x0952,
0x0964, 0x0965,
0x1CF2, 0x1CF2,
0xA830, 0xA839,
0x11480, 0x114C7,
0x114D0, 0x114D9,
},
normalizationFixes = handle_normalization_fixes{
from = {"𑒁𑒰", "𑒋𑒺", "𑒍𑒺", "𑒪𑒵", "𑒪𑒶"},
to = {"𑒂", "𑒌", "𑒎", "𑒉", "𑒊"}
},
}
m["Tnsa"] = process_ranges{
"Tangsa",
105576311,
"alphabet",
ranges = {
0x16A70, 0x16ABE,
0x16AC0, 0x16AC9,
},
}
m["Todr"] = process_ranges{
"Todhri",
10274731,
"alphabet",
direction = "rtl",
ranges = {
0x105C0, 0x105F3,
},
}
m["Tols"] = {
"Tolong Siki",
4459822,
"alphabet",
-- Not in Unicode
}
m["Toto"] = process_ranges{
"Toto",
104837516,
"abugida",
ranges = {
0x1E290, 0x1E2AE,
},
}
m["Tutg"] = process_ranges{
"Tigalari",
2604990,
"abugida",
aliases = {"Tulu"},
ranges = {
0x1CF2, 0x1CF2,
0x1CF4, 0x1CF4,
0xA8F1, 0xA8F1,
0x11380, 0x11389,
0x1138B, 0x1138B,
0x1138E, 0x1138E,
0x11390, 0x113B5,
0x113B7, 0x113C0,
0x113C2, 0x113C2,
0x113C5, 0x113C5,
0x113C7, 0x113CA,
0x113CC, 0x113D5,
0x113D7, 0x113D8,
0x113E1, 0x113E2,
},
}
m["Ugar"] = process_ranges{
"ยูการิต",
332652,
"abjad",
aliases = {"ยูการิติก", "Ugaritic"},
ranges = {
0x10380, 0x1039D,
0x1039F, 0x1039F,
},
}
m["Vaii"] = process_ranges{
"ไว",
523078,
"syllabary",
aliases = {"Vai"},
ranges = {
0xA500, 0xA62B,
},
}
m["Visp"] = {
"Visible Speech",
1303365,
"alphabet",
-- Not in Unicode
}
m["Vith"] = process_ranges{
"Vithkuqi",
3301993,
"alphabet",
ranges = {
0x10570, 0x1057A,
0x1057C, 0x1058A,
0x1058C, 0x10592,
0x10594, 0x10595,
0x10597, 0x105A1,
0x105A3, 0x105B1,
0x105B3, 0x105B9,
0x105BB, 0x105BC,
},
capitalized = true,
}
m["Wara"] = process_ranges{
"วรังจิติ",
79199,
aliases = {"วรังกษิติ", "Warang Citi", "Varang Kshiti"},
ranges = {
0x118A0, 0x118F2,
0x118FF, 0x118FF,
},
capitalized = true,
}
m["Wcho"] = process_ranges{
"Wancho",
33713728,
"alphabet",
ranges = {
0x1E2C0, 0x1E2F9,
0x1E2FF, 0x1E2FF,
},
}
m["Wole"] = {
"Woleai",
6643710,
"syllabary",
-- Not in Unicode
}
m["Xpeo"] = process_ranges{
"เปอร์เซียเก่า",
1471822,
aliases = {"Old Persian"},
ranges = {
0x103A0, 0x103C3,
0x103C8, 0x103D5,
},
}
m["Xsux"] = process_ranges{
"คูนิฟอร์ม",
401,
aliases = {"Cuneiform", "Sumero-Akkadian Cuneiform"},
ranges = {
0x12000, 0x12399,
0x12400, 0x1246E,
0x12470, 0x12474,
0x12480, 0x12543,
},
}
m["Yezi"] = process_ranges{
"Yezidi",
13175481,
"alphabet",
ranges = {
0x060C, 0x060C,
0x061B, 0x061B,
0x061F, 0x061F,
0x0660, 0x0669,
0x10E80, 0x10EA9,
0x10EAB, 0x10EAD,
0x10EB0, 0x10EB1,
},
direction = "rtl",
}
m["Yiii"] = process_ranges{
"อี๋",
1197646,
"syllabary",
aliases = {"Yi"},
ranges = {
0x3001, 0x3002,
0x3008, 0x3011,
0x3014, 0x301B,
0x30FB, 0x30FB,
0xA000, 0xA48C,
0xA490, 0xA4C6,
0xFF61, 0xFF65,
},
}
m["Zanb"] = process_ranges{
"Zanabazar Square",
50809208,
"abugida",
ranges = {
0x11A00, 0x11A47,
},
}
m["Zmth"] = process_ranges{
"mathematical notation",
1140046,
ranges = {
0x00AC, 0x00AC,
0x00B1, 0x00B1,
0x00D7, 0x00D7,
0x00F7, 0x00F7,
0x03D0, 0x03D2,
0x03D5, 0x03D5,
0x03F0, 0x03F1,
0x03F4, 0x03F6,
0x0606, 0x0608,
0x2016, 0x2016,
0x2032, 0x2034,
0x2040, 0x2040,
0x2044, 0x2044,
0x2052, 0x2052,
0x205F, 0x205F,
0x2061, 0x2064,
0x207A, 0x207E,
0x208A, 0x208E,
0x20D0, 0x20DC,
0x20E1, 0x20E1,
0x20E5, 0x20E6,
0x20EB, 0x20EF,
0x2102, 0x2102,
0x2107, 0x2107,
0x210A, 0x2113,
0x2115, 0x2115,
0x2118, 0x211D,
0x2124, 0x2124,
0x2128, 0x2129,
0x212C, 0x212D,
0x212F, 0x2131,
0x2133, 0x2138,
0x213C, 0x2149,
0x214B, 0x214B,
0x2190, 0x21A7,
0x21A9, 0x21AE,
0x21B0, 0x21B1,
0x21B6, 0x21B7,
0x21BC, 0x21DB,
0x21DD, 0x21DD,
0x21E4, 0x21E5,
0x21F4, 0x22FF,
0x2308, 0x230B,
0x2320, 0x2321,
0x237C, 0x237C,
0x239B, 0x23B5,
0x23B7, 0x23B7,
0x23D0, 0x23D0,
0x23DC, 0x23E2,
0x25A0, 0x25A1,
0x25AE, 0x25B7,
0x25BC, 0x25C1,
0x25C6, 0x25C7,
0x25CA, 0x25CB,
0x25CF, 0x25D3,
0x25E2, 0x25E2,
0x25E4, 0x25E4,
0x25E7, 0x25EC,
0x25F8, 0x25FF,
0x2605, 0x2606,
0x2640, 0x2640,
0x2642, 0x2642,
0x2660, 0x2663,
0x266D, 0x266F,
0x27C0, 0x27FF,
0x2900, 0x2AFF,
0x2B30, 0x2B44,
0x2B47, 0x2B4C,
0xFB29, 0xFB29,
0xFE61, 0xFE66,
0xFE68, 0xFE68,
0xFF0B, 0xFF0B,
0xFF1C, 0xFF1E,
0xFF3C, 0xFF3C,
0xFF3E, 0xFF3E,
0xFF5C, 0xFF5C,
0xFF5E, 0xFF5E,
0xFFE2, 0xFFE2,
0xFFE9, 0xFFEC,
0x1D400, 0x1D454,
0x1D456, 0x1D49C,
0x1D49E, 0x1D49F,
0x1D4A2, 0x1D4A2,
0x1D4A5, 0x1D4A6,
0x1D4A9, 0x1D4AC,
0x1D4AE, 0x1D4B9,
0x1D4BB, 0x1D4BB,
0x1D4BD, 0x1D4C3,
0x1D4C5, 0x1D505,
0x1D507, 0x1D50A,
0x1D50D, 0x1D514,
0x1D516, 0x1D51C,
0x1D51E, 0x1D539,
0x1D53B, 0x1D53E,
0x1D540, 0x1D544,
0x1D546, 0x1D546,
0x1D54A, 0x1D550,
0x1D552, 0x1D6A5,
0x1D6A8, 0x1D7CB,
0x1D7CE, 0x1D7FF,
0x1EE00, 0x1EE03,
0x1EE05, 0x1EE1F,
0x1EE21, 0x1EE22,
0x1EE24, 0x1EE24,
0x1EE27, 0x1EE27,
0x1EE29, 0x1EE32,
0x1EE34, 0x1EE37,
0x1EE39, 0x1EE39,
0x1EE3B, 0x1EE3B,
0x1EE42, 0x1EE42,
0x1EE47, 0x1EE47,
0x1EE49, 0x1EE49,
0x1EE4B, 0x1EE4B,
0x1EE4D, 0x1EE4F,
0x1EE51, 0x1EE52,
0x1EE54, 0x1EE54,
0x1EE57, 0x1EE57,
0x1EE59, 0x1EE59,
0x1EE5B, 0x1EE5B,
0x1EE5D, 0x1EE5D,
0x1EE5F, 0x1EE5F,
0x1EE61, 0x1EE62,
0x1EE64, 0x1EE64,
0x1EE67, 0x1EE6A,
0x1EE6C, 0x1EE72,
0x1EE74, 0x1EE77,
0x1EE79, 0x1EE7C,
0x1EE7E, 0x1EE7E,
0x1EE80, 0x1EE89,
0x1EE8B, 0x1EE9B,
0x1EEA1, 0x1EEA3,
0x1EEA5, 0x1EEA9,
0x1EEAB, 0x1EEBB,
0x1EEF0, 0x1EEF1,
},
translit = false,
}
m["Zname"] = process_ranges{
"Znamenny musical notation",
965834,
"pictography",
ranges = {
0x1CF00, 0x1CF2D,
0x1CF30, 0x1CF46,
0x1CF50, 0x1CFC3,
},
ietf_subtag = "Zsym",
translit = false,
}
m["Zsym"] = process_ranges{
"สัญลักษณ์",
80071,
"pictography",
aliases = {"symbolic"},
ranges = {
0x20DD, 0x20E0,
0x20E2, 0x20E4,
0x20E7, 0x20EA,
0x20F0, 0x20F0,
0x2100, 0x2101,
0x2103, 0x2106,
0x2108, 0x2109,
0x2114, 0x2114,
0x2116, 0x2117,
0x211E, 0x2123,
0x2125, 0x2127,
0x212A, 0x212B,
0x212E, 0x212E,
0x2132, 0x2132,
0x2139, 0x213B,
0x214A, 0x214A,
0x214C, 0x214F,
0x21A8, 0x21A8,
0x21AF, 0x21AF,
0x21B2, 0x21B5,
0x21B8, 0x21BB,
0x21DC, 0x21DC,
0x21DE, 0x21E3,
0x21E6, 0x21F3,
0x2300, 0x2307,
0x230C, 0x231F,
0x2322, 0x237B,
0x237D, 0x239A,
0x23B6, 0x23B6,
0x23B8, 0x23CF,
0x23D1, 0x23DB,
0x23E3, 0x23FF,
0x2500, 0x259F,
0x25A2, 0x25AD,
0x25B8, 0x25BB,
0x25C2, 0x25C5,
0x25C8, 0x25C9,
0x25CC, 0x25CE,
0x25D4, 0x25E1,
0x25E3, 0x25E3,
0x25E5, 0x25E6,
0x25ED, 0x25F7,
0x2600, 0x2604,
0x2607, 0x263F,
0x2641, 0x2641,
0x2643, 0x265F,
0x2664, 0x266C,
0x2670, 0x27BF,
0x2B00, 0x2B2F,
0x2B45, 0x2B46,
0x2B4D, 0x2B73,
0x2B76, 0x2B95,
0x2B97, 0x2BFF,
0x4DC0, 0x4DFF,
0x1F000, 0x1F02B,
0x1F030, 0x1F093,
0x1F0A0, 0x1F0AE,
0x1F0B1, 0x1F0BF,
0x1F0C1, 0x1F0CF,
0x1F0D1, 0x1F0F5,
0x1F300, 0x1F6D7,
0x1F6DC, 0x1F6EC,
0x1F6F0, 0x1F6FC,
0x1F700, 0x1F776,
0x1F77B, 0x1F7D9,
0x1F7E0, 0x1F7EB,
0x1F7F0, 0x1F7F0,
0x1F800, 0x1F80B,
0x1F810, 0x1F847,
0x1F850, 0x1F859,
0x1F860, 0x1F887,
0x1F890, 0x1F8AD,
0x1F8B0, 0x1F8B1,
0x1F900, 0x1FA53,
0x1FA60, 0x1FA6D,
0x1FA70, 0x1FA7C,
0x1FA80, 0x1FA88,
0x1FA90, 0x1FABD,
0x1FABF, 0x1FAC5,
0x1FACE, 0x1FADB,
0x1FAE0, 0x1FAE8,
0x1FAF0, 0x1FAF8,
0x1FB00, 0x1FB92,
0x1FB94, 0x1FBCA,
0x1FBF0, 0x1FBF9,
},
translit = false,
character_category = false, -- none
}
m["Zyyy"] = {
"ยังไม่กำหนด",
104839687,
aliases = {"undetermined"},
-- This should not have any characters listed, probably
translit = false,
character_category = false, -- none
}
m["Zzzz"] = {
"ยังไม่มีรหัส",
104839675,
aliases = {"uncoded"},
-- This should not have any characters listed
translit = false,
character_category = false, -- none
}
-- These should be defined after the scripts they are composed of.
m["Hrkt"] = process_ranges{
"คานะ",
187659,
"syllabary",
aliases = {"Kana", "Japanese syllabaries"},
ranges = union(
m["Hira"].ranges,
m["Kana"].ranges
),
spaces = false,
}
m["Jpan"] = process_ranges{
"ญี่ปุ่น",
190502,
"logography, syllabary",
aliases = {"Japanese"},
ranges = union(
m["Hrkt"].ranges,
m["Hani"].ranges,
m["Latn"].ranges
),
spaces = false,
sort_by_scraping = true,
}
m["Kore"] = process_ranges{
"เกาหลี",
711797,
"logography, syllabary",
aliases = {"Korean"},
ranges = union(
m["Hang"].ranges,
m["Hani"].ranges,
m["Latn"].ranges
),
-- `漢字(한자)`→`漢字`
-- `가-나-다`→`가나다`, `가--나--다`→`가-나-다`
-- `온돌(溫突/溫堗)`→`온돌` ([[ondol]])
strip_diacritics = {
remove_diacritics = u(0x302E) .. u(0x302F),
from = {"([" .. m["Hani"].characters .. "])%(.-%)", "^%-", "%-$", "%-(%-?)", "\1", "%([" .. m["Hani"].characters .. "/]+%)"},
to = {"%1", "\1", "\1", "%1", "-"}
}
}
return require("Module:languages").finalizeData(m, "script")
d83fmvbx3uwrbsx83c8wr37yf55bg6t
มอดูล:languages/data/2
828
36387
5775364
5771172
2026-10-15T07:36:00Z
Octahedron80
267
5775364
Scribunto
text/plain
local m_langdata = require("Module:languages/data")
-- Loaded on demand, as it may not be needed (depending on the data).
local function u(...)
u = require("Module:string utilities").char
return u(...)
end
local c = m_langdata.chars
local p = m_langdata.puaChars
local s = m_langdata.shared
-- Ideally, we want to move these into [[Module:languages/data]], but because (a) it's necessary to use require on that module, and (b) they're only used in this data module, it's less memory-efficient to do that at the moment. If it becomes possible to use mw.loadData, then these should be moved there.
s["de-Latn-sortkey"] = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove,
from = {"æ", "œ", "ß"},
to = {"ae", "oe", "ss"}
}
s["de-Latn-standardchars"] = "AaÄäBbCcDdEeFfGgHhIiJjKkLlMmNnOoÖöPpQqRrSsẞßTtUuÜüVvWwXxYyZz"
s["ka-stripdiacritics"] = {remove_diacritics = c.circ}
s["no-sortkey"] = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla,
remove_exceptions = {"å"},
from = {"æ", "ø", "å"},
to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]}
}
s["no-standardchars"] = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÆæØøÅå" .. c.punc
s["sa-Deva-stripdiacritics"] = { -- Don't use remove_diacritics for accent marks, as १ and ३ should also be removed if (and only if) they carry any.
from = {"ॐ", "[१३]?[" .. c.anudatta .. c.udatta .. c.dsvarita .. c.tsvarita .. "]+"},
to = {"ओँ"},
}
s["tg-stripdiacritics"] = {remove_diacritics = c.grave .. c.acute}
s["tk-stripdiacritics"] = {remove_diacritics = c.macron}
local m = {}
m["aa"] = {
"อาฟาร์",
27811,
"cus-eas",
"Latn, Ethi",
strip_diacritics = {
Latn = {remove_diacritics = c.acute},
},
}
m["ab"] = {
"อับคาเซีย",
5111,
"cau-abz",
"Cyrl, Geor, Latn",
translit = {
Cyrl = "ab-translit",
-- Geor translit in [[Module:scripts/data]]
},
override_translit = true,
display_text = {
Cyrl = s["cau-Cyrl-displaytext"]
},
strip_diacritics = {
Cyrl = {
remove_diacritics = c.acute,
from = {"^а%-"},
to = {"а"},
},
Latn = s["cau-Latn-stripdiacritics"],
},
sort_key = {
Cyrl = {
from = {
"х'ә", -- 3 chars
"гь", "гә", "ӷь", "ҕь", "ӷә", "ҕә", "дә", "ё", "жь", "жә", "ҙә", "ӡә", "ӡ'", "кь", "кә", "қь", "қә", "ҟь", "ҟә", "ҫә", "тә", "ҭә", "ф'", "хь", "хә", "х'", "ҳә", "ць", "цә", "ц'", "ҵә", "ҵ'", "шь", "шә", "џь", -- 2 chars
"ӷ", "ҕ", "ҙ", "ӡ", "қ", "ҟ", "ԥ", "ҧ", "ҫ", "ҭ", "ҳ", "ҵ", "ҷ", "ҽ", "ҿ", "ҩ", "џ", "ә", -- 1 char
"^а",
},
to = {
"х" .. p[4],
"г" .. p[1], "г" .. p[2], "г" .. p[5], "г" .. p[6], "г" .. p[7], "г" .. p[8], "д" .. p[1], "е" .. p[1], "ж" .. p[1], "ж" .. p[2], "з" .. p[2], "з" .. p[4], "з" .. p[5], "к" .. p[1], "к" .. p[2], "к" .. p[4], "к" .. p[5], "к" .. p[7], "к" .. p[8], "с" .. p[2], "т" .. p[1], "т" .. p[3], "ф" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "х" .. p[6], "ц" .. p[1], "ц" .. p[2], "ц" .. p[3], "ц" .. p[5], "ц" .. p[6], "ш" .. p[1], "ш" .. p[2], "ы" .. p[3],
"г" .. p[3], "г" .. p[4], "з" .. p[1], "з" .. p[3], "к" .. p[3], "к" .. p[6], "п" .. p[1], "п" .. p[2], "с" .. p[1], "т" .. p[2], "х" .. p[5], "ц" .. p[4], "ч" .. p[1], "ч" .. p[2], "ч" .. p[3], "ы" .. p[1], "ы" .. p[2], "ь" .. p[1],
"",
}
},
},
}
m["ae"] = {
"อเวสตะ",
29572,
"ira-cen",
"Avst, Gujr, Deva",
translit = {
Avst = "Avst-translit",
Gujr = "Gujr-translit",
Deva = "Deva-translit",
},
}
m["af"] = {
"อาฟรีกานส์",
14196,
"gmw-frk",
"Latn, Arab",
ancestors = "nl",
sort_key = {
Latn = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'",
from = {"['ʼ]n"},
to = {"n" .. p[1]}
}
},
}
m["ak"] = {
"อาคัน",
28026,
"alv-ctn",
"Latn",
}
m["am"] = {
"อัมฮารา",
28244,
"sem-eth",
"Ethi",
translit = "Ethi-translit",
}
m["an"] = {
"อารากอน",
8765,
"roa-nar",
"Latn",
}
m["ar"] = {
"อาหรับ",
13955,
"sem-arb",
"Arab, Hebr, Syrc, Brai, Nbat",
translit = {
Arab = "ar-translit"
},
strip_diacritics = {
Arab = "ar-stripdiacritics",
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["as"] = {
"อัสสัม",
29401,
"inc-bas",
"as-Beng",
ancestors = "inc-mas",
translit = "Beng-translit",
}
m["av"] = {
"อะวาร์",
29561,
"cau-ava",
"Cyrl, Latn, Arab",
ancestors = "oav",
translit = {
Cyrl = "cau-nec-translit",
Arab = "ar-translit",
},
override_translit = true,
display_text = {
Cyrl = s["cau-Cyrl-displaytext"],
},
strip_diacritics = {
Cyrl = s["cau-Cyrl-stripdiacritics"],
Latn = s["cau-Latn-stripdiacritics"],
},
sort_key = {
Cyrl = {
from = {"гъ", "гь", "гӏ", "ё", "кк", "къ", "кь", "кӏ", "лъ", "лӏ", "тӏ", "хх", "хъ", "хь", "хӏ", "цӏ", "чӏ"},
to = {"г" .. p[1], "г" .. p[2], "г" .. p[3], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "к" .. p[4], "л" .. p[1], "л" .. p[2], "т" .. p[1], "х" .. p[1], "х" .. p[2], "х" .. p[3], "х" .. p[4], "ц" .. p[1], "ч" .. p[1]}
},
},
}
m["ay"] = {
"ไอย์มารา",
4627,
"sai-aym",
"Latn",
}
m["az"] = {
"อาเซอร์ไบจาน",
9292,
"trk-ogz",
"Latn, Cyrl, Arab",
ancestors = "trk-oat",
dotted_dotless_i = true,
strip_diacritics = {
Latn = {
from = {"ʼ"},
to = {"'"},
},
Arab = {
module = "ar-stripdiacritics",
["from"] = {
"ۆ",
"ۇ",
"وْ",
"ڲ",
"ؽ",
},
["to"] = {
"و",
"و",
"و",
"گ",
"ی",
},
},
},
display_text = {
Latn = {
from = {"'"},
to = {"ʼ"}
}
},
sort_key = {
Latn = {
from = {
"i", -- Ensure "i" comes after "ı".
"ç", "ə", "ğ", "x", "ı", "q", "ö", "ş", "ü", "w"
},
to = {
"i" .. p[1],
"c" .. p[1], "e" .. p[1], "g" .. p[1], "h" .. p[1], "i", "k" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1], "z" .. p[1]
}
},
Cyrl = {
from = {"ғ", "ә", "ы", "ј", "ҝ", "ө", "ү", "һ", "ҹ"},
to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "и" .. p[2], "к" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1], "ч" .. p[1]}
},
},
}
m["ba"] = {
"แบชเคียร์",
13389,
"trk-kbu",
"Cyrl",
translit = "ba-translit",
override_translit = true,
sort_key = {
from = {"ғ", "ҙ", "ё", "ҡ", "ң", "ө", "ҫ", "ү", "һ", "ә"},
to = {"г" .. p[1], "д" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "с" .. p[1], "у" .. p[1], "х" .. p[1], "э" .. p[1]}
},
}
m["be"] = {
"เบลารุส",
9091,
"zle",
"Cyrl, Latn",
ancestors = "zle-mbe",
translit = {
Cyrl = "be-translit-Thai",
},
strip_diacritics = {
Cyrl = {
remove_diacritics = c.grave .. c.acute,
},
Latn = {
remove_diacritics = c.grave .. c.acute,
remove_exceptions = {"Ć", "ć", "Ń", "ń", "Ś", "ś", "Ź", "ź"},
},
},
sort_key = {
Cyrl = {
remove_diacritics = c.grave .. c.acute,
from = {"ґ", "ё", "і", "ў"},
to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "у" .. p[1]}
},
Latn = {
remove_diacritics = c.grave .. c.acute,
remove_exceptions = {"ć", "ń", "ś", "ź"},
from = {"ć", "č", "dz", "dź", "dž", "ch", "ł", "ń", "ś", "š", "ŭ", "ź", "ž"},
to = {"c" .. p[1], "c" .. p[2], "d" .. p[1], "d" .. p[2], "d" .. p[3], "h" .. p[1], "l" .. p[1], "n" .. p[1], "s" .. p[1], "s" .. p[2], "u" .. p[1], "z" .. p[1], "z" .. p[2]}
},
},
standard_chars = {
Cyrl = "АаБбВвГгДдЕеЁёЖжЗзІіЙйКкЛлМмНнОоПпРрСсТтУуЎўФфХхЦцЧчШшЫыЬьЭэЮюЯя",
Latn = "AaBbCcĆćČčDdEeFfGgHhIiJjKkLlŁłMmNnŃńOoPpRrSsŚśŠšTtUuŬŭVvYyZzŹźŽž",
(c.punc:gsub("'", "")) -- Exclude apostrophe.
},
}
m["bg"] = {
"บัลแกเรีย",
7918,
"zls",
"Cyrl",
ancestors = "cu-bgm",
translit = "bg-translit",
strip_diacritics = {
remove_diacritics = c.grave .. c.acute,
remove_exceptions = {"%f[^%z%s]ѝ%f[%z%s]"},
},
sort_key = {
remove_diacritics = c.grave .. c.acute,
remove_exceptions = {"%f[^%z%s]ѝ%f[%z%s]"},
},
standard_chars = "АаБбВвГгДдЕеЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЬьЮюЯя" .. c.punc,
}
m["bh"] = {
"พิหาร",
135305,
"inc-eas",
"Deva",
translit = "Deva-translit",
}
m["bi"] = {
"บิสลามา",
35452,
"crp",
"Latn",
ancestors = "en",
}
m["bm"] = {
"บัมบารา",
33243,
"dmn-emn",
"Latn, Nkoo",
sort_key = {
Latn = {
from = {"ɛ", "ɲ", "ŋ", "ɔ"},
to = {"e" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1]}
},
},
}
m["bn"] = {
"เบงกอล",
9610,
"inc-bas",
"Beng, Newa",
ancestors = "inc-mbn",
translit = {
Beng = "Beng-translit"
},
}
m["bo"] = {
"ทิเบต",
34271,
"sit-tib",
"Tibt", -- sometimes Deva?
ancestors = "xct",
override_translit = true,
-- Tibt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["br"] = {
"เบรอตง",
12107,
"cel-brs",
"Latn",
ancestors = "xbm",
sort_key = {
from = {"ch", "c['ʼ’]h"},
to = {"c" .. p[1], "c" .. p[2]}
},
}
m["ca"] = {
"กาตาลา",
7026,
"roa-ocr",
"Latn",
ancestors = "roa-oca",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla .. "·"},
standard_chars = "AaÀàBbCcÇçDdEeÉéÈèFfGgHhIiÍíÏïJjLlMmNnOoÓóÒòPpQqRrSsTtUuÚúÜüVvXxYyZz·" .. c.punc,
}
m["ce"] = {
"เชเชน",
33350,
"cau-vay",
"Cyrl, Latn, Arab",
translit = {
Cyrl = "cau-nec-translit",
Arab = "ar-translit",
},
override_translit = true,
display_text = {
Cyrl = s["cau-Cyrl-displaytext"]
},
strip_diacritics = {
Cyrl = s["cau-Cyrl-stripdiacritics"],
Latn = s["cau-Latn-stripdiacritics"],
},
sort_key = {
Cyrl = {
from = {"аь", "гӏ", "ё", "кх", "къ", "кӏ", "оь", "пӏ", "тӏ", "уь", "хь", "хӏ", "цӏ", "чӏ", "юь", "яь"},
to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "к" .. p[2], "к" .. p[3], "о" .. p[1], "п" .. p[1], "т" .. p[1], "у" .. p[1], "х" .. p[1], "х" .. p[2], "ц" .. p[1], "ч" .. p[1], "ю" .. p[1], "я" .. p[1]}
},
},
}
m["ch"] = {
"ชามอร์โร",
33262,
"poz",
"Latn",
sort_key = {
remove_diacritics = "'",
from = {"å", "ch", "ñ", "ng"},
to = {"a" .. p[1], "c" .. p[1], "n" .. p[1], "n" .. p[2]}
},
}
m["co"] = {
"คอร์ซิกา",
33111,
"roa-itr",
"Latn",
sort_key = {
from = {"chj", "ghj", "sc", "sg"},
to = {"c" .. p[1], "g" .. p[1], "s" .. p[1], "s" .. p[2]}
},
standard_chars = "AaÀàBbCcDdEeÈèFfGgHhIiÌìÏïJjLlMmNnOoÒòPpQqRrSsTtUuÙùÜüVvZz" .. c.punc,
}
m["cr"] = {
"ครี",
33390,
"alg",
"Latn, Cans",
translit = {
Cans = "cr-translit"
},
}
m["cs"] = {
"เช็ก",
9056,
"zlw",
"Latn",
ancestors = "cs-ear",
sort_key = {
from = {"á", "č", "ď", "é", "ě", "ch", "í", "ň", "ó", "ř", "š", "ť", "ú", "ů", "ý", "ž"},
to = {"a" .. p[1], "c" .. p[1], "d" .. p[1], "e" .. p[1], "e" .. p[2], "h" .. p[1], "i" .. p[1], "n" .. p[1], "o" .. p[1], "r" .. p[1], "s" .. p[1], "t" .. p[1], "u" .. p[1], "u" .. p[2], "y" .. p[1], "z" .. p[1]}
},
standard_chars = "AaÁáBbCcČčDdĎďEeÉéĚěFfGgHhIiÍíJjKkLlMmNnŇňOoÓóPpRrŘřSsŠšTtŤťUuÚúŮůVvYyÝýZzŽž" .. c.punc,
}
m["cu"] = {
"สลาวอนิกคริสตจักรเก่า",
35499,
"zls",
"Cyrs, Glag, Zname",
translit = {
Cyrs = "Cyrs-translit",
Glag = "Glag-translit"
},
-- Cyrs strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["cv"] = {
"ชูวัช",
33348,
"trk-ogr",
"Cyrl",
ancestors = "cv-mid",
translit = "cv-translit",
override_translit = true,
sort_key = {
from = {"ӑ", "ё", "ӗ", "ҫ", "ӳ"},
to = {"а" .. p[1], "е" .. p[1], "е" .. p[2], "с" .. p[1], "у" .. p[1]}
},
}
m["cy"] = {
"เวลส์",
9309,
"cel-brw",
"Latn",
ancestors = "wlm",
sort_key = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. "'",
from = {"ch", "dd", "ff", "ng", "ll", "ph", "rh", "th"},
to = {"c" .. p[1], "d" .. p[1], "f" .. p[1], "g" .. p[1], "l" .. p[1], "p" .. p[1], "r" .. p[1], "t" .. p[1]}
},
standard_chars = "ÂâAaBbCcDdEeÊêFfGgHhIiÎîLlMmNnOoÔôPpRrSsTtUuÛûWwŴŵYyŶŷ" .. c.punc,
}
m["da"] = {
"เดนมาร์ก",
9035,
"gmq-eas",
"Latn",
ancestors = "gmq-oda",
sort_key = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla,
remove_exceptions = {"å"},
from = {"æ", "ø", "å"},
to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]}
},
standard_chars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÆæØøÅå" .. c.punc,
}
m["de"] = {
"เยอรมัน",
188,
"gmw-hgm",
"Latn, Latf, Brai",
ancestors = "de-ear",
sort_key = {
Latn = s["de-Latn-sortkey"],
Latf = s["de-Latn-sortkey"],
},
standard_chars = {
Latn = s["de-Latn-standardchars"],
Latf = s["de-Latn-standardchars"],
Brai = c.braille,
c.punc
}
}
m["dv"] = {
"มัลดีฟส์",
32656,
"inc-ins",
"Thaa, Diak",
translit = {
Thaa = "Thaa-translit",
Diak = "Diak-translit",
},
ancestors = "dv-old",
override_translit = true,
}
m["dz"] = {
"ซองคา",
33081,
"sit-tib",
"Tibt",
ancestors = "xct",
override_translit = true,
-- Tibt translit, display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["ee"] = {
"เอเว",
30005,
"alv-gbe",
"Latn",
sort_key = {
remove_diacritics = c.tilde,
from = {"ɖ", "dz", "ɛ", "ƒ", "gb", "ɣ", "kp", "ny", "ŋ", "ɔ", "ts", "ʋ"},
to = {"d" .. p[1], "d" .. p[2], "e" .. p[1], "f" .. p[1], "g" .. p[1], "g" .. p[2], "k" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "t" .. p[1], "v" .. p[1]}
},
}
m["el"] = {
"กรีก",
9129,
"grk",
"Grek, Polyt, Brai",
ancestors = "el-kth",
translit = "el-translit",
override_translit = true,
-- Grek and Polyt display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
standard_chars = {
Grek = "΅·ͺ΄ΑαΆάΒβΓγΔδΕεέΈΖζΗηΉήΘθΙιΊίΪϊΐΚκΛλΜμΝνΞξΟοΌόΠπΡρΣσςΤτΥυΎύΫϋΰΦφΧχΨψΩωΏώ",
Brai = c.braille,
c.punc
},
}
m["en"] = {
"อังกฤษ",
1860,
"gmw-ang",
"Latn, Brai, Shaw, Dsrt", -- entries in Shaw or Dsrt might require prior discussion
wikimedia_codes = "en, simple",
ancestors = "en-ear",
sort_key = {
Latn = {
-- Many of these are needed for sorting language names.
remove_diacritics = "'\"%-%.,%s·ʻʼ" .. c.diacritics,
-- These are found in pagenames.
from = {"[ɒæ🅱¢©ᴄðđəǝɜɡħʜıɨłŋɲøɔœꝑꝓꝕßʋ]"},
to = {{
["ɒ"] = "a", ["æ"] = "ae", ["🅱"] = "b", ["¢"] = "c", ["©"] = "c",
["ᴄ"] = "c", ["ð"] = "d", ["đ"] = "d", ["ə"] = "e", ["ǝ"] = "e",
["ɜ"] = "e", ["ɡ"] = "g", ["ħ"] = "h", ["ʜ"] = "h", ["ı"] = "i",
["ɨ"] = "i", ["ł"] = "l", ["ŋ"] = "n", ["ɲ"] = "n", ["ø"] = "o",
["ɔ"] = "o", ["œ"] = "oe", ["ꝑ"] = "p", ["ꝓ"] = "p", ["ꝕ"] = "p",
["ß"] = "ss", ["ʋ"] = "v",
}},
},
},
standard_chars = {
Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
Brai = c.braille,
c.punc
},
}
m["eo"] = {
"เอสเปรันโต",
143,
"art",
"Latn",
--translit = "eo-translit", -- already handled in Module:headword & Module:links
sort_key = {
remove_diacritics = c.grave .. c.acute,
from = {"ĉ", "ĝ", "ĥ", "ĵ", "ŝ", "ŭ"},
to = {"c" .. p[1], "g" .. p[1], "h" .. p[1], "j" .. p[1], "s" .. p[1], "u" .. p[1]}
},
standard_chars = "AaBbCcĈĉDdEeFfGgĜĝHhĤĥIiJjĴĵKkLlMmNnOoPpRrSsŜŝTtUuŬŭVvZz" .. c.punc,
}
m["es"] = {
"สเปน",
1321,
"roa-cas",
"Latn, Brai",
ancestors = "es-ear",
--translit = "es-translit", -- already handled in Module:headword & Module:links
sort_key = {
Latn = {
remove_exceptions = {"ñ"},
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.diaer .. c.cedilla,
from = {"ª", "æ", "ñ", "º", "œ"},
to = {"a", "ae", "n" .. p[1], "o", "oe"}
},
},
standard_chars = {
Latn = "AaÁáBbCcDdEeÉéFfGgHhIiÍíJjLlMmNnÑñOoÓóPpQqRrSsTtUuÚúÜüVvXxYyZz",
Brai = c.braille,
c.punc
},
}
m["et"] = {
"เอสโตเนีย",
9072,
"urj-fin",
"Latn",
sort_key = {
from = {
"š", "ž", "õ", "ä", "ö", "ü", -- 2 chars
"z" -- 1 char
},
to = {
"s" .. p[1], "s" .. p[3], "w" .. p[1], "w" .. p[2], "w" .. p[3], "w" .. p[4],
"s" .. p[2]
}
},
standard_chars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvÕõÄäÖöÜü" .. c.punc,
}
m["eu"] = {
"บาสก์",
8752,
"euq",
"Latn",
sort_key = {
from = {"ç", "ñ"},
to = {"c" .. p[1], "n" .. p[1]}
},
standard_chars = "AaBbDdEeFfGgHhIiJjKkLlMmNnÑñOoPpRrSsTtUuXxZz" .. c.punc,
}
m["fa"] = {
"เปอร์เซีย",
9168,
"ira-swi",
"Arab, Hebr",
ancestors = "fa-cls",
strip_diacritics = {
Arab = {
-- character "ۂ" code U+06C2 to "ه" and "هٔ" (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif
from = {"هٔ", "ٱ"}, -- character "ۂ" code U+06C2 to "ه"; hamzatu l-waṣli to a regular alif
to = {"ه", "ا"},
remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef,
},
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["ff"] = {
"ฟูลา",
33454,
"alv-fwo",
"Latn, Adlm",
}
m["fi"] = {
"ฟินแลนด์",
1412,
"urj-fin",
"Latn",
display_text = {
from = {"'"},
to = {"’"}
},
strip_diacritics = { -- used to indicate gemination of the next consonant
remove_diacritics = "ˣ",
from = {"’"},
to = {"'"},
},
sort_key = { -- [[Appendix:Finnish alphabet#Collation]] + "aͤ" and "oͤ" as historical variants of "ä" and "ö".
remove_diacritics = "'’:" .. c.diacritics,
remove_exceptions = {
"a[" .. c.ringabove .. c.diaer .. c.small_e .. "]", -- åäaͤ
"o[" .. c.diaer .. c.tilde .. c.dacute .. c.small_e .. "]", -- öõőoͤ
"u[" .. c.diaer .. c.dacute .. "]" -- üű
},
from = {"æ", "[ðđ]", "ł", "ŋ", "œ", "ß", "þ", "u[" .. c.diaer .. c.dacute .. "]", "å", "aͤ", "o[" .. c.tilde .. c.dacute .. c.small_e .. "]", "ø", "(.)['%-]"},
to = {"ae", "d", "l", "n", "oe", "ss", "th", "y", "z" .. p[1], "ä", "ö", "ö", "%1"}
},
standard_chars = "AaBbDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvYyÄäÖö" .. c.punc,
}
m["fj"] = {
"ฟีจี",
33295,
"poz-pcc",
"Latn",
}
m["fo"] = {
"แฟโร",
25258,
"gmq-ins",
"Latn",
sort_key = {
from = {"á", "ð", "í", "ó", "ú", "ý", "æ", "ø"},
to = {"a" .. p[1], "d" .. p[1], "i" .. p[1], "o" .. p[1], "u" .. p[1], "y" .. p[1], "z" .. p[1], "z" .. p[2]}
},
standard_chars = "AaÁáBbDdÐðEeFfGgHhIiÍíJjKkLlMmNnOoÓóPpRrSsTtUuÚúVvYyÝýÆæØø" .. c.punc,
}
m["fr"] = {
"ฝรั่งเศส",
150,
"roa-oil",
"Latn, Brai",
ancestors = "frm",
sort_key = {
Latn = s["roa-oil-sortkey"]
},
standard_chars = {
Latn = "AaÀàÂâBbCcÇçDdEeÉéÈèÊêËëFfGgHhIiÎîÏïJjLlMmNnOoÔôŒœPpQqRrSsTtUuÙùÛûÜüVvXxYyZz",
Brai = c.braille,
c.punc
},
}
m["fy"] = {
"ฟรีเชียตะวันตก",
27175,
"gmw-fri",
"Latn",
sort_key = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer,
from = {"y"},
to = {"i"}
},
standard_chars = "AaâäàÆæBbCcDdEeéêëèFfGgHhIiïìYyỳJjKkLlMmNnOoôöòPpRrSsTtUuúûüùVvWwZz" .. c.punc,
}
m["ga"] = {
"ไอริช",
9142,
"cel-gae",
"Latn, Latg",
ancestors = "mga",
sort_key = {
remove_diacritics = c.acute,
from = {"ḃ", "ċ", "ḋ", "ḟ", "ġ", "ṁ", "ṗ", "ṡ", "ṫ"},
to = {"bh", "ch", "dh", "fh", "gh", "mh", "ph", "sh", "th"}
},
standard_chars = "AaÁáBbCcDdEeÉéFfGgHhIiÍíLlMmNnOoÓóPpRrSsTtUuÚúVv" .. c.punc,
}
m["gd"] = {
"แกลิกแบบสกอตแลนด์",
9314,
"cel-gae",
"Latn, Latg",
ancestors = "mga",
sort_key = {remove_diacritics = c.grave .. c.acute},
standard_chars = "AaÀàBbCcDdEeÈèFfGgHhIiÌìLlMmNnOoÒòPpRrSsTtUuÙù" .. c.punc,
}
m["gl"] = {
"กาลิเซีย",
9307,
"roa-gap",
"Latn",
sort_key = {
remove_diacritics = c.acute,
from = {"ñ"},
to = {"n" .. p[1]}
},
standard_chars = "AaÁáBbCcDdEeÉéFfGgHhIiÍíÏïLlMmNnÑñOoÓóPpQqRrSsTtUuÚúÜüVvXxZz" .. c.punc,
}
m["gu"] = {
"คุชราต",
5137,
"inc-wes",
"Arab, Gujr",
ancestors = "inc-mgu",
translit = {
Gujr = "Gujr-translit",
},
strip_diacritics = {
Arab = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.kasra .. c.shadda .. c.sukun},
Gujr = {remove_diacritics = "઼"},
},
}
m["gv"] = {
"แมงซ์",
12175,
"cel-gae",
"Latn",
ancestors = "mga",
sort_key = {remove_diacritics = c.cedilla .. "-"},
standard_chars = "AaBbCcÇçDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwYy" .. c.punc,
}
m["ha"] = {
"เฮาซา",
56475,
"cdc-wst",
"Latn, Arab",
strip_diacritics = {
Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron}
},
sort_key = {
Latn = {
from = {"ɓ", "b'", "ɗ", "d'", "ƙ", "k'", "sh", "ƴ", "'y"},
to = {"b" .. p[1], "b" .. p[2], "d" .. p[1], "d" .. p[2], "k" .. p[1], "k" .. p[2], "s" .. p[1], "y" .. p[1], "y" .. p[2]}
},
},
}
m["he"] = {
"ฮีบรู",
9288,
"sem-can",
"Hebr, Phnx, Brai, Samr",
ancestors = "he-med",
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
-- Samr strip_diacritics, sort_key in [[Module:scripts/data]]
-- Phnx translit in [[Module:scripts/data]] (NOTE: not present before, presumably an accidental omission)
}
m["hi"] = {
"ฮินดี",
1568,
"inc-hnd",
"Deva, Kthi, Newa",
translit = {
Deva = "Deva-translit",
Kthi = "Kthi-translit",
Newa = "Newa-translit",
},
standard_chars = {
Deva = "अआइईउऊएऐओऔकखगघङचछजझञटठडढणतथदधनपफबभमयरलवशषसहत्रज्ञक्षक़ख़ग़ज़झ़ड़ढ़फ़काखागाघाङाचाछाजाझाञाटाठाडाढाणाताथादाधानापाफाबाभामायारालावाशाषासाहात्राज्ञाक्षाक़ाख़ाग़ाज़ाझ़ाड़ाढ़ाफ़ाकिखिगिघिङिचिछिजिझिञिटिठिडिढिणितिथिदिधिनिपिफिबिभिमियिरिलिविशिषिसिहित्रिज्ञिक्षिक़िख़िग़िज़िझ़िड़िढ़िफ़िकीखीगीघीङीचीछीजीझीञीटीठीडीढीणीतीथीदीधीनीपीफीबीभीमीयीरीलीवीशीषीसीहीत्रीज्ञीक्षीक़ीख़ीग़ीज़ीझ़ीड़ीढ़ीफ़ीकुखुगुघुङुचुछुजुझुञुटुठुडुढुणुतुथुदुधुनुपुफुबुभुमुयुरुलुवुशुषुसुहुत्रुज्ञुक्षुक़ुख़ुग़ुज़ुझ़ुड़ुढ़ुफ़ुकूखूगूघूङूचूछूजूझूञूटूठूडूढूणूतूथूदूधूनूपूफूबूभूमूयूरूलूवूशूषूसूहूत्रूज्ञूक्षूक़ूख़ूग़ूज़ूझ़ूड़ूढ़ूफ़ूकेखेगेघेङेचेछेजेझेञेटेठेडेढेणेतेथेदेधेनेपेफेबेभेमेयेरेलेवेशेषेसेहेत्रेज्ञेक्षेक़ेख़ेग़ेज़ेझ़ेड़ेढ़ेफ़ेकैखैगैघैङैचैछैजैझैञैटैठैडैढैणैतैथैदैधैनैपैफैबैभैमैयैरैलैवैशैषैसैहैत्रैज्ञैक्षैक़ैख़ैग़ैज़ैझ़ैड़ैढ़ैफ़ैकोखोगोघोङोचोछोजोझोञोटोठोडोढोणोतोथोदोधोनोपोफोबोभोमोयोरोलोवोशोषोसोहोत्रोज्ञोक्षोक़ोख़ोग़ोज़ोझ़ोड़ोढ़ोफ़ोकौखौगौघौङौचौछौजौझौञौटौठौडौढौणौतौथौदौधौनौपौफौबौभौमौयौरौलौवौशौषौसौहौत्रौज्ञौक्षौक़ौख़ौग़ौज़ौझ़ौड़ौढ़ौफ़ौक्ख्ग्घ्ङ्च्छ्ज्झ्ञ्ट्ठ्ड्ढ्ण्त्थ्द्ध्न्प्फ्ब्भ्म्य्र्ल्व्श्ष्स्ह्त्र्ज्ञ्क्ष्क़्ख़्ग़्ज़्झ़्ड़्ढ़्फ़्।॥०१२३४५६७८९॰",
c.punc
},
}
m["ho"] = {
"ฮีรีโมตู",
33617,
"crp",
"Latn",
ancestors = "meu",
}
m["ht"] = {
"ครีโอลเฮติ",
33491,
"crp",
"Latn",
ancestors = "ht-sdm",
sort_key = {
from = {
"oun", -- 3 chars
"an", "ch", "è", "en", "ng", "ò", "on", "ou", "ui" -- 2 chars
},
to = {
"o" .. p[4],
"a" .. p[1], "c" .. p[1], "e" .. p[1], "e" .. p[2], "n" .. p[1], "o" .. p[1], "o" .. p[2], "o" .. p[3], "u" .. p[1]
}
},
}
m["hu"] = {
"ฮังการี",
9067,
"urj-ugr",
"Latn, Hung",
ancestors = "ohu",
sort_key = {
Latn = {
from = {
"dzs", -- 3 chars
"á", "cs", "dz", "é", "gy", "í", "ly", "ny", "ó", "ö", "ő", "sz", "ty", "ú", "ü", "ű", "zs", -- 2 chars
},
to = {
"d" .. p[2],
"a" .. p[1], "c" .. p[1], "d" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "l" .. p[1], "n" .. p[1], "o" .. p[1], "o" .. p[2], "o" .. p[3], "s" .. p[1], "t" .. p[1], "u" .. p[1], "u" .. p[2], "u" .. p[3], "z" .. p[1],
}
},
},
standard_chars = {
Latn = "AaÁáBbCcDdEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóÖöŐőPpQqRrSsTtUuÚúÜüŰűVvWwXxYyZz",
c.punc
},
}
m["hy"] = {
"อาร์มีเนีย",
8785,
"hyx",
"Armn, Brai",
ancestors = "axm",
-- Armn translit in [[Module:scripts/data]]
override_translit = true,
strip_diacritics = {
Armn = {
remove_diacritics = "՛՜՞՟",
from = {"եւ", "<sup>յ</sup>", "<sup>ի</sup>", "<sup>է</sup>", "յ̵", "ՙ", "՚"},
to = {"և", "յ", "ի", "է", "ֈ", "ʻ", "’"}
},
},
sort_key = {
Armn = {
from = {
"ու", "եւ", -- 2 chars
"և" -- 1 char
},
to = {
"ւ", "եվ",
"եվ"
}
},
},
}
m["hz"] = {
"เฮเรโร",
33315,
"bnt-swb",
"Latn",
}
m["ia"] = {
"อินเทอร์ลิงกวา",
35934,
"art",
"Latn",
}
m["id"] = {
"อินโดนีเซีย",
9240,
"poz-mly",
"Latn",
ancestors = "ms",
standard_chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz" .. c.punc,
}
m["ie"] = {
"อินเทร์ลิงเกว",
35850,
"art",
"Latn",
type = "appendix-constructed",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ},
}
m["ig"] = {
"อิกโบ",
33578,
"alv-igb",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.macron},
sort_key = {
from = {"gb", "gh", "gw", "ị", "kp", "kw", "ṅ", "nw", "ny", "ọ", "sh", "ụ"},
to = {"g" .. p[1], "g" .. p[2], "g" .. p[3], "i" .. p[1], "k" .. p[1], "k" .. p[2], "n" .. p[1], "n" .. p[2], "n" .. p[3], "o" .. p[1], "s" .. p[1], "u" .. p[1]}
},
}
m["ii"] = {
"นอซู",
34235,
"tbq-nlo",
"Yiii",
translit = "ii-translit",
}
m["ik"] = {
"Inupiaq",
27183,
"esx-inu",
"Latn",
sort_key = {
from = {
"ch", "ġ", "dj", "ḷ", "ł̣", "ñ", "ng", "r̂", "sr", "zr", -- 2 chars
"ł", "ŋ", "ʼ" -- 1 char
},
to = {
"c" .. p[1], "g" .. p[1], "h" .. p[1], "l" .. p[1], "l" .. p[3], "n" .. p[1], "n" .. p[2], "r" .. p[1], "s" .. p[1], "z" .. p[1],
"l" .. p[2], "n" .. p[2], "z" .. p[2]
}
},
}
m["io"] = {
"อีโด",
35224,
"art",
"Latn",
}
m["is"] = {
"ไอซ์แลนด์",
294,
"gmq-ins",
"Latn",
sort_key = {
from = {"á", "ð", "é", "í", "ó", "ú", "ý", "þ", "æ", "ö"},
to = {"a" .. p[1], "d" .. p[1], "e" .. p[1], "i" .. p[1], "o" .. p[1], "u" .. p[1], "y" .. p[1], "z" .. p[1], "z" .. p[2], "z" .. p[3]}
},
standard_chars = "AaÁáBbDdÐðEeÉéFfGgHhIiÍíJjKkLlMmNnOoÓóPpRrSsTtUuÚúVvXxYyÝýÞþÆæÖö" .. c.punc,
}
m["it"] = {
"อิตาลี",
652,
"roa-itr",
"Latn",
ancestors = "roa-oit",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.ringabove},
standard_chars = "AaÀàBbCcDdEeÈèÉéFfGgHhIiÌìLlMmNnOoÒòPpQqRrSsTtUuÙùVvZz" .. c.punc,
}
m["iu"] = {
"อินุกติตุต",
29921,
"esx-inu",
"Cans, Latn",
translit = {
Cans = "cr-translit"
},
override_translit = true,
}
m["ja"] = {
"ญี่ปุ่น",
5287,
"jpx",
"Jpan, Latn, Brai",
ancestors = "ja-ear",
translit = s["jpx-translit"],
link_tr = true,
display_text = s["jpx-displaytext"],
strip_diacritics = s["jpx-stripdiacritics"],
sort_key = s["jpx-sortkey"],
}
m["jv"] = {
"ชวา",
33549,
"poz",
"Latn, Java, Arab",
ancestors = "kaw",
translit = {
Java = "Java-translit"
},
link_tr = true,
strip_diacritics = {
Latn = {remove_diacritics = c.circ} -- Modern jv don't use ê
},
sort_key = {
Latn = {
from = {"å", "dh", "é", "è", "ng", "ny", "th"},
to = {"a" .. p[1], "d" .. p[1], "e" .. p[1], "e" .. p[2], "n" .. p[1], "n" .. p[2], "t" .. p[1]}
},
},
}
m["ka"] = {
"จอร์เจีย",
8108,
"ccs-gzn",
"Geor, Geok, Hebr", -- Hebr is used to write Judeo-Georgian
ancestors = "ka-mid",
-- Geor, Geok translit in [[Module:scripts/data]]
override_translit = true,
strip_diacritics = {
Geor = s["ka-stripdiacritics"],
Geok = s["ka-stripdiacritics"],
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["kg"] = {
"คองโก",
33702,
"bnt-kng",
"Latn",
}
m["ki"] = {
"เกโกโย",
33587,
"bnt-kka",
"Latn",
}
m["kj"] = {
"Kwanyama",
1405077,
"bnt-ova",
"Latn",
}
m["kk"] = {
"คาซัค",
9252,
"trk-kno",
"Cyrl, Latn, Arab",
translit = "kk-translit",
-- override_translit = true,
sort_key = {
Cyrl = {
from = {"ә", "ғ", "ё", "қ", "ң", "ө", "ұ", "ү", "һ", "і"},
to = {"а" .. p[1], "г" .. p[1], "е" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "у" .. p[2], "х" .. p[1], "ы" .. p[1]}
},
},
standard_chars = {
Cyrl = "АаӘәБбВвГгҒғДдЕеЁёЖжЗзИиЙйКкҚқЛлМмНнҢңОоӨөПпРрСсТтУуҰұҮүФфХхҺһЦцЧчШшЩщЪъЫыІіЬьЭэЮюЯя",
c.punc
},
}
m["kl"] = {
"กรีนแลนด์",
25355,
"esx-inu",
"Latn",
sort_key = {
from = {"æ", "ø", "å"},
to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]}
}
}
m["km"] = {
"เขมร",
9205,
"mkh-kmr",
"Khmr",
ancestors = "xhm",
translit = "Khmr-translit",
}
m["kn"] = {
"กันนฑะ",
33673,
"dra-kan",
"Knda, Tutg",
ancestors = "dra-mkn",
-- Knda translit in [[Module:scripts/data]]
}
m["ko"] = {
"เกาหลี",
9176,
"qfa-kor",
"Kore, Brai",
ancestors = "ko-ear",
translit = {
Kore = "ko-translit",
},
-- Kore strip_diacritics in [[Module:scripts/data]]
}
m["kr"] = {
"กานูรี",
36094,
"ssa-sah",
"Latn, Arab",
-- the sortkey and strip_diacritics are only for standard Kanuri; when dialectal entries get added, someone will have to work out how the dialects should be represented orthographically
strip_diacritics = {
Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.breve}
},
sort_key = {
Latn = {
from = {"ǝ", "ny", "ɍ", "sh"},
to = {"e" .. p[1], "n" .. p[1], "r" .. p[1], "s" .. p[1]}
},
},
}
m["ks"] = {
"แคชเมียร์",
33552,
"inc-kas",
"Aran, Deva, Shrd, Latn",
translit = {
Aran = "ks-Aran-translit",
Deva = "Deva-translit",
-- Shrd translit in [[Module:scripts/data]]
},
}
-- "kv" is treated as "koi", "kpv", see [[WT:LT]]
m["kw"] = {
"คอร์นวอลล์",
25289,
"cel-brs",
"Latn",
ancestors = "cnx",
sort_key = {
from = {"ch"},
to = {"c" .. p[1]}
},
}
m["ky"] = {
"คีร์กีซ",
9255,
"trk-kkp",
"Cyrl, Latn, Arab",
translit = {
Cyrl = "ky-translit"
},
override_translit = true,
sort_key = {
Cyrl = {
from = {"ё", "ң", "ө", "ү"},
to = {"е" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1]}
},
},
}
m["la"] = {
"ละติน",
397,
"itc-laf",
"Latn, Ital",
ancestors = "itc-ola",
--translit = "la-translit", -- already handled in Module:headword & Module:links
-- Ital translit in [[Module:scripts/data]] (NOTE: formerly not present, probably an accidental omission)
display_text = {
Latn = s["itc-Latn-displaytext"]
},
strip_diacritics = {
Latn = s["itc-Latn-stripdiacritics"]
},
sort_key = {
Latn = s["itc-Latn-sortkey"]
},
standard_chars = {
Latn = "AaBbCcDdEeFfGgHhIiLlMmNnOoPpQqRrSsTtUuVvXx",
c.punc
},
}
m["lb"] = {
"ลักเซมเบิร์ก",
9051,
"gmw-hgm",
"Latn, Brai",
ancestors = "gmw-cfr",
sort_key = {
Latn = {
from = {"ä", "ë", "é"},
to = {"z" .. p[1], "z" .. p[2], "z" .. p[3]}
},
},
}
m["lg"] = {
"ลูกันดา",
33368,
"bnt-nyg",
"Latn",
strip_diacritics = {remove_diacritics = c.acute .. c.circ},
sort_key = {
from = {"ŋ"},
to = {"n" .. p[1]}
},
}
m["li"] = {
"ลิมเบิร์ก",
102172,
"gmw-frk",
"Latn",
ancestors = "dum",
}
m["ln"] = {
"ลิงกาลา",
36217,
"bnt-bmo",
"Latn",
sort_key = {
remove_diacritics = c.acute .. c.circ .. c.caron,
from = {"ɛ", "gb", "mb", "mp", "nd", "ng", "nk", "ns", "nt", "ny", "nz", "ɔ"},
to = {"e" .. p[1], "g" .. p[1], "m" .. p[1], "m" .. p[2], "n" .. p[1], "n" .. p[2], "n" .. p[3], "n" .. p[4], "n" .. p[5], "n" .. p[6], "n" .. p[7], "o" .. p[1]}
},
}
m["lo"] = {
"ลาว",
9211,
"tai-swe",
"Laoo", -- also Tai Noi/Lao Buhan script
translit = "Laoo-translit",
--sort_key = "Laoo-sortkey",
standard_chars = "0-9ກຂຄງຈຊຍດຕຖທນບປຜຝພຟມຢຣລວສຫອຮຯ-ໝ" .. c.punc,
}
m["lt"] = {
"ลิทัวเนีย",
9083,
"bat-eas",
"Latn",
ancestors = "olt",
display_text = "lt-common",
strip_diacritics = "lt-common",
sort_key = "lt-common",
standard_chars = "AaĄąBbCcČčDdEeĘęĖėFfGgHhIiĮįYyJjKkLlMmNnOoPpRrSsŠšTtUuŲųŪūVvZzŽž" .. c.punc,
}
m["lu"] = {
"Luba-Katanga",
36157,
"bnt-lub",
"Latn",
}
m["lv"] = {
"ลัตเวีย",
9078,
"bat-eas",
"Latn",
strip_diacritics = {
-- This attempts to convert vowels with tone marks to vowels either with or without macrons. Specifically, there should be no macrons if the vowel is part of a diphthong (including resonant diphthongs such pìrksts -> pirksts not #pīrksts). What we do is first convert the vowel + tone mark to a vowel + tilde in a decomposed fashion, then remove the tilde in diphthongs, then convert the remaining vowel + tilde sequences to macroned vowels, then delete any other tilde. We leave already-macroned vowels alone: Both e.g. ar and ār occur before consonants. FIXME: This still might not be sufficient.
from = {"([Ee])" .. c.cedilla, "[" .. c.grave .. c.circ .. c.tilde .."]", "([aAeEiIoOuU])" .. c.tilde .."?([lrnmuiLRNMUI])" .. c.tilde .. "?([^aAeEiIoOuU])", "([aAeEiIoOuU])" .. c.tilde .."?([lrnmuiLRNMUI])" .. c.tilde .."?$", "([iI])" .. c.tilde .. "?([eE])" .. c.tilde .. "?", "([aAeEiIuU])" .. c.tilde, c.tilde},
to = {"%1", c.tilde, "%1%2%3", "%1%2", "%1%2", "%1" .. c.macron}
},
sort_key = {
from = {"ā", "č", "ē", "ģ", "ī", "ķ", "ļ", "ņ", "š", "ū", "ž"},
to = {"a" .. p[1], "c" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "k" .. p[1], "l" .. p[1], "n" .. p[1], "s" .. p[1], "u" .. p[1], "z" .. p[1]}
},
standard_chars = "AaĀāBbCcČčDdEeĒēFfGgĢģHhIiĪīJjKkĶķLlĻļMmNnŅņOoPpRrSsŠšTtUuŪūVvZzŽž" .. c.punc,
}
m["mg"] = {
"มาลากาซี",
7930,
"poz-bre",
"Latn, Arab",
}
m["mh"] = {
"มาร์แชลล์",
36280,
"poz-mic",
"Latn",
sort_key = {
from = {"ā", "ļ", "m̧", "ņ", "n̄", "o̧", "ō", "ū"},
to = {"a" .. p[1], "l" .. p[1], "m" .. p[1], "n" .. p[1], "n" .. p[2], "o" .. p[1], "o" .. p[2], "u" .. p[1]}
},
}
m["mi"] = {
"มาวรี",
36451,
"poz-pep",
"Latn",
sort_key = {
remove_diacritics = c.macron,
from = {"ng", "wh"},
to = {"n" .. p[1], "w" .. p[1]}
},
}
m["mk"] = {
"มาซิโดเนีย",
9296,
"zls",
"Cyrl, Polyt",
ancestors = "cu",
translit = {
Cyrl = "mk-translit",
-- FIXME: formerly no translit specified for Polyt; unclear if the default [[Module:grc-translit]] is
-- acceptable, so we disable it for now
Polyt = false,
},
strip_diacritics = {
Cyrl = {
remove_diacritics = c.acute,
remove_exceptions = {"Ѓ", "ѓ", "Ќ", "ќ"}
},
},
sort_key = {
Cyrl = {
remove_diacritics = c.grave,
remove_exceptions = {"ѓ", "ќ"},
from = {"ѓ", "ѕ", "ј", "љ", "њ", "ќ", "џ"},
to = {"д" .. p[1], "з" .. p[1], "и" .. p[1], "л" .. p[1], "н" .. p[1], "т" .. p[1], "ч" .. p[1]}
},
},
-- Polyt display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
standard_chars = {
Cyrl = "АаБбВвГгДдЃѓЕеЖжЗзЅѕИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЌќУуФфХхЦцЧчЏџШш",
c.punc
},
}
m["ml"] = {
"มลยาฬัม",
36236,
"dra-mal",
"Mlym",
override_translit = true,
-- Mlym translit in [[Module:scripts/data]]
}
m["mn"] = {
"มองโกเลีย",
9246,
"xgn-cen",
"Cyrl, Mong, Latn, Brai",
ancestors = "cmg",
translit = {
Cyrl = "mn-translit",
-- Mong translit in [[Module:scripts/data]]
},
override_translit = true,
-- Mong display_text and strip_diacritics in [[Module:scripts/data]]
strip_diacritics = {
Cyrl = {remove_diacritics = c.grave .. c.acute},
},
sort_key = {
Cyrl = {
remove_diacritics = c.grave,
from = {"ё", "ө", "ү"},
to = {"е" .. p[1], "о" .. p[1], "у" .. p[1]}
},
},
standard_chars = {
Cyrl = "АаБбВвГгДдЕеЁёЖжЗзИиЙйЛлМмНнОоӨөРрСсТтУуҮүХхЦцЧчШшЫыЬьЭэЮюЯя—",
Brai = c.braille,
c.punc
},
}
-- "mo" is treated as "ro", see [[WT:LT]]
m["mr"] = {
"มราฐี",
1571,
"inc-sou",
"Deva, Modi",
ancestors = "omr",
translit = {
Deva = "Deva-translit",
Modi = "Modi-translit",
},
strip_diacritics = {
Deva = {
from = {"च़", "ज़", "झ़"},
to = {"च", "ज", "झ"}
},
},
}
m["ms"] = {
"มาเลเซีย",
9237,
"poz-mly",
"Latn, Arab",
ancestors = "ms-cla",
standard_chars = {
Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
c.punc
},
}
m["mt"] = {
"มอลตา",
9166,
"sem-arb",
"Latn",
display_text = {
from = {"'"},
to = {"’"}
},
strip_diacritics = {
from = {"’"},
to = {"'"},
},
ancestors = "sqr",
sort_key = {
from = {
"ċ", "ġ", "ż", -- Convert into PUA so that decomposed form does not get caught by the next step.
"([cgz])", -- Ensure "c" comes after "ċ", "g" comes after "ġ" and "z" comes after "ż".
"g" .. p[1] .. "ħ", -- "għ" after initial conversion of "g".
p[3], p[4], "ħ", "ie", p[5] -- Convert "ċ", "ġ", "ħ", "ie", "ż" into final output.
},
to = {
p[3], p[4], p[5],
"%1" .. p[1],
"g" .. p[2],
"c", "g", "h" .. p[1], "i" .. p[1], "z"
}
},
}
m["my"] = {
"พม่า",
9228,
"tbq-brm",
"Mymr",
ancestors = "obr",
translit = "my-translit",
override_translit = true,
sort_key = {
from = {"ျ", "ြ", "ွ", "ှ", "ဿ"},
to = {"္ယ", "္ရ", "္ဝ", "္ဟ", "သ္သ"}
},
}
m["na"] = {
"นาอูรู",
13307,
"poz-mic",
"Latn",
}
m["nb"] = {
"นอร์เวย์แบบบุ๊กมอล",
25167,
"gmq",
"Latn",
wikimedia_codes = "no",
ancestors = "gmq-mno, da", -- da as an (but not the) ancestor of nb was agreed on - do not change without discussion
sort_key = s["no-sortkey"],
standard_chars = s["no-standardchars"],
}
m["nd"] = {
"Northern Ndebele",
35613,
"bnt-ngu",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron},
}
m["ne"] = {
"เนปาล",
33823,
"inc-pae",
"Deva, Newa",
translit = {
Deva = "Deva-translit",
Newa = "Newa-translit",
},
}
m["ng"] = {
"Ndonga",
33900,
"bnt-ova",
"Latn",
}
m["nl"] = {
"ดัตช์",
7411,
"gmw-frk",
"Latn, Brai",
ancestors = "dum",
sort_key = {
Latn = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'"},
},
standard_chars = {
Latn = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzÄäËëÏïÖöÜü",
Brai = c.braille,
c.punc
},
}
m["nn"] = {
"นอร์เวย์แบบนือนอสก์",
25164,
"gmq-wes",
"Latn",
ancestors = "gmq-mno",
strip_diacritics = {
remove_diacritics = c.grave .. c.acute,
},
sort_key = s["no-sortkey"],
standard_chars = s["no-standardchars"],
}
m["no"] = {
"นอร์เวย์",
9043,
"gmq-wes",
"Latn",
ancestors = "gmq-mno",
sort_key = s["no-sortkey"],
standard_chars = s["no-standardchars"],
}
m["nr"] = {
"Southern Ndebele",
36785,
"bnt-ngu",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron},
}
m["nv"] = {
"นาวาโฮ",
13310,
"apa",
"Latn, Brai",
sort_key = {
remove_diacritics = c.acute .. c.ogonek,
from = {
"chʼ", "tłʼ", "tsʼ", -- 3 chars
"ch", "dl", "dz", "gh", "hw", "kʼ", "kw", "sh", "tł", "ts", "zh", -- 2 chars
"ł", "ʼ" -- 1 char
},
to = {
"c" .. p[2], "t" .. p[2], "t" .. p[4],
"c" .. p[1], "d" .. p[1], "d" .. p[2], "g" .. p[1], "h" .. p[1], "k" .. p[1], "k" .. p[2], "s" .. p[1], "t" .. p[1], "t" .. p[3], "z" .. p[1],
"l" .. p[1], "z" .. p[2]
}
},
}
m["ny"] = {
"เจวา",
33273,
"bnt-nys",
"Latn",
strip_diacritics = {remove_diacritics = c.acute .. c.circ},
sort_key = {
from = {"ng'"},
to = {"ng"}
},
}
m["oc"] = {
"อุตซิตา",
14185,
"roa-ocr",
"Latn, Hebr",
ancestors = "pro",
sort_key = {
Latn = {
remove_diacritics = c.grave .. c.acute .. c.diaer .. c.cedilla,
from = {"([lns])·h"},
to = {"%1h"}
},
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["oj"] = {
"โอจิบเว",
33875,
"alg",
"Cans, Latn",
sort_key = {
Latn = {
from = {"aa", "ʼ", "ii", "oo", "sh", "zh"},
to = {"a" .. p[1], "h" .. p[1], "i" .. p[1], "o" .. p[1], "s" .. p[1], "z" .. p[1]}
},
},
}
m["om"] = {
"ออโรโม",
33864,
"cus-eas",
"Latn, Ethi",
}
m["or"] = {
"โอริยา",
33810,
"inc-eas",
"Orya",
ancestors = "inc-mor",
translit = "Orya-translit",
}
m["os"] = {
"ออสซีเซีย",
33968,
"xsc-sar",
"Cyrl, Geor, Latn",
ancestors = "oos",
translit = {
Cyrl = "os-translit",
-- Geor translit in [[Module:scripts/data]]
},
override_translit = true,
display_text = {
Cyrl = {
from = {"æ", "Æ"},
to = {"ӕ", "Ӕ"}
},
Latn = {
from = {"ӕ", "Ӕ"},
to = {"æ", "Æ"}
},
},
strip_diacritics = {
Cyrl = {
remove_diacritics = c.grave .. c.acute,
from = {"æ", "Æ"},
to = {"ӕ", "Ӕ"}
},
Latn = {
from = {"ӕ", "Ӕ"},
to = {"æ", "Æ"}
},
},
sort_key = {
Cyrl = {
from = {"ӕ", "гъ", "дж", "дз", "ё", "къ", "пъ", "тъ", "хъ", "цъ", "чъ"},
to = {"а" .. p[1], "г" .. p[1], "д" .. p[1], "д" .. p[2], "е" .. p[1], "к" .. p[1], "п" .. p[1], "т" .. p[1], "х" .. p[1], "ц" .. p[1], "ч" .. p[1]}
},
},
}
m["pa"] = {
"ปัญจาบ",
58635,
"inc-pan",
"Guru, Aran",
translit = {
Guru = "Guru-translit",
Aran = "pa-Aran-translit",
},
strip_diacritics = {
Aran = {
remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna,
from = {"ݨ", "ࣇ"},
to = {"ن", "ل"}
},
},
}
m["pi"] = {
"บาลี",
36727,
"inc-mid",
"Latn, Brah, Deva, Beng, Sinh, Mymr, Thai, Lana, Laoo, Khmr, Cakm", --and also Khom
ancestors = "sa",
translit = {
-- Brah translit in [[Module:scripts/data]]
Deva = "Deva-translit",
Beng = "Beng-translit",
Sinh = "Sinh-translit",
Mymr = "Mymr-translit",
--Thai = "pi-translit",
Lana = "Lana-translit",
Laoo = "Laoo-translit",
Khmr = "Khmr-translit",
Cakm = "Cakm-translit",
},
strip_diacritics = {
Thai = {
from = {"ึ", u(0xF700), u(0xF70F)}, -- FIXME: Not clear what's going on with the PUA characters here.
to = {"ิํ", "ฐ", "ญ"}
},
Mymr = {
remove_diacritics = c.VS01,
},
},
sort_key = { -- FIXME: This needs to be converted into the current standardized format.
from = {"ā", "ī", "ū", "ḍ", "ḷ", "m[" .. c.dotabove .. c.dotbelow .. "]", "ṅ", "ñ", "ṇ", "ṭ", "ॐ", "([เโ])([ก-ฮ])", "([ເໂ])([ກ-ຮ])", "ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ", u(0xFE00), u(0x200D)},
to = {"a~", "i~", "u~", "d~", "l~", "m~", "n~", "n~~", "n~~~", "t~", "ओँ", "%2%1", "%2%1", "ᩈ᩠ᩈ", "᩠ᩁ", "᩠ᩃ", "ᨦ᩠", "%1᩠ᨮ", "%1᩠ᨻ", "ᩣ"}
},
}
m["pl"] = {
"โปแลนด์",
809,
"zlw-lch",
"Latn",
ancestors = "zlw-mpl",
sort_key = {
from = {"ą", "ć", "ę", "ł", "ń", "ó", "ś", "ź", "ż"},
to = {"a" .. p[1], "c" .. p[1], "e" .. p[1], "l" .. p[1], "n" .. p[1], "o" .. p[1], "s" .. p[1], "z" .. p[1], "z" .. p[2]}
},
standard_chars = "AaĄąBbCcĆćDdEeĘęFfGgHhIiJjKkLlŁłMmNnŃńOoÓóPpRrSsŚśTtUuWwYyZzŹźŻż" .. c.punc,
}
m["ps"] = {
"ปาทาน",
58680,
"ira-pat",
"Arab",
strip_diacritics = {remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.zwarakay .. c.superalef},
}
m["pt"] = {
"โปรตุเกส",
5146,
"roa-gap",
"Latn, Brai",
sort_key = {
Latn = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.diaer .. c.cedilla,
from = {"ª", "æ", "º", "œ"},
to = {"a", "ae", "o", "oe"}
},
},
standard_chars = {
Latn = "AaÁáÂâÃãBbCcÇçDdEeÉéÊêFfGgHhIiÍíJjLlMmNnOoÓóÔôÕõPpQqRrSsTtUuÚúVvXxZz",
Brai = c.braille,
c.punc
},
}
m["qu"] = {
"เกชัว",
5218,
"qwe",
"Latn",
}
m["rm"] = {
"รูมันช์",
13199,
"roa-rhe",
ancestors = "rm-old",
"Latn",
sort_key = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.diaer .. c.small_e},
}
m["ro"] = {
"โรมาเนีย",
7913,
"roa-eas",
"Latn, Cyrl, Cyrs",
translit = {
Cyrl = "ro-translit"
},
display_text = {
Latn = {
from = {"'", "ţ", "Ţ"},
to = {"’", "ț", "Ț"}
},
},
strip_diacritics = {
Latn = {
from = {"’", "ţ", "Ţ"},
to = {"'", "ț", "Ț"}
},
},
sort_key = {
Latn = {
remove_diacritics = c.grave .. c.acute,
from = {"ă", "â", "î", "ș", "[țţ]"},
to = {"a" .. p[1], "a" .. p[2], "i" .. p[1], "s" .. p[1], "t" .. p[1]}
},
Cyrl = {
from = {"ӂ"},
to = {"ж" .. p[1]}
},
},
-- Cyrs strip_diacritics, sort_key in [[Module:scripts/data]]; presumably not present
standard_chars = {
Latn = "AaĂăÂâBbCcDdEeFfGgHhIiÎîJjLlMmNnOoPpRrSsȘșTtȚțUuVvXxZz",
Cyrl = "АаБбВвГгДдЕеЖжӁӂЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЫыЬьЭэЮюЯя",
c.punc
},
}
m["ru"] = {
"รัสเซีย",
7737,
"zle",
"Cyrl, Brai",
ancestors = "zle-mru",
translit = {
Cyrl = "ru-translit-Thai"
},
display_text = {
Cyrl = {
from = {"'"},
to = {"’"}
},
},
strip_diacritics = {
Cyrl = {
remove_diacritics = c.grave .. c.acute .. c.diaer,
remove_exceptions = {"Ё", "ё", "Ѣ̈", "ѣ̈", "Я̈", "я̈"},
from = {"’"},
to = {"'"},
},
},
sort_key = {
Cyrl = {
remove_diacritics = c.grave .. c.acute .. c.diaer,
from = {
"і", "ѣ", "ѳ", "ѵ"
},
to = {
"и" .. p[1], "ь" .. p[1], "я" .. p[2], "я" .. p[3]
}
},
},
standard_chars = {
Cyrl = "АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя—",
Brai = c.braille,
(c.punc:gsub("'", "")) -- Exclude apostrophe.
},
}
m["rw"] = {
"รวันดา-รุนดี",
3217514,
"bnt-glb",
"Latn",
strip_diacritics = {remove_diacritics = c.acute .. c.circ .. c.macron .. c.caron},
}
m["sa"] = {
"สันสกฤต",
11059,
"inc",
"as-Beng, Bali, Beng, Bhks, Brah, Mymr, xwo-Mong, Deva, Gujr, Guru, Gran, Hani, Java, Kthi, Knda, Kawi, Khar, Khmr, Laoo, Mlym, mnc-Mong, Marc, Modi, Mong, Nand, Newa, Orya, Phag, Ranj, Saur, Shrd, Sidd, Sinh, Soyo, Lana, Takr, Taml, Tang, Telu, Thai, Tibt, Tutg, Tirh, Zanb", --and also Khom; script codes sorted by canonical name rather than code for [[MOD:sa-convert]]
translit = {
Beng = "Beng-translit",
["as-Beng"] = "Beng-translit",
-- Brah translit in [[Module:scripts/data]]
Deva = "Deva-translit",
Gujr = "Gujr-translit",
Guru = "Guru-translit",
Java = "Java-translit",
Kthi = "Kthi-translit",
Khmr = "Khmr-translit",
Knda = "Knda-translit",
Lana = "Lana-translit",
Laoo = "Laoo-translit",
Mlym = "Mlym-translit",
Modi = "Modi-translit",
-- Mong, mnc-Mong, xwo-Mong translit in [[Module:scripts/data]]
-- NOTE: Formerly used xal-translit for transliterating xwo-Mong but that only handles Cyrillic; it has
-- code to transliterate xwo-Mong but it's broken so I've replaced it with the default xwo-translit.
Mymr = "Mymr-translit",
Orya = "Orya-translit",
-- Shrd translit in [[Module:scripts/data]]
-- Sidd translit in [[Module:scripts/data]]
Sinh = "Sinh-translit",
Taml = "Taml-translit",
Telu = "Telu-translit",
--Thai = "pi-translit",
-- Tibt translit in [[Module:scripts/data]]
},
-- Mong display_text and strip_diacritics in [[Module:scripts/data]]
-- Tibt display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
strip_diacritics = {
Deva = s["sa-Deva-stripdiacritics"],
Mymr = {
remove_diacritics = c.VS01,
},
Thai = {
from = {"ึ", u(0xF700), u(0xF70F)}, -- FIXME: Not clear what's going on with the PUA characters here.
to = {"ิํ", "ฐ", "ญ"}
},
},
sort_key = {
Deva = s["sa-Deva-stripdiacritics"], -- until we have a proper Sanskrit sorting algorithm.
Lana = { -- Tai Tham
from = {"ᩔ", "ᩕ", "ᩖ", "ᩘ", "([ᨭ-ᨱ])ᩛ", "([ᨷ-ᨾ])ᩛ", "ᩤ"},
to = {"ᩈ᩠ᩈ", "᩠ᩁ", "᩠ᩃ", "ᨦ᩠", "%1᩠ᨮ", "%1᩠ᨻ", "ᩣ"},
},
--Laoo = "Laoo-sortkey",
Latn = {
from = {"ā", "ī", "ū", "ḍ", "ḷ", "ḹ", "m[" .. c.dotabove .. c.dotbelow .. "]", "ṅ", "ñ", "ṇ", "ṛ", "ṝ", "ś", "ṣ", "ṭ"},
to = {"a~", "i~", "u~", "d~", "l~", "l~~", "m~", "n~", "n~~", "n~~~", "r~", "r~~", "s~", "s~~", "t~"},
},
Mymr = {
remove_diacritics = c.VS01,
},
--Thai = "Thai-sortkey",
-- FIXME: The previous sort key which mixed all scripts removed ZWJ; I don't know which script(s) this was
-- intended for and there are no other languages which remove it in the sort key AFAIK. If it needs to be
-- removed, specify the script(s) it needs to be removed under or add handling for the "all" script that applies
-- regardless of script.
--all = {
-- remove_diacritics = c.ZWJ,
--},
},
}
m["sc"] = {
"ซาร์ดิเนีย",
33976,
"roa-sou",
"Latn",
ancestors = "sc-old",
}
m["sd"] = {
"สินธ์",
33997,
"inc-snd",
"Arab, Deva, Sind, Khoj",
translit = {
Deva = "Deva-translit",
Sind = "Sind-translit",
Arab = "sd-Arab-translit"
},
strip_diacritics = {
Arab = {
remove_diacritics = c.kashida .. c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.superalef,
from = {"ٱ"},
to = {"ا"}
},
},
}
m["se"] = {
"ซามีเหนือ",
33947,
"smi",
"Latn",
display_text = {
from = {"'"},
to = {"ˈ"}
},
strip_diacritics = {remove_diacritics = c.macron .. c.dotbelow .. "'ˈ"},
sort_key = {
from = {"á", "č", "đ", "ŋ", "š", "ŧ", "ž"},
to = {"a" .. p[1], "c" .. p[1], "d" .. p[1], "n" .. p[1], "s" .. p[1], "t" .. p[1], "z" .. p[1]}
},
standard_chars = "AaÁáBbCcČčDdĐđEeFfGgHhIiJjKkLlMmNnŊŋOoPpRrSsŠšTtŦŧUuVvZzŽž" .. c.punc,
}
m["sg"] = {
"ซังโก",
33954,
"crp",
"Latn",
ancestors = "ngb",
}
m["sh"] = {
"เซอร์โบ-โครเอเชีย",
9301,
"zls",
"Latn, Cyrl, Glag, Arab",
ietf_subtag = "hbs", -- ISO 639-3 code, since "sh" is deprecated from ISO 639-1
wikimedia_codes = "sh, bs, hr, sr",
strip_diacritics = {
Latn = {
remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve,
remove_exceptions = {"Ć", "ć", "Ś", "ś", "Ź", "ź"}
},
Cyrl = {
remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve,
remove_exceptions = {"З́", "з́", "С́", "с́"}
},
},
sort_key = {
Latn = {
remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve,
remove_exceptions = {"ć", "ś", "ź"},
from = {"č", "ć", "dž", "đ", "lj", "nj", "š", "ś", "ž", "ź"},
to = {"c" .. p[1], "c" .. p[2], "d" .. p[1], "d" .. p[2], "l" .. p[1], "n" .. p[1], "s" .. p[1], "s" .. p[2], "z" .. p[1], "z" .. p[2]}
},
Cyrl = {
remove_diacritics = c.grave .. c.acute .. c.tilde .. c.macron .. c.dgrave .. c.invbreve,
remove_exceptions = {"з́", "с́"},
from = {"ђ", "з́", "ј", "љ", "њ", "с́", "ћ", "џ"},
to = {"д" .. p[1], "з" .. p[1], "и" .. p[1], "л" .. p[1], "н" .. p[1], "с" .. p[1], "т" .. p[1], "ч" .. p[1]}
},
},
standard_chars = {
Latn = "AaBbCcČčĆćDdĐđEeFfGgHhIiJjKkLlMmNnOoPpRrSsŠšTtUuVvZzŽž",
Cyrl = "АаБбВвГгДдЂђЕеЖжЗзИиЈјКкЛлЉљМмНнЊњОоПпРрСсТтЋћУуФфХхЦцЧчЏџШш",
c.punc
},
}
m["si"] = {
"สิงหล",
13267,
"inc-ins",
"Sinh",
translit = "Sinh-translit",
override_translit = true,
}
m["sk"] = {
"สโลวัก",
9058,
"zlw",
"Latn",
ancestors = "zlw-osk",
sort_key = {remove_diacritics = c.acute .. c.circ .. c.diaer .. c.caron},
standard_chars = "AaÁáÄäBbCcČčDdĎďEeÉéFfGgHhIiÍíJjKkLlĹ弾MmNnŇňOoÓóÔôPpRrŔŕSsŠšTtŤťUuÚúVvYyÝýZzŽž" .. c.punc,
}
m["sl"] = {
"สโลวีเนีย",
9063,
"zls",
"Latn",
strip_diacritics = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.dgrave .. c.invbreve .. c.dotbelow,
remove_exceptions = {"Ć", "ć", "Ǵ", "ǵ", "Ś", "ś", "Ź", "ź"},
from = {"Ə", "ə", "Ł", "ł"},
to = {"E", "e", "L", "l"},
},
sort_key = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dotabove .. c.ringabove .. c.dgrave .. c.invbreve .. c.dotbelow .. c.ringbelow .. c.ogonek,
remove_exceptions = {"ć", "ǵ", "ś", "ź"},
from = {"ä", "č", "ć", "đ", "ə", "ë", "ǧ", "ǵ", "ï", "ł", "ö", "š", "ś", "ü", "ž", "ź"},
to = {"a" .. p[1], "c" .. p[1], "c" .. p[2], "d" .. p[1], "e", "e" .. p[1], "g" .. p[1], "g" .. p[2], "i" .. p[1], "l", "o" .. p[1], "s" .. p[1], "s" .. p[2], "u" .. p[1], "z" .. p[1], "z" .. p[2]},
},
standard_chars = "AaBbCcČčDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsŠšTtUuVvZzŽž" .. c.punc,
}
m["sm"] = {
"ซามัว",
34011,
"poz-pnp",
"Latn",
}
m["sn"] = {
"โชนา",
34004,
"bnt-sho",
"Latn",
strip_diacritics = {remove_diacritics = c.acute},
}
m["so"] = {
"โซมาลี",
13275,
"cus-som",
"Latn, Arab, Osma",
strip_diacritics = {
Latn = {remove_diacritics = c.grave .. c.acute .. c.circ}
},
}
m["sq"] = {
"แอลเบเนีย",
8748,
"sqj",
"Latn, Grek, Arab, Elba, Todr, Vith",
translit = {
Elba = "Elba-translit",
Vith = "Vith-translit",
},
-- Grek display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
strip_diacritics = {
Latn = {
remove_diacritics = c.acute .. c.circ .. c.macron,
from = {'^[ie] (%w)', '^të (%w)'}, to = {'%1', '%1'},
},
},
sort_key = {
Latn = {
remove_diacritics = c.acute .. c.circ .. c.macron .. c.tilde .. c.breve .. c.caron,
from = {'^[ie] (%w)', '^të (%w)', 'ç', 'dh', 'ë', 'gj', 'll', 'nj', 'rr', 'sh', 'th', 'xh', 'zh'},
to = {'%1', '%1', 'c'..p[1], 'd'..p[1], 'e'..p[1], 'g'..p[1], 'l'..p[1], 'n'..p[1], 'r'..p[1], 's'..p[1], 't'..p[1], 'x'..p[1], 'z'..p[1]},
}
-- TODO: Grek if the default sort key is unsuitable
},
standard_chars = {
Latn = "AaBbCcÇçDdEeËëFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvXxYyZz",
c.punc
},
}
m["ss"] = {
"สวาซี",
34014,
"bnt-ngu",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron},
}
m["st"] = {
"ซูทู",
34340,
"bnt-sts",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron},
}
m["su"] = {
"ซุนดา",
34002,
"poz-msa",
"Latn, Sund, Arab",
ancestors = "osn",
translit = {
Sund = "Sund-translit"
},
}
m["sv"] = {
"สวีเดน",
9027,
"gmq-eas",
"Latn",
ancestors = "gmq-osw-lat",
sort_key = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.macron .. c.dacute .. c.caron .. c.cedilla .. "':",
remove_exceptions = {"å"},
from = {"ø", "æ", "œ", "ß", "ꜩ", "å", "aͤ", "oͤ"},
to = {"ö", "ae", "oe", "ss", "tz", "z" .. p[1], "ä", "ö"}
},
standard_chars = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpRrSsTtUuVvXxYyÅåÄäÖö" .. c.punc,
}
m["sw"] = {
"สวาฮีลี",
7838,
"bnt-swh",
"Latn, Arab",
sort_key = {
Latn = {
from = {"ng'"},
to = {"ng" .. p[1]}
},
},
}
m["ta"] = {
"ทมิฬ",
5885,
"dra-tam",
"Taml",
ancestors = "ta-mid",
translit = "Taml-translit",
override_translit = true,
}
m["te"] = {
"เตลูกู",
8097,
"dra-tel",
"Telu",
translit = "Telu-translit",
override_translit = true,
}
m["tg"] = {
"ทาจิก",
9260,
"ira-swi",
"Cyrl, Arab, Latn",
ancestors = "fa-cls",
translit = {
Cyrl = "tg-translit"
},
override_translit = true,
strip_diacritics = {
Cyrl = s["tg-stripdiacritics"],
Latn = s["tg-stripdiacritics"],
},
sort_key = {
Cyrl = {
from = {"ғ", "ё", "ӣ", "қ", "ӯ", "ҳ", "ҷ"},
to = {"г" .. p[1], "е" .. p[1], "и" .. p[1], "к" .. p[1], "у" .. p[1], "х" .. p[1], "ч" .. p[1]}
},
},
}
m["th"] = {
"ไทย",
9217,
"tai-swe",
"Thai, Khomt, Brai",
ancestors = "th-old",
--translit = {
-- Thai = "th-translit"
--},
--sort_key = {
-- Thai = "Thai-sortkey"
--},
}
m["ti"] = {
"ทือกรึญญา",
34124,
"sem-eth",
"Ethi",
translit = "Ethi-translit",
}
m["tk"] = {
"เติร์กเมน",
9267,
"trk-ogz",
"Latn, Cyrl, Arab",
strip_diacritics = {
Latn = s["tk-stripdiacritics"],
Cyrl = s["tk-stripdiacritics"],
},
sort_key = {
Latn = {
from = {"ç", "ä", "ž", "ň", "ö", "ş", "ü", "ý"},
to = {"c" .. p[1], "e" .. p[1], "j" .. p[1], "n" .. p[1], "o" .. p[1], "s" .. p[1], "u" .. p[1], "y" .. p[1]}
},
Cyrl = {
from = {"ё", "җ", "ң", "ө", "ү", "ә"},
to = {"е" .. p[1], "ж" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "э" .. p[1]}
},
},
ancestors = "trk-eog",
}
m["tl"] = {
"ตากาล็อก",
34057,
"phi",
"Latn, Tglg",
translit = {
Tglg = "tl-translit"
},
override_translit = true,
strip_diacritics = {
Latn = {remove_diacritics = c.grave .. c.acute .. c.circ}
},
standard_chars = {
Latn = "AaBbKkDdEeGgHhIiLlMmNnOoPpRrSsTtUuWwYy",
c.punc
},
sort_key = {
Latn = "tl-sortkey",
},
}
m["tn"] = {
"สวานา",
34137,
"bnt-sts",
"Latn",
}
m["to"] = {
"ตองงา",
34094,
"poz-ton",
"Latn",
strip_diacritics = {remove_diacritics = c.acute},
sort_key = {remove_diacritics = c.macron},
}
m["tr"] = {
"ตุรกี",
256,
"trk-ogz",
"Latn",
ancestors = "ota",
dotted_dotless_i = true,
sort_key = {
from = {
-- Ignore circumflex, but account for capital Î wrongly becoming ı + circ due to dotted dotless I logic.
"ı" .. c.circ, c.circ,
"i", -- Ensure "i" comes after "ı".
"ç", "ğ", "ı", "ö", "ş", "ü"
},
to = {
"i", "",
"i" .. p[1],
"c" .. p[1], "g" .. p[1], "i", "o" .. p[1], "s" .. p[1], "u" .. p[1]
}
},
standard_chars = "AaÂâBbCcÇçDdEeFfGgĞğHhIıİiÎîJjKkLlMmNnOoÖöPpRrSsŞşTtUuÛûÜüVvYyZz" .. c.punc,
}
m["ts"] = {
"Tsonga",
34327,
"bnt-tsr",
"Latn",
}
m["tt"] = {
"ตาตาร์",
25285,
"trk-kbu",
"Cyrl, Latn, Arab",
translit = {
Cyrl = "tt-translit",
Arab = "tt-translit"
},
--override_translit = true, -- enable override until Module code can detect Russian loans such as [[аэропорт]]
dotted_dotless_i = true,
sort_key = {
Cyrl = {
from = {"ә", "ў", "ғ", "ё", "җ", "қ", "ң", "ө", "ү", "һ"},
to = {"а" .. p[1], "в" .. p[1], "г" .. p[1], "е" .. p[1], "ж" .. p[1], "к" .. p[1], "н" .. p[1], "о" .. p[1], "у" .. p[1], "х" .. p[1]}
},
Latn = {
from = {
"i", -- Ensure "i" comes after "ı".
"ä", "ə", "ç", "ğ", "ı", "ñ", "ŋ", "ö", "ɵ", "ş", "ü"
},
to = {
"i" .. p[1],
"a" .. p[1], "a" .. p[2], "c" .. p[1], "g" .. p[1], "i", "n" .. p[1], "n" .. p[2], "o" .. p[1], "o" .. p[2], "s" .. p[1], "u" .. p[1]
}
},
},
}
-- "tw" is treated as "ak", see [[WT:LT]]
m["ty"] = {
"ตาฮีตี",
34128,
"poz-pep",
"Latn",
}
m["ug"] = {
"อุยกูร์",
13263,
"trk-kar",
"Arab, Latn, Cyrl",
ancestors = "chg",
translit = {
Arab = "ug-translit",
Cyrl = "ug-translit",
},
override_translit = true,
}
m["uk"] = {
"ยูเครน",
8798,
"zle",
"Cyrl",
ancestors = "zle-muk",
translit = "uk-translit-Thai",
strip_diacritics = {remove_diacritics = c.grave .. c.acute},
sort_key = {
remove_diacritics = c.grave .. c.acute,
from = {
"ї", -- 2 chars
"ґ", "є", "і" -- 1 char
},
to = {
"и" .. p[2],
"г" .. p[1], "е" .. p[1], "и" .. p[1]
}
},
standard_chars = "АаБбВвГгДдЕеЄєЖжЗзИиІіЇїЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЬьЮюЯя" .. c.punc:gsub("'", ""), -- Exclude apostrophe.
}
m["ur"] = {
"อูรดู",
1617,
"inc-hnd",
"Aran, Hebr",
translit = {
Aran = "ur-translit"
},
strip_diacritics = {
Aran = {
-- character "ۂ" code U+06C2 to "ه" and "هٔ" (U+0647 + U+0654) to "ه"; hamzatu l-waṣli to a regular alif
from = {"هٔ", "ۂ", "ٱ"},
to = {"ہ", "ہ", "ا"},
remove_diacritics = c.fathatan .. c.dammatan .. c.kasratan .. c.fatha .. c.damma .. c.kasra .. c.shadda .. c.sukun .. c.nunghunna .. c.superalef
},
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
standard_chars = {
Aran = "ایببپتثجچحخدذرزژسشصضطظعغفقکگلࣇڷمنݨوؤہھئٹڈڑآے",
c.punc,
},
}
m["uz"] = {
"อุซเบก",
9264,
"trk-kar",
"Latn, Cyrl, Arab",
ancestors = "chg",
translit = {
Cyrl = "uz-translit"
},
sort_key = {
Latn = {
from = {"oʻ", "gʻ", "sh", "ch", "ng"},
to = {"z" .. p[1], "z" .. p[2], "z" .. p[3], "z" .. p[4], "z" .. p[5]}
},
Cyrl = {
from = {"ё", "ў", "қ", "ғ", "ҳ"},
to = {"е" .. p[1], "я" .. p[1], "я" .. p[2], "я" .. p[3], "я" .. p[4]}
},
},
strip_diacritics = {
Arab = "ar-stripdiacritics",
},
}
m["ve"] = {
"เวนดา",
32704,
"bnt-bso",
"Latn",
}
m["vi"] = {
"เวียดนาม",
9199,
"mkh-vie",
"Latn, Hani",
ancestors = "mkh-mvi",
--translit = {Latn = "vi-translit"}, -- already handled in Module:headword & Module:links
sort_key = {
Latn = "vi-sortkey",
Hani = "Hani-sortkey",
},
}
m["vo"] = {
"โวลาปุก",
36986,
"art",
"Latn",
}
m["wa"] = {
"วัลลูน",
34219,
"roa-oil",
"Latn",
sort_key = s["roa-oil-sortkey"],
}
m["wo"] = {
"โวลอฟ",
34257,
"alv-fwo",
"Latn, Arab, Gara",
}
m["xh"] = {
"โคซา",
13218,
"bnt-ngu",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron},
}
m["yi"] = {
"ยิดดิช",
8641,
"gmw-hgm",
"Hebr, Latn",
ancestors = "gmh",
translit = {
Hebr = "yi-translit",
},
-- Hebr display_text, strip_diacritics, sort_key in [[Module:scripts/data]]
}
m["yo"] = {
"โยรูบา",
34311,
"alv-yor",
"Latn, Arab",
strip_diacritics = {
Latn = {remove_diacritics = c.grave .. c.acute .. c.macron}
},
sort_key = {
Latn = {
from = {"ẹ", "ɛ", "gb", "ị", "kp", "ọ", "ɔ", "ṣ", "sh", "ụ"},
to = {"e" .. p[1], "e" .. p[1], "g" .. p[1], "i" .. p[1], "k" .. p[1], "o" .. p[1], "o" .. p[1], "s" .. p[1], "s" .. p[1], "u" .. p[1]}
},
},
}
m["za"] = {
"จ้วง",
13216,
"tai",
"Latn, Hani",
sort_key = {
Latn = "za-sortkey",
Hani = "Hani-sortkey",
},
}
m["zh"] = {
"จีน",
7850,
"zhx",
"Hants, Latn, Bopo, Nshu, Brai",
ancestors = "ltc",
generate_alternants = "zh-generatealternants",
translit = {
Hani = "zh-translit",
Bopo = "zh-translit",
},
sort_key = {
Hani = "Hani-sortkey"
},
}
m["zu"] = {
"ซูลู",
10179,
"bnt-ngu",
"Latn",
strip_diacritics = {remove_diacritics = c.grave .. c.acute .. c.circ .. c.macron .. c.caron},
}
return require("Module:languages").finalizeData(m, "language")
iw6mjgiad0xdxnx6984eotmefyg2qpx
มอดูล:en-headword
828
37360
5775367
5723289
2026-10-15T08:25:46Z
Octahedron80
267
5775367
Scribunto
text/plain
local export = {}
local pos_functions = {}
--[==[
Author from 2020 on: mostly Benwing2, with significant contributions from Theknightwho. Based on a prior version by Rua
(by now mostly rewritten), with contributions from Erutuon and others (see history for full attribution).
]==]
local force_cat = false -- for testing; if true, categories appear in non-mainspace pages
local require = require
local require_when_needed = require("Module:require when needed")
local en_utilities_module = "Module:en-utilities"
local headword_utilities_module = "Module:headword utilities"
local headword_module = "Module:headword"
local inflection_utilities_module = "Module:inflection utilities"
local parse_utilities_module = "Module:parse utilities"
local JSON_module = "Module:JSON"
local labels_module = "Module:labels"
local links_module = "Module:links"
local parameters_module = "Module:parameters"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local utilities_module = "Module:utilities"
local yesno_module = "Module:yesno"
local iut = require_when_needed(inflection_utilities_module)
local put = require_when_needed(parse_utilities_module)
local m_headword_utilities = require_when_needed(headword_utilities_module)
local add_links_to_multiword_term = require_when_needed(headword_utilities_module, "add_links_to_multiword_term")
local add_suffix = require_when_needed(en_utilities_module, "add_suffix")
local apply_link_modifiers = require_when_needed(headword_utilities_module, "apply_link_modifiers")
local concat = table.concat
local deepEquals = require_when_needed(table_module, "deepEquals")
local dump = mw.dumpObject
local format_categories = require_when_needed(utilities_module, "format_categories")
local full_headword = require_when_needed(headword_module, "full_headword")
local get_label_info = require_when_needed(labels_module, "get_label_info")
local get_link_page = require_when_needed(links_module, "get_link_page")
local glossary_link = require_when_needed(headword_utilities_module, "glossary_link")
local insert = table.insert
local insertIfNot = require_when_needed(table_module, "insertIfNot")
local ipairs = ipairs
local is_regular_plural = require_when_needed(en_utilities_module, "is_regular_plural")
local list_to_set = require_when_needed(table_module, "listToSet")
local pairs = pairs
local process_params = require_when_needed(parameters_module, "process")
local remove = table.remove
local remove_links = require_when_needed(links_module, "remove_links")
local replacement_escape = require_when_needed(string_utilities_module, "replacement_escape")
local shallowCopy = require_when_needed(table_module, "shallowCopy")
local singularize = require_when_needed(en_utilities_module, "singularize")
local split = require_when_needed(string_utilities_module, "split")
local toJSON = require_when_needed(JSON_module, "toJSON")
local toNFD = mw.ustring.toNFD
local type = type
local ulen = require_when_needed(string_utilities_module, "len")
local ulower = require_when_needed(string_utilities_module, "lower")
local umatch = require_when_needed(string_utilities_module, "match")
local u = require_when_needed(string_utilities_module, "char")
local ugsub = require_when_needed(string_utilities_module, "gsub")
local lang = require("Module:languages").getByCode("en")
local langname = --[[lang:getCanonicalName()]] lang:getCategoryName()
local list_param = {list = true, disallow_holes = true}
local list_allow_holes = {list = true, allow_holes = true}
local boolean_param = {type = "boolean"}
local function ine(val)
if val == "" then return nil else return val end
end
local function track(page)
require("Module:debug/track")("en-headword/" .. page)
return true
end
------------------------------------------- UTILITY FUNCTIONS ------------------------------------------
-- Parse and return an inflection not requiring additional processing. The raw arguments come from `args[field]`, which
-- is parsed for inline modifiers.
local function parse_inflection(args, field, is_head)
local argfield = field
if type(argfield) == "table" then
argfield = argfield[1]
end
return m_headword_utilities.parse_term_list_with_modifiers {
paramname = field,
forms = args[argfield],
splitchar = ",",
is_head = is_head,
}
end
-- Insert the parsed inflections in `terms` (as parsed by `parse_inflection`) into `data.inflections`, with label
-- `label` and optional accelerator spec `accel`.
local function insert_inflection(data, terms, label, accel, no_label)
for _, termobj in ipairs(terms) do
m_headword_utilities.remove_termobj_field_modifiers(termobj)
end
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
no_label = no_label,
accel = accel and {form = accel} or nil,
}
end
-- Insert a fixed label `label` into the inflections for `data`. If `originating_term` is supplied, copy the decorations
-- from it into the fixed label.
local function insert_fixed_inflection(data, label, originating_term)
m_headword_utilities.insert_fixed_inflection {
headdata = data,
originating_term = originating_term,
label = label,
}
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments come
-- from `args[field]`, which is parsed for inline modifiers. `label` is the label that the inflections are given;
-- `accel` is the accelerator form, or nil.
local function parse_and_insert_inflection(data, args, field, label, accel)
m_headword_utilities.parse_and_insert_inflection {
headdata = data,
forms = args[field],
paramname = field,
splitchar = ",",
label = label,
accel = accel and {form = accel} or nil,
}
end
-- These functions are used directly in the <> format as well as in the utility functions #2 below.
local function compute_double_last_cons_stem(term)
local last_cons = term:match("([bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])$")
if not last_cons then
error("Verb stem '" .. term .. "' must end in a consonant to use ++")
end
return term .. last_cons
end
local function compute_plusplus_s_form(term, default_s_form)
if term:find("[szx]$") then
-- regas -> regasses, derez -> derezzes
return compute_double_last_cons_stem(term) .. "es"
else
return default_s_form
end
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local iparams = {
[1] = true,
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local parargs = frame:getParent().args
local poscat = iargs[1]
local pos_in_1 = not poscat
if pos_in_1 then
poscat = ine(parargs[1]) or
mw.title.getCurrentTitle().fullText == "แม่แบบ:en-head" and "คำอุทาน" or
error("Part of speech must be specified in 1=")
poscat_th = require("Module:th-utilities").th_pos(poscat) --th
poscat_th = require(headword_module).canonicalize_pos(poscat_th) --th_pos_to_form is already there
else
poscat_th = require("Module:th-utilities").th_pos(poscat) --th; initiation is needed
end
local indexing_poscat = pos_in_1 and "head" or poscat_th
local params = {
["head"] = list_param,
["id"] = true,
["json"] = boolean_param,
["sort"] = true,
["splithyph"] = boolean_param,
["nosplithyph"] = boolean_param,
["hyphspace"] = boolean_param,
["nolink"] = boolean_param,
["nolinkhead"] = {type = "boolean_param", alias_of = "nolink"},
["suffix"] = boolean_param,
["nosuffix"] = boolean_param,
["nomultiwordcat"] = boolean_param,
["abbr"] = list_param,
["the"] = true,
["def"] = {alias_of = "the"},
["pagename"] = true, -- for testing
}
if pos_in_1 then
params[1] = {required = true} -- required but ignored as already processed above
end
local pos_data = pos_functions[indexing_poscat]
local pos_func
if pos_data then
local pos_params = pos_data.params
if pos_params then
for key, val in pairs(pos_params) do
params[key] = val
end
end
pos_func = pos_data.func
end
local args = process_params(parargs, params)
-- Account for unsupported titles, e.g. 'C|N>K' instead of 'Unsupported titles/C through N to K'.
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local user_specified_heads = parse_inflection(args, "head", "is_head")
local heads = user_specified_heads
local autohead
if args.nolink or not pagename:find("[ '%-]") then
autohead = pagename
else
local en_no_split_apostrophe_words = list_to_set {
"one's",
"someone's",
"he's",
"she's",
"it's",
}
local en_include_hyphen_prefixes = list_to_set {
-- We don't include things that are also words even though they are often (perhaps mostly) prefixes, e.g.
-- "be", "counter", "cross", "extra", "half", "mid", "over", "pan", "under".
"acro",
"acousto",
"Afro",
"agro",
"anarcho",
"angio",
"Anglo",
"ante",
"anti",
"arch",
"auto",
"bi",
"bio",
"cis",
"co",
"cryo",
"crypto",
"de",
"demi",
"eco",
"electro",
"Euro",
"ex",
"Greco",
"hemi",
"hydro",
"hyper",
"hypo",
"infra",
"Indo",
"inter",
"intra",
"Judeo",
"macro",
"meta",
"micro",
"mini",
"multi",
"neo",
"neuro",
"non",
"para",
"peri",
"post",
"pre",
"pro",
"proto",
"pseudo",
"re",
"semi",
"sub",
"super",
"trans",
"un",
"vice",
}
local function is_english(term)
local title = mw.title.new(term)
if title and title.exists then
local content = title:getContent()
if content and content:find("== ?ภาษาอังกฤษ ?==\n") then
return true
end
end
return false
end
local function en_split_hyphen_when_space(word)
if not word:find("-", nil, true) then
return nil
end
if args.hyphspace then
return "[[" .. word:gsub("%-+", " ") .. "|" .. word .. "]]"
end
if args.nosplithyph then
return "[[" .. word .. "]]"
end
if not args.splithyph then
local space_word = word:gsub("%-+", " ")
if is_english(space_word) then
return "[[" .. space_word .. "|" .. word .. "]]"
end
if is_english(word) then
return "[[" .. word .. "]]"
end
end
return nil
end
local function en_split_apostrophe(word)
local base = word:match("^(.*)'s$")
if base then
return "[[" .. base .. "]][[-'s|'s]]"
end
-- Only treat final apostrophe as possessive if preceded by something that looks like a plural ending in /z/.
-- In particular we don't want to do it for words like [[truckin']].
base = word:match("^(.*[sxz])'$")
if base then
if base:find("s$") then
local sg = singularize(base)
if is_english(sg) then
return "[[" .. sg .. "|" .. base .. "]][[-'|']]"
end
end
return "[[" .. base .. "]][[-'|']]"
end
return "[[" .. word .. "]]"
end
autohead = add_links_to_multiword_term(pagename, {
split_hyphen_when_space = en_split_hyphen_when_space,
split_apostrophe = en_split_apostrophe,
no_split_apostrophe_words = en_no_split_apostrophe_words,
include_hyphen_prefixes = en_include_hyphen_prefixes,
})
end
if not heads[1] then
heads = {{term = autohead}}
else
for _, headobj in ipairs(heads) do
local head = headobj.term
if head:find("^~") then
head = apply_link_modifiers(autohead, head:sub(2), lang)
headobj.term = head
elseif head:find("^[!?]$") then
-- If explicit head= just consists of ! or ?, add it to the end of the default head.
headobj.term = autohead .. head
end
if head == autohead then
track("redundant-head")
end
end
end
-- handle the=/def=
if args.the == "~" then
local newheads = {}
for _, headobj in ipairs(heads) do
local barehead = shallowCopy(headobj)
insert(newheads, barehead)
headobj.term = "the " .. headobj.term
insert(newheads, headobj)
end
heads = newheads
elseif args.the then
local the = require(yesno_module)(args.the)
if the then
for _, headobj in ipairs(heads) do
headobj.term = "the " .. headobj.term
end
end
end
local data = {
lang = lang,
pos_category = poscat_th,
categories = {},
heads = heads,
user_specified_heads = user_specified_heads,
-- We use our own splitting algorithm so the redundant head cat will be inaccurate.
no_redundant_head_cat = true,
inflections = {},
nomultiwordcat = args.nomultiwordcat,
sort_key = args.sort,
pagename = pagename,
id = args.id,
force_cat_output = force_cat,
}
local function inscat(cat)
--insert(data.categories, langname .. " " .. cat)
insert(data.categories, require("Module:th-utilities").th_categorize(cat, langname))
end
local is_suffix = false
if args.suffix or not args.nosuffix and pagename:find("^%-") and not pagename:find("^%-%-") and poscat_th ~= "รูปปัจจัย" then
is_suffix = true
data.pos_category = "ปัจจัย"
local singular_poscat = --[[singularize(poscat)]] poscat_th
inscat("ปัจจัยสร้าง" .. singular_poscat)
insert(data.inflections, {label = "ปัจจัยสร้าง" .. singular_poscat})
end
if pos_func then
pos_func(args, data, is_suffix)
end
local extra_categories = {}
if pagename:find("[Qq]") then
-- Check for q not followed by u. We want to exclude things like [[13q deletion syndrome]] and [[BFOQ]] that
-- don't have a lowercase letter on either side, as well as things like [[& seq.]] and [[acq.]] that are
-- abbreviations for words containing a following u.
--
-- Approximate range of combining diacritics; we want to remove them so the checks below for
-- a lowercase letter next to the q aren't tripped up by diacritics on the letter.
local u300 = u(0x0300)
local u36F = u(0x036F)
local pagename_no_diacritics = ugsub(toNFD(pagename), "[" .. u300 .. "-" .. u36F .. "]", "")
if pagename_no_diacritics:find("[Qq][a-tv-z]") or pagename_no_diacritics:find("[a-z]q[^u.]") or
pagename_no_diacritics:find("[a-z]q$") then
inscat("ศัพท์ที่มี Q ไม่ตามด้วย U")
end
end
-- toNFD performs decomposition, so letters that decompose to an ASCII
-- vowel and a diacritic, such as é, are counted as vowels and do not do not
-- need to be included in the pattern.
if not umatch(ulower(toNFD(pagename)), "[aeiouyæœøəªºαεηιουω]") then
inscat("ศัพท์ที่ไม่มีสระ")
end
if pagename:find("yre$") then
inscat("ศัพท์ที่ลงท้ายด้วย -yre")
end
if not pagename:find(" ") and ulen(pagename) >= 25 then
insert(extra_categories, "ศัพท์" .. langname .. "ที่มีขนาดยาว")
end
if pagename:find("^[^aeiou ]*a[^aeiou ]*e[^aeiou ]*i[^aeiou ]*o[^aeiou ]*u[^aeiou ]*$") then
inscat("ศัพท์ที่ใช้สระทั้งหมดตามลำดับ")
end
parse_and_insert_inflection(data, args, "abbr", "คำย่อ")
if args.json then
return toJSON(data)
end
return full_headword(data)
.. (extra_categories[1]
and format_categories(extra_categories, lang, args.sort)
or "")
end
local function make_default_comparative(word)
if word == "good" or word == "well" then
return {"better"}
elseif word == "bad" or word == "badly" then
return {"worse"}
elseif word == "far" then
return {"further", "farther"}
else
return {add_suffix(word, "r")}
end
end
local function make_default_superlative(word)
if word == "good" or word == "well" then
return {"best"}
elseif word == "bad" or word == "badly" then
return {"worst"}
elseif word == "far" then
return {"furthest", "farthest"}
else
return {add_suffix(word, "st.superlative")}
end
end
-- This function does the common work between adjectives and adverbs.
local function process_comparative_args(data, args, plpos)
local pagename = data.pagename
local comps = parse_inflection(args, 1)
local sups = parse_inflection(args, "sup")
local outcomps, outsups
if args.componly then
if comps[1] then
error("Can't specify comparatives of comparative-only " .. plpos)
end
insert(data.inflections, {label = glossary_link("ขั้นกว่า") .. "เท่านั้น"})
insert(data.categories, plpos .. "ขั้นกว่าเท่านั้น" .. langname)
-- Set to empty list so we don't get any comparatives output, but process superlatives if specified.
outcomps = {}
if not sups[1] then
-- Set to empty list so we don't get any superlatives output unless explicitly given.
outsups = {}
end
elseif args.suponly then
if comps[1] or sups[1] then
error("Can't specify comparatives or superlatives of or superlative-only " .. plpos)
end
insert(data.inflections, {label = glossary_link("ขั้นสุด") .. "เท่านั้น"})
insert(data.categories, plpos .. "ขั้นสุดเท่านั้น" .. langname)
return
end
-- If the first parameter is ?, then don't show anything, just return.
if comps[1] and comps[1].term == "?" then
if comps[2] then
error("Can't specify additional comparatives along with '?'")
end
if sups[1] then
error("Can't specify superlatives along with '?' for the comparative")
end
return
end
if comps[1] and comps[1].term == "-" then
local hyphencomp = remove(comps, 1) -- Remove the "-" but retain for decorations.
-- Not (generally) comparable; may occasionally have a comparative
if comps[1] then
insert_fixed_inflection(data, "โดยทั่วไป<<เปรียบเทียบไม่ได้>>", hyphencomp)
elseif not sups[1] then
insert_fixed_inflection(data, "<<เปรียบเทียบไม่ได้>>", hyphencomp)
insert(data.categories, plpos .. "เปรียบเทียบไม่ได้" .. langname)
return
else
-- No comparative, but a superlative. insert_inflection() will correctly generate 'no comparative' if we
-- pass in "-" as the value.
outcomps = {hyphencomp}
end
elseif not comps[1] then
comps = {{term = "more"}}
end
if not outcomps then -- not if we set `outcomps` to "-" above or processed a comparative-only term
outcomps = {}
-- Go over each parameter given and create a comparative and superlative form.
for _, compobj in ipairs(comps) do
local comp = compobj.term
if comp == "-" then
error("Comparative of '-' only allowed as first comparative")
end
if comp == "+" then
comp = "+more"
elseif comp == "more" and pagename ~= "many" and pagename ~= "much" then
comp = "+more"
elseif comp == "further" and pagename ~= "far" then
comp = "+further"
elseif comp == "better" and pagename ~= "good" and pagename ~= "well" then
comp = "+better"
elseif comp:find("~") then
comp = comp:gsub("~", replacement_escape(pagename))
end
compobj.origterm = comp
if comp == "+more" then
comp = "more [[" .. pagename .. "]]"
elseif comp == "+further" then
comp = {"further [[" .. pagename .. "]]", "farther [[" .. pagename .. "]]"}
elseif comp == "+better" then
comp = "better [[" .. pagename .. "]]"
elseif comp == "er" then
-- Add -er.
comp = add_suffix(pagename, "r")
elseif comp == "ier" then
if pagename:sub(-1) ~= "y" then
error("Can't specify 'ier' comparative unless the term ends with 'y': " .. pagename)
end
comp = pagename:gsub("e?y$", "ier")
elseif comp:find("^%+") then
local special = m_headword_utilities.get_special_indicator(comp, "noerror")
if special then
comp = m_headword_utilities.handle_multiword(pagename, special, make_default_comparative)
end
end
if type(comp) == "table" and not comp[2] then
comp = comp[1]
end
if type(comp) == "table" then
for i = 1, #comp - 1 do
local outobj = shallowCopy(compobj)
outobj.term = comp[i]
insert(outcomps, outobj)
end
compobj.term = comp[#comp]
insert(outcomps, compobj)
else
compobj.term = comp
insert(outcomps, compobj)
end
end
end
if sups[1] and sups[1].term == "-" then
if sups[2] then
error("Can't specify '-' as superlative followed by further values")
end
-- No superlative. insert_inflection() will correctly generate 'no superlative' if we pass in "-" as the value.
outsups = sups
else
if not sups[1] then
sups = {{term = "+"}}
end
end
-- `outsups` will be set if we set `outsups` to "-" above or processed a comparative-only term without superlatives.
if not outsups then
outsups = {}
local function process_sup(sup, special, supobj, compobj)
if special then
sup = m_headword_utilities.handle_multiword(pagename, special, make_default_superlative)
elseif sup == "-" or sup == "+" then
error(("Internal error: Superlative value of '%s' should have been handled earlier"):format(sup))
elseif sup == "+most" then
sup = "most [[" .. pagename .. "]]"
elseif sup == "+furthest" then
sup = {"furthest [[" .. pagename .. "]]", "farthest [[" .. pagename .. "]]"}
elseif sup == "+best" then
sup = "best [[" .. pagename .. "]]"
elseif sup == "est" then
-- Add -est.
sup = add_suffix(pagename, "st.superlative")
elseif sup == "iest" then
if pagename:sub(-1) ~= "y" then
error("Can't specify 'iest' superlative unless the term ends with 'y': " .. pagename)
end
sup = pagename:gsub("e?y$", "iest")
end
if type(sup) == "table" and not sup[2] then
sup = sup[1]
end
if compobj then
supobj = shallowCopy(supobj)
supobj = m_headword_utilities.combine_termobj_decorations(supobj, compobj)
end
if type(sup) == "table" then
for i = 1, #sup - 1 do
local outobj = shallowCopy(supobj)
outobj.term = sup[i]
insert(outsups, outobj)
end
supobj.term = sup[#sup]
insert(outsups, supobj)
else
supobj.term = sup
insert(outsups, supobj)
end
end
for _, supobj in ipairs(sups) do
local sup = supobj.term
if sup == "-" then
error("Superlative of '-' only allowed as first superlative")
end
if sup == "+" then
if not comps[1] then
error("Superlative of '+' can't be specified when there are no comparatives")
end
for _, compobj in ipairs(comps) do
local comp = compobj.origterm
local special
if comp == "+more" then
sup = "+most"
elseif comp == "+further" then
sup = "+furthest"
elseif comp == "+better" then
sup = "+best"
elseif comp == "er" then
sup = "est"
elseif comp == "ier" then
sup = "iest"
else
if comp:find("^%+") then
special = m_headword_utilities.get_special_indicator(comp, "noerror")
end
if not special then
-- If the full comparative was given, then derive the superlative by replacing -er with
-- -est.
if comp:sub(-2) == "er" then
sup = comp:sub(1, -3) .. "est"
else
error(("The superlative cannot be derived automatically from comparative '%s' because it doesn't end in -er"):format(comp))
end
end
end
process_sup(sup, special, supobj, compobj)
end
else
local special = m_headword_utilities.get_special_indicator(sup, "noerror")
-- Do some work here rather than in process_sup() so we don't end up double-processing a term with a '~'
-- in it or a term that happens to be 'most' or similar after substitution of ~ in the comparative.
if not special then
if sup == "most" and pagename ~= "many" and pagename ~= "much" then
sup = "+most"
elseif sup == "furthest" and pagename ~= "far" then
sup = "+furthest"
elseif sup == "best" and pagename ~= "good" and pagename ~= "well" then
sup = "+best"
elseif sup:find("~") then
sup = sup:gsub("~", replacement_escape(pagename))
end
end
process_sup(sup, special, supobj)
end
end
end
insert_inflection(data, outcomps, "<<ขั้นกว่า>>", "ขั้นกว่า")
insert_inflection(data, outsups, "<<ขั้นสุด>>", "ขั้นสุด")
end
pos_functions["คำคุณศัพท์"] = {
params = {
[1] = list_param,
["comp_qual"] = {list = "comp\1_qual", allow_holes = true, replaced_by = false,
instead = "use <l:...> or <q:...> inline modifier on the comparative value",
},
["sup"] = list_param,
["sup_qual"] = {list = "sup\1_qual", allow_holes = true, replaced_by = false,
instead = "use <l:...> or <q:...> inline modifier on the superlative value",
},
["componly"] = boolean_param,
["suponly"] = boolean_param,
},
func = function(args, data)
-- Process the comparatives and superlatives.
process_comparative_args(data, args, "คำคุณศัพท์")
end,
}
pos_functions["คำกริยาวิเศษณ์"] = {
params = {
[1] = list_param,
["comp_qual"] = {list = "comp\1_qual", allow_holes = true, replaced_by = false,
instead = "use <l:...> or <q:...> inline modifier on the comparative value",
},
["sup"] = list_param,
["sup_qual"] = {list = "sup\1_qual", allow_holes = true, replaced_by = false,
instead = "use <l:...> or <q:...> inline modifier on the superlative value",
},
["componly"] = boolean_param,
["suponly"] = boolean_param,
},
func = function(args, data)
-- Process the comparatives and superlatives.
process_comparative_args(data, args, "คำกริยาวิเศษณ์")
end,
}
local function escape(str)
return (str:gsub("\\([:#])", "\\\\%1")
:gsub("[:#]", "\\%0"))
end
local function canonicalize_plural(pl, pagename, pos)
if pl == "+" then
return escape(add_suffix(pagename, "s.plural", pos))
elseif pl == "++" then
return escape(compute_plusplus_s_form(pagename, add_suffix(pagename, "s.plural", pos)))
elseif pl == "*" then
return escape(pagename)
elseif pl == "ies" then
if pagename:sub(-1) == "y" then
return escape(pagename:gsub("e?y$", pl))
end
error("Can't specify 'ies' plural unless the term ends with 'y'.")
elseif pl == "s" or pl == "es" or pl == "'s" then
return escape(pagename .. pl)
end
end
local function do_nouns(args, data, pos)
local pagename = data.pagename
pos = pos or "คำนาม"
local plurals = parse_inflection(args, 1)
local function insert_plurale_tantum_inflections(is_plural_only, originating_label)
if args.sg[1] then
insert_fixed_inflection(data, "พหูพจน์ปกติ", originating_label)
parse_and_insert_inflection(data, args, "sg", "เอกพจน์")
elseif is_plural_only then
insert_fixed_inflection(data, "พหูพจน์เท่านั้น", originating_label)
end
if args.attr[1] then
parse_and_insert_inflection(data, args, "attr", "ตัวบอกคุณลักษณะ")
end
end
local function first_pl_term()
return plurals[1] and plurals[1].term or nil
end
if first_pl_term() == "p" then
-- plurale tantum
if plurals[2] then
error("With plurale tantum noun, can't specify more than one plural")
end
data.genders = {"p"} -- this should auto-insert the correct 'pluralia tantum' category
insert_plurale_tantum_inflections("พหูพจน์เท่านั้น", plurals[1])
return
end
local function inscat(cat)
--insert(data.categories, langname .. " " .. cat)
insert(data.categories, require("Module:th-utilities").th_categorize(cat, langname))
end
local need_default_plural = pos == "คำนาม"
if first_pl_term() == "sp" then
-- construed as singular or plural
sp = remove(plurals, 1) -- Remove the "sp" but retain it for its decorations.
inscat("คำนาม★ที่อนุมานว่าเป็นเอกพจน์หรือพหูพจน์")
data.genders = {"s", "p"} -- this should auto-insert the correct 'pluralia tantum' category
insert_plurale_tantum_inflections(nil, sp)
need_default_plural = false
elseif first_pl_term() == "-" then
-- Uncountable noun; may occasionally have a plural
local hyphpl = remove(plurals, 1) -- Remove the "-" but retain for decorations.
inscat("คำนามนับไม่ได้")
-- If plural forms were given explicitly, then show "usually"
if plurals[1] then
insert_fixed_inflection(data, "โดยปกติ<<นับไม่ได้>>", hyphpl)
else
insert_fixed_inflection(data, "<<นับไม่ได้>>", hyphpl)
end
need_default_plural = false
elseif first_pl_term() == "#" then
-- Usually countable (e.g., "grilled cheese")
local hashpl = remove(plurals, 1) -- Remove the "#" but retain for qualifiers, labels, references
insert_fixed_inflection(data, "โดยปกติ<<นับได้>>", hashpl)
inscat("คำนามนับไม่ได้")
inscat("คำนามนับได้")
-- If no plural was given, add a default one now
if not plurals[1] then
plurals[1] = {term = escape(add_suffix(pagename, "s.plural", pos))}
end
elseif first_pl_term() == "~" then
-- Mixed countable/uncountable noun, always has a plural
local tildepl = remove(plurals, 1) -- Remove the "~" but retain for decorations.
insert_fixed_inflection(data, "<<นับได้>>และ<<นับไม่ได้>>", tildepl)
inscat("คำนามนับไม่ได้")
inscat("คำนามนับได้")
-- If no plural was given, add a default one now
if not plurals[1] then
plurals[1] = {term = escape(add_suffix(pagename, "s.plural", pos))}
end
end
-- Plural is unknown
if first_pl_term() == "?" then
local questionpl = remove(plurals, 1) -- Remove the "?" but retain for decorations.
-- Not desired; see [[Wiktionary:Tea_room/2021/August#"Plural unknown or uncertain"]]
-- insert_fixed_inflection(data, "plural unknown or uncertain", questionpl)
inscat("nouns with unknown or uncertain plurals")
if plurals[1] then
error("Can't specify explicit plurals along with '?' for unknown/uncertain plural")
end
return
end
-- Plural is not attested
if first_pl_term() == "!" then
local exclampl = remove(plurals, 1) -- Remove the "!" but retain for decorations.
insert_fixed_inflection(data, "plural not attested", exclampl)
inscat("nouns with unattested plurals")
if plurals[1] then
error("Can't specify explicit plurals along with '!' for unattested plural")
end
return
end
-- If no plural was given, maybe add a default one, otherwise (when "-" was given or proper noun) return.
if not plurals[1] then
if not need_default_plural then
inscat("คำนามนับไม่ได้")
return
end
plurals[1] = {term = escape(add_suffix(pagename, "s.plural", pos))}
end
-- There are plural forms to show, so show them.
inscat("คำนามนับได้")
local irregular, indeclinable
for i, pl in ipairs(plurals) do
local canon_pl = canonicalize_plural(pl.term, pagename, pos)
if canon_pl then
pl.term = canon_pl
end
local pl_term = get_link_page(pl.term, lang)
if not (pagename:find(" ") or is_regular_plural(pl_term, pagename)) then
irregular = true
if pl_term == pagename then
indeclinable = true
end
end
end
if irregular then
inscat("คำนาม★ที่มีพหูพจน์ไม่ปรกติ")
end
if indeclinable then
inscat("คำนามผันรูปไม่ได้")
end
insert_inflection(data, plurals, "พหูพจน์", "p")
end
-- Return the parameters to be used for nouns and proper nouns. Currently the same.
local noun_params = {
[1] = list_param,
["pl\1qual"] = {list = true, allow_holes = true, replaced_by = false,
instead = "use <l:...> or <q:...> inline modifier on the plural",
},
-- The following four only used for pluralia tantum (1=p)
["sg"] = list_param,
["attr"] = list_param,
}
pos_functions["คำนาม"] = {
params = noun_params,
func = do_nouns,
}
pos_functions["คำวิสามานยนาม"] = {
params = noun_params,
func = function(args, data)
return do_nouns(args, data, "คำวิสามานยนาม")
end,
}
local function base_default_verb_forms(verb)
return escape(add_suffix(verb, "s.verb")), escape(add_suffix(verb, "ing")), escape(add_suffix(verb, "d"))
end
local function default_verb_forms(verb)
local full_s_form, full_ing_form, full_ed_form = base_default_verb_forms(verb)
if verb:find(" ") then
local first, rest = verb:match("^(.-)( .*)$")
local first_s_form, first_ing_form, first_ed_form = base_default_verb_forms(first)
return full_s_form, full_ing_form, full_ed_form, first_s_form .. rest, first_ing_form .. rest,
first_ed_form .. rest, first, rest
else
return full_s_form, full_ing_form, full_ed_form, nil, nil, nil, nil, nil
end
end
local function compute_double_last_cons_stem_of_split_verb(verb, ending)
local first, rest = verb:match("^(.-)( .*)$")
if not first then
error("Verb '" .. verb .. "' must have a space in it to use **")
end
local last_cons = first:match("([bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])$")
if not last_cons then
error("First word '" .. first .. "' must end in a consonant to use **")
end
return first .. last_cons .. ending .. rest
end
local function check_non_nil_star_form(form, pagename)
if form == nil then
error("Verb '" .. pagename .. "' must have a space in it to use *, **, *l, *! or *'")
end
return form
end
local function sub_tilde(form, pagename)
if not form then
return nil
end
if form:find("~") then
form = form:gsub("~", replacement_escape(pagename))
end
return form
end
local deprecated_qual_replaced_by_inline_modifier = {
list = true, allow_holes = true, replaced_by = false,
instead = "use an inline modifier <q:...> or <l:...> on the value"
}
pos_functions["คำกริยา"] = {
params = {
[1] = {list = "pres_3sg", disallow_holes = true},
["pres_3sg\1_qual"] = deprecated_qual_replaced_by_inline_modifier,
[2] = {list = "pres_ptc", disallow_holes = true},
["pres_ptc\1_qual"] = deprecated_qual_replaced_by_inline_modifier,
[3] = {list = "past", disallow_holes = true},
["past\1_qual"] = deprecated_qual_replaced_by_inline_modifier,
[4] = {list = "past_ptc", allow_holes = true},
["past_ptc\1_qual"] = deprecated_qual_replaced_by_inline_modifier,
["noautolinkverb"] = boolean_param,
["angle_bracket"] = boolean_param,
},
func = function(args, data)
-- Get parameters
local par1s
local par2s = parse_inflection(args, {2, "pres_ptc"})
local par3s = parse_inflection(args, {3, "past"})
local par4s = parse_inflection(args, {4, "past_ptc"})
local pres_3sgs, pres_ptcs, pasts, past_ptcs
local pagename = data.pagename
------------------------------------------- UTILITY FUNCTIONS #2 ------------------------------------------
-- These functions are used in both in the separate-parameter format and in the override params such as past_ptc2=.
local full_default_s, full_default_ing, full_default_ed, split_default_s, split_default_ing, split_default_ed
local lemma
local function set_lemma_and_default_forms(the_lemma)
lemma = the_lemma
full_default_s, full_default_ing, full_default_ed, split_default_s, split_default_ing, split_default_ed,
lemma_first, lemma_rest = default_verb_forms(the_lemma)
end
local function canonicalize_s_form(form)
if form == "+" then
error("Internal error: Should not see '+' here")
elseif form == "^" then
return full_default_s
elseif form == "*" then
return check_non_nil_star_form(split_default_s, lemma)
elseif form == "++" then
return compute_plusplus_s_form(lemma, full_default_s)
elseif form == "**" then
if lemma:find("^[^ ]*[szx] ") then
return compute_double_last_cons_stem_of_split_verb(lemma, "es")
else
return check_non_nil_star_form(split_default_s, lemma)
end
elseif form == "+!" then
return lemma .. "s"
elseif form == "*!" then
return check_non_nil_star_form(lemma_first) .. "s" .. lemma_rest
elseif form == "+'" then
return lemma .. "'s"
elseif form == "*'" then
return check_non_nil_star_form(lemma_first) .. "'s" .. lemma_rest
elseif form == "+l" then
if lemma:find("[szx]$") then
return {{term = full_default_s, l = {"US"}},
{term = compute_plusplus_s_form(lemma, full_default_s), l = {"UK"}}}
else
return compute_plusplus_s_form(lemma, full_default_s)
end
elseif form == "*l" then
if lemma:find("^[^ ]*[szx] ") then
return {{term = check_non_nil_star_form(split_default_s, lemma), l = {"US"}},
{term = compute_double_last_cons_stem_of_split_verb(lemma, "es"), l = {"UK"}}}
else
return check_non_nil_star_form(split_default_s, lemma)
end
else
return sub_tilde(form, lemma)
end
end
local function canonicalize_ing_form(form)
if form == "+" then
error("Internal error: Should not see '+' here")
elseif form == "^" then
return full_default_ing
elseif form == "*" then
return check_non_nil_star_form(split_default_ing, lemma)
elseif form == "++" then
return compute_double_last_cons_stem(lemma) .. "ing"
elseif form == "**" then
return compute_double_last_cons_stem_of_split_verb(lemma, "ing")
elseif form == "+!" then
return lemma .. "ing"
elseif form == "*!" then
return check_non_nil_star_form(lemma_first) .. "ing" .. lemma_rest
elseif form == "+'" then
return lemma .. "'ing"
elseif form == "*'" then
return check_non_nil_star_form(lemma_first) .. "'ing" .. lemma_rest
elseif form == "+l" then
return {{term = full_default_ing, l = {"US"}},
{term = compute_double_last_cons_stem(lemma) .. "ing", l = {"UK"}}}
elseif form == "*l" then
return {{term = check_non_nil_star_form(split_default_ing, lemma), l = {"US"}},
{term = compute_double_last_cons_stem_of_split_verb(lemma, "ing"), l = {"UK"}}}
else
return sub_tilde(form, lemma)
end
end
local function canonicalize_ed_form(form)
if form == "+" then
error("Internal error: Should not see '+' here")
elseif form == "^" then
return full_default_ed
elseif form == "*" then
return check_non_nil_star_form(split_default_ed, lemma)
elseif form == "++" then
return compute_double_last_cons_stem(lemma) .. "ed"
elseif form == "+!" then
return lemma .. "ed"
elseif form == "*!" then
return check_non_nil_star_form(lemma_first) .. "ed" .. lemma_rest
elseif form == "+'" then
return {{term = lemma .. "'d"}, {term = lemma .. "'ed"}}
elseif form == "*'" then
return {{term = check_non_nil_star_form(lemma_first) .. "'d" .. lemma_rest},
{term = check_non_nil_star_form(lemma_first) .. "'ed" .. lemma_rest}}
elseif form == "**" then
return compute_double_last_cons_stem_of_split_verb(lemma, "ed")
elseif form == "+l" then
return {{term = full_default_ed, l = {"US"}},
{term = compute_double_last_cons_stem(lemma) .. "ed", l = {"UK"}}}
elseif form == "*l" then
return {{term = check_non_nil_star_form(split_default_ed, lemma), l = {"US"}},
{term = compute_double_last_cons_stem_of_split_verb(lemma, "ed"), l = {"UK"}}}
else
return sub_tilde(form, lemma)
end
end
-- FIXME: options should be "+", "*", "++", "**", "+n", "*n", "++n" and "**n", but not "n"
local function canonicalize_en_form(form)
if form == "n" then
track("n4")
return add_suffix(lemma, "n")
end
return canonicalize_ed_form(form)
end
--------------------------------- MAIN PARSING/CONJUGATING CODE --------------------------------
local is_angle_bracket = args.angle_bracket
if is_angle_bracket then
if par2s[1] or par3s[1] or par4s[1] then
error("Can't specify explicit values for 2=, 3= or 4= along with the angle-bracket format")
end
elseif is_angle_bracket == nil and not par2s[1] and not par3s[1] and not par4s[1] and not args[1][2] and
args[1][1] and args[1][1]:find("<") then
if put.term_contains_top_level_html(args[1][1]) then
-- Often, term_contains_top_level_html() returns true on the angle-bracket format, which would
-- make the pcall() below succeed but leave the angle brackets as-is. Check for this and only do the
-- pcall() if term_contains_top_level_html() returns false.
is_angle_bracket = true
else
-- If it's ambiguous whether it's an angle-bracket format or separate params with an inline modifier,
-- try to parse as the latter. If an error occurs, treat as the former.
local ok
ok, par1s = pcall(parse_inflection, args, {1, "pres_3sg"})
if not ok then
par1s = nil
is_angle_bracket = true
end
end
end
if is_angle_bracket then
-------------------------- ANGLE-BRACKET FORMAT --------------------------
-- (0) Expand multiword term with angle brackets just on the first word.
local arg11 = args[1][1]
if arg11:find("^<.*>$") and pagename:find(" ") then
local first, rest = pagename:match("^(.-)( .*)$")
arg11 = first .. arg11 .. rest
end
-- (1) Parse the indicator specs inside of angle brackets.
local function parse_indicator_spec(angle_bracket_spec)
local inside = angle_bracket_spec:match("^<(.*)>$")
assert(inside)
local segments = put.parse_balanced_segment_run(inside, "[", "]")
local comma_separated_groups = put.split_alternating_runs(segments, ",")
if #comma_separated_groups > 4 then
error("Too many comma-separated parts in indicator spec, expected at most 4: " ..
angle_bracket_spec)
end
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: '" .. concat(separated_group) .. "'")
end
if not footnotes then
footnotes = {}
end
insert(footnotes, separated_group[j])
end
return footnotes
end
local function fetch_specs(comma_separated_group)
if not comma_separated_group then
return {{term = "+"}}
end
local specs = {}
local colon_separated_groups = put.split_alternating_runs(comma_separated_group, ":")
for _, colon_separated_group in ipairs(colon_separated_groups) do
local form = colon_separated_group[1]
if form == "*" or form == "**" or form == "*l" or form == "*!" or form == "*'" then
error("*, **, *l, *! and *' not allowed inside of indicator specs: " .. angle_bracket_spec)
end
if form == "" then
form = "+"
end
local termobj = {
term = form
}
local footnotes = fetch_footnotes(colon_separated_group)
if footnotes then
for _, footnote in ipairs(footnotes) do
m_headword_utilities.add_footnote_to_termobj(termobj, footnote)
end
end
insert(specs, termobj)
end
return specs
end
local s_specs = fetch_specs(comma_separated_groups[1])
local ing_specs = fetch_specs(comma_separated_groups[2])
local ed_specs = fetch_specs(comma_separated_groups[3])
local en_specs = fetch_specs(comma_separated_groups[4])
return {
forms = {},
s_specs = s_specs,
ing_specs = ing_specs,
ed_specs = ed_specs,
en_specs = en_specs,
}
end
local parse_props = {
parse_indicator_spec = parse_indicator_spec,
}
local alternant_multiword_spec = iut.parse_inflected_text(arg11, parse_props)
-- (2) Check for user-specified brackets; remove any links from the lemma, but remember the original
-- form so we can use it below in the 'lemma_linked' form.
-- Check to see if there are brackets in the pre-text or post-text. If so, use the linked lemma (with the
-- verb autolinked unless noautolinkverb is given). Otherwise, use the default headword algorithm.
local function check_bracket(val)
if val:find("%[%[") then
alternant_multiword_spec.saw_bracket = true
end
end
for _, alternant_or_word_spec in ipairs(alternant_multiword_spec.alternant_or_word_specs) do
check_bracket(alternant_or_word_spec.before_text)
if alternant_or_word_spec.alternants then
for _, multiword_spec in ipairs(alternant_or_word_spec.alternants) do
for _, word_spec in ipairs(multiword_spec.word_specs) do
check_bracket(word_spec.before_text)
end
check_bracket(multiword_spec.post_text)
end
end
end
check_bracket(alternant_multiword_spec.post_text)
iut.map_word_specs(alternant_multiword_spec, function(base)
if base.lemma == "" then
base.lemma = pagename
end
base.orig_lemma = base.lemma
base.lemma = remove_links(base.lemma)
if args.noautolinkverb or base.orig_lemma:find("%[%[") then
base.linked_lemma = base.orig_lemma
else
base.linked_lemma = "[[" .. base.orig_lemma .. "]]"
end
end)
-- (3) Conjugate the verbs according to the indicator specs parsed above.
local all_verb_slots = {
lemma = "infinitive",
lemma_linked = "infinitive",
s_form = "3|s|pres",
ing_form = "pres|ptcp",
ed_form = "past",
en_form = "past|ptcp",
}
local function conjugate_verb(base)
local function process_specs(slot, specs, canon_func, default_values, default_already_formobj)
local function insert_termobj_into_slot(termobj)
local formobj = m_headword_utilities.convert_termobj_to_formobj(termobj)
-- If the form is -, don't insert any forms, which will result in there being no overall forms
-- (in fact it will be nil). We check for that down below and substitute a single "-" as the
-- form, which in turn gets turned into special labels like "no present participle".
if formobj.form == "-" then
if formobj.footnotes then
error("Unable to preserve footnotes specified on missing form '-': FIXME: " ..
dump(formobj.footnotes))
end
else
iut.insert_form(base.forms, slot, formobj)
end
end
local function canonicalize_and_insert(arg)
local canon_arg = canon_func(arg)
if type(canon_arg) == "string" then
arg.term = canon_arg
insert_termobj_into_slot(arg)
else
for _, canon in ipairs(canon_arg) do
m_headword_utilities.combine_termobj_decorations(canon, arg)
insert_termobj_into_slot(canon)
end
end
end
for _, arg in ipairs(specs) do
if arg.term == "+" then
if default_values then -- will be nil if past tense specified as - and no past ptc given
for _, val in ipairs(default_values) do
val = shallowCopy(val)
if default_already_formobj then
local argformobj = m_headword_utilities.convert_termobj_to_formobj(arg)
val.footnotes = iut.combine_footnotes(val.footnotes, argformobj.footnotes)
iut.insert_form(base.forms, slot, val)
else
m_headword_utilities.combine_termobj_decorations(val, arg)
canonicalize_and_insert(val)
end
end
end
else
canonicalize_and_insert(arg)
end
end
end
set_lemma_and_default_forms(base.lemma)
local all_part_default_specs = {}
local function process_and_canonicalize_s_form(arg)
local form = arg.term
if form == "+" then
error("Internal error: '+' should have been converted to '^' by now")
end
if form == "*" or form == "**" or form == "*l" or form == "*!" or form == "*'" then
error(("Internal error: '%s' should have already thrown an error"):format(form))
end
if form == "^" or form == "++" or form == "+l" or form == "+!" or form == "+'" then
insert(all_part_default_specs, shallowCopy(arg))
end
return canonicalize_s_form(form)
end
process_specs("s_form", base.s_specs, process_and_canonicalize_s_form, {{term = "^"}})
if not all_part_default_specs[1] then
all_part_default_specs[1] = {term = "^"}
end
process_specs("ing_form", base.ing_specs, function(arg) return canonicalize_ing_form(arg.term) end,
all_part_default_specs)
process_specs("ed_form", base.ed_specs, function(arg) return canonicalize_ed_form(arg.term) end,
all_part_default_specs)
process_specs("en_form", base.en_specs, function(arg) return canonicalize_en_form(arg.term) end,
base.forms.ed_form, "default already formobj")
iut.insert_form(base.forms, "lemma", {form = base.lemma})
-- Add linked version of lemma for use in head=. We write this in a general fashion in case
-- there are multiple lemma forms (which isn't possible currently at this level, although it's
-- possible overall using the ((...,...)) notation).
iut.insert_forms(base.forms, "lemma_linked", iut.map_forms(base.forms.lemma, function(form)
if form == base.lemma and base.linked_lemma:find("%[%[") then
return base.linked_lemma
else
return form
end
end))
end
local inflect_props = {
slot_table = all_verb_slots,
inflect_word_spec = conjugate_verb,
}
iut.inflect_multiword_or_alternant_multiword_spec(alternant_multiword_spec, inflect_props)
-- (4) Fetch the forms and put the conjugated lemmas in data.heads if not explicitly given.
local function fetch_termobjs(slot)
local forms = alternant_multiword_spec.forms[slot]
-- See above. This should only occur if the user explicitly used - for a spec.
if not forms or not forms[1] then
return {{term = "-"}}
end
local termobjs = {}
for _, formobj in ipairs(forms) do
insert(termobjs, m_headword_utilities.convert_formobj_to_termobj(formobj))
end
return termobjs
end
pres_3sgs = fetch_termobjs("s_form")
pres_ptcs = fetch_termobjs("ing_form")
pasts = fetch_termobjs("ed_form")
past_ptcs = fetch_termobjs("en_form")
-- Use the "linked" form of the lemma as the head if no head= explicitly given and the user specified
-- brackets in one of the lemmas. Otherwise we use the default headword-linking algorithm.
if not data.user_specified_heads[1] and alternant_multiword_spec.saw_bracket then
data.heads = {}
for _, lemma_obj in ipairs(alternant_multiword_spec.forms.lemma_linked) do
insert(data.heads, m_headword_utilities.convert_formobj_to_termobj(lemma_obj))
end
end
else
-------------------------- SEPARATE-PARAM FORMAT --------------------------
set_lemma_and_default_forms(pagename)
par1s = par1s or parse_inflection(args, {1, "pres_3sg"})
pres_3sgs = {}
pres_ptcs = {}
pasts = {}
past_ptcs = {}
if not par1s[1] then
par1s = {{term = "+"}}
end
if not par2s[1] then
par2s = {{term = "+"}}
end
if not par3s[1] then
par3s = {{term = "+"}}
end
if not par4s[1] then
par4s = {{term = "+"}}
end
local function process_argument(args, dest, canon_func, default_values, default_already_canonicalized)
local function canonicalize_and_insert(arg)
local canon_arg = canon_func(arg)
if type(canon_arg) == "string" then
arg.term = canon_arg
m_headword_utilities.insert_termobj_combining_duplicates(dest, arg)
else
for _, canon in ipairs(canon_arg) do
m_headword_utilities.combine_termobj_decorations(canon, arg)
m_headword_utilities.insert_termobj_combining_duplicates(dest, canon)
end
end
end
for _, arg in ipairs(args) do
if arg.term == "+" then
for _, val in ipairs(default_values) do
val = shallowCopy(val)
m_headword_utilities.combine_termobj_decorations(val, arg)
if default_already_canonicalized then
m_headword_utilities.insert_termobj_combining_duplicates(dest, val)
else
canonicalize_and_insert(val)
end
end
else
canonicalize_and_insert(arg)
end
end
end
local all_part_default_specs = {}
local function process_and_canonicalize_s_form(arg)
local form = arg.term
if form == "+" then
error("Internal error: '+' should have been converted to '^' by now")
end
if form == "^" or form == "++" or form == "+l" or form == "+!" or form == "+'" or
form == "*" or form == "**" or form == "*l" or form == "*!" or form == "*'" then
insert(all_part_default_specs, shallowCopy(arg))
end
return canonicalize_s_form(form)
end
process_argument(par1s, pres_3sgs, process_and_canonicalize_s_form, {{term = "^"}})
if not all_part_default_specs[1] then
all_part_default_specs[1] = {term = "^"}
end
process_argument(par2s, pres_ptcs, function(arg) return canonicalize_ing_form(arg.term) end,
all_part_default_specs)
process_argument(par3s, pasts, function(arg) return canonicalize_ed_form(arg.term) end,
all_part_default_specs)
process_argument(par4s, past_ptcs, function(arg) return canonicalize_en_form(arg.term) end,
pasts, "default already canonicalized")
end
------------------------------------------- INSERT INFLECTIONS ------------------------------------------
insert_inflection(data, pres_3sgs, "บุรุษที่สามเอกพจน์ปัจจุบันกาลสามัญ", "s-verb-form")
insert_inflection(data, pres_ptcs, "รูปกริยาขยายปัจจุบันกาล", "ing-form")
if deepEquals(pasts, past_ptcs) then
insert_inflection(data, pasts, "อดีตกาลสามัญ และรูปกริยาขยายอดีตกาล", "ed-form",
"no simple past or past participle")
else
insert_inflection(data, pasts, "อดีตกาลสามัญ", "spast")
insert_inflection(data, past_ptcs, "รูปกริยาขยายอดีตกาล", "past|part")
end
if pagename:find(" ") then
-- Check for placeholder "it"
local words = split(pagename, " ")
for _, word in ipairs(words) do
if word == "it" or word == "its" or word == "it's" then
insert(data.categories, langname .. ' terms with placeholder "it"')
break
end
end
-- Check for phrasal verbs
local phrasal_adverbs = list_to_set{
-- NOTE: This should only contain common phrasal adverbs, not random words like [[low]],
-- [[adrift]], etc.
"aback",
"about",
"above",
"across",
"after",
"against",
"ahead",
"along",
"apart",
"around",
"as",
"aside",
"at",
"away",
"back",
"before",
"behind",
"below",
"between",
"beyond",
"by",
"down",
"for",
"forth",
"from",
"in",
"into",
"of",
"off",
"on",
"onto",
"out",
"over",
"past",
"round",
"through",
"to",
"together",
"towards",
"under",
"up",
"upon",
"with",
"without",
}
local allowed_non_adverb_words = list_to_set{
"it",
"one",
"oneself",
"someone",
}
local base = pagename
local seen_adverbs = {}
-- Only consider a verb to be phrasal if it consists of a single base verb followed exclusively by either
-- adverbs from `phrasal_adverbs` or placeholder words from `allowed_non_adverb_words`, where at
-- least one following word is from `phrasal_adverbs` (hence [[can it]] is not a phrasal verb).
while true do
local prev, word = base:match("^(.+) (.-)$")
if not prev then
break
end
if phrasal_adverbs[word] then
insert(seen_adverbs, word)
elseif allowed_non_adverb_words[word] then
-- do nothing
else
break
end
base = prev
end
if not base:find(" ") and seen_adverbs[1] then
insert(data.categories, langname .. " phrasal verbs")
for i = #seen_adverbs, 1, -1 do
insert(data.categories, langname .. ' phrasal verbs formed with "' .. seen_adverbs[i] ..
'"')
end
end
end
end,
}
-----------------------------------------------------------------------------------------
-- Suffix forms --
-----------------------------------------------------------------------------------------
pos_functions["รูปปัจจัย"] = {
params = {
[1] = {required = true, list = true, disallow_holes = true},
},
func = function(args, data, is_suffix)
local suffix_type = {}
for _, typ in ipairs(args[1]) do
insert(suffix_type, "ปัจจัยสร้าง" .. typ)
end
insert(data.inflections, {label = "รูปผันของ " .. m_table.serialCommaJoin(suffix_type, {conj = "หรือ"})})
end,
}
return export
fht760bmwpkupk2wc7wymxz1dxq4acb
มอดูล:ar-headword
828
51049
5775324
5723290
2026-10-15T02:52:51Z
Octahedron80
267
5775324
Scribunto
text/plain
-- Author: primarily Benwing2; some work by Fenakhay, Erutuon; early version by Rua
local export = {}
local pos_functions = {}
local force_cat = false -- for testing; if true, categories appear in non-mainspace pages
local ar_translit = require("Module:ar-translit")
local ar_verb_module = "Module:ar-verb"
local ar_utilities_module = "Module:ar-utilities"
local ar = require(ar_utilities_module)
local en_utilities_module = "Module:en-utilities"
local headword_module = "Module:headword"
local headword_utilities_module = "Module:headword utilities"
local links_module = "Module:links"
local inflection_utilities_module = "Module:inflection utilities"
local parse_utilities_module = "Module:parse utilities"
local require_when_needed = require("Module:utilities/require when needed")
local remove_links = require_when_needed(links_module, "remove_links")
local m_table = require("Module:table")
local m_str_utils = require("Module:string utilities")
local m_en_utilities = require_when_needed(en_utilities_module)
local m_headword_utilities = require_when_needed(headword_utilities_module)
local glossary_link = require_when_needed(headword_utilities_module, "glossary_link")
local boolean_param = {type = "boolean"}
local list_to_set = m_table.listToSet
local rfind = m_str_utils.find
local rmatch = m_str_utils.match
local rsubn = m_str_utils.gsub
local u = m_str_utils.char
local rsplit = m_str_utils.split
local insert = table.insert
local concat = table.concat
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local langcode = "ar"
local lang = require("Module:languages").getByCode(langcode)
local langname = lang:getCategoryName() --th
local TEMPCOMMA = u(0xFFF0)
local TEMPARCOMMA = u(0xFFF1)
local misc_pos_with_gender = list_to_set {
"ปัจจับ",
"รูปคุณศัพท์",
"รูปนาม",
"รูปวิสามานยนาม",
"รูปสรรพนาม",
"รูปตัวกำหนด",
}
-----------------------------------------------------------------------------------------
-- Utility functions --
-----------------------------------------------------------------------------------------
local dump = mw.dumpObject
-- version of mw.ustring.gsub() that discards all but the first return value
local function rsub(term, foo, bar)
local retval = rsubn(term, foo, bar)
return retval
end
local function ine(val)
if val == "" then return nil else return val end
end
-- Replace comma with a temporary char in comma + whitespace.
local function escape_comma_whitespace(run)
local escaped = false
if run:find("\\,") then
run = run:gsub("\\,", "\\" .. TEMPCOMMA)
escaped = true
end
if run:find("\\،") then
run = run:gsub("\\،", "\\" .. TEMPARCOMMA)
escaped = true
end
if run:find(",%s") then
run = run:gsub(",(%s)", TEMPCOMMA .. "%1")
escaped = true
end
if run:find("،%s") then
run = run:gsub("،(%s)", TEMPARCOMMA .. "%1")
escaped = true
end
return run, escaped
end
-- Undo replacement of comma with a temporary char in comma + whitespace.
local function unescape_comma_whitespace(run)
return (run:gsub(TEMPCOMMA, ","):gsub(TEMPARCOMMA, "،"))
end
-- Split an argument on comma or Arabic comma, but not either type of comma followed by whitespace.
local function split_on_comma(val)
if rfind(val, "[,،]%s") or val:find("\\") then
return export.split_escaping(val, "[,،]", false, escape_comma_whitespace, unescape_comma_whitespace)
else
return rsplit(val, "[,،]")
end
end
local function replace_tr_ending(tr, from, to)
if not tr then
return nil
end
local pref = tr:match("^(.*)" .. from .. "$")
if not pref then
error(("Translit '%s' does not end in -%s, as expected"):format(tr, from))
end
return pref .. to
end
-----------------------------------------------------------------------------------------
-- Tracking functions --
-----------------------------------------------------------------------------------------
local trackfn = require("Module:debug/track")
local function track(page)
trackfn(langcode .. "-headword/" .. page)
return true
end
--[==[
Examples of what you can find by looking at what links to the given
pages:
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized]]
all unvocalized pages
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized/pl]]
all unvocalized pages where the plural is unvocalized,
whether specified using pl=, pl2=, etc.
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized/head]]
all unvocalized pages where the head is unvocalized
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized/head/nouns]]
all nouns excluding proper nouns, collective nouns,
singulative nouns where the head is unvocalized
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized/head/proper]]
nouns all proper nouns where the head is unvocalized
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized/head/not]]
proper nouns all words that are not proper nouns
where the head is unvocalized
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized/adjectives]]
all adjectives where any parameter is unvocalized;
currently only works for heads,
so equivalent to .../unvocalized/head/adjectives
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized-empty-head]]
all pages with an empty head
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized-manual-translit]]
all unvocalized pages with manual translit
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized-manual-translit/head/nouns]]
all nouns where the head is unvocalized but has manual translit
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/unvocalized-no-translit]]
all unvocalized pages without manual translit
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/i3rab]]
all pages with any parameter containing i3rab
of either -un, -u, -a or -i
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/i3rab-un]]
all pages with any parameter containing an -un i3rab ending
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/i3rab-un/pl]]
all pages where a form specified using pl=, pl2=, etc.
contains an -un i3rab ending
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/i3rab-u/head]]
all pages with a head containing an -u i3rab ending
[[Special:WhatLinksHere/Wiktionary:Tracking/ar-headword/i3rab/head/proper]]
nouns (all proper nouns with a head containing i3rab
of either -un, -u, -a or -i)
In general, the format is one of the following:
Wiktionary:Tracking/ar-headword/FIRSTLEVEL
Wiktionary:Tracking/ar-headword/FIRSTLEVEL/ARGNAME
Wiktionary:Tracking/ar-headword/FIRSTLEVEL/POS
Wiktionary:Tracking/ar-headword/FIRSTLEVEL/ARGNAME/POS
FIRSTLEVEL can be one of "unvocalized", "unvocalized-empty-head" or its
opposite "unvocalized-specified", "unvocalized-manual-translit" or its
opposite "unvocalized-no-translit", "i3rab", "i3rab-un", "i3rab-u",
"i3rab-a", or "i3rab-i".
ARGNAME is either "head" or an argument such as "pl", "f", "cons", etc.
This automatically includes arguments specified as head2=, pl3=, etc.
POS is a part of speech, lowercase and singular, e.g. "noun",
"adjective", "proper noun", "collective noun", etc. or
"not proper noun", which includes all parts of speech but proper nouns.
]==]
local function track_form(argname, form, translit, pos)
form = ar.reorder_shadda(remove_links(form))
function dotrack(page)
track(page)
track(page .. "/" .. argname)
if pos then
track(page .. "/" .. pos)
track(page .. "/" .. argname .. "/" .. pos)
if pos ~= "คำวิสามานยนาม" then
track(page .. "/not proper noun")
track(page .. "/" .. argname .. "/not proper noun")
end
end
end
function track_i3rab(arabic, tr)
if rfind(form, arabic .. "$") then
dotrack("i3rab")
dotrack("i3rab-" .. tr)
end
end
track_i3rab(ar.UN, "un")
track_i3rab(ar.U, "u")
track_i3rab(ar.A, "a")
track_i3rab(ar.I, "i")
if form == "" or not (lang:transliterate(form)) then
dotrack("unvocalized")
if form == "" then
dotrack("unvocalized-empty-head")
else
dotrack("unvocalized-specified")
end
if translit then
dotrack("unvocalized-manual-translit")
else
dotrack("unvocalized-no-translit")
end
end
end
-----------------------------------------------------------------------------------------
-- Inflection-parsing functions --
-----------------------------------------------------------------------------------------
-- Construct the default construct state or informal form of a term in lemma format. Usually this is the same as the
-- lemma but is different for final-weak nouns and adjectives ending in -n in their lemma. NOTE: Input must be
-- shadda-reordered for this to work properly.
local function default_construct_state_or_informal(term, tr)
local pref = term:match("^(.*)" .. ar.HAMZA .. ar.IN .."$")
-- Hamza on the line with -in changes to hamza-on-yā with -ī.
if pref then
return pref .. ar.HAMZA_ON_YA .. ar.II, replace_tr_ending(tr, "in", "ī")
end
-- Otherwise just change -in to -ī.
pref = term:match("^(.*)" .. ar.IN .. "$")
if pref then
return pref .. ar.II, replace_tr_ending(tr, "in", "ī")
end
-- Change -an with alif maqṣūra to -ā with alif maqṣūra.
pref = term:match("^(.*)" .. ar.AN .. ar.AMAQ .. "$")
if pref then
return pref .. ar.AAMAQ, replace_tr_ending(tr, "an", "ā")
end
-- Change -an with tall alif (e.g. عَصًا) to -ā with tall alif.
pref = term:match("^(.*)" .. ar.AN .. ar.ALIF .. "$")
if pref then
return pref .. ar.AA, replace_tr_ending(tr, "an", "ā")
end
return term, tr
end
local function generate_construct_state_or_informal_default(data, args)
local heads = data.heads
local consobjs = {}
local different_cons = false
for _, headobj in ipairs(data.heads) do
local consterm, constr = default_construct_state_or_informal(headobj.term, headobj.tr)
different_cons = different_cons or consterm ~= headobj.term or constr ~= headobj.tr
local consobj = m_table.shallowCopy(headobj)
consobj.term = consterm
consobj.tr = constr
insert(consobjs, consobj)
end
if different_cons then
return consobjs
else
return {}
end
end
local noun_field_cons = {
field = "cons", label = "<<construct state>>", generate_default = generate_construct_state_or_informal_default,
default_when_not_explicit = function(args, data) return true end,
}
local noun_field_inf = {field = "inf", label = "informal"}
local noun_field_obl = {field = "obl", label = "<<oblique>>"}
local noun_field_def = {field = "def", label = "<<definite>> state"}
local noun_inflections = {
noun_field_cons,
noun_field_inf,
noun_field_obl,
noun_field_def,
}
local adj_field_inf = {
field = "inf", label = "informal", generate_default = generate_construct_state_or_informal_default,
default_when_not_explicit = function(args, data) return true end,
}
local adj_field_obl = noun_field_obl
local adj_field_def = noun_field_def
local adjective_inflections = {
adj_field_inf,
adj_field_obl,
adj_field_def,
}
local function has_construct_state(data)
return data.pos_category ~= "adjectives"
end
local function parse_nominal_inflection(paramname, val, parse_err)
return m_headword_utilities.parse_term_with_modifiers {
val = val,
paramname = paramname,
splitchar = ",",
include_mods = {"tr", "g"},
}
end
local function make_nominal_inflection_param_mod_spec(paramname)
return {convert = function(val, parse_err)
return parse_nominal_inflection(paramname, val, parse_err)
end}
end
-- Parse an inflection. The raw arguments come from `args[field]`, which is parsed for inline modifiers. Multiple
-- comma-separated values are allowed.
local function parse_inflection(data, args, field, is_head)
local argfield = field
local argpref = field
if type(argfield) == "table" then
argpref = argfield[2]
argfield = argfield[1]
end
local include_mods
if is_head then
include_mods = {"tr"}
else
include_mods = {"tr", "g"}
for _, spec in ipairs(has_construct_state(data) and noun_inflections or adjective_inflections) do
insert(include_mods, {spec.field, make_nominal_inflection_param_mod_spec(argpref .. "." .. spec.field)})
end
end
if is_head then
local retval
if args[argfield] then
retval = m_headword_utilities.parse_term_with_modifiers {
val = args[argfield],
paramname = field,
splitchar = ",",
is_head = is_head,
include_mods = include_mods,
}
end
return retval or {}
else
return m_headword_utilities.parse_term_list_with_modifiers {
forms = args[argfield],
paramname = field,
splitchar = ",",
is_head = is_head,
include_mods = include_mods,
}
end
end
local function insert_inflection(data, terms, label, accel, defgender, track_field, no_label, usually_no_label)
local track_pos = m_en_utilities.singularize(data.pos_category)
for _, termobj in ipairs(terms) do
-- If the user supplied a construct state or informal form for the term with a value of "+", substitute the
-- default value for the term. If the user supplied a value of "--", they want no value displayed. Otherwise,
-- if the user didn't supply any value, we check to see if the default construct state or informal form is
-- different from the lemma and display it if so; this applies particularly to terms in '-in' and '-an', where
-- the default construct state or informal form is almost always correct.
local field = has_construct_state(data) and "cons" or "inf"
if not termobj[field] then
local defcons, defconstr = default_construct_state_or_informal(termobj.term, termobj.tr)
if termobj.term ~= defcons or termobj.tr ~= defconstr then
-- We don't want to copy decorations from the term object because we're a subinflection of the term
-- object.
termobj[field] = {{term = defcons, tr = defconstr}}
end
elseif termobj[field][1].term == "--" then
if termobj[field][2] then
error("Can't specify more than one value for <" .. field .. ":...> if first value is '--', meaning \"don't insert anything\"")
end
termobj[field] = nil
else
for i, consobj in ipairs(termobj[field]) do
if consobj.term == "+" then
if consobj.tr then
error("Can't specify translit for default value '+'")
end
consobj.term, consobj.tr = default_construct_state_or_informal(termobj.term, termobj.tr)
elseif consobj.term == "~" then
if consobj.tr then
error("Can't specify translit for term-requesting value '~'")
end
consobj.term, consobj.tr = termobj.term, termobj.tr
end
end
end
if defgender and not termobj.genders then
termobj.genders = {{spec = defgender}}
end
local function insert_nested_inflection(field, label)
if termobj[field] then
m_headword_utilities.insert_inflection {
headdata = data,
inflobj = termobj,
terms = termobj[field],
label = label
}
end
end
for _, spec in ipairs(has_construct_state(data) and noun_inflections or adjective_inflections) do
insert_nested_inflection(spec.field, spec.label)
end
track_form(track_field, termobj.term, termobj.tr, track_pos)
end
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
accel = accel and {form = accel} or nil,
no_label = no_label,
usually_no_label = usually_no_label,
}
end
-----------------------------------------------------------------------------------------
-- Main entry point --
-----------------------------------------------------------------------------------------
function export.show(frame)
local iparams = {
[1] = true,
}
local iargs = require("Module:parameters").process(frame.args, iparams)
local parargs = frame:getParent().args
local poscat = iargs[1]
local pos_in_1 = not poscat
if pos_in_1 then
poscat = ine(parargs[1]) or
mw.title.getCurrentTitle().fullText == "แม่แบบ:" .. langcode .. "-head" and "คำอุทาน" or
error("Part of speech must be specified in 1=")
poscat_th = require("Module:th-utilities").th_pos(poscat) --th
poscat_th = require(headword_module).canonicalize_pos(poscat_th) --th_pos_to_form is already there
else
poscat_th = require("Module:th-utilities").th_pos(poscat) --th; initiation is needed
end
local indexing_poscat = pos_in_1 and (misc_pos_with_gender[poscat_th] and "head_with_gender" or "head") or poscat_th
local params = {
["suffix"] = boolean_param,
["nosuffix"] = boolean_param,
["id"] = true,
["json"] = boolean_param,
["pagename"] = {}, -- for testing
}
if pos_in_1 then
params[1] = {required = true} -- required but ignored as already processed above
end
local head_is_head = pos_functions[indexing_poscat] and pos_functions[indexing_poscat].head_is_not_1
local headfield = head_is_head and "head" or pos_in_1 and 2 or 1
params[headfield] = head_is_head and true or {default = "+"}
params.head2 = {replaced_by = false, instead = "use multiple comma-separated values in |" .. headfield .. "="}
local tr_replaced_by = {replaced_by = false, instead = "use <tr:...> inline modifier on |" .. headfield .. "="}
params.tr = tr_replaced_by
params.tr2 = tr_replaced_by
if pos_functions[indexing_poscat] then
for key, val in pairs(pos_functions[indexing_poscat].params()) do
params[key] = val
end
end
local parargs = frame:getParent().args
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local data = {
lang = lang,
pos_category = poscat_th,
orig_pos_category = poscat_th,
categories = {},
heads = {},
genders = {},
inflections = {enable_auto_translit = true},
pagename = pagename,
id = args.id,
sort_key = args.sort,
force_cat_output = force_cat,
-- We expect a head always so the redundant head cat will be inaccurate.
no_redundant_head_cat = true,
}
data.heads = parse_inflection(data, args, headfield, "is_head")
for _, headobj in ipairs(data.heads) do
if headobj.term == "+" then
headobj.term = pagename
end
end
data.is_suffix = false
if args.suffix or (
not args.nosuffix and pagename:find("^%-") and poscat ~= "ปัจจัย" and poscat ~= "รูปปัจจัย"
) then
data.is_suffix = true
data.pos_category = "ปัจจัย"
local singular_poscat = --[[m_en_utilities.singularize(poscat)]] poscat_th
insert(data.categories, "ปัจจัยสร้าง" .. singular_poscat .. langname)
insert(data.inflections, {label = "ปัจจัยสร้าง" .. singular_poscat})
end
if pos_functions[indexing_poscat] then
pos_functions[indexing_poscat].func(data, args)
end
-- Do this after calling pos_functions[poscat].func() as it may modify data.heads (as verbs do).
local irreg_translit = false
for _, head in ipairs(data.heads) do
if ar_translit.irregular_translit(head.term, head.tr) then
irreg_translit = true
break
end
end
if irreg_translit then
insert(data.categories, "ศัพท์" .. langname .. "ที่มีการออกเสียงไม่ปรกติ")
end
if args.json then
return require("Module:JSON").toJSON(data)
end
return require(headword_module).full_headword(data)
end
-----------------------------------------------------------------------------------------
-- Gender handling --
-----------------------------------------------------------------------------------------
local valid_bare_genders = {false, "m", "f", "mf", "mfbysense", "mfequiv"}
local valid_bare_numbers = {false, "d", "p"}
local valid_bare_animacies = {false, "pr", "np"}
local valid_genders = {}
for _, gender in ipairs(valid_bare_genders) do
for _, number in ipairs(valid_bare_numbers) do
for _, animacy in ipairs(valid_bare_animacies) do
local parts = {}
local function ins_part(part)
if part then
insert(parts, part)
end
end
ins_part(gender)
ins_part(number)
ins_part(animacy)
local full_gender = concat(parts, "-")
valid_genders[full_gender == "" and "?" or full_gender] = true
end
end
end
local function is_masc_sg(g)
return g == "m" or g == "m-pr" or g == "m-np"
end
local function is_fem_sg(g)
return g == "f" or g == "f-pr" or g == "f-np"
end
local function is_masc_fem_sg(g)
g = g:gsub("%-pr", ""):gsub("%-np", "")
return g == "mf" or g == "mfequiv" or g == "mfbysense"
end
local function add_gender_params(params, default)
params[2] = {type = "genders", default = default or "?", template_default = "m"}
params["g2"] = {replaced_by = false, instead = "use comma-separated values in |g="}
end
-- Handle gender in params 2=, inserting into `data.genders`. Also, if a lemma, insert categories into `data.categories`
-- if the gender is unexpected for the form of the noun. (Note: If there are multiple genders,
-- [[Module:gender and number]] will automatically insert 'Arabic POS with multiple genders'.)
local function handle_gender(data, args, nonlemma, field)
if not args[field or 2] then
return
end
for _, gspec in ipairs(args[field or 2]) do
if not valid_genders[gspec.spec] then
error("Unrecognized gender: " .. gspec.spec)
end
end
data.genders = args[field or 2]
if nonlemma then
return
end
for _, gspec in ipairs(data.genders) do
local g = gspec.spec
if is_masc_sg(g) or is_fem_sg(g) or is_masc_fem_sg(g) then
local head = data.heads[1]
if head then
head = rsub(ar.reorder_shadda(remove_links(head.term)), ar.UNUOPT .. "$", "")
local ends_with_tam = rfind(head, "^[^ ]*" .. ar.TAM .. "$") or
rfind(head, "^[^ ]*" .. ar.TAM .. " ")
if (is_masc_sg(g) or is_masc_fem_sg(g)) and ends_with_tam then
insert(data.categories, "ศัพท์เพศชาย" .. langname .. "ที่ลงท้ายด้วยเพศหญิง")
elseif (is_fem_sg(g) or is_masc_fem_sg(g)) and not ends_with_tam and
not rfind(head, "[" .. ar.ALIF .. ar.AMAQ .. "]$") and
not rfind(head, ar.ALIF .. ar.HAMZA .. "$") then
insert(data.categories, "ศัพท์เพศหญิง" .. langname .. "ที่ไม่ลงท้ายด้วยเพศหญิง")
end
end
end
end
end
-----------------------------------------------------------------------------------------
-- Inflection handlers --
-----------------------------------------------------------------------------------------
-- Add list parameters to `params` (a structure as passed to [[Module:parameters]]) for a parameter named `argpref`.
-- If `argpref` is "*", add the nominal inflection parameters for construct state, definite state, etc. Related
-- transliteration and gender parameters are no longer supported in favor of inline modifiers, and error messages are
-- output if these parameters are used.
local function add_infl_params(params, argpref)
params[argpref] = {list = true, disallow_holes = true}
params[argpref .. "tr"] = {replaced_by = false, instead = "use <tr:...> inline modifier on |" .. argpref .. "="}
params[argpref .. "g"] = {replaced_by = false, instead = "use <g:...> inline modifier on |" .. argpref .. "="}
end
--[=[
Fetch a list of inflections from the arguments in `args` based on argument `field` (e.g. "pl"). Label with `label`
(e.g. "plural"), which will appear in the headword. Insert into `data.inflections`, where `data` is the structure
passed to [[Module:headword]]. If `generate_default` is specified, it should be a function of two arguments
(`data`, `args`), which should generate the default value if no values are specified or if "+" is explicitly given.
If `generate_default` isn't specified and the user gave no values, no inflection will be inserted.
]=]
local function handle_infl(data, args, spec)
local newinfls = parse_inflection(data, args, spec.field, false)
if not newinfls[1] and spec.default_when_not_explicit and spec.default_when_not_explicit(data, args) then
newinfls = {{term = "+"}}
end
if spec.handle then
spec.handle(data, args, newinfls)
end
local default_specs = spec.allowed_defspecs
if not default_specs then
default_specs = spec.generate_default and {["+"] = true} or {}
end
local saw_defspec = false
for _, newinfl in ipairs(newinfls) do
if default_specs[newinfl.term] or newinfl.term == "~" then
saw_defspec = true
break
end
end
if saw_defspec then
local newnewinfls = {}
for _, newinfl in ipairs(newinfls) do
if default_specs[newinfl.term] then
if newinfl.tr then
error("Can't specify translit for default value '" .. newinfl.term .. "'")
end
local definfls = spec.generate_default(data, args, newinfl.term)
for _, definfl in ipairs(definfls) do
m_headword_utilities.combine_termobj_decorations(definfl, newinfl)
insert(newnewinfls, definfl)
end
elseif newinfl.term == "~" then
if newinfl.tr then
error("Can't specify translit for head-requesting value '~'")
end
for _, headobj in ipairs(data.heads) do
headobj = m_table.shallowCopy(headobj)
m_headword_utilities.combine_termobj_decorations(headobj, newinfl)
insert(newnewinfls, headobj)
end
else
insert(newnewinfls, newinfl)
end
end
newinfls = newnewinfls
end
if newinfls[1] then
if newinfls[1].term == "--" then
if newinfls[2] then
error("Can't specify more than one term if first term is '--', meaning \"don't insert anything\"")
end
else
insert_inflection(data, newinfls, spec.label, nil, spec.defgender, spec.field, spec.no_label,
spec.usually_no_label)
end
end
end
local function add_infl_list_params(params, infl_list)
for _, infl in ipairs(infl_list) do
add_infl_params(params, infl.field)
end
end
local function handle_infl_list_args(data, args, infl_list)
for _, infl in ipairs(infl_list) do
handle_infl(data, args, infl)
end
end
-----------------------------------------------------------------------------------------
-- Default ending generators --
-----------------------------------------------------------------------------------------
local function make_conditional_default(specs)
return function(data, args)
local heads = data.heads
if not heads[1] then
heads = {{term = data.pagename}}
end
local newobjs = {}
for _, headobj in ipairs(heads) do
local term = ar.reorder_shadda(headobj.term)
local tr = headobj.tr
local matched = false
for _, spec in ipairs(specs) do
local from, fromtr, to, totr = unpack(spec)
if from:find("^%^") then
pref = rmatch(term, from .. "$")
else
pref = rmatch(term, "^(.*)" .. from .. "$")
end
if pref then
term = pref .. to
tr = replace_tr_ending(tr, fromtr, totr)
matched = true
headobj = m_table.shallowCopy(headobj)
headobj.term = ar.undo_reorder_shadda(term)
headobj.tr = tr
insert(newobjs, headobj)
break
end
end
if not matched then
error(("Internal error: No matching spec: head=%s"):format(dump(headobj)))
end
end
return newobjs
end
end
local default_feminine = make_conditional_default {
{ar.AN .. ar.AMAQ, "an", ar.AAH, "āh"},
{ar.AN .. ar.ALIF, "an", ar.AAH, "āh"}, -- e.g. مُحْيًا
{ar.HAMZA .. ar.IN, "in", ar.HAMZA_ON_YA .. ar.IYAH, "iya"},
{ar.IN, "in", ar.IYAH, "iya"},
{"", "", ar.AH, "a"},
}
local default_masculine = make_conditional_default {
-- tall alif substitutes for alif maqṣūra after a yāʔ
{ar.Y .. ar.AAH, "āh", ar.AN .. ar.ALIF, "an"},
{ar.AAH, "āh", ar.AN .. ar.AMAQ, "an"},
-- handle the common case of final-weak feminine active participle with preceding hamza;
-- the hamza-on-yāʔ always converts back to hamza on the line when preceded by ā (alif) but
-- may not otherwise, so we just leave it alone in that case
{ar.ALIF .. ar.HAMZA_ON_YA .. ar.IYAH, "iya", ar.HAMZA .. ar.IN, "in"},
{ar.IYAH, "iya", ar.IN, "in"},
{ar.AH, "a", "", ""},
{"", "", "", ""},
}
local default_masculine_plural = make_conditional_default {
{ar.AN .. ar.AMAQ, "an", ar.AWN, "awn"},
{ar.AN .. ar.ALIF, "an", ar.AWN, "awn"}, -- e.g. مُحْيًا
{ar.HAMZA .. ar.IN, "in", ar.HAMZA_ON_WAW .. ar.UUN, "ūn"},
{ar.IN, "in", ar.UUN, "ūn"},
{"", "", ar.UUN, "ūn"},
}
local default_feminine_plural = make_conditional_default {
-- صَلَاة pl. صَلَوَات and أَدَاة pl. أَدَوَات and similar; but نَوَاة and وَفَاة with a و in them become نَوَيَات and وَفَيَات;
-- and longer terms like مُبَارَاة and كُمَّثْرَاة invariably form their plural in -يَات.
{"^([^و]" .. ar.A .. "[^و])" .. ar.AAH, "āh", ar.A .. ar.W .. ar.AAT, "awāt"},
{ar.AAH, "āh", ar.AYAAT, "ayāt"},
{ar.AN .. ar.AMAQ, "an", ar.AYAAT, "ayāt"},
{ar.AN .. ar.ALIF, "an", ar.AYAAT, "ayāt"}, -- e.g. مُحْيًا
{ar.HAMZA .. ar.IN, "in", ar.HAMZA_ON_YA .. ar.IYAAT, "iyāt"},
{ar.IN, "in", ar.IYAAT, "iyāt"},
{ar.AH, "a", ar.AAT, "āt"},
{"", "", ar.AAT, "āt"},
}
local default_masculine_dual = make_conditional_default {
{ar.AN .. ar.AMAQ, "an", ar.AYAAN, "ayān"},
{ar.AN .. ar.ALIF, "an", ar.AYAAN, "ayān"}, -- e.g. مُحْيًا
{ar.HAMZA .. ar.IN, "in", ar.HAMZA_ON_YA .. ar.IYAAN, "iyān"},
{ar.IN, "in", ar.IYAAN, "iyān"},
{"", "", ar.AAN, "ān"},
}
local default_feminine_dual = make_conditional_default {
{ar.AN .. ar.AMAQ, "an", ar.AATAAN, "ātān"},
{ar.AN .. ar.ALIF, "an", ar.AATAAN, "ātān"}, -- e.g. مُحْيًا
{ar.HAMZA .. ar.IN, "in", ar.HAMZA_ON_YA .. ar.IY .. ar.ATAAN, "iyatān"},
{ar.IN, "in", ar.IY .. ar.ATAAN, "iyatān"},
{"", "", ar.ATAAN, "atān"},
}
-- Return whether `term` is a nisba noun or adjective, ending in -iyy or -iyyah. `nisba_val` is the value of
-- args.nisba; if non-nil, it overrides any auto-determination based on the shape of the term.
local function term_is_nisba(term, nisba_val)
if nisba_val ~= nil then
return nisba_val
end
term = ar.reorder_shadda(term) -- necessary to avoid issues with e.g. أُورُوبِّيّ.
local pref = rmatch(term, "^(.*)" .. ar.IYY .. ar.UN .. "?$")
if not pref then
pref = rmatch(term, "^(.*)" .. ar.IYYAH .. ar.UN .. "?$")
end
-- Avoid false positives for words like قَوِيّ "strong" and صَبِيّ "boy". There may be other false positives
-- but this should catch most of them and will avoid very many false negatives.
return pref and not rfind(pref, "^[^ا]" .. ar.A .. ".$")
end
-----------------------------------------------------------------------------------------
-- Adjectives --
-----------------------------------------------------------------------------------------
local function is_defaulting_adjective(data, args)
return data.orig_pos_category == "คำคุณศัพท์ปริยาย"
end
local adj_field_elative = {field = "el", label = "<<elative>>"}
local adj_inflections = {
adj_field_inf,
adj_field_obl,
adj_field_def,
{field = "f", label = "เพศหญิง", generate_default = default_feminine,
default_when_not_explicit = is_defaulting_adjective},
{field = "d", label = "เพศชายทวิพจน์", generate_default = default_masculine_dual},
{field = "fd", label = "เพศหญิงทวิพจน์", generate_default = default_feminine_dual},
{field = "cpl", label = "เพศรวมพหูพจน์"},
{field = "pl", label = "เพศชายพหูพจน์", generate_default = default_masculine_plural,
default_when_not_explicit = is_defaulting_adjective},
{field = "fpl", label = "เพศหญิงพหูพจน์", generate_default = default_feminine_plural,
default_when_not_explicit = is_defaulting_adjective},
}
local function get_adj_params()
local params = {}
add_infl_list_params(params, adj_inflections)
add_infl_params(params, "el")
params.nisba = boolean_param
return params
end
local function handle_adj_args(data, args)
handle_infl_list_args(data, args, adj_inflections)
handle_infl(data, args, adj_field_elative)
for _, headobj in ipairs(data.heads) do
if term_is_nisba(headobj.term, args.nisba) then
insert(data.categories, "คำคุณศัพท์สัมพันธ์ (นิสบะฮ์) " .. langname)
break
end
end
end
pos_functions["คำคุณศัพท์"] = {
params = get_adj_params,
func = handle_adj_args,
}
pos_functions["คำคุณศัพท์ปริยาย"] = {
params = get_adj_params,
func = function(data, args)
data.pos_category = "คำคุณศัพท์"
handle_adj_args(data, args)
end,
}
-----------------------------------------------------------------------------------------
-- Nouns, etc. --
-----------------------------------------------------------------------------------------
local function get_masc_or_feminine_gender(data, default_type)
local saw_m, saw_f, saw_mf
for _, gender in ipairs(data.genders) do
if is_masc_sg(gender.spec) then
saw_m = true
elseif is_fem_sg(gender.spec) then
saw_f = true
elseif is_masc_fem_sg(gender.spec) then
saw_mf = true
end
end
if saw_mf or saw_m and saw_f then
error("Can't generate default for " .. default_type .. " when gender is both masculine and feminine")
elseif saw_m then
return "m"
elseif saw_f then
return "f"
else
error("Can't generate default for " .. default_type .. " when gender is not specified as " ..
"masculine or feminine singular")
end
end
local function is_defaulting_noun(data, args)
return data.orig_pos_category == "คำนามปริยาย"
end
local noun_field_dual = {
field = "d", label = "ทวิพจน์",
generate_default = function(data, args)
local gender = get_masc_or_feminine_gender(data, "noun dual")
if gender == "m" then
return default_masculine_dual(data, args)
else
return default_feminine_dual(data, args)
end
end,
}
local noun_field_plural = {
field = "pl", label = "พหูพจน์",
generate_default = function(data, args, defspec)
local gender = get_masc_or_feminine_gender(data, "noun plural")
if gender == "m" then
if defspec == "+f" then
return default_feminine_plural(data, args)
else
return default_masculine_plural(data, args)
end
elseif defspec == "+f" then
error("Can't specify '+f' with feminine gender; just use '+'")
else
return default_feminine_plural(data, args)
end
end,
-- Handle the case where pl=-, indicating an uncountable noun.
handle = function(data, args, terms)
if terms[1] and terms[1] == "-" then
insert(data.categories, "คำนามนับไม่ได้" .. langname)
if args.pauc and args.pauc[1] then
error("Can't specify paucals when pl=-")
end
end
end,
allowed_defspecs = {["+"] = true, ["+f"] = true},
default_when_not_explicit = is_defaulting_noun,
no_label = "<<นับไม่ได้>>",
usually_no_label = "โดยปกติ<<นับไม่ได้>>",
}
local noun_field_paucal = {
field = "pauc", label = "<<ตัวบอกความน้อย>>", generate_default = default_feminine_plural,
}
local noun_field_feminine = {
field = "f", label = "เพศหญิง", generate_default = default_feminine,
default_when_not_explicit = function(data, args)
if data.orig_pos_category ~= "คำนามปริยาย" then
return nil
end
local gender = get_masc_or_feminine_gender(data, "defaulting-if-masculine noun feminine")
return gender == "m"
end,
}
local noun_field_masculine = {
field = "m", label = "เพศชาย", generate_default = default_masculine,
default_when_not_explicit = function(data, args)
if data.orig_pos_category ~= "คำนามปริยาย" then
return nil
end
local gender = get_masc_or_feminine_gender(data, "defaulting-if-feminine noun masculine")
return gender == "f"
end,
}
local noun_basic_inflections = {
noun_field_cons,
noun_field_inf,
noun_field_obl,
noun_field_def,
}
local noun_shared_inflections = {
noun_field_dual,
noun_field_plural,
}
local noun_extra_inflections = {
noun_field_paucal,
noun_field_feminine,
noun_field_masculine,
}
local function get_noun_params()
local params = {}
add_gender_params(params)
add_infl_list_params(params, noun_basic_inflections)
add_infl_list_params(params, noun_shared_inflections)
add_infl_list_params(params, noun_extra_inflections)
params.nisba = boolean_param
return params
end
local function handle_noun_args(data, args)
handle_gender(data, args)
handle_infl_list_args(data, args, noun_basic_inflections)
handle_infl_list_args(data, args, noun_shared_inflections)
handle_infl_list_args(data, args, noun_extra_inflections)
for _, headobj in ipairs(data.heads) do
if term_is_nisba(headobj.term, args.nisba) then
insert(data.categories, "คำนามสัมพันธ์ (นิสบะฮ์) " .. langname)
break
end
end
end
pos_functions["คำนาม"] = {
params = get_noun_params,
func = handle_noun_args,
}
pos_functions["คำนามปริยาย"] = {
params = get_noun_params,
func = function(data, args)
data.pos_category = "คำนาม"
handle_noun_args(data, args)
end,
}
local noun_field_singulative = {field = "sing", label = "<<คำเอกนาม>>", defgender = "f", generate_default = default_feminine}
local noun_field_collective = {field = "coll", label = "<<คำสมุหนาม>>", defgender = "m", generate_default = default_masculine}
local function handle_sing_coll_noun_infls(data, args, otherinfl, otherlabel, othergender)
-- Handle sing= (corresponding singulative noun) or coll= (corresponding collective noun) and their gender
handle_infl(data, args, otherinfl, otherlabel, nil, othergender)
handle_infl_list_args(data, args, sing_coll_noun_inflections)
end
local function get_singulative_collective_noun_params(defgender, otherinfl)
local params = {}
add_gender_params(params, defgender)
add_infl_list_params(params, noun_basic_inflections)
add_infl_params(params, otherinfl)
add_infl_list_params(params, noun_shared_inflections)
add_infl_params(params, "pauc")
return params
end
pos_functions["คำสมุหนาม"] = {
params = function() return get_singulative_collective_noun_params("m", "sing") end,
func = function(data, args)
data.pos_category = "คำนาม"
insert(data.categories, "คำสมุหนาม" .. langname)
m_headword_utilities.insert_fixed_inflection {
headdata = data,
label = "<<คำสมุหนาม>>",
}
handle_gender(data, args)
handle_infl_list_args(data, args, noun_basic_inflections)
handle_infl(data, args, noun_field_singulative)
handle_infl_list_args(data, args, noun_shared_inflections)
handle_infl(data, args, noun_field_paucal)
end
}
pos_functions["คำเอกนาม"] = {
params = function() return get_singulative_collective_noun_params("f", "coll") end,
func = function(data, args)
data.pos_category = "คำนาม"
insert(data.categories, "คำเอกนาม" .. langname)
m_headword_utilities.insert_fixed_inflection {
headdata = data,
label = "<<คำเอกนาม>>",
}
handle_gender(data, args)
handle_infl_list_args(data, args, noun_basic_inflections)
handle_infl(data, args, noun_field_collective)
handle_infl_list_args(data, args, noun_shared_inflections)
handle_infl(data, args, noun_field_paucal)
end
}
-- FIXME: Do numerals really behave almost as nouns? They vary by masc/fem.
pos_functions["เลข"] = {
params = get_noun_params,
func = function(data, args)
insert(data.categories, "เลขเชิงการนับ" .. langname)
handle_noun_args(data, args)
end
}
pos_functions["คำวิสามานยนาม"] = {
params = get_noun_params,
func = handle_noun_args,
}
local function get_pronoun_params()
local params = {}
add_gender_params(params, defgender)
add_infl_list_params(params, noun_basic_inflections)
add_infl_list_params(params, noun_shared_inflections)
add_infl_params(params, "f")
return params
end
pos_functions["คำสรรพนาม"] = {
params = get_pronoun_params,
func = function(data, args)
handle_gender(data, args)
handle_infl_list_args(data, args, noun_basic_inflections)
handle_infl_list_args(data, args, noun_shared_inflections)
handle_infl(data, args, noun_field_feminine)
end
}
-----------------------------------------------------------------------------------------
-- Non-lemma forms --
-----------------------------------------------------------------------------------------
local valid_forms = list_to_set(
{ "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII",
"XIII", "XIV", "XV", "Iq", "IIq", "IIIq", "IVq" })
-- FIXME: Partly duplicated in [[Module:ar-inflections]].
local function handle_conj_form(data, args)
local form = args[2]
if form then
if not valid_forms[form] then
error("Invalid verb conjugation form " .. form)
end
insert(data.inflections, { label = "[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป " .. form .. "|รูป " .. form .. "]]" })
end
end
pos_functions["รูปกริยา"] = {
params = function()
return {
[2] = {},
}
end,
func = function(data, args)
handle_conj_form(data, args)
end
}
local function get_participle_params()
local params = get_adj_params()
params[2] = {}
return params
end
pos_functions["รูปกริยาขยายกรรตุวาจก"] = {
params = get_participle_params,
func = function(data, args)
data.pos_category = "รูปกริยาขยาย"
insert(data.categories, "รูปกริยาขยายกรรตุวาจก" .. langname)
handle_conj_form(data, args)
handle_infl_list_args(data, args, adj_inflections)
end
}
pos_functions["รูปกริยาขยายกรรมวาจก"] = {
params = get_participle_params,
func = function(data, args)
data.pos_category = "รูปกริยาขยาย"
insert(data.categories, "รูปกริยาขยายกรรมวาจก" .. langname)
handle_conj_form(data, args)
handle_infl_list_args(data, args, adj_inflections)
end
}
-----------------------------------------------------------------------------------------
-- Verbs --
-----------------------------------------------------------------------------------------
pos_functions["คำกริยา"] = {
head_is_not_1 = true,
params = function() return {
[1] = {},
-- Comma-separated lists with possible inline modifiers
["past"] = {},
["past1s"] = {},
["nonpast"] = {},
["vn"] = {},
["noautolinktext"] = {type = "boolean"},
["noautolinkverb"] = {type = "boolean"},
} end,
func = function(data, args)
local ar_verb = require(ar_verb_module)
local alternant_multiword_spec =
args[1] ~= "-" and ar_verb.do_generate_forms(args, "ar-verb", data.pagename) or nil
local function do_slot(slots_to_check, override, label, slot_is_headword)
-- Do this even with an override so we can return the correct filled slot.
local slot, slotval
if alternant_multiword_spec then
for _, potential_slot in ipairs(slots_to_check) do
slotval = alternant_multiword_spec.forms[potential_slot]
if slotval then
slot = potential_slot
break
end
end
end
local function get_slot_values()
local terms = {}
for _, form in ipairs(slotval) do
local term = {
term = form.form,
id = form.id,
genders = form.genders,
pos = form.pos,
lit = form.lit,
}
term.tr = form.translit
if form.footnotes then
local quals, refs = require(inflection_utilities_module).
convert_footnotes_to_qualifiers_and_references(form.footnotes)
term.q = quals
term.refs = refs
end
insert(terms, term)
end
return terms
end
if override then
local override_param_mods = {
alt = {},
t = {
-- [[Module:headword]] expects the gloss in "gloss".
item_dest = "gloss",
},
gloss = {},
g = {
-- [[Module:headword]] expects the genders in "genders".
item_dest = "genders",
type = "genders",
},
pos = {},
lit = {},
id = {},
-- Qualifiers and labels
q = {
type = "qualifier",
},
qq = {
type = "qualifier",
},
l = {
type = "labels",
},
ll = {
type = "labels",
},
ref = {
-- [[Module:headword]] expects the references in "refs".
item_dest = "refs",
type = "references",
},
}
local function generate_obj(formval, parse_err)
if formval == "+" then
return {term = "+", underlying_terms = get_slot_values()}
end
local val, uncertain = formval:match("^(.*)(%?)$")
val = val or formval
uncertain = not not uncertain
local ar, translit = val:match("^(.*)//(.*)$")
if not ar then
ar = formval
end
local retval = {term = ar, uncertain = uncertain}
retval.tr = translit
end
local terms
if override:find("<") then
terms = require(parse_utilities_module).parse_inline_modifiers(override, {
paramname = paramname,
param_mods = override_param_mods,
generate_obj = generate_obj,
splitchar = "[,،]",
escape_fun = escape_comma_whitespace,
unescape_fun = unescape_comma_whitespace,
})
else
terms = split_on_comma(override)
for i, split in ipairs(terms) do
terms[i] = generate_obj(split)
end
end
-- See if + was supplied and we have to potentially flatten multiple default terms and harmonize
-- default properties with override properties.
local saw_underlying_terms = false
for _, term in ipairs(terms) do
if term.underlying_terms then
saw_underlying_terms = true
break
end
end
if saw_underlying_terms then
-- Flatten any default terms, copying the corresponding override properties over the default
-- properties. Non-default terms get inserted directly.
local flattened = {}
for _, term in ipairs(terms) do
if term.underlying_terms then
for _, underlying in ipairs(term.underlying_terms) do
for k, v in pairs(term) do
if k ~= "term" and k ~= "underlying_terms" then
if k == "uncertain" then
underlying.uncertain = underlying.uncertain or v
elseif type(v) ~= "table" or v[1] then
-- Don't copy empty lists (which are the default) over possibly non-empty
-- lists.
underlying[k] = v
end
end
end
insert(flattened, underlying)
end
else
insert(flattened, term)
end
end
terms = flattened
end
if not slot_is_headword then
terms.label = label
end
return terms, slot
elseif not alternant_multiword_spec then
return nil, slot
else
if not slotval then
if slot_is_headword then
-- FIXME, put "uncertain" as qualifier? Does this ever happen?
return nil, slot
elseif alternant_multiword_spec.slot_uncertain[slot] then
return {label = label .. " uncertain"}, slot
elseif alternant_multiword_spec.slot_explicitly_missing[slot] then
return {label = "no " .. label}, slot
else
-- just say nothing about this slot
return nil, slot
end
end
local terms = get_slot_values()
if not slot_is_headword then
terms.label = label
end
return terms, slot
end
end
local gloss_parts = {}
for _, vform in ipairs(alternant_multiword_spec.verb_forms) do
insert(gloss_parts, "[[Appendix:Arabic verbs#Form " .. vform .. "|" .. vform .. "]]")
end
if gloss_parts[1] then
data.gloss = concat(gloss_parts, ", ")
end
if data.heads[1] and args.past then
error("Can't specify both head= and past= to {{ar-verb}}; prefer past=")
end
if not alternant_multiword_spec.has_active then
insert(data.inflections, {label = "passive-only"})
end
-- Do this always so `past_slot` is correctly filled.
local past, past_slot = do_slot(ar_verb.potential_lemma_slots, args.past, "-", "slot is headword")
if data.heads[1] then
-- user specified head=; don't override with past= or slot 'past_3sm' etc.
else
if past then
data.heads = past
end
end
local should_do_past1s = not not args.past1s
if not should_do_past1s then
local is_form_I = false
for _, vform in ipairs(alternant_multiword_spec.verb_forms) do
if vform == "I" then
is_form_I = true
break
end
end
if is_form_I then
require(inflection_utilities_module).map_word_specs(alternant_multiword_spec, function(base)
if base.verb_form == "I" then
for _, vowel_spec in ipairs(base.conj_vowels) do
-- For form-I geminate verbs, the final vowel of the past is elided in the citation form.
-- We want to display it for all cases other than active a~u and a~i (the most common
-- cases).
if vowel_spec.weakness == "geminate" then
if ar_verb.is_passive_only(base.passive) then
should_do_past1s = true
break
end
local past_vowel = ar_verb.rget(vowel_spec.past)
local nonpast_vowel = ar_verb.rget(vowel_spec.nonpast)
if not (past_vowel == ar.A and (nonpast_vowel == ar.U or nonpast_vowel == ar.I)) then
should_do_past1s = true
break
end
end
end
-- FIXME, provide way of breaking early from map_word_specs().
end
end)
end
end
local past1s
if should_do_past1s then
past1s, _ = do_slot({"past_1s", "past_pass_1s"}, args.past1s, "บุรุษที่หนึ่งเอกพจน์อดีตกาล")
if past1s then
insert(data.inflections, past1s)
end
end
local nonpast_slots
if not past_slot or past_slot:find("^past_") then
nonpast_slots = {"ind_3ms", "ind_pass_3ms", "imp_2ms"}
else
nonpast_slots = {}
end
local nonpast, _ = do_slot(nonpast_slots, args.nonpast, "ไม่ใช่อดีตกาล")
if nonpast then
insert(data.inflections, nonpast)
end
local vn, _ = do_slot({"vn"}, args.vn, "คำกริยานาม")
if vn then
insert(data.inflections, vn)
end
-- FIXME: Should we insert categories? Conjugation also does it and is more likely to be accurate.
--for _, cat in ipairs(alternant_multiword_spec.categories) do
-- insert(data.categories, cat)
--end
--[=[
-- FIXME: Review this to see if we need to port it.
-- If the user didn't explicitly specify head=, or specified exactly one head (not 2+) and we were able to
-- incorporate any links in that head into the 1= specification, use the infinitive generated by
-- [[Module:pt-verb]] in place of the user-specified or auto-generated head. This was copied from
-- [[Module:it-headword]], where doing this gets accents marked on the verb(s). We don't have accents marked on
-- the verb but by doing this we do get any footnotes on the infinitive propagated here. Don't do this if the
-- user gave multiple heads or gave a head with a multiword-linked verbal expression such as Italian
-- '[[dare esca]] [[al]] [[fuoco]]' (FIXME: give Portuguese equivalent).
if not data.user_specified_heads[1] or (
not data.user_specified_heads[2] and alternant_multiword_spec.incorporated_headword_head_into_lemma
) then
data.heads = {}
for _, lemma_obj in ipairs(alternant_multiword_spec.forms.infinitive_linked) do
local quals, refs = require(inflection_utilities_module).
convert_footnotes_to_qualifiers_and_references(lemma_obj.footnotes)
insert(data.heads, {term = lemma_obj.form, q = quals, refs = refs})
end
end
]=]
end
}
-----------------------------------------------------------------------------------------
-- Generic parts of speech --
-----------------------------------------------------------------------------------------
pos_functions.head_with_gender = {
params = function()
return {
[3] = {type = "genders"},
}
end,
func = function(data, args)
handle_gender(data, args, "nonlemma", 3)
end,
}
return export
6hss1fyjjzda89cji7jjwgb3c9lekjv
अल्जीरिया
0
54064
5775358
5719925
2026-10-15T06:54:50Z
स्वर्ण
18519
5775358
wikitext
text/x-wiki
== ภาษาฮินดี ==
{{wp|lang=hi}}
=== การออกเสียง ===
* {{hi-IPA}}
=== คำวิสามานยนาม ===
{{hi-proper noun|g=m|ur=الجیریا}}
# [[แอลจีเรีย]] (ประเทศในทวีปแอฟริกา)
#: {{syn|hi|अल-जज़ाइर}}
==== การผันรูป ====
{{hi-ndecl|<M.unmarked.sg>}}
{{topics|hi|ประเทศ}}
rvgqmatgcstpacj84qcoavmbrfqerhz
มอดูล:etymology
828
135442
5775359
5775200
2026-10-15T07:04:30Z
Octahedron80
267
5775359
Scribunto
text/plain
local export = {}
-- For testing
local force_cat = false
local debug_track_module = "Module:debug/track"
local languages_module = "Module:languages"
local links_module = "Module:links"
local table_module = "Module:table"
local utilities_module = "Module:utilities"
local concat = table.concat
local insert = table.insert
local new_title = mw.title.new
local function debug_track(...)
debug_track = require(debug_track_module)
return debug_track(...)
end
local function format_categories(...)
format_categories = require(utilities_module).format_categories
return format_categories(...)
end
local function full_link(...)
full_link = require(links_module).full_link
return full_link(...)
end
local function get_language_data_module_name(...)
get_language_data_module_name = require(languages_module).getDataModuleName
return get_language_data_module_name(...)
end
local function get_link_page(...)
get_link_page = require(links_module).get_link_page
return get_link_page(...)
end
local function language_link(...)
language_link = require(links_module).language_link
return language_link(...)
end
local function serial_comma_join(...)
serial_comma_join = require(table_module).serialCommaJoin
return serial_comma_join(...)
end
local function shallow_copy(...)
shallow_copy = require(table_module).shallowCopy
return shallow_copy(...)
end
local function track(page, code)
local tracking_page = "etymology/" .. page
debug_track(tracking_page)
if code then
debug_track(tracking_page .. "/" .. code)
end
end
local function join_segs(segs, conj)
if not segs[2] then
return segs[1]
elseif conj == "และ" or conj == "หรือ" then
return serial_comma_join(segs, {conj = conj})
end
local sep
if conj == "," or conj == ";" then
sep = conj .. " "
elseif conj == "/" then
sep = "/"
elseif conj == "~" then
sep = " ~ "
elseif conj then
error(("Internal error: Unrecognized conjunction \"%s\""):format(conj))
else
error(("Internal error: No value supplied for conjunction"):format(conj))
end
return concat(segs, sep)
end
-- Returns true if `lang` is the same as `source`, or a variety of it.
local function lang_is_source(lang, source)
return lang:getCode() == source:getCode() or lang:hasParent(source)
end
--[==[
Format one or more links as specified in `termobjs`, a list of term objects of the format accepted by `full_link()` in
[[Module:links]], including decorations (qualifiers, labels and references). `conj` is used to join multiple terms
and must be specified if there is more than one term. `template_name` is the template name used in debug tracking and
must be specified. Optional `sourcetext` is text to prepend to the concatenated terms, separated by a space if the
concatenated terms are non-empty (which is always the case unless there is a single term with the value "-"). If
`decorations_on_outside` is given, any decorations specified in the first term go on the outside of (i.e before)
`sourcetext`; otherwise they will end up on the inside.
]==]
function export.format_links(termobjs, conj, template_name, sourcetext, decorations_on_outside)
if not template_name then
error("Internal error: Must specify `template_name` to format_links()")
end
for i, termobj in ipairs(termobjs) do
if termobj.lang:hasType("family") or termobj.lang:getFamilyCode() == "qfa-sub" then
if termobj.term and termobj.term ~= "-" then
debug_track(template_name .. "/family-with-term")
end
termobj.term = "-"
end
if termobj.term == "-" then
--[=[
[[Special:WhatLinksHere/Wiktionary:Tracking/cognate/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/derived/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/borrowed/no-term]]
[[Special:WhatLinksHere/Wiktionary:Tracking/calque/no-term]]
]=]
debug_track(template_name .. "/no-term")
termobjs[i] = i == 1 and sourcetext or ""
else
if i == 1 and decorations_on_outside and sourcetext then
termobj.pretext = sourcetext .. " "
sourcetext = nil
end
termobjs[i] = (i == 1 and sourcetext and sourcetext .. " " or "") .. full_link(termobj, "term")
end
end
return join_segs(termobjs, conj)
end
function export.get_display_and_cat_name(source, raw)
local display, cat_name
if source:getCode() == "und" then
display = "ยังไม่กำหนด"
cat_name = "ภาษาอื่น"
elseif source:getCode() == "mul" then
display = raw and "ร่วม" or "[[w:ภาษาร่วม|ภาษาร่วม]]"
cat_name = "ภาษาร่วม"
elseif source:getCode() == "mul-tax" then
display = raw and "ชื่ออนุกรมวิธาน" or "[[w:การตั้งชื่อทวินาม|ชื่ออนุกรมวิธาน]]"
cat_name = "ชื่ออนุกรมวิธาน"
else
display = raw and source:getCanonicalName() or source:makeWikipediaLink()
cat_name = "ภาษา" .. source:getDisplayForm()
end
return display, cat_name
end
function export.insert_source_cat_get_display(data)
local categories, lang, source = data.categories, data.lang, data.source
local display, cat_name = export.get_display_and_cat_name(source, data.raw)
if lang and not data.nocat then
-- Add the category, but only if there is a current language
if not categories then
categories = {}
end
local langname = lang:getFullName()
-- If `lang` is an etym-only language, we need to check both it and its parent full language against `source`.
-- Otherwise if e.g. `lang` is Medieval Latin and `source` is Latin, we'll end up wrongly constructing a
-- category 'Latin terms derived from Latin'.
insert(categories, "ศัพท์ภาษา" .. langname .. (
lang_is_source(lang, source) and "ที่ยืมกลับไปยัง" .. cat_name or
"ที่" .. (data.borrowing_type or "รับมา") .. "จาก" .. cat_name
))
end
return display, categories
end
function export.format_source(data)
local lang, sort_key = data.lang, data.sort_key
-- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/sortkey]]
if sort_key then
track("sortkey")
end
local display, categories = export.insert_source_cat_get_display(data)
if lang and not data.nocat then
-- Format categories, but only if there is a current language; {{cog}} currently gets no categories
categories = format_categories(categories, lang, sort_key, nil, data.force_cat or force_cat)
else
categories = ""
end
return "<span class=\"etyl\">" .. display .. categories .. "</span>"
end
--[==[
Format sources for etymology templates such as {{tl|bor}}, {{tl|der}}, {{tl|inh}} and {{tl|cog}}. There may potentially
be more than one source language (except currently {{tl|inh}}, which doesn't support it because it doesn't really
make sense). In that case, all but the last source language is linked to the first term, but only if there is such a
term and this linking makes sense, i.e. either (1) the term page exists after stripping diacritics according to the
source language in question, or (2) the result of stripping diacritics according to the source language in question
results in a different page from the same process applied with the last source language. For example, {{m|ru|соля́нка}}
will link to [[солянка]] but {{m|en|соля́нка}} will link to [[соля́нка]] with an accent, and since they are different
pages, the use of English as a non-final source with term 'соля́нка' will link to [[соля́нка]] even though it doesn't
exist, on the assumption that it is merely a redlink that might exist. If none of the above criteria apply, a non-final
source language will be linked to the Wikipedia entry for the language, just as final source languages always are.
`data` contains the following fields:
* `lang`: The destination language object into which the terms were borrowed, inherited or otherwise derived. Used for
categorization and can be nil, as with {{tl|cog}}.
* `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are
handled specially; see above.
* `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as
multiple term objects, the non-final source objects link to the first term object.
* `sort_key`: Sort key for categories. Usually nil.
* `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source
languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be
added.
* `nocat`: Don't add any categories to the page.
* `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized
values are `and`, `or`, `,`, `;`, `/` and `~`.
* `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}.
* `force_cat`: Force category generation on non-mainspace pages.
]==]
function export.format_sources(data)
local lang, sources, terms, borrowing_type, sort_key, categories, nocat =
data.lang, data.sources, data.terms, data.borrowing_type, data.sort_key, data.categories, data.nocat
local term1, sources_n, source_segs = terms[1], #sources, {}
local final_link_page
local term1_term, term1_sc = term1.term, term1.sc
if sources_n > 1 and term1_term and term1_term ~= "-" then
final_link_page = get_link_page(term1_term, sources[sources_n], term1_sc)
end
for i, source in ipairs(sources) do
local seg, display_term
if i < sources_n and term1_term and term1_term ~= "-" then
local link_page = get_link_page(term1_term, source, term1_sc)
display_term = (link_page ~= final_link_page) or (link_page and not not new_title(link_page):getContent())
end
-- TODO: if the display forms or transliterations are different, display the terms separately.
if display_term then
local display, this_cats = export.insert_source_cat_get_display{
lang = lang,
source = source,
borrowing_type = borrowing_type,
raw = true,
categories = categories,
nocat = nocat,
}
seg = language_link {
lang = source,
term = term1_term,
alt = display,
tr = "-",
}
if lang and not nocat then
-- Format categories, but only if there is a current language; {{cog}} currently gets no categories
this_cats = format_categories(this_cats, lang, sort_key, nil, data.force_cat or force_cat)
else
this_cats = ""
end
seg = "<span class=\"etyl\">" .. seg .. this_cats .. "</span>"
else
seg = export.format_source{
lang = lang,
source = source,
borrowing_type = borrowing_type,
sort_key = sort_key,
categories = categories,
nocat = nocat,
}
end
insert(source_segs, seg)
end
return join_segs(source_segs, data.sourceconj or "และ")
end
-- Internal implementation of {{cognate}}/{{cog}} template.
function export.format_cognate(data)
return export.format_derived {
sources = data.sources,
terms = data.terms,
sort_key = data.sort_key,
sourceconj = data.sourceconj,
conj = data.conj,
template_name = "cognate",
force_cat = data.force_cat,
}
end
--[==[
Internal implementation of {{derived}}/{{der}} template. This is called externally from [[Module:affix]],
[[Module:affixusex]] and [[Module:see]] and needs to support decorations (qualifiers, labels and references) on the
outside of the sources for use by those modules.
`data` contains the following fields:
* `lang`: The destination language object into which the terms were derived. Used for categorization and can be nil, as
with {{tl|cog}}; in this case, no categories are added.
* `sources`: List of source objects. Most commonly there is only one. If there are multiple, the non-final ones are
handled specially; see `format_sources()`.
* `terms`: List of term objects. Most commonly there is only one. If there are multiple source objects as well as
multiple term objects, the non-final source objects link to the first term object.
* `conj`: Conjunction used to separate multiple terms. '''Required'''. Currently recognized values are `and`, `or`, `,`,
`;`, `/` and `~`.
* `sourceconj`: Conjunction used to separate multiple source languages. Defaults to {"and"}. Currently recognized
values are as for `conj` above.
* `decorations_on_outside`: If specified, any decorations (qualifiers, labels or references) in the first term in
`terms` will be displayed on the outside of (before) the source language(s) in `sources`. Normally this should be
specified if there is only one term possible in `terms`.
* `template_name`: Name of the template invoking this function. Must be specified. Only used for tracking pages.
* `sort_key`: Sort key for categories. Usually nil.
* `categories`: Categories to add to the page. Additional categories may be added to `categories` based on the source
languages ('''in which case `categories` is destructively modified'''). If `lang` is nil, no categories will be
added.
* `nocat`: Don't add any categories to the page.
* `borrowing_type`: Borrowing type used in categories, such as {"learned borrowings"}. Defaults to {"terms derived"}.
* `force_cat`: Force category generation on non-mainspace pages.
]==]
function export.format_derived(data)
local terms = data.terms
local sourcetext = export.format_sources(data)
return export.format_links(terms, data.conj, data.template_name, sourcetext, data.decorations_on_outside)
end
function export.insert_borrowed_cat(categories, lang, source)
if lang_is_source(lang, source) then
return
end
-- If both are the same, we want e.g. [[:Category:English terms borrowed back into English]] not
-- [[:Category:English terms borrowed from English]]; the former is inserted automatically by format_source().
-- The second parameter here doesn't matter as it only affects `display`, which we don't use.
insert(categories, "ศัพท์ภาษา" .. lang:getFullName() .. "ที่ยืมมาจาก" .. select(2, export.get_display_and_cat_name(source, "raw")))
end
-- Internal implementation of {{borrowed}}/{{bor}} template.
function export.format_borrowed(data)
local categories = {}
if not data.nocat then
local lang = data.lang
for _, source in ipairs(data.sources) do
export.insert_borrowed_cat(categories, lang, source)
end
end
data = shallow_copy(data)
data.categories = categories
return export.format_links(data.terms, data.conj, "borrowed", export.format_sources(data))
end
do
-- Generate the non-ancestor error message.
local function show_language(lang)
local retval = ("%s (%s)"):format(lang:makeCategoryLink(), lang:getCode())
if lang:hasType("etymology-only") then
retval = retval .. (" (an etymology-only language whose regular parent is %s)"):format(
show_language(lang:getParent()))
end
return retval
end
-- Check that `lang` has `otherlang` (which may be an etymology-only language) as an ancestor. Throw an error if
-- not. When `lang` is a family, verifies that `otherlang` is a language in that family.
function export.check_ancestor(lang, otherlang)
-- When `lang` is a family, verify `otherlang` is in that family or in its parent family.
if lang.hasType and lang:hasType("family") then
local family_code = lang:getCode()
local function in_family_code(fcode, other)
if not fcode or fcode == "" then return false end
if other.inFamily and other:inFamily(fcode) then return true end
if other.getFamilyCode and other:getFamilyCode() == fcode then return true end
return false
end
local in_family = in_family_code(family_code, otherlang)
if not in_family then
local parent_code
if lang.getParent then
local parent_family = lang:getParent()
if parent_family and parent_family.getCode then
parent_code = parent_family:getCode()
end
end
if not parent_code and family_code:find("-", 1, true) then
parent_code = family_code:match("^(.+)-[^-]+$")
end
if parent_code then
in_family = in_family_code(parent_code, otherlang)
end
end
if not in_family then
local other_display = (otherlang.getCanonicalName and otherlang:getCanonicalName()) or (otherlang.getCode and otherlang:getCode()) or tostring(otherlang)
local fam_display = (lang.getCanonicalName and lang:getCanonicalName()) or family_code
error(("%s is not in family %s; inherited ancestor under a family must be a language in that family or its parent family.")
:format(other_display, fam_display))
end
return
end
-- FIXME: I don't know if this function works correctly with etym-only languages in `lang`. I have fixed up
-- the module link code appropriately (June 2024) but the remaining logic is untouched.
if lang:hasAncestor(otherlang) then
-- [[Special:WhatLinksHere/Wiktionary:Tracking/etymology/variety]]
-- Track inheritance from varieties of Latin that shouldn't have any descendants (everything except Old Latin, Classical Latin and Vulgar Latin).
if otherlang:getFullCode() == "la" then
otherlang = otherlang:getCode()
if not (otherlang == "itc-ola" or otherlang == "la-cla" or otherlang == "la-vul") then
track("bad ancestor", otherlang)
end
end
return
end
local ancestors = lang:getAncestors()
local postscript
local etym_module_link = lang:hasType("etymology-only") and "[[Module:etymology languages/data]] or " or ""
local module_link = "[[" .. get_language_data_module_name(lang:getFullCode()) .. "]]"
if not ancestors[1] then
postscript = show_language(lang) .. " has no ancestors."
else
local ancestor_list = {}
for _, ancestor in ipairs(ancestors) do
insert(ancestor_list, show_language(ancestor))
end
postscript = ("The ancestor%s of %s %s %s."):format(
ancestors[2] and "s" or "", lang:getCanonicalName(),
ancestors[2] and "are" or "is", concat(ancestor_list, " and "))
end
error(("%s is not set as an ancestor of %s in %s%s. %s")
:format(show_language(otherlang), show_language(lang), etym_module_link, module_link, postscript))
end
end
-- Internal implementation of {{inherited}}/{{inh}} template.
function export.format_inherited(data)
local lang, terms, nocat = data.lang, data.terms, data.nocat
local source = terms[1].lang
local categories = {}
if not nocat then
insert(categories, "ศัพท์ภาษา" .. lang:getFullName() .. "ที่สืบทอดจากภาษา" .. source:getCanonicalName())
end
export.check_ancestor(lang, source)
data = shallow_copy(data)
data.categories = categories
data.source = source
return export.format_links(terms, data.conj, "inherited", export.format_source(data))
end
-- Internal implementation of "misc variant" templates such as {{abbrev}}, {{clipping}}, {{reduplication}} and the like.
function export.format_misc_variant(data)
local lang, notext, terms, cats, parts = data.lang, data.notext, data.terms, data.cats, {}
if not notext then
insert(parts, data.text)
end
if terms[1] then
if not notext then
-- FIXME: If term is given as '-', we should consider displaying just "Clipping" not "Clipping of".
insert(parts, data.oftext or "ของ") --th
end
local termparts = {}
-- Make links out of all the parts.
for _, termobj in ipairs(terms) do
local result
if termobj.lang then
result = export.format_derived {
lang = lang,
terms = {termobj},
sources = termobj.termlangs or {termobj.lang},
template_name = "misc_variant",
decorations_on_outside = true,
force_cat = data.force_cat,
}
else
termobj.lang = lang
result = export.format_links({termobj}, nil, "misc_variant")
end
table.insert(termparts, result)
end
local linktext = join_segs(termparts, data.conj)
if not notext and linktext ~= "" then
insert(parts, " ")
end
insert(parts, linktext)
end
local categories = {}
if not data.nocat and cats then
for _, cat in ipairs(cats) do
--insert(categories, lang:getFullName() .. " " .. cat)
insert(categories, require("Module:th-utilities").th_categorize(cat, lang:getCategoryName())) --th
end
end
if categories[1] then
insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat))
end
return concat(parts)
end
-- Implementation of miscellaneous templates such as {{unknown}} and {{onomatopoeia}} that have no associated terms.
function export.format_misc_variant_no_term(data)
local parts = {}
if not data.notext then
insert(parts, data.title)
end
if not data.nocat and data.cat then
local lang, categories = data.lang, {}
--insert(categories, lang:getFullName() .. " " .. data.cat)
insert(categories, require("Module:th-utilities").th_categorize(data.cat, lang:getCategoryName())) --th
insert(parts, format_categories(categories, lang, data.sort_key, nil, data.force_cat or force_cat))
end
return concat(parts)
end
return export
cijdl75gr6acdn6dfuqsuk0zfa8o80h
มอดูล:scripts/canonical names
828
137426
5775307
5775296
2026-10-14T13:06:28Z
Octahedron80
267
5775307
Scribunto
text/plain
return {
["Ancient North Arabian"] = "Narb",
["Ancient South Arabian"] = "Sarb",
["Blissymbolic"] = "Blis",
["Canadian syllabic"] = "Cans",
["Caucasian Albanian"] = "Aghb",
["Chisoi"] = "Chis",
["Clear Script"] = "xwo-Mong",
["Cypro-Minoan"] = "Cpmn",
["Demotic"] = "Egyd",
["Deseret"] = "Dsrt",
["Dongba"] = "Nkdb",
["Duployan"] = "Dupl",
["Elymaic"] = "Elym",
["Garay"] = "Gara",
["Geba"] = "Nkgb",
["Hatran"] = "Hatr",
["Hieratic"] = "Egyh",
["Image-rendered"] = "Image",
["พาร์เทียจารึก"] = "Prti",
["Khema"] = "Gukh",
["Khojki"] = "Khoj",
["Khutsuri"] = "Geok",
["ฆวารัซม์"] = "Chrs",
["Kirat Rai"] = "Krai",
["Kpelle"] = "Kpel",
["Kulitan"] = "Kulit",
["Leke"] = "Leke",
["Loma"] = "Loma",
["Manichaean"] = "Mani",
["Marchen"] = "Marc",
["Medefaidrin"] = "Medf",
["Mende"] = "Mend",
["Meroitic cursive"] = "Merc",
["Meroitic hieroglyphic"] = "Mero",
["Moon"] = "Moon",
["Multani"] = "Mult",
["Mundari Bani"] = "Nagm",
["N'Ko"] = "Nkoo",
["Nabataean"] = "Nbat",
["Newa"] = "Newa",
["Nyiakeng Puachue Hmong"] = "Hmnp",
["Nüshu"] = "Nshu",
["Ogham"] = "Ogam",
["Ol Onal"] = "Onao",
["Old Permic"] = "Perm",
["Old Turkic"] = "Orkh",
["Osage"] = "Osge",
["Pahawh Hmong"] = "Hmng",
["แพลไมรา"] = "Palm",
["Pau Cin Hau"] = "Pauc",
["Pazend"] = "pal-Avst",
["Phags-pa"] = "Phag",
["Pollard"] = "Plrd",
["Proto-Cuneiform"] = "Pcun",
["Proto-Elamite"] = "Pelm",
["Proto-Sinaitic"] = "Psin",
["Ranjana"] = "Ranj",
["Rejang"] = "Rjng",
["Rongorongo"] = "Roro",
["Rumi numerals"] = "Rumin",
["Samaritan"] = "Samr",
["Saurashtra"] = "Saur",
["Shavian"] = "Shaw",
["Sidetic"] = "Sidt",
["SignWriting"] = "Sgnw",
["Sorang Sompeng"] = "Sora",
["Soyombo"] = "Soyo",
["Sui"] = "Shui",
["Sunuwar"] = "Sunu",
["Tangsa"] = "Tnsa",
["Tigalari"] = "Tutg",
["Todhri"] = "Todr",
["Tolong Siki"] = "Tols",
["Toto"] = "Toto",
["Visible Speech"] = "Visp",
["Vithkuqi"] = "Vith",
["Wancho"] = "Wcho",
["Woleai"] = "Wole",
["Yezidi"] = "Yezi",
["Zanabazar Square"] = "Zanb",
["Znamenny musical notation"] = "Zname",
["mathematical notation"] = "Zmth",
["กรีก"] = "Grek",
["กลาโกลิติก"] = "Glag",
["กวิ"] = "Kawi",
["กอท"] = "Goth",
["กะยา"] = "Kali",
["กันนฑะ"] = "Knda",
["ขอมไทย"] = "Khomt",
["ขุทาพาที"] = "Sind",
["ขโรษฐี"] = "Khar",
["ครันถะ"] = "Gran",
["คอปติก"] = "Copt",
["คาตากานะ"] = "Kana",
["คานะ"] = "Hrkt",
["คาเรีย"] = "Cari",
["คีตันเล็ก"] = "Kits",
["คีตันใหญ่"] = "Kitl",
["คุชราต"] = "Gujr",
["คุญชลาโคณฑี"] = "Gong",
["คุรมุขี"] = "Guru",
["คูนิฟอร์ม"] = "Xsux",
["จอร์เจีย"] = "Geor",
["จักมา"] = "Cakm",
["จาม"] = "Cham",
["จีน"] = "Hani",
["จีนตัวย่อ"] = "Hans",
["จีนตัวเต็ม"] = "Hant",
["จูร์เชน"] = "Jurc",
["จู้อิน"] = "Bopo",
["ชวา"] = "Java",
["ซอกเดีย"] = "Sogd",
["ซอกเดียเก่า"] = "Sogo",
["ซิเบ"] = "sjo-Mong",
["ซีริลลิก"] = "Cyrl",
["ซีริลลิกเก่า"] = "Cyrs",
["ซีรีแอก"] = "Syrc",
["ซุนดา"] = "Sund",
["ญี่ปุ่น"] = "Jpan",
["ฏากรี"] = "Takr",
["ดิเวส อกุรุ"] = "Diak",
["ตักบันวา"] = "Tagb",
["ตังกุต"] = "Tang",
["ตัมยิก"] = "sit-tam-Tibt",
["ติรหุตา"] = "Tirh",
["ทมิฬ"] = "Taml",
["ทานะ"] = "Thaa",
["ทิฟินาค"] = "Tfng",
["ทิเบต"] = "Tibt",
["นันทินาครี"] = "Nand",
["บัสซา"] = "Bass",
["บาตัก"] = "Batk",
["บามุม"] = "Bamu",
["บาหลี"] = "Bali",
["บูฮิด"] = "Buhd",
["ปาห์ลาวีคัมภีร์"] = "Phlv",
["ปาห์ลาวีจารึก"] = "Phli",
["ปาห์ลาวีเพลงสดุดี"] = "Phlp",
["พม่า"] = "Mymr",
["พราหมี"] = "Brah",
["ฟรักทูร์"] = "Latf",
["ฟินิเชีย"] = "Phnx",
["มณีปุระ"] = "Mtei",
["มรู"] = "Mroo",
["มลยาฬัม"] = "Mlym",
["มสรามโคณฑี"] = "Gonm",
["มหาชนี"] = "Mahj",
["มองโกเลีย"] = "Mong",
["มันดาอิก"] = "Mand",
["มากัซซาร์"] = "Maka",
["มายา"] = "Maya",
["ยังไม่กำหนด"] = "Zyyy",
["ยังไม่มีรหัส"] = "Zzzz",
["ยูการิต"] = "Ugar",
["รหัสมอร์ส"] = "Morse",
["รูน"] = "Runr",
["ลนตารา"] = "Bugi",
["ละติน"] = "Latn",
["ลายตัย"] = "Tayo",
["ลาว"] = "Laoo",
["ลิมบู"] = "Limb",
["ลิเชีย"] = "Lyci",
["ลิเดีย"] = "Lydi",
["ลิเนียร์บี"] = "Linb",
["ลิเนียร์เอ"] = "Lina",
["ลีสู่"] = "Lisu",
["วรังจิติ"] = "Wara",
["ศารทา"] = "Shrd",
["ศาหมุขี"] = "pa-Arab",
["สัญกรณ์ดนตรี"] = "Music",
["สัญญาณธง"] = "Semap",
["สัญลักษณ์"] = "Zsym",
["สัทอักษรสากล"] = "Ipach",
["สิงหล"] = "Sinh",
["สิทธัม"] = "Sidd",
["สินธุ"] = "Inds",
["สิเลฏินาครี"] = "Sylo",
["อัดลัม"] = "Adlm",
["อัสสัม"] = "as-Beng",
["อาฟากา"] = "Afak",
["อาร์มีเนีย"] = "Armn",
["อาหม"] = "Ahom",
["อาหรับ"] = "Arab",
["อิตาลิกเก่า"] = "Ital",
["อี๋"] = "Yiii",
["อุยกูร์เก่า"] = "Ougr",
["อุสมาน"] = "Osma",
["อเวสตะ"] = "Avst",
["อ็อลจิกิ"] = "Olck",
["ฮังการีเก่า"] = "Hung",
["ฮันกึล"] = "Hang",
["ฮานิฟ"] = "Rohg",
["ฮานูโนโอ"] = "Hano",
["ฮิรางานะ"] = "Hira",
["ฮีบรู"] = "Hebr",
["เกาหลี"] = "Kore",
["เขมร"] = "Khmr",
["เชโรกี"] = "Cher",
["เตลูกู"] = "Telu",
["เทงกวาร์"] = "Teng",
["เทวนาครี"] = "Deva",
["เบงกอล"] = "Beng",
["เบรลล์"] = "Brai",
["เปอร์เซียเก่า"] = "Xpeo",
["เลปชา"] = "Lepc",
["เอธิโอเปีย"] = "Ethi",
["เอลบาซาน"] = "Elba",
["แกลิก"] = "Latg",
["แมนจู"] = "mnc-Mong",
["แอราเมอิกจักรวรรดิ"] = "Armi",
["โฑครี"] = "Dogr",
["โมฑี"] = "Modi",
["โอริยา"] = "Orya",
["ไกถี"] = "Kthi",
["ไซปรัส"] = "Cprt",
["ไทธรรม"] = "Lana",
["ไทย"] = "Thai",
["ไทลื้อใหม่"] = "Talu",
["ไทเวียด"] = "Tavt",
["ไทใต้คง"] = "Tale",
["ไบบายิน"] = "Tglg",
["ไภกษุกี"] = "Bhks",
["ไม่ระบุ"] = "None",
["ไว"] = "Vaii",
["ไอบีเรียตะวันออกเฉียงเหนือ"] = "Ibrnn",
["ไอบีเรียตะวันออกเฉียงใต้"] = "Ibrns",
["ไฮเออโรกลีฟอานาโตเลีย"] = "Hluw",
["ไฮเออโรกลีฟอียิปต์"] = "Egyp",
}
c1sgnlqnkubcqs7nt2o109jrk5dihza
มอดูล:scripts/code to canonical name
828
211722
5775308
5775297
2026-10-14T13:06:33Z
Octahedron80
267
5775308
Scribunto
text/plain
return {
["Adlm"] = "อัดลัม",
["Afak"] = "อาฟากา",
["Aghb"] = "Caucasian Albanian",
["Ahom"] = "อาหม",
["Arab"] = "อาหรับ",
["Armi"] = "แอราเมอิกจักรวรรดิ",
["Armn"] = "อาร์มีเนีย",
["Avst"] = "อเวสตะ",
["Bali"] = "บาหลี",
["Bamu"] = "บามุม",
["Bass"] = "บัสซา",
["Batk"] = "บาตัก",
["Beng"] = "เบงกอล",
["Bhks"] = "ไภกษุกี",
["Blis"] = "Blissymbolic",
["Bopo"] = "จู้อิน",
["Brah"] = "พราหมี",
["Brai"] = "เบรลล์",
["Bugi"] = "ลนตารา",
["Buhd"] = "บูฮิด",
["Cakm"] = "จักมา",
["Cans"] = "Canadian syllabic",
["Cari"] = "คาเรีย",
["Cham"] = "จาม",
["Cher"] = "เชโรกี",
["Chis"] = "Chisoi",
["Chrs"] = "ฆวารัซม์",
["Copt"] = "คอปติก",
["Cpmn"] = "Cypro-Minoan",
["Cprt"] = "ไซปรัส",
["Cyrl"] = "ซีริลลิก",
["Cyrs"] = "ซีริลลิกเก่า",
["Deva"] = "เทวนาครี",
["Diak"] = "ดิเวส อกุรุ",
["Dogr"] = "โฑครี",
["Dsrt"] = "Deseret",
["Dupl"] = "Duployan",
["Egyd"] = "Demotic",
["Egyh"] = "Hieratic",
["Egyp"] = "ไฮเออโรกลีฟอียิปต์",
["Elba"] = "เอลบาซาน",
["Elym"] = "Elymaic",
["Ethi"] = "เอธิโอเปีย",
["Gara"] = "Garay",
["Geok"] = "Khutsuri",
["Geor"] = "จอร์เจีย",
["Glag"] = "กลาโกลิติก",
["Gong"] = "คุญชลาโคณฑี",
["Gonm"] = "มสรามโคณฑี",
["Goth"] = "กอท",
["Gran"] = "ครันถะ",
["Grek"] = "กรีก",
["Gujr"] = "คุชราต",
["Gukh"] = "Khema",
["Guru"] = "คุรมุขี",
["Hang"] = "ฮันกึล",
["Hani"] = "จีน",
["Hano"] = "ฮานูโนโอ",
["Hans"] = "จีนตัวย่อ",
["Hant"] = "จีนตัวเต็ม",
["Hatr"] = "Hatran",
["Hebr"] = "ฮีบรู",
["Hira"] = "ฮิรางานะ",
["Hluw"] = "ไฮเออโรกลีฟอานาโตเลีย",
["Hmng"] = "Pahawh Hmong",
["Hmnp"] = "Nyiakeng Puachue Hmong",
["Hrkt"] = "คานะ",
["Hung"] = "ฮังการีเก่า",
["Ibrnn"] = "ไอบีเรียตะวันออกเฉียงเหนือ",
["Ibrns"] = "ไอบีเรียตะวันออกเฉียงใต้",
["Image"] = "Image-rendered",
["Inds"] = "สินธุ",
["Ipach"] = "สัทอักษรสากล",
["Ital"] = "อิตาลิกเก่า",
["Java"] = "ชวา",
["Jpan"] = "ญี่ปุ่น",
["Jurc"] = "จูร์เชน",
["Kali"] = "กะยา",
["Kana"] = "คาตากานะ",
["Kawi"] = "กวิ",
["Khar"] = "ขโรษฐี",
["Khmr"] = "เขมร",
["Khoj"] = "Khojki",
["Khomt"] = "ขอมไทย",
["Kitl"] = "คีตันใหญ่",
["Kits"] = "คีตันเล็ก",
["Knda"] = "กันนฑะ",
["Kore"] = "เกาหลี",
["Kpel"] = "Kpelle",
["Krai"] = "Kirat Rai",
["Kthi"] = "ไกถี",
["Kulit"] = "Kulitan",
["Lana"] = "ไทธรรม",
["Laoo"] = "ลาว",
["Latf"] = "ฟรักทูร์",
["Latg"] = "แกลิก",
["Latn"] = "ละติน",
["Leke"] = "Leke",
["Lepc"] = "เลปชา",
["Limb"] = "ลิมบู",
["Lina"] = "ลิเนียร์เอ",
["Linb"] = "ลิเนียร์บี",
["Lisu"] = "ลีสู่",
["Loma"] = "Loma",
["Lyci"] = "ลิเชีย",
["Lydi"] = "ลิเดีย",
["Mahj"] = "มหาชนี",
["Maka"] = "มากัซซาร์",
["Mand"] = "มันดาอิก",
["Mani"] = "Manichaean",
["Marc"] = "Marchen",
["Maya"] = "มายา",
["Medf"] = "Medefaidrin",
["Mend"] = "Mende",
["Merc"] = "Meroitic cursive",
["Mero"] = "Meroitic hieroglyphic",
["Mlym"] = "มลยาฬัม",
["Modi"] = "โมฑี",
["Mong"] = "มองโกเลีย",
["Moon"] = "Moon",
["Morse"] = "รหัสมอร์ส",
["Mroo"] = "มรู",
["Mtei"] = "มณีปุระ",
["Mult"] = "Multani",
["Music"] = "สัญกรณ์ดนตรี",
["Mymr"] = "พม่า",
["Nagm"] = "Mundari Bani",
["Nand"] = "นันทินาครี",
["Narb"] = "Ancient North Arabian",
["Nbat"] = "Nabataean",
["Newa"] = "Newa",
["Nkdb"] = "Dongba",
["Nkgb"] = "Geba",
["Nkoo"] = "N'Ko",
["None"] = "ไม่ระบุ",
["Nshu"] = "Nüshu",
["Ogam"] = "Ogham",
["Olck"] = "อ็อลจิกิ",
["Onao"] = "Ol Onal",
["Orkh"] = "Old Turkic",
["Orya"] = "โอริยา",
["Osge"] = "Osage",
["Osma"] = "อุสมาน",
["Ougr"] = "อุยกูร์เก่า",
["Palm"] = "แพลไมรา",
["Pauc"] = "Pau Cin Hau",
["Pcun"] = "Proto-Cuneiform",
["Pelm"] = "Proto-Elamite",
["Perm"] = "Old Permic",
["Phag"] = "Phags-pa",
["Phli"] = "ปาห์ลาวีจารึก",
["Phlp"] = "ปาห์ลาวีเพลงสดุดี",
["Phlv"] = "ปาห์ลาวีคัมภีร์",
["Phnx"] = "ฟินิเชีย",
["Plrd"] = "Pollard",
["Polyt"] = "กรีก",
["Prti"] = "พาร์เทียจารึก",
["Psin"] = "Proto-Sinaitic",
["Ranj"] = "Ranjana",
["Rjng"] = "Rejang",
["Rohg"] = "ฮานิฟ",
["Roro"] = "Rongorongo",
["Rumin"] = "Rumi numerals",
["Runr"] = "รูน",
["Samr"] = "Samaritan",
["Sarb"] = "Ancient South Arabian",
["Saur"] = "Saurashtra",
["Semap"] = "สัญญาณธง",
["Sgnw"] = "SignWriting",
["Shaw"] = "Shavian",
["Shrd"] = "ศารทา",
["Shui"] = "Sui",
["Sidd"] = "สิทธัม",
["Sidt"] = "Sidetic",
["Sind"] = "ขุทาพาที",
["Sinh"] = "สิงหล",
["Sogd"] = "ซอกเดีย",
["Sogo"] = "ซอกเดียเก่า",
["Sora"] = "Sorang Sompeng",
["Soyo"] = "Soyombo",
["Sund"] = "ซุนดา",
["Sunu"] = "Sunuwar",
["Sylo"] = "สิเลฏินาครี",
["Syrc"] = "ซีรีแอก",
["Tagb"] = "ตักบันวา",
["Takr"] = "ฏากรี",
["Tale"] = "ไทใต้คง",
["Talu"] = "ไทลื้อใหม่",
["Taml"] = "ทมิฬ",
["Tang"] = "ตังกุต",
["Tavt"] = "ไทเวียด",
["Tayo"] = "ลายตัย",
["Telu"] = "เตลูกู",
["Teng"] = "เทงกวาร์",
["Tfng"] = "ทิฟินาค",
["Tglg"] = "ไบบายิน",
["Thaa"] = "ทานะ",
["Thai"] = "ไทย",
["Tibt"] = "ทิเบต",
["Tirh"] = "ติรหุตา",
["Tnsa"] = "Tangsa",
["Todr"] = "Todhri",
["Tols"] = "Tolong Siki",
["Toto"] = "Toto",
["Tutg"] = "Tigalari",
["Ugar"] = "ยูการิต",
["Vaii"] = "ไว",
["Visp"] = "Visible Speech",
["Vith"] = "Vithkuqi",
["Wara"] = "วรังจิติ",
["Wcho"] = "Wancho",
["Wole"] = "Woleai",
["Xpeo"] = "เปอร์เซียเก่า",
["Xsux"] = "คูนิฟอร์ม",
["Yezi"] = "Yezidi",
["Yiii"] = "อี๋",
["Zanb"] = "Zanabazar Square",
["Zmth"] = "mathematical notation",
["Zname"] = "Znamenny musical notation",
["Zsym"] = "สัญลักษณ์",
["Zyyy"] = "ยังไม่กำหนด",
["Zzzz"] = "ยังไม่มีรหัส",
["as-Beng"] = "อัสสัม",
["fa-Arab"] = "อาหรับ",
["kk-Arab"] = "อาหรับ",
["ks-Arab"] = "อาหรับ",
["ku-Arab"] = "อาหรับ",
["mnc-Mong"] = "แมนจู",
["ms-Arab"] = "อาหรับ",
["mzn-Arab"] = "อาหรับ",
["ota-Arab"] = "อาหรับ",
["pa-Arab"] = "ศาหมุขี",
["pal-Avst"] = "Pazend",
["pjt-Latn"] = "ละติน",
["ps-Arab"] = "อาหรับ",
["sd-Arab"] = "อาหรับ",
["sit-tam-Tibt"] = "ตัมยิก",
["sjo-Mong"] = "ซิเบ",
["tt-Arab"] = "อาหรับ",
["ug-Arab"] = "อาหรับ",
["ur-Arab"] = "อาหรับ",
["xwo-Mong"] = "Clear Script",
}
iz8fbxgwq98x6hw4lrnz1qiu74x8w6l
มอดูล:es-pronunc
828
232274
5775365
3018739
2026-10-15T07:57:32Z
Octahedron80
267
5775365
Scribunto
text/plain
--[=[
This module implements the templates {{es-pr}} and {{es-IPA}}.
Author: Benwing2
]=]
local export = {}
local m_IPA = require("Module:IPA")
local m_str_utils = require("Module:string utilities")
local m_table = require("Module:table")
local audio_module = "Module:audio"
local decorations_module = "Module:decorations"
local headword_data_module = "Module:headword/data"
local homophones_module = "Module:homophones"
local hyphenation_module = "Module:hyphenation"
local labels_module = "Module:labels"
local links_module = "Module:links"
local parameters_module = "Module:parameters"
local parse_utilities_module = "Module:parse utilities"
local references_module = "Module:references"
local rhymes_module = "Module:rhymes"
local force_cat = false -- for testing
--[=[
FIXME:
1. Port latest changes to production module. [DONE]
2. Finish work on rhymes and hyphenation. [DONE]
3. Handle <hmp:...> for homophones. [DONE]
4. Don't add comma before phonetic IPA. [DONE]
5. Handle secondary stress, suffixes, etc. in syllabification. [DONE]
6. Need some changes to syllable splitting in consonant clusters. (e.g. 'cum‧min‧gto‧ni‧ta') [DONE]
7. Fix handling of references to correspond to Portuguese module. [DONE]
8. Propagate qualifiers on individual pronun terms to rhymes and hyph.
9. Support raw phonemic/phonetic pronunciations. [DONE]
10. Support overall audio. [DONE]
11. Keep th/ph/kh/gh/tz ([[Ertzaintza]]) together when syllabifying (but not bh due to [[subhumano]], [[subhistoria]], etc.). [DONE]
12. Support <q:...> and <qq:...> on audio. [DONE]
13. Support <a:...> and <aa:...> (using {{a|...}}, left and right) on terms, rhymes, hyphenation, homophones and
audio. [DONE]
14. Support # instead of ; as separator between audio file and gloss and make sure it works if gloss has embedded # or
;. [DONE]
15. Use parse_inline_modifiers() in [[Module:parse utilities]]. [DONE]
]=]
--[=[
About styles, dialects and isoglosses:
From the standpoint of pronunciation, a given dialect is defined by isoglosses, which specify differences
in the way of pronouncing certain phonemes. You can think of a dialect as a collection of isoglosses.
For example, one isogloss is "distinción" (pronouncing written ''s'' and ''c/z'' differently) vs. "seseo"
(pronouncing them the same). Another is "lleísmo" (pronouncing written ''ll'' and ''y'' differently) vs.
"yeísmo" (pronouncing them the same). The dominant pronunciation in Spain can be described as
distinción + yeísmo, while the pronunciation in rural northern Spain can be described as distinción + lleísmo
and the pronunciation across much of the Andes mountains, Paraguay, and the Philippines can be described as seseo + lleísmo.
Specifically, the following isoglosses are recognized (note, the isogloss specs as used in this module
dispense with written accents):
-- "distincion" = pronouncing ''s'' and ''c/z'' differently
-- "seseo" = pronouncing ''s'' and ''c/z'' the same
-- "lleismo" = pronouncing ''ll'' and ''y'' differently
-- "yeismo" = pronouncing ''ll'' and ''y'' the same
-- "rioplatense" = Rioplatense speech, i.e. seseo+yeismo with ''ll'' and ''y'' pronounced specially, and a
clear distinction between initial ''hi-'' vs. initial ''ll-/y-''
-- "sheismo" = a type of Rioplatense speech, characteristic of Buenos Aires, where ''ll'' and ''y'' are
pronounced as /ʃ/
-- "zheismo" = a type of Rioplatense speech, found outside of Buenos Aires, where ''ll'' and ''y'' are
pronounced as /ʒ/
-- "quito" = seseo + lleismo, but pronouncing ''ll'' as /ʒ/
-- "yucatan" = seseo + yeismo, intervocalic ''y'' is pronounced ''i'' and lost in contact with ''i'' or ''e''
These isoglosses can be combined to yield one of the following eight dialects:
-- "distincion-lleismo": distinción + lleísmo
-- "distincion-yeismo": distinción + yeísmo
-- "seseo-lleismo": seseo + lleísmo
-- "seseo-yeismo": seseo + yeísmo
-- "rioplatense-sheismo": Rioplatense with /ʃ/ (Buenos Aires)
-- "rioplatense-zheismo": Rioplatense with /ʒ/ (non-Buenos Aires)
-- "quito"
-- "yucatan"
A "style" here is a set of dialects that pronounce a given word in a given fashion. For example, if we are only
considering the distinción/seseo and lleísmo/yeísmo isoglosses, there are four conceivable dialects (all of
which in fact exist). However, for a given word, more than one dialect may pronounce it the same. For
example, a word like [[paz]] has a ''z'' but no ''ll'', and so there are only two possible pronunciations for
the four dialects. Here, the two styles are "Spain" and "Latin America". Correspondingly, a word like [[pollo]]
with an ''ll'' but no ''z'' has two styles, which can approximately be described as "most of Spain and Latin
America" vs. "rural northern Spain, Andes Mountains, Paraguay, Philippines".
A "style spec" (indicated by the style= parameter to {{es-IPA}}) restricts the output to certain styles.
A style spec can be one of the following:
1. An isogloss, e.g. "distincion", "rioplatense"; if specified, only styles containing this isogloss are output.
2. A negated isogloss, e.g. "-rioplatense".
3. An intersection of isoglosses ("A and B"), e.g. "distincion+lleismo". This can be used to restrict to specific
dialects.
4. A union of isoglosses ("A or B"), e.g. "distincion,zheismo". If both plus and comma are used, plus takes
precedence, e.g. "seseo+lleismo,zheismo" means either the "seseo+lleismo" dialect or the "rioplatense-zheismo"
dialect.
An example where the style= parameter might be used is with the word [[bluetooth]], which has one pronunciation
in Spain/distinción (respelled "blutuz") but another in Latin America/seseo (respelled "blutud"). This might be
represented using {{es-pr}} as {{es-pr|blutuz<style:distincion>|blutud<style:seseo>}}.
]=]
local lang = require("Module:languages").getByCode("es")
local decompose = require("Module:es-common").decompose
local u = m_str_utils.char
local rfind = m_str_utils.find
local rsubn = m_str_utils.gsub
local rsplit = m_str_utils.split
local ulower = m_str_utils.lower
local ulen = m_str_utils.len
local unfd = mw.ustring.toNFD
local unfc = mw.ustring.toNFC
local AC = u(0x0301) -- acute = ́
local GR = u(0x0300) -- grave = ̀
local CFLEX = u(0x0302) -- circumflex = ̂
local TILDE = u(0x0303) -- tilde = ̃
local SYLDIV = u(0xFFF0) -- used to represent a user-specific syllable divider (.) so we won't change it
local vowel = "aeiouüyAEIOUÜY" -- vowel; include y so we get single-word y correct and for syllabifying from spelling
local V = "[" .. vowel .. "]" -- vowel class
local accent = AC .. GR .. CFLEX
local accent_c = "[" .. accent .. "]"
local stress = AC .. GR
local stress_c = "[" .. AC .. GR .. "]"
local ipa_stress = "ˈˌ"
local ipa_stress_c = "[" .. ipa_stress .. "]"
local sylsep = "%-." .. SYLDIV -- hyphen included for syllabifying from spelling
local sylsep_c = "[" .. sylsep .. "]"
local wordsep = "# "
local separator_not_wordsep = accent .. ipa_stress .. sylsep
local separator = separator_not_wordsep .. wordsep
local separator_c = "[" .. separator .. "]"
local C = "[^" .. vowel .. separator .. "]" -- consonant class including h
local C_NOT_H = "[^" .. vowel .. separator .. "h]" -- consonant class not including h
local C_OR_WORDSEP = "[^" .. vowel .. separator_not_wordsep .. "]" -- consonant class including h, or word separator
local T = "[^" .. vowel .. "lrɾjw" .. separator .. "]" -- obstruent or nasal
local unstressed_words = m_table.listToSet({
"el", "la", "los", "las", -- definite articles
"un", -- single-syllable indefinite articles
"me", "te", "se", "lo", "le", "nos", "os", "les", -- unstressed object pronouns
"mi", "mis", "tu", "tus", "su", "sus", -- unstressed possessive pronouns
"que", "si", -- subordinating conjunctions
"y", "e", "o", "u", "mas", -- coordinating conjunctions
"de", "del", "a", "al", -- basic prepositions + combinations with articles
"por", "en", "con", -- other prepositions
})
-- 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
-- apply rsub() repeatedly until no change
local function rsub_repeatedly(term, foo, bar)
while true do
local new_term = rsub(term, foo, bar)
if new_term == term then
return term
end
term = new_term
end
end
local function split_on_comma(term)
if not term then
return nil
end
if term:find(",%s") then
return require(parse_utilities_module).split_on_comma(term)
elseif term:find(",") then
return rsplit(term, ",")
else
return {term}
end
end
-- Remove any HTML from the formatted text and resolve links, since the extra characters don't contribute to the
-- displayed length.
local function convert_to_raw_text(text)
text = rsub(text, "<.->", "")
if text:find("%[%[") then
text = require(links_module).remove_links(text)
end
return text
end
-- Return the approximate displayed length in characters.
local function textual_len(text)
return ulen(convert_to_raw_text(text))
end
local function construct_default_differences(dialect)
if dialect == "distincion-lleismo" then
return {
distincion_different = false,
lleismo_different = false,
sheismo_different = false,
need_rioplat = false,
need_quito = false,
need_yucatan = false,
}
end
return nil
end
-- Main syllable-division algorithm. Can be called either directly on spelling (when hyphenating) or after
-- non-trivial processing of respelling in the direction of pronunciation (when generating pronunciation).
local function syllabify_from_spelling_or_pronun(text, is_spelling)
-- Part 1: Divide before the last consonant in a cluster of consonants between vowels (but don't divide a VhV
-- sequence; [[prohibir]] should be prohi.bir). Then move the syllable division marker leftwards over clusters that
-- can form onsets.
text = rsub_repeatedly(text, "(" .. V .. accent_c .. "*)(" .. C_NOT_H .. V .. ")", "%1.%2")
text = rsub_repeatedly(text, "(" .. V .. accent_c .. "*" .. C .. "+)(" .. C .. V .. ")", "%1.%2")
-- Puerto Rico + most of Spain divide tl as t.l. Mexico and the Canary Islands have .tl. Unclear what other regions
-- do. Here we choose to go with .tl. See https://catalog.ldc.upenn.edu/docs/LDC2019S07/Syllabification_Rules_in_Spanish.pdf
-- and https://www.spanishdict.com/guide/spanish-syllables-and-syllabification-rules.
-- NOTE: When run on pronun, we have already eliminated c and v, but not when run on spelling.
-- When run on pronun, don't include r, which at this point represents the trill.
local cluster_r = is_spelling and "rɾ" or "ɾ"
-- Don't divide Cl or Cr where C is a stop or fricative, except for dl.
text = rsub(text, "([pbfvkctg])%.([l" .. cluster_r .. "])", ".%1%2")
text = text:gsub("d%.([" .. cluster_r .. "])", ".d%1")
-- Don't divide ch, sh, ph, th, dh, fh, kh or gh. Do allow bh to be divided ([[subhumano]], [[subhúmedo]], etc.).
text = rsub(text, "([csptdfkg])%.h", ".%1h")
-- Don't divide ll or rr.
text = rsub(text, "([lr])%.%1", ".%1%1")
-- Don't divide tz ([[Ertzaintza]], [[quetzal]], [[hertziano]] and other words of Basque, Nahuatl and German
-- origin).
text = rsub(text, "t%.z", ".tz")
-- Per https://catalog.ldc.upenn.edu/docs/LDC2019S07/Syllabification_Rules_in_Spanish.pdf, tl at the end of a word
-- (as in nahuatl, Popocatepetl etc.) is divided .tl from the previous vowel.
if is_spelling then
text = text:gsub("([^. %-])tl$", "%1.tl")
text = text:gsub("([^. %-])(tl[ %-])", "%1.%2")
else
text = text:gsub("([^.#])tl#", "%1.tl")
end
-- Part 2: Divide hiatuses. Any aeo, or stressed iuüy, should be syllabically divided from a following aeo or
-- stressed iuüy. Also divide ii and uu sequences ([[antiincendios]], [[shiita]], [[vacuum]]). Note that words with
-- ii or uu next to a vowel (e.g. [[hawaiiano]]) will not make it to this point unchanged; the i or u adjacent to
-- a vowel (or the second one if both are adjacent to vowels) will get converted to a consonant symbol (temporarily
-- when syllabifying spelling).
text = rsub_repeatedly(text, "([aeoAEO]" .. accent_c .. "*)(h?[aeo])", "%1.%2")
text = rsub_repeatedly(text, "([aeoAEO]" .. accent_c .. "*)(h?" .. V .. stress_c .. ")", "%1.%2")
text = rsub(text, "([iuüyIUÜY]" .. stress_c .. ")(h?[aeo])", "%1.%2")
text = rsub_repeatedly(text, "([iuüyIUÜY]" .. stress_c .. ")(h?" .. V .. stress_c .. ")", "%1.%2")
text = rsub_repeatedly(text, "([iI]" .. accent_c .. "*)(h?i)", "%1.%2")
text = rsub_repeatedly(text, "([uU]" .. accent_c .. "*)(h?u)", "%1.%2")
return text
end
local function syllabify_from_spelling(text)
text = decompose(text)
-- start at FFF1 because FFF0 is used for SYLDIV
-- Temporary replacements for characters we want treated as default consonants. The C and related consonant regexes
-- treat all unknown characters as consonants.
local TEMP_I = u(0xFFF1)
local TEMP_U = u(0xFFF2)
local TEMP_Y_CONS = u(0xFFF3)
local TEMP_QU = u(0xFFF4)
local TEMP_QU_CAPS = u(0xFFF5)
local TEMP_GU = u(0xFFF6)
local TEMP_GU_CAPS = u(0xFFF7)
local TEMP_H = u(0xFFF8)
-- Change user-specified . into SYLDIV so we don't shuffle it around when dividing into syllables.
text = text:gsub("%.", SYLDIV)
text = rsub(text, "y(" .. V .. ")", TEMP_Y_CONS .. "%1")
-- We don't want to break -sh- except in desh-, e.g. [[deshuesar]], [[deshonra]], [[deshecho]]. Normally, -sh- is
-- automatically preserved, so we replace the h with a temporary symbol to avoid this.
text = text:gsub("^([Dd]es)h", "%1" .. TEMP_H)
text = text:gsub("([ %-][Dd]es)h", "%1" .. TEMP_H)
-- qu mostly handled correctly automatically, but not in quietud
text = rsub(text, "qu(" .. V .. ")", TEMP_QU .. "%1")
text = rsub(text, "Qu(" .. V .. ")", TEMP_QU_CAPS .. "%1")
text = rsub(text, "gu(" .. V .. ")", TEMP_GU .. "%1")
text = rsub(text, "Gu(" .. V .. ")", TEMP_GU_CAPS .. "%1")
local vowel_to_glide = { ["i"] = TEMP_I, ["u"] = TEMP_U }
-- i and u between vowels -> consonant-like substitutions: [[paranoia]], [[baiano]], [[abreuense]], [[alauita]],
-- [[Malaui]], etc.; also with h, as in [[marihuana]], [[parihuela]], [[antihielo]], [[pelluhuano]], [[náhuatl]],
-- etc. When we do this we need to help the syllabification particularly of words with -hiV- and -huV- in them,
-- otherwise we get e.g. 'an.tih.ie.lo' because we converted the i following the h to a consonant. Add .* at the
-- beginning so we go right-to-left, in the case of [[hawaiiano]] -> ha.wai.iano.
text = rsub_repeatedly(text, "(.*" .. V .. accent_c .. "*)(h?)([iu])(" .. V .. ")",
function (v1, h, iu, v2) return v1 .. "." .. h .. vowel_to_glide[iu] .. v2 end
)
text = syllabify_from_spelling_or_pronun(text, "is spelling")
text = text:gsub(SYLDIV, ".")
text = text:gsub(TEMP_I, "i")
text = text:gsub(TEMP_U, "u")
text = text:gsub(TEMP_Y_CONS, "y")
text = text:gsub(TEMP_QU, "qu")
text = text:gsub(TEMP_QU_CAPS, "Qu")
text = text:gsub(TEMP_GU, "gu")
text = text:gsub(TEMP_GU_CAPS, "Gu")
text = text:gsub(TEMP_H, "h")
text = unfc(text)
-- No qualifiers from dialect tags because we assume all dialects hyphenate the same way.
-- FIXME: There are region-specific ways of hyphenating -tl-. See above. We don't currently handle this properly.
return text
end
-- Generate the IPA of a given respelling, where a respelling is the representation of the pronunciation of a given
-- Spanish term using Spanish spelling conventions (augmented in a few cases with extra conventions such as 'sh' for
-- /ʃ/).
-- ɟ and ĉ are used internally to represent [ʝ⁓ɟ͡ʝ] and [t͡ʃ]
--
function export.IPA(text, dialect, phonetic)
local distincion = dialect == "distincion-lleismo" or dialect == "distincion-yeismo"
local lleismo = dialect == "distincion-lleismo" or dialect == "seseo-lleismo" or dialect == "quito"
local rioplat = dialect == "rioplatense-sheismo" or dialect == "rioplatense-zheismo"
local sheismo = dialect == "rioplatense-sheismo"
local quito = dialect == "quito"
local yucatan = dialect == "yucatan"
local distincion_different = false
local lleismo_different = false
local need_rioplat = false
local need_quito = false
local need_yucatan = false
local initial_hi = false
local sheismo_different = false
-- start at FFF1 because FFF0 is used for SYLDIV
local TEMP_Y = u(0xFFF1)
local TEMP_W = u(0xFFF2)
text = ulower(text or mw.loadData("Module:headword/data").pagename)
-- decompose everything but ç, ñ and ü
text = decompose(text)
-- convert commas and en/en dashes to IPA foot boundaries
text = rsub(text, "%s*[,–—]%s*", " | ")
-- question mark or exclamation point in the middle of a sentence -> IPA foot boundary
text = rsub(text, "([^%s])%s*[¡!¿?]%s*([^%s])", "%1 | %2")
-- canonicalize multiple spaces and remove leading and trailing spaces
local function canon_spaces(text)
text = rsub(text, "%s+", " ")
text = rsub(text, "^ ", "")
text = rsub(text, " $", "")
return text
end
text = canon_spaces(text)
-- Make prefixes unstressed unless they have an explicit stress marker; also make certain
-- monosyllabic words (e.g. [[el]], [[la]], [[de]], [[en]], etc.) without stress marks be
-- unstressed.
local words = rsplit(text, " ")
for i, word in ipairs(words) do
if rfind(word, "%-$") and not rfind(word, accent_c) or unstressed_words[word] then
-- add CFLEX to the last vowel not the first one, or we will mess up 'que' by
-- adding the CFLEX after the 'u'
words[i] = rsub(word, "^(.*" .. V .. ")", "%1" .. CFLEX)
end
end
text = table.concat(words, " ")
-- Convert hyphens to spaces, to handle [[Austria-Hungría]], [[franco-italiano]], etc.
text = rsub(text, "%-", " ")
-- canonicalize multiple spaces again, which may have been introduced by hyphens
text = canon_spaces(text)
-- now eliminate punctuation
text = rsub(text, "[¡!¿?']", "")
-- put # at word beginning and end and double ## at text/foot boundary beginning/end
text = rsub(text, " | ", "# | #")
text = "##" .. rsub(text, " ", "# #") .. "##"
--determining whether "y" is a consonant or a vowel
text = rsub(text, "y(" .. V .. ")", "ɟ%1") -- not the real sound
-- word-final -ay/-ey/-oy/-uy is stressed whereas word-final -ai/-ei/-oi/-ui is not; in addition,
-- word-final -uy is /uj/ whereas word-final -ui is /wi/ (e.g. [[muy]] vs. [[fui]])
text = rsub(text, "([aeou])y#", "%1" .. TEMP_Y .. "#") -- a temporary symbol; replaced with i below
text = rsub(text, "y", "i")
-- handle certain combinations; sh handling needs to go before x handling to avoid issues with [[exhausto]]
text = rsub(text, "ch", "ĉ") --not the real sound
-- We want to keep desh- ([[deshuesar]]) as-is. Converting to des- won't work because we want it syllabified as
-- 'des.we.saɾ' not #'de.swe.saɾ' (cf. [[desuelo]] /de.swe.lo/ from [[desolar]]).
text = rsub(text, "#desh", "!") --temporary symbol
text = rsub(text, "sh", "ʃ")
text = rsub(text, "!", "#desh") --restore
text = rsub(text, "#[ckp]([st])", "#%1") -- [[ctónico]], [[psicología]], [[pterodáctilo]]
--x
text = rsub(text, "#x", "#s") -- xenofobia, xilófono, etc.
text = rsub(text, "x", "ks")
--c, g, q
text = rsub(text, "c([ie])", (distincion and "θ" or "z") .. "%1") -- not the real LatAm sound
text = rsub(text, "g([ie])", "x%1") -- must happen after handling of x above
text = rsub(text, "gu([ie])", "g%1")
text = rsub(text, "gü([ie])", "gu%1")
-- following must happen before stress assignment; [[branding]] has initial stress like 'brandin'
text = rsub(text, "ng([^aeiouüwhlr])", "n%1") -- [[Bangkok]], [[ángstrom]], [[branding]]
text = rsub(text, "qu([ie])", "k%1")
text = rsub(text, "ü", "u") -- [[Düsseldorf]], [[hübnerita]], obsolete [[freqüentemente]], etc.
text = rsub(text, "q", "k") -- [[quark]], [[Qatar]], [[burqa]], [[Iraq]], etc.
text = rsub(text, "[zç]", distincion and "θ" or "z") -- not the real LatAm sound; "ç" became "z" in 1726
if rfind(text, "[θz]") then
distincion_different = true
end
-- map various consonants to their phoneme equivalent
text = rsub(text, "[cjñrv]", {["c"]="k", ["j"]="x", ["ñ"]="ɲ", ["r"]="ɾ", ["v"]="b" })
-- handle word- and syllable-initial hiV ([[hielo]], [[enhiesto]], [[deshielo]], ...)
local word_initial_hi, syl_initial_hi
text, word_initial_hi = rsubb(text, "#h?i(" .. V .. ")", rioplat and "#j%1" or "#ɟ%1")
text, syl_initial_hi = rsubb(text, "(" .. C .. sylsep_c .. "*)hi(" .. V .. ")", rioplat and "%1j%2" or "%1ɟ%2")
initial_hi = word_initial_hi or syl_initial_hi
-- handle word- and syllable-initial huV ([[huevo]], [[deshuesar]])
text = rsubb(text, "(" .. C_OR_WORDSEP .. sylsep_c .. "*)hu(" .. V .. ")", "%1" .. TEMP_W .. "%2")
-- handle double consonants that have a pronunciation different from their single equivalents
-- double l
lleismo_different = rfind(text, "ll")
need_quito = lleismo_different and rfind(text, "ɟ")
text = rsub(text, "ll", lleismo and "ʎ" or "ɟ")
-- handle intervocalic -y-
need_yucatan = rfind(text, V .. accent_c .. "*" .. sylsep_c .. "*[ʎɟ]" .. V)
if yucatan then
text = rsub_repeatedly(text, "([ei]" .. accent_c .. "*" .. sylsep_c .. "*)ɟ(" .. V .. ")", "%1.%2")
text = rsub_repeatedly(text, "(" .. V .. accent_c .. "*" .. sylsep_c .. "*)ɟ" .. "([ei])", "%1.%2")
text = rsub_repeatedly(text, "(" .. V .. accent_c .."*" .. sylsep_c .. "*)ɟ(" .. V .. ")", "%1i%2")
end
-- trill in #r, lr ([[alrededor]], [[malrotar]]), nr ([[enriquecer]], [[sonrisa]], etc.), sr ([[Israel]],
-- [[desregular]], etc.), zr ([[Azrael]], [[cruzrojista]]), rr
text = rsub(text, "ɾɾ", "r")
text = rsub(text, "([#lnszθ])ɾ", "%1r")
-- double n (e.g. [[[ennoblecer]])
text = rsub(text, "nn", "N")
-- double b (e.g. [[subbase]])
text = rsub(text, "bb", "B")
-- reduce any remaining double consonants ([[Addis Abeba]], [[cappa]], [[descender]] in Latin America ...);
-- do this before handling of -nm- e.g. in [[inmigración]], which generates a double consonant, and do this
-- before voicing stops before obstruents, to avoid problems with [[cappa]] and [[crackear]]
text = rsub(text, "(" .. C .. ")%1", "%1")
-- also reduce sz (Latin American in [[fascinante]], etc.)
text = rsub(text, "sz", "s")
-- restore double n, b
text = rsub(text, "N", "nn")
text = rsub(text, "B", "bb")
-- voiceless stop to voiced before obstruent or nasal; but intercept -ts-, -tz-
local voice_stop = { ["p"] = "b", ["t"] = "d", ["k"] = "g" }
text = rsub(text, "t(" .. separator_c .. "*[szθ])", "!%1") -- temporary symbol
text = rsub(text, "([ptk])(" .. separator_c .. "*" .. T .. ")",
function(stop, after) return voice_stop[stop] .. after end)
text = rsub(text, "!", "t")
text = rsub(text, "n([# .]*[bpm])", "m%1")
-- remove silent h before syllable division
text = rsub(text, "h", "")
-- convert i/u between vowels to glide
local vowel_to_glide = { ["i"] = "j", ["u"] = "w" }
-- i and u between vowels -> consonant-like substitutions: [[paranoia]], [[baiano]], [[abreuense]], [[alauita]],
-- [[Malaui]], etc.; also with h, as in [[marihuana]], [[parihuela]], [[antihielo]], [[pelluhuano]], [[náhuatl]],
-- etc. Add .* at the beginning so we go right-to-left, in the case of [[hawaiiano]] -> ha.wai.iano.
text = rsub_repeatedly(text, "(.*" .. V .. accent_c .. "*h?)([iu])(" .. V .. ")",
function (v1, iu, v2) return v1 .. vowel_to_glide[iu] .. v2 end
)
--syllable division
text = syllabify_from_spelling_or_pronun(text, false)
--diphthongs; do not include TEMP_Y here
text = rsub(text, "i([aeou])", "j%1")
text = rsub(text, "u([aeio])", "w%1")
local accent_to_stress_mark = { [AC] = "ˈ", [GR] = "ˌ", [CFLEX] = "" }
local function accent_word(word, syllables)
-- Now stress the word. If any accent exists in the word (including ^ indicating an unaccented word),
-- put the stress mark(s) at the beginning of the indicated syllable(s). Otherwise, apply the default
-- stress rule.
if rfind(word, accent_c) then
for i = 1, #syllables do
syllables[i] = rsub(syllables[i], "^(.*)(" .. accent_c .. ")(.*)$",
function(pre, accent, post) return accent_to_stress_mark[accent] .. pre .. post end
)
end
else
-- Default stress rule. Words without vowels (e.g. IPA foot boundaries) don't get stress.
if #syllables > 1 and (rfind(word, "[^" .. vowel .. "ns#]#") or rfind(word, C .. "[ns]#")) or #syllables == 1 and rfind(word, V) then
syllables[#syllables] = "ˈ" .. syllables[#syllables]
elseif #syllables > 1 then
syllables[#syllables - 1] = "ˈ" .. syllables[#syllables - 1]
end
end
end
local words = rsplit(text, " ")
for j, word in ipairs(words) do
-- accentuation
local syllables = rsplit(word, "%.")
if rfind(word, "men%.te#") then
local mente_syllables
-- Words ends in -mente (converted above to ménte); add a stress to the preceding portion
-- (e.g. [[agriamente]] -> 'ágriaménte') unless already stressed (e.g. [[rápidamente]]).
-- It will be converted to secondary stress further below. Essentially, we rip the word apart
-- into two words ('mente' and the preceding portion) and stress each one independently.
mente_syllables = {}
mente_syllables[2] = table.remove(syllables)
mente_syllables[1] = table.remove(syllables)
accent_word(table.concat(syllables, "."), syllables)
accent_word(table.concat(mente_syllables, "."), mente_syllables)
table.insert(syllables, mente_syllables[1])
table.insert(syllables, mente_syllables[2])
else
accent_word(word, syllables)
end
-- Vowels are nasalized if followed by nasal in same syllable.
if phonetic then
for i = 1, #syllables do
-- first check for two vowels (veinte)
syllables[i] = rsub(syllables[i], "(" .. V .. ")(" .. V .. ")([mnɲ])",
"%1" .. TILDE .. "%2" .. TILDE .. "%3")
-- then for one vowel
syllables[i] = rsub(syllables[i], "(" .. V .. ")([mnɲ])", "%1" .. TILDE .. "%2")
end
end
-- Reconstruct the word.
words[j] = table.concat(syllables, ".")
end
text = table.concat(words, " ")
text = rsub(text, TEMP_Y, "i") --final -ay/-ey/-oy/-uy
text = rsub(text, "z", "s") --real sound of LatAm Z
-- suppress syllable mark before IPA stress indicator
text = rsub(text, "%.(" .. ipa_stress_c .. ")", "%1")
--make all primary stresses but the last one be secondary
text = rsub_repeatedly(text, "ˈ(.+)ˈ", "ˌ%1ˈ")
if (not initial_hi and rfind(text, "[ʎɟ]")) or (rfind(text, sylsep_c .. "[ʎɟ]")) then
sheismo_different = true
end
if rioplat then
if not initial_hi then
if sheismo then
text = rsub(text, "ɟ", "ʃ")
else
text = rsub(text, "ɟ", "ʒ")
end
else
if sheismo then
text = rsub(text, sylsep_c .. "(ɟ)", "ʃ")
else
text = rsub(text, sylsep_c .. "(ɟ)", "ʒ")
end
end
end
if quito then text = rsub(text, "ʎ", "ʒ") end
--phonetic transcription
if phonetic then
-- θ, s, f before voiced consonants
local voiced = "mnɲbdɟgʎ" .. TEMP_W
local r = "ɾr"
local tovoiced = {
["θ"] = "θ̬",
["s"] = "z",
["f"] = "v",
}
local function voice(sound, following)
return tovoiced[sound] .. following
end
text = rsub(text, "([θs])(" .. separator_c .. "*[" .. voiced .. r .. "])", voice)
text = rsub(text, "(f)(" .. separator_c .. "*[" .. voiced .. "])", voice)
-- fricative vs. stop allophones; first convert stops to fricatives, then back to stops
-- after nasals and sometimes after l
local stop_to_fricative = {["b"] = "β", ["d"] = "ð", ["ɟ"] = "ʝ", ["g"] = "ɣ"}
local fricative_to_stop = {["β"] = "b", ["ð"] = "d", ["ʝ"] = "ɟ", ["ɣ"] = "g"}
text = rsub(text, "[bdɟg]", stop_to_fricative)
text = rsub(text, "([mnɲ]" .. separator_c .. "*)([βɣ])",
function(nasal, fricative) return nasal .. fricative_to_stop[fricative] end
)
text = rsub(text, "([lʎmnɲ]" .. separator_c .. "*)([ðʝ])",
function(nasal_l, fricative) return nasal_l .. fricative_to_stop[fricative] end
)
text = rsub(text, "(##" .. ipa_stress_c .. "*)([βɣðʝ])",
function(stress, fricative) return stress .. fricative_to_stop[fricative] end
)
text = rsub(text, "[td]", {["t"] = "t̪", ["d"] = "d̪"})
-- nasal assimilation before consonants
local labiodental, dentialveolar, dental, alveolopalatal, palatal, velar =
"ɱ", "n̪", "n̟", "nʲ", "ɲ", "ŋ"
local nasal_assimilation = {
["f"] = labiodental,
["t"] = dentialveolar, ["d"] = dentialveolar,
["θ"] = dental,
["ĉ"] = alveolopalatal,
["ʃ"] = alveolopalatal,
["ʒ"] = alveolopalatal,
["ɟ"] = palatal, ["ʎ"] = palatal,
["k"] = velar, ["x"] = velar, ["g"] = velar,
}
text = rsub(text, "n(" .. separator_c .. "*)(.)",
function(stress, following) return (nasal_assimilation[following] or "n") .. stress .. following end
)
-- lateral assimilation before consonants
text = rsub(text, "l(" .. separator_c .. "*)(.)",
function(stress, following)
local l = "l"
if following == "t" or following == "d" then -- dentialveolar
l = "l̪"
elseif following == "θ" then -- dental
l = "l̟"
elseif following == "ĉ" or following == "ʃ" then -- alveolopalatal
l = "lʲ"
end
return l .. stress .. following
end)
--semivowels
text = rsub(text, "([aeouãẽõũ][iĩ])", "%1̯")
text = rsub(text, "([aeioãẽĩõ][uũ])", "%1̯")
-- voiced fricatives are actually approximants
text = rsub(text, "([βðɣ])", "%1̞")
end
-- convert fake symbols to real ones
local final_conversions = {
["ħ"] = "h", -- fake aspirated "h" to real "h"
["ĉ"] = "t͡ʃ", -- fake "ch" to real "ch"
["ɟ"] = phonetic and "ɟ͡ʝ" or "ʝ", -- fake "y" to real "y"
-- do the following at the very end so we can use regular g throughout
["g"] = "ɡ", -- U+0067 LATIN SMALL LETTER G → U+0261 LATIN SMALL LETTER SCRIPT G
[TEMP_W] = "w̝", -- see https://en.wikipedia.org/wiki/Spanish_orthography for this
}
text = rsub(text, "[ħĉɟg" .. TEMP_W .. "]", final_conversions)
-- remove # symbols at word and text boundaries
text = rsub(text, "#", "")
text = unfc(text)
-- The values in `differences` are only accurate when the dialect is 'distincion-lleismo'
-- because we look for sounds like /θ/ and /ʎ/ that are only present in that dialect.
-- The calling code knows to only use this structure in conjunction with this dialect.
-- but to make sure of this we set the structure to nil for other dialects.
local differences = nil
if dialect == "distincion-lleismo" then
differences = {
distincion_different = distincion_different,
lleismo_different = lleismo_different,
need_rioplat = initial_hi or sheismo_different,
sheismo_different = sheismo_different,
need_quito = need_quito,
need_yucatan = need_yucatan,
}
end
local ret = {
text = text,
differences = differences,
}
return ret
end
-- For bot usage; {{#invoke:es-pronunc|IPA_string|SPELLING|style=STYLE|phonetic=PHONETIC}}
-- where
--
-- 1. SPELLING is the word or respelling to generate pronunciation for;
-- 2. required parameter style= indicates the pronunciation style to generate
-- (e.g. "distincion-yeismo" for distinción+yeísmo, as is common in Spain;
-- see the comment above export.IPA() above for the full list);
-- 3. phonetic=1 specifies to generate the phonetic rather than phonemic pronunciation;
function export.IPA_string(frame)
local iparams = {
[1] = {},
["style"] = {required = true},
["phonetic"] = {type = "boolean"},
}
local iargs = require(parameters_module).process(frame.args, iparams)
local retval = export.IPA(iargs[1], iargs.style, iargs.phonetic)
return retval.text
end
-- Generate all relevant dialect pronunciations and group into styles. See the comment above about dialects and styles.
-- A "pronunciation" here could be for example the IPA phonemic/phonetic representation of the term or the IPA form of
-- the rhyme that the term belongs to. If `style_spec` is nil, this generates all styles for all dialects, but
-- `style_spec` can also be a style spec such as "seseo" or "distincion+yeismo" (see comment above) to restrict the
-- output. `dodialect` is a function of two arguments, `ret` and `dialect`, where `ret` is the return-value table (see
-- below), and `dialect` is a string naming a particular dialect, such as "distincion-lleismo" or "rioplatense-sheismo".
-- `dodialect` should side-effect the `ret` table by adding an entry to `ret.pronun` for the dialect in question.
--
-- The return value is a table of the form
--
-- {
-- pronun = {DIALECT = {PRONUN, PRONUN, ...}, DIALECT = {PRONUN, PRONUN, ...}, ...},
-- expressed_styles = {STYLE_GROUP, STYLE_GROUP, ...},
-- }
--
-- where:
-- 1. DIALECT is a string such as "distincion-lleismo" naming a specific dialect.
-- 2. PRONUN is a table describing a particular pronunciation. If the dialect is "distincion-lleismo", there should be
-- a field in this table named `differences`, but where other fields may vary depending on the type of pronunciation
-- (e.g. phonemic/phonetic or rhyme). See below for the form of the PRONUN table for phonemic/phonetic pronunciation
-- vs. rhyme and the form of the `differences` field.
-- 3. STYLE_GROUP is a table of the form {tag = "HIDDEN_TAG", styles = {INNER_STYLE, INNER_STYLE, ...}}. This describes
-- a group of related styles (such as those for Latin America) that by default (the "hidden" form) are displayed as
-- a single line, with an icon on the right to "open" the style group into the "shown" form, with multiple lines
-- for each style in the group. The tag of the style group is the text displayed before the pronunciation in the
-- default "hidden" form, such as "Spain" or "Latin America". It can have the special value of `false` to indicate
-- that no tag text is to be displayed. Note that the pronunciation shown in the default "hidden" form is taken
-- from the first style in the style group.
-- 4. INNER_STYLE is a table of the form {tag = "SHOWN_TAG", pronun = {PRONUN, PRONUN, ...}}. This describes a single
-- style (such as for the Andes Mountains and Paraguay in the case where the seseo+lleismo accent differs from all others), to
-- be shown on a single line. `tag` is the text preceding the displayed pronunciation, or `false` if no tag text
-- is to be displayed. PRONUN is a table as described above and describes a particular pronunciation.
--
-- The PRONUN table has the following form for the full phonemic/phonetic pronunciation:
--
-- {
-- phonemic = "PHONEMIC",
-- phonetic = "PHONETIC",
-- differences = {FLAG = BOOLEAN, FLAG = BOOLEAN, ...},
-- }
--
-- Here, `phonemic` is the phonemic pronunciation (displayed as /.../) and `phonetic` is the phonetic pronunciation
-- (displayed as [...]).
--
-- The PRONUN table has the following form for the rhyme pronunciation:
--
-- {
-- rhyme = "RHYME_PRONUN",
-- num_syl = {NUM, NUM, ...},
-- q = nil or {QUALIFIER, QUALIFIER, ...},
-- differences = {FLAG = BOOLEAN, FLAG = BOOLEAN, ...},
-- }
--
-- Here, `rhyme` is a phonemic pronunciation such as "ado" for [[abogado]] or "iʝa"/"iʎa" for [[tortilla]] (depending
-- on the dialect), and `num_syl` is a list of the possible numbers of syllables for the term(s) that have this rhyme
-- (e.g. {4} for [[abogado]], {3} for [[tortilla]] and {4, 5} for [[biología]], which may be syllabified as
-- bio.lo.gí.a or bi.o.lo.gí.a). `num_syl` is used to generate syllable-count categories such as
-- [[Category:Rhymes:Spanish/ia/4 syllables]] in addition to [[Category:Rhymes:Spanish/ia]]. `num_syl` may be nil to
-- suppress the generation of syllable-count categories; this is typically the case with multiword terms.
-- `q`, if non-nil, comes from the user using the syntax e.g. <rhyme:iʃa<q:Buenos Aires>>.
--
-- The value of the `differences` field in the PRONUN table (which, as noted above, only needs to be present for the
-- "distincion-lleismo" dialect, and otherwise should be nil) is a table containing flags indicating whether and how
-- the per-dialect pronunciations differ. This is an optimization to avoid having to generate all six dialectal
-- pronunciations and compare them. It has the following form:
--
-- {
-- distincion_different = BOOLEAN,
-- lleismo_different = BOOLEAN,
-- need_rioplat = BOOLEAN,
-- sheismo_different = BOOLEAN,
-- need_quito = BOOLEAN,
-- need_yucatan = BOOLEAN,
-- }
--
-- where:
-- 1. `distincion_different` should be `true` if the "distincion" and "seseo" pronunciations differ;
-- 2. `lleismo_different` should be `true` if the "lleismo" and "yeismo" pronunciations differ;
-- 3. `need_rioplat` should be `true` if the Rioplatense pronunciations differ from the seseo+yeismo pronunciation;
-- 4. `sheismo_different` should be `true` if the "sheismo" and "zheismo" pronunciations differ.
-- 5. `need_quito` should be `true` if the "quito" and "zheismo" pronunciations differ.
-- 6. `need_yucatan` should be `true` if the "yucatan" and "yeismo" pronunciations differ;
local function express_all_styles(style_spec, dodialect)
local ret = {
pronun = {},
expressed_styles = {},
}
local need_rioplat
local need_quito
local need_yucatan
-- Add a style object (see INNER_STYLE above) that represents a particular style to `ret.expressed_styles`.
-- `hidden_tag` is the tag text to be used when the style group containing the style is in the default "hidden"
-- state (e.g. "Spain", "Latin America" or false if there is only one style group and no tag text should be
-- shown), while `tag` is the tag text to be used when the individual style is shown (e.g. a description such as
-- "most of Spain and Latin America", "Andes Mountains and Paraguay" or "everywhere but Argentina and Uruguay").
-- `representative_dialect` is one of the dialects that this style represents, and whose pronunciation is stored in
-- the style object. `matching_styles` is a hyphen separated string listing the isoglosses described by this style.
-- For example, if the term has an ''ll'' but no ''c/z'', the `tag` text for the yeismo pronunciation will be
-- "most of Spain and Latin America" and `matching_styles` will be "distincion-seseo-yeismo", indicating that
-- it corresponds to both the "distincion" and "seseo" isoglosses as well as the "yeismo" isogloss. This is used
-- when a particular style spec is given. If `matching_styles` is omitted, it takes its value from
-- `representative_dialect`; this is used when the style contains only a single dialect.
local function express_style(hidden_tag, tag, representative_dialect, matching_styles)
matching_styles = matching_styles or representative_dialect
-- If the Rioplatense pronunciation isn't distinctive, add all Rioplatense isoglosses.
if not need_rioplat then
matching_styles = matching_styles .. "-rioplatense-sheismo-zheismo"
end
-- also Quito
if not need_quito then
matching_styles = matching_styles .. "-quito"
end
-- Yucatan
if not need_yucatan then
matching_styles = matching_styles .. "-yucatan"
end
-- If style specified, make sure it matches the requested style.
local style_matches
if not style_spec then
style_matches = true
else
local style_parts = rsplit(matching_styles, "%-")
local or_styles = rsplit(style_spec, "%s*,%s*")
for _, or_style in ipairs(or_styles) do
local and_styles = rsplit(or_style, "%s*%+%s*")
local and_matches = true
for _, and_style in ipairs(and_styles) do
local negate
if and_style:find("^%-") then
and_style = and_style:gsub("^%-", "")
negate = true
end
local this_style_matches = false
for _, part in ipairs(style_parts) do
if part == and_style then
this_style_matches = true
break
end
end
if negate then
this_style_matches = not this_style_matches
end
if not this_style_matches then
and_matches = false
end
end
if and_matches then
style_matches = true
break
end
end
end
if not style_matches then
return
end
-- Fetch the representative dialect's pronunciation if not already present.
if not ret.pronun[representative_dialect] then
dodialect(ret, representative_dialect)
end
-- Insert the new style into the style group, creating the group if necessary.
local new_style = {
tag = tag,
pronun = ret.pronun[representative_dialect],
}
for _, hidden_tag_style in ipairs(ret.expressed_styles) do
if hidden_tag_style.tag == hidden_tag then
table.insert(hidden_tag_style.styles, new_style)
return
end
end
table.insert(ret.expressed_styles, {
tag = hidden_tag,
styles = {new_style},
})
end
-- For each type of difference, figure out if the difference exists in any of the given respellings. We do this by
-- generating the pronunciation for the dialect "distincion-lleismo", for each respelling. In the process of
-- generating the pronunciation for a given respelling, it computes how the other dialects for that respelling
-- differ. Then we take the union of these differences across the respellings.
dodialect(ret, "distincion-lleismo")
local differences = {}
for _, difftype in ipairs { "distincion_different", "lleismo_different", "need_rioplat", "sheismo_different", "need_quito", "need_yucatan" } do
for _, pronun in ipairs(ret.pronun["distincion-lleismo"]) do
if pronun.differences[difftype] then
differences[difftype] = true
end
end
end
local distincion_different = differences.distincion_different
local lleismo_different = differences.lleismo_different
need_rioplat = differences.need_rioplat
local sheismo_different = differences.sheismo_different
need_quito = differences.need_quito
need_yucatan = differences.need_yucatan
-- Now, based on the observed differences, figure out how to combine the individual dialects into styles and
-- style groups.
if not distincion_different and not lleismo_different then
if not need_rioplat then
if not need_yucatan then
express_style(false, false, "distincion-lleismo", "distincion-seseo-lleismo-yeismo")
else
express_style(false, "ทุกที่ยกเว้น<<Mexico>>เหนือ, <<Yucatán>> และ<<Central America>> (ยกเว้น<<Panama>>)", "distincion-lleismo", "distincion-seseo-lleismo-yeismo")
end
else
if not need_yucatan then
express_style(false, "ทุกที่ยกเว้น<<{{w|Pampas}}>>และ<<Argentina>>ใต้ และ<<Uruguay>>", "distincion-lleismo",
"distincion-seseo-lleismo-yeismo")
else
express_style(false, "ทุกที่ยกเว้น<<{{w|Pampas}}>>และ<<Argentina>>ใต้, <<Uruguay>>, <<Mexico>>เหนือ, <<Yucatán>> และ<<Central America>> (ยกเว้น<<Panama>>)", "distincion-lleismo", "distincion-seseo-lleismo-yeismo")
end
end
elseif distincion_different and not lleismo_different then
express_style("<<Spain>>, <<Equatorial Guinea>>", "<<Spain>>, <<Equatorial Guinea>>", "distincion-lleismo", "distincion-lleismo-yeismo")
if not need_rioplat and not need_yucatan then
express_style("<<Latin America>>, <<Philippines>>", "<<Latin America>>, <<Philippines>>", "seseo-lleismo", "seseo-lleismo-yeismo")
else
express_style("<<Latin America>>, <<Philippines>>", "ส่วนใหญ่ของ<<Latin America>>, <<Philippines>>", "seseo-lleismo", "seseo-lleismo-yeismo")
end
elseif not distincion_different and lleismo_different then
express_style(false, "<<Spain>>, ส่วนใหญ่ของ<<Latin America>>, <<Equatorial Guinea>>", "distincion-yeismo", "distincion-seseo-yeismo")
express_style(false, "<<northern Spain>><<rural>>, <<Andes>>เหนือและตอนกลาง (ยกเว้น<<Ecuador>>ตอนกลาง), <<Bolivia>>, <<Paraguay>>, <<Argentina>>ตะวันออกเฉียงเหนือ, <<Philippines>>", "distincion-lleismo", "distincion-seseo-lleismo")
else
express_style("<<Spain>>, <<Equatorial Guinea>>", "ส่วนใหญ่ของ<<Spain>>, <<Equatorial Guinea>>", "distincion-yeismo")
express_style("<<Latin America>>", "ส่วนใหญ่ของ<<Latin America>>", "seseo-yeismo")
express_style("<<Spain>>, <<Equatorial Guinea>>", "<<northern Spain>><<rural>>", "distincion-lleismo")
express_style("<<Latin America>>", "<<Andes>>เหนือและตอนกลาง (ยกเว้น<<Ecuador>>ตอนกลาง), <<Bolivia>>, <<Paraguay>>, <<Argentina>>ตะวันออกเฉียงเหนือ, <<Philippines>>", "seseo-lleismo")
end
if need_rioplat then
if lleismo_different then
local hidden_tag = distincion_different and "<<Latin America>>" or false
if sheismo_different then
if not need_quito then
express_style(hidden_tag, "<<Buenos Aires>>และปริมณฑล", "rioplatense-sheismo", "seseo-rioplatense-sheismo")
express_style(hidden_tag, "<<Ecuador>>ตอนกลาง, <<Santiago del Estero>>และปริมณฑล, ที่อื่นใน<<{{w|Pampas}}>>และ<<Argentina>>ใต้, <<Uruguay>>", "rioplatense-zheismo", "seseo-rioplatense-zheismo-quito")
else
express_style(hidden_tag, "<<Ecuador>>ตอนกลาง, <<Santiago del Estero>>และปริมณฑล", "quito", "seseo-quito")
express_style(hidden_tag, "<<Buenos Aires>>และปริมณฑล", "rioplatense-sheismo", "seseo-rioplatense-sheismo")
express_style(hidden_tag, "ที่อื่นใน<<{{w|Pampas}}>>และ<<Argentina>>ใต้, <<Uruguay>>", "rioplatense-zheismo", "seseo-rioplatense-zheismo")
end
else
express_style(hidden_tag, "<<{{w|Pampas}}>>และ<<Argentina>>ใต้, <<Uruguay>>", "rioplatense-sheismo", "seseo-rioplatense-sheismo-zheismo")
end
else
local hidden_tag = distincion_different and "<<Latin America>>, <<Philippines>>" or false
if sheismo_different then
express_style(hidden_tag, "<<Buenos Aires>>และปริมณฑล", "rioplatense-sheismo", "seseo-rioplatense-sheismo")
express_style(hidden_tag, "ที่อื่นใน<<{{w|Pampas}}>>และ<<Argentina>>ใต้, <<Uruguay>>", "rioplatense-zheismo", "seseo-rioplatense-zheismo")
else
express_style(hidden_tag, "<<{{w|Pampas}}>>และ<<Argentina>>ใต้, <<Uruguay>>", "rioplatense-sheismo", "seseo-rioplatense-sheismo-zheismo")
end
end
end
if need_yucatan then
local hidden_tag = distincion_different and (lleismo_different and "<<Latin America>>" or "<<Latin America>>, <<Philippines>>") or false
express_style(hidden_tag, "<<Mexico>>เหนือ, <<Yucatán>>, <<Central America>> (ยกเว้น<<Panama>>)", "yucatan")
end
-- If only one style group, don't indicate the style.
-- Not clear we want this in reality.
--if #ret.expressed_styles == 1 then
-- ret.expressed_styles[1].tag = false
-- if #ret.expressed_styles[1].styles == 1 then
-- ret.expressed_styles[1].styles[1].tag = false
-- end
--end
return ret
end
local function format_all_styles(expressed_styles, format_style)
for i, style_group in ipairs(expressed_styles) do
if #style_group.styles == 1 then
style_group.formatted, style_group.formatted_len =
format_style(style_group.styles[1].tag, style_group.styles[1], i == 1)
else
style_group.formatted, style_group.formatted_len =
format_style(style_group.tag, style_group.styles[1], i == 1)
for j, style in ipairs(style_group.styles) do
style.formatted, style.formatted_len =
format_style(style.tag, style, i == 1 and j == 1)
end
end
end
local maxlen = 0
for i, style_group in ipairs(expressed_styles) do
local this_len = style_group.formatted_len
if #style_group.styles > 1 then
for _, style in ipairs(style_group.styles) do
this_len = math.max(this_len, style.formatted_len)
end
end
maxlen = math.max(maxlen, this_len)
end
local lines = {}
local need_major_hack = false
for i, style_group in ipairs(expressed_styles) do
if #style_group.styles == 1 then
table.insert(lines, style_group.formatted)
need_major_hack = false
else
local inline = '\n<div class="vsShow" style="display:none">\n' .. style_group.formatted .. "</div>"
local full_prons = {}
for _, style in ipairs(style_group.styles) do
table.insert(full_prons, style.formatted)
end
local full = '\n<div class="vsHide">\n' .. table.concat(full_prons, "\n") .. "</div>"
local em_length = math.floor(maxlen * 0.68) -- from [[Module:grc-pronunciation]]
table.insert(lines, '<div class="vsSwitcher" data-toggle-category="pronunciations" style="width: ' .. em_length .. 'em; max-width:100%;"><span class="vsToggleElement" style="float: right;"> </span>' .. inline .. full .. "</div>")
need_major_hack = true
end
end
-- major hack to get bullets working on the next line after a div box
return table.concat(lines, "\n") .. (need_major_hack and "\n<span></span>" or "")
end
local function dodialect_pronun(args, ret, dialect)
ret.pronun[dialect] = {}
for i, term in ipairs(args.terms) do
local phonemic, phonetic, differences
if term.raw then
phonemic = term.raw_phonemic
phonetic = term.raw_phonetic
differences = construct_default_differences(dialect)
else
phonemic = export.IPA(term.term, dialect, false)
phonetic = export.IPA(term.term, dialect, true)
differences = phonemic.differences
phonemic = phonemic.text
phonetic = phonetic.text
end
ret.pronun[dialect][i] = {
raw = term.raw,
phonemic = phonemic,
phonetic = phonetic,
refs = term.refs,
q = term.q,
qq = term.qq,
a = term.a,
aa = term.aa,
differences = differences,
}
end
end
local function generate_pronun(args)
local function this_dodialect_pronun(ret, dialect)
dodialect_pronun(args, ret, dialect)
end
local ret = express_all_styles(args.style, this_dodialect_pronun)
local function format_style(tag, expressed_style, is_first)
local pronunciations = {}
local formatted_pronuns = {}
local function ins(formatted_part)
table.insert(formatted_pronuns, formatted_part)
end
-- Loop through each pronunciation. For each one, add the phonemic and phonetic versions to `pronunciations`,
-- for formatting by [[Module:IPA]], and also create an approximation of the formatted version so that we can
-- compute the appropriate width of the HTML switcher div box that holds the different per-dialect variants.
-- NOTE: The code below constructs the formatted approximation out-of-order in some cases but that doesn't
-- currently matter because we assume all characters have the same width. If we change the width computation
-- in a way that requires the correct order, we need changes to the code below.
for j, pronun in ipairs(expressed_style.pronun) do
-- Add tag to right accent qualifiers if last one
local aas = pronun.aa
if j == #expressed_style.pronun and tag then
if aas then
aas = m_table.deepCopy(aas)
table.insert(aas, tag)
else
aas = {tag}
end
end
local first_pronun = #pronunciations + 1
if not pronun.phonemic and not pronun.phonetic then
error("Internal error: Saw neither phonemic nor phonetic pronunciation")
end
if pronun.phonemic then -- missing if 'raw:[...]' given
-- don't display syllable division markers in phonemic
local slash_pron = "/" .. pronun.phonemic:gsub("%.", "") .. "/"
table.insert(pronunciations, {
pron = slash_pron,
})
ins(slash_pron)
end
if pronun.phonetic then -- missing if 'raw:/.../' given
local bracket_pron = "[" .. pronun.phonetic .. "]"
table.insert(pronunciations, {
pron = bracket_pron,
})
ins(bracket_pron)
end
local last_pronun = #pronunciations
if pronun.q then
pronunciations[first_pronun].q = pronun.q
end
if pronun.a then
pronunciations[first_pronun].a = pronun.a
end
if j > 1 then
pronunciations[first_pronun].separator = ", "
ins(", ")
end
if pronun.qq then
pronunciations[last_pronun].qq = pronun.qq
end
if aas then
pronunciations[last_pronun].aa = aas
end
if pronun.q or pronun.qq or pronun.a or aas then
-- Note: This inserts the actual formatted decoration text, including HTML and such, but the later call
-- to textual_len() removes all HTML and reduces links.
ins(require(decorations_module).format_decorations {
lang = lang,
text = "",
q = pronun.q,
qq = pronun.qq,
a = pronun.a,
aa = aas,
})
end
if pronun.refs then
pronunciations[last_pronun].refs = pronun.refs
-- Approximate the reference using a footnote notation. This will be slightly inaccurate if there are
-- more than nine references but that is rare.
ins(string.rep("[1]", #pronun.refs))
end
if first_pronun ~= last_pronun then
pronunciations[last_pronun].separator = " "
ins(" ")
end
end
local bullet = string.rep("*", args.bullets) .. " "
-- Here we construct the formatted line in `formatted`, and also try to construct the equivalent without HTML
-- and wiki markup in `formatted_for_len`, so we can compute the approximate textual length for use in sizing
-- the toggle box with the "more" button on the right.
local pre = is_first and args.pre and args.pre .. " " or ""
local post = is_first and args.post and " " .. args.post or ""
local formatted = bullet .. pre ..
m_IPA.format_IPA_full { lang = lang, items = pronunciations, separator = "" } .. post
local formatted_for_len = bullet .. pre .. "IPA(key): " .. table.concat(formatted_pronuns) .. post
return formatted, textual_len(formatted_for_len)
end
ret.text = format_all_styles(ret.expressed_styles, format_style)
return ret
end
local function parse_respelling(respelling, pagename, parse_err)
local raw_respelling = respelling:match("^raw:(.*)$")
if raw_respelling then
local raw_phonemic, raw_phonetic = raw_respelling:match("^/(.*)/ %[(.*)%]$")
if not raw_phonemic then
raw_phonemic = raw_respelling:match("^/(.*)/$")
end
if not raw_phonemic then
raw_phonetic = raw_respelling:match("^%[(.*)%]$")
end
if not raw_phonemic and not raw_phonetic then
parse_err(("Unable to parse raw respelling '%s', should be one of /.../, [...] or /.../ [...]")
:format(raw_respelling))
end
return {
raw = true,
raw_phonemic = raw_phonemic,
raw_phonetic = raw_phonetic,
}
end
if respelling == "+" then
respelling = pagename
end
return {term = respelling}
end
-- External entry point for {{es-IPA}}.
function export.show(frame)
local params = {
[1] = {},
["pre"] = {},
["post"] = {},
["ref"] = {},
["style"] = {},
["bullets"] = {type = "number", default = 1},
}
local parargs = frame:getParent().args
local args = require(parameters_module).process(parargs, params)
local text = args[1] or mw.loadData("Module:headword/data").pagename
args.terms = {{term = text}}
local ret = generate_pronun(args)
return ret.text
end
-- Return the number of syllables of a phonemic representation, which should have syllable dividers in it but no
-- hyphens.
local function get_num_syl_from_phonemic(phonemic)
-- Maybe we should just count vowels instead of the below code.
phonemic = rsub(phonemic, "|", " ") -- remove IPA foot boundaries
local words = rsplit(phonemic, " +")
for i, word in ipairs(words) do
-- IPA stress marks are syllable divisions if between characters; otherwise just remove.
word = rsub(word, "(.)[ˌˈ](.)", "%1.%2")
word = rsub(word, "[ˌˈ]", "")
words[i] = word
end
-- There should be a syllable boundary between words.
phonemic = table.concat(words, ".")
return ulen(rsub(phonemic, "[^.]", "")) + 1
end
-- Get the rhyme by truncating everything up through the last stress mark + any following consonants, and remove
-- syllable boundary markers.
local function convert_phonemic_to_rhyme(phonemic)
-- NOTE: This works because the phonemic vowels are just [aeiou] possibly with diacritics that are separate
-- Unicode chars. If we want to handle things like ɛ or ɔ we need to add them to `vowel`.
return rsub(rsub(phonemic, ".*[ˌˈ]", ""), "^[^" .. vowel .. "]*", ""):gsub("%.", ""):gsub("t͡ʃ", "tʃ")
end
local function split_syllabified_spelling(spelling)
return rsplit(spelling, "%.")
end
-- "Align" syllabification to original spelling by matching character-by-character, allowing for extra syllable and
-- accent markers in the syllabification. If we encounter an extra syllable marker (.), we allow and keep it. If we
-- encounter an extra accent marker in the syllabification, we drop it. In any other case, we return nil indicating
-- the alignment failed.
local function align_syllabification_to_spelling(syllab, spelling)
local result = {}
local syll_chars = rsplit(decompose(syllab), "")
local spelling_chars = rsplit(decompose(spelling), "")
local i = 1
local j = 1
while i <= #syll_chars or j <= #spelling_chars do
local ci = syll_chars[i]
local cj = spelling_chars[j]
if ci == cj then
table.insert(result, ci)
i = i + 1
j = j + 1
elseif ci == "." then
table.insert(result, ci)
i = i + 1
elseif ci == AC or ci == GR or ci == CFLEX then
-- skip character
i = i + 1
else
-- non-matching character
return nil
end
end
if i <= #syll_chars or j <= #spelling_chars then
-- left-over characters on one side or the other
return nil
end
return unfc(table.concat(result))
end
local function generate_hyph_obj(term)
return {syllabification = term, hyph = split_syllabified_spelling(term)}
end
-- Word should already be decomposed.
local function word_has_vowels(word)
return rfind(word, V)
end
local function all_words_have_vowels(term)
local words = rsplit(decompose(term), "[ %-]")
for i, word in ipairs(words) do
-- Allow empty word; this occurs with prefixes and suffixes.
if word ~= "" and not word_has_vowels(word) then
return false
end
end
return true
end
local function should_generate_rhyme_from_respelling(term)
local words = rsplit(decompose(term), " +")
return #words == 1 and -- no if multiple words
not words[1]:find(".%-.") and -- no if word is composed of hyphenated parts (e.g. [[Austria-Hungría]])
not words[1]:find("%-$") and -- no if word is a prefix
not (words[1]:find("^%-") and words[1]:find(CFLEX)) and -- no if word is an unstressed suffix
word_has_vowels(words[1]) -- no if word has no vowels (e.g. a single letter)
end
local function should_generate_rhyme_from_ipa(ipa)
return not ipa:find("%s") and word_has_vowels(decompose(ipa))
end
local function dodialect_specified_rhymes(rhymes, hyphs, parsed_respellings, rhyme_ret, dialect)
rhyme_ret.pronun[dialect] = {}
for _, rhyme in ipairs(rhymes) do
local num_syl = rhyme.num_syl
local no_num_syl = false
-- If user explicitly gave the rhyme but didn't explicitly specify the number of syllables, try to take it from
-- the hyphenation.
if not num_syl then
num_syl = {}
for _, hyph in ipairs(hyphs) do
if should_generate_rhyme_from_respelling(hyph.syllabification) then
local this_num_syl = 1 + ulen(rsub(hyph.syllabification, "[^.]", ""))
m_table.insertIfNot(num_syl, this_num_syl)
else
no_num_syl = true
break
end
end
if no_num_syl or #num_syl == 0 then
num_syl = nil
end
end
-- If that fails and term is single-word, try to take it from the phonemic.
if not no_num_syl and not num_syl then
for _, parsed in ipairs(parsed_respellings) do
for dialect, pronun in pairs(parsed.pronun.pronun[dialect]) do
-- Check that pronun.phonemic exists (it may not if raw phonetic-only pronun is given).
if pronun.phonemic then
if not should_generate_rhyme_from_ipa(pronun.phonemic) then
no_num_syl = true
break
end
-- Count number of syllables by looking at syllable boundaries (including stress marks).
local this_num_syl = get_num_syl_from_phonemic(pronun.phonemic)
m_table.insertIfNot(num_syl, this_num_syl)
end
end
if no_num_syl then
break
end
end
if no_num_syl or #num_syl == 0 then
num_syl = nil
end
end
table.insert(rhyme_ret.pronun[dialect], {
rhyme = rhyme.rhyme,
num_syl = num_syl,
q = rhyme.q,
qq = rhyme.qq,
a = rhyme.a,
aa = rhyme.aa,
differences = construct_default_differences(dialect),
})
end
end
local q_qq_inline_modifier_spec = {
store = "insert-flattened",
type = "qualifier",
}
local a_aa_inline_modifier_spec = {
store = "insert-flattened",
type = "labels",
}
local ref_inline_modifier_spec = {
store = "insert-flattened",
item_dest = "refs",
type = "references",
}
-- Parse a pronunciation modifier in `arg`, the argument portion in an inline modifier (after the prefix), which
-- specifies a pronunciation property such as rhyme, hyphenation/syllabification, homophones or audio. The argument
-- can itself have inline modifiers, e.g. <audio:Foo.ogg<a:Colombia>>. The allowed inline modifiers are specified
-- by `param_mods` (of the format expected by `parse_inline_modifiers()`); in addition to any modifiers specified
-- there, the modifiers <q:...>, <qq:...>, <a:...>, <aa:...> and <ref:...> are always accepted (and can be repeated).
-- `generate_obj` and `parse_err` are like in `parse_inline_modifiers()` and specify respectively a function to
-- generate the object into which modifier properties are stored given the non-modifier part of the argument, and
-- a function to generate an error message (given the message). Normally, a comma-separated list of pronunciation
-- properties is accepted and parsed, where each element in the list can have its own inline modifiers and where
-- no spaces are allowed next to the commas in order for them to be recognized as separators. If `no_split_on_comma`
-- is given, only a single pronunciation property is accepted. In all cases, however, the return value is a list
-- of property objects (when `no_split_on_comma` is given, the return value is a one-element list).
local function parse_pron_modifier(arg, parse_err, generate_obj, param_mods, no_split_on_comma)
if arg:find("<") then
param_mods.q = q_qq_inline_modifier_spec
param_mods.qq = q_qq_inline_modifier_spec
param_mods.a = a_aa_inline_modifier_spec
param_mods.aa = a_aa_inline_modifier_spec
param_mods.ref = ref_inline_modifier_spec
local retval = require(parse_utilities_module).parse_inline_modifiers(arg, {
param_mods = param_mods,
generate_obj = generate_obj,
parse_err = parse_err,
splitchar = not no_split_on_comma and "," or nil,
})
if no_split_on_comma then
retval = {retval}
end
return retval
elseif no_split_on_comma then
return {generate_obj(arg)}
else
local retval = {}
for _, term in ipairs(split_on_comma(arg)) do
table.insert(retval, generate_obj(term))
end
return retval
end
end
local function parse_rhyme(arg, parse_err)
local function generate_obj(term)
return {rhyme = term}
end
local param_mods = {
s = {
item_dest = "num_syl",
type = "number",
sublist = true,
},
}
return parse_pron_modifier(arg, parse_err, generate_obj, param_mods)
end
local function parse_hyph(arg, parse_err)
-- None other than decorations
local param_mods = {}
return parse_pron_modifier(arg, parse_err, generate_hyph_obj, param_mods)
end
local function parse_homophone(arg, parse_err)
local function generate_obj(term)
return {term = term}
end
local param_mods = {
t = {
-- [[Module:links]] expects the gloss in "gloss".
item_dest = "gloss",
},
gloss = {},
-- No tr=, ts=, or sc=; doesn't make sense for Spanish.
pos = {},
alt = {},
lit = {},
id = {},
g = {
-- [[Module:links]] expects the genders in "genders".
item_dest = "genders",
sublist = true,
},
}
return parse_pron_modifier(arg, parse_err, generate_obj, param_mods)
end
local function generate_audio_obj(arg)
local file, caption = arg:match("^(.-)%s*#%s*(.*)$")
file = file or arg
return {file = file, caption = caption}
end
local function parse_audio(arg, parse_err)
local param_mods = {
IPA = {
sublist = true,
},
text = {},
t = {
item_dest = "gloss",
},
-- No tr=, ts=, or sc=; doesn't make sense for Spanish.
gloss = {},
pos = {},
-- No alt=; text= already goes in alt=.
lit = {},
-- No id=; text= already goes in alt= and isn't normally linked.
g = {
item_dest = "genders",
sublist = true,
},
bad = {},
}
-- Don't split on comma because some filenames have embedded commas not followed by a space
-- (typically followed by an underscore).
local retvals = parse_pron_modifier(arg, parse_err, generate_audio_obj, param_mods, "no split on comma")
local retval = retvals[1]
retval.lang = lang
local textobj = require(audio_module).construct_audio_textobj(retval)
retval.text = textobj
retval.gloss = nil
retval.pos = nil
retval.lit = nil
retval.genders = nil
return retval
end
-- External entry point for {{es-pr}}.
function export.show_pr(frame)
local params = {
[1] = {list = true},
["rhyme"] = {convert = parse_rhyme},
["hyph"] = {convert = parse_hyph},
["hmp"] = {convert = parse_homophone},
["audio"] = {list = true},
["pagename"] = {},
}
local parargs = frame:getParent().args
local args = require(parameters_module).process(parargs, params)
local pagename = args.pagename or mw.loadData(headword_data_module).pagename
-- Parse the arguments.
local respellings = #args[1] > 0 and args[1] or {"+"}
local parsed_respellings = {}
local overall_rhyme = args.rhyme
local overall_hyph = args.hyph
local overall_hmp = args.hmp
local overall_audio
if args.audio then
-- We can't specify parse_audio() as a `convert` function because it needs access to `pagename` (i.e. another
-- parameter).
overall_audio = {}
for i, audio in ipairs(args.audio) do
local function parse_err(msg)
error(("%s: parameter audio%s=%s"):format(msg, i == 1 and "" or i, audio))
end
local parsed_audio = parse_audio(audio, parse_err, pagename)
table.insert(overall_audio, parsed_audio)
end
end
for i, respelling in ipairs(respellings) do
if respelling:find("<") then
local param_mods = {
pre = { overall = true },
post = { overall = true },
style = { overall = true },
bullets = {
overall = true,
type = "number",
},
rhyme = {
overall = true,
store = "insert-flattened",
convert = parse_rhyme,
},
hyph = {
overall = true,
store = "insert-flattened",
convert = parse_hyph,
},
hmp = {
overall = true,
store = "insert-flattened",
convert = parse_homophone,
},
audio = {
overall = true,
store = "insert",
convert = function(arg, parse_err)
return parse_audio(arg, parse_err, pagename)
end,
},
ref = ref_inline_modifier_spec,
q = q_qq_inline_modifier_spec,
qq = q_qq_inline_modifier_spec,
a = a_aa_inline_modifier_spec,
aa = a_aa_inline_modifier_spec,
}
local parsed = require(parse_utilities_module).parse_inline_modifiers(respelling, {
paramname = i,
param_mods = param_mods,
generate_obj = function(term, parse_err)
return parse_respelling(term, pagename, parse_err)
end,
splitchar = ",",
outer_container = {
audio = {}, rhyme = {}, hyph = {}, hmp = {}
}
})
if not parsed.bullets then
parsed.bullets = 1
end
table.insert(parsed_respellings, parsed)
else
local termobjs = {}
local function parse_err(msg)
error(msg .. ": " .. i .. "=" .. respelling)
end
for _, term in ipairs(split_on_comma(respelling)) do
table.insert(termobjs, parse_respelling(term, pagename, parse_err))
end
table.insert(parsed_respellings, {
terms = termobjs,
audio = {},
rhyme = {},
hyph = {},
hmp = {},
bullets = 1,
})
end
end
if overall_hyph then
local hyphs = {}
for _, hyph in ipairs(overall_hyph) do
if hyph.syllabification == "+" then
hyph.syllabification = syllabify_from_spelling(pagename)
hyph.hyph = split_syllabified_spelling(hyph.syllabification)
elseif hyph.syllabification == "-" then
overall_hyph = {}
break
end
end
end
-- Loop over individual respellings, processing each.
for _, parsed in ipairs(parsed_respellings) do
parsed.pronun = generate_pronun(parsed)
local no_auto_rhyme = false
for _, term in ipairs(parsed.terms) do
if term.raw then
if not should_generate_rhyme_from_ipa(term.raw_phonemic or term.raw_phonetic) then
no_auto_rhyme = true
break
end
elseif not should_generate_rhyme_from_respelling(term.term) then
no_auto_rhyme = true
break
end
end
if #parsed.hyph == 0 then
if not overall_hyph and all_words_have_vowels(pagename) then
for _, term in ipairs(parsed.terms) do
if not term.raw then
local syllabification = syllabify_from_spelling(term.term)
local aligned_syll = align_syllabification_to_spelling(syllabification, pagename)
if aligned_syll then
m_table.insertIfNot(parsed.hyph, generate_hyph_obj(aligned_syll))
end
end
end
end
else
for _, hyph in ipairs(parsed.hyph) do
if hyph.syllabification == "+" then
hyph.syllabification = syllabify_from_spelling(pagename)
hyph.hyph = split_syllabified_spelling(hyph.syllabification)
elseif hyph.syllabification == "-" then
parsed.hyph = {}
break
end
end
end
-- Generate the rhymes.
local function dodialect_rhymes_from_pronun(rhyme_ret, dialect)
rhyme_ret.pronun[dialect] = {}
-- It's possible the pronunciation for a passed-in dialect was never generated. This happens e.g. with
-- {{es-pr|cebolla<style:seseo>}}. The initial call to generate_pronun() fails to generate a pronunciation
-- for the dialect 'distinction-yeismo' because the pronunciation of 'cebolla' differs between distincion
-- and seseo and so the seseo style restriction rules out generation of pronunciation for distincion
-- dialects (other than 'distincion-lleismo', which always gets generated so as to determine on which axes
-- the dialects differ). However, when generating the rhyme, it is based only on -olla, whose pronunciation
-- does not differ between distincion and seseo, but does differ between lleismo and yeismo, so it needs to
-- generate a yeismo-specific rhyme, and 'distincion-yeismo' is the representative dialect for yeismo in the
-- situation where distincion and seseo do not have distinct results (based on the following line in
-- express_all_styles()):
-- express_style(false, "<<Spain>>, most of <<Latin America>>, <<Equatorial Guinea>>", "distincion-yeismo", "distincion-seseo-yeismo")
-- In this case we need to generate the missing overall pronunciation ourselves since we need it to generate
-- the dialect-specific rhyme pronunciation.
if not parsed.pronun.pronun[dialect] then
dodialect_pronun(parsed, parsed.pronun, dialect)
end
for _, pronun in ipairs(parsed.pronun.pronun[dialect]) do
-- We should have already excluded multiword terms and terms without vowels from rhyme generation (see
-- `no_auto_rhyme` below). But make sure to check that pronun.phonemic exists (it may not if raw
-- phonetic-only pronun is given).
if pronun.phonemic then
-- Count number of syllables by looking at syllable boundaries (including stress marks).
local num_syl = get_num_syl_from_phonemic(pronun.phonemic)
-- Get the rhyme by truncating everything up through the last stress mark + any following
-- consonants, and remove syllable boundary markers.
local rhyme = convert_phonemic_to_rhyme(pronun.phonemic)
local saw_already = false
for _, existing in ipairs(rhyme_ret.pronun[dialect]) do
if existing.rhyme == rhyme then
saw_already = true
-- We already saw this rhyme but possibly with a different number of syllables,
-- e.g. if the user specified two pronunciations 'biología' (4 syllables) and
-- 'bi.ología' (5 syllables), both of which have the same rhyme /ia/.
m_table.insertIfNot(existing.num_syl, num_syl)
break
end
end
if not saw_already then
local rhyme_diffs = nil
if dialect == "distincion-lleismo" then
rhyme_diffs = {}
if rhyme:find("θ") then
rhyme_diffs.distincion_different = true
end
if rhyme:find("ʎ") then
rhyme_diffs.lleismo_different = true
if rhyme:find("ɟ") then
rhyme_diffs.need_quito = true
end
end
if rfind(rhyme, "[ʎɟ]") then
rhyme_diffs.sheismo_different = true
rhyme_diffs.need_rioplat = true
if rfind(rhyme, V .. "[ʎɟ]" .. V) then
rhyme_diffs.need_yucatan = true
end
end
end
table.insert(rhyme_ret.pronun[dialect], {
rhyme = rhyme,
num_syl = {num_syl},
differences = rhyme_diffs,
})
end
end
end
end
if #parsed.rhyme == 0 then
if overall_rhyme or no_auto_rhyme then
parsed.rhyme = nil
else
parsed.rhyme = express_all_styles(parsed.style, dodialect_rhymes_from_pronun)
end
else
local no_rhyme = false
for _, rhyme in ipairs(parsed.rhyme) do
if rhyme.rhyme == "-" then
no_rhyme = true
break
end
end
if no_rhyme then
parsed.rhyme = nil
else
local function this_dodialect(rhyme_ret, dialect)
return dodialect_specified_rhymes(parsed.rhyme, parsed.hyph, {parsed}, rhyme_ret, dialect)
end
parsed.rhyme = express_all_styles(parsed.style, this_dodialect)
end
end
end
if overall_rhyme then
local no_overall_rhyme = false
for _, orhyme in ipairs(overall_rhyme) do
if orhyme.rhyme == "-" then
no_overall_rhyme = true
break
end
end
if no_overall_rhyme then
overall_rhyme = nil
else
local all_hyphs
if overall_hyph then
all_hyphs = overall_hyph
else
all_hyphs = {}
for _, parsed in ipairs(parsed_respellings) do
for _, hyph in ipairs(parsed.hyph) do
m_table.insertIfNot(all_hyphs, hyph)
end
end
end
local function dodialect_overall_rhyme(rhyme_ret, dialect)
return dodialect_specified_rhymes(overall_rhyme, all_hyphs, parsed_respellings, rhyme_ret, dialect)
end
overall_rhyme = express_all_styles(parsed.style, dodialect_overall_rhyme)
end
end
-- If all sets of pronunciations have the same rhymes, display them only once at the bottom.
-- Otherwise, display rhymes beneath each set, indented.
local first_rhyme_ret
local all_rhyme_sets_eq = true
for j, parsed in ipairs(parsed_respellings) do
if j == 1 then
first_rhyme_ret = parsed.rhyme
elseif not m_table.deepEquals(first_rhyme_ret, parsed.rhyme) then
all_rhyme_sets_eq = false
break
end
end
local function format_rhyme(rhyme_ret, num_bullets)
local function format_rhyme_style(tag, expressed_style, is_first)
local pronunciations = {}
local rhymes = {}
for _, pronun in ipairs(expressed_style.pronun) do
table.insert(rhymes, pronun)
end
local data = {
lang = lang,
rhymes = rhymes,
aa = tag and {tag} or nil,
force_cat = force_cat,
}
local bullet = string.rep("*", num_bullets) .. " "
local formatted = bullet .. require(rhymes_module).format_rhymes(data)
local formatted_for_len_parts = {}
table.insert(formatted_for_len_parts, bullet .. "Rhymes: " .. (tag and "(" .. tag .. ") " or ""))
for j, pronun in ipairs(expressed_style.pronun) do
if j > 1 then
table.insert(formatted_for_len_parts, ", ")
end
if pronun.q or pronun.qq or pronun.a or pronun.aa then
-- Note: This inserts the actual formatted decoration text, including HTML and such, but the later call
-- to textual_len() removes all HTML and reduces links.
table.insert(formatted_for_len_parts, require(decorations_module).format_decorations {
lang = lang,
text = "",
q = pronun.q,
qq = pronun.qq,
a = pronun.a,
aa = pronun.aa,
})
end
table.insert(formatted_for_len_parts, "-" .. pronun.rhyme)
end
return formatted, textual_len(table.concat(formatted_for_len_parts))
end
return format_all_styles(rhyme_ret.expressed_styles, format_rhyme_style)
end
-- If all sets of pronunciations have the same hyphenations, display them only once at the bottom.
-- Otherwise, display hyphenations beneath each set, indented.
local first_hyphs
local all_hyph_sets_eq = true
for j, parsed in ipairs(parsed_respellings) do
if j == 1 then
first_hyphs = parsed.hyph
elseif not m_table.deepEquals(first_hyphs, parsed.hyph) then
all_hyph_sets_eq = false
break
end
end
local function format_hyphenations(hyphs, num_bullets)
local hyphtext = require(hyphenation_module).format_hyphenations { lang = lang, hyphs = hyphs, caption = "การแบ่งพยางค์" }
return string.rep("*", num_bullets) .. " " .. hyphtext
end
-- If all sets of pronunciations have the same homophones, display them only once at the bottom.
-- Otherwise, display homophones beneath each set, indented.
local first_hmps
local all_hmp_sets_eq = true
for j, parsed in ipairs(parsed_respellings) do
if j == 1 then
first_hmps = parsed.hmp
elseif not m_table.deepEquals(first_hmps, parsed.hmp) then
all_hmp_sets_eq = false
break
end
end
local function format_homophones(hmps, num_bullets)
local hmptext = require(homophones_module).format_homophones { lang = lang, homophones = hmps }
return string.rep("*", num_bullets) .. " " .. hmptext
end
local function format_audio(audios, num_bullets)
local ret = {}
for i, audio in ipairs(audios) do
local text = require(audio_module).format_audio(audio)
table.insert(ret, string.rep("*", num_bullets) .. " " .. text)
end
return table.concat(ret, "\n")
end
local textparts = {}
local min_num_bullets = math.huge
for j, parsed in ipairs(parsed_respellings) do
if parsed.bullets < min_num_bullets then
min_num_bullets = parsed.bullets
end
if j > 1 then
table.insert(textparts, "\n")
end
table.insert(textparts, parsed.pronun.text)
if #parsed.audio > 0 then
table.insert(textparts, "\n")
-- If only one pronunciation set, add the audio with the same number of bullets, otherwise
-- indent audio by one more bullet.
table.insert(textparts, format_audio(parsed.audio,
#parsed_respellings == 1 and parsed.bullets or parsed.bullets + 1))
end
if not all_rhyme_sets_eq and parsed.rhyme then
table.insert(textparts, "\n")
table.insert(textparts, format_rhyme(parsed.rhyme, parsed.bullets + 1))
end
if not all_hyph_sets_eq and #parsed.hyph > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_hyphenations(parsed.hyph, parsed.bullets + 1))
end
if not all_hmp_sets_eq and #parsed.hmp > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_homophones(parsed.hmp, parsed.bullets + 1))
end
end
if overall_audio and #overall_audio > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_audio(overall_audio, min_num_bullets))
end
if all_rhyme_sets_eq and first_rhyme_ret then
table.insert(textparts, "\n")
table.insert(textparts, format_rhyme(first_rhyme_ret, min_num_bullets))
end
if overall_rhyme then
table.insert(textparts, "\n")
table.insert(textparts, format_rhyme(overall_rhyme, min_num_bullets))
end
if all_hyph_sets_eq and #first_hyphs > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_hyphenations(first_hyphs, min_num_bullets))
end
if overall_hyph and #overall_hyph > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_hyphenations(overall_hyph, min_num_bullets))
end
if all_hmp_sets_eq and #first_hmps > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_homophones(first_hmps, min_num_bullets))
end
if overall_hmp and #overall_hmp > 0 then
table.insert(textparts, "\n")
table.insert(textparts, format_homophones(overall_hmp, min_num_bullets))
end
return table.concat(textparts)
end
return export
6fdizosw79kuqmrsp5zlejow1ag3vff
มอดูล:pt-headword
828
236296
5775328
5729301
2026-10-15T03:49:07Z
Octahedron80
267
5775328
Scribunto
text/plain
-- This module contains code for Portuguese headword templates.
-- Templates covered are:
-- * {{pt-noun}}, {{pt-proper noun}};
-- * {{pt-verb}};
-- * {{pt-adj}}, {{pt-adj-comp}}, {{pt-adj-sup}};
-- * {{pt-det}};
-- * {{pt-pron-adj}};
-- * {{pt-contr-adj}};
-- * {{pt-pp}};
-- * {{pt-cardinal}};
-- * {{pt-adv}}.
-- See [[Module:pt-verb]] for Portuguese conjugation templates.
local export = {}
local pos_functions = {}
local force_cat = false -- for testing; if true, categories appear in non-mainspace pages
local m_strutils = require("Module:string utilities")
local require_when_needed = require("Module:utilities/require when needed")
local m_table = require("Module:table")
local com = require("Module:pt-common")
local en_utilities_module = "Module:en-utilities"
local headword_utilities_module = "Module:headword utilities"
local inflection_utilities_module = "Module:inflection utilities"
local romut_module = "Module:romance utilities"
local pt_verb_module = "Module:pt-verb"
local lang = require("Module:languages").getByCode("pt")
local langname = --[[lang:getCanonicalName()]] lang:getCategoryName()
local m_en_utilities = require_when_needed(en_utilities_module)
local m_headword_utilities = require_when_needed(headword_utilities_module)
local glossary_link = require_when_needed(headword_utilities_module, "glossary_link")
local insert = table.insert
local rfind = m_strutils.find
local rmatch = m_strutils.match
local ulower = m_strutils.lower
local usub = m_strutils.sub
local uupper = m_strutils.upper
-- When followed by a hyphen in a hyphenated compound, the hyphen will be included with the prefix when linked.
local include_hyphen_prefixes = m_table.listToSet {
"ab",
"afro",
"anarco",
"anglo",
"ântero",
"anti",
"auto",
"contra",
"ex",
"franco",
"hiper",
"infra",
"inter",
"intra",
"macro",
"micro",
"neo",
"pan",
"pós",
"pré",
"pró",
"proto",
"sobre",
"sub",
"super",
"vice",
}
-----------------------------------------------------------------------------------------
-- Utility functions --
-----------------------------------------------------------------------------------------
local function track(page)
require("Module:debug/track")("pt-headword/" .. page)
return true
end
local list_param = {list = true, disallow_holes = true}
local boolean_param = {type = "boolean"}
local metaphonic_label = "[[ภาคผนวก:การออกเสียงภาษาโปรตุเกส#เมทาโฟนี|เมทาโฟนี]]"
local function make_plural(sg, special)
local pl = com.make_plural(sg, special)
if not pl then
error(("Internal error: Unable to generate default plural of '%s'"):format(sg))
end
return pl
end
-- Parse and insert an inflection not requiring additional processing into `data.inflections`. The raw arguments come
-- from `args[field]`, which is parsed for inline modifiers. `label` is the label that the inflections are given;
-- `plpos` is the plural part of speech, used in [[Category:LANGNAME PLPOS with red links in their headword lines]].
-- `accel` is the accelerator form, or nil.
local function parse_and_insert_inflection(data, args, field, label, accel, frob)
m_headword_utilities.parse_and_insert_inflection {
headdata = data,
forms = args[field],
paramname = field,
splitchar = ",",
include_mods = {"g"},
label = label,
accel = accel and {form = accel} or nil,
frob = frob,
}
end
-- The main entry point.
-- This is the only function that can be invoked from a template.
function export.show(frame)
local poscat = frame.args[1] or error("Part of speech has not been specified. Please pass parameter 1 to the module invocation.")
-- หมวดหมู่เป็นภาษาไทย
local poscat_th = require("Module:th-utilities").th_pos(poscat)
local parargs = frame:getParent().args
local params = {
["head"] = list_param,
["id"] = true,
["json"] = boolean_param,
["splithyph"] = boolean_param,
["nolinkhead"] = boolean_param,
["nolink"] = {type = "boolean", alias_of = "nolinkhead"},
["abbr"] = list_param,
["pagename"] = true, -- for testing
}
if pos_functions[poscat_th] then
for key, val in pairs(pos_functions[poscat_th].params) do
params[key] = val
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local user_specified_heads = args.head
local heads = user_specified_heads
if args.nolinkhead then
if #heads == 0 then
heads = {pagename}
end
else
local romut = require(romut_module)
local auto_linked_head = romut.add_links_to_multiword_term(pagename, args.splithyph, nil,
include_hyphen_prefixes)
if #heads == 0 then
heads = {auto_linked_head}
else
for i, head in ipairs(heads) do
if head:find("^~") then
head = romut.apply_link_modifiers(auto_linked_head, usub(head, 2))
heads[i] = head
end
end
end
end
local data = {
lang = lang,
pos_category = pos_functions[poscat_th] and pos_functions[poscat_th].pos_category or poscat_th,
categories = {},
heads = heads,
user_specified_heads = user_specified_heads,
no_redundant_head_cat = #user_specified_heads == 0,
genders = {},
inflections = {},
pagename = pagename,
id = args.id,
force_cat_output = force_cat,
checkredlinks = pos_functions[poscat_th] and pos_functions[poscat_th].redlink_pos or true,
}
if pagename:find("^%-") and poscat_th ~= "รูปปัจจัย" then
data.is_suffix = true
data.pos_category = "ปัจจัย"
data.checkredlinks = true
local singular_poscat = --[[m_en_utilities.singularize(poscat)]] poscat_th
insert(data.categories, "ปัจจัยสร้าง" .. singular_poscat .. langname)
insert(data.inflections, {label = "ปัจจัยสร้าง" .. singular_poscat})
end
local pagename_lower = ulower(pagename)
for _, ch in ipairs{"gü", "jh", "kh", "ph", "qü", "sh", "th", "tl", "ts", "tz", "wh", "zh"} do
if pagename_lower:find(ch) then
insert(data.categories, "ศัพท์" .. langname .. "ที่สะกดด้วย " .. uupper(ch))
end
end
if pos_functions[poscat_th] then
pos_functions[poscat_th].func(args, data, is_suffix)
end
parse_and_insert_inflection(data, args, "abbr", "abbreviation")
if args.json then
return require("Module:JSON").toJSON(data)
end
return require("Module:headword").full_headword(data)
end
local function replace_hash_with_lemma(term, lemma)
-- If there is a % sign in the lemma, we have to replace it with %% so it doesn't get interpreted as a capture replace
-- expression.
lemma = lemma:gsub("%%", "%%%%")
return (term:gsub("#", lemma))
end
local function is_metaphonic(args, lemma)
if args.nometa then
return false
end
if args.meta then
return true
end
-- Anything in -oso with a preceding vowel (e.g. [[gostoso]], [[curioso]]) is normally metaphonic.
return rfind(lemma, com.V .. ".*oso$")
end
-----------------------------------------------------------------------------------------
-- Nouns --
-----------------------------------------------------------------------------------------
local allowed_genders = m_table.listToSet(
{"m", "f", "mf", "mfbysense", "mfequiv", "gneut", "n", "m-p", "f-p", "mf-p", "mfbysense-p", "mfequiv-p", "gneut-p", "n-p", "?", "?-p"}
)
local function validate_genders(genders)
for _, g in ipairs(genders) do
if type(g) == "table" then
g = g.spec
end
if not allowed_genders[g] then
error("Unrecognized gender: " .. g)
end
end
end
local function do_noun(args, data, is_proper)
local is_plurale_tantum = false
local has_singular = false
local category_plpos = data.checkredlinks
if category_plpos == true then
category_plpos = data.pos_category
end
local category_pos = --[[m_en_utilities.singularize(category_plpos)]] category_plpos
validate_genders(args[1])
data.genders = args[1]
local saw_m = false
local saw_f = false
local saw_gneut = false
local gender_for_irreg_ending
-- Check for specific genders and pluralia tantum.
for _, g in ipairs(args[1]) do
if type(g) == "table" then
g = g.spec
end
if g:find("-p$") then
is_plurale_tantum = true
else
has_singular = true
if g == "m" or g == "mf" or g == "mfbysense" then
saw_m = true
end
if g == "f" or g == "mf" or g == "mfbysense" then
saw_f = true
end
if g == "gneut" then
saw_gneut = true
end
end
end
if saw_m and saw_f then
gender_for_irreg_ending = "mf"
elseif saw_f then
gender_for_irreg_ending = "f"
else
gender_for_irreg_ending = "m"
end
local lemma = data.pagename
local plurals = {}
local function insert_noun_inflection(terms, label, accel)
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
accel = accel and {form = accel} or nil,
}
end
if is_plurale_tantum and not has_singular then
if args[2][1] then
error("Can't specify plurals of plurale tantum " .. category_pos)
end
insert(data.inflections, {label = glossary_link("พหูพจน์เท่านั้น")})
else
plurals = m_headword_utilities.parse_term_list_with_modifiers {
paramname = {2, "pl"},
forms = args[2],
splitchar = ",",
}
-- Check for special plural signals
local mode = nil
local pl1 = plurals[1]
if pl1 and #pl1.term == 1 then
mode = pl1.term
if mode == "?" or mode == "!" or mode == "-" or mode == "~" then
pl1.term = nil
if m_headword_utilities.termobj_has_decorations(pl1) then
error(("Can't specify inline modifiers with plural code '%s'"):format(mode))
end
table.remove(plurals, 1) -- Remove the mode parameter
elseif mode ~= "+" and mode ~= "#" then
error(("Unexpected plural code '%s'"):format(mode))
end
end
if is_plurale_tantum then
-- both singular and plural
insert(data.inflections, {label = "บางครั้ง" .. glossary_link("พหูพจน์เท่านั้น") .. "ในภาษาย่อย"})
end
if mode == "?" then
-- Plural is unknown
insert(data.categories, langname .. " " .. category_plpos .. " with unknown or uncertain plurals")
elseif mode == "!" then
-- Plural is not attested
insert(data.inflections, {label = "plural not attested"})
insert(data.categories, langname .. " " .. category_plpos .. " with unattested plurals")
if plurals[1] then
error("Can't specify any plurals along with unattested plural code '!'")
end
elseif mode == "-" then
-- Uncountable noun; may occasionally have a plural
insert(data.categories, category_plpos .. "นับไม่ได้" .. langname)
-- If plural forms were given explicitly, then show "usually"
if plurals[1] then
insert(data.inflections, {label = "โดยปกติ" .. glossary_link("นับไม่ได้")})
insert(data.categories, category_plpos .. "นับได้" .. langname)
else
insert(data.inflections, {label = glossary_link("นับไม่ได้")})
end
else
-- Countable or mixed countable/uncountable
if not plurals[1] and not is_proper then
plurals[1] = {term = "+"}
end
if mode == "~" then
-- Mixed countable/uncountable noun, always has a plural
insert(data.inflections, {label = glossary_link("นับได้") .. "และ" .. glossary_link("นับไม่ได้")})
insert(data.categories, category_plpos .. "นับไม่ได้" .. langname)
insert(data.categories, category_plpos .. "นับได้" .. langname)
elseif plurals[1] then
-- Countable nouns
insert(data.categories, category_plpos .. "นับได้" .. langname)
else
-- Uncountable nouns
insert(data.categories, category_plpos .. "นับไม่ได้" .. langname)
end
end
-- Gather plurals, handling requests for default plurals.
local has_default_or_hash = false
for _, pl in ipairs(plurals) do
if pl.term:find("^%+") or pl.term:find("#") then
has_default_or_hash = true
break
end
end
if has_default_or_hash then
for _, pl in ipairs(plurals) do
if pl.term == "+" then
pl.term = make_plural(lemma)
elseif pl.term:find("^%+") then
pl.term = require(romut_module).get_special_indicator(pl.term)
pl.term = make_plural(lemma, pl.term)
else
pl.term = replace_hash_with_lemma(pl.term, lemma)
end
end
end
local pl1 = plurals[1]
if pl1 and not plurals[2] and pl1.term == lemma then
insert(data.inflections, {label = glossary_link("ผันรูปไม่ได้"),
q = pl1.q, qq = pl1.qq, l = pl1.l, ll = pl1.ll, refs = pl1.refs
})
insert(data.categories, category_plpos .. "ผันรูปไม่ได้" .. langname)
else
insert_noun_inflection(plurals, "พหูพจน์", "p")
end
if plurals[2] then
insert(data.categories, langname .. " " .. category_plpos .. " with multiple plurals")
end
end
-- Gather masculines/feminines. For each one, generate the corresponding plural. `field` is the name of the field
-- containing the masculine or feminine forms (normally "m" or "f"); `inflect` is a function of one or two arguments
-- to generate the default masculine or feminine from the lemma (the arguments are the lemma and optionally a
-- "special" flag to indicate how to handle multiword lemmas, and the function is normally make_feminine or
-- make_masculine from [[Module:pt-common]]); and `default_plurals` is a list into which the corresponding default
-- plurals of the gathered or generated masculine or feminine forms are stored.
local function handle_mf(field, inflect, default_plurals)
local specials = {} -- Tracks the specific plural indicators for each entry in a multi-item list
local term_index = 0
local mfs = m_headword_utilities.parse_term_list_with_modifiers {
paramname = field,
forms = args[field],
splitchar = ",",
frob = function(term)
term_index = term_index + 1
if term == "+" then
-- Generate default masculine/feminine.
term = inflect(lemma)
else
term = replace_hash_with_lemma(term, lemma)
end
local special = require(romut_module).get_special_indicator(term)
if special then
specials[term_index] = special -- Store indicator unique to this specific item's index
term = inflect(lemma, special)
end
return term
end
}
for i, mf in ipairs(mfs) do
local plobj = m_table.shallowCopy(mf)
local term_special = specials[i] -- Retrieve indicator matching this exact singular's index
plobj.term = make_plural(mf.term, term_special)
-- Add an accelerator for each masculine/feminine plural whose lemma is the corresponding singular, so that
-- the accelerated entry that is generated has a definition that looks like
-- # {{plural of|pt|MFSING}}
plobj.accel = {form = "p", lemma = mf.term}
insert(default_plurals, plobj)
end
return mfs
end
local feminine_plurals = {}
local feminines = handle_mf("f", com.make_feminine, feminine_plurals)
local masculine_plurals = {}
local masculines = handle_mf("m", com.make_masculine, masculine_plurals)
local function handle_mf_plural(mfplfield, default_plurals, singulars)
local mfpl = m_headword_utilities.parse_term_list_with_modifiers {
paramname = mfplfield,
forms = args[mfplfield],
splitchar = ",",
}
if is_plurale_tantum then
return mfpl
end
local new_mfpls = {}
local saw_plus
for i, mfpl in ipairs(mfpl) do
local accel
if #mfpl == #singulars then
-- If same number of overriding masculine/feminine plurals as singulars, assume each plural goes with
-- the corresponding singular and use each corresponding singular as the lemma in the accelerator. The
-- generated entry will have
-- # {{plural of|pt|SINGULAR}}
-- as the definition.
accel = {form = "p", lemma = singulars[i].term}
else
accel = nil
end
if mfpl.term == "+" then
-- We should never see + twice. If we do, it will lead to problems since we overwrite the values of
-- default_plurals the first time around.
if saw_plus then
error(("Saw + twice when handling %s="):format(mfplfield))
end
saw_plus = true
if not default_plurals[1] then
-- FIXME: Can this happen? Not in corresponding Spanish code and the old Portuguese code tried to
-- handle this condition by generating the default plural from the lemma.
error("Internal error: Something wrong, no generated default m/f plurals at this stage")
end
for _, defpl in ipairs(default_plurals) do
-- defpl is already a table and has an accel field
m_headword_utilities.combine_termobj_decorations(defpl, mfpl)
insert(new_mfpls, defpl)
end
elseif mfpl.term:find("^%+") then
mfpl.term = require(romut_module).get_special_indicator(mfpl.term)
for _, mf in ipairs(singulars) do
local mfplobj = m_table.shallowCopy(mfpl)
mfplobj.term = make_plural(mf.term, mfpl.term)
mfplobj.accel = accel
m_headword_utilities.combine_termobj_decorations(mfplobj, mf)
insert(new_mfpls, mfplobj)
end
else
mfpl.accel = accel
mfpl.term = replace_hash_with_lemma(mfpl.term, lemma)
insert(new_mfpls, mfpl)
end
end
return new_mfpls
end
if args.fpl[1] then
-- Override any existing feminine plurals.
feminine_plurals = handle_mf_plural("fpl", feminine_plurals, feminines)
end
if args.mpl[1] then
-- Override any existing masculine plurals.
masculine_plurals = handle_mf_plural("mpl", masculine_plurals, masculines)
end
local function parse_and_insert_noun_inflection(field, label, accel)
parse_and_insert_inflection(data, args, field, label, accel)
end
insert_noun_inflection(feminines, "เพศหญิง", "f")
insert_noun_inflection(feminine_plurals, "เพศหญิงพหูพจน์")
insert_noun_inflection(masculines, "เพศชาย")
insert_noun_inflection(masculine_plurals, "เพศชายพหูพจน์")
if is_metaphonic(args, lemma) then
insert(data.inflections, {label = metaphonic_label})
insert(data.categories, plpos .. langname .. "ที่มีเมทาโฟนี")
end
parse_and_insert_noun_inflection("dim", "ตัวบอกความเล็ก")
parse_and_insert_noun_inflection("aug", "ตัวบอกความใหญ่")
parse_and_insert_noun_inflection("pej", "pejorative")
parse_and_insert_noun_inflection("dem", "คำประชานาม")
parse_and_insert_noun_inflection("fdem", "คำประชานามหญิง")
-- Maybe add category 'Portuguese nouns with irregular gender' (or similar)
local irreg_gender_lemma = com.rsub(lemma, " .*", "") -- only look at first word
if (rfind(irreg_gender_lemma, "[^ã]o$") and (gender_for_irreg_ending == "f" or gender_for_irreg_ending == "mf")) or
(irreg_gender_lemma:find("a$") and (gender_for_irreg_ending == "m" or gender_for_irreg_ending == "mf")) then
insert(data.categories, langname .. " " .. category_plpos .. " with irregular gender")
end
end
local function get_noun_params(is_proper)
return {
[1] = {list = "g", disallow_holes = true, required = not is_proper, default = "?", type = "genders",
flatten = true},
[2] = {list = "pl", disallow_holes = true},
["m"] = list_param,
["f"] = list_param,
["mpl"] = list_param,
["fpl"] = list_param,
["dim"] = list_param, --diminutive(s)
["aug"] = list_param, --diminutive(s)
["pej"] = list_param, --pejorative(s)
["dem"] = list_param, --demonym(s)
["fdem"] = list_param, --female demonym(s)
["meta"] = boolean_param, -- metaphonic
["nometa"] = boolean_param, -- explicitly not metaphonic
}
end
pos_functions["คำนาม"] = {
params = get_noun_params(),
func = do_noun,
}
pos_functions["คำวิสามานยนาม"] = {
params = get_noun_params("is proper"),
func = function(args, data)
do_noun(args, data, "is proper noun")
end,
}
-----------------------------------------------------------------------------------------
-- Pronouns --
-----------------------------------------------------------------------------------------
local function do_pronoun(args, data)
local lemma = data.pagename
validate_genders(args[1])
data.genders = args[1]
local function do_inflection(field, label, accel)
parse_and_insert_inflection(data, args, field, label, accel)
end
do_inflection("m", "เพศชาย")
do_inflection("f", "เพศหญิง")
do_inflection("sg", "เอกพจน์")
do_inflection("pl", "พหูพจน์")
do_inflection("mpl", "เพศชายพหูพจน์")
do_inflection("fpl", "เพศหญิงพหูพจน์")
do_inflection("n", "เพศกลาง")
end
local function get_pronoun_params()
local params = {
[1] = {list = "g", disallow_holes = true, type = "genders", flatten = true}, --gender(s)
["m"] = list_param, --masculine form(s)
["f"] = list_param, --feminine form(s)
["sg"] = list_param, --singular form(s)
["pl"] = list_param, --plural form(s)
["mpl"] = list_param, --masculine plural form(s)
["fpl"] = list_param, --feminine plural form(s)
["n"] = list_param, --neuter form(s)
}
return params
end
pos_functions["คำสรรพนาม"] = {
params = get_pronoun_params(),
func = do_pronoun,
}
-----------------------------------------------------------------------------------------
-- Adjectives --
-----------------------------------------------------------------------------------------
-- Handle comparatives and superlatives for adjectives and adverbs, including user-specified comparatives and
-- superlatives, default-requested comparatives/superlatives using '+', autogenerated comparatives/superlatives,
-- and hascomp=. Code is the same for adjectives and adverbs.
local function handle_adj_adv_comp(args, data, plpos, is_adv)
local lemma = data.pagename
local stem
if is_adv then
stem = com.rsub(lemma, "mente$", "")
else
stem = lemma
end
local function insert_inflection(terms, label, accel)
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
accel = accel and {form = accel} or nil,
}
end
local function make_absolute_superlative(special)
if is_adv then
return com.make_adverbial_absolute_superlative(stem, special)
else
return com.make_absolute_superlative(stem, special)
end
end
-- Maybe autogenerate default comparative/superlative.
local comp, sup
if args.comp and args.sup then-- comp= and sup= were given as options to the user
-- If no comp, but a non-default sup given, then add the default comparative/superlative.
-- This is useful when an absolute superlative is given.
comp = m_headword_utilities.parse_term_list_with_modifiers {
paramname = "comp",
forms = args.comp,
splitchar = ",",
}
sup = m_headword_utilities.parse_term_list_with_modifiers {
paramname = "sup",
forms = args.sup,
splitchar = ",",
}
local saw_sup_plus = false
if not comp[1] and sup[1] then
for _, supval in ipairs(sup) do
if supval.term == "+" then
saw_sup_plus = true
end
end
if not saw_sup_plus then
comp = {{term = "+"}}
insert(sup, 1, {term = "+"})
end
end
-- If comp=+, use default comparative 'mais ...', and set a default superlative if unspecified.
local saw_comp_plus = false
for _, compval in ipairs(comp) do
if compval.term == "+" then
saw_comp_plus = true
compval.term = "[[mais]] [[" .. lemma .. "]]"
end
end
if saw_comp_plus and not sup[1] then
sup = {{term = "+"}}
end
-- If sup=+ (possibly from comp=+), use default superlative 'o mais ...'. Also handle absolute superlatives.
for _, supval in ipairs(sup) do
if supval.term == "+" then
supval.term = "[[o]] [[mais]] [[" .. lemma .. "]]"
elseif supval.term == "+abs" then
supval.term = make_absolute_superlative()
elseif rfind(supval.term, "^%+abs:") then
local sp = rmatch(supval.term, "^%+abs:(.*)$")
supval.term = make_absolute_superlative(sp)
end
end
end
if args.hascomp then
if args.hascomp == "both" then
insert(data.inflections, {label = "บางครั้ง" .. glossary_link("เปรียบเทียบได้")})
insert(data.categories, plpos .. "เปรียบเทียบได้" .. langname)
insert(data.categories, plpos .. "เปรียบเทียบไม่ได้" .. langname)
else
local hascomp = require("Module:yesno")(args.hascomp)
if hascomp == true then
insert(data.inflections, {label = glossary_link("เปรียบเทียบได้")})
insert(data.categories, plpos .. "เปรียบเทียบได้" .. langname)
elseif hascomp == false then
insert(data.inflections, {label = glossary_link("เปรียบเทียบไม่ได้")})
insert(data.categories, plpos .. "เปรียบเทียบไม่ได้" .. langname)
else
error("Unrecognized value for hascomp=: " .. args.hascomp)
end
end
elseif comp and comp[1] or sup and sup[1] then
insert(data.inflections, {label = glossary_link("เปรียบเทียบได้")})
insert(data.categories, plpos .. "เปรียบเทียบได้" .. langname)
end
insert_inflection(comp, "ขั้นกว่า")
insert_inflection(sup, "ขั้นสุด")
end
local function do_adjective(args, data, is_superlative)
local feminines = {}
local masculine_plurals = {}
local feminine_plurals = {}
-- Use "participle" not "past participle" for categories such as 'invariable participles'
local category_plpos = data.checkredlinks
if category_plpos == true then
category_plpos = data.pos_category
end
local category_pos = --[[m_en_utilities.singularize(category_plpos)]] category_plpos
if args.sp then
local romut = require(romut_module)
if not romut.allowed_special_indicators[args.sp] then
local indicators = {}
for indic, _ in pairs(romut.allowed_special_indicators) do
insert(indicators, "'" .. indic .. "'")
end
table.sort(indicators)
error("Special inflection indicator beginning can only be " ..
mw.text.listToText(indicators) .. ": " .. args.sp)
end
end
local lemma = data.pagename
local function fetch_inflections(field)
local retval = m_headword_utilities.parse_term_list_with_modifiers {
paramname = field,
forms = args[field],
splitchar = ",",
}
if not retval[1] then
return {{term = "+"}}
end
return retval
end
local function insert_inflection(terms, label, accel)
m_headword_utilities.insert_inflection {
headdata = data,
terms = terms,
label = label,
accel = accel and {form = accel} or nil,
}
end
if args.short then
insert(data.inflections, {label = "[[Appendix:Portuguese verbs#Participles|short participle]]"})
end
if args.inv then
-- invariable adjective
insert(data.inflections, {label = glossary_link("ผันรูปไม่ได้")})
insert(data.categories, category_plpos .. "ผันรูปไม่ได้" .. langname)
if args.sp or args.f[1] or args.pl[1] or args.mpl[1] or args.fpl[1] then
error("Can't specify inflections with an invariable " .. category_pos)
end
elseif args.fonly then
-- feminine-only
if args.f[1] then
error("Can't specify explicit feminines with feminine-only " .. category_pos)
end
if args.pl[1] then
error("Can't specify explicit plurals with feminine-only " .. category_pos .. ", use fpl=")
end
if args.mpl[1] then
error("Can't specify explicit masculine plurals with feminine-only " .. category_pos)
end
local argsfpl = fetch_inflections("fpl")
for _, fpl in ipairs(argsfpl) do
if fpl.term == "+" then
fpl.term = make_plural(lemma, args.sp)
else
fpl.term = replace_hash_with_lemma(fpl.term, lemma)
end
insert(feminine_plurals, fpl)
end
insert(data.inflections, {label = "เพศหญิงเท่านั้น"})
insert_inflection(feminine_plurals, "เพศหญิงพหูพจน์", "f|p")
else
-- Gather feminines.
for _, f in ipairs(fetch_inflections("f")) do
if f.term == "+" then
-- Generate default feminine.
f.term = com.make_feminine(lemma, args.sp)
else
f.term = replace_hash_with_lemma(f.term, lemma)
end
insert(feminines, f)
end
local fem_like_lemma = #feminines == 1 and feminines[1].term == lemma and
not m_headword_utilities.termobj_has_decorations(feminines[1])
if fem_like_lemma then
insert(data.categories, category_plpos .. "epicene" .. langname)
end
local mpl_field = "mpl"
local fpl_field = "fpl"
if args.pl[1] then
if args.mpl[1] or args.fpl[1] then
error("Can't specify both pl= and mpl=/fpl=")
end
mpl_field = "pl"
fpl_field = "pl"
end
local argsmpl = fetch_inflections(mpl_field)
local argsfpl = fetch_inflections(fpl_field)
for _, mpl in ipairs(argsmpl) do
if mpl.term == "+" then
-- Generate default masculine plural.
mpl.term = make_plural(lemma, args.sp)
else
mpl.term = replace_hash_with_lemma(mpl.term, lemma)
end
insert(masculine_plurals, mpl)
end
for _, fpl in ipairs(argsfpl) do
if fpl.term == "+" then
for _, f in ipairs(feminines) do
-- Generate default feminine plural; f is a table.
local fplobj = m_table.shallowCopy(fpl)
fplobj.term = make_plural(f.term, args.sp)
m_headword_utilities.combine_termobj_decorations(fplobj, f)
insert(feminine_plurals, fplobj)
end
else
fpl.term = replace_hash_with_lemma(fpl.term, lemma)
insert(feminine_plurals, fpl)
end
end
local fem_pl_like_masc_pl = masculine_plurals[1] and feminine_plurals[1] and
m_table.deepEquals(masculine_plurals, feminine_plurals)
local masc_pl_like_lemma = #masculine_plurals == 1 and masculine_plurals[1].term == lemma and
not m_headword_utilities.termobj_has_decorations(masculine_plurals[1])
if fem_like_lemma and fem_pl_like_masc_pl and masc_pl_like_lemma then
-- actually invariable
insert(data.inflections, {label = glossary_link("ผันรูปไม่ได้")})
insert(data.categories, category_plpos .. "ผันรูปไม่ได้" .. langname)
else
-- Make sure there are feminines given and not same as lemma.
if not fem_like_lemma then
insert_inflection(feminines, "เพศหญิง", "f|s")
elseif args.gneut then
data.genders = {"gneut"}
else
data.genders = {"mf"}
end
if fem_pl_like_masc_pl then
if args.gneut then
insert_inflection(masculine_plurals, "พหูพจน์", "p")
else
-- This is how the Spanish module works.
-- insert_inflection(masculine_plurals, "masculine and feminine plural", "p")
insert_inflection(masculine_plurals, "พหูพจน์", "p")
end
else
insert_inflection(masculine_plurals, "เพศชายพหูพจน์", "m|p")
insert_inflection(feminine_plurals, "เพศหญิงพหูพจน์", "f|p")
end
end
end
local function parse_and_insert_adj_inflection(field, label, accel, frob)
parse_and_insert_inflection(data, args, field, label, accel, frob)
end
parse_and_insert_adj_inflection("n", "เพศกลาง")
handle_adj_adv_comp(args, data, category_plpos, false)
parse_and_insert_adj_inflection("dim", "ตัวบอกความเล็ก", nil, function(term)
if term == "+" then
term = com.make_diminutive(lemma)
elseif term:find("^%+") then
term = require(romut_module).get_special_indicator(term)
term = com.make_diminutive(lemma, term)
end
return term
end)
parse_and_insert_adj_inflection("aug", "ตัวบอกความใหญ่", nil, function(term)
if term == "+" then
term = com.make_augmentative(lemma)
elseif term:find("^%+") then
term = require(romut_module).get_special_indicator(term)
term = com.make_augmentative(lemma, term)
end
return term
end)
if is_metaphonic(args, lemma) then
insert(data.inflections, {label = metaphonic_label})
insert(data.categories, category_plpos .. langname .. "ที่มีเมทาโฟนี")
end
if args.irreg and is_superlative then
insert(data.categories, langname .. " irregular superlative " .. category_plpos)
end
end
local function get_adjective_params(adjtype)
local params = {
["inv"] = boolean_param, --invariable
["sp"] = true, -- special indicator: "first", "first-last", etc.
["f"] = list_param, --feminine form(s)
["pl"] = list_param, --plural override(s)
["mpl"] = list_param, --masculine plural override(s)
["fpl"] = list_param, --feminine plural override(s)
["meta"] = boolean_param, -- metaphonic
["nometa"] = boolean_param, -- explicitly not metaphonic
}
if adjtype == "base" then
params["comp"] = list_param --comparative(s)
params["sup"] = list_param --superlative(s)
params["dim"] = list_param --diminutive(s)
params["aug"] = list_param --augmentative(s)
params["fonly"] = boolean_param -- feminine only
params["gneut"] = boolean_param -- gender-neutral adjective e.g. [[latine]] (FIXME: do these exist in Portuguese?)
params["hascomp"] = true -- has comparative
end
if adjtype == "part" then
params["short"] = boolean_param -- short participle
end
if adjtype == "sup" then
params["irreg"] = boolean_param
end
if adjtype == "pron" or adjtype == "contr" then
params["n"] = list_param --neuter form(s)
end
return params
end
pos_functions["คำคุณศัพท์"] = {
params = get_adjective_params("base"),
func = do_adjective,
}
pos_functions["คำคุณศัพท์ขั้นกว่า"] = {
params = get_adjective_params("comp"),
func = do_adjective,
pos_category = "คำคุณศัพท์",
}
pos_functions["คำคุณศัพท์ขั้นสุด"] = {
params = get_adjective_params("sup"),
func = function(args, data)
do_adjective(args, data, "is superlative")
end,
pos_category = "คำคุณศัพท์",
}
pos_functions["รูปกริยาขยายอดีตกาล"] = {
params = get_adjective_params("part"),
func = do_adjective,
redlink_pos = "รูปกริยาขยาย",
}
pos_functions["ตัวกำหนด"] = {
params = get_adjective_params("det"),
func = do_adjective,
}
pos_functions["คำสรรพนามคล้ายคุณศัพท์"] = {
params = get_adjective_params("pron"),
func = do_adjective,
pos_category = "คำสรรพนาม",
}
pos_functions["รูปหดย่อคล้ายคุณศัพท์"] = {
params = get_adjective_params("contr"),
func = do_adjective,
pos_category = "รูปหดย่อ",
}
-----------------------------------------------------------------------------------------
-- Adverbs --
-----------------------------------------------------------------------------------------
local function do_adverb(args, data)
handle_adj_adv_comp(args, data, "คำกริยาวิเศษณ์", "is adv")
end
local function get_adverb_params(advtype)
local params = {}
if advtype == "base" then
params["comp"] = list_param --comparative(s)
params["sup"] = list_param --superlative(s)
params["hascomp"] = true -- has comparative
end
return params
end
pos_functions["คำกริยาวิเศษณ์"] = {
params = get_adverb_params("base"),
func = do_adverb,
}
pos_functions["คำกริยาวิเศษณ์ขั้นกว่า"] = {
params = get_adverb_params("comp"),
func = do_adverb,
pos_category = "คำกริยาวิเศษณ์",
}
pos_functions["คำกริยาวิเศษณ์ขั้นสุด"] = {
params = get_adverb_params("sup"),
func = do_adverb,
pos_category = "คำกริยาวิเศษณ์",
}
-----------------------------------------------------------------------------------------
-- Verbs --
-----------------------------------------------------------------------------------------
pos_functions["คำกริยา"] = {
params = {
[1] = true,
["pres"] = list_param, --present
["pres_qual"] = {list = "pres\1_qual", allow_holes = true},
["pres3s"] = list_param, --third-singular present
["pres3s_qual"] = {list = "pres3s\1_qual", allow_holes = true},
["pret"] = list_param, --preterite
["pret_qual"] = {list = "pret\1_qual", allow_holes = true},
["part"] = list_param, --participle
["part_qual"] = {list = "part\1_qual", allow_holes = true},
["short_part"] = list_param, --short participle
["short_part_qual"] = {list = "short_part\1_qual", allow_holes = true},
["noautolinktext"] = boolean_param,
["noautolinkverb"] = boolean_param,
["attn"] = boolean_param,
},
func = function(args, data, frame)
local preses, preses_3s, prets, parts, short_parts
if args.attn then
insert(data.categories, "Requests for attention concerning " .. langname)
return
end
local pt_verb = require(pt_verb_module)
local alternant_multiword_spec = pt_verb.do_generate_forms(args, "pt-verb", data.heads[1])
local specforms = alternant_multiword_spec.forms
local function slot_exists(slot)
return specforms[slot] and #specforms[slot] > 0
end
local function do_finite(slot_tense, label_tense)
-- Use pres_3s if it exists and pres_1s doesn't exist (e.g. impersonal verbs); similarly for pres_3p
-- (only3p verbs); but fall back to pres_1s if neither pres_1s nor pres_3s nor pres_3p exist (e.g.
-- [[empedernir]]).
local has_1s = slot_exists(slot_tense .. "_1s")
local has_3s = slot_exists(slot_tense .. "_3s")
local has_3p = slot_exists(slot_tense .. "_3p")
if has_1s or (not has_3s and not has_3p) then
return {
slot = slot_tense .. "_1s",
label = ("บุรุษที่หนึ่งเอกพจน์%s"):format(label_tense),
}, true
elseif has_3s then
return {
slot = slot_tense .. "_3s",
label = ("บุรุษที่สามเอกพจน์%s"):format(label_tense),
}, false
else
return {
slot = slot_tense .. "_3p",
label = ("บุรุษที่สามพหูพจน์%s"):format(label_tense),
}, false
end
end
local did_pres_1s
preses, did_pres_1s = do_finite("pres", "ปัจจุบันกาล")
preses_3s = {
slot = "pres_3s",
label = "บุรุษที่สามเอกพจน์ปัจจุบันกาล",
}
prets = do_finite("pret", "อดีตกาลสิ้นสุด")
parts = {
slot = "pp_ms",
label = "รูปกริยาขยายอดีตกาล",
}
short_parts = {
slot = "short_pp_ms",
label = "รูปกริยาขยายอดีตกาลสั้น",
}
if args.pres[1] or args.pres3s[1] or args.pret[1] or args.part[1] or args.short_part[1] then
track("verb-old-multiarg")
end
local function strip_brackets(qualifiers)
if not qualifiers then
return nil
end
local stripped_qualifiers = {}
for _, qualifier in ipairs(qualifiers) do
local stripped_qualifier = qualifier:match("^%[(.*)%]$")
if not stripped_qualifier then
error("Internal error: Qualifier should be surrounded by brackets at this stage: " .. qualifier)
end
insert(stripped_qualifiers, stripped_qualifier)
end
return stripped_qualifiers
end
local function do_verb_form(args, qualifiers, slot_desc, skip_if_empty)
local forms
local to_insert
if #args == 0 then
forms = specforms[slot_desc.slot]
if not forms or #forms == 0 then
if skip_if_empty then
return
end
forms = {{form = "-"}}
end
elseif #args == 1 and args[1] == "-" then
forms = {{form = "-"}}
else
forms = {}
for i, arg in ipairs(args) do
local qual = qualifiers[i]
if qual then
-- FIXME: It's annoying we have to add brackets and strip them out later. The inflection
-- code adds all footnotes with brackets around them; we should change this.
qual = {"[" .. qual .. "]"}
end
local form = arg
if not args.noautolinkverb then
-- [[Module:inflection utilities]] already loaded by [[Module:pt-verb]]
form = require(inflection_utilities_module).add_links(form)
end
insert(forms, {form = form, footnotes = qual})
end
end
if forms[1].form == "-" then
to_insert = {label = "no " .. slot_desc.label}
else
local into_table = {label = slot_desc.label}
for _, form in ipairs(forms) do
local qualifiers = strip_brackets(form.footnotes)
-- Strip redundant brackets surrounding entire form. These may get generated e.g.
-- if we use the angle bracket notation with a single word.
local stripped_form = rmatch(form.form, "^%[%[([^%[%]]*)%]%]$") or form.form
stripped_form = pt_verb.remove_variant_codes(stripped_form)
-- Don't include accelerators if brackets remain in form, as the result will be wrong.
-- FIXME: For now, don't include accelerators. We should use the new {{pt-verb form of}} once
-- implemented.
-- local this_accel = not stripped_form:find("%[%[") and accel or nil
local this_accel = nil
insert(into_table, {term = stripped_form, q = qualifiers, accel = this_accel})
end
to_insert = into_table
end
insert(data.inflections, to_insert)
end
local skip_pres_if_empty
if alternant_multiword_spec.no_pres1_and_sub then
insert(data.inflections, {label = "no first-person singular present"})
insert(data.inflections, {label = "no present subjunctive"})
end
if alternant_multiword_spec.no_pres_stressed then
insert(data.inflections, {label = "no stressed present indicative or subjunctive"})
skip_pres_if_empty = true
end
if alternant_multiword_spec.only3s then
insert(data.inflections, {label = glossary_link("impersonal")})
elseif alternant_multiword_spec.only3sp then
insert(data.inflections, {label = "บุรุษที่สามเท่านั้น"})
elseif alternant_multiword_spec.only3p then
insert(data.inflections, {label = "บุรุษที่สามพหูพจน์เท่านั้น"})
end
local has_vowel_alt
if alternant_multiword_spec.vowel_alt then
for _, vowel_alt in ipairs(alternant_multiword_spec.vowel_alt) do
if vowel_alt ~= "+" and vowel_alt ~= "í" and vowel_alt ~= "ú" then
has_vowel_alt = true
break
end
end
end
do_verb_form(args.pres, args.pres_qual, preses, skip_pres_if_empty)
-- We want to include both the pres_1s and pres_3s if there is a vowel alternation in the present singular. But
-- we don't want to redundantly include the pres_3s if we already included it.
if did_pres_1s and has_vowel_alt then
do_verb_form(args.pres3s, args.pres3s_qual, preses_3s, skip_pres_if_empty)
end
do_verb_form(args.pret, args.pret_qual, prets)
do_verb_form(args.part, args.part_qual, parts)
do_verb_form(args.short_part, args.short_part_qual, short_parts, "skip if empty")
-- Add categories.
for _, cat in ipairs(alternant_multiword_spec.categories) do
insert(data.categories, cat)
end
-- If the user didn't explicitly specify head=, or specified exactly one head (not 2+) and we were able to
-- incorporate any links in that head into the 1= specification, use the infinitive generated by
-- [[Module:pt-verb]] in place of the user-specified or auto-generated head. This was copied from
-- [[Module:it-headword]], where doing this gets accents marked on the verb(s). We don't have accents marked on
-- the verb but by doing this we do get any footnotes on the infinitive propagated here. Don't do this if the
-- user gave multiple heads or gave a head with a multiword-linked verbal expression such as Italian
-- '[[dare esca]] [[al]] [[fuoco]]' (FIXME: give Portuguese equivalent).
if #data.user_specified_heads == 0 or (
#data.user_specified_heads == 1 and alternant_multiword_spec.incorporated_headword_head_into_lemma
) then
data.heads = {}
for _, lemma_obj in ipairs(alternant_multiword_spec.forms.infinitive_linked) do
local quals, refs = require(inflection_utilities_module).
convert_footnotes_to_qualifiers_and_references(lemma_obj.footnotes)
insert(data.heads, {term = lemma_obj.form, q = quals, refs = refs})
end
end
end
}
-----------------------------------------------------------------------------------------
-- Suffix forms --
-----------------------------------------------------------------------------------------
pos_functions["รูปปัจจัย"] = {
params = {
[1] = {required = true, list = true, disallow_holes = true},
["g"] = {list = true, disallow_holes = true, type = "genders", flatten = true},
},
func = function(args, data)
validate_genders(args.g)
data.genders = args.g
local suffix_type = {}
for _, typ in ipairs(args[1]) do
insert(suffix_type, "ปัจจัยสร้าง" .. typ)
end
insert(data.inflections, {label = "รูปผันของ " .. m_table.serialCommaJoin(suffix_type, {conj = "หรือ"})})
end,
}
return export
169s07yj3rua526783j1x7r78g26edu
มอดูล:language-like
828
272817
5775360
5713303
2026-10-15T07:07:49Z
Octahedron80
267
5775360
Scribunto
text/plain
local export = {}
local families_module = "Module:families"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
-- In a locally installed Docker container containing Wiktionary, Wikibase is typically not installed because it's
-- a real pain to get working properly. In such a case, `mw.wikibase` returns nil. We now have checks in the code
-- below so it does reasonable things in the absence of Wikibase.
local wikibase = mw.wikibase
local category_name_has_suffix -- defined as export.categoryNameHasSuffix below
local get_entity = wikibase and wikibase.getEntity or nil
local get_entity_id_for_title = wikibase and wikibase.getEntityIdForTitle or nil
local gsub = string.gsub
local ipairs = ipairs
local match = string.match
local select = select
local sitelink = wikibase and wikibase.sitelink or nil
local type = type
local umatch = mw.ustring.match
--[==[
Loaders for functions in other modules, which overwrite themselves with the target function when called. This ensures modules are only loaded when needed, retains the speed/convenience of locally-declared pre-loaded functions, and has no overhead after the first call, since the target functions are called directly in any subsequent calls.]==]
local function case_insensitive_pattern(...)
case_insensitive_pattern = require(string_utilities_module).case_insensitive_pattern
return case_insensitive_pattern(...)
end
local function table_flatten(...)
table_flatten = require(table_module).flatten
return table_flatten(...)
end
--[==[
Loaders for objects, which load data (or some other object) into some variable, which can then be accessed as "foo or get_foo()", where the function get_foo sets the object to "foo" and then returns it. This ensures they are only loaded when needed, and avoids the need to check for the existence of the object each time, since once "foo" has been set, "get_foo" will not be called again.]==]
local content_lang
local function get_content_lang()
content_lang, get_content_lang = mw.getContentLanguage(), nil
return content_lang
end
-- Implementation of getAliases() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getAliases(self)
local aliases = self._aliases
if aliases == nil then
aliases = (self._data or self).aliases or {}
self._aliases = aliases
end
return aliases
end
-- Implementation of getVarieties() for languages, etymology languages,
-- families, scripts and writing systems. If `flatten` is passed in,
-- flatten down to a list of strings; otherwise, keep the structure.
function export.getVarieties(self, flatten)
local varieties = self._varieties
if varieties == nil then
varieties = (self._data or self).varieties or {}
self._varieties = varieties
end
if not flatten then
return varieties
end
local flattened_varieties = self._flattened_varieties
if flattened_varieties == nil then
flattened_varieties = table_flatten(varieties)
self._flattened_varieties = flattened_varieties
end
return flattened_varieties
end
-- Implementation of getOtherNames() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getOtherNames(self)
local other_names = self._other_names
if other_names == nil then
other_names = (self._data or self).other_names or {}
self._other_names = other_names
end
return other_names
end
-- Implementation of getAllNames() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getAllNames(self)
local all_names = self._allNames
if all_names == nil then
all_names = table_flatten{
self.getCanonicalNames and self:getCanonicalNames() or self:getCanonicalName(),
self:getAliases(),
self:getVarieties(),
self:getOtherNames(),
}
self._allNames = all_names
end
return all_names
end
function export.hasType(self, ...)
local n = select("#", ...)
if n == 0 then
error("Must specify at least one type.")
end
local types = self:getTypes()
if not types[...] then
return false
elseif n == 1 then
return true
end
local args = {...}
for i = 2, n do
if not types[args[i]] then
return false
end
end
return true
end
-- Implementation of template-callable getByCode() function for languages,
-- etymology languages, families and scripts. `item` is the language,
-- family or script in question; `args` is the arguments passed in by the
-- module invocation; `extra_processing`, if specified, is a function of
-- one argument (the requested property) and should return the value to
-- be returned to the caller, or nil if the property isn't recognized.
-- `extra_processing` is called after special-cased properties are handled
-- and before general-purpose processing code that works for all string
-- properties.
function export.templateGetByCode(args, extra_processing)
-- The item that the caller wanted to look up.
local item, itemname, list = args[1], args[2]
if itemname == "getAllNames" then
list = item:getAllNames()
elseif itemname == "getOtherNames" then
list = item:getOtherNames()
elseif itemname == "getAliases" then
list = item:getAliases()
elseif itemname == "getVarieties" then
list = item:getVarieties(true)
end
if list then
local index = args[3]; if index == "" then index = nil end
index = tonumber(index or error("Numeric index of the desired item in the list (parameter 3) has not been specified."))
return list[index] or ""
end
if itemname == "getFamily" and item.getFamily then
return item:getFamily():getCode()
end
if extra_processing then
local retval = extra_processing(itemname)
if retval then
return retval
end
end
if item[itemname] then
local ret = item[itemname](item)
if type(ret) == "string" then
return ret
end
error("The function \"" .. itemname .. "\" did not return a string value.")
end
error("Requested invalid item name \"" .. itemname .. "\".")
end
-- Implementation of getCommonsCategory() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getWikidataItem(self)
local item = self._WikidataItem
if item == nil then
item = (self._data or self)[2]
-- If the value is nil, it's cached as false.
item = item ~= nil and (type(item) == "number" and "Q" .. item or item) or false
self._WikidataItem = item
end
return item or nil
end
do
local function get_wiki_article(self, project)
local article
-- If the project is thwiki, check the language data.
if project == "thwiki" then
article = (self._data or self).wikipedia_article
if article then
return article
end
end
-- Otherwise, check the Wikidata item for a sitelink.
local item = self:getWikidataItem()
article = item and sitelink and sitelink(item, project) or false
if article then
return article
end
-- If there's still no article, try the parent (if any).
local get_parent = self.getParent
if get_parent then
local parent = get_parent(self)
if parent then
return get_wiki_article(parent, project)
end
end
return false
end
-- Implementation of getWikipediaArticle() for languages, etymology languages,
-- families, scripts and writing systems.
function export.getWikipediaArticle(self, noCategoryFallback, project)
if project == nil then
project = "thwiki"
end
local article
if project == "thwiki" then
article = self._wikipedia_article
if article == nil then
article = get_wiki_article(self, project)
self._wikipedia_article = article
end
else
-- If the project isn't thwiki, default to no category fallback, but
-- this can be overridden by specifying the value `false`.
if noCategoryFallback == nil then
noCategoryFallback = true
end
local non_en_wikipedia_articles = self._non_en_wikipedia_articles
if non_en_wikipedia_articles == nil then
non_en_wikipedia_articles = {}
self._non_en_wikipedia_articles = non_en_wikipedia_articles
else
article = non_en_wikipedia_articles[project]
end
if article == nil then
article = get_wiki_article(self, project)
non_en_wikipedia_articles[project] = article
end
end
if article or noCategoryFallback then
return article or nil
end
return (gsub(self:getCategoryName(), "ภาษาครีโอล", "ครีโอล"))
end
end
do
local function get_commons_cat_claim(item)
if item then
local entity = get_entity and get_entity(item) or nil
if entity then
-- P373 is the "Commons category" property.
local claim = entity:getBestStatements("P373")[1]
return claim and ("Category:" .. claim.mainsnak.datavalue.value) or nil -- don't translate
end
end
end
local function get_commons_cat_sitelink(item)
if item then
local commons_sitelink = sitelink and sitelink(item, "commonswiki") or nil
-- Reject any sitelinks that aren't categories.
return commons_sitelink and match(commons_sitelink, "^Category:") and commons_sitelink or nil -- don't translate
end
end
local function get_commons_cat(self)
-- Checks are in decreasing order of likelihood for a useful match.
-- Get the Commons Category claim from the object's item.
local lang_item = self:getWikidataItem()
local category = get_commons_cat_claim(lang_item)
if category then
return category
end
-- Otherwise, try the object's category's item.
local langcat_item = get_entity_id_for_title and get_entity_id_for_title("Category:" .. self:getCategoryName()) or nil -- don't translate
category = get_commons_cat_claim(langcat_item)
if category then
return category
end
-- If there's no P373 claim, there might be a sitelink on the
-- object's category's item.
category = get_commons_cat_sitelink(langcat_item)
if category then
return category
end
-- Otherwise, try for a sitelink on the object's own item.
category = get_commons_cat_sitelink(lang_item)
if category then
return category
end
-- If there's still no category, try the parent (if any).
local get_parent = self.getParent
if get_parent then
local parent = get_parent(self)
if parent then
return get_commons_cat(parent)
end
end
return false
end
-- Implementation of getCommonsCategory() for languages, etymology
-- languages, families, scripts and writing systems.
function export.getCommonsCategory(self)
local category
category = self._commons_category
-- Nil values cached as false.
if category ~= nil then
return category or nil
end
category = get_commons_cat(self)
self._commons_category = category
return category or nil
end
end
function export.categoryNameHasSuffix(name, suffixes)
for _, suffix in ipairs(suffixes) do
--if umatch(name, "%f[%w]" .. case_insensitive_pattern(suffix, "^.") .. "$") then -- th doesn't use this, but don't change param
if umatch(name, "^" .. case_insensitive_pattern(suffix, "^.")) then
return false
end
end
return true
end
category_name_has_suffix = export.categoryNameHasSuffix
function export.categoryNameToCode(name, suffix, data, suffixes)
--local truncated = match(name, "(.*)" .. suffix .. "$") -- th doesn't use this, but don't change param
local truncated = match(name, "^" .. suffix .. "(.*)")
if truncated and category_name_has_suffix(truncated, suffixes) then
local code = data[truncated]
if code ~= nil then
return code, truncated
end
truncated = (content_lang or get_content_lang()):lcfirst(truncated)
code = data[truncated]
if code ~= nil then
return code, truncated
end
end
if not category_name_has_suffix(name, suffixes) then
local code = data[name]
if code ~= nil then
return code, name
end
name = (content_lang or get_content_lang()):lcfirst(name)
code = data[name]
if code ~= nil then
return code, name
end
end
return nil, nil
end
-- If a language has no specified pseudo-family but its or its family's code begins with one or these prefixes,
-- assign it to the specified pseudo-family. Note that we don't do this across-the-board because there are (currently)
-- some families whose code begins with `nai-` but are considered in the `cai` pseudo-family.
local pseudo_family_prefixes = {
cai = true,
nai = true,
paa = true,
sai = true,
sgn = true,
}
-- Implementation of getPseudoFamilies() for languages, etymology languages
-- and families.
function export.getPseudoFamilies(self)
local pseudo_families = self._pseudo_families
local function insert_pseudo_family(code)
local fam = require(families_module).getByCode(code)
if not fam then
mw.log(("WARNING: Unrecognized pseudo-family code '%s'"):format(code))
else
table.insert(pseudo_families, fam)
end
end
if pseudo_families == nil then
pseudo_families = {}
local pseudo_family_string = (self._data or self).pseudo_families
if pseudo_family_string then
local pseudo_family_codes = require(string_utilities_module).split(pseudo_family_string, "%s*,%s*")
for _, code in ipairs(pseudo_family_codes) do
insert_pseudo_family(code)
end
end
if not pseudo_families[1] then
-- Check the parent. If it's a full language, we will have to fetch the extra data to get the
-- list of pseudo-families.
local get_parent = self.getParent
if get_parent then
local parent = get_parent(self)
if parent then
local parent_code = parent:getCode()
if pseudo_family_prefixes[parent_code] then
insert_pseudo_family(parent_code)
else
pseudo_families = parent:getPseudoFamilies()
end
end
end
end
if not pseudo_families[1] then
-- Check the family to see if it's in any pseudo-families.
local get_family = self.getFamily
if get_family then
local family = get_family(self)
if family then
local family_code = family:getCode()
if pseudo_family_prefixes[family_code] then
insert_pseudo_family(family_code)
elseif family_code ~= self:getCode() then -- qfa-not has itself as a family.
pseudo_families = family:getPseudoFamilies()
end
end
end
end
if not pseudo_families[1] then
local prefix = self:getCode():match("^([a-z][a-z][a-z])%-")
if prefix and pseudo_family_prefixes[prefix] then
insert_pseudo_family(prefix)
end
end
self._pseudo_families = pseudo_families
end
return pseudo_families
end
return export
tkkxpmbiihlrfymkggpiu4of00qesv8
แม่แบบ:female equivalent of
10
273452
5775327
5677142
2026-10-15T03:35:53Z
Octahedron80
267
5775327
wikitext
text/x-wiki
{{check deprecated lang param usage|lang={{{lang|}}}|<!--
-->{{#invoke:form of/templates|tagged_form_of_t|คำเทียบเท่าเพศหญิง}}<!--
-->}}<!--
--><noinclude>{{documentation}}</noinclude>
aho1xllxiwe4o445z8af98e1kzk9en8
มอดูล:headword utilities
828
304646
5775326
5689122
2026-10-15T03:34:39Z
Octahedron80
267
5775326
Scribunto
text/plain
local export = {}
--[==[
FIXME:
1. Implement ? = unknown or uncertain. There should be no label by default but it should be configurable.
The default category should be "{plpos} with unknown or uncertain plurals" for nouns/proper nouns. It should
be an error to specify values along with this. [DONE]
2. Implement ! = unattested. The default label should be "{label} not attested". The default category should be
"{plpos} with unattested plurals" for nouns/proper nouns. It should be an error to specify values along with
this. [DONE]
3. Implement +- = sometimes has a value, e.g. "countable and uncountable" for plurals. [DONE]
4. Implement ~ standing for the pagename in heads and inflections. [DONE]
5. Implement abbr= for abbreviations. [DONE]
6. Split insert_inflection into process_for_insertion() (which implements the logic for handling special mode signals)
and insert_processed_inflection() (which implements the labels and categories for mode signals) so that we can handle
mode signals correctly. [DONE]
7. Support no_label for booleans.
8. Document the various types of parts of speech and implement pos_category per part of speech definition. [DONE]
9. Implement apply_link_modifiers() for head=~~...
10. Correctly handle var=both. [DONE]
11. Implement checkredlinks and port simplify_pos to [[Module:headword]]. [CHECKREDLINKS SET; SIMPLIFY_POS NOT PORTED YET.]
12. Fix longstanding accelerator bug: if embedded links in inflection, don't make it green. [DONE]
13. Implement process_terms() callback after process_for_insertion. [DONE]
14. Implement validate_and_canonicalize() callback. [NOT DONE; INSTEAD HAVE A SEPARATE CANONICALIZE CALLBACK]
15. Document new methods.
16. Implement process_one_term() callback after process_for_insertion. [DONE]
17. Implement process() at a stage to happen universally when there is no argument to parse. [DONE]
18. Skip mode signals during validation and canonicalization. [DONE]
19. Implement inflsuf= with special handling and special inflectional categories. [DONE]
20. Add support for "boolean or string" type.
21. Support invocation-specified or user-specified languages. [DONE]
]==]
local require_when_needed = require("Module:utilities/require when needed")
local affix_module = "Module:affix"
local debug_track_module = "Module:debug/track"
local decorations_module = "Module:decorations"
local en_utilities_module = "Module:en-utilities"
local fun_is_callable_module = "Module:fun/isCallable"
local headword_module = "Module:headword"
local headword_data_module = "Module:headword/data"
local languages_module = "Module:languages"
local links_module = "Module:links"
local parameters_module = "Module:parameters"
local parse_interface_module = "Module:parse interface"
local parse_utilities_module = "Module:parse utilities"
local string_pattern_escape_module = "Module:string/patternEscape"
local string_replacement_escape_module = "Module:string/replacementEscape"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local dump = mw.dumpObject
local unpack = unpack or table.unpack -- Lua 5.2 compatibility
local insert = table.insert
local concat = table.concat
local remove = table.remove
local sort = table.sort
local contains = require_when_needed(table_module, "contains")
local deep_equals = require_when_needed(table_module, "deepEquals")
local extend = require_when_needed(table_module, "extend")
local insert_if_not = require_when_needed(table_module, "insertIfNot")
local is_array = require_when_needed(table_module, "isArray")
local list_to_set = require_when_needed(table_module, "listToSet")
local serial_comma_join = require_when_needed(table_module, "serialCommaJoin")
local shallow_copy = require_when_needed(table_module, "shallowCopy")
local split = require_when_needed(string_utilities_module, "split")
local ugsub = require_when_needed(string_utilities_module, "gsub")
local umatch = require_when_needed(string_utilities_module, "match")
local pattern_escape = require_when_needed(string_pattern_escape_module)
local replacement_escape = require_when_needed(string_replacement_escape_module)
local escape_wikicode = require_when_needed(parse_utilities_module, "escape_wikicode")
local parse_inline_modifiers = require_when_needed(parse_utilities_module, "parse_inline_modifiers")
local term_contains_top_level_html = require_when_needed(parse_utilities_module, "term_contains_top_level_html")
local get_lang_by_code = require_when_needed(languages_module, "getByCode")
local is_callable = require_when_needed(fun_is_callable_module)
local format_decorations = require_when_needed(decorations_module, "format_decorations")
local singularize = require_when_needed(en_utilities_module, "singularize")
local canonicalize_pos = require_when_needed(headword_module, "canonicalize_pos")
local pluralize_pos = require_when_needed(headword_module, "pluralize_pos")
--[==[ intro:
This module contains utilities for constructing language-specific headword modules.
[fill in]
===About parts of speech===
There are several versions of the part of speech (POS) of a given term:
* The ''primary categorizing POS'' is the basic part of speech to which a term belongs. The primary POS determines
whether the term is a lemma or non-lemma form, and in its plural form, it is used to categorize the terms (unless it
is a variant term), along with caetegorizing into a ''lemmas'' or ''non-lemma forms'' category. (Variant terms,
typically marked by {{para|var|1}}, are categorized into ''variant lemmas'' or ''variant non-lemma forms'' and are not
categorized into a primary POS category.)
* The ''raw {{tl|head}} POS'' is parameter {{para|2}} to {{tl|head}}. This is used to determine the primary categorizing
POS by a process of canonicalization, because this parameter may contain abbreviations (e.g. ''a'' or ''adj'' for an
adjective) and may be (and usually is) given in its singular form.
* The ''template-indicated POS'' is the part of speech indicated by a headword template such as {{tl|nl-noun}} or
{{tl|mn-head}}. It is either inherent to the template (in a case like {{tl|nl-noun}}), in which case it is specified
by the template code and should always be in canonical, plural form; or it is specified by the user in the template
call (in a case like {{tl|mn-head}} or other generic POS template, usually ending in `-head`), in which case it may
be given in raw form, like for the raw {{tl|head}} POS, and is canonicalized using the same code that canonicalizes
raw {{tl|head}} parts of speech. The template-indicate POS may not be a valid primary categorizing POS. For example,
Dutch has a template-indicated POS ''diminutiva tantum nouns'', specified through the template {{tl|nl-dim-tant}}, but
there is no such primary categorizing POS (that POS would be `nouns`). Similarly, Arabic has a template-indicated POS
''collective nouns'', whose primary categorizing POS is also `nouns`. As a result, the template-indicated POS may need
to be converted to a primary categorizing POS through a ''normalization'' process (which uses a `pos_category` field
attached to the `pos_functions` structure for the template-indicated POS). Note that the template-indicated POS comes
in several variants:
*# It may be ''head-raw'', meaning that it uses the literal string `head` in place of the user-specified POS in a
generic POS template like {{tl|mn-head}}; it may be ''non-head'', meaning that it uses the actual user-specified
POS in such a case; or it may be ''head-augmented'', meaning that in the case of a generic POS template it is of the
form e.g. `head.nouns`, contanining both the literal `head` and the user-specified POS.
*# It may be ''suffix-raw'', meaning that it uses the primary categorizing POS `suffixes` in place of the
template-indicated POS when the term is a suffix, or it may be ''non-suffix'', meaning that it uses the
template-indicated POS in such a case. The headword for a suffix uses the template corresponding to whatever POS the
suffix forms, e.g. {{nl-noun}} for Dutch noun-forming suffixes.
*# The ''indexing POS'' is the variant of the template-indicated POS that is used to index into the `pos_functions`
table. Normally it is head-raw and non-suffix, but it will be head-augmented if the corresponding head-augmented
entry exists in `pos_functions`.
*# The ''unnormalized categorizing POS'' is the variant of the template-indicated POS that is potentially usable as the
primary categorizing POS (see above). It is non-head and suffix-raw, i.e. it uses the actual template-specified or
user-specified form of the template-indicated POS except when the term is a suffix, in which case it has the value
`suffixes`. In most circumstances this can be used directly as the primary categorizing POS, but in some cases this
POS is not a valid primary categorizing POS and needs to be normalized to get the actual primary categorizing POS, as
mentioned above under the description for the template-indicated POS.
* Finally, there is a ''simplified categorizing POS''. This collapses variations of primary categorizing parts of speech
together for use in red-link and similar categories. For example, the POS `proper nouns` is collapsed into `nouns`,
and all types of participles are collapsed into `participles`. There are two variants of the simplification process,
''lemma-status-preserving'' and ''non-lemma-status-preserving''. The latter is the default and is simpler, in that
e.g. it means any part of speech ending in `nouns` to `nouns`, even if this causes non-lemma forms to become lemmas,
as with `diminutive nouns` and `verbal nouns` (which are non-lemma forms) and likewise with `comparative adjectives`
and `superlative adjectives` (which are again non-lemma forms). The former, ''lemma-status-preserving'', keeps lemmas
as lemmas and (more important) non-lemmas as non-lemmas by converting e.g. `diminutive nouns` and `verbal nouns` to
`noun forms` rather than `nouns`. The reason two variants exist in that they have different use cases. The default,
non-lemma-status-preserving, type is used for tracking categories such as red-link and request categories, where
completeness is more important than clutter. The lemma-status-preserving variant is used for informative categories
such as ` ``lang`` masculine nouns`, which should only have lemmas in them to avoid clutter. (For the same reason,
variant terms specified using {{para|var|1}} aren't normally categorized into informative categories but are placed
in tracking categories.)
===About properties and data objects===
[fill in]
]==]
local inflection_to_cats_and_label = {
plural = {
filter_pos = function(posvars)
-- plurals also occur with determiners, adjectives etc. and we don't want to generate categories like
-- 'countable determiners', 'countable adjectives', etc. Note that the passed-in `simp_plpos` has
-- `proper nouns` converted to `nouns`.
return posvars.simp_plpos == "คำนาม"
end,
cats = {"คำนามนับได้"},
no_cats = {"คำนามนับไม่ได้"},
fixed_adj_label = "<<นับได้>>",
fixed_adj_no_label = "<<นับไม่ได้>>",
sometimes_label = "<<นับได้>>และ<<นับไม่ได้>>",
unattested_cats = "คำนามที่พหูพจน์ไม่ปรากฏหลักฐาน",
unknown_cats = "คำนามที่พหูพจน์ไม่ทราบหรือไม่แน่ชัด",
},
comparative = {
cats = {"{simp_plpos}เปรียบเทียบได้"},
no_cats = {"{simp_plpos}เปรียบเทียบไม่ได้"},
fixed_adj_label = "<<เปรียบเทียบได้>>",
},
["female equivalent"] = {
cats = {"{simp_plpos}ที่มีคำเทียบเท่าเพศอื่น"},
},
["male equivalent"] = {
cats = {"{simp_plpos}ที่มีคำเทียบเท่าเพศอื่น"},
},
}
local param_mods = {
alt = {}, -- always allow so e.g. - can be specified as a suffix form
id = {}, -- disabled when `is_head = true`
q = {type = "qualifier"},
qq = {type = "qualifier"},
l = {type = "labels"},
ll = {type = "labels"},
-- [[Module:headword]] expects part references in `.refs`.
ref = {item_dest = "refs", type = "references", store = "insert-flattened"},
}
local optional_param_mods = {
g = {item_dest = "genders", type = "genders"},
lang = {type = "language"},
sc = {type = "script"},
t = {item_dest = "gloss"},
gloss = {},
pos = {},
ng = {},
lit = {},
tr = {},
ts = {},
face = {},
nolinkinfl = {type = "boolean"},
}
local optional_headword_param_mods = {
sc = {type = "script"},
tr = {},
ts = {},
}
local function split_on_comma(val)
if val:find(",") then
return require(parse_interface_module).split_on_comma(val)
else
return {val}
end
end
local function ine(val)
if not val then
return nil
end
val = mw.text.trim(val)
return val ~= "" and val or nil
end
--[=[
Add decorations to a term. `termobj` is the object describing the term, which should optionally contain:
* left qualifiers in `q`, an array of strings;
* right qualifiers in `qq`, an array of strings;
* left labels in `l`, an array of strings;
* right labels in `ll`, an array of strings;
* references in `refs`, an array either of strings (formatted reference text) or objects containing fields `text`
(formatted reference text) and optionally `name` and/or `group`;
`text` is the text of the term itself, and `lang` is the language object.
]=]
local function add_decorations(text, termobj, lang)
local function field_non_empty(field)
local list = termobj[field]
if not list then
return nil
end
if type(list) ~= "table" then
error(("Internal error: Wrong type for `termobj.%s`=%s, should be \"table\""):format(
field, mw.dumpObject(list)))
end
return list[1]
end
if field_non_empty("q") or field_non_empty("qq") or field_non_empty("l") or field_non_empty("ll") or
field_non_empty("refs") then
text = format_decorations {
lang = lang,
text = text,
q = termobj.q,
qq = termobj.qq,
l = termobj.l,
ll = termobj.ll,
refs = termobj.refs,
}
end
return text
end
--[==[
Parse a single inflection or headword form or list of such forms. In either case, inline modifiers may be attached.
`data` is an object with the following fields:
* `val`: The raw value to parse. Required.
* `paramname`: The name of the parameter from which the value was taken; used in error messages. Required.
* `is_head`: We are parsing a headword parameter (a value which goes into the `heads` field of `data`). This changes
the allowed modifiers, disabling the `id` modifier and only allowing a subset of optional modifiers.
* `frob`: An optional function of one value to apply to the form after inline modifiers have been removed (i.e. to
apply to the `.term` field of the returned object).
* `include_mods`: List of extra inline modifiers to include, besides the default ones (see below). Each list item is
either a string specifying a recognized extra inline modifier (see `optional_param_mods` in the code), or a two-item
list of modifier name and modifier spec, where the spec should follow the syntax for modifier specs in
`parse_inline_modifiers` in [[Module:parse utilities]].
* `exclude_mods`: List of default inline modifiers to not include.
* `splitchar`: If specified, the value in `val` can be a list of forms to parse, separated by the value of `splitchar`
(which is a Lua pattern, as in `parse_inline_modifiers` in [[Module:parse utilities]]). Most commonly, `splitchar` is
a single comma and the values are comma-separated (in this case, splitting will not happen if a space follows the
comma).
* `parse_lang_prefix`: If specified, allow a language prefix to precede a form, and if found, store into the `.lang`
field of the returned object.
* `disable_special_modes`: If specified, don't recognize and treat specially the special mode signals (e.g. '-' for
no inflection, '?' for unknown, etc.).
* `preserve_splitchar`, `delimiter_key`, `escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in
`parse_inline_modifiers` in [[Module:parse utilities]].
Returns an object suitable for storing as one element of one of the lists in `headdata.inflections`, where `headdata`
is the structure passed to [[Module:headword]]. If `splitchar` is specified, howeve, the return value is a list of such
objects.
The following default inline modifiers are currently recognized:
* `q`: Left qualifier.
* `qq`: Right qualifier.
* `l`: Comma-separated list of left labels. No space should follow the comma.
* `ll`: Comma-separated list of right labels. No space should follow the comma.
* `ref`: Reference or references. See {{tl|IPA}} for the syntax.
* `id`: Sense ID, in case there are multiple senses. See {{tl|l}}.
The following are the recognized additional inline modifiers:
* `g`: Comma-separated list of genders.
* `alt`: Display text.
* `lang`: Language code of language of the form, if different from the language of the headword.
* `sc`: Script code of script of the form. Almost never needed.
* `t`: Gloss for the form.
* `gloss`: Gloss for the form (alias for `t`).
* `pos`: Part of speech of the form.
* `lit`: Literal meaning of the form.
* `tr`: Manual transliteration of the form.
* `ts`: Transcription of the form, for languages where the transliteration differs markedly from the pronunciation.
* `face`: Face to display the form in, e.g. {"hypothetical"} for a hypothetical form (unlinkable and displayed in italics).
* `nolinkinfl`: Make the form unlinkable.
]==]
function export.parse_term_with_modifiers(data)
local paramname, val, frob = data.paramname, data.val, data.frob
local function generate_obj(term, parse_err)
if not data.disable_special_modes and export.special_modes[term] then
return {
term = term,
_is_mode = true
}
end
if frob then
term = frob(term, parse_err)
end
if data.parse_lang_prefix and term:find(":") then
return require(parse_utilities_module).generate_obj_maybe_parsing_lang_prefix {
term = term,
paramname = paramname,
parse_lang_prefix = true,
parse_err = parse_err,
}
else
return {term = term}
end
end
-- Check for inline modifier, e.g. מרים<tr:Miryem>. But exclude top-level HTML entry with <span ...>,
-- <sup> or similar in it.
if (val:find("<", nil, true) or data.splitchar) and not term_contains_top_level_html(val) and
-- don't parse inline modifiers if is_head and the value begins with a ~ (link modifier syntax)
(not data.is_head or not val:find("^~")) then
local param_mods = param_mods
if data.is_head then
param_mods = shallow_copy(param_mods)
param_mods.id = nil
end
if data.include_mods or data.exclude_mods then
if not data.is_head then
-- already copied when data.is_head
param_mods = shallow_copy(param_mods)
end
if data.include_mods then
local optional_mods = data.is_head and optional_headword_param_mods or optional_param_mods
for _, mod in ipairs(data.include_mods) do
if type(mod) == "table" then
if #mod ~= 2 then
error(("Internal error: Modifier spec %s in `include_mods` should be of length 2"):format(
dump(mod)))
end
local modkey, modvalue = unpack(mod)
param_mods[modkey] = modvalue
elseif not optional_mods[mod] then
error(("Internal error: Unrecognized modifier spec %s in `include_mods`"):format(
dump(mod)))
else
param_mods[mod] = optional_mods[mod]
end
end
end
if data.exclude_mods then
for _, mod in ipairs(data.exclude_mods) do
if not param_mods[mod] then
error(("Internal error: Modifier spec %s in `exclude_mods` not found among existing modifiers"
):format(dump(mod)))
else
param_mods[mod] = nil
end
end
end
end
return parse_inline_modifiers(val, {
paramname = paramname,
param_mods = param_mods,
generate_obj = generate_obj,
splitchar = data.splitchar,
preserve_splitchar = data.preserve_splitchar,
delimiter_key = data.delimiter_key,
escape_fun = data.escape_fun,
unescape_fun = data.unescape_fun,
pre_normalize_modifiers = data.pre_normalize_modifiers,
})
else
local retval = generate_obj(val)
if data.splitchar then
retval = {retval}
end
return retval
end
end
--[==[
Parse a list of inflection forms that may have inline modifiers attached. `data` is an object with the following fields:
* `forms`: The list of raw values to parse. Required.
* `paramname`: The name of the first parameter from which the value was taken; used in error messages. If this is a
two-element list, the first element is the first parameter and the second element is the prefix of the remaining
parameters. Parameter names that are numbers are handled correctly, as are those with \1 in it marking where the
parameter index goes. Required.
* `qualifiers`: If specified, a possibly gappy list of left qualifiers to add to the parsed terms (for compatibility
purposes).
* `splitchar`: As in `parse_term_with_modifiers()`. The resulting per-term lists will be flattened.
* `frob`, `include_mods`, `exclude_mods`, `is_head`, `preserve_splitchar`, `parse_lang_prefix`, `delimiter_key`,
`escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_with_modifiers()`.
Returns a list of objects, suitable for storing as one of the lists in `headdata.inflections` (once a label is added),
where `headdata` is the structure passed to [[Module:headword]].
]==]
function export.parse_term_list_with_modifiers(data)
local paramname, forms = data.paramname, data.forms
local qualifiers = data.qualifiers
local first, restpref
if type(paramname) == "table" then
first = paramname[1]
restpref = paramname[2]
else
first = paramname
restpref = paramname
end
local terms = {}
data = shallow_copy(data)
for i, val in ipairs(forms) do
data.paramname = i == 1 and first or type(restpref) == "number" and restpref + i - 1 or
restpref:find("\1", nil, true) and restpref:gsub("\1", tostring(i)) or restpref .. i
data.val = val
local parsed = export.parse_term_with_modifiers(data)
if qualifiers and qualifiers[i] then
if data.splitchar then
for _, term in ipairs(parsed) do
term.q = {qualifiers[i]}
end
else
parsed.q = {qualifiers[i]}
end
end
if data.splitchar then
extend(terms, parsed)
else
terms[i] = parsed
end
end
return terms
end
--[==[
Construct a link to [[Appendix:Glossary]] for `entry`. If `text` is specified, it is the display text; otherwise,
`entry` is used.
]==]
function export.glossary_link(entry, text)
text = text or entry
return "[[ภาคผนวก:อภิธานศัพท์#" .. entry .. "|" .. text .. "]]"
end
function export.replace_glossary_links_in_label(label)
if label:find("<<", nil, true) then
label = label:gsub("<<(.-)|(.-)>>", export.glossary_link):gsub("<<(.-)>>", export.glossary_link)
end
return label
end
-- If a part of speech ends with one of these, either pluralized or followed by ' forms', chop off whatever precedes.
-- Also, if a part of speech is of the form `BASIC_POS FOO forms` e.g. `noun construct forms`, remove the `FOO`
-- portion. Note that "phrase" is *NOT* listed here because 'prepositional phrase' and 'postpositional phrase' are not
-- types of 'phrase' per the definition of these parts of speech in Wiktionary.
-- !! THWIKT cannot apply this logic !!
local basic_poses = {
"adjective",
"adverb",
"contraction",
"proper noun", -- may be converted to noun
"noun",
"participle",
"pronoun",
"symbol",
"verb",
}
local function optimized_pattern_escape(pos)
if pos:find("-", nil, true) then
return pattern_escape(pos)
else
return pos
end
end
--[==[
Canonicalize and then simplify a qualified part of speech (e.g. ''comparative adjectives'', ''past participles'',
''pronoun possessive forms'') to its unqualified equivalent (e.g. ''adjectives'', ''participles'', ''pronoun forms''').
This is used for categorization, since generally the simplified part of speech is used in categories other than the one
for the part of speech itself. (For example, comparative adjectives are normally categorized as adjectives in categories
such as `Requests for inflections in ``lang`` adjective entries`, and proper nouns are, sometimes at least, categorized
under ` ``lang`` nouns with ...` rather than ` ``lang`` proper nouns with ...`.)
There are two cases where simplification does not happen: phrases and (optionally) proper nouns. In Wiktionary,
''phrase'' really means a clause or similar constituent (or occasionally non-constituent), so `prepositional phrases`
are not types of `phrases` and are not simplified. Proper nouns are simplified to nouns for some categories but left
as-is in other category names; by default, this function simplifies `proper nouns` to `nouns`, but if the parameter
`preserve_proper_nouns` is given, `proper nouns` is left as-is.
If `preserve_lemma_status` is given, the function attempts to return a part of speech that has the same lemma status
(lemma or non-lemma form) as the original part of speech; thus, `comparative adjectives` becomes `adjective forms`
and `diminutive nouns` becomes `noun forms` because both are non-lemma forms. If `preserve_lemma_status` is not given,
the function simply chops off the qualifiers, converting e.g. `comparative adjectives` to `adjectives` even though this
changes the lemma status of the part of speech.
The part of speech can be given singular or plural on input, but is always returned in plural form.
]==]
-- !! THWIKT cannot apply this logic !!
function export.simplify_pos(pos, preserve_proper_nouns, preserve_lemma_status)
-- This allows for both singular and plural parts of speech in 'pos'.
local plpos = canonicalize_pos(pos)
for _, basic_pos in ipairs(basic_poses) do
if basic_pos ~= "proper noun" or preserve_proper_nouns then
if plpos == basic_pos .. " forms" then
-- So 'proper noun forms' doesn't get converted to 'noun forms' in the next round
return plpos
end
local basic_pos_pattern = optimized_pattern_escape(basic_pos)
if plpos:find(("^%s .*. forms$"):format(basic_pos_pattern)) then
return basic_pos .. " forms"
end
if plpos:find(("^.* %s forms$"):format(basic_pos_pattern)) then
return basic_pos .. " forms"
end
local pl_basic_pos = pluralize_pos(basic_pos)
if plpos == pl_basic_pos then
-- So 'proper nouns' doesn't get converted to 'nouns' in the next round
return plpos
end
local pl_basic_pos_pattern = optimized_pattern_escape(pl_basic_pos)
if plpos:find(("^.* %s$"):format(pl_basic_pos_pattern)) then
if preserve_lemma_status then
local lemma_status = require(headword_module).pos_lemma_or_nonlemma(plpos)
if lemma_status == "non-lemma form" then
return basic_pos .. " forms"
end
end
return pl_basic_pos
end
end
end
return plpos
end
function export.get_pos_variants(pos)
local retval = {}
retval.origpos = pos
retval.plpos = canonicalize_pos(pos)
retval.sgpos = --[[singularize(retval.plpos)]] retval.plpos
retval.simp_plpos = --[[export.simplify_pos(retval.plpos)]] retval.plpos
retval.simp_sgpos = --[[singularize(retval.simp_plpos)]] retval.simp_plpos
retval.simp_with_propn_plpos = --[[export.simplify_pos(retval.plpos, "preserve_proper_nouns")]] retval.plpos
retval.simp_with_propn_sgpos = --[[singularize(retval.simp_with_propn_plpos)]] retval.simp_with_propn_plpos
return retval
end
--[==[
Canonicalize a single term or term-like object or a list of either into a list of term-like objects. `abterms` is the
term or list to canonicalize, and `field` is the name of the field holding the term (defaulting to {"term"}). This
does the minimal work necessary, meaning that the return value may partly or completely share memory with the value
passed in. As a special case, if `abterms` is {nil}, {nil} is returned. If `origin` or `originating_term` are specified,
add fields `_origin` and/or `_originating_term` containing the specified value(s) to each resulting term-like object (in
this case, the object will be copied a necessary to avoid side-effecting the passed-in objects). `origin` is intended to
be a string indicating where the term originated from (e.g. {"default"} if a default value, {"resolve_special"} if
originating from a shortcut value such as {"+"}) and `originating_term` is the shortcut term itself, if any. (There is
generally no such term for default values.) If `termobj_for_string_terms` is specified, any terms in `abterms` specified
as strings will have all their properties other than `field` taken from `termobj_for_string_terms`.
]==]
function export.canonicalize_termobj_list(abterms, field, origin, originating_term, termobj_for_string_terms)
if abterms == nil then
return nil
end
local function make_termobj_from_string_term(term)
local retval
if termobj_for_string_terms then
retval = shallow_copy(termobj_for_string_terms)
else
retval = {}
end
retval[field] = term
retval._origin = origin
retval._originating_term = originating_term
return retval
end
local function shallow_copy_and_add_origin(termobj)
termobj = shallow_copy(termobj)
termobj._origin = origin
termobj._originating_term = originating_term
return termobj
end
field = field or "term"
if type(abterms) == "string" then
return {make_termobj_from_string_term(abterms)}
elseif not abterms[1] then
if origin ~= nil or originating_term ~= nil then
abterms = shallow_copy_and_add_origin(abterms)
end
return {abterms}
else
-- Check if already in full list term and return directly if so (unless `origin_val` is given, in which case we
-- need to shallow-copy both the list and each term in it).
local must_convert = false
for _, term in ipairs(abterms) do
if type(term) == "string" then
must_convert = true
break
end
end
if not must_convert then
if origin ~= nil or originating_term ~= nil then
abterms = shallow_copy(abterms)
for i, abterm in ipairs(abterms) do
abterms[i] = shallow_copy_and_add_origin(abterm)
end
end
return abterms
end
end
local retval = {}
for _, term in ipairs(abterms) do
if type(term) == "string" then
insert(retval, make_termobj_from_string_term(term))
else
if origin ~= nil or originating_term ~= nil then
term = shallow_copy_and_add_origin(term)
end
insert(retval, term)
end
end
return retval
end
function export.canonicalize_category_list(abcats)
-- FIXME: We should allow category objects in `headdata.categories` and not just strings. This seems to require
-- changes to [[Module:headword]].
if abcats == nil then
return nil
end
if abcats == false then
return {}
end
if type(abcats) == "string" then
abcats = {abcats}
end
return abcats
end
--[==[
Insert a fixed inflection (a label not associated with any inflection values) into an `inflections` field. The
`inflections` field will be initialized if needed. `data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `originating_term`: The term object from which this label is derived. If specified, decorations will be taken from
this object.
]==]
function export.insert_fixed_inflection(data)
local headdata, origterm, label = data.headdata, data.originating_term, data.label
local inflobj = data.inflobj or headdata
inflobj.inflections = inflobj.inflections or {}
if not origterm then
insert(inflobj.inflections, {
label = export.replace_glossary_links_in_label(label)
})
else
if origterm.id then
error(("It doesn't make sense to pass in an ID '%s' for label '%s' in conjunction with a term value '%s'"
):format(origterm.id, label, origterm.term))
end
origterm = shallow_copy(origterm)
-- Preserve decorations
origterm.term = nil
origterm.label = export.replace_glossary_links_in_label(label)
insert(inflobj.inflections, origterm)
end
end
local function yes_and_no_cats(props)
if props.cats and props.no_cats then
local yes_cats = export.canonicalize_category_list(props.cats)
local no_cats = export.canonicalize_category_list(props.no_cats)
local cats = shallow_copy(yes_cats)
extend(cats, no_cats)
return cats
end
end
local function sometimes_or_yes_and_no_cats(props)
local sometimes_cats = export.canonicalize_category_list(props.sometimes_cats)
if sometimes_cats then
return sometimes_cats
else
return yes_and_no_cats(props)
end
end
local function no_value_fallback_label(props)
if props.fixed_adj_no_label then
return props.fixed_adj_no_label
end
if props.fixed_adj_label then
return "ไม่" .. props.fixed_adj_label
end
return "ไม่มี" .. (props.label_for_cats_and_modes or props.label)
end
local function with_value_fallback_label(props)
if props.fixed_adj_label then
return props.fixed_adj_label
end
-- FIXME, should this say 'with a plural/diminutive' etc. or is 'with plural/diminutive' enough?
return "ใช้กับ" .. (props.label_for_cats_and_modes or props.label)
end
--[==[ var:
Table describing how to handle the "mode" signals at the beginning of an inflection, generally indicating whether the
inflection exists and to what extent. The key is the mode signal itself, and the value is table with the following keys:
* `exists`: The value to return in the `exists` field of the object returned by `process_for_insertion`. This is
currently used in calling code simply to check for different modes; it is an easier-to-read equivalent of the mode
signal itself.
* `prefix`: The prefix used to directly specify the label and category/categories associated with the mode in calling
code. For example, the mode `--+` (which also arises when `-` is used with a following term) has prefix `usually_no_`,
which means that to directly specify its label, use `usually_no_label` and to directly specify its categories, use
`usually_no_cats`. If these fields don't exist, the functions in `fallback_label` and `fallback_cats` are used to
generate the label and categories.
* `fallback_label`: This is a function of one argument, `props` (the properties passed in by the caller), which should
generate the label if the user didn't directly specify a label (see `prefix` above).
* `fallback_cats`: This is a function of one argument, `props` (the properties passed in by the caller), which should
generate the categories if the user didn't directly specify them (see `prefix` above).
* `add_default`: If true, the code will attempt to add a default value if the user specifies this mode without giving
additional terms. This depends on the caller passing in a `mode_default` property (which can be a string, a term
object, a list of either, or a function generating any of those values). In many cases the `mode_default` property
may simply have a value such as {"+"}, which is processed later by resolve_special().
* `disallow_additional`: If true, no additional terms are allowed after the mode signal; if present, an error is
thrown.
]==]
export.special_modes = {
["-"] = {exists = "no", prefix = "no_",
fallback_label = no_value_fallback_label,
}, -- converted to "--+" if a term follows
["--+"] = {exists = "usually no", prefix = "usually_no_", add_default = true,
fallback_label = function(props)
if props.no_label then
return "โดยปกติ" .. props.no_label
end
return "โดยปกติ" .. no_value_fallback_label(props)
end,
fallback_cats = sometimes_or_yes_and_no_cats,
},
["+-"] = {exists = "sometimes", prefix = "sometimes_", add_default = true,
fallback_label = function(props)
return "บางครั้ง" .. with_value_fallback_label(props)
end,
fallback_cats = yes_and_no_cats,
},
["++-"] = {exists = "usually", prefix = "usually_", add_default = true,
fallback_label = function(props)
return "บางครั้ง" .. with_value_fallback_label(props)
end,
fallback_cats = sometimes_or_yes_and_no_cats,
},
["!"] = {exists = "unattested", prefix = "unattested_", disallow_additional = true,
fallback_label = function(props)
return (props.label_for_cats_and_modes or props.label) .. "ไม่ปรากฏหลักฐาน"
end,
-- No default cats; provided for plurals in inflection_to_cats_and_label.
},
["?"] = {exists = "unknown", prefix = "unknown_", disallow_additional = true,
-- No default label as people have preferred not to see 'plural unknown or uncertain'
-- written out. No default cats; provided for plurals in inflection_to_cats_and_label.
},
}
function export.process_for_insertion(data)
local terms, mode_default, headdata = data.terms, data.mode_default, data.headdata
local retval = {
headdata = data.headdata,
}
if terms and terms[1] then
local mode = terms[1].term
local modespec = export.special_modes[mode]
if modespec then
terms = shallow_copy(terms)
retval.mode_term = terms[1]
remove(terms, 1)
if mode == "-" and terms[1] then
mode = "--+"
end
if terms[1] and modespec.disallow_additional then
error(("It doesn't make sense to specify explicit terms along with mode signal %s (%s)"):format(
mode, modespec.exists))
elseif not terms[1] and modespec.add_default and mode_default then
if type(mode_default) == "function" then
mode_default = mode_default(headdata, retval.mode_term)
end
if mode_default then
terms = export.canonicalize_termobj_list(mode_default, "term", "mode_default", retval.mode_term)
end
end
retval.numterms = #terms
retval.terms = terms
retval.mode = mode
retval.exists = modespec.exists
retval.prefix = modespec.prefix
else
retval.numterms = #terms
retval.terms = terms
retval.exists = "yes"
retval.prefix = ""
end
else
retval.numterms = 0
retval.terms = {}
-- retval.exists = nil
retval.request = data.request
end
return retval
end
--[==[
Insert previously-parsed terms into an `inflections` field. The `inflections` field will be initialized if needed.
`data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `terms`: The list of parsed terms. If {nil} or omitted, nothing happens unless `request` is set.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `fixed_adj_label`: If specified, an adjective used to construct the defaults for the fixed labels specified by
`no_label`, `usually_no_label` and `sometimes_label`. Examples are "comparable" for a comparative and "countable"
for a plural.
* `no_label`: If the term is {"-"} and there are no other terms, insert a fixed label with this value. If
`fixed_adj_label` is given, defaults to {"not "} plus the adjective, else {"no "} plus the label.
* `usually_no_label`: If the term is {"-"} and there are other terms, insert a fixed label with this value. Defaults to
{"usually "} plus the value of `no_label`.
* `sometimes_label`: If the term is {"+-"}, insert a fixed label with this value. If `fixed_adj_label` is given,
defaults to {"sometimes "} plus the adjective, else {"sometimes with a(n) "} plus the label.
* `cats`: List of categories to insert when terms are given that are not {"-"}. Each category is a string naming a full
category to insert (including the appropriate language name prefixed).
* `no_cats`: List of categories to insert when a term is given as {"-"}.
* `usually_no_cats`: List of categories to insert when a term is given as {"-"} and additional terms are specified as
well (representing, e.g. for the inflection {"plural"}, a term which usually has no plural but does under some
circumstances). If omitted, both the categories in `cats` and `no_cats` are inserted.
* `sometimes_cats`: List of categories to insert when a term is given as {"+-"} (indicating that the inflection
sometimes exists and sometimes does not, normally depending on the precise sense involved). If omitted, both the
categories in `cats` and `no_cats` are inserted (same default as for `usually_no_cats`).
* `accel`: If specified, a full accelerator object to add to the inflections.
* `request`: If specified and no terms are given, insert a label with a request for inflections to be given.
* `enable_auto_translit`: If specified and terms are given, display automatic transliteration of the terms.
The return value indicates whether the inflection exists and how many terms are in it. It is an object with the
following fields:
* `exists`: {"yes"} if one or more terms were specified; {"no"} if the value was given as {"-"}; {"usually no"} if
the first value was given as {"-"} but additional terms were supplied; otherwise {nil}, indicating that the status
is unspecified.
* `numterms`: Number of terms in the inflection. Will be 0 unless `exists` has the value {"yes"} or {"usually no"}.
* `terms`: The terms that were inserted. If there are no terms, this is an empty list.
* `request`: True if no terms were specified but a term request was inserted into the inflection (because
`data.request` was specified). Otherwise {nil}.
]==]
function export.insert_processed_inflection(data)
local headdata, processed, label = data.headdata, data.processed, data.label
local inflobj = data.inflobj or headdata
local accel = data.accel
if data.accel_form then
if accel then
error("Internal error: can't specify both data.accel and data.accel_form")
end
if headdata.heads then
local lemmas = {}
local lemma_translits = {}
for i, headobj in ipairs(headdata.heads) do
lemmas[i] = headobj.term
if lemmas[i] == "+" then
error("Internal error: If you use data.accel_form, you should have resolved all occurrences of + in heads appropriately")
end
lemma_translits[i] = headobj.tr
end
accel = {
lemma = lemmas,
lemma_translit = lemma_translits,
form = data.accel_form,
}
else
accel = {
form = data.accel_form,
}
end
end
local function insert_cats(cats)
for _, cat in ipairs(cats) do
insert(headdata.categories, cat)
end
end
-- Handle the fixed label (if any) and cats (if any) associated with a mode.
if processed.mode then
local modespec = export.special_modes[processed.mode]
local mode_prefix = modespec.prefix
local fixed_label = data[mode_prefix .. "label"]
if not fixed_label and modespec.fallback_label then
fixed_label = modespec.fallback_label(data)
end
if fixed_label then
export.insert_fixed_inflection {
headdata = headdata,
inflobj = inflobj,
originating_term = processed.mode_term,
label = fixed_label,
}
end
local mode_cats = data[mode_prefix .. "cats"]
if not mode_cats and modespec.fallback_cats then
mode_cats = modespec.fallback_cats(data)
end
mode_cats = export.canonicalize_category_list(mode_cats)
if mode_cats then
insert_cats(mode_cats)
end
elseif processed.terms[1] and data.cats then
-- If no mode, no fixed label but there may be categories.
insert_cats(data.cats)
end
local terms = processed.terms
if terms[1] then
-- FIXME, if there's a mode we shallow_copy() twice.
terms = shallow_copy(terms)
terms.label = export.replace_glossary_links_in_label(label)
if accel then
terms.accel = accel
end
terms.enable_auto_translit = data.enable_auto_translit
inflobj.inflections = inflobj.inflections or {}
insert(inflobj.inflections, terms)
elseif processed.request then
inflobj.inflections = inflobj.inflections or {}
insert(inflobj.inflections, {
label = export.replace_glossary_links_in_label(label),
request = true,
})
end
end
--[==[
Insert previously-parsed terms into an `inflections` field. The `inflections` field will be initialized if needed.
`data` is an object with the following fields:
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `inflobj`: The object whose `inflections` field the terms are inserted into. Defaults to `headdata`. Only needs
to be set for nested inflections, which are specified for an inflection object rather than the headword data
structure as a whole.
* `terms`: The list of parsed terms. If {nil} or omitted, nothing happens unless `request` is set.
* `label`: The label that the inflections are given; any parts of the label surrounded in `<<...>>` are linked to the
glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.) Required.
* `fixed_adj_label`: If specified, an adjective used to construct the defaults for the fixed labels specified by
`no_label`, `usually_no_label` and `sometimes_label`. Examples are "comparable" for a comparative and "countable"
for a plural.
* `no_label`: If the term is {"-"} and there are no other terms, insert a fixed label with this value. If
`fixed_adj_label` is given, defaults to {"not "} plus the adjective, else {"no "} plus the label.
* `usually_no_label`: If the term is {"-"} and there are other terms, insert a fixed label with this value. Defaults to
{"usually "} plus the value of `no_label`.
* `sometimes_label`: If the term is {"+-"}, insert a fixed label with this value. If `fixed_adj_label` is given,
defaults to {"sometimes "} plus the adjective, else {"sometimes with a(n) "} plus the label.
* `cats`: List of categories to insert when terms are given that are not {"-"}. Each category is a string naming a full
category to insert (including the appropriate language name prefixed).
* `no_cats`: List of categories to insert when a term is given as {"-"}.
* `usually_no_cats`: List of categories to insert when a term is given as {"-"} and additional terms are specified as
well (representing, e.g. for the inflection {"plural"}, a term which usually has no plural but does under some
circumstances). If omitted, both the categories in `cats` and `no_cats` are inserted.
* `sometimes_cats`: List of categories to insert when a term is given as {"+-"} (indicating that the inflection
sometimes exists and sometimes does not, normally depending on the precise sense involved). If omitted, both the
categories in `cats` and `no_cats` are inserted (same default as for `usually_no_cats`).
* `accel`: If specified, a full accelerator object to add to the inflections.
* `request`: If specified and no terms are given, insert a label with a request for inflections to be given.
* `enable_auto_translit`: If specified and terms are given, display automatic transliteration of the terms.
The return value indicates whether the inflection exists and how many terms are in it. It is an object with the
following fields:
* `exists`: {"yes"} if one or more terms were specified; {"no"} if the value was given as {"-"}; {"usually no"} if
the first value was given as {"-"} but additional terms were supplied; otherwise {nil}, indicating that the status
is unspecified.
* `numterms`: Number of terms in the inflection. Will be 0 unless `exists` has the value {"yes"} or {"usually no"}.
* `terms`: The terms that were inserted. If there are no terms, this is an empty list.
* `request`: True if no terms were specified but a term request was inserted into the inflection (because
`data.request` was specified). Otherwise {nil}.
]==]
function export.insert_inflection(data)
local headdata, terms, mode_default = data.headdata, data.terms, data.mode_default
local processed = export.process_for_insertion {
headdata = headdata,
terms = terms,
mode_default = mode_default,
}
data = shallow_copy(data)
data.processed = processed
export.insert_processed_inflection(data)
return processed
end
--[==[
Parse raw arguments from `forms` for inline modifiers, and insert the resulting terms (which should not require
significant additional processing) into `headdata.inflections`. `data` is an object with the following fields:
* `forms`: The list of raw values to parse. If {nil} or omitted, nothing happens.
* `headdata`: The headword structure passed to [[Module:headword]]. Required.
* `paramname`: As in `parse_term_list_with_modifiers()`. Required.
* `label`: As in `insert_inflection()`. Required.
* `qualifiers`, `frob`, `include_mods`, `exclude_mods`, `is_head`, `splitchar`, `preserve_splitchar`, `delimiter_key`,
`escape_fun`, `unescape_fun`, `pre_normalize_modifiers`: As in `parse_term_list_with_modifiers()`.
* `accel`: As in `insert_inflection()`.
Return value is as in `insert_inflection()`.
]==]
function export.parse_and_insert_inflection(data)
local forms = data.forms
if forms and forms[1] then
data = shallow_copy(data)
data.forms = forms
data.terms = export.parse_term_list_with_modifiers(data)
return export.insert_inflection(data)
end
return {
numterms = 0
}
end
--[==[
Combine two sets of decorations. If either is {nil}, just return the other, and if both are {nil}, return {nil}.
]==]
function export.combine_decorations(decs1, decs2)
if not decs1 and not decs2 then
return nil
end
if not decs1 then
return decs2
end
if not decs2 then
return decs1
end
local combined = shallow_copy(decs1)
for _, dec in ipairs(decs2) do
insert_if_not(combined, dec)
end
return combined
end
function export.combine_qualifiers_or_labels(...)
-- FIXME: Added 2026-09-17. Remove after a month.
error("Use combine_decorations instead")
end
--[==[
Combine the decorations (qualifiers, labels, references) and ID's of two term objects. `destobj` is the "destination
term object" into which the combined properties are written, and `srcobj` is the "source object" into which the
properties are merged. `destobj` is side-effected (but the lists inside of `destobj` are not); if this is undesirable,
make sure to shallow-copy `destobj` first. If both objects have values for a given decoration, the values of `destobj`
come first. If both objects have a value for `id`, the values must match or an error is thrown; otherwise, the resulting
value of `id` comes from whichever one is defined.
'''NOTE:''' This may not be the correct behavior when deduplicating a list of term objects. See
`insert_termobj_combining_duplicates` for a different approach.
]==]
function export.combine_termobj_decorations(destobj, srcobj)
destobj.q = export.combine_decorations(destobj.q, srcobj.q)
destobj.qq = export.combine_decorations(destobj.qq, srcobj.qq)
destobj.l = export.combine_decorations(destobj.l, srcobj.l)
destobj.ll = export.combine_decorations(destobj.ll, srcobj.ll)
destobj.refs = export.combine_decorations(destobj.refs, srcobj.refs)
if destobj.id and srcobj.id and destobj.id ~= srcobj.id then
-- FIXME: We probably want to pass in an error function
error(("Can't specify two different ID's %s and %s when combining objects"):format(srcobj.id, destobj.id))
end
destobj.id = destobj.id or srcobj.id
return destobj
end
function export.combine_termobj_qualifiers_labels(...)
-- FIXME: Added 2026-09-17. Remove after a month.
error("Use combine_termobj_decorations instead")
end
function export.termobj_has_decorations(obj)
return obj.q and obj.q[1] or obj.qq and obj.qq[1] or obj.l and obj.l[1] or obj.ll and obj.ll[1] or
obj.refs and obj.refs[1]
end
function export.termobj_has_qualifiers_or_labels(...)
-- FIXME: Added 2026-09-17. Remove after a month.
error("Use termobj_has_decorations instead")
end
local function one_decoration_equal(prop1, prop2)
local prop1_is_nil = not prop1 or not prop1[1]
local prop2_is_nil = not prop2 or not prop2[1]
if prop1_is_nil and prop2_is_nil then
return true
end
if prop1_is_nil or prop2_is_nil then
return false
end
return deep_equals(prop1, prop2)
end
function export.termobj_decorations_equal(obj1, obj2)
return one_decoration_equal(obj1.q, obj2.q) and
one_decoration_equal(obj1.qq, obj2.qq) and
one_decoration_equal(obj1.l, obj2.l) and
one_decoration_equal(obj1.ll, obj2.ll) and
one_decoration_equal(obj1.refs, obj2.refs) and
obj1.id == obj2.id
end
function export.termobj_ancillary_properties_equal(...)
-- FIXME: Added 2026-09-17. Remove after a month.
error("Use termobj_decorations_equal instead")
end
function export.convert_termobj_to_formobj(termobj)
local formobj = {
form = termobj.term,
translit = termobj.tr,
}
local footnotes
local function mods_to_footnote(mod_prefix, mod_vals)
if mod_vals and mod_vals[1] then
footnotes = footnotes or {}
for _, val in ipairs(mod_vals) do
insert(footnotes, "[" .. mod_prefix .. ":" .. val .. "]")
end
end
end
mods_to_footnote("q", termobj.q)
mods_to_footnote("qq", termobj.qq)
mods_to_footnote("l", termobj.l)
mods_to_footnote("ll", termobj.ll)
mods_to_footnote("ref", termobj.refs)
mods_to_footnote("id", termobj.id and {termobj.id} or nil)
formobj.footnotes = footnotes
return formobj
end
local recognized_multi_mods = {
q = "q",
qq = "qq",
l = "l",
ll = "ll",
ref = "refs",
}
local recognized_single_mods = {
id = "id",
}
function export.add_footnote_to_termobj(termobj, footnote)
local stripped_footnote = footnote:match("^%[(.*)%]$")
if not stripped_footnote then
error("Internal error: Footnote should be surrounded by brackets at this stage: " .. footnote)
end
local prefix, rest = stripped_footnote:match("^([a-z]+):(.+)$")
local field, is_multi
if prefix then
if recognized_multi_mods[prefix] then
field = recognized_multi_mods[prefix]
is_multi = true
elseif recognized_single_mods[prefix] then
field = recognized_single_mods[prefix]
is_multi = false
end
end
if not field then
rest = stripped_footnote
field = "l"
is_multi = true
end
if is_multi then
if not termobj[field] then
termobj[field] = {}
end
insert(termobj[field], rest)
else
if termobj[field] and termobj[field] ~= rest then
error(("Can't set two values for '%s': '%s' and '%s'"):format(field, termobj[field], rest))
end
termobj[field] = rest
end
end
function export.convert_formobj_to_termobj(formobj)
local termobj = {
term = formobj.form,
tr = formobj.translit,
}
if formobj.footnotes then
for _, footnote in ipairs(formobj.footnotes) do
export.add_footnote_to_termobj(termobj, footnote)
end
end
return termobj
end
local function extract_termobj_field_modifiers(fieldval)
return fieldval:match("^([*+]?)(.*)$")
end
function export.remove_termobj_field_modifiers(termobj)
local function remove_field_modifiers(field)
if termobj[field] and termobj[field][1] then
local any_field_modifiers = false
for _, val in ipairs(termobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods ~= "" then
any_field_modifiers = true
break
end
end
local new_field = {}
if any_field_modifiers then
for _, val in ipairs(termobj[field]) do
local _, field_without_mods = extract_termobj_field_modifiers(val)
insert_if_not(new_field, field_without_mods)
end
termobj[field] = new_field
end
end
end
remove_field_modifiers("q")
remove_field_modifiers("qq")
remove_field_modifiers("l")
remove_field_modifiers("ll")
remove_field_modifiers("refs")
end
function export.insert_termobj_combining_duplicates(destobjs, termobj)
for _, destobj in ipairs(destobjs) do
if destobj.term == termobj.term and destobj.tr == termobj.tr then
-- Form already present; maybe combine footnotes.
local function combine_field_values(field)
if termobj[field] and termobj[field][1] then
-- Check to see if there are existing values with *; if so, remove them.
if destobj[field] and destobj[field][1] then
local any_values_with_asterisk = false
for _, val in ipairs(destobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods:find("%*") then
any_values_with_asterisk = true
break
end
end
if any_values_with_asterisk then
local filtered_values = {}
for _, val in ipairs(destobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if not field_mods:find("%*") then
insert(filtered_values, val)
end
end
if filtered_values[1] then
destobj[field] = filtered_values
else
destobj[field] = nil
end
end
end
local any_footnotes_with_plus = false
for _, val in ipairs(termobj[field]) do
local field_mods, _ = extract_termobj_field_modifiers(val)
if field_mods:find("%+") then
any_footnotes_with_plus = true
break
end
end
if any_footnotes_with_plus then
if not destobj[field] then
destobj[field] = {}
else
destobj[field] = shallow_copy(destobj[field])
end
for _, val in ipairs(termobj[field]) do
local already_seen = false
local field_mods, field_without_mods = extract_termobj_field_modifiers(val)
if field_mods:find("%+") then
for _, existing_val in ipairs(destobj[field]) do
local _, existing_field_without_mods =
extract_termobj_field_modifiers(existing_val)
if existing_field_without_mods == field_without_mods then
already_seen = true
break
end
end
if not already_seen then
insert(destobj[field], val)
end
end
end
end
end
end
combine_field_values("q")
combine_field_values("qq")
combine_field_values("l")
combine_field_values("ll")
combine_field_values("refs")
if destobj.id and termobj.id and destobj.id ~= termobj.id then
-- FIXME: We probably want to pass in an error function
error(("Can't specify two different ID's %s and %s when combining objects"):format(termobj.id, destobj.id))
end
destobj.id = destobj.id or termobj.id
return
end
end
insert(destobjs, termobj)
end
export.allowed_special_indicators = {
["first"] = true,
["first-second"] = true,
["first-last"] = true,
["second"] = true,
["last"] = true,
["each"] = true,
["+"] = true, -- requests the default behavior with preposition handling
}
--[==[
Check for special indicators (values such as {"+first"} or {"+first-last"} that are used in a `pl`, `f`, etc. argument
and indicate how to inflect a multiword term). If `form` is such an indicator, the return value is `form` minus
the initial `+` sign; otherwise, if form begins with a `+` sign, an error is thrown; otherwise the return value is nil.
]==]
function export.get_special_indicator(form, noerror)
if form:find("^%+") then
form = form:gsub("^%+", "")
if not export.allowed_special_indicators[form] then
if noerror then
return nil
end
local indicators = {}
for indic, _ in pairs(export.allowed_special_indicators) do
insert(indicators, "+" .. indic)
end
sort(indicators)
error("Special inflection indicator beginning with '+' can only be " ..
mw.text.listToText(indicators) .. ": +" .. form)
end
return form
end
return nil
end
local function add_endings(bases, endings)
local retval = {}
if type(bases) ~= "table" then
bases = {bases}
end
if type(endings) ~= "table" then
endings = {endings}
end
for _, base in ipairs(bases) do
for _, ending in ipairs(endings) do
insert(retval, base .. ending)
end
end
return retval
end
--[==[
Inflect a possibly multiword or hyphenated term `form` using the function `inflect`, which is a function of one argument
that is called on a single word to inflect and should return either the inflected word or a list of inflected words.
`special` indicates how to inflect the multiword term and should be e.g. {"first"} to inflect only the first word,
{"first-last"} to inflect the first and last words, {"each"} to inflect each word, etc. See `allowed_special_indicators`
above for the possibilities. If `special` is `+`, or is omitted and the term is multiword (i.e. containing a space
character), and `prepositions` is supplied, the function checks for multiword or hyphenated terms containing the
prepositions in `prepositions`, e.g. Italian [[senso di marcia]] or [[medaglia d'oro]] or Portuguese
[[tartaruga-do-mar]]. If such a term is found, only the first word is inflected. Otherwise, the default is
{"first-last"}. `prepositions` is a list of Lua patterns matching prepositions. The patterns will automatically have the
separator character (space or hyphen) added to the left side but not the right side, so they should contain a space
character (which will automatically be converted to the appropriate separator) on the right side unless the preposition
is joined on the right side with an apostrophe. Examples of preposition patterns for Italian are {"di "}, {"sull'"} and
{"d?all[oae] "} (which matches {"dallo "}, {"dalle "}, {"alla "}, etc.).
The return value is always either a list of inflected multiword or hyphenated terms, or nil if `special` is omitted
and `form` is not multiword. (If `special` is specified and `form` is not multiword or hyphenated, an error results.)
]==]
function export.handle_multiword(form, special, inflect, prepositions, sep)
sep = sep or form:find(" ") and " " or "%-"
local raw_sep = sep == " " and " " or "-"
-- Used to add regex version of separator in the replacement portion of ugsub() or :gsub()
local sep_replacement = sep == " " and " " or "%%-"
-- Given a Lua pattern, replace space with the appropriate separator.
local function hack_re(re)
if sep == " " then
return re
end
return (re:gsub(" ", sep_replacement))
end
if special == "first" then
local first, rest = form:match(hack_re("^(.-)( .*)$"))
if not first then
error("Special indicator 'first' can only be used with a multiword term: " .. form)
end
return add_endings(inflect(first), rest)
elseif special == "second" then
local first, second, rest = form:match(hack_re("^([^ ]+ )([^ ]+)( .*)$"))
if not first then
error("Special indicator 'second' can only be used with a term with three or more words: " .. form)
end
return add_endings(add_endings({first}, inflect(second)), rest)
elseif special == "first-second" then
local first, space, second, rest = form:match(hack_re("^([^ ]+)( )([^ ]+)( .*)$"))
if not first then
error("Special indicator 'first-second' can only be used with a term with three or more words: " .. form)
end
return add_endings(add_endings(add_endings(inflect(first), space), inflect(second)), rest)
elseif special == "each" then
local terms = split(form, sep)
if #terms < 2 then
error("Special indicator 'each' can only be used with a multiword term: " .. form)
end
for i, term in ipairs(terms) do
terms[i] = inflect(term)
if i > 1 then
terms[i] = add_endings(raw_sep, terms[i])
end
end
local result = ""
for _, term in ipairs(terms) do
result = add_endings(result, term)
end
return result
elseif special == "first-last" then
local first, middle, last = form:match(hack_re("^(.-)( .* )(.-)$"))
if not first then
first, middle, last = form:match(hack_re("^(.-)( )(.*)$"))
end
if not first then
error("Special indicator 'first-last' can only be used with a multiword term: " .. form)
end
return add_endings(add_endings(inflect(first), middle), inflect(last))
elseif special == "last" then
local rest, last = form:match(hack_re("^(.* )(.-)$"))
if not rest then
error("Special indicator 'last' can only be used with a multiword term: " .. form)
end
return add_endings(rest, inflect(last))
elseif special and special ~= "+" then
error("Unrecognized special=" .. special)
end
-- Only do default behavior if special indicator '+' explicitly given or separator is space; otherwise we will
-- break existing behavior with hyphenated words.
if (special == "+" or sep == " ") and form:find(sep) then
if prepositions then
-- check for prepositions in the middle of the word; do it this way so we can handle
-- more than one word before the preposition (and usually inflect each word)
for _, prep in ipairs(prepositions) do
local first, space_prep_rest = umatch(form, hack_re("^(.-)( " .. prep .. ".*)$"))
if first then
return add_endings(inflect(first), space_prep_rest)
end
end
end
-- multiword or hyphenated expressions default to first-last; we need to pass in the separator to avoid
-- problems with multiword terms containing hyphens in the individual words
return export.handle_multiword(form, "first-last", inflect, prepositions, sep)
end
return nil
end
local function link_hyphen_split_component(word, data)
if data.link_hyphen_split_component then
return data.link_hyphen_split_component(word)
else
return "[[" .. word .. "]]"
end
end
-- Default function to split a word on apostrophes. Don't split apostrophes at the beginning or end of a word (e.g.
-- [['ndrangheta]] or [[po']]). Handle multiple apostrophes correctly, e.g. [[l'altr'ieri]] -> [[l']][altr']][[ieri]].
function export.default_split_apostrophe(word, data)
local apostrophe_parts = split(word, "'", true, true)
local linked_apostrophe_parts = {}
local apostrophes_at_beginning = ""
local i = 1
-- Apostrophes at beginning get attached to the first word after (which will always exist but may
-- be blank if the word consists only of apostrophes).
while i < #apostrophe_parts do -- <, not <=, in case the word consists only of apostrophes
local apostrophe_part = apostrophe_parts[i]
i = i + 1
if apostrophe_part == "" then
apostrophes_at_beginning = apostrophes_at_beginning .. "'"
else
break
end
end
apostrophe_parts[i] = apostrophes_at_beginning .. apostrophe_parts[i]
-- Now, do the remaining parts. A blank part indicates more than one apostrophe in a row; we join
-- all of them to the preceding word.
while i <= #apostrophe_parts do
local apostrophe_part = apostrophe_parts[i]
if apostrophe_part == "" then
linked_apostrophe_parts[#linked_apostrophe_parts] =
linked_apostrophe_parts[#linked_apostrophe_parts] .. "'"
elseif i == #apostrophe_parts then
insert(linked_apostrophe_parts, apostrophe_part)
else
insert(linked_apostrophe_parts, apostrophe_part .. "'")
end
i = i + 1
end
for j, tolink in ipairs(linked_apostrophe_parts) do
linked_apostrophe_parts[j] = link_hyphen_split_component(tolink, data)
end
return concat(linked_apostrophe_parts)
end
--[=[
Auto-add links to a word that should not have spaces but may have hyphens and/or apostrophes. We split off final
punctuation, then split on hyphens if `data.split_hyphen` is given, and also split on apostrophes if
`data.split_apostrophe` is given. We only split on hyphens if they are in the middle of the word, not at the beginning
or end (hyphens at the beginning or end indicate suffixes or prefixes, respectively). `include_hyphen_prefixes`, if
given, is a set of prefixes (not including the final hyphen) where we should include the final hyphen in the prefix.
Hence, e.g. if "anti" is in the set, a Portuguese word like [[anti-herói]] "anti-hero" will be split [[anti-]][[herói]]
(whereas a word like [[código-fonte]] "source code" will be split as [[código]]-[[fonte]]).
If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and
the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the
default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in
Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French
[[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified
but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word
to split, and the return value should be the split and linked word.
]=]
local function add_single_word_links(space_word, data, term_has_spaces)
local space_word_no_punct, punct
local punct_pattern = data.punctuation
if punct_pattern and is_callable(punct_pattern) then
space_word_no_punct, punct = punct_pattern(space_word)
else
if punct_pattern == nil then
punct_pattern = "[,;:?!]"
end
space_word_no_punct, punct = umatch(space_word, "^(.*)(" .. punct_pattern .. ")$")
end
space_word_no_punct = space_word_no_punct or space_word
punct = punct or ""
local words
if space_word_no_punct:sub(1, 1) == "-" or space_word_no_punct:sub(-1) == "-" then
-- don't split prefixes and suffixes
words = {space_word_no_punct}
else
local splitter
if term_has_spaces then
splitter = data.split_hyphen_when_space
else
splitter = data.split_hyphen_when_no_space
end
if is_callable(splitter) then
words = splitter(space_word_no_punct)
if type(words) == "string" then
return words .. punct
end
end
end
if not words then
local split_hyphen
if term_has_spaces then
split_hyphen = data.split_hyphen_when_space
else
split_hyphen = data.split_hyphen_when_no_space
if split_hyphen == nil then -- default to true; use `false` to avoid this
split_hyphen = true
end
end
if split_hyphen then
words = split(space_word_no_punct, "-", true, true)
else
words = {space_word_no_punct}
end
end
local linked_words = {}
for j, word in ipairs(words) do
if j < #words and data.include_hyphen_prefixes and data.include_hyphen_prefixes[word] then
word = "[[" .. word .. "-]]"
elseif j > 1 and data.include_hyphen_suffixes and data.include_hyphen_suffixes[word] then
word = "[[-" .. word .. "]]"
else
-- Don't split on apostrophes if the word is in `no_split_apostrophe_words`.
if (not data.no_split_apostrophe_words or not data.no_split_apostrophe_words[word]) and
data.split_apostrophe and word:find("'", nil, true) then
if data.split_apostrophe == true then
word = export.default_split_apostrophe(word, data)
else -- custom apostrophe splitter/linker
word = data.split_apostrophe(word)
end
elseif word ~= "" then -- avoid -[[]]- (e.g. f--k)
word = link_hyphen_split_component(word, data)
end
if j < #words then
word = word .. "-"
end
end
insert(linked_words, word)
end
return concat(linked_words) .. punct
end
--[=[
Auto-add links to a multiword term. `data` contains fields customizing how to do this. By default we proceed as follows:
(1) If the term already has embedded links in it, they are left unchanged.
(2) Otherwise, if there are spaces present, we split on spaces and link each word separately.
(3) If a given space-separated component ends in punctuation (defaulting to [,;:?!]), it is separated off, the remainder
of the algorithm run, and the punctuation pasted back on.
(4) If there are hyphens in a given space-separated component, we may link each hyphenated term separately depending
on the settings in `data`. Normally the hyphens are not included in the linked terms, but this can be overridden
for specific prefixes and/or suffixes. By default, if there are spaces in the multiword term, we do not link
hyphenated components (because of cases like "boire du petit-lait" where "petit-lait" should be linked as a whole),
but do so otherwise (e.g. for "avant-avant-hier"); this can overridden for cases like "croyez-le ou non".
Cases where only some of the hyphens should be split can always be handled by explicitly specifying the head (e.g.
"Nord-Pas-de-Calais" given as head=[[Nord]]-[[Pas-de-Calais]]).
(5) If there are apostrophes in a given component, we may link each apostrophe-separated term separately depending
on the settings in `data`, including the apostrophe in the link to its left (so we split "de l'eau" as
"[[de]] [[l']][[eau]]").
The settings in `data` are as follows:
`split_hyphen_when_no_space`: Whether to split on hyphens when the term has no spaces. Defaults to true if set to `nil`.
This can be a function of one argument, to implement a custom splitting algorithm for hyphen-separated terms. If
this returns [FIXME: FINISH ME ...]
If `data.split_apostrophe` is specified, we split on apostrophes unless `data.no_split_apostrophe_words` is given and
the word is in the specified set, such as French [[c'est]] and [[quelqu'un]]. If `data.split_apostrophe` is true, the
default algorithm applies, which splits on all apostrophes except those at the beginning and end of a word (as in
Italian [['ndrangheta]] or [[po']]), and includes the apostrophe in the link to its left (so we auto-split French
[[l'eau]] as [[l']][[eau]] and [[l'altr'ieri]] as [[l']][altr']][[ieri]]). If `data.split_apostrophe` is specified
but not `true`, it should be a function of one argument that does custom apostrophe-splitting. The argument is the word
to split, and the return value should be the split and linked word.
We don't always split on hyphens because of cases like "boire du petit-lait" where "petit-lait" should be linked as a
whole, but provide the option to do it for cases like "croyez-le ou non". If there's no space, however, then it makes
sense to split on hyphens by `no_split_apostrophe_words` and `include_hyphen_prefixes` allow for special-case handling
of particular words and are as described in the comment above add_single_word_links().
]=]
function export.add_links_to_multiword_term(term, data)
if term:match("[%[%]]") then
return term
end
local words = split(term, " ", true, true)
local term_has_spaces = #words > 1
local linked_words = {}
for _, word in ipairs(words) do
insert(linked_words, add_single_word_links(word, data, term_has_spaces))
end
local retval = concat(linked_words, " ")
-- If we ended up with a single link consisting of the entire term,
-- remove the link.
return retval:match("^%[%[([^%[%]]*)%]%]$") or retval
end
local function canonicalize_begin_end_spec(spec)
local from, to = spec:match("^(.-):(.*)$")
if not from then
from = spec
to = ""
end
return from, to
end
--[==[
Given a `linked_term` that is the output of add_links_to_multiword_term(), apply modifications as given in
`modifier_spec` to change the link destination of subterms (normally single-word non-lemma forms; sometimes
collections of adjacent words). This is usually used to link non-lemma forms to their corresponding lemma, but can
also be used to replace a span of adjacent separately-linked words to a single multiword lemma. The format of
`modifier_spec` is one or more semicolon-separated subterm specs, where each such spec is of the form
SUBTERM:DEST, where SUBTERM is one or more words in the `linked_term` but without brackets in them, and DEST is the
corresponding link destination to link the subterm to. Any occurrence of ~ in DEST is replaced with SUBTERM.
Alternatively, a single modifier spec can be of the form BEGIN[FROM:TO], which is equivalent to writing
BEGINFROM:BEGINTO (see example below).
For example, given the source phrase [[il bue che dice cornuto all'asino]] "the pot calling the kettle black"
(literally "the ox that calls the donkey horned/cuckolded"), the result of calling add_links_to_multiword_term()
is [[il]] [[bue]] [[che]] [[dice]] [[cornuto]] [[all']][[asino]]. With a modifier_spec of 'dice:dire', the result
is [[il]] [[bue]] [[che]] [[dire|dice]] [[cornuto]] [[all']][[asino]]. Here, based on the modifier spec, the
non-lemma form [[dice]] is replaced with the two-part link [[dire|dice]].
Another example: given the source phrase [[chi semina vento raccoglie tempesta]] "sow the wind, reap the whirlwind"
(literally (he) who sows wind gathers [the] tempest"). The result of calling add_links_to_multiword_term() is
[[chi]] [[semina]] [[vento]] [[raccoglie]] [[tempesta]], and with a modifier_spec of 'semina:~re; raccoglie:~re',
the result is [[chi]] [[seminare|semina]] [[vento]] [[raccogliere|raccoglie]] [[tempesta]]. Here we use the ~
notation to stand for the non-lemma form in the destination link.
A more complex example is [[se non hai altri moccoli puoi andare a letto al buio]], which becomes
[[se]] [[non]] [[hai]] [[altri]] [[moccoli]] [[puoi]] [[andare]] [[a]] [[letto]] [[al]] [[buio]] after calling
add_links_to_multiword_term(). With the following modifier_spec:
'hai:avere; altr[i:o]; moccol[i:o]; puoi: potere; andare a letto:~; al buio:~', the result of applying the spec is
[[se]] [[non]] [[avere|hai]] [[altro|altri]] [[moccolo|moccoli]] [[potere|puoi]] [[andare a letto]] [[al buio]].
Here, we rely on the alternative notation mentioned above for e.g. 'altr[i:o]', which is equivalent to 'altri:altro',
and link multiword subterms using e.g. 'andare a letto:~'. (The code knows how to handle multiword subexpressions
properly, and if the link text and destination are the same, only a single-part link is formed.)
]==]
function export.apply_link_modifiers(linked_term, modifier_spec, lang)
local split_modspecs = split(modifier_spec, "%s*;%s*")
for j, modspec in ipairs(split_modspecs) do
local id
if modspec:find("<") then
local rest
rest, id = modspec:match("^(.*)<id:(.-)>$")
if rest then
modspec = rest
end
end
local subterm, dest, otherlang
local begin_spec, rest, end_spec = modspec:match("^%[(.-)%]([^:]*)%[(.-)%]$")
if begin_spec then
local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec)
local end_from, end_to = canonicalize_begin_end_spec(end_spec)
subterm = begin_from .. rest .. end_from
dest = begin_to .. rest .. end_to
end
if not subterm then
rest, end_spec = modspec:match("^([^:]*)%[(.-)%]$")
if rest then
local end_from, end_to = canonicalize_begin_end_spec(end_spec)
subterm = rest .. end_from
dest = rest .. end_to
end
end
if not subterm then
begin_spec, rest = modspec:match("^%[(.-)%]([^:]*)$")
if begin_spec then
local begin_from, begin_to = canonicalize_begin_end_spec(begin_spec)
subterm = begin_from .. rest
dest = begin_to .. rest
end
end
if not subterm then
subterm, dest = modspec:match("^(.-)%s*:%s*(.*)$")
if subterm and subterm ~= "^" and subterm ~= "$" then
local langdest
-- Parse off an initial language code (e.g. 'en:Higgs', 'la:minūtia' or 'grc:σκατός'). Also handle
-- Wikipedia prefixes ('w:Abatemarco' or 'w:it:Colle Val d'Elsa').
otherlang, langdest = dest:match("^([A-Za-z0-9._-]+):([^ ].*)$")
if otherlang == "w" then
local foreign_wikipedia, foreign_term = langdest:match("^([A-Za-z0-9._-]+):([^ ].*)$")
if foreign_wikipedia then
otherlang = otherlang .. ":" .. foreign_wikipedia
langdest = foreign_term
end
dest = ("%s:%s"):format(otherlang, langdest)
otherlang = nil
elseif otherlang then
otherlang = get_lang_by_code(otherlang, true, "allow etym")
dest = langdest
end
end
end
if not subterm then
if modspec == "?" or modspec == "!" then
subterm = "$"
dest = modspec
elseif modspec == "..." or modspec == "...?" then
subterm = "$"
dest = " " .. modspec
elseif modspec:find("^[A-Z]$") then
-- X, Y, etc. by themselves are unlinked, to help with snowclones
subterm = modspec
dest = "_"
else
subterm = modspec
dest = "~"
end
end
if subterm == "^" then
linked_term = dest:gsub("_", " ") .. linked_term
elseif subterm == "$" then
linked_term = linked_term .. dest:gsub("_", " ")
else
if subterm:find("[", nil, true) then
error(("Subterm '%s' in modifier spec '%s' cannot have brackets in it"):format(
escape_wikicode(subterm), escape_wikicode(modspec)))
end
local escaped_subterm = pattern_escape(subterm)
local subterm_re = "%[%[" .. escaped_subterm:gsub("(%%?[ ',%-])", "%%]*%1%%[*") .. "%]%]"
local expanded_dest
if dest:find("~", nil, true) then
expanded_dest = dest:gsub("~", replacement_escape(subterm))
else
expanded_dest = dest
end
if otherlang then
expanded_dest = expanded_dest .. "#" .. otherlang:getCanonicalName()
end
local subterm_replacement
if expanded_dest == "_" then
subterm_replacement = subterm
if id then
error("Can't supply <id:...> with an unlinked subterm")
end
if otherlang then
error("Can't supply prefixed language with an unlinked subterm")
end
elseif id or otherlang then
if id and expanded_dest:find("[", nil, true) then
error("Can't supply <id:...> with destination with embedded brackets")
end
subterm_replacement = require(links_module).language_link {
lang = otherlang or lang,
term = expanded_dest,
alt = subterm,
id = id,
}
elseif expanded_dest:find("[", nil, true) then
-- Use the destination directly if it has brackets in it (e.g. to put brackets around parts of a word).
subterm_replacement = expanded_dest
elseif expanded_dest == subterm then
subterm_replacement = "[[" .. subterm .. "]]"
else
subterm_replacement = "[[" .. expanded_dest .. "|" .. subterm .. "]]"
end
local escaped_subterm_replacement = replacement_escape(subterm_replacement)
local replaced_linked_term = ugsub(linked_term, subterm_re, escaped_subterm_replacement)
if replaced_linked_term == linked_term then
mw.log(("Attempted to replace %s with %s in %s"):format(subterm_re, escaped_subterm_replacement, linked_term))
error(("Subterm '%s' could not be located in %slinked expression %s, or replacement same as subterm"):format(
subterm, j > 1 and "intermediate " or "", escape_wikicode(linked_term)))
else
linked_term = replaced_linked_term
end
end
end
return linked_term
end
function export.format_validation_error_list(data)
local valid_list, valid_set, canonicalize = data.valid_list, data.valid_set, data.canonicalize
if not valid_list then
valid_list = {}
for valid_item, value in pairs(valid_set) do
if canonicalize then
if valid_item == value then
insert(valid_list, valid_item)
else
insert(valid_list, ("%s (mapped to %s)"):format(valid_item, value))
end
else
insert(valid_list, valid_item)
end
end
table.sort(valid_list)
end
return mw.text.listToText(valid_list, nil, " or ")
end
function export.validation_error(data)
local item_type, item, valid_list, valid_set, canonicalize =
data.item_type, data.item, data.valid_list, data.valid_set, data.canonicalize
if not valid_list then
valid_list = {}
for valid_item, value in pairs(valid_set) do
if canonicalize then
if valid_item == value then
insert(valid_list, valid_item)
else
insert(valid_list, ("%s (mapped to %s)"):format(valid_item, value))
end
else
insert(valid_list, valid_item)
end
end
table.sort(valid_list)
end
error(("Invalid %s: %s; expected one of %s"):format(item_type, item,
export.format_validation_error_list {
valid_list = valid_list,
valid_set = valid_set,
canonicalize = canonicalize,
}
))
end
--[=[
Validate the items in `items` against the list or set of valid items in `valid_items`. If `field` is given, fetch the
item to check from that-named field of each object in `items`; otherwise use the items in `items` directly. If an error
occurs, `item_type` specifies the type of item to mention in the error message, which will also list the allowed items
(either taken directly from `valid_items` if a list, or from the sorted keys if a set).
If `canonicalize`, `valid_items` must be a set mapping items to their canonical equivalents, and the items in `items`
will be canonicalized accordingly and returned.
]=]
local function validate_items(data, canonicalize)
local items, field, valid_items, item_type =
data.items, data.field, data.valid_items, data.item_type
local valid_list, valid_set
if not canonicalize and valid_items[1] and is_array(valid_items) then
valid_list = valid_items
valid_set = list_to_set(valid_items)
else
valid_set = valid_items
end
for _, item in ipairs(items) do
if field then
item = item[field]
end
if not item._is_mode and not valid_set[item] then
export.validation_error {
item_type = item_type,
item = item,
valid_list = valid_list,
valid_set = not valid_list and valid_set or nil,
canonicalize = canonicalize,
}
end
end
end
function export.validate_genders(data)
local genders, valid_genders, gender_type, no_augment, canonicalize =
data.genders, data.valid_genders, data.gender_type, data.no_augment, data.canonicalize
if not genders then
return genders
end
gender_type = gender_type or "headword"
local valid_gender_set
if not data.canonicalize and valid_genders[1] and is_array(valid_genders) then
valid_gender_set = list_to_set(valid_genders)
else
valid_gender_set = valid_genders
end
local augmented_gender_set
if no_augment then
augmented_gender_set = valid_gender_set
else
augmented_gender_set = {}
for g, gval in pairs(valid_gender_set) do
augmented_gender_set[g] = gval
if g:find("^m") and not g:find("^mf") and valid_gender_set[g:gsub("^m", "f")] then
augmented_gender_set[g:gsub("^m", "mf")] = type(gval) == "string" and (gval:gsub("^m", "mf")) or gval
augmented_gender_set[g:gsub("^m", "mfbysense")] = type(gval) == "string" and (gval:gsub("^m", "mfbysense")) or gval
augmented_gender_set[g:gsub("^m", "mfequiv")] = type(gval) == "string" and (gval:gsub("^m", "mfequiv")) or gval
end
end
end
return validate_items {
items = genders,
field = "spec",
valid_items = augmented_gender_set,
item_type = ("%s gender"):format(gender_type),
canonicalize = canonicalize,
}
end
function export.has_plural_gender(genders)
local saw_p, saw_non_p
for _, val in ipairs(genders) do
local g = val.spec
if g:find("p$") then
saw_p = true
elseif g ~= "?" then
saw_non_p = true
end
end
return saw_p, saw_non_p
end
function export.is_plurale_tantum(genders)
local saw_p, saw_non_p = export.has_plural_gender(genders)
return saw_p and not saw_non_p
end
local Headdata = {}
function Headdata:resolve_prop(prop, ...)
if type(prop) == "function" then
prop = prop(self, ...)
end
return prop
end
function Headdata:get_pos_variants()
if self.process_props.pos_variants == nil then
self.process_props.pos_variants = export.get_pos_variants(self.pos_category)
end
return self.process_props.pos_variants
end
--[==[
Canonicalize a category. The category string will have the full language name (i.e. the name of the L2 language under
which an entry is inserted, which may a parent language if the language in question is an etymology-only language)
prepended to it, and any occurrences of `{plpos}` in the string replaced with the actual plural part of speech (with
some canonicalization; specifically, `proper nouns` is converted to `nouns` when replacing `{plpos}`). To specify a
full category and not have the language name prepended to it, precede it with {"Category:"}, which will be removed.
]==]
function Headdata:canonicalize_category(category)
if category:find("{") then
category = require(string_utilities_module).format(category, self:get_pos_variants())
end
if category:find("^Category:") then
return (category:gsub("^Category:", ""))
else
return self.langfullname .. " " .. category
end
end
--[==[
Canonicalize a list of categories according to the process described in `Headdata:canonicalize_category`. This simply
loops over each category in `categories` and calls `Headdata:canonicalize_category` on each one.
]==]
function Headdata:canonicalize_categories(categories)
if not categories then
return categories
end
categories = export.canonicalize_category_list(categories)
local canon_cats = {}
for _, cat in ipairs(categories) do
insert(canon_cats, self:canonicalize_category(cat))
end
return canon_cats
end
--[==[
Insert a category into the `categories` list in the headword `data` structure. `category` is normally a string naming
the category, which will have the full language name prepended to it and any occurrences of `{plpos}` in the string
replaced with the actual plural part of speech (with some canonicalization; specifically, `proper nouns` is converted to
`nouns` when replacing `{plpos}`). To specify a full category and not have the language name prepended to it, precede it
with {"Category:"}.
]==]
function Headdata:insert_category(category)
insert(self.categories, self:canonicalize_category(category))
end
--[==[
Validate the genders in `genders` (a list of gender spec objects, as produced by {type = "genders"} in
[[Module:parameters]] and accepted by [[Module:gender and number]]), checking that all specified genders are in the list
or set given in `valid_genders`. Optional `props` controls how the validation happens. In particular, unless
`props.no_augment` is given, then for any gender beginning with `m`, if a corresponding gender beginning with `f`
occurs, analogous genders beginning with `mf`, `mfbysense` and `mfequiv` are also allowed. For example, if `m-d`
(masculine dual) and `f-d` (feminine dual) both occur, genders `mf-d`, `mfbysense-d` and `mfequiv-d` are also allowed.
If a disallowed gender is given, an error occurs, giving the disallowed gender along with the list of all allowed
genders.
]==]
function Headdata:validate_genders(genders, valid_genders, props)
-- FIXME: This has no dependency on self. Uses should be converted to call export.validate_genders() directly.
if not genders then
return
end
props = props or {}
local gender_type, no_augment = props.gender_type, props.no_augment
export.validate_genders {
genders = genders,
valid_genders = valid_genders,
gender_type = gender_type,
no_augment = no_augment,
}
end
--[==[
Parse an inflection specified in `field`, the name of a parameter holding an inflection. If the parameter is numeric,
the field should be given as a number (as with the `params` structure passed to [[Module:parameters]]), not a string
containing the representation of a number. The field can specify multiple comma-separated terms, and each term can have
associated inline modifiers that will be parsed (unless there is top-level HTML in the parameter, i.e. HTML not
contained inside an inline modifier, e.g. as may be generated by using {{tl|l}} or similar template inside a parameter).
This is a wrapper around the top-level `parse_term_with_modifiers()` function. `props` is an optional structure
containing additional properties, including all additional properties documented for the top-level
`parse_term_with_modifiers()` function.
If the parameter in `field` is unspecified, the return value of this function will be an empty list, not {nil}, so it
is always safe to iterate over the return value.
By default, the allowed modifiers are the same as for `parse_term_with_modifiers()`, except that (normally) the
`<tr:...>` modifier will be allowed if `include_tr` was specified in the original call to `process_headword()`; likewise
for the `<ts:...>` modifier if `include_ts` was specified and the `<sc:...>` modifier if `include_sc` was specified. If
If you pass in your own `include_mods` list of additional allowed modifiers, it will (normally) automatically be
augmented with {"tr"}, {"ts"} and/or {"sc"} if `include_tr`, `include_ts` and/or `include_sc` was specified when calling
`process_headword()`. To disable automatic augmentation of these modifiers (whether or not you specify an `include_mods`
property), specify {no_augment_include_mods = true} in `props`.
]==]
function Headdata:parse_inflection(field, props)
local val = self.process_props.args[field]
if not val then
return {}
end
props = props and shallow_copy(props) or {}
local include_mods = props.include_mods
local calldata = self.process_props.calldata
if not props.no_augment_include_mods and (calldata.include_tr or calldata.include_ts or calldata.include_sc) then
include_mods = include_mods and shallow_copy(include_mods) or {}
if calldata.include_tr then
insert_if_not(include_mods, "tr")
end
if calldata.include_ts then
insert_if_not(include_mods, "ts")
end
if calldata.include_sc then
insert_if_not(include_mods, "sc")
end
end
props.val = val
props.paramname = field
props.splitchar = props.splitchar or ","
props.include_mods = include_mods
local orig_frob = props.frob
local function convert_tilde_to_pagename(term)
if orig_frob then
term = orig_frob(term)
end
if not term:find("~", nil, true) then
return term
end
term = term:gsub("\\~", "\1"):gsub("~", replacement_escape(self.pagename)):gsub("\1", "~")
return term
end
props.frob = convert_tilde_to_pagename
return export.parse_term_with_modifiers(props) or {}
end
function Headdata:process_for_insertion(terms, props)
props = props and shallow_copy(props) or {}
props.headdata = self
props.terms = terms
return export.process_for_insertion(props)
end
--[==[
Insert previously-parsed terms into the `inflections` of the headword `data` structure. This is a wrapper around
the top-level `insert_inflection()` function. `terms` is the list of parsed terms. (If {nil}, nothing happens unless
`request` is set in `props`.) `label` is the the label that the inflections are given; any parts of the label surrounded
in `<<...>>` are linked to the glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.)
`props` is an optional structure containing additional properties, including all additional properties documented for
the top-level `insert_inflection()` function.
Unless `no_auto_cats` is given in `props`, certain labels automatically trigger the insertion of additional
categories in specific circumstances. This is controlled by the `inflection_to_cats_and_label` structure in
[[Module:headword utilities]]. For example, if the part of speech is {"nouns"} or {"proper nouns"} and the label (after
removing any links and `<<...>>` glossary specs) is {"plural"}, an additional category
<code><var>lang</var> countable nouns</code> will be added if a plural value is given (i.e. the value is not {"-"}). If
the value is {"-"} (which indicates that there is no plural and triggers the insertion of the fixed inflection label
{"no plural"}), <code><var>lang</var> uncountable nouns</code> will be inserted instead, and if both {"-"} and a value
are given (which triggers the insertion of the {"usually no plural"} fixed inflection label), both categories are added.
Similar categories are inserted when a comparative is given (with a label {"comparative"}), and if the label is
{"female equivalent"} or {"male equivalent"} and the value is not {"-"}, a category such as
<code><var>lang</var> nouns with other-gender equivalents</code> is inserted.
]==]
function Headdata:insert_processed_inflection(processed, label, props)
props = props and shallow_copy(props) or {}
if not props.no_auto_cats then
local bare_label = props.label_for_cats_and_modes or label
if bare_label:find("[[", nil, true) then
bare_label = require(links_module).remove_links(bare_label)
end
if bare_label:find("<<", nil, true) then
bare_label = bare_label:gsub("<<.-|(.-)>>", "%1"):gsub("<<(.-)>>", "%1")
end
local spec = inflection_to_cats_and_label[bare_label]
if spec and (not spec.filter_pos or spec.filter_pos(self:get_pos_variants())) then
-- Copy the properties other than filter_pos into `props`, but don't overwrite any existing values.
for specprop, specval in pairs(spec) do
if specprop ~= "filter_pos" and props[specprop] == nil then
props[specprop] = specval
end
end
end
end
-- Now resolve and canonicalize the properties.
local canon_props = {}
for prop, val in pairs(props) do
if prop ~= "no_auto_cats" and (prop == "cats" or prop:find("_cats$")) then
val = self:canonicalize_categories(self:resolve_prop(val))
elseif prop:find("_label$") then
val = self:resolve_prop(val)
end
canon_props[prop] = val
end
canon_props.headdata = self
canon_props.processed = processed
canon_props.label = label
export.insert_processed_inflection(canon_props)
return processed
end
--[==[
Insert previously-parsed terms into the `inflections` of the headword `data` structure. This is a wrapper around
the top-level `insert_inflection()` function. `terms` is the list of parsed terms. (If {nil}, nothing happens unless
`request` is set in `props`.) `label` is the the label that the inflections are given; any parts of the label surrounded
in `<<...>>` are linked to the glossary. (If the contents of `<<...>>` contain a `|` in them, they are a two-part link.)
`props` is an optional structure containing additional properties, including all additional properties documented for
the top-level `insert_inflection()` function.
Unless `no_auto_cats` is given in `props`, certain labels automatically trigger the insertion of additional
categories in specific circumstances. This is controlled by the `inflection_to_cats_and_label` structure in
[[Module:headword utilities]]. For example, if the part of speech is {"nouns"} or {"proper nouns"} and the label (after
removing any links and `<<...>>` glossary specs) is {"plural"}, an additional category
<code><var>lang</var> countable nouns</code> will be added if a plural value is given (i.e. the value is not {"-"}). If
the value is {"-"} (which indicates that there is no plural and triggers the insertion of the fixed inflection label
{"no plural"}), <code><var>lang</var> uncountable nouns</code> will be inserted instead, and if both {"-"} and a value
are given (which triggers the insertion of the {"usually no plural"} fixed inflection label), both categories are added.
Similar categories are inserted when a comparative is given (with a label {"comparative"}), and if the label is
{"female equivalent"} or {"male equivalent"} and the value is not {"-"}, a category such as
<code><var>lang</var> nouns with other-gender equivalents</code> is inserted.
]==]
function Headdata:insert_inflection(terms, label, props)
local processed = self:process_for_insertion(terms, props)
self:insert_processed_inflection(processed, label, props)
return processed
end
--[==[
Insert a "fixed" inflection (a label without associated values) into the `inflections` table of the headword `data`
structure, labeled according to `label` (which can have glossary links in it specified using `<<...>>`, exactly as for
`:insert_inflection()`). An example label (from {{tl|mn-noun}} in [[Module:mn-headword]]) is {"hidden-g declension"},
specifying that the noun belongs to the hidden-''g'' declension. This is a direct wrapper around the top-level function
`insert_fixed_inflection()`; see that function for more details on optional `props`.
]==]
function Headdata:insert_fixed_inflection(label, props)
props = props and shallow_copy(props) or {}
props.headdata = self
props.label = label
export.insert_fixed_inflection(props)
end
--[==[
Parse the inflection(s) specified in `field` and insert them into the `inflections` table of the headword `data`
structure, labeled according to `label`. This is equivalent to calling {terms = data:parse_inflection(field, props)}
followed by {return data:insert_inflection(terms, label, props)} and behaves the same as the combination of those two
functions. See their documentation for more details.
]==]
function Headdata:parse_and_insert_inflection(field, label, props)
local terms = self:parse_inflection(field, props)
return self:insert_inflection(terms, label, props)
end
--[==[
Generate an inflection that may be specified explicitly or defaulted (which involves looping over the specified or
defaulted heads and determining the script of each one, since the formation of the default depends on the script).
`data` is the data object passed into the POS handler. `terms` is the list of terms to process. Those where the term
itself is not `+` will be returned unchanged, while those where the term is `+` will be handled by generating the
appropriate inflections from the headwords using `make_inflection` (which is passed three arguments, `head`, `tr` and
`sccode`, i.e. the script code of `head`) and should return two values, term and translit, either of which can be
nil. A nil head will be ignored, and otherwise the decorations specified on the `+` term will be combined with the
decorations specified on the head. The return value is a list of inflections where no requests for the default
inflection remain.
]==]
function Headdata:resolve_special(terms, handle_special, props)
props = props or {}
local infls = {}
local is_special = props.is_special or function(_data, infl) return infl.term == "+" end
for _, termobj in ipairs(terms) do
local is_special_retval
if type(is_special) == "function" then
is_special_retval = is_special(self, termobj)
elseif type(is_special) == "table" then
is_special_retval = contains(is_special, termobj.term)
else
error(("Internal error: When checking whether term is special, is_special is neither a function nor a " ..
"list, but is %s; term is %s"):format(dump(is_special), dump(termobj)))
end
if not is_special_retval then
insert(infls, termobj)
else
for _, headobj in ipairs(self.heads) do
local head = headobj.term or self.pagename
local head_no_links
if props.with_links then
head = head:find("%[") and head or require(headword_module).add_multiword_links(head, not headobj.term)
head_no_links = require(links_module).remove_links(head)
else
head = require(links_module).remove_links(head)
head_no_links = head
end
local newterms = handle_special {
headdata = self,
head = head,
head_no_links = head_no_links,
tr = headobj.tr,
infl = termobj,
sc = self.lang:findBestScript(head_no_links),
}
if newterms then
newterms = export.canonicalize_termobj_list(newterms, "term", "resolve_special", termobj)
for _, newterm in ipairs(newterms) do
if not props.no_combine_handle_special_retval_with_origin then
export.combine_termobj_decorations(newterm, termobj)
end
if not props.no_combine_handle_special_retval_with_head then
export.combine_termobj_decorations(newterm, headobj)
end
insert(infls, newterm)
end
end
end
end
end
return infls
end
--[==[
Add the current page to a tracking page named `Wiktionary:Tracking/``lang``-headword/``page```, where ``lang`` is the
language code of the current language. For example, if the current language is `mak` and `page` is {"redundant-lon"},
the current page will get added to the tracking page `Wiktionary:Tracking/mak-headword/redundant-lon`. All pages added
to that tracking page can be seen by going to [[Special:WhatLinksHere/Wiktionary:Tracking/mak-headword/redundant-lon]].
This is typically used to track issues occurring in user-specified parameters that do not rise to the level of errors
(e.g. redundant parameters, deprecated usages or other dispreferred values).
]==]
function Headdata:track(page)
return require(debug_track_module)(self.langcode .. "-headword/" .. page)
end
local boolean_param = {type = "boolean"}
--[==[
Process an arbitrary headword in an arbitrary language, handling generic and language-specific arguments and calling
`full_headword()` in [[Module:headword]]. This is intended for use in implementing headword modules (e.g.
[[Module:uz-headword]] for Uzbek, [[Module:mn-headword]] for Uzbek, [[Module:gsw-headword]] for Alemannic German, etc.)
and provides a general implementation of such modules. On input, `data` is an object with the following fields:
* `lang`: The language object of the language being handled. '''Required.''' Use the special value {false} to indicate
that the language is specified by the user in {{para|1}}.
* `frame`: The frame object passed into the `show()` function of your module, which implements headword-handling for
all parts of speech in the module, including a generic POS-handling template (e.g. {{tl|uz-head}} or {{tl|mn-head}}),
which allows arbitrary parts of speech to be handled. '''Required.'''
* `pos_functions`: A table listing, for each part of speech requiring special handling, the extra parameters (if any)
that the part of speech accepts, along with how to handle them. See the examples below. '''Required.'''
* `validate_lang`: If {lang = true} is specified, this is a function of one argument (a language object, based on the
language specified in {{para|1}}) that should throw an error if the language object is disallowed. If omitted, all
languages are allowed.
* `numbered_head`: If true, explicit headwords are specified in a numbered param instead of in {{para|head}}. The param
used is usually {{para|1}}, but is {{para|2}} for generic POS templates such as {{tl|mn-head}} or for POS-specific
templates when {lang = true} is specified (e.g. {{tl|arb-noun}}), and is {{para|3}} for generic POS templates when
{lang = true} is spcified (e.g. {{tl|arb-head}}).
* `include_tr`: If true, allow explicit transliterations to be specified. The transliteration(s) for the headword(s)
themselves is/are specified in {{para|tr}} or through the {{cd|<tr:...>}} inline modifier on headwords, and
transliterations of inflections are specified through the {{cd|<tr:...>}} inline modifier. This should generally be
given when a headword for the language may be in a script other than Latin.
* `include_ts`: If true, allow explicit transcriptions to be specified. The transcription(s) for the headword(s)
themselves is/are specified in {{para|ts}} or through the {{cd|<ts:...>}} inline modifier on headwords, and
transcriptions of inflections are specified through the {{cd|<ts:...>}} inline modifier. This should generally only
be given for certain languages where the spelling is radically different from the pronunciation (e.g. in cuneiform
languages such as Hittite and Akkadian, and potentially in Tibetan), and represents a pronunciation-based rendering
(usually not direct IPA).
* `include_sc`: If true, allow an explicit script code to be specified. The overall script code for the headword(s)
themselves can be specified using {{para|sc}}, and per-headword or per-inflection script codes are specified using the
{{cd|<sc:...>}} inline modifier. This should generally be given when a language supports multiple scripts.
* `infls`: An inflections structure specifying extra generic parameters that apply to all parts of speech and how to
handle them. The format is the same as for the `infls` structure in `pos_functions`.
* `augment_params`: A callback function to add extra generic parameters, or modify existing generic parameters in the
`params` structure; but in general, extra generic parameters should be added through the `infls` structure instead.
This callback should not be used to add part-of-speech-specific parameters; those are handled through the appropriate
setting in `pos_functions`. It is passed two single arguments, the `headdata` object and the `params` table to be
augmented. See below for extra fields stored in the `process_props` structure of the `headdata` object. This function
is called after initializing the `params` table and processing the overall `infls` structure, but just before adding
part-of-speech-specific parameters (from `pos_functions`) to `params`. Thus, it can override any generic parameters
but may itself be overridden by a part-of-speech-specific parameter.
* `augment_headdata`: A callback function to modify the `headdata` object passed to `full_headword()` in
[[Module:headword]]. This should not be used to for part-of-speech-specific parameter handling; this is handled
through the appropriate setting in `pos_functions`. It is passed a single argument, the `headdata` object, as for
`augment_params`; but the `process_props` structure and other fields will be more filled out, as this callback is
called later. This can be used, for example, to override the value of a generic setting in `headdata` (e.g.
[[Module:uz-headword]] uses this to mark non-Latin terms as variant forms by setting `headdata.var`, being careful not
to override a value already set by the user). This function is called after initializing the `headdata` table with all
information taken from generic parameters and processing generic parameters specified in the overall `infls`
structure, and just before processing the appropriate part-of-speech-specific `infls` structure in `pos_functions`
(which in turn is followed by any handler function in `pos_functions`). Thus, it can override any value set during
generic parameter processing but may itself be overridden by a part-of-speech-specific parameter or handler.
* `force_cat`: If true, add the headword to the appropriate categories even on non-mainspace pages. This can be used for
testing category handling in sample template calls on userspace test pages or template documentation pages. It should
not be set in production code.
* `enable_auto_translit`: If true, turn on automatic transliteration of inflections at a global level (i.e. applying to
all inflections). This has no effect on headwords, which are automatically transliterated by default if in a non-Latin
script and automatic transliteration is available for the language. You can also set this value for particular
inflections in the `insert_inflection()` function.
The `headdata` headword data structure has an extra field in it called `process_props` that is specific to the
`process_headword()` function, containing various extra properies. As the operation of `process_headword()` proceeds,
this object gets filled out with more fields. For example, once parameter parsing happens, the resulting values are
available in the `args` field of `process_props`. The following fields are found in `process_props` (note that
`pos_category`, the canonicalized plural part of speech of the headword being processed, is *not* present here; it's
directly on `headdata`):
* `namespace`: The name of the current namespace; an empty string for the mainspace. This references the namespace of
the actual page and isn't affected by the {{para|pagename}} parameter.
* `indexing_pos`: The canonicalized part of speech of the headword used to index into `pos_functions`. This is the
same as `poscat` for specific part-of-speech templates such as {{tl|uz-noun}}, but has the value {"head"} for generic
part-of-speech templates such as {{tl|uz-head}}. (Note that `poscat` is directly available on `headdata`.)
* `generic_pos_template`: True if a generic POS templates like {{tl|uz-head}} or {{tl|mn-head}} was used. (This is
signaled by omitting the invocation parameter {{para|1}} to `process_headword`.)
* `lang_in_1`: True if the language code is to be fetched from {{para|1}}.
* `pos_param`: The parameter holding the part of speech, if a generic POS tempalte like {{tl|mn-head}} is being
processed (i.e. `generic_pos_template` is set). In such a case, it will have the value of {1} or {2}, depending on
whether the language code is being fetched from {{para|1}} (see `lang_in_1`). Otherwise it will be {nil}.
* `head_param`: The parameter holding the explicit headword. If `numbered_head` was specified (as for Mongolian headword
templates), this has the value {1}, {2} or {3} depending on whether the language code is being fetched from {{para|1}}
(see `lang_in_1`) and whether a generic POS template like {{tl|mn-head}} is being processed (see
`generic_pos_template`). Otherwise, it has the value {"head"}. Also see the `lang` and `numbered_head` properties in
the `data` structure sent to `process_headword()`.
* `is_suffix`: True if the current term is a suffix. This is set when processing the `suffix`, `nosuffix` and `clitic`
parameters; it is always {false} beforehand (i.e. during `augment_params` and processing of the general `infls`
structure).
* `insert_specs`: This is a table mapping parameter names to the return value of `Headdata:insert_inflection()`, filled
out as parameter values are processed. This lets a given parameter processing function in `infls` gain access to the
result of calling `insert_inflection()` on previous parameters (which indicates the number of items inserted as well
as whether `-` was specified).
The `pos_functions` table contains an entry for each part of speech needing special handling, where the key is the
canonical plural part of speech (e.g. {"adverbs"} or {"proper nouns"}). The value associated with each key is a table
normally containing a field `infls`, listing the extra part-of-speech-specific inflection and other parameters along
with how to handle them. The specs in `infls` are used in three ways:
# to augment the `params` object passed to the `process()` function in [[Module:parameters]], specifying how to parse
the appropriate inflectional parameters;
# to specify how to process any inflectional parameters given and insert them into the `headdata` object passed to
`full_headword()` in [[Module:headword]];
# to generate appropriate documentation for the parameters and other changes made by the headword template (e.g.
inserting categories).
Alternatively, you can separately control the augmentation of the `params` object and the procesing of the resulting
arguments. This is done by specifying two fields in place of `infls`, named `params` and `func`. `params` is a table
containing extra parameters to add to the overall `params` object passed to the `process()` function in
[[Module:parameters]]. `func` is a function of two arguments, normally called `data` (the headword data structure
`headdata`) and `args` (the processed arguments table). However, this alternative method is not normally recommended
because it leads to duplication between the `params and `func` fields and the documentation, which must be manually
specified.
A simple example, as used to handle pronouns for Turoyo, is
{
local valid_genders = {"m", "f", "m-p", "f-p", "p", "?"}
pos_functions["pronouns"] = {
infls = {
{2, type = "genders", validate = valid_genders},
{"f", label = "feminine"},
{"pl", label = "plural"},
},
}
}
The equivalent using `params` and `func` is
{
local valid_genders = {"m", "f", "m-p", "f-p", "p", "?"}
pos_functions["pronouns"] = {
params = {
[2] = {type = "genders"},
f = true,
pl = true,
},
func = function(data, args)
data:validate_genders(args[2], valid_genders)
data.genders = args[2]
data:parse_and_insert_inflection("f", "feminine")
data:parse_and_insert_inflection("pl", "plural")
end
}
}
Note how the version with separate `params and `func` is longer and splits information on the parameters between the
two fields. The `params` structure sets extra user-specifiable parameters {{para|2}} for genders (since the headword is
in {{para|1}}) as well a {{para|f}} and {{para|pl}}, and the `func` handler processes those parameters. Note how this is
done by calling methods on the headword `data` structure. Each such parameter can have multiple comma-separated values,
and each value can have inline modifiers attached to it to specify further properties of the value. The `infls` version
ends up making the same method calls, but does it for you instead of you having to do it yourself.
These methods are implemented through a metatable set on the headword `data` structure, which is removed before calling
`full_headword()` in [[Module:headword]]. The methods access extra information related to headword processing (such as
the `args` table) that is stored in the `process_props` field of the headword `data` strucuture. This field is also
removed prior to calling `full_headword()`.
The methods available on the headword `data` structure are as follows. Each one also has its own documentation.
* {parse_inflection(field, props)}: Parse value(s) specified in `field` (a user-specified parameter in the `args` table)
and return a list of term objects. Optional `props` specifies additional properties controlling the parsing.
* {insert_inflection(terms, label, props)}: Insert the terms in `terms` (a list of term objects as returned by
`parse_inflection()`) into the `inflections` list in the headword `data` structure, giving the inflection the label as
specified in `label`. Optional `props` specifies additional properties controlling the parsing.
* {parse_and_insert_inflection(field, label, props)}: A combination of `parse_inflection()` and `insert_inflection()`,
if no further processing of the parsed values needs to be done before insertion.
* {insert_fixed_inflection(label, props)}: Insert a "fixed" inflection (a label without associated values) into the
`inflections` table. An example (from {{tl|mn-noun}} in [[Module:mn-headword]]) is {"hidden-g declension"}, specifying
that the noun belongs to the hidden-''g'' declension.
* {resolve_special(terms, handle_special, props)}: Resolve "special" indicators as specified by the user in an inflection
parameter. A typical example is {"+"}, requesting a default value. `terms` is the list of parsed term objects and
`handle_special` is a handler function to process special indicators and convert them to their actual values.
* {validate_genders(genders, valid_genders, props)}: Validate that the user-specified genders in `genders` all belong to
the list given in `valid_genders`, throwing an error if not.
* {insert_category(category)}: Insert a category into the `categories` list in the headword `data` structure. `category`
is normally a string naming the category, which will have the language prepended to it and any occurrences of
`{plpos}` in the string replaced with the actual plural part of speech.
]==]
function export.process_headword(data)
local data_lang, frame, pos_functions, validate_lang, numbered_head, include_tr, include_ts, include_sc, force_cat,
enable_auto_translit, checkredlinks, infls, augment_params, augment_headdata =
data.lang, data.frame, data.pos_functions, data.validate_lang, data.numbered_head, data.include_tr,
data.include_ts, data.include_sc, data.force_cat, data.enable_auto_translit, data.checkredlinks, data.infls,
data.augment_params, data.augment_headdata
local iparams = {
[1] = true,
def = true,
}
if data_lang == "invocation" or data_lang == "invocation-or-user" then
iparams.lang = true
end
local iargs = require(parameters_module).process(frame.args, iparams)
local parargs = frame:getParent().args
local lang
local function generate_data_lang_error()
error("Internal error: `data.lang` must be either a language object, \"invocation\" for a " ..
"language specified in lang= in the invocation arguments, \"user\" for a language specified in 1= in " ..
"the user template call, or \"invocation-or-user\" for either; saw " .. dump(data.lang))
end
if not data_lang then
generate_data_lang_error()
end
local lang_in_1
if type(data_lang) == "string" then
if data_lang == "invocation" then
lang = iargs.lang
if not lang then
error("Internal error: lang= must be specified in the invocation arguments")
end
elseif data_lang == "invocation-or-user" or data_lang == "user" then
if data_lang == "invocation-or-user" then
lang = iargs.lang
end
if not lang then
lang = ine(parargs[1])
if not lang then
error("Language code (see [[WT:Language codes]]) must be specified in 1=")
end
lang_in_1 = true
end
else
generate_data_lang_error()
end
lang = require(languages_module).getByCode(lang, lang_in_1 and 1 or "lang", true)
elseif type(data_lang) ~= "table" or not data_lang.hasType or not data_lang:hasType("language") then
generate_data_lang_error()
else
lang = data_lang
end
local langcode = lang:getCode()
if validate_lang then
if type(validate_lang) == "function" then
validate_lang(langcode)
else
validate_items {
items = {langcode},
valid_items = validate_lang,
item_type = "language code"
}
end
end
local template_indicated_pos = iargs[1]
local generic_pos_template = not template_indicated_pos
local pos_param
if generic_pos_template then
pos_param = lang_in_1 and 2 or 1
template_indicated_pos = ine(parargs[pos_param]) or
mw.title.getCurrentTitle().fullText == ("Template:%s-head"):format(langcode) and "interjection" or
error(("Part of speech must be specified in %s="):format(pos_param))
template_indicated_pos = canonicalize_pos(template_indicated_pos)
end
local head_param = numbered_head and (generic_pos_template and lang_in_1 and 3 or
(generic_pos_template or lang_in_1) and 2 or 1) or "head"
local indexing_pos
if generic_pos_template then
indexing_pos = "head." .. template_indicated_pos
if not pos_functions[indexing_pos] then
indexing_pos = "head"
end
else
indexing_pos = template_indicated_pos
end
local namespace = mw.loadData(headword_data_module).page.namespace
-- Partly initialize headdata now for use in generic infls callbacks. Will be further initialized later after
-- processing parameters.
local headdata = {
lang = lang,
langcode = langcode,
langfullcode = lang:getFullCode(),
langname = lang:getCanonicalName(),
langfullname = lang:getFullName(),
process_props = {
namespace = namespace,
calldata = data,
-- preserve template-indicated POS in case we normalize it or change it to "suffix"
template_indicated_pos = template_indicated_pos,
indexing_pos = indexing_pos,
generic_pos_template = generic_pos_template,
lang_in_1 = lang_in_1,
pos_param = pos_param,
head_param = head_param,
is_suffix = false,
processed_specs = {},
insert_specs = {},
},
-- We may change this below to "suffix" or normalize it.
pos_category = template_indicated_pos,
categories = {},
inflections = {enable_auto_translit = enable_auto_translit},
force_cat_output = force_cat,
no_redundant_head_cat = true,
}
setmetatable(headdata, {__index = Headdata})
local function resolve_prop(...)
return headdata:resolve_prop(...)
end
local params = {
[head_param] = {template_default = iargs.def},
head2 = {replaced_by = false, instead = ("use comma-separated |%s="):format(head_param)},
id = true,
sort = true,
cat = true,
nolink = boolean_param,
nolinkhead = {type = "boolean", alias_of = "nolink"},
suffix = boolean_param,
nosuffix = boolean_param,
-- If true, this is an inflectional suffix (forming a given person/number/gender/etc. part of the inflection of
-- a given part of speech, potentially restricted to a given inflectional class). We always treat these as
-- suffixes, rather than suffix forms, even if they form non-lemma forms (e.g. modern English -s and archaic
-- -eth form the third-singular present indicative of a verb, i.e. they form a verb form, but they are not
-- themselves forms of some other suffix, which is what a suffix form is). We also display the label of
-- inflectional suffixes specially, and add an additional category 'LANG inflectional suffixes' along with
-- categories like 'LANG POS inflectional suffixes' in place of 'LANG POS suffix forms' etc.
inflsuf = boolean_param,
clitic = {type = "boolean or string"},
addlpos = true,
var = {type = "boolean or string", set = {"both"}},
abbr = true,
json = boolean_param,
pagename = true, -- for testing
}
if include_sc then
params.sc = {type = "script"}
end
if include_tr then
params.tr = true
params.tr2 = {replaced_by = false, instead = "use comma-separated |tr= or <tr:...> inline modifier on head"}
end
if include_ts then
params.ts = true
params.ts2 = {replaced_by = false, instead = "use comma-separated |ts= or <ts:...> inline modifier on head"}
end
if lang_in_1 then
params[1] = {required = true} -- required but ignored as already processed above
end
if generic_pos_template then
params[pos_param] = {required = true} -- required but ignored as already processed above
end
local function augment_params_from_infls(infls)
infls = resolve_prop(infls)
for _, infl in ipairs(infls) do
local function interr(txt)
error(("Internal error: %s (coming from infls spec %s)"):format(txt, dump(infl)))
end
local param = infl[1]
if param then
param = resolve_prop(param)
if type(param) ~= "string" and type(param) ~= "number" then
interr(("Parameter name %s must be a string or number"):format(dump(param)))
end
-- We handle defaults as well as validation ourselves.
local typ = resolve_prop(infl.type) or "string"
if typ ~= "genders" and typ ~= "boolean" and typ ~= "string" then
-- FIXME: Handle more types.
interr(('Unrecognized type %s; can only currently handle "genders", "boolean" and "string" (the default)'):format(
dump(typ)))
end
params[param] = {type = typ, required = resolve_prop(infl.required), template_default = resolve_prop(infl.template_default)}
if typ ~= "boolean" then
local allow_and_ignore_list_params = resolve_prop(infl.allow_and_ignore_list_params)
local ignore_param
if type(allow_and_ignore_list_params) == "string" then
ignore_param = allow_and_ignore_list_params
elseif type(param) == "string" then
ignore_param = param
end
if ignore_param then
local old_list_param = allow_and_ignore_list_params and true or
{replaced_by = false, instead = ("use comma-separated |%s="):format(param)}
params[ignore_param .. "2"] = old_list_param
params[ignore_param .. "3"] = old_list_param
params[ignore_param .. "4"] = old_list_param
end
end
end
end
end
if infls then
augment_params_from_infls(infls)
end
if augment_params then
augment_params(headdata, params)
end
if pos_functions[indexing_pos] then
local pos_infls = pos_functions[indexing_pos].infls
if pos_infls then
augment_params_from_infls(pos_infls)
end
local pos_params = pos_functions[indexing_pos].params
if pos_params then
for key, val in pairs(pos_params) do
params[key] = val
end
end
end
local args = require("Module:parameters").process(parargs, params)
local pagename = args.pagename or mw.loadData(headword_data_module).pagename
local sc = args.sc or lang:findBestScript(pagename)
headdata.pagename = pagename
headdata.process_props.args = args
headdata.sc = sc
headdata.id = args.id
headdata.sort = args.sort
-- No redundant script cat unless the user explicitly gave sc=
headdata.no_script_code_cat = not args.sc
headdata.var = args.var
local extra_term_mods = {}
if include_tr then
insert(extra_term_mods, "tr")
end
if include_ts then
insert(extra_term_mods, "ts")
end
if include_sc then
insert(extra_term_mods, "sc")
end
if not extra_term_mods[1] then
extra_term_mods = nil
end
local trs = args.tr and split_on_comma(args.tr) or {}
local num_trs = #trs
local tss = args.ts and split_on_comma(args.ts) or {}
local num_tss = #tss
local heads = args[head_param] and export.parse_term_with_modifiers {
val = args[head_param],
paramname = head_param,
splitchar = ",",
is_head = true,
include_mods = extra_term_mods,
} or {}
local num_heads = #heads
if num_heads > 0 and num_trs > 0 and num_heads ~= num_trs then
error(("%s head%s specified explicitly but %s translit%s; they must match; use '+' to stand for the default head (the pagename) or default automatic translit and '-' to stand for no translit"):format(
num_heads, num_heads > 1 and "s" or "", num_trs, num_trs > 1 and "s" or ""))
end
if num_heads > 0 and num_tss > 0 and num_heads ~= num_tss then
error(("%s head%s specified explicitly but %s transcription%s; they must match; use '+' to stand for the default head (the pagename) and '-' to stand for no transcription"):format(
num_heads, num_heads > 1 and "s" or "", num_tss, num_tss > 1 and "s" or ""))
end
if num_trs > 0 and num_tss > 0 and num_trs ~= num_tss then
error(("%s translit%s specified explicitly but %s transcription%s; they must match; use '+' to stand for default automatic translit and '-' to stand for no translit or transcription"):format(
num_trs, num_trs > 1 and "s" or "", num_tss, num_tss > 1 and "s" or ""))
end
-- Be careful here not to overwrite user_specified_heads if it's empty so we can later check user_specified_heads
-- to see if the user provided any heads.
local max_tr_ts = math.max(num_trs, num_tss)
if num_heads == 0 and max_tr_ts > 0 then
heads = {}
for i = 1, max_tr_ts do
heads[i] = {term = "+"}
end
end
if not heads[1] then
heads = {{term = "+"}}
end
for i, headobj in ipairs(heads) do
if headobj.tr and trs[i] then
if headobj.tr ~= trs[i] then
error(("Saw two different translits '%s' and '%s' for head #%s"):format(
headobj.tr, trs[i], i))
end
else
headobj.tr = headobj.tr or trs[i]
end
if headobj.tr == "+" then
headobj.tr = nil
end
if headobj.ts and tss[i] then
if headobj.ts ~= tss[i] then
error(("Saw two different transcriptions '%s' and '%s' for head #%s"):format(
headobj.ts, tss[i], i))
end
else
headobj.ts = headobj.ts or tss[i]
end
if headobj.ts == "-" then
headobj.ts = nil
end
if headobj.term == "+" then
headobj.term = args.nolink and pagename or nil
if headobj.term and namespace == "Reconstruction" then
headobj.term = "*" .. headobj.term
end
end
end
headdata.heads = heads
local pos_category = headdata.pos_category
-- Do this as late as possible in case the caller wants to conditionalize the primary categorizing POS on
-- arguments or even the presence or absence of explicit heads.
if pos_functions[indexing_pos] then
pos_category = resolve_prop(pos_functions[indexing_pos].pos_category) or pos_category
end
headdata.process_props.normalized_template_indicated_pos = pos_category
headdata.pos_category = pos_category
headdata.process_props.pos_variants = nil -- erase the cache
local function pagename_is_suffix()
if sc:getCode() == "Latn" then
-- shortcut Latin terms to avoid unnecessarily loading [[Module:affix]]
return pagename:find("^%-") and not pagename:find("%-$")
else
local affix_type, _, _, _ = require(affix_module).parse_term_for_affixes(pagename, lang, sc)
return affix_type == "suffix"
end
end
local clitic_label = args.clitic
if clitic_label == true then
clitic_label = "clitic"
end
if clitic_label then
headdata:insert_category("clitics")
headdata:insert_fixed_inflection(clitic_label)
elseif args.suffix or (
not args.nosuffix and pagename_is_suffix() and pos_category ~= "suffixes" and pos_category ~= "suffix forms"
) then
headdata.process_props.is_suffix = true
local pos_list_for_inflectional_suffix = {}
local pos_list_for_suffix_form = {}
local pos_list_for_forming_suffix = {}
local function handle_suffix_pos(pos, is_first)
-- Use the actual POS for the label we insert, but simplify the POS for the category. We need to separately check
-- each of them to see if they end in 'forms' because e.g. 'comparative adjectives' gets simplified to
-- 'adjective forms'.
local form_type = pos:match("^(.*) forms$")
if form_type then
if args.inflsuf then
insert(pos_list_for_inflectional_suffix, form_type)
else
insert(pos_list_for_suffix_form, form_type)
end
else
local singular_pos = --[[require(en_utilities_module).singularize(pos)]] pos
if args.inflsuf then
insert(pos_list_for_inflectional_suffix, singular_pos)
else
insert(pos_list_for_forming_suffix, singular_pos .. "-")
end
end
if args.inflsuf then
headdata:insert_category("ปัจจัยผันรูป")
end
local simplified_pos = --[[export.simplify_pos(pos, "preserve_proper_nouns", "preserve_lemma_status")]] pos
local simplified_form_type = simplified_pos:match("^รูป(.*)$")
if simplified_form_type then
if args.inflsuf then
headdata:insert_category(("ปัจจัยผันรูปคำ%s"):format(simplified_form_type))
else
headdata:insert_category(("รูปปัจจัยคำ%s"):format(simplified_form_type))
end
else
local singular_simplified_pos = --[[require(en_utilities_module).singularize(simplified_pos)]] simplified_pos
if args.inflsuf then
headdata:insert_category(("ปัจจัยผันรูปคำ%s"):format(singular_simplified_pos))
else
headdata:insert_category(("ปัจจัยสร้างคำ%s"):format(singular_simplified_pos))
end
end
local postype
if args.inflsuf then
postype = "คำหลัก"
end
if not postype then
postype = require(headword_module).pos_lemma_or_nonlemma(pos)
end
if not postype then
postype = require(headword_module).pos_lemma_or_nonlemma(simplified_pos)
end
if not postype then
error(("Unrecognized canonicalized part of speech '%s' in addlpos=, cannot determine whether lemma or non-lemma form"):format(
pos
))
end
local this_pos_category = postype == "คำหลัก" and "ปัจจัย" or "รูปปัจจัย"
if is_first then
headdata.pos_category = this_pos_category
headdata.process_props.pos_variants = nil -- erase the cache
elseif headdata.pos_category ~= this_pos_category then
local singular_normalized_this_pos_category =
--[[require(en_utilities_module).singularize(this_pos_category)]] this_pos_category
local singular_normalized_overall_pos_category =
--[[require(en_utilities_module).singularize(headdata.pos_category)]] headdata.pos_category
error(("Cannot mix suffixes and suffix forms using addlpos=; '%s' is of a %s while overall POS " ..
"'%s' is a %s; use separate POS headers for the two"):format(pos,
singular_normalized_this_pos_category, pos_category, singular_normalized_overall_pos_category))
end
end
handle_suffix_pos(pos_category, true)
if args.addlpos then
for _, addlpos in ipairs(split(args.addlpos, "%s*,%s*")) do
addlpos = canonicalize_pos(addlpos)
handle_suffix_pos(addlpos, false)
end
end
if pos_list_for_inflectional_suffix[1] then
headdata:insert_fixed_inflection(mw.text.listToText(pos_list_for_inflectional_suffix) .. " inflectional suffix")
end
if pos_list_for_suffix_form[1] then
headdata:insert_fixed_inflection(mw.text.listToText(pos_list_for_suffix_form) .. " suffix form")
end
if pos_list_for_forming_suffix[1] then
headdata:insert_fixed_inflection(mw.text.listToText(pos_list_for_forming_suffix) .. "forming suffix")
end
end
if args.cat then
for _, cat in ipairs(split_on_comma(args.cat)) do
headdata:insert_category(cat)
end
end
local function augment_headdata_from_infls(infls)
infls = resolve_prop(infls)
for _, infl in ipairs(infls) do
local function interr(txt)
error(("Internal error: %s (coming from infls spec %s)"):format(txt, dump(infl)))
end
local function process_labelobjs(labelobjs, originating_term, handle_labelobj)
if labelobjs == nil then
return
end
if type(labelobjs) ~= "string" and type(labelobjs) ~= "table" then
interr(("Wrong type '%s' for label object(s) %s, expected string or table"):format(
type(labelobjs), dump(labelobjs)
))
end
if type(labelobjs) == "string" or type(labelobjs) == "table" and not labelobjs[1] then
labelobjs = {labelobjs}
end
for _, labelobj in ipairs(labelobjs) do
local label, termobj
if type(labelobj) == "string" then
label = labelobj
termobj = originating_term
elseif type(labelobj) ~= "table" then
interr(("Wrong type '%s' for label object %s, expected string or table"):format(
type(labelobj), dump(labelobj)
))
label = labelobj.term
if type(label) ~= "string" then
interr(("Wrong type '%s' for label %s from label object %s, expected string"):format(
type(label), dump(label), dump(labelobj)
))
end
termobj = labelobj
end
handle_labelobj(label, termobj)
end
end
local param = infl[1]
if param then
local vals
-- Fetch the param and make sure it's a string or number.
param = resolve_prop(param)
if type(param) ~= "string" and type(param) ~= "number" then
interr(("Parameter name %s must be a string or number"):format(dump(param)))
end
-- Fetch the type and validate.
local typ = resolve_prop(infl.type)
if typ == nil then
typ = "string"
end
if typ ~= "genders" and typ ~= "boolean" and typ ~= "string" then
-- FIXME: Handle more types.
interr(('Unrecognized type %s; can only currently handle "genders", "boolean" and "string" (the default)'):format(
dump(typ)))
end
-- Fetch the value(s).
if typ == "genders" or typ == "boolean" then
vals = args[param]
elseif typ == "string" then
local parse_inflection_props = resolve_prop(infl.parse_inflection_props)
local include_mods = resolve_prop(infl.include_mods)
local no_augment_include_mods = resolve_prop(infl.no_augment_include_mods)
if include_mods ~= nil or no_augment_include_mods ~= nil then
if parse_inflection_props == nil then
parse_inflection_props = {}
else
parse_inflection_props = shallow_copy(parse_inflection_props)
end
if include_mods ~= nil then
parse_inflection_props.include_mods = include_mods
end
if no_augment_include_mods ~= nil then
parse_inflection_props.no_augment_include_mods = no_augment_include_mods
end
end
vals = headdata:parse_inflection(param, parse_inflection_props)
-- Convert an empty list to nil for consistent checking below.
if not vals[1] then
vals = nil
end
else
interr(("Unrecognized type '%s"):format(typ))
end
-- If value(s) nil, fetch the default.
if vals == nil and infl.default ~= nil then
local default = resolve_prop(infl.default)
if typ == "genders" then
vals = export.canonicalize_termobj_list(default, "spec", "default")
elseif typ == "boolean" then
vals = default
elseif typ == "string" then
vals = export.canonicalize_termobj_list(default, "term", "default")
else
interr(("Unrecognized type '%s"):format(typ))
end
end
-- Resolve "special" values (special signals a string values, such as requesting the default with "+").
if vals ~= nil and infl.resolve_special then
if typ ~= "string" then
interr(("Cannot specify resolve_special= for type %s"):format(dump(typ)))
end
local resolve_special_props = resolve_prop(infl.resolve_special_props, vals)
if infl.is_special ~= nil then
if resolve_special_props == nil then
resolve_special_props = {}
else
resolve_special_props = shallow_copy(resolve_special_props)
end
resolve_special_props.is_special = infl.is_special
end
vals = headdata:resolve_special(vals, infl.resolve_special, resolve_special_props)
end
-- Canonicalize the value(s).
if vals ~= nil and infl.canonicalize ~= nil then
if typ == "boolean" then
interr('Cannot specify canonicalize= when type is "boolean"')
end
local newvals = {}
local field = typ == "genders" and "spec" or "term"
for _, val in ipairs(vals) do
local newval
if val._is_mode then
newval = val
else
if type(infl.canonicalize) == "function" then
newval = infl.canonicalize(val[field])
else
newval = val[field]
newval = infl.canonicalize[newval] or newval
end
end
if val[field] ~= newval then
val = shallow_copy(val)
val[field] = newval
end
insert(newvals, val)
end
vals = newvals
end
-- Validate the value(s).
if vals ~= nil and infl.validate ~= nil then
if typ == "boolean" then
interr('Cannot specify validate= when type is "boolean"')
elseif type(infl.validate) == "function" then
infl.validate(headdata, vals)
elseif typ == "genders" then
export.validate_genders {
genders = vals,
valid_genders = infl.validate,
no_augment = resolve_prop(infl.no_augment_genders),
}
elseif typ == "string" then
validate_items {
items = vals,
field = "term",
valid_items = infl.validate,
item_type = ("values in |%s="):format(param),
}
else
interr(("Unrecognized type '%s"):format(typ))
end
end
local function run_and_check_return_value(fun, funname, ...)
local retval, intentionally_nil = fun(...)
if retval == nil and not intentionally_nil then
interr(("If you return nil from %s, you must return a second non-nil return " ..
"value to indicate that the nil return value was intentional"):format(funname))
end
return retval
end
-- Run the process_after_parse handler, if it exists.
if vals ~= nil and infl.process_after_parse ~= nil then
vals = run_and_check_return_value(infl.process_after_parse, "process_after_parse", headdata, vals)
end
-- Process strings for insertion, to handle special mode signals like -, +-, ?, etc.
local processed
if typ == "string" then
local process_for_insertion_props = resolve_prop(infl.process_for_insertion_props, vals)
processed = headdata:process_for_insertion(vals, process_for_insertion_props)
headdata.process_props.processed_specs[param] = processed
if processed.numterms > 0 and infl.process_one_term ~= nil then
local processed_terms = {}
for _, termobj in ipairs(processed.terms) do
local processed_term = run_and_check_return_value(infl.process_one_term, "process_one_term",
headdata, termobj)
if processed_term ~= nil then
-- FIXME: Should we add an origin of "process_one_term" here? (But this would erase
-- any "default" or "resolve_special" origins.)
local newterms = export.canonicalize_termobj_list(processed_term, "term", nil, nil,
termobj)
for _, newterm in ipairs(newterms) do
insert(processed_terms, newterm)
end
end
end
processed = shallow_copy(processed)
processed.terms = processed_terms
processed.numterms = #processed_terms
end
if processed.numterms > 0 and infl.process_terms ~= nil then
local process_terms_result = run_and_check_return_value(infl.process_terms, "process_terms",
processed)
process_terms_result = process_terms_result or {}
if process_terms_result[1] or not next(process_terms_result) then
processed = shallow_copy(processed)
processed.terms = process_terms_result
processed.numterms = #process_terms_result
elseif not process_terms_result.terms or not process_terms_result.numterms then
error("Return value from process_terms() should be either a list of term objects or a " ..
"`processed` structure containing such a list")
else
processed = process_terms_result
end
end
vals = processed.terms
end
local inserted_fixed_label
-- "Implement" the values. Fixed labels and cats only fire when non-falsy (i.e. we don't want to fire
-- on boolean false or empty list). We call insert_processed_inflection() always because there may be
-- a mode even when there are no values.
if vals == true or type(vals) == "table" and vals[1] then
if infl.fixed_label and infl.all_fixed_label then
interr("Cannot specify both fixed_label= and all_fixed_label=; specify one or the other")
end
local function check_fixed_label_references_val(label)
if type(label) == "table" and label[1] then
for _, lab in ipairs(label) do
if check_fixed_label_references_val(lab) then
return true
end
end
return false
end
if type(label) == "table" then
if not label.term then
interr(("Fixed label structure %s does not have a value for `.term`"):format(dump(label)))
end
label = label.term
end
if type(label) ~= "string" then
interr(("Wrong type for fixed label %s, should be string"):format(type(label)))
end
return not not label:find("{val}")
end
local fixed_label = infl.fixed_label
local all_fixed_label = infl.all_fixed_label
-- If the value being processed is boolean, there's only one value so treat a fixed_label as an
-- all_fixed_label and output only once; likewise if the caller specified a fixed_label without
-- {val} in it.
if fixed_label and (typ == "boolean" or type(fixed_label) ~= "function" and not
check_fixed_label_references_val(fixed_label)) then
all_fixed_label = fixed_label
fixed_label = nil
end
if fixed_label then
if typ == "boolean" then
interr("Boolean fixed_label values should have been converted to all_fixed_label")
end
for _, valobj in ipairs(vals) do
local labelobjs = resolve_prop(fixed_label, valobj)
process_labelobjs(labelobjs, valobj, function(label, termobj)
if label:find("{val}") then
if typ ~= "string" then
interr(('Cannot specify {val} in fixed_label %s when type is "%s"'):format(dump(label), typ))
end
label = label:gsub("{val}", replacement_escape(valobj.term))
end
headdata:insert_fixed_inflection(label, {
originating_term = termobj
})
inserted_fixed_label = true
end)
end
elseif all_fixed_label then
local labelobjs = resolve_prop(all_fixed_label, vals)
process_labelobjs(labelobjs, nil, function(label, termobj)
if label:find("{vals}") then
if typ ~= "string" then
interr(('Cannot specify {vals} in all_fixed_label %s when type is "%s"'):format(dump(label), typ))
end
local formatted_labels = {}
for _, valobj in ipairs(vals) do
insert(formatted_labels, add_decorations(valobj.term, valobj, lang))
end
label = label:gsub("{vals}", replacement_escape(serial_comma_join(formatted_labels)))
end
headdata:insert_fixed_inflection(label, termobj)
inserted_fixed_label = true
end)
end
end
-- See above; if there's a label (which can only happen when typ == "string"), always call
-- insert_processed_inflection.
local inserted_vals
if infl.label ~= nil then
if typ ~= "string" then
interr(("label=%s can only be specified for type 'string', not '%s'"):format(
dump(infl.label), typ
))
end
local label = resolve_prop(infl.label, vals)
if label ~= nil then
local insert_processed_inflection_props =
resolve_prop(infl.insert_processed_inflection_props, vals)
local function copy_to_insert_processed_inflection_props(field, val)
local fieldval = val or resolve_prop(infl[field], vals)
if fieldval ~= nil then
if insert_processed_inflection_props == nil then
insert_processed_inflection_props = {}
else
insert_processed_inflection_props =
shallow_copy(insert_processed_inflection_props)
end
insert_processed_inflection_props[field] = fieldval
end
end
copy_to_insert_processed_inflection_props("label_for_cats_and_modes")
copy_to_insert_processed_inflection_props("no_auto_cats")
copy_to_insert_processed_inflection_props("accel")
copy_to_insert_processed_inflection_props("accel_form")
copy_to_insert_processed_inflection_props("request")
if not processed then
interr("`processed` structure wasn't properly created")
end
headdata:insert_processed_inflection(processed, label, insert_processed_inflection_props)
inserted_vals = true
end
end
-- See above; only fire for cats (and gender insertion) on non-falsy values.
if vals == true or type(vals) == "table" and vals[1] then
if typ == "genders" then
headdata.genders = vals
end
local inserted_cat
if infl.cat then
if typ == "boolean" then
vals = {vals}
end
local allcats = {}
for _, valobj in ipairs(vals) do
local cats = resolve_prop(infl.cat, valobj)
if type(cats) == "string" then
cats = {cats}
end
if cats ~= nil then
for _, cat in ipairs(cats) do
if cat:find("{val}") then
cat = cat:gsub("{val}", replacement_escape(valobj.term))
end
insert_if_not(allcats, cat)
end
end
end
for _, cat in ipairs(allcats) do
headdata:insert_category(cat)
inserted_cat = true
end
end
if typ == "boolean" then
if not inserted_fixed_label and not inserted_cat then
interr(("User set boolean setting for %s= but no fixed label added and no category " ..
"inserted; if you took action in process_after_parse(), make sure to return " ..
"`nil, true`"):format(param))
end
elseif typ == "string" then
if not inserted_vals and not inserted_fixed_label and not inserted_cat then
interr(("User set value(s) %s for %s= but no inflection inserted and no fixed label " ..
"or category added"):format(dump(vals), param))
end
end
if processed then
-- FIXME, convert to use `processed_specs` field and remove this
headdata.process_props.insert_specs[param] = processed
end
end
else -- no param specified
if infl.label or infl.all_fixed_label then
interr("Cannot have label= or all_fixed_label= without specifying a param")
end
if infl.process then
infl.process(headdata)
end
if infl.fixed_label then
local labelobjs = resolve_prop(infl.fixed_label)
process_labelobjs(labelobjs, nil, function(label, termobj)
if label:find("{val}") then
interr("Cannot specify {val} in a fixed_label= value without specifying a param")
end
headdata:insert_fixed_inflection(label, {
originating_term = termobj
})
end)
end
if infl.cat then
local cats = resolve_prop(infl.cat)
if type(cats) == "string" then
cats = {cats}
end
if cats ~= nil then
for _, cat in ipairs(cats) do
if cat:find("{val}") then
interr("Cannot specify {val} in a cat= value without specifying a param")
end
headdata:insert_category(cat)
end
end
end
end
end
end
if infls then
augment_headdata_from_infls(infls)
end
if augment_headdata then
augment_headdata(headdata, args)
end
if pos_functions[indexing_pos] then
local pos_infls = pos_functions[indexing_pos].infls
if pos_infls then
augment_headdata_from_infls(pos_infls)
end
local func = pos_functions[indexing_pos].func
if func then
func(headdata, args)
end
end
headdata:parse_and_insert_inflection("abbr", "abbreviation")
headdata.checkredlinks = resolve_prop(checkredlinks)
setmetatable(headdata, nil)
headdata.process_props = nil
if args.json then
return require("Module:JSON").toJSON(headdata)
end
return require(headword_module).full_headword(headdata)
end
return export
kke0mt89ehf7myha88p00uzk58k180w
มอดูล:es-common
828
305938
5775366
1906758
2026-10-15T07:59:15Z
Octahedron80
267
5775366
Scribunto
text/plain
local export = {}
local romut_module = "Module:romance utilities"
local u = require("Module:string/char")
local rsplit = mw.text.split
local rfind = mw.ustring.find
local rmatch = mw.ustring.match
local rsubn = mw.ustring.gsub
local toNFD = mw.ustring.toNFD
local TILDE = u(0x0303) -- tilde = ̃
local DIA = u(0x0308) -- diaeresis = ̈
local CEDILLA = u(0x0327) -- cedilla = ̧
local TEMPC1 = u(0xFFF1)
local TEMPC2 = u(0xFFF2)
local TEMPV1 = u(0xFFF3)
local DIV = u(0xFFF4)
local vowel = "aeiouáéíóúý" .. TEMPV1
local V = "[" .. vowel .. "]"
local AV = "[áéíóúý]" -- accented vowel
local W = "[iyuw]" -- glide
local C = "[^" .. vowel .. ".]"
export.vowel = vowel
export.V = V
export.AV = AV
export.W = W
export.C = C
local remove_accent = {
["á"] = "a", ["é"] = "e", ["í"] = "i", ["ó"] = "o", ["ú"] = "u", ["ý"] = "y"
}
local add_accent = {
["a"] = "á", ["e"] = "é", ["i"] = "í", ["o"] = "ó", ["u"] = "ú", ["y"] = "ý"
}
export.remove_accent = remove_accent
export.add_accent = add_accent
local prepositions = {
"al? ",
"del? ",
"como ",
"con ",
"en ",
"para ",
"por ",
}
-- 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
export.rsub = rsub
-- apply rsub() repeatedly until no change
local function rsub_repeatedly(term, foo, bar)
while true do
local new_term = rsub(term, foo, bar)
if new_term == term then
return term
end
term = new_term
end
end
export.rsub_repeatedly = rsub_repeatedly
function export.decompose(text)
-- decompose everything but ç, ñ and ü
text = toNFD(text)
text = rsub(text, ".[" .. TILDE .. DIA .. CEDILLA .. "]", {
["c" .. CEDILLA] = "ç",
["C" .. CEDILLA] = "Ç",
["n" .. TILDE] = "ñ",
["N" .. TILDE] = "Ñ",
["u" .. DIA] = "ü",
["U" .. DIA] = "Ü",
})
return text
end
-- Apply vowel alternation to stem.
function export.apply_vowel_alternation(stem, alternation)
local ret, err
-- Treat final -gu, -qu as a consonant, so the previous vowel can alternate (e.g. conseguir -> consigo).
-- This means a verb in -guar can't have a u-ú alternation but I don't think there are any verbs like that.
stem = rsub(stem, "([gq])u$", "%1" .. TEMPC1)
local before_last_vowel, last_vowel, after_last_vowel = rmatch(stem, "^(.*)(" .. V .. ")(.-)$")
if alternation == "ie" then
if last_vowel == "e" or last_vowel == "i" then
-- allow i for adquirir -> adquiero, inquirir -> inquiero, etc.
ret = before_last_vowel .. "ie" .. after_last_vowel
else
err = "should have -e- or -i- as the last vowel"
end
elseif alternation == "ye" then
if last_vowel == "e" then
ret = before_last_vowel .. "ye" .. after_last_vowel
else
err = "should have -e- as the last vowel"
end
elseif alternation == "ue" then
if last_vowel == "o" or last_vowel == "u" then
-- allow u for jugar -> juego; correctly handle avergonzar -> avergüenzo
ret = (
last_vowel == "o" and before_last_vowel:find("g$") and before_last_vowel .. "üe" .. after_last_vowel or
before_last_vowel .. "ue" .. after_last_vowel
)
else
err = "should have -o- or -u- as the last vowel"
end
elseif alternation == "hue" then
if last_vowel == "o" then
ret = before_last_vowel .. "hue" .. after_last_vowel
else
err = "should have -o- as the last vowel"
end
elseif alternation == "i" then
if last_vowel == "e" then
ret = before_last_vowel .. "i" .. after_last_vowel
else
err = "should have -i- as the last vowel"
end
elseif alternation == "í" then
if last_vowel == "e" or last_vowel == "i" then
-- allow e for reír -> río, sonreír -> sonrío
ret = before_last_vowel .. "í" .. after_last_vowel
else
err = "should have -e- or -i- as the last vowel"
end
elseif alternation == "ú" then
if last_vowel == "u" then
ret = before_last_vowel .. "ú" .. after_last_vowel
else
err = "should have -u- as the last vowel"
end
else
error("Unrecognized vowel alternation '" .. alternation .. "'")
end
ret = ret and ret:gsub(TEMPC1, "u") or nil
return {ret = ret, err = err}
end
-- Syllabify a word. This implements the full syllabification algorithm, based on the corresponding code
-- in [[Module:es-pronunc]]. This is more than is needed for the purpose of this module, which doesn't
-- care so much about syllable boundaries, but won't hurt.
function export.syllabify(word)
word = DIV .. word .. DIV
-- gu/qu + front vowel; make sure we treat the u as a consonant; a following
-- i should not be treated as a consonant ([[alguien]] would become ''álguienes''
-- if pluralized)
word = rsub(word, "([gq])u([eiéí])", "%1" .. TEMPC2 .. "%2")
local vowel_to_glide = { ["i"] = TEMPC1, ["u"] = TEMPC2 }
-- i and u between vowels should behave like consonants ([[paranoia]], [[baiano]], [[abreuense]],
-- [[alauita]], [[Malaui]], etc.)
word = rsub_repeatedly(word, "(" .. V .. ")([iu])(" .. V .. ")",
function(v1, iu, v2) return v1 .. vowel_to_glide[iu] .. v2 end
)
-- y between consonants or after a consonant at the end of the word should behave like a vowel
-- ([[ankylosaurio]], [[cryptomeria]], [[brandy]], [[cherry]], etc.)
word = rsub_repeatedly(word, "(" .. C .. ")y(" .. C .. ")",
function(c1, c2) return c1 .. TEMPV1 .. c2 end
)
word = rsub_repeatedly(word, "(" .. V .. ")(" .. C .. W .. "?" .. V .. ")", "%1.%2")
word = rsub_repeatedly(word, "(" .. V .. C .. ")(" .. C .. V .. ")", "%1.%2")
word = rsub_repeatedly(word, "(" .. V .. C .. "+)(" .. C .. C .. V .. ")", "%1.%2")
word = rsub(word, "([pbcktdg])%.([lr])", ".%1%2")
word = rsub_repeatedly(word, "(" .. C .. ")%.s(" .. C .. ")", "%1s.%2")
-- Any aeo, or stressed iu, should be syllabically divided from a following aeo or stressed iu.
word = rsub_repeatedly(word, "([aeoáéíóúý])([aeoáéíóúý])", "%1.%2")
word = rsub_repeatedly(word, "([ií])([ií])", "%1.%2")
word = rsub_repeatedly(word, "([uú])([uú])", "%1.%2")
word = rsub(word, "([" .. DIV .. TEMPC1 .. TEMPC2 .. TEMPV1 .. "])", {
[DIV] = "",
[TEMPC1] = "i",
[TEMPC2] = "u",
[TEMPV1] = "y",
})
return rsplit(word, "%.")
end
-- Return the index of the (last) stressed syllable.
function export.stressed_syllable(syllables)
-- If a syllable is stressed, return it.
for i = #syllables, 1, -1 do
if rfind(syllables[i], AV) then
return i
end
end
-- Monosyllabic words are stressed on that syllable.
if #syllables == 1 then
return 1
end
local i = #syllables
-- Unaccented words ending in a vowel or a vowel + s/n are stressed on the preceding syllable.
if rfind(syllables[i], V .. "[sn]?$") then
return i - 1
end
-- Remaining words are stressed on the last syllable.
return i
end
-- Add an accent to the appropriate vowel in a syllable, if not already accented.
function export.add_accent_to_syllable(syllable)
-- Don't do anything if syllable already stressed.
if rfind(syllable, AV) then
return syllable
end
-- Prefer to accent an a/e/o in case of a diphthong or triphthong (the first one if for some reason
-- there are multiple, which should not occur with the standard syllabification algorithm);
-- otherwise, do the last i or u in case of a diphthong ui or iu.
if rfind(syllable, "[aeo]") then
return rsub(syllable, "^(.-)([aeo])", function(prev, v) return prev .. add_accent[v] end)
end
return rsub(syllable, "^(.*)([iu])", function(prev, v) return prev .. add_accent[v] end)
end
-- Remove any accent from a syllable.
function export.remove_accent_from_syllable(syllable)
return rsub(syllable, AV, remove_accent)
end
-- Return true if an accent is needed on syllable number `sylno` if that syllable were to receive the stress,
-- given the syllables of a word. The current accent may be on any syllable.
function export.accent_needed(syllables, sylno)
-- Diphthongs iu and ui are normally stressed on the second vowel, so if the accent is on the first vowel,
-- it's needed.
if rfind(syllables[sylno], "íu") or rfind(syllables[sylno], "úi") then
return true
end
-- If the default-stressed syllable is different from `sylno`, accent is needed.
local unaccented_syllables = {}
for _, syl in ipairs(syllables) do
table.insert(unaccented_syllables, export.remove_accent_from_syllable(syl))
end
local would_be_stressed_syl = export.stressed_syllable(unaccented_syllables)
if would_be_stressed_syl ~= sylno then
return true
end
-- At this point, we know that the stress would by default go on `sylno`, given the syllabification in
-- `syllables`. Now we have to check for situations where removing the accent mark would result in a
-- different syllabification. For example, países -> `pa.i.ses` but removing the accent mark would lead
-- to `pai.ses`. Similarly, río -> `ri.o` but removing the accent mark would lead to single-syllable `rio`.
-- We need to check whether (a) the stress falls on an i or u; (b) in the absence of an accent mark, the
-- i or u would form a diphthong with a preceding or following vowel and the stress would be on that vowel.
-- The conditions are slightly different when dealing with preceding or following vowels because ui and ui
-- diphthongs are by default stressed on the second vowel. We also have to ignore h between the vowels.
local accented_syllable = export.add_accent_to_syllable(unaccented_syllables[sylno])
if sylno > 1 and rfind(unaccented_syllables[sylno - 1], "[aeo]$") and rfind(accented_syllable, "^h?[íú]") then
return true
end
if sylno < #syllables then
if rfind(accented_syllable, "í$") and rfind(unaccented_syllables[sylno + 1], "^h?[aeou]") or
rfind(accented_syllable, "ú$") and rfind(unaccented_syllables[sylno + 1], "^h?[aeio]") then
return true
end
end
return false
end
function export.make_plural(form, gender, special)
local retval = require(romut_module).handle_multiword(form, special,
function(term) return export.make_plural(term, gender) end, prepositions)
if retval then
return retval
end
if gender == "gneut" and rfind(form, "[x@]$") then
return {form .. "s"}
end
-- ends in unstressed vowel or á, é, ó
if rfind(form, "[aeiouáéó]$") then return {form .. "s"} end
-- ends in í or ú
if rfind(form, "[íú]$") then
return {form .. "es", form .. "s"}
end
-- ends in a vowel + z
if rfind(form, V .. "z$") then
return {rsub(form, "z$", "ces")}
end
-- ends in cons + s/z
if rfind(form, C.."[sz]$") then return {form} end
-- ends in s/z + cons
if rfind(form, "[sz]"..C.."$") then return {form} end
local syllables = export.syllabify(form)
-- ends in s or x with more than 1 syllable, last syllable unstressed
if syllables[2] and rfind(form, "[sx]$") and not rfind(syllables[#syllables], AV) then
return {form}
end
-- ends in l, r, n, d, z, or j with 3 or more syllables, stressed on third to last syllable
if syllables[3] and rfind(form, "[lrndzj]$") and rfind(syllables[#syllables - 2], AV) then
return {form}
end
-- ends in an accented vowel + consonant
if rfind(form, AV .. C .. "$") then
return {rsub(form, "(.)(.)$", function(vowel, consonant)
return export.remove_accent[vowel] .. consonant .. "es"
end)}
end
-- ends in a vowel + y, l, r, n, d, j, s, x
if rfind(form, "[aeiou][ylrndjsx]$") then
-- two or more syllables: add stress mark to plural; e.g. joven -> jóvenes
if syllables[2] and rfind(form, "n$") then
syllables[#syllables - 1] = export.add_accent_to_syllable(syllables[#syllables - 1])
return {table.concat(syllables, "") .. "es"}
end
return {form .. "es"}
end
-- ends in a vowel + ch
if rfind(form, "[aeiou]ch$") then return {form .. "es"} end
-- ends in two consonants
if rfind(form, C .. C .. "$") then return {form .. "s"} end
-- ends in a vowel + consonant other than l, r, n, d, z, j, s, or x
if rfind(form, "[aeiou][^aeioulrndzjsx]$") then return {form .. "s"} end
return nil
end
function export.make_feminine(form, special)
local retval = require(romut_module).handle_multiword(form, special, export.make_feminine, prepositions)
if retval then
if #retval ~= 1 then
error("Internal error: Should have one return value for make_feminine: " .. table.concat(retval, ","))
end
return retval[1]
end
if form:find("o$") then
local retval = form:gsub("o$", "a") -- discard second retval
return retval
end
local function make_stem(form)
return rsub(
form,
"^(.+)(.)(.)$",
function (before_stress, stressed_vowel, after_stress)
return before_stress .. (export.remove_accent[stressed_vowel] or stressed_vowel) .. after_stress
end)
end
if rfind(form, "[áíó]n$") or rfind(form, "[éí]s$") or rfind(form, "[dtszxñ]or$") or rfind(form, "ol$") then
-- holgazán, comodín, bretón (not común); francés, kirguís (not mandamás);
-- volador, agricultor, defensor, avizor, flexor, señor (not posterior, bicolor, mayor, mejor, menor, peor);
-- español, mongol
return make_stem(form) .. "a"
end
return form
end
function export.make_masculine(form, special)
local retval = require(romut_module).handle_multiword(form, special, export.make_masculine, prepositions)
if retval then
if #retval ~= 1 then
error("Internal error: Should have one return value for make_masculine: " .. table.concat(retval, ","))
end
return retval[1]
end
if form:find("dora$") then
local retval = form:gsub("a$", "") -- discard second retval
return retval
end
if form:find("a$") then
local retval = form:gsub("a$", "o") -- discard second retval
return retval
end
return form
end
return export
qq46tgo6gtotmf220p5pp0dpz3e6kus
มอดูล:languages/data
828
324680
5775363
5683830
2026-10-15T07:16:35Z
Octahedron80
267
5775363
Scribunto
text/plain
local export = {}
-- We can't use mw.loadData() on [[Module:languages/chars]] because [[Module:languages/data]] itself is sometimes loaded
-- using mw.loadData(), and calling mw.loadData() on [[Module:languages/chars]] will insert metatables into the
-- character tables, which the second mw.loadData() will choke on.
local m_chars = require("Module:languages/chars")
local u = require("Module:string/char")
local c = m_chars.chars
export.chars = c
local p = m_chars.puaChars
export.puaChars = p
local cs = m_chars.chars_substitutions
export.chars_substitutions = cs
-- FIXME! Many of the script-specific values below can be moved to [[Module:scripts/data]] to serve as script-wide
-- fallback values instead of specifying them for each language using the script.
local s = {}
-- These values are placed here to make it possible to synchronise a group of languages without the need for a dedicated function module.
-- cau
do
local cau_remove_diacritics = c.grave .. c.acute .. c.macron
local cau_from = {"[IlΙІӀᴴ]"}
local cau_to = {{
["l"] = "ӏ",
["Ι"] = "ӏ",
["І"] = "ӏ",
["Ӏ"] = "ӏ",
["ᴴ"] = "ᵸ",
}}
s["cau-Cyrl-displaytext"] = {
from = cau_from,
to = cau_to,
}
s["cau-Cyrl-stripdiacritics"] = {
remove_diacritics = cau_remove_diacritics,
from = cau_from,
to = cau_to,
}
s["cau-Latn-stripdiacritics"] = {remove_diacritics = cau_remove_diacritics}
end
s["itc-Latn-displaytext"] = {
from = {c.caron},
to = {c.breve},
}
s["itc-Latn-stripdiacritics"] = {remove_diacritics = c.macron .. c.breve .. c.diaer .. c.caron .. c.dinvbreve}
s["itc-Latn-sortkey"] = {
remove_diacritics = c.circ .. c.tilde .. c.macron .. c.breve .. c.diaer .. c.caron .. c.zigzag .. c.dmacron .. c.dtilde .. c.dinvbreve .. c.small_a .. c.small_e .. c.small_i .. c.small_o .. c.small_u, -- Chiefly medieval abbreviations.
from = {"ᵃ", "æ", "[đꝱꟈ]", "ᵉ", "ⁱ", "ꝁ", "[ƚꝉꝲ]", "ꝳ", "ꝴ", "[ꝋᵒ]", "œ", "[ꝑꝓꝕ]", "[ꝗꝙ]", "[ꝛꝵꝶꝝ]", "[ꟊˢ]", "[ꝷᵗ]", "ᵘ", "ꝟ", "⁊"},
to = {"a", "ae", "d", "e", "i", "k", "l", "m", "n", "o", "oe", "p", "q", "r", "s", "t", "u", "v", "&"}
}
s["Jpan-standardchars"] = -- exclude ぢづヂヅ
"ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちっつてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろん" ..
"ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチッツテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロン"
local jpx_displaytext = {
from = {"~", "="},
to = {"〜", "゠"}
}
s["jpx-displaytext"] = {
Jpan = jpx_displaytext,
Hani = jpx_displaytext,
Hrkt = jpx_displaytext,
Hira = jpx_displaytext,
Kana = jpx_displaytext
-- not Latn or Brai
}
s["jpx-stripdiacritics"] = s["jpx-displaytext"]
s["jpx-sortkey"] = {
Jpan = "Jpan-sortkey",
Hani = "Hani-sortkey",
Hrkt = "Hira-sortkey", -- sort general kana by normalizing to Hira
Hira = "Hira-sortkey",
Kana = "Kana-sortkey",
Latn = {remove_diacritics = c.tilde .. c.macron .. c.diaer}
}
s["jpx-translit"] = {
Hrkt = "Hrkt-translit",
Hira = "Hrkt-translit",
Kana = "Hrkt-translit"
}
s["roa-oil-sortkey"] = {
remove_diacritics = c.grave .. c.acute .. c.circ .. c.tilde .. c.diaer .. c.ringabove .. c.cedilla .. "'",
from = {"æ", "œ", "·"},
to = {"ae", "oe", " "}
}
s["wen-sortkey"] = {
from = {"ch", "[lłßꞩẜ]", "dz[" .. c.caron .. c.acute .. "]", "[bcefmnoprswz][" .. c.caron .. c.acute .. c.dotabove .. "]"},
to = {
"h" .. p[1],
{
["l"] = "l" .. p[1], ["ł"] = "l", ["ß"] = "s", ["ꞩ"] = "š", ["ẜ"] = "š",
},
{
["dz" .. c.caron] = "d" .. p[1], ["dz" .. c.acute] = "d" .. p[2]
},
{
["b" .. c.acute] = "b" .. p[1],
["c" .. c.caron] = "c" .. p[1], ["c" .. c.acute] = "c" .. p[2],
["e" .. c.caron] = "e" .. p[1], ["e" .. c.dotabove] = "e" .. p[1],
["f" .. c.acute] = "f" .. p[1],
["m" .. c.acute] = "m" .. p[1],
["n" .. c.acute] = "n" .. p[1],
["o" .. c.acute] = "o" .. p[1],
["p" .. c.acute] = "p" .. p[1],
["r" .. c.caron] = "r" .. p[1], ["r" .. c.acute] = "r" .. p[2],
["s" .. c.caron] = "s" .. p[1], ["s" .. c.acute] = "s" .. p[2],
["w" .. c.acute] = "w" .. p[1],
["z" .. c.caron] = "z" .. p[1], ["z" .. c.acute] = "z" .. p[2],
}
}
}
-- Myanmar dotted form : https://www.unicode.org/Public/UNIDATA/StandardizedVariants.txt
s["aio-displaytext"] = {
from = {"([ကဂငတထပမယလဝဢေၵၸၺႀꩠꩡꩢꩣꩤꩥꩦꩫꩬꩯꩺ])"},
to = {"%1" .. c.VS01}
}
s["aio-stripdiacritics"] = {
remove_diacritics = c.VS01,
}
s["esx-displaytext"] = {
from = {"ǝ"},
to = {"ə"},
}
s["esx-stripdiacritics"] = s["esx-displaytext"]
s["phk-displaytext"] = s["aio-displaytext"]
s["phk-stripdiacritics"] = s["aio-stripdiacritics"]
s["kht-displaytext"] = s["aio-displaytext"]
s["kht-stripdiacritics"] = s["aio-stripdiacritics"]
export.shared = s
--[==[ var:
Short-term solution to override the standard substitution process, by forcing the module to substitute the entire
text in one pass, if "cont" is given. This results in any PUA characters that are used as stand-ins for formatting being
handled by the language-specific substitution process, which is usually undesirable. If the value is "none" then the
formatting tags do not get turned into PUA characters in the first place. This override is provided for languages which
use formatting between strings of text which might need to interact with each other (e.g. Korean 값이 transliterates as "gaps-i", but [[값]] has the formatting '''값'''[[-이]]. The normal process would split the text at the second '''.)
]==]
export.substitution = {
["gmy"] = "none",
["ja"] = "cont",
["jje"] = "cont",
["ket"] = "none",
["ko"] = "cont",
["ko-ear"] = "cont",
["ru"] = "cont",
["th-new"] = "cont",
["sa"] = "cont",
["zkt"] = "cont",
}
--[==[ var:
Code aliases. The left side is the alias and the right side is the canonical code. NOTE: These are gradually
being deprecated, so should not be added to on a permanent basis. Temporary additions are permitted under reasonable
circumstances (e.g. to facilitate changing a language's code). When an alias is no longer used, it should be removed.
Aliases in this table are tracked at [[Wiktionary:Tracking/languages/LANG]]; see e.g.
[[Special:WhatLinksHere/Wiktionary:Tracking/languages/VL.]] for the `VL.` alias.
]==]
export.aliases = {
["EL."] = "la-ecc",
["LL."] = "la-lat",
["ML."] = "la-med",
["NL."] = "la-new",
["VL."] = "la-vul",
["grc-epc"] = "grc-epi",
["nds-DE"] = "nds-de",
["nds-NL"] = "nds-nl",
["roa-oan"] = "roa-ona",
["sa-cls"] = "cls",
["sa-ved"] = "vsn",
}
--[==[ var:
Codes which are tracked. Note that all aliases listed above are also tracked, so should not be duplicated here.
Tracking uses the same mechanism described above in the comment above `export.aliases`.
]==]
export.track = {
-- Codes duplicated between full and etymology-only languages.
["lzh-lit"] = true,
["lzh"] = true,
-- Languages actively being converted to families.
["bh"] = true, -- inc-bih
["nan"] = true, -- zhx-nan
-- Transcription scheme being changed.
["trk-pro"] = true,
}
return export
mpdv2gw5dmhuaq7h15kvelv3q6pv46b
แม่แบบ:ar-form
10
327304
5775341
1654458
2026-10-15T04:56:54Z
Octahedron80
267
นำเข้าจาก enwikt
5775341
wikitext
text/x-wiki
{{#invoke:checkparams|warn}}<!-- Validate template parameters
-->{{#if:{{{1|}}}|[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป <!--
-->{{#switch:{{{1}}}|1=I|2=II|3=III|4=IV|5=V|6=VI|7=VII|8=VIII|9=IX|10=X|11=XI|12=XII|13=XIII|14=XIV|15=XV|1q=Iq|2q=IIq|3q=IIIq|4q=IVq|#default={{{1}}}}}<!--
-->{{!}}{{#if:{{{2|}}}|{{#switch:{{{2|}}}|-=|#default={{{2|}}} }}|{{#if:{{{nocap|}}}|f|F}}orm }}<!--
-->{{#switch:{{{1}}}|1=I|2=II|3=III|4=IV|5=V|6=VI|7=VII|8=VIII|9=IX|10=X|11=XI|12=XII|13=XIII|14=XIV|15=XV|1q=Iq|2q=IIq|3q=IIIq|4q=IVq|#default={{{1}}}}}<!--
-->]]|<span class="error">Provide a Roman numeral in the first parameter.</span>}}<noinclude>
{{documentation}}
</noinclude>
rzms7ycx8or4vhf1102r7jzzzubfprg
5775342
5775341
2026-10-15T04:58:01Z
Octahedron80
267
5775342
wikitext
text/x-wiki
{{#invoke:checkparams|warn}}<!-- Validate template parameters
-->{{#if:{{{1|}}}|[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป <!--
-->{{#switch:{{{1}}}|1=I|2=II|3=III|4=IV|5=V|6=VI|7=VII|8=VIII|9=IX|10=X|11=XI|12=XII|13=XIII|14=XIV|15=XV|1q=Iq|2q=IIq|3q=IIIq|4q=IVq|#default={{{1}}}}}<!--
-->{{!}}{{#if:{{{2|}}}|{{#switch:{{{2|}}}|-=|#default={{{2|}}} }}|{{#if:{{{nocap|}}}|รูป|รูป}} }}<!--
-->{{#switch:{{{1}}}|1=I|2=II|3=III|4=IV|5=V|6=VI|7=VII|8=VIII|9=IX|10=X|11=XI|12=XII|13=XIII|14=XIV|15=XV|1q=Iq|2q=IIq|3q=IIIq|4q=IVq|#default={{{1}}}}}<!--
-->]]|<span class="error">Provide a Roman numeral in the first parameter.</span>}}<noinclude>
{{documentation}}
</noinclude>
lu6nac41jhj2yuqhke2adul3dsag5t8
มอดูล:Mani-translit
828
428436
5775304
5775303
2026-10-14T12:47:59Z
Octahedron80
267
5775304
Scribunto
text/plain
local export = {}
local tt = {
["𐫀"] = "อ", -- aleph
["𐫁"] = "บ", -- beth
["𐫂"] = "บฺ", -- bheth
["𐫃"] = "ค", -- gimel
["𐫄"] = "ฆ", -- ghimel
["𐫅"] = "ด", -- daleth
["𐫆"] = "ฮ", -- he
["𐫇"] = "ว", -- waw
["𐫈"] = "วฺ", -- ud (conjunction)
["𐫉"] = "ซ", -- zayin
["𐫊"] = "ซฺ", -- zhayin
["𐫋"] = "จ", -- jayin
["𐫌"] = "จฺ", -- jhayin
["𐫍"] = "ฮฺ", -- heth
["𐫎"] = "ฏ", -- teth
["𐫏"] = "ย", -- yodh
["𐫐"] = "ก", -- kaph
["𐫑"] = "ข", -- xaph
["𐫒"] = "ข̱", -- khaph
["𐫓"] = "ล", -- lamedh
["𐫔"] = "ดฺ", -- dhamedh
["𐫕"] = "ตฺ", -- thamedh
["𐫖"] = "ม", -- mem
["𐫗"] = "น", -- nun
["𐫘"] = "ส", -- samekh
["𐫙"] = "อฺ", -- ayin
["𐫚"] = "อ̱", -- aayin
["𐫛"] = "พ", -- pe
["𐫜"] = "ฟ", -- fe
["𐫝"] = "ศ", -- sadhe
["𐫞"] = "กฺ", -- qoph
["𐫟"] = "ขฺ", -- xoph
["𐫠"] = "ก̱", -- qhoph
["𐫡"] = "ร", -- resh
["𐫢"] = "ช", -- shin
["𐫣"] = "ศฺ", -- sshin
["𐫤"] = "ต", -- taw
["𐫥"] = "~", -- abbreviation mark above
["𐫦"] = "~", -- abbreviation mark below
["𐫫"] = "[1]", -- one
["𐫬"] = "[5]", -- five
["𐫭"] = "[10]", -- ten
["𐫮"] = "[20]", -- twenty
["𐫯"] = "[100]", -- one hundred
}
function export.tr(text, lang, sc)
-- If the script is not Mani, do not transliterate
if sc ~= "Mani" then
return
end
-- Transliterate characters
text = mw.ustring.gsub(text, '.', tt)
return text
end
return export
2gznts50hr7vnyb2fxlw5v6p0nhq9ia
แม่แบบ:ar-rootbox
10
1714776
5775311
4733735
2026-10-15T02:16:55Z
Octahedron80
267
5775311
wikitext
text/x-wiki
{{#invoke:roots|root|lang=ar}}<noinclude>{{tcat|etym}}</noinclude>
s4t3ilfwet4fbwkl9bxl8aqbqkzxvlo
มอดูล:etymon/text
828
2297437
5775353
5754409
2026-10-15T06:39:51Z
Octahedron80
267
5775353
Scribunto
text/plain
local export = {}
local loader = require("Module:module loader")
local M = loader.init({
require = {
en_utilities = "Module:en-utilities",
references = "Module:references",
senseno = "Module:senseno",
},
loadData = {
data = "Module:etymon/data",
},
})
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local format_term_func = opts.format_term_func
local max_depth = opts.max_depth
local stop_at_blue_link = opts.stop_at_blue_link
local curr_page = opts.curr_page
local nodot = opts.nodot and opts.nodot ~= "" and opts.nodot ~= "0"
local function explicit_dot_override()
if opts.dot == nil or opts.dot == false then
return nil
end
local d = mw.text.trim(tostring(opts.dot))
if d == "" or d == "." then
return nil
end
return d
end
local dot_override = explicit_dot_override()
local function find_deepest_last_part(tree)
if not tree or not tree.container_parts or #tree.container_parts == 0 then
return nil
end
local last_part = tree.container_parts[#tree.container_parts]
if last_part.continuation then
return find_deepest_last_part(last_part.continuation)
end
return last_part
end
local function apply_final_punctuation_override(tree, punct)
if not tree or punct == nil then
return
end
local last_part = find_deepest_last_part(tree)
if last_part then
last_part.punctuation = punct
end
end
local function apply_closing_punctuation_override(tree, is_last_segment)
if not is_last_segment then
return
end
local punct
if nodot then
punct = ""
elseif dot_override ~= nil then
punct = dot_override
else
return
end
apply_final_punctuation_override(tree, punct)
end
local function has_supplements()
return data_tree.supplements and #data_tree.supplements > 0
end
local stop_at_lang = opts.stop_at_lang
local stop_at_lang_or_bluelink = opts.stop_at_lang_or_bluelink
local lang_matches_stop_code = opts.lang_matches_stop_code
local stop_lang_reached = false
local function term_matches_stop_code(term_lang, stop_code)
if lang_matches_stop_code then
return lang_matches_stop_code(term_lang, stop_code)
end
return term_lang and term_lang:getCode() == stop_code
end
local children = data_tree.children
local function has_text_supplements()
if not data_tree.supplements then
return false
end
for _, supplement in ipairs(data_tree.supplements) do
if supplement.type == "doublet" and supplement.terms and #supplement.terms > 0 then
return true
end
if supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
return true
end
end
return false
end
if (not children or #children == 0) and not has_text_supplements() then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
local entry_lang = data_tree.lang
local function lowercase_glossary_link_display(wikitext)
return wikitext:gsub("(%[%[Appendix:Glossary#[^|]+|)([^%]])([^%]]*)%]%]", function(prefix, first, rest)
return prefix .. mw.ustring.lower(first) .. rest .. "]]"
end)
end
local function format_sl_senseid_intro(senseid, keyword_text, keyword_phrase, capitalize_senseno, is_uncertain)
local senseids = mw.text.split(senseid, "!!", true)
local senseno_parts = {}
for i, id in ipairs(senseids) do
id = mw.text.trim(id)
if id ~= "" then
table.insert(senseno_parts, M.senseno.link_text(entry_lang:getCode(), { id }, {
title = curr_page,
uc = (i == 1 and capitalize_senseno) or nil,
}))
end
end
if #senseno_parts == 0 then
return keyword_text, keyword_phrase
end
local senseno_text = mw.text.listToText(senseno_parts)
local glossary_link = (keyword_text or ""):gsub(" from$", "")
local glossary_lower = lowercase_glossary_link_display(glossary_link)
if #senseno_parts > 1 then
local plural_link = glossary_lower:gsub("|semantic loan%]%]", "|semantic loans]]")
if is_uncertain then
return senseno_text .. " are possibly " .. plural_link .. " from",
senseno_text .. " are possibly semantic loans from"
end
return senseno_text .. " are " .. plural_link .. " from",
senseno_text .. " are semantic loans from"
end
if is_uncertain then
return senseno_text .. " is possibly a " .. glossary_lower .. " from",
senseno_text .. " is possibly a semantic loan from"
end
return senseno_text .. " is a " .. glossary_lower .. " from",
senseno_text .. " is a semantic loan from"
end
local function get_term_refs(term, defined_here)
if defined_here and term.refs and next(term.refs) then
return M.references.format_references(term.refs)
end
return ""
end
-- Build a text part for a single term
local function build_term_part(term, current_lang, defined_here)
local text = ""
local new_lang = current_lang
local lang_changed = term.lang:getCanonicalName() ~= current_lang:getCanonicalName()
-- Use centralized format_term (handles suppress_term, unknown_term, and regular terms)
local term_text = format_term_func(term)
if lang_changed then
new_lang = term.lang
if term_text then
text = term.lang:makeWikipediaLink() .. " " .. term_text
elseif term.is_family then
text = M.en_utilities.add_indefinite_article(term.lang:makeWikipediaLink() .. " language", false)
else
-- suppress_term with language change: show only language
text = term.lang:makeWikipediaLink()
end
else
text = term_text or ""
end
return {
type = "term",
text = text,
refs = get_term_refs(term, defined_here),
lang = new_lang,
is_uncertain = term.is_uncertain or false,
}
end
-- Build text parts for a container
local function build_container_part(container, node, depth, allow_continuation, fallback_to_bluelink)
local keyword_info = container.keyword_info
local keyword_modifiers = container.keyword_modifiers or {}
local terms = container.terms or {}
if not keyword_info or #terms == 0 then
return nil
end
-- Skip building text part when invisible in text ("all", "text", or true)
local inv = keyword_info.invisible
if inv == "all" or inv == true or inv == "text" then
return nil
end
local is_group = keyword_info.is_group
local keyword_uncertain = keyword_modifiers.unc or false
-- Determine text and phrase (allowing for overrides)
local intro_text = keyword_info.text
local phrase = keyword_info.phrase
local new_sentence = keyword_info.new_sentence or false
if keyword_modifiers.text then
-- User-provided override: assumed to be lowercase
phrase = keyword_modifiers.text
-- Auto-capitalize for intro text (e.g., "derived from" -> "Derived from")
intro_text = mw.ustring.upper(phrase:sub(1, 1)) .. phrase:sub(2)
end
local defined_here = (node.page_of or curr_page) == curr_page
-- Get keyword references
local keyword_refs = ""
if defined_here and keyword_modifiers.refs and next(keyword_modifiers.refs) then
keyword_refs = M.references.format_references(keyword_modifiers.refs)
end
-- Build term parts
local term_parts = {}
local current_lang = node.lang
for _, term in ipairs(terms) do
local term_part = build_term_part(term, current_lang, defined_here)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
current_lang = term_part.lang
end
end
-- Check uncertainty distribution
local uncertain_count = 0
for _, term_part in ipairs(term_parts) do
if term_part.is_uncertain then
uncertain_count = uncertain_count + 1
end
end
-- If keyword itself is uncertain, treat all terms as uncertain
local all_uncertain = keyword_uncertain or (uncertain_count == #term_parts and #term_parts > 0)
if is_group and uncertain_count > 0 then
all_uncertain = true
end
local has_mixed_uncertainty = not all_uncertain and uncertain_count > 0
-- Check if there are more steps (only if continuation is allowed)
local has_more_steps = false
local next_node = nil
local first_term = terms[1]
-- Check if we should stop at this language
local reached_stop_lang = false
if stop_at_lang then
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang) then
reached_stop_lang = true
stop_lang_reached = true
break
end
end
elseif stop_at_lang_or_bluelink then
-- Check if we should stop at this language, or at the first bluelink if it's a redlink
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang_or_bluelink) then
if first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
else
fallback_to_bluelink = true
end
break
end
end
if fallback_to_bluelink and first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
end
end
if allow_continuation and not is_group and #terms == 1 and not reached_stop_lang then
local first_term_children = first_term.children
if first_term_children and #first_term_children > 0 and (not max_depth or depth < max_depth) then
local next_container = first_term_children[1]
local next_keyword_info = next_container and next_container.keyword_info
if not (next_keyword_info and next_keyword_info.invisible) then
if stop_at_blue_link then
if first_term.status ~= M.data.STATUS.OK then
has_more_steps = true
next_node = first_term
end
else
has_more_steps = true
next_node = first_term
end
end
end
end
return {
type = "container",
intro_text = intro_text,
phrase = phrase,
senseid = keyword_modifiers.senseid,
sl_keyword_text = keyword_modifiers.senseid and keyword_info.text or nil,
is_uncertain = all_uncertain,
has_mixed_uncertainty = has_mixed_uncertainty,
term_parts = term_parts,
is_group = is_group,
has_more_steps = has_more_steps,
next_node = next_node,
new_sentence = new_sentence,
separate_clause = keyword_info.separate_clause or false,
conj = keyword_modifiers.conj or keyword_info.default_conj, -- custom conjunction: "and", "or", "and/or", etc.
lit = keyword_modifiers.lit,
keyword_refs = keyword_refs,
fallback_to_bluelink = fallback_to_bluelink,
}
end
-- Build the full tree of text parts
local function build_text_tree(node, depth, allow_continuation, fallback_to_bluelink)
local containers = node.children
if not containers or #containers == 0 then
return nil
end
local container_parts = {}
local function is_new_sentence(container)
return container.keyword_info and container.keyword_info.new_sentence or false
end
-- Count the containers that get a text part in the derivation's own sentence (invisible in text = "all",
-- "text", or true)
local visible_container_count = 0
for _, container in ipairs(containers) do
local keyword_info = container.keyword_info
local inv = keyword_info and keyword_info.invisible
if not (inv == "all" or inv == true or inv == "text") and not is_new_sentence(container) then
visible_container_count = visible_container_count + 1
end
end
-- If there are multiple visible containers in that sentence, don't allow continuation for any: alternatives
-- each name a different source, and an influence clause after a chain would read as influencing its last
-- step. A sentence of its own does not stop the derivation's chain.
local has_multiple_containers = visible_container_count > 1
local should_allow_continuation = allow_continuation and not has_multiple_containers
for _, container in ipairs(containers) do
local part = build_container_part(container, node, depth, should_allow_continuation and not is_new_sentence(container), fallback_to_bluelink)
if part then
-- Recursively build children if there are more steps
if part.has_more_steps and part.next_node then
part.continuation = build_text_tree(part.next_node, depth + 1, true, part.fallback_to_bluelink)
end
table.insert(container_parts, part)
end
end
if #container_parts == 0 then
return nil
end
return {
type = "tree",
container_parts = container_parts,
depth = depth,
}
end
-- Check if tree has mixed joining types
local function container_join_kind(part)
if part.type == "etydate" then
return nil
end
if part.new_sentence or part.separate_clause then
return "supplement"
end
return "or_join"
end
local function check_complexity(tree)
if not tree then return nil end
local parts = tree.container_parts
if #parts <= 1 then
-- Single container
if parts[1] and parts[1].continuation then
return check_complexity(parts[1].continuation)
end
return nil
end
-- Or-join containers must precede any supplemental (calque-like / influence) containers.
local seen_supplement = false
for _, part in ipairs(parts) do
local kind = container_join_kind(part)
if kind == "supplement" then
seen_supplement = true
elseif kind == "or_join" and seen_supplement then
error(
"Cannot generate etymology text: a main derivation step cannot follow a calque, semantic loan, or influence clause in the same list.")
end
end
for _, part in ipairs(parts) do
if part.continuation then
check_complexity(part.continuation)
end
end
return nil
end
-- Analyze tree and assign punctuation
local function analyze_punctuation(tree, is_toplevel)
if not tree then return end
local parts = tree.container_parts
local num_parts = #parts
for i, part in ipairs(parts) do
local is_first = (i == 1)
local is_last = (i == num_parts)
local next_part = parts[i + 1]
-- Analyze term punctuation within container
if part.term_parts then
-- Terms use Oxford comma style: "A, B, or C"
-- Custom conjunction can be specified via conj modifier (e.g., "and/or", "and")
local num_terms = #part.term_parts
local term_conj = part.conj or "or" -- default to "or"
for j, term_part in ipairs(part.term_parts) do
local is_last_term = (j == num_terms)
if part.is_group then
-- Group: terms joined with " + "
term_part.joiner = is_last_term and "" or " + "
elseif num_terms > 1 then
-- Multiple terms not in a group: Oxford comma style
if is_last_term then
term_part.joiner = ""
elseif j == num_terms - 1 then
-- Second to last term
if num_terms == 2 then
term_part.joiner = " " .. term_conj .. " "
else
term_part.joiner = ", " .. term_conj .. " "
end
else
term_part.joiner = ", "
end
else
-- Single term
term_part.joiner = ""
end
end
end
-- Determine container punctuation based on what comes next
if part.continuation then
-- Has continuation
part.punctuation = ","
-- Recursively analyze continuation
analyze_punctuation(part.continuation, false)
elseif is_last then
-- Last container at this level (may still continue in part.continuation)
part.punctuation = "."
elseif next_part and next_part.new_sentence then
-- Next container starts a new sentence
part.punctuation = "."
elseif next_part and next_part.separate_clause then
-- Next container is a separate clause
part.punctuation = ","
else
-- Not last, next is joined with "or"
-- Containers use repeated "or" style: "A, or B, or C"
part.punctuation = ","
end
-- Determine joiner to next part
-- Containers use repeated "or" style: ", or" between each
-- Custom conjunction can be specified via conj modifier
local container_conj = part.conj or "or" -- default to "or"
if not is_last then
if next_part and next_part.new_sentence then
-- New sentence
part.joiner = " "
elseif next_part and next_part.separate_clause then
-- Separate clause
part.joiner = " "
else
-- Same sentence: use custom conjunction or default "or"
part.joiner = " " .. container_conj .. " "
end
else
part.joiner = ""
end
-- Determine intro formatting
-- Capitalize if first at top level, OR if this container starts a new sentence
if (is_first and is_toplevel) or part.new_sentence then
part.intro_capitalized = true
part.use_full_intro = true
else
part.intro_capitalized = false
part.use_full_intro = false
end
end
end
-- Assemble text from analyzed tree
local function assemble_text(tree)
if not tree then return "" end
local result = ""
for i, part in ipairs(tree.container_parts) do
if part.type == "etydate" then
result = result .. part.etydate_text
if part.punctuation and part.punctuation ~= "" then
result = result .. part.punctuation
end
if part.etydate_refs and next(part.etydate_refs) then
result = result .. M.references.format_references(part.etydate_refs)
end
if part.joiner and part.joiner ~= "" then
result = result .. part.joiner
end
else
-- Build intro
local intro_text = part.intro_text
local phrase = part.phrase
if part.senseid then
intro_text, phrase = format_sl_senseid_intro(
part.senseid,
part.sl_keyword_text,
part.phrase,
part.intro_capitalized,
part.is_uncertain
)
end
local intro
if part.use_full_intro then
if part.is_uncertain and not part.senseid then
intro = "Possibly " .. phrase
else
intro = intro_text
end
else
if part.is_uncertain and not part.senseid then
intro = "possibly " .. phrase
else
intro = phrase
end
end
result = result .. intro
-- Build terms
if #part.term_parts > 0 then
result = result .. " "
for j, term_part in ipairs(part.term_parts) do
-- Add "possibly" prefix for uncertain terms when there's mixed uncertainty
if part.has_mixed_uncertainty and term_part.is_uncertain then
result = result .. "possibly "
end
result = result .. term_part.text
-- Add joiner between terms
if term_part.joiner ~= "" then
-- Check if joiner contains comma (punctuation)
local comma_pos = term_part.joiner:find(",")
if comma_pos then
-- Add up to and including comma
result = result .. term_part.joiner:sub(1, comma_pos)
-- Add refs after comma
if term_part.refs ~= "" then
result = result .. term_part.refs
end
-- Add rest of joiner
result = result .. term_part.joiner:sub(comma_pos + 1)
else
-- No comma, add refs before joiner
if term_part.refs ~= "" then
result = result .. term_part.refs
end
result = result .. term_part.joiner
end
end
end
-- For the last term, add punctuation then refs
local last_term = part.term_parts[#part.term_parts]
if last_term and last_term.joiner == "" then
if part.punctuation ~= "" then
-- If we have literal text, punctuation goes AFTER it
if part.lit then
-- Add refs first (attached to term)
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text
result = result .. ", literally “" .. part.lit .. "”"
-- Add punctuation
result = result .. part.punctuation
else
-- Normal behavior: punctuation then refs
result = result .. part.punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs after term refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
else
-- No punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text if present (even without punctuation)
if part.lit then
result = result .. ", literally “" .. part.lit .. "”"
end
end
end
else
-- No terms, just add punctuation and keyword refs
if part.punctuation ~= "" then
result = result .. part.punctuation
end
-- Add keyword refs even when there are no terms
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
-- Add continuation
if part.continuation then
result = result .. " " .. assemble_text(part.continuation)
end
-- Add joiner to next container
if part.joiner ~= "" then
result = result .. part.joiner
end
end
end
return result
end
local text_tree = build_text_tree(data_tree, 1, true, false)
-- Supplements (doublets, etydate, …) are rendered outside the main derivation text tree.
local function assemble_supplements()
if not data_tree.supplements then
return ""
end
local chunks = {}
local pending_trees = {}
local function flush_pending_trees()
local num = #pending_trees
for i, supplement_tree in ipairs(pending_trees) do
analyze_punctuation(supplement_tree, true)
apply_closing_punctuation_override(supplement_tree, i == num)
local chunk = assemble_text(supplement_tree)
if chunk ~= "" then
table.insert(chunks, chunk)
end
end
pending_trees = {}
end
for _, supplement in ipairs(data_tree.supplements) do
local supplement_tree
if supplement.type == "doublet" and supplement.config
and supplement.terms and #supplement.terms > 0 then
local config = supplement.config
local term_parts = {}
for _, term in ipairs(supplement.terms) do
local term_part = build_term_part(term, entry_lang, true)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
end
end
if #term_parts == 0 then
supplement_tree = nil
else
supplement_tree = {
type = "tree",
container_parts = {
{
type = "doublet",
intro_text = config.text,
phrase = config.phrase,
term_parts = term_parts,
conj = config.default_conj or "and",
new_sentence = true,
},
},
depth = 1,
}
end
elseif supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
supplement_tree = {
type = "tree",
container_parts = {
{
type = "etydate",
etydate_text = supplement.etydate_text,
etydate_refs = supplement.etydate_refs,
new_sentence = true,
},
},
depth = 1,
}
end
if supplement_tree then
table.insert(pending_trees, supplement_tree)
end
end
flush_pending_trees()
return table.concat(chunks, " ")
end
if not text_tree then
local supplement_text = assemble_supplements()
if supplement_text == "" then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
if stop_at_lang then
return supplement_text, { stop_lang_reached = false }
end
return supplement_text
end
local rendered = ""
if text_tree then
check_complexity(text_tree)
analyze_punctuation(text_tree, true)
apply_closing_punctuation_override(text_tree, not has_supplements())
rendered = assemble_text(text_tree)
end
local supplement_text = assemble_supplements()
if supplement_text ~= "" then
if rendered ~= "" then
rendered = rendered .. " " .. supplement_text
else
rendered = supplement_text
end
end
if stop_at_lang then
return rendered, { stop_lang_reached = stop_lang_reached }
end
return rendered
end
return export
60dpsf0pxj0apgpy33ukqivkz2zx3ix
5775354
5775353
2026-10-15T06:43:02Z
Octahedron80
267
5775354
Scribunto
text/plain
local export = {}
local loader = require("Module:module loader")
local M = loader.init({
require = {
en_utilities = "Module:en-utilities",
references = "Module:references",
senseno = "Module:senseno",
},
loadData = {
data = "Module:etymon/data",
},
})
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local format_term_func = opts.format_term_func
local max_depth = opts.max_depth
local stop_at_blue_link = opts.stop_at_blue_link
local curr_page = opts.curr_page
local nodot = opts.nodot and opts.nodot ~= "" and opts.nodot ~= "0"
local function explicit_dot_override()
if opts.dot == nil or opts.dot == false then
return nil
end
local d = mw.text.trim(tostring(opts.dot))
if d == "" or d == "." then
return nil
end
return d
end
local dot_override = explicit_dot_override()
local function find_deepest_last_part(tree)
if not tree or not tree.container_parts or #tree.container_parts == 0 then
return nil
end
local last_part = tree.container_parts[#tree.container_parts]
if last_part.continuation then
return find_deepest_last_part(last_part.continuation)
end
return last_part
end
local function apply_final_punctuation_override(tree, punct)
if not tree or punct == nil then
return
end
local last_part = find_deepest_last_part(tree)
if last_part then
last_part.punctuation = punct
end
end
local function apply_closing_punctuation_override(tree, is_last_segment)
if not is_last_segment then
return
end
local punct
if nodot then
punct = ""
elseif dot_override ~= nil then
punct = dot_override
else
return
end
apply_final_punctuation_override(tree, punct)
end
local function has_supplements()
return data_tree.supplements and #data_tree.supplements > 0
end
local stop_at_lang = opts.stop_at_lang
local stop_at_lang_or_bluelink = opts.stop_at_lang_or_bluelink
local lang_matches_stop_code = opts.lang_matches_stop_code
local stop_lang_reached = false
local function term_matches_stop_code(term_lang, stop_code)
if lang_matches_stop_code then
return lang_matches_stop_code(term_lang, stop_code)
end
return term_lang and term_lang:getCode() == stop_code
end
local children = data_tree.children
local function has_text_supplements()
if not data_tree.supplements then
return false
end
for _, supplement in ipairs(data_tree.supplements) do
if supplement.type == "doublet" and supplement.terms and #supplement.terms > 0 then
return true
end
if supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
return true
end
end
return false
end
if (not children or #children == 0) and not has_text_supplements() then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
local entry_lang = data_tree.lang
local function lowercase_glossary_link_display(wikitext)
return wikitext:gsub("(%[%[ภาคผนวก:อภิธานศัพท์#[^|]+|)([^%]])([^%]]*)%]%]", function(prefix, first, rest)
return prefix .. mw.ustring.lower(first) .. rest .. "]]"
end)
end
local function format_sl_senseid_intro(senseid, keyword_text, keyword_phrase, capitalize_senseno, is_uncertain)
local senseids = mw.text.split(senseid, "!!", true)
local senseno_parts = {}
for i, id in ipairs(senseids) do
id = mw.text.trim(id)
if id ~= "" then
table.insert(senseno_parts, M.senseno.link_text(entry_lang:getCode(), { id }, {
title = curr_page,
uc = (i == 1 and capitalize_senseno) or nil,
}))
end
end
if #senseno_parts == 0 then
return keyword_text, keyword_phrase
end
local senseno_text = mw.text.listToText(senseno_parts)
local glossary_link = (keyword_text or ""):gsub(" from$", "")
local glossary_lower = lowercase_glossary_link_display(glossary_link)
if #senseno_parts > 1 then
local plural_link = glossary_lower:gsub("|semantic loan%]%]", "|semantic loans]]")
if is_uncertain then
return senseno_text .. " are possibly " .. plural_link .. " from",
senseno_text .. " are possibly semantic loans from"
end
return senseno_text .. " are " .. plural_link .. " from",
senseno_text .. " are semantic loans from"
end
if is_uncertain then
return senseno_text .. " is possibly a " .. glossary_lower .. " from",
senseno_text .. " is possibly a semantic loan from"
end
return senseno_text .. " is a " .. glossary_lower .. " from",
senseno_text .. " is a semantic loan from"
end
local function get_term_refs(term, defined_here)
if defined_here and term.refs and next(term.refs) then
return M.references.format_references(term.refs)
end
return ""
end
-- Build a text part for a single term
local function build_term_part(term, current_lang, defined_here)
local text = ""
local new_lang = current_lang
local lang_changed = term.lang:getCanonicalName() ~= current_lang:getCanonicalName()
-- Use centralized format_term (handles suppress_term, unknown_term, and regular terms)
local term_text = format_term_func(term)
if lang_changed then
new_lang = term.lang
if term_text then
text = term.lang:makeWikipediaLink() .. " " .. term_text
elseif term.is_family then
text = M.en_utilities.add_indefinite_article(term.lang:makeWikipediaLink() .. " language", false)
else
-- suppress_term with language change: show only language
text = term.lang:makeWikipediaLink()
end
else
text = term_text or ""
end
return {
type = "term",
text = text,
refs = get_term_refs(term, defined_here),
lang = new_lang,
is_uncertain = term.is_uncertain or false,
}
end
-- Build text parts for a container
local function build_container_part(container, node, depth, allow_continuation, fallback_to_bluelink)
local keyword_info = container.keyword_info
local keyword_modifiers = container.keyword_modifiers or {}
local terms = container.terms or {}
if not keyword_info or #terms == 0 then
return nil
end
-- Skip building text part when invisible in text ("all", "text", or true)
local inv = keyword_info.invisible
if inv == "all" or inv == true or inv == "text" then
return nil
end
local is_group = keyword_info.is_group
local keyword_uncertain = keyword_modifiers.unc or false
-- Determine text and phrase (allowing for overrides)
local intro_text = keyword_info.text
local phrase = keyword_info.phrase
local new_sentence = keyword_info.new_sentence or false
if keyword_modifiers.text then
-- User-provided override: assumed to be lowercase
phrase = keyword_modifiers.text
-- Auto-capitalize for intro text (e.g., "derived from" -> "Derived from")
intro_text = mw.ustring.upper(phrase:sub(1, 1)) .. phrase:sub(2)
end
local defined_here = (node.page_of or curr_page) == curr_page
-- Get keyword references
local keyword_refs = ""
if defined_here and keyword_modifiers.refs and next(keyword_modifiers.refs) then
keyword_refs = M.references.format_references(keyword_modifiers.refs)
end
-- Build term parts
local term_parts = {}
local current_lang = node.lang
for _, term in ipairs(terms) do
local term_part = build_term_part(term, current_lang, defined_here)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
current_lang = term_part.lang
end
end
-- Check uncertainty distribution
local uncertain_count = 0
for _, term_part in ipairs(term_parts) do
if term_part.is_uncertain then
uncertain_count = uncertain_count + 1
end
end
-- If keyword itself is uncertain, treat all terms as uncertain
local all_uncertain = keyword_uncertain or (uncertain_count == #term_parts and #term_parts > 0)
if is_group and uncertain_count > 0 then
all_uncertain = true
end
local has_mixed_uncertainty = not all_uncertain and uncertain_count > 0
-- Check if there are more steps (only if continuation is allowed)
local has_more_steps = false
local next_node = nil
local first_term = terms[1]
-- Check if we should stop at this language
local reached_stop_lang = false
if stop_at_lang then
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang) then
reached_stop_lang = true
stop_lang_reached = true
break
end
end
elseif stop_at_lang_or_bluelink then
-- Check if we should stop at this language, or at the first bluelink if it's a redlink
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang_or_bluelink) then
if first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
else
fallback_to_bluelink = true
end
break
end
end
if fallback_to_bluelink and first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
end
end
if allow_continuation and not is_group and #terms == 1 and not reached_stop_lang then
local first_term_children = first_term.children
if first_term_children and #first_term_children > 0 and (not max_depth or depth < max_depth) then
local next_container = first_term_children[1]
local next_keyword_info = next_container and next_container.keyword_info
if not (next_keyword_info and next_keyword_info.invisible) then
if stop_at_blue_link then
if first_term.status ~= M.data.STATUS.OK then
has_more_steps = true
next_node = first_term
end
else
has_more_steps = true
next_node = first_term
end
end
end
end
return {
type = "container",
intro_text = intro_text,
phrase = phrase,
senseid = keyword_modifiers.senseid,
sl_keyword_text = keyword_modifiers.senseid and keyword_info.text or nil,
is_uncertain = all_uncertain,
has_mixed_uncertainty = has_mixed_uncertainty,
term_parts = term_parts,
is_group = is_group,
has_more_steps = has_more_steps,
next_node = next_node,
new_sentence = new_sentence,
separate_clause = keyword_info.separate_clause or false,
conj = keyword_modifiers.conj or keyword_info.default_conj, -- custom conjunction: "and", "or", "and/or", etc.
lit = keyword_modifiers.lit,
keyword_refs = keyword_refs,
fallback_to_bluelink = fallback_to_bluelink,
}
end
-- Build the full tree of text parts
local function build_text_tree(node, depth, allow_continuation, fallback_to_bluelink)
local containers = node.children
if not containers or #containers == 0 then
return nil
end
local container_parts = {}
local function is_new_sentence(container)
return container.keyword_info and container.keyword_info.new_sentence or false
end
-- Count the containers that get a text part in the derivation's own sentence (invisible in text = "all",
-- "text", or true)
local visible_container_count = 0
for _, container in ipairs(containers) do
local keyword_info = container.keyword_info
local inv = keyword_info and keyword_info.invisible
if not (inv == "all" or inv == true or inv == "text") and not is_new_sentence(container) then
visible_container_count = visible_container_count + 1
end
end
-- If there are multiple visible containers in that sentence, don't allow continuation for any: alternatives
-- each name a different source, and an influence clause after a chain would read as influencing its last
-- step. A sentence of its own does not stop the derivation's chain.
local has_multiple_containers = visible_container_count > 1
local should_allow_continuation = allow_continuation and not has_multiple_containers
for _, container in ipairs(containers) do
local part = build_container_part(container, node, depth, should_allow_continuation and not is_new_sentence(container), fallback_to_bluelink)
if part then
-- Recursively build children if there are more steps
if part.has_more_steps and part.next_node then
part.continuation = build_text_tree(part.next_node, depth + 1, true, part.fallback_to_bluelink)
end
table.insert(container_parts, part)
end
end
if #container_parts == 0 then
return nil
end
return {
type = "tree",
container_parts = container_parts,
depth = depth,
}
end
-- Check if tree has mixed joining types
local function container_join_kind(part)
if part.type == "etydate" then
return nil
end
if part.new_sentence or part.separate_clause then
return "supplement"
end
return "or_join"
end
local function check_complexity(tree)
if not tree then return nil end
local parts = tree.container_parts
if #parts <= 1 then
-- Single container
if parts[1] and parts[1].continuation then
return check_complexity(parts[1].continuation)
end
return nil
end
-- Or-join containers must precede any supplemental (calque-like / influence) containers.
local seen_supplement = false
for _, part in ipairs(parts) do
local kind = container_join_kind(part)
if kind == "supplement" then
seen_supplement = true
elseif kind == "or_join" and seen_supplement then
error(
"Cannot generate etymology text: a main derivation step cannot follow a calque, semantic loan, or influence clause in the same list.")
end
end
for _, part in ipairs(parts) do
if part.continuation then
check_complexity(part.continuation)
end
end
return nil
end
-- Analyze tree and assign punctuation
local function analyze_punctuation(tree, is_toplevel)
if not tree then return end
local parts = tree.container_parts
local num_parts = #parts
for i, part in ipairs(parts) do
local is_first = (i == 1)
local is_last = (i == num_parts)
local next_part = parts[i + 1]
-- Analyze term punctuation within container
if part.term_parts then
-- Terms use Oxford comma style: "A, B, or C"
-- Custom conjunction can be specified via conj modifier (e.g., "and/or", "and")
local num_terms = #part.term_parts
local term_conj = part.conj or "หรือ" -- default to "or"
for j, term_part in ipairs(part.term_parts) do
local is_last_term = (j == num_terms)
if part.is_group then
-- Group: terms joined with " + "
term_part.joiner = is_last_term and "" or " + "
elseif num_terms > 1 then
-- Multiple terms not in a group: Oxford comma style
if is_last_term then
term_part.joiner = ""
elseif j == num_terms - 1 then
-- Second to last term
if num_terms == 2 then
term_part.joiner = " " .. term_conj .. " "
else
term_part.joiner = ", " .. term_conj .. " "
end
else
term_part.joiner = ", "
end
else
-- Single term
term_part.joiner = ""
end
end
end
-- Determine container punctuation based on what comes next
if part.continuation then
-- Has continuation
part.punctuation = ","
-- Recursively analyze continuation
analyze_punctuation(part.continuation, false)
elseif is_last then
-- Last container at this level (may still continue in part.continuation)
part.punctuation = "."
elseif next_part and next_part.new_sentence then
-- Next container starts a new sentence
part.punctuation = "."
elseif next_part and next_part.separate_clause then
-- Next container is a separate clause
part.punctuation = ","
else
-- Not last, next is joined with "or"
-- Containers use repeated "or" style: "A, or B, or C"
part.punctuation = ","
end
-- Determine joiner to next part
-- Containers use repeated "or" style: ", or" between each
-- Custom conjunction can be specified via conj modifier
local container_conj = part.conj or "หรือ" -- default to "or"
if not is_last then
if next_part and next_part.new_sentence then
-- New sentence
part.joiner = " "
elseif next_part and next_part.separate_clause then
-- Separate clause
part.joiner = " "
else
-- Same sentence: use custom conjunction or default "or"
part.joiner = " " .. container_conj .. " "
end
else
part.joiner = ""
end
-- Determine intro formatting
-- Capitalize if first at top level, OR if this container starts a new sentence
if (is_first and is_toplevel) or part.new_sentence then
part.intro_capitalized = true
part.use_full_intro = true
else
part.intro_capitalized = false
part.use_full_intro = false
end
end
end
-- Assemble text from analyzed tree
local function assemble_text(tree)
if not tree then return "" end
local result = ""
for i, part in ipairs(tree.container_parts) do
if part.type == "etydate" then
result = result .. part.etydate_text
if part.punctuation and part.punctuation ~= "" then
result = result .. part.punctuation
end
if part.etydate_refs and next(part.etydate_refs) then
result = result .. M.references.format_references(part.etydate_refs)
end
if part.joiner and part.joiner ~= "" then
result = result .. part.joiner
end
else
-- Build intro
local intro_text = part.intro_text
local phrase = part.phrase
if part.senseid then
intro_text, phrase = format_sl_senseid_intro(
part.senseid,
part.sl_keyword_text,
part.phrase,
part.intro_capitalized,
part.is_uncertain
)
end
local intro
if part.use_full_intro then
if part.is_uncertain and not part.senseid then
intro = "Possibly " .. phrase
else
intro = intro_text
end
else
if part.is_uncertain and not part.senseid then
intro = "possibly " .. phrase
else
intro = phrase
end
end
result = result .. intro
-- Build terms
if #part.term_parts > 0 then
result = result .. " "
for j, term_part in ipairs(part.term_parts) do
-- Add "possibly" prefix for uncertain terms when there's mixed uncertainty
if part.has_mixed_uncertainty and term_part.is_uncertain then
result = result .. "possibly "
end
result = result .. term_part.text
-- Add joiner between terms
if term_part.joiner ~= "" then
-- Check if joiner contains comma (punctuation)
local comma_pos = term_part.joiner:find(",")
if comma_pos then
-- Add up to and including comma
result = result .. term_part.joiner:sub(1, comma_pos)
-- Add refs after comma
if term_part.refs ~= "" then
result = result .. term_part.refs
end
-- Add rest of joiner
result = result .. term_part.joiner:sub(comma_pos + 1)
else
-- No comma, add refs before joiner
if term_part.refs ~= "" then
result = result .. term_part.refs
end
result = result .. term_part.joiner
end
end
end
-- For the last term, add punctuation then refs
local last_term = part.term_parts[#part.term_parts]
if last_term and last_term.joiner == "" then
if part.punctuation ~= "" then
-- If we have literal text, punctuation goes AFTER it
if part.lit then
-- Add refs first (attached to term)
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text
result = result .. ", literally “" .. part.lit .. "”"
-- Add punctuation
result = result .. part.punctuation
else
-- Normal behavior: punctuation then refs
result = result .. part.punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs after term refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
else
-- No punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text if present (even without punctuation)
if part.lit then
result = result .. ", literally “" .. part.lit .. "”"
end
end
end
else
-- No terms, just add punctuation and keyword refs
if part.punctuation ~= "" then
result = result .. part.punctuation
end
-- Add keyword refs even when there are no terms
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
-- Add continuation
if part.continuation then
result = result .. " " .. assemble_text(part.continuation)
end
-- Add joiner to next container
if part.joiner ~= "" then
result = result .. part.joiner
end
end
end
return result
end
local text_tree = build_text_tree(data_tree, 1, true, false)
-- Supplements (doublets, etydate, …) are rendered outside the main derivation text tree.
local function assemble_supplements()
if not data_tree.supplements then
return ""
end
local chunks = {}
local pending_trees = {}
local function flush_pending_trees()
local num = #pending_trees
for i, supplement_tree in ipairs(pending_trees) do
analyze_punctuation(supplement_tree, true)
apply_closing_punctuation_override(supplement_tree, i == num)
local chunk = assemble_text(supplement_tree)
if chunk ~= "" then
table.insert(chunks, chunk)
end
end
pending_trees = {}
end
for _, supplement in ipairs(data_tree.supplements) do
local supplement_tree
if supplement.type == "doublet" and supplement.config
and supplement.terms and #supplement.terms > 0 then
local config = supplement.config
local term_parts = {}
for _, term in ipairs(supplement.terms) do
local term_part = build_term_part(term, entry_lang, true)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
end
end
if #term_parts == 0 then
supplement_tree = nil
else
supplement_tree = {
type = "tree",
container_parts = {
{
type = "doublet",
intro_text = config.text,
phrase = config.phrase,
term_parts = term_parts,
conj = config.default_conj or "and",
new_sentence = true,
},
},
depth = 1,
}
end
elseif supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
supplement_tree = {
type = "tree",
container_parts = {
{
type = "etydate",
etydate_text = supplement.etydate_text,
etydate_refs = supplement.etydate_refs,
new_sentence = true,
},
},
depth = 1,
}
end
if supplement_tree then
table.insert(pending_trees, supplement_tree)
end
end
flush_pending_trees()
return table.concat(chunks, " ")
end
if not text_tree then
local supplement_text = assemble_supplements()
if supplement_text == "" then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
if stop_at_lang then
return supplement_text, { stop_lang_reached = false }
end
return supplement_text
end
local rendered = ""
if text_tree then
check_complexity(text_tree)
analyze_punctuation(text_tree, true)
apply_closing_punctuation_override(text_tree, not has_supplements())
rendered = assemble_text(text_tree)
end
local supplement_text = assemble_supplements()
if supplement_text ~= "" then
if rendered ~= "" then
rendered = rendered .. " " .. supplement_text
else
rendered = supplement_text
end
end
if stop_at_lang then
return rendered, { stop_lang_reached = stop_lang_reached }
end
return rendered
end
return export
5cwggkq7jwz6gnf8dc13o6e256trfej
5775355
5775354
2026-10-15T06:45:13Z
Octahedron80
267
5775355
Scribunto
text/plain
local export = {}
local loader = require("Module:module loader")
local M = loader.init({
require = {
en_utilities = "Module:en-utilities",
references = "Module:references",
senseno = "Module:senseno",
},
loadData = {
data = "Module:etymon/data",
},
})
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local format_term_func = opts.format_term_func
local max_depth = opts.max_depth
local stop_at_blue_link = opts.stop_at_blue_link
local curr_page = opts.curr_page
local nodot = opts.nodot and opts.nodot ~= "" and opts.nodot ~= "0"
local function explicit_dot_override()
if opts.dot == nil or opts.dot == false then
return nil
end
local d = mw.text.trim(tostring(opts.dot))
if d == "" or d == "." then
return nil
end
return d
end
local dot_override = explicit_dot_override()
local function find_deepest_last_part(tree)
if not tree or not tree.container_parts or #tree.container_parts == 0 then
return nil
end
local last_part = tree.container_parts[#tree.container_parts]
if last_part.continuation then
return find_deepest_last_part(last_part.continuation)
end
return last_part
end
local function apply_final_punctuation_override(tree, punct)
if not tree or punct == nil then
return
end
local last_part = find_deepest_last_part(tree)
if last_part then
last_part.punctuation = punct
end
end
local function apply_closing_punctuation_override(tree, is_last_segment)
if not is_last_segment then
return
end
local punct
if nodot then
punct = ""
elseif dot_override ~= nil then
punct = dot_override
else
return
end
apply_final_punctuation_override(tree, punct)
end
local function has_supplements()
return data_tree.supplements and #data_tree.supplements > 0
end
local stop_at_lang = opts.stop_at_lang
local stop_at_lang_or_bluelink = opts.stop_at_lang_or_bluelink
local lang_matches_stop_code = opts.lang_matches_stop_code
local stop_lang_reached = false
local function term_matches_stop_code(term_lang, stop_code)
if lang_matches_stop_code then
return lang_matches_stop_code(term_lang, stop_code)
end
return term_lang and term_lang:getCode() == stop_code
end
local children = data_tree.children
local function has_text_supplements()
if not data_tree.supplements then
return false
end
for _, supplement in ipairs(data_tree.supplements) do
if supplement.type == "doublet" and supplement.terms and #supplement.terms > 0 then
return true
end
if supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
return true
end
end
return false
end
if (not children or #children == 0) and not has_text_supplements() then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
local entry_lang = data_tree.lang
local function lowercase_glossary_link_display(wikitext)
return wikitext:gsub("(%[%[ภาคผนวก:อภิธานศัพท์#[^|]+|)([^%]])([^%]]*)%]%]", function(prefix, first, rest)
return prefix .. mw.ustring.lower(first) .. rest .. "]]"
end)
end
local function format_sl_senseid_intro(senseid, keyword_text, keyword_phrase, capitalize_senseno, is_uncertain)
local senseids = mw.text.split(senseid, "!!", true)
local senseno_parts = {}
for i, id in ipairs(senseids) do
id = mw.text.trim(id)
if id ~= "" then
table.insert(senseno_parts, M.senseno.link_text(entry_lang:getCode(), { id }, {
title = curr_page,
uc = (i == 1 and capitalize_senseno) or nil,
}))
end
end
if #senseno_parts == 0 then
return keyword_text, keyword_phrase
end
local senseno_text = mw.text.listToText(senseno_parts)
local glossary_link = (keyword_text or ""):gsub(" from$", "")
local glossary_lower = lowercase_glossary_link_display(glossary_link)
if #senseno_parts > 1 then
local plural_link = glossary_lower:gsub("|semantic loan%]%]", "|semantic loans]]")
if is_uncertain then
return senseno_text .. " are possibly " .. plural_link .. " from",
senseno_text .. " are possibly semantic loans from"
end
return senseno_text .. " are " .. plural_link .. " from",
senseno_text .. " are semantic loans from"
end
if is_uncertain then
return senseno_text .. " is possibly a " .. glossary_lower .. " from",
senseno_text .. " is possibly a semantic loan from"
end
return senseno_text .. " is a " .. glossary_lower .. " from",
senseno_text .. " is a semantic loan from"
end
local function get_term_refs(term, defined_here)
if defined_here and term.refs and next(term.refs) then
return M.references.format_references(term.refs)
end
return ""
end
-- Build a text part for a single term
local function build_term_part(term, current_lang, defined_here)
local text = ""
local new_lang = current_lang
local lang_changed = term.lang:getCanonicalName() ~= current_lang:getCanonicalName()
-- Use centralized format_term (handles suppress_term, unknown_term, and regular terms)
local term_text = format_term_func(term)
if lang_changed then
new_lang = term.lang
if term_text then
text = term.lang:makeWikipediaLink() .. " " .. term_text
elseif term.is_family then
text = M.en_utilities.add_indefinite_article(term.lang:makeWikipediaLink() .. " language", false)
else
-- suppress_term with language change: show only language
text = term.lang:makeWikipediaLink()
end
else
text = term_text or ""
end
return {
type = "term",
text = text,
refs = get_term_refs(term, defined_here),
lang = new_lang,
is_uncertain = term.is_uncertain or false,
}
end
-- Build text parts for a container
local function build_container_part(container, node, depth, allow_continuation, fallback_to_bluelink)
local keyword_info = container.keyword_info
local keyword_modifiers = container.keyword_modifiers or {}
local terms = container.terms or {}
if not keyword_info or #terms == 0 then
return nil
end
-- Skip building text part when invisible in text ("all", "text", or true)
local inv = keyword_info.invisible
if inv == "all" or inv == true or inv == "text" then
return nil
end
local is_group = keyword_info.is_group
local keyword_uncertain = keyword_modifiers.unc or false
-- Determine text and phrase (allowing for overrides)
local intro_text = keyword_info.text
local phrase = keyword_info.phrase
local new_sentence = keyword_info.new_sentence or false
if keyword_modifiers.text then
-- User-provided override: assumed to be lowercase
phrase = keyword_modifiers.text
-- Auto-capitalize for intro text (e.g., "derived from" -> "Derived from")
intro_text = mw.ustring.upper(phrase:sub(1, 1)) .. phrase:sub(2)
end
local defined_here = (node.page_of or curr_page) == curr_page
-- Get keyword references
local keyword_refs = ""
if defined_here and keyword_modifiers.refs and next(keyword_modifiers.refs) then
keyword_refs = M.references.format_references(keyword_modifiers.refs)
end
-- Build term parts
local term_parts = {}
local current_lang = node.lang
for _, term in ipairs(terms) do
local term_part = build_term_part(term, current_lang, defined_here)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
current_lang = term_part.lang
end
end
-- Check uncertainty distribution
local uncertain_count = 0
for _, term_part in ipairs(term_parts) do
if term_part.is_uncertain then
uncertain_count = uncertain_count + 1
end
end
-- If keyword itself is uncertain, treat all terms as uncertain
local all_uncertain = keyword_uncertain or (uncertain_count == #term_parts and #term_parts > 0)
if is_group and uncertain_count > 0 then
all_uncertain = true
end
local has_mixed_uncertainty = not all_uncertain and uncertain_count > 0
-- Check if there are more steps (only if continuation is allowed)
local has_more_steps = false
local next_node = nil
local first_term = terms[1]
-- Check if we should stop at this language
local reached_stop_lang = false
if stop_at_lang then
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang) then
reached_stop_lang = true
stop_lang_reached = true
break
end
end
elseif stop_at_lang_or_bluelink then
-- Check if we should stop at this language, or at the first bluelink if it's a redlink
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang_or_bluelink) then
if first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
else
fallback_to_bluelink = true
end
break
end
end
if fallback_to_bluelink and first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
end
end
if allow_continuation and not is_group and #terms == 1 and not reached_stop_lang then
local first_term_children = first_term.children
if first_term_children and #first_term_children > 0 and (not max_depth or depth < max_depth) then
local next_container = first_term_children[1]
local next_keyword_info = next_container and next_container.keyword_info
if not (next_keyword_info and next_keyword_info.invisible) then
if stop_at_blue_link then
if first_term.status ~= M.data.STATUS.OK then
has_more_steps = true
next_node = first_term
end
else
has_more_steps = true
next_node = first_term
end
end
end
end
return {
type = "container",
intro_text = intro_text,
phrase = phrase,
senseid = keyword_modifiers.senseid,
sl_keyword_text = keyword_modifiers.senseid and keyword_info.text or nil,
is_uncertain = all_uncertain,
has_mixed_uncertainty = has_mixed_uncertainty,
term_parts = term_parts,
is_group = is_group,
has_more_steps = has_more_steps,
next_node = next_node,
new_sentence = new_sentence,
separate_clause = keyword_info.separate_clause or false,
conj = keyword_modifiers.conj or keyword_info.default_conj, -- custom conjunction: "and", "or", "and/or", etc.
lit = keyword_modifiers.lit,
keyword_refs = keyword_refs,
fallback_to_bluelink = fallback_to_bluelink,
}
end
-- Build the full tree of text parts
local function build_text_tree(node, depth, allow_continuation, fallback_to_bluelink)
local containers = node.children
if not containers or #containers == 0 then
return nil
end
local container_parts = {}
local function is_new_sentence(container)
return container.keyword_info and container.keyword_info.new_sentence or false
end
-- Count the containers that get a text part in the derivation's own sentence (invisible in text = "all",
-- "text", or true)
local visible_container_count = 0
for _, container in ipairs(containers) do
local keyword_info = container.keyword_info
local inv = keyword_info and keyword_info.invisible
if not (inv == "all" or inv == true or inv == "text") and not is_new_sentence(container) then
visible_container_count = visible_container_count + 1
end
end
-- If there are multiple visible containers in that sentence, don't allow continuation for any: alternatives
-- each name a different source, and an influence clause after a chain would read as influencing its last
-- step. A sentence of its own does not stop the derivation's chain.
local has_multiple_containers = visible_container_count > 1
local should_allow_continuation = allow_continuation and not has_multiple_containers
for _, container in ipairs(containers) do
local part = build_container_part(container, node, depth, should_allow_continuation and not is_new_sentence(container), fallback_to_bluelink)
if part then
-- Recursively build children if there are more steps
if part.has_more_steps and part.next_node then
part.continuation = build_text_tree(part.next_node, depth + 1, true, part.fallback_to_bluelink)
end
table.insert(container_parts, part)
end
end
if #container_parts == 0 then
return nil
end
return {
type = "tree",
container_parts = container_parts,
depth = depth,
}
end
-- Check if tree has mixed joining types
local function container_join_kind(part)
if part.type == "etydate" then
return nil
end
if part.new_sentence or part.separate_clause then
return "supplement"
end
return "or_join"
end
local function check_complexity(tree)
if not tree then return nil end
local parts = tree.container_parts
if #parts <= 1 then
-- Single container
if parts[1] and parts[1].continuation then
return check_complexity(parts[1].continuation)
end
return nil
end
-- Or-join containers must precede any supplemental (calque-like / influence) containers.
local seen_supplement = false
for _, part in ipairs(parts) do
local kind = container_join_kind(part)
if kind == "supplement" then
seen_supplement = true
elseif kind == "or_join" and seen_supplement then
error(
"Cannot generate etymology text: a main derivation step cannot follow a calque, semantic loan, or influence clause in the same list.")
end
end
for _, part in ipairs(parts) do
if part.continuation then
check_complexity(part.continuation)
end
end
return nil
end
-- Analyze tree and assign punctuation
local function analyze_punctuation(tree, is_toplevel)
if not tree then return end
local parts = tree.container_parts
local num_parts = #parts
for i, part in ipairs(parts) do
local is_first = (i == 1)
local is_last = (i == num_parts)
local next_part = parts[i + 1]
-- Analyze term punctuation within container
if part.term_parts then
-- Terms use Oxford comma style: "A, B, or C"
-- Custom conjunction can be specified via conj modifier (e.g., "and/or", "and")
local num_terms = #part.term_parts
local term_conj = part.conj or "หรือ" -- default to "or"
for j, term_part in ipairs(part.term_parts) do
local is_last_term = (j == num_terms)
if part.is_group then
-- Group: terms joined with " + "
term_part.joiner = is_last_term and "" or " + "
elseif num_terms > 1 then
-- Multiple terms not in a group: Oxford comma style
if is_last_term then
term_part.joiner = ""
elseif j == num_terms - 1 then
-- Second to last term
if num_terms == 2 then
term_part.joiner = " " .. term_conj .. " "
else
term_part.joiner = ", " .. term_conj .. " "
end
else
term_part.joiner = ", "
end
else
-- Single term
term_part.joiner = ""
end
end
end
-- Determine container punctuation based on what comes next
if part.continuation then
-- Has continuation
part.punctuation = ","
-- Recursively analyze continuation
analyze_punctuation(part.continuation, false)
elseif is_last then
-- Last container at this level (may still continue in part.continuation)
part.punctuation = "."
elseif next_part and next_part.new_sentence then
-- Next container starts a new sentence
part.punctuation = "."
elseif next_part and next_part.separate_clause then
-- Next container is a separate clause
part.punctuation = ","
else
-- Not last, next is joined with "or"
-- Containers use repeated "or" style: "A, or B, or C"
part.punctuation = ","
end
-- Determine joiner to next part
-- Containers use repeated "or" style: ", or" between each
-- Custom conjunction can be specified via conj modifier
local container_conj = part.conj or "หรือ" -- default to "or"
if not is_last then
if next_part and next_part.new_sentence then
-- New sentence
part.joiner = " "
elseif next_part and next_part.separate_clause then
-- Separate clause
part.joiner = " "
else
-- Same sentence: use custom conjunction or default "or"
part.joiner = " " .. container_conj .. " "
end
else
part.joiner = ""
end
-- Determine intro formatting
-- Capitalize if first at top level, OR if this container starts a new sentence
if (is_first and is_toplevel) or part.new_sentence then
part.intro_capitalized = true
part.use_full_intro = true
else
part.intro_capitalized = false
part.use_full_intro = false
end
end
end
-- Assemble text from analyzed tree
local function assemble_text(tree)
if not tree then return "" end
local result = ""
for i, part in ipairs(tree.container_parts) do
if part.type == "etydate" then
result = result .. part.etydate_text
if part.punctuation and part.punctuation ~= "" then
result = result .. part.punctuation
end
if part.etydate_refs and next(part.etydate_refs) then
result = result .. M.references.format_references(part.etydate_refs)
end
if part.joiner and part.joiner ~= "" then
result = result .. part.joiner
end
else
-- Build intro
local intro_text = part.intro_text
local phrase = part.phrase
if part.senseid then
intro_text, phrase = format_sl_senseid_intro(
part.senseid,
part.sl_keyword_text,
part.phrase,
part.intro_capitalized,
part.is_uncertain
)
end
local intro
if part.use_full_intro then
if part.is_uncertain and not part.senseid then
intro = "เป็นไปได้ว่า" .. phrase
else
intro = intro_text
end
else
if part.is_uncertain and not part.senseid then
intro = "เป็นไปได้ว่า" .. phrase
else
intro = phrase
end
end
result = result .. intro
-- Build terms
if #part.term_parts > 0 then
result = result .. " "
for j, term_part in ipairs(part.term_parts) do
-- Add "possibly" prefix for uncertain terms when there's mixed uncertainty
if part.has_mixed_uncertainty and term_part.is_uncertain then
result = result .. "เป็นไปได้ว่า"
end
result = result .. term_part.text
-- Add joiner between terms
if term_part.joiner ~= "" then
-- Check if joiner contains comma (punctuation)
local comma_pos = term_part.joiner:find(",")
if comma_pos then
-- Add up to and including comma
result = result .. term_part.joiner:sub(1, comma_pos)
-- Add refs after comma
if term_part.refs ~= "" then
result = result .. term_part.refs
end
-- Add rest of joiner
result = result .. term_part.joiner:sub(comma_pos + 1)
else
-- No comma, add refs before joiner
if term_part.refs ~= "" then
result = result .. term_part.refs
end
result = result .. term_part.joiner
end
end
end
-- For the last term, add punctuation then refs
local last_term = part.term_parts[#part.term_parts]
if last_term and last_term.joiner == "" then
if part.punctuation ~= "" then
-- If we have literal text, punctuation goes AFTER it
if part.lit then
-- Add refs first (attached to term)
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text
result = result .. ", แปลตามตัวอักษรว่า “" .. part.lit .. "”"
-- Add punctuation
result = result .. part.punctuation
else
-- Normal behavior: punctuation then refs
result = result .. part.punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs after term refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
else
-- No punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text if present (even without punctuation)
if part.lit then
result = result .. ", แปลตามตัวอักษรว่า “" .. part.lit .. "”"
end
end
end
else
-- No terms, just add punctuation and keyword refs
if part.punctuation ~= "" then
result = result .. part.punctuation
end
-- Add keyword refs even when there are no terms
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
-- Add continuation
if part.continuation then
result = result .. " " .. assemble_text(part.continuation)
end
-- Add joiner to next container
if part.joiner ~= "" then
result = result .. part.joiner
end
end
end
return result
end
local text_tree = build_text_tree(data_tree, 1, true, false)
-- Supplements (doublets, etydate, …) are rendered outside the main derivation text tree.
local function assemble_supplements()
if not data_tree.supplements then
return ""
end
local chunks = {}
local pending_trees = {}
local function flush_pending_trees()
local num = #pending_trees
for i, supplement_tree in ipairs(pending_trees) do
analyze_punctuation(supplement_tree, true)
apply_closing_punctuation_override(supplement_tree, i == num)
local chunk = assemble_text(supplement_tree)
if chunk ~= "" then
table.insert(chunks, chunk)
end
end
pending_trees = {}
end
for _, supplement in ipairs(data_tree.supplements) do
local supplement_tree
if supplement.type == "doublet" and supplement.config
and supplement.terms and #supplement.terms > 0 then
local config = supplement.config
local term_parts = {}
for _, term in ipairs(supplement.terms) do
local term_part = build_term_part(term, entry_lang, true)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
end
end
if #term_parts == 0 then
supplement_tree = nil
else
supplement_tree = {
type = "tree",
container_parts = {
{
type = "doublet",
intro_text = config.text,
phrase = config.phrase,
term_parts = term_parts,
conj = config.default_conj or "และ",
new_sentence = true,
},
},
depth = 1,
}
end
elseif supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
supplement_tree = {
type = "tree",
container_parts = {
{
type = "etydate",
etydate_text = supplement.etydate_text,
etydate_refs = supplement.etydate_refs,
new_sentence = true,
},
},
depth = 1,
}
end
if supplement_tree then
table.insert(pending_trees, supplement_tree)
end
end
flush_pending_trees()
return table.concat(chunks, " ")
end
if not text_tree then
local supplement_text = assemble_supplements()
if supplement_text == "" then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
if stop_at_lang then
return supplement_text, { stop_lang_reached = false }
end
return supplement_text
end
local rendered = ""
if text_tree then
check_complexity(text_tree)
analyze_punctuation(text_tree, true)
apply_closing_punctuation_override(text_tree, not has_supplements())
rendered = assemble_text(text_tree)
end
local supplement_text = assemble_supplements()
if supplement_text ~= "" then
if rendered ~= "" then
rendered = rendered .. " " .. supplement_text
else
rendered = supplement_text
end
end
if stop_at_lang then
return rendered, { stop_lang_reached = stop_lang_reached }
end
return rendered
end
return export
mjy2c5es032jpncz1fs5jcmc87ez4a0
5775356
5775355
2026-10-15T06:50:09Z
Octahedron80
267
5775356
Scribunto
text/plain
local export = {}
local loader = require("Module:module loader")
local M = loader.init({
require = {
en_utilities = "Module:en-utilities",
references = "Module:references",
senseno = "Module:senseno",
},
loadData = {
data = "Module:etymon/data",
},
})
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local format_term_func = opts.format_term_func
local max_depth = opts.max_depth
local stop_at_blue_link = opts.stop_at_blue_link
local curr_page = opts.curr_page
local nodot = opts.nodot and opts.nodot ~= "" and opts.nodot ~= "0"
local function explicit_dot_override()
if opts.dot == nil or opts.dot == false then
return nil
end
local d = mw.text.trim(tostring(opts.dot))
if d == "" or d == "." then
return nil
end
return d
end
local dot_override = explicit_dot_override()
local function find_deepest_last_part(tree)
if not tree or not tree.container_parts or #tree.container_parts == 0 then
return nil
end
local last_part = tree.container_parts[#tree.container_parts]
if last_part.continuation then
return find_deepest_last_part(last_part.continuation)
end
return last_part
end
local function apply_final_punctuation_override(tree, punct)
if not tree or punct == nil then
return
end
local last_part = find_deepest_last_part(tree)
if last_part then
last_part.punctuation = punct
end
end
local function apply_closing_punctuation_override(tree, is_last_segment)
if not is_last_segment then
return
end
local punct
if nodot then
punct = ""
elseif dot_override ~= nil then
punct = dot_override
else
return
end
apply_final_punctuation_override(tree, punct)
end
local function has_supplements()
return data_tree.supplements and #data_tree.supplements > 0
end
local stop_at_lang = opts.stop_at_lang
local stop_at_lang_or_bluelink = opts.stop_at_lang_or_bluelink
local lang_matches_stop_code = opts.lang_matches_stop_code
local stop_lang_reached = false
local function term_matches_stop_code(term_lang, stop_code)
if lang_matches_stop_code then
return lang_matches_stop_code(term_lang, stop_code)
end
return term_lang and term_lang:getCode() == stop_code
end
local children = data_tree.children
local function has_text_supplements()
if not data_tree.supplements then
return false
end
for _, supplement in ipairs(data_tree.supplements) do
if supplement.type == "doublet" and supplement.terms and #supplement.terms > 0 then
return true
end
if supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
return true
end
end
return false
end
if (not children or #children == 0) and not has_text_supplements() then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
local entry_lang = data_tree.lang
local function lowercase_glossary_link_display(wikitext)
return wikitext:gsub("(%[%[ภาคผนวก:อภิธานศัพท์#[^|]+|)([^%]])([^%]]*)%]%]", function(prefix, first, rest)
return prefix .. mw.ustring.lower(first) .. rest .. "]]"
end)
end
local function format_sl_senseid_intro(senseid, keyword_text, keyword_phrase, capitalize_senseno, is_uncertain)
local senseids = mw.text.split(senseid, "!!", true)
local senseno_parts = {}
for i, id in ipairs(senseids) do
id = mw.text.trim(id)
if id ~= "" then
table.insert(senseno_parts, M.senseno.link_text(entry_lang:getCode(), { id }, {
title = curr_page,
uc = (i == 1 and capitalize_senseno) or nil,
}))
end
end
if #senseno_parts == 0 then
return keyword_text, keyword_phrase
end
local senseno_text = mw.text.listToText(senseno_parts)
local glossary_link = (keyword_text or ""):gsub("จาก$", "")
local glossary_lower = lowercase_glossary_link_display(glossary_link)
if #senseno_parts > 1 then
local plural_link = --[=[glossary_lower:gsub("|ยืมความหมาย%]%]", "|ยืมความหมาย]]")]=] "|ยืมความหมาย]]"
if is_uncertain then
return senseno_text .. " เป็นไปได้ว่า" .. plural_link .. "จาก",
senseno_text .. " เป็นไปได้ว่ายืมความหมายจาก"
end
return senseno_text .. " " .. plural_link .. "จาก",
senseno_text .. " ยืมความหมายจาก"
end
if is_uncertain then
return senseno_text .. " เป็นไปได้ว่า" .. glossary_lower .. "จาก",
senseno_text .. " เป็นไปได้ว่ายืมความหมายจาก"
end
return senseno_text .. " " .. glossary_lower .. "จาก",
senseno_text .. " ยืมความหมายจาก"
end
local function get_term_refs(term, defined_here)
if defined_here and term.refs and next(term.refs) then
return M.references.format_references(term.refs)
end
return ""
end
-- Build a text part for a single term
local function build_term_part(term, current_lang, defined_here)
local text = ""
local new_lang = current_lang
local lang_changed = term.lang:getCanonicalName() ~= current_lang:getCanonicalName()
-- Use centralized format_term (handles suppress_term, unknown_term, and regular terms)
local term_text = format_term_func(term)
if lang_changed then
new_lang = term.lang
if term_text then
text = term.lang:makeWikipediaLink() .. " " .. term_text
elseif term.is_family then
text = M.en_utilities.add_indefinite_article(term.lang:makeWikipediaLink() .. " language", false)
else
-- suppress_term with language change: show only language
text = term.lang:makeWikipediaLink()
end
else
text = term_text or ""
end
return {
type = "term",
text = text,
refs = get_term_refs(term, defined_here),
lang = new_lang,
is_uncertain = term.is_uncertain or false,
}
end
-- Build text parts for a container
local function build_container_part(container, node, depth, allow_continuation, fallback_to_bluelink)
local keyword_info = container.keyword_info
local keyword_modifiers = container.keyword_modifiers or {}
local terms = container.terms or {}
if not keyword_info or #terms == 0 then
return nil
end
-- Skip building text part when invisible in text ("all", "text", or true)
local inv = keyword_info.invisible
if inv == "all" or inv == true or inv == "text" then
return nil
end
local is_group = keyword_info.is_group
local keyword_uncertain = keyword_modifiers.unc or false
-- Determine text and phrase (allowing for overrides)
local intro_text = keyword_info.text
local phrase = keyword_info.phrase
local new_sentence = keyword_info.new_sentence or false
if keyword_modifiers.text then
-- User-provided override: assumed to be lowercase
phrase = keyword_modifiers.text
-- Auto-capitalize for intro text (e.g., "derived from" -> "Derived from")
intro_text = mw.ustring.upper(phrase:sub(1, 1)) .. phrase:sub(2)
end
local defined_here = (node.page_of or curr_page) == curr_page
-- Get keyword references
local keyword_refs = ""
if defined_here and keyword_modifiers.refs and next(keyword_modifiers.refs) then
keyword_refs = M.references.format_references(keyword_modifiers.refs)
end
-- Build term parts
local term_parts = {}
local current_lang = node.lang
for _, term in ipairs(terms) do
local term_part = build_term_part(term, current_lang, defined_here)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
current_lang = term_part.lang
end
end
-- Check uncertainty distribution
local uncertain_count = 0
for _, term_part in ipairs(term_parts) do
if term_part.is_uncertain then
uncertain_count = uncertain_count + 1
end
end
-- If keyword itself is uncertain, treat all terms as uncertain
local all_uncertain = keyword_uncertain or (uncertain_count == #term_parts and #term_parts > 0)
if is_group and uncertain_count > 0 then
all_uncertain = true
end
local has_mixed_uncertainty = not all_uncertain and uncertain_count > 0
-- Check if there are more steps (only if continuation is allowed)
local has_more_steps = false
local next_node = nil
local first_term = terms[1]
-- Check if we should stop at this language
local reached_stop_lang = false
if stop_at_lang then
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang) then
reached_stop_lang = true
stop_lang_reached = true
break
end
end
elseif stop_at_lang_or_bluelink then
-- Check if we should stop at this language, or at the first bluelink if it's a redlink
for _, term in ipairs(terms) do
if term.lang and term_matches_stop_code(term.lang, stop_at_lang_or_bluelink) then
if first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
else
fallback_to_bluelink = true
end
break
end
end
if fallback_to_bluelink and first_term.status == M.data.STATUS.OK then
reached_stop_lang = true
end
end
if allow_continuation and not is_group and #terms == 1 and not reached_stop_lang then
local first_term_children = first_term.children
if first_term_children and #first_term_children > 0 and (not max_depth or depth < max_depth) then
local next_container = first_term_children[1]
local next_keyword_info = next_container and next_container.keyword_info
if not (next_keyword_info and next_keyword_info.invisible) then
if stop_at_blue_link then
if first_term.status ~= M.data.STATUS.OK then
has_more_steps = true
next_node = first_term
end
else
has_more_steps = true
next_node = first_term
end
end
end
end
return {
type = "container",
intro_text = intro_text,
phrase = phrase,
senseid = keyword_modifiers.senseid,
sl_keyword_text = keyword_modifiers.senseid and keyword_info.text or nil,
is_uncertain = all_uncertain,
has_mixed_uncertainty = has_mixed_uncertainty,
term_parts = term_parts,
is_group = is_group,
has_more_steps = has_more_steps,
next_node = next_node,
new_sentence = new_sentence,
separate_clause = keyword_info.separate_clause or false,
conj = keyword_modifiers.conj or keyword_info.default_conj, -- custom conjunction: "and", "or", "and/or", etc.
lit = keyword_modifiers.lit,
keyword_refs = keyword_refs,
fallback_to_bluelink = fallback_to_bluelink,
}
end
-- Build the full tree of text parts
local function build_text_tree(node, depth, allow_continuation, fallback_to_bluelink)
local containers = node.children
if not containers or #containers == 0 then
return nil
end
local container_parts = {}
local function is_new_sentence(container)
return container.keyword_info and container.keyword_info.new_sentence or false
end
-- Count the containers that get a text part in the derivation's own sentence (invisible in text = "all",
-- "text", or true)
local visible_container_count = 0
for _, container in ipairs(containers) do
local keyword_info = container.keyword_info
local inv = keyword_info and keyword_info.invisible
if not (inv == "all" or inv == true or inv == "text") and not is_new_sentence(container) then
visible_container_count = visible_container_count + 1
end
end
-- If there are multiple visible containers in that sentence, don't allow continuation for any: alternatives
-- each name a different source, and an influence clause after a chain would read as influencing its last
-- step. A sentence of its own does not stop the derivation's chain.
local has_multiple_containers = visible_container_count > 1
local should_allow_continuation = allow_continuation and not has_multiple_containers
for _, container in ipairs(containers) do
local part = build_container_part(container, node, depth, should_allow_continuation and not is_new_sentence(container), fallback_to_bluelink)
if part then
-- Recursively build children if there are more steps
if part.has_more_steps and part.next_node then
part.continuation = build_text_tree(part.next_node, depth + 1, true, part.fallback_to_bluelink)
end
table.insert(container_parts, part)
end
end
if #container_parts == 0 then
return nil
end
return {
type = "tree",
container_parts = container_parts,
depth = depth,
}
end
-- Check if tree has mixed joining types
local function container_join_kind(part)
if part.type == "etydate" then
return nil
end
if part.new_sentence or part.separate_clause then
return "supplement"
end
return "or_join"
end
local function check_complexity(tree)
if not tree then return nil end
local parts = tree.container_parts
if #parts <= 1 then
-- Single container
if parts[1] and parts[1].continuation then
return check_complexity(parts[1].continuation)
end
return nil
end
-- Or-join containers must precede any supplemental (calque-like / influence) containers.
local seen_supplement = false
for _, part in ipairs(parts) do
local kind = container_join_kind(part)
if kind == "supplement" then
seen_supplement = true
elseif kind == "or_join" and seen_supplement then
error(
"Cannot generate etymology text: a main derivation step cannot follow a calque, semantic loan, or influence clause in the same list.")
end
end
for _, part in ipairs(parts) do
if part.continuation then
check_complexity(part.continuation)
end
end
return nil
end
-- Analyze tree and assign punctuation
local function analyze_punctuation(tree, is_toplevel)
if not tree then return end
local parts = tree.container_parts
local num_parts = #parts
for i, part in ipairs(parts) do
local is_first = (i == 1)
local is_last = (i == num_parts)
local next_part = parts[i + 1]
-- Analyze term punctuation within container
if part.term_parts then
-- Terms use Oxford comma style: "A, B, or C"
-- Custom conjunction can be specified via conj modifier (e.g., "and/or", "and")
local num_terms = #part.term_parts
local term_conj = part.conj or "หรือ" -- default to "or"
for j, term_part in ipairs(part.term_parts) do
local is_last_term = (j == num_terms)
if part.is_group then
-- Group: terms joined with " + "
term_part.joiner = is_last_term and "" or " + "
elseif num_terms > 1 then
-- Multiple terms not in a group: Oxford comma style
if is_last_term then
term_part.joiner = ""
elseif j == num_terms - 1 then
-- Second to last term
if num_terms == 2 then
term_part.joiner = " " .. term_conj .. " "
else
term_part.joiner = ", " .. term_conj .. " "
end
else
term_part.joiner = ", "
end
else
-- Single term
term_part.joiner = ""
end
end
end
-- Determine container punctuation based on what comes next
if part.continuation then
-- Has continuation
part.punctuation = ","
-- Recursively analyze continuation
analyze_punctuation(part.continuation, false)
elseif is_last then
-- Last container at this level (may still continue in part.continuation)
part.punctuation = "."
elseif next_part and next_part.new_sentence then
-- Next container starts a new sentence
part.punctuation = "."
elseif next_part and next_part.separate_clause then
-- Next container is a separate clause
part.punctuation = ","
else
-- Not last, next is joined with "or"
-- Containers use repeated "or" style: "A, or B, or C"
part.punctuation = ","
end
-- Determine joiner to next part
-- Containers use repeated "or" style: ", or" between each
-- Custom conjunction can be specified via conj modifier
local container_conj = part.conj or "หรือ" -- default to "or"
if not is_last then
if next_part and next_part.new_sentence then
-- New sentence
part.joiner = " "
elseif next_part and next_part.separate_clause then
-- Separate clause
part.joiner = " "
else
-- Same sentence: use custom conjunction or default "or"
part.joiner = " " .. container_conj .. " "
end
else
part.joiner = ""
end
-- Determine intro formatting
-- Capitalize if first at top level, OR if this container starts a new sentence
if (is_first and is_toplevel) or part.new_sentence then
part.intro_capitalized = true
part.use_full_intro = true
else
part.intro_capitalized = false
part.use_full_intro = false
end
end
end
-- Assemble text from analyzed tree
local function assemble_text(tree)
if not tree then return "" end
local result = ""
for i, part in ipairs(tree.container_parts) do
if part.type == "etydate" then
result = result .. part.etydate_text
if part.punctuation and part.punctuation ~= "" then
result = result .. part.punctuation
end
if part.etydate_refs and next(part.etydate_refs) then
result = result .. M.references.format_references(part.etydate_refs)
end
if part.joiner and part.joiner ~= "" then
result = result .. part.joiner
end
else
-- Build intro
local intro_text = part.intro_text
local phrase = part.phrase
if part.senseid then
intro_text, phrase = format_sl_senseid_intro(
part.senseid,
part.sl_keyword_text,
part.phrase,
part.intro_capitalized,
part.is_uncertain
)
end
local intro
if part.use_full_intro then
if part.is_uncertain and not part.senseid then
intro = "เป็นไปได้ว่า" .. phrase
else
intro = intro_text
end
else
if part.is_uncertain and not part.senseid then
intro = "เป็นไปได้ว่า" .. phrase
else
intro = phrase
end
end
result = result .. intro
-- Build terms
if #part.term_parts > 0 then
result = result .. " "
for j, term_part in ipairs(part.term_parts) do
-- Add "possibly" prefix for uncertain terms when there's mixed uncertainty
if part.has_mixed_uncertainty and term_part.is_uncertain then
result = result .. "เป็นไปได้ว่า"
end
result = result .. term_part.text
-- Add joiner between terms
if term_part.joiner ~= "" then
-- Check if joiner contains comma (punctuation)
local comma_pos = term_part.joiner:find(",")
if comma_pos then
-- Add up to and including comma
result = result .. term_part.joiner:sub(1, comma_pos)
-- Add refs after comma
if term_part.refs ~= "" then
result = result .. term_part.refs
end
-- Add rest of joiner
result = result .. term_part.joiner:sub(comma_pos + 1)
else
-- No comma, add refs before joiner
if term_part.refs ~= "" then
result = result .. term_part.refs
end
result = result .. term_part.joiner
end
end
end
-- For the last term, add punctuation then refs
local last_term = part.term_parts[#part.term_parts]
if last_term and last_term.joiner == "" then
if part.punctuation ~= "" then
-- If we have literal text, punctuation goes AFTER it
if part.lit then
-- Add refs first (attached to term)
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text
result = result .. ", แปลตามตัวอักษรว่า “" .. part.lit .. "”"
-- Add punctuation
result = result .. part.punctuation
else
-- Normal behavior: punctuation then refs
result = result .. part.punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs after term refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
else
-- No punctuation
if last_term.refs ~= "" then
result = result .. last_term.refs
end
-- Add keyword refs
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
-- Add literal text if present (even without punctuation)
if part.lit then
result = result .. ", แปลตามตัวอักษรว่า “" .. part.lit .. "”"
end
end
end
else
-- No terms, just add punctuation and keyword refs
if part.punctuation ~= "" then
result = result .. part.punctuation
end
-- Add keyword refs even when there are no terms
if part.keyword_refs and part.keyword_refs ~= "" then
result = result .. part.keyword_refs
end
end
-- Add continuation
if part.continuation then
result = result .. " " .. assemble_text(part.continuation)
end
-- Add joiner to next container
if part.joiner ~= "" then
result = result .. part.joiner
end
end
end
return result
end
local text_tree = build_text_tree(data_tree, 1, true, false)
-- Supplements (doublets, etydate, …) are rendered outside the main derivation text tree.
local function assemble_supplements()
if not data_tree.supplements then
return ""
end
local chunks = {}
local pending_trees = {}
local function flush_pending_trees()
local num = #pending_trees
for i, supplement_tree in ipairs(pending_trees) do
analyze_punctuation(supplement_tree, true)
apply_closing_punctuation_override(supplement_tree, i == num)
local chunk = assemble_text(supplement_tree)
if chunk ~= "" then
table.insert(chunks, chunk)
end
end
pending_trees = {}
end
for _, supplement in ipairs(data_tree.supplements) do
local supplement_tree
if supplement.type == "doublet" and supplement.config
and supplement.terms and #supplement.terms > 0 then
local config = supplement.config
local term_parts = {}
for _, term in ipairs(supplement.terms) do
local term_part = build_term_part(term, entry_lang, true)
if term_part.text ~= "" then
table.insert(term_parts, term_part)
end
end
if #term_parts == 0 then
supplement_tree = nil
else
supplement_tree = {
type = "tree",
container_parts = {
{
type = "doublet",
intro_text = config.text,
phrase = config.phrase,
term_parts = term_parts,
conj = config.default_conj or "และ",
new_sentence = true,
},
},
depth = 1,
}
end
elseif supplement.type == "etydate" and supplement.etydate_text and supplement.etydate_text ~= "" then
supplement_tree = {
type = "tree",
container_parts = {
{
type = "etydate",
etydate_text = supplement.etydate_text,
etydate_refs = supplement.etydate_refs,
new_sentence = true,
},
},
depth = 1,
}
end
if supplement_tree then
table.insert(pending_trees, supplement_tree)
end
end
flush_pending_trees()
return table.concat(chunks, " ")
end
if not text_tree then
local supplement_text = assemble_supplements()
if supplement_text == "" then
if stop_at_lang then
return "", { stop_lang_reached = false }
end
return ""
end
if stop_at_lang then
return supplement_text, { stop_lang_reached = false }
end
return supplement_text
end
local rendered = ""
if text_tree then
check_complexity(text_tree)
analyze_punctuation(text_tree, true)
apply_closing_punctuation_override(text_tree, not has_supplements())
rendered = assemble_text(text_tree)
end
local supplement_text = assemble_supplements()
if supplement_text ~= "" then
if rendered ~= "" then
rendered = rendered .. " " .. supplement_text
else
rendered = supplement_text
end
end
if stop_at_lang then
return rendered, { stop_lang_reached = stop_lang_reached }
end
return rendered
end
return export
eb0rob1g8lwo0m8whlgct1kxeq77yma
มอดูล:etymon/tree
828
2297438
5775357
5754449
2026-10-15T06:54:32Z
Octahedron80
267
5775357
Scribunto
text/plain
local export = {}
local html_create = mw.html.create
local max = math.max
local function create_vertical_connector()
return html_create('span'):addClass('etytree-connector-vertical')
end
local function create_abbr(text, title, glossary)
local abbr = html_create('abbr')
:attr('title', title)
:wikitext(text)
if glossary then
abbr = '[[ภาคผนวก:อภิธานศัพท์#' .. glossary .. '|' .. tostring(abbr) .. ']]'
end
return html_create('span'):addClass('etytree-label'):node(abbr)
end
local function create_uncertainty_marker()
return html_create('abbr')
:addClass('etytree-unc')
:attr('title', 'uncertain')
:wikitext('?')
end
local function create_label_container()
return html_create('span'):addClass('etytree-label-container')
end
local function invisible_in_tree(inv)
return inv == "all" or inv == true or inv == "tree"
end
local function render_label(term_block, keyword_info, keyword_modifiers, is_uncertain, is_group_child, term_labels)
-- Skip label when invisible in tree
local has_label = keyword_info and keyword_info.abbrev and not is_group_child and not invisible_in_tree(keyword_info.invisible)
-- For group children, keyword uncertainty is shown on the group label, not on individual terms
local keyword_uncertain = keyword_modifiers and keyword_modifiers.unc and not is_group_child
local show_term_uncertainty = is_uncertain
-- Check if we have term-specific labels
local has_term_labels = term_labels and #term_labels > 0
if not has_label and not show_term_uncertainty and not keyword_uncertain and not has_term_labels then
return
end
local label_span = create_label_container()
if has_label then
local glossary_title = keyword_info.glossary
and keyword_info.glossary:gsub("_", " ")
or keyword_info.abbrev
label_span:node(create_abbr(
keyword_info.abbrev,
glossary_title,
keyword_info.glossary
))
-- Show uncertainty marker if term or keyword is uncertain
if show_term_uncertainty or keyword_uncertain then
label_span:node(create_uncertainty_marker())
end
else
-- No label, but term or keyword is uncertain
if show_term_uncertainty or keyword_uncertain then
label_span:node(create_uncertainty_marker())
end
end
-- Add term-specific labels
if has_term_labels then
for _, label_info in ipairs(term_labels) do
label_span:node(create_abbr(label_info.abbrev, label_info.title, label_info.glossary))
end
end
term_block:node(label_span)
end
local function render_term_block(node_data, format_term_func, is_toplevel)
local link_content = html_create()
link_content
:tag('span')
:addClass('etyl')
:wikitext(node_data.lang:getCanonicalName())
:done()
local term_text = format_term_func(node_data, is_toplevel)
if term_text then
link_content
:wikitext(' ')
:tag('span')
:addClass('etytree-term')
:wikitext(term_text)
:done()
end
local block = html_create('div'):addClass('etytree-block'):node(link_content)
-- Add duplicate styling if this is a duplicate node
if node_data.is_duplicate then
block:addClass('etytree-duplicate')
end
return block
end
local function create_dotted_connector()
return html_create('span'):addClass('etytree-connector-dotted')
end
-- Create an L-shaped connector for nodes with hidden ancestry (duplicate or no_child_categories)
local function create_duplicate_connector()
local container = html_create('div'):addClass('etytree-duplicate-connector')
local inner_wrapper = container:tag('div')
inner_wrapper:tag('span'):addClass('etytree-dup-right')
inner_wrapper:tag('span'):addClass('etytree-dup-horiz')
inner_wrapper:tag('span'):addClass('etytree-dup-left')
inner_wrapper:tag('span'):addClass('etytree-dup-arrow'):wikitext('▲')
return container
end
local function render_group_label(connecting_line, keyword_info, keyword_modifiers)
local has_abbrev = keyword_info and keyword_info.abbrev
local keyword_uncertain = keyword_modifiers and keyword_modifiers.unc
-- Nothing to show if no abbrev and no uncertainty
if not has_abbrev and not keyword_uncertain then
return
end
local label_span = connecting_line:tag('span'):addClass('etytree-group-label')
if has_abbrev then
local glossary_title = keyword_info.glossary
and keyword_info.glossary:gsub("_", " ")
or keyword_info.abbrev
label_span:node(create_abbr(keyword_info.abbrev, glossary_title, nil))
end
-- Add uncertainty marker if keyword has <unc> modifier
if keyword_uncertain then
label_span:node(create_uncertainty_marker())
end
end
local function add_branch_connector(column, index, total)
if index == 1 then
column:tag('span'):addClass('etytree-branch-left')
elseif index == total then
column:tag('span'):addClass('etytree-branch-right')
else
column:tag('span'):addClass('etytree-connector-vertical-short')
column:tag('span'):addClass('etytree-branch-mid')
end
end
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local format_term_func = opts.format_term_func
-- Forward declaration
local render_term
-- Render a container (keyword + its terms)
local function render_container(container, is_toplevel)
local keyword_info = container.keyword_info
local keyword_modifiers = container.keyword_modifiers or {}
local is_group = keyword_info and keyword_info.is_group
local terms = container.terms or {}
-- Skip container entirely only when invisible = "all" (or true)
if keyword_info and invisible_in_tree(keyword_info.invisible) then
return nil, 0, 0
end
if #terms == 0 then
return nil, 0, 0
end
-- For no_child_categories keywords (calque, semantic loan, etc.), don't render term's children
local skip_child_rendering = keyword_info and keyword_info.no_child_categories
-- Render each term in the container
local rendered_terms = {}
local container_height = 0
local container_width = 0
for _, term in ipairs(terms) do
-- Collect term-specific labels
local term_labels = {}
if term.bor then
table.insert(term_labels, { abbrev = "bor.", title = "ยืมมา", glossary = "loanword" })
end
if term.slbor then
table.insert(term_labels, { abbrev = "slbor.", title = "ยืมโดยกึ่งเรียนรู้", glossary = "semi-learned_borrowing" })
end
if term.lbor then
table.insert(term_labels, { abbrev = "lbor.", title = "ยืมโดยเรียนรู้", glossary = "learned_borrowing" })
end
local term_tree, term_height, term_width = render_term(term, keyword_info, keyword_modifiers, is_group, false, skip_child_rendering, term_labels)
table.insert(rendered_terms, {
tree = term_tree,
height = term_height,
width = term_width,
is_uncertain = term.is_uncertain,
})
container_height = max(container_height, term_height)
container_width = container_width + term_width
end
local rendered_html
local has_connector = false
if #rendered_terms == 1 then
-- Single term: just return it directly
rendered_html = rendered_terms[1].tree
container_height = rendered_terms[1].height
container_width = rendered_terms[1].width
else
-- Multiple terms: group them together
local subtree_container = html_create('div'):addClass('etytree-branch-group')
for i, term_data in ipairs(rendered_terms) do
local column = html_create('div'):addClass('etytree-branch')
column:node(term_data.tree)
add_branch_connector(column, i, #rendered_terms)
subtree_container:node(column)
end
local connecting_line = create_vertical_connector()
-- Add group label for group keywords
if is_group and not invisible_in_tree(keyword_info.invisible) then
render_group_label(connecting_line, keyword_info, keyword_modifiers)
end
rendered_html = html_create()
:node(subtree_container)
:node(connecting_line)
has_connector = true
end
return rendered_html, container_height, container_width, has_connector
end
-- Render a term node
render_term = function(term_node, keyword_info, keyword_modifiers, is_group_child, is_toplevel_term, skip_child_rendering, term_labels)
local tree_width, tree_height = 0, 0
local subtrees = {}
-- Process term's children (which are containers)
local has_hidden_children = false
if not term_node.is_duplicate and not skip_child_rendering then
for _, container in ipairs(term_node.children or {}) do
local subtree, sub_height, sub_width, subtree_has_connector = render_container(container, is_toplevel_term)
if subtree then
table.insert(subtrees, {
tree = subtree,
height = sub_height,
width = sub_width,
has_connector = subtree_has_connector,
})
tree_height = max(tree_height, sub_height)
tree_width = tree_width + sub_width
end
end
elseif skip_child_rendering then
-- Check if there are any visible children
-- When stop_recursion is true, children aren't parsed, but has_visible_children flag is set
if term_node.has_visible_children then
has_hidden_children = true
elseif term_node.children and #term_node.children > 0 then
-- Fallback: check parsed children for visibility
for _, container in ipairs(term_node.children) do
local child_keyword_info = container.keyword_info
if not (child_keyword_info and (child_keyword_info.invisible == "all" or child_keyword_info.invisible == true)) then
has_hidden_children = true
break
end
end
end
end
local is_toplevel_node = (keyword_info == nil)
local term_block = render_term_block(term_node, format_term_func, is_toplevel_node)
render_label(term_block, keyword_info, keyword_modifiers, term_node.is_uncertain, is_group_child, term_labels or {})
local term_html = html_create()
if #subtrees == 0 then
local show_connector = (term_node.is_duplicate and term_node.original_has_children) or has_hidden_children
if show_connector then
term_html:node(create_duplicate_connector())
end
term_html:node(term_block)
tree_width = tree_width + 1
elseif #subtrees == 1 then
term_html:node(subtrees[1].tree)
if not subtrees[1].has_connector then
term_html:node(create_vertical_connector())
end
term_html:node(term_block)
else
-- Multiple containers: need to merge them
local subtree_container = html_create('div'):addClass('etytree-branch-group')
for i, subtree_data in ipairs(subtrees) do
local column = html_create('div'):addClass('etytree-branch')
column:node(subtree_data.tree)
add_branch_connector(column, i, #subtrees)
subtree_container:node(column)
end
local connecting_line = create_vertical_connector()
term_html
:node(subtree_container)
:node(connecting_line)
:node(term_block)
end
return term_html, tree_height + 1, tree_width
end
local final_tree, final_height, final_width = render_term(data_tree, nil, nil, false, true)
local container = html_create('div')
:addClass('etytree-body')
:node(final_tree)
return tostring(html_create('div')
:addClass('etytree NavFrame')
:attr('data-etytree-height', final_height)
:attr('data-etytree-width', final_width)
:tag('div')
:addClass('NavHead')
:tag('div')
:wikitext('แผนผังรากศัพท์')
:done()
:done()
:tag('div')
:addClass('NavContent')
:node(container)
:done())
end
return export
7dkz3nprcyhdb23jueq38l6ewyv3ek6
มอดูล:etymon/categories
828
2297439
5775312
5775229
2026-10-15T02:19:39Z
Octahedron80
267
5775312
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
etymology = "Module:etymology",
affix = "Module:affix",
etymology_specialized = "Module:etymology/specialized",
utilities = "Module:utilities",
roots = "Module:roots",
},
loadData = {
data = "Module:etymon/data",
},
})
-- Evaluate whether a keyword is transitive for a given term
local function is_transitive(transitive_mode, page_lang, term_lang)
if transitive_mode == M.data.TRANSITIVE.ALWAYS then
return true
elseif transitive_mode == M.data.TRANSITIVE.NEVER then
return false
elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG then
return page_lang:getCode() ~= term_lang:getCode()
elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
return page_lang:getCode() ~= term_lang:getCode()
end
error("Unknown transitive mode: " .. tostring(transitive_mode))
end
-- Get keyword config with language-specific overrides
local function get_keyword_config(keyword, lang_exc)
local base_config = M.data.keywords[keyword]
if not base_config then
return nil -- Invalid keyword
end
local overrides = lang_exc and lang_exc.keyword_overrides and lang_exc.keyword_overrides[keyword]
if not overrides then
return base_config
end
-- Merge overrides into base config
local merged = {}
for k, v in pairs(base_config) do
merged[k] = v
end
for k, v in pairs(overrides) do
merged[k] = v
end
return merged
end
function export.get_cat_name(source)
local _, cat_name = M.etymology.get_display_and_cat_name(source, true)
return cat_name
end
-- Normalize affix type aliases
local function add_category(categories, cat_name, sort_key, sort_base)
if categories[cat_name] == nil then
categories[cat_name] = {
sort_key = sort_key,
sort_base = sort_base,
}
return
end
local existing = categories[cat_name]
if existing.sort_key == nil and sort_key ~= nil then
existing.sort_key = sort_key
end
if existing.sort_base == nil and sort_base ~= nil then
existing.sort_base = sort_base
end
end
-- Collect affix categories from top-level group containers
local function collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc)
local parts = {}
local part_index = 1
for _, container in ipairs(node.children or {}) do
local config = container.keyword_info
if config and config.affix_categories then
for _, term in ipairs(container.terms or {}) do
if not term.unknown_term then
local part_data = {
term = term.title,
tr = term.tr,
ts = term.ts,
alt = term.alt,
itemno = part_index,
orig_index = part_index
}
-- Determine affix type: explicit aftype > pos=root > auto-detect
local aftype = term.aftype
if aftype then
aftype = M.data.aftype_aliases[aftype] or aftype
part_data.type = aftype
elseif term.args and term.args.pos and (term.args.pos == "root" or term.args.pos == "ราก") then
part_data.type = "ไม่ใช่หน่วยคำเติม"
end
if term.lang:getCode() ~= page_lang:getCode() then
part_data.lang = term.lang
end
local target_ids = available_etymon_ids[term.target_key]
local has_multiple_ids = target_ids and #target_ids > 1
local id_exists_in_disambiguation = false
local matched_id = nil
-- Count available senseids for the target page
local senseid_count = 0
local target_prefix = term.target_key .. ":"
if senseid_parent_etymon then
for key, _ in pairs(senseid_parent_etymon) do
if key:sub(1, #target_prefix) == target_prefix then
senseid_count = senseid_count + 1
end
end
end
local has_multiple_senseids = senseid_count > 1
if term.id then
-- Check if user provided a valid senseid
local senseid_key = term.target_key .. ":" .. term.id
if senseid_parent_etymon and senseid_parent_etymon[senseid_key] then
if has_multiple_senseids then
-- Ambiguous senseid: use senseid
matched_id = term.id
id_exists_in_disambiguation = true
elseif has_multiple_ids then
-- Unique senseid but ambiguous etymon: use etymon ID
matched_id = term.etymon_id or term.id
id_exists_in_disambiguation = true
end
else
-- Check if user provided a valid etymon ID
if has_multiple_ids and target_ids then
for _, id_data in ipairs(target_ids) do
local stored_id = type(id_data) == "table" and id_data.id or id_data
if stored_id == term.id then
-- Ambiguous etymon: use etymon ID
id_exists_in_disambiguation = true
matched_id = term.id
break
end
end
end
-- Fallback: check resolved etymon_id (e.g. from previous steps)
if not id_exists_in_disambiguation and has_multiple_ids and term.etymon_id and target_ids then
for _, id_data in ipairs(target_ids) do
local stored_id = type(id_data) == "table" and id_data.id or id_data
if stored_id == term.etymon_id then
id_exists_in_disambiguation = true
matched_id = term.etymon_id
break
end
end
end
end
end
-- Use the matched ID if found
if term.override or id_exists_in_disambiguation then
part_data.id = matched_id or term.id
end
table.insert(parts, part_data)
part_index = part_index + 1
end
end
end
end
if #parts == 0 then return {} end
local affix_data = {
lang = page_lang,
parts = parts,
pos = "ศัพท์",
sort_key = nil,
}
if #parts == 1 then
affix_data.allow_no_affixes_or_compounds = true
end
local affix_categories = M.affix.get_affix_categories_only(affix_data)
local result = {}
for _, cat in ipairs(affix_categories) do
if type(cat) == "table" then
table.insert(result, { cat = cat.cat, sort_key = cat.sort_key, sort_base = cat.sort_base })
else
table.insert(result, { cat = cat })
end
end
return result
end
local function lang_is_source(page_lang, source)
return page_lang:getCode() == source:getCode() or page_lang:hasParent(source)
end
local function is_borrowing_keyword_config(config)
return config and (config.borrowing_type or config.specialized_borrowing)
end
local function add_reborrow_category(categories, page_lang)
local lang_name = page_lang:getCategoryName() --th
add_category(categories, lang_name .. " terms borrowed back into " .. lang_name)
end
local function borrow_returns_to_page_lang(page_lang, source, in_foreign_branch)
if not in_foreign_branch then
return false
end
if source:getFullCode() == page_lang:getFullCode() then
return true
end
return page_lang:hasParent(source)
end
local function node_borrows_from_lang(node, page_lang, visited, in_foreign_branch)
visited = visited or {}
if not node or visited[node] then
return false
end
visited[node] = true
if node.is_duplicate then
if node.duplicate_of then
return node_borrows_from_lang(node.duplicate_of, page_lang, visited, in_foreign_branch)
end
return false
end
local node_is_foreign = in_foreign_branch
or (node.lang and node.lang:getFullCode() ~= page_lang:getFullCode())
for _, container in ipairs(node.children or {}) do
if is_borrowing_keyword_config(container.keyword_info) then
for _, child_term in ipairs(container.terms or {}) do
if borrow_returns_to_page_lang(page_lang, child_term.lang, node_is_foreign) then
return true
end
end
end
for _, child_term in ipairs(container.terms or {}) do
if child_term.status == M.data.STATUS.OK or child_term.status == M.data.STATUS.INLINE then
if node_borrows_from_lang(child_term, page_lang, visited, node_is_foreign) then
return true
end
end
end
end
return false
end
local function should_add_reborrow_category(page_lang, term)
if page_lang:getCode() == term.lang:getCode() then
return false
end
if term.status ~= M.data.STATUS.OK and term.status ~= M.data.STATUS.INLINE then
return false
end
return node_borrows_from_lang(term, page_lang, {}, false)
end
-- Add borrowing-related categories (top-level only)
local function collect_borrowing_categories(categories, page_lang, term, config, check_reborrow_path)
if check_reborrow_path and should_add_reborrow_category(page_lang, term) then
add_reborrow_category(categories, page_lang)
end
if config.borrowing_type == "ยืมมา" and not lang_is_source(page_lang, term.lang) then
local temp_categories = {}
M.etymology.insert_borrowed_cat(temp_categories, page_lang, term.lang)
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
if config.specialized_borrowing and not lang_is_source(page_lang, term.lang) then
local _, cat_names = M.etymology_specialized.specialized_borrowing {
bortype = config.specialized_borrowing,
lang = page_lang,
sources = { term.lang },
terms = { { lang = term.lang, term = "-" } },
notext = true,
}
for _, cat_name in ipairs(cat_names) do
add_category(categories, cat_name)
end
end
end
-- Add source-based derivation categories (top-level only)
local function collect_source_derivation_categories(categories, page_lang, term, config)
if not config.source_category_type then
return
end
local temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
borrowing_type = config.source_category_type,
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
-- Add source language categories
local function collect_source_categories(categories, page_lang, term, chain, get_norm_lang_func)
if page_lang:getCode() == get_norm_lang_func(term.lang):getCode() then
return
end
local temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
if chain.inherited then
temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
borrowing_type = "สืบทอด",
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
end
-- Add root/word categories
local function collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, chain,
get_norm_lang_func, lang_exc, keyword)
local pos_types = { root = "ราก", word = "คำ" }
-- Determine pos: from term's postype, keyword's pos_override, or args.pos
local pos
local config = get_keyword_config(keyword, lang_exc)
if term.postype then
-- Term-level postype modifier takes highest priority
pos = term.postype
elseif config and config.pos_override then
pos = config.pos_override
elseif type(term.args) == "table" and term.args.pos then
pos = term.args.pos
end
local pos_type = pos_types[pos]
if not pos_type or term.unknown_term then
return
end
-- Skip root/word categories for descendants of affix groups
-- if pos_type then
-- return
-- end
local same_language = get_norm_lang_func(page_lang):getFullCode() == get_norm_lang_func(term.lang):getFullCode()
-- Skip self-references
if same_language and root_title == term.title then
return
end
local entry_name
if pos_type == "root" or pos_type == "ราก" then
entry_name = term.title
M.roots.assert_root(term.lang, entry_name)
else
entry_name = term.lang:makeEntryName(term.title)
end
local lang_name = page_lang:getCategoryName() --th
local cat_name
if chain.passed_through then
local etymon_lang_name = export.get_cat_name(term.lang)
cat_name = "ศัพท์ภาษา" .. lang_name .. "ที่รับมาจาก" .. pos_type .. "ภาษา" .. etymon_lang_name .. " " .. entry_name
else
cat_name = "ศัพท์ภาษา" .. lang_name .. "ที่เป็นของ" .. pos_type .. " " .. entry_name
end
-- Add ID disambiguation if needed (for roots/words: use etymon_id if resolved via senseid, otherwise use id)
local target_ids = available_etymon_ids[term.target_key]
local effective_id = term.etymon_id or term.id -- etymon_id if senseid, otherwise id is already an etymon id
if target_ids and effective_id then
local same_pos_count = 0
for _, id_data in ipairs(target_ids) do
if type(id_data) == "table" and id_data.pos == pos then
same_pos_count = same_pos_count + 1
end
end
if same_pos_count > 1 then
cat_name = cat_name .. " (" .. effective_id .. ")"
end
end
add_category(categories, cat_name)
end
-- Compute chain state for a term based on parent chain and keyword config
-- Hyphen patterns for affix detection (regular hyphen + script-specific)
local AFFIX_HYPHEN_PATTERN = "[%-%־ـ᠊]" -- regular hyphen, Hebrew maqqef, Arabic tatweel, Mongolian hyphen
-- Check if a term is an actual affix (not a non-affix member of an affix group)
local function is_actual_affix(term)
-- Check explicit aftype modifier
if term.aftype then
local normalized = M.data.aftype_aliases[term.aftype] or term.aftype
return normalized ~= "ไม่ใช่หน่วยคำเติม"
end
-- Check if pos=root (treated as non-affix)
if term.args and term.args.pos and (term.args.pos == "root" or term.args.pos == "ราก") then
return false
end
-- Auto-detect by hyphen: prefix ends with -, suffix starts with -, etc.
if term.title then
local title = term.title
-- Strip leading * for reconstructed terms before checking hyphens
title = title:gsub("^%*", "")
-- Check for hyphens at start or end (handles script-specific hyphens too)
if title:match("^" .. AFFIX_HYPHEN_PATTERN) or title:match(AFFIX_HYPHEN_PATTERN .. "$") then
return true
end
end
-- Default: not an affix
return false
end
local function compute_category_chain(parent_chain, config, page_lang, term_lang, get_norm_lang_func, parent_term_lang, term)
-- Track if we're inside an actual affix (for suppressing root categories on descendants)
-- Only set if the term is an actual affix (prefix, suffix, etc.), not a non-affix member
local inside_affix = parent_chain.inside_affix
if config.affix_categories and term and is_actual_affix(term) then
inside_affix = true
end
-- If no_child_categories is set, disable everything
if config.no_child_categories then
return {
passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(),
inherited = false,
source = false,
pos = false,
recurse = false,
inside_affix = inside_affix,
}
end
local term_is_transitive = is_transitive(config.transitive, page_lang, term_lang)
local new_source = parent_chain.source and term_is_transitive
-- For CROSS_LANG_NO_INTERNAL_SOURCE: track internal derivation language context
-- Check if this term is internal relative to parent term's language (if parent_term_lang provided)
-- or relative to page language (if no parent_term_lang)
local internal_lang = parent_chain.internal_lang
local is_internal_in_context = false
if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
local check_lang = parent_term_lang or page_lang
local term_lang_code = get_norm_lang_func(term_lang):getCode()
local check_lang_code = get_norm_lang_func(check_lang):getCode()
if internal_lang then
-- Already in an internal derivation context: check if this term is also internal
is_internal_in_context = term_lang_code == internal_lang
else
-- Check if this term is internal relative to parent term (or page if no parent)
is_internal_in_context = term_lang_code == check_lang_code
end
end
-- Source chain behavior for CROSS_LANG_NO_INTERNAL_SOURCE
if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
if is_internal_in_context then
-- Internal derivation
new_source = false
internal_lang = get_norm_lang_func(term_lang):getCode()
else
-- Cross-language
new_source = parent_chain.source and term_is_transitive
internal_lang = nil
end
end
local new_pos = parent_chain.pos
return {
passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(),
inherited = parent_chain.inherited and config.inherited_chain,
source = new_source,
pos = new_pos,
internal_lang = internal_lang,
recurse = new_source or new_pos,
inside_affix = inside_affix,
}
end
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local page_lang = opts.page_lang
local available_etymon_ids = opts.available_etymon_ids
local senseid_parent_etymon = opts.senseid_parent_etymon
local get_norm_lang_func = opts.get_norm_lang_func
local lang_exc = opts.lang_exc
local categories = {}
local seen = {}
local lang_name = page_lang:getCategoryName() --th
local root_title = data_tree.title
-- Collect the tree recursively
local function collect(node, parent_chain, is_toplevel)
-- Avoid processing same node twice
if not node.unknown_term and node.title then
local key = node.lang:getFullCode() .. ":" .. (node.title or "") .. ":" .. (node.id or "")
if seen[key] then return end
seen[key] = true
end
-- Collect affix categories at top level only
if is_toplevel then
local affix_cats = collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc)
for _, cat in ipairs(affix_cats) do
--add_category(categories, lang_name .. " " .. cat.cat, cat.sort_key, cat.sort_base)
add_category(categories, require("Module:th-utilities").th_categorize(cat.cat, lang_name), cat.sort_key, cat.sort_base)
end
if node.supplements then
for _, supplement in ipairs(node.supplements) do
local config = supplement.config
if config and config.toplevel_category then
--add_category(categories, lang_name .. " " .. config.toplevel_category)
add_category(categories, require("Module:th-utilities").th_categorize(config.toplevel_category, lang_name))
end
end
end
end
-- Process each container
for _, container in ipairs(node.children or {}) do
local keyword = container.keyword
local config = get_keyword_config(keyword, lang_exc)
-- Skip invalid keywords
if config then
-- Process each term in the container
for _, term in ipairs(container.terms or {}) do
local term_chain = compute_category_chain(parent_chain, config, page_lang, term.lang, get_norm_lang_func, node.lang, term)
local no_child_categories = config.no_child_categories == true
local term_is_transitive = is_transitive(config.transitive, page_lang, term.lang)
-- Top-level only processing
if is_toplevel then
-- Missing/ambiguous etymon tracking
if not term.unknown_term and (term.status == M.data.STATUS.MISSING or term.status == M.data.STATUS.REDLINK) then
add_category(categories, lang_name .. " entries referencing missing etymons")
end
if not term.unknown_term and term.status == M.data.STATUS.AMBIGUOUS then
add_category(categories, lang_name .. " entries referencing ambiguous etymons")
end
if term.missing_descendants_header then
add_category(categories, lang_name .. " entries referencing etymons without Descendants sections")
end
if term.missing_descendants_entry then
add_category(categories, lang_name .. " entries referencing etymons without this term in Descendants sections")
end
-- Top-level category (e.g., "undefined derivations")
if config.toplevel_category then
add_category(categories, lang_name .. " " .. config.toplevel_category)
end
-- Borrowing categories (bor, lbor, slbor, ubor, obor)
if config.borrowing_type or config.specialized_borrowing then
collect_borrowing_categories(categories, page_lang, term, config, true)
end
-- Borrowing categories from <bor>, <lbor>, or <slbor> modifiers on affix-group terms
local kw_config = M.data.keywords[keyword]
if kw_config and kw_config.affix_categories then
if term.bor then
local bor_config = { borrowing_type = "ยืมมา" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
elseif term.lbor then
local bor_config = { specialized_borrowing = "learned" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
elseif term.slbor then
local bor_config = { specialized_borrowing = "semi-learned" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
end
end
-- Source-based derivation categories (sl, calque, pcal)
if config.source_category_type then
collect_source_derivation_categories(categories, page_lang, term, config)
end
-- Skip all child categorisation if no_child_categories is set
if not no_child_categories then
-- Source categories only if transitive
if term_is_transitive then
collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func)
end
-- Pos categories always (unless no_child_categories)
collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain,
get_norm_lang_func, lang_exc, keyword)
end
else
-- Below top level, respect the parent chain
if parent_chain.source then
collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func)
end
if parent_chain.pos then
collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain,
get_norm_lang_func, lang_exc, keyword)
end
end
-- Recurse into term's children if needed and status allows
if term_chain.recurse and (term.status == M.data.STATUS.OK or term.status == M.data.STATUS.INLINE) then
collect(term, term_chain, false)
end
end
end
end
end
-- Initial chain state
local initial_chain = {
passed_through = false,
inherited = true,
source = true,
pos = true,
internal_lang = nil,
recurse = true,
inside_affix = false,
}
collect(data_tree, initial_chain, true)
local cat_list = {}
for cat_name, sort_data in pairs(categories) do
if sort_data.sort_key ~= nil or sort_data.sort_base ~= nil then
table.insert(cat_list, {
name = cat_name,
sort_key = sort_data.sort_key,
sort_base = sort_data.sort_base,
})
else
table.insert(cat_list, cat_name)
end
end
return cat_list
end
function export.build(opts)
opts = opts or {}
local categories = {}
if not opts.suppress_categories and not opts.nocat then
categories = export.render({
data_tree = opts.data_tree,
page_lang = opts.page_lang,
available_etymon_ids = opts.available_etymon_ids,
senseid_parent_etymon = opts.senseid_parent_etymon,
get_norm_lang_func = opts.get_norm_lang_func,
lang_exc = opts.lang_exc,
})
end
local page_lang = opts.page_lang
if not page_lang then
return categories
end
local lang_name = page_lang:getCategoryName() --th
table.insert(categories, "Pages with etymon")
table.insert(categories, lang_name .. " entries with etymon")
if opts.tree then
table.insert(categories, "Pages with etymology trees")
table.insert(categories, lang_name .. " entries with etymology trees")
end
if opts.text then
table.insert(categories, lang_name .. " entries with etymology texts")
end
if opts.exnihilo then
table.insert(categories, lang_name .. " terms coined ex nihilo")
end
if opts.toplevel_has_inline_etymology then
table.insert(categories, "Pages with inline etymon for redlinks")
end
if opts.toplevel_redundant_etymology then
table.insert(categories, "Pages with redundant inline etymon")
end
if opts.toplevel_idless_etymon then
table.insert(categories, "Pages using etymon with no ID")
end
if opts.has_mismatched_id then
table.insert(categories, lang_name .. " entries referencing etymons with mismatched IDs")
end
if opts.linked_page_multiple_etymons_idless then
table.insert(categories,
lang_name .. " entries referencing pages with multiple etymons missing IDs")
end
if opts.linked_page_partial_etymology_sections then
table.insert(categories,
lang_name .. " entries referencing pages with etymology sections missing etymons")
end
if opts.text_stop_lang_missing then
table.insert(categories, "Pages with etymology text stop language not in chain")
table.insert(categories, lang_name .. " entries with etymology text stop language not in chain")
end
return categories
end
function export.format(entries, lang)
if type(entries) ~= "table" or #entries == 0 then
return ""
end
local parts = {}
for _, category in ipairs(entries) do
if type(category) == "table" and type(category.name) == "string" then
table.insert(parts, M.utilities.format_categories({ category.name }, lang, category.sort_key, category.sort_base))
elseif type(category) == "string" then
table.insert(parts, M.utilities.format_categories({ category }, lang))
end
end
return table.concat(parts)
end
return export
bqvmsa9unm4tzmftlwtakufe64yzre4
5775313
5775312
2026-10-15T02:20:33Z
Octahedron80
267
5775313
Scribunto
text/plain
local export = {}
local M = require("Module:module loader").init({
require = {
etymology = "Module:etymology",
affix = "Module:affix",
etymology_specialized = "Module:etymology/specialized",
utilities = "Module:utilities",
roots = "Module:roots",
},
loadData = {
data = "Module:etymon/data",
},
})
-- Evaluate whether a keyword is transitive for a given term
local function is_transitive(transitive_mode, page_lang, term_lang)
if transitive_mode == M.data.TRANSITIVE.ALWAYS then
return true
elseif transitive_mode == M.data.TRANSITIVE.NEVER then
return false
elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG then
return page_lang:getCode() ~= term_lang:getCode()
elseif transitive_mode == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
return page_lang:getCode() ~= term_lang:getCode()
end
error("Unknown transitive mode: " .. tostring(transitive_mode))
end
-- Get keyword config with language-specific overrides
local function get_keyword_config(keyword, lang_exc)
local base_config = M.data.keywords[keyword]
if not base_config then
return nil -- Invalid keyword
end
local overrides = lang_exc and lang_exc.keyword_overrides and lang_exc.keyword_overrides[keyword]
if not overrides then
return base_config
end
-- Merge overrides into base config
local merged = {}
for k, v in pairs(base_config) do
merged[k] = v
end
for k, v in pairs(overrides) do
merged[k] = v
end
return merged
end
function export.get_cat_name(source)
local _, cat_name = M.etymology.get_display_and_cat_name(source, true)
return cat_name
end
-- Normalize affix type aliases
local function add_category(categories, cat_name, sort_key, sort_base)
if categories[cat_name] == nil then
categories[cat_name] = {
sort_key = sort_key,
sort_base = sort_base,
}
return
end
local existing = categories[cat_name]
if existing.sort_key == nil and sort_key ~= nil then
existing.sort_key = sort_key
end
if existing.sort_base == nil and sort_base ~= nil then
existing.sort_base = sort_base
end
end
-- Collect affix categories from top-level group containers
local function collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc)
local parts = {}
local part_index = 1
for _, container in ipairs(node.children or {}) do
local config = container.keyword_info
if config and config.affix_categories then
for _, term in ipairs(container.terms or {}) do
if not term.unknown_term then
local part_data = {
term = term.title,
tr = term.tr,
ts = term.ts,
alt = term.alt,
itemno = part_index,
orig_index = part_index
}
-- Determine affix type: explicit aftype > pos=root > auto-detect
local aftype = term.aftype
if aftype then
aftype = M.data.aftype_aliases[aftype] or aftype
part_data.type = aftype
elseif term.args and term.args.pos and (term.args.pos == "root" or term.args.pos == "ราก") then
part_data.type = "ไม่ใช่หน่วยคำเติม"
end
if term.lang:getCode() ~= page_lang:getCode() then
part_data.lang = term.lang
end
local target_ids = available_etymon_ids[term.target_key]
local has_multiple_ids = target_ids and #target_ids > 1
local id_exists_in_disambiguation = false
local matched_id = nil
-- Count available senseids for the target page
local senseid_count = 0
local target_prefix = term.target_key .. ":"
if senseid_parent_etymon then
for key, _ in pairs(senseid_parent_etymon) do
if key:sub(1, #target_prefix) == target_prefix then
senseid_count = senseid_count + 1
end
end
end
local has_multiple_senseids = senseid_count > 1
if term.id then
-- Check if user provided a valid senseid
local senseid_key = term.target_key .. ":" .. term.id
if senseid_parent_etymon and senseid_parent_etymon[senseid_key] then
if has_multiple_senseids then
-- Ambiguous senseid: use senseid
matched_id = term.id
id_exists_in_disambiguation = true
elseif has_multiple_ids then
-- Unique senseid but ambiguous etymon: use etymon ID
matched_id = term.etymon_id or term.id
id_exists_in_disambiguation = true
end
else
-- Check if user provided a valid etymon ID
if has_multiple_ids and target_ids then
for _, id_data in ipairs(target_ids) do
local stored_id = type(id_data) == "table" and id_data.id or id_data
if stored_id == term.id then
-- Ambiguous etymon: use etymon ID
id_exists_in_disambiguation = true
matched_id = term.id
break
end
end
end
-- Fallback: check resolved etymon_id (e.g. from previous steps)
if not id_exists_in_disambiguation and has_multiple_ids and term.etymon_id and target_ids then
for _, id_data in ipairs(target_ids) do
local stored_id = type(id_data) == "table" and id_data.id or id_data
if stored_id == term.etymon_id then
id_exists_in_disambiguation = true
matched_id = term.etymon_id
break
end
end
end
end
end
-- Use the matched ID if found
if term.override or id_exists_in_disambiguation then
part_data.id = matched_id or term.id
end
table.insert(parts, part_data)
part_index = part_index + 1
end
end
end
end
if #parts == 0 then return {} end
local affix_data = {
lang = page_lang,
parts = parts,
pos = "ศัพท์",
sort_key = nil,
}
if #parts == 1 then
affix_data.allow_no_affixes_or_compounds = true
end
local affix_categories = M.affix.get_affix_categories_only(affix_data)
local result = {}
for _, cat in ipairs(affix_categories) do
if type(cat) == "table" then
table.insert(result, { cat = cat.cat, sort_key = cat.sort_key, sort_base = cat.sort_base })
else
table.insert(result, { cat = cat })
end
end
return result
end
local function lang_is_source(page_lang, source)
return page_lang:getCode() == source:getCode() or page_lang:hasParent(source)
end
local function is_borrowing_keyword_config(config)
return config and (config.borrowing_type or config.specialized_borrowing)
end
local function add_reborrow_category(categories, page_lang)
local lang_name = page_lang:getCategoryName() --th
add_category(categories, lang_name .. " terms borrowed back into " .. lang_name)
end
local function borrow_returns_to_page_lang(page_lang, source, in_foreign_branch)
if not in_foreign_branch then
return false
end
if source:getFullCode() == page_lang:getFullCode() then
return true
end
return page_lang:hasParent(source)
end
local function node_borrows_from_lang(node, page_lang, visited, in_foreign_branch)
visited = visited or {}
if not node or visited[node] then
return false
end
visited[node] = true
if node.is_duplicate then
if node.duplicate_of then
return node_borrows_from_lang(node.duplicate_of, page_lang, visited, in_foreign_branch)
end
return false
end
local node_is_foreign = in_foreign_branch
or (node.lang and node.lang:getFullCode() ~= page_lang:getFullCode())
for _, container in ipairs(node.children or {}) do
if is_borrowing_keyword_config(container.keyword_info) then
for _, child_term in ipairs(container.terms or {}) do
if borrow_returns_to_page_lang(page_lang, child_term.lang, node_is_foreign) then
return true
end
end
end
for _, child_term in ipairs(container.terms or {}) do
if child_term.status == M.data.STATUS.OK or child_term.status == M.data.STATUS.INLINE then
if node_borrows_from_lang(child_term, page_lang, visited, node_is_foreign) then
return true
end
end
end
end
return false
end
local function should_add_reborrow_category(page_lang, term)
if page_lang:getCode() == term.lang:getCode() then
return false
end
if term.status ~= M.data.STATUS.OK and term.status ~= M.data.STATUS.INLINE then
return false
end
return node_borrows_from_lang(term, page_lang, {}, false)
end
-- Add borrowing-related categories (top-level only)
local function collect_borrowing_categories(categories, page_lang, term, config, check_reborrow_path)
if check_reborrow_path and should_add_reborrow_category(page_lang, term) then
add_reborrow_category(categories, page_lang)
end
if config.borrowing_type == "ยืมมา" and not lang_is_source(page_lang, term.lang) then
local temp_categories = {}
M.etymology.insert_borrowed_cat(temp_categories, page_lang, term.lang)
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
if config.specialized_borrowing and not lang_is_source(page_lang, term.lang) then
local _, cat_names = M.etymology_specialized.specialized_borrowing {
bortype = config.specialized_borrowing,
lang = page_lang,
sources = { term.lang },
terms = { { lang = term.lang, term = "-" } },
notext = true,
}
for _, cat_name in ipairs(cat_names) do
add_category(categories, cat_name)
end
end
end
-- Add source-based derivation categories (top-level only)
local function collect_source_derivation_categories(categories, page_lang, term, config)
if not config.source_category_type then
return
end
local temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
borrowing_type = config.source_category_type,
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
-- Add source language categories
local function collect_source_categories(categories, page_lang, term, chain, get_norm_lang_func)
if page_lang:getCode() == get_norm_lang_func(term.lang):getCode() then
return
end
local temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
if chain.inherited then
temp_categories = {}
M.etymology.insert_source_cat_get_display {
lang = page_lang,
source = term.lang,
categories = temp_categories,
borrowing_type = "สืบทอด",
nocat = false,
}
for _, cat in ipairs(temp_categories) do
add_category(categories, cat)
end
end
end
-- Add root/word categories
local function collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, chain,
get_norm_lang_func, lang_exc, keyword)
local pos_types = { root = "ราก", word = "คำ" }
-- Determine pos: from term's postype, keyword's pos_override, or args.pos
local pos
local config = get_keyword_config(keyword, lang_exc)
if term.postype then
-- Term-level postype modifier takes highest priority
pos = term.postype
elseif config and config.pos_override then
pos = config.pos_override
elseif type(term.args) == "table" and term.args.pos then
pos = term.args.pos
end
local pos_type = pos_types[pos]
if not pos_type or term.unknown_term then
return
end
-- Skip root/word categories for descendants of affix groups
-- if pos_type then
-- return
-- end
local same_language = get_norm_lang_func(page_lang):getFullCode() == get_norm_lang_func(term.lang):getFullCode()
-- Skip self-references
if same_language and root_title == term.title then
return
end
local entry_name
if pos_type == "root" or pos_type == "ราก" then
entry_name = term.title
M.roots.assert_root(term.lang, entry_name)
else
entry_name = term.lang:makeEntryName(term.title)
end
local lang_name = page_lang:getCategoryName() --th
local cat_name
if chain.passed_through then
local etymon_lang_name = export.get_cat_name(term.lang)
cat_name = "ศัพท์" .. lang_name .. "ที่รับมาจาก" .. pos_type .. etymon_lang_name .. " " .. entry_name
else
cat_name = "ศัพท์" .. lang_name .. "ที่เป็นของ" .. pos_type .. " " .. entry_name
end
-- Add ID disambiguation if needed (for roots/words: use etymon_id if resolved via senseid, otherwise use id)
local target_ids = available_etymon_ids[term.target_key]
local effective_id = term.etymon_id or term.id -- etymon_id if senseid, otherwise id is already an etymon id
if target_ids and effective_id then
local same_pos_count = 0
for _, id_data in ipairs(target_ids) do
if type(id_data) == "table" and id_data.pos == pos then
same_pos_count = same_pos_count + 1
end
end
if same_pos_count > 1 then
cat_name = cat_name .. " (" .. effective_id .. ")"
end
end
add_category(categories, cat_name)
end
-- Compute chain state for a term based on parent chain and keyword config
-- Hyphen patterns for affix detection (regular hyphen + script-specific)
local AFFIX_HYPHEN_PATTERN = "[%-%־ـ᠊]" -- regular hyphen, Hebrew maqqef, Arabic tatweel, Mongolian hyphen
-- Check if a term is an actual affix (not a non-affix member of an affix group)
local function is_actual_affix(term)
-- Check explicit aftype modifier
if term.aftype then
local normalized = M.data.aftype_aliases[term.aftype] or term.aftype
return normalized ~= "ไม่ใช่หน่วยคำเติม"
end
-- Check if pos=root (treated as non-affix)
if term.args and term.args.pos and (term.args.pos == "root" or term.args.pos == "ราก") then
return false
end
-- Auto-detect by hyphen: prefix ends with -, suffix starts with -, etc.
if term.title then
local title = term.title
-- Strip leading * for reconstructed terms before checking hyphens
title = title:gsub("^%*", "")
-- Check for hyphens at start or end (handles script-specific hyphens too)
if title:match("^" .. AFFIX_HYPHEN_PATTERN) or title:match(AFFIX_HYPHEN_PATTERN .. "$") then
return true
end
end
-- Default: not an affix
return false
end
local function compute_category_chain(parent_chain, config, page_lang, term_lang, get_norm_lang_func, parent_term_lang, term)
-- Track if we're inside an actual affix (for suppressing root categories on descendants)
-- Only set if the term is an actual affix (prefix, suffix, etc.), not a non-affix member
local inside_affix = parent_chain.inside_affix
if config.affix_categories and term and is_actual_affix(term) then
inside_affix = true
end
-- If no_child_categories is set, disable everything
if config.no_child_categories then
return {
passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(),
inherited = false,
source = false,
pos = false,
recurse = false,
inside_affix = inside_affix,
}
end
local term_is_transitive = is_transitive(config.transitive, page_lang, term_lang)
local new_source = parent_chain.source and term_is_transitive
-- For CROSS_LANG_NO_INTERNAL_SOURCE: track internal derivation language context
-- Check if this term is internal relative to parent term's language (if parent_term_lang provided)
-- or relative to page language (if no parent_term_lang)
local internal_lang = parent_chain.internal_lang
local is_internal_in_context = false
if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
local check_lang = parent_term_lang or page_lang
local term_lang_code = get_norm_lang_func(term_lang):getCode()
local check_lang_code = get_norm_lang_func(check_lang):getCode()
if internal_lang then
-- Already in an internal derivation context: check if this term is also internal
is_internal_in_context = term_lang_code == internal_lang
else
-- Check if this term is internal relative to parent term (or page if no parent)
is_internal_in_context = term_lang_code == check_lang_code
end
end
-- Source chain behavior for CROSS_LANG_NO_INTERNAL_SOURCE
if config.transitive == M.data.TRANSITIVE.CROSS_LANG_NO_INTERNAL_SOURCE then
if is_internal_in_context then
-- Internal derivation
new_source = false
internal_lang = get_norm_lang_func(term_lang):getCode()
else
-- Cross-language
new_source = parent_chain.source and term_is_transitive
internal_lang = nil
end
end
local new_pos = parent_chain.pos
return {
passed_through = parent_chain.passed_through or page_lang:getCode() ~= get_norm_lang_func(term_lang):getCode(),
inherited = parent_chain.inherited and config.inherited_chain,
source = new_source,
pos = new_pos,
internal_lang = internal_lang,
recurse = new_source or new_pos,
inside_affix = inside_affix,
}
end
function export.render(opts)
opts = opts or {}
local data_tree = opts.data_tree
local page_lang = opts.page_lang
local available_etymon_ids = opts.available_etymon_ids
local senseid_parent_etymon = opts.senseid_parent_etymon
local get_norm_lang_func = opts.get_norm_lang_func
local lang_exc = opts.lang_exc
local categories = {}
local seen = {}
local lang_name = page_lang:getCategoryName() --th
local root_title = data_tree.title
-- Collect the tree recursively
local function collect(node, parent_chain, is_toplevel)
-- Avoid processing same node twice
if not node.unknown_term and node.title then
local key = node.lang:getFullCode() .. ":" .. (node.title or "") .. ":" .. (node.id or "")
if seen[key] then return end
seen[key] = true
end
-- Collect affix categories at top level only
if is_toplevel then
local affix_cats = collect_affix_categories(node, page_lang, available_etymon_ids, senseid_parent_etymon, lang_exc)
for _, cat in ipairs(affix_cats) do
--add_category(categories, lang_name .. " " .. cat.cat, cat.sort_key, cat.sort_base)
add_category(categories, require("Module:th-utilities").th_categorize(cat.cat, lang_name), cat.sort_key, cat.sort_base)
end
if node.supplements then
for _, supplement in ipairs(node.supplements) do
local config = supplement.config
if config and config.toplevel_category then
--add_category(categories, lang_name .. " " .. config.toplevel_category)
add_category(categories, require("Module:th-utilities").th_categorize(config.toplevel_category, lang_name))
end
end
end
end
-- Process each container
for _, container in ipairs(node.children or {}) do
local keyword = container.keyword
local config = get_keyword_config(keyword, lang_exc)
-- Skip invalid keywords
if config then
-- Process each term in the container
for _, term in ipairs(container.terms or {}) do
local term_chain = compute_category_chain(parent_chain, config, page_lang, term.lang, get_norm_lang_func, node.lang, term)
local no_child_categories = config.no_child_categories == true
local term_is_transitive = is_transitive(config.transitive, page_lang, term.lang)
-- Top-level only processing
if is_toplevel then
-- Missing/ambiguous etymon tracking
if not term.unknown_term and (term.status == M.data.STATUS.MISSING or term.status == M.data.STATUS.REDLINK) then
add_category(categories, lang_name .. " entries referencing missing etymons")
end
if not term.unknown_term and term.status == M.data.STATUS.AMBIGUOUS then
add_category(categories, lang_name .. " entries referencing ambiguous etymons")
end
if term.missing_descendants_header then
add_category(categories, lang_name .. " entries referencing etymons without Descendants sections")
end
if term.missing_descendants_entry then
add_category(categories, lang_name .. " entries referencing etymons without this term in Descendants sections")
end
-- Top-level category (e.g., "undefined derivations")
if config.toplevel_category then
add_category(categories, lang_name .. " " .. config.toplevel_category)
end
-- Borrowing categories (bor, lbor, slbor, ubor, obor)
if config.borrowing_type or config.specialized_borrowing then
collect_borrowing_categories(categories, page_lang, term, config, true)
end
-- Borrowing categories from <bor>, <lbor>, or <slbor> modifiers on affix-group terms
local kw_config = M.data.keywords[keyword]
if kw_config and kw_config.affix_categories then
if term.bor then
local bor_config = { borrowing_type = "ยืมมา" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
elseif term.lbor then
local bor_config = { specialized_borrowing = "learned" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
elseif term.slbor then
local bor_config = { specialized_borrowing = "semi-learned" }
collect_borrowing_categories(categories, page_lang, term, bor_config, true)
end
end
-- Source-based derivation categories (sl, calque, pcal)
if config.source_category_type then
collect_source_derivation_categories(categories, page_lang, term, config)
end
-- Skip all child categorisation if no_child_categories is set
if not no_child_categories then
-- Source categories only if transitive
if term_is_transitive then
collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func)
end
-- Pos categories always (unless no_child_categories)
collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain,
get_norm_lang_func, lang_exc, keyword)
end
else
-- Below top level, respect the parent chain
if parent_chain.source then
collect_source_categories(categories, page_lang, term, term_chain, get_norm_lang_func)
end
if parent_chain.pos then
collect_pos_categories(categories, page_lang, root_title, term, available_etymon_ids, term_chain,
get_norm_lang_func, lang_exc, keyword)
end
end
-- Recurse into term's children if needed and status allows
if term_chain.recurse and (term.status == M.data.STATUS.OK or term.status == M.data.STATUS.INLINE) then
collect(term, term_chain, false)
end
end
end
end
end
-- Initial chain state
local initial_chain = {
passed_through = false,
inherited = true,
source = true,
pos = true,
internal_lang = nil,
recurse = true,
inside_affix = false,
}
collect(data_tree, initial_chain, true)
local cat_list = {}
for cat_name, sort_data in pairs(categories) do
if sort_data.sort_key ~= nil or sort_data.sort_base ~= nil then
table.insert(cat_list, {
name = cat_name,
sort_key = sort_data.sort_key,
sort_base = sort_data.sort_base,
})
else
table.insert(cat_list, cat_name)
end
end
return cat_list
end
function export.build(opts)
opts = opts or {}
local categories = {}
if not opts.suppress_categories and not opts.nocat then
categories = export.render({
data_tree = opts.data_tree,
page_lang = opts.page_lang,
available_etymon_ids = opts.available_etymon_ids,
senseid_parent_etymon = opts.senseid_parent_etymon,
get_norm_lang_func = opts.get_norm_lang_func,
lang_exc = opts.lang_exc,
})
end
local page_lang = opts.page_lang
if not page_lang then
return categories
end
local lang_name = page_lang:getCategoryName() --th
table.insert(categories, "Pages with etymon")
table.insert(categories, lang_name .. " entries with etymon")
if opts.tree then
table.insert(categories, "Pages with etymology trees")
table.insert(categories, lang_name .. " entries with etymology trees")
end
if opts.text then
table.insert(categories, lang_name .. " entries with etymology texts")
end
if opts.exnihilo then
table.insert(categories, lang_name .. " terms coined ex nihilo")
end
if opts.toplevel_has_inline_etymology then
table.insert(categories, "Pages with inline etymon for redlinks")
end
if opts.toplevel_redundant_etymology then
table.insert(categories, "Pages with redundant inline etymon")
end
if opts.toplevel_idless_etymon then
table.insert(categories, "Pages using etymon with no ID")
end
if opts.has_mismatched_id then
table.insert(categories, lang_name .. " entries referencing etymons with mismatched IDs")
end
if opts.linked_page_multiple_etymons_idless then
table.insert(categories,
lang_name .. " entries referencing pages with multiple etymons missing IDs")
end
if opts.linked_page_partial_etymology_sections then
table.insert(categories,
lang_name .. " entries referencing pages with etymology sections missing etymons")
end
if opts.text_stop_lang_missing then
table.insert(categories, "Pages with etymology text stop language not in chain")
table.insert(categories, lang_name .. " entries with etymology text stop language not in chain")
end
return categories
end
function export.format(entries, lang)
if type(entries) ~= "table" or #entries == 0 then
return ""
end
local parts = {}
for _, category in ipairs(entries) do
if type(category) == "table" and type(category.name) == "string" then
table.insert(parts, M.utilities.format_categories({ category.name }, lang, category.sort_key, category.sort_base))
elseif type(category) == "string" then
table.insert(parts, M.utilities.format_categories({ category }, lang))
end
end
return table.concat(parts)
end
return export
h5my5gklyyqqhcm7j1tavhwuyou5fib
มอดูล:languages/chars
828
2323855
5775362
5720750
2026-10-15T07:11:02Z
Octahedron80
267
5775362
Scribunto
text/plain
local export = {}
local table = table
local insert = table.insert
local u = require("Module:string/char")
-- UTF-8 encoded strings for some commonly-used diacritics.
local c = {
prime = u(0x02B9),
grave = u(0x0300),
acute = u(0x0301),
circ = u(0x0302), -- circumflex
tilde = u(0x0303),
macron = u(0x0304),
overline = u(0x0305),
breve = u(0x0306),
dotabove = u(0x0307),
diaer = u(0x0308), -- diaeresis
ringabove = u(0x030A),
dacute = u(0x030B), -- double acute
caron = u(0x030C),
lineabove = u(0x030D),
dgrave = u(0x030F), -- double grave
invbreve = u(0x0311), -- inverted breve
turnedcommaabove = u(0x0312),
commaabove = u(0x0313),
revcommaabove = u(0x0314), -- reversed comma above
dotbelow = u(0x0323),
diaerbelow = u(0x0324), -- diaeresis below
ringbelow = u(0x0325),
commabelow = u(0x0326),
cedilla = u(0x0327),
ogonek = u(0x0328),
caronbelow = u(0x032C),
brevebelow = u(0x032E),
macronbelow = u(0x0331),
perispomeni = u(0x0342),
ypogegrammeni = u(0x0345),
CGJ = u(0x034F), -- combining grapheme joiner
zigzag = u(0x035B),
dbrevebelow = u(0x035C), -- double breve below
dmacron = u(0x035E), -- double macron
dtilde = u(0x0360), -- double tilde
dinvbreve = u(0x0361), -- double inverted breve
small_a = u(0x0363),
small_e = u(0x0364),
small_i = u(0x0365),
small_o = u(0x0366),
small_u = u(0x0367),
keraia = u(0x0374),
lowerkeraia = u(0x0375),
tonos = u(0x0384),
palatalization = u(0x0484),
dasiapneumata = u(0x0485),
psilipneumata = u(0x0486),
kashida = u(0x0640),
fathatan = u(0x064B),
dammatan = u(0x064C),
kasratan = u(0x064D),
fatha = u(0x064E),
damma = u(0x064F),
kasra = u(0x0650),
shadda = u(0x0651),
sukun = u(0x0652),
hamzaabove = u(0x0654),
nunghunna = u(0x0658),
zwarakay = u(0x0659),
smallv = u(0x065A),
superalef = u(0x0670),
udatta = u(0x0951),
anudatta = u(0x0952),
tacute = u(0x1ACB), -- triple acute
dsvarita = u(0x1CDA), -- double svarita
tsvarita = u(0x1CDB), -- triple svarita
dottedgrave = u(0x1DC0),
dottedacute = u(0x1DC1),
coronis = u(0x1FBD),
psili = u(0x1FBF),
dasia = u(0x1FEF),
ZWNJ = u(0x200C), -- zero width non-joiner
ZWJ = u(0x200D), -- zero width joiner
RSQuo = u(0x2019), -- right single quote
kavyka = u(0xA67C),
VS01 = u(0xFE00), -- variation selector 1
-- Punctuation for the standard_chars field.
-- Note: characters are literal (i.e. no magic characters).
punc = " ',-‐‑‒–—…∅◌",
-- Range covering all diacritics.
diacritics = u(0x300) .. "-" .. u(0x34E) ..
u(0x350) .. "-" .. u(0x36F) ..
u(0x1AB0) .. "-" .. u(0x1ACE) ..
u(0x1DC0) .. "-" .. u(0x1DFF) ..
u(0x20D0) .. "-" .. u(0x20F0) ..
u(0xFE20) .. "-" .. u(0xFE2F),
}
-- Braille characters for the standard_chars field.
local braille = {}
for i = 0x2800, 0x28FF do
insert(braille, u(i))
end
c.braille = table.concat(braille)
export.chars = c
-- Pre-generate PUA characters, generally used in sortkeys.
-- Note: if changing the amount, use powers of 2 to maximise memory efficiency (due to the way memory is allocated for tables).
local p = {}
for i = 1, 32 do
p[i] = u(0xF000+i-1)
end
export.puaChars = p
local cs = {}
-- Used in the default strip_diacritics and sort_key for Cyrs, but also used directly by Old Ruthenian (zle-ort).
cs["Cyrs_remove_diacritics"] = c.grave .. c.acute .. c.dotabove .. c.diaer .. c.invbreve .. c.palatalization .. c.dasiapneumata .. c.psilipneumata .. c.dottedgrave .. c.dottedacute .. c.kavyka
export.chars_substitutions = cs
return export
4jo6gnddmlyjm1f3me7obw2m2tjok4g
มอดูล:roots
828
2359206
5775309
5775236
2026-10-15T02:10:57Z
Octahedron80
267
5775309
Scribunto
text/plain
local export = {}
local force_cat = false -- for debugging
local M = require("Module:module loader").init({
require = {
str_utils = "Module:string utilities",
utilities = "Module:utilities",
links = "Module:links",
headword = "Module:headword",
languages = "Module:languages",
parameters = "Module:parameters",
inflection_table = "Module:inflection-table",
},
loadData = {
radicals = "Module:roots/data/radicals",
},
lazy = {
concat = function() return table.concat end,
insert = function() return table.insert end,
},
})
local UI_STRINGS = {
no_langcode = "Please provide a language code.",
invalid_langcode = "Invalid language code: %s",
not_a_table = "rootTable is not a table",
min_radicals = "Root must have at least %s %s.",
max_radicals = "Root must have at most %s %s.",
unrecognized_pos = "Unrecognized %s radical %s in %s",
unrecognized_mem = "Unrecognized radical %s in %s",
not_single_letter = "'%s' in the root '%s' should be a single letter.",
invalid_validation = "Unknown validation model: %s",
only_one_root = "There should be only one root.",
bad_root = "Invalid %s root '%s': %s",
wrong_separator = "Radicals should be separated by '%s'.",
root_vs_pagename = "Root is different from the pagename.",
move_to_appendix = "The root page should be in the Appendix namespace. Please move it to : [[%s]]",
appendix_subpage = "ภาคผนวก:รากภาษา%s/",
root_category = "ศัพท์ภาษา%sที่เป็นของราก %s%s",
derived_category = "ศัพท์ภาษา%sที่รับมาจากรากภาษา%s %s%s",
derived_language = "ศัพท์ภาษา%sที่รับมาจากภาษา%s",
root_heading = "\n! [[w:%s|%s]]",
sense_wrapper = "‎ <span class=\"gloss-content\">(%s)</span>",
article_semitic = "en:Semitic root", --ใช้ en จนกว่าจะมีหน้า th
article_generic = "en:Root (linguistics)", --ใช้ en จนกว่าจะมีหน้า th
}
local DEFAULT_LINK_TARGET = "bare"
local DEFAULT_HEADWORD = {}
local function split_root(root, separator)
if not separator then
return { root }
end
return mw.text.split(root, separator, true)
end
local function radicals_word(count)
return count == 1 and "radical" or "radicals"
end
function export.get_data_module_name(langcode)
return "Module:roots/data/" .. langcode
end
local function try_load_data(langcode)
local ok, data = pcall(mw.loadData, export.get_data_module_name(langcode))
if ok then
return data
end
return nil
end
function export.get_data(langcode)
return try_load_data(langcode)
end
local function get_lang_and_data(frame)
local code = frame.args["lang"]
if not code or code == "" then
error(UI_STRINGS.no_langcode)
end
local lang = M.languages.getByCode(code)
if not lang then
error(UI_STRINGS.invalid_langcode:format(code))
end
return lang, try_load_data(code) or {}
end
local function resolve_radicals(data)
if data.validation == "positional" or data.radicals then
return data.radicals
end
if data.shared_radicals then
return M.radicals[data.shared_radicals]
end
return nil
end
local function transliterate_root(root_string, romanization)
if not romanization then
return nil
end
local out = root_string
for _, pair in ipairs(romanization) do
out = M.str_utils.gsub(out, pair[1], pair[2])
end
return out
end
export.transliterate = transliterate_root
local function validate_root(rootTable, joined_root, data, radical_set)
if type(rootTable) ~= "table" then
return nil, UI_STRINGS.not_a_table
end
local len = #rootTable
if data.min_radicals and len < data.min_radicals then
return nil, UI_STRINGS.min_radicals:format(data.min_radicals, radicals_word(data.min_radicals))
end
if data.max_radicals and len > data.max_radicals then
return nil, UI_STRINGS.max_radicals:format(data.max_radicals, radicals_word(data.max_radicals))
end
if data.validation == "positional" then
for i, radical in ipairs(rootTable) do
local set, label
if i == 1 then
set, label = radical_set.initial, "initial"
elseif i == len then
set, label = radical_set.final, "final"
else
set, label = radical_set.medial, "medial"
end
if not set[radical] then
return nil, UI_STRINGS.unrecognized_pos:format(label, radical, joined_root)
end
end
elseif data.validation == "membership" then
for _, radical in ipairs(rootTable) do
if not radical_set[radical] then
return nil, UI_STRINGS.unrecognized_mem:format(radical, joined_root)
end
end
elseif data.validation == "single_letter" then
for _, radical in ipairs(rootTable) do
if mw.ustring.len(radical) ~= 1 then
return nil, UI_STRINGS.not_single_letter:format(radical, joined_root)
end
end
elseif data.validation ~= nil then
return nil, UI_STRINGS.invalid_validation:format(tostring(data.validation))
end
return true
end
local function link(term, alt, translit, id, lang)
if term == "" or term == "—" then
return term
end
return M.links.full_link({
term = term,
alt = alt ~= term and alt or nil,
tr = translit,
lang = lang,
id = id,
})
end
local function root_category(lang, source, root, qualifier)
local suffix = (qualifier and qualifier ~= "") and (" (" .. qualifier .. ")") or ""
if lang:getCode() == source:getCode() then
return UI_STRINGS.root_category:format(lang:getFullName(), root, suffix)
end
return UI_STRINGS.derived_category:format(
lang:getFullName(), source:getCanonicalName(), root, suffix)
end
local function check_root(source, root)
local data = try_load_data(source:getCode())
if not data then
return true
end
local bare = (root:gsub("^%*", ""))
local radicals = split_root(bare, data.separator)
if data.separator and #radicals == 1 and mw.ustring.len(bare) > 1 then
return nil, UI_STRINGS.wrong_separator:format(data.separator)
end
return validate_root(radicals, bare, data, resolve_radicals(data))
end
function export.get_link_page(lang, root)
local data = try_load_data(lang:getCode())
if not data or data.link_target ~= "appendix_subpage" then
return nil
end
export.assert_root(lang, root)
return UI_STRINGS.appendix_subpage:format(lang:getCanonicalName()) .. (root:gsub("^%*", ""))
end
function export.assert_root(source, root)
local ok, err = check_root(source, root)
if not ok then
error(UI_STRINGS.bad_root:format(source:getCanonicalName(), root, err))
end
return true
end
function export.get_categories(lang, source, roots, ids)
local categories = {}
ids = ids or {}
if lang:getCode() ~= source:getCode() then
M.insert(categories,
UI_STRINGS.derived_language:format(lang:getFullName(), source:getCanonicalName()))
end
for index, root in ipairs(roots) do
M.insert(categories, root_category(lang, source, root, ids[index]))
export.assert_root(source, root)
end
return categories
end
function export.categorize(lang, source, roots, ids, sort_key)
return M.utilities.format_categories(
export.get_categories(lang, source, roots, ids), lang, sort_key, nil, force_cat)
end
function export.show(frame)
local params = {
[1] = { required = true, type = "language" },
[2] = { required = true, type = "language" },
[3] = { required = true, list = true },
["id"] = { list = true, allow_holes = true },
["sort"] = {},
}
local args = M.parameters.process(frame:getParent().args, params)
return export.categorize(args[1], args[2], args[3], args.id, args.sort)
end
function export.root(frame)
local lang, data = get_lang_and_data(frame)
local radical_set = resolve_radicals(data)
local link_target = data.link_target or DEFAULT_LINK_TARGET
local output = {}
local categories = {}
local title = mw.title.getCurrentTitle()
local namespace = title.nsText
local params = {
[1] = { list = true },
["nocat"] = { type = "boolean" },
["plain"] = { type = "boolean" },
["notext"] = { type = "boolean" },
["sense"] = {},
}
if link_target == "bare" then
params["head"] = true
params["pagename"] = true
end
local args = M.parameters.process(frame:getParent().args, params)
local roots = args[1]
local roots_len = #roots
local plain = args["plain"]
if frame.args["plain"] then
plain = true
end
local separator = data.separator
local identity
local subpage = ""
if link_target == "appendix_subpage" then
subpage = UI_STRINGS.appendix_subpage:format(lang:getCanonicalName())
local fulltitle = title.fullText
fulltitle = M.str_utils.gsub(fulltitle, M.str_utils.gsub(subpage, "([^%w])", "%%%1"), "")
identity = fulltitle
else
identity = args["pagename"] or mw.loadData("Module:headword/data").pagename
end
local rootLetters = {}
if roots_len == 0 and not args["pagename"] and namespace == "Template" and data.preview_root then
M.insert(rootLetters, split_root(data.preview_root, separator))
elseif roots_len ~= 0 then
for _, root in ipairs(roots) do
M.insert(rootLetters, split_root(root, separator))
end
else
if link_target == "bare" then
local head = frame.args["head"]
if args["head"] ~= nil and identity ~= lang:stripDiacritics(args["head"]) then
error(UI_STRINGS.root_vs_pagename)
end
if head and args["head"] ~= nil then
identity = args["head"]
end
end
M.insert(rootLetters, split_root(identity, separator))
end
local joined_roots = {}
for i, rootLetter in ipairs(rootLetters) do
M.insert(joined_roots, M.concat(rootLetter, separator))
local ok, err = validate_root(rootLetter, joined_roots[i], data, radical_set)
if not ok then
error(err)
end
end
local sense = args["sense"]
local sense_formatted = ""
if sense ~= nil and sense ~= "" then
sense_formatted = UI_STRINGS.sense_wrapper:format(sense)
end
if identity == joined_roots[1] then
if link_target == "appendix_subpage" and namespace == "" then
error(UI_STRINGS.move_to_appendix:format(subpage .. joined_roots[1]))
end
if roots_len > 1 then
error(UI_STRINGS.only_one_root)
end
local headword_args = {
lang = lang,
pos_category = "roots",
categories = {},
heads = { identity },
nomultiwordcat = true,
}
local headword_opts = data.headword or DEFAULT_HEADWORD
if headword_opts.translits then
headword_args.translits = { transliterate_root(identity, data.romanization) }
end
if headword_opts.noposcat then
headword_args.noposcat = true
elseif headword_opts.nolemmacat then
headword_args.nolemmacat = true
end
M.insert(output, M.headword.full_headword(headword_args))
if args["nocat"] then
return M.concat(output)
end
return M.concat(output) .. M.concat(categories)
else
local link_texts = {}
local term_counts = {}
for i, joined_root in ipairs(joined_roots) do
local link_text
if link_target == "appendix_subpage" then
link_text = subpage .. joined_root
else
link_text = joined_root
end
local translit = data.romanization and transliterate_root(joined_root, data.romanization) or nil
M.insert(link_texts, link(link_text, joined_root, translit, sense, lang) .. sense_formatted)
M.insert(categories, M.utilities.format_categories(
{ root_category(lang, lang, joined_root, sense) }, lang, nil, nil, force_cat))
M.insert(term_counts, mw.site.stats.pagesInCategory(
root_category(lang, lang, joined_root, sense), "pages"))
end
if args["nocat"] or plain then
if args["nocat"] then
return M.concat(link_texts, ", ")
end
return M.concat(link_texts, ", ") .. M.concat(categories)
else
local link_text_output = ""
for i, link_text in ipairs(link_texts) do
link_text_output = link_text_output ..
"\n|-\n| " .. link_text ..
"\n|-\n| [[:Category:" ..
root_category(lang, lang, joined_roots[i], sense) ..
"|" .. term_counts[i] .. " term" .. (term_counts[i] == 1 and "" or "s") .. "]]\n"
end
local wikicode = M.inflection_table.make_top{
title = "-",
palette = data.palette,
class = "floatright tr-alongside"
}
local article = lang:inFamily("sem") and UI_STRINGS.article_semitic or UI_STRINGS.article_generic
wikicode = wikicode .. UI_STRINGS.root_heading:format(article, #term_counts == 1 and "Root" or "Roots")
wikicode = wikicode .. link_text_output
wikicode = wikicode .. M.inflection_table.make_bottom{}
return wikicode .. M.concat(categories)
end
end
end
return export
bi8outk8rcm7cakp5g1uqpb3yuypusg
5775310
5775309
2026-10-15T02:15:37Z
Octahedron80
267
5775310
Scribunto
text/plain
local export = {}
local force_cat = false -- for debugging
local M = require("Module:module loader").init({
require = {
str_utils = "Module:string utilities",
utilities = "Module:utilities",
links = "Module:links",
headword = "Module:headword",
languages = "Module:languages",
parameters = "Module:parameters",
inflection_table = "Module:inflection-table",
},
loadData = {
radicals = "Module:roots/data/radicals",
},
lazy = {
concat = function() return table.concat end,
insert = function() return table.insert end,
},
})
local UI_STRINGS = {
no_langcode = "Please provide a language code.",
invalid_langcode = "Invalid language code: %s",
not_a_table = "rootTable is not a table",
min_radicals = "Root must have at least %s %s.",
max_radicals = "Root must have at most %s %s.",
unrecognized_pos = "Unrecognized %s radical %s in %s",
unrecognized_mem = "Unrecognized radical %s in %s",
not_single_letter = "'%s' in the root '%s' should be a single letter.",
invalid_validation = "Unknown validation model: %s",
only_one_root = "There should be only one root.",
bad_root = "Invalid %s root '%s': %s",
wrong_separator = "Radicals should be separated by '%s'.",
root_vs_pagename = "Root is different from the pagename.",
move_to_appendix = "The root page should be in the Appendix namespace. Please move it to : [[%s]]",
appendix_subpage = "ภาคผนวก:รากภาษา%s/",
root_category = "ศัพท์ภาษา%sที่เป็นของราก %s%s",
derived_category = "ศัพท์ภาษา%sที่รับมาจากรากภาษา%s %s%s",
derived_language = "ศัพท์ภาษา%sที่รับมาจากภาษา%s",
root_heading = "\n! [[w:%s|%s]]",
sense_wrapper = "‎ <span class=\"gloss-content\">(%s)</span>",
article_semitic = "en:Semitic root", --ใช้ en จนกว่าจะมีหน้า th
article_generic = "en:Root (linguistics)", --ใช้ en จนกว่าจะมีหน้า th
}
local DEFAULT_LINK_TARGET = "bare"
local DEFAULT_HEADWORD = {}
local function split_root(root, separator)
if not separator then
return { root }
end
return mw.text.split(root, separator, true)
end
local function radicals_word(count)
return count == 1 and "radical" or "radicals"
end
function export.get_data_module_name(langcode)
return "Module:roots/data/" .. langcode
end
local function try_load_data(langcode)
local ok, data = pcall(mw.loadData, export.get_data_module_name(langcode))
if ok then
return data
end
return nil
end
function export.get_data(langcode)
return try_load_data(langcode)
end
local function get_lang_and_data(frame)
local code = frame.args["lang"]
if not code or code == "" then
error(UI_STRINGS.no_langcode)
end
local lang = M.languages.getByCode(code)
if not lang then
error(UI_STRINGS.invalid_langcode:format(code))
end
return lang, try_load_data(code) or {}
end
local function resolve_radicals(data)
if data.validation == "positional" or data.radicals then
return data.radicals
end
if data.shared_radicals then
return M.radicals[data.shared_radicals]
end
return nil
end
local function transliterate_root(root_string, romanization)
if not romanization then
return nil
end
local out = root_string
for _, pair in ipairs(romanization) do
out = M.str_utils.gsub(out, pair[1], pair[2])
end
return out
end
export.transliterate = transliterate_root
local function validate_root(rootTable, joined_root, data, radical_set)
if type(rootTable) ~= "table" then
return nil, UI_STRINGS.not_a_table
end
local len = #rootTable
if data.min_radicals and len < data.min_radicals then
return nil, UI_STRINGS.min_radicals:format(data.min_radicals, radicals_word(data.min_radicals))
end
if data.max_radicals and len > data.max_radicals then
return nil, UI_STRINGS.max_radicals:format(data.max_radicals, radicals_word(data.max_radicals))
end
if data.validation == "positional" then
for i, radical in ipairs(rootTable) do
local set, label
if i == 1 then
set, label = radical_set.initial, "initial"
elseif i == len then
set, label = radical_set.final, "final"
else
set, label = radical_set.medial, "medial"
end
if not set[radical] then
return nil, UI_STRINGS.unrecognized_pos:format(label, radical, joined_root)
end
end
elseif data.validation == "membership" then
for _, radical in ipairs(rootTable) do
if not radical_set[radical] then
return nil, UI_STRINGS.unrecognized_mem:format(radical, joined_root)
end
end
elseif data.validation == "single_letter" then
for _, radical in ipairs(rootTable) do
if mw.ustring.len(radical) ~= 1 then
return nil, UI_STRINGS.not_single_letter:format(radical, joined_root)
end
end
elseif data.validation ~= nil then
return nil, UI_STRINGS.invalid_validation:format(tostring(data.validation))
end
return true
end
local function link(term, alt, translit, id, lang)
if term == "" or term == "—" then
return term
end
return M.links.full_link({
term = term,
alt = alt ~= term and alt or nil,
tr = translit,
lang = lang,
id = id,
})
end
local function root_category(lang, source, root, qualifier)
local suffix = (qualifier and qualifier ~= "") and (" (" .. qualifier .. ")") or ""
if lang:getCode() == source:getCode() then
return UI_STRINGS.root_category:format(lang:getFullName(), root, suffix)
end
return UI_STRINGS.derived_category:format(
lang:getFullName(), source:getCanonicalName(), root, suffix)
end
local function check_root(source, root)
local data = try_load_data(source:getCode())
if not data then
return true
end
local bare = (root:gsub("^%*", ""))
local radicals = split_root(bare, data.separator)
if data.separator and #radicals == 1 and mw.ustring.len(bare) > 1 then
return nil, UI_STRINGS.wrong_separator:format(data.separator)
end
return validate_root(radicals, bare, data, resolve_radicals(data))
end
function export.get_link_page(lang, root)
local data = try_load_data(lang:getCode())
if not data or data.link_target ~= "appendix_subpage" then
return nil
end
export.assert_root(lang, root)
return UI_STRINGS.appendix_subpage:format(lang:getCanonicalName()) .. (root:gsub("^%*", ""))
end
function export.assert_root(source, root)
local ok, err = check_root(source, root)
if not ok then
error(UI_STRINGS.bad_root:format(source:getCanonicalName(), root, err))
end
return true
end
function export.get_categories(lang, source, roots, ids)
local categories = {}
ids = ids or {}
if lang:getCode() ~= source:getCode() then
M.insert(categories,
UI_STRINGS.derived_language:format(lang:getFullName(), source:getCanonicalName()))
end
for index, root in ipairs(roots) do
M.insert(categories, root_category(lang, source, root, ids[index]))
export.assert_root(source, root)
end
return categories
end
function export.categorize(lang, source, roots, ids, sort_key)
return M.utilities.format_categories(
export.get_categories(lang, source, roots, ids), lang, sort_key, nil, force_cat)
end
function export.show(frame)
local params = {
[1] = { required = true, type = "language" },
[2] = { required = true, type = "language" },
[3] = { required = true, list = true },
["id"] = { list = true, allow_holes = true },
["sort"] = {},
}
local args = M.parameters.process(frame:getParent().args, params)
return export.categorize(args[1], args[2], args[3], args.id, args.sort)
end
function export.root(frame)
local lang, data = get_lang_and_data(frame)
local radical_set = resolve_radicals(data)
local link_target = data.link_target or DEFAULT_LINK_TARGET
local output = {}
local categories = {}
local title = mw.title.getCurrentTitle()
local namespace = title.nsText
local params = {
[1] = { list = true },
["nocat"] = { type = "boolean" },
["plain"] = { type = "boolean" },
["notext"] = { type = "boolean" },
["sense"] = {},
}
if link_target == "bare" then
params["head"] = true
params["pagename"] = true
end
local args = M.parameters.process(frame:getParent().args, params)
local roots = args[1]
local roots_len = #roots
local plain = args["plain"]
if frame.args["plain"] then
plain = true
end
local separator = data.separator
local identity
local subpage = ""
if link_target == "appendix_subpage" then
subpage = UI_STRINGS.appendix_subpage:format(lang:getCanonicalName())
local fulltitle = title.fullText
fulltitle = M.str_utils.gsub(fulltitle, M.str_utils.gsub(subpage, "([^%w])", "%%%1"), "")
identity = fulltitle
else
identity = args["pagename"] or mw.loadData("Module:headword/data").pagename
end
local rootLetters = {}
if roots_len == 0 and not args["pagename"] and namespace == "แม่แบบ" and data.preview_root then
M.insert(rootLetters, split_root(data.preview_root, separator))
elseif roots_len ~= 0 then
for _, root in ipairs(roots) do
M.insert(rootLetters, split_root(root, separator))
end
else
if link_target == "bare" then
local head = frame.args["head"]
if args["head"] ~= nil and identity ~= lang:stripDiacritics(args["head"]) then
error(UI_STRINGS.root_vs_pagename)
end
if head and args["head"] ~= nil then
identity = args["head"]
end
end
M.insert(rootLetters, split_root(identity, separator))
end
local joined_roots = {}
for i, rootLetter in ipairs(rootLetters) do
M.insert(joined_roots, M.concat(rootLetter, separator))
local ok, err = validate_root(rootLetter, joined_roots[i], data, radical_set)
if not ok then
error(err)
end
end
local sense = args["sense"]
local sense_formatted = ""
if sense ~= nil and sense ~= "" then
sense_formatted = UI_STRINGS.sense_wrapper:format(sense)
end
if identity == joined_roots[1] then
if link_target == "appendix_subpage" and namespace == "" then
error(UI_STRINGS.move_to_appendix:format(subpage .. joined_roots[1]))
end
if roots_len > 1 then
error(UI_STRINGS.only_one_root)
end
local headword_args = {
lang = lang,
pos_category = "roots",
categories = {},
heads = { identity },
nomultiwordcat = true,
}
local headword_opts = data.headword or DEFAULT_HEADWORD
if headword_opts.translits then
headword_args.translits = { transliterate_root(identity, data.romanization) }
end
if headword_opts.noposcat then
headword_args.noposcat = true
elseif headword_opts.nolemmacat then
headword_args.nolemmacat = true
end
M.insert(output, M.headword.full_headword(headword_args))
if args["nocat"] then
return M.concat(output)
end
return M.concat(output) .. M.concat(categories)
else
local link_texts = {}
local term_counts = {}
for i, joined_root in ipairs(joined_roots) do
local link_text
if link_target == "appendix_subpage" then
link_text = subpage .. joined_root
else
link_text = joined_root
end
local translit = data.romanization and transliterate_root(joined_root, data.romanization) or nil
M.insert(link_texts, link(link_text, joined_root, translit, sense, lang) .. sense_formatted)
M.insert(categories, M.utilities.format_categories(
{ root_category(lang, lang, joined_root, sense) }, lang, nil, nil, force_cat))
M.insert(term_counts, mw.site.stats.pagesInCategory(
root_category(lang, lang, joined_root, sense), "pages"))
end
if args["nocat"] or plain then
if args["nocat"] then
return M.concat(link_texts, ", ")
end
return M.concat(link_texts, ", ") .. M.concat(categories)
else
local link_text_output = ""
for i, link_text in ipairs(link_texts) do
link_text_output = link_text_output ..
"\n|-\n| " .. link_text ..
"\n|-\n| [[:Category:" ..
root_category(lang, lang, joined_roots[i], sense) ..
"|ศัพท์ " .. term_counts[i] .. " คำ" --[[.. (term_counts[i] == 1 and "" or "s")]] .. "]]\n"
end
local wikicode = M.inflection_table.make_top{
title = "-",
palette = data.palette,
class = "floatright tr-alongside"
}
local article = lang:inFamily("sem") and UI_STRINGS.article_semitic or UI_STRINGS.article_generic
wikicode = wikicode .. UI_STRINGS.root_heading:format(article, --[[#term_counts == 1 and "ราก" or]] "ราก")
wikicode = wikicode .. link_text_output
wikicode = wikicode .. M.inflection_table.make_bottom{}
return wikicode .. M.concat(categories)
end
end
end
return export
iiqg0ol8sybojgj3dvyznk3arz79337
5775315
5775310
2026-10-15T02:25:54Z
Octahedron80
267
5775315
Scribunto
text/plain
local export = {}
local force_cat = false -- for debugging
local M = require("Module:module loader").init({
require = {
str_utils = "Module:string utilities",
utilities = "Module:utilities",
links = "Module:links",
headword = "Module:headword",
languages = "Module:languages",
parameters = "Module:parameters",
inflection_table = "Module:inflection-table",
},
loadData = {
radicals = "Module:roots/data/radicals",
},
lazy = {
concat = function() return table.concat end,
insert = function() return table.insert end,
},
})
local UI_STRINGS = {
no_langcode = "Please provide a language code.",
invalid_langcode = "Invalid language code: %s",
not_a_table = "rootTable is not a table",
min_radicals = "Root must have at least %s %s.",
max_radicals = "Root must have at most %s %s.",
unrecognized_pos = "Unrecognized %s radical %s in %s",
unrecognized_mem = "Unrecognized radical %s in %s",
not_single_letter = "'%s' in the root '%s' should be a single letter.",
invalid_validation = "Unknown validation model: %s",
only_one_root = "There should be only one root.",
bad_root = "Invalid %s root '%s': %s",
wrong_separator = "Radicals should be separated by '%s'.",
root_vs_pagename = "Root is different from the pagename.",
move_to_appendix = "The root page should be in the Appendix namespace. Please move it to : [[%s]]",
appendix_subpage = "ภาคผนวก:รากภาษา%s/",
root_category = "ศัพท์ภาษา%sที่เป็นของราก %s%s",
derived_category = "ศัพท์ภาษา%sที่รับมาจากรากภาษา%s %s%s",
derived_language = "ศัพท์ภาษา%sที่รับมาจากภาษา%s",
root_heading = "\n! [[w:%s|%s]]",
sense_wrapper = "‎ <span class=\"gloss-content\">(%s)</span>",
article_semitic = "en:Semitic root", --ใช้ en จนกว่าจะมีหน้า th
article_generic = "en:Root (linguistics)", --ใช้ en จนกว่าจะมีหน้า th
}
local DEFAULT_LINK_TARGET = "bare"
local DEFAULT_HEADWORD = {}
local function split_root(root, separator)
if not separator then
return { root }
end
return mw.text.split(root, separator, true)
end
local function radicals_word(count)
return count == 1 and "radical" or "radicals"
end
function export.get_data_module_name(langcode)
return "Module:roots/data/" .. langcode
end
local function try_load_data(langcode)
local ok, data = pcall(mw.loadData, export.get_data_module_name(langcode))
if ok then
return data
end
return nil
end
function export.get_data(langcode)
return try_load_data(langcode)
end
local function get_lang_and_data(frame)
local code = frame.args["lang"]
if not code or code == "" then
error(UI_STRINGS.no_langcode)
end
local lang = M.languages.getByCode(code)
if not lang then
error(UI_STRINGS.invalid_langcode:format(code))
end
return lang, try_load_data(code) or {}
end
local function resolve_radicals(data)
if data.validation == "positional" or data.radicals then
return data.radicals
end
if data.shared_radicals then
return M.radicals[data.shared_radicals]
end
return nil
end
local function transliterate_root(root_string, romanization)
if not romanization then
return nil
end
local out = root_string
for _, pair in ipairs(romanization) do
out = M.str_utils.gsub(out, pair[1], pair[2])
end
return out
end
export.transliterate = transliterate_root
local function validate_root(rootTable, joined_root, data, radical_set)
if type(rootTable) ~= "table" then
return nil, UI_STRINGS.not_a_table
end
local len = #rootTable
if data.min_radicals and len < data.min_radicals then
return nil, UI_STRINGS.min_radicals:format(data.min_radicals, radicals_word(data.min_radicals))
end
if data.max_radicals and len > data.max_radicals then
return nil, UI_STRINGS.max_radicals:format(data.max_radicals, radicals_word(data.max_radicals))
end
if data.validation == "positional" then
for i, radical in ipairs(rootTable) do
local set, label
if i == 1 then
set, label = radical_set.initial, "initial"
elseif i == len then
set, label = radical_set.final, "final"
else
set, label = radical_set.medial, "medial"
end
if not set[radical] then
return nil, UI_STRINGS.unrecognized_pos:format(label, radical, joined_root)
end
end
elseif data.validation == "membership" then
for _, radical in ipairs(rootTable) do
if not radical_set[radical] then
return nil, UI_STRINGS.unrecognized_mem:format(radical, joined_root)
end
end
elseif data.validation == "single_letter" then
for _, radical in ipairs(rootTable) do
if mw.ustring.len(radical) ~= 1 then
return nil, UI_STRINGS.not_single_letter:format(radical, joined_root)
end
end
elseif data.validation ~= nil then
return nil, UI_STRINGS.invalid_validation:format(tostring(data.validation))
end
return true
end
local function link(term, alt, translit, id, lang)
if term == "" or term == "—" then
return term
end
return M.links.full_link({
term = term,
alt = alt ~= term and alt or nil,
tr = translit,
lang = lang,
id = id,
})
end
local function root_category(lang, source, root, qualifier)
local suffix = (qualifier and qualifier ~= "") and (" (" .. qualifier .. ")") or ""
if lang:getCode() == source:getCode() then
return UI_STRINGS.root_category:format(lang:getFullName(), root, suffix)
end
return UI_STRINGS.derived_category:format(
lang:getFullName(), source:getCanonicalName(), root, suffix)
end
local function check_root(source, root)
local data = try_load_data(source:getCode())
if not data then
return true
end
local bare = (root:gsub("^%*", ""))
local radicals = split_root(bare, data.separator)
if data.separator and #radicals == 1 and mw.ustring.len(bare) > 1 then
return nil, UI_STRINGS.wrong_separator:format(data.separator)
end
return validate_root(radicals, bare, data, resolve_radicals(data))
end
function export.get_link_page(lang, root)
local data = try_load_data(lang:getCode())
if not data or data.link_target ~= "appendix_subpage" then
return nil
end
export.assert_root(lang, root)
return UI_STRINGS.appendix_subpage:format(lang:getCanonicalName()) .. (root:gsub("^%*", ""))
end
function export.assert_root(source, root)
local ok, err = check_root(source, root)
if not ok then
error(UI_STRINGS.bad_root:format(source:getCanonicalName(), root, err))
end
return true
end
function export.get_categories(lang, source, roots, ids)
local categories = {}
ids = ids or {}
if lang:getCode() ~= source:getCode() then
M.insert(categories,
UI_STRINGS.derived_language:format(lang:getFullName(), source:getCanonicalName()))
end
for index, root in ipairs(roots) do
M.insert(categories, root_category(lang, source, root, ids[index]))
export.assert_root(source, root)
end
return categories
end
function export.categorize(lang, source, roots, ids, sort_key)
return M.utilities.format_categories(
export.get_categories(lang, source, roots, ids), lang, sort_key, nil, force_cat)
end
function export.show(frame)
local params = {
[1] = { required = true, type = "language" },
[2] = { required = true, type = "language" },
[3] = { required = true, list = true },
["id"] = { list = true, allow_holes = true },
["sort"] = {},
}
local args = M.parameters.process(frame:getParent().args, params)
return export.categorize(args[1], args[2], args[3], args.id, args.sort)
end
function export.root(frame)
local lang, data = get_lang_and_data(frame)
local radical_set = resolve_radicals(data)
local link_target = data.link_target or DEFAULT_LINK_TARGET
local output = {}
local categories = {}
local title = mw.title.getCurrentTitle()
local namespace = title.nsText
local params = {
[1] = { list = true },
["nocat"] = { type = "boolean" },
["plain"] = { type = "boolean" },
["notext"] = { type = "boolean" },
["sense"] = {},
}
if link_target == "bare" then
params["head"] = true
params["pagename"] = true
end
local args = M.parameters.process(frame:getParent().args, params)
local roots = args[1]
local roots_len = #roots
local plain = args["plain"]
if frame.args["plain"] then
plain = true
end
local separator = data.separator
local identity
local subpage = ""
if link_target == "appendix_subpage" then
subpage = UI_STRINGS.appendix_subpage:format(lang:getCanonicalName())
local fulltitle = title.fullText
fulltitle = M.str_utils.gsub(fulltitle, M.str_utils.gsub(subpage, "([^%w])", "%%%1"), "")
identity = fulltitle
else
identity = args["pagename"] or mw.loadData("Module:headword/data").pagename
end
local rootLetters = {}
if roots_len == 0 and not args["pagename"] and namespace == "แม่แบบ" and data.preview_root then
M.insert(rootLetters, split_root(data.preview_root, separator))
elseif roots_len ~= 0 then
for _, root in ipairs(roots) do
M.insert(rootLetters, split_root(root, separator))
end
else
if link_target == "bare" then
local head = frame.args["head"]
if args["head"] ~= nil and identity ~= lang:stripDiacritics(args["head"]) then
error(UI_STRINGS.root_vs_pagename)
end
if head and args["head"] ~= nil then
identity = args["head"]
end
end
M.insert(rootLetters, split_root(identity, separator))
end
local joined_roots = {}
for i, rootLetter in ipairs(rootLetters) do
M.insert(joined_roots, M.concat(rootLetter, separator))
local ok, err = validate_root(rootLetter, joined_roots[i], data, radical_set)
if not ok then
error(err)
end
end
local sense = args["sense"]
local sense_formatted = ""
if sense ~= nil and sense ~= "" then
sense_formatted = UI_STRINGS.sense_wrapper:format(sense)
end
if identity == joined_roots[1] then
if link_target == "appendix_subpage" and namespace == "" then
error(UI_STRINGS.move_to_appendix:format(subpage .. joined_roots[1]))
end
if roots_len > 1 then
error(UI_STRINGS.only_one_root)
end
local headword_args = {
lang = lang,
pos_category = "roots",
categories = {},
heads = { identity },
nomultiwordcat = true,
}
local headword_opts = data.headword or DEFAULT_HEADWORD
if headword_opts.translits then
headword_args.translits = { transliterate_root(identity, data.romanization) }
end
if headword_opts.noposcat then
headword_args.noposcat = true
elseif headword_opts.nolemmacat then
headword_args.nolemmacat = true
end
M.insert(output, M.headword.full_headword(headword_args))
if args["nocat"] then
return M.concat(output)
end
return M.concat(output) .. M.concat(categories)
else
local link_texts = {}
local term_counts = {}
for i, joined_root in ipairs(joined_roots) do
local link_text
if link_target == "appendix_subpage" then
link_text = subpage .. joined_root
else
link_text = joined_root
end
local translit = data.romanization and transliterate_root(joined_root, data.romanization) or nil
M.insert(link_texts, link(link_text, joined_root, translit, sense, lang) .. sense_formatted)
M.insert(categories, M.utilities.format_categories(
{ root_category(lang, lang, joined_root, sense) }, lang, nil, nil, force_cat))
M.insert(term_counts, mw.site.stats.pagesInCategory(
root_category(lang, lang, joined_root, sense), "pages"))
end
if args["nocat"] or plain then
if args["nocat"] then
return M.concat(link_texts, ", ")
end
return M.concat(link_texts, ", ") .. M.concat(categories)
else
local link_text_output = ""
for i, link_text in ipairs(link_texts) do
link_text_output = link_text_output ..
"\n|-\n| " .. link_text ..
"\n|-\n| [[:Category:" ..
root_category(lang, lang, joined_roots[i], sense) ..
"|ศัพท์ " .. term_counts[i] .. " รายการ" --[[.. (term_counts[i] == 1 and "" or "s")]] .. "]]\n"
end
local wikicode = M.inflection_table.make_top{
title = "-",
palette = data.palette,
class = "floatright tr-alongside"
}
local article = lang:inFamily("sem") and UI_STRINGS.article_semitic or UI_STRINGS.article_generic
wikicode = wikicode .. UI_STRINGS.root_heading:format(article, --[[#term_counts == 1 and "ราก" or]] "ราก")
wikicode = wikicode .. link_text_output
wikicode = wikicode .. M.inflection_table.make_bottom{}
return wikicode .. M.concat(categories)
end
end
end
return export
6tg7ni4x0f0onkep1awdomtheaa7w42
มอดูล:Palm-translit
828
2359216
5775305
2026-10-14T13:02:37Z
Octahedron80
267
สร้างหน้าด้วย "local export = {} local tt = { ["𐡠"] = "อ", -- aleph ["𐡡"] = "บ", -- beth ["𐡢"] = "ค", -- gimel ["𐡣"] = "ด", -- daleth ["𐡤"] = "ฮ", -- he ["𐡥"] = "ว", -- waw ["𐡦"] = "ซ", -- zayin ["𐡧"] = "ฮฺ", -- heth ["𐡨"] = "ฏ", -- teth ["𐡩"] = "ย", -- yodh ["𐡪"] = "ก", -- kaph ["𐡫"] = "ล", -- lamedh ["𐡬"] = "ม", -- mem..."
5775305
Scribunto
text/plain
local export = {}
local tt = {
["𐡠"] = "อ", -- aleph
["𐡡"] = "บ", -- beth
["𐡢"] = "ค", -- gimel
["𐡣"] = "ด", -- daleth
["𐡤"] = "ฮ", -- he
["𐡥"] = "ว", -- waw
["𐡦"] = "ซ", -- zayin
["𐡧"] = "ฮฺ", -- heth
["𐡨"] = "ฏ", -- teth
["𐡩"] = "ย", -- yodh
["𐡪"] = "ก", -- kaph
["𐡫"] = "ล", -- lamedh
["𐡬"] = "ม", -- mem
["𐡭"] = "น", -- final nun
["𐡮"] = "น", -- nun
["𐡯"] = "ส", -- samekh
["𐡰"] = "อฺ", -- ayin
["𐡱"] = "พ", -- pe
["𐡲"] = "ศ", -- sadhe
["𐡳"] = "กฺ", -- qoph
["𐡴"] = "ร", -- resh
["𐡵"] = "ช", -- shin
["𐡶"] = "ต", -- taw
["𐡷"] = "☙", -- left-pointing fleuron
["𐡸"] = "❧", -- right-pointing fleuron
["𐡹"] = "[1]", -- one
["𐡺"] = "[2]", -- two
["𐡻"] = "[3]", -- three
["𐡼"] = "[4]", -- four
["𐡽"] = "[5]", -- five
["𐡾"] = "[10]", -- ten
["𐡿"] = "[20]", -- twenty
}
function export.tr(text, lang, sc)
if sc ~= "Palm" then
return
end
-- Transliterate characters
text = mw.ustring.gsub(text, '.', tt)
return text
end
return export
cys42npb5af43i00frfkc6hyoxnhajc
احتواء
0
2359217
5775314
2026-10-15T02:24:49Z
Octahedron80
267
เก็บกวาด
5775314
wikitext
text/x-wiki
== ภาษาอาหรับ ==
{{ar-rootbox|ح و ي}}
=== รากศัพท์ ===
{{ety|ar|id=containment|:root|ح و ي<id:root>|tree=1}}
{{ar-verbal noun}} ของ {{m|ar|اِحْتَوَى}}
=== การออกเสียง ===
{{ar-pr|اِحْتِوَاء}}
=== คำนาม ===
{{ar-noun|اِحْتِوَاء|m}}
# {{ar-verbal noun of|اِحْتَوَى|form=VIII}}
# [[การบรรจุ]], [[การควบคุม]] (ไม่ให้ลุกลาม/ขยายตัว)
# [[การจัดการ]], [[การควบคุม]]
#: {{coi|ar|'''اِحْتِوَاءُ''' الْأَزْمَةِ|t='''การจัดการ'''วิกฤตการณ์, '''การควบคุม'''วิกฤตการณ์}}
==== การผันรูป ====
{{ar-decl-noun|اِحْتِوَاء}}
==== คำสืบทอด ====
* {{desc|ota|احتوا|tr=ihtiva|bor=1}}
byv2i9913qe8f5t72yf1ryrefehllk0
แม่แบบ:ar-verbal noun
10
2359218
5775316
2026-10-15T02:27:51Z
Octahedron80
267
นำเข้าจาก enwikt
5775316
wikitext
text/x-wiki
{{#invoke:checkparams|warn}}<!-- Validate template parameters
-->{{#if:{{{lc|{{{nocap|}}}}}}|[[ภาคผนวก:หน่วยนามภาษาอาหรับ#คำกริยานาม|คำกริยานาม]]|[[ภาคผนวก:หน่วยนามภาษาอาหรับ#คำกริยานาม|คำกริยานาม]]}} {{#if:{{{nocat|}}}||{{catlangname|ar|คำกริยานาม}}}}<!--
--><noinclude>{{documentation}}</noinclude>
oywkyj81g5h5p71xnviy699gsiohkq8
ภาคผนวก:หน่วยนามภาษาอาหรับ
100
2359219
5775317
2026-10-15T02:29:16Z
Octahedron80
267
สร้างหน้าด้วย "{{softredirect|en:Appendix:Arabic nominals}}"
5775317
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
93mzxop1tm3yoob4rsi8hgf81g511tl
5775330
5775317
2026-10-15T04:27:45Z
Octahedron80
267
5775330
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
nla30gtodxqcvufejkkax8pc7stvou9
5775331
5775330
2026-10-15T04:32:07Z
Octahedron80
267
5775331
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
2x8rdgttlg3g60aww7llao1xfmjjq09
5775332
5775331
2026-10-15T04:34:06Z
Octahedron80
267
5775332
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
cgij5wfldl9jvtnkbl51g2did9a7hvi
5775333
5775332
2026-10-15T04:41:01Z
Octahedron80
267
5775333
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
507qyiuvkpiq45vb1thn7umytskae2s
5775334
5775333
2026-10-15T04:43:56Z
Octahedron80
267
5775334
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
as9rq8pvm0plm4w96ts93tpt5yjc3wh
5775335
5775334
2026-10-15T04:44:12Z
Octahedron80
267
/* คำคุณศัพท์บอกสีหรือข้อบกพร่อง */
5775335
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
dsh3qe69ovds9do1wbl78p6mxd0urob
5775336
5775335
2026-10-15T04:47:06Z
Octahedron80
267
5775336
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์บอกชนิดพันธุ์'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
ie7y1oghtzxtk2crc94rcsl3e43ijyv
5775338
5775336
2026-10-15T04:49:51Z
Octahedron80
267
/* คำเอกนาม */
5775338
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
ox1b9y1wbokgu7e1p3azvsnxr3y475m
5775339
5775338
2026-10-15T04:53:48Z
Octahedron80
267
5775339
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
kbv82wms4mmcabu4urzzygt9zqey9r9
5775340
5775339
2026-10-15T04:55:09Z
Octahedron80
267
5775340
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
1s8j4dszkngw35k4q1ajmy9zew4oui3
5775343
5775340
2026-10-15T05:01:50Z
Octahedron80
267
5775343
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการแปลแบบยืมโครงสร้าง (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
dr5rn0csggab15y1mj8xy1o25jq36kh
5775344
5775343
2026-10-15T05:03:19Z
Octahedron80
267
5775344
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการแปลแบบยืมโครงสร้าง (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
sopt75v6vzpg2l0t9rdjzeweqo1nzo1
5775345
5775344
2026-10-15T05:05:58Z
Octahedron80
267
5775345
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการแปลแบบยืมโครงสร้าง (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّล}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
nbxyhpyodrfi3lqopfvr33bgvustlpn
5775346
5775345
2026-10-15T05:07:27Z
Octahedron80
267
5775346
wikitext
text/x-wiki
{{softredirect|en:Appendix:Arabic nominals}}
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการแปลแบบยืมโครงสร้าง (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّล}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
==ดูเพิ่ม==
*[[:ภาคผนวก:รูปกริยาภาษาอาหรับ]]
[[หมวดหมู่:ภาคผนวกคำนาม|อาหรับ]]
[[หมวดหมู่:ภาคผนวกคำคุณศัพท์|อาหรับ]]
[[หมวดหมู่:ภาคผนวกภาษาอาหรับ|หน่วยนาม]]
f32ucpdg4yplsfy1m2hiekdhlp4fm5j
5775347
5775346
2026-10-15T05:07:59Z
Octahedron80
267
5775347
wikitext
text/x-wiki
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการแปลแบบยืมโครงสร้าง (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّล}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
==ดูเพิ่ม==
*[[:ภาคผนวก:รูปกริยาภาษาอาหรับ]]
[[หมวดหมู่:ภาคผนวกคำนาม|อาหรับ]]
[[หมวดหมู่:ภาคผนวกคำคุณศัพท์|อาหรับ]]
[[หมวดหมู่:ภาคผนวกภาษาอาหรับ|หน่วยนาม]]
l1p9fbum0z9b1e1dvn4tijme3ebnom1
5775348
5775347
2026-10-15T05:09:14Z
Octahedron80
267
/* คำนามบอกเครื่องมือ */
5775348
wikitext
text/x-wiki
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการยืมตรงตัว (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّล}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
==ดูเพิ่ม==
*[[:ภาคผนวก:รูปกริยาภาษาอาหรับ]]
[[หมวดหมู่:ภาคผนวกคำนาม|อาหรับ]]
[[หมวดหมู่:ภาคผนวกคำคุณศัพท์|อาหรับ]]
[[หมวดหมู่:ภาคผนวกภาษาอาหรับ|หน่วยนาม]]
tly2xr6z9vwj3nmcvjj84qe1fq3ctfy
5775349
5775348
2026-10-15T06:20:04Z
Octahedron80
267
/* ตัวบอกความเล็ก */
5775349
wikitext
text/x-wiki
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا|tr=biriṭāniyā||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ|tr=biriṭāniyy||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة|tr=dimuqrāṭiyya||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ|tr=dimuqrāṭiyy||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการยืมตรงตัว (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]|tr=kāsiḥat al-jalīd}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]|tr=kāsiḥat al-ʔalḡām}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]|tr=kāsiḥat aṯ-ṯulūj}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّل}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
==ดูเพิ่ม==
*[[:ภาคผนวก:รูปกริยาภาษาอาหรับ]]
[[หมวดหมู่:ภาคผนวกคำนาม|อาหรับ]]
[[หมวดหมู่:ภาคผนวกคำคุณศัพท์|อาหรับ]]
[[หมวดหมู่:ภาคผนวกภาษาอาหรับ|หน่วยนาม]]
1atxpih5239777qoudervesxwd7c50s
5775350
5775349
2026-10-15T06:21:57Z
Octahedron80
267
5775350
wikitext
text/x-wiki
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการยืมตรงตัว (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّل}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
==ดูเพิ่ม==
*[[:ภาคผนวก:รูปกริยาภาษาอาหรับ]]
[[หมวดหมู่:ภาคผนวกคำนาม|อาหรับ]]
[[หมวดหมู่:ภาคผนวกคำคุณศัพท์|อาหรับ]]
[[หมวดหมู่:ภาคผนวกภาษาอาหรับ|หน่วยนาม]]
t8u3h383hu3nyojdbcz4zgzh5gbtjuc
5775351
5775350
2026-10-15T06:23:24Z
Octahedron80
267
/* ดูเพิ่ม */
5775351
wikitext
text/x-wiki
==พหูพจน์หลายรูป==
คำนามภาษาอาหรับมักมีรูปพหูพจน์ได้หลายรูป ตัวอย่างเช่น {{m|ar|بَحْر||[[ทะเล]]}} สามารถมีรูปพหูพจน์เป็น {{m|ar|بِحَار}}, {{m|ar|بُحُور}}, {{m|ar|أَبْحَار}} หรือ {{m|ar|أَبْحُر}} รูปเหล่านี้เป็นทางเลือกต่าง ๆ ในการทำคำนามเดียวกันให้เป็นรูปพหูพจน์ ในบางครั้งรูปพหูพจน์รูปแบบใดรูปแบบหนึ่งจะสัมพันธ์กับนัยความหมายเฉพาะของคำนามนั้น ตัวอย่างเช่นในคำว่า {{m|ar|عين#คำนาม|عَيْن|t=[[ตา]]}} นัยความหมายที่ 5 คือ "ตัวสิ่งนั้นเอง" มีรูปพหูพจน์เฉพาะคือ {{m|ar|أَعْيُن}} ส่วนในกรณีอื่น ๆ อาจเป็นเรื่องของความนิยมในการเลือกใช้หรือภาษาถิ่น ในการระบุหัวข้อรายการศัพท์ที่มีพหูพจน์หลายรูป ควรพยายามเรียงรูปพหูพจน์ที่พบบ่อยที่สุดไว้เป็นลำดับแรก
==คำนามและคำคุณศัพท์ที่รับมา==
ในภาษาอาหรับ คำนามและคำคุณศัพท์หลากหลายประเภทสามารถรับมาจากรากกริยาได้ โดยทั่วไป การรับมาและแม่แบบอื่น ๆ สำหรับกริยาสามพยัญชนะจะแสดงโดยใช้ราก {{ar-root|ف ع ل|nocat=1}} สำหรับกริยาสี่พยัญชนะ รากดั้งเดิมคือ {{ar-root|ف ع ل ل|nocat=1}} แต่สิ่งนี้สร้างความสับสนเนื่องจากพยัญชนะตัวที่สามและสี่เหมือนกัน ซึ่งอาจทำให้เข้าใจผิดว่าเป็นกริยาพยัญชนะซ้ำ เราจึงใช้ {{ar-root|ف ع ز ل|nocat=1}} แทน
===คำกริยานาม===
คำกริยานาม ({{m|ar|مَصْدَر}}) ของ[[ภาคผนวก:คำกริยาภาษาอาหรับ#รูป I|รูป I]] ไม่ได้ดำเนินตามรูปแบบใดรูปแบบหนึ่งเป็นพิเศษ ที่พบบ่อยที่สุดคือ {{m|ar||فَعْل}} แต่ยังมีรูปแบบอื่น ๆ อีกมาก เช่น {{m|ar||فِعْل}}, {{m|ar||فُعْل}}, {{m|ar||فَعَل}}, {{m|ar||فَعَال}}, {{m|ar||فِعَال}}, {{m|ar||فُعُول}}, {{m|ar||فُعَال}}, {{m|ar||فَعُول}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعِل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعْلَان}}, {{m|ar||فُعْلَان}}, {{m|ar||فَعَلَان}} ฯลฯ รวมไปถึงรูปเพศหญิงที่คู่กัน เช่น {{m|ar||فَعْلَة}}, {{m|ar||فِعْلَة}}, {{m|ar||فُعْلَة}}, {{m|ar||فَعَلَة}}, {{m|ar||فَعَالَة}}, {{m|ar||فِعَالَة}}, {{m|ar||فُعُولَة}}, {{m|ar||فَعْلُولَة}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} ฯลฯ
ส่วนคำกริยานามของรูปอื่น ๆ จะดำเนินตามรูปแบบเฉพาะดังนี้:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! คำกริยานามสมบูรณ์ !! คำกริยานามท้ายอ่อน
|-
| I || ไม่มีรูปแบบเฉพาะ || ไม่มีรูปแบบเฉพาะ
|-
| II || {{m|ar||تَفْعِيل}}, {{m|ar||تَفْعَال}}, {{m|ar||فِعَّال}}, {{m|ar||تَفْعِلَة}} || {{m|ar||تَفْعِيَة}}
|-
| III || {{m|ar||مُفَاعَلَة}}, {{m|ar||فِعَال}} || {{m|ar||مُفَاعَاة}}, {{m|ar||فِعَاء}}
|-
| IV || {{m|ar||إِفْعَال}} || {{m|ar||إفْعَاء}}
|-
| V || {{m|ar||تَفَعُّل}}, {{m|ar||تِفِعَّال}} || {{m|ar||تَفَعٍّ}}
|-
| VI || {{m|ar||تَفَاعُل}} || {{m|ar||تَفَاعٍ}}
|-
| VII || {{m|ar||اِنْفِعَال}} || {{m|ar||اِنْفِعَاء}}
|-
| VIII || {{m|ar||اِفْتِعَال}} || {{m|ar||اِفْتِعَاء}}
|-
| IX || {{m|ar||اِفْعِلَال}} ||
|-
| X || {{m|ar||اِسْتِفْعَال}} || {{m|ar||اِسْتِفْعَاء}}
|-
| XI || {{m|ar||اِفْعِيلَال}} ||
|-
| XII || {{m|ar||اِفْعِيعَال}} || {{m|ar||اِفْعِيعَاء}}
|-
| XIII || {{m|ar||اِفْعِوَّال}} || {{m|ar||اِفْعِوَّاء}}
|-
| XIV || {{m|ar||اِفْعِنْلَال}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| XV || {{m|ar||اِفْعِنْلَاء}} || {{m|ar||اِفْعِنْيَاء}}??
|-
| Iq || {{m|ar||فَعْزَلَة}}, {{m|ar||فَعْزَال}}, {{m|ar||فِعْزَال}}, {{m|ar||فُعْزَال}} || {{m|ar||فَعْزَال}}??
|-
| IIq || {{m|ar||تَفَعْزُل}} || {{m|ar||تَفَعْزٍ}}
|-
| IIIq || {{m|ar||اِفْعِنْزَال}} || {{m|ar||اِفْعِنْزَاء}}
|-
| IVq || {{m|ar||اِفْعِزْلَال}} || {{m|ar||اِفْعِزْيَاء}}??
|-
|}
===รูปกริยาขยายกรรตุวาจก===
รูปกริยาขยายกรรตุวาจก ({{m|ar|اسم فاعل|اِسْم الْفَاعِل}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรตุวาจกสมบูรณ์ !! รูปกริยาขยายกรรตุวาจกท้ายอ่อน
|-
| I || {{m|ar||فَاعِل}} || {{m|ar||فَاعٍ}}
|-
| II || {{m|ar||مُفَعِّل}} || {{m|ar||مُفَعٍّ}}
|-
| III || {{m|ar||مُفَاعِل}} || {{m|ar||مُفَاعٍ}}
|-
| IV || {{m|ar||مُفْعِل}} || {{m|ar||مُفْعٍ}}
|-
| V || {{m|ar||مُتَفَعِّل}} || {{m|ar||مُتَفَعٍّ}}
|-
| VI || {{m|ar||مُتَفَاعِل}} || {{m|ar||مُتَفَاعٍ}}
|-
| VII || {{m|ar||مُنْفَعِل}} || {{m|ar||مُنْفَعٍ}}
|-
| VIII || {{m|ar||مُفْتَعِل}} || {{m|ar||مُفْتَعٍ}}
|-
| IX || {{m|ar||مُفْعَلّ}} || {{m|ar||مُفْعَيّ}}??
|-
| X || {{m|ar||مُسْتَفْعِل}} || {{m|ar||مُسْتَفْعٍ}}
|-
| XI || {{m|ar||مُفْعَالّ}} || {{m|ar||مُفْعَايّ}}??
|-
| XII || {{m|ar||مُفْعَوْعِل}} || {{m|ar||مُفْعَوْعٍ}}
|-
| XIII || {{m|ar||مُفْعَوِّل}} || {{m|ar||مُفْعَوٍّ}}
|-
| XIV || {{m|ar||مُفْعَنْلِل}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| XV || {{m|ar||مُفْعَنْلٍ}} || {{m|ar||مُفْعَنْيٍ}}??
|-
| Iq || {{m|ar||مُفَعْزِل}} || {{m|ar||مُفَعْزٍ}}
|-
| IIq || {{m|ar||مُتَفَعْزِل}} || {{m|ar||مُตَفَعْزٍ}}
|-
| IIIq || {{m|ar||مُفْعَنْزِل}} || {{m|ar||مُفْعَنْزٍ}}
|-
| IVq || {{m|ar||مُفْعَزِلّ}} || {{m|ar||مُفْعَزِيّ}}??
|-
|}
===รูปกริยาขยายกรรมวาจก===
รูปกริยาขยายกรรมวาจก ({{m|ar|اِسم مَفعول|اِسْم الْمَفْعُول}}) ดำเนินตามรูปแบบปรกติ:
:{| class="wikitable" style="text-align:center"
|-
! รูป !! รูปกริยาขยายกรรมวาจกสมบูรณ์ !! รูปกริยาขยายกรรมวาจกท้ายอ่อน
|-
| I || {{m|ar||مَفْعُول}} || {{m|ar||مَفْعُوّ}}, {{m|ar||مَفْعِيّ}}
|-
| II || {{m|ar||مُفَعَّل}} || {{m|ar||مُفَعًّى}}
|-
| III || {{m|ar||مُفَاعَل}} || {{m|ar||مُفَاعًى}}
|-
| IV || {{m|ar||مُفْعَل}} || {{m|ar||مُفْعًى}}
|-
| V || {{m|ar||مُتَفَعَّل}} || {{m|ar||مُتَفَعًّى}}
|-
| VI || {{m|ar||مُتَفَاعَل}} || {{m|ar||مُتَفَاعًى}}
|-
| VII || {{m|ar||مُنْفَعَل}} || {{m|ar||مُنْفَعًى}}
|-
| VIII || {{m|ar||مُفْتَعَل}} || {{m|ar||مُفْتَعًى}}
|-
| IX || ({{m|ar||مُفْعَلّ}}) || ({{m|ar||مُفْعَيّ}}??)
|-
| X || {{m|ar||مُسْتَفْعَل}} || {{m|ar||مُسْتَفْعًى}}
|-
| XI || ({{m|ar||مُفْعَالّ}}) || ({{m|ar||مُفْعَايّ}}??)
|-
| XII || {{m|ar||مُفْعَوْعَل}} || {{m|ar||مُفْعَوْعًى}}
|-
| XIII || {{m|ar||مُفْعَوَّل}} || {{m|ar||مُفْعَوًّى}}
|-
| XIV || {{m|ar||مُفْعَنْلَل}} || {{m|ar||مُفْعَنْلًى}}
|-
| XV || {{m|ar||مُفْعَنْلًى}} || {{m|ar||مُفْعَنْيًى}}??
|-
| Iq || {{m|ar||مُفَعْزَل}} || {{m|ar||مُفَعْزًى}}
|-
| IIq || {{m|ar||مُتَفَعْزَل}} || {{m|ar||مُتَفَعْزًى}}
|-
| IIIq || {{m|ar||مُفْعَنْزَل}} || {{m|ar||مُفْعَنْزًى}}
|-
| IVq || {{m|ar||مُفْعَزَلّ}} || {{m|ar||مُفْعَزَيّ}}??
|-
|}
===คำคุณศัพท์สัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ หรือที่รู้จักกันในคำภาษาอาหรับว่า [[nisba|นิสบะฮ์]] เป็นคำคุณศัพท์ที่สร้างขึ้นจากคำอื่นโดยการเติม {{m|ar|ـِيّ}} (มักออกเสียงเสมือนเขียนว่า {{m|ar||ـِي}} ทั้งนี้การออกเสียงด้วย ''yy'' จะกลับมาในรูปเพศหญิง {{m|ar||ـِيَّة}}, รูปพหูพจน์เพศชาย {{m|ar||ـِيُّون}} และรูปพหูพจน์เพศหญิง {{m|ar||ـِيَّات}}) โครงสร้างนี้ค่อนข้างยืดหยุ่น และสามารถเติมปัจจัยนิสบะฮ์เข้ากับคำนามชนิดใดก็ได้ รวมถึงรูปพหูพจน์ เช่นเดียวกับในบางกรณีที่เติมเข้ากับชนิดของคำอื่น ๆ (เช่น {{m|ar|خَارِجِيّ||[[ภายนอก]]}} จากคำคุณศัพท์ {{m|ar|خَارِج||[[ภายนอก]], [[ข้างนอก]]}}, {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จากคำคุณศัพท์ {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จากคำสรรพนาม {{m|ar|أَنَا||[[ฉัน]]}}, {{m|ar|فَوْقَانِيّ||[[ส่วนบน]]}} จากคำกริยาวิเศษณ์ {{m|ar|فَوْقُ||[[ข้างบน]]}}) คำคุณศัพท์นิสบะฮ์ยังสามารถสร้างขึ้นโดยตรงจากคำยืมภาษาต่างประเทศได้ด้วย เช่น {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} ซึ่งไม่มีคำว่า *{{m|ar||دِيمُقْرَاط}} ปรากฏอยู่จริง
เมื่อนำคำคุณศัพท์นิสบะฮ์ไปเติมเข้ากับคำนามเพศหญิงที่ลงท้ายด้วย {{m|ar|ـَة}} หรือ {{m|ar|ـَاة}} โดยปรกติจะตัดปัจจัยนี้ออก ดังเช่นในคำคุณศัพท์ {{m|ar|مَادِّيّ||[[ทางกายภาพ]], [[เชิงวัตถุ]]}} ซึ่งสร้างขึ้นจากคำนาม {{m|ar|مَادَّة||[[สสาร]], [[วัตถุ]]}} ปัจจัยที่พบบ่อยอย่าง {{m|ar|ـِيَا}} ซึ่งปรากฏในชื่อประเทศ (บางครั้งเขียนเป็น {{m|ar|ـِيَة}} โดยทั้งสองรูปยืมมาจาก {{m|la|-ia}}) ก็จะถูกตัดออกเช่นกัน ตัวอย่างเช่น จาก {{m|ar|بِرِيطَانِيَا||[[บริเตน]]}} สร้างเป็น {{m|ar|بِرِيطَانِيّ||[[เกี่ยวกับบริเตน]]}} ปัจจัยอื่น ๆ อาจถูกตัดออกได้เช่นกัน เช่น จาก {{m|ar|كِيمِيَاء||[[เคมี]]}} สร้างเป็น {{m|ar|كِيمِيّ||[[ทางเคมี]]}} (รวมถึง {{m|ar|كِيمِيَائِيّ}} หรือ {{m|ar|كِيمَاوِيّ}})
ในบางกรณี โดยเฉพาะคำสั้นมากที่มีเพียงพยัญชนะและสระสั้นคั่น จะมีการเพิ่มพยัญชนะเชื่อมเข้ามา ดังเช่นใน {{m|ar|سَنَوِيّ||[[ประจำปี]]}} จาก {{m|ar|سَنَة||[[ปี]]}}, {{m|ar|نَوَوِيّ||[[นิวเคลียร์]]}} จาก {{m|ar|نَوَاة||[[นิวเคลียส]], [[เมล็ด]]}}, {{m|ar|يَدَوِيّ||[[ทำด้วยมือ]], [[คู่มือ]]}} จาก {{m|ar|يَد||[[มือ]]}}, {{m|ar|دَمَوِيّ||[[เกี่ยวกับเลือด]]}} จาก {{m|ar|دَم||[[เลือด]]}} (รวมถึง {{m|ar|دَمِيّ}} โดยไม่มีพยัญชนะเชื่อม) โดยปรกติพยัญชนะเชื่อมเฉพาะนี้คือ {{m|ar|و}} แต่อาจเป็นพยัญชนะตัวอื่นหากพยัญชนะนั้นปรากฏในรูปที่รับมารูปอื่นของคำพื้นฐานนั้น เทียบกับ {{m|ar|شَفَهِيّ||[[เกี่ยวกับริมฝีปาก]]}} และ {{m|ar|شَفَوِيّ}} จาก {{m|ar|شَفَة||[[ริมฝีปาก]]}} (เทียบกับรูปพหูพจน์ {{m|ar|شِفَاه||[[ริมฝีปากทั้งหลาย]]}} และ {{m|ar|شَفَوَات}}) โปรดสังเกตว่าพยัญชนะเชื่อมจะ''ไม่''ถูกนำมาใช้ในกรณีเช่น {{m|ar|عَادِيّ||[[ปรกติ]]}} ซึ่งมีสระยาว (จาก {{m|ar|عَادَة||[[ธรรมเนียม]], [[นิสัย]]}}) หรือ {{m|ar|صِحِّيّ||[[เกี่ยวกับสุขภาพ]]}} ซึ่งมีพยัญชนะซ้ำ (จาก {{m|ar|صِحَّة||[[สุขภาพ]]}}) พยัญชนะเชื่อมอาจปรากฏร่วมกับลำต้นที่มาจากรากท้ายอ่อน เช่น {{m|ar|ثَانَوِيّ||[[ทุติยภูมิ]], [[มัธยม]]}} จาก {{m|ar|ثَانٍ||[[ที่สอง]]}}, {{m|ar|عَلَوِيّ||[[ส่วนบน]], [[แห่งสวรรค์]], [[อะละวี]]}} จาก {{m|ar|عَلِيّ||[[สูง]], [[สูงส่ง]], [[อะลี]]}} ตัวอย่างที่มีตัวเชื่อม {{m|ar||ـَانـ}} ได้แก่ {{m|ar|أَنَانِيّ||[[เห็นแก่ตัว]]}} จาก {{m|ar|أَنَا||[[ฉัน]]}} และ {{m|ar|عَلْمَانِيّ||[[ทางโลก]], [[โลกียะ]]}} จาก {{m|ar|عَالَم||[[โลก]]}} ในบางครั้งลำต้นอาจเกิดการแปรเปลี่ยนรูปไป (มักจะสั้นลง) ในรูปนิสบะฮ์ ดังเช่นใน {{m|ar|عَلْمَانِيّ}} ที่เพิ่งกล่าวไป (ออกเสียงเป็น {{m|ar|عِلْمَانِيّ}} ได้เช่นกัน) และ {{m|ar|عُلْوِيّ||[[ส่วนบน]]}} จาก {{m|ar|عُلُوّ||[[ความสูง]]}}
===คำนามสัมพันธ์ (นิสบะฮ์)===
คำคุณศัพท์สัมพันธ์ ([[nisba|นิสบะฮ์]]) สามารถนำมาทำเป็นคำนามได้อย่างอิสระ ตัวอย่างเช่น จากคำคุณศัพท์ {{m|ar|بِرِيطَانِيّ||[[เกี่ยวกับบริเตน]]}} รับมาเป็นคำนาม {{m|ar|بِرِيطَانِيّ||[[ชายชาวบริเตน]], [[ชาวบริเตน]]}} และจากคำคุณศัพท์ {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} สร้างเป็นคำนาม {{m|ar|دِيمُقْرَاطِيّ||[[นักประชาธิปไตย]]}} คำนามเหล่านี้สร้างรูปเพศหญิงและรูปพหูพจน์ในแบบเดียวกับคำคุณศัพท์ที่คู่กัน
นอกจากนี้ คำนามนิสบะฮ์เพศหญิงมักมีความหมายเป็นอาการนาม ตัวอย่างเช่น {{m|ar|دِيمُقْرَاطِيَّة||[[ประชาธิปไตย]]}} จาก {{m|ar|دِيمُقْرَاطِيّ||[[เกี่ยวกับประชาธิปไตย]]}} หรือ {{m|ar|ذِهْنِيَّة||[[กรอบความคิด]], [[จิตตานุภาพ]]}} จาก {{m|ar|ذِهْنِيّ||[[ทางจิตใจ]]}} (ซึ่งสร้างมาจาก {{m|ar|ذِهْن||[[จิตใจ]]}} อีกทอดหนึ่ง) ในบางกรณี วิธีที่ดีที่สุดคือมองว่าคำนามเหล่านี้สร้างขึ้นโดยตรงโดยใช้ปัจจัย {{m|ar|ـِيَّة}} โดยเฉพาะอย่างยิ่งเนื่องจากอาจไม่มีคำที่ลงท้ายด้วย {{m|ar|ـِيّ}} ที่คู่กันปรากฏอยู่ ตัวอย่างเช่น {{m|ar|كَمِّيَّة||[[ปริมาณ]]}} สร้างขึ้นจาก {{m|ar|كَمّ||[[ปริมาณ]]}}, {{m|ar|أَهَمِّيَّة||[[ความสำคัญ]]}} สร้างขึ้นจาก {{m|ar|أَهَمّ||[[สำคัญกว่า]], [[สำคัญมาก]]}} และ {{m|ar|هُوِيَّة||[[อัตลักษณ์]]}} สร้างขึ้นจาก {{m|ar|هُوَ||[[เขา]]}} (โปรดสังเกตว่าสองตัวอย่างหลังสร้างขึ้นจากชนิดของคำอื่นที่ไม่ใช่คำนาม)
===คำคุณศัพท์พื้นฐาน===
คำคุณศัพท์จำนวนมากสร้างขึ้นจากรากสามพยัญชนะโดยใช้รูปแบบ {{m|ar||فَعِيل}} ตัวอย่างเช่น:
* {{m|ar|كَبِير|t=ใหญ่}} จาก {{ar-root|ك ب ر|nocat=1}}
* {{m|ar|كَثِير|t=มาก, หลาย}} จาก {{ar-root|ك ث ر|nocat=1}}
* {{m|ar|سَعِيد|t=มีความสุข}} จาก {{ar-root|س ع د|nocat=1}}
* {{m|ar|جَدِيد|t=ใหม่}} จาก {{ar-root|ج د د|nocat=1}}
* {{m|ar|قَرِيب|t=ใกล้}} จาก {{ar-root|ق ر ب|nocat=1}}
* {{m|ar|جَمِيل|t=สวย, งาม}} จาก {{ar-root|ج م ل|nocat=1}}
คำนามบางคำใช้รูปนี้เช่นกัน ตัวอย่างเช่น {{m|ar|الْخَمِيس|t=วันพฤหัสบดี}}
รูปพหูพจน์เพศชายอาจเป็นแบบสมบูรณ์ หรือแบบแตก รูปแบบที่พบบ่อยที่สุดคือ {{m|ar||فُعَلَاء}} และ {{m|ar||فِعَال}} ส่วนรูปแบบอื่น ๆ ได้แก่ {{m|ar||أَفْعِلَاء}}, {{m|ar||فُعُل}} และ {{m|ar||أَفْعَال}}
* เอกพจน์ {{m|ar|سَعِيد|t=มีความสุข}}, พหูพจน์ {{m|ar|سُعَدَاء}}
* เอกพจน์ {{m|ar|كَبِير|t=ใหญ่}}, พหูพจน์ {{m|ar|كُبَرَاء}} หรือ {{m|ar|كِبَار}}
* เอกพจน์ {{m|ar|صَدِيق|t=เพื่อน}}, พหูพจน์ {{m|ar|أَصْدِقَاء}}
===คำคุณศัพท์ยกระดับ===
[[elative|คำคุณศัพท์ยกระดับ]] ({{m|ar|اِسْم تَفْضِيل|اِسْم التَّفْضِيل}} หรือ {{m|ar|أَفْعَل التَّفْضِيل}}) สร้างขึ้นจากคำคุณศัพท์พื้นฐานสามพยัญชนะ โดยทั่วไปมาจากรูป {{m|ar||فَعِيل}} หรือ {{m|ar||فَاعِل}} แต่ก็พบรูปอย่าง {{m|ar||فَعْل}}, {{m|ar||فِعْل}} หรือ {{m|ar||فُعْل}} ได้เช่นกัน คำคุณศัพท์ยกระดับสร้างขึ้นโดยตรงจากรากของคำคุณศัพท์ และมีรูป[[diptote|ดิปโทต]] {{m|ar||أَفْعَل}} ในเพศชายเอกพจน์ คำคุณศัพท์ยกระดับมีความหมายเป็น[[comparative|ขั้นกว่า]] (เช่น ''smarter'' หรือ ''more intelligent'' ในภาษาอังกฤษ), [[superlative|ขั้นสุด]] (เช่น ''smartest'' หรือ ''most intelligent'' ในภาษาอังกฤษ) และ[[absolute superlative|ขั้นบริบูรณ์]] (เช่น ''very smart'', ''utterly intelligent'' ในภาษาอังกฤษ) ความแตกต่างมักแสดงออกผ่านโครงสร้างทางวากยสัมพันธ์ที่ต่างกัน คำคุณศัพท์บางคำมีรูปเป็นคำคุณศัพท์ยกระดับโดยไม่มีความหมายเชิงยกระดับ ตัวอย่างเช่น {{m|ar|آخَر||อื่น}} ในทางตรงกันข้าม คำคุณศัพท์บางคำถูกนำมาใช้เป็นคำคุณศัพท์ยกระดับโดยไม่ได้อยู่ในรูปยกระดับ ตัวอย่างเช่น {{m|ar|خَيْر||ดีกว่า, ดีที่สุด}}
รูปแบบการผันคำสำหรับคำคุณศัพท์ยกระดับมีดังนี้: เพศหญิงเอกพจน์มีรูป {{m|ar||فُعْلَى}} ซึ่งไม่ผันแปรตามการกและสถานะ ส่วนพหูพจน์เพศชายเป็นดิปโทต {{m|ar||أَفَاعِل}} หรือแบบสมบูรณ์ {{m|ar||أَفْعَلُون}} พหูพจน์เพศหญิงอาจเป็น {{m|ar||فُعَل}} หรือแบบสมบูรณ์ {{m|ar||فُعْلَيَات}} ตัวอย่างที่มีการแจกวิภัตติครบถ้วนคือ {{m|ar|أَكْبَر||[[ใหญ่กว่า]], [[ใหญ่ที่สุด]]}} ซึ่งเป็นคำคุณศัพท์ยกระดับของ {{m|ar|كَبِير||[[ใหญ่]]}} คำคุณศัพท์นี้มีเพศหญิงเอกพจน์เป็น {{m|ar|كُبْرَى}}, พหูพจน์เพศชายเป็น {{m|ar|أَكْبَرُون}} และ {{m|ar|أَكَابِر}} และพหูพจน์เพศหญิงเป็น {{m|ar|كُبْرَيَات}}
คำคุณศัพท์ยกระดับบางคำ เช่น {{m|ar||آخَر}} และ {{m|ar|أَوَّل||แรก, อันดับแรก}} ดำเนินตามการผันเหล่านี้อย่างสม่ำเสมอ อย่างไรก็ตาม คำคุณศัพท์ยกระดับส่วนใหญ่สามารถอยู่ในรูปเพศชายเอกพจน์ได้ แม้ว่าจะอ้างถึงคำนามเพศหญิงหรือพหูพจน์ก็ตาม อันที่จริง มีรูปคำคุณศัพท์ยกระดับที่ผันแล้วเพียงจำนวนจำกัดเท่านั้นที่ใช้กันในภาษาอาหรับร่วมสมัย และรูปเหล่านี้มักจำกัดอยู่เฉพาะในนัยความหมายขั้นบริบูรณ์ เช่น ใน {{m|ar|بِرِيطانْيَا اَلْعُظْمَى||บริเตนใหญ่}} ส่วนในภาษาอาหรับคลาสสิก รูปคำคุณศัพท์ยกระดับที่ผันแล้วถูกนำมาใช้อย่างอิสระมากกว่า
===คำคุณศัพท์บอกสีหรือข้อบกพร่อง===
{{anchor|Color/defect adjectives}}
คำคุณศัพท์บอกสีหรือข้อบกพร่อง คือคำคุณศัพท์ในรูป {{m|ar||أَفْعَل}} โดยมีเพศหญิงเอกพจน์เป็น {{m|ar||فَعْلَاء}} โดยทั่วไปหมายถึงสีและข้อบกพร่องทางกายภาพ ทั้งเพศชายและเพศหญิงเป็นคำแบบ[[diptote|ดิปโทต]] โปรดสังเกตว่าเพศชายเอกพจน์มีรูปเดียวกับคำคุณศัพท์ยกระดับ แต่เพศหญิงเอกพจน์จะแตกต่างกัน รูปพหูพจน์ทั้งเพศชายและเพศหญิงมักอยู่ในรูป {{m|ar||فُعْل}} แต่ก็มีข้อยกเว้น เช่น {{m|ar|أَحْمَق||[[บ้า]]}} ซึ่งมีพหูพจน์ปรกติเป็น {{m|ar|حُمْق}} แต่ก็มีรูปพหูพจน์เป็น {{m|ar|حُمُق}}, {{m|ar|حَمْقَى}} และ {{m|ar|حَمَاقَى}} เช่นกัน ตัวอย่างต้นแบบของคำคุณศัพท์บอกสีในรูปนี้ ได้แก่:
* {{m|ar|أَبْيَض||[[ขาว]]}},
* {{m|ar|أَسْوَد||[[ดำ]]}},
* {{m|ar|أَحْمَر||[[แดง]]}},
* {{m|ar|أَزْرَق||[[น้ำเงิน]], [[ฟ้า]]}},
* {{m|ar|أَخْضَر||[[เขียว]]}} และ
* {{m|ar|أَصْفَر||[[เหลือง]]}}
ยังมีคำอื่น ๆ อีก เช่น
* {{m|ar|أَغْبَر||[[สีฝุ่น]], [[สีกระดำกระด่าง]]}},
* {{m|ar|أَسْمَر||[[ผิวคล้ำ]], [[สีน้ำตาลแกมเหลือง]]}} และ
* {{m|ar|أَشْقَر||[[ผมบลอนด์]], [[สีทองแดง]]}}
แต่สีส่วนใหญ่ที่เหลือมักอยู่ในรูปคำคุณศัพท์[[nisba|นิสบะฮ์]] เช่น
* {{m|ar|بُنِّيّ||[[น้ำตาล]]}} (ตามตัวอักษรคือ "กาแฟ" มาจาก {{m|ar|بُنّ||[[กาแฟ]]}}),
* {{m|ar|بَنَفْسَجِيّ||[[ม่วง]]}} (มาจาก {{m|ar|بَنَفْسَج||[[ไวโอเลต]] {{gloss|[[ดอกไม้]]}}}}),
* {{m|ar|بُرْتُقَالِيّ||[[ส้ม]]}} (มาจาก {{m|ar|بُرْتُقَال||[[ส้ม]] {{gloss|[[ผลไม้]]}}}}), ฯลฯ
คำคุณศัพท์บอก "ข้อบกพร่อง" ที่เป็นต้นแบบจะหมายถึงข้อบกพร่องทางกายภาพจริง ๆ เช่น
* {{m|ar|أَطْرَش||[[หูหนวก]]}},
* {{m|ar|أَعْمَى||[[ตาบอด]]}},
* {{m|ar|أَعْوَر||[[ตาบอดข้างเดียว]]}},
* {{m|ar|أَحْوَل||[[ตาเข]]}},
* {{m|ar|أَجْرَب||[[เป็นขี้เรื้อน]]}},
* {{m|ar|أَجْرَد||[[หัวล้าน]]}}
แต่คำอื่น ๆ อาจหมายถึงข้อบกพร่องทางจิตใจ เช่น
* {{m|ar|أَبْلَه||[[โง่เขลา]], [[เซ่อ]]}} และ
* {{m|ar|أَحْمَق||[[บ้า]]}}
ในขณะที่บางคำหมายถึงคุณลักษณะที่อาจมีความหมายโดยนัยเชิงลบ แต่ไม่ได้เป็น "ข้อบกพร่อง" อย่างชัดเจน เช่น
* {{m|ar|أَخْشَن||[[หยาบ]], [[หยาบคาย]]}},
* {{m|ar|أَعْقَد||[[เป็นปม]]}},
* {{m|ar|أَزَبّ||[[มีขนดก]]}},
* {{m|ar|أَمْيَل||[[เอียง]], [[ลาด]]}},
* {{m|ar|أَجْوَف||[[เว้า]], [[กลวง]]}},
* {{m|ar|أَغْلَف||[[ยังไม่ทำสุหนัต]], [[ไร้อารยธรรม]]}},
* {{m|ar|أَعْزَب||[[โสด]]}} และ
* {{m|ar|أَبْتَر||[[ไร้บุตร]], [[ไร้ทายาท]]}}
และยังมีคำอื่น ๆ ที่มีความหมายซึ่งไม่สามารถจัดว่าเป็นข้อบกพร่องได้เลยในทางใดทางหนึ่ง เช่น
* {{m|ar|أَلْيَس||[[กล้าหาญ]]}},
* {{m|ar|أَشْوَส||[[ทรนง]], [[บ้าบิ่น]]}} และ
* {{m|ar|أَجْمَع||[[ทั้งหมด]], [[ทั้งสิ้น]]}}
รากต้นอ่อนและรากกลางอ่อนจะสร้างขึ้นในลักษณะเดียวกับรากแข็งแรง เช่น {{m|ar|أَوْجَر||[[ขี้ขลาด]], [[หวาดกลัว]]}} และ {{m|ar|أَبْيَض||[[ขาว]]}}; รากท้ายอ่อนสร้างขึ้นตามรูปแบบ {{m|ar||أَفْعَى}} เช่น {{m|ar|أَعْمَى||[[ตาบอด]]}}; ส่วนรากพยัญชนะซ้ำสร้างขึ้นตามรูปแบบ {{m|ar||أَفَعّ}} เช่น {{m|ar|أَزَبّ||[[มีขนดก]]}}
===คำสมุหนาม===
คำสมุหนามมีรูปเป็นเอกพจน์แต่มีความหมายเป็นพหูพจน์ คำสมุหนามส่วนใหญ่หมายถึงสิ่งที่ไม่ใช่มนุษย์ (มักเป็นสัตว์หรือพืช) แต่ก็มีคำสมุหนามสำหรับมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญาอื่น ๆ ด้วยเช่นกัน กลุ่มหลังนี้บางครั้งเรียกว่า ''คำสมุหนามบอกชาติพันธุ์'' (ethnic collectives) ซึ่งมักใช้การสอดคล้องแบบพหูพจน์ ในขณะที่คำสมุหนามสิ่งที่ไม่ใช่มนุษย์โดยทั่วไปจะใช้การสอดคล้องแบบเอกพจน์
คำนามที่มีความหมายเป็นเอกพจน์ที่คู่กันคือ ''คำเอกนาม'' (ดูด้านล่าง) ซึ่งคำเอกนามนี้มักสามารถนำไปสร้างเป็นรูปพหูพจน์แท้จริงต่อได้
===คำเอกนาม===
คำเอกนาม ({{l|ar|اِسْم وَحْدَة}}) มีความหมายเป็นเอกพจน์และสร้างขึ้นจากคำสมุหนามโดยการเติม {{m|ar|َة}} เว้นแต่ว่าคำสมุหนามนั้นหมายถึงมนุษย์หรือสิ่งมีชีวิตทรงภูมิปัญญา ซึ่งในกรณีนี้จะลงท้ายด้วยส่วนลงท้าย[[nisba|นิสบะฮ์]] {{m|ar|ـِيّ}} เช่น {{m|ar|عَرَب||[[ชาวอาหรับ]]ทั้งหลาย}}, {{m|ar|عَرَبِيّ||[[ชาวอาหรับ]]คนหนึ่ง}} หรือ {{m|ar|يَهُود||[[ชาวยิว]]ทั้งหลาย}}, {{m|ar|يَهُودِيّ||[[ชาวยิว]]คนหนึ่ง}} หรือ {{m|ar|جِنّ||[[ญิน]], ปีศาจทั้งหลาย}}, {{m|ar|جِنِّي||ญินตนหนึ่ง, ปีศาจตนหนึ่ง}}
คำเอกนามสร้างรูปพหูพจน์ตามวิธีปรกติ เช่น จาก {{m|ar|شَجَرَة||ต้นไม้}} เป็นรูปพหูพจน์ {{m|ar|أَشْجَار}} ทั้งรูปนี้และคำสมุหนาม {{m|ar|شَجَر}} ต่างแปลเป็นภาษาอังกฤษได้ว่า “trees” (ต้นไม้หลายต้น) ความแตกต่างคือ {{m|ar||أَشْجَار}} มองต้นไม้เหล่านั้นเป็นรายต้นหรือแยกเป็นเอกเทศ ส่วน {{m|ar|شَجَر}} มองในภาพรวม (กรณีคล้ายกันในภาษาอังกฤษอาจเทียบได้กับความแตกต่างระหว่าง {{m|en|persons}} และ {{m|en|people}}) รูปพหูพจน์ของคำเอกนามในบางครั้งเรียกว่า ''พหูพจน์แสดงความหลากหลาย'' (plurals of variety) คำเรียกนี้อาจทำให้เข้าใจคลาดเคลื่อนได้อยู่บ้าง แต่มีที่มาจากข้อเท็จจริงที่ว่า {{m|ar||أَشْجَار}} ยังถูกนำมาใช้ในความหมายว่า “ต้นไม้หลากชนิด” ได้ด้วยเช่นกัน
===คำนามบอกครั้ง===
คำนามบอกครั้ง ({{l|ar|اِسْم مَرَّة}}) มีความหมายว่า "การกระทำสิ่งใดสิ่งหนึ่งหนึ่งครั้ง" และสร้างขึ้นจากคำกริยานามโดยการเติม {{m|ar|َة}} เช่น จากคำกริยานาม {{m|ar|ضَرْب||[[การตี]], [[การชก]]}} สร้างเป็น {{m|ar|ضَرْبَة||[[การตีหนึ่งครั้ง]], [[การฟาดหนึ่งที]]}} และจากคำกริยานาม {{m|ar|اِنْتِفَاض||[[การสลัดออก]]}} สร้างเป็น {{m|ar|اِنْتِفَاضَة||[[การสลัดออกหนึ่งครั้ง]], [[การลุกฮือ]], [[อินติฟาดะฮ์]]}}
===คำนามบอกสถานที่===
[[noun of place|คำนามบอกสถานที่]] ({{l|ar|اِسْم مَكَان}}) โดยทั่วไปรับมาจากรากกริยา และมีความหมายโดยประมาณว่า “สถานที่สำหรับกระทำ <var>x</var>” โดยที่ <var>x</var> คือความหมายของกริยานั้น คำนามบอกสถานที่ของ[[base stem|ลำต้นฐาน]] ({{ar-form|I|nocap=1}}) โดยทั่วไปจะมีอุปสรรค {{m|ar||مَـ}} โดยมีรูปเป็น {{m|ar||مَفْعِل}}, {{m|ar||مَفْعَل}}, {{m|ar||مَفْعَلَة}}, {{m|ar||مَفْعِلَة}} และพบรูป {{m|ar||مَفْعُلَة}} ได้ยาก
ตัวอย่างเช่น:
* {{m|ar|مَكْتَب|t=[[โต๊ะทำงาน]], [[สำนักงาน]]}} และ {{m|ar|مَكْتَبَة|t=[[ห้องสมุด]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
* {{m|ar|مَطْبَخ|t=[[ครัว]]}} จาก {{m|ar|طَبَخَ|t=[[ปรุงอาหาร]]}}
* {{m|ar|مَصْنَع|t=[[โรงงาน]]}} จาก {{m|ar|صَنَعَ|t=[[ทำ]], [[ผลิต]]}}
* {{m|ar|مَجْلِس|t=[[ที่นั่ง]]}} จาก {{m|ar|جَلَسَ|t=[[นั่ง]]}}
* {{m|ar|مَقْبَرَة}} และ {{m|ar|مَقْبُرَة|t=[[สุสาน]]}} จาก {{m|ar|قَبَرَ|t=[[ฝัง]]}}
คำนามบอกสถานที่บางคำสร้างขึ้นจากรากที่ไม่ใช่กริยา เช่น {{m|ar|مَقْهًى||[[คาเฟ่]], [[ร้านกาแฟ]]}} สร้างขึ้นจากรากของ {{m|ar|قَهْوَة||[[กาแฟ]]}} และมีความหมายตามตัวอักษรว่า “สถานที่แห่งกาแฟ”
คำนามบอกสถานที่ของกริยาที่นอกเหนือจากรูป I จะใช้รูปเดียวกันกับ[[passive participle|รูปกริยาขยายกรรมวาจก]] ซึ่งหมายความว่าจะขึ้นต้นด้วย {{m|ar||مُـ}} เช่น {{m|ar|مُسْتَشْفًى|t=[[โรงพยาบาล]]}} สร้างขึ้นจากกริยารูป X {{m|ar|اِسْتَشْفَى|t=[[แสวงหา]][[การรักษา]]}} จึงหมายถึง “สถานที่สำหรับแสวงหาการรักษา”, {{m|ar|مُنْتَزَه}} ของ{{ar-form|VII|nocap=1}} และ {{m|ar|مُتَنَزَّه}} ของ{{ar-form|V|nocap=1}} แปลว่า “สวนสาธารณะ, ที่ซึ่งผู้คนไปเดินเล่น”, {{m|ar|مُسْتَنْبَت|t=สถานที่เพาะปลูกพืช}} จากกริยารูป X {{m|ar|اِسْتَنْبَتَ|t=ปลูก, เพาะปลูก}}
===คำนามบอกเครื่องมือ===
คำนามบอกเครื่องมือ ({{m|ar|اسم آلة|اِسْم الْآلَة}}) โดยทั่วไปรับมาจากคำกริยา และมีความหมายโดยประมาณว่า ''เครื่องมือสำหรับกระทำ X'' โดยที่ ''X'' คือความหมายของคำกริยาพื้นฐาน คำนามบอกเครื่องมือมักมีอุปสรรค {{m|ar||مِـ}} และมักอยู่ในรูป {{m|ar|مِفْعَل}}, {{m|ar|مِفْعَلَة}} หรือ {{m|ar|مِفْعَال}} ตัวอย่างเช่น:
*{{m|ar|مِحْفَر||[[พลั่ว]]}}, จาก {{m|ar|حَفَرَ||[[ขุด]]}}
*{{m|ar|مِكْشَط||[[มีดขูดลบ]]}}, จาก {{m|ar|كَشَطَ||[[ขูดลบ]], [[ขูดออก]]}}
*{{m|ar|مِكْنَسَة||[[ไม้กวาด]]}}, จาก {{m|ar|كَنَسَ||[[กวาด]]}}
*{{m|ar|مِكْوَاة||[[เตารีด]]}}, จาก {{m|ar|كَوَى||[[รีดผ้า]], [[เผาไหม้]]}}
*{{m|ar|مِيزَان||[[ตาชั่ง]]}}, จาก {{m|ar|وَزَنَ||[[ชั่ง]]}}
*{{m|ar|مِحَشّ||[[เคียว]]}}, รวมถึง {{m|ar|مِحَشَّة}}, จาก {{m|ar|حَشَّ||[[เกี่ยวหญ้า]], [[ตัดหญ้า]]}}
*{{m|ar|مِلْعَقَة||[[ช้อน]]}}, จาก {{m|ar|لَعِقَ||[[เลีย]]}}
*{{m|ar|مِكْتَاب||[[เครื่องพิมพ์ดีด]]}}, จาก {{m|ar|كَتَبَ||[[เขียน]]}}
คำนามบางคำในกลุ่มนี้รับมาจากคำนามอื่น โดยมีความหมายโดยประมาณว่า "เครื่องมือที่เกี่ยวข้องกับ X":
* {{m|ar|مِكْوَر||[[ผ้าโพกศีรษะ]]}}, รวมถึง {{m|ar|مِكْوَرَة}}, จาก {{m|ar|كُورَة||[[ลูกบอล]], [[ทรงกลม]]}}
* {{m|ar|مِرْوَحَة||[[พัดลม]], [[พัด]]}}, จากราก {{m|ar|ر و ح|pos=root}} ของ {{m|ar|رِيح||[[ลม]]}}
แนวโน้มเมื่อไม่นานมานี้จะหันไปรับคำนามบอกเครื่องมือมาจากรูปเพศหญิงของคำนาม/คำคุณศัพท์บอกอาชีพหรือลักษณะเฉพาะ หรือจากรูปกริยาขยายกรรตุวาจก ซึ่งอาจเป็นการยืมตรงตัว (calque) จากภาษาอังกฤษ:
* {{m|ar|دَبَّابَة||[[รถถัง]]}}, จาก {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|دَبَّ||[[คืบคลาน]]}}
* {{m|ar|نَظَّارَة||[[กล้องโทรทรรศน์]], [[แว่นตา]]}}, จาก {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}, จาก {{m|ar|نَظَرَ||[[มอง]], [[ดู]]}}
* {{m|ar|طَابِعَة||[[เครื่องพิมพ์]] {{gloss|อุปกรณ์คอมพิวเตอร์}}}}, จาก {{m|ar|طَابِع||[[ช่างพิมพ์]] {{gloss|บุคคล}}}}, จาก {{m|ar|طَبَعَ||[[พิมพ์]], [[ประทับตรา]]}}; เทียบกับ {{m|ar|مِطْبَعَة||[[แท่นพิมพ์]], [[โรงพิมพ์]]}}
* {{m|ar|كَاسِحَة||[[เครื่องกวาด]]}} (เทียบกับ {{m|ar|كَاسِحَة الجَلِيد||[[เรือตัดน้ำแข็ง]]}}, {{m|ar|كَاسِحَة الأَلْغَام||[[เรือกวาดทุ่นระเบิด]]}}, {{m|ar|كَاسِحَة الثُلُوج||[[รถกวาดหิมะ]]}}, จาก {{m|ar|كَاسِح||[[ที่กวาดล้างทุกสิ่ง]]}}, จาก {{m|ar|كَسَحَ||[[กวาด]], [[เก็บกวาด]]}}
คำนามบอกเครื่องมือบางคำรับมาจากรูปกริยาขยายกรรตุวาจกโดยตรง:
* {{m|ar|مُحَرِّك||[[เครื่องยนต์]]}} (เดิมหมายถึง "สิ่งที่ขับเคลื่อน"), จาก {{m|ar|حَرَّكَ||[[ขับเคลื่อน]], [[ขยับ]]}}
===คำนามบอกอาชีพ===
''คำนามบอกอาชีพ'' สามารถรับมาจากลำต้นกริยาได้เป็นจำนวนมาก โดยทั่วไปใช้รูป {{m|ar||فَعَّال}} เช่น {{m|ar|كَتَّاب||[[เสมียน]], [[อาลักษณ์]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}
[[active participle|รูปกริยาขยายกรรตุวาจก]]ก็สามารถนำมาใช้สร้างคำนามบอกอาชีพได้เช่นกัน เช่น {{m|ar|طَالِب||[[นักเรียน]], [[นักศึกษา]]}} จาก {{m|ar|طَلَبَ||[[ขอ]], [[แสวงหา]]}}, {{m|ar|كَاتِب||[[นักเขียน]], [[เสมียน]]}} จาก {{m|ar|كَتَبَ||[[เขียน]]}}, {{m|ar|بَائِع||[[ผู้ขาย]]}} จาก {{m|ar|بَاعَ||[[ขาย]]}}, {{m|ar|مُهَنْدِس||[[วิศวกร]]}} จาก {{m|ar|هَنْدَسَ||[[ออกแบบทางวิศวกรรม]]}} คำที่ใช้รูป {{m|ar||فَاعِل}} มักมีรูปพหูพจน์เป็น {{m|ar||فُعَّال}} หรือบางครั้งเป็น {{m|ar||فَعَلَة}}; ในบางครั้งปรากฏทั้งสองรูปพหูพจน์โดยมีความหมายต่างกัน เช่น {{m|ar|كُتَّاب||[[นักเขียนทั้งหลาย]]}} แต่ {{m|ar|كَتَبَة||[[เสมียนทั้งหลาย]]}}
นอกจากนี้ คำนามบอกอาชีพบางคำยังอยู่ในรูป[[nisba|นิสบะฮ์]] (มีปัจจัย {{m|ar|ـِيّ}}) เช่น {{m|ar|صُحُفِيّ||[[นักข่าว]]}} หรือ {{m|ar|صِحَافِيّ||[[นักหนังสือพิมพ์]]}} ซึ่งรับมาจาก {{m|ar|صُحُف||[[หนังสือพิมพ์ทั้งหลาย]]}} และ {{m|ar|صِحَافَة||[[วารสารศาสตร์]], [[การสื่อสารมวลชน]]}} ตามลำดับ
===คำนามและคำคุณศัพท์บอกคุณลักษณะ===
''คำนามบอกคุณลักษณะ'' สามารถรับมาจากลำต้นกริยาโดยใช้รูป {{m|ar||فَعَّال}} ซึ่งสร้างคำนามที่มีความหมายว่า "ผู้ที่กระทำ X เป็นนิสัยหรือเป็นอาจิณ" เช่น {{m|ar|كَذَّاب||[[คนโกหก]]}} โปรดสังเกตว่าเป็นรูปเดียวกันกับที่ใช้ใน[[#คำนามบอกอาชีพ|คำนามบอกอาชีพ]]จำนวนมาก ส่วน''คำคุณศัพท์บอกคุณลักษณะ''ก็มีรูปเดียวกันกับคำนามบอกคุณลักษณะ เช่น {{m|ar|دَبَّاب||[[ที่คืบคลาน]]}}, {{m|ar|نَظَّار||[[สายตาไว]], [[ช่างสังเกต]]}}
===ตัวบอกความเล็ก===
''ตัวบอกความเล็ก'' สามารถรับมาจากคำนามสามพยัญชนะ และคำนามสี่พยัญชนะหรือคำที่ยาวกว่าบางคำ โดยใช้รูป {{m|ar||فُعَيْل}} หรือ {{m|ar||فُعَيِّل}}; และรูป {{m|ar||فُعَيْزِل}} สำหรับคำนามสี่พยัญชนะและคำที่ยาวกว่า ตัวบอกความเล็กไม่มีพลังในการสร้างคำมากนักในภาษาอาหรับมาตรฐานสมัยใหม่ หรือในภาษาถิ่นสมัยใหม่หลายภาษา (เช่น ภาษาถิ่นอียิปต์) แต่เคยมีพลังในการสร้างคำมากกว่ามากในภาษาถิ่นอาหรับคลาสสิกบางถิ่น ดังที่เห็นได้จากความแพร่หลายและพลังสร้างคำที่ยังคงมีอยู่อย่างต่อเนื่องในบางภาษาถิ่น เช่น ภาษาอาหรับมอร็อกโก ซึ่งคำนามเกือบทุกคำจะมีตัวบอกความเล็กคู่กัน คำนามบอกความเล็กมีความหมายว่า "X ขนาดเล็ก" หรือ "X ตัวน้อยน่ารัก" ตัวอย่างเช่น {{m|ar|كُلَيْب||[[หมา]][[ตัวน้อย]]}} จาก {{m|ar|كَلْب}}, {{m|ar|كُتَيِّب||[[หนังสือเล่มเล็ก]], [[จุลสาร]]}} จาก {{m|ar|كِتَاب||[[หนังสือ]]}} และ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}} จาก {{m|ar|اِبْن||[[ลูกชาย]]}} ตัวอย่างจากคำนามยาว ได้แก่ {{m|ar|أُبَيْطِر||[[จักรพรรดิ]][[องค์น้อย]]}} จาก {{m|ar|إِمْبِرَاطُور||[[จักรพรรดิ]]}} ตัวบอกความเล็กเพศหญิงก็สามารถสร้างได้เช่นกัน เช่น {{m|ar|قُصَيْبَة||[[ข้าวโอ๊ต]]}} จาก {{m|ar|قَصَبَة||[[อ้อย]], [[ต้นกก]]}} และ {{m|ar|بُنَيَّة||[[ลูกสาว]][[ตัวน้อย]]}} (เทียบกับ {{m|ar|بُنَيّ||[[ลูกชาย]][[ตัวน้อย]]}})
==อ้างอิง==
* {{cite-journal|de|authorlink=August Fischer|last=Fischer|first=August|title=Das Geschlecht der Infinitive im Arabischen|url=https://nbn-resolving.org/urn:nbn:de:gbv:3:5-8179-52331-18/fragment/page=00000923|pages=839–859|year=1906|volume=60|journal=Zeitschrift der Deutschen Morgenländischen Gesellschaft}}
<references/>
==ดูเพิ่ม==
*[[:ภาคผนวก:คำกริยาภาษาอาหรับ]]
[[หมวดหมู่:ภาคผนวกคำนาม|อาหรับ]]
[[หมวดหมู่:ภาคผนวกคำคุณศัพท์|อาหรับ]]
[[หมวดหมู่:ภาคผนวกภาษาอาหรับ|หน่วยนาม]]
fm8uk3s5ue9dpujje4vqwy6xwr6mujt
احتوى
0
2359220
5775318
2026-10-15T02:33:22Z
Octahedron80
267
เก็บกวาด
5775318
wikitext
text/x-wiki
== ภาษาอาหรับ ==
{{ar-rootbox|ح و ي}}
{{ety|ar|id=to contain|:root|ح و ي<id:root>|tree=1}}
=== การออกเสียง ===
{{ar-pr|اِحْتَوَى}}
=== คำกริยา ===
{{ar-verb|VIII.III:ي.pass}}
# {{lb|ar|สกรรม|หรือ|ใช้ร่วมกับ {{l|ar|على}}}} [[บรรจุ]], [[ประกอบ]][[ด้วย]]
#: {{uxa|ar|'''يَحْتَوِي''' الْكُتَيِّبُ عَلَى مَعْلُومَاتٍ قَدْ تَنْفَعُنَا فِي الْمُسْتَقْبَلِ.|t=จุลสารนี้'''บรรจุ'''ข้อมูลที่อาจเป็นประโยชน์แก่เราในอนาคต|subst=الْ//ٱلْ,يَحْتَوِي//يَحْتَوِ,فِي//فِ}}
# [[จัดการ]], [[ควบคุม]]
==== การผันรูป ====
{{ar-conj|VIII.III:ي.pass}}
en62ax8xdybzlxijpn81d34kiqgavze
تحوى
0
2359221
5775319
2026-10-15T02:34:53Z
Octahedron80
267
เก็บกวาด
5775319
wikitext
text/x-wiki
== ภาษาอาหรับ ==
=== รากศัพท์ 1 ===
{{ar-rootbox|ح و ي}}
{{ety|ar|id=to contract|:root|ح و ي<id:root>|tree=1}}
เทียบ{{m|ar|حَوَى||to [[gather]]}}.
==== คำกริยา ====
{{ar-verb|V.III:ي.ipass?}}
# {{lb|ar|อกรรม}} [[หด]], [[หดตัว]]
# {{lb|ar|อกรรม}} [[ขด]] {{qualifier|ใช้แก่[[งู]]}}
===== การผันรูป =====
{{ar-conj|V.III:ي.ipass?}}
===== อ้างอิง =====
* {{R:ar:Steingass}}
=== รากศัพท์ 2 ===
{{ety|ar|nl=1}}
==== คำกริยา ====
{{ar-verb form|+حوى<I>}}
=== รากศัพท์ 3 ===
{{ety|ar|nl=1}}
==== คำกริยา ====
{{ar-verb form|+حوي<I>}}
c4ysbgvghhgaixah3fkhk5nx8u6njt5
حاو
0
2359222
5775320
2026-10-15T02:38:12Z
Octahedron80
267
นำเข้าจาก enwikt เก็บกวาด
5775320
wikitext
text/x-wiki
== ภาษาอาหรับ ==
{{ar-rootbox|ح و ي}}
=== รากศัพท์ ===
{{ety|ar|id=containing|:root|ح و ي<id:root>|tree=1}}
{{ar-active participle}} ของคำกริยา {{m|ar|حَوَى}}
=== การออกเสียง ===
{{ar-pr|حَاوٍ}}
=== คำคุณศัพท์ ===
{{ar-adj+|حَاوٍ|pl=+,حُوَاة}}
# {{active participle of|ar|حَوَى}}: ที่บรรจุอยู่, ที่รวบรวมไว้
==== การผันรูป ====
{{ar-decl-adj|حَاوٍ|pl=sp|pl2=حُوَاة}}
==== คำสืบทอด ====
* {{desc|fa|حاوی|tr= hâvi|bor=1}}
* {{desctree|ota|حاوی|tr= hâvi|bor=1}}
fn5rlg30mxfkp2dwinmqyfe4nlwz4d4
แม่แบบ:ar-active participle
10
2359223
5775321
2026-10-15T02:39:52Z
Octahedron80
267
นำเข้าจาก enwikt
5775321
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
-->{{#if:{{{noderived|}}}||{{#if:{{{lc|{{{nocap|}}}}}}|รับมา|รับมา}}จาก }}[[ภาคผนวก:หน่วยนามภาษาอาหรับ#รูปกริยาขยายกรรตุวาจก|รูปกริยาขยายกรรตุวาจก]]<!--
-->{{#if:{{{nocat|}}}<!--
-->|<!--
-->|{{if-ar-lect|{{{1|ar}}}|{{cln|{{{1|ar}}}|รูปกริยาขยาย|รูปกริยาขยายกรรตุวาจก|ศัพท์ที่รับมาจากรูปกริยาขยายกรรตุวาจก}}}}<!--
-->}}<!--
--><noinclude>{{documentation}}</noinclude>
pt5k9k54kd55gv3jvadhkpx2kws13nl
5775322
5775321
2026-10-15T02:40:05Z
Octahedron80
267
5775322
wikitext
text/x-wiki
{{#invoke:checkparams|error}}<!-- Validate template parameters
-->{{#if:{{{noderived|}}}||{{#if:{{{lc|{{{nocap|}}}}}}|รับมา|รับมา}}จาก}}[[ภาคผนวก:หน่วยนามภาษาอาหรับ#รูปกริยาขยายกรรตุวาจก|รูปกริยาขยายกรรตุวาจก]]<!--
-->{{#if:{{{nocat|}}}<!--
-->|<!--
-->|{{if-ar-lect|{{{1|ar}}}|{{cln|{{{1|ar}}}|รูปกริยาขยาย|รูปกริยาขยายกรรตุวาจก|ศัพท์ที่รับมาจากรูปกริยาขยายกรรตุวาจก}}}}<!--
-->}}<!--
--><noinclude>{{documentation}}</noinclude>
l6ua55pbtf86gm3s8rf0qmhcq2qg5ts
แม่แบบ:if-ar-lect
10
2359224
5775323
2026-10-15T02:40:18Z
Octahedron80
267
นำเข้าจาก enwikt
5775323
wikitext
text/x-wiki
<includeonly>{{#ifeq:<!--
-->{{#invoke:languages/templates|getByCode|{{{1|<noinclude>ar</noinclude>}}}|getFamily}}<!--
-->|{{#invoke:languages/templates|getByCode|ar|getFamily}}<!--
-->|{{{2|}}}<!--
-->|{{#if:<!--
-->{{#invoke:languages/templates|exists|{{{1}}}}}<!--
-->|{{{3|{{error|Language "{{#invoke:languages/templates|getByCode|{{{1|<noinclude>ar</noinclude>}}}|getCanonicalName}}" ({{{1|<noinclude>ar</noinclude>}}}) does not descend from {{#invoke:languages/templates|getByCode|ar|getFamily}}}}}}}<!--
(throw module error if not exists:)
-->|{{{4|{{{3|{{#invoke:languages/templates|getByCode|{{{1|<noinclude>ar</noinclude>}}}|getFamily}}}}}}}}<!--
-->}}<!--
-->}}<!--
--></includeonly><noinclude>{{documentation}}</noinclude>
cmwf0thrpsyvrg6wbvkc5p8bqo4grjw
แม่แบบ:ar-adj+
10
2359225
5775325
2026-10-15T02:53:02Z
Octahedron80
267
นำเข้าจาก enwikt
5775325
wikitext
text/x-wiki
{{#invoke:ar-headword|show|คำคุณศัพท์ปริยาย}}<!--
--><noinclude>{{documentation}}</noinclude>
i7vtcgp95y2f40xmd4uze6mbqcidh48
حواية
0
2359226
5775329
2026-10-15T04:12:26Z
Octahedron80
267
นำเข้าจาก enwikt เก็บกวาด
5775329
wikitext
text/x-wiki
== ภาษาอาหรับ ==
{{ar-rootbox|ح و ي}}
{{ety|ar|id=containing|:root|ح و ي<id:root>|tree=1}}
=== คำนาม ===
{{ar-noun|حَوَايَة|f}}
# {{ar-verbal noun of|حَوَى|form=I}}
==== การผันรูป ====
{{ar-decl-noun|حَوَايَة}}
sxi1au6us1cibmfh43cutorbjd46i4c
ชาวยิว
0
2359227
5775337
2026-10-15T04:47:55Z
Octahedron80
267
เปลี่ยนทางหน้าไปยัง [[ยิว]]
5775337
wikitext
text/x-wiki
#เปลี่ยนทาง [[ยิว]]
nmxwm4fbk4c3hw7xc3u2dd7j4tl63re
حكومت
0
2359228
5775352
2026-10-15T06:35:09Z
Octahedron80
267
นำเข้าจาก enwikt เก็บกวาด
5775352
wikitext
text/x-wiki
== ภาษาตุรกีแบบออตโตมัน ==
=== รากศัพท์ ===
{{etymon|ota|id=government|:bor|ar:حُكُومَة<id:government>|tree=1|text=++}}
=== การออกเสียง ===
* {{IPA|ota|/hy.cuːmet/}}
=== คำนาม ===
{{ota-noun|tr=hükûmet}}
# [[รัฐบาล]]
==== คำสืบทอด ====
* {{desc|tr|hükûmet|hükümet}}
* {{desc|crh|ükümet|bor=1}}
* {{desc|mk|уќумат|bor=1}}
* {{desc|ady|хьыкумэт}}
* {{desc|kbd|хьыкумэт}}
so8l1wnair9n2kmaorb8md28co8s07l
artery
0
2359229
5775361
2026-10-15T07:11:02Z
Apisite
10648
สร้างหน้าด้วย "== ภาษาอังกฤษ == === คำนาม === {{en-noun}} # [[เส้นเลือดแดง]], [[หลอดเลือดแดง]]"
5775361
wikitext
text/x-wiki
== ภาษาอังกฤษ ==
=== คำนาม ===
{{en-noun}}
# [[เส้นเลือดแดง]], [[หลอดเลือดแดง]]
gtz2jokypytz8vy1qq54n4tc5qiahy1