galaaz 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +696 -270
  3. data/Rakefile +9 -22
  4. data/bin/gknit +2 -217
  5. data/bin/gknit_old_r +236 -0
  6. data/bin/grun +5 -0
  7. data/blogs/dev/dev.Rmd +7 -0
  8. data/blogs/dev/dev.html +34 -26
  9. data/blogs/dev/dev.md +40 -25
  10. data/blogs/dev/dev_files/figure-html/bubble-1.png +0 -0
  11. data/blogs/dev/dev_files/figure-html/diverging_bar. +0 -0
  12. data/blogs/dev/dev_files/figure-html/diverging_bar.png +0 -0
  13. data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +4 -4
  14. data/blogs/galaaz_ggplot/galaaz_ggplot.html +251 -59
  15. data/blogs/galaaz_ggplot/galaaz_ggplot.log +640 -0
  16. data/blogs/galaaz_ggplot/galaaz_ggplot.md +199 -95
  17. data/blogs/galaaz_ggplot/galaaz_ggplot.tex +45 -228
  18. data/blogs/galaaz_ggplot/midwest.png +0 -0
  19. data/blogs/galaaz_ggplot/scatter_plot.png +0 -0
  20. data/blogs/gknit/gknit.Rmd +271 -148
  21. data/blogs/manual/manual.Rmd +212 -0
  22. data/blogs/manual/manual.html +1832 -0
  23. data/blogs/manual/manual.md +751 -0
  24. data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
  25. data/blogs/ruby_plot/ruby_plot.Rmd +5 -69
  26. data/blogs/ruby_plot/ruby_plot.html +195 -236
  27. data/blogs/ruby_plot/ruby_plot.md +1 -261
  28. data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.svg +38 -38
  29. data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +5 -5
  30. data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +1 -0
  31. data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +3 -7
  32. data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +3 -1
  33. data/lib/R_interface/r.rb +12 -9
  34. data/lib/R_interface/r_methods.rb +2 -2
  35. data/lib/R_interface/rbinary_operators.rb +2 -20
  36. data/lib/R_interface/rdata_frame.rb +56 -9
  37. data/lib/R_interface/rdevices.R +0 -12
  38. data/lib/R_interface/rexpression.rb +0 -97
  39. data/lib/R_interface/rindexed_object.rb +12 -3
  40. data/lib/R_interface/rlanguage.rb +1 -1
  41. data/lib/R_interface/rlist.rb +29 -4
  42. data/lib/R_interface/rlogical_operators.rb +50 -0
  43. data/lib/R_interface/rmatrix.rb +7 -1
  44. data/lib/R_interface/robject.rb +29 -15
  45. data/lib/R_interface/rsupport.rb +74 -58
  46. data/lib/R_interface/rsymbol.rb +2 -1
  47. data/lib/R_interface/ruby_extensions.rb +11 -2
  48. data/lib/R_interface/rvector.rb +26 -11
  49. data/lib/gknit.rb +2 -0
  50. data/lib/gknit/include_engine.rb +57 -0
  51. data/lib/gknit/knitr_engine.rb +596 -50
  52. data/lib/gknit/rb_engine.rb +56 -0
  53. data/lib/gknit/ruby_engine.rb +13 -36
  54. data/lib/util/exec_ruby.rb +132 -21
  55. data/lib/util/inline_file.rb +9 -7
  56. data/specs/all.rb +5 -0
  57. data/specs/figures/bg.jpeg +0 -0
  58. data/specs/figures/bg.png +0 -0
  59. data/specs/figures/bg.svg +57 -0
  60. data/specs/figures/no_args.jpeg +0 -0
  61. data/specs/figures/no_args.png +0 -0
  62. data/specs/figures/no_args.svg +57 -0
  63. data/specs/figures/width_height.jpeg +0 -0
  64. data/specs/figures/width_height.png +0 -0
  65. data/specs/figures/width_height_units1.jpeg +0 -0
  66. data/specs/figures/width_height_units1.png +0 -0
  67. data/specs/figures/width_height_units2.jpeg +0 -0
  68. data/specs/figures/width_height_units2.png +0 -0
  69. data/specs/r_dataframe.spec.rb +29 -27
  70. data/specs/r_devices.spec.rb +347 -0
  71. data/specs/r_eval.spec.rb +10 -3
  72. data/specs/r_formula.spec.rb +2 -2
  73. data/specs/r_language.spec.rb +112 -0
  74. data/specs/r_list.spec.rb +174 -14
  75. data/specs/r_list_apply.spec.rb +17 -10
  76. data/specs/r_matrix.spec.rb +3 -3
  77. data/specs/r_vector_operators.spec.rb +13 -7
  78. data/specs/tmp.rb +42 -12
  79. data/version.rb +1 -1
  80. metadata +28 -24
  81. data/bin/gknit2 +0 -14
  82. data/bin/prepareR.rb +0 -3
  83. data/bin/tmp.py +0 -51
  84. data/blogs/gknit/gknit.html +0 -528
  85. data/blogs/gknit/gknit.md +0 -628
  86. data/blogs/gknit/gknit.pdf +0 -0
  87. data/blogs/gknit/gknit.tex +0 -745
  88. data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
  89. data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
  90. data/blogs/ruby_plot/figures/dose_len.png +0 -0
  91. data/blogs/ruby_plot/figures/facet_by_delivery.png +0 -0
  92. data/blogs/ruby_plot/figures/facet_by_dose.png +0 -0
  93. data/blogs/ruby_plot/figures/facets_by_delivery_color.png +0 -0
  94. data/blogs/ruby_plot/figures/facets_by_delivery_color2.png +0 -0
  95. data/blogs/ruby_plot/figures/facets_with_decorations.png +0 -0
  96. data/blogs/ruby_plot/figures/facets_with_jitter.png +0 -0
  97. data/blogs/ruby_plot/figures/facets_with_points.png +0 -0
  98. data/blogs/ruby_plot/figures/final_box_plot.png +0 -0
  99. data/blogs/ruby_plot/figures/final_violin_plot.png +0 -0
  100. data/blogs/ruby_plot/figures/violin_with_jitter.png +0 -0
  101. data/lib/R/eng_ruby.R +0 -62
  102. data/lib/R_interface/rdevices.rb +0 -225
