File: reader.rb

package info (click to toggle)
ruby-jekyll-data 1.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 420 kB
  • sloc: ruby: 909; sh: 95; makefile: 10
file content (226 lines) | stat: -rw-r--r-- 6,159 bytes parent folder | download
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# frozen_string_literal: true

require "csv"

module JekyllData
  class Reader < Jekyll::Reader
    def initialize(site)
      @site = site
      @theme = site.theme

      if @theme.data_path
        @theme_data_files = Dir[File.join(@theme.data_path, "**", "*.{yaml,yml,json,csv,tsv}")]
      end
    end

    # Read data files within theme-gem.
    #
    # Returns nothing.
    def read
      super
      read_theme_data
    end

    # Read data files within a theme gem and add them to internal data
    #
    # Returns a hash appended with new data
    def read_theme_data
      if @theme.data_path
        #
        # show contents of "<theme>/_data/" dir being read while degugging.
        inspect_theme_data
        theme_data = ThemeDataReader.new(site).read(site.config["data_dir"])
        @site.data = Jekyll::Utils.deep_merge_hashes(theme_data, @site.data)
        #
        # show contents of merged site.data hash while debugging with
        # additional --show-data switch.
        inspect_merged_hash if site.config["show-data"] && site.config["verbose"]
      end
    end

    private

    # Private:
    # (only while debugging)
    #
    # Print a list of data file(s) within the theme-gem
    def inspect_theme_data
      print_clear_line
      Jekyll.logger.debug "Reading:", "Theme Data Files..."
      @theme_data_files.each { |file| Jekyll.logger.debug "", file }
      print_clear_line
      Jekyll.logger.debug "Merging:", "Theme Data Hash..."

      unless site.config["show-data"] && site.config["verbose"]
        Jekyll.logger.debug "", "use --show-data with --verbose to output " \
                                "merged Data Hash.".cyan
        print_clear_line
      end
    end

    # Private:
    # (only while debugging)
    #
    # Print contents of the merged data hash
    def inspect_merged_hash
      Jekyll.logger.debug "Inspecting:", "Site Data >>"

      # the width of generated logger[message]
      @width = 50
      @dashes = "-" * @width

      inspect_hash @site.data
      print_clear_line
    end

    # --------------------------------------------------------------------
    # Private helper methods to inspect data hash and output contents
    # to logger at level debugging.
    # --------------------------------------------------------------------

    # Dissect the (merged) site.data hash and print its contents
    #
    # - Print the key string(s)
    # - Individually analyse the hash[key] values and extract contents
    #   to output.
    def inspect_hash(hash)
      hash.each do |key, value|
        print_key key
        if value.is_a? Hash
          inspect_inner_hash value
        elsif value.is_a? Array
          extract_hashes_and_print value
        else
          print_string value.to_s
        end
      end
    end

    # Analyse deeper hashes and extract contents to output
    def inspect_inner_hash(hash)
      hash.each do |key, value|
        if value.is_a? Array
          print_label key
          extract_hashes_and_print value
        elsif value.is_a? Hash
          print_subkey_and_value key, value
        else
          print_hash key, value
        end
      end
    end

    # If an array of strings, print. Otherwise assume as an
    # array of hashes (sequences) that needs further analysis.
    def extract_hashes_and_print(array)
      array.each do |entry|
        if entry.is_a? String
          print_list entry
        else
          inspect_inner_hash entry
        end
      end
    end

    #

    # --------------------------------------------------------------------
    # Private methods for formatting log messages while debugging
    # --------------------------------------------------------------------

    # Splits a string longer than the value of '@width' into smaller
    # strings and prints each line as a logger[message]
    #
    # string - the long string
    #
    # label - optional text to designate the printed lines.
    def print_long_string(string, label = "")
      strings = string.scan(%r!(.{1,#{@width}})(\s+|\W|\Z)!).map { |s| s.join.strip }
      first_line = strings.first.cyan

      label.empty? ? print_value(first_line) : print(label, first_line)
      strings[1..-1].each { |s| print_value s.cyan }
    end

    # Prints key as logger[topic] and value as [message]
    def print_hash(key, value)
      if value.length > @width
        print_long_string value, "#{key}:"
      else
        print "#{key}:", value.cyan
      end
    end

    def print_list(item)
      if item.length > @width
        print_long_string item, "-"
      else
        print "-", item.cyan
      end
    end

    def print_string(str)
      if str.length > @width
        print_long_string str
      else
        print_value str.inspect
      end
    end

    # Prints the site.data[key] in color
    def print_key(key)
      print_clear_line
      print "Data Key:", " #{key} ".center(@width, "=")
      print_clear_line
    end

    # Prints label, keys and values of mappings
    def print_subkey_and_value(key, value)
      print_label key
      value.each do |subkey, val|
        if val.is_a? Hash
          print_inner_subkey subkey
          inspect_inner_hash val
        elsif val.is_a? Array
          print_inner_subkey subkey
          extract_hashes_and_print val
        elsif val.is_a? String
          print_hash subkey, val
        end
      end
    end

    # Print only logger[message], [topic] = nil
    def print_value(value)
      if value.is_a? Array
        extract_hashes_and_print value
      else
        print "", value
      end
    end

    # Print only logger[topic] appended with a colon
    def print_label(key)
      print_value " #{key} ".center(@width, "-")
    end

    def print_inner_subkey(key)
      print "#{key}:", @dashes
    end

    def print_dashes
      print "", @dashes
    end

    def print_clear_line
      print ""
    end

    # Redefine Jekyll Loggers to have the [topic] indented by 30.
    # (rjust by just 29 to accomodate the additional whitespace added
    # by Jekyll)
    def print(topic, message = "")
      Jekyll.logger.debug topic.rjust(29), message
    end
  end
end