Class: TaskJuggler::SyntaxReference

Inherits:
Object
  • Object
show all
Defined in:
lib/taskjuggler/SyntaxReference.rb

Overview

This class can traverse the syntax rules of the ProjectFileParser and extract all documented keywords including their arguments and relations. All this work in done in the contructor. The documentation can then be generated for all found keyword or just a single one. Currently plain text output as well as HTML files are supported.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(manual = nil, ignoreOld = false) ⇒ SyntaxReference

The constructor is the most important function of this class. It creates a parser object and then traverses all rules and extracts the documented patterns. In a second pass the extracted KeywordDocumentation objects are then cross referenced to capture their relationships. manual is an optional reference to the UserManual object that uses this SyntaxReference.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/taskjuggler/SyntaxReference.rb', line 37

def initialize(manual = nil, ignoreOld = false)
  @manual = manual
  @parser = ProjectFileParser.new
  @parser.updateParserTables

  # This hash stores all documented keywords using the keyword as
  # index.
  @keywords = {}
  @parser.rules.each_value do |rule|
    rule.patterns.each do |pattern|
      #  Only patterns that are documented are of interest.
      next if pattern.doc.nil?
      # Ignore deprecated and removed keywords if requested
      next if ignoreOld &&
              [ :deprecated, :removed ].include?(pattern.supportLevel)

      # Make sure each keyword is unique.
      if @keywords.include?(pattern.keyword)
        raise "Multiple patterns have the same keyword #{pattern.keyword}"
      end

      argDocs = []
      # Create a new KeywordDocumentation object and fill-in all extracted
      # values.
      kwd = KeywordDocumentation.new(rule, pattern,
              pattern.to_syntax(argDocs, @parser.rules), argDocs,
              optionalAttributes(pattern, {}), @manual)
      @keywords[pattern.keyword] = kwd
    end
  end

  # Make sure all references to other keywords are present.
  @keywords.each_value do |kwd|
    kwd.crossReference(@keywords, @parser.rules)
  end

  # Figure out whether the keyword describes an inheritable attribute or
  # not.
  @keywords.each_value do |kwd|
    kwd.computeInheritance
  end
end

Instance Attribute Details

#keywordsObject (readonly)

Returns the value of attribute keywords.



29
30
31
# File 'lib/taskjuggler/SyntaxReference.rb', line 29

def keywords
  @keywords
end

Instance Method Details

#allObject

Return a sorted Array with all keywords (as String objects).



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/taskjuggler/SyntaxReference.rb', line 81

def all
  sorted = @keywords.keys.sort
  # Register the neighbours with each keyword so we can use this info in
  # navigation bars.
  pred = nil
  sorted.each do |kwd|
    keyword = @keywords[kwd]
    pred.successor = keyword if pred
    keyword.predecessor = pred
    pred = keyword
  end
end

#generateHTMLnavbar(directory, keywords) ⇒ Object

Generate 2 files named navbar.html and alphabet.html. They are used to support navigating through the syntax reference.



145
146
147
148
149
150
151
152
153
154
155
156
157
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/taskjuggler/SyntaxReference.rb', line 145

def generateHTMLnavbar(directory, keywords)
  html = HTMLDocument.new
  head = html.generateHead('TaskJuggler Syntax Reference Navigator')
  head << XMLElement.new('base', 'target' => 'display')
  html.html << (body = XMLElement.new('body'))

  body << XMLNamedText.new('Table Of Contents', 'a', 'href' => 'toc.html')
  body << XMLElement.new('br', {}, true)

  normalizedKeywords = {}
  keywords.each do |keyword|
    normalizedKeywords[@keywords[keyword].title] = keyword
  end
  letter = nil
  letters = []
  normalizedKeywords.keys.sort!.each do |normalized|
    if normalized[0, 1] != letter
      letter = normalized[0, 1]
      letters << letter
      body << (h = XMLElement.new('h3'))
      h << XMLNamedText.new(letter.upcase, 'a', 'name' => letter)
    end
    keyword = normalizedKeywords[normalized]
    body << XMLNamedText.new("#{normalized}", 'a',
                             'href' => "#{keyword}.html")
    body << XMLElement.new('br', {}, true)
  end

  html.write(directory + 'navbar.html')

  html = HTMLDocument.new
  head = html.generateHead('TaskJuggler Syntax Reference Navigator')
  head << XMLElement.new('base', 'target' => 'navigator')
  html.html << (body = XMLElement.new('body'))

  body << (divf = XMLElement.new('div'))
  divf << (form = XMLElement.new(
    'form', 'action' => 'http://www.google.com/search',
    'method' => "get", 'target' => '_blank', 'style' => 'margin:0'))
  form << XMLElement.new('input', 'type' => 'text',
                         'value' => '',
                         'maxlength' => '255',
                         'size' => '25',
                         'name' => 'q')
  form << XMLElement.new('input', 'type' => 'submit', 'value' => 'Search')
  form << XMLElement.new('input', 'type' => 'hidden',
                         'value' => 'taskjuggler.org/manual',
                         'name' => 'sitesearch')
  body << (h3 = XMLElement.new('h3'))

  letters.each do |l|
    h3 << XMLNamedText.new(l.upcase, 'a',
                           'href' => "navbar.html##{l}")
  end
  html.write(directory + 'alphabet.html')
end

#generateHTMLreference(directory, keyword) ⇒ Object

Generate a documentation for the keyword or an error message. The result is a XML String for known keywords. In case of an error the result is empty but an error message will be send to $stderr.



135
136
137
138
139
140
141
# File 'lib/taskjuggler/SyntaxReference.rb', line 135

def generateHTMLreference(directory, keyword)
  if checkKeyword(keyword)
    @keywords[keyword].generateHTML(directory)
  else
    ''
  end
end

#internalReferencesObject



112
113
114
115
116
117
118
119
# File 'lib/taskjuggler/SyntaxReference.rb', line 112

def internalReferences
  references = {}
  @keywords.each_value do |keyword|
    (refs = keyword.references.uniq).empty? ||
      references[keyword.keyword] = refs
  end
  references
end

#tableOfContents(toc, sectionPrefix) ⇒ Object

Generate entries for a TableOfContents for each of the keywords. The entries are appended to the TableOfContents toc. sectionPrefix is the prefix that is used for the chapter numbers. In case we have 20 keywords and sectionPrefix is ‘A’, the keywords will be enumerated ‘A.1’ to ‘A.20’.



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/taskjuggler/SyntaxReference.rb', line 99

def tableOfContents(toc, sectionPrefix)
  keywords = all
  # Set the chapter name to 'Syntax Reference' with a link to the first
  # keyword.
  toc.addEntry(TOCEntry.new(sectionPrefix, 'Syntax Reference', keywords[0]))
  i = 1
  keywords.each do |keyword|
    title = @keywords[keyword].title
    toc.addEntry(TOCEntry.new("#{sectionPrefix}.#{i}", title, keyword))
    i += 1
  end
end

#to_s(keyword) ⇒ Object

Generate a documentation for the keyword or an error message. The result is a multi-line plain text String for known keywords. In case of an error the result is empty but an error message will be send to $stderr.



124
125
126
127
128
129
130
# File 'lib/taskjuggler/SyntaxReference.rb', line 124

def to_s(keyword)
  if checkKeyword(keyword)
    @keywords[keyword].to_s
  else
    ''
  end
end