Skip to content

Khối mã fenced

Khối mã fenced là tính năng quan trọng của cú pháp mở rộng Markdown, cung cấp khả năng hiển thị mã mạnh mẽ hơn so với khối mã cơ bản, hỗ trợ các tính năng nâng cao như tô sáng cú pháp, số dòng, tên tệp.

Khối mã fenced cơ bản

Ba backtick

Sử dụng ba backtick ``` để tạo khối mã:

markdown
```
function hello() {
    console.log("Hello, World!");
}
```

Hiệu ứng hiển thị:

function hello() {
    console.log("Hello, World!");
}

Ba dấu ngã

Cũng có thể dùng ba dấu ngã ~~~ để tạo khối mã:

markdown
~~~
function hello() {
    console.log("Hello, World!");
}
~~~

Hiệu ứng hiển thị:

function hello() {
    console.log("Hello, World!");
}

Tô sáng cú pháp

Chỉ định ngôn ngữ lập trình

Chỉ định tên ngôn ngữ sau nhãn mở để bật tô sáng cú pháp:

markdown
```javascript
function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(10)); // 55
```

Hiệu ứng hiển thị:

javascript
function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(10)); // 55

Ví dụ ngôn ngữ phổ biến

Python

markdown
```python
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    
    return quicksort(left) + middle + quicksort(right)

# Ví dụ sử dụng
numbers = [3, 6, 8, 10, 1, 2, 1]
print(quicksort(numbers))
```

Hiệu ứng hiển thị:

python
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    
    return quicksort(left) + middle + quicksort(right)

# Ví dụ sử dụng
numbers = [3, 6, 8, 10, 1, 2, 1]
print(quicksort(numbers))

TypeScript

markdown
```typescript
interface User {
    id: number;
    name: string;
    email: string;
    isActive: boolean;
}

class UserService {
    private users: User[] = [];

    async createUser(userData: Omit<User, 'id'>): Promise<User> {
        const newUser: User = {
            id: Date.now(),
            ...userData
        };
        
        this.users.push(newUser);
        return newUser;
    }

    async getUserById(id: number): Promise<User | undefined> {
        return this.users.find(user => user.id === id);
    }
}
```

Hiệu ứng hiển thị:

typescript
interface User {
    id: number;
    name: string;
    email: string;
    isActive: boolean;
}

class UserService {
    private users: User[] = [];

    async createUser(userData: Omit<User, 'id'>): Promise<User> {
        const newUser: User = {
            id: Date.now(),
            ...userData
        };
        
        this.users.push(newUser);
        return newUser;
    }

    async getUserById(id: number): Promise<User | undefined> {
        return this.users.find(user => user.id === id);
    }
}

Go

markdown
```go
package main

import (
    "fmt"
    "net/http"
    "log"
)

type Server struct {
    port string
}

func NewServer(port string) *Server {
    return &Server{port: port}
}

func (s *Server) Start() error {
    http.HandleFunc("/", s.handleHome)
    http.HandleFunc("/api/health", s.handleHealth)
    
    fmt.Printf("Server starting on port %s\n", s.port)
    return http.ListenAndServe(":"+s.port, nil)
}

func (s *Server) handleHome(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to Go Server!")
}

func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    fmt.Fprintf(w, `{"status": "healthy"}`)
}

func main() {
    server := NewServer("8080")
    log.Fatal(server.Start())
}
```

Hiệu ứng hiển thị:

go
package main

import (
    "fmt"
    "net/http"
    "log"
)

type Server struct {
    port string
}

func NewServer(port string) *Server {
    return &Server{port: port}
}

func (s *Server) Start() error {
    http.HandleFunc("/", s.handleHome)
    http.HandleFunc("/api/health", s.handleHealth)
    
    fmt.Printf("Server starting on port %s\n", s.port)
    return http.ListenAndServe(":"+s.port, nil)
}

func (s *Server) handleHome(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Welcome to Go Server!")
}

func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    fmt.Fprintf(w, `{"status": "healthy"}`)
}

func main() {
    server := NewServer("8080")
    log.Fatal(server.Start())
}

Tính năng nâng cao

Tô sáng dòng

Một số bộ xử lý Markdown hỗ trợ tô sáng các dòng cụ thể:

markdown
```javascript {2,4-6}
function calculateTotal(items) {
    let total = 0; // Dòng này được tô sáng
    
    for (const item of items) { // Những dòng này được tô sáng
        total += item.price * item.quantity;
    } // Kết thúc tô sáng
    
    return total;
}
```

Hiển thị số dòng

Hiển thị số thứ tự dòng mã:

markdown
```python:line-numbers
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    
    return -1
