From d70ca94988187d9a642c3965015cc8512b20edd9 Mon Sep 17 00:00:00 2001 From: David Eisinger Date: Tue, 31 Oct 2023 11:24:50 -0400 Subject: [PATCH] comment + refactor renumber --- bin/renumber | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/bin/renumber b/bin/renumber index e53f1c7..c82ee9f 100755 --- a/bin/renumber +++ b/bin/renumber @@ -6,33 +6,40 @@ files = Array(ARGV.shift || Dir.glob("./**/*.md")) files.each do |file| content = File.read(file) + # First, scan for all references ([#]: at beginning of line) + # and look for duplicates refs = content.scan(/^\[\d+\]:/) + dups = refs.combination(2).filter_map { |i, j| i if i == j } - unless refs == refs.uniq - warn "Error in #{file}: duplicate refs detected" + # If duplicate refs detected, this won't work, so bail out + if dups.any? + warn "Duplicate refs detected in #{file} (#{dups * ", "})" exit 1 end idx = 0 code_block = false - refs = {} + cache = {} - updated = content.gsub(/\[\d+\]|```|`/) do |token| + # Find all numbered links (in text + references) + code delimeters + # (for fenced code blocks, "`" suffices because "```" is an odd number) + updated = content.gsub(/\[\d+\]|`/) do |token| case token - when "```", "`" + when "`" + # We don't want to do substitution inside code blocks + # (where `[#]` sometimes occurs) but we do want to toggle + # whether or not we're in a code block code_block = !code_block token else - if code_block - token - else - refs[token] ||= "[$$#{idx += 1}]" - end + # If we're in a code block, just return the token + # Otherwise, check if the reference has already been assigned + # - If so, return the cached value + # - If not, bump the index, cache the value, and return it + code_block ? token : cache[token] ||= "[#{idx += 1}]" end end - updated.gsub!("$$", "") - if fix File.write(file, updated) elsif content != updated