@@ -29,6 +29,7 @@ module R
29
29
  include ExecBinOp
30
30
  include UnaryOperators
31
31
  include ExecUniOp
32
+ include LogicalOperators
32
33
  include Enumerable
33
34
 
34
35
  #--------------------------------------------------------------------------------------
@@ -47,7 +48,9 @@ module R
47
48
  # @return the Ruby element at the given index in the vector
48
49
  #--------------------------------------------------------------------------------------
49
50
 
50
- def <<(index)
51
+ def >>(index)
52
+ raise IndexError.new("index #{index} out of array bounds: -#{index - 1}...#{index - 1}") if
53
+ (index >= @r_interop.size)
51
54
  @r_interop[index]
52
55
  end
53
56
 
@@ -56,7 +59,7 @@ module R
56
59
  #--------------------------------------------------------------------------------------
57
60
 
58
61
  def pop
59
- self << 0
62
+ self >> 0
60
63
  end
61
64
 
62
65
  #--------------------------------------------------------------------------------------
@@ -70,13 +73,13 @@ module R
70
73
  case result
71
74
  when :vec
72
75
  # length is a R::Vector, in order to extract its size as a Numeric we need to
73
- # use the << operator
74
- (1..length << 0).each do |i|
76
+ # use the >> operator
77
+ (1..length >> 0).each do |i|
75
78
  yield self[i]
76
79
  end
77
80
  when :native
78
- (0...length << 0).each do |i|
79
- yield self << i
81
+ (0...length >> 0).each do |i|
82
+ yield self >> i
80
83
  end
81
84
  else
82
85
  raise "Type #{result} is unknown for method :each"
@@ -91,12 +94,12 @@ module R
91
94
  def each_with_index(result = :vec)
92
95
  case result
93
96
  when :vec
94
- (1..length << 0).each do |i|
97
+ (1..length >> 0).each do |i|
95
98
  yield self[i], i
96
99
  end
97
100
  when :native
98
- (0...length << 0).each do |i|
99
- yield self << i, i
101
+ (0...length >> 0).each do |i|
102
+ yield self >> i, i
100
103
  end
101
104
  else
102
105
  raise "Type #{result} is unknown for method :each"
@@ -105,12 +108,24 @@ module R
105
108
  end
106
109
 
107
110
  #--------------------------------------------------------------------------------------
108
- # SHOULD DEFINE COMPARISON BETWEEN TWO VECTORS
111
+ # @TODO: SHOULD DEFINE COMPARISON BETWEEN TWO VECTORS
109
112
  #--------------------------------------------------------------------------------------
110
113
 
111
114
  def <=>(other_vector)
112
-
115
+ puts "comparison called"
116
+ end
117
+
118
+ #=begin
119
+ #--------------------------------------------------------------------------------------
120
+ # @TODO Need to understand why to_ary is being called here and what the effect is of
121
+ # returning the empty array. For now, doing this returns better error messages in
122
+ # rspec
123
+ #--------------------------------------------------------------------------------------
124
+
125
+ def to_ary
126
+ []
113
127
  end
128
+ #=end
114
129
 
115
130
  end
116
131
 
@@ -25,3 +25,5 @@ require 'galaaz'
25
25
 
26
26
  require_relative 'gknit/knitr_engine'
27
27
  require_relative 'gknit/ruby_engine'
28
+ require_relative 'gknit/rb_engine'
29
+ require_relative 'gknit/include_engine'
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # @author Rodrigo Botafogo
5
+ #
6
+ # Copyright © 2018 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
7
+ # and distribute this software and its documentation, without fee and without a signed
8
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
9
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
10
+ # distributions.
11
+ #
12
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
13
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
14
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
15
+ # POSSIBILITY OF SUCH DAMAGE.
16
+ #
17
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
19
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
20
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
21
+ # OR MODIFICATIONS.
22
+ ##########################################################################################
23
+
24
+ class IncludeEngine < KnitrEngine
25
+ include Singleton
26
+
27
+ attr_reader :engine
28
+
29
+ #--------------------------------------------------------------------------------------
30
+ # Ruby engine for processing 'include' chunks
31
+ #--------------------------------------------------------------------------------------
32
+
33
+ def initialize
34
+
35
+ # call super to make @base_engine available
36
+ super
37
+
38
+ @engine = Proc.new do |options|
39
+
40
+ # check if require should be relative or not
41
+ req = (options[['relative']].is__null | options[['relative']].isTRUE) >> 0
42
+
43
+ # load the content of the file in options.code
44
+ options.code = GalaazUtil.inline_file(options.label >> 0, req)
45
+
46
+ @base_engine.call(options)
47
+ end
48
+
49
+ # Add the include engine function for processing the rb block
50
+ add(include: @engine)
51
+
52
+ end
53
+
54
+ end
55
+
56
+ include_engine = IncludeEngine.instance
57
+
@@ -21,6 +21,9 @@
21
21
  # OR MODIFICATIONS.
