taskjuggler 0.2.1 → 0.2.2

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 (443) hide show
  1. data/{tasks/missing.rake → .gemtest} +0 -0
  2. data/CHANGELOG +27 -0
  3. data/Rakefile +8 -9
  4. data/bin/tj3 +2 -1
  5. data/bin/tj3client +2 -1
  6. data/bin/tj3d +2 -1
  7. data/bin/tj3man +2 -1
  8. data/bin/tj3ss_receiver +2 -1
  9. data/bin/tj3ss_sender +2 -1
  10. data/bin/tj3ts_receiver +2 -1
  11. data/bin/tj3ts_sender +2 -1
  12. data/bin/tj3ts_summary +2 -1
  13. data/data/tjp.vim +425 -419
  14. data/examples/Fedora-20/f-20.tjp +2442 -0
  15. data/examples/Fedora-20/icons/fedoralogo.png +0 -0
  16. data/examples/Fedora-20/reports.tji +423 -0
  17. data/lib/header.tmpl +13 -0
  18. data/lib/taskjuggler/AppConfig.rb +5 -0
  19. data/lib/taskjuggler/Attributes.rb +22 -0
  20. data/lib/taskjuggler/Journal.rb +273 -10
  21. data/lib/taskjuggler/Log.rb +9 -8
  22. data/lib/taskjuggler/Project.rb +28 -60
  23. data/lib/taskjuggler/ProjectFileScanner.rb +2 -1
  24. data/lib/taskjuggler/PropertySet.rb +3 -0
  25. data/lib/taskjuggler/PropertyTreeNode.rb +4 -0
  26. data/lib/taskjuggler/Query.rb +2 -1
  27. data/lib/taskjuggler/Resource.rb +0 -103
  28. data/lib/taskjuggler/RichText/RTFQuery.rb +42 -4
  29. data/lib/taskjuggler/SheetHandlerBase.rb +0 -20
  30. data/lib/taskjuggler/SheetReceiver.rb +23 -21
  31. data/lib/taskjuggler/Task.rb +3 -5
  32. data/lib/taskjuggler/TaskJuggler.rb +4 -0
  33. data/lib/taskjuggler/TaskScenario.rb +81 -103
  34. data/lib/taskjuggler/TextParser/Scanner.rb +19 -18
  35. data/lib/taskjuggler/Tj3Config.rb +1 -1
  36. data/lib/taskjuggler/TjpSyntaxRules.rb +180 -45
  37. data/lib/taskjuggler/UTF8String.rb +30 -0
  38. data/lib/taskjuggler/apps/Tj3.rb +1 -1
  39. data/lib/taskjuggler/apps/Tj3Man.rb +54 -2
  40. data/lib/taskjuggler/reports/ICalReport.rb +4 -4
  41. data/lib/taskjuggler/reports/NikuReport.rb +6 -0
  42. data/lib/taskjuggler/reports/Report.rb +5 -5
  43. data/lib/taskjuggler/reports/ReportContext.rb +4 -2
  44. data/lib/taskjuggler/reports/ResourceListRE.rb +10 -1
  45. data/lib/taskjuggler/reports/StatusSheetReport.rb +3 -0
  46. data/lib/taskjuggler/reports/TableReport.rb +8 -3
  47. data/lib/taskjuggler/reports/TimeSheetReport.rb +3 -0
  48. data/lib/updateheader.sh +15 -0
  49. data/manual/Installation +11 -22
  50. data/manual/Software +17 -3
  51. data/manual/html/Day_To_Day_Juggling.html +359 -0
  52. data/manual/html/Getting_Started.html +62 -0
  53. data/manual/html/How_To_Contribute.html +88 -0
  54. data/manual/html/Installation.html +172 -0
  55. data/manual/html/Intro.html +74 -0
  56. data/manual/html/Reporting_Bugs.html +47 -0
  57. data/manual/html/Rich_Text_Attributes.html +174 -0
  58. data/manual/html/Software.html +147 -0
  59. data/manual/html/TaskJuggler_2x_Migration.html +71 -0
  60. data/manual/html/TaskJuggler_Internals.html +61 -0
  61. data/manual/html/The_TaskJuggler_Syntax.html +89 -0
  62. data/manual/html/Tutorial.html +498 -0
  63. data/manual/html/account.html +152 -0
  64. data/manual/html/account.task.html +68 -0
  65. data/manual/html/accountprefix.html +67 -0
  66. data/manual/html/active.html +66 -0
  67. data/manual/html/adopt.task.html +73 -0
  68. data/manual/html/alert level.html +66 -0
  69. data/manual/html/alert.html +66 -0
  70. data/manual/html/allocate.html +92 -0
  71. data/manual/html/alphabet.html +33 -0
  72. data/manual/html/alternative.html +77 -0
  73. data/manual/html/author.html +69 -0
  74. data/manual/html/balance.html +73 -0
  75. data/manual/html/booking.resource.html +122 -0
  76. data/manual/html/booking.task.html +120 -0
  77. data/manual/html/caption.html +96 -0
  78. data/manual/html/cellcolor.column.html +71 -0
  79. data/manual/html/celltext.column.html +68 -0
  80. data/manual/html/center.html +67 -0
  81. data/manual/html/charge.html +89 -0
  82. data/manual/html/chargeset.html +73 -0
  83. data/manual/html/columnid.html +358 -0
  84. data/manual/html/columns.html +73 -0
  85. data/manual/html/complete.html +80 -0
  86. data/manual/html/copyright.html +97 -0
  87. data/manual/html/credit.html +117 -0
  88. data/{benchmarks → manual/html}/css/tjmanual.css +0 -0
  89. data/{benchmarks → manual/html}/css/tjreport.css +0 -0
  90. data/manual/html/currency.html +120 -0
  91. data/manual/html/currencyformat.html +99 -0
  92. data/manual/html/dailymax.html +144 -0
  93. data/manual/html/dailymin.html +132 -0
  94. data/manual/html/dailyworkinghours.html +90 -0
  95. data/manual/html/date.extend.html +77 -0
  96. data/manual/html/date.html +100 -0
  97. data/manual/html/definitions.html +94 -0
  98. data/manual/html/depends.html +110 -0
  99. data/manual/html/details.html +69 -0
  100. data/manual/html/disabled.html +85 -0
  101. data/manual/html/duration.html +133 -0
  102. data/manual/html/efficiency.html +93 -0
  103. data/manual/html/effort.html +134 -0
  104. data/manual/html/email.html +68 -0
  105. data/manual/html/enabled.html +69 -0
  106. data/manual/html/end.column.html +67 -0
  107. data/manual/html/end.html +87 -0
  108. data/manual/html/end.limit.html +69 -0
  109. data/manual/html/end.report.html +99 -0
  110. data/manual/html/end.timesheet.html +94 -0
  111. data/manual/html/endcredit.html +110 -0
  112. data/manual/html/epilog.html +72 -0
  113. data/manual/html/export.html +197 -0
  114. data/manual/html/extend.html +87 -0
  115. data/manual/html/fail.html +69 -0
  116. data/manual/html/fdl.html +430 -0
  117. data/manual/html/flags.account.html +66 -0
  118. data/manual/html/flags.html +66 -0
  119. data/manual/html/flags.journalentry.html +66 -0
  120. data/manual/html/flags.report.html +66 -0
  121. data/manual/html/flags.resource.html +68 -0
  122. data/manual/html/flags.statussheet.html +66 -0
  123. data/manual/html/flags.task.html +68 -0
  124. data/manual/html/flags.timesheet.html +66 -0
  125. data/manual/html/fontcolor.column.html +71 -0
  126. data/manual/html/footer.html +72 -0
  127. data/manual/html/formats.html +80 -0
  128. data/manual/html/functions.html +78 -0
  129. data/manual/html/gapduration.html +93 -0
  130. data/manual/html/gaplength.html +93 -0
  131. data/manual/html/halign.center.html +66 -0
  132. data/manual/html/halign.column.html +67 -0
  133. data/manual/html/halign.left.html +66 -0
  134. data/manual/html/halign.right.html +66 -0
  135. data/manual/html/hasalert.html +71 -0
  136. data/manual/html/header.html +72 -0
  137. data/manual/html/headline.html +69 -0
  138. data/manual/html/hidejournalentry.html +69 -0
  139. data/manual/html/hidereport.html +67 -0
  140. data/manual/html/hideresource.html +73 -0
  141. data/manual/html/hidetask.html +73 -0
  142. data/manual/html/icalreport.html +137 -0
  143. data/manual/html/include.macro.html +70 -0
  144. data/manual/html/include.project.html +71 -0
  145. data/manual/html/include.properties.html +168 -0
  146. data/manual/html/index.html +18 -0
  147. data/manual/html/inherit.extend.html +68 -0
  148. data/manual/html/interval1.html +99 -0
  149. data/manual/html/interval2.html +98 -0
  150. data/manual/html/interval3.html +99 -0
  151. data/manual/html/interval4.html +100 -0
  152. data/manual/html/isactive.html +67 -0
  153. data/manual/html/ischildof.html +67 -0
  154. data/manual/html/isdependencyof.html +75 -0
  155. data/manual/html/isdutyof.html +71 -0
  156. data/manual/html/isfeatureof.html +71 -0
  157. data/manual/html/isleaf.html +66 -0
  158. data/manual/html/ismilestone.html +67 -0
  159. data/manual/html/isongoing.html +67 -0
  160. data/manual/html/isresource.html +66 -0
  161. data/manual/html/istask.html +66 -0
  162. data/manual/html/journalattributes.html +107 -0
  163. data/manual/html/journalentry.html +83 -0
  164. data/manual/html/journalmode.html +83 -0
  165. data/manual/html/left.html +66 -0
  166. data/manual/html/length.html +104 -0
  167. data/manual/html/limits.allocate.html +72 -0
  168. data/manual/html/limits.html +72 -0
  169. data/manual/html/limits.resource.html +80 -0
  170. data/manual/html/limits.task.html +113 -0
  171. data/manual/html/listitem.column.html +66 -0
  172. data/manual/html/listtype.column.html +79 -0
  173. data/manual/html/loadunit.html +99 -0
  174. data/manual/html/logicalexpression.html +110 -0
  175. data/manual/html/logicalflagexpression.html +82 -0
  176. data/manual/html/macro.html +103 -0
  177. data/manual/html/managers.html +109 -0
  178. data/manual/html/mandatory.html +66 -0
  179. data/manual/html/maxend.html +69 -0
  180. data/manual/html/maximum.html +99 -0
  181. data/manual/html/maxstart.html +69 -0
  182. data/manual/html/milestone.html +71 -0
  183. data/manual/html/minend.html +69 -0
  184. data/manual/html/minimum.html +99 -0
  185. data/manual/html/minstart.html +69 -0
  186. data/manual/html/monthlymax.html +99 -0
  187. data/manual/html/monthlymin.html +99 -0
  188. data/manual/html/navbar.html +513 -0
  189. data/manual/html/navigator.html +70 -0
  190. data/manual/html/newtask.html +83 -0
  191. data/manual/html/nikureport.html +216 -0
  192. data/manual/html/note.task.html +68 -0
  193. data/manual/html/now.html +67 -0
  194. data/manual/html/numberformat.html +85 -0
  195. data/manual/html/onend.html +68 -0
  196. data/manual/html/onstart.html +68 -0
  197. data/manual/html/opennodes.html +66 -0
  198. data/manual/html/overtime.booking.html +76 -0
  199. data/manual/html/period.column.html +67 -0
  200. data/manual/html/period.limit.html +69 -0
  201. data/manual/html/period.report.html +69 -0
  202. data/manual/html/period.task.html +69 -0
  203. data/manual/html/persistent.html +66 -0
  204. data/manual/html/precedes.html +86 -0
  205. data/manual/html/priority.html +114 -0
  206. data/manual/html/priority.timesheet.html +68 -0
  207. data/manual/html/project.html +88 -0
  208. data/manual/html/projectid.html +66 -0
  209. data/manual/html/projectid.task.html +68 -0
  210. data/manual/html/projectids.html +66 -0
  211. data/manual/html/projection.html +75 -0
  212. data/manual/html/prolog.html +72 -0
  213. data/manual/html/properties.html +64 -0
  214. data/manual/html/purge.html +69 -0
  215. data/manual/html/rate.html +66 -0
  216. data/manual/html/rate.resource.html +68 -0
  217. data/manual/html/reference.extend.html +77 -0
  218. data/manual/html/remaining.html +117 -0
  219. data/manual/html/replace.html +66 -0
  220. data/manual/html/report.html +333 -0
  221. data/manual/html/reportprefix.html +67 -0
  222. data/manual/html/resource.html +194 -0
  223. data/manual/html/resourceattributes.html +83 -0
  224. data/manual/html/resourceprefix.html +67 -0
  225. data/manual/html/resourcereport.html +69 -0
  226. data/manual/html/resourceroot.html +90 -0
  227. data/manual/html/resources.limit.html +82 -0
  228. data/manual/html/responsible.html +69 -0
  229. data/manual/html/richtext.extend.html +78 -0
  230. data/manual/html/right.html +66 -0
  231. data/manual/html/rollupresource.html +92 -0
  232. data/manual/html/rolluptask.html +69 -0
  233. data/manual/html/scale.column.html +87 -0
  234. data/manual/html/scenario.html +123 -0
  235. data/manual/html/scenario.ical.html +67 -0
  236. data/manual/html/scenarios.export.html +66 -0
  237. data/manual/html/scenarios.html +66 -0
  238. data/manual/html/scenariospecific.extend.html +68 -0
  239. data/manual/html/scheduled.html +68 -0
  240. data/manual/html/scheduling.html +74 -0
  241. data/manual/html/select.html +86 -0
  242. data/manual/html/selfcontained.html +66 -0
  243. data/manual/html/shift.html +128 -0
  244. data/manual/html/shift.resource.html +74 -0
  245. data/manual/html/shift.task.html +74 -0
  246. data/manual/html/shift.timesheet.html +70 -0
  247. data/manual/html/shifts.allocate.html +71 -0
  248. data/manual/html/shifts.resource.html +73 -0
  249. data/manual/html/shifts.task.html +73 -0
  250. data/manual/html/shorttimeformat.html +67 -0
  251. data/manual/html/sloppy.booking.html +77 -0
  252. data/manual/html/sloppy.projection.html +66 -0
  253. data/manual/html/sortjournalentries.html +81 -0
  254. data/manual/html/sortresources.html +73 -0
  255. data/manual/html/sorttasks.html +73 -0
  256. data/manual/html/start.column.html +67 -0
  257. data/manual/html/start.html +78 -0
  258. data/manual/html/start.limit.html +69 -0
  259. data/manual/html/start.report.html +69 -0
  260. data/manual/html/startcredit.html +68 -0
  261. data/manual/html/status.statussheet.html +73 -0
  262. data/manual/html/status.timesheet.html +91 -0
  263. data/manual/html/statussheet.html +124 -0
  264. data/manual/html/statussheetreport.html +125 -0
  265. data/manual/html/strict.projection.html +66 -0
  266. data/manual/html/summary.html +69 -0
  267. data/manual/html/supplement.html +108 -0
  268. data/manual/html/supplement.resource.html +195 -0
  269. data/manual/html/supplement.task.html +329 -0
  270. data/manual/html/tagfile.html +73 -0
  271. data/manual/html/task.html +320 -0
  272. data/manual/html/task.statussheet.html +74 -0
  273. data/manual/html/task.timesheet.html +89 -0
  274. data/manual/html/taskattributes.html +115 -0
  275. data/manual/html/taskprefix.html +67 -0
  276. data/manual/html/taskreport.html +69 -0
  277. data/manual/html/taskroot.html +103 -0
  278. data/manual/html/text.extend.html +77 -0
  279. data/manual/html/textreport.html +66 -0
  280. data/manual/html/timeformat.html +160 -0
  281. data/manual/html/timeoff.nikureport.html +71 -0
  282. data/manual/html/timesheet.html +129 -0
  283. data/manual/html/timesheetreport.html +107 -0
  284. data/manual/html/timezone.export.html +66 -0
  285. data/manual/html/timezone.html +72 -0
  286. data/manual/html/timezone.report.html +66 -0
  287. data/manual/html/timezone.shift.html +70 -0
  288. data/manual/html/timingresolution.html +71 -0
  289. data/manual/html/title.column.html +67 -0
  290. data/manual/html/title.html +68 -0
  291. data/manual/html/toc.html +1330 -0
  292. data/manual/html/tooltip.column.html +72 -0
  293. data/manual/html/trackingscenario.html +80 -0
  294. data/manual/html/treelevel.html +66 -0
  295. data/manual/html/vacation.html +71 -0
  296. data/manual/html/vacation.resource.html +73 -0
  297. data/manual/html/vacation.shift.html +71 -0
  298. data/manual/html/warn.html +69 -0
  299. data/manual/html/weeklymax.html +99 -0
  300. data/manual/html/weeklymin.html +99 -0
  301. data/manual/html/weekstartsmonday.html +66 -0
  302. data/manual/html/weekstartssunday.html +66 -0
  303. data/manual/html/width.column.html +66 -0
  304. data/manual/html/work.html +105 -0
  305. data/manual/html/workinghours.project.html +102 -0
  306. data/manual/html/workinghours.resource.html +79 -0
  307. data/manual/html/workinghours.shift.html +81 -0
  308. data/manual/html/yearlyworkingdays.html +70 -0
  309. data/spec/StatusSheets_spec.rb +0 -6
  310. data/spec/TimeSheets_spec.rb +0 -6
  311. data/spec/Tj3Daemon_spec.rb +2 -0
  312. data/spec/support/DaemonControl.rb +10 -0
  313. data/taskjuggler.gemspec +71 -0
  314. data/tasks/changelog.rake +2 -2
  315. data/tasks/gem.rake +50 -21
  316. data/tasks/manual.rake +1 -1
  317. data/tasks/rdoc.rake +5 -12
  318. data/tasks/spec.rake +1 -1
  319. data/tasks/test.rake +5 -8
  320. data/test/ReferenceGenerator.rb +91 -0
  321. data/test/TestSuite/CSV-Reports/refs/resourcereport.csv +4 -4
  322. data/test/TestSuite/ReportGenerator/Correct/Journal.tjp +21 -0
  323. data/test/TestSuite/ReportGenerator/Correct/JournalMode.tjp +124 -0
  324. data/test/TestSuite/ReportGenerator/Correct/refs/Alerts-1.csv +124 -124
  325. data/test/TestSuite/ReportGenerator/Correct/refs/Journal-1.csv +1 -7
  326. data/test/TestSuite/ReportGenerator/Correct/refs/Journal-2.csv +7 -3
  327. data/test/TestSuite/ReportGenerator/Correct/refs/JournalMode-1.csv +79 -0
  328. data/test/TestSuite/ReportGenerator/Correct/refs/JournalMode-2.csv +208 -0
  329. data/test/TjpGen.rb +152 -0
  330. metadata +1290 -741
  331. data/benchmarks/666tasks.tjp +0 -3183
  332. data/benchmarks/allocate.tjp +0 -30
  333. data/benchmarks/allocatedSlots.tjp +0 -1602
  334. data/benchmarks/booking.tjp +0 -76
  335. data/benchmarks/depends.tjp +0 -113
  336. data/benchmarks/gantt.tjp +0 -57
  337. data/benchmarks/htmltaskreport.tjp +0 -71
  338. data/benchmarks/icons/details.png +0 -0
  339. data/benchmarks/icons/flag-green.png +0 -0
  340. data/benchmarks/icons/flag-red.png +0 -0
  341. data/benchmarks/icons/flag-yellow.png +0 -0
  342. data/benchmarks/icons/resource.png +0 -0
  343. data/benchmarks/icons/resourcegroup.png +0 -0
  344. data/benchmarks/icons/task.png +0 -0
  345. data/benchmarks/icons/taskgroup.png +0 -0
  346. data/benchmarks/icons/trend-down.png +0 -0
  347. data/benchmarks/icons/trend-flat.png +0 -0
  348. data/benchmarks/icons/trend-up.png +0 -0
  349. data/benchmarks/runbench.rb +0 -30
  350. data/benchmarks/scripts/wz_tooltip.js +0 -1301
  351. data/gem_spec.rb +0 -37
  352. data/lib/exchangebug.rb +0 -42
  353. data/lib/ruby-signal-bug.rb +0 -55
  354. data/prj_cfg.rb +0 -50
  355. data/tasks/csts.rake +0 -72
  356. data/tasks/rcov.rake +0 -14
  357. data/tasks/rexml_fix.rb +0 -16
  358. data/tasks/rexml_fix_19.rb +0 -49
  359. data/tasks/show.rake +0 -21
  360. data/tasks/stats.rake +0 -25
  361. data/test/TestSuite/Export-Reports/refs/DST.tjp +0 -60
  362. data/test/TestSuite/Export-Reports/refs/ReleasePlan.tjp +0 -80
  363. data/test/TestSuite/Export-Reports/tp.tjp +0 -49
  364. data/test/TestSuite/HTML-Reports/Alerts.html +0 -424
  365. data/test/TestSuite/HTML-Reports/TimeSheet.html +0 -79
  366. data/test/TestSuite/HTML-Reports/css/tjmanual.css +0 -86
  367. data/test/TestSuite/HTML-Reports/css/tjreport.css +0 -413
  368. data/test/TestSuite/HTML-Reports/icons/details.png +0 -0
  369. data/test/TestSuite/HTML-Reports/icons/flag-green.png +0 -0
  370. data/test/TestSuite/HTML-Reports/icons/flag-red.png +0 -0
  371. data/test/TestSuite/HTML-Reports/icons/flag-yellow.png +0 -0
  372. data/test/TestSuite/HTML-Reports/icons/resource.png +0 -0
  373. data/test/TestSuite/HTML-Reports/icons/resourcegroup.png +0 -0
  374. data/test/TestSuite/HTML-Reports/icons/task.png +0 -0
  375. data/test/TestSuite/HTML-Reports/icons/taskgroup.png +0 -0
  376. data/test/TestSuite/HTML-Reports/icons/trend-down.png +0 -0
  377. data/test/TestSuite/HTML-Reports/icons/trend-flat.png +0 -0
  378. data/test/TestSuite/HTML-Reports/icons/trend-up.png +0 -0
  379. data/test/TestSuite/HTML-Reports/reference.html +0 -51
  380. data/test/TestSuite/HTML-Reports/scripts/wz_tooltip.js +0 -1301
  381. data/test/TestSuite/ReportGenerator/Correct/css/tjmanual.css +0 -86
  382. data/test/TestSuite/ReportGenerator/Correct/css/tjreport.css +0 -413
  383. data/test/TestSuite/ReportGenerator/Correct/icons/details.png +0 -0
  384. data/test/TestSuite/ReportGenerator/Correct/icons/flag-green.png +0 -0
  385. data/test/TestSuite/ReportGenerator/Correct/icons/flag-red.png +0 -0
  386. data/test/TestSuite/ReportGenerator/Correct/icons/flag-yellow.png +0 -0
  387. data/test/TestSuite/ReportGenerator/Correct/icons/resource.png +0 -0
  388. data/test/TestSuite/ReportGenerator/Correct/icons/resourcegroup.png +0 -0
  389. data/test/TestSuite/ReportGenerator/Correct/icons/task.png +0 -0
  390. data/test/TestSuite/ReportGenerator/Correct/icons/taskgroup.png +0 -0
  391. data/test/TestSuite/ReportGenerator/Correct/icons/trend-down.png +0 -0
  392. data/test/TestSuite/ReportGenerator/Correct/icons/trend-flat.png +0 -0
  393. data/test/TestSuite/ReportGenerator/Correct/icons/trend-up.png +0 -0
  394. data/test/TestSuite/ReportGenerator/Correct/opennodes.tjp +0 -26
  395. data/test/TestSuite/ReportGenerator/Correct/refs/opennodes-1.csv +0 -2
  396. data/test/TestSuite/ReportGenerator/Correct/scripts/wz_tooltip.js +0 -1301
  397. data/test/TestSuite/Scheduler/Correct/Allocate.html +0 -1075
  398. data/test/TestSuite/Scheduler/Correct/Duration.html +0 -610
  399. data/test/TestSuite/Scheduler/Correct/css/tjmanual.css +0 -85
  400. data/test/TestSuite/Scheduler/Correct/css/tjreport.css +0 -413
  401. data/test/TestSuite/Scheduler/Correct/icons/details.png +0 -0
  402. data/test/TestSuite/Scheduler/Correct/icons/flag-green.png +0 -0
  403. data/test/TestSuite/Scheduler/Correct/icons/flag-red.png +0 -0
  404. data/test/TestSuite/Scheduler/Correct/icons/flag-yellow.png +0 -0
  405. data/test/TestSuite/Scheduler/Correct/icons/resource.png +0 -0
  406. data/test/TestSuite/Scheduler/Correct/icons/resourcegroup.png +0 -0
  407. data/test/TestSuite/Scheduler/Correct/icons/task.png +0 -0
  408. data/test/TestSuite/Scheduler/Correct/icons/taskgroup.png +0 -0
  409. data/test/TestSuite/Scheduler/Correct/icons/trend-down.png +0 -0
  410. data/test/TestSuite/Scheduler/Correct/icons/trend-flat.png +0 -0
  411. data/test/TestSuite/Scheduler/Correct/icons/trend-up.png +0 -0
  412. data/test/TestSuite/Scheduler/Correct/scripts/wz_tooltip.js +0 -1301
  413. data/test/TestSuite/StatusSheetTemplates/project.tji +0 -35
  414. data/test/TestSuite/StatusSheetTemplates/project.tjp +0 -56
  415. data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/missing-reports +0 -2
  416. data/test/TestSuite/StatusSheets/TimeSheets/2002-03-01/resource1_2002-03-01.tji +0 -0
  417. data/test/TestSuite/StatusSheets/boss.tji +0 -45
  418. data/test/TestSuite/StatusSheets/boss_mail +0 -51
  419. data/test/TestSuite/StatusSheets/dev2_mail +0 -37
  420. data/test/TestSuite/StatusSheets/project.tjp +0 -275
  421. data/test/TestSuite/StatusSheets/run +0 -54
  422. data/test/TestSuite/Syntax/Correct/DST.tjp +0 -11
  423. data/test/TestSuite/Syntax/Correct/ReleasePlan.tjp +0 -32
  424. data/test/TestSuite/Syntax/Correct/css/tjmanual.css +0 -86
  425. data/test/TestSuite/Syntax/Correct/css/tjreport.css +0 -413
  426. data/test/TestSuite/Syntax/Correct/icons/details.png +0 -0
  427. data/test/TestSuite/Syntax/Correct/icons/flag-green.png +0 -0
  428. data/test/TestSuite/Syntax/Correct/icons/flag-red.png +0 -0
  429. data/test/TestSuite/Syntax/Correct/icons/flag-yellow.png +0 -0
  430. data/test/TestSuite/Syntax/Correct/icons/resource.png +0 -0
  431. data/test/TestSuite/Syntax/Correct/icons/resourcegroup.png +0 -0
  432. data/test/TestSuite/Syntax/Correct/icons/task.png +0 -0
  433. data/test/TestSuite/Syntax/Correct/icons/taskgroup.png +0 -0
  434. data/test/TestSuite/Syntax/Correct/icons/trend-down.png +0 -0
  435. data/test/TestSuite/Syntax/Correct/icons/trend-flat.png +0 -0
  436. data/test/TestSuite/Syntax/Correct/icons/trend-up.png +0 -0
  437. data/test/TestSuite/Syntax/Correct/scripts/wz_tooltip.js +0 -1301
  438. data/test/TestSuite/TimeSheets/dev2_mail1 +0 -84
  439. data/test/TestSuite/TimeSheets/dev2_mail2 +0 -87
  440. data/test/TestSuite/TimeSheets/project.tjp +0 -271
  441. data/test/TestSuite/TimeSheets/receiver.log.mod +0 -1056
  442. data/test/TestSuite/TimeSheets/run +0 -76
  443. data/test/TestSuite/TimeSheets/uu.txt +0 -29
