GENERATORS.md in antelope-0.3.2 vs GENERATORS.md in antelope-0.4.0
- old
+ new
@@ -1,124 +1,180 @@
-# Generators
-
-_Antelope_ comes with an assortment of generators; however, if you wish to create a custom generator, here's how.
-
-First, you'll want to make your generator a subclass of `Antelope::Generator::Base`. This sets up a basic framework for you to build upon.
-
-```Ruby
-class MyGenerator < Antelope::Generator::Base
-
-end
-```
-
-Next, you'll want to define a `generate` method on your generator that takes no arguments. This is used internally by _Antelope_ to actually have your generator perform its generation. In the case of this generator, we'll have it copy over a template (after running the templating generator over it over it).
-
-```Ruby
-class MyGenerator < Antelope::Generator::Base
-
- def generate
- template "my_template", "#{file}.my_file"
- end
-end
-```
-
-`Base` provides a few convienince methods for you, one of them being [`template`](http://rubydoc.info/github/medcat/antelope/master/Antelope/Generator/Base#template-instance_method); `file` is also provided, and it contains the base part of the file name of the parser ace file that this is being generated for. The template, by default, should rest in `<lib path>/lib/antelope/generator/templates` (with `<lib path>` being the place that _Antelope_ was installed); however, if it should be changed, you can overwrite the `source_root` method on the class:
-
-```Ruby
-class MyGenerator < Antelope::Generator::Base
-
- def self.source_root
- Pathname.new("/path/to/source")
- end
-
- def generate
- template "my_template", "#{file}.my_file"
- end
-end
-```
-
-In the template, the code is run in the context of the instance of the class, so you have access to instance variables and methods as if you were defining a method on the class:
-
-```
-{{ table.each_with_index do |hash, i| }}
- state {{= i }}:
-{{ hash.each do |token, action| }}
- for {{= token }}, I'll {{= action[0] }} {{= action[1] }}
-{{ end }}
-{{ end }}
-```
-
-_Note: in templates, blocks that start at the beginning of a line and end at the end of a line do not produce any whitespace._
-
-`table` here is defined on the base class, and we're iterating over all of the values of it.
-
-The last thing to do is to register the generator with _Antelope_. This is as simple as adding a line `register_as "my_generator"` to the class definition. Then, if any grammar file has the type `"my_generator"`, your generator will be run (assuming it's been required by _Antelope_).
-
-The finialized product:
-
-```Ruby
-# my_generator.rb
-class MyGenerator < Antelope::Generator::Base
-
- register_as "my_generator"
-
- def self.source_root
- Pathname.new("/path/to/source")
- end
-
- def generate
- template "my_template.erb", "#{file}.my_file"
- end
-end
-```
-
-```
-# my_template.ant
-{{ table.each_with_index do |hash, i| }}
- state {{= i }}:
-{{ hash.each do |token, action| }}
- for {{= token }}, I'll {{= action[0] }} {{= action[1] }}
-{{ end }}
-{{ end }}
-```
-
-## Bundling
-
-If you want to bundle a few generators together such that the bundle is generated together, you can use an `Antelope::Generator::Group`. This would be useful for something like a C language generator, which may need to generate both a header and a source file:
-
-```Ruby
-class CHeader < Antelope::Generator::Base
- # ...
-end
-
-class CSource < Antelope::Generator::Base
- # ...
-end
-
-
-class C < Antelope::Generator::Group
- register_generator CHeader, "c-header"
- register_generator CSource, "c-source"
-end
-```
-
-The `register_generator` takes a generator class and a name for the generator, and adds the generator to the list of generators on the receiver (in this case, the `C` class). Now, when `C#generate` is run, it will run both `CHeader#generate` and `CSource#generate`.
-
-## Using Compiler Directives
-
-Directives are statements that are used in Ace files in order to pass information to _Antelope_. They normally follow the syntax `%<directive name> [directive arguments]*`. See [the Ace file format](http://rubydoc.info/github/medcat/antelope/Antelope/Ace) for more information about directives.
-
-In some cases, like in the [Ruby generator][Ruby], options from the Ace file are needed for generation. In the case of the Ruby generator, we need the error class that the developer wants the generator to use; and we reference it through the `ruby.error-class` directive. In order to define directives that can be used in custom generators, you just need to add a few lines:
-
-```Ruby
-class MyGenerator < Antelope::Generator::Base
-
- has_directive "my-generator.some-value", Boolean
-
-end
-```
-
-In this example, we define a directive named `my-generator.some-value`; this directive is eventually coerced into a `true`/`false` value. In order to actually use the value of the directive, in either the template or a method on the generator, you can reference `directives["my-generator.some-value"]`, which will be `nil` (it wasn't defined), `true` (it was defined, with any arguments), or `false` (it was explicitly defined with one argument, `"false"`). Some other values you can pass in place of `Boolean` would be `:single` (or `:one`), which only gives the first argument passed to the directive; an `Array` of types, which would coerce each argument into its corresponding element of the array; `Array`, which will give an array of the given arguments; `String`, which gives a string representation of the first argument; any `Numeric` subclass, which would coerce the first argument into an integer; `Float`, which would coerce the first argument into a float; any class, which would be instantized with the arguments to the directive. Any other values would yield an error.
-
-It is recommended that you namespace directives that only your generator would use, using dashed syntax, like in our example above. However, some directives are not namespaced, or are not namespaced under a generator; these may be used by any generator. It is also recommended that you declare every directive that you use.
-
-[Ruby]: http://rubydoc.info/github/medcat/antelope/Antelope/Generator/Ruby
+# Generators
+
+_Antelope_ comes with an assortment of generators; however, if you
+wish to create a custom generator, here's how.
+
+First, you'll want to make your generator a subclass of
+`Antelope::Generator::Base`. This sets up a basic framework for you
+to build upon.
+
+```Ruby
+class MyGenerator < Antelope::Generator::Base
+
+end
+```
+
+Next, you'll want to define a `generate` method on your generator that
+takes no arguments. This is used internally by _Antelope_ to actually
+have your generator perform its generation. In the case of this
+generator, we'll have it copy over a template (after running the
+templating generator over it over it).
+
+```Ruby
+class MyGenerator < Antelope::Generator::Base
+
+ def generate
+ template "my_template", "#{file}.my_file"
+ end
+end
+```
+
+`Base` provides a few convienince methods for you, one of them being [`template`](http://rubydoc.info/github/medcat/antelope/master/Antelope/Generator/Base#template-instance_method);
+`file` is also provided, and it contains the base part of the file
+name of the parser ace file that this is being generated for. The
+template, by default, should rest in
+`<lib path>/lib/antelope/generator/templates` (with `<lib path>` being
+ the place that _Antelope_ was installed); however, if it should be
+ changed, you can overwrite the `source_root` method on the class:
+
+```Ruby
+class MyGenerator < Antelope::Generator::Base
+
+ def self.source_root
+ Pathname.new("/path/to/source")
+ end
+
+ def generate
+ template "my_template", "#{file}.my_file"
+ end
+end
+```
+
+In the template, the code is run in the context of the instance of the
+class, so you have access to instance variables and methods as if you
+were defining a method on the class:
+
+```
+{{ table.each_with_index do |hash, i| }}
+ state {{= i }}:
+{{ hash.each do |token, action| }}
+ for {{= token }}, I'll {{= action[0] }} {{= action[1] }}
+{{ end }}
+{{ end }}
+```
+
+_Note: in templates, blocks that start at the beginning of a line and
+end at the end of a line do not produce any whitespace._
+
+`table` here is defined on the base class, and we're iterating over
+all of the values of it.
+
+The last thing to do is to register the generator with _Antelope_.
+This is as simple as adding a line `register_as "my_generator"` to the
+class definition. Then, if any grammar file has the type
+`"my_generator"`, your generator will be run (assuming it's been
+required by _Antelope_).
+
+The finialized product:
+
+```Ruby
+# my_generator.rb
+class MyGenerator < Antelope::Generator::Base
+
+ register_as "my_generator"
+
+ def self.source_root
+ Pathname.new("/path/to/source")
+ end
+
+ def generate
+ template "my_template.erb", "#{file}.my_file"
+ end
+end
+```
+
+```
+# my_template.ant
+{{ table.each_with_index do |hash, i| }}
+ state {{= i }}:
+{{ hash.each do |token, action| }}
+ for {{= token }}, I'll {{= action[0] }} {{= action[1] }}
+{{ end }}
+{{ end }}
+```
+
+## Bundling
+
+If you want to bundle a few generators together such that the bundle
+is generated together, you can use an `Antelope::Generator::Group`.
+This would be useful for something like a C language generator, which
+may need to generate both a header and a source file:
+
+```Ruby
+class CHeader < Antelope::Generator::Base
+ # ...
+end
+
+class CSource < Antelope::Generator::Base
+ # ...
+end
+
+
+class C < Antelope::Generator::Group
+ register_generator CHeader, "c-header"
+ register_generator CSource, "c-source"
+end
+```
+
+The `register_generator` takes a generator class and a name for the
+generator, and adds the generator to the list of generators on the
+receiver (in this case, the `C` class). Now, when `C#generate` is
+run, it will run both `CHeader#generate` and `CSource#generate`.
+
+## Using Compiler Directives
+
+Directives are statements that are used in Ace files in order to pass
+information to _Antelope_. They normally follow the syntax
+`%<directive name> [directive arguments]*`. See
+[the Ace file format](http://rubydoc.info/github/medcat/antelope/Antelope/Ace)
+for more information about directives.
+
+In some cases, like in the [Ruby generator][Ruby], options from the
+Ace file are needed for generation. In the case of the Ruby
+generator, we need the error class that the developer wants the
+generator to use; and we reference it through the `ruby.error-class`
+directive. In order to define directives that can be used in custom
+generators, you just need to add a few lines:
+
+```Ruby
+class MyGenerator < Antelope::Generator::Base
+
+ has_directive "my-generator.some-value", Boolean
+
+end
+```
+
+In this example, we define a directive named
+`my-generator.some-value`; this directive is eventually coerced into
+a `true`/`false` value. In order to actually use the value of the
+directive, in either the template or a method on the generator, you
+can reference `directives["my-generator.some-value"]`, which will be
+`nil` (it wasn't defined), `true` (it was defined, with any
+arguments), or `false` (it was explicitly defined with one argument,
+`"false"`). Some other values you can pass in place of `Boolean`
+would be `:single` (or `:one`), which only gives the first argument
+passed to the directive; an `Array` of types, which would coerce each
+argument into its corresponding element of the array; `Array`, which
+will give an array of the given arguments; `String`, which gives a
+string representation of the first argument; any `Numeric` subclass,
+which would coerce the first argument into an integer; `Float`, which
+would coerce the first argument into a float; any class, which would
+be instantized with the arguments to the directive. Any other values
+would yield an error.
+
+It is recommended that you namespace directives that only your
+generator would use, using dashed syntax, like in our example above.
+However, some directives are not namespaced, or are not namespaced
+under a generator; these may be used by any generator. It is also
+recommended that you declare every directive that you use.
+
+[Ruby]: http://rubydoc.info/github/medcat/antelope/Antelope/Generator/Ruby