Các trình soạn thảo WYSIWYG (What You See Is What You Get) rất trực quan và phổ biến. Tuy nhiên, chúng thường gặp phải thách thức lớn khi người dùng cần chèn các nội dung kỹ thuật phức tạp như khối mã lập trình (code blocks), biểu đồ (diagrams), hay công thức toán học (LaTeX). Việc định dạng các nội dung này thường khó khăn và dễ phát sinh lỗi.
Để giải quyết vấn đề này, một giải pháp thay thế mạnh mẽ đã ra đời: Markdown.
Markdown là gì?
Markdown là một ngôn ngữ đánh dấu siêu nhẹ (lightweight markup language) được tạo ra với mục tiêu cốt lõi là dễ đọc và dễ viết ngay cả ở dạng văn bản thô. Thay vì dùng các nút bấm phức tạp, bạn sử dụng các ký tự đơn giản như # để tạo tiêu đề, * để in nghiêng, hay ** để in đậm.
Quan trọng nhất, văn bản Markdown có thể được chuyển đổi một cách dễ dàng và chính xác sang HTML để hiển thị trên web. Điều này cho phép người dùng tập trung vào nội dung mà không cần bận tâm đến các thẻ HTML phức tạp.
Vai trò của Markdig
Nhưng làm thế nào để chuyển đổi từ văn bản Markdown sang HTML? Quá trình này cần một công cụ gọi là bộ phân tích (parser). Và khi nói đến các ứng dụng .NET/C#, Markdig chính là câu trả lời hàng đầu.
Đây là một thư viện C# cực kỳ nhanh, mạnh mẽ và có khả năng mở rộng, giúp bạn tích hợp tính năng xử lý Markdown vào ứng dụng của mình một cách hiệu quả. Nó sẽ đọc văn bản Markdown của bạn và tạo ra HTML chuẩn xác, sẵn sàng để hiển thị trên trình duyệt.
Tích hợp Prism.js
Prism.js là một thư viện JavaScript nhẹ, mạnh mẽ và có khả năng mở rộng, chuyên dùng để làm nổi bật cú pháp (syntax highlighting)
using Markdig;
namespace MarkdigSample.Services;
public class MarkdownService: IMarkdownService
{
public string ToHtml(string markdown)
{
// Build the pipeline with advanced extensions and mathematics support for LaTeX.
var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions() // For tables, figures, etc.
.UseGenericAttributes()
.Build();
return Markdown.ToHtml(markdown, pipeline);
}
}
Tạo action mới
public IActionResult Readme()
{
// 1. Construct the full path to the file.
// ContentRootPath gives you the root directory of the application.
var filePath = Path.Combine(_env.ContentRootPath, "Templates", "readme.md");
if (!System.IO.File.Exists(filePath))
{
return NotFound("The readme.md file was not found.");
}
// 2. Read all the content from the markdown file.
var markdownContent = System.IO.File.ReadAllText(filePath);
// 3. Use the service to convert the Markdown content to HTML.
var contentAsHtml = _markdownService.ToHtml(markdownContent);
// 4. Pass the HTML to a ViewModel.
var viewModel = new BlogPostViewModel
{
Title = "Readme File",
ContentAsHtml = contentAsHtml
};
// Assuming you have a View named "Display.cshtml" to show the content.
return View("Display", viewModel);
}
File Display.cshtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MarkdigSample</title>
<script type="importmap"></script>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/MarkdigSample.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">MarkdigSample</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2025 - MarkdigSample - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Hiển thị công thức Toán học
KaTeX cũng là một thư viện JavaScript mã nguồn mở để hiển thị toán học trên web, nhưng nó đặt trọng tâm đặc biệt vào hai yếu tố: tốc độ và sự dễ sử dụng.
Giả sử bạn có đoạn text sau: Chú ý 2 dấu \\File readme.md
\\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\\]
Công thức sẽ hiển thị
\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
Bootstrap
Bạn có thể dùng extension .UseBootstrap() của Markdig để nó tự động thêm các lớp (classes) CSS của Bootstrap vào HTML được tạo ra. Việc này giúp các thành phần như bảng, trích dẫn, v.v. hiển thị theo phong cách của Bootstrap một cách dễ dàng.public string ToHtml(string markdown)
{
// Build the pipeline with advanced extensions and mathematics support for LaTeX.
var pipeline = new MarkdownPipelineBuilder()
.UseAdvancedExtensions()
.UseBootstrap()
.UseGenericAttributes()
.Build();
return Markdown.ToHtml(markdown, pipeline);
}
Bạn sửa lại code Markdown
### Sơ lược Lịch sử Trung Quốc
Lịch sử Trung Quốc là một trong những nền văn minh lâu đời và liên tục nhất thế giới, kéo dài hàng ngàn năm với các triều đại hưng thịnh và suy tàn, để lại một di sản văn hóa và khoa học kỹ thuật đồ sộ.
Dưới đây là bảng tóm tắt một vài triều đại quan trọng:
| Triều đại | Giai đoạn (ước tính) | Thành tựu nổi bật |
|-----------|----------------------|-------------------|
| Nhà Hạ | ~2070–1600 TCN | Triều đại đầu tiên trong lịch sử, Đại Vũ trị thủy |
| Nhà Thương | ~1600–1046 TCN | Chữ viết trên xương (Giáp cốt văn), đồ đồng phát triển |
| Nhà Châu | ~1046–256 TCN | Khái niệm Thiên mệnh, Nho giáo và Đạo giáo ra đời |
| Nhà Tần | 221–206 TCN | Thống nhất Trung Quốc, xây Vạn Lý Trường Thành |
| Nhà Hán | 206 TCN – 220 SCN | Mở ra Con đường tơ lụa, phát minh giấy viết |
| Nhà Đường | 618–907 | Thời kỳ hoàng kim của thơ ca và nghệ thuật |
| Nhà Minh | 1368–1644 | Xây dựng Tử Cấm Thành, các chuyến hải hành của Trịnh Hòa |
| Nhà Thanh | 1644–1912 | Triều đại phong kiến cuối cùng của Trung Quốc |Bạn có thể tham khảo thêm các link sau để tùy biến HTML:
Enhancing UI/UX in LLM Responses with Markdown Formatting Using Markdig and Bootstrap in C#
How to Write a .NET Markdig Extension for Markdown Processing
Nhận xét
Đăng nhận xét