22
22
  ##########################################################################################
23
23
 
24
+ require 'singleton'
25
+ require 'fileutils'
26
+
24
27
  R.install_and_loads('knitr', 'rmarkdown')
25
28
 
26
29
  # dir = File.dirname(File.expand_path('.', __FILE__))
@@ -29,6 +32,327 @@ R.install_and_loads('knitr', 'rmarkdown')
29
32
  class KnitrEngine
30
33
 
31
34
  attr_reader :options
35
+
36
+ #
37
+ # Code Evaluation
38
+ #
39
+
40
+ # eval: (TRUE; logical) whether to evaluate the code chunk
41
+ attr_reader :eval
42
+
43
+ #
44
+ # Text Results
45
+ #
46
+
47
+ # echo: (TRUE; logical) whether to include Ruby source code in
48
+ # the output file
49
+ attr_reader :echo
50
+
51
+ # results: ('markup'; character) takes these possible values
52
+ # markup: mark up the results using the output hook, e.g. put results in a
53
+ # special LaTeX environment
54
+ # asis: output as-is, i.e., write raw results from R into the output document
55
+ # hold: hold all the output pieces and push them to the end of a chunk
56
+ # hide (or FALSE): hide results; this option only applies to normal R
57
+ # output (not warnings, messages or errors)
58
+ attr_reader :results
59
+
60
+ # collapse: (FALSE; logical; applies to Markdown output only) whether to,
61
+ # if possible, collapse all the source and output blocks from one code chunk
62
+ # into a single block (by default, they are written to separate <pre></pre> blocks)
63
+ attr_reader :collapse
64
+
65
+ # warning: (TRUE; logical) whether to preserve warnings (produced by warning())
66
+ # in the output like we run R code in a terminal (if FALSE, all warnings will
67
+ # be printed in the console instead of the output document); it can also
68
+ # take numeric values as indices to select a subset of warnings to
69
+ # include in the output
70
+ attr_reader :warning
71
+
72
+ # error: (TRUE; logical) whether to preserve errors (from stop()); by default,
73
+ # the evaluation will not stop even in case of errors!! if we want R to stop
74
+ # on errors, we need to set this option to FALSE
75
+ # when the chunk option include = FALSE, error knitr will stop on error,
76
+ # because it is easy to overlook potential errors in this case
77
+ attr_reader :error
78
+
79
+ # message: (TRUE; logical) whether to preserve messages emitted by
80
+ # message() (similar to warning)
81
+ attr_reader :message
82
+
83
+ # split: (FALSE; logical) whether to split the output from R into separate
84
+ # files and include them into LaTeX by \input{} or HTML by <iframe></iframe>;
85
+ # this option only works for .Rnw, .Rtex, and .Rhtml documents
86
+ # (it does not work for R Markdown)
87
+ attr_reader :split
88
+
89
+ # include: (TRUE; logical) whether to include the chunk output in the final
90
+ # output document; if include=FALSE, nothing will be written into the output
91
+ # document, but the code is still evaluated and plot files are generated if
92
+ # there are any plots in the chunk, so you can manually insert figures;
93
+ # note this is the only chunk option that is not cached, i.e., changing it
94
+ # will not invalidate the cache
95
+ attr_reader :include
96
+
97
+ # strip.white: (TRUE; logical) whether to remove the white lines in the
98
+ # beginning or end of a source chunk in the output
99
+ attr_reader :strip__white
100
+
101
+ # render: (knitr::knit_print; function(x, options, ...)) the function which
102
+ # formats the result of the chunk for the final output format. The function
103
+ # is given the chunk result as first argument and the list of chunk options
104
+ # as a named argument options. If the function contains further arguments
105
+ # which match names of chunk options, they are filled with the respective
106
+ # values. The function is expected to return one string which is then
107
+ # rendered appropriately for the current output format. For more information,
108
+ # invoke the help about custom chunk rendering: Invoke in R:
109
+ # vignette('knit_print', package = 'knitr') and ?knitr::knit_print.
110
+ attr_reader :render
111
+
112
+ # class.output: (NULL; character) useful for HTML output, appends classes
113
+ # that can be used in conjunction with css, so you can apply custom formatting.
114
+ attr_reader :class__output
115
+
116
+ #
117
+ # Code Decoration
118
+ #
119
+
120
+ # tidy: (FALSE) whether to reformat the R code; other possible values are:
121
+ # * TRUE (equivalent to 'formatR'): use formatR::tidy_source() to reformat the code;
122
+ # * 'styler': use styler::style_text() to reformat the code;
123
+ # * a custom function of the form function(code, ...) {} to return the reformatted code;
124
+ # * if reformatting failed, the original R code will not be changed (with a warning)
125
+ attr_reader :tidy
126
+
127
+ # tidy.opts: (NULL; list) a list of options to be passed to the function
128
+ # determined by the tidy option, e.g.,
129
+ # tidy.opts = list(blank = FALSE, width.cutoff = 60) for tidy = 'formatR'
130
+ # to remove blank lines and set the approximate line width to be 60
131
+ attr_reader :tidy__opts
132
+
133
+ # prompt: (FALSE; logical) whether to add the prompt characters in the R
134
+ # code (see prompt and continue in ?base::options; note that adding prompts
135
+ # can make it difficult for readers to copy R code from the output, so
136
+ # prompt=FALSE may be a better choice
137
+ # this option may not work well when the chunk option engine is not R (#1274)
138
+ attr_reader :prompt
139
+
140
+ # comment: ('##'; character) the prefix to be put before source code output;
141
+ # default is to comment out the output by ##, which is good for readers to copy
142
+ # R source code since output is masked in comments
143
+ # (set comment=NA to disable this feature)
144
+ attr_reader :comment
145
+
146
+ # highlight: (TRUE; logical) whether to highlight the source code
147
+ # (it is FALSE by default if the output is Sweave or listings)
148
+ attr_reader :highlight
149
+
150
+ # size: ('normalsize'; character) font size for the default LaTeX
151
+ # output (see ?highlight in the highlight package for a list of possible values)
152
+ attr_reader :size
153
+
154
+ # background: ('#F7F7F7'; character or numeric) background color of chunks
155
+ # in LaTeX output (passed to the LaTeX package framed); the color model is rgb;
156
+ # it can be either a numeric vector of length 3, with each element between 0 and 1
157
+ # to denote red, green and blue, or any built-in color in R like red or
158
+ # springgreen3 (see colors() for a full list), or a hex string like #FFFF00,
159
+ # or an integer (all these colors will be converted to the RGB model;
160
+ # see ?col2rgb for details)
161
+ attr_reader :background
162
+
163
+ # class.source: (NULL; character) useful for HTML output, appends classes that
164
+ # can be used in conjunction with css, so you can apply custom formatting.
165
+ attr_reader :class__source
166
+
167
+ #
168
+ # Plots
169
+ #
170
+
171
+ # fig.path: ('figure/'; character) prefix to be used for figure filenames
172
+ # (fig.path and chunk labels are concatenated to make filenames); it may contain
173
+ # a directory like figure/prefix- (will be created if it does not exist);
174
+ # this path is relative to the current working directory; if the prefix ends in
175
+ # a trailing slash, e.g. output/figures/, figures will be saved in the specified
176
+ # directory without any changes to filename prefix, thus providing a relative
177
+ # filepath alternative to the package-level option base.dir
178
+ attr_reader :fig__path
179
+ attr_reader :fig__filename
180
+
181
+ # fig.keep: ('high'; character) how plots in chunks should be kept; it takes
182
+ # five possible character values or a numeric vector
183
+ # (see the end of this section for an example)
184
+ # * high: only keep high-level plots (merge low-level changes into high-level plots);
185
+ # * none: discard all plots;
186
+ # * all: keep all plots (low-level plot changes may produce new plots)
187
+ # * first: only keep the first plot
188
+ # * last: only keep the last plot
189
+ # if set to a numeric vector: interpret value as index of (low-level) plots to keep
190
+ attr_reader :fig__keep
191
+
192
+ # fig.show: ('asis'; character) how to show/arrange the plots; four
193
+ # possible values are
194
+ # * asis: show plots exactly in places where they were generated
195
+ # (as if the code were run in an R terminal);
196
+ # * hold: hold all plots and output them in the very end of a code chunk;
197
+ # * animate: wrap all plots into an animation if there are mutiple plots in a chunk;
198
+ # * hide: generate plot files but hide them in the output document
199
+ attr_reader :fig__show
200
+
201
+ # dev: ('pdf' for LaTeX output and 'png' for HTML/markdown; character) the function
202
+ # name which will be used as a graphical device to record plots; for the convenience
203
+ # of usage, this package has included all the graphics devices in base R as well as
204
+ # those in Cairo, cairoDevice and tikzDevice, e.g. if we set dev='CairoPDF', the
205
+ # function with the same name in the Cairo package will be used for graphics output;
206
+ # if none of the 20 built-in devices is appropriate, we can still provide yet another
207
+ # name as long as it is a legal function name which can record plots
208
+ # (it must be of the form function(filename, width, height)); note the units for
209
+ # images are always inches (even for bitmap devices, in which DPI is used to convert
210
+ # between pixels and inches); currently available devices are bmp, postscript, pdf,
211
+ # png, svg, jpeg, pictex, tiff, win.metafile, cairo_pdf, cairo_ps, CairoJPEG,
212
+ # CairoPNG, CairoPS, CairoPDF, CairoSVG, CairoTIFF, Cairo_pdf, Cairo_png, Cairo_ps,
213
+ # Cairo_svg, tikz and a series of quartz devices including quartz_pdf, quartz_png,
214
+ # quartz_jpeg, quartz_tiff, quartz_gif, quartz_psd, quartz_bmp which are just
215
+ # wrappers to the function quartz() with different file types
216
+ # * the options dev, fig.ext, fig.width, fig.height and dpi can be vectors
217
+ # (shorter ones will be recycled), e.g. <<foo, dev=c('pdf', 'png')>>= creates
218
+ # two files for the same plot: foo.pdf and foo.png
219
+ attr_reader :dev
220
+
221
+ # dev.args: (NULL) more arguments to be passed to the device, e.g.
222
+ # dev.args=list(bg='yellow', pointsize=10); note this depends on the specific
223
+ # device (see the device documentation); when dev has multiple elements, dev.args
224
+ # can be a list of lists of arguments with each list of arguments to be passed to
225
+ # each single device, e.g. <<dev=c('pdf', 'tiff'),
226
+ # dev.args=list(pdf = list(colormodel = 'cmyk', useDingats = TRUE),
227
+ # tiff = list(compression = 'lzw'))>>=
228
+ attr_reader :dev__args
229
+
230
+ # fig.ext: (NULL; character) file extension of the figure output
231
+ # (if NULL, it will be derived from the graphical device; see
232
+ # knitr:::auto_exts for details)
233
+ attr_reader :fig__ext
234
+
235
+ # dpi: (72; numeric) the DPI (dots per inch) for bitmap devices (dpi * inches = pixels)
236
+ attr_reader :dpi
237
+
238
+ # fig.width, fig.height: (both are 7; numeric) width and height of the plot,
239
+ # to be used in the graphics device (in inches) and have to be numeric
240
+ attr_reader :fig__width
241
+ attr_reader :fig__height
242
+
243
+ # fig.asp: (NULL; numeric) the aspect ratio of the plot, i.e. the ratio of
244
+ # height/width; when fig.asp is specified, the height of a plot (the chunk option
245
+ # fig.height) is calculated from fig.width * fig.asp
246
+ attr_reader :fig__asp
247
+
248
+ # fig.dim: (NULL; numeric) if a numeric vector of length 2, it gives fig.width
249
+ # and fig.height, e.g., fig.dim = c(5, 7) is a shorthand of fig.width = 5,
250
+ # fig.height = 7; if both fig.asp and fig.dim are provided, fig.asp will
251
+ # be ignored (with a warning)
252
+ attr_reader :fig__dim
253
+
254
+ # out.width, out.height: (NULL; character) width and height of the plot in
255
+ # the final output file (can be different with its real fig.width and fig.height,
256
+ # i.e. plots can be scaled in the output document); depending on the output format,
257
+ # these two options can take flexible values, e.g. for LaTeX output, they
258
+ # can be .8\\linewidth, 3in or 8cm and for HTML, they may be 300px (do not have to
259
+ # be in inches like fig.width and fig.height; backslashes must be escaped as \\);
260
+ # for LaTeX output, the default value for out.width will be changed to \\maxwidth
261
+ # which is defined here out.width can also be a percentage, e.g. '40%' will be
262
+ # translated to 0.4\linewidth when the output format is LaTeX
263
+ attr_reader :out__width
264
+ attr_reader :out__height
265
+
266
+ # out.extra: (NULL; character) extra options for figures, e.g. out.extra='angle=90'
267
+ # in LaTeX output will rotate the figure by 90 degrees; it can be an arbitrary
268
+ # string, e.g. you can write multiple figure options in this option; it also applies
269
+ # to HTML images (extra options will be written into the <img /> tag, e.g.
270
+ # out.extra='style="display:block;"')
271
+ attr_reader :out__extra
272
+
273
+ # fig.retina: (1; numeric) this option only applies to HTML output; for Retina
274
+ # displays, setting this option to a ratio (usually 2) will change the chunk
275
+ # option dpi to dpi * fig.retina, and out.width to fig.width * dpi / fig.retina
276
+ # internally; for example, the physical size of an image is doubled and its display
277
+ # size is halved when fig.retina = 2
278
+ attr_reader :fig__retina
279
+
280
+ # resize.width, resize.height: (NULL; character) the width and height to be used
281
+ # in \resizebox{}{} in LaTeX; these two options are not needed unless you want to
282
+ # resize tikz graphics because there is no natural way to do it; however, according
283
+ # to tikzDevice authors, tikz graphics is not meant to be resized to maintain
284
+ # consistency in style with other texts in LaTeX; if only one of them is NULL,
285
+ # ! will be used (read the documentation of graphicx if you do not understand this)
286
+ attr_reader :resize__width
287
+ attr_reader :resize__height
288
+
289
+ # fig.align: ('default'; character) alignment of figures in the output document
290
+ # (possible values are left, right and center; default is not to make any
291
+ # alignment adjustments); note that for Markdown output, forcing figure
292
+ # alignments will lead to the HTML tag <img /> instead of the original Markdown
293
+ # syntax ![](), because Markdown does not have native support for figure
294
+ # alignments (see #611)
295
+ attr_reader :fig__align
296
+
297
+ # fig.env: ('figure') the LaTeX environment for figures, e.g. set
298
+ # fig.env='marginfigure' to get \begin{marginfigure}
299
+ attr_reader :fig__env
300
+
301
+ # fig.cap: (NULL; character) figure caption to be used in a figure environment
302
+ # in LaTeX (in \caption{}); if NULL or NA, it will be ignored, otherwise a
303
+ # figure environment will be used for the plots in the chunk
304
+ # (output in \begin{figure} and \end{figure})
305
+ attr_reader :fig__cap
306
+
307
+ # fig.scap: (NULL; character) short caption; if NULL, all the words before .
308
+ # or ; or : will be used as a short caption; if NA, it will be ignored
309
+ attr_reader :fig__scap
310
+
311
+ # fig.lp: ('fig:'; character) label prefix for the figure label to be used
312
+ # in \label{}; the actual label is made by concatenating this prefix and the
313
+ # chunk label, e.g. the figure label for <<foo-plot>>= will be fig:foo-plot by default
314
+ attr_reader :label
315
+ attr_reader :fig__lp
316
+
317
+ # fig.pos: (''; character) a character string for the figure position arrangement
318
+ # to be used in \begin{figure}[fig.pos]
319
+ attr_reader :fig__pos
320
+
321
+ # fig.subcap: (NULL) captions for subfigures; when there are multiple plots in
322
+ # a chunk, and neither fig.subcap nor fig.cap is NULL, \subfloat{} will be used
323
+ # for individual plots (you need to add \usepackage{subfig} in the preamble);
324
+ # see 067-graphics-options.Rnw for an example
325
+ attr_reader :fig__subcap
326
+
327
+ # fig.ncol: (NULL; integer) the number of columns of subfigures; see here for
328
+ # examples (note that fig.ncol and fig.sep only work for LaTeX output)
329
+ attr_reader :fig__ncol
330
+
331
+ # fig.sep: (NULL; character) a character vector of separators to be inserted among
332
+ # subfigures; when fig.ncol is specified, fig.sep defaults to a character vector
333
+ # of which every N-th element is \newline (where N is the number of columns),
334
+ # e.g., fig.ncol = 2 means
335
+ # fig.sep = c('', '', '\\newline', '', '', '\\newline', '', ...)
336
+ attr_reader :fig__sep
337
+
338
+ # fig.process: (NULL) a function to post-process a figure file; it should take a
339
+ # filename, and return a character string as the new source of the figure to be
340
+ # inserted in the output
341
+ attr_reader :fig__process
342
+
343
+ # fig.showtext: (NULL) if TRUE, call showtext::showtext.begin() before drawing
344
+ # plots; see the documentation of the showtext package for details
345
+ attr_reader :fig__showtext
346
+
347
+ # external: (TRUE; logical) whether to externalize tikz graphics (pre-compile
348
+ # tikz graphics to PDF); it is only used for the tikz() device in the tikzDevice
349
+ # package (i.e., when dev='tikz') and it can save time for LaTeX compilation
350
+ attr_reader :external
351
+
352
+ # sanitize: (FALSE; character) whether to sanitize tikz graphics (escape
353
+ # special LaTeX characters); see documentation in the tikzDevice package
354
+ attr_reader :sanitize
355
+
32
356
  attr_reader :keep
