mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-08-04 18:28:02 +00:00
fix: block math align center (#1762)
Some checks failed
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / build-binary (push) Has been cancelled
tinymist::ci / build-vsc-assets (push) Has been cancelled
tinymist::ci / build-vscode (push) Has been cancelled
tinymist::ci / build-vscode-others (push) Has been cancelled
tinymist::ci / publish-vscode (push) Has been cancelled
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-2019) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Has been cancelled
Some checks failed
tinymist::ci / Duplicate Actions Detection (push) Has been cancelled
tinymist::ci / Check Clippy, Formatting, Completion, Documentation, and Tests (Linux) (push) Has been cancelled
tinymist::ci / Check Minimum Rust version and Tests (Windows) (push) Has been cancelled
tinymist::ci / prepare-build (push) Has been cancelled
tinymist::gh_pages / build-gh-pages (push) Has been cancelled
tinymist::ci / build-binary (push) Has been cancelled
tinymist::ci / build-vsc-assets (push) Has been cancelled
tinymist::ci / build-vscode (push) Has been cancelled
tinymist::ci / build-vscode-others (push) Has been cancelled
tinymist::ci / publish-vscode (push) Has been cancelled
tinymist::ci / E2E Tests (darwin-arm64 on macos-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-22.04) (push) Has been cancelled
tinymist::ci / E2E Tests (linux-x64 on ubuntu-latest) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-2019) (push) Has been cancelled
tinymist::ci / E2E Tests (win32-x64 on windows-latest) (push) Has been cancelled
* fix: block math align center * fix: block math align center (#1764) * fix: process block children * test: update snapshot --------- Co-authored-by: Hong Jiarong <me@jrhim.com>
This commit is contained in:
parent
953f997281
commit
a33ab6a79b
26 changed files with 136 additions and 43 deletions
|
@ -4,6 +4,6 @@ expression: "JsonRepr::new_redacted(result, &REDACT_LOC)"
|
|||
input_file: crates/tinymist-query/src/fixtures/hover/render_equation.typ
|
||||
---
|
||||
{
|
||||
"contents": "```typc\nlet lam(\n A: type,\n B: type,\n) = dictionary;\n```\n\n---\n\nLambda constructor.\n\nTyping Rule:\n\n<img alt=\"typst-block\" src=\"data:image-hash/svg+xml;base64,redacted\" />\n\n# Positional Parameters\n\n## A\n\n```typc\ntype: type\n```\n\nThe type of the argument.\n \n - <!-- typlite:begin:list-item 1 -->It can be also regarded as the condition of the proposition.<!-- typlite:end:list-item 1 -->\n\n## B (positional)\n\n```typc\ntype: type\n```\n\nThe type of the body.\n \n - <!-- typlite:begin:list-item 1 -->It can be also regarded as the conclusion of the proposition.<!-- typlite:end:list-item 1 -->",
|
||||
"contents": "```typc\nlet lam(\n A: type,\n B: type,\n) = dictionary;\n```\n\n---\n\nLambda constructor.\n\nTyping Rule:\n\n<p align=\"center\"><img alt=\"typst-block\" src=\"data:image-hash/svg+xml;base64,redacted\" /></p>\n\n# Positional Parameters\n\n## A\n\n```typc\ntype: type\n```\n\nThe type of the argument.\n \n - <!-- typlite:begin:list-item 1 -->It can be also regarded as the condition of the proposition.<!-- typlite:end:list-item 1 -->\n\n## B (positional)\n\n```typc\ntype: type\n```\n\nThe type of the body.\n \n - <!-- typlite:begin:list-item 1 -->It can be also regarded as the conclusion of the proposition.<!-- typlite:end:list-item 1 -->",
|
||||
"range": "12:20:12:23"
|
||||
}
|
||||
|
|
|
@ -103,6 +103,43 @@ impl HighlightNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Node for centered content
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[custom_node]
|
||||
pub struct CenterNode {
|
||||
/// The content to be centered
|
||||
pub node: Node,
|
||||
}
|
||||
|
||||
impl CenterNode {
|
||||
pub fn new(children: Vec<Node>) -> Self {
|
||||
CenterNode {
|
||||
node: Node::HtmlElement(cmark_writer::ast::HtmlElement {
|
||||
tag: "p".to_string(),
|
||||
attributes: vec![cmark_writer::ast::HtmlAttribute {
|
||||
name: "align".to_string(),
|
||||
value: "center".to_string(),
|
||||
}],
|
||||
children,
|
||||
self_closing: false,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_custom(&self, writer: &mut dyn CustomNodeWriter) -> WriteResult<()> {
|
||||
let mut temp_writer = cmark_writer::writer::CommonMarkWriter::new();
|
||||
temp_writer.write(&self.node)?;
|
||||
let content = temp_writer.into_string();
|
||||
writer.write_str(&content)?;
|
||||
writer.write_str("\n")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_block_custom(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Common writer interface for different formats
|
||||
pub trait FormatWriter {
|
||||
/// Write AST document to output format
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/typlite/src/tests.rs
|
||||
expression: "conv(world, false)"
|
||||
expression: "conv(world, ConvKind::Md { for_docs: false })"
|
||||
input_file: crates/typlite/src/fixtures/integration/figure_caption.typ
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
|
@ -13,6 +13,7 @@ input_file: crates/typlite/src/fixtures/integration/figure_caption.typ
|
|||
</html>
|
||||
|
||||
=====
|
||||

|
||||
<p align="center">
|
||||
|
||||
Caption
|
||||
</p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/typlite/src/tests.rs
|
||||
expression: "conv(world, false)"
|
||||
expression: "conv(world, ConvKind::Md { for_docs: false })"
|
||||
input_file: crates/typlite/src/fixtures/integration/figure_image.typ
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
|
@ -13,4 +13,6 @@ input_file: crates/typlite/src/fixtures/integration/figure_image.typ
|
|||
</html>
|
||||
|
||||
=====
|
||||

|
||||
<p align="center">
|
||||
|
||||
</p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/typlite/src/tests.rs
|
||||
expression: "conv(world, false)"
|
||||
expression: "conv(world, ConvKind::Md { for_docs: false })"
|
||||
input_file: crates/typlite/src/fixtures/integration/figure_image_alt.typ
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
|
@ -13,4 +13,6 @@ input_file: crates/typlite/src/fixtures/integration/figure_image_alt.typ
|
|||
</html>
|
||||
|
||||
=====
|
||||

|
||||
<p align="center">
|
||||
|
||||
</p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/typlite/src/tests.rs
|
||||
expression: "conv(world, false)"
|
||||
expression: "conv(world, ConvKind::Md { for_docs: false })"
|
||||
input_file: crates/typlite/src/fixtures/integration/math_block.typ
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
|
@ -13,4 +13,4 @@ input_file: crates/typlite/src/fixtures/integration/math_block.typ
|
|||
</html>
|
||||
|
||||
=====
|
||||
<img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" />
|
||||
<p align="center"><img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" /></p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/typlite/src/tests.rs
|
||||
expression: "conv(world, false)"
|
||||
expression: "conv(world, ConvKind::Md { for_docs: false })"
|
||||
input_file: crates/typlite/src/fixtures/integration/math_block2.typ
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
|
@ -13,4 +13,4 @@ input_file: crates/typlite/src/fixtures/integration/math_block2.typ
|
|||
</html>
|
||||
|
||||
=====
|
||||
<img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" />
|
||||
<p align="center"><img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" /></p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
source: crates/typlite/src/tests.rs
|
||||
expression: "conv(world, false)"
|
||||
expression: "conv(world, ConvKind::Md { for_docs: false })"
|
||||
input_file: crates/typlite/src/fixtures/integration/outline.typ
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
|
@ -63,7 +63,7 @@ namespace MyApplication
|
|||
|
||||
Math inline:<img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" />and block:
|
||||
|
||||
<img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" />
|
||||
<p align="center"><img alt="typst-block" src="data:image-hash/svg+xml;base64,redacted" /></p>
|
||||
|
||||
- First item
|
||||
- Second item
|
||||
|
|
|
@ -15,11 +15,14 @@ input_file: crates/typlite/src/fixtures/integration/figure_caption.typ
|
|||
=====
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{fig.svg}
|
||||
\caption{Caption}
|
||||
\end{figure}
|
||||
|
||||
\end{center}
|
||||
|
||||
|
||||
\end{document}
|
||||
|
|
|
@ -15,10 +15,13 @@ input_file: crates/typlite/src/fixtures/integration/figure_image.typ
|
|||
=====
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{fig.svg}
|
||||
\end{figure}
|
||||
|
||||
\end{center}
|
||||
|
||||
|
||||
\end{document}
|
||||
|
|
|
@ -15,10 +15,13 @@ input_file: crates/typlite/src/fixtures/integration/figure_image_alt.typ
|
|||
=====
|
||||
\begin{document}
|
||||
|
||||
\begin{center}
|
||||
\begin{figure}[htbp]
|
||||
\centering
|
||||
\includegraphics[width=0.8\textwidth]{fig.svg}
|
||||
\end{figure}
|
||||
|
||||
\end{center}
|
||||
|
||||
|
||||
\end{document}
|
||||
|
|
|
@ -15,7 +15,8 @@ input_file: crates/typlite/src/fixtures/integration/math_block.typ
|
|||
=====
|
||||
\begin{document}
|
||||
|
||||
|
||||
\begin{center}
|
||||
\end{center}
|
||||
|
||||
|
||||
\end{document}
|
||||
|
|
|
@ -15,7 +15,8 @@ input_file: crates/typlite/src/fixtures/integration/math_block2.typ
|
|||
=====
|
||||
\begin{document}
|
||||
|
||||
|
||||
\begin{center}
|
||||
\end{center}
|
||||
|
||||
|
||||
\end{document}
|
||||
|
|
|
@ -65,7 +65,8 @@ namespace MyApplication
|
|||
|
||||
Math inline:and block:
|
||||
|
||||
|
||||
\begin{center}
|
||||
\end{center}
|
||||
|
||||
\begin{itemize}
|
||||
\item First item
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/figure_caption.typ
|
||||
---
|
||||
siphash128_13:17d544d88231b74b1119c35f627026b
|
||||
siphash128_13:57521e02b1a93b78c212f39755cf70f
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/figure_image.typ
|
||||
---
|
||||
siphash128_13:89ee713812f00bde9ac174f72c81760
|
||||
siphash128_13:57521e02b1a93b78c212f39755cf70f
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/figure_image_alt.typ
|
||||
---
|
||||
siphash128_13:89ee713812f00bde9ac174f72c81760
|
||||
siphash128_13:57521e02b1a93b78c212f39755cf70f
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/math_block.typ
|
||||
---
|
||||
siphash128_13:ca4f0e6c5b2afee90d9736cb2d3bd6ba
|
||||
siphash128_13:57521e02b1a93b78c212f39755cf70f
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/math_block2.typ
|
||||
---
|
||||
siphash128_13:1c9f3489f7742ef572998ff2b4fd5abd
|
||||
siphash128_13:57521e02b1a93b78c212f39755cf70f
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/math_inline.typ
|
||||
---
|
||||
siphash128_13:2ac3d241b41c4ee23a122b73e43c8063
|
||||
siphash128_13:d822231ced812e25cf1951464239a2c6
|
||||
|
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/outline.typ
|
||||
---
|
||||
siphash128_13:549cf83e9b77d8ae061c95ceb4f93ef6
|
||||
siphash128_13:3f03c4d1977d61d03c9da495a480baaa
|
||||
|
|
|
@ -167,12 +167,17 @@
|
|||
)
|
||||
show math.equation.where(block: true): it => if-not-paged(
|
||||
it,
|
||||
html.elem(
|
||||
"m1eqblock",
|
||||
if sys.inputs.at("x-remove-html", default: none) != "true" { html.frame(block(inset: 0.5em, it)) } else {
|
||||
process-math-eq(it.body).flatten().join()
|
||||
},
|
||||
),
|
||||
if sys.inputs.at("x-remove-html", default: none) != "true" {
|
||||
html.elem(
|
||||
"m1eqblock",
|
||||
html.frame(block(inset: 0.5em, it)),
|
||||
)
|
||||
} else {
|
||||
html.elem(
|
||||
"m1eqinline",
|
||||
process-math-eq(it.body).flatten().join(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
// show linebreak: it => if-not-paged(it, md-linebreak)
|
||||
|
|
|
@ -4,7 +4,7 @@ use cmark_writer::ast::{CustomNode, HtmlAttribute, HtmlElement as CmarkHtmlEleme
|
|||
use typst::html::{tag, HtmlElement, HtmlNode};
|
||||
|
||||
use crate::attributes::{HeadingAttr, RawAttr, TypliteAttrsParser};
|
||||
use crate::common::ListState;
|
||||
use crate::common::{CenterNode, ListState};
|
||||
use crate::tags::md_tag;
|
||||
use crate::Result;
|
||||
use crate::TypliteFeat;
|
||||
|
@ -134,10 +134,12 @@ impl HtmlToAstParser {
|
|||
md_tag::math_equation_inline | md_tag::math_equation_block => {
|
||||
if element.tag == md_tag::math_equation_block {
|
||||
self.flush_inline_buffer();
|
||||
}
|
||||
self.convert_children(element)?;
|
||||
if element.tag == md_tag::math_equation_block {
|
||||
self.flush_inline_buffer();
|
||||
self.convert_children(element)?;
|
||||
let content = std::mem::take(&mut self.inline_buffer);
|
||||
self.blocks
|
||||
.push(Node::Custom(Box::new(CenterNode::new(content))));
|
||||
} else {
|
||||
self.convert_children(element)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ use cmark_writer::ast::Node;
|
|||
use typst::html::HtmlElement;
|
||||
|
||||
use crate::attributes::{FigureAttr, ImageAttr, LinkAttr, TypliteAttrsParser};
|
||||
use crate::common::{FigureNode, HighlightNode};
|
||||
use crate::common::{CenterNode, FigureNode, HighlightNode};
|
||||
use crate::Result;
|
||||
|
||||
use super::core::HtmlToAstParser;
|
||||
|
@ -88,10 +88,12 @@ impl InlineParser {
|
|||
parser.convert_children_into(&mut body_content, element)?;
|
||||
let body = Box::new(Node::Paragraph(body_content));
|
||||
|
||||
// Create figure node using generic definition
|
||||
parser
|
||||
.blocks
|
||||
.push(Node::Custom(Box::new(FigureNode { body, caption })));
|
||||
// Create figure node with centering
|
||||
let figure_node = Box::new(FigureNode { body, caption });
|
||||
let centered_node = CenterNode::new(vec![Node::Custom(figure_node)]);
|
||||
|
||||
// Add the centered figure to blocks
|
||||
parser.blocks.push(Node::Custom(Box::new(centered_node)));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -7,14 +7,15 @@ use ecow::EcoString;
|
|||
use std::fs;
|
||||
use std::io::Cursor;
|
||||
|
||||
use crate::common::{FigureNode, FormatWriter};
|
||||
use crate::common::{CenterNode, FigureNode, FormatWriter};
|
||||
use crate::Result;
|
||||
|
||||
use super::image_processor::DocxImageProcessor;
|
||||
use super::numbering::DocxNumbering;
|
||||
use super::styles::DocxStyles;
|
||||
|
||||
/// DOCX writer that generates DOCX directly from AST (without intermediate representation)
|
||||
/// DOCX writer that generates DOCX directly from AST (without intermediate
|
||||
/// representation)
|
||||
pub struct DocxWriter {
|
||||
styles: DocxStyles,
|
||||
numbering: DocxNumbering,
|
||||
|
@ -416,8 +417,30 @@ impl DocxWriter {
|
|||
}
|
||||
Node::Custom(custom_node) => {
|
||||
if let Some(figure_node) = custom_node.as_any().downcast_ref::<FigureNode>() {
|
||||
// Process figure node with special handling
|
||||
docx = self.process_figure(docx, figure_node)?;
|
||||
} else if let Some(center_node) = custom_node.as_any().downcast_ref::<CenterNode>()
|
||||
{
|
||||
// Handle regular node but with center alignment
|
||||
match ¢er_node.node {
|
||||
Node::Paragraph(content) => {
|
||||
docx = self.process_paragraph(docx, content, None)?;
|
||||
// Get the last paragraph and center it
|
||||
if let Some(DocumentChild::Paragraph(para)) =
|
||||
docx.document.children.last_mut()
|
||||
{
|
||||
para.property = para.property.clone().align(AlignmentType::Center);
|
||||
}
|
||||
}
|
||||
other => {
|
||||
docx = self.process_node(docx, other)?;
|
||||
// Get the last element and center it if it's a paragraph
|
||||
if let Some(DocumentChild::Paragraph(para)) =
|
||||
docx.document.children.last_mut()
|
||||
{
|
||||
para.property = para.property.clone().align(AlignmentType::Center);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(external_frame) = custom_node
|
||||
.as_any()
|
||||
.downcast_ref::<crate::common::ExternalFrameNode>(
|
||||
|
|
|
@ -6,7 +6,9 @@ use cmark_writer::ast::Node;
|
|||
use ecow::EcoString;
|
||||
use tinymist_std::path::unix_slash;
|
||||
|
||||
use crate::common::{ExternalFrameNode, FigureNode, FormatWriter, HighlightNode, ListState};
|
||||
use crate::common::{
|
||||
CenterNode, ExternalFrameNode, FigureNode, FormatWriter, HighlightNode, ListState,
|
||||
};
|
||||
use crate::Result;
|
||||
|
||||
/// LaTeX writer implementation
|
||||
|
@ -290,6 +292,11 @@ impl LaTeXWriter {
|
|||
}
|
||||
|
||||
output.push_str("\\end{figure}\n\n");
|
||||
} else if let Some(center_node) = custom_node.as_any().downcast_ref::<CenterNode>()
|
||||
{
|
||||
output.push_str("\\begin{center}\n");
|
||||
self.write_node(¢er_node.node, output)?;
|
||||
output.push_str("\\end{center}\n\n");
|
||||
} else if let Some(highlight_node) =
|
||||
custom_node.as_any().downcast_ref::<HighlightNode>()
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue