ppr 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 71f7684269c365ceabde0b9a78723562b4e05557
4
- data.tar.gz: 1dd28975ce62b8b8983fbeb300acf8d135c6569b
3
+ metadata.gz: 9c406b99cf38bd9244827b268c16a331b41f752d
4
+ data.tar.gz: 213074c919132f292e4edff0e0389c537f3b5349
5
5
  SHA512:
6
- metadata.gz: 75867d46fd7a09643f1b3c91cc48110ec5f37ce38d8175714fdec7991b2828c19071836deb4c82f9b233294ab812085a061e277380cbe63d77779c5049b6816a
7
- data.tar.gz: 22ccdc04aaba51bae61700b8afb5c5ad51308ae47607bfe964605cb96d82c9b515ff6d39fb77e1d5eff8baeb8a4dc38e6714c29f4f64e0884d461c3b9d1b31ed
6
+ metadata.gz: 4e908bea3122b499442c72844fa5675a0cf58626dc15d2b2437d574f7536e2f6c0861c89d242de5242a97076e4c0d37bf86b2f21a8f2573820b8ea48a1c0479a
7
+ data.tar.gz: 412ca44eee6324788cd342ff83b75502bb133bb10f933814e403e3933137bb12fd0939a9fe9cbfb340b02811ccb61f9b3a7c6b2c8ab5c99e4eca4de1e15aacd7
@@ -2,11 +2,12 @@
2
2
  ## Map class for searching keywords in a text. ##
3
3
  ######################################################################
4
4
 
5
-
5
+ ##
6
+ # Tool for looking for keywords within a string.
6
7
  class KeywordSearcher
7
8
 
8
- ## Creates a new keyword searcher, where words are between +seperators+
9
- # regular expressions.
9
+ # Creates a new keyword searcher, where words are between +seperators+
10
+ # regular expressions.
10
11
  def initialize(separator = "")
11
12
  # Checks and set the separator.
12
13
  @separator = Regexp.new(separator).to_s
@@ -25,7 +26,7 @@ class KeywordSearcher
25
26
  return self
26
27
  end
27
28
 
28
- ## Adds a +keyword+ to the searcher associated with an +object+.
29
+ # Adds a +keyword+ to the searcher associated with an +object+.
29
30
  def []=(keyword,object)
30
31
  # Ensure the keyword is a valid string.
31
32
  keyword = keyword.to_str
@@ -41,17 +42,17 @@ class KeywordSearcher
41
42
  @keyword_extract = Regexp.new(@keywords.join("|"))
42
43
  end
43
44
 
44
- ## Get the object corresponding to +keyword+.
45
+ # Get the object corresponding to +keyword+.
45
46
  def [](keyword)
46
47
  return @map[keyword.to_s]
47
48
  end
48
49
 
49
- ## Search a keyword inside a +text+ and return the corresponding object
50
- # if found with the range in the string where it has been found.
50
+ # Search a keyword inside a +text+ and return the corresponding object
51
+ # if found with the range in the string where it has been found.
51
52
  #
52
- # If a keyword is in +skip+ it s ignored.
53
+ # If a keyword is in +skip+ it s ignored.
53
54
  #
54
- # NOTE: the first found object is returned.
55
+ # NOTE: the first found object is returned.
55
56
  def find(text,skip = [])
56
57
  # print "skip=#{skip} @keywords=#{@keywords}\n"
57
58
  # Compute the regular expression for finding the keywords.
@@ -78,13 +79,13 @@ class KeywordSearcher
78
79
  end
79
80
  end
80
81
 
81
- ## Search each keyword inside a +text+ and apply the block on the
82
- # corresponding objects if found with the range in the string where it
83
- # has been found.
82
+ # Search each keyword inside a +text+ and apply the block on the
83
+ # corresponding objects if found with the range in the string where it
84
+ # has been found.
84
85
  #
85
- # Returns an enumerator if no block is given.
86
+ # Returns an enumerator if no block is given.
86
87
  #
87
- # NOTE: keywords included into a longer one are ignored.
88
+ # NOTE: keywords included into a longer one are ignored.
88
89
  def each_in(text)
89
90
  return to_enum(:each_in,text) unless block_given?
90
91
  # Check and clone the text to avoid side effects.
