mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-22 12:34:39 +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)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[custom_node(block = false, html_impl = true)]
|
#[custom_node(block = false, html_impl = true)]
|
||||||
pub struct VerbatimNode {
|
pub struct VerbatimNode {
|
||||||
/// The content to directly output
|
/// The content to directly output inline
|
||||||
pub content: EcoString,
|
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
|
/// Alert node for alert messages
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
#[custom_node(block = true, html_impl = false)]
|
#[custom_node(block = true, html_impl = false)]
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ separately rendered SVG
|
||||||
|
|
||||||
</td><td>
|
</td><td>
|
||||||
|
|
||||||
<p>````
|
````
|
||||||
|
|
||||||
== Under the Greenwood Tree
|
== Under the Greenwood Tree
|
||||||
by Shakespeare.
|
by Shakespeare.
|
||||||
|
|
@ -74,8 +74,7 @@ Under the greenwood tree #emoji.tree
|
||||||
Who loves to lie with me,
|
Who loves to lie with me,
|
||||||
...
|
...
|
||||||
```)
|
```)
|
||||||
````</p>
|
````
|
||||||
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,4 @@ source: crates/typlite/src/tests.rs
|
||||||
expression: hash
|
expression: hash
|
||||||
input_file: crates/typlite/src/fixtures/integration/issue-1844.typ
|
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::Result;
|
||||||
use crate::TypliteFeat;
|
use crate::TypliteFeat;
|
||||||
use crate::attributes::{
|
use crate::attributes::{AlertsAttr, HeadingAttr, RawAttr, TypliteAttrsParser, VerbatimAttr};
|
||||||
AlertsAttr, HeadingAttr, RawAttr, TypliteAttrsParser, VerbatimAttr, md_attr,
|
use crate::common::{AlertNode, BlockVerbatimNode, CenterNode, VerbatimNode};
|
||||||
};
|
|
||||||
use crate::common::{AlertNode, CenterNode, VerbatimNode};
|
|
||||||
use crate::diagnostics::WarningCollector;
|
use crate::diagnostics::WarningCollector;
|
||||||
use crate::tags::md_tag;
|
use crate::tags::md_tag;
|
||||||
|
|
||||||
|
|
@ -196,9 +194,9 @@ impl HtmlToAstParser {
|
||||||
let attrs = VerbatimAttr::parse(&element.attrs)?;
|
let attrs = VerbatimAttr::parse(&element.attrs)?;
|
||||||
if attrs.block {
|
if attrs.block {
|
||||||
self.flush_inline_buffer();
|
self.flush_inline_buffer();
|
||||||
self.blocks.push(Node::Paragraph(vec![Node::Custom(Box::new(
|
self.blocks.push(Node::Custom(Box::new(BlockVerbatimNode {
|
||||||
VerbatimNode { content: attrs.src },
|
content: attrs.src,
|
||||||
))]));
|
})));
|
||||||
} else {
|
} else {
|
||||||
self.inline_buffer
|
self.inline_buffer
|
||||||
.push(Node::Custom(Box::new(VerbatimNode { content: attrs.src })));
|
.push(Node::Custom(Box::new(VerbatimNode { content: attrs.src })));
|
||||||
|
|
@ -405,12 +403,8 @@ impl HtmlToAstParser {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_verbatim_block(element: &HtmlElement) -> bool {
|
fn is_verbatim_block(element: &HtmlElement) -> bool {
|
||||||
element
|
VerbatimAttr::parse(&element.attrs)
|
||||||
.attrs
|
.map(|attrs| attrs.block)
|
||||||
.0
|
|
||||||
.iter()
|
|
||||||
.find(|(name, _)| *name == md_attr::block)
|
|
||||||
.and_then(|(_, value)| value.parse::<bool>().ok())
|
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ use base64::Engine;
|
||||||
use cmark_writer::ast::{ListItem, Node};
|
use cmark_writer::ast::{ListItem, Node};
|
||||||
use docx_rs::*;
|
use docx_rs::*;
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
use log::{debug, warn};
|
use log::debug;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::common::{
|
use crate::common::{
|
||||||
CenterNode, FigureNode, FormatWriter, HighlightNode, InlineNode, VerbatimNode,
|
BlockVerbatimNode, CenterNode, FigureNode, FormatWriter, HighlightNode, InlineNode,
|
||||||
|
VerbatimNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::image_processor::DocxImageProcessor;
|
use super::image_processor::DocxImageProcessor;
|
||||||
|
|
@ -253,10 +254,7 @@ impl DocxWriter {
|
||||||
}
|
}
|
||||||
node if node.is_custom_type::<VerbatimNode>() => {
|
node if node.is_custom_type::<VerbatimNode>() => {
|
||||||
let node = node.as_custom_type::<VerbatimNode>().unwrap();
|
let node = node.as_custom_type::<VerbatimNode>().unwrap();
|
||||||
warn!(
|
run = run.style("CodeInline").add_text(&node.content);
|
||||||
"ignoring `m1verbatim` content in DOCX export: {:?}",
|
|
||||||
node.content
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// Other inline element types
|
// Other inline element types
|
||||||
_ => {
|
_ => {
|
||||||
|
|
@ -504,6 +502,15 @@ impl DocxWriter {
|
||||||
docx = docx.add_paragraph(para);
|
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>() => {
|
node if node.is_custom_type::<InlineNode>() => {
|
||||||
let inline_node = node.as_custom_type::<InlineNode>().unwrap();
|
let inline_node = node.as_custom_type::<InlineNode>().unwrap();
|
||||||
// Handle InlineNode at block level (convert to paragraph)
|
// Handle InlineNode at block level (convert to paragraph)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use tinymist_std::path::unix_slash;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::common::{
|
use crate::common::{
|
||||||
CenterNode, ExternalFrameNode, FigureNode, FormatWriter, HighlightNode, InlineNode, ListState,
|
BlockVerbatimNode, CenterNode, ExternalFrameNode, FigureNode, FormatWriter, HighlightNode,
|
||||||
VerbatimNode,
|
InlineNode, ListState, VerbatimNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// LaTeX writer implementation
|
/// LaTeX writer implementation
|
||||||
|
|
@ -289,6 +289,11 @@ impl LaTeXWriter {
|
||||||
self.write_node(child, output)?;
|
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>() => {
|
node if node.is_custom_type::<VerbatimNode>() => {
|
||||||
let inline_node = node.as_custom_type::<VerbatimNode>().unwrap();
|
let inline_node = node.as_custom_type::<VerbatimNode>().unwrap();
|
||||||
output.push_str(&inline_node.content);
|
output.push_str(&inline_node.content);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ use cmark_writer::ast::Node;
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
use crate::common::{ExternalFrameNode, FigureNode, FormatWriter};
|
use crate::common::{BlockVerbatimNode, ExternalFrameNode, FigureNode, FormatWriter, VerbatimNode};
|
||||||
|
|
||||||
/// Text writer implementation
|
/// Text writer implementation
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -161,6 +161,12 @@ impl TextWriter {
|
||||||
output.push_str(&external_frame.alt_text);
|
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>() => {
|
node if node.is_custom_type::<crate::common::HighlightNode>() => {
|
||||||
if let Some(highlight) = node.as_custom_type::<crate::common::HighlightNode>() {
|
if let Some(highlight) = node.as_custom_type::<crate::common::HighlightNode>() {
|
||||||
for child in &highlight.content {
|
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(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue