Module: Ruby2D::CLI::Examples
- Defined in:
- lib/ruby2d/cli/examples.rb
Constant Summary collapse
- EXAMPLES_DIR =
File.('../../../examples', __dir__)
- ROOT_DIR =
The gem root, where the bundled
assets/directory sits alongsideexamples/. Examples resolve asset paths relative to this — the same relative layoutruby2d buildmounts into the web VFS and copies into the native bundle — so example runschdirhere (seerun). File.('..', EXAMPLES_DIR)
Class Method Summary collapse
- .all ⇒ Object
- .browse ⇒ Object
- .find(query) ⇒ Object
-
.parse(path) ⇒ Object
Parse the leading comment block from an example file.
-
.print_header(example) ⇒ Object
Print the example's leading comment block (prose only, no title) in dim text, indented to match the surrounding "Running …" message.
-
.print_list ⇒ Object
Non-interactive list, matching the style of
ruby2d usage. - .run(example) ⇒ Object
Class Method Details
.all ⇒ Object
63 64 65 |
# File 'lib/ruby2d/cli/examples.rb', line 63 def self.all @all ||= Dir.glob("#{EXAMPLES_DIR}/*.rb").sort.map { |p| parse(p) } end |
.browse ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/ruby2d/cli/examples.rb', line 103 def self.browse list = all if list.empty? puts "\n No examples found.\n\n" return end Browser.run(list: list, label: 'Examples', footer_action: 'run', fallback: -> { print_list }) do |ex| puts puts " #{'Ruby 2D'.ruby2d_red.bold} — Examples" puts puts " Running #{ex[:title].bold} #{"(#{ex[:name]}.rb)".dim}" puts print_header(ex) ok = run(ex) unless ok print "\n #{'Example exited with errors. Press Enter to continue…'.dim}" $stdin.gets end end end |
.find(query) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ruby2d/cli/examples.rb', line 67 def self.find(query) list = all if query.match?(/\A\d+\z/) idx = query.to_i # 1-based; out-of-range (incl. 0) returns nil rather than wrapping. return idx.between?(1, list.length) ? list[idx - 1] : nil end norm = ->(s) { s.downcase.tr('-_', ' ').delete("'").squeeze(' ').strip } q = norm.call(query) return nil if q.empty? # an empty query must not match (and run) the first item list.find { |e| norm.call(e[:name]) == q || norm.call(e[:title]) == q } || list.find { |e| norm.call(e[:name]).include?(q) || norm.call(e[:title]).include?(q) } end |
.parse(path) ⇒ Object
Parse the leading comment block from an example file. The convention
across examples/*.rb is:
# Title
# Short description (one or two lines, shown in the picker preview).
#
# Longer narrative — controls, context, anything beyond the tagline.
The short description (first paragraph after the title) becomes
:description; the entire post-title block becomes :header.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/ruby2d/cli/examples.rb', line 26 def self.parse(path) title = nil header = [] File.foreach(path) do |line| line = line.chomp break unless line.start_with?('#') stripped = line.sub(/^#\s?/, '') if title.nil? title = stripped unless stripped.empty? next end header << stripped end # Drop leading/trailing blank separator lines around the header block. header.shift while header.first == '' header.pop while header.last == '' # `description` is the first paragraph of the header, joined as one line. first_para = header.take_while { |l| !l.empty? } name = File.basename(path, '.rb') { name: name, title: title || name, description: first_para.join(' ').strip, header: header, path: path } end |
.print_header(example) ⇒ Object
Print the example's leading comment block (prose only, no title) in dim text, indented to match the surrounding "Running …" message.
56 57 58 59 60 61 |
# File 'lib/ruby2d/cli/examples.rb', line 56 def self.print_header(example) lines = example[:header] return if lines.nil? || lines.all?(&:empty?) lines.each { |line| puts(line.empty? ? '' : " #{line.dim}") } puts end |
.print_list ⇒ Object
Non-interactive list, matching the style of ruby2d usage.
89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/ruby2d/cli/examples.rb', line 89 def self.print_list list = all if list.empty? puts "\n No examples found.\n\n" return end w = list.length.to_s.length puts "\n #{'Ruby 2D'.ruby2d_red.bold} — Examples\n\n" list.each_with_index do |ex, i| puts " #{(i + 1).to_s.rjust(w).dim} #{ex[:title]}" end puts "\n #{'ruby2d examples <name|number>'.dim}\n\n" end |
.run(example) ⇒ Object
82 83 84 85 86 |
# File 'lib/ruby2d/cli/examples.rb', line 82 def self.run(example) # Run from `ROOT_DIR` so an example's relative asset paths (e.g. # `assets/resources/spritesheets`) resolve against the bundled assets. system(Gem.ruby, example[:path], chdir: ROOT_DIR) end |