generateLinkBibliography.hs
Generates per-page "forward citation" bibliographies listing all outbound links with their annotations
Read this when Use this page when tracing the Haskell build pipeline, generators, metadata code, or backend utility behavior around generateLinkBibliography.
Overview
This module creates link bibliographies—ordered lists of all outbound links from a page or annotation, displayed with their full annotations where available. Link bibliographies are the "forward citation" counterpart to backlinks: while backlinks show what points to a page, link bibliographies show what a page points out to.
The output is an HTML fragment (not a full page) designed for transclusion into popups and page metadata blocks. Each bibliography is written to metadata/annotation/link-bibliography/$ESCAPED_PATH.html. The fragment contains a numbered list with the header "Bibliography" and appends a count only when N >= 2.
A key design decision is separating Wikipedia links into a collapsed sub-list at the end. Wikipedia links are "so numerous, and so bulky" (per source comments) that they would overwhelm the primary bibliography. Links without full annotations still get entries—if a title exists, it's rendered as titlecased HTML; if the title is empty, the path is shown in code styling, with optional context transclusion via .include-block-context.
Public API
main :: IO ()
Entry point. Loads metadata databases and generates bibliography fragments for all known pages/annotations in parallel.
Called by: sync.sh (full-build phase: el generateLinkBibliography, after the missing-annotation one-shot Hakyll pass)
Calls: readLinkMetadata, readArchiveMetadata, writeLinkBibliographyFragment
writeLinkBibliographyFragment :: ArchiveMetadata -> Metadata -> FilePath -> IO ()
Writes a link bibliography HTML fragment for a single page path if:
- The path has a non-empty abstract in metadata
- The original source is newer than the existing bibliography (or bibliography doesn't exist)
- There are enough non-Wikipedia links (≥
C.mininumLinkBibliographyFragment)
Called by: main (via parallel map)
Calls: getLinkBibLink, getAnnotationLinkCheck, parseExtractCompileWrite (which calls extractLinksFromPage)
Internal Architecture
Data Flow
Metadata DB
│
▼
┌─────────────────────────────────────┐
│ For each path in metadata keys: │
│ 1. Check if update needed │
│ 2. Extract links from source │
│ 3. Look up annotations for links │
│ 4. Generate HTML bibliography │
│ 5. Write to link-bib path │
└─────────────────────────────────────┘
│
▼
metadata/annotation/link-bibliography/*.html
Key Data Structures
Link tuple: (String, String) — URL and its context ID (hash anchor where it appears in the parent)
Triplet: (String, String, MetadataItem) — URL, context ID, and full annotation data
Bibliography structure:
Para [Link "Bibliography (N):"]
OrderedList [
[primary items...],
[Div.collapse [
Para "Wikipedia Bibliography:",
OrderedList [wikipedia items...]
]]
]
Link Extraction Path
For essays (/path with no extension):
- Parse the
.mdfile with Pandoc - Extract all
(URL, ID)pairs viaextractLinkIDsWith - Normalize
https://gwern.net/to/
For annotations (external URLs, files):
- Parse the abstract field as Pandoc
- Extract links from the abstract text
Key Patterns
Wikipedia Link Segregation
Wikipedia links are filtered out of the primary list and placed in a collapsed sub-section:
let itemsWP = filter (\(u,_,_) -> "https://en.wikipedia.org/wiki/" `isPrefixOf` u) items
itemsPrimary = items \\ itemsWP
This prevents bibliographies from being dominated by encyclopedic reference links.
Context Link Generation
Each bibliography item can include a "context link" pointing back to where the link appeared in the source:
prefix = [Link ("",["id-not", "link-bibliography-context"],[])
[Str "\8203"] -- zero-width space
(pathParent ++ "#" ++ ident, "Original context in page.")]
The zero-width space creates a clickable but visually minimal element.
Unannotated Link Transclusion
For local links without annotations (like /question#feynman), the module generates an .include-block-context transclusion:
transcludeTarget = [BlockQuote [Para [
Link ("", ["backlink-not", "include-block-context", ...], [])
[Span ... [Str "[Transclude the forward-link's context]"]]
(f, "")]]]
This ensures even unannotated section links show useful context.
Staleness Check
Updates are conditional on modification time:
originalLastModified <- getModificationTime target
lbLastModified <- getModificationTime path'
return (originalLastModified >= lbLastModified)
This prevents regenerating unchanged bibliographies.
Configuration
| Setting | Location | Effect |
|---|---|---|
mininumLinkBibliographyFragment | Config.Misc | Minimum non-Wikipedia links required to generate a bibliography |
Integration Points
Inputs
- Metadata database — Via
readLinkMetadatafrom LinkMetadata.hs - Archive metadata — Via
readArchiveMetadatafrom LinkArchive.hs - Markdown sources — Read directly from disk for essay pages
Outputs
- HTML fragments — Written to
metadata/annotation/link-bibliography/*.html - Uses
writeUpdatedFilefor atomic updates with change detection
Dependencies
| Module | Usage |
|---|---|
LinkBacklink | getLinkBibLink for output path, getAnnotationLinkCheck for source path |
LinkMetadata | generateAnnotationTransclusionBlock for full annotation rendering |
LinkID | metadataItem2ID for generating stable link IDs |
Typography | typographyTransformTemporary, titlecase' for text formatting |
Query | extractLinkIDsWith for parsing links from Pandoc AST |
Interwiki | convertInterwikiLinks for expanding shorthand links |
Inflation | isInflationURL to filter out inflation adjustment links |
Filters Applied
Links are excluded if they:
- Are self-references (link to the page being processed)
- Are inflation URLs
- Result in fewer than minimum required links (after excluding Wikipedia)
Output Format
The generated HTML has this structure:
<p><a class="icon-special" href="/design#link-bibliographies">
<strong>Bibliography (42):</strong>
</a></p>
<ol>
<li><!-- Primary link with annotation transclusion --></li>
<li><!-- Another link --></li>
...
<li>
<div class="collapse">
<p><strong>Wikipedia Bibliography:</strong></p>
<ol>
<li><!-- Wikipedia links --></li>
</ol>
</div>
</li>
</ol>
Items with full annotations use generateAnnotationTransclusionBlock for rich display. Items without annotations show as:
- Code-styled path for external URLs
- Titlecased title as link text (if title exists)
- Optional
.include-block-contextblockquote for local anchors
See Also
- hakyll.hs - Main site generator using bibliography fragments
- LinkMetadata.hs - Annotation database and transclusion blocks
- sync.sh - Build orchestrator that invokes this module
- LinkBacklink.hs - Backlinks (the "reverse" of link bibliographies)
- Annotation.hs - URL annotation dispatcher
- Query.hs - Link extraction utilities