diff options
Diffstat (limited to 'railties/guides/rails_guides/indexer.rb')
-rw-r--r-- | railties/guides/rails_guides/indexer.rb | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/railties/guides/rails_guides/indexer.rb b/railties/guides/rails_guides/indexer.rb new file mode 100644 index 0000000000..5b5ad3fee1 --- /dev/null +++ b/railties/guides/rails_guides/indexer.rb @@ -0,0 +1,55 @@ +module RailsGuides + class Indexer + attr_reader :body, :result, :level_hash + + def initialize(body) + @body = body + @result = @body.dup + end + + def index + @level_hash = process(body) + end + + private + + def process(string, current_level= 3, counters = [1]) + s = StringScanner.new(string) + + level_hash = ActiveSupport::OrderedHash.new + + while !s.eos? + s.match?(/\h[0-9]\..*$/) + if matched = s.matched + matched =~ /\h([0-9])\.(.*)$/ + level, title = $1.to_i, $2 + + if level < current_level + # This is needed. Go figure. + return level_hash + elsif level == current_level + index = counters.join(".") + bookmark = '#' + title.strip.downcase.gsub(/\s+|_/, '-').delete('^a-z0-9-') + + raise "Parsing Fail" unless @result.sub!(matched, "h#{level}(#{bookmark}). #{index}#{title}") + + key = { + :title => title, + :id => bookmark + } + # Recurse + counters << 1 + level_hash[key] = process(s.post_match, current_level + 1, counters) + counters.pop + + # Increment the current level + last = counters.pop + counters << last + 1 + end + end + s.getch + end + level_hash + end + end +end |