@@ -103,14 +103,6 @@ class TaskJuggler::TextParser
103
103
  if (@line = @stream.gets)
104
104
  # Update activity meter about every 1024 lines.
105
105
  @log.activity if (@stream.lineno & 0x3FF) == 0
106
- # Check for DOS or Mac end of line signatures.
107
- if @line[-1] == ?\r
108
- # Mac: Convert CR into LF
109
- @line[-1] = ?\n
110
- elsif @line[-2] == ?\r
111
- # DOS: Convert CR+LF into LF
112
- @line = @line.chomp + "\n"
113
- end
114
106
  else
115
107
  # We've reached the end of the current file.
116
108
  @scanner = nil
@@ -173,8 +165,13 @@ class TaskJuggler::TextParser
173
165
  def initialize(fileName, log)
174
166
  super(log)
175
167
  @fileName = fileName.dup.untaint
176
- @stream = fileName == '.' ? $stdin : File.new(@fileName, 'r')
177
- @log << "Parsing file #{@fileName} ..."
168
+ data = (fileName == '.' ? $stdin : File.new(@fileName, 'r')).read
169
+ begin
170
+ @stream = StringIO.new(data.forceUTF8Encoding)
171
+ rescue
172
+ error('fileEncoding', $!)
173
+ end
174
+ @log.msg { "Parsing file #{@fileName} ..." }
178
175
  @log.startProgressMeter("Reading file #{fileName}")
