Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'gems/ipynbdiff/lib/ipynb_diff/symbol_map.rb')
-rw-r--r--gems/ipynbdiff/lib/ipynb_diff/symbol_map.rb109
1 files changed, 109 insertions, 0 deletions
diff --git a/gems/ipynbdiff/lib/ipynb_diff/symbol_map.rb b/gems/ipynbdiff/lib/ipynb_diff/symbol_map.rb
new file mode 100644
index 00000000000..383f1de5c18
--- /dev/null
+++ b/gems/ipynbdiff/lib/ipynb_diff/symbol_map.rb
@@ -0,0 +1,109 @@
+# 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
+ # rubocop:disable Lint/UnusedMethodArgument
+ 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
+ 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
+ # rubocop:enable Lint/UnusedMethodArgument
+ end
+end