taskjuggler 0.0.6 → 0.0.7

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.
Files changed (545) hide show
  1. data/CHANGELOG +160 -0
  2. data/benchmarks/UTF-8-Strings.rb +58 -0
  3. data/data/css/tjreport.css +7 -2
  4. data/doc/AppConfig.html +10 -4
  5. data/doc/Arguments.html +10 -4
  6. data/doc/CHANGELOG.html +171 -5
  7. data/doc/COPYING.html +10 -4
  8. data/doc/Object.html +11 -107
  9. data/doc/README.html +10 -4
  10. data/doc/RuntimeConfig.html +10 -4
  11. data/doc/String.html +16 -11
  12. data/doc/StringIO.html +10 -4
  13. data/doc/TaskJuggler.html +506 -435
  14. data/doc/TaskJuggler/Account.html +10 -4
  15. data/doc/TaskJuggler/AccountAttribute.html +10 -4
  16. data/doc/TaskJuggler/AccountScenario.html +10 -4
  17. data/doc/TaskJuggler/Allocation.html +69 -60
  18. data/doc/TaskJuggler/AllocationAttribute.html +10 -4
  19. data/doc/TaskJuggler/AttributeBase.html +10 -4
  20. data/doc/TaskJuggler/AttributeDefinition.html +10 -4
  21. data/doc/TaskJuggler/BatchProcessor.html +202 -192
  22. data/doc/TaskJuggler/Booking.html +10 -4
  23. data/doc/TaskJuggler/BookingListAttribute.html +10 -4
  24. data/doc/TaskJuggler/BooleanAttribute.html +10 -4
  25. data/doc/TaskJuggler/CSVFile.html +10 -4
  26. data/doc/TaskJuggler/CellSettingPattern.html +10 -4
  27. data/doc/TaskJuggler/CellSettingPatternList.html +10 -4
  28. data/doc/TaskJuggler/Charge.html +10 -4
  29. data/doc/TaskJuggler/ChargeListAttribute.html +10 -4
  30. data/doc/TaskJuggler/ChargeSet.html +10 -4
  31. data/doc/TaskJuggler/ChargeSetListAttribute.html +10 -4
  32. data/doc/TaskJuggler/ColumnListAttribute.html +10 -4
  33. data/doc/TaskJuggler/ColumnTable.html +10 -4
  34. data/doc/TaskJuggler/Daemon.html +71 -52
  35. data/doc/TaskJuggler/DateAttribute.html +10 -4
  36. data/doc/TaskJuggler/DefinitionListAttribute.html +10 -4
  37. data/doc/TaskJuggler/DependencyListAttribute.html +10 -4
  38. data/doc/TaskJuggler/DurationAttribute.html +10 -4
  39. data/doc/TaskJuggler/{MacroParser.html → FileList.html} +58 -173
  40. data/doc/TaskJuggler/{RichTextException.html → FileRecord.html} +59 -80
  41. data/doc/TaskJuggler/FixnumAttribute.html +10 -4
  42. data/doc/TaskJuggler/FlagListAttribute.html +10 -4
  43. data/doc/TaskJuggler/FloatAttribute.html +10 -4
  44. data/doc/TaskJuggler/FormatListAttribute.html +10 -4
  45. data/doc/TaskJuggler/GanttChart.html +10 -4
  46. data/doc/TaskJuggler/GanttContainer.html +14 -8
  47. data/doc/TaskJuggler/GanttHeader.html +10 -4
  48. data/doc/TaskJuggler/GanttHeaderScaleItem.html +10 -4
  49. data/doc/TaskJuggler/GanttLine.html +29 -24
  50. data/doc/TaskJuggler/GanttLoadStack.html +10 -4
  51. data/doc/TaskJuggler/GanttMilestone.html +10 -4
  52. data/doc/TaskJuggler/GanttRouter.html +10 -4
  53. data/doc/TaskJuggler/GanttTaskBar.html +20 -10
  54. data/doc/TaskJuggler/HTMLDocument.html +10 -4
  55. data/doc/TaskJuggler/HTMLGraphics.html +10 -4
  56. data/doc/TaskJuggler/Interval.html +10 -4
  57. data/doc/TaskJuggler/IntervalListAttribute.html +10 -4
  58. data/doc/TaskJuggler/JobInfo.html +10 -4
  59. data/doc/TaskJuggler/Journal.html +227 -160
  60. data/doc/TaskJuggler/JournalEntry.html +10 -4
  61. data/doc/TaskJuggler/JournalEntryList.html +158 -72
  62. data/doc/TaskJuggler/KeywordArray.html +21 -9
  63. data/doc/TaskJuggler/KeywordDocumentation.html +612 -475
  64. data/doc/TaskJuggler/Limits.html +13 -8
  65. data/doc/TaskJuggler/Limits/Limit.html +10 -4
  66. data/doc/TaskJuggler/LimitsAttribute.html +10 -4
  67. data/doc/TaskJuggler/ListAttributeBase.html +10 -4
  68. data/doc/TaskJuggler/Log.html +10 -4
  69. data/doc/TaskJuggler/LogFile.html +10 -4
  70. data/doc/TaskJuggler/LogicalAttribute.html +10 -4
  71. data/doc/TaskJuggler/LogicalExpression.html +11 -5
  72. data/doc/TaskJuggler/LogicalExpressionAttribute.html +10 -4
  73. data/doc/TaskJuggler/LogicalFlag.html +10 -4
  74. data/doc/TaskJuggler/LogicalFunction.html +132 -124
  75. data/doc/TaskJuggler/LogicalOperation.html +10 -4
  76. data/doc/TaskJuggler/Macro.html +16 -10
  77. data/doc/TaskJuggler/MacroTable.html +44 -38
  78. data/doc/TaskJuggler/ManagerResponsibilities.html +10 -4
  79. data/doc/TaskJuggler/ManagerStatusRecord.html +10 -4
  80. data/doc/TaskJuggler/Message.html +92 -68
  81. data/doc/TaskJuggler/MessageHandler.html +349 -28
  82. data/doc/TaskJuggler/Navigator.html +10 -4
  83. data/doc/TaskJuggler/NavigatorElement.html +10 -4
  84. data/doc/TaskJuggler/NikuProject.html +10 -4
  85. data/doc/TaskJuggler/NikuReport.html +10 -4
  86. data/doc/TaskJuggler/NikuResource.html +10 -4
  87. data/doc/TaskJuggler/NodeListAttribute.html +10 -4
  88. data/doc/TaskJuggler/OnShiftCache.html +10 -4
  89. data/doc/TaskJuggler/ProcessIntercom.html +118 -111
  90. data/doc/TaskJuggler/ProcessIntercomIface.html +75 -22
  91. data/doc/TaskJuggler/Project.html +886 -913
  92. data/doc/TaskJuggler/ProjectBroker.html +442 -331
  93. data/doc/TaskJuggler/ProjectBrokerIface.html +95 -38
  94. data/doc/TaskJuggler/ProjectFileParser.html +320 -317
  95. data/doc/TaskJuggler/ProjectFileScanner.html +336 -339
  96. data/doc/TaskJuggler/ProjectRecord.html +119 -56
  97. data/doc/TaskJuggler/ProjectServer.html +282 -237
  98. data/doc/TaskJuggler/ProjectServerIface.html +45 -39
  99. data/doc/TaskJuggler/PropertyAttribute.html +10 -4
  100. data/doc/TaskJuggler/PropertyList.html +177 -173
  101. data/doc/TaskJuggler/PropertySet.html +11 -5
  102. data/doc/TaskJuggler/PropertyTreeNode.html +194 -191
  103. data/doc/TaskJuggler/Query.html +280 -256
  104. data/doc/TaskJuggler/RTFHandlers.html +10 -4
  105. data/doc/TaskJuggler/RTFNavigator.html +33 -26
  106. data/doc/TaskJuggler/RTFQuery.html +135 -169
  107. data/doc/TaskJuggler/RTFReport.html +63 -56
  108. data/doc/TaskJuggler/RTFReportLink.html +58 -47
  109. data/doc/TaskJuggler/RTFWithQuerySupport.html +666 -0
  110. data/doc/TaskJuggler/RealFormat.html +10 -4
  111. data/doc/TaskJuggler/RealFormatAttribute.html +10 -4
  112. data/doc/TaskJuggler/ReferenceAttribute.html +10 -4
  113. data/doc/TaskJuggler/Report.html +333 -290
  114. data/doc/TaskJuggler/ReportBase.html +182 -174
  115. data/doc/TaskJuggler/ReportContext.html +10 -4
  116. data/doc/TaskJuggler/ReportServer.html +144 -126
  117. data/doc/TaskJuggler/ReportServerIface.html +50 -44
  118. data/doc/TaskJuggler/ReportServerRecord.html +38 -32
  119. data/doc/TaskJuggler/ReportServlet.html +144 -137
  120. data/doc/TaskJuggler/ReportTable.html +10 -4
  121. data/doc/TaskJuggler/ReportTableCell.html +169 -164
  122. data/doc/TaskJuggler/ReportTableColumn.html +10 -4
  123. data/doc/TaskJuggler/ReportTableLegend.html +10 -4
  124. data/doc/TaskJuggler/ReportTableLine.html +10 -4
  125. data/doc/TaskJuggler/Resource.html +121 -115
  126. data/doc/TaskJuggler/ResourceListAttribute.html +10 -4
  127. data/doc/TaskJuggler/ResourceListRE.html +10 -4
  128. data/doc/TaskJuggler/ResourceScenario.html +13 -7
  129. data/doc/TaskJuggler/RichText.html +61 -37
  130. data/doc/TaskJuggler/RichTextAttribute.html +10 -4
  131. data/doc/TaskJuggler/RichTextDocument.html +91 -81
  132. data/doc/TaskJuggler/RichTextElement.html +378 -317
  133. data/doc/TaskJuggler/RichTextFunctionExample.html +10 -4
  134. data/doc/TaskJuggler/RichTextFunctionHandler.html +16 -11
  135. data/doc/TaskJuggler/RichTextImage.html +10 -4
  136. data/doc/TaskJuggler/RichTextIntermediate.html +138 -70
  137. data/doc/TaskJuggler/RichTextParser.html +48 -40
  138. data/doc/TaskJuggler/RichTextScanner.html +328 -906
  139. data/doc/TaskJuggler/RichTextSnip.html +59 -57
  140. data/doc/TaskJuggler/RichTextSyntaxRules.html +458 -369
  141. data/doc/TaskJuggler/Scenario.html +10 -4
  142. data/doc/TaskJuggler/ScenarioData.html +33 -30
  143. data/doc/TaskJuggler/ScenarioListAttribute.html +10 -4
  144. data/doc/TaskJuggler/Scoreboard.html +10 -4
  145. data/doc/TaskJuggler/SheetHandlerBase.html +315 -191
  146. data/doc/TaskJuggler/SheetReceiver.html +334 -313
  147. data/doc/TaskJuggler/SheetSender.html +10 -4
  148. data/doc/TaskJuggler/Shift.html +10 -4
  149. data/doc/TaskJuggler/ShiftAssignment.html +10 -4
  150. data/doc/TaskJuggler/ShiftAssignments.html +10 -4
  151. data/doc/TaskJuggler/ShiftAssignmentsAttribute.html +10 -4
  152. data/doc/TaskJuggler/ShiftScenario.html +10 -4
  153. data/doc/TaskJuggler/SimpleQueryExpander.html +697 -0
  154. data/doc/TaskJuggler/SortListAttribute.html +10 -4
  155. data/doc/TaskJuggler/SourceFileInfo.html +10 -4
  156. data/doc/TaskJuggler/StatusSheetReceiver.html +10 -4
  157. data/doc/TaskJuggler/StatusSheetReport.html +10 -4
  158. data/doc/TaskJuggler/StatusSheetSender.html +10 -4
  159. data/doc/TaskJuggler/StringAttribute.html +10 -4
  160. data/doc/TaskJuggler/SymbolAttribute.html +10 -4
  161. data/doc/TaskJuggler/SyntaxReference.html +260 -230
  162. data/doc/TaskJuggler/TOCEntry.html +99 -42
  163. data/doc/TaskJuggler/TSResourceRecord.html +10 -4
  164. data/doc/TaskJuggler/TSTaskRecord.html +10 -4
  165. data/doc/TaskJuggler/TableColumnDefinition.html +10 -4
  166. data/doc/TaskJuggler/TableOfContents.html +54 -12
  167. data/doc/TaskJuggler/TableReport.html +877 -872
  168. data/doc/TaskJuggler/Task.html +117 -68
  169. data/doc/TaskJuggler/TaskDependency.html +10 -4
  170. data/doc/TaskJuggler/TaskListAttribute.html +10 -4
  171. data/doc/TaskJuggler/TaskListRE.html +10 -4
  172. data/doc/TaskJuggler/TaskScenario.html +1681 -1563
  173. data/doc/TaskJuggler/TextFormatter.html +10 -4
  174. data/doc/TaskJuggler/TextParser.html +567 -534
  175. data/doc/TaskJuggler/TextParser/Pattern.html +128 -118
  176. data/doc/TaskJuggler/TextParser/Rule.html +26 -15
  177. data/doc/TaskJuggler/TextParser/StackElement.html +10 -4
  178. data/doc/TaskJuggler/TextParser/TextParserResultArray.html +22 -16
  179. data/doc/TaskJuggler/TextParser/TokenDoc.html +10 -4
  180. data/doc/TaskJuggler/TextReport.html +15 -6
  181. data/doc/TaskJuggler/TextScanner.html +319 -287
  182. data/doc/TaskJuggler/TextScanner/BufferStreamHandle.html +16 -10
  183. data/doc/TaskJuggler/TextScanner/FileStreamHandle.html +23 -17
  184. data/doc/TaskJuggler/TextScanner/MacroStackEntry.html +17 -11
  185. data/doc/TaskJuggler/TextScanner/StreamHandle.html +102 -96
  186. data/doc/TaskJuggler/TimeSheet.html +138 -175
  187. data/doc/TaskJuggler/TimeSheetReceiver.html +10 -4
  188. data/doc/TaskJuggler/TimeSheetRecord.html +65 -58
  189. data/doc/TaskJuggler/TimeSheetReport.html +47 -42
  190. data/doc/TaskJuggler/TimeSheetSender.html +10 -4
  191. data/doc/TaskJuggler/TimeSheetSummary.html +91 -83
  192. data/doc/TaskJuggler/TimeSheets.html +22 -16
  193. data/doc/TaskJuggler/Tj3AppBase.html +10 -4
  194. data/doc/TaskJuggler/Tj3Client.html +399 -365
  195. data/doc/TaskJuggler/Tj3Daemon.html +107 -94
  196. data/doc/TaskJuggler/Tj3SheetAppBase.html +10 -4
  197. data/doc/TaskJuggler/Tj3SsReceiver.html +10 -4
  198. data/doc/TaskJuggler/Tj3SsSender.html +10 -4
  199. data/doc/TaskJuggler/Tj3TsReceiver.html +10 -4
  200. data/doc/TaskJuggler/Tj3TsSender.html +10 -4
  201. data/doc/TaskJuggler/Tj3TsSummary.html +10 -4
  202. data/doc/TaskJuggler/TjException.html +10 -4
  203. data/doc/TaskJuggler/TjTime.html +145 -140
  204. data/doc/TaskJuggler/TjpExample.html +10 -4
  205. data/doc/TaskJuggler/TjpExportRE.html +122 -118
  206. data/doc/TaskJuggler/TjpSyntaxRules.html +4065 -4052
  207. data/doc/TaskJuggler/URLParameter.html +10 -4
  208. data/doc/TaskJuggler/UserManual.html +162 -155
  209. data/doc/TaskJuggler/VimSyntax.html +1028 -0
  210. data/doc/TaskJuggler/WebServer.html +45 -27
  211. data/doc/TaskJuggler/WorkingHours.html +10 -4
  212. data/doc/TaskJuggler/WorkingHoursAttribute.html +10 -4
  213. data/doc/TaskJuggler/XMLBlob.html +10 -4
  214. data/doc/TaskJuggler/XMLComment.html +10 -4
  215. data/doc/TaskJuggler/XMLDocument.html +10 -4
  216. data/doc/TaskJuggler/XMLElement.html +10 -4
  217. data/doc/TaskJuggler/XMLNamedText.html +10 -4
  218. data/doc/TaskJuggler/XMLText.html +10 -4
  219. data/doc/index.html +735 -677
  220. data/doc/lib/AccountScenario_rb.html +1 -1
  221. data/doc/lib/Account_rb.html +1 -1
  222. data/doc/lib/Allocation_rb.html +1 -1
  223. data/doc/lib/AppConfig_rb.html +1 -1
  224. data/doc/lib/AttributeBase_rb.html +1 -1
  225. data/doc/lib/AttributeDefinition_rb.html +1 -1
  226. data/doc/lib/Attributes_rb.html +1 -1
  227. data/doc/lib/BatchProcessor_rb.html +1 -1
  228. data/doc/lib/Booking_rb.html +1 -1
  229. data/doc/lib/ChargeSet_rb.html +1 -1
  230. data/doc/lib/Charge_rb.html +1 -1
  231. data/doc/lib/{Message_rb.html → FileList_rb.html} +3 -5
  232. data/doc/lib/HTMLDocument_rb.html +1 -1
  233. data/doc/lib/Interval_rb.html +1 -1
  234. data/doc/lib/Journal_rb.html +1 -1
  235. data/doc/lib/KeywordArray_rb.html +1 -1
  236. data/doc/lib/KeywordDocumentation_rb.html +1 -1
  237. data/doc/lib/Limits_rb.html +1 -1
  238. data/doc/lib/LogFile_rb.html +1 -1
  239. data/doc/lib/Log_rb.html +1 -1
  240. data/doc/lib/LogicalExpression_rb.html +1 -1
  241. data/doc/lib/LogicalFunction_rb.html +1 -1
  242. data/doc/lib/LogicalOperation_rb.html +1 -1
  243. data/doc/lib/MacroTable_rb.html +1 -3
  244. data/doc/lib/MessageHandler_rb.html +1 -1
  245. data/doc/lib/ProjectFileParser_rb.html +1 -1
  246. data/doc/lib/ProjectFileScanner_rb.html +1 -1
  247. data/doc/lib/Project_rb.html +4 -2
  248. data/doc/lib/PropertyList_rb.html +1 -1
  249. data/doc/lib/PropertySet_rb.html +1 -1
  250. data/doc/lib/PropertyTreeNode_rb.html +1 -1
  251. data/doc/lib/Query_rb.html +1 -1
  252. data/doc/lib/RTFHandlers_rb.html +1 -1
  253. data/doc/lib/RTFNavigator_rb.html +1 -1
  254. data/doc/lib/RTFQuery_rb.html +2 -2
  255. data/doc/lib/RTFReportLink_rb.html +4 -2
  256. data/doc/lib/RTFReport_rb.html +1 -1
  257. data/doc/lib/{MacroParser_rb.html → RTFWithQuerySupport_rb.html} +4 -6
  258. data/doc/lib/RealFormat_rb.html +1 -1
  259. data/doc/lib/ResourceScenario_rb.html +1 -1
  260. data/doc/lib/Resource_rb.html +1 -1
  261. data/doc/lib/RichTextDocument_rb.html +1 -1
  262. data/doc/lib/RichTextElement_rb.html +1 -1
  263. data/doc/lib/RichTextFunctionExample_rb.html +1 -1
  264. data/doc/lib/RichTextFunctionHandler_rb.html +1 -1
  265. data/doc/lib/RichTextParser_rb.html +1 -1
  266. data/doc/lib/RichTextScanner_rb.html +3 -1
  267. data/doc/lib/RichTextSnip_rb.html +1 -1
  268. data/doc/lib/RichTextSyntaxRules_rb.html +1 -1
  269. data/doc/lib/RichText_rb.html +3 -1
  270. data/doc/lib/RuntimeConfig_rb.html +1 -1
  271. data/doc/lib/ScenarioData_rb.html +2 -2
  272. data/doc/lib/Scenario_rb.html +1 -1
  273. data/doc/lib/Scoreboard_rb.html +1 -1
  274. data/doc/lib/SheetHandlerBase_rb.html +5 -1
  275. data/doc/lib/SheetReceiver_rb.html +3 -1
  276. data/doc/lib/SheetSender_rb.html +1 -1
  277. data/doc/lib/ShiftAssignments_rb.html +1 -1
  278. data/doc/lib/ShiftScenario_rb.html +1 -1
  279. data/doc/lib/Shift_rb.html +1 -1
  280. data/doc/lib/SimpleQueryExpander_rb.html +67 -0
  281. data/doc/lib/SourceFileInfo_rb.html +1 -1
  282. data/doc/lib/StatusSheetReceiver_rb.html +1 -1
  283. data/doc/lib/StatusSheetSender_rb.html +1 -1
  284. data/doc/lib/SyntaxReference_rb.html +1 -1
  285. data/doc/lib/TOCEntry_rb.html +1 -1
  286. data/doc/lib/TableColumnDefinition_rb.html +1 -1
  287. data/doc/lib/TableOfContents_rb.html +1 -1
  288. data/doc/lib/TaskDependency_rb.html +1 -1
  289. data/doc/lib/TaskJuggler_rb.html +1 -1
  290. data/doc/lib/TaskScenario_rb.html +1 -1
  291. data/doc/lib/Task_rb.html +1 -1
  292. data/doc/lib/TextFormatter_rb.html +1 -1
  293. data/doc/lib/TextParser/Pattern_rb.html +1 -1
  294. data/doc/lib/TextParser/Rule_rb.html +1 -1
  295. data/doc/lib/TextParser/StackElement_rb.html +1 -1
  296. data/doc/lib/TextParser/TokenDoc_rb.html +1 -1
  297. data/doc/lib/TextParser_rb.html +3 -1
  298. data/doc/lib/TextScanner_rb.html +1 -3
  299. data/doc/lib/TimeSheetReceiver_rb.html +1 -1
  300. data/doc/lib/TimeSheetSender_rb.html +1 -1
  301. data/doc/lib/TimeSheetSummary_rb.html +1 -1
  302. data/doc/lib/TimeSheets_rb.html +1 -1
  303. data/doc/lib/Tj3AppBase_rb.html +1 -1
  304. data/doc/lib/Tj3Config_rb.html +1 -1
  305. data/doc/lib/Tj3SheetAppBase_rb.html +1 -1
  306. data/doc/lib/TjException_rb.html +1 -1
  307. data/doc/lib/TjTime_rb.html +1 -1
  308. data/doc/lib/TjpExample_rb.html +1 -1
  309. data/doc/lib/TjpSyntaxRules_rb.html +1 -1
  310. data/doc/lib/URLParameter_rb.html +1 -1
  311. data/doc/lib/UTF8String_rb.html +1 -1
  312. data/doc/lib/UserManual_rb.html +1 -1
  313. data/doc/lib/{ruby-signal-bug_rb.html → VimSyntax_rb.html} +17 -4
  314. data/doc/lib/WorkingHours_rb.html +1 -1
  315. data/doc/lib/XMLDocument_rb.html +1 -1
  316. data/doc/lib/XMLElement_rb.html +1 -1
  317. data/doc/lib/daemon/Daemon_rb.html +1 -1
  318. data/doc/lib/daemon/ProcessIntercom_rb.html +1 -1
  319. data/doc/lib/daemon/ProjectBroker_rb.html +1 -1
  320. data/doc/lib/daemon/ProjectServer_rb.html +1 -1
  321. data/doc/lib/daemon/ReportServer_rb.html +1 -3
  322. data/doc/lib/daemon/WebServer_rb.html +1 -1
  323. data/doc/lib/deep_copy_rb.html +1 -1
  324. data/doc/lib/reports/CSVFile_rb.html +1 -1
  325. data/doc/lib/reports/ColumnTable_rb.html +1 -1
  326. data/doc/lib/reports/GanttChart_rb.html +1 -1
  327. data/doc/lib/reports/GanttContainer_rb.html +1 -1
  328. data/doc/lib/reports/GanttHeaderScaleItem_rb.html +1 -1
  329. data/doc/lib/reports/GanttHeader_rb.html +1 -1
  330. data/doc/lib/reports/GanttLine_rb.html +1 -1
  331. data/doc/lib/reports/GanttLoadStack_rb.html +1 -1
  332. data/doc/lib/reports/GanttMilestone_rb.html +1 -1
  333. data/doc/lib/reports/GanttRouter_rb.html +1 -1
  334. data/doc/lib/reports/GanttTaskBar_rb.html +1 -1
  335. data/doc/lib/reports/HTMLGraphics_rb.html +1 -1
  336. data/doc/lib/reports/Navigator_rb.html +1 -1
  337. data/doc/lib/reports/NikuReport_rb.html +1 -1
  338. data/doc/lib/reports/ReportBase_rb.html +1 -1
  339. data/doc/lib/reports/ReportContext_rb.html +1 -1
  340. data/doc/lib/reports/ReportTableCell_rb.html +1 -1
  341. data/doc/lib/reports/ReportTableColumn_rb.html +1 -1
  342. data/doc/lib/reports/ReportTableLegend_rb.html +1 -1
  343. data/doc/lib/reports/ReportTableLine_rb.html +1 -1
  344. data/doc/lib/reports/ReportTable_rb.html +1 -1
  345. data/doc/lib/reports/Report_rb.html +1 -1
  346. data/doc/lib/reports/ResourceListRE_rb.html +1 -1
  347. data/doc/lib/reports/StatusSheetReport_rb.html +1 -1
  348. data/doc/lib/reports/TableReport_rb.html +1 -1
  349. data/doc/lib/reports/TaskListRE_rb.html +1 -1
  350. data/doc/lib/reports/TextReport_rb.html +1 -1
  351. data/doc/lib/reports/TimeSheetReport_rb.html +1 -1
  352. data/doc/lib/reports/TjpExportRE_rb.html +1 -1
  353. data/doc/lib/taskjuggler3_rb.html +1 -1
  354. data/doc/lib/tj3client_rb.html +1 -1
  355. data/doc/lib/tj3d_rb.html +1 -1
  356. data/doc/lib/tj3man_rb.html +1 -1
  357. data/doc/lib/tj3ss_receiver_rb.html +1 -1
  358. data/doc/lib/tj3ss_sender_rb.html +1 -1
  359. data/doc/lib/tj3ts_receiver_rb.html +1 -1
  360. data/doc/lib/tj3ts_sender_rb.html +1 -1
  361. data/doc/lib/tj3ts_summary_rb.html +1 -1
  362. data/lib/Allocation.rb +8 -5
  363. data/lib/BatchProcessor.rb +7 -3
  364. data/lib/FileList.rb +58 -0
  365. data/lib/Journal.rb +73 -33
  366. data/lib/KeywordArray.rb +4 -0
  367. data/lib/KeywordDocumentation.rb +45 -11
  368. data/lib/Limits.rb +0 -1
  369. data/lib/LogicalExpression.rb +1 -1
  370. data/lib/LogicalFunction.rb +14 -12
  371. data/lib/MacroTable.rb +3 -4
  372. data/lib/MessageHandler.rb +136 -7
  373. data/lib/Project.rb +72 -86
  374. data/lib/ProjectFileParser.rb +30 -33
  375. data/lib/ProjectFileScanner.rb +7 -16
  376. data/lib/PropertyList.rb +25 -27
  377. data/lib/PropertySet.rb +1 -1
  378. data/lib/PropertyTreeNode.rb +9 -12
  379. data/lib/Query.rb +5 -4
  380. data/lib/RTFNavigator.rb +2 -1
  381. data/lib/RTFQuery.rb +4 -11
  382. data/lib/RTFReport.rb +2 -1
  383. data/lib/RTFReportLink.rb +10 -4
  384. data/lib/RTFWithQuerySupport.rb +45 -0
  385. data/lib/Resource.rb +20 -20
  386. data/lib/ResourceScenario.rb +3 -3
  387. data/lib/RichText.rb +15 -7
  388. data/lib/RichTextDocument.rb +8 -4
  389. data/lib/RichTextElement.rb +35 -12
  390. data/lib/RichTextFunctionHandler.rb +11 -12
  391. data/lib/RichTextParser.rb +5 -3
  392. data/lib/RichTextScanner.rb +144 -565
  393. data/lib/RichTextSnip.rb +3 -7
  394. data/lib/RichTextSyntaxRules.rb +51 -32
  395. data/lib/ScenarioData.rb +16 -25
  396. data/lib/SheetHandlerBase.rb +59 -2
  397. data/lib/SheetReceiver.rb +36 -18
  398. data/lib/SimpleQueryExpander.rb +58 -0
  399. data/lib/SyntaxReference.rb +9 -5
  400. data/lib/TOCEntry.rb +2 -0
  401. data/lib/TableOfContents.rb +4 -0
  402. data/lib/Task.rb +23 -12
  403. data/lib/TaskJuggler.rb +72 -33
  404. data/lib/TaskScenario.rb +131 -53
  405. data/lib/TextParser.rb +43 -30
  406. data/lib/TextParser/Pattern.rb +17 -13
  407. data/lib/TextParser/Rule.rb +5 -0
  408. data/lib/TextScanner.rb +46 -25
  409. data/lib/TimeSheetSummary.rb +9 -7
  410. data/lib/TimeSheets.rb +14 -23
  411. data/lib/Tj3Config.rb +1 -1
  412. data/lib/TjTime.rb +1 -2
  413. data/lib/TjpSyntaxRules.rb +128 -104
  414. data/lib/UTF8String.rb +0 -1
  415. data/lib/UserManual.rb +5 -4
  416. data/lib/VimSyntax.rb +223 -0
  417. data/lib/daemon/Daemon.rb +9 -0
  418. data/lib/daemon/ProcessIntercom.rb +19 -4
  419. data/lib/daemon/ProjectBroker.rb +149 -68
  420. data/lib/daemon/ProjectServer.rb +119 -79
  421. data/lib/daemon/ReportServer.rb +42 -31
  422. data/lib/daemon/WebServer.rb +21 -2
  423. data/lib/deep_copy.rb +1 -1
  424. data/lib/reports/GanttContainer.rb +2 -2
  425. data/lib/reports/GanttLine.rb +2 -3
  426. data/lib/reports/GanttTaskBar.rb +7 -3
  427. data/lib/reports/Report.rb +62 -57
  428. data/lib/reports/ReportBase.rb +6 -4
  429. data/lib/reports/ReportTableCell.rb +13 -14
  430. data/lib/reports/TableReport.rb +2 -1
  431. data/lib/reports/TextReport.rb +3 -0
  432. data/lib/reports/TimeSheetReport.rb +2 -3
  433. data/lib/reports/TjpExportRE.rb +0 -2
  434. data/lib/tj3client.rb +31 -3
  435. data/lib/tj3d.rb +8 -1
  436. data/manual/Day_To_Day_Juggling +2 -95
  437. data/manual/How_To_Contribute +2 -1
  438. data/manual/Rich_Text_Attributes +37 -3
  439. data/manual/Software +203 -0
  440. data/test/MessageChecker.rb +4 -4
  441. data/test/TestSuite/HTML-Reports/Alerts.html +172 -0
  442. data/test/TestSuite/HTML-Reports/CellText.html +758 -0
  443. data/test/TestSuite/HTML-Reports/ColumnPeriods.html +156 -0
  444. data/test/TestSuite/HTML-Reports/IsOngoing.html +172 -0
  445. data/test/TestSuite/HTML-Reports/LogicalFunctions.html +245 -0
  446. data/test/TestSuite/HTML-Reports/Query.html +31 -0
  447. data/test/TestSuite/HTML-Reports/css/tjmanual.css +14 -0
  448. data/test/TestSuite/HTML-Reports/css/tjreport.css +233 -21
  449. data/test/TestSuite/HTML-Reports/depArrows.html +842 -0
  450. data/test/TestSuite/HTML-Reports/scripts/scripts/wz_tooltip.js +1301 -0
  451. data/test/TestSuite/HTML-Reports/scripts/wz_tooltip.js +20 -20
  452. data/test/TestSuite/ReportGenerator/Correct/Alerts.tjp +48 -0
  453. data/test/TestSuite/ReportGenerator/Correct/Macros.tjp +57 -0
  454. data/test/TestSuite/ReportGenerator/Correct/refs/Alerts-1.csv +386 -0
  455. data/test/TestSuite/ReportGenerator/Correct/refs/Macros-1.csv +6 -0
  456. data/test/TestSuite/ReportGenerator/{Correct → Errors}/css/tjmanual.css +0 -0
  457. data/test/TestSuite/ReportGenerator/{Correct → Errors}/css/tjreport.css +0 -0
  458. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/details.png +0 -0
  459. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-green.png +0 -0
  460. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-red.png +0 -0
  461. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/flag-yellow.png +0 -0
  462. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/resource.png +0 -0
  463. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/resourcegroup.png +0 -0
  464. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/task.png +0 -0
  465. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/taskgroup.png +0 -0
  466. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-down.png +0 -0
  467. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-flat.png +0 -0
  468. data/test/TestSuite/ReportGenerator/{Correct → Errors}/icons/trend-up.png +0 -0
  469. data/test/TestSuite/ReportGenerator/Errors/rtp_report_recursion.html +26 -0
  470. data/test/TestSuite/ReportGenerator/{Correct → Errors}/scripts/wz_tooltip.js +0 -0
  471. data/test/TestSuite/Scheduler/Correct/Allocate.html +3210 -0
  472. data/test/TestSuite/Scheduler/Correct/Allocate.tjp +19 -0
  473. data/test/TestSuite/Scheduler/Correct/Container.html +22 -22
  474. data/test/TestSuite/Scheduler/Correct/Limits.html +4964 -0
  475. data/test/TestSuite/Scheduler/Correct/Shift.html +1707 -417
  476. data/test/TestSuite/Scheduler/Correct/Shift2.html +9 -9
  477. data/test/TestSuite/Scheduler/Correct/css/tjreport.css +6 -2
  478. data/test/TestSuite/Scheduler/Errors/css/tjmanual.css +66 -0
  479. data/test/TestSuite/Scheduler/Errors/css/tjreport.css +407 -0
  480. data/test/TestSuite/Scheduler/Errors/icons/details.png +0 -0
  481. data/test/TestSuite/Scheduler/Errors/icons/flag-green.png +0 -0
  482. data/test/TestSuite/Scheduler/Errors/icons/flag-red.png +0 -0
  483. data/test/TestSuite/Scheduler/Errors/icons/flag-yellow.png +0 -0
  484. data/test/TestSuite/Scheduler/Errors/icons/resource.png +0 -0
  485. data/test/TestSuite/Scheduler/Errors/icons/resourcegroup.png +0 -0
  486. data/test/TestSuite/Scheduler/Errors/icons/task.png +0 -0
  487. data/test/TestSuite/Scheduler/Errors/icons/taskgroup.png +0 -0
  488. data/test/TestSuite/Scheduler/Errors/icons/trend-down.png +0 -0
  489. data/test/TestSuite/Scheduler/Errors/icons/trend-flat.png +0 -0
  490. data/test/TestSuite/Scheduler/Errors/icons/trend-up.png +0 -0
  491. data/test/TestSuite/Scheduler/Errors/loop_detected_1.tjp +1 -1
  492. data/test/TestSuite/Scheduler/Errors/loop_detected_10.tjp +1 -1
  493. data/test/TestSuite/Scheduler/Errors/loop_detected_11.tjp +1 -1
  494. data/test/TestSuite/Scheduler/Errors/loop_detected_12.tjp +1 -1
  495. data/test/TestSuite/Scheduler/Errors/loop_detected_13.tjp +1 -1
  496. data/test/TestSuite/Scheduler/Errors/loop_detected_14.tjp +1 -1
  497. data/test/TestSuite/Scheduler/Errors/loop_detected_2.tjp +1 -1
  498. data/test/TestSuite/Scheduler/Errors/loop_detected_3.tjp +1 -1
  499. data/test/TestSuite/Scheduler/Errors/loop_detected_4.tjp +1 -1
  500. data/test/TestSuite/Scheduler/Errors/loop_detected_5.tjp +1 -1
  501. data/test/TestSuite/Scheduler/Errors/loop_detected_6.tjp +1 -1
  502. data/test/TestSuite/Scheduler/Errors/loop_detected_7.tjp +1 -1
  503. data/test/TestSuite/Scheduler/Errors/loop_detected_8.tjp +1 -1
  504. data/test/TestSuite/Scheduler/Errors/loop_detected_9.tjp +1 -1
  505. data/test/TestSuite/Scheduler/Errors/scripts/wz_tooltip.js +1301 -0
  506. data/test/TestSuite/Scheduler/Errors/task_pred_before.tjp +11 -0
  507. data/test/TestSuite/Scheduler/Errors/task_pred_before_gd.tjp +11 -0
  508. data/test/TestSuite/Scheduler/Errors/task_pred_before_gl.tjp +11 -0
  509. data/test/TestSuite/Scheduler/Errors/task_succ_after.tjp +12 -0
  510. data/test/TestSuite/Scheduler/Errors/task_succ_after_gd.tjp +12 -0
  511. data/test/TestSuite/Scheduler/Errors/task_succ_after_gl.tjp +12 -0
  512. data/test/TestSuite/StatusSheets/dev2.tji +22 -0
  513. data/test/TestSuite/StatusSheets/resrep.tji +7 -0
  514. data/test/TestSuite/StatusSheets/run +6 -4
  515. data/test/TestSuite/StatusSheets/tj3d.log +312 -0
  516. data/test/TestSuite/Syntax/Correct/Managers.html +263 -0
  517. data/test/TestSuite/Syntax/Correct/tutorial.tjp +1 -2
  518. data/test/TestSuite/Syntax/Errors/empty.tjp +1 -1
  519. data/test/TestSuite/Syntax/Errors/macro_stack_overflow.tjp +1 -1
  520. data/test/TestSuite/TimeSheets/acceptable_intervals +1 -0
  521. data/test/TestSuite/TimeSheets/resrep.tji +7 -0
  522. data/test/TestSuite/TimeSheets/run +6 -5
  523. data/test/TestSuite/TimeSheets/statussheets.log +1 -0
  524. data/test/TestSuite/TimeSheets/ts.tji +351 -0
  525. data/test/TestSuite/TimeSheets/tsdef.tji +2 -0
  526. data/test/test_PropertySet.rb +2 -2
  527. data/test/test_RichText.rb +178 -387
  528. data/test/test_SimpleQueryExpander.rb +55 -0
  529. data/test/test_deep_copy.rb +2 -2
  530. metadata +854 -834
  531. data/lib/MacroParser.rb +0 -77
  532. data/lib/Message.rb +0 -56
  533. data/lib/ruby-signal-bug.rb +0 -43
  534. data/test/TestSuite/HTML-Reports/TimeSheet.html +0 -79
  535. data/test/TestSuite/HTML-Reports/reference.html +0 -51
  536. data/test/TestSuite/ReportGenerator/Correct/Journal.html +0 -63
  537. data/test/TestSuite/ReportGenerator/Correct/LogicalFunctions2.csv +0 -3
  538. data/test/TestSuite/ReportGenerator/Correct/opennodes.csv +0 -2
  539. data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +0 -26
  540. data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +0 -2
  541. data/test/TestSuite/Scheduler/Correct/Booking2.html +0 -603
  542. data/test/TestSuite/Scheduler/Correct/TimeSheet2.html +0 -108
  543. data/test/TestSuite/StatusSheetTemplates/project.tji +0 -35
  544. data/test/TestSuite/StatusSheetTemplates/project.tjp +0 -56
  545. data/test/TestSuite/Syntax/Correct/ResourcePrefix.html +0 -32
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby -w
2
+ # encoding: UTF-8
3
+ #
4
+ # = RTFWithQuerySupport.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 'RichTextFunctionHandler'
14
+
15
+ class TaskJuggler
16
+
17
+ class RTFWithQuerySupport < RichTextFunctionHandler
18
+
19
+ def initialize(messageHandler, type, sourceFileInfo = nil)
20
+ super
21
+ @query = nil
22
+ end
23
+
24
+ # This function must be called to register the Query object that will be
25
+ # used to resolve the queries. It will create a copy of the object since
26
+ # it will modify it.
27
+ def setQuery(query)
28
+ @query = query.dup
29
+ end
30
+
31
+ end
32
+
33
+ class RichTextIntermediate
34
+
35
+ def setQuery(query)
36
+ @functionHandlers.each_value do |handler|
37
+ if handler.respond_to?('setQuery')
38
+ handler.setQuery(query)
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -63,14 +63,18 @@ class TaskJuggler
63
63
  (numberOfLevels - 1).downto(0) do |level|
