Dokumentationen för denna modul kan skapas på Modul:translit/ar/dok /test


Modul:translit/ar/dok

-- Denna modul används för att transkribera arabiska till svenska.
-- 
-- För att transkribera persiska/farsi, urdu eller andra språk som
-- använder det arabiska alfabetet kan ett liknande system användas.
-- Det hanteras dock av särskilda moduler. Se:
-- 
-- [TODO]
-- 
--
-- Systemet för transkribering följer det som anges i
-- "Svenska skrivregler" (2017), fjärde upplagan, red. Ola Karlsson
-- Den ger inte en uttömmande beskrivning av hur samtliga tecken ska
-- hanteras. Av nödvändighet (och i brist på bättre källor) har jag
-- valt att hantera resten av dem på ett visst sätt.
--
-- Notera att det finns otaliga system för att transkribera arabiska,
-- som alla ger olika utfall.
--
--
-- Några generella anmärkningar om det arabiska skriftspråket och denna modul:
-- 
-- Det skrivs från höger till vänster. Förutsatt att det är korrekt inmatat
-- kommer denna modul hantera det.
-- 
-- Arabiska gör ingen skillnad på stor och liten bokstav. Däremot kan tecken
-- se olika ut om de förekommer initialt, medialt, finalt, eller isolerat.
-- Datorer (mer specifikt, UTF-8) kan lagra detta som fyra stycken olika tecken.
-- Det finns även ett sätt att lagra tecknen som ej tar ställning till vilken
-- position de har. Alltså finns det upp till fem olika sätt att lagra varje
-- "bokstav" på i Unicode.
--
-- Arabiska har korta och långa vokaler. Normalt skrivs de korta vokalerna ej ut
-- i vanlig text. För pedagogiska syften (som till exempel i en ordbok) kan de
-- markeras med hjälp av diakritiska tecken som kallas "harakat". För att få en
-- korrekt återgivning bör modulen anropas med texten tillsammans med dessa
-- korta vokaler.
--
-- Denna modul beaktar inte reglerna för solbokstäver (shamsiya). När den bestämda
-- artikeln ("al") förekommer före ett ord som börjar på en solbokstav ska den
-- bestämda artikelns konsonant istället uttals som den första konsonanten av
-- huvudordet. Exempelvis ska uttrycket الشرق الأوسط ("Mellanöstern") egentligen
-- inte uttalas med "al-sh" i början, utan "ash-sh". Denna modul transkriberar dock
-- detta som "al-sh".
--
--
-- Denna modul används av följande mall:
-- {{tr}}
--
-- Modulen är författad av (och underhålls av) [[Användare:Gabbe]]

local export = {}

latinska = {}