data/lib/ppr/ppr_core.rb CHANGED
@@ -8,38 +8,42 @@ require "ppr/keyword_searcher.rb"
8
8
  module Ppr
9
9
 
10
10
 
11
- ## Converts a +name+ to an attribute symbol.
11
+ ##
12
+ # Converts a +name+ to an attribute symbol.
12
13
  def Ppr.to_attribute(name)
13
14
  name = name.to_s
14
15
  (name.start_with?("@") ? name : "@" + name).to_sym
15
16
  end
16
17
 
17
- ## Describes a storage for line number
18
+ ##
19
+ # Describes a storage for line number
18
20
  class LineNumber < SimpleDelegator
19
- ## Creates a new storage for line number +num+.
21
+ # Creates a new storage for line number +num+.
20
22
  def initialize(num)
21
23
  super(num.to_i)
22
24
  end
23
25
 
24
- ## Sets the line number to +num+.
26
+ # Sets the line number to +num+.
25
27
  def set(num)
26
28
  __setobj__(num.to_i)
27
29
  end
28
30
  end
29
31
 
30
32
 
31
- ## Describes a macro of the ruby preprocessor.
33
+ ##
34
+ # Describes a macro of the ruby preprocessor.
32
35
  class Macro
33
36
 
34
- ## The name of the macro.
37
+ # The name of the macro.
35
38
  attr_reader :name
36
39
 
37
- ## Creates a new macro named +name+, starting at line number +num+,
38
- # generated from preprocessor +ppr+ and with possible +variables+.
39
- #
40
- # The +expand+ strings can be redefined through keyword arguments.
41
- # The +final+ flag indicates that the result of the macro expansion
42
- # shall not be preprocessed again.
40
+ # Creates a new macro named +name+, starting at line number +num+,
41
+ # generated from preprocessor +ppr+ and with possible +variables+.
42
+ #
43
+ # Other parameters:
44
+ # +expand+:: used to redefine the expand operator
45
+ # +final+:: indicates that the result of the macro expansion
46
+ # shall not be preprocessed again.
43
47
  def initialize(name, num, ppr, *variables, expand: ":<", final: true)
44
48
  # Check and set the name.
45
49
  @name = name.to_str
@@ -82,13 +86,13 @@ class Macro
82
86
  #}}} This comment is just to avoid confusing the text editor.
83
87
  end
84
88
 
85
- ## Tells if the maco expansion result is final (i.e. it is not preprocessed
86
- # again) or not.
89
+ # Tells if the maco expansion result is final (i.e., it is not preprocessed
90
+ # again) or not.
87
91
  def final?
88
92
  return @final
89
93
  end
90
94
 
91
- ## Adds a +line+ to the macro.
95
+ # Adds a +line+ to the macro.
92
96
  def add(line)
93
97
  # Process the line.
94
98
  # Remove the ending newline if any.
@@ -96,13 +100,13 @@ class Macro
96
100
  end
97
101
  alias << add
98
102
 
99
- ## Checks if the macro is empty (no code line yet).
103
+ # Checks if the macro is empty (no code line yet).
100
104
  def empty?
101
105
  return @lines.empty?
102
106
  end
103
107
 
104
- ## Generates the code of the macro invoked at line number +i_number+
105
- # using +values+ for the variables.
108
+ # Generates the code of the macro invoked at line number +i_number+
109
+ # using +values+ for the variables.
106
110
  def generate(i_number,*values)
107
111
  # First generate a variable for the resulting text.
108
112
  result = "result_"
@@ -140,13 +144,13 @@ class Macro
140
144
 
141
145
  # Methods used by apply for handling exception messages.
142
146
 
143
- ## Regular expression for identifying a line number inside an exception
144
- # message
147
+ # Regular expression for identifying a line number inside an exception
148
+ # message.
145
149
  E_NUMBER = /:[1-9][0-9]*:/
146
- ## Type of exception which correspond to a macro execution.
150
+ # Type of exception which correspond to a macro execution.
147
151
  E_TYPE = /\(eval\)\s*/
148
152
 
149
- ## Tells if an exception +message+ includes a line number.
153
+ # Tells if an exception +message+ includes a line number.
150
154
  def e_number(message)