64
64
  levelList = listByLevel[level]
65
65
  levelRecord = @project['alertLevels'][level]
66
- alertName = "[[File:icons/flag-#{levelRecord[0]}.png|" +
67
- "alt=[#{levelRecord[1]}]|text-bottom]]"
66
+ if query.selfContained
67
+ alertName = "<nowiki>[#{levelRecord[1]}]</nowiki>"
68
+ else
69
+ alertName = "[[File:icons/flag-#{levelRecord[0]}.png|" +
70
+ "alt=[#{levelRecord[1]}]|text-bottom]]"
71
+ end
68
72
  levelList.each do |entry|
69
73
  tsRecord = entry.timeSheetRecord
70
74
 
71
75
  if entry.property.is_a?(Task)
72
- rText += "== #{alertName} <nowiki>#{entry.property.name}</nowiki> "+
73
- "(ID: #{entry.property.fullId}) ==\n\n"
76
+ rText += "=== #{alertName} <nowiki>#{entry.property.name}" +
77
+ "</nowiki> (ID: #{entry.property.fullId}) ===\n\n"
74
78
  if tsRecord
75
79
  rText += "'''Work:''' #{tsRecord.actualWorkPercent.to_i}% "
76
80
  if tsRecord.actualWorkPercent != tsRecord.planWorkPercent