```

Tiêu đề tên tệp

Hiển thị tên tệp mã nguồn:

markdown
```typescript title="userService.ts"
export class UserService {
    private apiUrl = '/api/users';

    async getUsers(): Promise<User[]> {
        const response = await fetch(this.apiUrl);
        return response.json();
    }

    async createUser(user: CreateUserDto): Promise<User> {
        const response = await fetch(this.apiUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(user)
        });
        return response.json();
    }
}
```

Hiển thị khác biệt khối mã

Hiển thị thay đổi mã:

markdown
```diff
function calculateTax(amount) {
-   return amount * 0.05; // Thuế suất cũ
+   return amount * 0.08; // Thuế suất mới
}

+ // Hàm mới thêm
+ function calculateDiscount(amount, percentage) {
+     return amount * (percentage / 100);
+ }
```

Hiệu ứng hiển thị:

diff
function calculateTax(amount) {
-   return amount * 0.05; // Thuế suất cũ
+   return amount * 0.08; // Thuế suất mới
}

+ // Hàm mới thêm
+ function calculateDiscount(amount, percentage) {
+     return amount * (percentage / 100);
+ }

Ví dụ tệp cấu hình

Cấu hình JSON

markdown
```json
{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "build": "webpack --mode production",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.0.3",
    "jsonwebtoken": "^9.0.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.22",
    "jest": "^29.5.0",
    "webpack": "^5.82.0"
  }
}
```

Hiệu ứng hiển thị:

json
{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "build": "webpack --mode production",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.0.3",
    "jsonwebtoken": "^9.0.0"
  },
  "devDependencies": {
    "nodemon": "^2.0.22",
    "jest": "^29.5.0",
    "webpack": "^5.82.0"
  }
}

Cấu hình YAML

markdown
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web
        image: nginx:1.21
        ports:
        - containerPort: 80
        env:
        - name: NODE_ENV
          value: production
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
```

Hiệu ứng hiển thị:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: web
        image: nginx:1.21
        ports:
        - containerPort: 80
        env:
        - name: NODE_ENV
          value: production
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

Truy vấn SQL

markdown
```sql
-- Tạo bảng người dùng
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Tạo chỉ mục
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_username ON users(username);

-- Truy vấn người dùng hoạt động
SELECT 
    u.id,
    u.username,
    u.email,
    COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
WHERE u.created_at >= NOW() - INTERVAL '30 days'
GROUP BY u.id, u.username, u.email
HAVING COUNT(p.id) > 0
ORDER BY post_count DESC
LIMIT 10;
```

Hiệu ứng hiển thị:

sql
-- Tạo bảng người dùng
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Tạo chỉ mục
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_username ON users(username);

-- Truy vấn người dùng hoạt động
SELECT 
    u.id,
    u.username,
    u.email,
    COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
WHERE u.created_at >= NOW() - INTERVAL '30 days'
GROUP BY u.id, u.username, u.email
HAVING COUNT(p.id) > 0
ORDER BY post_count DESC
LIMIT 10;

Shell script và lệnh

Script Bash

markdown
```bash
#!/bin/bash

# Script triển khai
set -e

APP_NAME="my-app"
DEPLOY_DIR="/var/www/${APP_NAME}"
BACKUP_DIR="/var/backups/${APP_NAME}"
CURRENT_DATE=$(date +%Y%m%d_%H%M%S)

echo "Bắt đầu triển khai ${APP_NAME}..."

# Tạo bản sao lưu
if [ -d "$DEPLOY_DIR" ]; then
    echo "Tạo bản sao lưu vào ${BACKUP_DIR}/${CURRENT_DATE}"
    mkdir -p "$BACKUP_DIR"
    cp -r "$DEPLOY_DIR" "${BACKUP_DIR}/${CURRENT_DATE}"
fi

# Dừng dịch vụ
echo "Dừng dịch vụ..."
sudo systemctl stop $APP_NAME || true

# Triển khai phiên bản mới
echo "Triển khai phiên bản mới..."
rm -rf "$DEPLOY_DIR"
mkdir -p "$DEPLOY_DIR"
tar -xzf "${APP_NAME}.tar.gz" -C "$DEPLOY_DIR"

# Cài đặt phụ thuộc
echo "Cài đặt phụ thuộc..."
cd "$DEPLOY_DIR"
npm ci --production

# Khởi động dịch vụ
echo "Khởi động dịch vụ..."
sudo systemctl start $APP_NAME
sudo systemctl enable $APP_NAME

echo "Hoàn tất triển khai!"
```

Hiệu ứng hiển thị:

bash
#!/bin/bash

