taskjuggler 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +2086 -0
- data/benchmarks/666tasks.tjp +3183 -0
- data/benchmarks/booking.tjp +14 -10
- data/doc/AppConfig.html +95 -73
- data/doc/Arguments.html +22 -2
- data/doc/CHANGELOG.html +2587 -0
- data/doc/COPYING.html +21 -1
- data/doc/Object.html +161 -122
- data/doc/README.html +21 -1
- data/doc/RuntimeConfig.html +26 -6
- data/doc/String.html +38 -18
- data/doc/StringIO.html +579 -0
- data/doc/TaskJuggler.html +251 -143
- data/doc/TaskJuggler/Account.html +26 -6
- data/doc/TaskJuggler/AccountAttribute.html +28 -8
- data/doc/TaskJuggler/AccountScenario.html +24 -4
- data/doc/TaskJuggler/Allocation.html +30 -10
- data/doc/TaskJuggler/AllocationAttribute.html +28 -8
- data/doc/TaskJuggler/AttributeBase.html +46 -26
- data/doc/TaskJuggler/AttributeDefinition.html +22 -2
- data/doc/TaskJuggler/BatchProcessor.html +40 -20
- data/doc/TaskJuggler/Booking.html +26 -6
- data/doc/TaskJuggler/BookingListAttribute.html +28 -8
- data/doc/TaskJuggler/BooleanAttribute.html +28 -8
- data/doc/TaskJuggler/CSVFile.html +308 -146
- data/doc/TaskJuggler/CellSettingPattern.html +22 -2
- data/doc/TaskJuggler/CellSettingPatternList.html +26 -6
- data/doc/TaskJuggler/Charge.html +26 -6
- data/doc/TaskJuggler/ChargeListAttribute.html +26 -6
- data/doc/TaskJuggler/ChargeSet.html +33 -13
- data/doc/TaskJuggler/ChargeSetListAttribute.html +28 -8
- data/doc/TaskJuggler/ColumnListAttribute.html +26 -6
- data/doc/TaskJuggler/ColumnTable.html +24 -4
- data/doc/TaskJuggler/Daemon.html +26 -6
- data/doc/TaskJuggler/DateAttribute.html +26 -6
- data/doc/TaskJuggler/DefinitionListAttribute.html +22 -2
- data/doc/TaskJuggler/DependencyListAttribute.html +28 -8
- data/doc/TaskJuggler/DurationAttribute.html +28 -8
- data/doc/TaskJuggler/FixnumAttribute.html +24 -4
- data/doc/TaskJuggler/FlagListAttribute.html +28 -8
- data/doc/TaskJuggler/FloatAttribute.html +26 -6
- data/doc/TaskJuggler/FormatListAttribute.html +24 -4
- data/doc/TaskJuggler/GanttChart.html +147 -126
- data/doc/TaskJuggler/GanttContainer.html +34 -14
- data/doc/TaskJuggler/GanttHeader.html +28 -8
- data/doc/TaskJuggler/GanttHeaderScaleItem.html +24 -4
- data/doc/TaskJuggler/GanttLine.html +38 -18
- data/doc/TaskJuggler/GanttLoadStack.html +26 -6
- data/doc/TaskJuggler/GanttMilestone.html +34 -14
- data/doc/TaskJuggler/GanttRouter.html +50 -30
- data/doc/TaskJuggler/GanttTaskBar.html +34 -14
- data/doc/TaskJuggler/HTMLDocument.html +26 -6
- data/doc/TaskJuggler/HTMLGraphics.html +30 -10
- data/doc/TaskJuggler/Interval.html +40 -22
- data/doc/TaskJuggler/IntervalListAttribute.html +28 -8
- data/doc/TaskJuggler/JobInfo.html +24 -4
- data/doc/TaskJuggler/Journal.html +226 -147
- data/doc/TaskJuggler/JournalEntry.html +22 -2
- data/doc/TaskJuggler/JournalEntryList.html +129 -112
- data/doc/TaskJuggler/KeywordArray.html +26 -6
- data/doc/TaskJuggler/KeywordDocumentation.html +46 -26
- data/doc/TaskJuggler/Limits.html +152 -123
- data/doc/TaskJuggler/Limits/Limit.html +149 -70
- data/doc/TaskJuggler/LimitsAttribute.html +36 -51
- data/doc/TaskJuggler/ListAttributeBase.html +24 -4
- data/doc/TaskJuggler/Log.html +50 -32
- data/doc/TaskJuggler/LogFile.html +37 -17
- data/doc/TaskJuggler/LogicalAttribute.html +53 -33
- data/doc/TaskJuggler/LogicalExpression.html +26 -6
- data/doc/TaskJuggler/LogicalExpressionAttribute.html +32 -12
- data/doc/TaskJuggler/LogicalFlag.html +42 -22
- data/doc/TaskJuggler/LogicalFunction.html +204 -140
- data/doc/TaskJuggler/LogicalOperation.html +135 -111
- data/doc/TaskJuggler/Macro.html +22 -2
- data/doc/TaskJuggler/MacroParser.html +32 -12
- data/doc/TaskJuggler/MacroTable.html +32 -12
- data/doc/TaskJuggler/ManagerResponsibilities.html +24 -4
- data/doc/TaskJuggler/ManagerStatusRecord.html +24 -4
- data/doc/TaskJuggler/Message.html +24 -4
- data/doc/TaskJuggler/MessageHandler.html +24 -4
- data/doc/TaskJuggler/Navigator.html +104 -71
- data/doc/TaskJuggler/NavigatorElement.html +32 -12
- data/doc/TaskJuggler/NikuProject.html +22 -2
- data/doc/TaskJuggler/NikuReport.html +310 -228
- data/doc/TaskJuggler/NikuResource.html +22 -2
- data/doc/TaskJuggler/NodeListAttribute.html +615 -0
- data/doc/TaskJuggler/OnShiftCache.html +32 -12
- data/doc/TaskJuggler/ProcessIntercom.html +205 -78
- data/doc/TaskJuggler/ProcessIntercomIface.html +26 -6
- data/doc/TaskJuggler/Project.html +708 -660
- data/doc/TaskJuggler/ProjectBroker.html +506 -304
- data/doc/TaskJuggler/ProjectBrokerIface.html +61 -41
- data/doc/TaskJuggler/ProjectFileParser.html +429 -373
- data/doc/TaskJuggler/ProjectFileScanner.html +1790 -0
- data/doc/TaskJuggler/ProjectRecord.html +80 -60
- data/doc/TaskJuggler/ProjectServer.html +312 -237
- data/doc/TaskJuggler/ProjectServerIface.html +101 -43
- data/doc/TaskJuggler/PropertyAttribute.html +32 -12
- data/doc/TaskJuggler/PropertyList.html +166 -145
- data/doc/TaskJuggler/PropertySet.html +254 -224
- data/doc/TaskJuggler/PropertyTreeNode.html +670 -536
- data/doc/TaskJuggler/Query.html +169 -148
- data/doc/TaskJuggler/RTFHandlers.html +622 -0
- data/doc/TaskJuggler/RTFNavigator.html +28 -8
- data/doc/TaskJuggler/RTFQuery.html +40 -20
- data/doc/TaskJuggler/RTFReport.html +62 -25
- data/doc/TaskJuggler/RTFReportLink.html +765 -0
- data/doc/TaskJuggler/RealFormat.html +26 -6
- data/doc/TaskJuggler/RealFormatAttribute.html +26 -6
- data/doc/TaskJuggler/ReferenceAttribute.html +59 -39
- data/doc/TaskJuggler/Report.html +402 -251
- data/doc/TaskJuggler/ReportBase.html +162 -137
- data/doc/TaskJuggler/ReportContext.html +112 -29
- data/doc/TaskJuggler/ReportServer.html +89 -64
- data/doc/TaskJuggler/ReportServerIface.html +75 -55
- data/doc/TaskJuggler/ReportServerRecord.html +54 -31
- data/doc/TaskJuggler/ReportServlet.html +980 -0
- data/doc/TaskJuggler/ReportTable.html +41 -21
- data/doc/TaskJuggler/ReportTableCell.html +214 -170
- data/doc/TaskJuggler/ReportTableColumn.html +30 -10
- data/doc/TaskJuggler/ReportTableLegend.html +36 -16
- data/doc/TaskJuggler/ReportTableLine.html +32 -12
- data/doc/TaskJuggler/Resource.html +99 -87
- data/doc/TaskJuggler/ResourceListAttribute.html +59 -39
- data/doc/TaskJuggler/ResourceListRE.html +47 -26
- data/doc/TaskJuggler/ResourceScenario.html +403 -437
- data/doc/TaskJuggler/RichText.html +26 -6
- data/doc/TaskJuggler/RichTextAttribute.html +50 -30
- data/doc/TaskJuggler/RichTextDocument.html +37 -17
- data/doc/TaskJuggler/RichTextElement.html +475 -413
- data/doc/TaskJuggler/RichTextException.html +22 -2
- data/doc/TaskJuggler/RichTextFunctionExample.html +28 -8
- data/doc/TaskJuggler/RichTextFunctionHandler.html +24 -4
- data/doc/TaskJuggler/RichTextImage.html +22 -2
- data/doc/TaskJuggler/RichTextIntermediate.html +38 -18
- data/doc/TaskJuggler/RichTextParser.html +56 -34
- data/doc/TaskJuggler/RichTextScanner.html +82 -61
- data/doc/TaskJuggler/RichTextSnip.html +34 -14
- data/doc/TaskJuggler/RichTextSyntaxRules.html +507 -353
- data/doc/TaskJuggler/Scenario.html +22 -2
- data/doc/TaskJuggler/ScenarioData.html +30 -46
- data/doc/TaskJuggler/ScenarioListAttribute.html +38 -18
- data/doc/TaskJuggler/Scoreboard.html +42 -22
- data/doc/TaskJuggler/SheetHandlerBase.html +40 -20
- data/doc/TaskJuggler/SheetReceiver.html +333 -295
- data/doc/TaskJuggler/SheetSender.html +253 -230
- data/doc/TaskJuggler/Shift.html +26 -6
- data/doc/TaskJuggler/ShiftAssignment.html +89 -73
- data/doc/TaskJuggler/ShiftAssignments.html +226 -234
- data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +39 -54
- data/doc/TaskJuggler/ShiftScenario.html +28 -8
- data/doc/TaskJuggler/SortListAttribute.html +34 -14
- data/doc/TaskJuggler/SourceFileInfo.html +24 -4
- data/doc/TaskJuggler/StatusSheetReceiver.html +24 -3
- data/doc/TaskJuggler/StatusSheetReport.html +168 -153
- data/doc/TaskJuggler/StatusSheetSender.html +24 -3
- data/doc/TaskJuggler/StringAttribute.html +38 -18
- data/doc/TaskJuggler/SymbolAttribute.html +32 -12
- data/doc/TaskJuggler/SyntaxReference.html +40 -20
- data/doc/TaskJuggler/TOCEntry.html +26 -6
- data/doc/TaskJuggler/TSResourceRecord.html +22 -2
- data/doc/TaskJuggler/TSTaskRecord.html +22 -2
- data/doc/TaskJuggler/TableColumnDefinition.html +59 -22
- data/doc/TaskJuggler/TableOfContents.html +26 -6
- data/doc/TaskJuggler/TableReport.html +937 -904
- data/doc/TaskJuggler/Task.html +55 -36
- data/doc/TaskJuggler/TaskDependency.html +24 -4
- data/doc/TaskJuggler/TaskListAttribute.html +50 -30
- data/doc/TaskJuggler/TaskListRE.html +27 -7
- data/doc/TaskJuggler/TaskScenario.html +1273 -1153
- data/doc/TaskJuggler/TextFormatter.html +28 -8
- data/doc/TaskJuggler/TextParser.html +585 -338
- data/doc/TaskJuggler/TextParser/Pattern.html +54 -34
- data/doc/TaskJuggler/TextParser/Rule.html +95 -73
- data/doc/TaskJuggler/TextParser/StackElement.html +39 -17
- data/doc/TaskJuggler/TextParser/TextParserResultArray.html +24 -4
- data/doc/TaskJuggler/TextParser/TokenDoc.html +22 -2
- data/doc/TaskJuggler/TextReport.html +28 -8
- data/doc/TaskJuggler/TextScanner.html +400 -1404
- data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +28 -240
- data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +37 -184
- data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +682 -0
- data/doc/TaskJuggler/TextScanner/StreamHandle.html +342 -67
- data/doc/TaskJuggler/TimeSheet.html +48 -28
- data/doc/TaskJuggler/TimeSheetReceiver.html +24 -3
- data/doc/TaskJuggler/TimeSheetRecord.html +47 -27
- data/doc/TaskJuggler/TimeSheetReport.html +154 -133
- data/doc/TaskJuggler/TimeSheetSender.html +24 -3
- data/doc/TaskJuggler/TimeSheetSummary.html +137 -91
- data/doc/TaskJuggler/TimeSheets.html +26 -6
- data/doc/TaskJuggler/Tj3AppBase.html +85 -58
- data/doc/TaskJuggler/Tj3Client.html +292 -238
- data/doc/TaskJuggler/Tj3Daemon.html +159 -74
- data/doc/TaskJuggler/Tj3SheetAppBase.html +26 -6
- data/doc/TaskJuggler/Tj3SsReceiver.html +26 -6
- data/doc/TaskJuggler/Tj3SsSender.html +53 -26
- data/doc/TaskJuggler/Tj3TsReceiver.html +28 -7
- data/doc/TaskJuggler/Tj3TsSender.html +26 -6
- data/doc/TaskJuggler/Tj3TsSummary.html +26 -6
- data/doc/TaskJuggler/TjException.html +22 -2
- data/doc/TaskJuggler/TjTime.html +216 -160
- data/doc/TaskJuggler/TjpExample.html +34 -14
- data/doc/TaskJuggler/TjpExportRE.html +403 -407
- data/doc/TaskJuggler/TjpSyntaxRules.html +4805 -4408
- data/doc/TaskJuggler/URLParameter.html +649 -0
- data/doc/TaskJuggler/UserManual.html +42 -22
- data/doc/TaskJuggler/WebServer.html +702 -0
- data/doc/TaskJuggler/WorkingHours.html +38 -18
- data/doc/TaskJuggler/WorkingHoursAttribute.html +61 -41
- data/doc/TaskJuggler/XMLBlob.html +24 -4
- data/doc/TaskJuggler/XMLComment.html +24 -4
- data/doc/TaskJuggler/XMLDocument.html +30 -10
- data/doc/TaskJuggler/XMLElement.html +34 -14
- data/doc/TaskJuggler/XMLNamedText.html +22 -2
- data/doc/TaskJuggler/XMLText.html +24 -4
- data/doc/index.html +1841 -1666
- data/doc/lib/AccountScenario_rb.html +1 -1
- data/doc/lib/Account_rb.html +1 -1
- data/doc/lib/Allocation_rb.html +1 -1
- data/doc/lib/AppConfig_rb.html +2 -2
- data/doc/lib/AttributeBase_rb.html +1 -1
- data/doc/lib/AttributeDefinition_rb.html +1 -1
- data/doc/lib/Attributes_rb.html +2 -2
- data/doc/lib/BatchProcessor_rb.html +1 -1
- data/doc/lib/Booking_rb.html +1 -1
- data/doc/lib/ChargeSet_rb.html +1 -1
- data/doc/lib/Charge_rb.html +1 -1
- data/doc/lib/HTMLDocument_rb.html +1 -1
- data/doc/lib/Interval_rb.html +1 -1
- data/doc/lib/Journal_rb.html +2 -2
- data/doc/lib/KeywordArray_rb.html +1 -1
- data/doc/lib/KeywordDocumentation_rb.html +1 -1
- data/doc/lib/Limits_rb.html +2 -2
- data/doc/lib/LogFile_rb.html +2 -2
- data/doc/lib/Log_rb.html +1 -1
- data/doc/lib/LogicalExpression_rb.html +1 -1
- data/doc/lib/LogicalFunction_rb.html +2 -2
- data/doc/lib/LogicalOperation_rb.html +2 -2
- data/doc/lib/MacroParser_rb.html +1 -1
- data/doc/lib/MacroTable_rb.html +1 -1
- data/doc/lib/MessageHandler_rb.html +1 -1
- data/doc/lib/Message_rb.html +1 -1
- data/doc/lib/ProjectFileParser_rb.html +4 -8
- data/doc/lib/ProjectFileScanner_rb.html +67 -0
- data/doc/lib/Project_rb.html +2 -2
- data/doc/lib/PropertyList_rb.html +2 -2
- data/doc/lib/PropertySet_rb.html +2 -2
- data/doc/lib/PropertyTreeNode_rb.html +2 -2
- data/doc/lib/Query_rb.html +2 -2
- data/doc/lib/RTFHandlers_rb.html +73 -0
- data/doc/lib/RTFNavigator_rb.html +1 -1
- data/doc/lib/RTFQuery_rb.html +1 -1
- data/doc/lib/RTFReportLink_rb.html +71 -0
- data/doc/lib/RTFReport_rb.html +2 -2
- data/doc/lib/RealFormat_rb.html +1 -1
- data/doc/lib/ResourceScenario_rb.html +2 -2
- data/doc/lib/Resource_rb.html +2 -2
- data/doc/lib/RichTextDocument_rb.html +1 -1
- data/doc/lib/RichTextElement_rb.html +2 -2
- data/doc/lib/RichTextFunctionExample_rb.html +1 -1
- data/doc/lib/RichTextFunctionHandler_rb.html +1 -1
- data/doc/lib/RichTextParser_rb.html +2 -2
- data/doc/lib/RichTextScanner_rb.html +2 -2
- data/doc/lib/RichTextSnip_rb.html +1 -1
- data/doc/lib/RichTextSyntaxRules_rb.html +2 -2
- data/doc/lib/RichText_rb.html +1 -1
- data/doc/lib/RuntimeConfig_rb.html +1 -1
- data/doc/lib/ScenarioData_rb.html +2 -2
- data/doc/lib/Scenario_rb.html +1 -1
- data/doc/lib/Scoreboard_rb.html +1 -1
- data/doc/lib/SheetHandlerBase_rb.html +1 -1
- data/doc/lib/SheetReceiver_rb.html +2 -2
- data/doc/lib/SheetSender_rb.html +4 -2
- data/doc/lib/ShiftAssignments_rb.html +4 -2
- data/doc/lib/ShiftScenario_rb.html +1 -1
- data/doc/lib/Shift_rb.html +1 -1
- data/doc/lib/SourceFileInfo_rb.html +1 -1
- data/doc/lib/StatusSheetReceiver_rb.html +2 -2
- data/doc/lib/StatusSheetSender_rb.html +2 -2
- data/doc/lib/SyntaxReference_rb.html +1 -1
- data/doc/lib/TOCEntry_rb.html +1 -1
- data/doc/lib/TableColumnDefinition_rb.html +2 -2
- data/doc/lib/TableOfContents_rb.html +1 -1
- data/doc/lib/TaskDependency_rb.html +1 -1
- data/doc/lib/TaskJuggler_rb.html +2 -2
- data/doc/lib/TaskScenario_rb.html +2 -2
- data/doc/lib/Task_rb.html +2 -2
- data/doc/lib/TextFormatter_rb.html +1 -1
- data/doc/lib/TextParser/Pattern_rb.html +1 -1
- data/doc/lib/TextParser/Rule_rb.html +2 -2
- data/doc/lib/TextParser/StackElement_rb.html +2 -2
- data/doc/lib/TextParser/TokenDoc_rb.html +1 -1
- data/doc/lib/TextParser_rb.html +2 -2
- data/doc/lib/TextScanner_rb.html +6 -2
- data/doc/lib/TimeSheetReceiver_rb.html +2 -2
- data/doc/lib/TimeSheetSender_rb.html +2 -2
- data/doc/lib/TimeSheetSummary_rb.html +2 -2
- data/doc/lib/TimeSheets_rb.html +2 -2
- data/doc/lib/Tj3AppBase_rb.html +2 -2
- data/doc/lib/Tj3Config_rb.html +2 -2
- data/doc/lib/Tj3SheetAppBase_rb.html +2 -2
- data/doc/lib/TjException_rb.html +1 -1
- data/doc/lib/TjTime_rb.html +2 -2
- data/doc/lib/TjpExample_rb.html +1 -1
- data/doc/lib/TjpSyntaxRules_rb.html +2 -2
- data/doc/lib/URLParameter_rb.html +67 -0
- data/doc/lib/UTF8String_rb.html +1 -1
- data/doc/lib/UserManual_rb.html +1 -1
- data/doc/lib/WorkingHours_rb.html +1 -1
- data/doc/lib/XMLDocument_rb.html +2 -2
- data/doc/lib/XMLElement_rb.html +1 -1
- data/doc/lib/daemon/Daemon_rb.html +1 -1
- data/doc/lib/daemon/ProcessIntercom_rb.html +2 -2
- data/doc/lib/daemon/ProjectBroker_rb.html +4 -2
- data/doc/lib/daemon/ProjectServer_rb.html +2 -2
- data/doc/lib/daemon/ReportServer_rb.html +2 -2
- data/doc/lib/daemon/WebServer_rb.html +75 -0
- data/doc/lib/deep_copy_rb.html +2 -2
- data/doc/lib/reports/CSVFile_rb.html +2 -2
- data/doc/lib/reports/ColumnTable_rb.html +1 -1
- data/doc/lib/reports/GanttChart_rb.html +2 -2
- data/doc/lib/reports/GanttContainer_rb.html +1 -1
- data/doc/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
- data/doc/lib/reports/GanttHeader_rb.html +1 -1
- data/doc/lib/reports/GanttLine_rb.html +1 -1
- data/doc/lib/reports/GanttLoadStack_rb.html +1 -1
- data/doc/lib/reports/GanttMilestone_rb.html +1 -1
- data/doc/lib/reports/GanttRouter_rb.html +1 -1
- data/doc/lib/reports/GanttTaskBar_rb.html +1 -1
- data/doc/lib/reports/HTMLGraphics_rb.html +1 -1
- data/doc/lib/reports/Navigator_rb.html +2 -2
- data/doc/lib/reports/NikuReport_rb.html +2 -2
- data/doc/lib/reports/ReportBase_rb.html +2 -2
- data/doc/lib/reports/ReportContext_rb.html +2 -2
- data/doc/lib/reports/ReportTableCell_rb.html +2 -2
- data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
- data/doc/lib/reports/ReportTableLegend_rb.html +1 -1
- data/doc/lib/reports/ReportTableLine_rb.html +1 -1
- data/doc/lib/reports/ReportTable_rb.html +2 -2
- data/doc/lib/reports/Report_rb.html +2 -2
- data/doc/lib/reports/ResourceListRE_rb.html +2 -2
- data/doc/lib/reports/StatusSheetReport_rb.html +2 -2
- data/doc/lib/reports/TableReport_rb.html +2 -2
- data/doc/lib/reports/TaskListRE_rb.html +2 -2
- data/doc/lib/reports/TextReport_rb.html +1 -1
- data/doc/lib/reports/TimeSheetReport_rb.html +2 -2
- data/doc/lib/reports/TjpExportRE_rb.html +2 -2
- data/doc/lib/ruby-signal-bug_rb.html +1 -1
- data/doc/lib/taskjuggler3_rb.html +2 -2
- data/doc/lib/tj3client_rb.html +2 -2
- data/doc/lib/tj3d_rb.html +2 -2
- data/doc/lib/tj3man_rb.html +1 -1
- data/doc/lib/tj3ss_receiver_rb.html +1 -1
- data/doc/lib/tj3ss_sender_rb.html +2 -2
- data/doc/lib/tj3ts_receiver_rb.html +2 -2
- data/doc/lib/tj3ts_sender_rb.html +1 -1
- data/doc/lib/tj3ts_summary_rb.html +1 -1
- data/doc/rdoc.css +9 -4
- data/examples/tutorial.tjp +17 -15
- data/gem_spec.rb +3 -0
- data/lib/AppConfig.rb +3 -1
- data/lib/Attributes.rb +10 -8
- data/lib/Journal.rb +55 -20
- data/lib/Limits.rb +72 -46
- data/lib/LogFile.rb +3 -3
- data/lib/LogicalFunction.rb +19 -6
- data/lib/LogicalOperation.rb +5 -1
- data/lib/Project.rb +37 -9
- data/lib/ProjectFileParser.rb +25 -22
- data/lib/ProjectFileScanner.rb +365 -0
- data/lib/PropertyList.rb +2 -1
- data/lib/PropertySet.rb +14 -4
- data/lib/PropertyTreeNode.rb +42 -29
- data/lib/Query.rb +3 -1
- data/lib/RTFHandlers.rb +35 -0
- data/lib/RTFReport.rb +23 -6
- data/lib/RTFReportLink.rb +72 -0
- data/lib/Resource.rb +8 -16
- data/lib/ResourceScenario.rb +1 -22
- data/lib/RichTextElement.rb +42 -0
- data/lib/RichTextParser.rb +6 -4
- data/lib/RichTextScanner.rb +5 -5
- data/lib/RichTextSyntaxRules.rb +48 -10
- data/lib/ScenarioData.rb +5 -3
- data/lib/SheetReceiver.rb +24 -6
- data/lib/SheetSender.rb +17 -13
- data/lib/ShiftAssignments.rb +56 -52
- data/lib/StatusSheetReceiver.rb +1 -0
- data/lib/StatusSheetSender.rb +1 -0
- data/lib/TableColumnDefinition.rb +4 -2
- data/lib/Task.rb +8 -9
- data/lib/TaskJuggler.rb +21 -11
- data/lib/TaskScenario.rb +61 -26
- data/lib/TextParser.rb +268 -106
- data/lib/TextParser/Rule.rb +4 -2
- data/lib/TextParser/StackElement.rb +6 -4
- data/lib/TextScanner.rb +283 -700
- data/lib/TimeSheetReceiver.rb +1 -0
- data/lib/TimeSheetSender.rb +1 -0
- data/lib/TimeSheetSummary.rb +51 -26
- data/lib/TimeSheets.rb +1 -1
- data/lib/Tj3AppBase.rb +8 -1
- data/lib/Tj3Config.rb +1 -1
- data/lib/TjTime.rb +5 -0
- data/lib/TjpSyntaxRules.rb +360 -144
- data/lib/URLParameter.rb +30 -0
- data/lib/XMLDocument.rb +2 -2
- data/lib/daemon/ProcessIntercom.rb +50 -9
- data/lib/daemon/ProjectBroker.rb +63 -10
- data/lib/daemon/ProjectServer.rb +47 -16
- data/lib/daemon/ReportServer.rb +9 -4
- data/lib/daemon/WebServer.rb +204 -0
- data/lib/deep_copy.rb +4 -1
- data/lib/reports/CSVFile.rb +150 -66
- data/lib/reports/GanttChart.rb +2 -1
- data/lib/reports/Navigator.rb +18 -5
- data/lib/reports/NikuReport.rb +32 -2
- data/lib/reports/Report.rb +65 -37
- data/lib/reports/ReportBase.rb +14 -9
- data/lib/reports/ReportContext.rb +19 -4
- data/lib/reports/ReportTable.rb +2 -2
- data/lib/reports/ReportTableCell.rb +54 -30
- data/lib/reports/ResourceListRE.rb +4 -3
- data/lib/reports/StatusSheetReport.rb +8 -13
- data/lib/reports/TableReport.rb +47 -32
- data/lib/reports/TaskListRE.rb +3 -3
- data/lib/reports/TimeSheetReport.rb +14 -5
- data/lib/reports/TjpExportRE.rb +14 -19
- data/lib/taskjuggler3.rb +15 -0
- data/lib/tj3client.rb +9 -7
- data/lib/tj3d.rb +38 -10
- data/lib/tj3ss_sender.rb +7 -0
- data/lib/tj3ts_receiver.rb +1 -0
- data/manual/Day_To_Day_Juggling +1 -1
- data/manual/Rich_Text_Attributes +8 -0
- data/manual/TaskJuggler_2x_Migration +7 -0
- data/manual/The_TaskJuggler_Syntax +20 -6
- data/prj_cfg.rb +3 -2
- data/tasks/changelog.rake +36 -0
- data/tasks/csts.rake +2 -3
- data/tasks/gem.rake +10 -0
- data/tasks/missing.rake +0 -17
- data/test/TestSuite/ReportGenerator/Correct/Journal.html +63 -0
- data/test/TestSuite/ReportGenerator/Correct/Journal.tjp +14 -0
- data/test/TestSuite/{HTML-Reports/LogicalFunctions.tjp → ReportGenerator/Correct/LogicalFunctions1.tjp} +2 -2
- data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.csv +3 -0
- data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.tjp +19 -0
- data/test/TestSuite/ReportGenerator/Correct/css/tjmanual.css +66 -0
- data/test/TestSuite/ReportGenerator/Correct/css/tjreport.css +407 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/details.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/resource.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/task.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/ReportGenerator/Correct/opennodes.csv +2 -0
- data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +26 -0
- data/test/TestSuite/ReportGenerator/Correct/refs/Journal-1.csv +6 -0
- data/test/TestSuite/ReportGenerator/Correct/refs/LogicalFunctions1-1.csv +7 -0
- data/test/TestSuite/ReportGenerator/Correct/refs/LogicalFunctions2-1.csv +2 -0
- data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +2 -0
- data/test/TestSuite/ReportGenerator/Correct/scripts/wz_tooltip.js +1301 -0
- data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.tjp +20 -0
- data/test/TestSuite/Scheduler/Correct/Container.html +349 -0
- data/test/TestSuite/Scheduler/Correct/Limits.tjp +11 -4
- data/test/TestSuite/Scheduler/Correct/Shift2.html +464 -150
- data/test/TestSuite/Scheduler/Correct/TimeSheet2.html +108 -0
- data/test/TestSuite/Scheduler/Correct/TimeSheet2.tjp +7 -0
- data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +14 -0
- data/test/TestSuite/Scheduler/Correct/css/tjreport.css +233 -21
- data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +20 -20
- data/test/TestSuite/StatusSheetTemplates/project.tji +35 -0
- data/test/TestSuite/StatusSheetTemplates/project.tjp +56 -0
- data/test/TestSuite/StatusSheets/run +3 -2
- data/test/TestSuite/Syntax/Correct/Include.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/Macro-1.tjp +1 -1
- data/test/TestSuite/Syntax/Correct/Macro-2.tjp +6 -0
- data/test/TestSuite/Syntax/Correct/Macro-3.tjp +14 -0
- data/test/TestSuite/Syntax/Correct/ResourcePrefix.html +32 -0
- data/test/TestSuite/Syntax/Correct/css/tjmanual.css +66 -0
- data/test/TestSuite/Syntax/Correct/css/tjreport.css +407 -0
- data/test/TestSuite/Syntax/Correct/icons/details.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-green.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-red.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/flag-yellow.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/resource.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/resourcegroup.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/task.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/taskgroup.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/trend-down.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/trend-flat.png +0 -0
- data/test/TestSuite/Syntax/Correct/icons/trend-up.png +0 -0
- data/test/TestSuite/Syntax/Correct/include/dir1/file2.tji +3 -0
- data/test/TestSuite/Syntax/Correct/include/dir1/file5.tji +2 -0
- data/test/TestSuite/Syntax/Correct/include/dir3/all.tji +3 -0
- data/test/TestSuite/Syntax/Correct/include/dir3/file1.tji +2 -0
- data/test/TestSuite/Syntax/Correct/include/dir3/file2.tji +1 -0
- data/test/TestSuite/Syntax/Correct/scripts/wz_tooltip.js +1301 -0
- data/test/TestSuite/Syntax/Correct/tutorial.tjp +13 -13
- data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
- data/test/TestSuite/Syntax/Errors/include_recursion.tjp +1 -0
- data/test/TestSuite/Syntax/Errors/macro_stack_overflow.tjp +2 -1
- data/test/TestSuite/Syntax/Errors/{eof_in_istring1.tjp → no_token_match1.tjp} +2 -2
- data/test/TestSuite/Syntax/Errors/{eof_in_istring2.tjp → no_token_match2.tjp} +2 -2
- data/test/TestSuite/Syntax/Errors/{eof_in_istring3.tjp → no_token_match3.tjp} +1 -1
- data/test/TestSuite/Syntax/Errors/{eof_in_istring4.tjp → no_token_match4.tjp} +1 -1
- data/test/TestSuite/Syntax/Errors/{eof_in_istring5.tjp → no_token_match5.tjp} +1 -1
- data/test/TestSuite/Syntax/Errors/not_scheduled.tjp +13 -0
- data/test/TestSuite/Syntax/Errors/unsupported_token.tjp +1 -1
- data/test/TestSuite/TimeSheets/run +5 -5
- data/test/test_CSVFile.rb +75 -0
- data/test/test_Limits.rb +63 -5
- data/test/test_ProjectFileScanner.rb +163 -0
- data/test/test_ReportGenerator.rb +81 -0
- data/test/test_RichText.rb +21 -3
- data/test/test_Scheduler.rb +1 -1
- data/test/test_ShiftAssignments.rb +4 -4
- data/test/test_Syntax.rb +1 -1
- data/test/test_URLParameter.rb +30 -0
- metadata +126 -32
- data/test/TestSuite/Scheduler/Errors/not_scheduled.tjp +0 -8
- data/test/TestSuite/Syntax/Errors/bad_comment.tjp +0 -7
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/boss_2002-03-01.tji +0 -36
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/dev1_2002-03-01.tji +0 -48
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/dev2_2002-03-01.tji +0 -67
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/dev3_2002-03-01.tji +0 -67
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/doc_2002-03-01.tji +0 -48
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/resources.yml +0 -31
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/2002-03-01/test_2002-03-01.tji +0 -36
- data/test/TestSuite/TimeSheets/TimeSheetTemplates/acceptable_intervals +0 -1
- data/test/TestSuite/TimeSheets/TimeSheets/2002-03-01/all.tji +0 -1
- data/test/TestSuite/TimeSheets/TimeSheets/2002-03-01/dev2_2002-03-01.tji +0 -54
- data/test/TestSuite/TimeSheets/TimeSheets/all.tji +0 -2
- data/test/TestSuite/TimeSheets/receiver.log +0 -102
- data/test/TestSuite/TimeSheets/sender.log +0 -794
- data/test/TestSuite/TimeSheets/summary.log +0 -884
- data/test/TestSuite/TimeSheets/timesheets.log +0 -45
- data/test/TestSuite/TimeSheets/tj3d.log +0 -292
- data/test/test_TextScanner.rb +0 -95
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
#!/usr/bin/env ruby -w
|
|
2
|
+
# encoding: UTF-8
|
|
3
|
+
#
|
|
4
|
+
# = WebServer.rb -- The TaskJuggler III Project Management Software
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2006, 2007, 2008, 2009, 2010 by Chris Schlaeger <cs@kde.org>
|
|
7
|
+
#
|
|
8
|
+
# This program is free software; you can redistribute it and/or modify
|
|
9
|
+
# it under the terms of version 2 of the GNU General Public License as
|
|
10
|
+
# published by the Free Software Foundation.
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
require 'drb'
|
|
14
|
+
require 'webrick'
|
|
15
|
+
require 'stringio'
|
|
16
|
+
|
|
17
|
+
require 'AppConfig'
|
|
18
|
+
require 'RichText'
|
|
19
|
+
|
|
20
|
+
# StringIO needs to be extended so we can send $stdout and $stderr over DRb.
|
|
21
|
+
class StringIO
|
|
22
|
+
include DRbUndumped
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class TaskJuggler
|
|
26
|
+
|
|
27
|
+
# The WebServer class provides a self-contained HTTP server that can serve
|
|
28
|
+
# HTML versions of Report objects that are generated on the fly.
|
|
29
|
+
class WebServer
|
|
30
|
+
|
|
31
|
+
attr_reader :broker
|
|
32
|
+
|
|
33
|
+
# Create a web server object that runs in a separate thread.
|
|
34
|
+
def initialize(broker, port)
|
|
35
|
+
@broker = broker
|
|
36
|
+
|
|
37
|
+
config = { :Port => port }
|
|
38
|
+
@server = WEBrick::HTTPServer.new(config)
|
|
39
|
+
@server.mount('/taskjuggler', ReportServlet, @broker)
|
|
40
|
+
|
|
41
|
+
# Serve some directories via the FileHandler servlet.
|
|
42
|
+
%w( css icons scripts ).each do |dir|
|
|
43
|
+
fullDir = AppConfig.dataDirs("data/#{dir}")[0]
|
|
44
|
+
@server.mount("/#{dir}", WEBrick::HTTPServlet::FileHandler, fullDir)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Start the web server in a new thread so we don't block this thread.
|
|
48
|
+
@thread = Thread.new { @server.start }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Stop the web server.
|
|
52
|
+
def stop
|
|
53
|
+
if @server
|
|
54
|
+
@server.shutdown
|
|
55
|
+
@server = nil
|
|
56
|
+
@thread.join
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class ReportServlet < WEBrick::HTTPServlet::AbstractServlet
|
|
63
|
+
|
|
64
|
+
def initialize(config, *options)
|
|
65
|
+
@broker = options[0]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.get_instance(config, options)
|
|
69
|
+
self.new(config, *options)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def do_GET(req, res)
|
|
73
|
+
@req = req
|
|
74
|
+
@res = res
|
|
75
|
+
begin
|
|
76
|
+
projectId = req.query['project']
|
|
77
|
+
reportId = req.query['report']
|
|
78
|
+
if projectId.nil? || reportId.nil?
|
|
79
|
+
generateWelcomePage(projectId)
|
|
80
|
+
else
|
|
81
|
+
attributes = req.query['attributes'] || ''
|
|
82
|
+
generateReport(projectId, reportId, attributes)
|
|
83
|
+
end
|
|
84
|
+
rescue
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def generateReport(projectId, reportId, attributes)
|
|
91
|
+
# Request the Project credentials from the ProbjectBroker.
|
|
92
|
+
@ps_uri, @ps_authKey = @broker.getProject(projectId)
|
|
93
|
+
if @ps_uri.nil?
|
|
94
|
+
error("No project with ID #{projectId} loaded")
|
|
95
|
+
end
|
|
96
|
+
# Get the responsible ReportServer that can generate the report.
|
|
97
|
+
begin
|
|
98
|
+
@projectServer = DRbObject.new(nil, @ps_uri)
|
|
99
|
+
@rs_uri, @rs_authKey = @projectServer.getReportServer(@ps_authKey)
|
|
100
|
+
@reportServer = DRbObject.new(nil, @rs_uri)
|
|
101
|
+
rescue
|
|
102
|
+
error("Cannot get report server")
|
|
103
|
+
end
|
|
104
|
+
# Create two StringIO buffers that will receive the $stdout and $stderr
|
|
105
|
+
# text from the report server. This buffer will contain the generated
|
|
106
|
+
# report as HTML encoded text.
|
|
107
|
+
stdOut = StringIO.new('')
|
|
108
|
+
stdErr = StringIO.new('')
|
|
109
|
+
begin
|
|
110
|
+
@reportServer.connect(@rs_authKey, stdOut, stdErr, $stdin, true)
|
|
111
|
+
rescue
|
|
112
|
+
error("Can't connect IO: #{$!}")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Ask the ReportServer to generate the reports with the provided ID.
|
|
116
|
+
begin
|
|
117
|
+
@reportServer.generateReport(@rs_authKey, reportId, false, attributes)
|
|
118
|
+
rescue
|
|
119
|
+
stdOut.rewind
|
|
120
|
+
stdErr.rewind
|
|
121
|
+
error("Report server crashed: #{$!}\n#{stdErr.read}\n#{stdOut.read}")
|
|
122
|
+
end
|
|
123
|
+
# Disconnect the ReportServer
|
|
124
|
+
begin
|
|
125
|
+
@reportServer.disconnect(@rs_authKey)
|
|
126
|
+
rescue
|
|
127
|
+
error("Can't disconnect IO: #{$!}")
|
|
128
|
+
end
|
|
129
|
+
# And send a termination request.
|
|
130
|
+
begin
|
|
131
|
+
@reportServer.terminate(@rs_authKey)
|
|
132
|
+
rescue
|
|
133
|
+
error("Report server termination failed: #{$!}")
|
|
134
|
+
end
|
|
135
|
+
@reportServer = nil
|
|
136
|
+
|
|
137
|
+
@res['content-type'] = 'text/html'
|
|
138
|
+
stdErr.rewind
|
|
139
|
+
$stderr.puts stdErr.read
|
|
140
|
+
# To read the $stdout of the ReportServer we need to rewind the buffer
|
|
141
|
+
# and then read the full text.
|
|
142
|
+
stdOut.rewind
|
|
143
|
+
@res.body = stdOut.read
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def generateWelcomePage(projectId)
|
|
147
|
+
projects = @broker.getProjectList
|
|
148
|
+
|
|
149
|
+
text = "== Welcome to the TaskJuggler Project Server ==\n----\n"
|
|
150
|
+
projects.each do |id|
|
|
151
|
+
if id == projectId
|
|
152
|
+
# Show the list of reports for this project.
|
|
153
|
+
text << "* [/taskjuggler #{getProjectName(id)}]\n"
|
|
154
|
+
reports = getReportList(id)
|
|
155
|
+
if reports.empty?
|
|
156
|
+
text << "** This project has no reports defined.\n"
|
|
157
|
+
else
|
|
158
|
+
reports.each do |reportId, reportName|
|
|
159
|
+
text << "** [/taskjuggler?project=#{id};report=#{reportId} " +
|
|
160
|
+
"#{reportName}]\n"
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
else
|
|
164
|
+
# Just show a link to open the report list.
|
|
165
|
+
text << "* [/taskjuggler?project=#{id} #{getProjectName(id)}]\n"
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
rt = RichText.new(text)
|
|
169
|
+
rti = rt.generateIntermediateFormat
|
|
170
|
+
rti.sectionNumbers = false
|
|
171
|
+
page = HTMLDocument.new
|
|
172
|
+
page.generateHead("The TaskJuggler Project Server")
|
|
173
|
+
page << rti.to_html
|
|
174
|
+
@res['content-type'] = 'text/html'
|
|
175
|
+
@res.body = page.to_s
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def getProjectName(id)
|
|
179
|
+
uri, authKey = @broker.getProject(id)
|
|
180
|
+
return nil unless uri
|
|
181
|
+
projectServer = DRbObject.new(nil, uri)
|
|
182
|
+
return nil unless projectServer
|
|
183
|
+
projectServer.getProjectName(authKey)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def getReportList(id)
|
|
187
|
+
uri, authKey = @broker.getProject(id)
|
|
188
|
+
return [] unless uri
|
|
189
|
+
projectServer = DRbObject.new(nil, uri)
|
|
190
|
+
return [] unless projectServer
|
|
191
|
+
projectServer.getReportList(authKey)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def error(message)
|
|
195
|
+
@res.status = 412
|
|
196
|
+
@res.body = "ERROR: #{message}"
|
|
197
|
+
@res['content-type'] = 'text/plain'
|
|
198
|
+
raise "Error: #{message}"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
end
|
|
204
|
+
|
data/lib/deep_copy.rb
CHANGED
|
@@ -34,7 +34,10 @@ class Object
|
|
|
34
34
|
# This is a variant of Object#clone that returns a deep copy of an object.
|
|
35
35
|
def deep_clone
|
|
36
36
|
# We can't clone frozen objects. So just return a reference to them.
|
|
37
|
-
|
|
37
|
+
# Built-in classed can't be cloned either. The check below is probably
|
|
38
|
+
# cheaper than the frequent (hiddent) exceptions from those objects.
|
|
39
|
+
return self if frozen? || nil? || is_a?(Fixnum) || is_a?(Float) ||
|
|
40
|
+
is_a?(TrueClass) || is_a?(FalseClass)
|
|
38
41
|
|
|
39
42
|
# In case we have loops in our graph, we return references, not
|
|
40
43
|
# deep-copied objects.
|
data/lib/reports/CSVFile.rb
CHANGED
|
@@ -19,12 +19,16 @@ class TaskJuggler
|
|
|
19
19
|
# Hence we use our own class.
|
|
20
20
|
class CSVFile
|
|
21
21
|
|
|
22
|
+
attr_reader :data
|
|
23
|
+
|
|
22
24
|
# At construction time you need to specify the +data+ container. This is an
|
|
23
25
|
# Array of Arrays that holds the table. Optionally, you can specify a
|
|
24
26
|
# +separator+ and a +quote+ string for the CSV file.
|
|
25
|
-
def initialize(data, separator = ';', quote = '"')
|
|
27
|
+
def initialize(data = nil, separator = ';', quote = '"')
|
|
26
28
|
@data = data
|
|
29
|
+
raise "Illegal separator: #{separator}" if '."'.include?(separator)
|
|
27
30
|
@separator = separator
|
|
31
|
+
raise "Illegal quote: #{separator}" if quote == '.'
|
|
28
32
|
@quote = quote
|
|
29
33
|
end
|
|
30
34
|
|
|
@@ -37,19 +41,7 @@ class TaskJuggler
|
|
|
37
41
|
file = File.open(fileName, 'w')
|
|
38
42
|
end
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
first = true
|
|
42
|
-
line.each do |field|
|
|
43
|
-
# Don't output a separator before the first field of the line.
|
|
44
|
-
if first
|
|
45
|
-
first = false
|
|
46
|
-
else
|
|
47
|
-
file.write @separator
|
|
48
|
-
end
|
|
49
|
-
file.write(marshal(field))
|
|
50
|
-
end
|
|
51
|
-
file.write "\n"
|
|
52
|
-
end
|
|
44
|
+
file.write(to_s)
|
|
53
45
|
|
|
54
46
|
file.close unless fileName == '.'
|
|
55
47
|
end
|
|
@@ -63,81 +55,173 @@ class TaskJuggler
|
|
|
63
55
|
file = File.open(fileName, 'r')
|
|
64
56
|
end
|
|
65
57
|
|
|
66
|
-
|
|
67
|
-
file.each_line do |line|
|
|
68
|
-
csv << parseLine(line)
|
|
69
|
-
end
|
|
58
|
+
@data = parse(file.read)
|
|
70
59
|
|
|
71
60
|
file.close unless fileName == '.'
|
|
72
|
-
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Read the data as Array of Arrays from a CSV formated String +str+.
|
|
76
|
-
def parse(str)
|
|
77
|
-
csv = []
|
|
78
|
-
str.each_line do |line|
|
|
79
|
-
csv << parseLine(line)
|
|
80
|
-
end
|
|
61
|
+
@data
|
|
81
62
|
end
|
|
82
63
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
64
|
+
# Convert the CSV data into a CSV formatted String.
|
|
65
|
+
def to_s
|
|
66
|
+
s = ''
|
|
67
|
+
@data.each do |line|
|
|
68
|
+
first = true
|
|
69
|
+
line.each do |field|
|
|
70
|
+
# Don't output a separator before the first field of the line.
|
|
71
|
+
if first
|
|
72
|
+
first = false
|
|
73
|
+
else
|
|
74
|
+
s << @separator
|
|
75
|
+
end
|
|
76
|
+
s << marshal(field)
|
|
77
|
+
end
|
|
78
|
+
s << "\n"
|
|
91
79
|
end
|
|
92
|
-
|
|
80
|
+
s
|
|
93
81
|
end
|
|
94
82
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
@
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
83
|
+
# Read the data as Array of Arrays from a CSV formated String +str+.
|
|
84
|
+
def parse(str)
|
|
85
|
+
@data = []
|
|
86
|
+
state = :startOfRecord
|
|
87
|
+
fields = field = quoted = nil
|
|
88
|
+
|
|
89
|
+
# Make sure the input is terminated with a record end.
|
|
90
|
+
str += "\n" unless str[-1] == ?\n
|
|
91
|
+
|
|
92
|
+
str.each_utf8_char do |c|
|
|
93
|
+
#puts "c: #{c} State: #{state}"
|
|
94
|
+
case state
|
|
95
|
+
when :startOfRecord
|
|
96
|
+
# This will store the fields of a record
|
|
97
|
+
fields = []
|
|
98
|
+
state = :startOfField
|
|
99
|
+
redo
|
|
100
|
+
when :startOfField
|
|
101
|
+
field = ''
|
|
102
|
+
quoted = false
|
|
102
103
|
if c == @quote
|
|
103
|
-
|
|
104
|
+
# We've found the start of a quoted field.
|
|
105
|
+
state = :inQuotedField
|
|
106
|
+
quoted = true
|
|
107
|
+
elsif c == @separator || c == "\n"
|
|
108
|
+
# We've found an empty field
|
|
109
|
+
field = nil
|
|
110
|
+
state = :fieldEnd
|
|
111
|
+
redo
|
|
104
112
|
else
|
|
105
|
-
|
|
106
|
-
|
|
113
|
+
# We've found the first character of an unquoted field
|
|
114
|
+
field << c
|
|
115
|
+
state = :inUnquotedField
|
|
107
116
|
end
|
|
108
|
-
when
|
|
117
|
+
when :inQuotedField
|
|
118
|
+
# We are processing the content of a quoted field
|
|
109
119
|
if c == @quote
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
closeField
|
|
120
|
+
# This could be then end of the field or a quoted quote.
|
|
121
|
+
state = :quoteInQuotedField
|
|
113
122
|
else
|
|
114
|
-
|
|
123
|
+
# We've found a normal character of the quoted field
|
|
124
|
+
field << c
|
|
115
125
|
end
|
|
116
|
-
when
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
when :quoteInQuotedField
|
|
127
|
+
# We are processing a quoted quote or the end of a quoted field
|
|
128
|
+
if c == @quote
|
|
129
|
+
# We've found a quoted quote
|
|
130
|
+
field << c
|
|
131
|
+
state = :inQuotedField
|
|
132
|
+
elsif c == @separator || c == "\n"
|
|
133
|
+
state = :fieldEnd
|
|
134
|
+
redo
|
|
119
135
|
else
|
|
120
|
-
|
|
136
|
+
raise "Unexpected character #{c} in CSV"
|
|
121
137
|
end
|
|
122
|
-
when
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
138
|
+
when :inUnquotedField
|
|
139
|
+
# We are processing an unquoted field
|
|
140
|
+
if c == @separator || c == "\n"
|
|
141
|
+
# We've found the end of a unquoted field
|
|
142
|
+
state = :fieldEnd
|
|
143
|
+
redo
|
|
126
144
|
else
|
|
127
|
-
|
|
145
|
+
# A normal character of an unquoted field
|
|
146
|
+
field << c
|
|
128
147
|
end
|
|
148
|
+
when :fieldEnd
|
|
149
|
+
# We've completed processing a field. Add the field to the list of
|
|
150
|
+
# fields. Convert Fixnums and Floats in native types.
|
|
151
|
+
fields << unMarshal(field, quoted)
|
|
152
|
+
|
|
153
|
+
if c == "\n"
|
|
154
|
+
# The field end is an end of a record as well.
|
|
155
|
+
state = :recordEnd
|
|
156
|
+
redo
|
|
157
|
+
else
|
|
158
|
+
# Get the next field.
|
|
159
|
+
state = :startOfField
|
|
160
|
+
end
|
|
161
|
+
when :recordEnd
|
|
162
|
+
# We've found the end of a record. Add fields to the @data
|
|
163
|
+
# structure.
|
|
164
|
+
@data << fields
|
|
165
|
+
# Look for a new record.
|
|
166
|
+
state = :startOfRecord
|
|
129
167
|
else
|
|
130
168
|
raise "Unknown state #{state}"
|
|
131
169
|
end
|
|
132
170
|
end
|
|
133
|
-
|
|
134
|
-
|
|
171
|
+
|
|
172
|
+
unless state == :startOfRecord
|
|
173
|
+
raise "CSV state machine error in state #{state}"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
@data
|
|
135
177
|
end
|
|
136
178
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
179
|
+
# Utility function that tries to convert a String into a native type that
|
|
180
|
+
# is supported by the CSVFile generator. If no native type is found, the
|
|
181
|
+
# input String _str_ will be returned unmodified. nil is returned as nil.
|
|
182
|
+
def CSVFile.strToNative(str)
|
|
183
|
+
if str.nil?
|
|
184
|
+
nil
|
|
185
|
+
elsif /^[-+]?\d+$/ =~ str
|
|
186
|
+
# field is a Fixnum
|
|
187
|
+
str.to_i
|
|
188
|
+
elsif /^[-+]?\d*\.?\d+([eE][-+]?\d+)?$/ =~ str
|
|
189
|
+
# field is a Float
|
|
190
|
+
str.to_f
|
|
191
|
+
else
|
|
192
|
+
# Everything else is kept as String
|
|
193
|
+
str
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
private
|
|
198
|
+
|
|
199
|
+
# This function is used to properly quote @quote and @separation
|
|
200
|
+
# characters contained in the +field+.
|
|
201
|
+
def marshal(field)
|
|
202
|
+
if field.nil?
|
|
203
|
+
''
|
|
204
|
+
elsif field.is_a?(Fixnum) || field.is_a?(Float)
|
|
205
|
+
# Numbers don't have to be quoted.
|
|
206
|
+
field.to_s
|
|
207
|
+
else
|
|
208
|
+
# Duplicate quote characters.
|
|
209
|
+
f = field.gsub(/@quote/, "#{@quote * 2}")
|
|
210
|
+
# Enclose the field in quote characters
|
|
211
|
+
@quote + f.to_s + @quote
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# Convert the String _field_ into a native Ruby type. If field was
|
|
216
|
+
# _quoted_, the result is always the String.
|
|
217
|
+
def unMarshal(field, quoted)
|
|
218
|
+
# Quoted Strings and nil are returned verbatim.
|
|
219
|
+
if quoted || field.nil?
|
|
220
|
+
field
|
|
221
|
+
else
|
|
222
|
+
# Unquoted fields are inspected for special types
|
|
223
|
+
CSVFile.strToNative(field)
|
|
224
|
+
end
|
|
141
225
|
end
|
|
142
226
|
|
|
143
227
|
end
|