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ã:
```
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ã:
~~~
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:
```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ị:
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci(10)); // 55Ví dụ ngôn ngữ phổ biến
Python
```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ị:
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
```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ị:
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
```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ị:
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ể:
```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ã:
```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:
```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ã:
```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ị:
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
```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ị:
{
"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
```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ị:
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
```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ị:
-- 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
```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ị:
#!/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
❌ Sai:
```javascript
function hello() {
console.log("Hello");
}
`` ← Chỉ có hai backtick
✅ Đúng:
```javascript
function hello() {
console.log("Hello");
}
``` ← Ba backtick2. Định danh ngôn ngữ sai
❌ 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
❌ 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 danh | Bí danh |
|---|---|---|
| JavaScript | javascript | js |
| TypeScript | typescript | ts |
| Python | python | py |
| Java | java | |
| C++ | cpp | c++, cxx |
| C# | csharp | cs |
| Go | go | golang |
| Rust | rust | rs |
| PHP | php | |
| Ruby | ruby | rb |
| Swift | swift | |
| Kotlin | kotlin | kt |
Ngôn ngữ đánh dấu và cấu hình
| Ngôn ngữ | Định danh | Mục đích |
|---|---|---|
| HTML | html | Đánh dấu web |
| CSS | css | Bảng kiểu |
| XML | xml | Trao đổi dữ liệu |
| JSON | json | Định dạng dữ liệu |
| YAML | yaml, yml | Tệp cấu hình |
| TOML | toml | Tệp cấu hình |
| Markdown | markdown, md | Soạn tài liệu |
Ngôn ngữ dữ liệu và truy vấn
| Ngôn ngữ | Định danh | Mục đích |
|---|---|---|
| SQL | sql | Truy vấn cơ sở dữ liệu |
| GraphQL | graphql | Truy vấn API |
| R | r | Tính toán thống kê |
| MATLAB | matlab | Tính toán số học |
Shell và script
| Ngôn ngữ | Định danh | Mục đích |
|---|---|---|
| Bash | bash, sh | Unix Shell |
| PowerShell | powershell, ps1 | Windows Shell |
| Batch | batch, bat | Xử lý hàng loạt Windows |
| Dockerfile | dockerfile | Cấu hình container |
Thực tiễn tốt
1. Chọn định danh ngôn ngữ phù hợp
✅ 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
✅ 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
✅ 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
✅ 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
## 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
## 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ã
## 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:
```javascript
function hello() {
console.log("Hello");
}
```Chuyển đổi thành:
<pre><code class="language-javascript">
function hello() {
console.log("Hello");
}
</code></pre>Cú pháp liên quan
- Cú pháp mã cơ bản - Mã nội dòng và khối mã cơ bản
- Cú pháp HTML - Tính năng mở rộng HTML
- Tổng quan cú pháp mở rộng - Các tính năng mở rộng khác
Luyện tập
Thử tạo các khối mã sau:
- Một bộ sưu tập ví dụ mã với nhiều ngôn ngữ lập trình
- Một hướng dẫn sử dụng API đầy đủ (bao gồm yêu cầu và phản hồi)
- Tài liệu hướng dẫn script triển khai
- 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