Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tables Seem To Not Tokenize Properly #563

Closed
NathanielSunday opened this issue Dec 17, 2024 · 3 comments
Closed

Tables Seem To Not Tokenize Properly #563

NathanielSunday opened this issue Dec 17, 2024 · 3 comments

Comments

@NathanielSunday
Copy link

I am using v19.0.0 of ngx-markdown. I am having trouble with getting tables to parse properly. It would seem that anything that should be tokenized as a

tag after a table gets tokenized as a part of the table instead. In the TS snippet below, 'spell' is just a template to hold the JSON object and follows the same structure as the JSON object in the API, which I provided through the API link below. I also provided CSS, settings, and an image of errant behavior.

API table example

TS snippet of where the table is being rendered

<div markdown>
  {{ spell.desc.join('\\n') }}
</div>

CSS snippet

div {
  white-space: pre-wrap;
}

table {
  table-layout: fixed;
  width: 100%;
}

Settings snippet

provideMarkdown({
  sanitize: SecurityContext.NONE,
})

End result
image

@jfcere
Copy link
Owner

jfcere commented Jan 31, 2025

Hi @NathanielSunday,

The problem is that the line that follow the table need to be blank to break the table... this is the same thing here on GitHub.


Your code on GitHub

Objects come to life at your command. Choose up to ten nonmagical objects within range that are not being worn or carried. Medium targets count as two objects, Large targets count as four objects, Huge targets count as eight objects. You can't animate any object larger than Huge. Each target animates and becomes a creature under your control until the spell ends or until reduced to 0 hit points.
As a bonus action, you can mentally command any creature you made with this spell if the creature is within 500 feet of you (if you control multiple creatures, you can command any or all of them at the same time, issuing the same command to each one). You decide what action the creature will take and where it will move during its next turn, or you can issue a general command, such as to guard a particular chamber or corridor. If you issue no commands, the creature only defends itself against hostile creatures. Once given an order, the creature continues to follow it until its task is complete.

Animated Object Statistics
Size HP AC Attack Str Dex
Tiny 20 18 +8 to hit, 1d4 + 4 damage 4 18
Small 25 16 +6 to hit, 1d8 + 2 damage 6 14
Medium 40 13 +5 to hit, 2d6 + 1 damage 10 12
Large 50 10 +6 to hit, 2d10 + 2 damage 14 10
Huge 80 10 +8 to hit, 2d12 + 4 damage 18 6
An animated object is a construct with AC, hit points, attacks, Strength, and Dexterity determined by its size. Its Constitution is 10 and its Intelligence and Wisdom are 3, and its Charisma is 1. Its speed is 30 feet; if the object lacks legs or other appendages it can use for locomotion, it instead has a flying speed of 30 feet and can hover. If the object is securely attached to a surface or a larger object, such as a chain bolted to a wall, its speed is 0. It has blindsight with a radius of 30 feet and is blind beyond that distance. When the animated object drops to 0 hit points, it reverts to its original object form, and any remaining damage carries over to its original object form.
If you command an object to attack, it can make a single melee attack against a creature within 5 feet of it. It makes a slam attack with an attack bonus and bludgeoning damage determined by its size. The GM might rule that a specific object inflicts slashing or piercing damage based on its form.

The same code but with a blank line between the table and the next text line

Objects come to life at your command. Choose up to ten nonmagical objects within range that are not being worn or carried. Medium targets count as two objects, Large targets count as four objects, Huge targets count as eight objects. You can't animate any object larger than Huge. Each target animates and becomes a creature under your control until the spell ends or until reduced to 0 hit points.
As a bonus action, you can mentally command any creature you made with this spell if the creature is within 500 feet of you (if you control multiple creatures, you can command any or all of them at the same time, issuing the same command to each one). You decide what action the creature will take and where it will move during its next turn, or you can issue a general command, such as to guard a particular chamber or corridor. If you issue no commands, the creature only defends itself against hostile creatures. Once given an order, the creature continues to follow it until its task is complete.

Animated Object Statistics
Size HP AC Attack Str Dex
Tiny 20 18 +8 to hit, 1d4 + 4 damage 4 18
Small 25 16 +6 to hit, 1d8 + 2 damage 6 14
Medium 40 13 +5 to hit, 2d6 + 1 damage 10 12
Large 50 10 +6 to hit, 2d10 + 2 damage 14 10
Huge 80 10 +8 to hit, 2d12 + 4 damage 18 6

An animated object is a construct with AC, hit points, attacks, Strength, and Dexterity determined by its size. Its Constitution is 10 and its Intelligence and Wisdom are 3, and its Charisma is 1. Its speed is 30 feet; if the object lacks legs or other appendages it can use for locomotion, it instead has a flying speed of 30 feet and can hover. If the object is securely attached to a surface or a larger object, such as a chain bolted to a wall, its speed is 0. It has blindsight with a radius of 30 feet and is blind beyond that distance. When the animated object drops to 0 hit points, it reverts to its original object form, and any remaining damage carries over to its original object form.
If you command an object to attack, it can make a single melee attack against a creature within 5 feet of it. It makes a slam attack with an attack bonus and bludgeoning damage determined by its size. The GM might rule that a specific object inflicts slashing or piercing damage based on its form.

@jfcere
Copy link
Owner

jfcere commented Jan 31, 2025

Because I am a great guy and I love challenges, if you don't want or are not able to modify the source you can fix the problem by adding a blank line programmatically after a table.

In your component (or move this to a service, a pipe or whatever depending on your needs)...

get spellDesc(): string {
  return this.fixTableEnd(this.spell.desc).join('\n');
}

private fixTableEnd(markdown: string[]): string[] {
  const tableStartIndex = markdown.findIndex((line) => line.startsWith('|'));
  // if there is no table, return the markdown as is
  if (tableStartIndex === -1) {
    return markdown;
  }
  const tableEndIndex = markdown.findIndex((line, index) => index > tableStartIndex && !line.startsWith('|'));
  // if the table is the last element or the next element is already an empty string, return the markdown as is
  if (tableEndIndex === -1 || markdown[tableEndIndex] === '') {
    return markdown;
  }
  // add an empty line after the table to fix the table end
  return [...markdown.slice(0, tableEndIndex), '', ...markdown.slice(tableEndIndex)];
}

Then in your HTML template...

<div markdown>
  {{ spellDesc }}
</div>

@jfcere
Copy link
Owner

jfcere commented Jan 31, 2025

Closing as this behaviour is intended

@jfcere jfcere closed this as completed Jan 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@jfcere @NathanielSunday and others