2017-08-13 09:02:48 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-08-06 13:21:59 -04:00
|
|
|
require "active_support/core_ext/object/blank"
|
|
|
|
require "active_support/core_ext/string/inflections"
|
2010-04-06 18:20:27 -04:00
|
|
|
|
2009-02-05 20:57:02 -05:00
|
|
|
module RailsGuides
|
|
|
|
class Indexer
|
2010-04-06 18:20:27 -04:00
|
|
|
attr_reader :body, :result, :warnings, :level_hash
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2010-04-06 18:20:27 -04:00
|
|
|
def initialize(body, warnings)
|
|
|
|
@body = body
|
|
|
|
@result = @body.dup
|
|
|
|
@warnings = warnings
|
2009-02-05 20:57:02 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
def index
|
|
|
|
@level_hash = process(body)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
2016-10-28 23:05:58 -04:00
|
|
|
def process(string, current_level = 3, counters = [1])
|
2016-08-06 13:55:02 -04:00
|
|
|
s = StringScanner.new(string)
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
level_hash = {}
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
while !s.eos?
|
|
|
|
re = %r{^h(\d)(?:\((#.*?)\))?\s*\.\s*(.*)$}
|
|
|
|
s.match?(re)
|
|
|
|
if matched = s.matched
|
|
|
|
matched =~ re
|
|
|
|
level, idx, title = $1.to_i, $2, $3.strip
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
if level < current_level
|
|
|
|
# This is needed. Go figure.
|
|
|
|
return level_hash
|
|
|
|
elsif level == current_level
|
|
|
|
index = counters.join(".")
|
|
|
|
idx ||= "#" + title_to_idx(title)
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
raise "Parsing Fail" unless @result.sub!(matched, "h#{level}(#{idx}). #{index} #{title}")
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
key = {
|
|
|
|
title: title,
|
|
|
|
id: idx
|
|
|
|
}
|
|
|
|
# Recurse
|
|
|
|
counters << 1
|
|
|
|
level_hash[key] = process(s.post_match, current_level + 1, counters)
|
|
|
|
counters.pop
|
2009-02-05 20:57:02 -05:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
# Increment the current level
|
|
|
|
last = counters.pop
|
|
|
|
counters << last + 1
|
|
|
|
end
|
2009-02-05 20:57:02 -05:00
|
|
|
end
|
2016-08-06 13:55:02 -04:00
|
|
|
s.getch
|
2009-02-05 20:57:02 -05:00
|
|
|
end
|
2016-08-06 13:55:02 -04:00
|
|
|
level_hash
|
2009-02-05 20:57:02 -05:00
|
|
|
end
|
2010-04-06 18:20:27 -04:00
|
|
|
|
2016-08-06 13:55:02 -04:00
|
|
|
def title_to_idx(title)
|
|
|
|
idx = title.strip.parameterize.sub(/^\d+/, "")
|
|
|
|
if warnings && idx.blank?
|
|
|
|
puts "BLANK ID: please put an explicit ID for section #{title}, as in h5(#my-id)"
|
|
|
|
end
|
|
|
|
idx
|
2010-04-06 18:20:27 -04:00
|
|
|
end
|
2009-02-05 20:57:02 -05:00
|
|
|
end
|
|
|
|
end
|