Skip to main content

rename.hs

Generates shell commands for safely renaming pages across the gwern.net codebase

Pathbuild/rename.hs
LanguageHaskell
Lines14
Sourcebuild/rename.hs
at 406d3e423

Read this when Use this page when tracing the Haskell build pipeline, generators, metadata code, or backend utility behavior around rename.

Overview

rename.hs is a tiny code generator that produces a multi-step shell script for renaming pages on gwern.net. Renaming a page is surprisingly complex because links can appear in many different syntactic forms across markdown files, HTML includes, and configuration files. Rather than attempt the transformation directly, this script outputs a sequence of commands that the user can review and execute.

The generated script handles: git file moves, multiple link syntax variants (markdown, HTML attributes with both single and escaped double quotes), and nginx redirect configuration updates. This defensive approach ensures no link references are silently broken by a rename operation.


Public API

main :: IO ()

Reads two command-line arguments (old path, new path) and prints a shell script to stdout.

Called by: Manual invocation from command line Calls: foo

foo :: String -> String -> IO ()

The actual script generator. Takes old and new paths (without .md extension or leading dot) and constructs a &&-chained shell command sequence.

Called by: main Calls: putStrLn


Internal Architecture

The script is minimal—just 14 lines. It builds a single string by concatenating six shell commands:

git mv '.{old}.md' '.{new}.md' && \
gwsed.sh ' {old}' ' {new}' && \
gwsed.sh ']({old}' ']({new}' && \
gwsed.sh 'href="{old}"' 'href="{new}"' && \
gwsed.sh 'href=\"{old}\"' 'href=\"{new}\"' && \
echo '"~^{old}$" "{new}";' >> ~/wiki/static/nginx/redirect/move.conf

Each step targets a different link format:

  1. git mv — Move the actual file (the leading dot turns the site-absolute path like /foo into a relative path ./foo.md)
  2. Space-prefixed — Catches references like "see /foo" in prose
  3. Markdown links](/old-path)](/new-path)
  4. HTML href (plain)href="/old-path" with regular quotes
  5. HTML href (escaped)href=\"/old-path\" with backslash-escaped quotes (common in JSON/JS)
  6. nginx redirect — Appends a regex redirect rule so old URLs still work

Key Patterns

Code generation over direct action: Rather than executing the rename itself, the script outputs commands for the user to run. This allows inspection before execution—critical since a broken rename can corrupt many files.

Pattern multiplication: The same path must be searched in multiple syntactic contexts. This is a common theme in gwern.net's tooling: content appears in markdown, HTML, and escaped forms, requiring parallel handling.

Relative path convention: The .{path}.md naming is not a hidden-file convention: page paths are given site-absolute (eg. /foo), so prepending . yields a path relative to the wiki root (./foo.md) for git mv.


Configuration

None. The script is hardcoded to:

  • Assume files are .md, addressed relative to the wiki root (. + site-absolute path)
  • Use gwsed.sh for replacements
  • Append redirects to ~/wiki/static/nginx/redirect/move.conf

Integration Points

Dependencies

ToolPurpose
gitVersion-controlled file moves
gwsed.shSite-wide string replacement utility
nginx.confRedirect rules for URL preservation

Downstream

The generated nginx redirect rules are picked up by the web server configuration, ensuring old URLs continue to work after a rename.


Usage Example

# Generate rename script for moving "/spaced-repetition" to "/srs"
$ runghc rename.hs /spaced-repetition /srs
git mv './spaced-repetition.md' './srs.md' && gwsed.sh ' /spaced-repetition' ' /srs' && gwsed.sh '](/spaced-repetition' '](/srs' && gwsed.sh 'href="/spaced-repetition"' 'href="/srs"' && gwsed.sh 'href=\"/spaced-repetition\"' 'href=\"/srs\"' && echo '"~^/spaced-repetition$" "/srs";' >> ~/wiki/static/nginx/redirect/move.conf

# Review output, then execute
$ runghc rename.hs /spaced-repetition /srs | bash

Limitations

  • Does not handle anchor/fragment references (#section-id)
  • No validation that paths exist or are valid
  • Assumes all files use .md extension
  • The relative path in git mv (.{path}.md) requires running from the wiki root directory
  • No rollback mechanism if partial execution fails

See Also
  • Utils.hs - Core utilities for string manipulation and file operations
  • stringReplace.hs - Parallel string replacement utility for batch processing
  • sync.sh - Build orchestrator (does not invoke rename.hs; renames are run manually)
  • redirectGuesser - Generates nginx redirect rules for broken URLs
  • gwern.net.conf - Nginx configuration where redirects are stored