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
|