רכיב מעולה בריאקט לתצוגת קוד ב-markdown

קומפוננטה ריאקטית לתצוגת markdown שעושה חיים מאוד קלים למי שרוצה להשתמש ב-markdown הנוח במסגרת אתר או אפליקציה.

אם יש משהו שאני ממש ממש אוהב זה את פורמט markdown שכמעט כל מתכנת מכיר. משתמשים בו באמת בכל מקום: מפול ריקווסטים בגיטהאב ועד מסמכי דוקומנטציה שונים. אבל אפשר להשתמש בו גם במערכות CMS וכתחליף למסד נתונים באתרים מסוימים.

בימים אלו אני עובד על אתר תרגול לספר ״ללמוד ג׳אווהסקריפט בעברית״. למי שלא יודע, זו סדרת ספרים ללימוד ג׳אווהסקריפט ומגוון הפלטפורמות שלו. הפרויקט יצא לאור יחד עם הקריה האקדמית אונו ועם חברות מסחריות רבות (Really Good האהובים, Wix, צ׳ג, Outbrain, Honeybook, איירון סורס ועוד) וכ-2500 איש הורידו אותו. במסגרת הפרויקט, אמור לצאת גם אתר תרגול שילווה את הספר. בספר יש תרגילים, אבל בלימוד תכנות – כל המרבה הרי זה משובח ואם אני יכול לספק אתר עם מאות תרגילים נוספים לתרגול עצמי – זה יהיה מעולה.

בחרתי לבנות את אתר התרגילים בריאקט, אבל אז נשאלת השאלה – איפה אאחסן את המידע של התרגילים? כן, אפשר להרים מסד נתונים וכו׳ לאוויר עם API אבל זה נראה קצת overkill, במיוחד כאשר אתר התרגילים ישב באתר של הספר שבו יש את בקרת הכניסה. אני צריך קבצים טקסטואליים שיחזיקו את המידע על התרגילים, שהוא בעצם טקסט הכולל את השאלה ותצוגת קוד של התשובה (שהקוד הזה מוצג למשתמש רק לאחר לחיצה על כפתור ובעתיד תהיה גם דרך להריץ אותו ישירות על הדפדפן). פורמט טקסטואלי שיש בו מידע של טקסט וגם קוד? markdown הוא התשובה. הפורמט הזה מתוכנן להכיל כותרות, להכיל קוד ומידע אחר.

אבל כדי להציג אותו בריאקט, אני צריך parser שידע לקחת את ה-markdown ולהמיר אותו ל-HTML. ולכאן נכנסת בדיוק קומפוננטת React Markdown. קומפוננטה סופר מגניבה ופשוטה מאוד לשימוש שמקבלת markdown ומחזירה פלט נאה של HTML. יש לה גם דמו מגניב.

איך היא עובדת? מייד לאחר ההתקנה, אפשר להשתמש בה כך:

import ReactMarkdown from 'react-markdown';
<ReactMarkdown>{context.md}</ReactMarkdown>

זה הכל! אבל כמובן שהשימוש הבסיסי לא טוב מספיק. כי מה לעשות, כשאני כותב קוד אני לא רוצה שהוא יוצג כטקסט אפור ומשעמם ב-pre. אני רוצה לצבוע אותו. highlight כפי שנאמר. זו הסיבה שבקומפוננטה יש יכולת להעביר אובייקט שיש בו פירוט של האלמנטים השונים וקומפוננטות נוספות שיטפלו בהן. לצורך העניין, אני אבקש באמצעות ההגדרות האלו שכל אלמנט code יעבור דרך קומפוננטה אחרת שתצבע אותו. איך אני עושה את זה? כך:

<ReactMarkdown renderers={{ code: CodeBlock }}>{context.md}</ReactMarkdown>

קומפוננטת CodeBlock אחראית על הצביעה. איך בדיוק? ככה:

import React from 'react';
import SyntaxHighlighter from 'react-syntax-highlighter';
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';

export default function(props) {
  const { language, value } = props;
  return (
    <SyntaxHighlighter language={language} style={docco}>
      {value}
    </SyntaxHighlighter>);
}

כלומר כל קטע ב-markdown שאני מקיף ב:

```js
```

יקבל highlight באמצעות קומפוננטה אחרת שנקראת react-syntax-highlighter. בעתיד אני אוכל להשתמש באותה קומפוננטה על מנת להוסיף יכולות יותר מתקדמות. כך למשל, הגדרתי שאם אני כותב קטע קוד שבמקום js כתוב שם JSANSWER, התצוגה תהיה מעט שונה – בתוך תגית details.

```JSANSWER
```
import React from 'react';
import SyntaxHighlighter from 'react-syntax-highlighter';
import DetailsBlock from './../DetailsBlock';
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';
import ENUMS from '../../enums/MD_ENUMS';

export default function(props) {
  const { language, value } = props;
  let returnValue;
  if(language === ENUMS.JSANSWER) {
    returnValue = (
    <DetailsBlock>
      {value}
    </DetailsBlock>
    );
  } else {
    returnValue = (
    <SyntaxHighlighter language={language} style={docco}>
      {value}
    </SyntaxHighlighter>);
  }
  return returnValue;
}

אם תסתכלו על הקוד, תראו שאם השפה המתקבלת היא JSANSWER, שזה שם שאני המצאתי, מי שמטפל בהצגת המידע הזה הוא DetailsBlock. ושם אני מוסיף כבר יכולת להציג את הקוד רק אם הצופה לוחץ על כפתור. דבר אידיאלי לתשובות שאני לא רוצה לחשוף. בעתיד אני אוכל להוסיף שם יכולת להריץ את הקוד ואולי גם לערוך אותו ישירות.

הכוח של ריאקט, אנגולר או Vue הוא בדיוק במרכיבים האלו. הצלחתי תוך שעות בודדות של עבודה לייצר אתר עם פונקציונליות מלאה שמציג קוד, מציג טקסט מתוך קבצי markdown סטטיים. הקוד כבר צבוע בהתאם לשפה. עכשיו מה שנותר לי לעשות זה לכתוב 1,000 תרגילים.כמובן, אבל לפחות אני לא אצטרך לעבוד עם CMS ומול מסד נתונים מקוון אלא ישירות מול markdown קלים לתפעול ואידיאליים לסוג כזה של אתר.

פוסטים נוספים שכדאי לקרוא

רספברי פיי

מה זה AIoT? ואיך אפשר להתחיל?

פוסט עם המון קישורים, מידע, סרטונים ופרק בפודקאסט שיפתח לכם שער לעולם ה-AIoT המרתק.

בינה מלאכותית

Safeguards על מודל שפה גדול (LLM)

פוסט בשילוב עם פודקאסט וסרטון על ההגנות שאפשר להציב על LLM בסביבת פרודקשן

גלילה לראש העמוד