Class: Glyph::Document

Inherits:
Object
  • Object
show all
Defined in:
lib/glyph/document.rb

Overview

The Glyph::Document class stores information about a document or a chunk of text currently being interpreted.

It is responsible of analyzing (evaluating) the syntax tree and return the corresponding output as well as replacing placeholders.

Constant Summary collapse

ESCAPES =

A Regexp containing the characters to escape

/\\([\\\]\[\|\/=])/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tree, context = {}) ⇒ Document

Creates a new document

Parameters:

  • tree (GlyphSyntaxNode)

    the syntax tree to be evaluate

  • context (Glyph::Node) (defaults to: {})

    the context associated with the tree

Raises:

  • (RuntimeError)

    unless tree responds to :evaluate



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/glyph/document.rb', line 22

def initialize(tree, context={})
  @tree = tree
  @context = context
  @context[:source] ||= {:file => nil, :name => '--', :topic => nil}
  @placeholders = {}
  @bookmarks = {}
  @headers = {}
  @snippets = {}
  @fragments = {}
  @styles = []
  @errors = []
  @todos = []
  @topics = []
  @links = []
  @toc = {}
  @state = :new
end

Instance Attribute Details

#bookmarksObject (readonly)

Returns the value of attribute bookmarks



15
16
17
# File 'lib/glyph/document.rb', line 15

def bookmarks
  @bookmarks
end

#contextObject (readonly)

Returns the value of attribute context



15
16
17
# File 'lib/glyph/document.rb', line 15

def context
  @context
end

#errorsObject (readonly)

Returns the value of attribute errors



16
17
18
# File 'lib/glyph/document.rb', line 16

def errors
  @errors
end

#fragmentsObject (readonly)

Returns the value of attribute fragments



16
17
18
# File 'lib/glyph/document.rb', line 16

def fragments
  @fragments
end

#headersObject (readonly)

Returns the value of attribute headers



15
16
17
# File 'lib/glyph/document.rb', line 15

def headers
  @headers
end

Returns the value of attribute links



16
17
18
# File 'lib/glyph/document.rb', line 16

def links
  @links
end

#placeholdersObject (readonly)

Returns the value of attribute placeholders



15
16
17
# File 'lib/glyph/document.rb', line 15

def placeholders
  @placeholders
end

#snippetsObject (readonly)

Returns the value of attribute snippets



16
17
18
# File 'lib/glyph/document.rb', line 16

def snippets
  @snippets
end

#stylesObject (readonly)

Returns the value of attribute styles



15
16
17
# File 'lib/glyph/document.rb', line 15

def styles
  @styles
end

#tocObject (readonly)

Returns the value of attribute toc



16
17
18
# File 'lib/glyph/document.rb', line 16

def toc
  @toc
end

#todosObject (readonly)

Returns the value of attribute todos



16
17
18
# File 'lib/glyph/document.rb', line 16

def todos
  @todos
end

#topicsObject (readonly)

Returns the value of attribute topics



16
17
18
# File 'lib/glyph/document.rb', line 16

def topics
  @topics
end

Instance Method Details

#analyze:analyzed

Analyzes the document by evaluating its @tree

Returns:

  • (:analyzed)

Raises:

  • (RuntimeError)

    if the document is already analyzed or finalized



147
148
149
150
151
152
# File 'lib/glyph/document.rb', line 147

def analyze
  raise RuntimeError, "Document is #{@state}" if analyzed? || finalized?
  @context[:document] = self
  @output = @tree.evaluate @context
  @state = :analyzed
end

#analyzed?Boolean

Returns true if the document is analyzed, false otherwise

Returns:

  • (Boolean)

    Returns true if the document is analyzed, false otherwise



201
202
203
# File 'lib/glyph/document.rb', line 201

def analyzed?
  @state == :analyzed
end

#bookmark(hash) ⇒ Glyph::Bookmark

Returns the stored bookmark

Returns:

Raises:

  • (RuntimeError)

    if the bookmark is already defined.



88
89
90
91
92
93
# File 'lib/glyph/document.rb', line 88

def bookmark(hash)
  b = Glyph::Bookmark.new(hash)
  raise RuntimeError, "Bookmark '#{b.code}' already exists" if @bookmarks.has_key? b.code
  @bookmarks[b.code] = b
  b
end

#bookmark?(key) ⇒ Glyph::Bookmark?

Returns a stored bookmark or nil