@@ -122,13 +126,11 @@ class TaskJuggler
122
126
 
123
127
  # Now convert the RichText markup String into RichTextIntermediate
124
128
  # format.
125
- begin
126
- rti = RichText.new(rText, RTFHandlers.create(@project)).
127
- generateIntermediateFormat
128
- rescue RichTextException => msg
129
- $stderr.puts "Error while processing Rich Text\n" +
130
- "Line #{msg.lineNo}: #{msg.text}\n" +
131
- "#{msg.line}"
129
+ unless (rti = RichText.new(rText, RTFHandlers.create(@project),
130
+ @project.messageHandler).
131
+ generateIntermediateFormat)
132
+ @project.messageHandler.warning(
133
+ 'res_journal_text', 'Syntax error in journal text')
132
134
  return nil
133
135
  end
134
136
  # No section numbers, please!
@@ -161,21 +163,19 @@ class TaskJuggler
161
163
  rText = ''
162
164
 
163
165
  taskList.each do |task|
164
- rText += "== <nowiki>[#{task.query_alert(query)}] Task: " +
165
- "#{task.name}</nowiki> (#{task.fullId}) ==\n\n"
166
+ rText += "=== <nowiki>[#{task.query_alert(query)}] Task: " +
167
+ "#{task.name}</nowiki> (#{task.fullId}) ===\n\n"
166
168
  rText += task.query_journalmessages(query).richText.inputText + "\n\n"
