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
|