Parameters:

  • key (#to_sym)

    the bookmark identifier

Returns:



79
80
81
# File 'lib/glyph/document.rb', line 79

def bookmark?(key)
  @bookmarks[key.to_sym]
end

#finalize:finalized

Finalizes the document by evaluating its @placeholders

Returns:

  • (:finalized)

Raises:

  • (RuntimeError)

    if the document the document has not been analyzed, if it is already finalized or if errors occurred during analysis



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/glyph/document.rb', line 158

def finalize
  raise RuntimeError, "Document has not been analyzed" unless analyzed?
  raise RuntimeError, "Document has already been finalized" if finalized?
  return (@state = :finalized) if @context[:embedded]
  raise RuntimeError, "Document cannot be finalized due to previous errors" unless @context[:document].errors.blank?
  # Substitute placeholders
  @placeholders.each_pair do |key, value| 
    begin
      key_s = key.to_s
      value_s = value.call(self).to_s
      toc[:contents].gsub! key_s, value_s rescue nil
      @topics.each do |t|
        t[:contents].gsub! key_s, value_s
      end
      @output.gsub! key_s, value_s
    rescue Glyph::MacroError => e
      e.macro.macro_warning e.message, e
    rescue Exception => e
      Glyph.warning e.message
    end
  end
  # Substitute escape sequences
  @output.gsub!(ESCAPES) { |match| ($1 == '/') ? '' : $1 }
  toc[:contents].gsub!(ESCAPES) { |match| ($1 == '/') ? '' : $1 } rescue nil
  @topics.each do |t|
    t[:contents].gsub!(ESCAPES) { |match| ($1 == '/') ? '' : $1 }
  end
  @state = :finalized
end

#finalized?Boolean

Returns true if the document is analyzed, false otherwise

Returns:

  • (Boolean)

    Returns true if the document is analyzed, false otherwise



206
207
208
# File 'lib/glyph/document.rb', line 206

def finalized?
  @state == :finalized
end

#header(hash) ⇒ Glyph::Header

Returns the stored header

Returns:

Raises:

  • (RuntimeError)

    if the bookmark is already defined.



100
101
102
103
104
105
106
# File 'lib/glyph/document.rb', line 100

def header(hash)
  b = Glyph::Header.new(hash)
  raise RuntimeError, "Bookmark '#{b.code}' already exists" if @bookmarks.has_key? b.code
  @bookmarks[b.code] = b
  @headers[b.code] = b
  b
end

#header?(key) ⇒ Glyph::Header?

Returns a stored header or nil

Parameters:

Returns:

  • (Glyph::Header, nil)

    the header or nil if no header is found



111
112
113
# File 'lib/glyph/document.rb', line 111

def header?(key)
  @headers[key.to_sym]
end

#inherit_from(document, data = {}) ⇒ Object

Copies bookmarks, headers, todos, styles and placeholders from another Glyph::Document

Examples:

Inheriting everything except topics

doc1.inherit_from doc2, :topics => false 

Parameters:

  • document (Glyph::Document)

    a valid Glyph::Document

  • data (Hash) (defaults to: {})

    specifies which data will be inherited (e.g. bookmarks, headers, …). By default, all data is inherited.



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/glyph/document.rb', line 53

def inherit_from(document, data={})
  @bookmarks = document.bookmarks unless data[:bookmarks] == false
  @headers = document.headers unless data[:headers] == false
  @snippets = document.snippets unless data[:snippets] == false
  @todos = document.todos unless data[:todos] == false
  @styles = document.styles unless data[:styles] == false
  @topics = document.topics unless data[:topics] == false
  @placeholders = document.placeholders unless data[:placeholders] == false
  @toc = document.toc unless data[:toc] == false
  @links = document.links unless data[:links] == false
  @fragments = document.fragments unless data[:fragments] == false
  self
end

#new?Boolean

Returns true if the document is new, false otherwise

Returns:

  • (Boolean)

    Returns true if the document is new, false otherwise



196
197
198
# File 'lib/glyph/document.rb', line 196

def new?
  @state == :new
end

#outputObject

Returns the document output

Raises:

  • (RuntimeError)

    unless the document is finalized.



190
191
192
193
# File 'lib/glyph/document.rb', line 190

def output
  raise RuntimeError, "Document is not finalized" unless finalized?
  @output
end

#placeholder(&block) ⇒ String

Defines a placeholder block that will be evaluated after the whole document has been analyzed

Parameters:

  • &block (Proc)

    a block taking the document itself as parameter

Returns:

  • (String)

    the placeholder key string



70
71
72
73
74
# File 'lib/glyph/document.rb', line 70

def placeholder(&block)
  key = "‡‡‡‡‡PLACEHOLDER¤#{@placeholders.length+1}‡‡‡‡‡".to_sym
  @placeholders[key] = block
  key
end

#snippet(key, value) ⇒ String

Stores a new snippet

Parameters:

  • key (Symbol, String)

    the snippet identifier

  • value (string)

    the snippet contents

Returns:

  • (String)

    the stored snippet

Since:

  • 0.5.0



120
121
122
# File 'lib/glyph/document.rb', line 120

def snippet(key, value)
  @snippets[key.to_sym] = value
end

#snippet?(key) ⇒ String?

Returns a stored snippet or nil

Parameters:

Returns:

  • (String, nil)

    the snippet contents or nil if no snippet is found

Since:

  • 0.5.0



128
129
130
# File 'lib/glyph/document.rb', line 128

def snippet?(key)
  @snippets[key.to_sym]
end

#structureObject

Returns a tree of Glyph::Node objects corresponding to the analyzed document

Raises:

  • (RuntimeError)

    unless the document has been analized



42
43
44
45
# File 'lib/glyph/document.rb', line 42

def structure
  raise RuntimeError, "Document has not been analyzed" unless analyzed? || finalized?
  @tree
end

#style(file) ⇒ Object

Stores a stylesheet

Parameters:

  • file (String)

    the stylesheet file

Raises:

  • (RuntimeError)

    if the stylesheet is already specified for the document (unless the output has more than one file)

Since:

  • 0.4.0



136
137
138
139
140
141
142
# File 'lib/glyph/document.rb', line 136

def style(file)
  f = Pathname.new file
  if @styles.include?(f) && !Glyph.multiple_output_files? then
    raise RuntimeError, "Stylesheet '#{f}' already specified for the current document" 
  end
  @styles << f
end