I’ve been haphazardly attempting to organize my site files for a while. One thing I routinely need to know is what sort of content I’m working with.
I started with a Raku one-liner:
hugo list all \ | raku -e 'say bag(map({ $*SPEC.extension(split(",", $_)[0]) }, lines[1..*]))'Not pretty, but quick and effective.
Bag(html(39) md(542))Unfortunately, it didn’t cover all the content extension once I figured out that
Hugo can ignore *.txt files, allowing me to try all sorts of tricks with
content generation.
So I’ve had this Ruby code embedded in my justfile.
#!/usr/bin/env ruby
require 'tty-table'content_exts = %w{.md .md.txt .rst .rst.txt .adoc .org}ext_glob = "*\{#{content_exts.join(',')}\}"format_glob = "content/**/#{ext_glob}"puts format_globt = Dir.glob(format_glob) .select { |f| File.file? f } .map { |f| content_exts.detect { |e| f.end_with? e } } .tally .map { |k, v| [k, v] }puts TTY::Table.new(["Format", "Count"], t).render(:unicode)More verbose than the Raku solution for sure, but much of that is making sure it looks nice in a TTY::Table.
❯ just formatscontent/**/*{.md,.md.txt,.rst,.rst.txt,.adoc,.org}┌────────┬─────┐│Format │Count│├────────┼─────┤│.md │590 ││.md.txt │22 ││.rst.txt│19 │└────────┴─────┘It works! It’s great. Nothin wrong with it whatsoever.
But I’ve been looking at Node.js recently for assorted reasons, including the possibility of porting this site to one of the many Node-based static site generators.
So why not try the task in Node.js?
const glob = require("glob");
const contentExts = "md md.txt rst rst.txt adoc adoc.txt org".split(" ");const contentGlob = `content/**/*.{${contentExts.join(",")}}`;
glob(contentGlob, (err, paths) => { if (err) return console.error(err);
// Path.extname would be fine here if not for my BASE.FORMAT.txt habit let countedExts = contentExts.reduce((extCounts, ext) => { const extMatchCount = paths.reduce((matchCount, path) => { return path.endsWith(ext) ? ++matchCount : matchCount; }, 0);
if (extMatchCount > 0) { extCounts[ext] = extMatchCount; }
return extCounts; }, {});
console.table(countedExts);});I’m only now attempting to use the platform with any kind of seriousness, so I apologize if there’s anything in there that’s not quite idiomatic.
I grabbed glob to simplify the task of recursively drilling down into
content/. Array.reduce helps me count files matching each of my content
extensions, then construct an object with those tallies. Since Console.table
comes standard, I didn’t need to dig for any formatting libraries today.
Though I might later for a little more control over display.
┌─────────┬────────┐│ (index) │ Values │├─────────┼────────┤│ md │ 590 ││ md.txt │ 22 ││ rst.txt │ 19 │└─────────┴────────┘But hey it works.
Got a comment? A question? More of a comment than a question?
Talk to me about this page on: Hacker's Town