179
176
  end
180
177
 
@@ -190,8 +187,12 @@ class TaskJuggler::TextParser
190
187
 
191
188
  def initialize(buffer, log)
192
189
  super(log)
193
- @stream = StringIO.new(buffer)
194
- @log << "Parsing buffer #{buffer[0, 20]} ..."
190
+ begin
191
+ @stream = StringIO.new(buffer.forceUTF8Encoding)
192
+ rescue
193
+ error('bufferEncoding', $!)
194
+ end
195
+ #@log.msg { "Parsing buffer #{buffer[0, 20]} ..." }
195
196
  end
196
197
 
197
198
  end
@@ -286,8 +287,8 @@ class TaskJuggler::TextParser
286
287
  begin
287
288
  @fileStack = [ [ @cf = FileStreamHandle.new(@masterFile, @log),
288
289
  nil, nil ] ]
289
- rescue StandardError
290
- error('open_file', "Cannot open file #{@masterFile}")
290
+ rescue IOError, SystemCallError
291
+ error('open_file', "Cannot open file #{@masterFile}: #{$!}")
291
292
  end
292
293
  end
293
294
  @masterPath = @cf.dirname + '/'
@@ -335,7 +336,7 @@ class TaskJuggler::TextParser
335
336
  begin
336
337
  @fileStack << [ (@cf = FileStreamHandle.new(includeFileName, @log)),
337
338
  nil, block ]
