Module:Buffer/doc: Difference between revisions

Content deleted Content added
save
save
Line 9:
The interface for Module:Buffer objects is similar to that of {{Luaref|HTML_library|mw.html}} objects in that you may build complex strings with independent child nodes. In most cases, you may use Buffer objects like a normal string, including using {{code|..}} operator (though {{luaself|:_}} has the same role, but potentially [[#performance|over 10 times faster than {{code|..}}]]). See also: [[#Calling string, mw.ustring, and mw.text libraries]]
 
Additionally, there are threefour specialized modesforms, described further in their respective sections: {{luaself|:stream|plain=y}}, {{luaself|\-HTML|plain=y}}, and {{luaself|pre=Element{{-|\|plain=y}} and {{luaself|\-variable|plain=y}}.
 
Last but not least, this module has an ordered [[#require'Module:Buffer'.__pairs|__pairs]] more thorough than {{luaref|ipairs||y}} and {{luaref|pairs||y}}. (Even reads nil keys!) The <span title='This is a bad Star Trek joke'>logical uniqueness</span> of this iterator may be reason enough to {{luaref|require|assimilate|y}} Module:Buffer.
Line 19:
{{luaself|Buffer|\|require'Module:***'|subpage= |args=...|args2=_G, name, save, ...}}
 
Creates a new Module:Buffer object when it (the module) is called as a function{{--}}i.e., there is no 'main'.
 
InitializePass the module with(or {{luaself|:_in}}) your "local" global variable {{luaref|_G}} prior to creating any Buffer objects to enable [[#Global functions|global functions]]. If passed _G then the next two {{luaref|varargs|plain=y}} will pass to {{luaself|:_G}} and any extra will pass to {{luaself|:_}}. If initialized without _G then all varargs will pass to {{luaself|:_|args=...}}.
 
You may also use most Buffer object functions directly on the module{{--}}i.e <code style='white-space:nowrap'>require'Module:Buffer':''function''{...}</code> is equivalent to <code style='white-space:nowrap'>require'Module:Buffer'():''function''{...}</code>.<ref Thegroup=note>For your convience, the self operator, {{code|:}}, and {{code|.}} are interchangable when used on the Module directly, butthough the self-op is required for nearly all other interactions with Buffer objects (othercreated thanby {{luaself|.last_concat}})the Module.</ref>
 
===Buffer===
Line 30:
:''See also {{luaself|:_str|plain=y}} for advanced string conversion.
 
Get Buffer as type {{luaref|string||y}} by performing a function call on the Buffer ''object'' (as opposed to [[#require'Module:Buffer'|a call on the ''Module'']]).
Calling a Buffer is basically shorthand for {{luaref|table.concat|args=Buffer, ...}}, or, with no args, {{luaref|tostring|args=Buffer}}.
However, if your Buffer contains [[#raw|raw]] objects or out-of-sequence values, then the return string would be the result of {{luaself|Buffer|:_all|empty-buffer:_all|args=Buffer )( ...}} instead.<ref group=note name=raw />
 
Unconventionally, any <code>i</code> or <code>j<code> of type {{luaref|string|plain=y}} would be treated as ''relative to length'';
that is, {{luaself|\|args='-', -1, '-3'}} is equivalent to {{luaself|\|args='-', -1, #Buffer - 3}}
Unconventionally, a ''pos'' of type {{luaref|string|plain=y}} is treated as relative to length; that is, {{luaself|:_|args='string', '-1'}} is equivalent to {{luaself|:_|args='string', #Buffer - 1}} (obviating the need to set a {{luaref|Local variable declarations|local|y}} Buffer to use the {{luaref|Length operator|length operator|y}}).
 
Note you do not need to string a Buffer object to append it to an {{luaref|HTML library|mw.html|y}} object via {{luaref|mw.html:node}} (though not mw.html:wikitext because of type checking).
Line 45 ⟶ 51:
:''See also {{luaself|:stream|plain=y}} for a faster, simpler version of this op.
 
Appends a value to the Buffer. In rough terms, {{code|lang=lua|Buffer:_'string1':_'string2'}} is the same as {{code|lang=lua|Buffer {{=}} Buffer..'string1'..'string2'}}.
(It may help to imagine {{code|:_}} as a {{code|..}} that has stood up and is now casting a shadow.)
{{anchor|valid|invalid|no-op}}
 
{{anchor|valid|no-op}}
If passed an ''invalid'' {{code|value}} listed below, this is a no-op:
* {{luaref|boolean||y}}
Line 54 ⟶ 61:
* {{luaref|table||y}} without a {{luaref|Metatables|__tostring metamethod}} and which {{code|table[1]|lang=lua}} is nil or false.
 
A table with no __tostring will pass through {{luaref|table.concat}} before insertion. An {{luaref|error|plain=y}} may be thrown if the table would cause table.concat to error.
(Use {{luaself|:_all}} instead for such tables.) For all other ''value'', the result of {{luaref|tostring|args=value}} would be inserted so long as it is not an empty string.
 
When passed {{code|pos}} of type {{luaref|number|plain=y}}, the argument is identical to ''pos'' for {{luaref|table.insert|args=table, pos, value}}.
In fact, assuming a [[#valid|valid value]], {{luaself|:_|args='string', 1}} is exactly the same as {{luaref|table.insert|args=Buffer, 1, 'string'}}.
 
Unconventionally, a ''pos'' of type {{luaref|string|plain=y}} is treated as relative to length; that is, {{luaself|:_|args='string', '-1'}} is equivalent to {{luaself|:_|args='string', #Buffer - 1}} (obviating the need to set a {{luaref|Local variable declarations|local|y}} Buffer to use the {{luaref|Length operator|length operator|y}}).
 
Just like with the position arguments of [[#Buffer|Buffer()]], any ''pos'' of type {{luaref|string|plain=y}} would be treated as relative to length.
{{anchor|raw}}
 
Set {{code|raw}} to true to force ''value'' in Buffer without tostring coercion, including [[#no-op|invalid]] values.<ref group=note name=raw>Setting a Buffer to ''raw'' incurs [[#performance|performance]] penalty for all future tostring ops as it must re-validate each indexed value through {{luaself|:_all}} to a new table before passing that to table.concat (vs. passing itself directly). That said, re-stringing a raw Buffer is still usually several times faster than using the {{luaref|Concatenation operator|..}} op to join an equivalent number of strings. (See [[#Tips]] for ways to avoid using raw)</ref> If given only two (non-self) arguments with the second being a boolean, then the second is read as ''raw'' instead.
Set {{code|raw}} to true to force append a ''value'' without tostring coercion, including [[#no-op|invalid]] values.
<ref group=note name=raw>Setting a Buffer to ''raw'' incurs [[#performance|performance]] penalty for all future tostring ops as it must re-validate each indexed value
through {{luaself|:_all}} to a new table before passing that to table.concat (vs. passing itself directly).
That said, re-stringing a raw Buffer is still usually several times faster than using the {{luaref|Concatenation operator|..}} op to join an equivalent number of strings.
(See [[#Tips]] for ways to avoid using raw)</ref>
If given only two (non-self) arguments with the second being a boolean, then the second is read as ''raw'' instead.
 
===Buffer:_nil===
Line 71 ⟶ 85:
If {{code|replacement}} is provided, then this will replace the value at the ''pos'' index as long as ''replacement'' is not a boolean, in which case, this is a no-op.
 
When ''replacement'' is nil, the op is simply {{luaref|table.remove|args=Buffer, pos}} with string ''pos'' relative to length.
Note however there is no further type checking on replacement, so, if nil nor boolean, then Buffer will be set to [[#raw|raw mode]].
 
Pos cannot be omitted if replacement is passed, though a ''pos'' that is nil will be treated as <code>{{#tag:syntaxhighlight|#Buffer|lang=lua|enclose='none'}}</code>.
Line 79 ⟶ 94:
{{luaself|:_all|args={ value, ... }|args2={ ..., value = pos, functionName = args, ... }, nanKeys}}
 
Takes a table {{code|value}}, iterates through all number keys {{luaref|table.sort|in order|plain=yes}}, appending each [[#valid|valid]] value to the end of the Buffer.
In contrast to {{luaref|ipairs}}, this starts at the most negative key (down to {{luaref|math.huge|-inf|y}}), continues through any nil keys,
until it reaches the most positive index and includes [[Double-precision floating-point format|non-integer number keys]].
(Note: despite Module:Buffer.__pairs having a more thorough iteration than ipairs, the difference in their runtimes is almost statistically insignificant.
Details at [[#Performance]] and [[#Using the iterator outside of buffer]].)
 
A table ''value'' that has no metatable will have its contents iterated by this function before moving on to the next value. All other data types are processed by {{luaself|:_}}.
 
{{anchor|nanKeys}}
By default, this ignores non-number keys unless {{code|nanKeys}} evaluates true. If so, non-number keys are processed after number keys. Keep in mind such keys are iterated in {{luaref|next|no particular|y}} order, though an order may be imposed by wrapping each pair in a table indexed at a number key.
 
By default, this ignores non-number keys unless {{code|nanKeys}} evaluates true. If so, non-number keys are processed after number keys.
If given a <code>''value'' = ''pos''</code> pair, defined as a number or number string indexed at a non-number key, then they will be passed as the {{code|value}} and {{code|pos}} arguments for {{luaself|:_|plain=y}}. Thus, {{luaself|:_all|args=({1,2,3,'... done',[3.5]=variable and 4 or {four='1',zero=1{{))}},true)}} produces the same result as:
By default, this ignores non-number keys unless {{code|nanKeys}} evaluates true. If so, non-number keys are processed after number keys. Keep in mind such keys are iterated in {{luaref|next|no particular|y}} order, though an order may be imposed by wrapping each pair in a table indexed at a number key.
 
If given a <code>''value'' = ''pos''</code> pair, defined as a number or number string indexed at a non-number key, then they will be passed as the {{code|value}} and {{code|pos}} arguments for {{luaself|:_|plain=y}}. Thus, {{luaself|:_all|args=({1,2,3,'... done',[3.5]=variable and 4 or {four='1',zero=1{{))}},true)}} produces the same result as:
 
Thus, {{luaself|:_all|args=({1,2,3,'... done',[3.5]=variable and 4 or {four='1',zero=1{{))}},true)}} produces the same result as:
{{#tag:syntaxhighlight|Buffer:_(1):_(2):_(3)
if variable then
Line 95 ⟶ 117:
Buffer:_'... done'|lang=lua}}
 
If a non-number key points to a value that cannot be coerced into a {{luaref|tonumber|coerced into a number|y}} then the pair may be treated as <code>''functionName'' = ''args''</code>,
when ''functionName'' matches a Buffer object function and ''args'' is not boolean.
If ''args'' is such that {{code|value[1]|lang=lua}} evaluates true, then this will pass the return of {{luaref|unpack|args=value, 1, table.maxn(value)}} to the named function; otherwise, the value is passed as is.
<ref group=note>In other words, if ''args'' is a string or a table without [1] set, it will be passed as the only argument.
Further note it is not possible to pass a <code>''functionName'' = ''args''</code> pair where ''args'' is numerical since such would be read as <code>''value'' = ''pos''</code>.
Finally, passing a function type as ''args'' will throw an error message.</ref>
For example:
 
{{code|1=p(_G,'arg', true):_all({'arg',arg==true and {'==true: ' ,_in={_G, 't', nil, ' awesome'}{{))}}, true):_(t and {t(), t..'r', t..'st'})|lang=lua}}
Line 105 ⟶ 133:
{{luaself|:_in|args=...|args2=_G, name, save, ...}}
 
CreatesPasses andany returnsarguments to [[#require'Module:Buffer'|Module:Buffer]] to create a new Buffer object. Thisand doesthen notsets <u>not</u>an appendexternal the new Bufferreference to the parent. (SeeBuffer nextand section)returns the child.
<ref group='note' name='in-dependents'>There is no 'getChild' method. If a child needed after returning to the parent, set it {{luaref|Local_variable_declarations|locally|y}}
<ref group='note' name='in-dependents'>There is no 'getChild' method. If a child needed after returning to the parent, set it {{luaref|Local_variable_declarations|locally|y}} (or use {{luaself|:_G}}) prior to returning. (No, {{u|Codehydro}} did not get lazy. Rather, this allows {{luaref|Garbage collection|garbage collection|y}} on children with no further purpose.)</ref> Do not pass _G if the Module:Buffer instance was not initialized with [[#Global functions|global functions]] enabled.
 
This does <u>not</u> append the child to the parent. (See {{luaself|:_out|plain=y}})
More precisely, it re-calls the [[#require'Module:Buffer'|Module:Buffer]] instance which created the Buffer object with the passed arguments and then adds a reference for new Buffer to allow it to retrieve its parent.
<ref group='note' name='in-dependents'>There is no 'getChild' method. If a child needed after returning to the parent, set it {{luaref|Local_variable_declarations|locally|y}} (or use {{luaself|:_G}}) prior to returning. (No, {{u|Codehydro}} did not get lazy. Rather, this allows {{luaref|Garbage collection|garbage collection|y}} on children with no further purpose.)</ref> Do not pass _G if the Module:Buffer instance was not initialized with [[#Global functions|global functions]] enabled.
 
NoteAlso, thatbe allaware that Buffer parent references are {{luaref|weak tables|weak|y}}. IfThus, aif variableyou iswere to (re-)set toa thelocal parentvariable andthat is thencurrently set to somethingthe elseparent, such maycould trigger immediate garbage collection on the parent.
 
===Buffer:_out===
Line 132 ⟶ 161:
===Buffer:_cc===
 
{{luaself|:_cc|args=clear|args=clear, copy, meta|args2=0, true}}
 
Nils all keys of the table referenced by {{code|clear}} and unsets its metatable. If ''clear'' evaluates false, this simply purges the cache at {{luaself|.last_concat}}.
 
If given a table to {{code|copy}}, this will duplicate all key-value pairs of ''copy'' into ''clear'', cloning any table held by ''copy''value recursively via <{{code>|lang=lua|Buffer:_cc(0, value)</}}. This returns the Buffer unless passed the number {{code>|lang=lua|0}} as ''clear'', which returnscauses this to create a new table insteadand return that instead. ofPassing changing{{code|lang=lua|true}} anas existing''copy'' is equivalent to passing the Buffer itself. If ''copy'' is not a table, then it will be set as the first item in ''clear'' as long as it is not ''false''.
 
While this may resemble {{luaref|mw.clone}}, there are several differences, namely that this:
* This sets the metatable ofGives ''clear'' tothe thatsame ofmetatable as ''copy'' instead of cloning its metatable (or tosets <code>meta</code>, if given) as opposed to a "clone" of the metatable.
* Conserves {{luaref|Length operator|Length|y}} is always conservedattribute (though empty strings may replace some nil keys<ref group=note>
For example, given {{code|lang=lua|{nil, 'string'} }} as ''copy'', {{code|lang=lua|Buffer:_cc(clear, copy)}} makes {{code|lang=lua|#clear}} equal <code>2</code>,
whereas {{code|lang=lua|#mw.clone{nil, 'string'} }} equals <code>0</code> (as of March 2015).
This replicates length by filling clear halfway to the length of copy (the minimum needed to 'trick's lengthLua) and then setting those keys nil whenevery key suchthat would not trigger recalculation.
As a result, any keys whichthat would resize ''clear'' when set nil are left as empty strings. Such should be fairly rare;
given tables representing every combinationpossible ofway positionsto forposition a single nil key for all lengths between 2 and 32 (inclusive), only 8.39 percent such tables would have aits nil copied as an empty string instead.
Also note that tables returned byfrom {{code|lang=lua|Buffer:_(0, copy)}} have length declared on creation instead, and thus won't have extra strings attached.
The odds can be estimated using <math>y {{=}} 0.5 / \sqrt{x}</math>, where <math>y</math> is the upper limit that an arbitrary nil key from ''copy'' of length ranging from 1 to <math>x</math> is imaged as an empty string.</ref>)
* All values are set via {{luaselfluaref|rawsetRawset||y}}s values and iteratediterates without invoking any __pairs {{luaref|Metatables|metamethod|y}}.
* Also copiesIncludes Buffer parent and [[#raw|raw]] settingsattributes (which are stored externally)
 
If ''copy'' is not a table, then it will be inserted as the first index of the ''clear''ed table so long as ''copy'' is not nil or false. Passing {{code|lang=lua|true}} as ''copy'' is equivalent to passing the Buffer itself.
 
To obtain the table of key-value pairs left as empty strings in the previous copy op, simply call this again with any same value passed to both ''clear'' and ''copy'' (as long as they do not evaluate false).
Line 160 ⟶ 187:
:''To skip generations without breaking the Buffer chain, see [[#global functions]].
 
Similar to {{luaself|:_out}} except, instead of apending the Buffer to its parent, this calls {{luaself|:_str}} on the parent(s) and appends the resultancestor(s).
The parent is unaffected by this operation and may still be retrieved via {{luaself|:_out}} or re-appended again with this function.
 
===Buffer:getParent===
 
{{luaself|:getParent|args=value|args2=functionName, ...}}
Also know:''Note that herethere is no 'getChild' method.<ref group='note' name='in-dependents'/>
 
Returns parent Buffer, or, if none exists, sets a newly created Buffer as the 'parent' and returns the adopted parent.
 
FollowingIn thisaccording Module'swith the "waste no {{code|()}} philosophy" of this Module, arguments are passed to the parent. If passed only one {{code|value}}, this is equivalent to {{luaself|Buffer|:_|***:getParent():_|args=value}}.
If anyadditional {{luaself|varargs|plain=yes}} are given, {{code|functionName}} must be a string naming a Buffer object function (or [[#library]]) to be called on the parent using the varargs.
 
Also know that here is no 'getChild' method.<ref group='note' name='in-dependents'/>
 
===Buffer:killParent===
Line 184 ⟶ 211:
===Buffer:stream===
 
{{luaself|:stream|args='string'|args2={concat{{ndash}}list}|args3=(var)}}{{anchor|streaming|calling a Buffer:stream...}}
 
Switches the Buffer to stream mode., Inin this mode,which the [[#call Buffer object|Buffer__call callmetamethod]] operation, instead of returning a string, now acts as streamlined version of {{luaself|:_}}. Though using the same helper method as :_ to [[#valid|validate]] values, the stream call op performs [[#performance|50 percent faster]].
 
Note that any args given are passed to {{luaself|pre=Stream{{ndash}}|\:each}} rather than to __call for a reason that should be evident after you read that section.
 
===Stream-Buffer===
 
{{luaself|pre=Stream-|\|args='string'|args2={concat{{ndash}}list}|args3=(var)}}{{anchor|streaming|calling a Buffer:stream}}
 
When streaming, you can append string (and table) literals with nothing between them (or only {{luaref|Character class|ASCII space chars|y}} if desired). For example, both A and B will produce identical strings:
{{#tag:syntaxhighlight|local A = require'Module:Buffer':stream'A string of text may flow''with nothing between each string' 'or perhaps only a space'
'or even tab and line-break characters''and continue to append individually''for use with a joiner'
 
local B = require'Module:Buffer':_'A string of text may flow':_'with nothing between each string' :_ 'or perhaps only a space'
:_'or even tab and line-break characters':_'and continue to append individually':_'for use with a joiner'
mw.logObject{log(A==B, A:_str' '})
"true A string of text may flow with nothing between each string or perhaps only a space or even tab and line-break characters and continue to append individually for use with a joiner",
}|lang=lua}}
 
Keep in mind that Lua numbers<ref group=note>It is best practice to pass number ''strings'' instead of number literals (i.e. {{code|lang=lua|Buffer:stream'1'}} instead of {{code|lang=lua|Buffer:stream(1)}}). Such improves performance (and is perhaps more aesthetically pleasing in this mode).</ref>named variables are too shy to [[skinny dip]] in a Buffer stream and must wear parenthesis {{code|lang=lua|()}} as with any {{luaref|Function calls|function call|y}}.
mw.logObject{A==B, A:_str' '}
Such improves performance (and is perhaps more aesthetically pleasing in this mode).</ref>
table#1 {
and named variables are too shy to [[skinny dip]] in a Buffer stream and must wear parenthesis {{code|lang=lua|()}} as with any {{luaref|Function calls|function call|y}}.
true,
"A string of text may flow with nothing between each string or perhaps only a space or even tab and line-break characters and continue to append individually for use with a joiner",
}|lang=lua}}
 
Aside from saving two keystrokes per op, this mode runs about [[#performance|50 percent faster]] than {{code|:_|lang=lua}} (which, in turn, is over 10 times faster than {{code|..|lang=lua}} for long strings).
 
Keep in mind that Lua numbers<ref group=note>It is best practice to pass number ''strings'' instead of number literals (i.e. {{code|lang=lua|Buffer:stream'1'}} instead of {{code|lang=lua|Buffer:stream(1)}}). Such improves performance (and is perhaps more aesthetically pleasing in this mode).</ref>named variables are too shy to [[skinny dip]] in a Buffer stream and must wear parenthesis {{code|lang=lua|()}} as with any {{luaref|Function calls|function call|y}}.
 
No special action is needed to exit this mode. The normal call to string op is restored upon the use of any regular Buffer function or any operation which coerces the Buffer into a string.
'''Returning to normal mode'''<br/>
No special action is needed to exit this mode. The normal call to string op is restored upon the use of any regular Buffer function or any operation which coerces the Buffer into a string.<ref group=note>No explicit trigger to exit stream mode has been programmed for {{luaself|pre=Element{{ndash}}-|\}} functions (including Buffer-HTML redirects). Stringing an Element-Buffer without its outer HTML-Buffer was deemed uncommon enough such that the inconvience of exiting via using <code>:_()</code> on the last item was outweighed by the [[#performance]] penalty that may result from modifying the specialized functions.</ref>
Stringing an Element-Buffer without its outer HTML-Buffer was deemed uncommon enough that the [[#performance]] penalty from modifying those specialized functions
would outweigh the inconvience of having to exit via typing <code>[[#Buffer:|:_( ... )]]</code> around the last item.</ref>
 
===Stream-Buffer:stream:each===
 
{{luaself|:pre=Stream-|\stream:each|args=...}}
 
Appends an undetermined number of [[#valid|valid]] values.
 
While analogous to {{luaref|mw.html:wikitext|plain=y}}, one distinguishing point (other than being [[#performance|twice as fast]] and able to [[#Buffer:_|handle tables and booleans]]) is that this does ''not'' stop at the first ''nil'' value.
In short, something like {{code|lang=lua|:wikitext('string1', varName, 'string2')}} can be replaced with {{code|lang=lua|:each('string1', {varName, 'string2'})}} when <code>varName</code> is either a string or nil.
 
==HTML extension==
Line 241 ⟶ 273:
Buffer-HTML objects may be used like any mw.html object. (In fact, if the only change were to substitute {{code|mw.html.create}} with {{code|require'Module:Buffer':_inHTML}} in an existing Module, its output should remain the same.)
 
Call the object as a function to return its {{luaself|pre=Element{{ndash}}-|\|plain=y}}, which is the table found at {{code|mw.html{{ndash}}object.nodes}} converted into a Module:Buffer object.
 
Strings are passed to the Element-Buffer via {{luaself|:_}} which basically has the same effect as though <code>:wikitext</code> were between {{code|Buffer-HTML}} and {{code|lang=lua|'string'}}, the only difference being the object returned. Tables are passed to {{luaself|pre=Element{{ndash}}-|:_add}}.
 
Most Buffer object functions are either unavailable for use directly on the Buffer-HTML object. Those listed below have been modified so that
Line 249 ⟶ 281:
===Element-Buffer===
 
{{luaself|pre=Element{{ndash}}-|\|args=sep, i , j}}
 
Element-Buffers have the same metatable as normal Buffer objects, so [[#call Buffer object|calling it]] will string it in the same manner.
Line 257 ⟶ 289:
You may use most Buffer object functions normally, however those which have a Buffer-HTML version (such as {{luaself|\-HTML:_out}}) will instead behave as though used on the [[#Buffer-HTML|outer HTML object]].<ref group=note>While Buffer-HTML objects may use [[#global functions]], there is no separate Buffer-HTML version. In other words, the self-action of a global function on an Element-Buffer is <u>not</u> redirected to the outer Buffer-HTML object.</ref> Also, {{luaself|pre-Element|:_inHTML}} has been modified as described in that section.
 
Additionally, you may chain any mw.html object function directly on an Element-Buffer. With the exception of {{luaself|pre=Element{{ndash}}-|:tag}} and {{luaself|pre=Element{{ndash}}-|:done}}, the mw.html function has been placed in a wrapper function that merely redirects the self-action to the outside Buffer-HTML.<ref group=note>{{luaref|mw.html:allDone}} is doubly wrapped for Element-Buffers. The inner wrapper sets a Buffer parent reference as described at {{luaself|:_inHTML}}.</ref>
 
Concatenate an Element-Buffer to another value with the {{code|lang=lua|..}} operator to return the result inside the tag, such that:
Line 276 ⟶ 308:
====Element-Buffer:done====
 
{{luaself|pre=Element{{ndash}}-|\|args=dones}}
 
When called without arguments, this behaves just like {{luaref|mw.html:done}} as called on the outer HTML object.
Line 282 ⟶ 314:
However, it has been modified to accept {{code|dones}}, the number of :done() operations to perform. Thus, {{code|Element{{ndash}}Buffer:done(4)|lang=lua}} is equivalent to {{code|Buffer{{ndash}}HTML:done():done():done():done()|lang=lua}}.
 
Pass zero ({{code|lang=lua|0}}) as ''dones'' to return to the Element-Buffer's direct HTML container. (Using an mw.html function to no-op is another way to return to the Buffer-HTML object, e.g. {{luaself|pre=Element{{ndash}}-|:node|args=()}}, though that example does not work for selfClosing tags.)
 
===ipairs with HTML-Buffer===
Line 305 ⟶ 337:
==Global functions==
 
{{anchor|Buffer-variable}}
==Buffer-variable objects==
 
===Buffer:_var===
 
{{luaself|:_var|args=initial{{ndash}}value, name}}
 
Appends a Buffer-variable object. This also disables future caching at {{luaself|.last_concat|plain=y}} for all Buffer objects in your module (and any module which may require it).
 
If passed a number as <code>initial-value</code>, the number will increase by one each time the Buffer-variable is strung.
Similarily, if it is a string, then it reappear as the next ASCII character each time.
 
When passed a table, the first item will be used, then the second, and so on. This loops back to the first after reaching the last item.
You may also pass your own custom function, though how to code one is beyond the scope of this manual.
 
For example:
{{#tag:syntaxhighlight|require'Module:Buffer'
:_inHTML'div'
{{((}}tag='br'},'Heading ',color='blue',['text-decoration']='underline'}
:_var'A':_' - ':_var{'odd', 'even'}
:_out()
:_in(_G, 'bod'):_'Body ':_var(1):_'\n':_out():_html():_(bod):_html():_(bod)
--[[ Produces:
<div style="color:blue;text-decoration:underline"><br />Heading A - odd</div>Body 1
<div style="color:blue;text-decoration:underline"><br />Heading B - even</div>Body 2
<div style="color:blue;text-decoration:underline"><br />Heading C - odd</div>Body 3 --]]|lang=lua}}
 
Pass a boolean to re-append the last Buffer-variable object created. Anything that is not false or nil will append the object [[#raw]]. False appends the previous value as a string without incrementing the object. If passed nil, this is a no-op.
 
If given <code>name</code>, then, if [[#global functions|global functions]] are enabled, the Buffer-variable will be saved via {{luaself|:_G}}.
 
==Modified {{code|..}} operator==
Line 315 ⟶ 377:
 
<code>value .. ''Element-Buffer''</code><br />
 
 
==require'Module:Buffer'.__pairs==