# Script triển khai
set -e

APP_NAME="my-app"
DEPLOY_DIR="/var/www/${APP_NAME}"
BACKUP_DIR="/var/backups/${APP_NAME}"
CURRENT_DATE=$(date +%Y%m%d_%H%M%S)

echo "Bắt đầu triển khai ${APP_NAME}..."

# Tạo bản sao lưu
if [ -d "$DEPLOY_DIR" ]; then
    echo "Tạo bản sao lưu vào ${BACKUP_DIR}/${CURRENT_DATE}"
    mkdir -p "$BACKUP_DIR"
    cp -r "$DEPLOY_DIR" "${BACKUP_DIR}/${CURRENT_DATE}"
fi

# Dừng dịch vụ
echo "Dừng dịch vụ..."
sudo systemctl stop $APP_NAME || true

# Triển khai phiên bản mới
echo "Triển khai phiên bản mới..."
rm -rf "$DEPLOY_DIR"
mkdir -p "$DEPLOY_DIR"
tar -xzf "${APP_NAME}.tar.gz" -C "$DEPLOY_DIR"

# Cài đặt phụ thuộc
echo "Cài đặt phụ thuộc..."
cd "$DEPLOY_DIR"
npm ci --production

# Khởi động dịch vụ
echo "Khởi động dịch vụ..."
sudo systemctl start $APP_NAME
sudo systemctl enable $APP_NAME

echo "Hoàn tất triển khai!"

Lỗi thường gặp và giải pháp

1. Số lượng backtick không khớp

markdown
❌ Sai:
```javascript
function hello() {
    console.log("Hello");
}
``  ← Chỉ có hai backtick

Đúng:
```javascript
function hello() {
    console.log("Hello");
}
```  ← Ba backtick

2. Định danh ngôn ngữ sai

markdown
❌ Sai:
```js  ← Một số trình không nhận diện
function hello() {}
```

✅ Khuyến nghị:
```javascript  ← Dùng tên đầy đủ
function hello() {}
```

3. Khối mã lồng nhau

markdown
❌ Vấn đề: Không thể hiển thị mã chứa ```

✅ Giải pháp: Dùng bốn backtick bao quanh ba backtick
````markdown
```javascript
console.log("hello");
```

### 4. Xử lý ký tự đặc biệt

````markdown
```markdown
<!-- Hiển thị cú pháp markdown trong khối mã markdown -->
\```javascript  ← Thoát backtick
code here
\```
```

Danh sách ngôn ngữ được hỗ trợ

Ngôn ngữ lập trình

Ngôn ngữĐịnh danhBí danh
JavaScriptjavascriptjs
TypeScripttypescriptts
Pythonpythonpy
Javajava
C++cppc++, cxx
C#csharpcs
Gogogolang
Rustrustrs
PHPphp
Rubyrubyrb
Swiftswift
Kotlinkotlinkt

Ngôn ngữ đánh dấu và cấu hình

Ngôn ngữĐịnh danhMục đích
HTMLhtmlĐánh dấu web
CSScssBảng kiểu
XMLxmlTrao đổi dữ liệu
JSONjsonĐịnh dạng dữ liệu
YAMLyaml, ymlTệp cấu hình
TOMLtomlTệp cấu hình
Markdownmarkdown, mdSoạn tài liệu

Ngôn ngữ dữ liệu và truy vấn

Ngôn ngữĐịnh danhMục đích
SQLsqlTruy vấn cơ sở dữ liệu
GraphQLgraphqlTruy vấn API
RrTính toán thống kê
MATLABmatlabTính toán số học

Shell và script

Ngôn ngữĐịnh danhMục đích
Bashbash, shUnix Shell
PowerShellpowershell, ps1Windows Shell
Batchbatch, batXử lý hàng loạt Windows
DockerfiledockerfileCấu hình container

Thực tiễn tốt

1. Chọn định danh ngôn ngữ phù hợp

markdown
✅ Khuyến nghị: Dùng định danh ngôn ngữ chính xác
```typescript
interface User {
    id: number;
    name: string;
}
```

❌ Không khuyến nghị: Dùng định danh sai
```javascript  ← Đây là mã TypeScript
interface User {
    id: number;
    name: string;
}
```

2. Thêm chú thích có ý nghĩa

markdown
✅ Khuyến nghị: Bao gồm chú thích giải thích
```python
def fibonacci(n):
    """Tính số Fibonacci thứ n"""
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
```

❌ Không khuyến nghị: Mã thiếu giải thích
```python
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)
```

3. Giữ mã đơn giản

