Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,36 @@ jobs:
- name: Collect external URLs from sources
run: |
mkdir -p lychee
# Allow `)` inside URLs (Wikipedia disambiguation titles), then strip
# a single trailing `)` only when unbalanced (handles markdown
# `[text](url)`). Drop resolver templates containing `{placeholder}`.
# Restrict to YAML/MD so lockfiles inside data/ are not scanned.
# A URL may legitimately contain `(` and `)`, because Wikipedia and
# Wikisource put disambiguation titles there. The match therefore
# keeps parentheses and the trailing markup is trimmed afterwards.
#
# The trim runs as one loop, not as a fixed sequence. A URL at the
# end of a markdown link, a bold run, or a sentence carries several
# layers of trailing markup at once — `…/4.0/).`, `…/arks.org/)**`,
# `…/rfc3987))` — so each pass strips punctuation, then one
# unbalanced `)`, until the string stops changing. Doing this in a
# single pass leaves a `)` behind whenever punctuation follows it,
# which is what produced the false 404s in #3.
#
# Resolver templates are dropped: `{placeholder}` literally, and
# `%7B`/`%7D` for the percent-encoded spelling.
#
# Restrict to YAML/MD, and skip node_modules, so lockfiles and
# dependency READMEs inside data/ are not scanned.
grep -rhoE --include='*.yaml' --include='*.yml' --include='*.md' --include='*.mdx' \
--exclude-dir=node_modules \
'https?://[^]["'\''<>[:space:]]+' data/ src/content/docs/ \
| awk '{ n=gsub(/\(/,"&"); m=gsub(/\)/,"&"); if (m>n) sub(/\)$/,""); print }' \
| grep -v '[{}]' \
| sed -E 's/[.,;:]+$//' \
| awk '{
do {
changed = 0
if (sub(/[.,;:!?*_`]+$/, "")) changed = 1
n = gsub(/\(/, "&"); m = gsub(/\)/, "&")
if (m > n && sub(/\)$/, "")) changed = 1
} while (changed)
if (length($0) > 0) print
}' \
| grep -viE '[{}]|%7b|%7d' \
| sort -u > lychee/urls.txt
echo "Collected $(wc -l < lychee/urls.txt) unique URLs"

Expand Down
2 changes: 2 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ exclude = [
"^https?://([a-z0-9-]+\\.)*twitter\\.com",
"^https?://([a-z0-9-]+\\.)*x\\.com",
"^https?://([a-z0-9-]+\\.)*opencollective\\.com",
"^https?://([a-z0-9-]+\\.)*iso\\.org",
"^https?://([a-z0-9-]+\\.)*loc\\.gov",
"^https?://localhost(:\\d+)?(/|$)",
]

Expand Down
134 changes: 0 additions & 134 deletions src/components/CitationBox.astro

This file was deleted.

18 changes: 16 additions & 2 deletions src/components/Tombstone.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ interface Props {

const { status, supersededBy } = Astro.props;

// ADR-0004 and specification.md §12 make `deprecated`, `withdrawn` and `blocked`
// one tombstone category, and the compiler agrees (`RETIRED_STATUSES` in
// scripts/compile.ts). The three differ in reach, not in kind: a `deprecated`
// record is retained and still resolves, while a `withdrawn` or `blocked` record
// is additionally excluded from `Work` mapping projections. The banner therefore
// stays one presentation, and the copy below states which of the three applies.
const isDraft = status === 'draft';
const isTombstone = status === 'withdrawn' || status === 'blocked';
const isTombstone =
status === 'deprecated' || status === 'withdrawn' || status === 'blocked';
---

{
Expand All @@ -33,9 +40,16 @@ const isTombstone = status === 'withdrawn' || status === 'blocked';
<strong>
{status === 'blocked'
? 'This record is blocked by a rights, trust, or policy dispute.'
: 'This record has been withdrawn.'}
: status === 'deprecated'
? 'This record is deprecated.'
: 'This record has been withdrawn.'}
</strong>
</p>
{status === 'deprecated' && (
<p>
It is retained and it still resolves, but it is no longer recommended.
</p>
)}
{supersededBy ? (
<p>
Superseded by <a href={supersededBy}>{supersededBy}</a>.
Expand Down
22 changes: 20 additions & 2 deletions src/pages/id/ref/[uuid]/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,18 @@ const escapeHtml = (s: string) =>
.replace(/"/g, '&quot;');
const chicagoHtml = escapeHtml(chicago).replace(/\*([^*]+)\*/g, '<em>$1</em>');

// ADR-0004 and specification.md §12 make `deprecated`, `withdrawn` and `blocked`
// one tombstone category, and the compiler agrees (`RETIRED_STATUSES` in
// scripts/compile.ts). The three differ in reach, not in kind: a `deprecated`
// record is retained and still resolves, while a `withdrawn` or `blocked` record
// is additionally excluded from `Work` mapping projections. The banner therefore
// stays one presentation, and the copy below states which of the three applies.
// Kept in step with src/components/Tombstone.astro by hand until #100 lands.
const isDraft = ref.status === 'draft';
const isTombstone = ref.status === 'withdrawn' || ref.status === 'blocked';
const isTombstone =
ref.status === 'deprecated' ||
ref.status === 'withdrawn' ||
ref.status === 'blocked';
---

<RecordPage
Expand Down Expand Up @@ -119,9 +129,17 @@ const isTombstone = ref.status === 'withdrawn' || ref.status === 'blocked';
<strong>
{ref.status === 'blocked'
? 'This record is blocked by a rights, trust, or policy dispute.'
: 'This record has been withdrawn.'}
: ref.status === 'deprecated'
? 'This record is deprecated.'
: 'This record has been withdrawn.'}
</strong>
</p>
{ref.status === 'deprecated' && (
<p>
It is retained and it still resolves, but it is no longer
recommended.
</p>
)}
{ref.superseded_by ? (
<p>
Superseded by <a href={ref.superseded_by}>{ref.superseded_by}</a>.
Expand Down
Loading