Skip to content

Commit

Permalink
🐛 Improve handling of superscript in footnotes; resolves #232
Browse files Browse the repository at this point in the history
  • Loading branch information
ebullient committed Oct 10, 2023
1 parent 6197f64 commit b7b1a95
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public interface JsonTextReplacement extends JsonTextConverter<Tools5eIndexType>
Pattern homebrewPattern = Pattern.compile("\\{@homebrew ([^}]+)}");
Pattern quickRefPattern = Pattern.compile("\\{@quickref ([^}]+)}");
Pattern notePattern = Pattern.compile("\\{@note (\\*|Note:)?\\s?([^}]+)}");
Pattern footnotePattern = Pattern.compile("\\{@footnote ([^}]+)}");
Pattern abilitySavePattern = Pattern.compile("\\{@(ability|savingThrow) ([^}]+)}"); // {@ability str 20}
Pattern skillCheckPattern = Pattern.compile("\\{@skillCheck ([^}]+)}"); // {@skillCheck animal_handling 5}
Pattern optionalFeaturesFilter = Pattern.compile("\\{@filter ([^|}]+)\\|optionalfeatures\\|([^}]+)*}");
Expand Down Expand Up @@ -213,10 +214,6 @@ default String _replaceTokenText(String input, boolean nested) {
.replaceAll("\\{@cult ([^|}]+)\\|([^|}]+)\\|[^|}]*}", "$2")
.replaceAll("\\{@cult ([^|}]+)\\|[^}]*}", "$1")
.replaceAll("\\{@cult ([^|}]+)}", "$1")
// {@footnote directly in text|This is primarily for homebrew purposes, as the official texts (so far) avoid using footnotes},
// {@footnote optional reference information|This is the footnote. References are free text.|Footnote 1, page 20}.",
.replaceAll("\\{@footnote ([^|}]+)\\|([^|}]+)\\|([^}]*)}", "$1 ^[$2, _$3_]")
.replaceAll("\\{@footnote ([^|}]+)\\|([^}]*)}", "$1 ^[$2]")
.replaceAll("\\{@language ([^|}]+)\\|?[^}]*}", "$1")
.replaceAll("\\{@book ([^}|]+)\\|?[^}]*}", "\"$1\"")
.replaceAll("\\{@hit ([+-][^}<]+)}", "$1")
Expand Down Expand Up @@ -265,6 +262,21 @@ default String _replaceTokenText(String input, boolean nested) {
tui().errorf(e, "Unable to parse string from %s: %s", getSources().getKey(), input);
}

result = footnotePattern.matcher(result).replaceAll((match) -> {
// {@footnote directly in text|This is primarily for homebrew purposes, as the official texts (so far) avoid using footnotes},
// {@footnote optional reference information|This is the footnote. References are free text.|Footnote 1, page 20}.",
// We're converting these to _inline_ markdown footnotes, as numbering is difficult to track
String[] parts = match.group(1).split("\\|");
if (parts[0].contains("<sup>")) {
// This already assumes what the footnote name will be
return String.format("%s", parts[0]);
}
if (parts.length > 2) {
return String.format("%s ^[%s, _%s_]", parts[0], parts[1], parts[2]);
}
return String.format("%s ^[%s]", parts[0], parts[1]);
});

result = notePattern.matcher(result).replaceAll((match) -> {
if (nested) {
return "***Note:** " + match.group(2).trim() + "*";
Expand Down
100 changes: 100 additions & 0 deletions src/test/resources/other/monster-all.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
obsidianUIMode: preview
cssclass: json5e-monster
{#if resource.tags }
tags:
{#for tag in resource.tags}
- {tag}
{/for}
{/if}
aliases: ["{resource.name}"]
---

# {resource.name}
*Source: {resource.source}*

{#if resource.description }
{resource.description}

{/if}
```statblock
{resource.5eStatblockYaml}
```
^statblock

```ad-statblock
title: {resource.name}{#if resource.token}
![{resource.token.title}]({resource.token.vaultPath}#token){/if}
*{resource.size} {resource.fullType}, {resource.alignment}*

- **Armor Class** {#if resource.ac }{resource.ac} {/if}{#if resource.acText }({resource.acText}){/if}
- **Hit Points** {resource.hp or ' '} {#if resource.hitDice }(`{resource.hitDice}`){/if} {#if resource.hpText }({resource.hpText}){/if}
- **Speed** {resource.speed}

|STR|DEX|CON|INT|WIS|CHA|
|:---:|:---:|:---:|:---:|:---:|:---:|
|{resource.scores}|

- **Proficiency Bonus** {resource.pb}
- **Saving Throws** {#if resource.savingThrows }{resource.savingThrows}{#else}⏤{/if}
- **Skills** {#if resource.skills }{resource.skills}{#else}⏤{/if}
- **Senses** {#if resource.senses }{resource.senses}, {/if}passive Perception {resource.passive}
{#if resource.vulnerable }
- **Damage Vulnerabilities** {resource.vulnerable}
{/if}{#if resource.resist}
- **Damage Resistances** {resource.resist}
{/if}{#if resource.immune}
- **Damage Immunities** {resource.immune}
{/if}{#if resource.conditionImmune}
- **Condition Immunities** {resource.conditionImmune}
{/if}
- **Languages** {#if resource.languages }{resource.languages}{#else}—{/if}
- **Challenge** {resource.cr}
{#if resource.trait}

## Traits
{#for trait in resource.trait}

{#if trait.name }***{trait.name}.*** {/if}{trait.desc}
{/for}{/if}{#if resource.spellcasting}{#for spellcasting in resource.spellcasting}

***{spellcasting.name}.*** {spellcasting.desc}
{/for}{/if}{#if resource.action}

## Actions
{#for action in resource.action}

{#if action.name }***{action.name}.*** {/if}{action.desc}
{/for}{/if}{#if resource.bonusAction}

## Bonus Actions
{#for bonusAction in resource.bonusAction}

{#if bonusAction.name }***{bonusAction.name}.*** {/if}{bonusAction.desc}
{/for}{/if}{#if resource.reaction}

## Reactions
{#for reaction in resource.reaction}

{#if reaction.name }***{reaction.name}.*** {/if}{reaction.desc}
{/for}{/if}{#if resource.legendary}

## Legendary Actions
{#for legendary in resource.legendary}

{#if legendary.name }***{legendary.name}.*** {/if}{legendary.desc}
{/for}{/if}{#if resource.legendaryGroup}{#for group in resource.legendaryGroup}

## {group.name}

{group.desc}
{/for}{/if}
```
^statblock-manual

{#if resource.environment }

## Environment

{resource.environment}
{/if}
5 changes: 4 additions & 1 deletion src/test/resources/sources-homebrew.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@
],
"excludePattern": [
"race|.*|dmg"
]
],
"template": {
"monster": "src/test/resources/other/monster-all.txt"
}
}

0 comments on commit b7b1a95

Please sign in to comment.