Class: Cecil::Code
- Inherits:
-
Object
- Object
- Cecil::Code
- Defined in:
- lib/cecil/code.rb
Overview
Code serves as the base class for generating source code using Cecil. Subclassing Code allows customizing the behavior (indentation, auto-closing brackets, etc) and providing helpers.
- Override Code instance methods to change behavior.
- Defined a module named
Helpers
in your subclass to add methods available in the Cecil block.
Check out classes in the Lang module for examples of customizing Code.
Direct Known Subclasses
Defined Under Namespace
Modules: Helpers
Constant Summary collapse
- PLACEHOLDER_NO_BRACKETS_PAIR =
{ "" => "" }.freeze
Class Method Summary collapse
-
.generate(out = $stdout) { ... } ⇒ Object
Generates output by executing the given block and writing its return value to the provided output buffer/stream.
-
.generate_string { ... } ⇒ String
Generates output and returns it as a string.
Instance Method Summary collapse
-
#block_ending_pairs ⇒ Hash{String => String}
When indenting with a code block, the end of the code string is searched for consecutive opening brackets, each of which gets closed with a matching closing bracket.
-
#handle_ambiguous_indentation ⇒ Object
What do to in case of ambiguous indentation.
-
#indent_chars ⇒ String
Returns the string to use for each level of indentation.
-
#placeholder_delimiting_pairs ⇒ Regexp
Pairs that can be used to surround placeholder names.
-
#placeholder_ident_re ⇒ Regexp
Regexp to use to match a placeholder's name.
-
#placeholder_re ⇒ Regexp
Regexp to match placeholders.
-
#placeholder_start_re ⇒ Regexp
Regexp to match a placeholder's starting character(s).
-
#scan_for_placeholders(src) ⇒ Array<Placeholder>
Returns a list of Placeholder objects representing placeholders found in the given string.
Class Method Details
.generate(out = $stdout) { ... } ⇒ Object
Generates output by executing the given block and writing its return value to the provided output buffer/stream.
The stream is written to by calling #<<
with the generated source code.
73 |
# File 'lib/cecil/code.rb', line 73 def generate(out = $stdout, &) = Cecil.generate(syntax_class: self, out:, &) |
.generate_string { ... } ⇒ String
Generates output and returns it as a string
85 |
# File 'lib/cecil/code.rb', line 85 def generate_string(&) = generate("", &) |
Instance Method Details
#block_ending_pairs ⇒ Hash{String => String}
When indenting with a code block, the end of the code string is searched for consecutive opening brackets, each of which gets closed with a matching closing bracket.
E.g.
`my_func( (<`[] do
`more code`
end
# outputs:
# my_func((<
# more code
# >) )
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/cecil/code.rb', line 167 def block_ending_pairs { "{" => "}", "[" => "]", "<" => ">", "(" => ")", " " => " ", # allows for "my_func ( [ " to be closed with " ] ) " "\t" => "\t" # allows for "my_func\t([\t" to be closed with "\t])\t" } end |
#handle_ambiguous_indentation ⇒ Object
What do to in case of ambiguous indentation.
2 examples of ambiguous indentation:
`def python_fn():
pass`
`def ruby_method
end`
Because only the second line strings have leading indentation, we don't know how pass
or end
should be
indented.
In the future we could use caller
to identify the source location of that line and read the ruby file to figure
out the indentation.
For now, though, you can return:
- Indentation::Ambiguity.raise_error
- Indentation::Ambiguity.ignore (works for the Ruby example)
- Indentation::Ambiguity.adjust_by (works for the Python example)
332 |
# File 'lib/cecil/code.rb', line 332 def handle_ambiguous_indentation = Indentation::Ambiguity.raise_error |
#indent_chars ⇒ String
Returns the string to use for each level of indentation. Default is 4 spaces.
To turn off indentation, override this method to return an empty string.
128 |
# File 'lib/cecil/code.rb', line 128 def indent_chars = " " |
#placeholder_delimiting_pairs ⇒ Regexp
Pairs that can be used to surround placeholder names. The pairs that are used do not change the placeholder's name.
E.g., these all produce the same result:
`const $field`[field: 'username']
`const ${field}`[field: 'username']
`const $[field]`[field: 'username']
`const $<field>`[field: 'username']
`const $(field)`[field: 'username']
By default, "" => ""
is one of the pairs, meaning you don't need to surround placeholder names.
205 206 207 208 209 210 211 212 213 |
# File 'lib/cecil/code.rb', line 205 def placeholder_delimiting_pairs { "{" => "}", "[" => "]", "<" => ">", "(" => ")", **PLACEHOLDER_NO_BRACKETS_PAIR # this needs to be last } end |
#placeholder_ident_re ⇒ Regexp
Regexp to use to match a placeholder's name.
232 |
# File 'lib/cecil/code.rb', line 232 def placeholder_ident_re = /[[:alnum:]_]+/ |
#placeholder_re ⇒ Regexp
Regexp to match placeholders. By default, this constructs a Regexp from the pieces defined in:
If you override this method, make sure it returns a Regexp that has a capture group named "placeholder".
258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/cecil/code.rb', line 258 def placeholder_re / #{placeholder_start_re} #{Regexp.union( placeholder_delimiting_pairs.map do |pstart, pend| / #{Regexp.quote pstart} (?<placeholder>#{placeholder_ident_re}) #{Regexp.quote pend} /x end )} /x end |
#placeholder_start_re ⇒ Regexp
Regexp to match a placeholder's starting character(s).
247 |
# File 'lib/cecil/code.rb', line 247 def placeholder_start_re = /\$/ |
#scan_for_placeholders(src) ⇒ Array<Placeholder>
Returns a list of Placeholder objects representing placeholders found in the given string. The default implementation scans the string for matches of #placeholder_re.
This method can be overriden to change the way placeholders are parsed, or to omit, add, or modify placeholders.
292 293 294 295 296 297 |
# File 'lib/cecil/code.rb', line 292 def scan_for_placeholders(src) Text.scan_for_re_matches(src, placeholder_re) .map do |match| Placeholder.new(match[:placeholder], *match.offset(0)) end end |