338
- @log << "Parsing file #{includeFileName}"
339
+ @log.msg { "Parsing file #{includeFileName}" }
339
340
  rescue StandardError
340
341
  error('bad_include', "Cannot open include file #{includeFileName}", sfi)
341
342
  end
@@ -384,7 +385,7 @@ class TaskJuggler::TextParser
384
385
  # completion. Close it and remove the corresponding entry from the
385
386
  # @fileStack.
386
387
  @finishLastFile = false
387
- #@log << "Completed file #{@cf.fileName}"
388
+ #@log.msg { "Completed file #{@cf.fileName}" }
388
389
 
389
390
  # If we have a block to be executed on EOF, we call it now.
390
391
  onEof = @fileStack.last[2]
@@ -401,7 +402,7 @@ class TaskJuggler::TextParser
401
402
  else
402
403
  # Continue parsing the file that included the current file.
403
404
  @cf, tokenBuffer = @fileStack.last
404
- @log << "Parsing file #{@cf.fileName} ..."
405
+ @log.msg { "Parsing file #{@cf.fileName} ..." }
405
406
  # If we have a left over token from previously processing this file,
406
407
  # return it now.
407
408
  if tokenBuffer
@@ -462,7 +463,7 @@ class TaskJuggler::TextParser
462
463
  # Return a token to retrieve it with the next nextToken() call again. Only 1
