<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FSmalljim%2FParsePageTest</id>
	<title>Module:Sandbox/Smalljim/ParsePageTest - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://stockhub.co/index.php?action=history&amp;feed=atom&amp;title=Module%3ASandbox%2FSmalljim%2FParsePageTest"/>
	<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/Smalljim/ParsePageTest&amp;action=history"/>
	<updated>2026-08-01T23:14:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://stockhub.co/index.php?title=Module:Sandbox/Smalljim/ParsePageTest&amp;diff=146200&amp;oldid=prev</id>
		<title>imported&gt;Smalljim: try 3 - (match fail → nil)</title>
		<link rel="alternate" type="text/html" href="https://stockhub.co/index.php?title=Module:Sandbox/Smalljim/ParsePageTest&amp;diff=146200&amp;oldid=prev"/>
		<updated>2013-04-01T22:46:41Z</updated>

		<summary type="html">&lt;p&gt;try 3 - (match fail → nil)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[&lt;br /&gt;
&lt;br /&gt;
20130330: I have unashamedly copied this from User:Dragons flight&amp;#039;s ParsePage module, whose comments follow:&lt;br /&gt;
&lt;br /&gt;
This module is a collection of functions to assist in extracting information&lt;br /&gt;
from full Wikipedia pages.&lt;br /&gt;
&lt;br /&gt;
It is not intended to be a full parser, or anything like that, merely a simple&lt;br /&gt;
system for grabbing a few relevant details.  These functions are not intended &lt;br /&gt;
to be called directly from templates, but rather these functions would be &lt;br /&gt;
included and referenced in other Lua modules that examine page text.&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
p = {}&lt;br /&gt;
&lt;br /&gt;
p.getUsers = &lt;br /&gt;
function ( text, sort, unique )    &lt;br /&gt;
    sort = sort or false;&lt;br /&gt;
    unique = unique or false;&lt;br /&gt;
    local user_table = {};&lt;br /&gt;
    local search_re, link;&lt;br /&gt;
    &lt;br /&gt;
    -- Note, mw.ustring.gmatch is relatively slow.  Should switch to &lt;br /&gt;
    -- string once the string.gmatch bug is resolved.&lt;br /&gt;
    if not sort then &lt;br /&gt;
        search_re = &amp;#039;()%[%[User:([^/]-)[|%]#]&amp;#039;;&lt;br /&gt;
        for ind, name in string.gmatch( text, search_re ) do&lt;br /&gt;
            link = table.concat( {&amp;#039;[[User:&amp;#039;, name, &amp;#039;|&amp;#039;, name, &amp;#039;]]&amp;#039;} );&lt;br /&gt;
            table.insert( user_table, {ind, name, link} );&lt;br /&gt;
        end&lt;br /&gt;
        search_re = &amp;#039;()%[%[User talk:([^/]-)[|%]#]&amp;#039;;&lt;br /&gt;
        for ind, name in string.gmatch( text, search_re ) do&lt;br /&gt;
            if string.match( name, &amp;#039;^%d-%.%d-%.%d-%.%d-$&amp;#039; ) or string.match( name, &amp;#039;^[%dA-F]-:[%dA-F]-:[%dA-F]-:[%dA-F]-:[%dA-F]-:[%dA-F]$&amp;#039; ) then&lt;br /&gt;
                link = table.concat( {&amp;#039;[[Special:Contributions/&amp;#039;, name, &amp;#039;|&amp;#039;, name, &amp;#039;]]&amp;#039;} );&lt;br /&gt;
                table.insert( user_table, {ind, name, link} );&lt;br /&gt;
            else       &lt;br /&gt;
                link = table.concat( {&amp;#039;[[User:&amp;#039;, name, &amp;#039;|&amp;#039;, name, &amp;#039;]]&amp;#039;} );&lt;br /&gt;
                table.insert( user_table, {ind, name, link} );&lt;br /&gt;
            end            &lt;br /&gt;
        end&lt;br /&gt;
        table.sort( user_table, p._comp1 );&lt;br /&gt;
    else&lt;br /&gt;
        search_re = &amp;#039;%[%[User:([^/]-)[|%]#]&amp;#039;;&lt;br /&gt;
        for name in string.gmatch( text, search_re ) do&lt;br /&gt;
            link = table.concat( {&amp;#039;[[User:&amp;#039;, name, &amp;#039;|&amp;#039;, name, &amp;#039;]]&amp;#039;} );&lt;br /&gt;
            table.insert( user_table, {0, name, link} );&lt;br /&gt;
        end&lt;br /&gt;
        search_re = &amp;#039;%[%[User talk:([^/]-)[|%]#]&amp;#039;;&lt;br /&gt;
        for name in string.gmatch( text, search_re ) do&lt;br /&gt;
            if string.match( name, &amp;#039;^%d-%.%d-%.%d-%.%d-$&amp;#039; ) or string.match( name, &amp;#039;^[%dA-F]-:[%dA-F]-:[%dA-F]-:[%dA-F]-:[%dA-F]-:[%dA-F]$&amp;#039; ) then&lt;br /&gt;
                link = table.concat( {&amp;#039;[[Special:Contributions/&amp;#039;, name, &amp;#039;|&amp;#039;, name, &amp;#039;]]&amp;#039;} );&lt;br /&gt;
                table.insert( user_table, {0, name, link} );&lt;br /&gt;
            else       &lt;br /&gt;
                link = table.concat( {&amp;#039;[[User:&amp;#039;, name, &amp;#039;|&amp;#039;, name, &amp;#039;]]&amp;#039;} );&lt;br /&gt;
                table.insert( user_table, {0, name, link} );&lt;br /&gt;
            end            &lt;br /&gt;
        end    &lt;br /&gt;
        local comp = function( a, b )&lt;br /&gt;
            return a[2] &amp;lt; b[2];&lt;br /&gt;
        end    &lt;br /&gt;
        table.sort( user_table, comp );&lt;br /&gt;
    end&lt;br /&gt;
           &lt;br /&gt;
    if unique then&lt;br /&gt;
        user_table = p._makeUniqueTable( user_table, 2, sort );&lt;br /&gt;
    end      &lt;br /&gt;
&lt;br /&gt;
    local name_table = {};&lt;br /&gt;
    local last;&lt;br /&gt;
    for _, v in ipairs( user_table ) do&lt;br /&gt;
        if v[2] ~= last then&lt;br /&gt;
            table.insert( name_table, {v[2], v[3]} );&lt;br /&gt;
        end&lt;br /&gt;
        last = v[2];&lt;br /&gt;
    end    &lt;br /&gt;
&lt;br /&gt;
    return name_table;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.getSections =&lt;br /&gt;
function( text, header_level )&lt;br /&gt;
    local head_item = &amp;#039;^&amp;#039; .. string.rep( &amp;#039;=&amp;#039;, header_level ) .. &amp;#039;[^=]&amp;#039;;&lt;br /&gt;
    local head_filter = table.concat( { &amp;#039;^&amp;#039;,  string.rep( &amp;#039;=&amp;#039;, header_level ),&lt;br /&gt;
        &amp;#039;%s*(.*)%s*&amp;#039; .. string.rep( &amp;#039;=&amp;#039;, header_level ) } );&lt;br /&gt;
    &lt;br /&gt;
    local pos, last_pos, total_len;&lt;br /&gt;
    local new_table = {};&lt;br /&gt;
        &lt;br /&gt;
    local line_group = {};&lt;br /&gt;
    local headings = { &amp;#039;&amp;#039; };&lt;br /&gt;
    local header_delink;&lt;br /&gt;
    &lt;br /&gt;
    for line in string.gmatch( text, &amp;quot;\n([^\n]*)&amp;quot; ) do&lt;br /&gt;
        if string.match( line, head_item ) then&lt;br /&gt;
            table.insert( new_table, table.concat( line_group, &amp;quot;\n&amp;quot; ) );&lt;br /&gt;
            header_delink = mw.ustring.match( line, head_filter );&lt;br /&gt;
            header_delink = string.match( header_delink, &amp;quot;%|(.*)%]%]&amp;quot;) or header_delink; --strip piped links&lt;br /&gt;
            table.insert( headings, header_delink );&lt;br /&gt;
            &lt;br /&gt;
            line_group = { line };&lt;br /&gt;
        else&lt;br /&gt;
            table.insert( line_group, line );&lt;br /&gt;
        end&lt;br /&gt;
    end    &lt;br /&gt;
    table.insert( new_table, table.concat( line_group ) );&lt;br /&gt;
    &lt;br /&gt;
    return new_table, headings;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.getTimestamps = &lt;br /&gt;
function ( text )    &lt;br /&gt;
    local time_table = {};&lt;br /&gt;
    local lang = mw.getContentLanguage();&lt;br /&gt;
    local val;&lt;br /&gt;
    &lt;br /&gt;
    -- 01:02, 28 February 2013 (UTC)&lt;br /&gt;
    for ts in string.gmatch( text, &amp;#039;%d%d:%d%d, %d%d? %w- %d%d%d%d %(UTC%)&amp;#039; ) do&lt;br /&gt;
        val = tonumber( lang:formatDate( &amp;#039;U&amp;#039;, ts ) );  &lt;br /&gt;
        table.insert( time_table, {ts, val} );&lt;br /&gt;
    end&lt;br /&gt;
    return time_table;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.formatSectionLink =&lt;br /&gt;
function( root, text )&lt;br /&gt;
    local frame = mw.getCurrentFrame();&lt;br /&gt;
    local link = text;&lt;br /&gt;
    &lt;br /&gt;
    link = string.gsub( link, &amp;#039;%b&amp;lt;&amp;gt;&amp;#039;, &amp;#039;&amp;#039; );&lt;br /&gt;
    link = string.gsub( link, &amp;#039;%[%[&amp;#039;, &amp;#039;&amp;#039; );&lt;br /&gt;
    link = string.gsub( link, &amp;#039;%]%]&amp;#039;, &amp;#039;&amp;#039; );&lt;br /&gt;
        &lt;br /&gt;
    return table.concat( {&amp;#039;[[&amp;#039;, root, &amp;#039;#&amp;#039;, frame:preprocess( &amp;#039;{{anchorencode:&amp;#039; .. text .. &amp;#039;}}&amp;#039; ), &lt;br /&gt;
        &amp;#039;|&amp;#039; .. link .. &amp;#039;]]&amp;#039; } );    &lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.formatDateDiff = &lt;br /&gt;
function( date_diff )&lt;br /&gt;
    if date_diff &amp;lt; 60*60 then&lt;br /&gt;
        return tonumber( math.floor(date_diff/6)/10 ) .. &amp;#039; minutes&amp;#039;;&lt;br /&gt;
    elseif date_diff &amp;lt; 60*60*24 then&lt;br /&gt;
        return tonumber( math.floor(date_diff/(6*60))/10 ) .. &amp;#039; hours&amp;#039;;&lt;br /&gt;
    else&lt;br /&gt;
        return tonumber( math.floor(date_diff/(6*60*24))/10 ) .. &amp;#039; days&amp;#039;;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
p.getExcerpt = &lt;br /&gt;
function( text, length )&lt;br /&gt;
    length = length or 200;&lt;br /&gt;
    text = &amp;#039;\n&amp;#039; .. text .. &amp;#039;\n&amp;#039;;&lt;br /&gt;
    text = string.gsub( text, &amp;#039;\n=+[^=]-=+&amp;#039;, &amp;#039;\n&amp;#039; ); --headings&lt;br /&gt;
    text = string.gsub( text, &amp;#039;%[%[File:[^%]]*%]%]&amp;#039;, &amp;#039;&amp;#039; ); --files&lt;br /&gt;
    text = string.gsub( text, &amp;#039;%[%[Image:[^%]]*%]%]&amp;#039;, &amp;#039;&amp;#039; ); --images&lt;br /&gt;
    text = mw.ustring.match( text, &amp;#039;%s*(%S.*%S)%s*&amp;#039; ); --trim&lt;br /&gt;
    text = string.gsub( text, &amp;#039;|&amp;#039;, &amp;quot;&amp;amp;#124;&amp;quot; ); --table&lt;br /&gt;
    text = string.gsub( text, &amp;#039;%b&amp;lt;&amp;gt;&amp;#039;, &amp;quot;&amp;quot; ); --tags&lt;br /&gt;
    text = string.gsub( text, &amp;#039;{&amp;#039;, &amp;quot;&amp;amp;#123;&amp;quot; ); --tags&lt;br /&gt;
    text = string.gsub( text, &amp;#039;{&amp;#039;, &amp;quot;&amp;amp;#125;&amp;quot; ); --tags&lt;br /&gt;
    &lt;br /&gt;
    if mw.ustring.len( text ) &amp;lt; length then&lt;br /&gt;
        return text;&lt;br /&gt;
    else&lt;br /&gt;
        return mw.ustring.sub( text, 1, length ) ..&lt;br /&gt;
            mw.ustring.match( text, &amp;#039;%S*&amp;#039;, length+1 ) .. &amp;#039;...&amp;#039;;&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function p._compKey( a, b, key )&lt;br /&gt;
    return a[key] &amp;lt; b[key];&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._comp1( a, b )&lt;br /&gt;
    return p._compKey( a, b, 1 );&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._makeUniqueTable( t, key, sort )    &lt;br /&gt;
    sort = sort or false;&lt;br /&gt;
    local comp;&lt;br /&gt;
    &lt;br /&gt;
    if key then &lt;br /&gt;
        comp = function( a, b )&lt;br /&gt;
            return p._compKey( a, b, key );&lt;br /&gt;
        end&lt;br /&gt;
    else&lt;br /&gt;
        comp = nil;&lt;br /&gt;
    end    &lt;br /&gt;
    &lt;br /&gt;
    if sort then            &lt;br /&gt;
        if comp then&lt;br /&gt;
            table.sort( t, comp );&lt;br /&gt;
        else&lt;br /&gt;
            table.sort( t );&lt;br /&gt;
        end  &lt;br /&gt;
        &lt;br /&gt;
        local new_table, last;&lt;br /&gt;
        new_table = {};&lt;br /&gt;
        &lt;br /&gt;
        last = &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
        for k, v in ipairs( t ) do            &lt;br /&gt;
            if key then&lt;br /&gt;
                if v[key] ~= last then&lt;br /&gt;
                    table.insert( new_table, v );&lt;br /&gt;
                    last = v[key];&lt;br /&gt;
                end&lt;br /&gt;
            else&lt;br /&gt;
                if v ~= last then&lt;br /&gt;
                    table.insert( new_table, v );&lt;br /&gt;
                    last = v;&lt;br /&gt;
                end&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
        return new_table;&lt;br /&gt;
    else&lt;br /&gt;
        local simple_table = {};&lt;br /&gt;
        local new_table = {};&lt;br /&gt;
        for _, item in ipairs( t ) do  &lt;br /&gt;
            if key then&lt;br /&gt;
                if not simple_table[item[key]] then&lt;br /&gt;
                    table.insert( new_table, item )&lt;br /&gt;
                end                &lt;br /&gt;
                simple_table[item[key]] = true;&lt;br /&gt;
            else&lt;br /&gt;
                if not simple_table[item] then&lt;br /&gt;
                    table.insert( new_table, item )                    &lt;br /&gt;
                end                &lt;br /&gt;
                simple_table[item] = true;&lt;br /&gt;
            end            &lt;br /&gt;
        end&lt;br /&gt;
                    &lt;br /&gt;
        return new_table;               &lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p;&lt;/div&gt;</summary>
		<author><name>imported&gt;Smalljim</name></author>
	</entry>
</feed>