151
155
  found = E_NUMBER.match(message)
152
156
  if found then
@@ -158,12 +162,12 @@ class Macro
158
162
  end
159
163
  end
160
164
 
161
- ## Tells if an exception message is of a given +type+.
165
+ # Tells if an exception message is of a given +type+.
162
166
  def e_type?(message,type)
163
167
  return message =~ Regexp.new(type)
164
168
  end
165
169
 
166
- ## Shifts the line number inside an exception +message+ by +sh+.
170
+ # Shifts the line number inside an exception +message+ by +sh+.
167
171
  def e_shift_number(message,sh)
168
172
  # Edit the message to fix the line number and raise then.
169
173
  return message.gsub(E_NUMBER) { |str|
@@ -181,8 +185,8 @@ class Macro
181
185
  }
182
186
  end
183
187
 
184
- ## Update an exception +message+ to refer macro +name+ invoked at line
185
- # number +i_number+ and adds a possible macro line +number+.
188
+ # Update an exception +message+ to refer macro +name+ invoked at line
189
+ # number +i_number+ and adds a possible macro line +number+.
186
190
  def Macro.e_message(name, message, i_number, number = nil)
187
191
  result = "Ppr error (#{name}:#{i_number})"
188
192
  result << ":#{number}: " if number
@@ -190,13 +194,13 @@ class Macro
190
194
  return result
191
195
  end
192
196
 
193
- ## Update an exception +message+ to refer the macro invoked at line number
194
- # +i_number+ and adds a possible macro line +number+.
197
+ # Update an exception +message+ to refer the macro invoked at line number
198
+ # +i_number+ and adds a possible macro line +number+.
195
199
  def e_message(message, i_number, number = nil)
196
200
  Macro.e_message(@name,message,i_number,number)
197
201
  end
198
202
 
199
- ## Applies the macro invoked at line number +i_number+ with +arguments+.
203
+ # Applies the macro invoked at line number +i_number+ with +arguments+.
200
204
  def apply(i_number,*arguments)
201
205
  # Generate the code of the macro.
202
206
  code = self.generate(i_number,*arguments)
@@ -261,20 +265,22 @@ class Macro
261
265
  end
262
266
 
263
267
 
264
- ## Describes an assignment macro of the ruby preprocessor.
268
+ ##
269
+ # Describes an assignment macro of the ruby preprocessor.
265
270
  class Assign < Macro
266
- ## Creates a new assignment macro whose assigned variable is +var+,
267
- # starting at line number +num+ generated from preprocessor +ppr+.
268
- #
269
- # The +expand+ strings be redefined through keyword arguments.
271
+ # Creates a new assignment macro whose assigned variable is +var+,
272
+ # starting at line number +num+ generated from preprocessor +ppr+.
273
+ #
274
+ # Other parameters:
275
+ # +expand+:: redefines the expand operator string.
270
276
  def initialize(name, num, ppr, expand: ":<")
271
277
  super(name,num,ppr,expand: expand)
272
278
  # Creates the attribute which will be assigned.
273
279
  @var_sym = Ppr.to_attribute(name)
274
280
  end
275
281
 
276
- ## Applies the macro invoked at line number +i_number+,
277
- # its result in assigned to the class variable.
282
+ # Applies the macro invoked at line number +i_number+,
283
+ # its result in assigned to the class variable.
278
284
  def apply(i_number)
279
285
  # Expands the macro.
280
286
  line = super(i_number)
@@ -285,17 +291,18 @@ class Assign < Macro
285
291
  end
286
292
  end
287
293
 
288
- ## Descibes an abstract class for loading or requiring files.
294
+ ##
295
+ # Descibes an abstract class for loading or requiring files.
289
296
  class LoadRequire < Macro
290
- ## Creates a new load or require macro starting at line number +num+
291
- # generated from preprocessor +ppr+.
292
- #
293
- # The +expand+ strings be redefined through keyword arguments.
297
+ # Creates a new load or require macro starting at line number +num+
298
+ # generated from preprocessor +ppr+.
299
+ #
300
+ # The +expand+ strings be redefined through keyword arguments.
294
301
  def initialize(num, ppr, expand: ":<")
295
302
  super("",num,ppr,expand: expand)
