galaaz 0.4.10 → 2.0.0

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 (391) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/LICENSE +0 -0
  4. data/README.md +3123 -882
  5. data/Rakefile +62 -41
  6. data/bin/galaaz-bootstrap +137 -0
  7. data/bin/galaaz-jruby +14 -0
  8. data/bin/galaaz_jruby_env.inc.sh +6 -0
  9. data/bin/gbookdown +64 -0
  10. data/bin/gknit +223 -6
  11. data/bin/gknit-draft +105 -0
  12. data/bin/gknit-draft.rb +28 -0
  13. data/bin/gknit_Rscript +127 -0
  14. data/bin/grun +27 -1
  15. data/bin/gstudio +49 -4
  16. data/bin/{gstudio.rb → gstudio_irb.rb} +0 -0
  17. data/bin/gstudio_pry.rb +7 -0
  18. data/bin/install-tinytex +6 -0
  19. data/bin/run_all_rspec +43 -0
  20. data/bin/run_example +14 -0
  21. data/bin/run_old_rspec +19 -0
  22. data/bin/run_rspec +23 -0
  23. data/bin/run_rspec_subset +38 -0
  24. data/bin/run_slow_rspec +19 -0
  25. data/blogs/R-on-Rails-Planning-Document.md +940 -0
  26. data/blogs/README.md +100 -0
  27. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
  28. data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
  29. data/blogs/galaaz_ggplot/galaaz_ggplot.md +364 -0
  30. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
  31. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
  32. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
  33. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
  34. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
  35. data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
  36. data/blogs/galaaz_ggplot/midwest_external_png +0 -0
  37. data/blogs/gknit/gknit.Rmd +52 -55
  38. data/blogs/gknit/gknit.md +94 -94
  39. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  40. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  41. data/blogs/gknit/lst.rds +0 -0
  42. data/blogs/gknit/model.rb +1 -1
  43. data/blogs/gknit/stats.bib +0 -0
  44. data/blogs/manual/include_model_local_repro.Rmd +14 -0
  45. data/blogs/manual/include_model_local_repro.md +75 -0
  46. data/blogs/manual/lst.rds +0 -0
  47. data/blogs/manual/manual.Rmd +1582 -196
  48. data/blogs/manual/manual.log +1786 -0
  49. data/blogs/manual/manual.md +3107 -890
  50. data/blogs/manual/manual.tex +3018 -1086
  51. data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
  52. data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
  53. data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
  54. data/blogs/manual/model.rb +41 -0
  55. data/blogs/nse_dplyr/nse_dplyr.Rmd +277 -151
  56. data/blogs/nse_dplyr/nse_dplyr.log +928 -0
  57. data/blogs/nse_dplyr/nse_dplyr.md +457 -293
  58. data/blogs/oh_my/not_so.rb +0 -0
  59. data/blogs/oh_my/oh_my.Rmd +1234 -25
  60. data/blogs/oh_my/oh_my.log +804 -0
  61. data/blogs/oh_my/oh_my.md +1808 -228
  62. data/blogs/oh_my/oh_my.tex +821 -0
  63. data/blogs/oh_my/old.Rmd +15 -14
  64. data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
  65. data/blogs/ruby_plot/ruby_plot.log +885 -0
  66. data/blogs/ruby_plot/ruby_plot.md +71 -103
  67. data/blogs/ruby_plot/ruby_plot.tex +940 -0
  68. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
  69. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
  70. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
  71. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
  72. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
  73. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
  74. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
  75. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
  76. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
  77. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
  78. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
  79. data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
  80. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
  81. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
  82. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
  83. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
  84. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
  85. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
  86. data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
  87. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
  88. data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
  89. data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
  90. data/blogs/test/test.Rmd +14 -0
  91. data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
  92. data/examples/50Plots_MasterList/ScatterPlot.rb +0 -0
  93. data/examples/50Plots_MasterList/scatter_plot.rb +0 -0
  94. data/examples/Bibliography/master.bib +50 -0
  95. data/examples/Bibliography/stats.bib +72 -0
  96. data/examples/R/calc.R +0 -0
  97. data/examples/R/java_interop.R +0 -0
  98. data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
  99. data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +53 -0
  100. data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
  101. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +33 -0
  102. data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +34 -0
  103. data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
  104. data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
  105. data/examples/islr/all.rb +13 -0
  106. data/examples/islr/ch2.spec.rb +37 -7
  107. data/examples/islr/ch3.spec.rb +11 -2
  108. data/examples/islr/ch3_boston.rb +27 -0
  109. data/examples/islr/ch3_multiple_regression.rb +0 -0
  110. data/examples/islr/ch6.spec.rb +24 -1
  111. data/examples/islr/x_y_rnorm.jpg +0 -0
  112. data/examples/latex_templates/Test-acm_article/Makefile +16 -0
  113. data/examples/latex_templates/Test-acm_article/Test-acm_article.Rmd +65 -0
  114. data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +1670 -0
  115. data/examples/latex_templates/Test-acm_article/sensys-abstract.cls +703 -0
  116. data/examples/latex_templates/Test-acm_article/sigproc.bib +59 -0
  117. data/examples/latex_templates/Test-acs_article/Test-acs_article.Rmd +260 -0
  118. data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +11 -0
  119. data/examples/latex_templates/Test-acs_article/acs-my_output.bib +11 -0
  120. data/examples/latex_templates/Test-acs_article/acstest.bib +17 -0
  121. data/examples/latex_templates/Test-aea_article/AEA.cls +1414 -0
  122. data/{blogs/gknit/marshal.dump → examples/latex_templates/Test-aea_article/BibFile.bib} +0 -0
  123. data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +108 -0
  124. data/examples/latex_templates/Test-aea_article/aea.bst +1269 -0
  125. data/examples/latex_templates/Test-aea_article/multicol.sty +853 -0
  126. data/examples/latex_templates/Test-aea_article/references.bib +0 -0
  127. data/examples/latex_templates/Test-aea_article/setspace.sty +546 -0
  128. data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +256 -0
  129. data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +3397 -0
  130. data/examples/latex_templates/Test-ams_article/Test-ams_article.Rmd +215 -0
  131. data/examples/latex_templates/Test-ams_article/amstest.bib +436 -0
  132. data/examples/latex_templates/Test-asa_article/Test-asa_article.Rmd +153 -0
  133. data/examples/latex_templates/Test-asa_article/agsm.bst +1353 -0
  134. data/examples/latex_templates/Test-asa_article/bibliography.bib +233 -0
  135. data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +2409 -0
  136. data/examples/latex_templates/Test-ieee_article/IEEEtran.cls +6346 -0
  137. data/examples/latex_templates/Test-ieee_article/Test-ieee_article.Rmd +175 -0
  138. data/examples/latex_templates/Test-ieee_article/mybibfile.bib +20 -0
  139. data/examples/latex_templates/Test-rjournal_article/RJournal.sty +335 -0
  140. data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +18 -0
  141. data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +52 -0
  142. data/examples/latex_templates/Test-springer_article/Test-springer_article.Rmd +65 -0
  143. data/examples/latex_templates/Test-springer_article/bibliography.bib +26 -0
  144. data/examples/latex_templates/Test-springer_article/spbasic.bst +1658 -0
  145. data/examples/latex_templates/Test-springer_article/spmpsci.bst +1512 -0
  146. data/examples/latex_templates/Test-springer_article/spphys.bst +1443 -0
  147. data/examples/latex_templates/Test-springer_article/svglov3.clo +113 -0
  148. data/examples/latex_templates/Test-springer_article/svjour3.cls +1431 -0
  149. data/examples/misc/baseball.csv +0 -0
  150. data/examples/misc/ggplot.rb +3 -2
  151. data/examples/misc/moneyball.rb +0 -0
  152. data/examples/misc/subsetting.rb +0 -0
  153. data/examples/multithread_shards_to_r/shards_to_r.rb +67 -0
  154. data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +73 -0
  155. data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +382 -0
  156. data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +164 -0
  157. data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +92 -0
  158. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +482 -0
  159. data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +280 -0
  160. data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +386 -0
  161. data/examples/sthda_ggplot/README.md +0 -0
  162. data/examples/sthda_ggplot/RUN.md +41 -0
  163. data/examples/sthda_ggplot/all.rb +0 -0
  164. data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +0 -0
  165. data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +0 -0
  166. data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +2 -0
  167. data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +0 -0
  168. data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +0 -0
  169. data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +0 -0
  170. data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +0 -0
  171. data/examples/sthda_ggplot/one_variable_continuous/stat.rb +0 -0
  172. data/examples/sthda_ggplot/one_variable_discrete/bar.rb +0 -0
  173. data/examples/sthda_ggplot/qplots/box_violin_dot.rb +0 -0
  174. data/examples/sthda_ggplot/qplots/scatter_plots.rb +0 -0
  175. data/examples/sthda_ggplot/scatter_gg.rb +0 -0
  176. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +0 -0
  177. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +0 -0
  178. data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +0 -0
  179. data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +0 -0
  180. data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +0 -0
  181. data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +0 -0
  182. data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +4 -3
  183. data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +0 -0
  184. data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +0 -0
  185. data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +0 -0
  186. data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +0 -0
  187. data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +0 -0
  188. data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +0 -0
  189. data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +0 -0
  190. data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +0 -0
  191. data/ext/new_bridge/Makefile +46 -0
  192. data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
  193. data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
  194. data/lib/R_interface/galaaz_device.R +20 -0
  195. data/lib/R_interface/include_engine.R +109 -0
  196. data/lib/R_interface/new_bridge_adapter.rb +824 -0
  197. data/lib/R_interface/r.rb +177 -25
  198. data/lib/R_interface/r_arrow.rb +113 -0
  199. data/lib/R_interface/r_libs.R +4 -4
  200. data/lib/R_interface/r_methods.rb +13 -116
  201. data/lib/R_interface/r_module_s.rb +0 -0
  202. data/lib/R_interface/rbinary_operators.rb +20 -2
  203. data/lib/R_interface/rclosure.rb +5 -1
  204. data/lib/R_interface/rdata_frame.rb +34 -70
  205. data/lib/R_interface/rdevice.rb +125 -0
  206. data/lib/R_interface/rdevices.R +0 -0
  207. data/lib/R_interface/renvironment.rb +10 -4
  208. data/lib/R_interface/rexpression.rb +5 -1
  209. data/lib/R_interface/rindexed_object.rb +41 -13
  210. data/lib/R_interface/rlanguage.rb +20 -62
  211. data/lib/R_interface/rlist.rb +115 -25
  212. data/lib/R_interface/rlogical_operators.rb +0 -0
  213. data/lib/R_interface/rmatrix.rb +2 -11
  214. data/lib/R_interface/rmd_indexed_object.rb +5 -1
  215. data/lib/R_interface/robject.rb +348 -290
  216. data/lib/R_interface/rpkg.rb +1 -0
  217. data/lib/R_interface/rsupport.rb +610 -331
  218. data/lib/R_interface/rsupport_scope.rb +2 -1
  219. data/lib/R_interface/rsymbol.rb +50 -0
  220. data/lib/R_interface/ruby_callback.rb +2 -3
  221. data/lib/R_interface/ruby_extensions.rb +225 -175
  222. data/lib/R_interface/runary_operators.rb +0 -0
  223. data/lib/R_interface/rvector.rb +147 -31
  224. data/lib/galaaz.rb +0 -0
  225. data/lib/galaaz_jruby.rb +22 -0
  226. data/lib/gknit/diagnostics.rb +50 -0
  227. data/lib/gknit/draft.rb +111 -0
  228. data/lib/gknit/include_engine.rb +15 -7
  229. data/lib/gknit/knitr_engine.rb +223 -107
  230. data/lib/gknit/rb_engine.rb +3 -3
  231. data/lib/gknit/ruby_engine.rb +0 -0
  232. data/lib/gknit.rb +3 -0
  233. data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
  234. data/lib/new_bridge/envelope.rb +51 -0
  235. data/lib/new_bridge/eval_result.rb +26 -0
  236. data/lib/new_bridge/framing.rb +39 -0
  237. data/lib/new_bridge/instance_pool_client.rb +38 -0
  238. data/lib/new_bridge/r_instance_manager.rb +404 -0
  239. data/lib/new_bridge/session_client.rb +530 -0
  240. data/lib/new_bridge/tcp_framed.rb +44 -0
  241. data/lib/new_bridge.rb +9 -0
  242. data/lib/util/exec_ruby.rb +95 -46
  243. data/lib/util/inline_file.rb +35 -30
  244. data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
  245. data/new_bridge_specs/eval_r_async_spec.rb +113 -0
  246. data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
  247. data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
  248. data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
  249. data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
  250. data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
  251. data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
  252. data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
  253. data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
  254. data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
  255. data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
  256. data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
  257. data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
  258. data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
  259. data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
  260. data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
  261. data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
  262. data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
  263. data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
  264. data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
  265. data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
  266. data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
  267. data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
  268. data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
  269. data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
  270. data/r_requires/ggplot.rb +0 -0
  271. data/r_requires/knitr.rb +0 -0
  272. data/specs/all.rb +15 -11
  273. data/specs/arrow_from_ruby_batches_spec.rb +50 -0
  274. data/specs/arrow_semantics_spec.rb +64 -0
  275. data/specs/bridge_concurrent_spec.rb +46 -0
  276. data/specs/bridge_nested_spec.rb +25 -0
  277. data/specs/dataframe_semantics_spec.rb +122 -0
  278. data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
  279. data/specs/dispatch_probe_cache_spec.rb +38 -0
  280. data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
  281. data/specs/dispatch_probe_fallback_spec.rb +18 -0
  282. data/specs/environment_semantics_spec.rb +89 -0
  283. data/specs/field_access_spec.rb +31 -0
  284. data/specs/figures/bg.jpeg +0 -0
  285. data/specs/figures/bg.png +0 -0
  286. data/specs/figures/bg.svg +168 -57
  287. data/specs/figures/dose_len.png +0 -0
  288. data/specs/figures/no_args.jpeg +0 -0
  289. data/specs/figures/no_args.png +0 -0
  290. data/specs/figures/no_args.svg +168 -57
  291. data/specs/figures/width_height.jpeg +0 -0
  292. data/specs/figures/width_height.png +0 -0
  293. data/specs/figures/width_height_units1.jpeg +0 -0
  294. data/specs/figures/width_height_units1.png +0 -0
  295. data/specs/figures/width_height_units2.jpeg +0 -0
  296. data/specs/figures/width_height_units2.png +0 -0
  297. data/specs/formula_semantics_spec.rb +81 -0
  298. data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
  299. data/specs/galaaz_util_inline_file_spec.rb +54 -0
  300. data/specs/gknit_cli_option_permutation_spec.rb +24 -0
  301. data/specs/gknit_include_engine_spec.rb +72 -0
  302. data/specs/gknit_install_timeout_report_spec.rb +69 -0
  303. data/specs/gknit_internal_error_report_spec.rb +57 -0
  304. data/specs/gknit_vector_map_output_spec.rb +59 -0
  305. data/specs/globalenv_guardrail_spec.rb +52 -0
  306. data/specs/language_expression_semantics_spec.rb +145 -0
  307. data/specs/list_semantics_spec.rb +111 -0
  308. data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
  309. data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
  310. data/specs/new_bridge_callback_timeout_spec.rb +69 -0
  311. data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
  312. data/specs/nil_null_spec.rb +42 -0
  313. data/specs/object_build_phase2_spec.rb +53 -0
  314. data/specs/phase1_callback_bridge_spec.rb +84 -0
  315. data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
  316. data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
  317. data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
  318. data/specs/plot_device_semantics_spec.rb +28 -0
  319. data/specs/plot_snapshot_semantics_spec.rb +58 -0
  320. data/specs/protocol_result_spec.rb +236 -0
  321. data/specs/r_batch_fail_fast_spec.rb +47 -0
  322. data/specs/r_bridge_bootstrap_spec.rb +11 -0
  323. data/specs/r_devices.spec.rb +1 -1
  324. data/specs/r_eval.spec.rb +16 -18
  325. data/specs/r_function.spec.rb +1 -1
  326. data/specs/r_instance_manager_spec.rb +285 -0
  327. data/specs/r_list_apply.spec.rb +15 -15
  328. data/specs/r_matrix.spec.rb +0 -0
  329. data/specs/r_nse.spec.rb +5 -5
  330. data/specs/r_object_send_dispatch_spec.rb +13 -0
  331. data/specs/r_vector_comparator_spec.rb +8 -0
  332. data/specs/r_vector_creation.spec.rb +0 -0
  333. data/specs/r_vector_functions.spec.rb +0 -0
  334. data/specs/r_vector_object.spec.rb +0 -0
  335. data/specs/r_vector_operators.spec.rb +0 -0
  336. data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
  337. data/specs/r_vector_subsetting.spec.rb +0 -0
  338. data/specs/range_helper_spec.rb +21 -0
  339. data/specs/rsupport_scope_spec.rb +28 -0
  340. data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
  341. data/specs/scalar_character_spec.rb +44 -0
  342. data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
  343. data/specs/session_env_bridge_spec.rb +25 -0
  344. data/specs/simplecov_bootstrap_spec.rb +10 -0
  345. data/specs/spec_helper.rb +10 -0
  346. data/specs/tmp.rb +41 -20
  347. data/specs/unboxing_recursion_regression_spec.rb +30 -0
  348. data/specs/unboxing_spec.rb +49 -0
  349. data/specs/verify_callbacks.rb +42 -0
  350. data/sty/galaaz.sty +0 -0
  351. data/version.rb +1 -1
  352. metadata +239 -71
  353. data/blogs/galaaz_ggplot/galaaz_ggplot.aux +0 -41
  354. data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -705
  355. data/blogs/galaaz_ggplot/galaaz_ggplot.out +0 -10
  356. data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
  357. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-latex/midwest_rb.pdf +0 -0
  358. data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-latex/scatter_plot_rb.pdf +0 -0
  359. data/blogs/galaaz_ggplot/midwest.html +0 -188
  360. data/blogs/gknit/gknit.html +0 -2266
  361. data/blogs/gknit/gknit.pdf +0 -0
  362. data/blogs/gknit/gknit.tex +0 -1358
  363. data/blogs/manual/graph.rb +0 -29
  364. data/blogs/manual/manual.html +0 -2995
  365. data/blogs/manual/manual.pdf +0 -0
  366. data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
  367. data/blogs/nse_dplyr/nse_dplyr.html +0 -960
  368. data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
  369. data/blogs/nse_dplyr/nse_dplyr.tex +0 -1373
  370. data/blogs/oh_my/oh_my.html +0 -680
  371. data/blogs/ruby_plot/ruby_plot.Rmd_external_figs +0 -662
  372. data/blogs/ruby_plot/ruby_plot.html +0 -729
  373. data/blogs/ruby_plot/ruby_plot.pdf +0 -0
  374. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.svg +0 -57
  375. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.svg +0 -106
  376. data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.svg +0 -110
  377. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.svg +0 -174
  378. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.svg +0 -236
  379. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.svg +0 -296
  380. data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.svg +0 -236
  381. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.svg +0 -218
  382. data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.svg +0 -128
  383. data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.svg +0 -150
  384. data/examples/paper/paper.rb +0 -36
  385. data/specs/r_dataframe.spec.rb +0 -379
  386. data/specs/r_environment.spec.rb +0 -140
  387. data/specs/r_formula.spec.rb +0 -232
  388. data/specs/r_language.spec.rb +0 -112
  389. data/specs/r_list.spec.rb +0 -293
  390. data/specs/r_plots.spec.rb +0 -72
  391. data/specs/ruby_expression.spec.rb +0 -315
