debian-mirror-gitlab/vendor/gems/ipynbdiff/lib/symbol_map.rb
2022-08-13 15:12:31 +05:30

107 lines
2 KiB
Ruby

# frozen_string_literal: true
module IpynbDiff
require 'oj'
# Creates a map from a symbol to the line number it appears in a Json file
#
# Example:
#
# Input:
#
# 1. {
# 2. 'obj1': [
# 3. {
# 4. 'obj2': 5
# 5. },
# 6. 3,
# 7. {
# 8. 'obj3': {
# 9. 'obj4': 'b'
# 10. }
# 11. }
# 12. ]
# 13.}
#
# Output:
#
# Symbol Line Number
# .obj1 -> 2
# .obj1.0 -> 3
# .obj1.0 -> 3
# .obj1.0.obj2 -> 4
# .obj1.1 -> 6
# .obj1.2 -> 7
# .obj1.2.obj3 -> 8
# .obj1.2.obj3.obj4 -> 9
#
class SymbolMap
class << self
def handler
@handler ||= SymbolMap.new
end
def parser
@parser ||= Oj::Parser.new(:saj).tap { |p| p.handler = handler }
end
def parse(notebook, *args)
handler.reset
parser.parse(notebook)
handler.symbols
end
end
attr_accessor :symbols
def hash_start(key, line, column)
add_symbol(key_or_index(key), line)
end
def hash_end(key, line, column)
@current_path.pop
end
def array_start(key, line, column)
@current_array_index << 0
add_symbol(key, line)
end
def array_end(key, line, column)
@current_path.pop
@current_array_index.pop
end
def add_value(value, key, line, column)
add_symbol(key_or_index(key), line)
@current_path.pop
end
def add_symbol(symbol, line)
@symbols[@current_path.append(symbol).join('.')] = line if symbol
end
def key_or_index(key)
if key.nil? # value in an array
if @current_path.empty?
@current_path = ['']
return nil
end
symbol = @current_array_index.last
@current_array_index[-1] += 1
symbol
else
key
end
end
def reset
@current_path = []
@symbols = {}
@current_array_index = []
end
end
end