296
303
  end
297
304
 
298
- ## Loads and preprocess file +name+.
305
+ # Loads and preprocess file +name+.
299
306
  def loadm(name)
300
307
  output = StringIO.new("")
301
308
  # print "name=#{name}\n"
@@ -306,10 +313,11 @@ class LoadRequire < Macro
306
313
  end
307
314
  end
308
315
 
309
- ## Describes a macro loading and pasting a file into the current one.
316
+ ##
317
+ # Describes a macro loading and pasting a file into the current one.
310
318
  class Load < LoadRequire
311
- ## Applies the macro invoked at line number +i_number+,
312
- # its result is the name of the file to be loaded.
319
+ # Applies the macro invoked at line number +i_number+,
320
+ # its result is the name of the file to be loaded.
313
321
  def apply(i_number)
314
322
  # Expand the macro, its result is the name of the file to load.
315
323
  name = super(i_number)
@@ -320,13 +328,13 @@ class Load < LoadRequire
320
328
  end
321
329
  end
322
330
 
323
- ## Describes a macro loading and pasting a file into the current one
324
- # only if it has not already been loaded before.
331
+ # Describes a macro loading and pasting a file into the current one
332
+ # only if it has not already been loaded before.
325
333
  class Require < LoadRequire
326
334
  @@required = [] # The already required files.
327
335
 
328
- ## Applies the macro invoked at line number +i_number+,
329
- # its result is the name of the file to be loaded if not already loaded.
336
+ # Applies the macro invoked at line number +i_number+,
337
+ # its result is the name of the file to be loaded if not already loaded.
330
338
  def apply(i_number)
331
339
  # Expand the macro, its result is the name of the file to load.
332
340
  name = super(i_number)
@@ -343,36 +351,38 @@ class Require < LoadRequire
343
351
  end
344
352
  end
345
353
 
346
- ## Describes a conditional macro.
354
+ ##
355
+ # Describes a conditional macro.
347
356
  class If < Macro
348
- ## Creates a new load or require macro starting at line number +num+
349
- # generated from preprocessor +ppr+.
350
- #
351
- # The +expand+ strings be redefined through keyword arguments.
357
+ # Creates a new load or require macro starting at line number +num+
358
+ # generated from preprocessor +ppr+.
359
+ #
360
+ # The +expand+ strings be redefined through keyword arguments.
352
361
  def initialize(num, ppr, expand: ":<")
353
362
  super("",num,ppr,expand: expand)
354
363
  end
355
364
  end
356
365
 
357
366
 
358
- ## Describes the ruby preprocessor.
367
+ ##
368
+ # Describes the ruby preprocessor.
359
369
  #
360
- # Usage:
370
+ # Usage:
361
371
  # ppr = Ppr::Preprocessor.new(<some options>)
362
372
  # ppr.preprocess(<some input stream>, <some output stream>)
363
373
  class Preprocessor
364
374
 
365
- ## Creates a new preprocessor, where +apply+, +applyR+, +define+, +defineR+,
366
- # +assign+, +loadm+, +requirem+, +ifm+, +elsem+ and +endm+ are the
367
- # keywords defining the beginings and end of a macro definitions,
368
- # and where +separator+ is the regular expression used for
369
- # separating macro references to the remaining of the code, +expand+ is
370
- # the string representing the expansion operator of the macro, +glue+ is
371
- # string used for glueing a macro expension to the text,
372
- # +escape+ is the escape character.
375
+ # Creates a new preprocessor, where +apply+, +applyR+, +define+, +defineR+,
376
+ # +assign+, +loadm+, +requirem+, +ifm+, +elsem+ and +endm+ are the
377
+ # keywords defining the beginings and end of a macro definitions,
378
+ # and where +separator+ is the regular expression used for
379
+ # separating macro references to the remaining of the code, +expand+ is
380
+ # the string representing the expansion operator of the macro, +glue+ is
381
+ # string used for glueing a macro expension to the text,
382
+ # +escape+ is the escape character.
373
383
  #