167
169
  end
168
170
  end
169
171
 
170
172
  # Now convert the RichText markup String into RichTextIntermediate
171
173
  # format.
172
- begin
173
- rti = RichText.new(rText, RTFHandlers.create(@project)).
174
- generateIntermediateFormat
175
- rescue RichTextException => msg
176
- $stderr.puts "Error while processing Rich Text\n" +
177
- "Line #{msg.lineNo}: #{msg.text}\n" +
178
- "#{msg.line}"
174
+ unless (rti = RichText.new(rText, RTFHandlers.create(@project),
175
+ @project.messageHandler).
176
+ generateIntermediateFormat)
177
+ @project.messageHandler.warning(
178
+ 'res_dashboard', 'Syntax error in dashboard text')
179
179
  return nil
180
180
  end
181
181
  # No section numbers, please!
@@ -193,7 +193,7 @@ class TaskJuggler
193
193
  "Resource #{@property.fullId} has multiple conflicting " +
194
194
  "bookings for #{@scoreboard.idxToDate(sbIdx)}. The " +
195
195
  "conflicting tasks are #{@scoreboard[sbIdx].fullId} and " +
196
- "#{booking.task.fullId}.", true, booking.sourceFileInfo)
196
+ "#{booking.task.fullId}.", booking.sourceFileInfo)
197
197
  end
