Class: Newstile::Converter::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/newstile/converter/base.rb

Overview

Base class for converters

This class serves as base class for all converters. It provides methods that can/should be used by all converters (like #generate_id) as well as common functionality that is automatically applied to the result (for example, embedding the output into a template).

Implementing a converter

Implementing a new converter is rather easy: just create a new sub class from this class and put it in the Newstile::Converter module (the latter is only needed if auto-detection should work properly). Then you need to implement the #convert(tree) method which takes a document tree and should return the converted output.

The document instance is automatically set as @doc in Base#initialize. Furthermore, the document instance provides a hash called ‘conversion_infos` that is also automatically cleared and can be used to store information about the conversion process.

The actual transformation of the document tree can be done in any way. However, writing one method per tree element type is a straight forward way to do it - this is how the Html and Latex converters do the transformation.

Direct Known Subclasses

Html, Latex, Markdown, Newstile

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(doc) ⇒ Base

Initialize the converter with the given Newstile document doc.



52
53
54
55
# File 'lib/newstile/converter/base.rb', line 52

def initialize(doc)
  @doc = doc
  @doc.conversion_infos.clear
end

Class Method Details

.apply_template(doc, body) ⇒ Object

Apply the template specified in the doc options, using body as the body string.



70
71
72
73
74
75
76
# File 'lib/newstile/converter/base.rb', line 70

def self.apply_template(doc, body)
  erb = ERB.new(get_template(doc.options[:template]))
  obj = Object.new
  obj.instance_variable_set(:@doc, doc)
  obj.instance_variable_set(:@body, body)
  erb.result(obj.instance_eval{binding})
end

.convert(doc) ⇒ Object

Convert the Newstile document doc to the output format implemented by a subclass.

Initializes a new instance of the calling class and then calls the #convert method that must be implemented by each subclass. If the template option is specified and non-empty, the result is rendered into the specified template.



63
64
65
66
67
# File 'lib/newstile/converter/base.rb', line 63

def self.convert(doc)
  result = new(doc).convert(doc.tree)
  result = apply_template(doc, result) if !doc.options[:template].empty?
  result
end

.get_template(template) ⇒ Object

Return the template specified by template.



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/newstile/converter/base.rb', line 79

def self.get_template(template)
  format_ext = '.' + self.name.split(/::/).last.downcase
  shipped = File.join(::Newstile.data_dir, template + format_ext)
  if File.exist?(template)
    File.read(template)
  elsif File.exist?(template + format_ext)
    File.read(template + format_ext)
  elsif File.exist?(shipped)
    File.read(shipped)
  else
    raise "The specified template file #{template} does not exist"
  end
end

Instance Method Details

#generate_id(str) ⇒ Object

Generate an unique alpha-numeric ID from the the string str for use as header ID.



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/newstile/converter/base.rb', line 95

def generate_id(str)
  gen_id = str.gsub(/[^a-zA-Z0-9 -]/, '').gsub(/^[^a-zA-Z]*/, '').gsub(' ', '-').downcase
  gen_id = 'section' if gen_id.length == 0
  @used_ids ||= {}
  if @used_ids.has_key?(gen_id)
    gen_id += '-' + (@used_ids[gen_id] += 1).to_s
  else
    @used_ids[gen_id] = 0
  end
  @doc.options[:auto_id_prefix] + gen_id
end