📚معرفی و شروع سریع

Marked.js یک رشتهٔ Markdown را می‌گیرد و خروجی HTML برمی‌گرداند. تنها کاری که لازم است صدا زدن marked.parse() است.

<!-- بارگذاری کتابخانه -->
<script src="marked.min.js"></script>

<div id="out"></div>
<script>
const md = '# سلام دنیا\n\nاین **Markdown** است.';
document.getElementById('out').innerHTML = marked.parse(md);
</script>
▶ دمو: خروجی parse
ⓘ نکته: marked.parse(str) برای یک سند کامل است. برای متن یک‌خطی (بدون تگ <p>) از marked.parseInline() استفاده کنید (بخش ۶).

ویرایشگر زنده

متن سمت راست را تغییر دهید تا خروجی HTML بلافاصله سمت چپ رندر شود — قلب اکثر ویرایشگرهای Markdown همین است.

const input  = document.getElementById('editor');
const output = document.getElementById('preview');

input.addEventListener('input', () => {
  output.innerHTML = marked.parse(input.value);
});
▶ دمو زنده: بنویسید و فوری ببینید

📄نحو Markdown

مرجع سریع پرکاربردترین نحوها. سمت راست کد Markdown، سمت چپ خروجی رندرشده.

▶ دمو: نحوهای رایج کنار خروجی
نحونتیجه
# متنسرتیتر (h1 تا h6 با ۱ تا ۶ علامت #)
**متن**بولد
*متن*ایتالیک
[عنوان](url)لینک
![alt](url)تصویر
> متننقل‌قول (blockquote)
- موردلیست نامرتب
```code```بلوک کد

گزینه‌ها (options)

با marked.use() یا پاس دادن آبجکت گزینه به parse، رفتار را تنظیم کنید.

// تنظیم سراسری
marked.use({
  gfm:        true,    // GitHub Flavored Markdown (پیش‌فرض)
  breaks:     true,    // تک خط جدید = <br>
  pedantic:   false    // سخت‌گیری به نسخهٔ اصلی markdown.pl
});

// یا فقط برای یک فراخوانی
marked.parse(md, { breaks: true });
▶ دمو زنده: تأثیر breaks را ببینید

حالت فعلی: breaks: false

💡 breaks: در Markdown استاندارد، یک Enter ساده پاراگراف جدید نمی‌سازد. با breaks:true هر خط جدید به <br> تبدیل می‌شود — برای ورودی کاربر معمولی مفید است.

📊GFM و جدول

با gfm:true (پیش‌فرض) امکاناتی مثل جدول، چک‌لیست، خط‌خورده و auto-link فعال می‌شوند.

// جدول GFM
| نام   | نقش       | امتیاز |
|-------|-----------|:------:|
| علی   | فرانت‌اند  |   ۹۵   |
| سارا  | بک‌اند     |   ۹۲   |

// چک‌لیست
- [x] انجام شد
- [ ] در حال انجام
▶ دمو: جدول و چک‌لیست GFM

🔗parseInline

برای رشته‌های کوتاه که نمی‌خواهید داخل <p> پیچیده شوند (مثل عنوان یا برچسب)، از parseInline استفاده کنید.

marked.parse('**سلام**');
// <p><strong>سلام</strong></p>

marked.parseInline('**سلام**');
// <strong>سلام</strong>   ← بدون <p>
▶ دمو: مقایسهٔ parse و parseInline

parse()

parseInline()

🎨Renderer سفارشی

با override کردن متدهای renderer، خروجی HTML هر عنصر را کنترل کنید — مثلاً افزودن کلاس به لینک‌ها یا target="_blank".

marked.use({
  renderer: {
    link({ href, title, text }) {
      return `<a href="${href}" target="_blank" ` +
             `rel="noopener" class="ext">${text}</a>`;
    },
    heading({ text, depth }) {
      return `<h${depth} class="md-h">${text}</h${depth}>`;
    }
  }
});
▶ دمو: لینک‌ها با target=_blank و آیکون
ⓘ توکن‌ها: در نسخهٔ ۱۲، متدهای renderer یک آبجکت توکن می‌گیرند (مثل { href, text }) نه آرگومان‌های جدا. برای منطق پیچیده‌تر می‌توانید از walkTokens هم استفاده کنید.

ترکیب با Highlight.js

برای رنگ‌آمیزی بلوک‌های کد داخل Markdown، Marked را با Highlight.js ترکیب کنید.

// بعد از بارگذاری هر دو کتابخانه
marked.use({
  renderer: {
    code({ text, lang }) {
      const valid = hljs.getLanguage(lang) ? lang : 'plaintext';
      const html = hljs.highlight(text, { language: valid }).value;
      return `<pre><code class="hljs">${html}</code></pre>`;
    }
  }
});
💡 پلاگین رسمی: بستهٔ marked-highlight هم همین کار را تمیزتر انجام می‌دهد. برای آفلاین، همین renderer ساده کافی است.

🔐امنیت و XSS

Marked به‌صورت پیش‌فرض خروجی را پاک‌سازی (sanitize) نمی‌کند. اگر Markdown از کاربر می‌آید، حتماً خروجی را با ابزاری مثل DOMPurify پاک کنید.

// خطرناک — ورودی کاربر بدون پاک‌سازی
out.innerHTML = marked.parse(userInput);  // ❌ خطر XSS

// امن — با DOMPurify
const dirty = marked.parse(userInput);
out.innerHTML = DOMPurify.sanitize(dirty);    // ✅
⚠ مهم: هرگز خروجی marked.parse() از داده‌های نامطمئن (نظرات، پیام‌ها، ورودی فرم) را مستقیم در innerHTML قرار ندهید. تگ‌هایی مثل <script> یا <img onerror> می‌توانند کد اجرا کنند.
▶ دمو: HTML خام درون Markdown عبور می‌کند

ورودی: <b style="color:red">خام</b> و **markdown**

🔥الگوهای رایج

رندر فایل README از سرور

const res = await fetch('/README.md');
const md  = await res.text();
document.getElementById('doc').innerHTML =
  DOMPurify.sanitize(marked.parse(md));

بخش نظرات با Markdown

// کاربر Markdown می‌نویسد، شما امن رندر می‌کنید
function renderComment(text) {
  marked.use({ breaks: true });   // Enter = خط جدید
  return DOMPurify.sanitize(marked.parse(text));
}

📄 چیت‌شیت API

متد / گزینهکاربرد
marked.parse(md)تبدیل سند کامل به HTML
marked.parseInline(md)تبدیل بدون تگ بلوکی <p>
marked.use(opt)تنظیمات/افزونه/renderer سراسری
marked.lexer(md)فقط توکن‌سازی (بدون رندر)
gfmGitHub Flavored Markdown
breaksتبدیل \n به <br>
pedanticسازگاری سخت‌گیرانه با markdown.pl
💡 جمع‌بندی: برای ۹۹٪ موارد فقط marked.parse() + DOMPurify.sanitize() لازم است. renderer سفارشی و افزونه‌ها را وقتی نیاز شد اضافه کنید.

🚀زمین بازی کد (Playground)

Markdown بنویس و خروجی HTML را زنده ببین. در مثال اول داخل کادر تایپ کن تا لحظه‌ای رندر شود. نسخهٔ ۱۲.۰.۲ آفلاین بارگذاری می‌شود.