198
198
  val = @scoreboard[sbIdx]
199
199
  if ((val & 2) != 0 && booking.overtime < 1)
@@ -202,7 +202,7 @@ class TaskJuggler
202
202
  if booking.sloppy < 1
203
203
  error('booking_no_duty',
204
204
  "Resource #{@property.fullId} has no duty at " +
205
- "#{@scoreboard.idxToDate(sbIdx)}.", true,
205
+ "#{@scoreboard.idxToDate(sbIdx)}.",
206
206
  booking.sourceFileInfo)
207
207
  end
208
208
  return false
@@ -213,7 +213,7 @@ class TaskJuggler
213
213
  if booking.sloppy < 2
214
214
  error('booking_on_vacation',
215
215
  "Resource #{@property.fullId} is on vacation at " +
216
- "#{@scoreboard.idxToDate(sbIdx)}.", true,
216
+ "#{@scoreboard.idxToDate(sbIdx)}.",
217
217
  booking.sourceFileInfo)
218
218
  end
219
219
  return false
@@ -12,6 +12,7 @@
12
12
 
13
13
  require 'RichTextElement'
14
14
  require 'RichTextParser'
15
+ require 'MessageHandler'
15
16
 
16
17
  class TaskJuggler
17
18
 
@@ -70,17 +71,18 @@ class TaskJuggler
70
71
  #
71
72
  class RichText
72
73
 
73
- attr_reader :inputText
74
+ attr_reader :inputText, :messageHandler
74
75
 
75
76
  # Create a rich text object by passing a String with markup elements to it.
76
77
  # _text_ must be plain text with MediaWiki compatible markup elements. In
77
78
  # case an error occurs, an exception of type TjException will be raised.
78
79
  # _functionHandlers_ is a Hash that maps RichTextFunctionHandler objects
79
80
  # by their function name.
80
- def initialize(text, functionHandlers = [])
81
+ def initialize(text, functionHandlers = [], messageHandler = nil)
81
82
  # Keep a copy of the original text.
82
83
  @inputText = text
83
84
  @functionHandlers = functionHandlers
85
+ @messageHandler = messageHandler || MessageHandler.new
84
86
  end
85
87
 
86
88
  # Convert the @inputText into an abstract syntax tree that can then be
@@ -93,10 +95,12 @@ class TaskJuggler
93
95
  rti.registerFunctionHandler(h)
94
96
  end
95
97
  # Parse the input text into an abstract syntax tree.
96
- parser = RichTextParser.new(rti, sectionCounter, tokenSet)
98
+ parser = RichTextParser.new(@messageHandler, rti, sectionCounter,
99
+ tokenSet)
97
100
  parser.open(@inputText)
98
101
  # Parse the input text and convert it to the intermediate representation.
99
- tree = parser.parse('richtext')
102
+ return nil if (tree = parser.parse('richtext')) == false
103
+
100
104
  # In case the result is empty, use an empty RichTextElement as result
101
105
  tree = RichTextElement.new(rti, :richtext, nil) unless tree
102
106
  tree.cleanUp
@@ -124,7 +128,7 @@ class TaskJuggler
124
128
  # generated by RichText::generateIntermediateFormat.
125
129
  class RichTextIntermediate
126
130
 
127
- attr_reader :richText
131
+ attr_reader :richText, :functionHandlers
128
132
  attr_accessor :blockMode, :sectionNumbers,
129
133
  :lineWidth, :indent, :titleIndent, :parIndent, :listIndent,
130
134
  :preIndent,
@@ -197,12 +201,16 @@ class TaskJuggler
197
201
 
198
202
  # Convert the intermediate format into a plain text String object.
199
203
  def to_s
200
- @tree.to_s
204
+ str = @tree.to_s
205
+ str.chomp! while str[-1] == ?\n
206
+ str
201
207
  end
202
208
 
203
209
  # Convert the intermediate format into a XMLElement objects tree.
204
210
  def to_html
205
- @tree.to_html
211
+ html = @tree.to_html
212
+ html.chomp! while html[-1] == ?\n
213
+ html
206
214
  end
207
215
 
208
216
  # Convert the intermediate format into a tagged syntax String object.
@@ -34,6 +34,7 @@ class TaskJuggler
34
34
  @sectionCounter = [ 0, 0, 0 ]
35
35
  @linkTarget = nil
36
36
  @toc = nil
37
+ @anchors = []
37
38
  end
38
39
 
39
40
  # Register a new RichTextFunctionHandler for this document.
@@ -53,17 +54,20 @@ class TaskJuggler
53
54
  # Call this method to generate a table of contents for all files that were
54
55
  # registered so far. The table of contents is stored internally and will be
55
56
  # used when the document is produced in a new format. This function also
56
- # collects a list of all snip names to @snipNames and gathers a list of
57
+ # collects a list of all snip names to @anchors and gathers a list of
57
58
  # all references to other snippets in @references. As these two lists will
58
59
  # be used by RichTextDocument#checkInternalReferences this function must be
59
60
  # called first.
60
61
  def tableOfContents
61
62
  @toc = TableOfContents.new
62
63
  @references = {}
63
- @snipNames = []
64
+ @anchors = []
64
65
  @snippets.each do |snip|
65
66
  snip.tableOfContents(@toc, snip.name)
66
- @snipNames << snip.name
67
+ @anchors << snip.name
68
+ @toc.each do |tocEntry|
69
+ @anchors << snip.name + '#' + tocEntry.tag
70
+ end
67
71
  (refs = snip.internalReferences).empty? ||
68
72
  @references[snip.name] = refs
69
73
  end
@@ -73,7 +77,7 @@ class TaskJuggler
73
77
  def checkInternalReferences
74
78
  @references.each do |snip, refs|
75
79
  refs.each do |reference|
76
- unless @snipNames.include?(reference)
80
+ unless @anchors.include?(reference)
77
81
  # TODO: Probably an Exception is cleaner here.
78
82
  puts "Warning: Rich text file #{snip} references unknown " +
79
83
  "object #{reference}"
@@ -216,7 +216,6 @@ class TaskJuggler
216
216
  when :href
217
217
  when :blockfunc
218
218
  when :inlinefunc
219
- noChilds = true
220
219
  checkHandler
221
220
  pre = @richText.functionHandler(@data[0]).to_s(@data[1])
222
221
  when :italic
@@ -224,7 +223,7 @@ class TaskJuggler
224
223
  when :code
225
224
  when :text
226
225
  else
227
- raise TjException.new, "Unknown RichTextElement category #{@category}"
226
+ raise "Unknown RichTextElement category #{@category}"
228
227
  end
229
228
 
230
229
  pre + children_to_s + post
@@ -323,7 +322,7 @@ class TaskJuggler
323
322
  pre = "<blockfunc:#{@data[0]}"
324
323
  if @data[1]
325
324
  @data[1].keys.sort.each do |key|
326
- pre += " #{key}=\"#{@data[1][key]}\""
325
+ pre += " #{key}=\"#{@data[1][key].gsub(/"/, '\"')}\""
327
326
  end
328
327
  end
329
328
  post = "/>"
@@ -348,7 +347,7 @@ class TaskJuggler
348
347
  pre = '['
349
348
  post = ']'
350
349
  else
351
- raise TjException.new, "Unknown RichTextElement category #{@category}"
350
+ raise "Unknown RichTextElement category #{@category}"
352
351
  end
353
352
 
354
353
  out = ''
@@ -425,14 +424,17 @@ class TaskJuggler
425
424
  when :numberitem4
426
425
  XMLElement.new('li')
427
426
  when :img
428
- el = XMLElement.new('img', 'src' => @data.fileName)
429
- el['alt'] = @data.altText if @data.altText
430
- if @data.verticalAlign
431
- el['style'] = "vertical-align:#{@data.verticalAlign}; "
432
- end
433
- el
427
+ htmlObject
434
428
  when :ref
435
- XMLElement.new('a', 'href' => "#{@data}.html")
429
+ href = if @data.include?('#')
430
+ # If the @data includes a reference to an anchor, we put the
431
+ # anchor part after the .html extension.
432
+ pre, post = @data.split('#')
433
+ pre + '.html#' + post
434
+ else
435
+ @data + '.html'
436
+ end
437
+ XMLElement.new('a', 'href' => href)
436
438
  when :href
437
439
  a = XMLElement.new('a', 'href' => @data.to_s)
438
440
  a['target'] = @richText.linkTarget if @richText.linkTarget
@@ -455,7 +457,7 @@ class TaskJuggler
455
457
  noChilds = true
456
458
  XMLText.new(@children[0])
457
459
  else
458
- raise TjException.new, "Unknown RichTextElement category #{@category}"
460
+ raise "Unknown RichTextElement category #{@category}"
459
461
  end
460
462
 
461
463
  # Some elements never have leaves.
@@ -530,6 +532,27 @@ class TaskJuggler
530
532
  el
531
533
  end
532
534
 
