Modul:LinkPhone

Aus Wikivoyage
Zur Navigation springen Zur Suche springen
Template-info.png Dokumentation für das Modul LinkPhone[Ansicht] [Bearbeiten] [Versionsgeschichte] [Aktualisieren]

Der Modul stellt Funktionen zur Verlinkung von Telefonnummern bereit. Faxnummern werden überprüft, aber nicht verlinkt. Kommentare müssen hinter der Telefonnummer in Klammern angefügt werden.

Das Modul wird auch von der Vorlage {{LinkPhone}} aufgerufen. Die Beschreibung der Parameter erfolgt dort.

Das Modul benutzt den Modul Modul:LinkPhone/i18n zur Internationalisierung. Die Bedeutung der Teilarrays wird dort beschrieben.

Wartungskategorien

Beispiele

Text Code Ergebnis
+49 123 2 567.890 App. 5 {{#invoke:LinkPhone|linkPhone|+49 123 2 567.890 App. 5}} +49 123 2 567.890 App. 5
+49 123 2 567.890 App. 5 {{#invoke:LinkPhone|linkPhone|+49 123 2 567.890 App. 5|isFax=true}} +49 123 2 567.890 App. 5
+49 123 / 2 567.890 {{#invoke:LinkPhone|linkPhone|+49 123 / 2 567.890}} +49 123 / 2 567.890 Category:Telefon mit SchrägstrichTelefon mit Schrägstrich
++49 (123) 2 56 78 90 ext. 34 (Bar) {{#invoke:LinkPhone|linkPhone|++49 (123) 2 56 78 90 ext. 34 (Bar)}} +49 (123) 2 56 78 90 ext. 34 (Bar)
++49 0123 2 56 78 90 ext. 34 (Bar) {{#invoke:LinkPhone|linkPhone|++49 0123 2 56 78 90 ext. 34 (Bar)|cc=+49}} +49 (0)123 2 56 78 90 ext. 34 (Bar)
+49 (123) 2 56 78 90 Bar {{#invoke:LinkPhone|linkPhone|+49 (123) 2 56 78 90 Bar}} +49 (123) 2 56 78 90 Bar Category:Ungültiges TelefonformatUngültiges Telefonformat
+49 (0)123 VOYAGE {{#invoke:LinkPhone|linkPhone|+''49'' (0)123 VOYAGE}} +49 (0)123 VOYAGE
(0)123 256 78 90 {{#invoke:LinkPhone|linkPhone|(0)123 256 78 90}} (0)123 256 78 90 Category:Telefon ohne LändervorwahlTelefon ohne Ländervorwahl
(0)123 256 78 90 {{#invoke:LinkPhone|linkPhone|(0)123 256 78 90|cc=+49}} (0)123 256 78 90
123 256 78 90 (Bar) {{#invoke:LinkPhone|linkPhone|123 256 78 90 (Bar)|cc=+49}} 123 256 78 90 (Bar) Category:Ungültiges TelefonformatUngültiges Telefonformat
+49 (123) 2 56 78 90 (Lobby Bar), 0049 (123) 2 56 78 90 (Oasis Restaurant) {{#invoke:LinkPhone|linkPhone|+49 (123) 2 56 78 90 (Lobby Bar), 0049 (123) 2 56 78 91 (Oasis Restaurant)}} +49 (123) 2 56 78 90 (Lobby Bar), +49 (123) 2 56 78 91 (Oasis Restaurant)
+49 (123) 2 56 78 90 oder +49 (123) 2 56 78 91 {{#invoke:LinkPhone|linkPhone|+49 (123) 2 56 78 90 oder +49 (123) 2 56 78 91}} +49 (123) 2 56 78 90, +49 (123) 2 56 78 91
(212) 307 4100 (USA) {{#invoke:LinkPhone|linkPhone|(212) 307 4100 (USA)|cc=+1}} (212) 307 4100 (USA)
+49-345-1234567 {{#invoke:LinkPhone|linkPhone|+49-345-1234567|format=true}} +49 (0)345 123 45 67
+20-92-1234567 {{#invoke:LinkPhone|linkPhone|+20-92-1234567|format=true|size=4}} +20 (0)92 123 4567
0800 12 34 56 (gebührenfrei) {{#invoke:LinkPhone|linkPhone|0800 12 34 56 (gebührenfrei)|isTollfree=true}} 0800 12 34 56 (gebührenfrei)
112 {{#invoke:LinkPhone|linkPhone|112|cc=+49}} 112
0900 12 34 56 (teure Servicenummer) {{#invoke:LinkPhone|linkPhone|0900 12 34 56 (teure Servicenummer)}} 0900 12 34 56 (teure Servicenummer)

Fehlersuche

Im Fehlerfall wird neben der Fehlerkategorie auch ein ausgeblendeter Fehlertext hinter der Telefonnummer ausgegeben.

Beschreibung der Funktionen

local function errorInfo( catPrefix, aCat )
catPrefix: string;
aCat: string;

Die Funktion gibt die Fehlerausschrift aCat im Haupt- oder Modul-Namenraum aus und legt eine gleichnamige Wartungskategorie an. Der Modulparameter demo legt fest, ob die Kategorie angelegt oder nur verlinkt werden soll.

local function formatNumber( number, size )
number: string;
size: integer >= 0;

Die Funktion formatiert die anzuzeigende Telefonnummer, die meist aus Wikidata bezogen wird. Die Bindestriche werden durch Leerräume ersetzt, die letzte Zifferngruppe wird mit Leerräumen aufgelockert und dadurch besser lesbar gemacht, und es wird, falls nötig, eine Verkehrsausscheidungsziffer an die Ortsvorwahl angefügt. Wenn size Null ist, werden keine Leerzeichen eingefügt.

local function checkNumberMatch( key, number )
key: string;
number: string;

Die Funktion prüft, ob die Telefonnummer einem Muster aus dem Array [[Modul:LinkPhone/i18n|exceptions]] entspricht. der Schlüssel, key, tollfree liefert Muster für gebührenfreie Nummern, service für Servicenummern und alle anderen Schlüssel Muster für länderspezifische Sondernummern. service erhält als Nummer den Kommentar zu einer Telefonnummer, wobei die Muster an beliebiger Stelle im Kommentar vorkommen können.

function lp.linkPhoneNumber(s, args)
s: string;
args: arguments array;

Die Funktion prüft und verlinkt eine einzelne Telefonnummer.

function lp.linkPhoneNumberSet(args)
args: arguments array;

Die Funktion spaltet eine Liste von Telefonnummern auf und übergibt jede einzelne Telefonnummer an lp.linkPhoneNumber.

function lp.linkPhone(frame)
frame: frame object;

Die Funktion stellt die Schnittstelle für einen {{#invoke: ...}}-Aufruf zur Verfügung.

function lp.linkPhoneTemplate(frame)
frame: frame object;
Die Funktion stellt die Schnittstelle für einen Vorlagen-Aufruf zur Verfügung.
Hinweise
local cm = require( 'Module:CountryData' )
local li = require( 'Module:LinkPhone/i18n' )
local lp = {}

local function errorInfo( catPrefix, aCat )
	local ns = mw.title.getCurrentTitle().namespace
	if (ns == 0) or (ns == 828) then
		return catPrefix .. aCat .. ']]' .. '<span class="error" title="'
			.. aCat .. '">' .. aCat .. '</span>'
	else return '' end
end

local function formatNumber( number, size )
	if not li.formattingWikidata then return number end

	local pos, first, last, newLast, country, localCode

	number = number:gsub( '-', ' ' )
	_, pos = number:find( '.* ' ) -- find last space
	if size > 0 and pos then
		first = number:sub( 1, pos )
		last = number:sub( pos + 1, #number )
		newLast = ''
		if tonumber( last ) then -- inserting additional spaces
			while ( #last > size + 1 ) do
				if newLast == '' then
					newLast = last:sub( -size )
				else
					newLast = last:sub( -size ) .. ' ' .. newLast
				end
				last = last:sub( 1, #last - size )
			end
			if newLast ~= '' then last = last .. ' ' .. newLast end
		end
		pos,_ = first:find( ' ' )
		if li.addZeros and pos and ( pos ~= #first ) then
			country = first:sub( 1, pos - 1 )
			localCode = first:sub( pos + 1, #first )
			if li.noZero[ country ] == nil then
				localCode = localCode:gsub( '[%(%)]', '' )
				if localCode:sub( 1, 1 ) == '0' then
					localCode = '(0)' .. localCode:sub( 2, #localCode ) 
				else
					localCode = '(0)' .. localCode
				end
				first = country .. ' ' .. localCode
			end
		end
		number = first .. last
	end
	return number
end

local function checkNumberMatch( key, number )
	local ar = li.exceptions[ key ], i
	if not ar then return false end
	for i = 1, #ar, 1 do
		if number:find( ar[i] ) then return true end
	end
	return false
end

-- handle a single phone number s
function lp.linkPhoneNumber(s, args)
	local number = mw.text.trim( s )
	if number == '' then return number end -- empty string
	local catPrefix = '[[Category:'
	if args.demo == 'true' then catPrefix = ' [[:Category:' end

	local comment = ''
	local ext = ''
	local extraCats = ''

	-- extract comment in parentheses
	-- remove spaces between number and comment
	local t = mw.ustring.gsub( number, '(.*)(%(.*%))$', '%2' )
	if t ~= number then
		comment = t
		number = mw.ustring.gsub( mw.ustring.gsub( number, '(.*)(%(.*%))$', '%1' ), '( +)$', '' )
	end

	-- extract extension
	for i = 1, #li.extensions, 1 do
		t = mw.ustring.gsub( number, li.extensions[i], '%2' )
		if t ~= number then
			ext = t
			number = mw.text.trim( mw.ustring.gsub( number, li.extensions[i], '%1' ) )
		end
	end

	-- formatting phone numbers retrieved from Wikidata
	if args.format == 'true' then number = formatNumber( number, args.size ) end

	if li.addZeros and (args.cc ~= '+39') and (args.cc ~= '+378') and (number:find( '^00' ) == nil)
		then number = number:gsub( '^0', '(0)' ) end
	number = number:gsub( '^00', '+' )
	number = number:gsub( '^%+%+', '+' )
	if li.addZeros and (args.cc ~= '') and (args.cc ~= '+39') and (args.cc ~= '+378')
		then number = number:gsub( '^(%' .. args.cc .. ')( *)0', '%1%2(0)' ) end

	-- plain is number for link
	local plain = number
	-- check if slashes are used
	if plain:find( '/', 1, true ) ~= nil then
		extraCats = errorInfo( catPrefix, li.categories.withSlash )
	end

	-- remove delimiters -.()/' and spaces
	plain = plain:gsub( "[ '/%.%-%)]", '' )
	args.cc = args.cc:gsub( '%-', '' )
	local exception = false
	-- handling country code including ++49, 0049 etc.
	if plain:sub( 1, 1 ) == '+' then
		plain = plain:gsub( '%(0', '' ) -- zero in parenthesis
		plain = plain:gsub( '%(', '' )
	else
		plain = plain:gsub( '%(0', '0' )
		if comment ~= '' and checkNumberMatch( 'service', comment ) then
			exception = true
			number = number:gsub( '[%(%)]', '' )
		elseif args.isTollfree == 'true' and checkNumberMatch( 'tollfree', plain ) then
			exception = true
			number = number:gsub( '[%(%)]', '' )
		elseif checkNumberMatch( args.cc, plain ) then
			exception = true
		elseif (args.cc ~= '') then
			if li.noZero[args.cc] ~= nil then
				plain = args.cc .. plain:gsub( '^%(', '' )
			elseif (plain:sub( 1, 1 ) == '0') then
				plain = args.cc .. plain:gsub( '^0', '' )
			else
				return s .. errorInfo( catPrefix, li.categories.invalid )
			end
		else
			return s .. errorInfo( catPrefix, li.categories.noCC )
		end
	end

	-- minimum 5 characters including country code
	if not exception and #plain < 5 then
		return s .. errorInfo( catPrefix, li.categories.invalid )
	end

	-- lower case letters for numbers are not allowed
	if plain:find( '(%l)', 1 ) ~= nil then
		return s .. errorInfo( catPrefix, li.categories.invalid )
	end

	-- substitude letters
	plain = plain:gsub( '[A-C]', '2' );
	plain = plain:gsub( '[D-F]', '3' );
	plain = plain:gsub( '[G-I]', '4' );
	plain = plain:gsub( '[J-L]', '5' );
	plain = plain:gsub( '[M-O]', '6' );
	plain = plain:gsub( '[P-S]', '7' );
	plain = plain:gsub( '[T-V]', '8' );
	plain = plain:gsub( '[W-Z]', '9' );

	-- remove zero from local area code
	if (args.cc ~= '') and (args.cc ~= '+39') and (args.cc ~= '+378') then
		plain = plain:gsub( args.cc .. '0', args.cc ) end

	-- final test
	if not exception and plain:match( '^%+[%d]+$') == nil then
		return s .. errorInfo( catPrefix, li.categories.invalid )
	end

	-- assemble number, link, ext, comment, and categories
	if args.isFax == 'true' then 
		t = '<span class="listing-phone-number'
		if exception then
			t = t .. ' listing-phone-exception" title="' .. li.texts.onlyDomestic
		end
		t = t .. '" data-phone="' .. plain .. '">' .. number .. '</span>'
	else
		t = '<span class="plainlinks nourlexpansion listing-phone-number'
		if exception then
			t = t .. ' listing-phone-exception" title="' .. li.texts.onlyDomestic
		end
		t = t .. '" data-phone="' .. plain .. '">[tel:' .. plain .. ' ' .. number .. ']</span>'
	end
	if ext ~= '' then t = t .. ' ' .. ext end
	if comment ~= '' then t = t .. ' ' .. comment end

	return t .. extraCats
end

function lp.linkPhoneNumberSet(args)
	args.demo = args.demo or ''
	args.phone = args.phone or args.mobile or args[1] or ''
	args.isFax = args.isFax or ''
	args.isTollfree = args.isTollfree or ''
	args.cc = args.cc or ''
	args.nocc = args.nocc or ''
	args.format = args.format or ''
	args.size = tonumber( args.size )

	if args.cc ~= '' then
		args.cc = args.cc:gsub( '^00', '+' )
		args.cc = args.cc:gsub( '^%+%+', '+' )
	end

	local s, size
	local result = ''
	local addNum = li.addNum
	if args.isFax == 'true' then addNum = li.addNumFax end

	if args.phone ~= '' then
		-- get country code
		if (args.cc == '') or (string.sub( args.cc, 1, 1 ) ~= '+') then
			if (args.nocc ~= 'true') then
				args.cc, size = cm.getCountryCode()
				if not args.size then args.size = size end
			end
		end
		args.size = args.size or 2

		-- substitude delimiters
		for i = 1, #li.delimiters, 1 do
			args.phone = mw.ustring.gsub( args.phone, li.delimiters[i], ',' );
		end

		-- split separate numbers and analyse them
		i = 0
		for s in mw.ustring.gmatch( args.phone .. ',', '([^,]+)' ) do
			s = lp.linkPhoneNumber( s, args )
			if s ~= '' then
				if result == '' then result = s
				else
					if i == addNum then
						result = result .. '<span class="listing-add-contact">, ' .. s
					else
						result = result .. ', ' .. s
					end
				end
				i = i + 1
			end
		end
		if i > addNum then result = result .. '</span>' end
	end

	return result;
end

-- for #invoke call
function lp.linkPhone(frame)
	local args = frame.args
	return lp.linkPhoneNumberSet(args)
end

-- for template call
function lp.linkPhoneTemplate(frame)
	local args = frame:getParent().args
	return lp.linkPhoneNumberSet(args)
end

return lp