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

symbol_map.rb « lib « ipynbdiff « gems « vendor - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 89cbccbed1bdc56ac0d40be452f6484e9397f4a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 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