535
+ def htmlObject
536
+ fileTypes = { 'png' => { 'type' => 'image/png' },
537
+ 'gif' => { 'type' => 'image/gif' },
538
+ 'jpg' => { 'type' => 'image/jpg' },
539
+ 'svg' => { 'type' => 'image/svg+xml', 'class' => 'img' }}
540
+ # Error checking must have been done in the parser!
541
+ # File types must be in sync with
542
+ # RichTextSyntaxRules::rule_plainTextWithLinks
543
+ return nil unless (index = @data.fileName.rindex('.'))
544
+ extension = @data.fileName[index + 1..-1].downcase
545
+ return nil unless (attributes = fileTypes[extension])
546
+ attributes['data'] = @data.fileName
547
+
548
+ el = XMLElement.new('object', attributes)
549
+ el['alt'] = @data.altText if @data.altText
550
+ if @data.verticalAlign
551
+ el['style'] = "vertical-align:#{@data.verticalAlign}; "
552
+ end
553
+ el
554
+ end
555
+
533
556
  def textBlockFormat(indent, label, str, width)
534
557
  labLen = label.length
535
558
  TextFormatter.new(width, indent + labLen, indent).format(label + str)
@@ -12,29 +12,28 @@
12
12
 
13
13
  class TaskJuggler
14
14
 
15
- # This class is the abstract base class for all RichText function handlers. A
16
- # function handler is responsible for a certain function such as 'example' or
17
- # 'query'. functions are used in internal RichText references such as
15
+ # This class is the abstract base class for all RichText function handlers.
16
+ # A function handler is responsible for a certain function such as 'example'
17
+ # or 'query'. functions are used in internal RichText references such as
18
18
  # '[[example:Allocation 2]]'. 'example' is the function, 'Allocation' is the
19
- # path and '2' is the first argument. Arguments are optional. function handler
20
- # can turn such internal references into Strings or XMLElement trees.
21
- # Therefor, each derived handler needs to implement a to_s, to_html and
22
- # to_tagged method that takes two parameter. The first is the path, the second
23
- # is the argument Array.
19
+ # path and '2' is the first argument. Arguments are optional. The function
20
+ # handler can turn such internal references into Strings or XMLElement
21
+ # trees. Therefor, each derived handler needs to implement a to_s, to_html
22
+ # and to_tagged method that takes two parameter. The first is the path, the
23
+ # second is the argument Array.
24
24
  class RichTextFunctionHandler
25
25
 
26
26
  attr_reader :function, :blockFunction
27
27
 
28
- def initialize(project, function, sourceFileInfo = nil)
29
- @project = project
28
+ def initialize(messageHandler, function, sourceFileInfo = nil)
29
+ @messageHandler = messageHandler
30
30
  @function = function
31
31
  @blockFunction = false
32
32
  @sourceFileInfo = sourceFileInfo
33
33
  end
34
34
 
35
35
  def error(id, text)
36
- message = Message.new(id, 'error', text, nil, nil, @sourceFileInfo)
37
- @project.sendMessage(message)
36
+ @messageHandler.error(id, text, @sourceFileInfo) if @messageHandler
38
37
  end
39
38
 
40
39
  end
@@ -27,8 +27,9 @@ class TaskJuggler
27
27
 
28
28
  # Create the parser and initialize the rule set. _rt_ is the RichText object
29
29
  # the resulting tree of RichTextElement objects should belong to.
30
- def initialize(rti, sectionCounter = [ 0, 0, 0, 0 ], tokenSet = nil)
31
- super()
30
+ def initialize(messageHandler, rti, sectionCounter = [ 0, 0, 0, 0 ],
31
+ tokenSet = nil)
32
+ super(messageHandler)
32
33
  @richTextI = rti
33
34
  # These are the tokens that can be returned by the RichTextScanner.
