Chuyển đến nội dung chính

Markdown: Sử dụng Markdig

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

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.