-- först de "vanliga" bokstäverna
latinska["ا"]="ā"; latinska["ﺍ"]="ā"; latinska["ﺎ"]="ā"
latinska["ب"]="b"; latinska["ﺏ"]="b"; latinska["ﺐ"]="b"; latinska["ﺒ"]="b"; latinska["ﺑ"]="b"
latinska["ت"]="t"; latinska["ﺕ"]="t"; latinska["ﺖ"]="t"; latinska["ﺘ"]="t"; latinska["ﺗ"]="t"
latinska["ث"]="th"; latinska["ﺙ"]="th"; latinska["ﺚ"]="th"; latinska["ﺜ"]="th"; latinska["ﺛ"]="th"
latinska["ج"]="j"; latinska["ﺝ"]="j"; latinska["ﺞ"]="j"; latinska["ﺠ"]="j"; latinska["ﺟ"]="j"
latinska["ح"]="ḥ"; latinska["ﺡ"]="ḥ"; latinska["ﺢ"]="ḥ"; latinska["ﺤ"]="ḥ"; latinska["ﺣ"]="ḥ"
latinska["خ"]="kh"; latinska["ﺥ"]="kh"; latinska["ﺦ"]="kh"; latinska["ﺨ"]="kh"; latinska["ﺧ"]="kh"
latinska["د"]="d"; latinska["ﺩ"]="d"; latinska["ﺪ"]="d"
latinska["ذ"]="dh"; latinska["ﺫ"]="dh"; latinska["ﺬ"]="dh"
latinska["ر"]="r"; latinska["ﺭ"]="r"; latinska["ﺮ"]="r"
latinska["ز"]="z"; latinska["ﺯ"]="z"; latinska["ﺰ"]="z"
latinska["س"]="s"; latinska["ﺱ"]="s"; latinska["ﺲ"]="s"; latinska["ﺴ"]="s"; latinska["ﺳ"]="s"
latinska["ش"]="sh"; latinska["ﺵ"]="sh"; latinska["ﺶ"]="sh"; latinska["ﺸ"]="sh"; latinska["ﺷ"]="sh"
latinska["ص"]="ṣ"; latinska["ﺹ"]="ṣ"; latinska["ﺺ"]="ṣ"; latinska["ﺼ"]="ṣ"; latinska["ﺻ"]="ṣ"
latinska["ض"]="ḍ"; latinska["ﺽ"]="ḍ"; latinska["ﺾ"]="ḍ"; latinska["ﻀ"]="ḍ"; latinska["ﺿ"]="ḍ"
latinska["ط"]="ṭ"; latinska["ﻁ"]="ṭ"; latinska["ﻂ"]="ṭ"; latinska["ﻄ"]="ṭ"; latinska["ﻃ"]="ṭ"
latinska["ظ"]="ẓ"; latinska["ﻅ"]="ẓ"; latinska["ﻆ"]="ẓ"; latinska["ﻈ"]="ẓ"; latinska["ﻇ"]="ẓ"
latinska["ع"]="ʿ"; latinska["ﻉ"]="ʿ"; latinska["ﻊ"]="ʿ"; latinska["ﻌ"]="ʿ"; latinska["ﻋ"]="ʿ"
latinska["غ"]="gh"; latinska["ﻍ"]="gh"; latinska["ﻎ"]="gh"; latinska["ﻐ"]="gh"; latinska["ﻏ"]="gh"
latinska["ف"]="f"; latinska["ﻑ"]="f"; latinska["ﻒ"]="f"; latinska["ﻔ"]="f"; latinska["ﻓ"]="f"
latinska["ق"]="q"; latinska["ﻕ"]="q"; latinska["ﻖ"]="q"; latinska["ﻘ"]="q"; latinska["ﻗ"]="q"
latinska["ك"]="k"; latinska["ﻙ"]="k"; latinska["ﻚ"]="k"; latinska["ﻜ"]="k"; latinska["ﻛ"]="k"
latinska["ل"]="l"; latinska["ﻝ"]="l"; latinska["ﻞ"]="l"; latinska["ﻠ"]="l"; latinska["ﻟ"]="l"
latinska["م"]="m"; latinska["ﻡ"]="m"; latinska["ﻢ"]="m"; latinska["ﻤ"]="m"; latinska["ﻣ"]="m"
latinska["ن"]="n"; latinska["ﻥ"]="n"; latinska["ﻦ"]="n"; latinska["ﻨ"]="n"; latinska["ﻧ"]="n"
latinska["ه"]="h"; latinska["ﻩ"]="h"; latinska["ﻪ"]="h"; latinska["ﻬ"]="h"; latinska["ﻫ"]="h"
latinska["و"]="ū"; latinska["ﻭ"]="ū"; latinska["ﻮ"]="ū"
latinska["ي"]="ī"; latinska["ﻱ"]="ī"; latinska["ﻲ"]="ī"; latinska["ﻴ"]="ī"; latinska["ﻳ"]="ī"

-- sen de korta vokalerna
latinska["َ"]="a" -- fathah
latinska["ُ"]="u" -- dammah
latinska["ِ"]="i" -- kasrah
latinska["ْ"]="" -- sukun

-- sen specialfallet "alif maddah"
latinska["آ"]="ā"; latinska["ﺁ"]="ā"; latinska["ﺂ"]="ā"

-- sen specialfallet "ta marbuta"
latinska["ة"]=""; latinska["ﺓ"]=""; latinska["ﺔ"]=""

-- sen specialfallet "alif maqsurah"
latinska["ى"]="ā"; latinska["ﻯ"]="ā"; latinska["ﻰ"]="ā"

-- fyra specialfall av diakritisk "hamza"
latinska["أ"]="ā"
latinska["ؤ"]="ū"
latinska["إ"]="ī"
latinska["ئ"]="ā"

-- specialfallet isolerat "hamza"
latinska["ء"]=""

-- specialfallet isolerat "shadda"
latinska["ّ"]=""

-- specialfallet "alif khanjariyah"
latinska["ٰ"]="ā"

-- kasusmarkörer
latinska["ٌ"]="un"
latinska["ً"]="an"
latinska["ٍ"]="in"

-- Fem köfunktioner
function enqueue(q, val)
  q.last = q.last + 1
  q.data[q.last] = val
end

function dequeue(q)
  local rval
  if (q.first > q.last) then
    rval = -1
  else
    rval = q.data[q.first]
    q.data[q.first] = nil
    q.first = q.first + 1
  end
  return rval
