taskjuggler 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +30 -0
- data/README.rdoc +1 -0
- data/data/tjp.vim +13 -9
- data/lib/taskjuggler/Allocation.rb +2 -2
- data/lib/taskjuggler/AttributeBase.rb +10 -0
- data/lib/taskjuggler/Attributes.rb +2 -8
- data/lib/taskjuggler/Journal.rb +20 -19
- data/lib/taskjuggler/PTNProxy.rb +14 -1
- data/lib/taskjuggler/ProjectFileParser.rb +3 -0
- data/lib/taskjuggler/ProjectFileScanner.rb +54 -44
- data/lib/taskjuggler/PropertyList.rb +32 -0
- data/lib/taskjuggler/PropertyTreeNode.rb +4 -0
- data/lib/taskjuggler/ResourceScenario.rb +53 -20
- data/lib/taskjuggler/RichText/Document.rb +7 -5
- data/lib/taskjuggler/RichText/Scanner.rb +38 -38
- data/lib/taskjuggler/RichText/TOCEntry.rb +1 -1
- data/lib/taskjuggler/TaskScenario.rb +78 -62
- data/lib/taskjuggler/TextParser.rb +4 -3
- data/lib/taskjuggler/TextParser/MacroTable.rb +3 -1
- data/lib/taskjuggler/TextParser/Scanner.rb +73 -58
- data/lib/taskjuggler/Tj3Config.rb +1 -1
- data/lib/taskjuggler/TjpSyntaxRules.rb +215 -67
- data/lib/taskjuggler/apps/Tj3Client.rb +1 -1
- data/lib/taskjuggler/daemon/ReportServer.rb +8 -1
- data/lib/taskjuggler/reports/ExportRE.rb +46 -0
- data/lib/taskjuggler/reports/MspXmlRE.rb +409 -0
- data/lib/taskjuggler/reports/Report.rb +29 -4
- data/lib/taskjuggler/reports/ReportBase.rb +0 -8
- data/lib/taskjuggler/reports/TableReport.rb +13 -3
- data/lib/taskjuggler/reports/TaskListRE.rb +1 -0
- data/lib/taskjuggler/reports/TjpExportRE.rb +1 -1
- data/manual/Rich_Text_Attributes +2 -2
- data/manual/Tutorial +15 -11
- data/manual/html/Day_To_Day_Juggling.html +1 -1
- data/manual/html/Getting_Started.html +1 -1
- data/manual/html/How_To_Contribute.html +1 -1
- data/manual/html/Installation.html +1 -1
- data/manual/html/Intro.html +1 -1
- data/manual/html/Reporting_Bugs.html +1 -1
- data/manual/html/Rich_Text_Attributes.html +1 -1
- data/manual/html/Software.html +1 -1
- data/manual/html/TaskJuggler_2x_Migration.html +1 -1
- data/manual/html/TaskJuggler_Internals.html +1 -1
- data/manual/html/The_TaskJuggler_Syntax.html +1 -1
- data/manual/html/Tutorial.html +5 -2
- data/manual/html/account.html +1 -1
- data/manual/html/account.task.html +1 -1
- data/manual/html/accountprefix.html +1 -1
- data/manual/html/accountreport.html +9 -3
- data/manual/html/accountroot.html +1 -1
- data/manual/html/active.html +1 -1
- data/manual/html/adopt.task.html +3 -3
- data/manual/html/aggregate.html +1 -1
- data/manual/html/alert.html +1 -1
- data/manual/html/alertlevels.html +1 -1
- data/manual/html/allocate.html +5 -2
- data/manual/html/alphabet.html +1 -1
- data/manual/html/alternative.html +1 -1
- data/manual/html/author.html +1 -1
- data/manual/html/balance.html +1 -1
- data/manual/html/booking.resource.html +1 -1
- data/manual/html/booking.task.html +1 -1
- data/manual/html/caption.html +1 -1
- data/manual/html/cellcolor.column.html +1 -1
- data/manual/html/celltext.column.html +43 -4
- data/manual/html/center.html +1 -1
- data/manual/html/charge.html +1 -1
- data/manual/html/chargeset.html +2 -2
- data/manual/html/columnid.html +6 -6
- data/manual/html/columns.html +1 -1
- data/manual/html/complete.html +1 -1
- data/manual/html/copyright.html +1 -1
- data/manual/html/credits.html +1 -1
- data/manual/html/currency.html +1 -1
- data/manual/html/currencyformat.html +1 -1
- data/manual/html/dailymax.html +1 -1
- data/manual/html/dailymin.html +1 -1
- data/manual/html/dailyworkinghours.html +1 -1
- data/manual/html/date.extend.html +1 -1
- data/manual/html/date.html +2 -2
- data/manual/html/definitions.html +1 -1
- data/manual/html/depends.html +1 -1
- data/manual/html/details.html +1 -1
- data/manual/html/disabled.html +1 -1
- data/manual/html/duration.html +1 -1
- data/manual/html/efficiency.html +1 -1
- data/manual/html/effort.html +1 -1
- data/manual/html/email.html +1 -1
- data/manual/html/enabled.html +1 -1
- data/manual/html/end.column.html +1 -1
- data/manual/html/end.html +1 -1
- data/manual/html/end.limit.html +1 -1
- data/manual/html/end.report.html +9 -3
- data/manual/html/end.timesheet.html +1 -1
- data/manual/html/endcredit.html +1 -1
- data/manual/html/epilog.html +1 -1
- data/manual/html/export.html +73 -5
- data/manual/html/extend.html +1 -1
- data/manual/html/fail.html +1 -1
- data/manual/html/fdl.html +1 -1
- data/manual/html/flags.account.html +1 -1
- data/manual/html/flags.html +1 -1
- data/manual/html/flags.journalentry.html +1 -1
- data/manual/html/flags.report.html +1 -1
- data/manual/html/flags.resource.html +1 -1
- data/manual/html/flags.statussheet.html +1 -1
- data/manual/html/flags.task.html +1 -1
- data/manual/html/flags.timesheet.html +1 -1
- data/manual/html/fontcolor.column.html +1 -1
- data/manual/html/footer.html +1 -1
- data/manual/html/formats.export.html +72 -0
- data/manual/html/formats.html +3 -3
- data/manual/html/functions.html +3 -3
- data/manual/html/gapduration.html +2 -2
- data/manual/html/gaplength.html +1 -1
- data/manual/html/halign.center.html +1 -1
- data/manual/html/halign.column.html +1 -1
- data/manual/html/halign.left.html +1 -1
- data/manual/html/halign.right.html +1 -1
- data/manual/html/hasalert.html +1 -1
- data/manual/html/header.html +1 -1
- data/manual/html/headline.html +1 -1
- data/manual/html/height.html +1 -1
- data/manual/html/hideaccount.html +1 -1
- data/manual/html/hidejournalentry.html +1 -1
- data/manual/html/hidereport.html +1 -1
- data/manual/html/hideresource.html +1 -1
- data/manual/html/hidetask.html +1 -1
- data/manual/html/icalreport.html +1 -1
- data/manual/html/include.macro.html +1 -1
- data/manual/html/include.project.html +1 -1
- data/manual/html/include.properties.html +1 -1
- data/manual/html/index.html +1 -1
- data/manual/html/inherit.extend.html +1 -1
- data/manual/html/interval1.html +2 -2
- data/manual/html/interval2.html +2 -2
- data/manual/html/interval3.html +2 -2
- data/manual/html/interval4.html +2 -2
- data/manual/html/isactive.html +1 -1
- data/manual/html/ischildof.html +1 -1
- data/manual/html/isdependencyof.html +1 -1
- data/manual/html/isdutyof.html +1 -1
- data/manual/html/isfeatureof.html +1 -1
- data/manual/html/isleaf.html +1 -1
- data/manual/html/ismilestone.html +1 -1
- data/manual/html/isongoing.html +1 -1
- data/manual/html/isresource.html +1 -1
- data/manual/html/isresponsibilityof.html +1 -1
- data/manual/html/istask.html +1 -1
- data/manual/html/journalattributes.html +1 -1
- data/manual/html/journalentry.html +1 -1
- data/manual/html/journalmode.html +11 -3
- data/manual/html/leaveallowance.html +1 -1
- data/manual/html/leaves.html +1 -1
- data/manual/html/left.html +1 -1
- data/manual/html/length.html +1 -1
- data/manual/html/limits.allocate.html +1 -1
- data/manual/html/limits.html +1 -1
- data/manual/html/limits.resource.html +1 -1
- data/manual/html/limits.task.html +1 -1
- data/manual/html/listitem.column.html +1 -1
- data/manual/html/listtype.column.html +1 -1
- data/manual/html/loadunit.html +2 -2
- data/manual/html/logicalexpression.html +1 -1
- data/manual/html/logicalflagexpression.html +1 -1
- data/manual/html/macro.html +1 -1
- data/manual/html/managers.html +1 -1
- data/manual/html/mandatory.html +1 -1
- data/manual/html/maxend.html +1 -1
- data/manual/html/maximum.html +1 -1
- data/manual/html/maxstart.html +1 -1
- data/manual/html/milestone.html +1 -1
- data/manual/html/minend.html +1 -1
- data/manual/html/minimum.html +1 -1
- data/manual/html/minstart.html +1 -1
- data/manual/html/monthlymax.html +1 -1
- data/manual/html/monthlymin.html +1 -1
- data/manual/html/navbar.html +5 -1
- data/manual/html/navigator.html +1 -1
- data/manual/html/newtask.html +1 -1
- data/manual/html/nikureport.html +1 -1
- data/manual/html/note.task.html +1 -1
- data/manual/html/now.html +1 -1
- data/manual/html/numberformat.html +1 -1
- data/manual/html/onend.html +1 -1
- data/manual/html/onstart.html +1 -1
- data/manual/html/opennodes.html +1 -1
- data/manual/html/overtime.booking.html +1 -1
- data/manual/html/period.column.html +1 -1
- data/manual/html/period.limit.html +1 -1
- data/manual/html/period.report.html +1 -1
- data/manual/html/period.task.html +1 -1
- data/manual/html/persistent.html +1 -1
- data/manual/html/precedes.html +1 -1
- data/manual/html/priority.html +1 -1
- data/manual/html/priority.timesheet.html +1 -1
- data/manual/html/project.html +1 -1
- data/manual/html/projectid.html +1 -1
- data/manual/html/projectid.task.html +1 -1
- data/manual/html/projectids.html +1 -1
- data/manual/html/projection.html +1 -1
- data/manual/html/prolog.html +1 -1
- data/manual/html/properties.html +1 -1
- data/manual/html/purge.html +8 -5
- data/manual/html/rate.html +1 -1
- data/manual/html/rate.resource.html +1 -1
- data/manual/html/reference.extend.html +1 -1
- data/manual/html/remaining.html +1 -1
- data/manual/html/replace.html +1 -1
- data/manual/html/reportprefix.html +1 -1
- data/manual/html/resource.html +1 -1
- data/manual/html/resourceattributes.html +1 -1
- data/manual/html/resourceprefix.html +1 -1
- data/manual/html/resourcereport.html +9 -3
- data/manual/html/resourceroot.html +1 -1
- data/manual/html/resources.limit.html +1 -1
- data/manual/html/responsible.html +1 -1
- data/manual/html/richtext.extend.html +1 -1
- data/manual/html/right.html +1 -1
- data/manual/html/rollupaccount.html +1 -1
- data/manual/html/rollupresource.html +1 -1
- data/manual/html/rolluptask.html +1 -1
- data/manual/html/scale.column.html +1 -1
- data/manual/html/scenario.html +1 -1
- data/manual/html/scenario.ical.html +1 -1
- data/manual/html/scenarios.export.html +1 -1
- data/manual/html/scenarios.html +1 -1
- data/manual/html/scenariospecific.extend.html +1 -1
- data/manual/html/scheduled.html +2 -2
- data/manual/html/scheduling.html +1 -1
- data/manual/html/select.html +1 -1
- data/manual/html/selfcontained.html +1 -1
- data/manual/html/shift.allocate.html +1 -1
- data/manual/html/shift.html +1 -1
- data/manual/html/shift.resource.html +1 -1
- data/manual/html/shift.task.html +1 -1
- data/manual/html/shift.timesheet.html +1 -1
- data/manual/html/shifts.allocate.html +1 -1
- data/manual/html/shifts.resource.html +1 -1
- data/manual/html/shifts.task.html +1 -1
- data/manual/html/shorttimeformat.html +1 -1
- data/manual/html/sloppy.booking.html +1 -1
- data/manual/html/sloppy.projection.html +1 -1
- data/manual/html/sortaccounts.html +1 -1
- data/manual/html/sortjournalentries.html +1 -1
- data/manual/html/sortresources.html +1 -1
- data/manual/html/sorttasks.html +1 -1
- data/manual/html/start.column.html +1 -1
- data/manual/html/start.html +1 -1
- data/manual/html/start.limit.html +1 -1
- data/manual/html/start.report.html +1 -1
- data/manual/html/startcredit.html +1 -1
- data/manual/html/status.statussheet.html +1 -1
- data/manual/html/status.timesheet.html +1 -1
- data/manual/html/statussheet.html +1 -1
- data/manual/html/statussheetreport.html +1 -1
- data/manual/html/strict.projection.html +1 -1
- data/manual/html/summary.html +1 -1
- data/manual/html/supplement.html +1 -1
- data/manual/html/supplement.resource.html +1 -1
- data/manual/html/supplement.task.html +1 -1
- data/manual/html/tagfile.html +1 -1
- data/manual/html/task.html +1 -1
- data/manual/html/task.statussheet.html +1 -1
- data/manual/html/task.timesheet.html +1 -1
- data/manual/html/taskattributes.html +1 -1
- data/manual/html/taskprefix.html +1 -1
- data/manual/html/taskreport.html +9 -3
- data/manual/html/taskroot.export.html +104 -0
- data/manual/html/taskroot.html +3 -3
- data/manual/html/text.extend.html +3 -3
- data/manual/html/textreport.html +9 -3
- data/manual/html/timeformat.html +1 -1
- data/manual/html/timeoff.nikureport.html +1 -1
- data/manual/html/timesheet.html +1 -1
- data/manual/html/timesheetreport.html +1 -1
- data/manual/html/timezone.export.html +1 -1
- data/manual/html/timezone.html +1 -1
- data/manual/html/timezone.report.html +1 -1
- data/manual/html/timezone.shift.html +1 -1
- data/manual/html/timingresolution.html +1 -1
- data/manual/html/title.column.html +1 -1
- data/manual/html/title.html +1 -1
- data/manual/html/toc.html +203 -189
- data/manual/html/tooltip.column.html +1 -1
- data/manual/html/tracereport.html +9 -3
- data/manual/html/trackingscenario.html +1 -1
- data/manual/html/treelevel.html +1 -1
- data/manual/html/vacation.html +1 -1
- data/manual/html/vacation.resource.html +1 -1
- data/manual/html/vacation.shift.html +1 -1
- data/manual/html/warn.html +1 -1
- data/manual/html/weeklymax.html +1 -1
- data/manual/html/weeklymin.html +1 -1
- data/manual/html/weekstartsmonday.html +1 -1
- data/manual/html/weekstartssunday.html +1 -1
- data/manual/html/width.column.html +1 -1
- data/manual/html/width.html +1 -1
- data/manual/html/work.html +1 -1
- data/manual/html/workinghours.project.html +1 -1
- data/manual/html/workinghours.resource.html +1 -1
- data/manual/html/workinghours.shift.html +1 -1
- data/manual/html/yearlyworkingdays.html +1 -1
- data/test/TestSuite/CSV-Reports/project-1.tji +0 -6
- data/test/TestSuite/CSV-Reports/refs/alert.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/celltext.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/resourcereport_with_tasks.csv +0 -3
- data/test/TestSuite/CSV-Reports/refs/sortByTree.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/sortBy_duration.down.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/sortBy_effort.up.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/sortBy_plan.start.down.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/taskreport.csv +0 -7
- data/test/TestSuite/CSV-Reports/refs/taskreport_with_resources.csv +0 -18
- data/test/TestSuite/CSV-Reports/refs/weekly.csv +0 -1
- data/test/TestSuite/HTML-Reports/Alerts-2.tjp +46 -0
- data/test/TestSuite/Scheduler/Correct/purge.tjp +30 -0
- data/test/TestSuite/Syntax/Correct/Export.tjp +8 -2
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +0 -1
- metadata +16 -10
- data/test/TestSuite/CSV-Reports/refs/taskcounter.csv +0 -9
@@ -339,7 +339,8 @@ class TaskJuggler
|
|
339
339
|
# the syntax rules.
|
340
340
|
error("no_reduce",
|
341
341
|
"Unexpected token '#{token[1]}' found. " +
|
342
|
-
"Expecting
|
342
|
+
"Expecting #{@stack.last.state.expectedTokens.length > 1 ?
|
343
|
+
'one of ' : ''}" +
|
343
344
|
"#{@stack.last.state.expectedTokens.join(', ')}",
|
344
345
|
@scanner.sourceFileInfo)
|
345
346
|
end
|
@@ -428,8 +429,8 @@ class TaskJuggler
|
|
428
429
|
end
|
429
430
|
end
|
430
431
|
end
|
431
|
-
|
432
|
-
|
432
|
+
puts " -> #{sl.state ? sl.state.to_s(true) : 'nil'}" +
|
433
|
+
"#{sl.function.nil? ? '' : '(Called)'}"
|
433
434
|
end
|
434
435
|
end
|
435
436
|
|
@@ -62,9 +62,11 @@ class TaskJuggler::TextParser
|
|
62
62
|
resolved = @macros[name].value.dup
|
63
63
|
i = 0
|
64
64
|
args.each do |arg|
|
65
|
-
resolved.gsub!("
|
65
|
+
resolved.gsub!(Regexp.new("(([^$]|^))\\$\\{#{i}\\}"), "\\1#{arg}")
|
66
66
|
i += 1
|
67
67
|
end
|
68
|
+
# Remove the escape character from all the escaped '${...}'.
|
69
|
+
resolved.gsub!('$${', '${')
|
68
70
|
[ @macros[name], resolved ]
|
69
71
|
end
|
70
72
|
|
@@ -84,12 +84,11 @@ class TaskJuggler::TextParser
|
|
84
84
|
@line = preCall + text + @scanner.post_match
|
85
85
|
# Start the StringScanner again at the first character of the injected
|
86
86
|
# text.
|
87
|
-
@scanner =
|
87
|
+
@scanner.string = @line
|
88
88
|
@scanner.pos = preCall.bytesize
|
89
89
|
end
|
90
90
|
|
91
91
|
def injectMacro(macro, args, text, callLength)
|
92
|
-
# We add 3 chars more for the ${}.
|
93
92
|
injectText(text, callLength)
|
94
93
|
|
95
94
|
# Simple detection for recursive macro calls.
|
@@ -99,7 +98,7 @@ class TaskJuggler::TextParser
|
|
99
98
|
true
|
100
99
|
end
|
101
100
|
|
102
|
-
def
|
101
|
+
def readyNextLine
|
103
102
|
# We read the file line by line with gets(). If we don't have a line
|
104
103
|
# yet or we've reached the end of a line, we get the next one.
|
105
104
|
if @scanner.nil? || @scanner.eos?
|
@@ -109,15 +108,20 @@ class TaskJuggler::TextParser
|
|
109
108
|
else
|
110
109
|
# We've reached the end of the current file.
|
111
110
|
@scanner = nil
|
112
|
-
|
113
|
-
return :scannerEOF
|
111
|
+
return false
|
114
112
|
end
|
115
113
|
@scanner = StringScanner.new(@line)
|
116
114
|
@wrapped = @line[-1] == ?\n
|
117
115
|
end
|
118
|
-
return nil if (token = @scanner.scan(re)).nil?
|
119
|
-
#puts "#{re.to_s[0..20]}: [#{token}]"
|
120
116
|
|
117
|
+
true
|
118
|
+
end
|
119
|
+
|
120
|
+
def scan(re)
|
121
|
+
@scanner.scan(re)
|
122
|
+
end
|
123
|
+
|
124
|
+
def cleanupMacroStack
|
121
125
|
if @nextMacroEnd
|
122
126
|
pos = @scanner.pos
|
123
127
|
while @nextMacroEnd && @nextMacroEnd < pos
|
@@ -125,8 +129,6 @@ class TaskJuggler::TextParser
|
|
125
129
|
@nextMacroEnd = @macroStack.empty? ? nil : @macroStack.last.endPos
|
126
130
|
end
|
127
131
|
end
|
128
|
-
|
129
|
-
token
|
130
132
|
end
|
131
133
|
|
132
134
|
def peek(n)
|
@@ -240,9 +242,9 @@ class TaskJuggler::TextParser
|
|
240
242
|
tokenPatterns.each do |pat|
|
241
243
|
type = pat[0]
|
242
244
|
regExp = pat[1]
|
243
|
-
mode = pat[
|
244
|
-
postProc = pat[
|
245
|
-
addPattern(type, regExp, mode, postProc)
|
245
|
+
mode = pat[3] || :tjp
|
246
|
+
postProc = pat[4]
|
247
|
+
addPattern(type, Regexp.new(regExp), mode, postProc)
|
246
248
|
end
|
247
249
|
self.mode = defaultMode
|
248
250
|
end
|
@@ -415,52 +417,7 @@ class TaskJuggler::TextParser
|
|
415
417
|
end
|
416
418
|
end
|
417
419
|
|
418
|
-
|
419
|
-
@startOfToken = sourceFileInfo
|
420
|
-
loop do
|
421
|
-
match = nil
|
422
|
-
begin
|
423
|
-
@activePatterns.each do |type, re, postProc|
|
424
|
-
if (match = @cf.scan(re))
|
425
|
-
if match == :scannerEOF
|
426
|
-
if @scannerMode != @defaultMode
|
427
|
-
# The stream resets the line number to 1. Since we still
|
428
|
-
# know the start of the token, we setup @lineDelta so that
|
429
|
-
# sourceFileInfo() returns the proper line number.
|
430
|
-
@lineDelta = -(@startOfToken.lineNo - 1)
|
431
|
-
error('runaway_token',
|
432
|
-
"Unterminated token starting at #{@startOfToken}")
|
433
|
-
end
|
434
|
-
# We've found the end of an input file. Return a special token
|
435
|
-
# that describes the end of a file.
|
436
|
-
@finishLastFile = true
|
437
|
-
return [ :eof, '<END>', @startOfToken ]
|
438
|
-
end
|
439
|
-
|
440
|
-
raise "#{re} matches empty string" if match.empty?
|
441
|
-
# If we have a post processing method, call it now. It may modify
|
442
|
-
# the type or the found token String.
|
443
|
-
type, match = postProc.call(type, match) if postProc
|
444
|
-
|
445
|
-
break if type.nil? # Ignore certain tokens with nil type.
|
446
|
-
|
447
|
-
return [ type, match, @startOfToken ]
|
448
|
-
end
|
449
|
-
end
|
450
|
-
rescue ArgumentError
|
451
|
-
error('scan_encoding_error', $!.to_s)
|
452
|
-
end
|
453
|
-
|
454
|
-
if match.nil?
|
455
|
-
if @cf.eof?
|
456
|
-
error('unexpected_eof',
|
457
|
-
"Unexpected end of file found")
|
458
|
-
else
|
459
|
-
error('no_token_match',
|
460
|
-
"Unexpected characters found: '#{@cf.peek(10)}...'")
|
461
|
-
end
|
462
|
-
end
|
463
|
-
end
|
420
|
+
scanToken
|
464
421
|
end
|
465
422
|
|
466
423
|
# Return a token to retrieve it with the next nextToken() call again. Only 1
|
@@ -515,6 +472,64 @@ class TaskJuggler::TextParser
|
|
515
472
|
|
516
473
|
private
|
517
474
|
|
475
|
+
def scanToken
|
476
|
+
@startOfToken = sourceFileInfo
|
477
|
+
begin
|
478
|
+
match = nil
|
479
|
+
loop do
|
480
|
+
# First make sure that the line buffer has been filled and we have a
|
481
|
+
# line to parse.
|
482
|
+
unless @cf.readyNextLine
|
483
|
+
if @scannerMode != @defaultMode
|
484
|
+
# The stream resets the line number to 1. Since we still
|
485
|
+
# know the start of the token, we setup @lineDelta so that
|
486
|
+
# sourceFileInfo() returns the proper line number.
|
487
|
+
@lineDelta = -(@startOfToken.lineNo - 1)
|
488
|
+
error('runaway_token',
|
489
|
+
"Unterminated token starting at line #{@startOfToken}")
|
490
|
+
end
|
491
|
+
# We've found the end of an input file. Return a special token
|
492
|
+
# that describes the end of a file.
|
493
|
+
@finishLastFile = true
|
494
|
+
return [ :eof, '<END>', @startOfToken ]
|
495
|
+
end
|
496
|
+
|
497
|
+
@activePatterns.each do |type, re, postProc|
|
498
|
+
if (match = @cf.scan(re))
|
499
|
+
#raise "#{re} matches empty string" if match.empty?
|
500
|
+
# If we have a post processing method, call it now. It may modify
|
501
|
+
# the type or the found token String.
|
502
|
+
type, match = postProc.call(type, match) if postProc
|
503
|
+
|
504
|
+
break if type.nil? # Ignore certain tokens with nil type.
|
505
|
+
|
506
|
+
@cf.cleanupMacroStack
|
507
|
+
return [ type, match, @startOfToken ]
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
if match.nil?
|
512
|
+
# If we haven't found a match, we either hit EOF or a token we did
|
513
|
+
# not expect.
|
514
|
+
if @cf.eof?
|
515
|
+
error('unexpected_eof',
|
516
|
+
"Unexpected end of file found")
|
517
|
+
else
|
518
|
+
error('no_token_match',
|
519
|
+
"Unexpected characters found: '#{@cf.peek(10)}...'")
|
520
|
+
end
|
521
|
+
else
|
522
|
+
# Remove completely scanned expanded macros from stack.
|
523
|
+
@cf.cleanupMacroStack
|
524
|
+
end
|
525
|
+
end
|
526
|
+
rescue ArgumentError
|
527
|
+
# This is triggered by StringScanner.scan, but we don't want to put
|
528
|
+
# the block in the inner loops for performance reasons.
|
529
|
+
error('scan_encoding_error', $!.to_s)
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
518
533
|
def message(type, id, text, sfi, data)
|
519
534
|
unless text.empty?
|
520
535
|
line = @cf ? @cf.line : nil
|
@@ -14,7 +14,7 @@
|
|
14
14
|
require 'taskjuggler/UTF8String'
|
15
15
|
require 'taskjuggler/AppConfig'
|
16
16
|
|
17
|
-
AppConfig.version = '3.
|
17
|
+
AppConfig.version = '3.3.0'
|
18
18
|
AppConfig.packageName = 'taskjuggler'
|
19
19
|
AppConfig.softwareName = 'TaskJuggler'
|
20
20
|
AppConfig.packageInfo = 'A Project Management Software'
|
@@ -247,6 +247,11 @@ exactly it will be assigned to the task. Shifts and limits can be used to
|
|
247
247
|
restrict the allocation to certain time intervals or to limit them to a
|
248
248
|
certain maximum per time period. The purge statement can be used to remove
|
249
249
|
inherited allocations or flags.
|
250
|
+
|
251
|
+
For effort-based tasks the task duration is clipped to only extend from the
|
252
|
+
begining of the first allocation to the end of the last allocation. This is
|
253
|
+
done to optimize for an overall minimum project duration as dependent tasks
|
254
|
+
can potentially use the unallocated, clipped slots.
|
250
255
|
EOT
|
251
256
|
)
|
252
257
|
example('Allocate-1', '1')
|
@@ -611,7 +616,7 @@ consists of one or more accounts. Each account must be a leaf account. The
|
|
611
616
|
account ID may be followed by a percentage value that determines the share for
|
612
617
|
this account. The total percentage of all accounts must be exactly 100%. If
|
613
618
|
some accounts don't have a percentage specification, the remainder to 100% is
|
614
|
-
distributed evenly
|
619
|
+
distributed evenly between them.
|
615
620
|
EOT
|
616
621
|
)
|
617
622
|
end
|
@@ -731,7 +736,7 @@ which cells the text should be used. If multiple celltext patterns are
|
|
731
736
|
provided for a column, the first matching one is taken for each cell.
|
732
737
|
EOT
|
733
738
|
)
|
734
|
-
arg(
|
739
|
+
arg(2, 'text',
|
735
740
|
'Alterntive cell text specified as [[Rich_Text_Attributes|Rich Text]]')
|
736
741
|
|
737
742
|
pattern(%w( _cellcolor !logicalExpression !color ), lambda {
|
@@ -1012,7 +1017,7 @@ EOT
|
|
1012
1017
|
|
1013
1018
|
def rule_export
|
1014
1019
|
pattern(%w( !exportHeader !exportBody ), lambda {
|
1015
|
-
@property =
|
1020
|
+
@property = @property.parent
|
1016
1021
|
})
|
1017
1022
|
doc('export', <<'EOT'
|
1018
1023
|
The export report looks like a regular TaskJuggler file with the provided
|
@@ -1033,30 +1038,6 @@ EOT
|
|
1033
1038
|
example('Export')
|
1034
1039
|
end
|
1035
1040
|
|
1036
|
-
def rule_exportHeader
|
1037
|
-
pattern(%w( _export !optionalID $STRING ), lambda {
|
1038
|
-
newReport(@val[1], @val[2], :export, @sourceFileInfo[0])
|
1039
|
-
@property.set('formats', [ :tjp ])
|
1040
|
-
|
1041
|
-
# By default, we export all scenarios.
|
1042
|
-
scenarios = Array.new(@project.scenarios.items) { |i| i }
|
1043
|
-
scenarios.delete_if { |sc| !@project.scenario(sc).get('active') }
|
1044
|
-
@property.set('scenarios', scenarios)
|
1045
|
-
# Show all tasks, sorted by seqno-up.
|
1046
|
-
@property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
|
1047
|
-
@property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
|
1048
|
-
# Show all resources, sorted by seqno-up.
|
1049
|
-
@property.set('hideResource',
|
1050
|
-
LogicalExpression.new(LogicalOperation.new(0)))
|
1051
|
-
@property.set('sortResources', [ [ 'seqno', true, -1 ] ])
|
1052
|
-
})
|
1053
|
-
arg(2, 'file name', <<'EOT'
|
1054
|
-
The name of the report file to generate. It must end with a .tjp or .tji
|
1055
|
-
extension, or use . to use the standard output channel.
|
1056
|
-
EOT
|
1057
|
-
)
|
1058
|
-
end
|
1059
|
-
|
1060
1041
|
def rule_exportAttributes
|
1061
1042
|
optional
|
1062
1043
|
repeatable
|
@@ -1078,10 +1059,26 @@ EOT
|
|
1078
1059
|
'projecids' => 'Include project IDs',
|
1079
1060
|
'tasks' => 'Include task definitions',
|
1080
1061
|
'resources' => 'Include resource definitions' })
|
1062
|
+
|
1063
|
+
pattern(%w( _formats !exportFormats ), lambda {
|
1064
|
+
@property.set('formats', @val[1])
|
1065
|
+
})
|
1066
|
+
level(:beta)
|
1067
|
+
doc('formats.export', <<'EOT'
|
1068
|
+
This attribute defines for which output formats the export report should be
|
1069
|
+
generated. By default, the TJP format will be used.
|
1070
|
+
EOT
|
1071
|
+
)
|
1072
|
+
|
1081
1073
|
pattern(%w( !hideresource ))
|
1082
1074
|
pattern(%w( !hidetask ))
|
1075
|
+
|
1076
|
+
pattern(%w( !loadunit ))
|
1077
|
+
|
1078
|
+
pattern(%w( !purge ))
|
1083
1079
|
pattern(%w( !reportEnd ))
|
1084
1080
|
pattern(%w( !reportPeriod ))
|
1081
|
+
pattern(%w( !reports ))
|
1085
1082
|
pattern(%w( !reportStart ))
|
1086
1083
|
|
1087
1084
|
pattern(%w( _resourceattributes !exportableResourceAttributes ), lambda {
|
@@ -1131,6 +1128,24 @@ EOT
|
|
1131
1128
|
'priority' => 'Include priorities',
|
1132
1129
|
'responsible' => 'Include responsible resource' })
|
1133
1130
|
|
1131
|
+
pattern(%w( _taskroot !taskId), lambda {
|
1132
|
+
if @val[1].leaf?
|
1133
|
+
error('taskroot_leaf',
|
1134
|
+
"#{@val[1].fullId} is not a container task",
|
1135
|
+
@sourceFileInfo[1])
|
1136
|
+
end
|
1137
|
+
@property.set('taskroot', @val[1])
|
1138
|
+
})
|
1139
|
+
level(:experimental)
|
1140
|
+
doc('taskroot.export', <<'EOT'
|
1141
|
+
Only tasks below the specified root-level tasks are exported. The exported
|
1142
|
+
tasks will have the ID of the root-level task stripped from their ID, so that
|
1143
|
+
the sub-tasks of the root-level task become top-level tasks in the report
|
1144
|
+
file.
|
1145
|
+
EOT
|
1146
|
+
)
|
1147
|
+
example('TaskRoot')
|
1148
|
+
|
1134
1149
|
pattern(%w( _timezone !validTimeZone ), lambda {
|
1135
1150
|
@property.set('timezone', @val[1])
|
1136
1151
|
})
|
@@ -1142,6 +1157,72 @@ EOT
|
|
1142
1157
|
optionsRule('exportAttributes')
|
1143
1158
|
end
|
1144
1159
|
|
1160
|
+
def rule_exportFormat
|
1161
|
+
pattern(%w( _tjp ), lambda {
|
1162
|
+
:tjp
|
1163
|
+
})
|
1164
|
+
descr('Export of the scheduled project in TJP syntax.')
|
1165
|
+
|
1166
|
+
pattern(%w( _mspxml ), lambda {
|
1167
|
+
:mspxml
|
1168
|
+
})
|
1169
|
+
descr(<<'EOT'
|
1170
|
+
Export of the scheduled project in Microsoft Project XML format. This will
|
1171
|
+
export the data of the fully scheduled project. The exported data include the
|
1172
|
+
tasks, resources and the assignments of resources to task. This is only a
|
1173
|
+
small subset of the data that TaskJuggler can manage. This export is intended
|
1174
|
+
to share resource assignment data with other teams using Microsoft Project.
|
1175
|
+
TaskJuggler manages assignments with a larger accuracy than the Microsft
|
1176
|
+
Project XML format can represent. This will inevitably lead to some rounding
|
1177
|
+
errors and different interpretation of the data. The numbers you will see in
|
1178
|
+
Project are not necessarily an exact match of the numbers you see in
|
1179
|
+
TaskJuggler.
|
1180
|
+
EOT
|
1181
|
+
)
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
def rule_exportFormats
|
1185
|
+
pattern(%w( !exportFormat !moreExportFormats ), lambda {
|
1186
|
+
[ @val[0] ] + (@val[1].nil? ? [] : @val[1])
|
1187
|
+
})
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
def rule_exportHeader
|
1191
|
+
pattern(%w( _export !optionalID $STRING ), lambda {
|
1192
|
+
newReport(@val[1], @val[2], :export, @sourceFileInfo[0])
|
1193
|
+
unless @property.modified?('formats')
|
1194
|
+
@property.set('formats', [ :tjp ])
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
# By default, we export all scenarios.
|
1198
|
+
unless @property.modified?('scenarios')
|
1199
|
+
scenarios = Array.new(@project.scenarios.items) { |i| i }
|
1200
|
+
scenarios.delete_if { |sc| !@project.scenario(sc).get('active') }
|
1201
|
+
@property.set('scenarios', scenarios)
|
1202
|
+
end
|
1203
|
+
# Show all tasks, sorted by seqno-up.
|
1204
|
+
unless @property.modified?('hideTask')
|
1205
|
+
@property.set('hideTask', LogicalExpression.new(LogicalOperation.new(0)))
|
1206
|
+
end
|
1207
|
+
unless @property.modified?('sortTasks')
|
1208
|
+
@property.set('sortTasks', [ [ 'seqno', true, -1 ] ])
|
1209
|
+
end
|
1210
|
+
# Show all resources, sorted by seqno-up.
|
1211
|
+
unless @property.modified?('hideResource')
|
1212
|
+
@property.set('hideResource',
|
1213
|
+
LogicalExpression.new(LogicalOperation.new(0)))
|
1214
|
+
end
|
1215
|
+
unless @property.modified?('sortResources')
|
1216
|
+
@property.set('sortResources', [ [ 'seqno', true, -1 ] ])
|
1217
|
+
end
|
1218
|
+
})
|
1219
|
+
arg(2, 'file name', <<'EOT'
|
1220
|
+
The name of the report file to generate. It must end with a .tjp or .tji
|
1221
|
+
extension, or use . to use the standard output channel.
|
1222
|
+
EOT
|
1223
|
+
)
|
1224
|
+
end
|
1225
|
+
|
1145
1226
|
def rule_extendAttributes
|
1146
1227
|
optional
|
1147
1228
|
repeatable
|
@@ -1912,12 +1993,23 @@ EOT
|
|
1912
1993
|
error('zero_duration', "The interval duration may not be 0.",
|
1913
1994
|
@sourceFileInfo[1])
|
1914
1995
|
end
|
1915
|
-
duration = @val[0] * convFactors[@val[1]]
|
1996
|
+
duration = (@val[0] * convFactors[@val[1]]).to_i
|
1916
1997
|
resolution = @project.nil? ? 60 * 60 : @project['scheduleGranularity']
|
1998
|
+
if @val[1] == 4
|
1999
|
+
# If the duration unit is months, we have to align the duration with
|
2000
|
+
# the timing resolution of the project.
|
2001
|
+
duration = (duration / resolution).to_i * resolution
|
2002
|
+
end
|
1917
2003
|
# Make sure the interval aligns with the timing resolution.
|
1918
|
-
|
2004
|
+
if duration % resolution != 0
|
2005
|
+
error('iv_duration_not_aligned',
|
2006
|
+
"The interval duration must be a multiple of the specified " +
|
2007
|
+
"timing resolution (#{resolution / 60} min) of the project.")
|
2008
|
+
end
|
2009
|
+
duration
|
1919
2010
|
})
|
1920
|
-
arg(0, 'duration', 'The duration of the interval. May not be 0
|
2011
|
+
arg(0, 'duration', 'The duration of the interval. May not be 0 and must ' +
|
2012
|
+
'be a multiple of [[timingresolution]].')
|
1921
2013
|
end
|
1922
2014
|
|
1923
2015
|
def rule_intervalEnd
|
@@ -1993,6 +2085,14 @@ EOT
|
|
1993
2085
|
This mode only yields entries if used in the context of a task. It contains
|
1994
2086
|
all journal entries that are dated in the query interval for the task and all
|
1995
2087
|
its sub tasks.
|
2088
|
+
EOT
|
2089
|
+
)
|
2090
|
+
pattern(%w( _status_dep ), lambda { :status_dep })
|
2091
|
+
descr(<<'EOT'
|
2092
|
+
In this mode only the last entries before the report end date for each
|
2093
|
+
property and all its sub-properties and their dependencies are included. If
|
2094
|
+
there are multiple entries at the exact same date, then all these entries are
|
2095
|
+
included.
|
1996
2096
|
EOT
|
1997
2097
|
)
|
1998
2098
|
pattern(%w( _status_down ), lambda { :status_down })
|
@@ -2009,6 +2109,16 @@ property are included. If there are multiple entries at the exact same date,
|
|
2009
2109
|
then all these entries are included. If any of the parent properties has a
|
2010
2110
|
more recent entry that is still before the report end date, no entries will be
|
2011
2111
|
included.
|
2112
|
+
EOT
|
2113
|
+
)
|
2114
|
+
pattern(%w( _alerts_dep ), lambda { :alerts_dep })
|
2115
|
+
descr(<<'EOT'
|
2116
|
+
In this mode only the last entries before the report end date for the context
|
2117
|
+
property and all its sub-properties and their dependencies is included. If
|
2118
|
+
there are multiple entries at the exact same date, then all these entries are
|
2119
|
+
included. In contrast to the ''''status_down'''' mode, only entries with an
|
2120
|
+
alert level above the default level, and only those with the highest overall
|
2121
|
+
alert level are included.
|
2012
2122
|
EOT
|
2013
2123
|
)
|
2014
2124
|
pattern(%w( _alerts_down ), lambda { :alerts_down })
|
@@ -2412,6 +2522,16 @@ EOT
|
|
2412
2522
|
end
|
2413
2523
|
|
2414
2524
|
def rule_loadunit
|
2525
|
+
pattern(%w( _loadunit !loadunitName ), lambda {
|
2526
|
+
@property.set('loadUnit', @val[1])
|
2527
|
+
})
|
2528
|
+
doc('loadunit', <<'EOT'
|
2529
|
+
Determines what unit should be used to display all load values in this report.
|
2530
|
+
EOT
|
2531
|
+
)
|
2532
|
+
end
|
2533
|
+
|
2534
|
+
def rule_loadunitName
|
2415
2535
|
pattern([ '_days' ], lambda { :days })
|
2416
2536
|
descr('Display all load and duration values as days.')
|
2417
2537
|
|
@@ -2455,7 +2575,7 @@ EOT
|
|
2455
2575
|
LogicalExpression.new(@val[0], sourceFileInfo)
|
2456
2576
|
})
|
2457
2577
|
pattern(%w( _@ !allOrNone ), lambda {
|
2458
|
-
LogicalOperation.new(@val[1])
|
2578
|
+
LogicalExpression.new(LogicalOperation.new(@val[1]), sourceFileInfo)
|
2459
2579
|
})
|
2460
2580
|
doc('logicalexpression', <<'EOT'
|
2461
2581
|
A logical expression is a combination of operands and mathematical operations.
|
@@ -2559,6 +2679,10 @@ EOT
|
|
2559
2679
|
commaListRule('!taskDep')
|
2560
2680
|
end
|
2561
2681
|
|
2682
|
+
def rule_moreExportFormats
|
2683
|
+
commaListRule('!exportFormat')
|
2684
|
+
end
|
2685
|
+
|
2562
2686
|
def rule_moreJournalSortCriteria
|
2563
2687
|
commaListRule('!journalSortCriterium')
|
2564
2688
|
end
|
@@ -2909,6 +3033,17 @@ EOT
|
|
2909
3033
|
@val[0] / 100.0
|
2910
3034
|
})
|
2911
3035
|
end
|
3036
|
+
def rule_optionalScenarioIdCol
|
3037
|
+
optional
|
3038
|
+
pattern(%w( $ID_WITH_COLON ), lambda {
|
3039
|
+
if (@scenarioIdx = @project.scenarioIdx(@val[0])).nil?
|
3040
|
+
error('unknown_scenario_id', "Unknown scenario: #{@val[0]}",
|
3041
|
+
@sourceFileInfo[0])
|
3042
|
+
end
|
3043
|
+
@scenarioIdx
|
3044
|
+
})
|
3045
|
+
end
|
3046
|
+
|
2912
3047
|
|
2913
3048
|
def rule_optionalVersion
|
2914
3049
|
optional
|
@@ -3447,21 +3582,27 @@ EOT
|
|
3447
3582
|
end
|
3448
3583
|
|
3449
3584
|
def rule_purge
|
3450
|
-
pattern(%w( _purge $ID ), lambda {
|
3451
|
-
|
3585
|
+
pattern(%w( _purge !optionalScenarioIdCol $ID ), lambda {
|
3586
|
+
attrId = @val[2]
|
3587
|
+
if (attributeDefinition = @property.attributeDefinition(attrId)).nil?
|
3452
3588
|
error('purge_unknown_id',
|
3453
|
-
"#{
|
3454
|
-
@sourceFileInfo[
|
3589
|
+
"#{attrId} is not a known attribute for this property",
|
3590
|
+
@sourceFileInfo[2])
|
3455
3591
|
end
|
3456
3592
|
if attributeDefinition.scenarioSpecific
|
3457
|
-
|
3593
|
+
@scenarioIdx = 0 unless @val[1]
|
3594
|
+
attr = @property[attrId, 0]
|
3458
3595
|
else
|
3459
|
-
|
3596
|
+
if @val[1]
|
3597
|
+
error('purge_non_sc_spec_attr',
|
3598
|
+
'Scenario specified for a non-scenario specific attribute')
|
3599
|
+
end
|
3600
|
+
attr = @property.get(attrId)
|
3460
3601
|
end
|
3461
|
-
if @property.attributeDefinition(
|
3462
|
-
@property.getAttribute(
|
3602
|
+
if @property.attributeDefinition(attrId).scenarioSpecific
|
3603
|
+
@property.getAttribute(attrId, @scenarioIdx).reset
|
3463
3604
|
else
|
3464
|
-
@property.getAttribute(
|
3605
|
+
@property.getAttribute(attrId).reset
|
3465
3606
|
end
|
3466
3607
|
})
|
3467
3608
|
doc('purge', <<'EOT'
|
@@ -3475,6 +3616,10 @@ the list that was inherited from the enclosing property. The purge
|
|
3475
3616
|
attribute resets any attribute to its default value. A subsequent definition
|
3476
3617
|
for the attribute within the property will then add their values to an empty
|
3477
3618
|
list. The value of the enclosing property is not affected by purge.
|
3619
|
+
|
3620
|
+
For scenario specific attributes, an optional scenario ID can be specified
|
3621
|
+
before the attribute ID. If it's missing, the default (first) scenario will be
|
3622
|
+
used.
|
3478
3623
|
EOT
|
3479
3624
|
)
|
3480
3625
|
arg(1, 'attribute', 'Any name of a list attribute')
|
@@ -3506,6 +3651,7 @@ EOT
|
|
3506
3651
|
|
3507
3652
|
def rule_reports
|
3508
3653
|
pattern(%w( !accountReport ))
|
3654
|
+
pattern(%w( !export ))
|
3509
3655
|
pattern(%w( !resourceReport ))
|
3510
3656
|
pattern(%w( !taskReport ))
|
3511
3657
|
pattern(%w( !textReport ))
|
@@ -3524,14 +3670,14 @@ EOT
|
|
3524
3670
|
singlePattern('_annualleave')
|
3525
3671
|
descr(<<'EOT'
|
3526
3672
|
The number of annual leave units within the reported time period. The unit
|
3527
|
-
can be adjusted with [[loadunit]].
|
3673
|
+
can be adjusted with [[loadunit.report]].
|
3528
3674
|
EOT
|
3529
3675
|
)
|
3530
3676
|
|
3531
3677
|
singlePattern('_annualleavebalance')
|
3532
3678
|
descr(<<'EOT'
|
3533
3679
|
The balance of the annual leave at the end of the reporting interval. The unit
|
3534
|
-
can be adjusted with [[loadunit]].
|
3680
|
+
can be adjusted with [[loadunit.report]].
|
3535
3681
|
EOT
|
3536
3682
|
)
|
3537
3683
|
|
@@ -3880,14 +4026,14 @@ EOT
|
|
3880
4026
|
singlePattern('_sickleave')
|
3881
4027
|
descr(<<'EOT'
|
3882
4028
|
The number of sick leave units within the reported time period. The unit can
|
3883
|
-
be adjusted with [[loadunit]].
|
4029
|
+
be adjusted with [[loadunit.report]].
|
3884
4030
|
EOT
|
3885
4031
|
)
|
3886
4032
|
|
3887
4033
|
singlePattern('_specialleave')
|
3888
4034
|
descr(<<'EOT'
|
3889
4035
|
The number of special leave units within the reported time period. The unit
|
3890
|
-
can be adjusted with [[loadunit]].
|
4036
|
+
can be adjusted with [[loadunit.report]].
|
3891
4037
|
EOT
|
3892
4038
|
)
|
3893
4039
|
|
@@ -3921,7 +4067,7 @@ EOT
|
|
3921
4067
|
singlePattern('_unpaidleave')
|
3922
4068
|
descr(<<'EOT'
|
3923
4069
|
The number of unpaid leave units within the reported time period. The unit
|
3924
|
-
can be adjusted with [[loadunit]].
|
4070
|
+
can be adjusted with [[loadunit.report]].
|
3925
4071
|
EOT
|
3926
4072
|
)
|
3927
4073
|
|
@@ -4084,13 +4230,7 @@ EOT
|
|
4084
4230
|
)
|
4085
4231
|
example('textreport')
|
4086
4232
|
|
4087
|
-
pattern(%w(
|
4088
|
-
@property.set('loadUnit', @val[1])
|
4089
|
-
})
|
4090
|
-
doc('loadunit', <<'EOT'
|
4091
|
-
Determines what unit should be used to display all load values in this report.
|
4092
|
-
EOT
|
4093
|
-
)
|
4233
|
+
pattern(%w( !loadunit ))
|
4094
4234
|
|
4095
4235
|
pattern(%w( !numberFormat ), lambda {
|
4096
4236
|
@property.set('numberFormat', @val[0])
|
@@ -4308,7 +4448,6 @@ EOT
|
|
4308
4448
|
end
|
4309
4449
|
|
4310
4450
|
def rule_reportProperties
|
4311
|
-
pattern(%w( !export ))
|
4312
4451
|
pattern(%w( !iCalReport ))
|
4313
4452
|
pattern(%w( !nikuReport ))
|
4314
4453
|
pattern(%w( !reports ))
|
@@ -4393,7 +4532,7 @@ EOT
|
|
4393
4532
|
})
|
4394
4533
|
|
4395
4534
|
pattern(%w( _supplement !resourceId !resourceBody ), lambda {
|
4396
|
-
@property = @
|
4535
|
+
@property = @idStack.pop
|
4397
4536
|
})
|
4398
4537
|
doc('supplement.resource', <<'EOT'
|
4399
4538
|
The supplement keyword provides a mechanism to add more attributes to already
|
@@ -5416,21 +5555,22 @@ EOT
|
|
5416
5555
|
|
5417
5556
|
def rule_supplement
|
5418
5557
|
pattern(%w( !supplementAccount !accountBody ), lambda {
|
5419
|
-
@property =
|
5558
|
+
@property = @idStack.pop
|
5420
5559
|
})
|
5421
5560
|
pattern(%w( !supplementReport !reportBody ), lambda {
|
5422
|
-
@property =
|
5561
|
+
@property = @idStack.pop
|
5423
5562
|
})
|
5424
5563
|
pattern(%w( !supplementResource !resourceBody ), lambda {
|
5425
|
-
@property =
|
5564
|
+
@property = @idStack.pop
|
5426
5565
|
})
|
5427
5566
|
pattern(%w( !supplementTask !taskBody ), lambda {
|
5428
|
-
@property =
|
5567
|
+
@property = @idStack.pop
|
5429
5568
|
})
|
5430
5569
|
end
|
5431
5570
|
|
5432
5571
|
def rule_supplementAccount
|
5433
5572
|
pattern(%w( _account !accountId ), lambda {
|
5573
|
+
@idStack.push(@property)
|
5434
5574
|
@property = @val[1]
|
5435
5575
|
})
|
5436
5576
|
arg(1, 'account ID', 'The ID of an already defined account.')
|
@@ -5438,6 +5578,7 @@ EOT
|
|
5438
5578
|
|
5439
5579
|
def rule_supplementReport
|
5440
5580
|
pattern(%w( _report !reportId ), lambda {
|
5581
|
+
@idStack.push(@property)
|
5441
5582
|
@property = @val[1]
|
5442
5583
|
})
|
5443
5584
|
arg(1, 'report ID', 'The absolute ID of an already defined report.')
|
@@ -5445,6 +5586,7 @@ EOT
|
|
5445
5586
|
|
5446
5587
|
def rule_supplementResource
|
5447
5588
|
pattern(%w( _resource !resourceId ), lambda {
|
5589
|
+
@idStack.push(@property)
|
5448
5590
|
@property = @val[1]
|
5449
5591
|
})
|
5450
5592
|
arg(1, 'resource ID', 'The ID of an already defined resource.')
|
@@ -5452,6 +5594,7 @@ EOT
|
|
5452
5594
|
|
5453
5595
|
def rule_supplementTask
|
5454
5596
|
pattern(%w( _task !taskId ), lambda {
|
5597
|
+
@idStack.push(@property)
|
5455
5598
|
@property = @val[1]
|
5456
5599
|
})
|
5457
5600
|
arg(1, 'task ID', 'The absolute ID of an already defined task.')
|
@@ -5533,13 +5676,16 @@ EOT
|
|
5533
5676
|
})
|
5534
5677
|
level(:experimental)
|
5535
5678
|
doc('adopt.task', <<'EOT'
|
5536
|
-
Add a previously defined task
|
5537
|
-
to create virtual
|
5538
|
-
|
5539
|
-
parents. However, the adopting task is scheduled to fit all adopted
|
5540
|
-
|
5679
|
+
Add a previously defined task and its sub-tasks to this task. This can be used
|
5680
|
+
to create virtual projects that contain task (sub-)trees that are originally
|
5681
|
+
defined in another task context. Adopted tasks don't inherit anything from
|
5682
|
+
their step parents. However, the adopting task is scheduled to fit all adopted
|
5683
|
+
sub-tasks.
|
5541
5684
|
|
5542
|
-
A top-level tasks must never
|
5685
|
+
A top-level task and all its sub-tasks must never contain the same task more
|
5686
|
+
than once. All reports must use appropriate filters by setting [[taskroot]],
|
5687
|
+
[[hidetask]] or [[rolluptask]] to ensure that no tasks are contained more than
|
5688
|
+
once in the report.
|
5543
5689
|
EOT
|
5544
5690
|
)
|
5545
5691
|
|
@@ -5557,7 +5703,7 @@ EOT
|
|
5557
5703
|
pattern(%w( !purge ))
|
5558
5704
|
|
5559
5705
|
pattern(%w( _supplement !supplementTask !taskBody ), lambda {
|
5560
|
-
@property = @
|
5706
|
+
@property = @idStack.pop
|
5561
5707
|
})
|
5562
5708
|
doc('supplement.task', <<'EOT'
|
5563
5709
|
The supplement keyword provides a mechanism to add more attributes to already
|
@@ -6245,8 +6391,10 @@ EOT
|
|
6245
6391
|
@property['scheduled', @scenarioIdx] = true
|
6246
6392
|
})
|
6247
6393
|
doc('scheduled', <<'EOT'
|
6248
|
-
This is mostly for internal use. It specifies that the task
|
6249
|
-
scheduling in the scenario.
|
6394
|
+
This is mostly for internal use. It specifies that the task should be ignored
|
6395
|
+
for scheduling in the scenario. This option only makes sense if you provide
|
6396
|
+
all resource [[booking.resource|bookings]] manually. Without booking
|
6397
|
+
statements, the task will be reported with 0 effort and no resources assigned.
|
6250
6398
|
EOT
|
6251
6399
|
)
|
6252
6400
|
|