Skip to content

fix(message-parser): parse timestamps inside bold and italic (#39376)#39395

Open
7vignesh wants to merge 1 commit intoRocketChat:developfrom
7vignesh:fix/parse-timestamp-in-bold-italic
Open

fix(message-parser): parse timestamps inside bold and italic (#39376)#39395
7vignesh wants to merge 1 commit intoRocketChat:developfrom
7vignesh:fix/parse-timestamp-in-bold-italic

Conversation

@7vignesh
Copy link

@7vignesh 7vignesh commented Mar 5, 2026

This PR fixes an issue in the message parser where Discord-style timestamps (<t:timestamp:format>) are not parsed when placed inside bold or italic markdown formatting.

The PEG grammar is updated so that TimestampRules are included in both BoldContentPreferentialItemPattern and ItalicContentPreferentialItemPattern, allowing timestamps to be correctly recognized within , , , and content.

Changes made:

  1. Extend bold content parsing to treat timestamps as valid inline items.
  2. ​Extend italic content parsing to treat timestamps as valid inline items.
  3. ​Add unit tests covering timestamps inside bold and italic markers to prevent regressions.

Issue(s)Fixes #39376.

Steps to test or reproduce

  1. Send a message containing a timestamp inside bold, for example: <t:1708551317> or <t:1708551317>.
  2. Send a message containing a timestamp inside italic, for example: <t:1708551317> or <t:1708551317>.
  3. Confirm that the timestamp is rendered correctly rather than shown as raw <t:…> text.
  4. Run the updated unit tests for the message parser to ensure all timestamp formatting cases pass.

​### Benchmark: Before vs After

Measured with yarn bench from packages/message-parser/ (tinybench, 1000 ms run / 200 ms warmup).

Emphasis / Formatting

Task Before (ops/sec) After (ops/sec) Δ
bold 13,933 10,743 −23%
italic 13,293 12,053 −9%
strike 13,195 12,857 −3%
nested 11,325 11,139 −2%
deep nesting 9,655 8,923 −8%
multiple 6,152 5,773 −6%

Timestamps

Task Before (ops/sec) After (ops/sec) Δ
unix format 16,823 15,695 −7%

The dip in bold (~23%) is because TimestampRules is now tried before MaybeReferences in the ordered-choice list. On inputs that don't contain a timestamp (like **Hello world**), the parser incurs a failed <t: probe on every token. In absolute terms this is ~3–4 µs per parse call — well within acceptable range. All other categories are unaffected.

Further comments
The approach keeps the change localized to the parser grammar by reusing existing TimestampRules in the bold and italic content patterns, matching how other inline elements are supported and minimizing impact on unrelated parsing behavior.

Summary by CodeRabbit

  • New Features
    • Timestamps can now be displayed within bold and italic formatted text.

Copilot AI review requested due to automatic review settings March 5, 2026 19:53
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

⚠️ No Changeset found

Latest commit: f821346

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@dionisio-bot
Copy link
Contributor

dionisio-bot bot commented Mar 5, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2026

Walkthrough

This PR adds support for parsing timestamps within bold and italic text by including TimestampRules in the BoldContentPreferentialItemPattern and ItalicContentPreferentialItemPattern grammar rules, and extends test coverage to verify this functionality works correctly.

Changes

Cohort / File(s) Summary
Grammar Rules
packages/message-parser/src/grammar.pegjs
Added TimestampRules alternative to ItalicContentPreferentialItemPattern and BoldContentPreferentialItemPattern, enabling timestamp tokens to be parsed within italic and bold emphasis contexts.
Test Coverage
packages/message-parser/tests/timestamp.test.ts
Added ITALIC node helper and extended test cases to verify timestamps are correctly parsed and preserved as TIMESTAMP nodes within bold and italic emphasis variations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Suggested labels

type: bug

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing timestamp parsing within bold and italic markdown formatting.
Linked Issues check ✅ Passed All coding requirements from issue #39376 are met: TimestampRules added to both BoldContentPreferentialItemPattern and ItalicContentPreferentialItemPattern [#39376], and tests added to verify timestamp parsing in bold and italic contexts [#39376].
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: grammar modifications to include TimestampRules in bold/italic patterns and corresponding test updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the message-parser PEG grammar so Discord-style timestamps (<t:...>) are recognized when nested inside bold and italic inline formatting, and adds regression tests for those cases.

Changes:

  • Allow TimestampRules inside italic preferential item parsing.
  • Allow TimestampRules inside bold preferential item parsing.
  • Extend timestamp parsing tests to cover bold/italic wrappers.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/message-parser/src/grammar.pegjs Adds TimestampRules into bold/italic preferential item patterns so timestamps parse inside emphasis.
packages/message-parser/tests/timestamp.test.ts Adds regression cases asserting timestamps parse as TIMESTAMP nodes inside bold/italic markup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +40 to +42
['**<t:1708551317>**', [paragraph([bold([timestampNode('1708551317')])])]],
['_<t:1708551317>_', [paragraph([italic([timestampNode('1708551317')])])]],
['__<t:1708551317>__', [paragraph([italic([timestampNode('1708551317')])])]],
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description claims support for ****…**** and ____…____, but the added tests only cover *, **, _, and __. If **** / ____ are valid emphasis delimiters in this parser, add explicit regression cases for ****<t:1708551317>**** and ____<t:1708551317>____ to prevent the specific reported variants from regressing.

Suggested change
['**<t:1708551317>**', [paragraph([bold([timestampNode('1708551317')])])]],
['_<t:1708551317>_', [paragraph([italic([timestampNode('1708551317')])])]],
['__<t:1708551317>__', [paragraph([italic([timestampNode('1708551317')])])]],
['**<t:1708551317>**', [paragraph([bold([timestampNode('1708551317')])])]],
['****<t:1708551317>****', [paragraph([bold([timestampNode('1708551317')])])]],
['_<t:1708551317>_', [paragraph([italic([timestampNode('1708551317')])])]],
['__<t:1708551317>__', [paragraph([italic([timestampNode('1708551317')])])]],
['____<t:1708551317>____', [paragraph([italic([timestampNode('1708551317')])])]],

Copilot uses AI. Check for mistakes.
BoldContentPreferentialItem = item:BoldContentPreferentialItemPattern { skipBoldEmoji = false; return item; }

BoldContentPreferentialItemPattern = Whitespace / InlineCode / MaybeReferences / UserMention / ChannelMention / MaybeItalic / MaybeStrikethrough / BoldEmoji / BoldEmoticon
BoldContentPreferentialItemPattern = Whitespace / InlineCode / TimestampRules / MaybeReferences / UserMention / ChannelMention / MaybeItalic / MaybeStrikethrough / BoldEmoji / BoldEmoticon
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This preferential item pattern is getting quite long and harder to diff/maintain. Consider formatting it like ItalicContentPreferentialItemPattern (one alternative per line) to keep subsequent additions readable and reduce merge conflicts.

Suggested change
BoldContentPreferentialItemPattern = Whitespace / InlineCode / TimestampRules / MaybeReferences / UserMention / ChannelMention / MaybeItalic / MaybeStrikethrough / BoldEmoji / BoldEmoticon
BoldContentPreferentialItemPattern = Whitespace
/ InlineCode
/ TimestampRules
/ MaybeReferences
/ UserMention
/ ChannelMention
/ MaybeItalic
/ MaybeStrikethrough
/ BoldEmoji
/ BoldEmoticon

Copilot uses AI. Check for mistakes.
['**<t:1708551317>**', [paragraph([bold([timestampNode('1708551317')])])]],
['_<t:1708551317>_', [paragraph([italic([timestampNode('1708551317')])])]],
['__<t:1708551317>__', [paragraph([italic([timestampNode('1708551317')])])]],
])('parses timestamp inside emphasis: %p', (input, output) => {
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name uses the generic term "emphasis" while the cases specifically cover bold and italic. Renaming it to something like "parses timestamp inside bold/italic" would make failures quicker to understand.

Suggested change
])('parses timestamp inside emphasis: %p', (input, output) => {
])('parses timestamp inside bold/italic/strike: %p', (input, output) => {

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/message-parser/tests/timestamp.test.ts (1)

37-45: Good test coverage for the grammar changes.

The tests properly verify timestamps are parsed correctly inside all emphasis variants (~, *, **, _, __).

Consider adding edge case tests for nested emphasis scenarios like ****<t:1708551317>**** (bold-within-bold) or ____<t:1708551317>____ if the PR objectives intend to prevent regressions for these patterns.
,

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/message-parser/tests/timestamp.test.ts` around lines 37 - 45, Add
edge-case tests covering nested/repeated emphasis around timestamps in the
existing test matrix: extend the test.each in timestamp.test.ts to include
inputs like '****<t:1708551317>****' and '____<t:1708551317>____' (and any other
nested variants you want to guard) and assert the expected AST using parse(...)
matching paragraph([bold([...])]) or paragraph([italic([...])]) or strike([...])
as appropriate (reuse timestampNode('1708551317') in the expected output); this
ensures parse, timestampNode, paragraph, bold, italic and strike behavior for
nested emphasis is validated to prevent regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/message-parser/tests/timestamp.test.ts`:
- Around line 37-45: Add edge-case tests covering nested/repeated emphasis
around timestamps in the existing test matrix: extend the test.each in
timestamp.test.ts to include inputs like '****<t:1708551317>****' and
'____<t:1708551317>____' (and any other nested variants you want to guard) and
assert the expected AST using parse(...) matching paragraph([bold([...])]) or
paragraph([italic([...])]) or strike([...]) as appropriate (reuse
timestampNode('1708551317') in the expected output); this ensures parse,
timestampNode, paragraph, bold, italic and strike behavior for nested emphasis
is validated to prevent regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b7050e73-418e-4210-b3c9-49692582ea4d

📥 Commits

Reviewing files that changed from the base of the PR and between d08306b and f821346.

📒 Files selected for processing (2)
  • packages/message-parser/src/grammar.pegjs
  • packages/message-parser/tests/timestamp.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • packages/message-parser/tests/timestamp.test.ts
🧠 Learnings (9)
📓 Common learnings
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Utilize Playwright fixtures (`test`, `page`, `expect`) for consistency in test files

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Ensure tests run reliably in parallel without shared state conflicts

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `test.step()` for complex test scenarios to improve organization in Playwright tests

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to apps/meteor/tests/e2e/**/*.spec.ts : Use `expect` matchers for assertions (`toEqual`, `toContain`, `toBeTruthy`, `toHaveLength`, etc.) instead of `assert` statements in Playwright tests

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2025-11-24T17:08:17.065Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat PR: 0
File: .cursor/rules/playwright.mdc:0-0
Timestamp: 2025-11-24T17:08:17.065Z
Learning: Applies to **/*.spec.ts : Use descriptive test names that clearly communicate expected behavior in Playwright tests

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • packages/message-parser/tests/timestamp.test.ts
📚 Learning: 2025-11-19T18:20:07.720Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37419
File: packages/i18n/src/locales/en.i18n.json:918-921
Timestamp: 2025-11-19T18:20:07.720Z
Learning: Repo: RocketChat/Rocket.Chat — i18n/formatting
Learning: This repository uses a custom message formatting parser in UI blocks/messages; do not assume standard Markdown rules. For keys like Call_ended_bold, Call_not_answered_bold, Call_failed_bold, and Call_transferred_bold in packages/i18n/src/locales/en.i18n.json, retain the existing single-asterisk emphasis unless maintainers request otherwise.

Applied to files:

  • packages/message-parser/src/grammar.pegjs
🔇 Additional comments (3)
packages/message-parser/src/grammar.pegjs (2)

531-540: LGTM! Timestamp support correctly added to italic content.

The addition of TimestampRules to ItalicContentPreferentialItemPattern is consistent with how StrikethroughContent (line 572) already handles timestamps. The placement after InlineCode maintains proper parsing priority.


555-558: LGTM! Timestamp support correctly added to bold content.

The change mirrors the italic pattern update and aligns with StrikethroughContent (line 572), ensuring consistent timestamp parsing across all emphasis types.

packages/message-parser/tests/timestamp.test.ts (1)

9-10: LGTM!

The italic helper follows the established pattern of the existing bold and strike helpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Timestamps not parsed inside bold and italic text

2 participants