diff --git a/Telegram/SourceFiles/data/data_document_resolver.cpp b/Telegram/SourceFiles/data/data_document_resolver.cpp index 79c1669928..de4d90b669 100644 --- a/Telegram/SourceFiles/data/data_document_resolver.cpp +++ b/Telegram/SourceFiles/data/data_document_resolver.cpp @@ -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) { diff --git a/Telegram/SourceFiles/iv/markdown/README.md b/Telegram/SourceFiles/iv/markdown/README.md deleted file mode 100644 index f147d807d3..0000000000 --- a/Telegram/SourceFiles/iv/markdown/README.md +++ /dev/null @@ -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 diff --git a/Telegram/SourceFiles/iv/markdown/REPORT.md b/Telegram/SourceFiles/iv/markdown/REPORT.md deleted file mode 100644 index b922c4222a..0000000000 --- a/Telegram/SourceFiles/iv/markdown/REPORT.md +++ /dev/null @@ -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 diff --git a/Telegram/SourceFiles/tests/fixtures/markdown_iv/latex-markdown-test.md b/Telegram/SourceFiles/tests/fixtures/markdown_iv/latex-markdown-test.md new file mode 100644 index 0000000000..c80b4d150e --- /dev/null +++ b/Telegram/SourceFiles/tests/fixtures/markdown_iv/latex-markdown-test.md @@ -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} +$$ diff --git a/Telegram/SourceFiles/tests/fixtures/markdown_iv/markdown-example.md b/Telegram/SourceFiles/tests/fixtures/markdown_iv/markdown-example.md new file mode 100644 index 0000000000..7166f14a4b --- /dev/null +++ b/Telegram/SourceFiles/tests/fixtures/markdown_iv/markdown-example.md @@ -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): + +- H2O using subscript +- E = mc2 using superscript +- Highlighted text using HTML 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: + +Autolink email: + +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: + + + +Reference image: + +![Ref image][img-ref] + +[img-ref]: https://telegram.org/file/400780400980/2/iUU7FUunyXc.515989.jpg/61df261b21f2499762 "Reference Image" + +Data URI image: + + +Broken image test: + + + +## 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: +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 + + + HTML block content + This paragraph is inside a div element. + + + + Click to expand details/summary block + Hidden content inside details. Useful for testing collapsible sections. + + +## 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: + + + + +## 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 + diff --git a/Telegram/SourceFiles/tests/test_markdown_iv.cpp b/Telegram/SourceFiles/tests/test_markdown_iv.cpp index 67daaf3c85..7d58cb8105 100644 --- a/Telegram/SourceFiles/tests/test_markdown_iv.cpp +++ b/Telegram/SourceFiles/tests/test_markdown_iv.cpp @@ -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; } diff --git a/Telegram/cmake/td_iv.cmake b/Telegram/cmake/td_iv.cmake index 8c595ed05f..f4cb6c2334 100644 --- a/Telegram/cmake/td_iv.cmake +++ b/Telegram/cmake/td_iv.cmake @@ -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 diff --git a/Telegram/cmake/telegram_options.cmake b/Telegram/cmake/telegram_options.cmake index 1e7c5afe17..402040d7f0 100644 --- a/Telegram/cmake/telegram_options.cmake +++ b/Telegram/cmake/telegram_options.cmake @@ -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) diff --git a/Telegram/cmake/tests.cmake b/Telegram/cmake/tests.cmake index 25e19c2d03..75a6f1b764 100644 --- a/Telegram/cmake/tests.cmake +++ b/Telegram/cmake/tests.cmake @@ -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 + $ +) - 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)
This paragraph is inside a div element.