mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-20 11:55:34 +00:00
feat: add BlockVerbatimNode for block-level raw text output and update related handling in parser and writers
This commit is contained in:
parent
32f1543343
commit
4a0edcbda3
7 changed files with 63 additions and 28 deletions
|
|
@ -208,11 +208,11 @@ impl InlineNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Verbatim node for raw text output
|
||||
/// Inline verbatim node for raw text output
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[custom_node(block = false, html_impl = true)]
|
||||
pub struct VerbatimNode {
|
||||
/// The content to directly output
|
||||
/// The content to directly output inline
|
||||
pub content: EcoString,
|
||||
}
|
||||
|
||||
|
|
@ -226,6 +226,25 @@ impl VerbatimNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Block verbatim node for raw text output without paragraph wrapping
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[custom_node(block = true, html_impl = true)]
|
||||
pub struct BlockVerbatimNode {
|
||||
/// The content to directly output as a block
|
||||
pub content: EcoString,
|
||||
}
|
||||
|
||||
impl BlockVerbatimNode {
|
||||
fn write_custom(&self, writer: &mut BlockWriterProxy) -> WriteResult<()> {
|
||||
writer.write_str(&self.content)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_html_custom(&self, writer: &mut HtmlWriter) -> HtmlWriteResult<()> {
|
||||
writer.write_trusted_html(&self.content)
|
||||
}
|
||||
}
|
||||
|
||||
/// Alert node for alert messages
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[custom_node(block = true, html_impl = false)]
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ separately rendered SVG
|
|||
|
||||
</td><td>
|
||||
|
||||
<p>````
|
||||
````
|
||||
|
||||
== Under the Greenwood Tree
|
||||
by Shakespeare.
|
||||
|
|
@ -74,8 +74,7 @@ Under the greenwood tree #emoji.tree
|
|||
Who loves to lie with me,
|
||||
...
|
||||
```)
|
||||
````</p>
|
||||
|
||||
````
|
||||
|
||||
</td>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
|||
expression: hash
|
||||
input_file: crates/typlite/src/fixtures/integration/issue-1844.typ
|
||||
---
|
||||
siphash128_13:5680ee2c48f93da5b40c162e391ef15
|
||||
siphash128_13:b700ae0ff0daf675a40354416190674e
|
||||
|
|
|
|||
|
|
@ -14,10 +14,8 @@ use typst_html::{HtmlElement, HtmlNode, tag};
|
|||
|
||||
use crate::Result;
|
||||
use crate::TypliteFeat;
|
||||
use crate::attributes::{
|
||||
AlertsAttr, HeadingAttr, RawAttr, TypliteAttrsParser, VerbatimAttr, md_attr,
|
||||
};
|
||||
use crate::common::{AlertNode, CenterNode, VerbatimNode};
|
||||
use crate::attributes::{AlertsAttr, HeadingAttr, RawAttr, TypliteAttrsParser, VerbatimAttr};
|
||||
use crate::common::{AlertNode, BlockVerbatimNode, CenterNode, VerbatimNode};
|
||||
use crate::diagnostics::WarningCollector;
|
||||
use crate::tags::md_tag;
|
||||
|
||||
|
|
@ -196,9 +194,9 @@ impl HtmlToAstParser {
|
|||
let attrs = VerbatimAttr::parse(&element.attrs)?;
|
||||
if attrs.block {
|
||||
self.flush_inline_buffer();
|
||||
self.blocks.push(Node::Paragraph(vec![Node::Custom(Box::new(
|
||||
VerbatimNode { content: attrs.src },
|
||||
))]));
|
||||
self.blocks.push(Node::Custom(Box::new(BlockVerbatimNode {
|
||||
content: attrs.src,
|
||||
})));
|
||||
} else {
|
||||
self.inline_buffer
|
||||
.push(Node::Custom(Box::new(VerbatimNode { content: attrs.src })));
|
||||
|
|
@ -405,12 +403,8 @@ impl HtmlToAstParser {
|
|||
}
|
||||
|
||||
fn is_verbatim_block(element: &HtmlElement) -> bool {
|
||||
element
|
||||
.attrs
|
||||
.0
|
||||
.iter()
|
||||
.find(|(name, _)| *name == md_attr::block)
|
||||
.and_then(|(_, value)| value.parse::<bool>().ok())
|
||||
VerbatimAttr::parse(&element.attrs)
|
||||
.map(|attrs| attrs.block)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ use base64::Engine;
|
|||
use cmark_writer::ast::{ListItem, Node};
|
||||
use docx_rs::*;
|
||||
use ecow::EcoString;
|
||||
use log::{debug, warn};
|
||||
use log::debug;
|
||||
use std::fs;
|
||||
use std::io::Cursor;
|
||||
|
||||
use crate::Result;
|
||||
use crate::common::{
|
||||
CenterNode, FigureNode, FormatWriter, HighlightNode, InlineNode, VerbatimNode,
|
||||
BlockVerbatimNode, CenterNode, FigureNode, FormatWriter, HighlightNode, InlineNode,
|
||||
VerbatimNode,
|
||||
};
|
||||
|
||||
use super::image_processor::DocxImageProcessor;
|
||||
|
|
@ -253,10 +254,7 @@ impl DocxWriter {
|
|||
}
|
||||
node if node.is_custom_type::<VerbatimNode>() => {
|
||||
let node = node.as_custom_type::<VerbatimNode>().unwrap();
|
||||
warn!(
|
||||
"ignoring `m1verbatim` content in DOCX export: {:?}",
|
||||
node.content
|
||||
);
|
||||
run = run.style("CodeInline").add_text(&node.content);
|
||||
}
|
||||
// Other inline element types
|
||||
_ => {
|
||||
|
|
@ -504,6 +502,15 @@ impl DocxWriter {
|
|||
docx = docx.add_paragraph(para);
|
||||
}
|
||||
}
|
||||
node if node.is_custom_type::<BlockVerbatimNode>() => {
|
||||
let block_node = node.as_custom_type::<BlockVerbatimNode>().unwrap();
|
||||
for line in block_node.content.split('\n') {
|
||||
let para = Paragraph::new()
|
||||
.style("CodeBlock")
|
||||
.add_run(Run::new().add_text(line));
|
||||
docx = docx.add_paragraph(para);
|
||||
}
|
||||
}
|
||||
node if node.is_custom_type::<InlineNode>() => {
|
||||
let inline_node = node.as_custom_type::<InlineNode>().unwrap();
|
||||
// Handle InlineNode at block level (convert to paragraph)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ use tinymist_std::path::unix_slash;
|
|||
|
||||
use crate::Result;
|
||||
use crate::common::{
|
||||
CenterNode, ExternalFrameNode, FigureNode, FormatWriter, HighlightNode, InlineNode, ListState,
|
||||
VerbatimNode,
|
||||
BlockVerbatimNode, CenterNode, ExternalFrameNode, FigureNode, FormatWriter, HighlightNode,
|
||||
InlineNode, ListState, VerbatimNode,
|
||||
};
|
||||
|
||||
/// LaTeX writer implementation
|
||||
|
|
@ -289,6 +289,11 @@ impl LaTeXWriter {
|
|||
self.write_node(child, output)?;
|
||||
}
|
||||
}
|
||||
node if node.is_custom_type::<BlockVerbatimNode>() => {
|
||||
let block_node = node.as_custom_type::<BlockVerbatimNode>().unwrap();
|
||||
output.push_str(&block_node.content);
|
||||
output.push_str("\n\n");
|
||||
}
|
||||
node if node.is_custom_type::<VerbatimNode>() => {
|
||||
let inline_node = node.as_custom_type::<VerbatimNode>().unwrap();
|
||||
output.push_str(&inline_node.content);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use cmark_writer::ast::Node;
|
|||
use ecow::EcoString;
|
||||
|
||||
use crate::Result;
|
||||
use crate::common::{ExternalFrameNode, FigureNode, FormatWriter};
|
||||
use crate::common::{BlockVerbatimNode, ExternalFrameNode, FigureNode, FormatWriter, VerbatimNode};
|
||||
|
||||
/// Text writer implementation
|
||||
#[derive(Default)]
|
||||
|
|
@ -161,6 +161,12 @@ impl TextWriter {
|
|||
output.push_str(&external_frame.alt_text);
|
||||
}
|
||||
}
|
||||
node if node.is_custom_type::<BlockVerbatimNode>() => {
|
||||
if let Some(block_node) = node.as_custom_type::<BlockVerbatimNode>() {
|
||||
output.push_str(&block_node.content);
|
||||
output.push_str("\n\n");
|
||||
}
|
||||
}
|
||||
node if node.is_custom_type::<crate::common::HighlightNode>() => {
|
||||
if let Some(highlight) = node.as_custom_type::<crate::common::HighlightNode>() {
|
||||
for child in &highlight.content {
|
||||
|
|
@ -168,6 +174,11 @@ impl TextWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
node if node.is_custom_type::<VerbatimNode>() => {
|
||||
if let Some(inline_node) = node.as_custom_type::<VerbatimNode>() {
|
||||
output.push_str(&inline_node.content);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue