Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/cm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::ctype::{isalpha, isdigit, ispunct, ispunct_char, isspace, isspace_cha
use crate::nodes::{
ListDelimType, ListType, Node, NodeAlert, NodeBlockDirective, NodeCodeBlock, NodeHeading,
NodeHtmlBlock, NodeLink, NodeList, NodeMath, NodeTaskItem, NodeValue, NodeWikiLink,
TableAlignment,
TableAlignment, TableRowKind,
};
use crate::parser::options::{Options, Plugins, WikiLinksMode};
#[cfg(feature = "phoenix_heex")]
Expand Down Expand Up @@ -446,7 +446,7 @@ impl<'a, 'o, 'c, 'w> CommonMarkFormatter<'a, 'o, 'c, 'w> {
.next_sibling()
.is_none_or(|next| next.data().value.block());
let text_in_cell = node_matches!(node, NodeValue::Text(..))
&& parent_node.is_some_and(|n| node_matches!(n, NodeValue::TableCell));
&& parent_node.is_some_and(|n| node_matches!(n, NodeValue::TableCell(..)));

match node.data().value {
NodeValue::Document => (),
Expand Down Expand Up @@ -493,7 +493,7 @@ impl<'a, 'o, 'c, 'w> CommonMarkFormatter<'a, 'o, 'c, 'w> {
NodeValue::ShortCode(ref ne) => self.format_shortcode(ne, entering)?,
NodeValue::Table(..) => self.format_table(entering),
NodeValue::TableRow(..) => self.format_table_row(entering)?,
NodeValue::TableCell => self.format_table_cell(node, entering)?,
NodeValue::TableCell(..) => self.format_table_cell(node, entering)?,
NodeValue::FootnoteDefinition(ref nfd) => {
self.format_footnote_definition(&nfd.name, entering)?
}
Expand Down Expand Up @@ -1079,12 +1079,12 @@ impl<'a, 'o, 'c, 'w> CommonMarkFormatter<'a, 'o, 'c, 'w> {
write!(self, " |")?;

let row = &node.parent().unwrap().data().value;
let in_header = match *row {
NodeValue::TableRow(header) => header,
let kind = match *row {
NodeValue::TableRow(trk) => trk,
_ => panic!(),
};

if in_header && node.next_sibling().is_none() {
if kind == TableRowKind::Header && node.next_sibling().is_none() {
let table = &node.parent().unwrap().parent().unwrap().data().value;
let alignments = match table {
NodeValue::Table(nt) => &nt.alignments,
Expand Down Expand Up @@ -1273,7 +1273,7 @@ fn is_autolink(node: Node<'_>, nl: &NodeLink) -> bool {

fn table_escape(node: Node<'_>, c: char) -> bool {
match node.data().value {
NodeValue::Table(..) | NodeValue::TableRow(..) | NodeValue::TableCell => false,
NodeValue::Table(..) | NodeValue::TableRow(..) | NodeValue::TableCell(..) => false,
_ => c == '|',
}
}
Expand Down
22 changes: 11 additions & 11 deletions src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::nodes::NodeShortCode;
use crate::nodes::{
ListType, Node, NodeAlert, NodeBlockDirective, NodeCode, NodeCodeBlock, NodeFootnoteDefinition,
NodeFootnoteReference, NodeHeading, NodeHtmlBlock, NodeLink, NodeList, NodeMath, NodeTaskItem,
NodeValue, NodeWikiLink, TableAlignment,
NodeValue, NodeWikiLink, TableAlignment, TableRowKind,
};
use crate::parser::options::{AlertStyleType, Options, Plugins};
use crate::{node_matches, scanners};
Expand Down Expand Up @@ -386,8 +386,8 @@ pub fn format_node_default<T>(
NodeValue::Highlight => render_highlight(context, node, entering),
NodeValue::Insert => render_insert(context, node, entering),
NodeValue::Table(_) => render_table(context, node, entering),
NodeValue::TableCell => render_table_cell(context, node, entering),
NodeValue::TableRow(thead) => render_table_row(context, node, entering, thead),
NodeValue::TableCell(..) => render_table_cell(context, node, entering),
NodeValue::TableRow(trk) => render_table_row(context, node, entering, trk),
NodeValue::TaskItem(ref nti) => render_task_item(context, node, entering, nti),

// Extensions
Expand Down Expand Up @@ -1146,8 +1146,8 @@ fn render_table_cell<T>(
panic!("rendered a table cell without a containing table row");
};
let row = &row_node.data().value;
let in_header = match *row {
NodeValue::TableRow(header) => header,
let kind = match *row {
NodeValue::TableRow(trk) => trk,
_ => panic!("rendered a table cell contained by something other than a table row"),
};

Expand All @@ -1164,7 +1164,7 @@ fn render_table_cell<T>(

if entering {
context.cr()?;
if in_header {
if kind == TableRowKind::Header {
context.write_str("<th")?;
render_sourcepos(context, node)?;
} else {
Expand Down Expand Up @@ -1193,7 +1193,7 @@ fn render_table_cell<T>(
}

context.write_str(">")?;
} else if in_header {
} else if kind == TableRowKind::Header {
context.write_str("</th>")?;
} else {
context.write_str("</td>")?;
Expand All @@ -1206,15 +1206,15 @@ fn render_table_row<T>(
context: &mut Context<T>,
node: Node<'_>,
entering: bool,
thead: bool,
kind: TableRowKind,
) -> Result<ChildRendering, fmt::Error> {
if entering {
context.cr()?;
if thead {
if kind == TableRowKind::Header {
context.write_str("<thead>")?;
context.lf()?;
} else if let Some(n) = node.previous_sibling() {
if let NodeValue::TableRow(true) = n.data().value {
if let NodeValue::TableRow(TableRowKind::Header) = n.data().value {
context.write_str("<tbody>")?;
context.lf()?;
}
Expand All @@ -1225,7 +1225,7 @@ fn render_table_row<T>(
} else {
context.cr()?;
context.write_str("</tr>")?;
if thead {
if kind == TableRowKind::Header {
context.cr()?;
context.write_str("</thead>")?;
}
Expand Down
103 changes: 73 additions & 30 deletions src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ pub enum NodeValue {

/// **Block**. A table row. The `bool` represents whether the row is the header row or not.
/// Contains table cells.
TableRow(bool),
TableRow(TableRowKind),

/// **Block**. A table cell. Contains **inlines**.
TableCell,
TableCell(NodeTableCell),

/// **Inline**. [Textual content](https://github.github.com/gfm/#textual-content). All text
/// in a document will be contained in a `Text` node.
Expand Down Expand Up @@ -297,6 +297,9 @@ impl TableAlignment {
/// The metadata of a table
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct NodeTable {
/// XXX
pub kind: TableKind,

/// The table alignments
pub alignments: Vec<TableAlignment>,

Expand All @@ -310,6 +313,44 @@ pub struct NodeTable {
pub num_nonempty_cells: usize,
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Copy)]
/// XXX
pub enum TableKind {
#[default]
/// XXX
Pipe,

/// XXX
Grid,
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Copy)]
/// XXX
pub enum TableRowKind {
/// XXX
Header,

#[default]
/// XXX
Body,

/// XXX
Footer,
}

#[derive(Debug, Default, Clone, PartialEq, Eq, Copy)]
/// XXX
pub struct NodeTableCell {
/// XXX
pub colspan: usize,

/// XXX
pub rowspan: usize,

/// XXX
pub grid_column: usize,
}

/// A task list item's contents, and where it was found
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub struct NodeTaskItem {
Expand Down Expand Up @@ -677,7 +718,7 @@ impl NodeValue {
| NodeValue::ThematicBreak
| NodeValue::Table(..)
| NodeValue::TableRow(..)
| NodeValue::TableCell
| NodeValue::TableCell(..)
| NodeValue::TaskItem(..)
| NodeValue::MultilineBlockQuote(_)
| NodeValue::Alert(_)
Expand All @@ -695,7 +736,7 @@ impl NodeValue {
*self,
NodeValue::Paragraph
| NodeValue::Heading(..)
| NodeValue::TableCell
| NodeValue::TableCell(..)
| NodeValue::Subtext
)
}
Expand Down Expand Up @@ -743,7 +784,7 @@ impl NodeValue {
NodeValue::ThematicBreak => "thematic_break",
NodeValue::Table(..) => "table",
NodeValue::TableRow(..) => "table_row",
NodeValue::TableCell => "table_cell",
NodeValue::TableCell(..) => "table_cell",
NodeValue::Text(..) => "text",
NodeValue::SoftBreak => "softbreak",
NodeValue::LineBreak => "linebreak",
Expand Down Expand Up @@ -1078,8 +1119,8 @@ impl<'a> arena_tree::Node<'a, RefCell<Ast>> {
| NodeValue::EscapedTag(_)
=> !child.block(),
NodeValue::Table(..) => matches!(*child, NodeValue::TableRow(..)),
NodeValue::TableRow(..) => matches!(*child, NodeValue::TableCell),
NodeValue::TableCell => {
NodeValue::TableRow(..) => matches!(*child, NodeValue::TableCell(..)),
NodeValue::TableCell(..) => {
#[cfg(feature = "shortcodes")]
if matches!(*child, NodeValue::ShortCode(..)) {
return true;
Expand All @@ -1090,29 +1131,31 @@ impl<'a> arena_tree::Node<'a, RefCell<Ast>> {
return true;
}

matches!(
*child,
NodeValue::Text(..)
| NodeValue::Code(..)
| NodeValue::Emph
| NodeValue::Strong
| NodeValue::Link(..)
| NodeValue::Image(..)
| NodeValue::Strikethrough
| NodeValue::Highlight
| NodeValue::Insert
| NodeValue::HtmlInline(..)
| NodeValue::Math(..)
| NodeValue::WikiLink(..)
| NodeValue::FootnoteReference(..)
| NodeValue::Superscript
| NodeValue::SpoileredText
| NodeValue::Underline
| NodeValue::Subscript
| NodeValue::TaskItem(_)
| NodeValue::Escaped
| NodeValue::EscapedTag(_)
)
// XXX: only true for grid table cells? :thonk:
child.block() ||
matches!(
*child,
NodeValue::Text(..)
| NodeValue::Code(..)
| NodeValue::Emph
| NodeValue::Strong
| NodeValue::Link(..)
| NodeValue::Image(..)
| NodeValue::Strikethrough
| NodeValue::Highlight
| NodeValue::Insert
| NodeValue::HtmlInline(..)
| NodeValue::Math(..)
| NodeValue::WikiLink(..)
| NodeValue::FootnoteReference(..)
| NodeValue::Superscript
| NodeValue::SpoileredText
| NodeValue::Underline
| NodeValue::Subscript
| NodeValue::TaskItem(_)
| NodeValue::Escaped
| NodeValue::EscapedTag(_)
)
}
NodeValue::MultilineBlockQuote(_) => {
child.block() && !matches!(*child, NodeValue::Item(..) | NodeValue::TaskItem(..))
Expand Down
4 changes: 2 additions & 2 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ where
}
NodeValue::Heading(..)
| NodeValue::TableRow(..)
| NodeValue::TableCell
| NodeValue::TableCell(..)
| NodeValue::Subtext => {
break;
}
Expand Down Expand Up @@ -2614,7 +2614,7 @@ where

let parent = node.parent().unwrap();

if node_matches!(parent, NodeValue::TableCell) {
if node_matches!(parent, NodeValue::TableCell(..)) {
if !self.options.parse.tasklist_in_table {
return;
}
Expand Down
36 changes: 30 additions & 6 deletions src/parser/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::borrow::Cow;
use std::cmp::min;
use std::mem;

use crate::nodes::{Ast, LineColumn, Node, NodeTable, NodeValue, TableAlignment};
use crate::nodes::{
Ast, LineColumn, Node, NodeTable, NodeTableCell, NodeValue, TableAlignment, TableKind,
TableRowKind,
};
use crate::parser::Parser;
use crate::scanners;
use crate::strings::{count_newlines, is_line_end_char, newlines_of, trim_cow};
Expand Down Expand Up @@ -90,6 +93,7 @@ fn try_opening_header<'a>(
let start = container.data().sourcepos.start;
let child = Ast::new(
NodeValue::Table(Box::new(NodeTable {
kind: TableKind::Pipe,
alignments,
num_columns: header_row.cells.len(),
num_rows: 0,
Expand All @@ -100,7 +104,11 @@ fn try_opening_header<'a>(
let table = parser.arena.alloc(child.into());
container.append(table);

let header = parser.add_child(table, NodeValue::TableRow(true), start.column);
let header = parser.add_child(
table,
NodeValue::TableRow(TableRowKind::Header),
start.column,
);
{
let header_ast = &mut header.data_mut();
header_ast.sourcepos.start.line = start.line;
Expand All @@ -118,7 +126,11 @@ fn try_opening_header<'a>(
let cell = &mut header_row.cells[i];
let ast_cell = parser.add_child(
header,
NodeValue::TableCell,
NodeValue::TableCell(NodeTableCell {
colspan: 1,
rowspan: 1,
grid_column: i,
}),
start.column + cell.start_offset - header_row.paragraph_offset,
);
let ast = &mut ast_cell.data_mut();
Expand Down Expand Up @@ -164,7 +176,7 @@ fn try_opening_row<'a>(

let new_row = parser.add_child(
container,
NodeValue::TableRow(false),
NodeValue::TableRow(TableRowKind::Body),
sourcepos.start.column,
);
new_row.data_mut().sourcepos.end.column = parser.curline_end_col;
Expand All @@ -176,7 +188,11 @@ fn try_opening_row<'a>(
let cell = &mut this_row.cells[i];
let cell_node = parser.add_child(
new_row,
NodeValue::TableCell,
NodeValue::TableCell(NodeTableCell {
colspan: 1,
rowspan: 1,
grid_column: i,
}),
sourcepos.start.column + cell.start_offset,
);
let cell_ast = &mut cell_node.data_mut();
Expand All @@ -192,7 +208,15 @@ fn try_opening_row<'a>(
}

while i < alignments.len() {
let cell_node = parser.add_child(new_row, NodeValue::TableCell, last_column + 1);
let cell_node = parser.add_child(
new_row,
NodeValue::TableCell(NodeTableCell {
colspan: 1,
rowspan: 1,
grid_column: i,
}),
last_column + 1,
);
// for autocompleted (empty) cells, set end column equal to start
let cell_ast = &mut cell_node.data_mut();
cell_ast.sourcepos.end.column = last_column + 1;
Expand Down
Loading
Loading