@@ -23,11 +23,25 @@
23
23
 
24
24
  require 'singleton'
25
25
  require 'fileutils'
26
+ require 'pathname'
26
27
 
28
+ # gKnit touches the bridge before the first document chunk runs (install.packages, source, …).
29
+ # If GALAAZ_BRIDGE_TIMEOUT_SEC is unset, use a generous default so render does not hit 60s while
30
+ # the Rmd setup chunk has not yet run. Whitespace-only counts as unset.
31
+ if ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'].nil? || ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'].to_s.strip.empty?
32
+ ENV['GALAAZ_BRIDGE_TIMEOUT_SEC'] = '300'
33
+ end
34
+
35
+ # Load these before anything else to ensure bridge is initialized and libraries are present
27
36
  R.install_and_loads('knitr', 'rmarkdown')
28
37
 
29
- # dir = File.dirname(File.expand_path('.', __FILE__))
30
- # src = "#{dir}/R/eng_ruby.R"
38
+ # Source the R-side include engine wrapper that reads files before calling Ruby
39
+ # This avoids callback deadlock and escaping issues with file content
40
+ dir = File.dirname(File.expand_path(__FILE__))
41
+ include_engine_r = File.join(dir, '..', 'R_interface', 'include_engine.R')
42
+ if File.exist?(include_engine_r)
43
+ R.bridge.eval_r("source('#{include_engine_r}')")
44
+ end
31
45
 