33
357
 
34
358
  #--------------------------------------------------------------------------------------
@@ -38,32 +362,56 @@ class KnitrEngine
38
362
  #--------------------------------------------------------------------------------------
39
363
 
40
364
  R::Support.eval(<<-R)
41
- _ck_dv = function(width, height, record = TRUE, dev, dev.args, dpi, options,
42
- tmp = tempfile()) {
43
- knitr:::chunk_device(width, height, record, dev, dev.args, dpi, options, tmp)
44
- }
45
- R
46
365
 
47
- #--------------------------------------------------------------------------------------
48
- # The showtext package, is able to support more font formats and more graphics
49
- # devices, and avoids using external software such as Ghostscript. showtext makes it
50
- # even easier to use various types of fonts (TrueType, OpenType, Type 1, web fonts,
51
- # etc.) in R graphs.
52
- #--------------------------------------------------------------------------------------
366
+ # Function to guess the extension name of a file based on the device type
367
+ knitr_dev2ext = function(x) {
368
+ knitr:::dev2ext(x)
369
+ }
53
370
 
54
- R::Support.eval(<<-R)
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()
379
+ }
380
+
381
+ knitr_wrap = function(x, options) {
382
+ knitr:::wrap(x, options)
383
+ }
384
+
385
+ wrap.message = function(x, options) {
386
+ knitr:::msg_wrap(paste("Message:\n", x$message, collapse = ''), 'message', options)
387
+ }
388
+
389
+ # The showtext package, is able to support more font formats and more graphics
390
+ # devices, and avoids using external software such as Ghostscript. showtext makes it
391
+ # even easier to use various types of fonts (TrueType, OpenType, Type 1, web fonts,
392
+ # etc.) in R graphs.
55
393
  showtext = function() {
56
394
  showtext::showtext_begin()
57
395
  }
