Module: AlFolioCore

Defined in:
lib/al_folio_core.rb,
lib/al_folio_core/version.rb

Defined Under Namespace

Modules: Filters, JekyllCacheBustThemeFallback, JekyllTerserThemeGuard, Tags

Constant Summary collapse

LEGACY_PATTERN =
/
  data-(?:toggle|target|dismiss)\s*=\s*["'](?:collapse|dropdown|tooltip|popover|table|modal)["']|
  \b(?:jumbotron|input-group|form-group|form-row|modal(?:-dialog|-content|-header|-body|-footer)?|carousel(?:-\w+)?|alert(?:-\w+)?|badge-pill|pagination-lg)\b
/x
MIGRATIONS_DIR =
File.expand_path("../migrations", __dir__)
THEME_ROOT =
File.expand_path("..", __dir__)
VERSION =
"1.0.8"

Class Method Summary collapse

Class Method Details

.bundler_gem_asset_paths(relative_asset_path) ⇒ Object



174
175
176
177
178
179
# File 'lib/al_folio_core.rb', line 174

def bundler_gem_asset_paths(relative_asset_path)
  Gem.path.flat_map do |gem_path|
    Dir[File.join(gem_path, "bundler", "gems", "*", relative_asset_path)] +
      Dir[File.join(gem_path, "gems", "*", relative_asset_path)]
  end
end

.command_available?(command) ⇒ Boolean

Returns:

  • (Boolean)


216
217
218
219
220
221
222
223
224
# File 'lib/al_folio_core.rb', line 216

def command_available?(command)
  path_entries = ENV.fetch("PATH", "").split(File::PATH_SEPARATOR)
  return false if path_entries.empty?

  path_entries.any? do |path_entry|
    candidate = File.join(path_entry, command)
    File.file?(candidate) && File.executable?(candidate)
  end
end

.compat_enabled?(site) ⇒ Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/al_folio_core.rb', line 137

def compat_enabled?(site)
  site.config.dig("al_folio", "compat", "bootstrap", "enabled") == true
end

.config_contract_violations(site) ⇒ Object



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/al_folio_core.rb', line 226

def config_contract_violations(site)
  violations = []
  cfg = site.config
  api_version = cfg.dig("al_folio", "api_version")
  style_engine = cfg.dig("al_folio", "style_engine")
  tailwind_version = cfg.dig("al_folio", "tailwind", "version")
  tailwind_preflight = cfg.dig("al_folio", "tailwind", "preflight")
  tailwind_css_entry = cfg.dig("al_folio", "tailwind", "css_entry")
  distill_engine = cfg.dig("al_folio", "distill", "engine")
  distill_source = cfg.dig("al_folio", "distill", "source")

  violations << "expected `al_folio.api_version: 1` but found #{api_version.inspect}" unless api_version == 1
  violations << "expected `al_folio.style_engine: tailwind` but found #{style_engine.inspect}" unless style_engine == "tailwind"
  violations << "missing `al_folio.tailwind.version`" if tailwind_version.to_s.strip.empty?
  violations << "expected `al_folio.tailwind.preflight: false` for v1 parity mode" unless tailwind_preflight == false
  violations << "missing `al_folio.tailwind.css_entry`" if tailwind_css_entry.to_s.strip.empty?
  violations << "missing `al_folio.distill.engine`" if distill_engine.to_s.strip.empty?
  violations << "missing `al_folio.distill.source`" if distill_source.to_s.strip.empty?
  violations
end

.jupyter_plugin_enabled?(site) ⇒ Boolean

Returns:

  • (Boolean)


212
213
214
# File 'lib/al_folio_core.rb', line 212

def jupyter_plugin_enabled?(site)
  Array(site.config["plugins"]).map(&:to_s).include?("jekyll-jupyter-notebook")
end

.legacy_hits(site, limit: 5) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/al_folio_core.rb', line 148

def legacy_hits(site, limit: 5)
  hits = []

  markdown_and_template_files(site).each do |path|
    next unless File.file?(path)

    File.foreach(path).with_index(1) do |line, index|
      next unless line.match?(LEGACY_PATTERN)

      rel = path.sub(%r{^#{Regexp.escape(site.source)}/?}, "")
      hits << "#{rel}:#{index}"
      return hits if hits.length >= limit
    end
  end

  hits
end

.local_source_asset?(asset_path, site_source) ⇒ Boolean

Returns:

  • (Boolean)


181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/al_folio_core.rb', line 181

def local_source_asset?(asset_path, site_source)
  expanded_asset_path = File.expand_path(asset_path)
  expanded_site_source = File.expand_path(site_source)
  return false unless expanded_asset_path.start_with?("#{expanded_site_source}#{File::SEPARATOR}")

  # Bundler-installed gems can live under `<site>/vendor/bundle/**`.
  # Treat those as external runtime assets, not local source overrides.
  vendored_bundle_prefix = File.join(expanded_site_source, "vendor", "bundle") + File::SEPARATOR
  return false if expanded_asset_path.start_with?(vendored_bundle_prefix)

  true
end

.markdown_and_template_files(site) ⇒ Object



141
142
143
144
145
146
# File 'lib/al_folio_core.rb', line 141

def markdown_and_template_files(site)
  roots = %w[_pages _includes _layouts]
  roots.flat_map do |root|
    Dir.glob(File.join(site.source, root, "**", "*.{md,markdown,html,liquid}"))
  end
end

.migration_manifest_pathsObject



166
167
168
# File 'lib/al_folio_core.rb', line 166

def migration_manifest_paths
  Dir.glob(File.join(MIGRATIONS_DIR, "*.yml")).sort
end

.patch_jekyll_cache_bust_for_theme_assets!Object



203
204
205
206
207
208
209
210
# File 'lib/al_folio_core.rb', line 203

def patch_jekyll_cache_bust_for_theme_assets!
  return unless defined?(Jekyll::CacheBust::CacheDigester)

  cache_digester = Jekyll::CacheBust::CacheDigester
  return if cache_digester.ancestors.include?(JekyllCacheBustThemeFallback)

  cache_digester.prepend(JekyllCacheBustThemeFallback)
end

.patch_jekyll_terser_for_theme_assets!Object



194
195
196
197
198
199
200
201
# File 'lib/al_folio_core.rb', line 194

def patch_jekyll_terser_for_theme_assets!
  return unless defined?(Jekyll::Terser::TerserGenerator)

  generator = Jekyll::Terser::TerserGenerator
  return if generator.ancestors.include?(JekyllTerserThemeGuard)

  generator.prepend(JekyllTerserThemeGuard)
end

.theme_asset_path(relative_asset_path) ⇒ Object



170
171
172
# File 'lib/al_folio_core.rb', line 170

def theme_asset_path(relative_asset_path)
  File.join(THEME_ROOT, relative_asset_path)
end