end

function peekonce(q)
  local rval
  if (q.first > q.last) then
    rval = -1
  else
    rval = q.data[q.first]
  end
  return rval
end

function peektwice(q)
  local rval
  if (q.first+1 > q.last) then
    rval = -1
  else
    rval = q.data[q.first+1]
  end
  return rval
end

function peeklast(q)
  local rval
  if (q.first > q.last) then
    rval = -1
  else
    rval = q.data[q.last]
  end
  return rval
end

-- Själva transkriberingsfunktionen för arabiska
function transkribera_ar(text)
  -- Två köer: en för arabiska bokstäver och en för latinska bokstäver
  indata = {}
  indata.first = 0
  indata.last = -1
  indata.data = {}

  utdata = {}
  utdata.first = 0
  utdata.last = -1
  utdata.data = {}

  -- en separat kö att returnera på slutet
  local returndata = {}

  for c in string.gmatch(text, ".[\128-\191]*") do
    enqueue(indata, c)
  end

  repeat
    local x = dequeue(indata)
    local y = peekonce(indata)
    local z = peektwice(indata)
    local u = peeklast(utdata)
    if (latinska[x] == nil) then -- icke-arabiskt tecken
      enqueue(utdata, x)
    -- först, de långa vokalerna i fullt vokaliserad text
    elseif(string.match(x,"َ") and string.match(y,"ا")) then
      enqueue(utdata, "ā")
      dequeue(indata)
    elseif(string.match(x,"َ") and string.match(y,"ٰ")) then
      enqueue(utdata, "ā")
      dequeue(indata)
    elseif(string.match(x,"ا") and string.match(y,"َ")) then
      enqueue(utdata, "ā")
      dequeue(indata)
    elseif(string.match(x,"َ") and string.match(y,"ى")) then
      enqueue(utdata, "ā")
      dequeue(indata)
    elseif(string.match(x,"أ") and string.match(y,"َ")) then
      enqueue(utdata, "ā")
      dequeue(indata)
    elseif(string.match(x,"إ") and string.match(y,"ِ")) then
      enqueue(utdata, "ī")
      dequeue(indata)
    elseif(string.match(x,"ِ") and string.match(y,"ى")) then
      enqueue(utdata, "ī") -- eventuellt vore "y" eller "iy" lämpligare
      dequeue(indata)
    elseif(string.match(x,"ُ") and string.match(y,"و")) then
      enqueue(utdata, "ū") -- eventuellt vore "uw" lämpligare
      dequeue(indata)
    elseif(string.match(x,"و") and string.match(y,"ُ")) then
      enqueue(utdata, "ū")
      dequeue(indata)
    elseif(string.match(x,"ِ") and string.match(y,"ي")) then
      enqueue(utdata, "ī") -- eventuellt vore "iy" lämpligare
      dequeue(indata)
    -- sen, diftongerna
    elseif(string.match(x,"َ") and string.match(y,"ي")) then
      enqueue(utdata, "ay") -- eventuellt vore "ai" eller "ay" lämpligare
      dequeue(indata)
    elseif(string.match(x,"َ") and string.match(y,"و")) then
      enqueue(utdata, "aw") -- eventuellt vore "au" lämpligare
      dequeue(indata)
    -- sen, dubbleringen "shadda" när den används efter andra diakriter
    elseif((string.match(y,"ّ") and string.match(x,"َ")) or
           (string.match(y,"ّ") and string.match(x,"ِ")) or
           (string.match(y,"ّ") and string.match(x,"ُ"))) then
      enqueue(utdata,u)
      enqueue(utdata,latinska[x])
      dequeue(indata)
    -- sen, dubbleringen "shadda" när den används före andra diakriter
    elseif((string.match(x,"ّ") and string.match(y,"َ")) or
           (string.match(x,"ّ") and string.match(y,"ِ")) or
           (string.match(x,"ّ") and string.match(y,"ُ"))) then
      enqueue(utdata,u)
    -- sen, dubbleringen "shadda" när den används utan andra diakriter
    elseif(string.match(x,"ّ")) then
      enqueue(utdata,u)
    -- sen...
    -- sist, övriga tecken enligt tabellen ovan
    else
      enqueue(utdata, latinska[x])
    end
  until (indata.first > indata.last)

  repeat
    local x = dequeue(utdata)
    table.insert(returndata,x)
  until (utdata.first > utdata.last)

  return returndata
end

function export.transkribera( argument )
	local text = argument.args["text"]
	outputdata = transkribera_ar(text)
	outputtext = table.concat(outputdata,"")
	return outputtext
end

return export