58
- R
59
396
 
397
+ R
398
+
399
+ #--------------------------------------------------------------------------------------
400
+ #
401
+ #--------------------------------------------------------------------------------------
402
+
403
+ def units
404
+ opt_units = (@options[["units"]])
405
+ (opt_units.is__null >> 0) ? "in" : opt_units
406
+ end
407
+
60
408
  #--------------------------------------------------------------------------------------
61
409
  # Process the fig.keep chunk option
62
410
  # @param keep [String/Numeric] a string or a number. If it is a string then it should
63
411
  # be one of the following:
64
412
  # * high: only keep high-level plots (merge low-level changes into high-level plots);
65
413
  # * none: discard all plots;
66
- # * all: keep all plots (low-level plot changes may produce new plots)
414
+ # * all: keep all plots (low-level plot changes may produce new plots)
67
415
  # * first: only keep the first plot
68
416
  # * last: only keep the last plot
69
417
  # if set to a numeric vector: interpret value as index of (low-level) plots to keep
@@ -71,66 +419,180 @@ class KnitrEngine
71
419
  # index.
72
420
  #--------------------------------------------------------------------------------------
73
421
 
74
- def self.fig_keep
422
+ def fig_keep
75
423
  @keep = @options.fig__keep
76
424
  @keep_idx = nil