34
35
  @variables = %w( LINEBREAK SPACE WORD BOLD ITALIC CODE BOLDITALIC PRE
@@ -53,7 +54,8 @@ class TaskJuggler
53
54
  def open(text)
54
55
  # Make sure that the last line is properly terminated with a newline.
55
56
  # Multiple newlines at the end are simply ignored.
56
- @scanner = RichTextScanner.new(text + "\n\n")
57
+ @scanner = RichTextScanner.new(text + "\n\n", @messageHandler)
58
+ @scanner.open(true)
57
59
  end
58
60
 
59
61
  # Get the next token from the scanner.
@@ -11,623 +11,202 @@
11
11
  #
12
12
 
13
13
  require 'UTF8String'
14
+ require 'TextScanner'
14
15
 
15
16
  class TaskJuggler
16
17
 
17
18
  # The RichTextScanner is used by the RichTextParser to chop the input text
18
- # into digestable tokens. The parser and the scanner only communicate over
19
- # RichTextScanner#nextToken and RichTextScanner#returnToken. The scanner can
20
- # break the text into words and special tokens.
21
- class RichTextScanner
22
-
23
- # Create the RichTextScanner object and initialize all state variables.
24
- def initialize(text)
25
- # The token buffer is used to hold a returned token. Only one token can
26
- # be returned at a time.
27
- @tokenBuffer = nil
28
- # A reference to the input text.
29
- @text = text
30
- # The reference text should not change during processing. So we can
31
- # determine the length upfront. It's frequently used.
32
- @textLength = text.length
33
- # The number of current line.
34
- @lineNo = 1
35
- # This is the current position withing @text.
36
- @pos = 0
37
- # This flag is set to true whenever we are at the start of a text line.
38
- @beginOfLine = true
39
- # This is the position of the start of the currently processed line.
40
- # It's only used for error reporting.
41
- @lineStart = 0
42
- # This variable stores the mode that the parser is operating in. The
43
- # following modes are supported:
44
- # :wiki : accept supported MediaWiki subset plus TJ extensions
45
- # :nowiki : ignore most markup except for the </nowiki> token
46
- # :funcarg : parse name and parameters of an block or inline parser
47
- # function.
48
- @mode = :wiki
49
- # Enable to trigger printout instead of exception.
50
- @debug = false
51
- end
52
-
53
- # This is a wrapper for nextToken only used for debugging.
54
- #def nextToken
55
- # tok = nextTokenI
56
- # raise "Token Error:" unless tok && tok[0] && tok[1]
57
- # puts "#{tok[0]}: #{tok[1]}"
58
- # tok
59
- #end
60
-
61
- # Return the next token from the input text.
62
- def nextToken
63
- # If we have a returned token, this is returned first.
64
- if @tokenBuffer
65
- tok = @tokenBuffer
66
- @tokenBuffer = nil
67
- return tok
68
- end
69
-
70
- if @mode == :funcarg
71
- return nextTokenFuncArg
72
- elsif @mode == :href
73
- return nextTokenHRef
74
- elsif @mode == :ref
75
- return nextTokenRef
76
- end
77
- if @beginOfLine && @mode == :wiki
78
- if (res = nextTokenWikiBOL)
79
- return res
80
- end
81
- end
82
-
83
- # Many inline control character sequences consit of multiple characters.
84
- # In case of incomplete sequences, we roll back to the start character
85
- # and set the ignoreInlineMarkup flag to simply treat them as normal
86
- # text.
87
- @ignoreInlineMarkup = false
88
- loop do
89
- if res = (@mode == :wiki ? nextTokenWikiInline : nextTokenNoWikiInline)
90
- return res
91
- end
92
- end
93
- end
94
-
95
- # Return the last issued token to the token buffer.
96
- def returnToken(token)
97
- unless @tokenBuffer.nil?
98
- raise TjException.new, 'Token buffer overflow!'
99
- end
100
- @tokenBuffer = token
101
- end
19
+ # into digestable tokens. It specializes the TextScanner class for RichText
20
+ # syntax. The scanner can operate in various modes. The current mode is
21
+ # context dependent. The following modes are supported:
22
+ #
23
+ # :bop : at the begining of a paragraph.
24
+ # :bol : at the begining of a line.
25
+ # :inline : in the middle of a line
26
+ # :nowiki : ignoring all MediaWiki special tokens
27
+ # :ref : inside of a REF [[ .. ]]
28
+ # :href : inside of an HREF [ .. ]
29
+ # :func : inside of a block <[ .. ]> or inline <- .. -> function
30
+ class RichTextScanner < TextScanner
31
+
32
+ def initialize(masterFile, messageHandler)
33
+ tokenPatterns = [
34
+ # :bol mode rules
35
+ [ 'LINEBREAK', /\s*\n/, :bol, method('linebreak') ],
36
+ [ nil, /\s+/, :bol, method('inlineMode') ],
37
+
38
+ # :bop mode rules
39
+ [ 'PRE', / [^\n]+\n?/, :bop, method('pre') ],
40
+ [ nil, /\s*\n/, :bop, method('linebreak') ],
41
+
42
+ # :inline mode rules
43
+ [ 'SPACE', /[ \t\n]+/, :inline, method('space') ],
44
+
45
+ # :bop and :bol mode rules
46
+ [ 'INLINEFUNCSTART', /<-/, [ :bop, :bol, :inline ],
47
+ method('functionStart') ],
48
+ [ 'BLOCKFUNCSTART', /<\[/, [ :bop, :bol ], method('functionStart') ],
49
+ [ 'TITLE*', /={2,5}/, [ :bop, :bol ], method('titleStart') ],
50
+ [ 'TITLE*END', /={2,5}/, :inline, method('titleEnd') ],
51
+ [ 'BULLET*', /\*{1,4} /, [ :bop, :bol ], method('bullet') ],
52
+ [ 'NUMBER*', /\#{1,4} /, [ :bop, :bol ], method('number') ],
53
+ [ 'HLINE', /----/, [ :bop, :bol ], method('inlineMode') ],
54
+
55
+ # :bop, :bol and :inline mode rules
56
+ # The <nowiki> token puts the scanner into :nowiki mode.
57
+ [ nil, /<nowiki>/, [ :bop, :bol, :inline ], method('nowikiStart') ],
58
+ [ 'QUOTES', /'{2,5}/, [ :bop, :bol, :inline ], method('quotes') ],
59
+ [ 'REF', /\[\[/, [ :bop, :bol, :inline ], method('refStart') ],
60
+ [ 'HREF', /\[/, [ :bop, :bol, :inline], method('hrefStart') ],
61
+ [ 'WORD', /.[^ \n\t\[<']*/, [ :bop, :bol, :inline ],
62
+ method('inlineMode') ],
102
63
 
103
- # Report the current cursor position.
104
- def sourceFileInfo
105
- [ @lineNo, @pos ]
106
- end
64
+ # :nowiki mode rules
65
+ [ nil, /<\/nowiki>/, :nowiki, method('nowikiEnd') ],
66
+ [ 'WORD', /(<(?!\/nowiki>)|[^ \t\n<])+/, :nowiki ],
67
+ [ 'SPACE', /[ \t]+/, :nowiki ],
68
+ [ 'LINEBREAK', /\s*\n/, :nowiki ],
107
69
 
108
- # This function makes more sense for parsers that process actual files. As
109
- # we don't have a file name, we just return 'input text'.
110
- def fileName
111
- 'input text'
112
- end
70
+ # :ref mode rules
71
+ [ 'REFEND', /\]\]/, :ref, method('refEnd') ],
72
+ [ 'WORD', /(<(?!-)|(\](?!\])|[^|<\]]))+/, :ref ],
73
+ [ 'QUERY', /<-\w+->/, :ref, method('query') ],
74
+ [ 'LITERAL', /./, :ref ],
113
75
 
114
- # The parser uses this function to report any errors during parsing.
115
- def error(id, text, foo = nil, bar = nil)
116
- if @debug
117
- $stderr.puts "Line #{@lineNo}: #{text}\n" +
118
- "#{@text[@lineStart, @pos - @lineStart]}"
119
- else
120
- raise RichTextException.new(id, @lineNo, text,
121
- @text[@lineStart, @pos - @lineStart])
122
- end
123
- end
76
+ # :href mode rules
77
+ [ 'HREFEND', /\]/, :href, method('hrefEnd') ],
78
+ [ 'WORD', /(<(?!-)|[^ \t\n\]<])+/, :href ],
79
+ [ 'QUERY', /<-\w+->/, :href, method('query') ],
80
+ [ 'SPACE', /[ \t\n]+/, :href ],
124
81
 
125
- private
126
-
127
- # Function arguments have the following formats:
128
- # <[blockfunc par1="value1" par2='value2']>
129
- # <-inlinefunc par1="value1" ... ->
130
- def nextTokenFuncArg
131
- token = [ '.', '<END>' ]
132
- while (c = nextChar)
133
- case c
134
- when ' ', "\n", "\t"
135
- if (tok = readBlanks(c))
136
- token = tok
137
- break
138
- end
139
- when '='
140
- return [ '_=', '=' ]
141
- when "'"
142
- return readString(c)
143
- when '"'
144
- return readString(c)
145
- when 'a'..'z', 'A'..'Z', '_'
146
- return readId(c)
147
- when ']'
148
- if nextChar == '>'
149
- @mode = :wiki
150
- return [ 'BLOCKFUNCEND', ']>' ]
151
- end
152
- returnChar
153
- when '-'
154
- if nextChar == '>'
155
- @mode = :wiki
156
- return [ 'INLINEFUNCEND', '->' ]
157
- end
158
- returnChar
159
- end
160
- end
161
- token
82
+ # :func mode rules
83
+ [ 'INLINEFUNCEND', /->/ , :func, method('functionEnd') ],
84
+ [ 'BLOCKFUNCEND', /\]>/, :func, method('functionEnd') ],
85
+ [ 'ID', /[a-zA-Z_]\w*/, :func ],
86
+ [ 'STRING', /"(\\"|[^"])*"/, :func, method('dqString') ],
87
+ [ 'STRING', /'(\\'|[^'])*'/, :func, method('sqString') ],
88
+ [ nil, /[ \t\n]+/, :func ],
89
+ [ 'LITERAL', /./, :func ]
90
+ ]
91
+ super(masterFile, messageHandler, tokenPatterns, :bop)
162
92
  end
163
93
 
164
- def nextTokenRef
165
- c = nextChar
166
- return [ '.', '<END' ] if c.nil?
94
+ private
167
95
 
168
- return [ 'LITERAL', '|' ] if c == '|'
169
-
170
- if c == ']' && peek == ']'
171
- nextChar
172
- @mode = :wiki
173
- return [ 'REFEND', ']]' ]
174
- end
175
-
176
- token = c
177
- while (c = nextChar)
178
- break if c.nil?
179
- if c == '|' || (c == ']' && peek == ']')
180
- returnChar
181
- break
182
- end
183
- token << c
96
+ def space(type, match)
97
+ if match.index("\n")
98
+ # If the match contains a linebreak we switch to :bol mode.
99
+ self.mode = :bol
100
+ # And return an empty string.
101
+ match = ''
184
102
  end
185
- [ 'WORD', token ]
103
+ [type, match ]
186
104
  end
187
105
 
188
- def nextTokenHRef
189
- token = [ '.', '<END>' ]
190
- while (c = nextChar)
191
- if c.nil?
192
- # We've reached the end of the text.
193
- return token
194
- elsif c == ' ' || c == "\t" || c == "\n"
195
- # Sequences of tabs, spaces and newlines are treated as token
196
- # boundaries, but otherwise they are ignored.
197
- readSequence(" \n\t")
198
- return [ 'SPACE', ' ' ]
199
- elsif c == '<' && !@ignoreInlineMarkup
200
- if nextChar == '-' && isIdStart(peek(1))
201
- token = readId('', 'QUERY')
202
- unless nextChar == '-' && nextChar == '>'
203
- error('unterminated_query',
204
- "Inline query must be terminated with '->'")
205
- end
206
- return token
207
- else
208
- # It's not a query.
209
- returnChar(2)
210
- @ignoreInlineMarkup = true
211
- next
212
- end
213
- elsif c == ']'
214
- @mode = :wiki
215
- return [ 'HREFEND', ']' ]
216
- else
217
- return nextTokenWord(c)
218
- end
219
- end
220
- token
106
+ def linebreak(type, match)
107
+ self.mode = :bop
108
+ [ type, match ]
221
109
  end
222
110
 
223
- def nextTokenWikiBOL
224
- # Some characters have only a special meaning at the start of the line.
225
- # When the last token pushed the cursor into a new line, this flag is set
226
- # to true.
227
-
228
- # Reset the flag again.
229
- @beginOfLine = false
230
-
231
- # We already know that the last newline was a real linebreak. Further
232
- # newlines can safely be ignored.
233
- readSequence("\n")
234
-
235
- # All the lead characters of a token here also need to be registered
236
- # with nextTokenNewline!
237
- case (c = nextChar)
238
- when '='
239
- # Headings start with 2 or more = and must be followed by a space.
240
- level = readSequenceMax('=', 5)
241
- if level == 1
242
- # 1 = does not mean anything. Push it back and process it as normal
243
- # text further down.
244
- returnChar
245
- else
246
- # Between the = characters and the title text must be exactly one
247
- # space.
248
- return [ "TITLE#{level - 1}", '=' * level ] if nextChar == ' '
249
- # If that's missing, The = are treated as normal text further down.
250
- returnChar(level + 1)
251
- end
252
- when '-'
253
- # Horizontal ruler. Must have exactly 4 -.
254
- level = readSequenceMax('-', 4)
255
- return [ "HLINE", '-' * 4 ] if level == 4
256
- returnChar(level)
257
- when '*'
258
- # Bullet lists start with one to three * characters.
259
- level = readSequenceMax('*', 4)
260
- # Between the * characters and the bullet text must be exactly one
261
- # space.
262
- return [ "BULLET#{level}", '*' * level ] if nextChar == ' '
263
- # If that's missing, The # are treated as normal text further down.
264
- returnChar(level + 1)
265
- when '#'
266
- # Numbered list start with one to three # characters.
267
- level = readSequenceMax('#', 4)
268
- # Between the # characters and the bullet text must be exactly one
269
- # space.
270
- return [ "NUMBER#{level}", '#' * level ] if nextChar == ' '
271
- # If that's missing, The # are treated as normal text further down.
272
- returnChar(level + 1)
273
- when '<'
274
- # This may be the start of a block generating function.
275
- if nextChar == '['
276
- # Switch the parser to block function argument parsing mode.
277
- @mode = :funcarg
278
- return [ 'BLOCKFUNCSTART', '<[' ]
279
- end
280
- # Maybe not.
281
- returnChar(2)
282
- when ' '
283
- # Lines that start with a space are treated as verbatim text.
284
- return [ "PRE", readCode ] if (c = peek) && c != "\n"
285
- else
286
- # If the character is not a known control character we push it back
287
- # and treat it as normal text further down.
288
- returnChar
289
- end
290
-
291
- return nil
111
+ def inlineMode(type, match)
112
+ self.mode = :inline
113
+ [ type, match ]
292
114
  end
293
115
 
294
- def nextTokenWikiInline
295
- c = nextChar
296
- if c.nil?
297
- # We've reached the end of the text.
298
- [ '.', '<END>' ]
299
- elsif c == ' ' || c == "\t"
300
- # Sequences of tabs or spaces are treated as token boundaries, but
301
- # otherwise they are ignored.
302
- readSequence(" \t")
303
- [ 'SPACE', ' ' ]
304
- elsif c == "'" && !@ignoreInlineMarkup
305
- # Sequence of 2 ' means italic, 3 ' means bold, 4 ' means monospaced
306
- # code, 5 ' means italic and bold. Anything else is just normal text.
307
- level = readSequenceMax("'", 5)
308
- if level == 2
309
- [ 'ITALIC', "'" * level ]
310
- elsif level == 3
311
- [ 'BOLD', "'" * level ]
312
- elsif level == 4
313
- [ 'CODE', "'" * level ]
314
- elsif level == 5
315
- [ 'BOLDITALIC', "'" * level ]
316
- else
317
- # We have not found the right syntax. Treat the found characters as
318
- # normal text. Push all ' back and start again but ignoring the '
319
- # code for once.
320
- returnChar(level)
321
- @ignoreInlineMarkup = true
322
- nil
323
- end
324
- elsif c == '=' && !@ignoreInlineMarkup
325
- level = readSequenceMax('=', 5)
326
- if level > 1
327
- [ "TITLE#{level - 1}END", '=' * level ]
328
- else
329
- # We have not found the right syntax. Treat found characters as
330
- # normal text. Push all = back and start again but ignoring the =
331
- # code for once.
332
- returnChar(level)
333
- @ignoreInlineMarkup = true
334
- nil
335
- end
336
- elsif c == '['
337
- level = readSequenceMax('[', 2)
338
- if level == 1
339
- @mode = :href
340
- [ 'HREF' , '[' ]
341
- else
342
- @mode = :ref
343
- [ 'REF', '[[' ]
344
- end
345
- elsif c == ']' && peek == ']'
346
- nextChar
347
- [ 'REFEND', ']]' ]
348
- elsif c == "\n"
349
- nextTokenNewline
350
- elsif c == '<' && !@ignoreInlineMarkup
351
- nextTokenOpenAngle
352
- else
353
- nextTokenWord(c)
354
- end
116
+ def titleStart(type, match)
117
+ self.mode = :inline
118
+ [ "TITLE#{match.length - 1}", match ]
355
119
  end
356
120
 
357
- def nextTokenNoWikiInline
358
- c = nextChar
359
- if c.nil?
360
- # We've reached the end of the text.
361
- [ '.', '<END>' ]
362
- elsif c == ' ' || c == "\t"
363
- # Sequences of tabs or spaces are treated as token boundaries, but
364
- # otherwise they are ignored.
365
- readSequence(" \t")
366
- [ 'SPACE', ' ' ]
367
- elsif c == "\n"
368
- nextTokenNewline
369
- elsif c == '<' && !@ignoreInlineMarkup
370
- nextTokenOpenAngle
371
- else
372
- nextTokenWord(c)
373
- end
121
+ def titleEnd(type, match)
122
+ [ "TITLE#{match.length - 1}END", match ]
374
123
  end
375
124
 
376
- # We've just read a newline. Now we need to figure out whether this is a
377
- # LINEBREAK or just a SPACE. This is determined by looking at the next
378
- # character.
379
- def nextTokenNewline
380
- # Newlines are pretty important as they can terminate blocks and turn
381
- # the next character into the start of a control sequence.
382
- # Hard linebreaks consist of a newline followed by another newline or
383
- # any of the begin-of-line control characters.
384
- if (c = nextChar).nil?
385
- # We hit the end of the text.
386
- [ '.', '<END>' ]
387
- elsif c == '<' && peekMatch('[')
388
- # the '<' can be a start of a block (BLOCKFUNCSTART) or inline text
389
- # (INLINEFUNCSTART). Only for the first case the linebreak is real.
390
- returnChar if c != "\n"
391
- # The next character may be a control character.
392
- @beginOfLine = true
393
- [ 'LINEBREAK', "\n" ]
394
- elsif "\n*#=-".include?(c)
395
- # These characters correspond to the first characters of a block
396
- # element. When they are found at the begin of the line, the newline
397
- # was really a line break.
398
- returnChar if c != "\n"
399
- # The next character may be a control character.
400
- @beginOfLine = true
401
- [ 'LINEBREAK', "\n" ]
402
- else
403
- # Single line breaks are treated as spaces. Return the char after
404
- # the newline and start with this one again.
405
- returnChar
406
- [ 'SPACE', ' ' ]
407
- end
125
+ def bullet(type, match)
126
+ self.mode = :inline
127
+ [ "BULLET#{match.length - 1}", match ]
408
128
  end
409
129
 
410
- def nextTokenOpenAngle
411
- if peekMatch('nowiki>')
412
- # Turn most wiki markup interpretation off.
413
- @pos += 'nowiki>'.length
414
- @mode = :nowiki
415
- elsif peekMatch('/nowiki>')
416
- # Turn most wiki markup interpretation on.
417
- @pos += '/nowiki>'.length
418
- @mode = :wiki
419
- elsif peekMatch('-') && @mode == :wiki
420
- nextChar
421
- # Switch the parser to function argument parsing mode.
422
- @mode = :funcarg
423
- return [ 'INLINEFUNCSTART', '<-' ]
424
- else
425
- # We've not found a valid control sequence. Push back the character
426
- # and make sure we treat it as a normal character.
427
- @ignoreInlineMarkup = true
428
- returnChar
429
- end
430
- nil
130
+ def number(type, match)
131
+ self.mode = :inline
132
+ [ "NUMBER#{match.length - 1}", match ]
431
133
  end
432
134
 
433
- # _c_ does not match any start of a control sequence, so we read
434
- # characters until we find the end of the word.
435
- def nextTokenWord(c)
436
- # Reset this flag again.
437
- @ignoreInlineMarkup = false
438
- str = ''
439
- str << c
440
- # Now we can collect characters of a word until we hit a whitespace.
441
- while (c = nextChar) && !" \n\t".include?(c)
442
- case @mode
443
- when :wiki
444
- # Or at least two ' characters in a row.
445
- break if c == "'" && peek == "'"
446
- # Or a ] or <
447
- break if ']<'.include?(c)
448
- when :href
449
- # Look for - of the end mark -> end ']'
450
- break if '-]<'.include?(c)
451
- else
452
- # Make sure we find the </nowiki> tag even within a word.
453
- break if c == '<'
454
- end
455
- str << c
456
- end
457
- # Return the character that indicated the word end.
458
- returnChar
459
- [ 'WORD', str ]
135
+ def quotes(type, match)
136
+ self.mode = :inline
137
+ types = [ nil, nil, 'ITALIC', 'BOLD' , 'CODE', 'BOLDITALIC' ]
138
+ [ types[match.length], match ]
460
139
  end
461
140
 
462
- # Deliver the next character. Keep track of the cursor position. In case we
463
- # reach the end, nil is returned.
464
- def nextChar
465
- if @pos >= @textLength
466
- # Correct @pos so that returnChar works properly but mutliple reads of
467
- # EOT are ignored.
468
- @pos = @textLength + 1
469
- return nil
470
- end
471
- c = @text[@pos]
472
- @pos += 1
473
- if c == ?\n
474
- @lineNo += 1
475
- # Save the position of the line start for later use during error
476
- # reporting. The line begins after the newline.
477
- @lineStart = @pos
478
- end
479
- # Since Ruby 1.9 is returning Strings for String#[] we need to emulate
480
- # this for Ruby 1.8.
481
- '' << c
141
+ def nowikiStart(type, match)
142
+ self.mode = :nowiki
143
+ [ type, match ]
482
144
  end
483
145
 
484
- # Return one or more characters. _n_ is the number of characters to move
485
- # back the cursor.
486
- def returnChar(n = 1)
487
- crossedNewline = false
488
- if @pos <= @textLength && @pos >= n
489
- # Check for newlines and update @lineNo accordingly.
490
- n.times do |i|
491
- if @text[@pos - i - 1] == ?\n
492
- crossedNewline = true
493
- @lineNo -= 1
494
- end
495
- end
496
- @pos -= n
497
- end
498
-
499
- # If we have crossed a newline during rewind, we have to find the start of
500
- # the current line again.
501
- if crossedNewline
502
- @lineStart = @pos
503
- @lineStart -= 1 while @lineStart > 0 && @text[@lineStart - 1] != ?\n
504
- end
146
+ def nowikiEnd(type, match)
147
+ self.mode = :inline
148
+ [ type, match ]
505
149
  end
506
150
 
507
- # Return a character further up the text without moving the cursor.
508
- # _lookAhead_ is the number of characters to peek ahead. A value of 0 would
509
- # return the last character provided by nextChar().
510
- def peek(lookAhead = 1)
511
- return nil if (@pos + lookAhead - 1) >= @textLength
512
- # Since Ruby 1.9 is returning Strings for String#[] we need to emulate
513
- # this for Ruby 1.8.
514
- '' << @text[@pos + lookAhead - 1]
151
+ def functionStart(type, match)
152
+ # When restoring :bol or :bop mode, we need to switch to :inline mode.
153
+ @funcLastMode = (@scannerMode == :bop || @scannerMode == :bol) ?
154
+ :inline : @scannerMode
155
+ self.mode = :func
156
+ [ type, match ]
515
157
  end
516
158
 
517
- # Return true if the next characters match exactly the character sequence in
518
- # word.
519
- def peekMatch(word)
520
- # Since Ruby 1.9 is returning Strings for String#[] we need to emulate
521
- # this for Ruby 1.8.
522
- ('' << @text[@pos, word.length]) == word
159
+ def functionEnd(type, match)
160
+ self.mode = @funcLastMode
161
+ @funcLastMode = nil
162
+ [ type, match ]
523
163
  end
524
164
 
525
- # Read a sequence of characters that are all contained in the _chars_ Array.
526
- # If a character is found that is not in _chars_ the method returns the so
527
- # far found sequence of chars as String.
528
- def readSequence(chars)
529
- sequence = ''
530
- while (c = nextChar) && chars.index(c)
531
- sequence << c
532
- end
533
- # Push back the character that did no longer match.
534
- returnChar
535
- sequence
165
+ def pre(type, match)
166
+ [ type, match[1..-1] ]
536
167
  end
537
168
 
538
- # Read a sequence of _c_ characters until a different character is found or
539
- # _max_ count has been reached.
540
- def readSequenceMax(c, max = 3)
541
- i = 1
542
- while nextChar == c && i < max
543
- i += 1
544
- end
545
- # Return the non matching character.
546
- returnChar
547
- i
169
+ def dqString(type, match)
170
+ # Remove first and last character and remove backslashes from quoted
171
+ # double quotes.
172
+ [ type, match[1..-2].gsub(/\\"/, '"') ]
548
173
  end
549
174
 
550
- # Read a block of pre-formatted text. All lines must start with a space
551
- # character.
552
- def readCode
553
- tok = ''
554
- loop do
555
- # Read until the end of the line
556
- while (c = nextChar) && c != "\n"
557
- # Append a found characters.
558
- tok << c
559
- end
560
- # Append the newline.
561
- tok << c
562
- # If the next line does not start with a space, we've reached the end of
563
- # the code block.
564
- if (c = nextChar) && c != ' '
565
- break
566
- end
567
- end
568
- returnChar
569
- @beginOfLine = true
570
- tok
175
+ def sqString(type, match)
176
+ # Remove first and last character and remove backslashes from quoted
177
+ # single quotes.
178
+ [ type, match[1..-2].gsub(/\\'/, "'") ]
571
179
  end
572
180
 
573
- def readBlanks(c)
574
- loop do
575
- if c != ' ' && c != "\n" && c != "\t"
576
- returnChar
577
- return nil
578
- end
579
- c = nextChar
580
- end
181
+ def query(type, match)
182
+ # Remove <- and ->.
183
+ [ type, match[2..-3] ]
581
184
  end
582
185
 
583
- def isIdStart(c)
584
- (('a'..'z') === c || ('A'..'Z') === c || c == '_')
186
+ def hrefStart(type, match)
187
+ # When restoring :bol or :bop mode, we need to switch to :inline mode.
188
+ @hrefLastMode = (@scannerMode == :bop || @scannerMode == :bol) ?
189
+ :inline : @scannerMode
190
+ self.mode = :href
191
+ [ type, match ]
585
192
  end
586
193
 
587
- def readId(c, tokenType = 'ID')
588
- token = ""
589
- token << c
590
- while (c = nextChar) &&
591
- (('a'..'z') === c || ('A'..'Z') === c || ('0'..'9') === c ||
592
- c == '_')
593
- token << c
594
- end
595
- returnChar
596
- return [ tokenType, token ]
194
+ def hrefEnd(type, match)
195
+ self.mode = @hrefLastMode
196
+ @hrefLastMode = nil
197
+ [ type, match ]
597
198
  end
598
199
 
599
- def readString(terminator)
600
- token = ""
601
- while (c = nextChar) && c != terminator
602
- if c == "\\"
603
- # Terminators can be used as regular characters when prefixed by a \.
604
- if (c = nextChar) && c != terminator
605
- # \ followed by non-terminator. Just add both.
606
- token << "\\"
607
- end
608
- end
609
- token << c
610
- end
611
-
612
- [ 'STRING', token ]
200
+ def refStart(type, match)
201
+ self.mode = :ref
202
+ [ type, match ]
613
203
  end
614
- end
615
-
616
- # Exception raised by the RichTextScanner in case of processing errors. Its
617
- # primary purpose is to carry the id, lineNo, error message and the currently
618
- # parsed line information.
619
- class RichTextException < RuntimeError
620
204
 
621
- attr_reader :lineNo, :id, :text, :line
622
-
623
- def initialize(id, lineNo, msgText, line)
624
- @id = id
625
- @lineNo = lineNo
626
- @text = msgText
627
- @line = line
205
+ def refEnd(type, match)
206
+ self.mode = :inline
207
+ [ type, match ]
628
208
  end
629
209
 
630
210
  end
631
211
 
632
212
  end
633
-