fix(markdown): address review of font-name consumers

- Monotype is a foundry prefix on proportional faces (Monotype Corsiva,
  Monotype Garamond); it must not satisfy is_monospace_font's generic
  "mono" token. Regression tests pin both directions.
- Flush the pending code block before inserting a positioned table or
  image, so a block that falls between two code lines cannot be emitted
  ahead of code that precedes it in reading order; a code line after
  the block reopens a new fence naturally.
This commit is contained in:
Abimael Martell
2026-08-17 16:12:48 -07:00
parent 02e2cdf5e9
commit 893c8fd44d
2 changed files with 25 additions and 0 deletions
+17
View File
@@ -233,6 +233,12 @@ pub(crate) fn line_is_monospace(line: &crate::types::TextLine) -> bool {
/// Check if font name indicates monospace
pub(crate) fn is_monospace_font(font_name: &str) -> bool {
let lower = font_name.to_lowercase();
// "Monotype" is a foundry prefix on proportional faces (Monotype
// Corsiva, Monotype Garamond) — it must not satisfy the generic "mono"
// token below.
if lower.contains("monotype") {
return false;
}
let patterns = [
"courier",
"consolas",
@@ -257,6 +263,17 @@ pub(crate) fn is_monospace_font(font_name: &str) -> bool {
mod tests {
use super::*;
#[test]
fn monotype_foundry_faces_are_not_monospace() {
// "Monotype" is a foundry prefix on proportional faces; the generic
// "mono" token must not classify them as code fonts.
assert!(!is_monospace_font("MonotypeCorsiva"));
assert!(!is_monospace_font("ABCDEF+Monotype-Garamond"));
assert!(is_monospace_font("RobotoMono-Regular"));
assert!(is_monospace_font("PTMono"));
assert!(is_monospace_font("Courier"));
}
#[test]
fn format_list_item_plain_bullet() {
assert_eq!(format_list_item("● Item"), "- Item");
+8
View File
@@ -877,6 +877,14 @@ pub(super) fn to_markdown_from_lines_with_tables_and_images(
PositionedBlockKind::Image => inserted_images.contains(&(current_page, idx)),
};
if positioned_block_precedes_line(block, line) && !already_inserted {
// Code lines buffer until their block closes; flush them
// first so this block cannot jump ahead of code that
// precedes it in reading order. A code line after the
// block reopens a new fence naturally.
if in_code_block {
flush_code_block(&mut output, &mut pending_code);
in_code_block = false;
}
if in_paragraph {
output.push_str("\n\n");
in_paragraph = false;