Module: AlFolioCore

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

Defined Under Namespace

Modules: Filters, JekyllCacheBustThemeFallback, JekyllMinifierEintrRetry, 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.9"

Class Method Summary collapse

Class Method Details

.bundler_gem_asset_paths(relative_asset_path) ⇒ Object



189
190
191
192
193
194
# File 'lib/al_folio_core.rb', line 189

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)


241
242
243
244
245
246
247
248
249
# File 'lib/al_folio_core.rb', line 241

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)


152
153
154
# File 'lib/al_folio_core.rb', line 152

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

.config_contract_violations(site) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/al_folio_core.rb', line 251

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)


237
238
239
# File 'lib/al_folio_core.rb', line 237

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

.legacy_hits(site, limit: 5) ⇒ Object



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/al_folio_core.rb', line 163

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)


196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/al_folio_core.rb', line 196

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



156
157
158
159
160
161
# File 'lib/al_folio_core.rb', line 156

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



181
182
183
# File 'lib/al_folio_core.rb', line 181

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

.patch_jekyll_cache_bust_for_theme_assets!Object



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

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_minifier_for_notebook_output!Object



227
228
229
230
231
232
233
234
235
# File 'lib/al_folio_core.rb', line 227

def patch_jekyll_minifier_for_notebook_output!
  return unless defined?(Jekyll::Compressor)

  [Jekyll::Document, Jekyll::Page, Jekyll::StaticFile].each do |klass|
    next if klass.ancestors.include?(JekyllMinifierEintrRetry)

    klass.prepend(JekyllMinifierEintrRetry)
  end
end

.patch_jekyll_terser_for_theme_assets!Object



209
210
211
212
213
214
215
216
# File 'lib/al_folio_core.rb', line 209

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



185
186
187
# File 'lib/al_folio_core.rb', line 185

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