77
-
78
- if (@keep.is__numeric << 0)
425
+
426
+ if (@keep.is__numeric >> 0)
79
427
  @keep_idx = @keep
80
428
  @keep = "index"
81
429
  end
82
-
430
+
83
431
  end
84
-
432
+
85
433
  #--------------------------------------------------------------------------------------
86
434
  #
87
435
  #--------------------------------------------------------------------------------------
88
436
 
89
- def self.file_ext
437
+ def file_ext
90
438
  # guess plot file type if it is NULL
91
- if (((@keep != 'none') << 0) && (@options.fig__ext.is__null << 0))
92
- # TODO: allow @options.fig__ext when it is null... confusing otherwise!
93
- @options["fig.ext"] = R.knitr_dev2ext(@options.dev)
94
- puts @options.fig__ext
95
- end
96
- end
97
-
98
- #--------------------------------------------------------------------------------------
99
- #
100
- #--------------------------------------------------------------------------------------
101
-
102
- def self.capture_plot
103
-
104
- plot = R.evaluate_plot_snapshot
105
-
106
- if (!(R.is__null(plot) << 0))
107
- R.png(@filename)
108
- R.print(plot)
109
- R.dev__off
439
+ if (((@keep != 'none') >> 0) && (@options.fig__ext.is__null >> 0))
440
+ @fig__ext = (R.knitr_dev2ext(@options.dev) >> 0)
110
441
  end