463
464
  # token can be returned before the next nextToken() call.
464
465
  def returnToken(token)
465
- #@log << "-> Returning Token: [#{token[0]}][#{token[1]}]"
466
+ #@log.msg { "-> Returning Token: [#{token[0]}][#{token[1]}]" }
466
467
  unless @tokenBuffer.nil?
467
468
  $stderr.puts @tokenBuffer
468
469
  raise "Fatal Error: Cannot return more than 1 token in a row"
@@ -14,7 +14,7 @@
14
14
  require 'taskjuggler/UTF8String'
15
15
  require 'taskjuggler/AppConfig'
16
16
 
17
- AppConfig.version = '0.2.1'
17
+ AppConfig.version = '0.2.2'
18
18
  AppConfig.packageName = 'taskjuggler'
19
19
  AppConfig.softwareName = 'TaskJuggler III'
20
20
  AppConfig.packageInfo = 'A Project Management Software'
@@ -1526,8 +1526,12 @@ EOT
1526
1526
 
1527
1527
  pattern(%w( _scenario !scenarioId ), lambda {
1528
1528
  # Don't include disabled scenarios in the report
1529
- @val[1].delete_if { |sc| !@project.scenario(sc).get('active') }
1530
- @property.set('scenarios', @val[1])
1529
+ sc = @val[1]
1530
+ unless @project.scenario(sc).get('active')
1531
+ warning('ical_sc_disabled',
1532
+ "Scenario #{sc} has been disabled")
1533
+ end
1534
+ @property.set('scenarios', [ @val[1] ])
1531
1535
  })
