คู่มือการใช้งาน LynPDF RS
API-first HTML/CSS/Markdown to PDF Toolkit
Version 0.1.0 — Production Guide & Reference
ครอบคลุม API, CLI, layout engine, typography และแนวทางทดสอบ regression แบบ end-to-end
รองรับ Thai/CJK typography, color emoji, syntax highlighting, certificate templates, tables ข้ามหน้า
เผยแพร่โดย LynPDF RS Team · MIT License
บทที่ 2 — การติดตั้งและเริ่มต้นใช้งาน
บทที่ 5 — ระบบฟอนต์ (Thai, OTF, Variable)
บทที่ 6 — ตารางและ Thead Repeat
บทที่ 7 — คุณสมบัติข้อความ (Justify, Kerning, Ligatures)
บทที่ 9 — ตั้งค่าขั้นสูง (Page Size, Orientation, Margins, Metadata, PDFOptions)
บทที่ 11 — Markdown → PDF (Syntax Highlighting, Containers, Alerts)
LynPDF เป็นไลบรารี Rust สำหรับแปลง HTML/CSS เป็นไฟล์ PDF คุณภาพสูง โดยไม่ต้องพึ่งพา Headless Browser เช่น Chrome หรือ Puppeteer ทำให้มีน้ำหนักเบา ทำงานรวดเร็ว และเหมาะสำหรับใช้งานฝั่ง Server-side
ออกแบบมาเพื่อรองรับภาษาไทยเป็นพิเศษ — ตัดคำไทยอัตโนมัติ, จัดการสระลอย/วรรณยุกต์, รองรับฟอนต์ไทยมากกว่า 20 ตระกูล และรองรับอักขระบาลี/สันสกฤต
ใช้ Flex-like layout engine (จาก Meta) เป็น Flexbox layout engine และ native PDF emitter สำหรับสร้าง PDF รองรับ compression, metadata, hyperlinks
รองรับ TTF, OTF (IBM Plex Sans), Variable Fonts (Inter Variable) พร้อม kerning และ ligatures อัตโนมัติผ่าน HarfBuzz
ฟอนต์ไทย 20+ ตระกูล, ตัดคำไทยอัตโนมัติ, text-align: justify, นิคหิต/พินทุ/ทัณฑฆาต แสดงผลถูกต้อง
ตารางยาวข้ามหลายหน้าได้อัตโนมัติ, thead ซ้ำทุกหน้า, สามารถปิด thead repeat ได้ด้วย -lynpdf-repeat: none
แสดงผล SVG แบบ Vector, รองรับ Color Emoji (Twemoji), กำหนดขนาดกระดาษและการจัดวางหน้าได้ผ่าน @page { size: A4 landscape; margin: 2cm; } หรือ API
| รายการ | เวอร์ชันขั้นต่ำ | หมายเหตุ |
|---|---|---|
| Rust Toolchain | 1.76+ | แนะนำ rustup + cargo เวอร์ชันล่าสุด |
| Cargo + Rustup | stable | ใช้ build/test/run และจัดการ toolchain |
| Poppler (pdftoppm) | optional | จำเป็นเมื่อทำ visual diff จาก PDF เป็น PNG |
| พื้นที่ดิสก์ | ~200 MB | รวม target/ + output artifacts |
cargo add lynpdf-rs
หรือติดตั้งจาก source:
git clone https://github.com/lynpdf/lynpdf.git
cd lynpdf/lynpdf-rs && cargo build
use lynpdf_rs::{render_file_to_pdf, RenderOptions};
fn main() {
let options = RenderOptions::default();
render_file_to_pdf(
"examples/demo-invoice.html",
Some("examples/styles.css"),
"examples/output/demo-invoice-rust.pdf",
options,
).unwrap();
}
cargo run --bin lynpdf-rs -- input.html -o output.pdf
cargo run --bin lynpdf-rs -- input.html -c styles.css -o output.pdf
cargo run --bin lynpdf-rs -- input.html --font-dir ./fonts -o output.pdf
| ตัวเลือก | คำอธิบาย | ค่าเริ่มต้น |
|---|---|---|
| -o, --output | ชื่อไฟล์ PDF ที่จะสร้าง | output.pdf |
| -c, --css | ไฟล์ CSS ภายนอก | — |
| --font-dir | เพิ่มโฟลเดอร์ฟอนต์สำหรับค้นหาแบบอัตโนมัติ | — |
| -v, --verbose | แสดงรายละเอียดการทำงาน | false |
LynPDF ทำงานตาม Pipeline 6 ขั้นตอน:
| ไฟล์ | หน้าที่ |
|---|---|
| src/renderer.rs | API หลัก — ประสานงานทุกขั้นตอน |
| src/html.rs | แปลง HTML เป็น DOM และดึง metadata/head content |
| src/style.rs | จับคู่ CSS selector กับ DOM element |
| src/layout.rs | คำนวณ layout, pagination, table fragmentation และ paint ops |
| src/pdf.rs | แปลง paint ops เป็น PDF objects/resources จริง |
| src/text.rs | text shaping, Thai dictionary break, kerning, ligature |
| src/markdown.rs | แปลง Markdown เป็น HTML พร้อม container/alert preprocess |
LynPDF ใช้วิธี "virtual scroll" — Flex-like layout engine คำนวณ layout เป็นเอกสารเดียวยาวต่อเนื่อง จากนั้น post-layout passes จะจัดการ page-break และ renderer จะแยกเนื้อหาออกเป็นหน้าๆ:
pageIndex = Math.floor(node.ly / PAGE_HEIGHT)
localY = node.ly - pageIndex * PAGE_HEIGHT
ขนาดกระดาษ A4 = 595.28 × 841.89 points (ค่าเริ่มต้น), ระยะขอบ = 50 points ทุกด้าน (กำหนดเองได้ผ่าน @page). การใช้
@page { size: A4 landscape; } หรือ @page { size: 297mm 210mm; } จะเปลี่ยนขนาดกระดาษใน PDF
โดยอัตโนมัติ — รองรับ A0–A6, B4, B5, letter, legal, ledger, tabloid
| Property | ตัวอย่าง | สถานะ |
|---|---|---|
| width, height | width: 200px; | ✓ |
| min/max-width/height | max-width: 500px; | ✓ |
| margin | margin: 10px 20px; | ✓ |
| padding | padding: 8px 16px; | ✓ |
| border | border: 1px solid #333; | ✓ |
| border-radius | border-radius: 8px; | ✓ |
| border-collapse | border-collapse: collapse; | ✓ |
| overflow | overflow: hidden; | ✓ |
| Property | ค่าที่รองรับ |
|---|---|
| display | flex, block, inline |
| flex-direction | row, column, row-reverse, column-reverse |
| flex-wrap | nowrap, wrap, wrap-reverse |
| justify-content | flex-start, center, flex-end, space-between, space-around, space-evenly |
| align-items | flex-start, center, flex-end, stretch, baseline |
| flex-grow, flex-shrink | 0, 1, 2, ... |
| flex-basis | auto, px values |
| gap | 10px (row-gap, column-gap) |
| Property | ค่า | คำอธิบาย |
|---|---|---|
| page-break-before | always | ขึ้นหน้าใหม่ก่อน element |
| page-break-after | always | ขึ้นหน้าใหม่หลัง element |
| page-break-inside | avoid | ป้องกันไม่ให้ตัดกลาง element |
| break-before | page | เหมือน page-break-before: always |
| break-inside | avoid | เหมือน page-break-inside: avoid |
| orphans / widows | 2, 3, ... | จำนวนบรรทัดขั้นต่ำบน/ล่างหน้า |
| @page { size } | A4 landscape, A3, letter, 297mm 210mm | กำหนดขนาดและทิศทางกระดาษ |
Sarabun — สวัสดีครับ กขคงจ ฉชซฌ ญฎฏฐ (ฟอนต์เริ่มต้น)
Prompt — สวัสดีครับ กขคงจ ฉชซฌ ญฎฏฐ
Kanit — สวัสดีครับ กขคงจ ฉชซฌ ญฎฏฐ
Mitr — สวัสดีครับ กขคงจ ฉชซฌ ญฎฏฐ
Chakra Petch — สวัสดีครับ กขคงจ ฉชซฌ ญฎฏฐ
Garuda (Sans-serif) — กขคงจ ฉชซฌ ไทยสากล
Norasi (Serif) — กขคงจ ฉชซฌ ไทยสากล
Loma (Sans-serif) — กขคงจ ฉชซฌ ไทยสากล
Kinnari (Serif) — กขคงจ ฉชซฌ ไทยสากล
Laksaman (Serif) — กขคงจ ฉชซฌ ไทยสากล
Sawasdee (Sans-serif) — กขคงจ ฉชซฌ ไทยสากล
Purisa (Handwriting) — กขคงจ ฉชซฌ ไทยสากล
Waree (Sans-serif) — กขคงจ ฉชซฌ ไทยสากล
LynPDF รองรับไฟล์ OTF (.otf) โดยตรง พร้อม kerning pairs และ ligatures อัตโนมัติ:
IBM Plex Sans (OTF) — office fi fl ff ffi ffl
Kerning: AV AW AY AT VA To Te Ty We Yo PA
IBM Plex Sans Italic — The quick brown fox jumps over
Variable font คือไฟล์ฟอนต์เดียวที่รวมหลาย weight/style ไว้ด้วยกัน:
Inter Variable (Weight 400) — Hello World, fi fl ff
Inter Variable (Bold) — Hello World, fi fl ff
Inter Variable (Italic) — Hello World, fi fl ff
เมื่อฟอนต์หลักไม่มี glyph สำหรับอักขระบางตัว ระบบจะสลับไปใช้ฟอนต์สำรองอัตโนมัติ:
ตัวอย่าง: ✓ สำเร็จ ✗ ล้มเหลว ★ สำคัญ → ถัดไป ← ย้อนกลับ
LynPDF รองรับตาราง HTML มาตรฐาน (table, thead, tbody, tfoot, tr, td, th) โดยใช้ Flexbox สำหรับ layout:
| คุณสมบัติ | คำอธิบาย | สถานะ |
|---|---|---|
| border-collapse | รวมเส้นขอบเซลล์ที่อยู่ติดกัน | ✓ |
| colspan (ผ่าน flex) | รวมเซลล์ในแนวนอน | ✓ |
| thead repeat | ซ้ำหัวตารางทุกหน้าอัตโนมัติ | ✓ |
| Cross-page tables | ตารางยาวข้ามหลายหน้า | ✓ |
| -lynpdf-repeat: none | ปิดการซ้ำ thead | ✓ ใหม่! |
เมื่อตารางยาวข้ามหลายหน้า LynPDF จะ repeat หัวตาราง (thead) อัตโนมัติทุกหน้า:
| # | รายการ | คำอธิบาย | สถานะ |
|---|---|---|---|
| 1 | HTML Parsing | แปลง HTML string เป็น DOM tree ด้วย Rust HTML parser | ✓ |
| 2 | CSS Parsing | แปลง CSS string เป็น AST ด้วย Rust CSS parser | ✓ |
| 3 | Style Resolution | จับคู่ CSS selector กับ DOM element | ✓ |
| 4 | Layout Engine | คำนวณขนาดและตำแหน่งด้วย Flex-like layout engine Layout | ✓ |
| 5 | Text Measurement | วัดความกว้างข้อความด้วย fontkit + HarfBuzz | ✓ |
| 6 | Thai Word Break | ตัดคำไทยด้วย Thai dictionary segmenter | ✓ |
| 7 | PDF Rendering | วาดเนื้อหาลง native PDF emitter document | ✓ |
| 8 | SVG Rendering | แสดงผล SVG vector ด้วย native SVG paint ops | ✓ |
| 9 | Color Parser | แปลงสี hex, rgb, rgba, named ทุกรูปแบบ | ✓ |
| 10 | Emoji Support | ดาวน์โหลดและแสดง Twemoji PNG | ✓ |
ในบางกรณีอาจต้องการปิดการ repeat thead เช่น ตารางที่ header ไม่สำคัญมาก:
/* วิธีที่ 1: กำหนดที่ thead */
thead { -lynpdf-repeat: none; }
/* วิธีที่ 2: กำหนดที่ table */
table.no-repeat { -lynpdf-repeat: none; }
ตารางตัวอย่างที่ปิด thead repeat:
| # | รายการ (thead ไม่ repeat) | หมายเหตุ |
|---|---|---|
| 1 | รายการที่ 1 | thead จะแสดงเฉพาะหน้าแรกเท่านั้น |
| 2 | รายการที่ 2 | หน้าถัดไปจะไม่มี thead |
| 3 | รายการที่ 3 | ประหยัดพื้นที่ในกรณีตารางยาว |
Tip: -lynpdf-repeat เป็น CSS property เฉพาะของ LynPDF ไม่มีผลในเบราว์เซอร์ทั่วไป สามารถใส่ได้ทั้ง inline style หรือใน stylesheet
LynPDF รองรับ text-justify สำหรับทั้งภาษาไทยและอังกฤษ โดยใช้ Thai dictionary segmenter สำหรับตัดคำไทยแล้วกระจายช่องว่างระหว่างคำเท่าๆ กัน:
text-align: justify
การจัดรูปแบบข้อความแบบกระจายเต็มบรรทัด (Justify) ในภาษาไทยนั้นมีความท้าทายอย่างมากเนื่องจากภาษาไทยไม่มีการเว้นวรรคระหว่างคำเหมือนภาษาอังกฤษหากใช้การกระจายช่องว่างระหว่างคำเพียงอย่างเดียว จะทำให้เกิดช่องว่างขนาดใหญ่ที่ดูไม่สวยงามและอ่านยากดังนั้นระบบจึงต้องใช้เทคนิคการกระจายช่องว่างระดับคลัสเตอร์(Cluster-based Justification) โดยอาศัย HarfBuzz ในการแยกแยะพยัญชนะ สระและวรรณยุกต์ให้อยู่เป็นกลุ่มเดียวกันแล้วจึงกระจายช่องว่างเล็กๆ แทรกเข้าไปอย่างแนบเนียนพร้อมทั้งให้น้ำหนักกับรอยต่อระหว่างคำมากกว่ารอยต่อระหว่างคลัสเตอร์เพื่อรักษารูปแบบการอ่านที่เป็นธรรมชาติ
text-align: left (เปรียบเทียบ)
การจัดรูปแบบข้อความแบบกระจายเต็มบรรทัด (Justify) ในภาษาไทยนั้นมีความท้าทายอย่างมาก เนื่องจากภาษาไทยไม่มีการเว้นวรรคระหว่างคำเหมือนภาษาอังกฤษ หากใช้การกระจายช่องว่างระหว่างคำเพียงอย่างเดียว จะทำให้เกิดช่องว่างขนาดใหญ่ที่ดูไม่สวยงามและอ่านยาก ดังนั้นระบบจึงต้องใช้เทคนิคการกระจายช่องว่างระดับคลัสเตอร์ (Cluster-based Justification) โดยอาศัย HarfBuzz ในการแยกแยะพยัญชนะ สระ และวรรณยุกต์ให้อยู่เป็นกลุ่มเดียวกัน แล้วจึงกระจายช่องว่างเล็กๆ แทรกเข้าไปอย่างแนบเนียน พร้อมทั้งให้น้ำหนักกับรอยต่อระหว่างคำมากกว่ารอยต่อระหว่างคลัสเตอร์ เพื่อรักษารูปแบบการอ่านที่เป็นธรรมชาติ
ใช้ Thai dictionary segmenter (locale: th-TH) ตัดคำอัตโนมัติ ช่วยให้ข้อความยาวขึ้นบรรทัดใหม่ได้ถูกต้อง:
สำนักงานพัฒนาธุรกรรมทางอิเล็กทรอนิกส์เป็นหน่วยงานภายใต้กระทรวงดิจิทัลเพื่อเศรษฐกิจและสังคมมีหน้าที่ส่งเสริมและสนับสนุนการทำธุรกรรมทางอิเล็กทรอนิกส์ของประเทศไทยรวมถึงการพัฒนามาตรฐานและกฎเกณฑ์ที่เกี่ยวข้อง
LynPDF ใช้ HarfBuzz สำหรับ OpenType shaping — GSUB (glyph substitution) และ GPOS (glyph positioning):
Kerning Pairs (Sarabun 24px):
AV AW AY AT VA To Te Ty We Yo PA
Standard Ligatures (Sarabun 24px):
fi fl ff ffi ffl — office, difficult, waffle
| Property | ตัวอย่าง |
|---|---|
| font-family | Sarabun, Prompt, Kanit, IBM Plex Sans, Inter Variable |
| font-size | 14px, 1.2em |
| font-weight | normal, bold, 100-900 |
| font-style | normal, italic |
| color | #hex, rgb(), rgba(), named colors |
| text-align | left, center, right, justify |
| line-height | 1.5, 24px |
| letter-spacing | 2px, -0.5px |
| word-spacing | 4px |
| text-decoration | underline, line-through |
LynPDF รองรับอักขระพิเศษที่ใช้ในบาลี/สันสกฤตเขียนด้วยอักษรไทย ผ่าน HarfBuzz text shaping:
พยัญชนะเฉพาะ ฎ ฏ ฐ ญ ฬ (Sarabun 28px):
ฎ ฏ ฐ ญ ฬ
พยัญชนะ + สระบน + วรรณยุกต์ (ซ้อน 2-3 ชั้น):
ฎี ฎี่ ฎี้ ฏิ ฏิ่ ฏิ้ ฐึ ฐึ่ ญี ญี้ ฬี ฬี้
สระล่าง ( ุ ู ):
ฎุ ฎู ฏุ ฏู ฐุ ฐู ญุ ญู ฬุ ฬู
นิคหิต ( ํ ) — วงกลมบนอักษร:
อํ กํ คํ ปํ สํ ตํ ภํ ธํ
พินทุ ( ฺ ) — จุดล่างอักษร (สันสกฤต):
กฺ ขฺ คฺ ตฺ ทฺ ปฺ พฺ สฺ
ทัณฑฆาต ( ์ ) / ยามักการ ( ๆ ) / อังคั่น ( ฯ ):
สมฺภว กรฺม ธรฺม ฯลฯ นมัสฺการ ญาณ์ จิตฺต สุตฺต
Sarabun (20px):
สพฺเพ ธมฺมา อนตฺตา ฯ สพฺเพ สงฺขารา อนิจฺจา ฯ สพฺเพ สงฺขารา ทุกฺขา ฯ
Norasi (20px):
ธรฺมจกฺรปฺรวรฺตนสูตฺร — กฺริยา ปฺรชฺญา สมฺภว ปฺรตีตฺยสมุทฺปาท
Garuda (20px):
นะโม ตัสสะ ภะคะวะโต อะระหะโต สัมมาสัมพุทธัสสะ
Kinnari (20px):
อิติปิ โส ภะคะวา อะระหํ สัมมาสัมพุทโธ วิชชาจะระณะสัมปันโน
หมายเหตุ: HarfBuzz จัดตำแหน่ง glyph ได้ถูกต้องโดยอัตโนมัติ — สระบน/ล่าง วรรณยุกต์ นิคหิต พินทุ ไม่ทับกัน ทุกฟอนต์ที่มี GSUB/GPOS tables จะทำงานได้ดี
กำหนดระยะขอบหน้ากระดาษผ่าน CSS @page rule (ค่าเริ่มต้น: 50pt):
/* ตั้ง margin ด้วยหน่วยต่างๆ */
@page { margin: 1in; } /* 72pt ทุกด้าน */
@page { margin: 2cm; } /* ~56.7pt */
@page { margin: 30px; } /* 22.5pt */
@page { margin: 40pt; } /* 40pt */
หรือกำหนดผ่าน PDFOptions API:
let options = RenderOptions::default();
let options = RenderOptions { margin_pt: 72.0, ..RenderOptions::default() };
render_file_to_pdf("input.html", Some("styles.css"), "output.pdf", options)?;
| หน่วย | ตัวอย่าง | เทียบเท่า (pt) |
|---|---|---|
| pt (points) | 50pt | 50 |
| px (pixels) | 30px | 22.5 |
| in (inches) | 1in | 72 |
| cm | 2cm | 56.69 |
| mm | 25mm | 70.87 |
กำหนดขนาดกระดาษและทิศทางผ่าน CSS @page rule:
/* รูปแบบแนวนอน (Named size) */
@page { size: A4; } /* 595.28 × 841.89 pt */
@page { size: A3; } /* 841.89 × 1190.55 pt */
@page { size: letter; } /* 612 × 792 pt */
/* Landscape — แนวนอนหัน */
@page { size: A4 landscape; } /* 841.89 × 595.28 pt */
@page { size: A3 landscape; } /* 1190.55 × 841.89 pt */
/* ขนาดกำหนดเอง (Explicit dimensions) */
@page { size: 297mm 210mm; } /* A4 landscape */
@page { size: 200mm 150mm; } /* เล็มพาอเน็กเชต */
@page { size: 500pt 700pt; } /* pt โดยตรง */
| Named Size | Portrait (pt) | Landscape (pt) |
|---|---|---|
| A3 | 841.89 × 1190.55 | 1190.55 × 841.89 |
| A4 (ค่าเริ่มต้น) | 595.28 × 841.89 | 841.89 × 595.28 |
| A5 | 419.53 × 595.28 | 595.28 × 419.53 |
| letter | 612 × 792 | 792 × 612 |
| legal | 612 × 1008 | 1008 × 612 |
| ledger / tabloid | 792 × 1224 | 1224 × 792 |
Tip: @page { size } ใน CSS จะ override ค่า pageSize ใน PDFOptions เสมอ — ตัวเลือกการควบคุมขนาดกระดาษผ่าน CSS ทำให้ไฟล์ HTML อิสระจาก code
LynPDF สร้าง metadata จาก HTML meta tags อัตโนมัติ:
<head>
<title>ชื่อเอกสาร</title>
<meta name="author" content="ผู้เขียน">
<meta name="description" content="คำอธิบาย">
<meta name="keywords" content="คำค้นหา">
</head>
| HTML Source | PDF Key |
|---|---|
| <title> | /Title |
| meta name="author" | /Author |
| meta name="description" | /Subject |
| meta name="keywords" | /Keywords |
| meta name="creator" | /Creator (default: LynPDF) |
| meta name="producer" | /Producer (default: LynPDF/native PDF emitter) |
Tip: รองรับ prefix "pdf-" ด้วย เช่น pdf-title, pdf-author API-level metadata จะ override ค่าจาก HTML
interface PDFOptions {
pageSize?: string | [number, number] // 'A4' | 'A3' | 'letter' | [w, h]
margin?: number | [t, r, b, l] // points
css?: string // CSS เพิ่มเติม
defaultFont?: string // path to .ttf/.otf
colorEmoji?: boolean // Twemoji (default: true)
verbose?: boolean // logs (default: false)
compress?: boolean // compression (default: true)
pdfVersion?: string // '1.3'–'1.7ext3'
metadata?: { Title, Author, Subject, Keywords, Creator, Producer }
}
LynPDF รองรับ SVG แบบ inline ด้วย native SVG paint ops:
วงกลม
สี่เหลี่ยม
สามเหลี่ยม
ดาว
รองรับสีหลายรูปแบบ:
#b87436
rgb(15,52,96)
rgba(.5)
steelblue
gold
| Property | คำอธิบาย |
|---|---|
| background-color | สีพื้นหลัง — รองรับ rgba ด้วย |
| opacity | ความโปร่งใส (0 ถึง 1) |
| border-radius | มุมโค้ง (px) |
| box-shadow | เงา CSS (จำกัด) |
LynPDF รองรับการแปลง Markdown เป็น PDF โดยตรง ผ่าน CLI หรือ Rust API โดยไม่ต้องเขียน HTML เองแม้แต่บรรทัดเดียว รองรับ GitHub Flavored Markdown (GFM) พร้อมฟีเจอร์เสริมหลัก: custom containers, GitHub-style alerts, tables, task lists, footnotes และการจัดรูปแบบ code block สำหรับเอกสารเทคนิค
Terminal
# แปลง .md เป็น PDF (ตรวจจาก extension อัตโนมัติ)
cargo run --bin lynpdf-rs -- README.md -o readme.pdf
# เพิ่ม CSS เสริม
cargo run --bin lynpdf-rs -- doc.md -c custom.css -o doc.pdf
# รันแบบ verbose เพื่อดู diagnostics
cargo run --bin lynpdf-rs -- doc.md -o doc.pdf --verbose
Rust API
use lynpdf_rs::{render_file_to_pdf, render_html_to_pdf, RenderOptions, RenderRequest};
let options = RenderOptions::default();
// จากไฟล์ .md (แปลง Markdown แล้วเรนเดอร์อัตโนมัติ)
render_file_to_pdf("docs/guide.md", Some("examples/styles.css"), "guide.pdf", options.clone())?;
// low-level: จาก HTML string โดยตรง
let doc = render_html_to_pdf(RenderRequest {
html: "<h1>Hello</h1>".into(),
css: "h1{color:#b87436;}".into(),
base_dir: std::path::PathBuf::from("."),
css_base_dir: None,
options,
})?;
Code block สามารถทำ syntax highlight ได้ด้วย class token เช่น
token-keyword, token-string, token-function
ผ่าน CSS ธีมเดียวกับเอกสาร (ดูตัวอย่างด้านล่าง) เพื่อ lock สีและรูปแบบให้สม่ำเสมอในการ render PDF
| Token | สี (GitHub Light) | ตัวอย่าง |
|---|---|---|
| keyword | #d73a49 | const, function, return, if |
| string | #032f62 | "hello world" |
| number | #005cc5 | 42, 3.14, 0xFF |
| function / title | #6f42c1 | myFunction() |
| built-in | #e36209 | console, print, len |
| comment | #6a737d | // comment, # remark |
| type / class | #005cc5 | string, boolean, MyClass |
| operator | #d73a49 | =>, ===, +, -> |
Markdown source
```rust
struct Config {
page_size: &'static str,
margin_pt: f32,
}
fn generate(cfg: Config) {
let _ = cfg;
// render_file_to_pdf(...);
}
```
ภาษาที่รองรับ (ตัวอย่าง): Rust, JavaScript, Python, HTML, CSS, JSON, SQL, Bash, Dockerfile, Go, Rust, Java, C/C++, PHP, Ruby, Swift, Kotlin, YAML, XML, Markdown และอีกกว่า 190 ภาษา
---ใน Markdown → PDF โมเดลของ LynPDF จะแปลง --- (thematic break / <hr>)
เป็น page break อัตโนมัติ ทำให้จัดหน้าได้สะดวกโดยไม่ต้องเขียน HTML:
Markdown — จัดแต่ละ section คนละหน้า
## บทที่ 1: บทนำ
ข้อความบทที่ 1...
---
## บทที่ 2: เนื้อหา
ข้อความบทที่ 2...
บรรทัด --- สร้าง <hr style="page-break-after: always">
โดยอัตโนมัติผ่าน default CSS ของ LynPDF
ใช้ syntax :::type เพื่อสร้าง container พิเศษ (ต้องการ plugin
markdown-it-container ซึ่งรวมมาแล้ว):
| Syntax | ประเภท | สีพื้นหลัง |
|---|---|---|
:::info |
ข้อมูลทั่วไป | ฟ้าอ่อน |
:::tip ชื่อ |
เคล็ดลับ | เขียวอ่อน |
:::warning ชื่อ |
คำเตือน | เหลืองอ่อน |
:::danger |
อันตราย | แดงอ่อน |
:::note |
หมายเหตุ | เทาอ่อน |
:::caution |
ข้อควรระวัง | ส้มอ่อน |
:::important |
สำคัญ | ม่วงอ่อน |
:::warning ระวัง!
อย่าลืมตั้งค่า @page { margin } เมื่อใช้ custom CSS
:::
รองรับ > [!NOTE] syntax เหมือน GitHub README:
| Syntax | ประเภท |
|---|---|
> [!NOTE] |
หมายเหตุ (ฟ้า) |
> [!TIP] |
เคล็ดลับ (เขียว) |
> [!WARNING] |
คำเตือน (เหลือง) |
> [!CAUTION] |
ข้อควรระวัง (แดง) |
> [!IMPORTANT] |
สำคัญ (ม่วง) |
| Syntax | สีกรอบ / พื้น |
|---|---|
:::card ชื่อ |
การ์ดขาว มีเงา |
:::box-blue |
ฟ้า |
:::box-green |
เขียว |
:::box-red |
แดง |
:::box-yellow |
เหลือง |
:::box-purple |
ม่วง |
:::box-gray |
เทา |
:::box-orange |
ส้ม |
| Feature | หมายเหตุ |
|---|---|
| GFM Tables | ตาราง | col | col | พร้อม border |
| Task Lists | - [x] done / - [ ] todo |
| Footnotes | [^1] อ้างอิงท้ายหน้า |
| Strikethrough | ~~ข้อความ~~ |
| --- เป็น Page Break | แปลง <hr> เป็น page-break-after: always |
| Mermaid Diagrams | แนะนำ pre-render Mermaid เป็น SVG/PNG ก่อนนำเข้า Markdown |
| Inline HTML | HTML ใน Markdown จะถูกประมวลผลปกติ |
| Custom CSS | เพิ่มไฟล์ CSS ผ่าน -c custom.css (ถูก append ต่อจาก default markdown css) |
LynPDF ใส่ default stylesheet ให้อัตโนมัติเมื่อแปลง Markdown และสามารถเพิ่ม custom css ได้ผ่าน
-c custom.css เพื่อ override style เฉพาะเอกสาร
| Element | Default Style |
|---|---|
@page |
margin: 2cm |
body |
font: Sarabun 14px, line-height 1.6 |
pre (code block) |
พื้น #f6f8fa, border, monospace 12px, padding 16px 18px |
.code-lang-badge |
แถบชื่อภาษา (#eaeef2) แสดงชื่อภาษาเหนือ code block |
hr |
page-break-after: always (ไม่แสดงเส้น) |
table |
border-collapse, th พื้น #f6f8fa, แถบสลับสี |
| Package | Description |
|---|---|
| html5ever + markup5ever_rcdom | HTML parser และ DOM model |
| lightningcss | CSS parsing และ stylesheet diagnostics |
| rustybuzz + ttf-parser | OpenType shaping และ font parsing |
| Rust HTML parser | HTML parser (WHATWG standard) |
| Rust CSS parser | CSS parser & AST toolkit |
| image | PNG raster decoding สำหรับภาพและ visual diff workflow |
| pulldown-cmark | Markdown parser (tables, task lists, footnotes) |
| unicode-segmentation + dictionary | word break สำหรับภาษาไทยและข้อความหลายภาษา |
| รายการ | ค่า |
|---|---|
| ขนาดกระดาษ (ค่าเริ่มต้น) | A4 (595.28 × 841.89 pt) — กำหนดเองได้ผ่าน @page { size } |
| ระยะขอบ (ค่าเริ่มต้น) | 36pt ทุกด้าน (กำหนดเองได้ผ่าน @page หรือ RenderOptions) |
| ฟอนต์เริ่มต้น | Sarabun 10.5pt |
| PDF Compression | กำหนดตาม renderer defaults |
| PDF Version | 1.7 (กำหนดเองได้ 1.3–1.7ext3) |
| Color space | DeviceRGB |
| Text Shaping | HarfBuzz (GSUB + GPOS) — macOS, Linux, Windows (รองรับทุกแพลตฟอร์ม) |
| Thai Word Break | Thai dictionary segmenter (th-TH) |
| ชื่อฟอนต์ | ประเภท | Variants |
|---|---|---|
| Garuda | Sans-serif | Regular, Bold, Oblique, BoldOblique |
| Loma | Sans-serif | Regular, Bold, Oblique, BoldOblique |
| Norasi | Serif | Regular, Bold, Italic, BoldItalic |
| Kinnari | Serif | Regular, Bold, Italic, BoldItalic |
| Laksaman | Serif | Regular, Bold, Italic, BoldItalic |
| Sawasdee | Sans-serif | Regular, Bold, Oblique, BoldOblique |
| Purisa | Handwriting | Regular, Bold, Oblique, BoldOblique |
| Umpush | Sans-serif | Regular, Bold, Light, Oblique |
| Waree | Sans-serif | Regular, Bold, Oblique, BoldOblique |
| TlwgMono | Monospace | Regular, Bold |
| TlwgTypewriter | Monospace | Regular, Bold |
| TlwgTypist | Monospace | Regular, Bold |
| TlwgTypo | Monospace | Regular, Bold |
LynPDF เผยแพร่ภายใต้ MIT License — ใช้งานในโปรเจกต์ส่วนตัวและเชิงพาณิชย์ได้อิสระ
ฟอนต์ที่รวมมากับ LynPDF:
Sarabun, Prompt, Kanit, Mitr, Chakra Petch — OFL (SIL Open Font License)
TLWG Fonts — GPL with Font Exception
Inter Variable — OFL (SIL Open Font License)
IBM Plex Sans — OFL (SIL Open Font License)
Noto Emoji — Apache License 2.0
— จบเอกสาร —
สร้างด้วย LynPDF v2.1 • HTML/CSS → PDF Creator