Modul:URIutil: Unterschied zwischen den Versionen
te>PerfektesChaos (update) |
te>PerfektesChaos (fix) |
||
Zeile 1: | Zeile 1: | ||
− | --[=[ URIutil | + | --[=[ URIutil 2014-01-26 |
Utilities for URI etc. | Utilities for URI etc. | ||
* coreISSN() | * coreISSN() | ||
Zeile 76: | Zeile 76: | ||
j = j + 1; | j = j + 1; | ||
if allowX and i == n then | if allowX and i == n then | ||
− | if allowX == true or allowX == | + | if allowX == true or allowX == j then |
r[ j ] = 10; | r[ j ] = 10; | ||
else | else |
Version vom 27. Januar 2014, 21:37 Uhr
--[=[ URIutil 2014-01-26 Utilities for URI etc.
- coreISSN()
- formatISBN()
- formatISSN()
- formatLCCN()
- isDNBvalid()
- isDOI()
- isEscValid()
- isGTINvalid()
- isISBN()
- isISBNvalid()
- isISSNvalid()
- isLCCN()
- linkDOI()
- linkISBN()
- linkISSN()
- linkLCCN()
- mayDOI()
- mayISBN()
- mayISSN()
- mayLCCN()
- mayURI()
- mayURN()
- plainISBN()
- uriDOI()
- URIutil()
loadData: URIutil/config URIutil/isbn ]=]
-- table for export local URIutil = {};
local factory = function ( attempt, allowX )
-- Retrieve plain digits of attempt -- Precondition: -- attempt -- string; with digits (+xX) and hyphens, not trimmed -- allowX -- number; of (last) position for permitted xX -- boolean; xX at last position permitted -- Postcondition: -- Returns table; success -- [1]...[8]/[10]...[13] -- digits 0...9 -- 10 at last position -- .hyphens -- number of hyphens -- .type -- number of digits -- number; no string or bad length or data -- 0 -- no string -- >0 -- unexpected char at position (trimmed) local r; if type( attempt ) == "string" then local c, i; local j = 0; local k = 1; local s = mw.text.trim( attempt ); local n = mw.ustring.len( s ); r = { hyphens = 0 }; for i = 1, n do c = mw.ustring.codepoint( s, i, i + 1 ); if c >= 48 and c <= 57 then j = j + 1; r[ j ] = c - 48; k = false; elseif c == 45 then -- hyphen if i > 1 and i < n then r.hyphens = r.hyphens + 1; k = i; else r = j; break; end elseif c == 88 or c == 120 then -- X x j = j + 1; if allowX and i == n then if allowX == true or allowX == j then r[ j ] = 10; else r = j; end else r = j; end break; else r = j; break; end end -- for i if type( r ) == "table" then r.type = j; end else r = 0; end return r;
end -- factory()
local faculty = function ( ask, auto )
-- Evaluate possible string as boolean signal, if brief -- Precondition: -- ask -- trimmed string or nil or other -- auto -- fallback value if nil -- Postcondition: -- Returns appropriate value, or ask local r; if type( ask ) == "string" then if ask == "1" or ask == "" then r = true; elseif ask == "0" or ask == "-" then r = false; else r = ask; end elseif ask == nil then r = auto; else r = ask; end return r;
end -- faculty()
local fair = function ( assert )
-- Compute check digit (11 minus modulo 11) for descending factor -- Precondition: -- assert -- table; as of factory() -- .type -- number of digits including check digit -- Postcondition: -- Returns checksum local i; local n = assert.type; local k = n; local r = 0; for i = 1, n - 1 do r = r + k * assert[ i ]; k = k - 1; end -- for i return ( 11 - r % 11 );
end -- fair()
local format = function ( assigned, ahead, amount )
-- Convert part of digit sequence into string -- Precondition: -- assigned -- table; as of factory() -- ahead -- index of first digit -- amount -- number of digits to append -- Postcondition: -- Returns string with digits and hyphens local i, k; local r = ""; for i = ahead, ahead + amount - 1 do k = assigned[ i ]; if k == 10 then r = r .. "X"; else r = r .. tostring( k ); end end -- for i return r;
end -- format()
local DNBfaith = function ( assert, ancestor )
-- Compute DNB (also GND, ZDB) check digit and verify -- Precondition: -- assert -- table; as of factory() -- .type -- until 11 including check digit -- ancestor -- true: 2011 mode -- Postcondition: -- Returns true: check digit matches -- 2013-09-01 local k = fair( assert ) % 11; if ancestor then k = 11 - k; end return ( k == assert[ assert.type ] );
end -- DNBfaith()
local GTINfair = function ( assert )
-- Compute GTIN check digit -- Precondition: -- assert -- table; ~ 13 digits -- .type -- 13 ... -- Postcondition: -- Returns number 0...9 local i, k; local lead = true; local r = 0; for i = 1, assert.type - 1 do k = assert[ i ]; r = r + k; if lead then -- odd lead = false; else -- even r = r + k + k; lead = true; end end -- for i r = (10 - r % 10) % 10; return r;
end -- GTINfair()
local GTINfaith = function ( assert )
-- Compute GTIN check digit and verify -- Precondition: -- assert -- table; ~ 13 digits -- .type -- 13 ... -- Postcondition: -- Returns true: check digit matches return ( GTINfair( assert ) == assert[ assert.type ] );
end -- GTINfaith()
local ISBNfactory = function ( attempt )
-- Retrieve plain digits of ISBN attempt -- Precondition: -- attempt -- string with digits (+xX) and hyphens, not trimmed -- Postcondition: -- Returns table; success -- [1]...[13] -- digits 0...9 -- 10 at ISBN-10 last position -- .type -- 10 or 13 -- .hyphens -- 0... number of hyphens -- number; no string or bad length or data -- 0 -- no string -- >0 -- unexpected char at position (trimmed) -- -1 -- bad digit count -- -2 -- bad bookland local r; if type( attempt ) == "string" then r = factory( attempt, 10 ); if type( r ) == "table" then if r.type == 13 then if r[1] ~= 9 or r[2] ~= 7 or r[3] < 8 then r = -2; end elseif r.type ~= 10 then r = -1; end end else r = 0; end return r;
end -- ISBNfactory()
local ISBNfaith = function ( assert )
-- Compute ISBN check digit and verify -- Precondition: -- assert -- table; as of ISBNfactory() -- .type -- 10 or 13 -- Postcondition: -- Returns true: check digit matches local r; if assert.type == 10 then local i; local k = 0; for i = 1, 9 do k = k + i * assert[ i ]; end -- for i k = k % 11; r = ( k == assert[ 10 ] ); elseif assert.type == 13 then r = GTINfaith( assert ); else r = false; end return r;
end -- ISBNfaith()
local ISBNflat = function ( assigned )
-- Plain digits of attempt ISBN -- Precondition: -- assigned -- table; as of ISBNfactory() -- Postcondition: -- Returns string with digits; ISBN-10 with 'X' at last position local i; local r = ""; local n = assigned.type; if n == 10 then if assigned[ assigned.type ] == 10 then n = 9; end end for i = 1, n do r = r .. tostring( assigned[ i ] ); end -- for i if n == 9 then r = r .. "X"; end return r;
end -- ISBNflat()
local ISBNfold = function ( assigned, apply, allocate, already )
-- Retrieve number of digits for ISBN publisher/group -- Precondition: -- assigned -- table; as of ISBNfactory() -- apply -- number; of bookland (978 or 979) -- allocate -- number; of country -- already -- number; position in assigned to inspect -- Postcondition: -- Returns number of digits, at least 0 local r = 0; local lucky, def = pcall( mw.loadData, "Module:URIutil/isbn" ); if type( def ) == "table" then local bookland = def[ apply ]; if type( bookland ) == "table" then local country = bookland[ allocate ]; if type( country ) == "table" then local e, i, j, k, m, v; for i = 1, 4 do v = country[ i ]; if type( v ) == "table" then m = tonumber( format( assigned, already, i ) ); for k, e in pairs( v ) do if m >= e[ 1 ] and m <= e[ 2 ] then r = e[ 3 ]; break; -- for k end end -- for k end if r > 0 then break; -- for i end end -- for i end end end return r;
end -- ISBNfold()
local ISBNformat = function ( attempt, assigned )
-- Hyphen formatting; at least try minimum -- Precondition: -- attempt -- string with presumable ISBN -- assigned -- table; as of ISBNfactory() -- .type -- 10 or 13 -- .hyphens -- 0...4 -- Postcondition: -- Returns string with digits and hyphens local r = false; local j, k, m, n; if assigned.type == 10 then m = 978; r = ""; j = 1; else m = 970 + assigned[ 3 ]; r = tostring( m ) .. "-"; j = 4; end if assigned[ j ] < 8 then k = 1; else k = 2; if assigned[ j + 1 ] > 4 then k = 3; if assigned[ j + 1 ] > 8 then k = 4; if assigned[ j + 2 ] > 8 then k = false; -- invalid end end end end if k then n = format( assigned, j, k ); r = r .. n .. "-"; j = j + k; n = ISBNfold( assigned, m, tonumber( n ), j ); if n > 0 then r = r .. format( assigned, j, n ) .. "-"; j = j + n; end end r = r .. format( assigned, j, assigned.type - j ); if assigned[ assigned.type ] == 10 then r = r .. "-X"; else r = r .. "-" .. tostring( assigned[ assigned.type ] ); end if not r then r = mw.ustring.upper( mw.text.trim( attempt ) ); end return r;
end -- ISBNformat()
local ISSNfactory = function ( attempt )
-- Retrieve plain digits of ISSN attempt -- Precondition: -- attempt -- string with digits (+xX) and hyphens, not trimmed -- Postcondition: -- Returns table; success -- [1]...[13] -- digits 0...9 -- 10 at ISSN-8 last position -- .type -- 8 or 13 -- .hyphens -- 0... number of hyphens -- number; no string or bad length or data -- 0 -- no string -- >0 -- unexpected char at position (trimmed) -- -1 -- bad digit count -- -2 -- bad issnland local r; if type( attempt ) == "string" then r = factory( attempt, 8 ); if type( r ) == "table" then if r.type == 13 then if r[1] ~= 9 or r[2] ~= 7 or r[3] ~= 7 then r = -2; end elseif r.type ~= 8 then r = -1; end end else r = 0; end return r;
end -- ISSNfactory()
local ISSNfaith = function ( assert )
-- Compute ISSN check digit and verify -- Precondition: -- assert -- table; as of ISSNfactory() -- .type -- 8 or 13 -- Postcondition: -- Returns true: check digit matches local r; if assert.type == 8 then r = ( fair( assert ) == assert[ 8 ] ); elseif assert.type == 13 then r = GTINfaith( assert ); else r = false; end return r;
end -- ISSNfaith()
local ISSNformat = function ( assigned, achieve )
-- Hyphen formatting of ISSN -- Precondition: -- assigned -- table; as of ISSNfactory(), and valid -- achieve -- 8 or 13 -- Postcondition: -- Returns string with digits and hyphens local r; if achieve == 8 then local x; if assigned.type == 8 then r = format( assigned, 1, 4 ) .. "-" .. format( assigned, 5, 3 ); x = assigned[ 8 ]; elseif assigned.type == 13 then r = format( assigned, 4, 4 ) .. "-" .. format( assigned, 8, 3 ); x = fair( assigned ); end if x == 10 then r = r .. "X"; else r = r .. tostring( x ); end elseif achieve == 13 then if assigned.type == 8 then r = "977-" .. format( assigned, 1, 7 ) .. "-00-" .. GTINfair( assigned ); elseif assigned.type == 13 then r = "977-" .. format( assigned, 4, 7 ) .. format( assigned, 10, 2 ) .. "-" .. tostring( assigned[ 13 ] ); end end return r;
end -- ISSNformat()
local LCCNfactory = function ( attempt, allow )
-- Retrieve segments of LCCN attempt (format since 2001) -- Precondition: -- attempt -- string with presumable LCCN -- allow -- false or string: "/" -- Postcondition: -- Returns table; success -- false if not correct, bad data -- 2013-08-25 local r = false; local pat = "^[%s]*([%a]*)(/?)(%d[%S]+)[%s]*$"; local pre, sep, s = attempt:match( pat ); if pre and s then local year, serial; if pre == "" then pre = false; if sep ~= "" then s = false; end elseif #pre > 3 then s = false; else pre = pre:lower(); end if s then if allow ~= "/" or sep == "/" then if sep == "/" then year, serial = s:match( "^([%d]+)/([%d].+)$" ); elseif s:find( "-", 2, true ) then year, serial = s:match( "^([%d]+)%-([%d].+)$" ); else year = s:match( "^([%d]+)" ); if year then if #year <= 8 then year = s:sub( 1, 2 ); serial = s:sub( 3 ); elseif #year <= 10 then year = s:sub( 1, 4 ); serial = s:sub( 5 ); else year = false; serial = s; end elseif tonumber( s ) then serial = s; end end end if year then if #year == 4 then local n = tonumber( year ); if n <= 2000 then -- 2000 -> "00" serial = false; elseif n > tonumber( os.date( "%Y" ) ) then serial = false; end elseif #year ~= 2 then serial = false; end end if serial then r = { pre = pre, serial = serial }; if year then r.year = year; end if serial:find( "/", 2, true ) then local q; serial, q = serial:tolower() :match( "^([%d]+)/([a-z]+)$" ); if q == "dc" or q == "mads" or q == "marcxml" or q == "mods" then r.serial = serial; r.qualifier = q; end end serial = serial:match( "^0*([1-9][%d]*)$" ); if not serial then r = false; elseif #serial < 6 then r.serial = mw.ustring.format( "%06d", tonumber( serial ) ); elseif #serial > 6 then r = false; end end end end return r;
end -- LCCNfactory()
local LCCNformat = function ( assigned, achieve )
-- Standard or hyphen or slash formatting of LCCN -- Precondition: -- assigned -- table; as of LCCNfactory(), and valid -- achieve -- additional formatting desires, like "-" or "/" -- Postcondition: -- Returns string with letters, digits and hyphens -- 2013-07-14 local r; if assigned.pre then r = assigned.pre; else r = ""; end if assigned.year then if achieve == "/" and r ~= "" then r = r .. "/"; end r = r .. assigned.year; if achieve then r = r .. achieve; end end if assigned.serial then r = r .. assigned.serial; end if assigned.qualifier then r = r .. "/" .. assigned.qualifier; end return r;
end -- LCCNformat()
local LCCNforward = function ( attempt, achieve )
-- Retrieve bracketed titled external LCCN permalink -- Precondition: -- attempt -- string with presumable LCCN -- achieve -- additional title formatting desires, like "-" -- Postcondition: -- Returns link, or plain attempt if bad LCCN -- 2013-07-14 local lccn = LCCNfactory( attempt ); local r; if lccn then r = LCCNformat( lccn, false ); if r then if achieve then r = r .. " " .. LCCNformat( lccn, achieve ); else r = r .. " " .. r; end r = "" .. r .. ""; end else r = attempt; end return r;
end -- LCCNforward()
local URNnamespace = function ( area, acquire )
-- Are these parts of a correct URN? -- Precondition: -- area -- string with lowercase namespace -- acquire -- string with identification -- Postcondition: -- Returns false if no problem -- string with violation local lucky, r = pcall( mw.loadData, "Module:URIutil/config" ); if type( r ) == "table" then r = r.urn; if type( r ) == "table" then local s = r.sns; if type( s ) == "string" then r = ":" .. area .. ":"; if s:match( r ) then s = "[^%w%(%)%+,%-%.:=@;%$_!%*'].*$"; r = acquire:match( s ); else r = ":" .. area .. ":"; end if not r then r = false; if area == "isbn" then if not URIutil.isISBNvalid( acquire ) then r = acquire; end elseif area == "issn" then if not URIutil.isISSNvalid( acquire ) then r = acquire; end end end else r = "Module:URIutil/config.urn.sns"; end else r = "Module:URIutil/config.urn"; end end return r;
end -- URNnamespace()
function URIutil.coreISSN( attempt )
-- Fetch significant ISSN -- Precondition: -- attempt -- string with presumable ISSN -- Postcondition: -- Returns string with 7 digits, without check digit nor GTIN -- unmodified input if wrong local r; local issn = ISSNfactory( attempt ); if type( issn ) == "table" then if issn.type == 8 then r = format( issn, 1, 7 ); elseif issn.type == 13 then r = format( issn, 4, 7 ); end else r = mw.ustring.upper( mw.text.trim( attempt ) ); end return r;
end -- URIutil.coreISSN()
function URIutil.formatISBN( attempt, assigned )
-- Format ISBN, if no hyphens present -- Precondition: -- attempt -- string with presumable ISBN -- assigned -- table or false; as of ISBNfactory() -- Postcondition: -- Returns string with some hyphens, if not yet -- unmodified input if already hyphens or wrong local r; local isbn; if type( assigned ) == "table" then isbn = assigned; else isbn = ISBNfactory( attempt ); end if type( isbn ) == "table" then r = ISBNformat( attempt, isbn ); else r = mw.ustring.upper( mw.text.trim( attempt ) ); end return r;
end -- URIutil.formatISBN()
function URIutil.formatISSN( attempt, achieve )
-- Format ISSN -- Precondition: -- attempt -- string with presumable ISSN -- achieve -- false or 8 or 13; requested presentation -- Postcondition: -- Returns string with some hyphens, if not yet -- unmodified input if already hyphens or wrong local r = false; local issn = ISSNfactory( attempt ); if type( issn ) == "table" then if ISSNfaith( issn ) then local k, m; if type( achieve ) == "string" then m = tonumber( achieve ); else m = achieve; end if m == 8 or m == 13 then k = m; else k = issn.type; end r = ISSNformat( issn, k ); end end if not r then r = mw.ustring.upper( mw.text.trim( attempt ) ); end return r;
end -- URIutil.formatISSN()
function URIutil.formatLCCN( attempt, achieve )
-- Standard or hyphen formatting of LCCN -- Precondition: -- attempt -- string with presumable LCCN -- achieve -- additional formatting desires, like "-" -- Postcondition: -- Returns string with letters, digits and hyphens -- unmodified input if wrong local r = LCCNfactory( attempt ); if r then r = LCCNformat( r, achieve ); end return r;
end -- URIutil.formatLCCN()
function URIutil.isDNBvalid( attempt, also )
-- Is this DNB (also GND, ZDB) formally correct (check digit)? -- Precondition: -- attempt -- string with any presumable DNB code -- also -- string or nil; optional requirement DMA GND SWD -- currently not implemented -- DMA starting with 3 and no hyphen -- GND not DNB2011 -- SWD DNB2011 starting with 4 or 7 and no X check -- Postcondition: -- Returns number of digits or 2011, if valid -- false if not correct, bad data or check digit wrong -- 2013-09-01 local s = mw.text.trim( attempt ); local j = s:find( "/", 5, true ); local r = false; local dnb; if j then s = attempt:sub( 1, j - 1 ); end j = s:find( "-", 2, true ); if j then if j > 3 and j <= 8 then if s:match( "^[0-9]+-[0-9xX]$" ) then dnb = factory( s, #s ); end end elseif #s > 7 then if s:match( "^[0-9]+$" ) then dnb = factory( s, false ); end end if type( dnb ) == "table" then if j then if DNBfaith( dnb, true ) then r = 2011; end else if DNBfaith( dnb, false ) then r = dnb.type; end end end return r;
end -- URIutil.isDNBvalid()
function URIutil.isDOI( attempt )
-- Is this a syntactically correct DOI? -- Precondition: -- attempt -- string with presumable DOI code -- Postcondition: -- Returns number of organization, if valid -- false if not correct, bad character or syntax local r = false; local k, s = attempt:match( "^ *10%.([1-9][0-9]+)/(.+) *$" ); if k then k = tonumber( k ); if k >= 1000 and k < 100000000 then local pc = "^[0-9A-Za-z]" .. "[%-0-9/A-Z%.a-z%(%)_%[%];:<>]+" .. "[0-9A-Za-z]$"; s = mw.uri.decode( mw.text.decode( s ), "PATH" ); if s:match( pc ) then r = k; end end end return r;
end -- URIutil.isDOI()
function URIutil.isEscValid( attempt )
-- Are bad percent escapings in attempt? -- Precondition: -- attempt -- string with possible percent escapings -- Postcondition: -- Returns string with violating sequence -- false if correct local i = 0; local r = false; local h, s; while i do i = attempt:find( "%", i, true ); if i then s = attempt:sub( i + 1, i + 2 ); h = s:match( "%x%x" ); if h then if h == "00" then r = "%00"; break; -- while i end i = i + 2; else r = "%" .. s; break; -- while i end end end -- while i return r;
end -- URIutil.isEscValid()
function URIutil.isGTINvalid( attempt )
-- Is this GTIN (EAN) formally correct (check digit)? -- Precondition: -- attempt -- string with presumable GTIN -- Postcondition: -- Returns GTIN length -- false if not correct, bad data or check digit wrong local r; local gtin = factory( attempt, false ); if type( gtin ) == "table" then if gtin.type == 13 then if GTINfaith( gtin ) then r = gtin.type; end else r = false; end else r = false; end return r;
end -- URIutil.isGTINvalid()
function URIutil.isISBN( attempt )
-- Is this a syntactically correct ISBN? -- Precondition: -- attempt -- string with presumable ISBN -- Postcondition: -- Returns -- 1 -- 10 if 10 digits and hyphens; also X at end of ISBN-10 -- 13 if 13 digits and hyphens; beginning with bookland -- false if not an ISBN -- 2 -- internal table, if (1) local r; local isbn = ISBNfactory( attempt ); if type( isbn ) == "table" then r = isbn.type; else r = false; end return r, isbn;
end -- URIutil.isISBN()
function URIutil.isISBNvalid( attempt )
-- Is this ISBN formally correct (check digit)? -- Precondition: -- attempt -- string with presumable ISBN -- Postcondition: -- Returns -- 1 -- 10 if 10 digits and hyphens; also X at end of ISBN-10 -- 13 if 13 digits and hyphens; beginning with bookland -- false if not correct, bad data or check digit wrong -- 2 -- internal table, if (1) local r = false; local isbn = ISBNfactory( attempt ); if type( isbn ) == "table" then if ISBNfaith( isbn ) then r = isbn.type; end end return r, isbn;
end -- URIutil.isISBNvalid()
function URIutil.isISSNvalid( attempt )
-- Is this ISSN formally correct (check digit)? -- Precondition: -- attempt -- string with presumable ISSN -- Postcondition: -- Returns 8 if 8 digits and up to 1 hyphen; also X at end -- 13 if 13 digits and hyphens; beginning with 977 -- false if not correct, bad data or check digit wrong local r = false; local issn = ISSNfactory( attempt ); if type( issn ) == "table" then if ISSNfaith( issn ) then r = issn.type; end end return r;
end -- URIutil.isISSNvalid()
function URIutil.isLCCN( attempt, allow )
-- Is this a syntactically correct LCCN? -- Precondition: -- attempt -- string with presumable LCCN -- allow -- false or string: "/" -- Postcondition: -- Returns string with LCCN formatted aa9999-99999999 -- false if not correct, bad data local r = false; local lccn = LCCNfactory( attempt, allow ); if lccn then r = LCCNformat( lccn, "-" ); end return r;
end -- URIutil.isLCCN()
function URIutil.linkDOI( attempt )
-- Retrieve bracketed titled external link on DOI resolver -- Precondition: -- attempt -- string with presumable DOI -- Postcondition: -- Returns external link, or false local r = URIutil.isDOI( attempt ); if r then r = mw.text.decode( mw.text.trim( attempt ), "PATH" ); r = string.format( "[%s%s %s]", "http://dx.doi.org/", mw.uri.encode( r ), mw.text.encode( r, "<>&%]" ) ); end return r;
end -- URIutil.linkDOI()
function URIutil.linkISBN( attempt, allow, abbr, adhere )
-- Retrieve bracketed titled wikilink on booksources page with "ISBN" -- Precondition: -- attempt -- string with presumable ISBN -- allow -- true: permit invalid check digit -- abbr -- true or string: link ISBN abbreviation -- adhere -- true: use else: use simple space; -- Postcondition: -- Returns link local lapsus; local source = mw.text.trim( attempt ); local r = ""; local isbn = ISBNfactory( source ); if type( isbn ) == "table" then local lenient; if type( allow ) == "string" then lenient = ( allow ~= "0" ); else lenient = allow; end if lenient then lapsus = false; else lapsus = ( not ISBNfaith( isbn ) ); end r = r .. ISBNformat( attempt, isbn ); else lapsus = true; r = r .. source; end r = r .. ""; if lapsus then r = "" .. r .. "(?!?!)"; end if adhere then r = " " .. r; else r = " " .. r; end if abbr then local s; if type( abbr ) == "string" then s = abbr; else s = "International Standard Book Number"; end r = string.format( "ISBN%s", s, r ); else r = "ISBN" .. r; end return r;
end -- URIutil.linkISBN()
function URIutil.linkISSN( attempt, allow, abbr, adhere )
-- Retrieve bracketed titled external link on ISSN DB with "ISSN" -- Precondition: -- attempt -- string with presumable ISSN -- allow -- true: permit invalid check digit -- abbr -- true or string: link ISSN abbreviation -- adhere -- true: use else: use simple space; -- Postcondition: -- Returns link local issn = ISSNfactory( attempt ); local lapsus; local r; if type( issn ) == "table" then local lucky, cnf = pcall( mw.loadData, "Module:URIutil/config" ); local lenient; if type( allow ) == "string" then lenient = ( allow ~= "0" ); else lenient = allow; end if lenient then lapsus = false; else lapsus = ( not ISSNfaith( issn ) ); end r = ISSNformat( issn, issn.type ); if type( cnf ) == "table" then if type( cnf.issn ) == "string" then r = string.format( "[%s %s]", cnf.issn:gsub( "%$1", r ), r ); end end else lapsus = true; r = attempt; end if lapsus then r = "" .. r .. "(?!?!)"; end if adhere then r = " " .. r; else r = " " .. r; end if abbr then local s; if type( abbr ) == "string" then s = abbr; else s = "International Standard Serial Number"; end r = string.format( "ISSN%s", s, r ); else r = "ISSN" .. r; end return r;
end -- URIutil.linkISSN()
function URIutil.linkLCCN( attempt, achieve )
-- Retrieve bracketed titled external LCCN permalink -- Precondition: -- attempt -- string with presumable LCCN -- achieve -- additional title formatting desires, like "-" -- Postcondition: -- Returns link, or false if bad LCCN return LCCNforward( attempt, achieve );
end -- URIutil.linkLCCN()
function URIutil.mayDOI( attempt )
-- Is this a syntactically correct DOI, or empty? -- Precondition: -- attempt -- string with presumable DOI -- Postcondition: -- Returns number of organization -- 0 if empty -- false if not empty and not a DOI local r; if type( attempt ) == "string" then local s = mw.text.trim( attempt ); if #s >= 10 then r = URIutil.isDOI( attempt ); elseif #s == 0 then r = 0; else r = false; end else r = false; end return r;
end -- URIutil.mayDOI()
function URIutil.mayISBN( attempt )
-- Is this a syntactically correct ISBN, or empty? -- Precondition: -- attempt -- string with presumable ISBN -- Postcondition: -- Returns 10 if 10 digits and hyphens; also X at end of ISBN-10 -- 13 if 13 digits and hyphens; beginning with bookland -- 0 if empty -- false if not empty and not an ISBN local r; if type( attempt ) == "string" then local s = mw.text.trim( attempt ); if #s >= 10 then r = URIutil.isISBN( attempt ); elseif #s == 0 then r = 0; else r = false; end else r = false; end return r;
end -- URIutil.mayISBN()
function URIutil.mayISSN( attempt )
-- Is this a correct ISSN, or empty? -- Precondition: -- attempt -- string with presumable ISSN -- Postcondition: -- Returns 8 if 8 digits and hyphens; also X at end -- 13 if 13 digits and hyphens; beginning with issnland -- 0 if empty -- false if not empty and not an ISSN local r; if type( attempt ) == "string" then local s = mw.text.trim( attempt ); if #s >= 8 then r = URIutil.isISSNvalid( attempt ); elseif #s == 0 then r = 0; else r = false; end else r = false; end return r;
end -- URIutil.mayISSN()
function URIutil.mayLCCN( attempt )
-- Is this a syntactically correct LCCN? -- Precondition: -- attempt -- string with presumable LCCN -- Postcondition: -- Returns string with LCCN formatted aa9999-99999999 -- 0 if empty -- false if not recognized if type( attempt ) == "string" then local s = mw.text.trim( attempt ); if s == "" then r = 0; else r = URIutil.isLCCN( s ); end else r = false; end return r;
end -- URIutil.mayLCCN()
function URIutil.mayURI( attempt, ascii )
-- Is this a syntactically correct URI, or empty? -- Precondition: -- attempt -- string with presumable URI -- ascii -- limit to ASCII (no IRI) -- Postcondition: -- Returns false if no problem -- string with violation local r = URIutil.isEscValid( attempt ); if not r then local s = mw.text.trim( attempt ); r = s:match( "%s(.+)$" ); if not r then r = s:match( "#(.*)$" ); if r then r = "#" .. r; elseif ascii then local pat = mw.ustring.char( 128,45,255 ); pat = "[" .. pat .. "].+$"; r = mw.ustring.match( s, pat ); end end end return r;
end -- URIutil.mayURI()
function URIutil.mayURN( attempt )
-- Is this a syntactically correct URN, or empty? -- Precondition: -- attempt -- string with presumable URN -- Postcondition: -- Returns false if no problem -- string with violation local r = URIutil.mayURI( attempt, true ); if not r then local s = attempt:match( "^%s*[uU][rR][nN]:(.+)$" ); if s then local ns, id = s:match( "^(%w+):(.+)$" ); if ns then r = URNnamespace( ns:lower(), id ); else r = s; end elseif mw.text.trim( attempt ) == "" then r = false; else r = "urn:"; end end return r;
end -- URIutil.mayURN()
function URIutil.plainISBN( attempt )
-- Format ISBN as digits (and 'X') only string -- Precondition: -- attempt -- string with presumable ISBN -- Postcondition: -- Returns string with 10 or 13 chars -- false if not empty and not an ISBN local r; local isbn = ISBNfactory( attempt ); if type( isbn ) == "table" then r = ISBNflat( isbn ); else r = false; end return r;
end -- URIutil.plainISBN()
function URIutil.uriDOI( attempt, anything, abbr )
-- Retrieve linked URI on DOI resolver -- Precondition: -- attempt -- string with presumable DOI -- anything -- intentionally dummy parameter -- abbr -- true or string: link doi: abbreviation local r = URIutil.linkDOI( attempt ); if r then if abbr then local s; if type( abbr ) == "string" then s = abbr; else s = "Digital Object Identifier"; end r = string.format( "doi:%s", s, r ); else r = "doi:" .. r; end end return r;
end -- URIutil.uriDOI()
local Template = function ( frame, action )
-- Retrieve library result for template access
-- Precondition:
-- frame -- object
-- action -- string; function name
-- Postcondition:
-- Returns appropriate string, or error message (development)
local lucky, r = pcall( URIutil[ action ],
frame.args[ 1 ] or "",
frame.args[ 2 ],
faculty( frame.args.link, true ),
faculty( frame.args.nbsp, true ) );
if lucky then
if r then
r = tostring( r );
else
r = "";
end
else
r = "" .. r .. "";
end
return r;
end -- Template()
-- Provide template access and expose URIutil table to require()
local p = {};
function p.coreISSN( frame )
return Template( frame, "coreISSN" );
end function p.formatISBN( frame )
return Template( frame, "formatISBN" );
end function p.formatISSN( frame )
return Template( frame, "formatISSN" );
end function p.formatLCCN( frame )
return Template( frame, "formatLCCN" );
end function p.isDNBvalid( frame )
return Template( frame, "isDNBvalid" );
end function p.isDOI( frame )
return Template( frame, "isDOI" );
end function p.isEscValid( frame )
return Template( frame, "isEscValid" );
end function p.isGTINvalid( frame )
return Template( frame, "isGTINvalid" );
end function p.isISBN( frame )
return Template( frame, "isISBN" );
end function p.isISBNvalid( frame )
return Template( frame, "isISBNvalid" );
end function p.isISSNvalid( frame )
return Template( frame, "isISSNvalid" );
end function p.isLCCN( frame )
return Template( frame, "isLCCN" );
end function p.linkDOI( frame )
return Template( frame, "linkDOI" );
end function p.linkISBN( frame )
return Template( frame, "linkISBN" );
end function p.linkISSN( frame )
return Template( frame, "linkISSN" );
end function p.linkLCCN( frame )
return Template( frame, "linkLCCN" );
end function p.mayDOI( frame )
return Template( frame, "mayDOI" );
end function p.mayISBN( frame )
return Template( frame, "mayISBN" );
end function p.mayISSN( frame )
return Template( frame, "mayISSN" );
end function p.mayLCCN( frame )
return Template( frame, "mayLCCN" );
end function p.mayURI( frame )
return Template( frame, "mayURI" );
end function p.mayURN( frame )
return Template( frame, "mayURN" );
end function p.plainISBN( frame )
return Template( frame, "plainISBN" );
end function p.uriDOI( frame )
return Template( frame, "uriDOI" );
end function p.URIutil()
return URIutil;
end
return p;