1532
1536
  doc('scenario.ical', <<'EOT'
1533
1537
  Id of the scenario that should be included in the report. By default, the
@@ -1768,6 +1772,73 @@ EOT
1768
1772
  singlePattern('!intervals')
1769
1773
  end
1770
1774
 
1775
+ def rule_journalReportAttributes
1776
+ pattern(%w( _journalattributes !journalReportAttributesList ), lambda {
1777
+ @property.set('journalAttributes', @val[1])
1778
+ })
1779
+ doc('journalattributes', <<'EOT'
1780
+ A list that determines which of the journal attributes should be included in
1781
+ the journal report.
1782
+ EOT
1783
+ )
1784
+ allOrNothingListRule('journalReportAttributesList',
1785
+ { 'author' => 'Include the author if known',
1786
+ 'date' => 'Include the date',
1787
+ 'details' => 'Include the details',
1788
+ 'flags' => 'Include the flags',
1789
+ 'headline' => 'Include the headline',
1790
+ 'property' => 'Include the task or resource name',
1791
+ 'propertyid' => 'Include the property ID. ' +
1792
+ 'Requires \'property\'.',
1793
+ 'summary' => 'Include the summary',
1794
+ 'timesheet' => 'Include the timesheet information.' +
1795
+ ' Requires \'property\'.'})
1796
+ end
1797
+
1798
+ def rule_journalReportMode
1799
+ pattern(%w( _journal ), lambda { :journal })
1800
+ descr(<<'EOT'
1801
+ This is the regular journal. It contains all journal entries that are dated in
1802
+ the query interval. If a property is given, only entries of this property are
1803
+ included. Without a property context, all the project entries are included
1804
+ unless hidden by other attributes like [[hidejournalentry]].
1805
+ EOT
1806
+ )
1807
+ pattern(%w( _journal_sub ), lambda { :journal_sub })
1808
+ descr(<<'EOT'
1809
+ This mode only yields entries if used in the context of a task. It contains
1810
+ all journal entries that are dated in the query interval for the task and all
1811
+ its sub tasks.
1812
+ EOT
1813
+ )
1814
+ pattern(%w( _status_down ), lambda { :status_down })
1815
+ descr(<<'EOT'
1816
+ In this mode only the last entries before the report end date for each
1817
+ property and all its sub-properties are included. If there are multiple entries
1818
+ at the exact same date, then all these entries are included.
1819
+ EOT
1820
+ )
1821
+ pattern(%w( _status_up ), lambda { :status_up })
1822
+ descr(<<'EOT'
1823
+ In this mode only the last entries before the report end date for each
1824
+ property are included. If there are multiple entries at the exact same date,
1825
+ then all these entries are included. If any of the parent properties has a
1826
+ more recent entry that is still before the report end date, no entries will be
1827
+ included.
1828
+ EOT
1829
+ )
1830
+ pattern(%w( _alerts_down ), lambda { :alerts_down })
1831
+ descr(<<'EOT'
1832
+ In this mode only the last entries before the report end date for the context
1833
+ property and all its sub-properties is included. If there are multiple entries
1834
+ at the exact same date, then all these entries are included. In contrast to
1835
+ the ''''status_down'''' mode, only entries with an alert level above the
1836
+ default level, and only those with the highest overall alert level are
1837
+ included.
1838
+ EOT
1839
+ )
1840
+ end
1841
+
1771
1842
  def rule_journalEntry
1772
1843
  pattern(%w( !journalEntryHeader !journalEntryBody ), lambda {
1773
1844
  @val[0]
@@ -1848,6 +1919,30 @@ The headline of the journal entry. It will be interpreted as
1848
1919
  EOT
1849
1920
  )
1850
1921
  end
1922
+
1923
+ def rule_journalSortCriteria
1924
+ pattern(%w( !journalSortCriterium !moreJournalSortCriteria ), lambda {
1925
+ [ @val[0] ] + (@val[1].nil? ? [] : @val[1])
1926
+ })
1927
+ end
1928
+
1929
+ def rule_journalSortCriterium
1930
+ pattern(%w( $ABSOLUTE_ID ), lambda {
1931
+ supported = []
1932
+ JournalEntryList::SortingAttributes.each do |attr|
1933
+ supported << "#{attr}.up"
1934
+ supported << "#{attr}.down"
1935
+ end
1936
+ unless supported.include?(@val[0])
1937
+ error('bad_journal_sort_criterium',
1938
+ "Unsupported sorting criterium #{@val[0]}. Must be one of " +
1939
+ "#{supported.join(', ')}.")
1940
+ end
1941
+ attr, direction = @val[0].split('.')
1942
+ [ attr.intern, direction == 'up' ? 1 : -1 ]
1943
+ })
1944
+ end
1945
+
1851
1946
  def rule_leafResourceId
1852
1947
  pattern(%w( !resourceId ), lambda {
1853
1948
  resource = @val[0]
@@ -2192,6 +2287,10 @@ EOT
2192
2287
  commaListRule('!taskDep')
2193
2288
  end
2194
2289
 
2290
+ def rule_moreJournalSortCriteria
2291
+ commaListRule('!journalSortCriterium')
2292
+ end
2293
+
2195
2294
  def rule_moreLeafResources
2196
2295
  commaListRule('!resourceLeafList')
2197
2296
  end
@@ -3058,7 +3157,11 @@ EOT
3058
3157
  "#{@val[1]} is not a list attribute. Only those can be purged.",
3059
3158
  @sourceFileInfo[1])
3060
3159
  end
3061
- @property.getAttribute(@val[1], @scenarioIdx).reset
3160
+ if @property.attributeDefinition(@val[1]).scenarioSpecific
3161
+ @property.getAttribute(@val[1], @scenarioIdx).reset
3162
+ else
3163
+ @property.getAttribute(@val[1]).reset
3164
+ end
3062
3165
  })
3063
3166
  doc('purge', <<'EOT'
3064
3167
  List attributes, like regular attributes, can inherit their values from the
@@ -3134,20 +3237,10 @@ EOT
3134
3237
  )
3135
3238
 
3136
3239
  singlePattern('_alertmessages')
3137
- descr(<<'EOT'
3138
- The headlines, the summary and the details of the message from the journal
3139
- entries that caused the current alert level to be larger than the defaul level
3140
- for this task or any of its sub tasks.
3141
- EOT
3142
- )
3240
+ descr('Deprecated. Please use ''''journal'''' instead')
3143
3241
 
3144
3242
  singlePattern('_alertsummaries')
3145
- descr(<<'EOT'
3146
- The headlines and the summary message from the journal entries that caused the
3147
- current alert level to be larger than the default for this task or any of its
3148
- sub tasks.
3149
- EOT
3150
- )
3243
+ descr('Deprecated. Please use ''''journal'''' instead')
3151
3244
 
3152
3245
  singlePattern('_alerttrend')
3153
3246
  descr(<<'EOT'
@@ -3168,7 +3261,18 @@ EOT
3168
3261
  )
3169
3262
 
3170
3263
  singlePattern('_complete')
3171
- descr('The completion degree of a task')
3264
+ descr(<<'EOT'
3265
+ The completion degree of a task. Unless a completion degree is manually
3266
+ provided, this is a computed value relative the [[now]] date of the project. A
3267
+ task that has ended before the now date is always 100% complete. A task that
3268
+ starts at or after the now date is always 0%. For [[effort]] based task the
3269
+ computation degree is the percentage of done effort of the overall effort. For
3270
+ other leaf task, the completion degree is the percentage of the already passed
3271
+ duration of the overall task duration. For container task, it's always the
3272
+ average of the direct sub tasks. If the sub tasks consist of a mixture of
3273
+ effort and non-effort tasks, the completion value is only of limited value.
3274
+ EOT
3275
+ )
3172
3276
 
3173
3277
  pattern([ '_completed' ], lambda {
3174
3278
  'complete'
@@ -3287,30 +3391,22 @@ EOT
3287
3391
 
3288
3392
  singlePattern('_journal')
3289
3393
  descr(<<'EOT'
3290
- The journal entries for the task or resource for the reported interval.
3394
+ The journal entries for the task or resource for the reported interval. The
3395
+ generated text can be customized with the [[journalmode]],
3396
+ [[journalattributes]], [[hidejournalentry]] and [[sortjournalentries]]. If
3397
+ used in queries without a property context, the journal for the complete
3398
+ project is generated.
3291
3399
  EOT
3292
3400
  )
3293
3401
 
3294
3402
  singlePattern('_journal_sub')
3295
- descr(<<'EOT'
3296
- The journal entries for the task or resource and all its subtasks or resources
3297
- for the reported interval.
3298
- EOT
3299
- )
3403
+ descr('Deprecated. Please use ''''journal'''' instead')
3300
3404
 
3301
3405
  singlePattern('_journalmessages')
3302
- descr(<<'EOT'
3303
- The headlines, the summary and the details of the message from the journal
3304
- entries that caused the current alert level for this task.
3305
- EOT
3306
- )
3406
+ descr('Deprecated. Please use ''''journal'''' instead')
3307
3407
 
3308
3408
  singlePattern('_journalsummaries')
3309
- descr(<<'EOT'
3310
- The headlines and the summary message from the journal entries that caused the
3311
- current alert level for this task.
3312
- EOT
3313
- )
3409
+ descr('Deprecated. Please use ''''journal'''' instead')
3314
3410
 
3315
3411
  singlePattern('_line')
3316
3412
  descr('The line number in the report')
@@ -3541,8 +3637,15 @@ EOT
3541
3637
  pattern(%w( !headline ))
3542
3638
  pattern(%w( !hidejournalentry ))
3543
3639
  pattern(%w( !hideresource ))
3544
-
3545
3640
  pattern(%w( !hidetask ))
3641
+ pattern(%w( !journalReportAttributes ))
3642
+ pattern(%w( _journalmode !journalReportMode ), lambda {
3643
+ @property.set('journalMode', @val[1])
3644
+ })
3645
+ doc('journalmode', <<'EOT'
3646
+ This attribute controls what journal entries are aggregated into the report.
3647
+ EOT
3648
+ )
3546
3649
 
3547
3650
  pattern(%w( _left $STRING ), lambda {
3548
3651
  @property.set('left', newRichText(@val[1], @sourceFileInfo[1]))
@@ -3566,6 +3669,11 @@ EOT
3566
3669
  @property.set('numberFormat', @val[0])
3567
3670
  })
3568
3671
 
3672
+ pattern(%w( _opennodes !nodeIdList ), lambda {
3673
+ @property.set('openNodes', @val[1])
3674
+ })
3675
+ doc('opennodes', 'For internal use only!')
3676
+
3569
3677
  pattern(%w( !reportPeriod ))
3570
3678
 
3571
3679
  pattern(%w( _prolog $STRING ), lambda {
@@ -3578,11 +3686,7 @@ EOT
3578
3686
  )
3579
3687
  also(%w( epilog footer header ))
3580
3688
 
3581
- pattern(%w( _opennodes !nodeIdList ), lambda {
3582
- @property.set('openNodes', @val[1])
3583
- })
3584
- doc('opennodes', 'For internal use only!')
3585
-
3689
+ pattern(%w( !purge ))
3586
3690
  pattern(%w( !report ))
3587
3691
 
3588
3692
  pattern(%w( _right $STRING ), lambda {
@@ -3622,6 +3726,7 @@ used.
3622
3726
  EOT
3623
3727
  )
3624
3728
 
3729
+ pattern(%w( !sortJournalEntries ))
3625
3730
  pattern(%w( !sortResources ))
3626
3731
  pattern(%w( !sortTasks ))
3627
3732
 
@@ -4501,6 +4606,31 @@ EOT
4501
4606
  )
4502
4607
  end
4503
4608
 
4609
+ def rule_sortJournalEntries
4610
+ pattern(%w( _sortjournalentries !journalSortCriteria ), lambda {
4611
+ @property.set('sortJournalEntries', @val[1])
4612
+ })
4613
+ doc('sortjournalentries', <<'EOT'
4614
+ Determines how the entries in a journal are sorted. Multiple criteria can be
4615
+ specified as a comma separated list. If one criteria is not sufficient to sort
4616
+ a group of journal entries, the next criteria will be used to sort the entries
4617
+ in this group.
4618
+
4619
+ The following values are supported:
4620
+ * ''''date.down'''': Sort descending order by the date of the journal entry
4621
+ * ''''date.up'''': Sort ascending order by the date of the journal entry
4622
+ * ''''alert.down'''': Sort in descending order by the alert level of the
4623
+ journal entry
4624
+ * ''''alert.up'''': Sort in ascending order by the alert level of the
4625
+ journal entry
4626
+ ''''property.down'''': Sort in descending order by the task or resource
4627
+ the journal entry is associated with
4628
+ * ''''property.up'''': Sort in ascending order by the task or resource the
4629
+ journal entry is associated with
4630
+ EOT
4631
+ )
4632
+ end
4633
+
4504
4634
  def rule_sortResources
4505
4635
  pattern(%w( _sortresources !sortCriteria ), lambda {
4506
4636
  @property.set('sortResources', @val[1])
@@ -5287,17 +5417,21 @@ EOT
5287
5417
  also(%w( effort length ))
5288
5418
 
5289
5419
  pattern(%w( _effort !workingDuration ), lambda {
5290
- if @val[1] <= 0.0
5291
- error('effort_zero', "Effort value must be larger than 0",
5420
+ if @val[1] <= 0
5421
+ error('effort_zero', "Effort value must at least as large as the " +
5422
+ "timing resolution " +
5423
+ "(#{@project['scheduleGranularity'] / 60}min).",
5292
5424
  @sourceFileInfo[1], @property)
5293
5425
  end
5294
5426
  setDurationAttribute('effort', @val[1])
5295
5427
  })
5296
5428
  doc('effort', <<'EOT'
5297
- Specifies the effort needed to complete the task. An effort of 4d can be done
5298
- with 2 full-time resources in 2 days. The task will not finish before the
5299
- resources have contributed the specified effort. So the duration of the task
5300
- will depend on the availability of the resources.
5429
+ Specifies the effort needed to complete the task. An effort of ''''6d'''' (6
5430
+ resource-days) can be done with 2 full-time resources in 3 working days. The
5431
+ task will not finish before the allocated resources have contributed the
5432
+ specified effort. Hence the duration of the task will depend on the
5433
+ availability of the allocated resources. The specified effort value must be at
5434
+ least as large as the [[timingresolution]].
5301
5435
 
5302
5436
  WARNING: In almost all real world projects effort is not the product of time
5303
5437
  and resources. This is only true if the task can be partitioned without adding
@@ -5305,7 +5439,8 @@ any overhead. For more information about this read ''The Mythical Man-Month'' by
5305
5439
  Frederick P. Brooks, Jr.
5306
5440
 
5307
5441
  Tasks may not have subtasks if this attribute is used. Setting this attribute
5308
- will reset the [[duration]] and [[length]] attributes.
5442
+ will reset the [[duration]] and [[length]] attributes. A task with an effort
5443
+ value cannot be a [[milestone]].
5309
5444
  EOT
5310
5445
  )
5311
5446
  example('Durations')
@@ -112,4 +112,34 @@ class String
112
112
  gsub(/\n/, "\r\n")
113
113
  end
114
114
 
115
+ # Ensure the String is really UTF-8 encoded and newlines are only \n. If
116
+ # that's not possible, an Encoding::UndefinedConversionError is raised.
117
+ def forceUTF8Encoding
118
+ if RUBY_VERSION < '1.9.0'
119
+ # Ruby 1.8 really only support 7 bit ASCII well. Only do the line-end
120
+ # clean-up.
121
+ gsub(/\r\n/, "\n")
122
+ else
123
+ begin
124
+ # Ensure that the text has LF line ends and is UTF-8 encoded.
125
+ encode('UTF-8', :universal_newline => true)
126
+ rescue
127
+ # The encoding of the String is broken. Find the first broken line and
128
+ # report it.
129
+ lineCtr = 1
130
+ each_line do |line|
131
+ begin
132
+ line.encode('UTF-8')
133
+ rescue
134
+ line = line.encode('UTF-8', :invalid => :replace,
135
+ :undef => :replace, :replace => '<?>')
136
+ raise Encoding::UndefinedConversionError,
137
+ "UTF-8 encoding error in line #{lineCtr}: #{line}"
138
+ end
139
+ lineCtr += 1
140
+ end
141
+ end
142
+ end
143
+ end
144
+
115
145
  end