Remove option for conditional build.

This commit is contained in:
John Preston
2026-05-01 16:55:07 +07:00
parent 0d4cd753c1
commit f1e2f9d37f
9 changed files with 819 additions and 273 deletions
@@ -20,10 +20,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_gif.h"
#include "history/history.h"
#include "history/history_item.h"
#ifdef TDESKTOP_NATIVE_MARKDOWN_IV
#include "iv/markdown/iv_markdown_common.h"
#include "iv/markdown/iv_markdown_controller.h"
#endif
#include "lang/lang_keys.h"
#include "media/player/media_player_instance.h"
#include "platform/platform_file_utilities.h"
@@ -254,13 +252,11 @@ void ResolveDocument(
if (!openImageInApp()) {
const auto path = document->filepath(true);
if (!path.isEmpty()) {
#ifdef TDESKTOP_NATIVE_MARKDOWN_IV
const auto fileName = QFileInfo(path).fileName();
if (Iv::Markdown::LooksLikeMarkdownFile(fileName)
&& Iv::Markdown::TryOpenLocalFile(path)) {
return;
}
#endif
LaunchWithWarning(path, item);
} else if (document->status == FileReady
|| document->status == FileDownloadFailed) {
@@ -1,89 +0,0 @@
# Native Markdown Instant View
This directory contains the native Markdown Instant View proof of concept behind `TDESKTOP_NATIVE_MARKDOWN_IV`.
Current scope:
- local `.md` / `.markdown` interception from the saved-document open flow
- UTF-8 validation plus explicit parser limits
- cmark-gfm parsing with tables, task lists, strikethrough, autolinks, tagfilter, and footnotes
- native prepare/layout/paint for paragraphs, lists, quotes, code blocks, tables, details blocks, and math
- MicroTeX-backed formula rendering with a preview-lifetime cache
- selection, copy, `Copy Link`, and `Open Link` actions inside the native preview
## Build
The feature is compiled only when `TDESKTOP_NATIVE_MARKDOWN_IV=ON`.
For the app build, use a Debug tree:
```bat
cmake --build out --config Debug --target Telegram
```
The regression probe is emitted only when the build tree is also configured with `DESKTOP_APP_TEST_APPS=ON`. In that case:
```bat
cmake --build out --config Debug --target test_markdown_iv
out\Debug\test_markdown_iv.exe
```
## Manual smoke test
1. Build a Debug app with `TDESKTOP_NATIVE_MARKDOWN_IV=ON`.
2. Launch Telegram Desktop from that build.
3. Save or download a local Markdown file.
4. Click the local `.md` or `.markdown` document from chat history.
Expected behavior:
- supported local Markdown opens in the native preview
- validation, parse, or unsupported-document rejection falls back to the normal file open path
- terminal post-open prepare failures show `Can't preview this Markdown file` with an `Open file` action
Useful manual checks:
- drag selection across multiple blocks
- copy inline math, display math, code blocks, and tables
- verify `Copy Link` / `Open Link` on external, anchor, footnote, and local-Markdown links
- verify rejected relative links do not expose an open action
## Regression target coverage
`test_markdown_iv` now exercises both parser and prepare/render layers:
- parses `markdown-example.md` and `latex-markdown-test.md`
- checks known inline/display formula counts
- keeps the currency, escaped-dollar, fenced-code, and inline-code exclusions
- asserts inline-formula `copySource`, display-math `formulaTex`, details/footnote preservation, and link classification
- verifies oversized-table flattening diagnostics
- runs a headless MicroTeX render/cache smoke pass twice through the same renderer and checks second-pass cache hits
## Limits and failure policy
Current hard limits:
- source bytes: 4 MiB
- cmark nodes: 100000
- nesting depth: 128
- formula bytes: 64 KiB
- formula count: 10000
- prepared blocks: 4096
- rendered table rows / columns / cells: 128 / 16 / 1024
- display-math logical render cap: 1600 x 1200
- formula image cap: 128 MiB physical image budget
- formula cache budget: 32 MiB per preview renderer
Policy:
- oversized or invalid sources reject before native open and fall back to normal file open
- oversized tables flatten into fallback blocks with diagnostics instead of failing the whole preview
- formula overflow or render failure falls back per formula and keeps the preview alive
- terminal prepare failures, including the prepared-block budget, switch the preview surface to the user-facing failure state
## Known gaps
- preview entry is local-file-only; message-bubble embedding is still future work
- details-body reparsing still falls back to plain paragraph text when nested formulas or footnotes would be introduced
- table interaction supports per-cell text selection and whole-table copy, but not arbitrary rectangular multi-cell selection
- relative links are accepted only when they resolve to safe local Markdown targets under the source directory
@@ -1,87 +0,0 @@
# Native Markdown IV Report
Status: production-direction PoC hardening completed with the expanded prepare/render test target kept in place.
## Verification snapshot
Local verification was run in Debug trees with `TDESKTOP_NATIVE_MARKDOWN_IV=ON`:
- build: `out`, target `Telegram`, result pass
- executable: `out/Debug/test_markdown_iv.exe`, result pass
- throwaway `out_phase5/Debug/test_markdown_iv.exe`, result pass before cleanup
- MicroTeX backend: linked
## Explicit limits
- source bytes: 4 MiB
- cmark nodes: 100000
- nesting depth: 128
- formula bytes: 64 KiB
- formula count: 10000
- prepared blocks: 4096
- rendered table rows: 128
- rendered table columns: 16
- rendered table cells: 1024
- display-math logical render cap: 1600 x 1200
- formula physical image cap: 128 MiB
- formula cache budget: 32 MiB per preview renderer
## Failure behavior
- Pre-open validation or parse rejection returns control to the normal file-open path.
- Unsupported or empty Markdown documents also fall back before native preview open.
- Post-open terminal prepare failures, including the prepared-block budget, switch the preview surface to `Can't preview this Markdown file` and expose `Open file`.
- Oversized tables flatten into fallback blocks and increment prepare warnings instead of failing the preview.
- Formula overflow or render failure stays local to the formula slot and uses fallback text / overflow styling instead of aborting the document.
## Selection and copy scope
- drag selection works across multiple prepared segments in document order
- inline formulas copy their original `$...$` source through `copySource`
- display math copies as `$$...$$`
- code blocks copy the raw prepared block text, not visually wrapped lines
- tables support per-cell text selection and whole-table copy serialization
- context menus expose `Copy Text` / `Copy Selected Text`, `Copy Link`, and `Open Link`
- rejected relative links and details toggles intentionally do not expose open actions
## Measured debug counters
From the local `test_markdown_iv.exe` run:
- `markdown-example.md`: `prepare_ms=18`, `formula_ms=14`, `prepare_warnings=0`, `formula_warnings=0`, `prepared_formulas=2`
- `latex-markdown-test.md`: `prepare_ms=342`, `formula_ms=340`, `prepare_warnings=0`, `formula_warnings=0`, `prepared_formulas=124`
- cache smoke, first pass: `hits=6`, `misses=120`
- cache smoke, second pass through the same renderer: `hits=126`, `misses=0`
- cache usage after second pass: `1651956` bytes
The regression target also exercises a synthetic display-math render-cap failure by forcing `displayMathMaxRenderWidth = 1` and verifying that prepare completes with formula warnings and a nonterminal fallback result. It separately builds a parsed document that exceeds the prepared-block budget and verifies the real terminal `prepared-block-limit` failure path.
## Regression target coverage
`test_markdown_iv` now covers:
- parser validation and both shipped fixtures
- known inline/display formula counts
- currency, escaped-dollar, fenced-code, and inline-code exclusions
- inline-formula `copySource`
- display-math `formulaTex`
- prepared table structure and oversize-table flatten diagnostics
- prepared-block terminal failure behavior
- details-block preservation
- footnote references, backlinks, and bottom-list preservation
- safe local-Markdown-link classification versus rejected relative links
- MicroTeX render/cache reuse across repeated prepare passes
## Known unsupported or intentionally deferred cases
- native preview entry is still limited to local files; message-bubble embedding is not implemented
- details-body reparsing degrades to plain paragraph text when nested formulas or footnotes would need a second prepared subdocument
- table selection is not a spreadsheet-style rectangular model; whole-table copy is the supported fallback
- formula cache reuse is scoped to a preview renderer lifetime, not shared globally across preview windows
## Next steps for message-bubble embedding
- split the local-file controller surface from the reusable document-view surface more explicitly
- define a bubble-friendly width policy and table overflow policy for chat layout
- add preview-root creation from message media data instead of the local-file resolver only
- decide whether preview renderers should share a broader formula cache across bubbles or windows
@@ -0,0 +1,403 @@
# LaTeX in Markdown — Ultimate Test File
This document tests every common (and uncommon) way LaTeX appears in Markdown rendering.
---
## 1. Basic Inline Math
Single variable: $x$, $y$, $\alpha$, $\beta$, $\pi$.
In a sentence: The famous identity $e^{i\pi} + 1 = 0$ connects five fundamental constants.
Multiple inline: We have $a = 1$, $b = 2$, and $c = a + b = 3$.
Inline with operators: $f(x) = x^2 + 2x - 1$ evaluated at $x = 3$ gives $f(3) = 14$.
Greek letters: $\alpha$, $\beta$, $\gamma$, $\delta$, $\epsilon$, $\zeta$, $\eta$, $\theta$, $\iota$, $\kappa$, $\lambda$, $\mu$, $\nu$, $\xi$, $\pi$, $\rho$, $\sigma$, $\tau$, $\upsilon$, $\phi$, $\chi$, $\psi$, $\omega$.
Capital Greek: $\Gamma, \Delta, \Theta, \Lambda, \Xi, \Pi, \Sigma, \Upsilon, \Phi, \Psi$.
---
## 2. Display Math
Standard display:
$$
E = mc^2
$$
The quadratic formula:
$$
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$
Euler's identity:
$$
e^{i\pi} + 1 = 0
$$
---
## 3. Fractions, Roots, and Powers
Inline fractions: $\frac{1}{2}$, $\frac{a+b}{c-d}$, $\frac{x^2}{y^3}$.
Nested fractions: $\frac{1}{1 + \frac{1}{1 + \frac{1}{x}}}$.
Display fraction:
$$
\frac{\partial f}{\partial x} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}
$$
Roots: $\sqrt{2}$, $\sqrt[3]{27}$, $\sqrt[n]{x^n} = x$.
Display roots:
$$
\sqrt{1 + \sqrt{1 + \sqrt{1 + \sqrt{1 + \cdots}}}} = \varphi
$$
Powers and subscripts: $x^2$, $x_i$, $x_i^2$, $x^{i+j}$, $x_{i,j}^{2k}$.
---
## 4. Sums, Products, Integrals, Limits
Inline: $\sum_{i=1}^{n} i$, $\prod_{i=1}^{n} i$, $\int_0^1 x \, dx$, $\lim_{x \to 0} \frac{\sin x}{x}$.
Display sum:
$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$
Display product:
$$
\prod_{p \text{ prime}} \frac{1}{1 - p^{-s}} = \sum_{n=1}^{\infty} \frac{1}{n^s}
$$
Definite integral:
$$
\int_{-\infty}^{\infty} e^{-x^2} \, dx = \sqrt{\pi}
$$
Double integral:
$$
\iint_D f(x, y) \, dA
$$
Contour integral:
$$
\oint_C \mathbf{F} \cdot d\mathbf{r} = \iint_S (\nabla \times \mathbf{F}) \cdot d\mathbf{S}
$$
Limits:
$$
\lim_{n \to \infty} \left(1 + \frac{1}{n}\right)^n = e
$$
---
## 5. Matrices and Arrays
Plain matrix:
$$
\begin{matrix}
a & b \\
c & d
\end{matrix}
$$
Parenthesized:
$$
\begin{pmatrix}
1 & 2 & 3 \\
4 & 5 & 6 \\
7 & 8 & 9
\end{pmatrix}
$$
Bracketed:
$$
\begin{bmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 1
\end{bmatrix}
$$
Determinant (vertical bars):
$$
\begin{vmatrix}
a & b \\
c & d
\end{vmatrix} = ad - bc
$$
Double bars (norm):
$$
\begin{Vmatrix}
v_1 \\
v_2
\end{Vmatrix}
$$
Curly braces:
$$
\begin{Bmatrix}
x \\
y
\end{Bmatrix}
$$
---
## 6. Cases and Piecewise Functions
$$
f(x) = \begin{cases}
x^2 & \text{if } x \geq 0 \\
-x^2 & \text{if } x < 0
\end{cases}
$$
$$
\text{sgn}(x) = \begin{cases}
1 & x > 0 \\
0 & x = 0 \\
-1 & x < 0
\end{cases}
$$
---
## 7. Aligned Equations
$$
\begin{aligned}
(a + b)^2 &= a^2 + 2ab + b^2 \\
(a - b)^2 &= a^2 - 2ab + b^2 \\
(a + b)(a - b) &= a^2 - b^2
\end{aligned}
$$
Multi-step derivation:
$$
\begin{aligned}
\nabla \times (\nabla \times \mathbf{A}) &= \nabla(\nabla \cdot \mathbf{A}) - \nabla^2 \mathbf{A} \\
&= \nabla(\nabla \cdot \mathbf{A}) - \Delta \mathbf{A}
\end{aligned}
$$
---
## 8. Operators and Symbols
Logic: $\land, \lor, \neg, \implies, \iff, \forall, \exists, \nexists$.
Set theory: $\in, \notin, \subset, \subseteq, \supset, \supseteq, \cup, \cap, \emptyset, \setminus$.
Comparison: $<, >, \leq, \geq, \neq, \approx, \equiv, \sim, \simeq, \cong, \propto$.
Arrows: $\to, \gets, \leftrightarrow, \Rightarrow, \Leftarrow, \Leftrightarrow, \mapsto, \hookrightarrow$.
Misc: $\infty, \partial, \nabla, \pm, \mp, \times, \div, \cdot, \circ, \star, \ast$.
Number sets: $\mathbb{N}, \mathbb{Z}, \mathbb{Q}, \mathbb{R}, \mathbb{C}, \mathbb{H}, \mathbb{F}_p$.
---
## 9. Functions and Operators
Trig: $\sin x, \cos x, \tan x, \csc x, \sec x, \cot x$.
Inverse trig: $\arcsin x, \arccos x, \arctan x$.
Hyperbolic: $\sinh x, \cosh x, \tanh x$.
Logs: $\log x, \ln x, \log_2 x, \log_{10} x$.
Other: $\exp x, \min, \max, \sup, \inf, \arg\min, \arg\max, \det, \dim, \ker, \deg, \gcd, \lim, \limsup, \liminf$.
---
## 10. Accents and Decorations
Bar: $\bar{x}, \overline{ABC}$.
Hat: $\hat{x}, \widehat{xyz}$.
Tilde: $\tilde{x}, \widetilde{xyz}$.
Vector: $\vec{v}, \overrightarrow{AB}$.
Dot: $\dot{x}, \ddot{x}, \dddot{x}$.
Bold/script: $\mathbf{v}, \mathbf{0}, \boldsymbol{\alpha}, \mathcal{L}, \mathfrak{g}, \mathscr{F}$.
---
## 11. Probability and Statistics
Expected value: $\mathbb{E}[X] = \int_{-\infty}^{\infty} x f(x) \, dx$.
Variance: $\text{Var}(X) = \mathbb{E}[(X - \mu)^2]$.
Normal distribution:
$$
f(x \mid \mu, \sigma^2) = \frac{1}{\sqrt{2\pi\sigma^2}} \exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right)
$$
Bayes' theorem:
$$
P(A \mid B) = \frac{P(B \mid A) \, P(A)}{P(B)}
$$
---
## 12. Edge Cases and Common Pitfalls
### Dollar signs as currency (should NOT render as math)
The shirt costs \$20 and the pants cost \$30. Together: \$50.
### Dollar signs near math
I have $5 in my pocket, not $5x + 3$ dollars.
### Underscores in inline math vs Markdown
Variables like $x_1, x_2, x_3$ should render correctly without triggering italic.
### Backslashes in text
Use `\frac{a}{b}` to write $\frac{a}{b}$.
### Math inside lists
1. First item with math: $a^2 + b^2 = c^2$
2. Second with display:
$$
\int_0^\infty e^{-x} \, dx = 1
$$
3. Third with fraction: $\frac{p}{q}$
### Math inside blockquotes
> The Cauchy-Schwarz inequality:
> $$
> \left(\sum_{i=1}^n a_i b_i\right)^2 \leq \left(\sum_{i=1}^n a_i^2\right)\left(\sum_{i=1}^n b_i^2\right)
> $$
### Math in tables
| Function | Derivative | Integral |
|----------|------------|----------|
| $x^n$ | $nx^{n-1}$ | $\frac{x^{n+1}}{n+1}$ |
| $e^x$ | $e^x$ | $e^x$ |
| $\sin x$ | $\cos x$ | $-\cos x$ |
| $\ln x$ | $\frac{1}{x}$ | $x \ln x - x$ |
### Math in headers
#### The equation $ax^2 + bx + c = 0$
### Bold and italic with math
**Bold text with $E = mc^2$ inline.**
*Italic with $\pi \approx 3.14$ inline.*
### Code blocks should NOT render math
```
This is a code block: $x^2 + y^2 = z^2$ — should be literal.
```
Inline code: `$x^2$` — also literal.
### Escaped dollar signs
To write a literal dollar sign: \$100 or \$x^2\$.
---
## 13. Long and Complex Expressions
Maxwell's equations:
$$
\begin{aligned}
\nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \\
\nabla \cdot \mathbf{B} &= 0 \\
\nabla \times \mathbf{E} &= -\frac{\partial \mathbf{B}}{\partial t} \\
\nabla \times \mathbf{B} &= \mu_0 \mathbf{J} + \mu_0 \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}
\end{aligned}
$$
Schrödinger equation:
$$
i\hbar \frac{\partial}{\partial t} \Psi(\mathbf{r}, t) = \left[-\frac{\hbar^2}{2m} \nabla^2 + V(\mathbf{r}, t)\right] \Psi(\mathbf{r}, t)
$$
Einstein field equations:
$$
R_{\mu\nu} - \frac{1}{2} R g_{\mu\nu} + \Lambda g_{\mu\nu} = \frac{8\pi G}{c^4} T_{\mu\nu}
$$
Fourier transform:
$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) \, e^{-2\pi i x \xi} \, dx
$$
---
## 14. Spacing Tests
No space: $a+b$, $a-b$, $a=b$.
Thin space: $a\,b$.
Medium space: $a\:b$.
Thick space: $a\;b$.
Quad: $a\quad b$.
Double quad: $a\qquad b$.
Negative space: $a\!b$.
---
## 15. Stretchy Delimiters
$$
\left( \frac{a}{b} \right), \quad \left[ \frac{a}{b} \right], \quad \left\{ \frac{a}{b} \right\}, \quad \left| \frac{a}{b} \right|, \quad \left\| \frac{a}{b} \right\|
$$
$$
\left( \sum_{i=1}^{n} \frac{x_i^2}{\sqrt{1 + x_i^4}} \right)^{1/2}
$$
@@ -0,0 +1,330 @@
# Markdown Display Test File
This file is a comprehensive Markdown sample for testing rendering behavior.
## Table of Contents
- [Headings](#headings)
- [Text Styles](#text-styles)
- [Blockquotes](#blockquotes)
- [Lists](#lists)
- [Code](#code)
- [Links](#links)
- [Images](#images)
- [Tables](#tables)
- [Task Lists](#task-lists)
- [Rules and Breaks](#rules-and-breaks)
- [Escaping Characters](#escaping-characters)
- [Footnotes](#footnotes)
- [Inline HTML](#inline-html)
- [Definition Lists (renderer-dependent)](#definition-lists-renderer-dependent)
- [Math (renderer-dependent)](#math-renderer-dependent)
- [Diagram Blocks (renderer-dependent)](#diagram-blocks-renderer-dependent)
- [Edge Cases](#edge-cases)
---
## Headings
# H1 Heading
## H2 Heading
### H3 Heading
#### H4 Heading
##### H5 Heading
###### H6 Heading
## Text Styles
Plain text paragraph with normal sentence flow.
**Bold text**
__Bold text with underscores__
*Italic text*
_Italic text with underscores_
***Bold + italic***
~~Strikethrough~~
`Inline code`
Combination: **bold**, *italic*, ~~strike~~, and `code` in one line.
HTML-based styles (depends on renderer support):
- H<sub>2</sub>O using subscript
- E = mc<sup>2</sup> using superscript
- <mark>Highlighted text using HTML mark</mark>
## Blockquotes
> Single-level blockquote.
> Multi-line blockquote:
> This is line 1.
> This is line 2.
> Nested quote level 1
>> Nested quote level 2
>>> Nested quote level 3
> Quote with formatting: **bold**, *italic*, and `code`.
## Lists
### Unordered Lists
- Item A
- Item B
- Item C
* Item using asterisk
* Another asterisk item
+ Item using plus
+ Another plus item
### Ordered Lists
1. First item
2. Second item
3. Third item
1. Numbering can restart at 1
1. Many parsers auto-increment
1. Final item
### Mixed and Nested Lists
1. Top-level ordered item
2. Top-level ordered item
- Nested unordered under ordered
- Another nested unordered
1. Nested ordered under unordered
2. Nested ordered second item
3. Back to top-level ordered
- Top-level unordered
1. Nested ordered
2. Nested ordered second
- Back to unordered
## Code
### Fenced Code Block (no language)
```
This is a plain fenced code block.
Special chars: < > & * _ `
```
### Fenced Code Block (language: javascript)
```javascript
function greet(name) {
console.log(`Hello, ${name}!`);
}
greet("Markdown");
```
### Fenced Code Block (language: python)
```python
def fib(n):
a, b = 0, 1
out = []
while len(out) < n:
out.append(a)
a, b = b, a + b
return out
print(fib(8))
```
### Indented Code Block
This is an indented code block.
It starts with four spaces.
## Links
Inline link: [OpenAI](https://openai.com)
Autolink URL: <https://example.com/path?query=1&lang=en>
Autolink email: <test@example.com>
Reference-style link: [Search Engine][search]
[search]: https://duckduckgo.com "DuckDuckGo"
Link with title: [Markdown Guide](https://www.markdownguide.org "Markdown Guide")
Relative link (for app routing tests): [Local Path](./docs/getting-started.md)
## Images
Inline image:
![Placeholder image](https://telegram.org/file/400780400931/3/L6HFfelQm5E.394826.jpg/c82f3df5fb2bdde5f3)
Reference image:
![Ref image][img-ref]
[img-ref]: https://telegram.org/file/400780400980/2/iUU7FUunyXc.515989.jpg/61df261b21f2499762 "Reference Image"
Data URI image:
![a red dot](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==)
Broken image test:
![Broken image](https://example.com/this-image-does-not-exist.png)
## Tables
| Column A | Column B | Column C |
| --- | --- | --- |
| Text | **Bold** | `Code` |
| Left | Center | Right |
| Multi word | With [link](https://example.com) | ~~Strikethrough~~ |
Alignment table:
| Left Align | Center Align | Right Align |
| :--- | :---: | ---: |
| apple | middle | 10 |
| banana | center | 200 |
| cherry | aligned | 3000 |
## Task Lists
- [x] Completed task
- [ ] Incomplete task
- [x] Completed with `inline code`
- [ ] Pending with [link](https://example.com)
## Rules and Breaks
Paragraph above first rule.
---
Paragraph above second rule.
***
Paragraph above third rule.
___
Line break test (two spaces at end of line):
This should be on a new line.
HTML line break test:<br>
This should also be on a new line.
## Escaping Characters
Literal asterisks: \*not italic\*
Literal underscores: \_not italic\_
Literal backticks: \`not code\`
Literal brackets: \[not a link\]
Literal hash: \# not a heading
Literal pipe in table-like text: A \| B
## Footnotes
Footnote reference one.[^1]
Footnote reference two with more text.[^long-note]
[^1]: This is footnote number one.
[^long-note]: This is a longer footnote with **formatting**, `code`, and a [link](https://example.com).
## Inline HTML
<div>
<strong>HTML block content</strong>
<p>This paragraph is inside a div element.</p>
</div>
<details>
<summary>Click to expand details/summary block</summary>
Hidden content inside details. Useful for testing collapsible sections.
</details>
## Definition Lists (renderer-dependent)
Term 1
: Definition for term 1
Term 2
: First definition for term 2
: Second definition for term 2
## Math (renderer-dependent)
Inline math style: $a^2 + b^2 = c^2$
Block math style:
$$
\int_0^1 x^2\,dx = \frac{1}{3}
$$
## Diagram Blocks (renderer-dependent)
```mermaid
graph TD
A[Start] --> B{Condition}
B -->|Yes| C[Do thing]
B -->|No| D[Do other thing]
C --> E[End]
D --> E[End]
```
## Edge Cases
Empty emphasis markers:
****
Long line test:
ThisIsALongUnbrokenStringToTestWrappingBehavior_ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789_abcdefghijklmnopqrstuvwxyz_0123456789
Unicode test:
- Accents: cafe, naive, fiance
- Cyrillic: primer teksta
- Greek: alpha beta gamma
Backslash at end of line test:\
HTML comment should be hidden in some renderers:
<!-- Hidden comment: markdown-renderer-test -->
## Final Checklist
- [ ] Headings render correctly
- [ ] Inline styles render correctly
- [ ] Nested lists and mixed lists render correctly
- [ ] Code blocks and syntax highlighting work
- [ ] Tables render with alignment
- [ ] Images and broken images handled correctly
- [ ] Footnotes and reference links work
- [ ] HTML blocks are sanitized or rendered as expected
- [ ] Renderer-dependent features fail gracefully if unsupported
@@ -106,12 +106,15 @@ void PrintError(const QString &line) {
}
const auto repoFixtureFromApplication = QDir::cleanPath(
applicationDir.filePath(
FromLatin1("../../Telegram/MarkdownMathProbes/fixtures/") + name));
FromLatin1(
"../../Telegram/SourceFiles/tests/fixtures/markdown_iv/")
+ name));
if (QFileInfo::exists(repoFixtureFromApplication)) {
return repoFixtureFromApplication;
}
const auto repoFixtureFromCurrent = QDir::current().filePath(
FromLatin1("Telegram/MarkdownMathProbes/fixtures/") + name);
FromLatin1("Telegram/SourceFiles/tests/fixtures/markdown_iv/")
+ name);
if (QFileInfo::exists(repoFixtureFromCurrent)) {
return repoFixtureFromCurrent;
}
+26 -34
View File
@@ -21,41 +21,33 @@ PRIVATE
iv/iv_prepare.h
)
if (TDESKTOP_NATIVE_MARKDOWN_IV)
nice_target_sources(td_iv ${src_loc}
PRIVATE
iv/markdown/README.md
iv/markdown/iv_markdown_common.cpp
iv/markdown/iv_markdown_common.h
iv/markdown/iv_markdown_controller.cpp
iv/markdown/iv_markdown_controller.h
iv/markdown/iv_markdown_document.cpp
iv/markdown/iv_markdown_document.h
iv/markdown/iv_markdown_math.cpp
iv/markdown/iv_markdown_math.h
iv/markdown/iv_markdown_math_renderer.cpp
iv/markdown/iv_markdown_math_renderer.h
iv/markdown/iv_markdown_microtex.cpp
iv/markdown/iv_markdown_microtex.h
iv/markdown/iv_markdown_parse.cpp
iv/markdown/iv_markdown_parse.h
iv/markdown/iv_markdown_prepare.cpp
iv/markdown/iv_markdown_prepare.h
iv/markdown/iv_markdown_view.cpp
iv/markdown/iv_markdown_view.h
)
nice_target_sources(td_iv ${src_loc}
PRIVATE
iv/markdown/iv_markdown_common.cpp
iv/markdown/iv_markdown_common.h
iv/markdown/iv_markdown_controller.cpp
iv/markdown/iv_markdown_controller.h
iv/markdown/iv_markdown_document.cpp
iv/markdown/iv_markdown_document.h
iv/markdown/iv_markdown_math.cpp
iv/markdown/iv_markdown_math.h
iv/markdown/iv_markdown_math_renderer.cpp
iv/markdown/iv_markdown_math_renderer.h
iv/markdown/iv_markdown_microtex.cpp
iv/markdown/iv_markdown_microtex.h
iv/markdown/iv_markdown_parse.cpp
iv/markdown/iv_markdown_parse.h
iv/markdown/iv_markdown_prepare.cpp
iv/markdown/iv_markdown_prepare.h
iv/markdown/iv_markdown_view.cpp
iv/markdown/iv_markdown_view.h
)
target_link_libraries(td_iv
PRIVATE
desktop-app::external_cmark_gfm
desktop-app::external_microtex
)
target_compile_definitions(td_iv
PRIVATE
TDESKTOP_NATIVE_MARKDOWN_IV
)
endif()
target_link_libraries(td_iv
PRIVATE
desktop-app::external_cmark_gfm
desktop-app::external_microtex
)
nice_target_sources(td_iv ${res_loc}
PRIVATE
-5
View File
@@ -5,7 +5,6 @@
# https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
option(TDESKTOP_API_TEST "Use test API credentials." OFF)
option(TDESKTOP_NATIVE_MARKDOWN_IV "Build native Markdown Instant View proof of concept." OFF)
set(TDESKTOP_API_ID "0" CACHE STRING "Provide 'api_id' for the Telegram API access.")
set(TDESKTOP_API_HASH "" CACHE STRING "Provide 'api_hash' for the Telegram API access.")
@@ -53,10 +52,6 @@ if (DESKTOP_APP_SPECIAL_TARGET)
target_compile_definitions(Telegram PRIVATE TDESKTOP_ALLOW_CLOSED_ALPHA)
endif()
if (TDESKTOP_NATIVE_MARKDOWN_IV)
target_compile_definitions(Telegram PRIVATE TDESKTOP_NATIVE_MARKDOWN_IV)
endif()
option(DESKTOP_APP_DISABLE_SWIFT6 "Disable local on-device translation (build without Swift 6 on macOS)." OFF)
if (DESKTOP_APP_DISABLE_SWIFT6)
target_compile_definitions(Telegram PRIVATE TDESKTOP_DISABLE_SWIFT6)
+55 -52
View File
@@ -43,63 +43,66 @@ add_dependencies(Telegram test_text)
target_prepare_qrc(test_text)
if (TDESKTOP_NATIVE_MARKDOWN_IV)
add_executable(test_markdown_iv)
init_target(test_markdown_iv "(tests)")
add_executable(test_markdown_iv)
init_target(test_markdown_iv "(tests)")
target_precompile_headers(test_markdown_iv PRIVATE ${src_loc}/iv/iv_pch.h)
target_precompile_headers(test_markdown_iv PRIVATE ${src_loc}/iv/iv_pch.h)
target_include_directories(test_markdown_iv PRIVATE
${src_loc}
${CMAKE_BINARY_DIR}/Telegram/gen
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen
)
target_include_directories(test_markdown_iv PRIVATE
${src_loc}
${CMAKE_BINARY_DIR}/Telegram/gen
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen
)
nice_target_sources(test_markdown_iv ${src_loc}
PRIVATE
tests/test_markdown_iv.cpp
iv/markdown/iv_markdown_common.cpp
iv/markdown/iv_markdown_common.h
iv/markdown/iv_markdown_document.cpp
iv/markdown/iv_markdown_document.h
iv/markdown/iv_markdown_math.cpp
iv/markdown/iv_markdown_math.h
iv/markdown/iv_markdown_math_renderer.cpp
iv/markdown/iv_markdown_math_renderer.h
iv/markdown/iv_markdown_microtex.cpp
iv/markdown/iv_markdown_microtex.h
iv/markdown/iv_markdown_parse.cpp
iv/markdown/iv_markdown_parse.h
iv/markdown/iv_markdown_prepare.cpp
iv/markdown/iv_markdown_prepare.h
)
nice_target_sources(test_markdown_iv ${src_loc}
PRIVATE
tests/test_markdown_iv.cpp
iv/markdown/iv_markdown_common.cpp
iv/markdown/iv_markdown_common.h
iv/markdown/iv_markdown_document.cpp
iv/markdown/iv_markdown_document.h
iv/markdown/iv_markdown_math.cpp
iv/markdown/iv_markdown_math.h
iv/markdown/iv_markdown_math_renderer.cpp
iv/markdown/iv_markdown_math_renderer.h
iv/markdown/iv_markdown_microtex.cpp
iv/markdown/iv_markdown_microtex.h
iv/markdown/iv_markdown_parse.cpp
iv/markdown/iv_markdown_parse.h
iv/markdown/iv_markdown_prepare.cpp
iv/markdown/iv_markdown_prepare.h
)
target_sources(test_markdown_iv PRIVATE
${CMAKE_BINARY_DIR}/Telegram/gen/styles/style_iv.cpp
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen/styles/palette.cpp
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen/styles/style_basic.cpp
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen/styles/style_widgets.cpp
)
target_sources(test_markdown_iv PRIVATE
${CMAKE_BINARY_DIR}/Telegram/gen/styles/style_iv.cpp
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen/styles/palette.cpp
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen/styles/style_basic.cpp
${CMAKE_BINARY_DIR}/Telegram/lib_ui/gen/styles/style_widgets.cpp
)
target_compile_definitions(test_markdown_iv
PRIVATE
TDESKTOP_NATIVE_MARKDOWN_IV
)
target_link_libraries(test_markdown_iv
PRIVATE
desktop-app::external_cmark_gfm
desktop-app::external_microtex
desktop-app::external_qt
desktop-app::external_qt_static_plugins
desktop-app::lib_base
desktop-app::lib_crl
desktop-app::lib_tl
desktop-app::lib_ui
)
target_link_libraries(test_markdown_iv
PRIVATE
desktop-app::external_cmark_gfm
desktop-app::external_microtex
desktop-app::external_qt
desktop-app::external_qt_static_plugins
desktop-app::lib_base
desktop-app::lib_crl
desktop-app::lib_tl
desktop-app::lib_ui
)
set_target_properties(
test_markdown_iv
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)
set_target_properties(test_markdown_iv PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_command(TARGET test_markdown_iv POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${src_loc}/tests/fixtures/markdown_iv/markdown-example.md
${src_loc}/tests/fixtures/markdown_iv/latex-markdown-test.md
$<TARGET_FILE_DIR:test_markdown_iv>
)
add_dependencies(Telegram test_markdown_iv)
add_dependencies(test_markdown_iv lib_ui_styles td_scheme_scheme td_ui_styles)
endif()
add_dependencies(Telegram test_markdown_iv)
add_dependencies(test_markdown_iv lib_ui_styles td_scheme_scheme td_ui_styles)