lib/csl/info.rb in csl-1.0.0.pre3 vs lib/csl/info.rb in csl-1.0.0.pre4

- old
+ new

@@ -1,112 +1,227 @@ module CSL - + # + # {Info} nodes contain a {Style} (or {Locale}) metadata. Their XML structure + # is based on the Atom Syndication Format. For independent styles an {Info} + # node typically has the following child elements: + # + # * {Author} and {Contributor}: used to respectively acknowledge + # style authors and contributors, may each be used multiple times. + # * {Category}: styles may be assigned one or more categories. One + # {Category} node may be used once to describe how in-text citations + # are rendered, using its citation-format attribute. + # * {Id}: Must appear once. The element should contain a URI to establish + # the identity of the style. A stable, unique and dereferenceable URI + # is desired for publicly available styles. + # * {Link}: Multiple links can be added to an {Info} node: self, + # documentation, and template links all have dedicated accessors. + # * {Title}: Must appear once. The contents of this node should be the + # name of the style as shown to users. + # * {TitleShort}: May appear once. The contents of this node should be a + # shortened style name (e.g. "APA"). + # * {Summary}: This node gives a description of the style. + # * {Rights}: This node specifies the license under which the style file + # is released. The element may carry a license attribute to specify the + # URI of the license. + # * {Updated}: Must appear once. This node must contain a timestamp that + # shows when the style was last updated. + # + # In dependent styles, the {Info} node must contain a {Link} with rel set + # to "independent-parent", with the URI of the independent parent style + # set on href. This link is also accessible as a string using the + # {#independent_parent} accessors. In addition, dependent styles should + # not contain template links. + # + # In a {Locale} node the {Info} node typically carries only {Translator}, + # {Rights} and {Updated} nodes. class Info < Node attr_children :title, :'title-short', :id, :issn, :eissn, :issnl, :link, :author, :contributor, :category, :published, :summary, :updated, :rights, :'link-dependent-style' - + alias_child :contributors, :contributor - alias_child :authors, :contributor + alias_child :authors, :author alias_child :links, :link - + alias_child :categories, :category + def initialize(attributes = {}) super(attributes, &nil) - children[:link] = [] + children[:link], children[:category] = [], [] yield self if block_given? end - + # @!attribute self_link # @return [String,nil] the style's URI # @!attribute template_link # @return [String,nil] URI of the style from which the current style is derived - + # @!attribute documentation_link # @return [String,nil] URI of style documentation - [:self, :template, :documentation].each do |type| - method_id = "#{type}_link" - + + # @!attribute independent_parent_link + # @return [String,nil] URI of independent-parent + %w{ self template documentation independent-parent }.each do |type| + method_id = "#{type.tr('-', '_')}_link" + define_method method_id do - link = links.detect { |l| l.match? :rel => type.to_s } + link = links.detect { |l| l.match? :rel => type } link.nil? ? nil : link[:href] end - + alias_method "has_#{method_id}?", method_id - + define_method "#{method_id}=" do |value| - link = links.detect { |l| l.match? :rel => type.to_s } - + link = links.detect { |l| l.match? :rel => type } + if link.nil? - set_child_link :href => value.to_s, :rel => type.to_s + set_child_link :href => value.to_s, :rel => type else link[:href] = value.to_s link end end end - + + # Ruby 1.8 still has Object#id methods so the attr_children generator + # has not created those; since #id is deprecated in 1.8.7 we're + # forcing the override anyway. Live dangerously! + + # @return [Id] the id text node def id children[:id] end - + alias id= set_child_id + # @return [Time,nil] when the info node's parent was last updated + def updated_at + return unless has_updated? + updated.to_time + end + # Sets the updated_at timestamp. + # @return [self] + def update!(timestamp = Time.now) + ts = timestamp.respond_to?(:xmlschema) ? timestamp.xmlschema : timestamp.to_s + + if has_updated? + updated = Updated.new { |u| u.text = ts } + else + updated.text = ts + end + + self + end + + # @return [Time,nil] when the info node's parent was published + def published_at + return unless has_published? + published.to_time + end + + # Sets the updated_at timestamp. + # @return [self] + def publish!(timestamp = Time.now) + ts = timestamp.respond_to?(:xmlschema) ? timestamp.xmlschema : timestamp.to_s + + if has_published? + published = Published.new { |u| u.text = ts } + else + published.text = ts + end + + self + end + + # @return [Symbol] the parent style's citation format + def citation_format + return unless has_categories? + + end + + def ciation_format=(new_format) + end + + # + # Info Child Nodes + # + class Contributor < Node attr_children :name, :email, :uri end - + class Author < Node attr_children :name, :email, :uri end - + class Translator < Node attr_children :name, :email, :uri end - + class Link < Node attr_struct :href, :rel + + # TODO xml:lang end class DependentStyle < TextNode attr_struct :href, :rel end class Category < Node attr_struct :field, :'citation-format' - end + end class Id < TextNode end - + class Name < TextNode end - + class Email < TextNode end + class URI < TextNode + end + class Title < TextNode + # TODO xml:lang end - class ShortTitle < TextNode + class TitleShort < TextNode + # TODO xml:lang end class Summary < TextNode + # TODO xml:lang end - + class Rights < TextNode + attr_struct :license + # TODO xml:lang end - class Uri < TextNode + class Updated < TextNode + + def to_time + return if empty? + Time.parse(to_s) + end + alias to_date to_time end - class Updated < TextNode + class Published < TextNode + def to_time + return if empty? + Time.parse(to_s) + end + alias to_date to_time end end - - + + end \ No newline at end of file