374
- # Assigned parameters can be added through +param+ to be used within
375
- # the macros of the preprocessed text.
384
+ # Assigned parameters can be added through +param+ to be used within
385
+ # the macros of the preprocessed text.
376
386
  def initialize(params = {},
377
387
  apply: ".do", applyR: ".doR",
378
388
  define: ".def", defineR: ".defR",
@@ -447,27 +457,27 @@ class Preprocessor
447
457
 
448
458
  # Methods for handling the execution context of the macros.
449
459
 
450
- ## Executes a macro in a safe context.
460
+ # Executes a macro in a safe context.
451
461
  def run(&proc)
452
462
  @generator.run do |__stream__|
453
463
  @context.instance_exec(__stream__,&proc)
454
464
  end
455
465
  end
456
466
 
457
- ## Sets parameter +param+ to +value+.
467
+ # Sets parameter +param+ to +value+.
458
468
  def parameter_set(param,value)
459
469
  # print "Setting #{Ppr.to_attribute(param)} with #{value.to_s}\n"
460
470
  @context.instance_variable_set(Ppr.to_attribute(param),value.to_s)
461
471
  end
462
472
 
463
- ## Gets the value of parameter +param.
473
+ # Gets the value of parameter +param.
464
474
  def parameter_get(param)
465
475
  return @context.instance_variable_get(Ppr.to_attribute(param))
466
476
  end
467
477
 
468
478
  # Methods for parsing the lines.
469
479
 
470
- ## Restores a +string+ whose begining may have been glued.
480
+ # Restores a +string+ whose begining may have been glued.
471
481
  def unglue_front(string)
472
482
  if string.start_with?(@glue) then
473
483
  # There is a glue, so remove it.
@@ -479,7 +489,7 @@ class Preprocessor
479
489
  return string
480
490
  end
481
491
 
482
- ## Restores a +string+ whose ending may have been glued.
492
+ # Restores a +string+ whose ending may have been glued.
483
493
  def unglue_back(string)
484
494
  if string.end_with?(@glue) then
485
495
  # There is a glue, so remove it.
@@ -491,8 +501,7 @@ class Preprocessor
491
501
  return string
492
502
  end
493
503
 
494
- ## Gest the range of an argument starting
495
- # from offset +start+ of +line+.
504
+ # Gets the range of an argument starting at offset +start+ in +line+.
496
505
  def get_argument_range(line, start)
497
506
  if start >= line.size then
498
507
  raise "incomplete arguments in macro call."
@@ -501,8 +510,9 @@ class Preprocessor
501
510
  return (range[0]+start)..(range[1]+start-1)
502
511
  end
503
512
 
504
- ## Iterates over the range each argument of a +line+ from offset +start+.
505
- # NOTE: keywords included into a longer one are ignored.
513
+ # Iterates over the range each argument of a +line+ from offset +start+.
514
+ #
515
+ # NOTE: keywords included into a longer one are ignored.
506
516
  def each_argument_range(line,start)
507
517
  return to_enum(:each_argument_range,line,start) unless block_given?
508
518
  begin
@@ -519,22 +529,22 @@ class Preprocessor
519
529
  end
520
530
 
521
531
 
522
- ## Tells if a line corresponds to an end keyword.
532
+ # Tells if a line corresponds to an end keyword.
523
533
  def is_endm?(line)
524
534
  @endm.match(line)
525
535
  end
526
536
 
527
- ## Tells if a line corresponds to an else keyword.
537
+ # Tells if a line corresponds to an else keyword.
528
538
  def is_elsem?(line)
529
539
  @elsem.match(line)
530
540
  end
531
541
 
532
- ## Tells if a line corresponds to an endif keyword.
542
+ # Tells if a line corresponds to an endif keyword.
533
543
  def is_endifm?(line)
534
544
  @endifm.match(line)
535
545
  end
536
546
 
537
- ## Extract a macro definition from a +line+ if there is one.
547
+ # Extract a macro definition from a +line+ if there is one.
538
548
  def get_macro_def(line)
539
549
  line = line.strip
540
550
  # Locate and identify the macro keyword.
@@ -613,9 +623,9 @@ class Preprocessor
613
623
  end
614
624
 
615
625
 
616
- ## Apply recursively each element of +macros+ to +line+.
626
+ # Applies recursively each element of +macros+ to +line+.
617
627
  #
618
- # NOTE: a same macro is apply only once in a portion of the line.
628
+ # NOTE: a same macro is apply only once in a portion of the line.
619
629
  def apply_macros(line)
620
630
  # print "apply_macros on line=#{line}\n"
621
631
 
@@ -677,10 +687,10 @@ class Preprocessor
677
687
  return expanded
678
688
  end
679
689
 
680
- ## Close a +macro+ being input registering it if named or applying it
681
- # otherwise.
690
+ # Close a +macro+ being input registering it if named or applying it
691
+ # otherwise.
682
692
  #
683
- # NOTE: for internal use only.
693
+ # NOTE: for internal use only.
684
694
  def close_macro(macro)
685
695
  # Is the macro named?
686
696
  unless macro.name.empty? or macro.is_a?(Assign) then
@@ -717,8 +727,8 @@ class Preprocessor
717
727
  end
718
728
  private :close_macro
719
729
 
720
- ## Preprocess an +input+ stream and write the result to an +output+
721
- # stream.
730
+ # Preprocess an +input+ stream and write the result to an +output+
731
+ # stream.
722
732
  def preprocess(input, output)
723
733
  # # The current list of macros.
724
734
  # @macros = KeywordSearcher.new(@separator)
@@ -5,24 +5,24 @@
5
5
  ######################################################################
6
6
 
7
7
 
8
- ## Class which allows to safely execute a proc which generate safely
9
- # a string into a stream.
8
+ # Tool for executing in a safer sandbox a proc that generates a string into a
9
+ # stream.
10
10
  class SaferGenerator
11
11
 
12
- ## The exception raised when the safer processed failed.
12
+ # The exception raised when the safer processed failed.
13
13
  class SaferException < RuntimeError
14
14
  end
15
15
 
16
- ## The list of dangerous constants of Object.
16
+ # The list of dangerous constants of Object.
17
17
  DANGER_CONSTANTS = [ :File, :IO, :Dir ]
18
18
 
19
- ## The list of dangerous methods of Kernel
19
+ # The list of dangerous methods of Kernel
20
20
  DANGER_METHODS = [ :system, :`, :open ]
21
21
 
22
22
 
23
- ## Creates a new safe context with while removing Kernel methods and
24
- # constants from +black_list+ in addition to the default dangerous
25
- # ones.
23
+ # Creates a new safe context with while removing Kernel methods and
24
+ # constants from +black_list+ in addition to the default dangerous
25
+ # ones.
26
26
  def initialize(*black_list)
27
27
  # Set the black list of methods.
28
28
  @black_methods = black_list.select do |symbol|
@@ -34,10 +34,10 @@ class SaferGenerator
34
34
  end
35
35
  end
36
36
 
37
- ## Strips all the Kernel methods and constants appart from the
38
- # elements of the white list.
39
- # Also strip Object from dangerous methods and constants apart
40
- # from the elements of the white list.
37
+ # Strips all the Kernel methods and constants appart from the
38
+ # elements of the white list.
39
+ # Also strip Object from dangerous methods and constants apart
40
+ # from the elements of the white list.
41
41
  def secure
42
42
  # Gather the methods to strip.
43
43
  methods = DANGER_METHODS + @black_methods
@@ -54,9 +54,9 @@ class SaferGenerator
54
54
  end
55
55
 
56
56
 
57
- ## Executes +block+ in a safe context for generating text into a +stream+.
57
+ # Executes +block+ in a safe context for generating text into a +stream+.
58
58
  #
59
- # If no stream is given, returns the result as a string instead.
59
+ # If no stream is given, returns the result as a string instead.
60
60
  def run(stream = nil, &block)
61
61
  unless stream
62
62
  # No stream given
data/lib/ppr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ppr
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/lib/ppr.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  require "ppr/version"
2
2
  require "ppr/ppr_core"
3
3
 
4
- ## Module including the classes implementing the preprocessor in Ruby.
4
+ ##
5
+ # Module including the classes implementing the preprocessor in Ruby.
5
6
  #
6
- # Usage:
7
+ # Usage:
7
8
  # ppr = Ppr::Preprocessor.new(<some options>)
8
9
  # ppr.preprocess(<input stream to preprocess>,
9
10
  # <output stream where to write the preprocessing result>)}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ppr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lovic Gauthier