111
442
 
112
443
  end
113
-
444
+
114
445
  #--------------------------------------------------------------------------------------
115
446
  # Process the chunk options
116
447
  #--------------------------------------------------------------------------------------
117
448
 
118
- def self.process_options(options)
449
+ def process_options(options)
450
+
119
451
  @options = options
452
+
453
+ # Chunk options
454
+ @label = (options['label'] >> 0)
455
+
456
+ # Text results
457
+ @eval = options['eval']
458
+ @echo = (options['echo'] >> 0)
459
+ @results = options['results']
460
+ @collapse = options['collapse']
461
+ @warning = options['warning']
462
+ @error = options['error']
463
+ @message = options['message']
464
+ @split = options['split']
465
+ @include = options['include']
466
+ @strip__white = options['strip.white']
467
+ # @render = options['render'] # a function
468
+ @class__output = options['class.output']
469
+
470
+ # Code Decoration
471
+ # @tidy = options['tidy']
472
+ # @tidy__opts = options['tidy.opts']
473
+ @prompt = options['prompt']
474
+ @comment = options['comment']
475
+ @highlight = options['highlight']
476
+ @size = options['size']
477
+ @background = options['background']
478
+ @class__source = options['class_source']
120
479
 
480
+ # Plots
481
+ @fig__path = (options['fig.path'] >> 0)
482
+ # @fig__keep = options['fig.keep'] # can be a vector
483
+ @fig__show = options['fig.show']
484
+ @dev = options['dev']
485
+ # @dev__args = options['dev.args'] # can be a vector
486
+ @fig__ext = (options['fig.ext'] >> 0)
487
+ @dpi = options['dpi']
488
+ @fig__width = options['fig.width']
489
+ @fig__height = options['fig.height']
490
+ @fig__asp = options['fig.asp']
491
+ # @fig__dim = options['fig.dim'] # vector with two elements
492
+ @out__width = options['out.width']
493
+ @out__height = options['out.height']
494
+ @out__extra = options['out.extra']
495
+ @fig__retina = options['fig.retina']
496
+ @resize__width = options['resize.width']
497
+ @resize__height = options['resize.height']
498
+ @fig__align = options['fig.align']
499
+ @fig__env = options['fig.env']
500
+ @fig__cap = options['fig.cap']
501
+ @fig__scap = options['fig.scap']
502
+ @fig__lp = options['fig.lp']
503
+ @fig__pos = options['fig.pos']
504
+ @fig__subcap = options['fig.subcap']
505
+ @fig__ncol = options['fig.ncol']
506
+ # @fig__sep = options['fig.sep'] # a vector
507
+ @fig__process = options['fig.process']
508
+ @fig__showtext = options['fig.showtext']
509
+ @external = options['external']
510
+ @sanitize = options['sanitize']
511
+
121
512
  # verifies if figures should be kept
122
513
  fig_keep
123
514
 
124
515
  # if figures are to be kept, take or guess the file extension
125
516
  file_ext
126
-
127
- # puts @keep
128
517
 
129
518
  # make final filename
130
- @filename = R.paste0(@options.fig__path, @options.label, ".", @options.fig__ext)
519
+ @filename = "#{@fig__path}#{@label}.#{@fig__ext}"
520
+ @options["filename"] = "."
521
+
522
+ # create temporary file for storing plots
523
+ # TODO: should remove this directory afterwards
524
+ @tmp_fig = (R.tempfile() >> 0)
525
+
526
+ end
527
+
528
+ #--------------------------------------------------------------------------------------
529
+ # @param dev_type [String] name of the device type to open
530
+ # @param filename [String] filename to store the image. By default nil for the awt
531
+ # device
532
+ # @param args [Array] other parameters to be passed to device. Right now, there are
533
+ # no other parameters that should be passed to the available devices. Might be
534
+ # needed when more devices are available
535
+ # @param width [Numeric] width of the figure, by default 480
536
+ # @param height [Numeric] hegiht of the figure, by default 480
537
+ # @param units [String] string with units definition, by default 'px'. Could be
538
+ # 'in', 'cm'
539
+ # @param res [Numeric] resolution in dpi, if not provided set to 72
540
+ # @param pointsize [Numeric]
541
+ # @param bg [String]
542
+ #--------------------------------------------------------------------------------------
543
+
544
+ def self.device(dev_type, filename = nil, *args, width: 480, height: 480,
545
+ units: "px", res: 72, pointsize: 12, bg: "white")
546
+
547
+ case dev_type
548
+
549
+ when "awt"
550
+ when "svg"
551
+ R.svg(filename)
552
+ when "png", "pdf"
553
+ R.png(filename, width, height, units, pointsize, bg, res, *args)
554
+ when "jpg", "jpeg"
555
+ R.jpeg(filename, width, height, units, pointsize, bg, res, *args)
556
+ when "bmp"
557
+ R.bmp(filename, width, height, units, pointsize, bg, res, *args)
558
+ else
559
+ raise "Invalid device type #{device}"
560
+ end
131
561
 
