כתבתי Markdown כל יום עבודה במשך שנים - תוסף READMEs, יומני שינויים, מסמכים עבור Toolz.dev, שחרר הערות עבור WP Adminify, חצי הודעות commit שלי ובמשך רוב הזמן הזה התייחסתי לשלב העיבוד כקסם אתה כותב כוכביות, GitHub מראה מודגש בסדר גמור. להמשיך הלאה.
ואז בניתי מדור מסמכים שהוציא את Markdown ממסד הנתונים והפך אותו לדף Next.js, והקסם הפך לרשימה של החלטות מאוד ספציפיות שהייתי צריך לקבל האם שורה חדשה אחת הופכת ל- <br>? (הערות GitHub אומרות שכן. מפרט Markdown אומר לא.) האם <div> בעיבוד המקור כדיב או כטקסט מילולי? (תלוי מי שואל, והאם אתה סומך על המחבר.) איזו מחלקה עוברת על בלוק קוד מגודר כך שהמדגיש קולט אותה? למה מנתח אחד מסתובב **bold**text לתוך נועז ואחר משאיר את זה לבד?
שום דבר מזה הוא אקזוטי זה רק החומר שאף אחד לא אומר לך, כי מרקדאון נראה כל כך פשוט שאנשים מניחים שאין כלום מתחתיו יש די הרבה מתחתיו סימון ל-HTML ממיר על Toolz.dev חושף את ההחלטות האלה כמתגים במקום להסתיר אותן, וזו הגרסה של הכלי הזה שרציתי כשניקיתי באגים מדוע מעברי השורות שלי המשיכו להיעלם.
TL;DR: Markdown הוא פורמט כתיבה; HTML הוא פורמט התצוגה משהו צריך להרכיב אחד לתוך השני הכללים שמכשילים אנשים: שורות עוקבות מצטרפות לפסקה אחת אלא אם כן אתה מסיים שורה עם שני רווחים (או מפעיל אפשרות "breaks"), HTML גולמי מועבר או נמלט בהתאם להגדרות האמון של מנתח 's, ו-GitHub's דיאלקט (GFM) מוסיף טבלאות, רשימות משימות, קו חוצה וקישור אוטומטי חשוף ב-URL על גבי CommonMark קו בסיס. קוד מגודר מהדר ל
<pre><code class="language-js">, שהוא הקרס פריזמה, highlight.js ושיקי לחפש. ה Markdown כדי HTML ממיר עושה את כל זה בדפדפן שלך, עם כל מתג חשוף.
מהו Markdown, ולמה הוא צריך המרה בכלל?
Markdown הוא תחביר טקסט רגיל שג'ון גרובר פרסם ב-2004, עם מטרת עיצוב מוצהרת אחת: מסמך Markdown צריך להיות ניתן לפרסום כפי שהוא, קריא כטקסט רגיל, מבלי להיראות כאילו הוא סומן בתגיות. לכן התחביר שואל מהמוסכמות שאנשים כבר השתמשו בהן בדואל - כוכביות סביב מילה להדגשה, שורת מקפים תחת כותרת, א > להצעת מחיר.
התוצאה היא ש-Markdown אינו פורמט רינדור. שום דבר לא מציג Markdown. דפדפנים מציגים HTML, וכל מקום שיש לך אי פעם נראה Markdown rended - GitHub, אתר סטטי, פורטל מסמכים, אפליקציית צ'אט - הפעיל תחילה מנתח ושם HTML על המסך.
אז ההמרה צריכה לקרות איפשהו האפשרויות שלך הן בערך:
- בזמן הבנייה, במחולל אתרים סטטי או באנדלר. בסדר כשהתוכן חי בריפו שלך.
- במועד הבקשה, בשרת. הכרחי כאשר התוכן מגיע ממסד נתונים, יקר אם אתה עושה זאת בכל בקשה ללא מטמון.
- בדפדפן, כרגע אתה צריך את זה. וזה מה שאתה רוצה כשהתשובה ל-" אני רק צריך את ה-HTML עבור הדבר האחד הזה" הוא העתק-הדבק, לא צינור בנייה.
המקרה השלישי הזה נפוץ יותר ממה שהוא נשמע הדבקת הערות שחרור לשדה CMS שלוקח רק HTML. הכנסת README לתבנית דואל. בדיקת איך ייראה מסמך לפני שאתה מתחייב. המרת טיוטה שנכתבה ב-Obsidian למשהו שאתה יכול למסור למעצב. אף אחד מאלה לא מצדיק חיווט מנתח לפרויקט.
מה ההבדל בין CommonMark לבין GitHub בטעם Markdown?
Gruber' המפרט המקורי של Gruber היה עמוד של פרוזה ותסריט של Perl, והוא הותיר מספיק אי בהירות כדי שכל יישום לא הסכים לגבי מקרי הקצה. CommonMark האם התשובה לכך היא: מפרט קפדני וניתן לבדיקה עם חבילת התאמה של מאות דוגמאות, כך ששני מנתחים תואמים מייצרים פלט זהה עבור אותו קלט. הוא מגדיר את קו הבסיס - כותרות, פסקאות, הדגשה, קישורים, תמונות, רשימות, ציטוטים בלוקים, בלוקי קוד, הפסקות נושאיות, בריחות לאחור, בלוקי HTML.
סימון בטעם GitHub (GFM) הוא ערכת-על רשמית של CommonMark, שצוינה על ידי GitHub, שמוסיפה את הדברים שאנשים כל הזמן ביקשו:
| תכונה | CommonMark | GFM | תחביר |
|---|---|---|---|
| טבלאות | לא | כן | | a | b | עם א | --- | --- | שורת תוחם |
| רשימות משימות | לא | כן | - [x] done / - [ ] todo |
| דרך עוקפת | לא | כן | ~~gone~~ |
| כתובות אתרים חשופות מקושרות אוטומטית | לא | כן | https://toolz.dev ללא סוגריים |
| הערות שוליים | לא | כן (סיומת GitHub) | [^1] |
| כותרות, רשימות, קוד, הדגשה | כן | כן | זהה |
אם ה-Markdown שלך הגיע מ-GitHub README, ויקי GitLab, ייצוא Notion או רוב העורכים המודרניים, זה GFM. הפעל את GFM בממיר או שהטבלאות שלך יעבדו כצינורות מילוליים, שזה מספר אחת " הממיר שבור" שאלת תמיכה כל מי ששולח אחד מהכלים האלה מקבל.
למה הפסקת הקו שלי נעלמה?
מכיוון ש-Markdown, בעקבות המוסכמות של דואר אלקטרוני בטקסט רגיל, מתייחס לשורות לא ריקות עוקבות כאל פסקה אחת. זֶה:
Line one
Line two
מייצרת <p>Line one\nLine two</p>- פסקה אחת, והשורה החדשה קורסת לרווח כשהדפדפן מעבד אותה. זה לא באג; זה המפרט, והוא קיים כך שתוכל לעטוף את הפרוזה שלך ב-80 עמודות בעורך טקסט מבלי שהעטיפה הזו תדלוף לפלט.
ישנן שלוש דרכים לקבל הפסקה בפועל:
- שורה ריקה מתחיל פסקה חדשה זה מה שאתה רוצה רוב הזמן.
- שני חללים נגררים בסוף שורה לייצר הפסקה קשה -
<br />. זה הטריק הסטנדרטי, והוא בלתי נראה בעורך שלך, וזו הסיבה שאנשים מוצאים את זה מטריף. - קו נטוי אחורי בסוף השורה עושה את אותו הדבר ב-CommonMark, ולפחות נראה לעין.
ואז יש את הדרך הרביעית, שהיא מקור הבלבול: פלטפורמות רבות מדליקות "breaks" מצב שבו כל שורה חדשה הופכת ל- <br />. הערות ובעיות של GitHub עושים זאת. רוב אפליקציות הצ'אט עושות זאת. קבצי GitHub README לא. אז אותו טקסט מציג אחרת בגיליון GitHub וב-README של אותו מאגר, שהוא חתיכת עיצוב גרועה באמת שכולנו תקועים איתה כעת.
הממיר חושף זאת כמתג אם המקור שלך נכתב עבור מעבד בסגנון צ'אט, הפעל שורות הפסקות אם זה מסמך, השאר אותו כבוי והשתמש בשורות ריקות כמו שהמפרט מתכוון.
כיצד מטפלים ב-HTML גולמי?
Markdown מתיר HTML מוטבע - המפרט המקורי אומר במפורש שכל HTML שאתה כותב עובר ישר דרכו. זו תכונה כשאתה המחבר (אתה רוצה את שלך <details> בלוק, שלך <img> עם תכונת רוחב, העוגן שלך עם א rel), וזו אחריות כשאתה לא.
מכיוון שאם אתה הופך סימון לא מהימן עם העברת HTML מופעלת, יש לך פגיעות XSS. <script>alert(document.cookie)</script> תקף Markdown. כך גם <img src=x onerror="...">. כך גם <a href="javascript:...">. תיבת הערות, ביוגרפיה של פרופיל משתמש, ויקי ציבורי - בכל מקום שבו זרים כותבים Markdown שאנשים אחרים קוראים - חייבים לברוח מ-HTML או לחטא את הפלט עם חומר חיטוי אמיתי (DOMPurify היא התשובה הרגילה, וזה חומר חיטוי אמיתי בדיוק בגלל ש-regex אינו מספיק לקלט עוין).
ממיר זה כברירת מחדל ל בריחה HTML גולמי: <div> במקור שלך מופיע כטקסט המילולי <div> בפלט, בדיוק כאילו שכתבת <div>. אתה יכול להפעיל מעבר כאשר המקור הוא שלך. וללא קשר להגדרה זו, התצוגה המקדימה החיה מתפשטת <script>, <style>, בשורה on* מטפלי אירועים ו javascript: כתובות אתרים לפני שהוא מציג - אמצעי הגנה לעומק, אז הדבקת מישהו אחר 's README בחלונית התצוגה המקדימה לא יכולה להפעיל את הקוד שלו. זהו מדד בטיחות תצוגה מקדימה, לא חומר חיטוי למטרות כלליות: אם אתה בונה מוצר שמעבד את המשתמש Markdown, השתמש בצד שרת חיטוי ייעודי ואל תסמוך על regex, כולל שלי.
אם אתה צריך לברוח מדמות מ סימון למטה כך שהוא מציג מילולית - כוכבית שאמורה להישאר כוכבית, קו תחתון בשם קובץ - קו נטוי אחורי עושה את זה: \*not emphasis\*. ואם אתם מתקוטטים ישויות בכיוון השני, ה מקודד/מפענח ישויות HTML הוא הכלי לעבודה הזו.
איזה HTML בעצם צריך לפלוט ממיר טוב?
HTML סמנטי, משעמם, ללא כיתה - למעט חריג אחד.
- כותרות הופכות
<h1>-<h6>. עם מזהי כותרת מופעלים, כל אחד מהם מקבל גם סליגהid, ביטול שכפול כאשר שתי כותרות חולקות כותרת (#setup,#setup-1). זה מה שעושה#anchorקישורים עמוקים עובדים, וזה מה שמחולל תוכן תלוי. - בלוק מגודר עם מחרוזת מידע -
```js- הופך<pre><code class="language-js">. *זה היוצא מן הכלל.** השפה-`class is the convention Prism, highlight.js and Shiki כולם מחפשים, וזו הסיבה שהממיר פולט מחלקה בכלל. הממיר לא צובע את הקוד שלך; ההדגשה בדף שלך כן, והוא צריך את הקרס הזה. - רשימות הופכות
<ul>/<ol>, והנה עדינות שכדאי לדעת: א הדוק רשימה (ללא שורות ריקות בין פריטים) מכניסה את הטקסט ישירות פנימה<li>, בעוד א רופף רשימה (שורות ריקות בין פריטים) עוטפת כל פריט 's תוכן ב<p>. זו התנהגות CommonMark, לא מוזרות, וזו הסיבה שהרשימה שלך גדלה לפתע במרווחים אנכיים כשאתה מוסיף שורה ריקה בין שני כדורים. ה-CSS לא שבור; ה-HTML באמת השתנה. - שולחנות הופכים לאמיתיים
<table>/<thead>/<tbody>סימון, עםstyle="text-align:center"על תאים כאשר שורת המפריד משתמשת:---:. - רשימות משימות הופכות
<input type="checkbox" disabled>בתוך ה<li>, שזה בדיוק מה ש-GitHub פולט.
תוכן-ראשון, ללא דיוות עטיפה, ללא שיעורי שירות. אתה מעצב את זה מבחוץ, עם א .prose מחלקה או חוקים משלך, והסימון נשאר נייד.
איך אני משתמש בממיר?
שלב 1: הדבק את ה-Markdown
Drop in a README, a changelog, release notes, a draft.Output updates as you type - אין כפתור המרה, ושום דבר לא מועלה.
שלב 2: הגדר את המתגים
בטעם GitHub על אם למקור יש טבלאות, רשימות משימות או מחיקות (כנראה שכן). מזהי כותרת על אם אתה רוצה עוגנים. מעברי שורות על רק אם המקור נכתב עבור מעבד בסגנון צ'אט. אפשר HTML גולמי על רק אם המקור הוא שלך. מסמך מלא על אם אתה רוצה דף HTML5 שלם עם doctype, charset, viewport ו-a <title> נלקח מהראשון שלך <h1>- שימושי כאשר ברצונך לפתוח את התוצאה ישירות בדפדפן או להפיל אותה על מארח סטטי.
שלב 3: בדוק את התצוגה המקדימה
עבור ללשונית התצוגה המקדימה ואשר את המבנה שורת הנתונים הסטטיסטיים אומרת לך מילים, כותרות, קישורים, תמונות, בלוקי קוד וזמן קריאה - שימושי לבדיקת פוסט הוא האורך שחשבת שהוא לפני שפרסמת אותו לספירה יסודית יותר, ה מונה מילים האם קריאות וצפיפות מילות מפתח על אותו טקסט.
שלב 4: קח את הפלט
העתק את ה-HTML, הורד אותו בתור .html קובץ, או העתק את תוכן העניינים שנוצר - רשימה מקוננת של Markdown המקשרת לכל עוגן כותרת, מוכנה להדבקה בחזרה בראש המסמך שלך.
אם אתה מדביק את התוצאה בדף שבו בתים חשובים, הפעל אותה דרך ממיר HTML לאחר מכן. הפלט של הממיר's מחורץ לקריאה, לא עבור החוט.
מקרי שימוש נפוצים
קבלת README לאתר
מחברי תוספים וחבילות כותבים README טוב, ואז צריכים את אותו תוכן בדף נחיתה. README הוא GFM עם טבלאות ותגים; דף הנחיתה זקוק ל-HTML. המר, הדבק, סגנון עם ה-CSS הקיים שלך. מזהי הכותרות נותנים לך סרגל צד TOC בחינם.
פרסום ל-CMS שמקבל רק HTML
שפע של שדות CMS, פלטפורמות דואל ופאנלים אדמין מדור קודם לוקחים HTML ותו לא אם אתה מנסח ב-Markdown - ורוב האנשים שכותבים באופן קבוע עושים זאת - זה הגשר. להמיר עם מסמך מלא כבוי, כך שתקבל את הפרגמנט ולא דף שלם, והדבק אותו בשדה.
יצירת אב טיפוס של דף מסמכים
לפני שאתה מתחייב תוכן לאתר docs, המרתו באופן מקומי מראה לך את היררכיית הכותרות בפועל והאם גדרות הקוד שלך נושאות את השפה הנכונה. א h3 זה היה צריך להיות א h2 ברור ב-TOC ובלתי נראה במקור.
ביקורת תוכן שמישהו אחר כתב
הדבק תורם's Markdown, הסתכל על ה-HTML הנפלט, ותוכל לראות מיד אם הם השתמשו בכותרות אמיתיות או מודגשות בשורה כדי לזייף אחת - הרגל שהורס את מבנה המסמכים והנגישות.קוראי מסך מנווטים לפי כותרת; **Big Text** זה לא כותרת, זו פסקה מודגשת, והממיר מראה לך את זה בשורה אחת של פלט.
חילוץ תוכן עניינים
מסמכים ארוכים צריכים אחד, ושמירה עליו ביד מבטיחה שהוא יתיישן. צור אותו מהכותרות, הדבק אותו, התחדש בכל פעם שהכותרות משתנות.
מתקדם: מה המנתח הזה עושה ומה לא עושה
זהו מנתח בכתב יד, בערך 400 שורות, ללא תלות - וזה מכוון, כי מנתח Markdown שמושך תלות של 200KB לתוך דף שכל הנקודה שלו היא להיות מהיר הוא טרייד גרוע.
מכוסה: כותרות ATX (# x) וכותרות setext (מסומנות בקו תחתון עם === / ---), פסקאות, הדגשה וחזקה (*, _, **, __), קוד מוטבע עם התאמת backtick-run, קוד מגודר עם מחרוזות מידע, בלוקי קוד מחורצים, ציטוטים בלוק עם המשך עצלן, רשימות מקוננות (מסודרות ולא מסודרות, הדוקות ומשוחררות), הפסקות נושאיות, קישורים ותמונות עם כותרות, סוגר זווית קישורים אוטומטיים, קישורים אוטומטיים בדואל, בריחות לאחור וערכת GFM: טבלאות עם יישור, רשימות משימות, קו חוצה, קישור אוטומטי חשוף ל-URL.
לא מכוסה: קישורים בסגנון התייחסות ([text][ref] עם א [ref]: url הגדרה במקום אחר), הערות שוליים, רשימות הגדרות וכמה מקרים סתומים באמת בפינה של CommonMark סביב בלוקי HTML המפריעים לפסקאות. אם אתה מפעיל את חבילת ההתאמה של CommonMark נגדה, היא לא תקבל ציון של 100%. אם אתה ממיר README, יומן שינויים או פוסט בבלוג, לא תשים לב.
זהו סחר כנה, וזו הסיבה שהממיר נטען באופן מיידי ועובד כשהרשת כבויה. עבור צינורות תוכן שבהם אתה צריך התאמה מדויקת של CommonMark, השתמש markdown-it, remark או cmark במבנה שלך; בשביל זה הם מיועדים.
שָׁוא
כיצד אוכל להמיר את Markdown ל-HTML?
הדבק את ה-Markdown שלך בעורך וה-HTML מופיע מיד - אין כפתור המרה ואין קובץ להעלאה הפעל את GitHub Flavored Markdown אם המקור שלך משתמש בטבלאות או ברשימות משימות, ולאחר מכן העתק את ה-HTML או הורד אותו כקובץ.html. הכל פועל בדפדפן שלך, כך שטיוטות שטרם פורסמו ומסמכים פנימיים לעולם לא עוזבים את המכשיר שלך.
מהו Markdown בטעם GitHub?
GitHub Flavored Markdown (GFM) הוא ערכת-על שצוינה רשמית של CommonMark שמוסיפה טבלאות, תיבות סימון של רשימת משימות, קו חוצה עם טילדות כפולות וקישור אוטומטי של כתובות URL חשופות. זהו הניב שבו משתמש GitHub לעיבוד קבצים ובעיות README, וזה מה שרוב עורכי Markdown פולטים כיום. זה מופעל כברירת מחדל בממיר זה.
למה הפסקת השורה הבודדת שלי נעלמה?
Markdown סטנדרטי מצטרף שורות עוקבות לפסקה אחת; הפסקת שורה שורדת רק אם אתה מסיים את השורה בשני רווחים, משתמש בקו נטוי אחורי או משאיר שורה ריקה. אם אתה רוצה שכל שורה חדשה תהפוך ל- <br />, אפשר את אפשרות מעברי השורות - כלומר ההתנהגות שבה משתמשים הערות GitHub ורוב אפליקציות הצ'אט, אבל זה לא מה שעושים קבצי README.
האם הממיר מדגיש את הקוד שלי?
הוא פולט את הסימון שהדגשה צריכה אבל לא צובע את הקוד עצמו. בלוק קוד מגודר מתויג בשפה js הופך <pre><code class="language-js">, שהוא מוסכמות הכיתה פריזמה, highlight.js ו Shiki כולם לחפש.הוסף אחת מאותן ספריות לדף שבו אתה מדביק את הפלט ואת ההדגשה מופיעה באופן אוטומטי.
האם HTML גולמי בתוך ה-Markdown שלי נשמר?
כברירת מחדל זה נמלט, אז <div> מופיע כטקסט מילולי ולא כתג הפעל את האפשרות allow-raw-HTML כדי להעביר תגיות ישר, וזה מה שאתה רוצה כאשר ה-Markdown שלך מתערבב בכוונה ב-HTML - א <details> בלוק, או תמונה עם תכונות הפעל אותה רק עבור מקור שאתה סומך עליו, מכיוון ש-HTML גולמי ממחבר לא מהימן הוא וקטור XSS.
האם זה בטוח להדביק סימון שלא כתבתי?
כן. HTML נמלט כברירת מחדל, והתצוגה המקדימה החיה מפשיטה בנוסף תגי סקריפט וסגנון, מטפלי אירועים מוטבעים ו-javascript: כתובות אתרים לפני העיבוד. שום דבר שאתה מדביק לא מועבר לשום מקום. אם אתה בונה מוצר שמעבד Markdown מאנשים זרים, עדיין השתמש בחומר חיטוי ייעודי כגון DOMPurify בצד השרת - מסנן תצוגה מקדימה אינו תחליף לאחד.
האם אוכל ליצור תוכן עניינים מהכותרות שלי?
כן. עם מזהי כותרות מופעלים, כל כותרת מקבלת עוגן משוחרר, לא משוכפל, והכלי בונה תוכן עניינים של Markdown המקשר לכל אחד מהם. העתק אותו בחזרה לחלק העליון של המסמך שלך והקישורים נפתרים כנגד המזהים שנוצרו. צור אותו מחדש בכל פעם שהכותרות שלך משתנות במקום לשמור אותו ביד.
האם ממיר זה מיישם את CommonMark במלואו?
הוא מיישם את המבנים שאנשים כותבים בפועל - כותרות ATX ו-setext, פסקאות, הדגשות, קישורים, תמונות, קישורים אוטומטיים, ציטוטים בלוקים, רשימות מקוננות ומשוחררות, קוד מגודר ומחורץ, הפסקות נושאיות, בריחות נטוי לאחור - בתוספת הרחבות GFM. קישורים בסגנון הפניה, הערות שוליים וכמה מקרי קצה נדירים של CommonMark HTML-block אינם מכוסים. להתאמה מדויקת של סיביות בצינור בנייה, השתמש ב-markdown-it, הערה או סימן.
כלים קשורים: סימון ל-HTML · ישויות HTML · ממיר HTML · מונה מילים · מְרַגֵל
קריאה קשורה: מפתח האינטרנט 's ערכת כלים · מדריך כלי טקסט