32
46
  class KnitrEngine
33
47
 
@@ -361,40 +375,62 @@ class KnitrEngine
361
375
  # the non-exported function.
362
376
  #--------------------------------------------------------------------------------------
363
377
 
364
- R::Support.eval(<<-R)
378
+ R::Support.eval(<<-GK_BOOT)
365
379
 
366
- # Function to guess the extension name of a file based on the device type
367
- knitr_dev2ext = function(x) {
380
+ # Bind on .GlobalEnv so Ruby exec_function("evaluate_plot_snapshot") / recordPlot / knitr
381
+ # always resolve them (new bridge evaluates in a per-session env; plain '=' here can leave
382
+ # helpers only in transient frames, so gknit never records ggplot output).
383
+ .GlobalEnv$knitr_dev2ext <- function(x) {
368
384
  knitr:::dev2ext(x)
369
385
  }
370
386
 
371
- #" Capture snapshot of current device.
372
- #"
373
- #" There's currently no way to capture when a graphics device changes,
374
- #" except to check its contents after the evaluation of every expression.
375
- #" This means that only the last plot of a series will be captured.
376
- #"
377
- evaluate_plot_snapshot = function() {
378
- evaluate:::plot_snapshot()
387
+ #" Capture snapshot of current device (base R recordPlot; same as galaaz_device.R).
388
+ # g_simpleMessage: same signature as simpleMessage; transforms "; " to newlines then calls base::simpleMessage
389
+ .GlobalEnv$g_simpleMessage <- function(message) {
390
+ message <- gsub("; ", "; \n", message, fixed = TRUE)
391
+ base::simpleMessage(message)
392
+ }
393
+
394
+ # g_simpleWarning: same signature as simpleWarning; transforms "; " to newlines then calls base::simpleWarning
395
+ .GlobalEnv$g_simpleWarning <- function(message) {
396
+ message <- gsub("; ", "; \n", message, fixed = TRUE)
397
+ base::simpleWarning(message)
398
+ }
399
+
400
+ #" evaluate:::plot_snapshot() does not exist in the evaluate package, so use recordPlot().
401
+ .GlobalEnv$evaluate_plot_snapshot <- function() {
402
+ grDevices::recordPlot()
379
403
  }
380
404
 
381
- knitr_wrap = function(x, options) {
405
+ # Save a recorded plot to a file in one R call (open device, replayPlot, dev.off) so device state is consistent.
406
+ .GlobalEnv$save_recorded_plot <- function(path, plot, width, height, dev, res, units) {
407
+ if (dev == "png" || dev == "pdf") {
408
+ if (dev == "png") do.call(grDevices::png, list(path, width = width, height = height, res = res, units = units))
409
+ else do.call(grDevices::pdf, list(path, width = width, height = height))
410
+ grDevices::replayPlot(plot)
411
+ grDevices::dev.off()
412
+ }
413
+ }
414
+
415
+ .GlobalEnv$knitr_wrap <- function(x, options) {
382
416
  knitr:::wrap(x, options)
383
417
  }
384
418
 
385
- wrap.message = function(x, options) {
419
+ assign("wrap.message", function(x, options) {
386
420
  knitr:::msg_wrap(paste("Message:\n", x$message, collapse = ''), 'message', options)
387
- }
421
+ }, envir = .GlobalEnv)
388
422
 
389
423
  # The showtext package, is able to support more font formats and more graphics
390
424
  # devices, and avoids using external software such as Ghostscript. showtext makes it
391
425
  # even easier to use various types of fonts (TrueType, OpenType, Type 1, web fonts,
392
426
  # etc.) in R graphs.
393
- showtext = function() {
427
+ .GlobalEnv$showtext <- function() {
394
428
  showtext::showtext_begin()
395
429
  }
396
-
397
- R
430
+
431
+ invisible(NULL)
432
+
433
+ GK_BOOT
398
434
 
399
435
  #--------------------------------------------------------------------------------------
400
436
  #
@@ -402,7 +438,18 @@ class KnitrEngine
402
438
 
403
439
  def units
404
440
  opt_units = (@options[["units"]])
405
- (opt_units.is__null >> 0) ? "in" : opt_units
441
+ (opt_units.is__null.unboxed_get(0)) ? "in" : opt_units
442
+ end
443
+
444
+ #--------------------------------------------------------------------------------------
445
+ # Safely normalize scalar chunk option values that may come boxed from R.
446
+ #--------------------------------------------------------------------------------------
447
+
448
+ def scalar_option_string(opt)
449
+ return opt.unboxed_get(0).to_s if opt.respond_to?(:unboxed_get)
450
+ opt.to_s
451
+ rescue StandardError
452
+ opt.to_s
406
453
  end
407
454
 
408
455
  #--------------------------------------------------------------------------------------
@@ -420,10 +467,10 @@ class KnitrEngine
420
467
  #--------------------------------------------------------------------------------------
421
468
 
422
469
  def fig_keep
423
- @keep = @options.fig__keep
470
+ @keep = @fig__keep
424
471
  @keep_idx = nil
425
472
 
426
- if (@keep.is__numeric >> 0)
473
+ if (@keep.is__numeric.unboxed_get(0))
427
474
  @keep_idx = @keep
428
475
  @keep = "index"
429
476
  end
@@ -436,10 +483,13 @@ class KnitrEngine
436
483
 
437
484
  def file_ext
438
485
  # guess plot file type if it is NULL
439
- if (((@keep != 'none') >> 0) && (@options.fig__ext.is__null >> 0))
440
- @fig__ext = (R.knitr_dev2ext(@options.dev) >> 0)
486
+ # Use @fig__ext (already set from options['fig.ext']) to avoid calling R's fig.ext(options) which triggers invalid connection
487
+ fig_ext_empty = @fig__ext.nil? || (@fig__ext.respond_to?(:to_s) && @fig__ext.to_s.strip.empty?)
488
+ # NA from knitr "inherit" must not skip dev2ext (same as GalaazUtil.knitr_logical_trueish? for chunk options).
489
+ keep_plots = GalaazUtil.knitr_logical_trueish?(((@keep != 'none') rescue nil))
490
+ if keep_plots && fig_ext_empty
491
+ @fig__ext = (R.knitr_dev2ext(@options).unboxed_get(0))
441
492
  end
442
-
443
493
  end
444
494
 
445
495
  #--------------------------------------------------------------------------------------
@@ -451,18 +501,18 @@ class KnitrEngine
451
501
  @options = options
452
502
 
453
503
  # Chunk options
454
- @label = (options['label'] >> 0)
504
+ @label = (options['label'].unboxed_get(0))
455
505
 
456
506
  # Text results
457
- @eval = options['eval']
458
- @echo = (options['echo'] >> 0)
507
+ @eval = options[["eval"]]
508
+ @echo = GalaazUtil.knitr_option_trueish?(options, 'echo', default: true)
459
509
  @results = options['results']
460
510
  @collapse = options['collapse']
461
511
  @warning = options['warning']
462
512
  @error = options['error']
463
513
  @message = options['message']
464
514
  @split = options['split']
465
- @include = options['include']
515
+ @include = GalaazUtil.knitr_option_trueish?(options, 'include', default: true)
466
516
  @strip__white = options['strip.white']
467
517
  # @render = options['render'] # a function
468
518
  @class__output = options['class.output']
@@ -477,13 +527,13 @@ class KnitrEngine
477
527
  @background = options['background']
478
528
  @class__source = options['class_source']
479
529
 
480
- # Plots
481
- @fig__path = (options['fig.path'] >> 0)
482
- # @fig__keep = options['fig.keep'] # can be a vector
530
+ # Plots - avoid unboxed_get in callback as it uses RESULT_FIFO which fails with "invalid connection"
531
+ @fig__path = scalar_option_string(options['fig.path'])
532
+ @fig__keep = options['fig.keep'] # can be a vector; use options['fig.keep'] not options.fig__keep to avoid R's fig.keep() which triggers invalid connection
483
533
  @fig__show = options['fig.show']
484
534
  @dev = options['dev']
485
535
  # @dev__args = options['dev.args'] # can be a vector
486
- @fig__ext = (options['fig.ext'] >> 0)
536
+ @fig__ext = scalar_option_string(options['fig.ext'])
487
537
  @dpi = options['dpi']
488
538
  @fig__width = options['fig.width']
489
539
  @fig__height = options['fig.height']
@@ -521,7 +571,7 @@ class KnitrEngine
521
571
 
522
572
  # create temporary file for storing plots
523
573
  # TODO: should remove this directory afterwards
524
- @tmp_fig = (R.tempfile() >> 0)
574
+ @tmp_fig = (R.tempfile().unboxed_get(0))
525
575
 
526
576
  end
527
577
 
@@ -543,24 +593,58 @@ class KnitrEngine
543
593
 
544
594
  def self.device(dev_type, filename = nil, *args, width: 480, height: 480,
545
595
  units: "px", res: 72, pointsize: 12, bg: "white")
596
+ supported_devices = %w[awt svg png pdf jpg jpeg bmp]
597
+ dev_name = dev_type.to_s.strip
598
+ unless supported_devices.include?(dev_name)
599
+ raise "Unsupported graphics device '#{dev_name}'. Supported devices: #{supported_devices.join(', ')}"
600
+ end
546
601
 
547
- case dev_type
602
+ case dev_name
548
603
 
549
604
  when "awt"
550
605
  when "svg"
551
606
  R.svg(filename)
552
- when "png", "pdf"
607
+ when "png"
553
608
  R.png(filename, width, height, units, pointsize, bg, res, *args)
609
+ when "pdf"
610
+ width_in = width
611
+ height_in = height
612
+ units_s = units.to_s
613
+ if units_s == "px"
614
+ width_in = width.to_f / res.to_f
615
+ height_in = height.to_f / res.to_f
616
+ elsif units_s == "cm"
617
+ width_in = width.to_f / 2.54
618
+ height_in = height.to_f / 2.54
619
+ end
620
+ R.pdf(filename, width_in, height_in, *args)
554
621
  when "jpg", "jpeg"
555
622
  R.jpeg(filename, width, height, units, pointsize, bg, res, *args)
556
623
  when "bmp"
557
624
  R.bmp(filename, width, height, units, pointsize, bg, res, *args)
558
- else
559
- raise "Invalid device type #{device}"
560
625
  end
561
626
 
562
627
  end
563
628
 
629
+ #--------------------------------------------------------------------------------------
630
+ # A figure is renderable only if the artifact exists and is valid for its device.
631
+ # For PDFs, enforce at least one page so LaTeX includegraphics won't fail.
632
+ #--------------------------------------------------------------------------------------
633
+
634
+ def figure_artifact_ready?(path)
635
+ return false unless File.exist?(path)
636
+ return false unless File.size(path).to_i > 0
637
+
638
+ ext = File.extname(path).downcase
639
+ return true unless ext == ".pdf"
640
+
641
+ pdf_data = File.binread(path)
642
+ counts = pdf_data.scan(%r{/Count\s+(\d+)}).flatten.map(&:to_i)
643
+ !counts.empty? && counts.max > 0
644
+ rescue StandardError
645
+ false
646
+ end
647
+
564
648
  #--------------------------------------------------------------------------------------
565
649
  # Captures a plot by calling evaluate::plot_snapshot, which has the latest plotted
566
650
  # graphics.
@@ -568,25 +652,50 @@ class KnitrEngine
568
652
 
569
653
  def capture_plot
570
654
 
571
- # gets a plot snapshot. Uses function plot_snapshot from package 'evaluate'
655
+ # gets a plot snapshot (base R recordPlot via evaluate_plot_snapshot)
572
656
  plot = R.evaluate_plot_snapshot
573
657
 
574
- if (!(plot.is__null >> 0))
658
+ if (!(plot.is__null.unboxed_get(0)))
575
659
  # create directory for the graphics files if does not already exists
576
- # unless (R.dir__exists(@fig__path) >> 0)
577
660
  unless File.directory?(@fig__path)
578
661
  FileUtils.mkdir_p(@fig__path)
579
662
  end
580
663
 
581
- @options.dev.each do |dev_type|
582
- KnitrEngine.device(dev_type >> 0, @filename,
583
- width: @options.fig__width,
584
- height: @options.fig__height, units: units)
585
- R.print(plot)
586
- R.dev__off
587
- return plot
588
- end
589
-
664
+ # use absolute path so the file is created where Ruby expects and include_graphics can find it
665
+ filename_abs = File.expand_path(@filename)
666
+ # Save in one R call (open device, replayPlot, dev.off) so the file is actually written
667
+ w = (@fig__width >> 0) rescue 480
668
+ h = (@fig__height >> 0) rescue 480
669
+ res = (@dpi >> 0) rescue 72
670
+ dev_str = @dev.respond_to?(:>>) ? (@dev >> 0) : @dev.to_s
671
+ dev_str = dev_str.to_s.split.first if dev_str.respond_to?(:to_s)
672
+ units_str = (units.respond_to?(:>>) ? (units >> 0) : units).to_s rescue "in"
673
+ R.save_recorded_plot(filename_abs, plot, w, h, dev_str, res, units_str)
674
+ return plot
675
+ end
676
+
677
+ # Fallback when recordPlot() returns NULL on non-screen devices:
678
+ # copy from the active device to the target figure file.
679
+ unless File.directory?(@fig__path)
680
+ FileUtils.mkdir_p(@fig__path)
681
+ end
682
+ filename_abs = File.expand_path(@filename)
683
+ w = (@fig__width >> 0) rescue 480
684
+ h = (@fig__height >> 0) rescue 480
685
+ res = (@dpi >> 0) rescue 72
686
+ dev_str = @dev.respond_to?(:>>) ? (@dev >> 0).to_s : @dev.to_s
687
+ dev_str = dev_str.gsub('"', '').strip
688
+
689
+ case
690
+ when dev_str.include?('png')
691
+ R::Support.eval("grDevices::dev.copy(grDevices::png, filename='#{filename_abs.gsub("'", "\\\\'")}', width=#{w}, height=#{h}, units='in', res=#{res}); grDevices::dev.off()")
692
+ return true
693
+ when dev_str.include?('svg')
694
+ R::Support.eval("grDevices::dev.copy(grDevices::svg, filename='#{filename_abs.gsub("'", "\\\\'")}', width=#{w}, height=#{h}); grDevices::dev.off()")
695
+ return true
696
+ when dev_str.include?('pdf')
697
+ R::Support.eval("grDevices::dev.copy(grDevices::pdf, file='#{filename_abs.gsub("'", "\\\\'")}', width=#{w}, height=#{h}); grDevices::dev.off()")
698
+ return true
590
699
  end
591
700
 
592
701
  false
@@ -600,7 +709,8 @@ class KnitrEngine
600
709
  #--------------------------------------------------------------------------------------
601
710
 
602
711
  def add(spec)
603
- (~:knit_engines).set.call(spec)
712
+ # Use [[ so R returns the engine function; single bracket [ returns a list, not callable
713
+ R.knitr___knit_engines[["set"]].call(spec)
604
714
  end
605
715
 
606
716
  #--------------------------------------------------------------------------------------
@@ -623,34 +733,54 @@ class KnitrEngine
623
733
  #--------------------------------------------------------------------------------------
624
734
 
625
735
  def initialize
626
-
736
+
737
+ @chunk_index = 0
738
+
739
+ # Knitr invokes this proc with top-level self (main). Engine state (@options, @filename,
740
+ # capture_plot, process_options) must run on this KnitrEngine singleton (RubyEngine.instance).
741
+ _gknit_self = self
742
+
627
743
  #--------------------------------------------------------------------------------------
628
744
  # Basic engine for processing a chunk
629
745
  #--------------------------------------------------------------------------------------
630
746
 
631
747
  @base_engine = Proc.new do |options|
632
-
748
+ _gknit_self.instance_eval do
749
+ # grDevices::dev.cur() as an R handle (g2_v*) can be reassigned across NewBridge
750
+ # callbacks; dev.off(that_handle) then sees wrong/empty `which`. Unbox immediately.
751
+ dv_n = nil
633
752
  begin
634
753
 
635
754
  out = R.list
636
755
 
637
756
  # process the chunk options.
638
757
  process_options(options)
758
+ @chunk_index += 1
759
+ $stderr.puts "[gknit] Processing chunk #{@chunk_index}: #{@label}"
639
760
 
640
- # opens a device for the current chunk for plot recording
641
- KnitrEngine.device(@options.dev >> 0, @tmp_fig)
642
-
643
- # dv gets the current device
644
- dv = R.dev__cur
761
+ # Open chunk device directly on the final figure target path so inclusion does not
762
+ # depend on later snapshot copying behavior.
763
+ FileUtils.mkdir_p(@fig__path) unless File.directory?(@fig__path)
764
+ chunk_fig_target = File.expand_path(@filename)
765
+ KnitrEngine.device(@dev.unboxed_get(0), chunk_fig_target)
645
766
 
767
+ v = (R.dev__cur >> nil) rescue nil
768
+ if v
769
+ x = v.is_a?(Array) ? v.first : v
770
+ dv_n = x.to_i if x.is_a?(Numeric)
771
+ end
772
+
646
773
  # executes the code chunk with the given options
647
774
  # the returned value is a list properly formatted to be given to engine_output
648
775
  # exec_ruby catches StandardError, so no execution errors on the block will
649
776
  # reach here, they are formatted in the return list to be printed
650
777
  res = GalaazUtil.exec_ruby(@options)
651
778
 
779
+ include_chunk = !!@include
780
+
652
781
  # function engine_output will format whatever is in out inside a white box
653
- out = R.engine_output(@options, out: res) if @echo
782
+ # (exec_ruby now uses simpleMessage/simpleWarning so conditionMessage() works in engine_output)
783
+ out = @echo ? R.engine_output(@options, out: res) : res
654
784
 
655
785
  # ouputs the data in RubyChunk '@outputs' variable. Everything that should
656
786
  # be processed by 'pandoc' and not appear in the output block from
@@ -660,63 +790,49 @@ class KnitrEngine
660
790
  out = R.c(out, RChunk.out_list)
661
791
  RChunk.reset_outputs
662
792
 
663
- # @TODO: allow capturing many plots in the block. For now, only the last
664
- # plot will be captured. Not a very serious problem for now.
665
- # Captures the last plot in the Ruby block.
666
- if (capture_plot)
667
- plot = R.knitr_wrap(R.knit_print(R.include_graphics(@filename)), @options)
668
-
669
- # add to the output the result of plot. Whatever is included after the
670
- # engine_output output will appear 'as.is' in the report. The 'plot'
671
- # variable is a command that in rmarkdown includes the image in the
672
- # report
673
- out = R.c(out, plot)
793
+ # Finalize the chunk device before testing/including artifact; PDF files are not
794
+ # valid for includegraphics until dev.off() closes the page stream.
795
+ if dv_n.is_a?(Integer) && dv_n > 1
796
+ R.dev__off(dv_n)
797
+ dv_n = nil
674
798
  end
675
799
 
800
+ # Include only real, renderable figure artifacts for this chunk.
801
+ if include_chunk
802
+ fig_path = File.expand_path(@filename)
803
+ if figure_artifact_ready?(fig_path)
804
+ fig_rel = Pathname.new(fig_path).relative_path_from(Pathname.new(Dir.pwd)).to_s rescue fig_path
805
+ fig_md = "![](" + fig_rel + ")"
806
+ out = R.c(out, fig_md)
807
+ end
808
+ end
809
+
810
+ # knitr semantics: include=FALSE still evaluates code/side effects, but emits nothing.
811
+ out = R.list unless include_chunk
812
+
676
813
  out
677
814
 
815
+ rescue StandardError, RuntimeError => e
816
+ begin
817
+ GknitDiagnostics.record(chunk_label: (@label || 'unknown'), error: e) if defined?(GknitDiagnostics)
818
+ rescue StandardError
819
+ nil
820
+ end
821
+ # Format error with newlines so R/knitr displays it on multiple lines (not semicolon-joined).
822
+ formatted = e.message.to_s
823
+ formatted += "\n\n--- Ruby backtrace ---\n" + e.backtrace.join("\n") if e.backtrace && !e.backtrace.empty?
824
+ R.list(R.simpleMessage(formatted))
678
825
  ensure
679
- # closes the current device
680
- # R.dev__off(dv)
826
+ # Close the device we opened (which > 1; 1 is the null device and must not be passed to dev.off).
827
+ if dv_n.is_a?(Integer) && dv_n > 1
828
+ R.dev__off(dv_n)
829
+ end
681
830
  end
682
-
683
- end
684
-
685
- super
686
-
687
- end
688
-
689
- end
690
-
691
- =begin
692
- module R
693
-
694
- class Object
695
-
696
- #--------------------------------------------------------------------------------------
697
- # Redefine to_s in order to capture plots when in knitr
698
- #--------------------------------------------------------------------------------------
699
-
700
- def to_s
701
-
702
- STDERR.puts "+++++++++++++++++++++++++++"
703
- STDERR.puts "in to_s"
704
- STDERR.puts "+++++++++++++++++++++++++++"
705
-
706
- cap = nil
707
- cap = R::Support.capture.call(r_interop)
708
- str = String.new
709
- (0...(cap.size - 1)).each do |i|
710
- str << cap[i] << "\n"
711
831
  end
712
- str << cap[cap.size - 1] if cap.size >= 1
713
- re = RubyEngine.instance
714
- re.capture_plot
715
- str
716
832
  end
717
833
 
834
+ super
835
+
718
836
  end
719
837
 
720
838
  end
721
-
722
- =end
@@ -34,10 +34,10 @@ class RbEngine < KnitrEngine
34
34
 
35
35
  @engine = Proc.new do |options|
36
36
 
37
- # the 'rb' engine has the code to be executed in the options.label
38
- # argument
37
+ # the 'rb' engine has the code to be executed in the options['label']
38
+ # argument (use list indexing; options.label would call R's label() which does not exist)
39
39
  # options[['code']] = options[['label']]
40
- options.code = options.label
40
+ options.code = options['label']
41
41
  # we do not want the code to be returned
42
42
  options.echo = false
43
43
 
File without changes
data/lib/gknit.rb CHANGED
@@ -23,7 +23,10 @@
23
23
 
24
24
  require 'galaaz'
25
25
 
26
+ require_relative 'gknit/diagnostics'
26
27
  require_relative 'gknit/knitr_engine'
27
28
  require_relative 'gknit/ruby_engine'
28
29
  require_relative 'gknit/rb_engine'
29
30
  require_relative 'gknit/include_engine'
31
+ require_relative 'gknit/draft'
32
+