markdown
✅ Khuyến nghị: Trình bày logic cốt lõi
```javascript
// Middleware xác thực người dùng
function authenticate(req, res, next) {
    const token = req.headers.authorization;
    if (!token) {
        return res.status(401).json({ error: 'No token provided' });
    }
    // Logic xác thực...
    next();
}
```

❌ Không khuyến nghị: Bao gồm quá nhiều chi tiết
```javascript
// Bỏ qua nhiều mã không liên quan...
```

4. Dùng tiêu đề tên tệp

markdown
✅ Khuyến nghị: Hiển thị tên tệp
```javascript title="middleware/auth.js"
export function authenticate(req, res, next) {
    // Logic xác thực
}
```

✅ Khuyến nghị: Hiển thị tên tệp cấราหา hình
```json title="package.json"
{
  "name": "my-app",
  "version": "1.0.0"
}
```

Kịch bản ứng dụng thực tế

1. Tài liệu API

markdown
## API đăng nhập người dùng

**Ví dụ yêu cầu:**

```bash
curl -X POST https://api.example.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123"
  }'
```

**Ví dụ phản hồi:**

```json
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "user": {
      "id": 1,
      "email": "user@example.com",
      "name": "Zhang San"
    }
  }
}
```

**Phản hồi lỗi:**

```json
{
  "success": false,
  "error": {
    "code": "INVALID_CREDENTIALS",
    "message": "Invalid email or password"
  }
}
```

2. Hướng dẫn cài đặt

markdown
## Cấu hình môi trường

### 1. Cài đặt Node.js

**macOS (dùng Homebrew):**

```bash
# Cài đặt Homebrew (nếu chưa có)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Cài đặt Node.js
brew install node

# Kiểm tra cài đặt
node --version
npm --version
```

**Ubuntu/Debian:**

```bash
# Cập nhật danh sách gói
sudo apt update

# Cài đặt Node.js và npm
sudo apt install nodejs npm

# Kiểm tra cài đặt
node --version
npm --version
```

**Windows (dùng Chocolatey):**

```powershell
# Cài đặt Chocolatey (với quyền quản trị viên)
Set-ExecutionPolicy Bypass -Scope Process -Force; 
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; 
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

# Cài đặt Node.js
choco install nodejs

# Kiểm tra cài đặt
node --version
npm --version
```

3. So sánh mã

markdown
## So sánh trước và sau khi tái cấu trúc

**Trước tái cấu trúc (callback hell):**

```javascript
function getUserData(userId, callback) {
    getUser(userId, function(err, user) {
        if (err) {
            callback(err);
            return;
        }
        
        getPosts(user.id, function(err, posts) {
            if (err) {
                callback(err);
                return;
            }
            
            getComments(posts[0].id, function(err, comments) {
                if (err) {
                    callback(err);
                    return;
                }
                
                callback(null, { user, posts, comments });
            });
        });
    });
}
```

**Sau tái cấu trúc (async/await):**

```javascript
async function getUserData(userId) {
    try {
        const user = await getUser(userId);
        const posts = await getPosts(user.id);
        const comments = await getComments(posts[0].id);
        
        return { user, posts, comments };
    } catch (error) {
        throw error;
    }
}
```

Đầu ra HTML

Khối mã fenced chuyển đổi thành HTML:

markdown
```javascript
function hello() {
    console.log("Hello");
}
```

Chuyển đổi thành:

html
<pre><code class="language-javascript">
function hello() {
    console.log("Hello");
}
</code></pre>

Cú pháp liên quan

Luyện tập

Thử tạo các khối mã sau:

  1. Một bộ sưu tập ví dụ mã với nhiều ngôn ngữ lập trình
  2. Một hướng dẫn sử dụng API đầy đủ (bao gồm yêu cầu và phản hồi)
  3. Tài liệu hướng dẫn script triển khai
  4. Script SQL thiết kế cơ sở dữ liệu

Công cụ và plugin

Thư viện tô sáng cú pháp

  • Prism.js: Tô sáng cú pháp nhẹ
  • highlight.js: Thư viện tô sáng phong phú
  • CodeMirror: Trình soạn thảo mã trực tuyến
  • Monaco Editor: Lõi trình soạn thảo VS Code

Bộ xử lý Markdown

  • markdown-it: Trình phân tích Markdown mở rộng được
  • remark: Bộ xử lý Markdown thống nhất
  • marked: Trình phân tích Markdown nhanh
  • gray-matter: Phân tích Front Matter

Plugin trình soạn thảo

  • VS Code: Markdown Preview Enhanced
  • Sublime Text: MarkdownEditing
  • Atom: markdown-preview-plus
  • Vim: vim-markdown

Được xây dựng bởi www.markdownlang.com