From b7b910b1b7425a1710a2f9e932c4df03ef1437f6 Mon Sep 17 00:00:00 2001 From: Erin Schnabel Date: Wed, 25 Mar 2026 16:06:32 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Resolve=20reprinted=20class=20so?= =?UTF-8?q?urce=20in=20subclass=20link=20generation;=20refs=20#779?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add resolveClassSource() to Tools5eIndex to look up reprinted class sources (e.g. PHB→XPHB). Call it in getSubclassResource() so that subclass file links use the correct class prefix when both PHB and XPHB are included. Add XPHB to homebrew test sources to reproduce. Co-Authored-By: Claude Opus 4.6 --- .../convert/tools/dnd5e/Tools5eIndex.java | 19 +++++++++++++++++++ .../convert/tools/dnd5e/Tools5eLinkifier.java | 2 ++ src/test/resources/5e/sources-homebrew.json | 3 ++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eIndex.java b/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eIndex.java index d4a82775..84b09589 100644 --- a/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eIndex.java +++ b/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eIndex.java @@ -1055,6 +1055,25 @@ public Set findSubclasses(String classKey) { return subclassMap.getOrDefault(classKey, Set.of()); } + /** + * Resolve the effective class source through reprints. + * If the class identified by className+classSource was reprinted + * (e.g., PHB Druid → XPHB Druid), return the reprint target's source. + */ + public String resolveClassSource(String className, String classSource) { + String classKey = String.join("|", + Tools5eIndexType.classtype.name(), + className, classSource).toLowerCase(); + String reprint = reprints.get(classKey); + if (reprint != null) { + Tools5eSources reprintSources = Tools5eSources.findSources(reprint); + if (reprintSources != null && reprintSources.includedByConfig()) { + return reprintSources.primarySource(); + } + } + return classSource; + } + public Set findClassFeatures(String classOrSubclassKey) { return classFeatures.getOrDefault(classOrSubclassKey, Set.of()); } diff --git a/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eLinkifier.java b/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eLinkifier.java index bbc1efbb..3b138c24 100644 --- a/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eLinkifier.java +++ b/src/main/java/dev/ebullient/convert/tools/dnd5e/Tools5eLinkifier.java @@ -390,6 +390,8 @@ public String getSubclassResource(String subclassKey) { } public String getSubclassResource(String subclass, String parentClass, String classSource, String subclassSource) { + // Resolve classSource through reprints (e.g., PHB → XPHB when PHB class is reprinted) + classSource = index.resolveClassSource(parentClass, classSource); String parentFile = Tui.slugify(parentClass); String defaultSource = Tools5eIndexType.classtype.defaultOutputSource(); if (!classSource.equalsIgnoreCase(defaultSource) && diff --git a/src/test/resources/5e/sources-homebrew.json b/src/test/resources/5e/sources-homebrew.json index 4347e82d..6cbf2d50 100644 --- a/src/test/resources/5e/sources-homebrew.json +++ b/src/test/resources/5e/sources-homebrew.json @@ -49,7 +49,8 @@ "MM", "EGW", "FTD", - "PHB" + "PHB", + "XPHB" ] }, "include": [