File: TjpExample.rb

package info (click to toggle)
tj3 3.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,048 kB
  • sloc: ruby: 36,481; javascript: 1,113; sh: 19; makefile: 17
file content (122 lines) | stat: -rw-r--r-- 3,628 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env ruby -w
# encoding: UTF-8
#
# = TjpExample.rb -- The TaskJuggler III Project Management Software
#
# Copyright (c) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
#               by Chris Schlaeger <cs@taskjuggler.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#

require 'stringio'

class TaskJuggler

  # This class can extract snippets from an annotated TJP syntax file. The file
  # does not care about the TJP syntax but the annotation lines must start with
  # a '#' character at the begining of the line. The snippets must be enclosed
  # by a starting line and an ending line. Each snippet must have a unique tag
  # that can be used to retrieve the specific snip.
  #
  # The following line starts a snip called 'foo':
  # # *** EXAMPLE: foo +
  #
  # The following line ends a snip called 'foo':
  # # *** EXAMPLE: foo -
  #
  # The function TjpExample#to_s() can be used to get the content of the snip.
  # It takes the tag name as optional parameter. If no tag is specified, the
  # full example without the annotation lines is returned.
  class TjpExample

    # Create a new TjpExample object.
    def initialize
      @snippets = { }
      # Here we will store the complete example.
      @snippets['full text'] = []
      @file = nil
    end

    # Use this function to process the file called _fileName_.
    def open(fileName)
      @file = File.open(fileName, 'r')
      process
      @file.close
    end

    # Use this function to process the String _text_.
    def parse(text)
      @file = StringIO.new(text)
      process
    end

    # This method returns the snip identified by _tag_.
    def to_s(tag = nil)
      tag = 'full text' unless tag
      return nil unless @snippets[tag]

      s = ''
      @snippets[tag].each { |l| s << l }
      s
    end

  private

    def process
      # This mark identifies the annotation lines.
      mark = '# *** EXAMPLE: '

      # We need this to remember what snippets are currently active.
      snippetState = { }
      # Now process the file or String line by line.
      @file.each_line do |line|
        if line[0, mark.length] == mark
          # We've found an annotation line. Get the tag and indicator.
          tokens = line.split
          tag = tokens[3]
          indicator = tokens[4]

          if indicator == '+'
            # Start a new snip
            if snippetState[tag]
              raise "Snippet #{tag} has already been started"
            end
            snippetState[tag] = true
          elsif indicator == '-'
            # Stop an existing snip
            unless snippetState[tag]
              raise "Snippet #{tag} has not yet been started"
            end
            snippetState[tag] = false
          else
            raise "Bad indicator #{indicator}. Must be '+' or '-': #{line}"
          end
        else
          # Process the regular lines and add them to all currently active
          # snippets.
          snippetState.each do |t, state|
            if state
              # Create a new snip buffer if it does not yet exist.
              @snippets[t] = [] unless @snippets[t]
              # Add the line.
              @snippets[t] << line
            end
          end
          # Add all lines to this buffer.
          @snippets['full text'] << line
        end
      end

      # Remove empty lines at end of all snips
      @snippets.each_value do |snip|
        snip.delete_at(-1) if snip[-1] == "\n"
      end
    end

  end

end