lib/infoboxer/templates/set.rb in infoboxer-0.1.0 vs lib/infoboxer/templates/set.rb in infoboxer-0.1.1
- old
+ new
@@ -1,33 +1,105 @@
# encoding: utf-8
module Infoboxer
module Templates
+ # Base class for defining set of templates, used for some site/domain.
+ #
+ # Currently only can be plugged in via {MediaWiki::Traits.templates}.
+ #
+ # Template set defines a DSL for creating new template definitions --
+ # also simplest ones and very complicated.
+ #
+ # You can look at implementation of English Wikipedia
+ # [common templates set](https://github.com/molybdenum-99/infoboxer/blob/master/lib/infoboxer/definitions/en.wikipedia.org.rb)
+ # in Infoboxer's repo.
+ #
class Set
def initialize(&definitions)
@templates = []
define(&definitions) if definitions
end
-
+
+ # @private
def find(name)
_, template = @templates.detect{|m, t| m === name.downcase}
template || Base
end
+ # @private
def define(&definitions)
instance_eval(&definitions)
end
+ # @private
def clear
@templates.clear
end
- private
-
+ # Most common form of template definition.
+ #
+ # Can be used like:
+ #
+ # ```ruby
+ # template 'Age' do
+ # def from
+ # fetch_date('1', '2', '3')
+ # end
+ #
+ # def to
+ # fetch_date('4', '5', '6') || Date.today
+ # end
+ #
+ # def value
+ # (to - from).to_i / 365 # FIXME: obviously
+ # end
+ #
+ # def text
+ # "#{value} years"
+ # end
+ # end
+ # ```
+ #
+ # @param name Definition name.
+ # @param options Definition options.
+ # Currently recognized options are:
+ # * `:match` -- regexp or string, which matches template name to
+ # add this definition to (if not provided, `name` param used
+ # to match relevant templates);
+ # * `:base` -- name of template definition to use as a base class;
+ # for example you can do things like:
+ #
+ # ```ruby
+ # # ...inside template set definition...
+ # template 'Infobox', match: /^Infobox/ do
+ # # implementation
+ # end
+ #
+ # template 'Infobox cheese', base: 'Infobox' do
+ # end
+ # ```
+ #
+ # Expected to be used inside Set definition block.
def template(name, options = {}, &definition)
setup_class(name, Base, options, &definition)
end
+ # Define list of "replacements": templates, which text should be replaced
+ # with arbitrary value.
+ #
+ # Example:
+ #
+ # ```ruby
+ # # ...inside template set definition...
+ # replace(
+ # '!!' => '||',
+ # '!(' => '['
+ # )
+ # ```
+ # Now, all templates with name `!!` will render as `||` when you
+ # call their (or their parents') {Tree::Node#text}.
+ #
+ # Expected to be used inside Set definition block.
def replace(*replacements)
case
when replacements.count == 2 && replacements.all?{|r| r.is_a?(String)}
name, what = *replacements
setup_class(name, Replace) do
@@ -42,21 +114,53 @@
else
fail(ArgumentError, "Can't call :replace with #{replacements.join(', ')}")
end
end
+ # Define list of "show children" templates. Those ones, when rendered
+ # as text, just provide join of their children text (space-separated).
+ #
+ # Example:
+ #
+ # ```ruby
+ # #...in template set definition...
+ # show 'Small'
+ # ```
+ # Now, wikitext paragraph looking like...
+ #
+ # ```
+ # This is {{small|text}} in template
+ # ```
+ # ...before this template definition had rendered like
+ # `"This is in template"` (template contents ommitted), and after
+ # this definition it will render like `"This is text in template"`
+ # (template contents rendered as is).
+ #
+ # Expected to be used inside Set definition block.
def show(*names)
names.each do |name|
setup_class(name, Show)
end
end
+ # Define list of "literally rendered templates". It means, when
+ # rendering text, template is replaced with just its name.
+ #
+ # Explanation: in
+ # MediaWiki, there are contexts (deeply in other templates and
+ # tables), when you can't just type something like `","` and not
+ # have it interpreted. So, wikis oftenly define wrappers around
+ # those templates, looking like `{{,}}` -- so, while rendering texts,
+ # such templates can be replaced with their names.
+ #
+ # Expected to be used inside Set definition block.
def literal(*names)
names.each do |name|
setup_class(name, Literal)
end
end
+ # @private
def setup_class(name, base_class, options = {}, &definition)
match = options.fetch(:match, name.downcase)
base = options.fetch(:base, base_class)
base = self.find(base) if base.is_a?(String)