132
562
  end
133
563
 
564
+ #--------------------------------------------------------------------------------------
565
+ # Captures a plot by calling evaluate::plot_snapshot, which has the latest plotted
566
+ # graphics.
567
+ #--------------------------------------------------------------------------------------
568
+
569
+ def capture_plot
570
+
571
+ # gets a plot snapshot. Uses function plot_snapshot from package 'evaluate'
572
+ plot = R.evaluate_plot_snapshot
573
+
574
+ if (!(plot.is__null >> 0))
575
+
576
+ # create directory for the graphics files if does not already exists
577
+ unless File.directory?(@fig__path)
578
+ FileUtils.mkdir_p(@fig__path)
579
+ end
580
+
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
+
590
+ end
591
+
592
+ false
593
+
594
+ end
595
+
134
596
  #--------------------------------------------------------------------------------------
135
597
  # Adds the new knitr engine to the list of engines
136
598
  # @param spec [Hash] hash with only one pair containing the machine key and the engine
@@ -140,35 +602,119 @@ class KnitrEngine
140
602
  def add(spec)
141
603
  (~:knit_engines).set.call(spec)
142
604
  end
605
+
606
+ #--------------------------------------------------------------------------------------
607
+ #
608
+ #--------------------------------------------------------------------------------------
609
+
610
+ def add_hook(spec)
611
+
612
+ end
143
613
 
144
- end
614
+
615
+ #--------------------------------------------------------------------------------------
616
+ #
617
+ #--------------------------------------------------------------------------------------
618
+
619
+ private
145
620
 
621
+ #--------------------------------------------------------------------------------------
622
+ #
623
+ #--------------------------------------------------------------------------------------
624
+
625
+ def initialize
626
+
627
+ #--------------------------------------------------------------------------------------
628
+ # Basic engine for processing a chunk
629
+ #--------------------------------------------------------------------------------------
146
630
 
631
+ @base_engine = Proc.new do |options|
632
+
633
+ begin
634
+
635
+ out = R.list
636
+
637
+ # process the chunk options.
638
+ process_options(options)
639
+
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
645
+
646
+ # executes the code chunk with the given options
647
+ # the returned value is a list properly formatted to be given to engine_output
648
+ # exec_ruby catches StandardError, so no execution errors on the block will
649
+ # reach here, they are formatted in the return list to be printed
650
+ res = GalaazUtil.exec_ruby(@options)
651
+
652
+ # function engine_output will format whatever is in out inside a white box
653
+ out = R.engine_output(@options, out: res) if @echo
654
+
655
+ # ouputs the data in RubyChunk '@@outputs' variable. Everything that should
656
+ # be processed by 'pandoc' and not appear in the output block from
657
+ # engine_output, should be outputed with the 'outputs' function and will be
658
+ # stored in the @@outputs variable
659
+ out = R.c(out, RubyChunk.get_outputs)
660
+
661
+ # @TODO: allow capturing many plots in the block. For now, only the last
662
+ # plot will be captured. Not a very serious problem for now.
663
+ # Captures the last plot in the Ruby block.
664
+ if (capture_plot)
665
+ plot = R.knitr_wrap(R.knit_print(R.include_graphics(@filename)), @options)
666
+
667
+ # add to the output the result of plot. Whatever is included after the
668
+ # engine_output output will appear 'as.is' in the report. The 'plot'
669
+ # variable is a command that in rmarkdown includes the image in the
670
+ # report
671
+ out = R.c(out, plot)
672
+ end
673
+
674
+ out
675
+
676
+ ensure
677
+ # closes the current device
678
+ # R.dev__off(dv)
679
+ end
680
+
681
+ end
682
+
683
+ super
684
+
685
+ end
686
+
687
+ end
147
688
 
689
+ =begin
148
690
  module R
149
691
 
150
692
  class Object
151
-
693
+
152
694
  #--------------------------------------------------------------------------------------
153
695
  # Redefine to_s in order to capture plots when in knitr
154
696
  #--------------------------------------------------------------------------------------
155
697
 
156
698
  def to_s
157
699
 
700
+ STDERR.puts "+++++++++++++++++++++++++++"
701
+ STDERR.puts "in to_s"
702
+ STDERR.puts "+++++++++++++++++++++++++++"
703
+
158
704
  cap = nil
159
- # dev = R::Device.new('png', width: 5, height: 7, dpi: 300, record: true) {
160
705
  cap = R::Support.capture.call(r_interop)
161
- # cap = R::Support.capture_output.call(r_interop)
162
- # }
163
706
  str = String.new
164
707
  (0...(cap.size - 1)).each do |i|
165
708
  str << cap[i] << "\n"
166
709
  end
167
710
  str << cap[cap.size - 1] if cap.size >= 1
168
- KnitrEngine.capture_plot
711
+ re = RubyEngine.instance
712
+ re.capture_plot
169
713
  str
170
714
  end
171
715
 
172
716
  end
173
717
 
174
718
  end
719
+
720
+ =end