From 9fd3a55182a030a79780c6dafad19e42dfce41f7 Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Thu, 1 Jan 2026 02:43:07 -0700 Subject: [PATCH] Updated auto-doc formatting for markdown files --- csharp_mod/TmpFormatter.cs | 62 ++++++++++++------- .../libs/helpers/src/helper_funcs.rs | 36 +++++++++++ rust_compiler/libs/helpers/src/lib.rs | 1 + rust_compiler/libs/helpers/src/macros.rs | 18 +++--- 4 files changed, 84 insertions(+), 33 deletions(-) diff --git a/csharp_mod/TmpFormatter.cs b/csharp_mod/TmpFormatter.cs index 5dd8611..e4d5950 100644 --- a/csharp_mod/TmpFormatter.cs +++ b/csharp_mod/TmpFormatter.cs @@ -1,59 +1,73 @@ +using System; using System.Text.RegularExpressions; namespace Slang; public static class TextMeshProFormatter { - private const string CODE_COLOR = "#FFD700"; + private const string CODE_COLOR = "#FFD700"; // Gold + private const string LINK_COLOR = "#0099FF"; // Blue + private const string QUOTE_COLOR = "#90EE90"; // Light Green public static string FromMarkdown(string markdown) { if (string.IsNullOrEmpty(markdown)) return ""; - // 1. Normalize Line Endings + // Normalize Line Endings string text = markdown.Replace("\r\n", "\n"); - // 2. Handle Code Blocks (```) + // Process code blocks FIRST (``` ... ```) text = Regex.Replace( text, - @"```\s*(.*?)\s*```", + @"```[^\n]*\n(.*?)\n```", match => { var codeContent = match.Groups[1].Value; - return $"{codeContent}"; // Gold color for code + return $"{codeContent}"; }, RegexOptions.Singleline ); + // Process headers - check for 1-6 hashes + text = Regex.Replace(text, @"^#{1}\s+(.+)$", "$1", RegexOptions.Multiline); + text = Regex.Replace(text, @"^#{2}\s+(.+)$", "$1", RegexOptions.Multiline); + text = Regex.Replace(text, @"^#{3}\s+(.+)$", "$1", RegexOptions.Multiline); + text = Regex.Replace(text, @"^#{4}\s+(.+)$", "$1", RegexOptions.Multiline); + text = Regex.Replace(text, @"^#{5}\s+(.+)$", "$1", RegexOptions.Multiline); + text = Regex.Replace(text, @"^#{6}\s+(.+)$", "$1", RegexOptions.Multiline); + + // Process markdown links [text](url) text = Regex.Replace( text, - @"^\s*##\s+(.+)$", - "$1", - RegexOptions.Multiline + @"\[([^\]]+)\]\(([^\)]+)\)", + $"$1" ); - // 3. Handle # Headers SECOND (General) - text = Regex.Replace( - text, - @"^\s*#\s+(.+)$", - "$1", - RegexOptions.Multiline - ); - - // 4. Handle Inline Code (`code`) + // Process inline code (`code`) text = Regex.Replace(text, @"`([^`]+)`", $"$1"); - // 5. Handle Bold (**text**) + // Process bold (**text**) text = Regex.Replace(text, @"\*\*(.+?)\*\*", "$1"); - // 6. Handle Italics (*text*) - text = Regex.Replace(text, @"\*(.+?)\*", "$1"); + // Process italics (*text*) + text = Regex.Replace(text, @"(?$1"); - // 7. Convert Newlines to TMP Line Breaks - // Stationpedia needs
or explicit newlines. - // Often just ensuring \n is preserved is enough, but
is safer for HTML-like parsers. - text = text.Replace("\n", "
"); + // Process block quotes (> text) + text = Regex.Replace( + text, + @"^>\s+(.+)$", + $"$1", + RegexOptions.Multiline + ); + + // Process unordered lists (- items) + text = Regex.Replace( + text, + @"^-\s+(.+)$", + " • $1", + RegexOptions.Multiline + ); return text; } diff --git a/rust_compiler/libs/helpers/src/helper_funcs.rs b/rust_compiler/libs/helpers/src/helper_funcs.rs index 3e68894..e0049ec 100644 --- a/rust_compiler/libs/helpers/src/helper_funcs.rs +++ b/rust_compiler/libs/helpers/src/helper_funcs.rs @@ -1,4 +1,5 @@ use crc32fast::hash as crc32_hash; + /// This function takes an input which is meant to be hashed via the CRC32 algorithm, but it then /// converts the generated UNSIGNED number into it's SIGNED counterpart. pub fn crc_hash_signed(input: &str) -> i128 { @@ -9,3 +10,38 @@ pub fn crc_hash_signed(input: &str) -> i128 { hash_value_i32 as i128 } + +/// Removes common leading whitespace from all lines in a string (dedent). +/// This is useful for cleaning up documentation strings that have uniform indentation. +pub fn dedent(text: &str) -> String { + let lines: Vec<&str> = text.lines().collect(); + + // Find minimum indentation (excluding empty lines) + let mut min_indent = usize::MAX; + for line in &lines { + if !line.trim().is_empty() { + let indent = line.len() - line.trim_start().len(); + min_indent = min_indent.min(indent); + } + } + + // If no lines or all empty, return as-is + if min_indent == usize::MAX { + return text.to_string(); + } + + // Remove the common indentation + lines + .iter() + .map(|line| { + if line.trim().is_empty() { + "" + } else if line.len() >= min_indent { + &line[min_indent..] + } else { + line + } + }) + .collect::>() + .join("\n") +} diff --git a/rust_compiler/libs/helpers/src/lib.rs b/rust_compiler/libs/helpers/src/lib.rs index aea7024..a7ef370 100644 --- a/rust_compiler/libs/helpers/src/lib.rs +++ b/rust_compiler/libs/helpers/src/lib.rs @@ -1,4 +1,5 @@ mod helper_funcs; +pub use helper_funcs::dedent; mod macros; mod syscall; diff --git a/rust_compiler/libs/helpers/src/macros.rs b/rust_compiler/libs/helpers/src/macros.rs index ca9d260..20f5f51 100644 --- a/rust_compiler/libs/helpers/src/macros.rs +++ b/rust_compiler/libs/helpers/src/macros.rs @@ -99,12 +99,12 @@ macro_rules! documented { ),* ]; - doc_lines.iter() + let combined = doc_lines.iter() .filter_map(|&d| d) .collect::>() - .join("\n") - .trim() - .to_string() + .join("\n"); + + $crate::dedent(&combined).trim().to_string() } )* } @@ -122,12 +122,13 @@ macro_rules! documented { documented!(@doc_filter #[ $($variant_attr)* ]) ),* ]; - doc_lines.iter() + + let combined = doc_lines.iter() .filter_map(|&d| d) .collect::>() - .join("\n") - .trim() - .to_string() + .join("\n"); + + $crate::dedent(&combined).trim().to_string() } ) ),* @@ -136,4 +137,3 @@ macro_rules! documented { } }; } -