UNPKG

@knowcode/doc-builder

Version:

Reusable documentation builder for markdown-based sites with Vercel deployment support

352 lines (321 loc) 18.3 kB
/** * Emoji to Phosphor Icons mapping * Maps Unicode emojis to their Phosphor icon equivalents */ const emojiToPhosphor = { // Status & Validation '✅': '<i class="ph ph-check-circle" aria-label="checked"></i>', '✓': '<i class="ph ph-check" aria-label="check"></i>', '✔️': '<i class="ph ph-check-square" aria-label="checked"></i>', '❌': '<i class="ph ph-x-circle" aria-label="error"></i>', '❓': '<i class="ph ph-question" aria-label="question"></i>', '❗': '<i class="ph ph-warning" aria-label="warning"></i>', '⚠️': '<i class="ph ph-warning-circle" aria-label="warning"></i>', '⚖️': '<i class="ph ph-scales" aria-label="balance"></i>', '⛔': '<i class="ph ph-prohibit" aria-label="prohibited"></i>', '🚫': '<i class="ph ph-prohibit-inset" aria-label="not allowed"></i>', '🚨': '<i class="ph ph-siren" aria-label="alert"></i>', '🚧': '<i class="ph ph-barricade" aria-label="under construction"></i>', '🆘': '<i class="ph ph-first-aid" aria-label="emergency"></i>', // Development & Tech '💻': '<i class="ph ph-laptop" aria-label="laptop"></i>', '🖥️': '<i class="ph ph-desktop" aria-label="desktop"></i>', '📱': '<i class="ph ph-device-mobile" aria-label="mobile"></i>', '⌨️': '<i class="ph ph-keyboard" aria-label="keyboard"></i>', '🖱️': '<i class="ph ph-mouse" aria-label="mouse"></i>', '💾': '<i class="ph ph-floppy-disk" aria-label="save"></i>', '💿': '<i class="ph ph-disc" aria-label="disc"></i>', '🔧': '<i class="ph ph-wrench" aria-label="settings"></i>', '🔨': '<i class="ph ph-hammer" aria-label="build"></i>', '⚙️': '<i class="ph ph-gear" aria-label="settings"></i>', '🛠️': '<i class="ph ph-gear-six" aria-label="tools"></i>', '⚡': '<i class="ph ph-lightning" aria-label="fast"></i>', '🔌': '<i class="ph ph-plug" aria-label="plugin"></i>', '💡': '<i class="ph ph-lightbulb" aria-label="idea"></i>', '🐛': '<i class="ph ph-bug" aria-label="bug"></i>', '🐞': '<i class="ph ph-bug-beetle" aria-label="bug"></i>', '🤖': '<i class="ph ph-robot" aria-label="automation"></i>', '🐙': '<i class="ph ph-github-logo" aria-label="github"></i>', // Documents & Files '📝': '<i class="ph ph-note-pencil" aria-label="edit"></i>', '📄': '<i class="ph ph-file-text" aria-label="document"></i>', '📃': '<i class="ph ph-file" aria-label="file"></i>', '📋': '<i class="ph ph-clipboard-text" aria-label="clipboard"></i>', '📁': '<i class="ph ph-folder" aria-label="folder"></i>', '📂': '<i class="ph ph-folder-open" aria-label="open folder"></i>', '🗂️': '<i class="ph ph-folders" aria-label="folders"></i>', '🗃️': '<i class="ph ph-archive" aria-label="archive"></i>', '📚': '<i class="ph ph-books" aria-label="documentation"></i>', '📖': '<i class="ph ph-book-open" aria-label="reading"></i>', '📕': '<i class="ph ph-book" aria-label="book"></i>', '📗': '<i class="ph ph-book" aria-label="book"></i>', '📘': '<i class="ph ph-book" aria-label="book"></i>', '📙': '<i class="ph ph-book" aria-label="book"></i>', '📓': '<i class="ph ph-notebook" aria-label="notebook"></i>', '📔': '<i class="ph ph-notebook" aria-label="journal"></i>', // UI & Design '🎨': '<i class="ph ph-palette" aria-label="design"></i>', '🖌️': '<i class="ph ph-paint-brush" aria-label="paint"></i>', '🖍️': '<i class="ph ph-pencil" aria-label="draw"></i>', '✏️': '<i class="ph ph-pencil-simple" aria-label="edit"></i>', '✒️': '<i class="ph ph-pen" aria-label="write"></i>', '✍️': '<i class="ph ph-hand-waving" aria-label="writing"></i>', '🖊️': '<i class="ph ph-pen-nib" aria-label="pen"></i>', '🖋️': '<i class="ph ph-pen-nib-straight" aria-label="fountain pen"></i>', '🏷️': '<i class="ph ph-tag" aria-label="tag"></i>', '👁️': '<i class="ph ph-eye" aria-label="view"></i>', '🔵': '<i class="ph ph-circle" aria-label="blue circle"></i>', '🟦': '<i class="ph ph-square" aria-label="blue square"></i>', '📐': '<i class="ph ph-ruler" aria-label="measure"></i>', '📏': '<i class="ph ph-ruler" aria-label="ruler"></i>', // Actions & Navigation '🚀': '<i class="ph ph-rocket-launch" aria-label="launch"></i>', '✈️': '<i class="ph ph-airplane" aria-label="deploy"></i>', '🎯': '<i class="ph ph-target" aria-label="goal"></i>', '🏁': '<i class="ph ph-flag-checkered" aria-label="finish"></i>', '🚩': '<i class="ph ph-flag" aria-label="flag"></i>', '📍': '<i class="ph ph-push-pin" aria-label="pin"></i>', '📌': '<i class="ph ph-push-pin" aria-label="pinned"></i>', '🔗': '<i class="ph ph-link" aria-label="link"></i>', '⚓': '<i class="ph ph-anchor" aria-label="anchor"></i>', '🧭': '<i class="ph ph-compass" aria-label="navigation"></i>', '🗺️': '<i class="ph ph-map-trifold" aria-label="map"></i>', '🌐': '<i class="ph ph-globe" aria-label="global"></i>', '🌍': '<i class="ph ph-globe-hemisphere-west" aria-label="world"></i>', // Communication '📧': '<i class="ph ph-envelope" aria-label="email"></i>', '📨': '<i class="ph ph-envelope-open" aria-label="inbox"></i>', '📥': '<i class="ph ph-tray-arrow-down" aria-label="inbox"></i>', '📤': '<i class="ph ph-tray-arrow-up" aria-label="outbox"></i>', '📬': '<i class="ph ph-mailbox" aria-label="mailbox"></i>', '📮': '<i class="ph ph-mailbox" aria-label="postbox"></i>', '💬': '<i class="ph ph-chat-circle" aria-label="chat"></i>', '💭': '<i class="ph ph-chat-circle-dots" aria-label="thinking"></i>', '🗨️': '<i class="ph ph-chat-teardrop" aria-label="comment"></i>', '📢': '<i class="ph ph-megaphone" aria-label="announce"></i>', '📣': '<i class="ph ph-megaphone-simple" aria-label="broadcast"></i>', '🔔': '<i class="ph ph-bell" aria-label="notification"></i>', '🔕': '<i class="ph ph-bell-slash" aria-label="muted"></i>', // Security '🔐': '<i class="ph ph-lock-key" aria-label="secure"></i>', '🔒': '<i class="ph ph-lock" aria-label="locked"></i>', '🔓': '<i class="ph ph-lock-open" aria-label="unlocked"></i>', '🔑': '<i class="ph ph-key" aria-label="key"></i>', '🗝️': '<i class="ph ph-key" aria-label="key"></i>', '🛡️': '<i class="ph ph-shield" aria-label="security"></i>', '⚔️': '<i class="ph ph-sword" aria-label="battle"></i>', // Analytics & Data '📊': '<i class="ph ph-chart-bar" aria-label="chart"></i>', '📈': '<i class="ph ph-chart-line-up" aria-label="growth"></i>', '📉': '<i class="ph ph-chart-line-down" aria-label="decline"></i>', '🔍': '<i class="ph ph-magnifying-glass" aria-label="search"></i>', '🔎': '<i class="ph ph-magnifying-glass-plus" aria-label="zoom in"></i>', '🔬': '<i class="ph ph-flask" aria-label="experiment"></i>', '🔭': '<i class="ph ph-binoculars" aria-label="explore"></i>', // Time '⏰': '<i class="ph ph-alarm" aria-label="alarm"></i>', '⏱️': '<i class="ph ph-timer" aria-label="timer"></i>', '⏲️': '<i class="ph ph-timer" aria-label="stopwatch"></i>', '🕐': '<i class="ph ph-clock" aria-label="time"></i>', '📅': '<i class="ph ph-calendar" aria-label="calendar"></i>', '📆': '<i class="ph ph-calendar-blank" aria-label="date"></i>', '🗓️': '<i class="ph ph-calendar" aria-label="schedule"></i>', // Media '📷': '<i class="ph ph-camera" aria-label="photo"></i>', '📸': '<i class="ph ph-camera" aria-label="screenshot"></i>', '📹': '<i class="ph ph-video-camera" aria-label="video"></i>', '🎥': '<i class="ph ph-film-strip" aria-label="movie"></i>', '📽️': '<i class="ph ph-film-slate" aria-label="production"></i>', '🎬': '<i class="ph ph-film-slate" aria-label="action"></i>', '🎤': '<i class="ph ph-microphone" aria-label="microphone"></i>', '🎙️': '<i class="ph ph-microphone-stage" aria-label="studio microphone"></i>', '🎧': '<i class="ph ph-headphones" aria-label="audio"></i>', '🎵': '<i class="ph ph-music-note" aria-label="music"></i>', '🎶': '<i class="ph ph-music-notes" aria-label="music"></i>', '🔊': '<i class="ph ph-speaker-high" aria-label="volume high"></i>', '🔇': '<i class="ph ph-speaker-none" aria-label="muted"></i>', '🔈': '<i class="ph ph-speaker-low" aria-label="volume low"></i>', // Nature & Weather '☀️': '<i class="ph ph-sun" aria-label="sunny"></i>', '🌙': '<i class="ph ph-moon" aria-label="night"></i>', '⭐': '<i class="ph ph-star" aria-label="star"></i>', '🐧': '<i class="ph ph-penguin" aria-label="penguin"></i>', '🐳': '<i class="ph ph-whale" aria-label="whale"></i>', '🌟': '<i class="ph ph-star-four" aria-label="sparkle"></i>', '✨': '<i class="ph ph-sparkle" aria-label="special"></i>', '☁️': '<i class="ph ph-cloud" aria-label="cloud"></i>', '🌧️': '<i class="ph ph-cloud-rain" aria-label="rain"></i>', '❄️': '<i class="ph ph-snowflake" aria-label="snow"></i>', '🔥': '<i class="ph ph-fire" aria-label="hot"></i>', '💧': '<i class="ph ph-drop" aria-label="water"></i>', '🌊': '<i class="ph ph-waves" aria-label="wave"></i>', // People & Activities '👤': '<i class="ph ph-user" aria-label="user"></i>', '👥': '<i class="ph ph-users" aria-label="team"></i>', '👨‍💻': '<i class="ph ph-user-circle" aria-label="developer"></i>', '🏃': '<i class="ph ph-person-simple-run" aria-label="running"></i>', '🚶': '<i class="ph ph-person-simple-walk" aria-label="walking"></i>', '🤝': '<i class="ph ph-handshake" aria-label="partnership"></i>', '👍': '<i class="ph ph-thumbs-up" aria-label="approve"></i>', '👎': '<i class="ph ph-thumbs-down" aria-label="disapprove"></i>', '👏': '<i class="ph ph-hands-clapping" aria-label="applause"></i>', '🙌': '<i class="ph ph-hands-clapping" aria-label="celebrate"></i>', '💪': '<i class="ph ph-hand-fist" aria-label="strong"></i>', '💼': '<i class="ph ph-briefcase" aria-label="business"></i>', '👔': '<i class="ph ph-necktie" aria-label="formal wear"></i>', '🧠': '<i class="ph ph-brain" aria-label="thinking"></i>', // Objects & Things '🏠': '<i class="ph ph-house" aria-label="home"></i>', '🏢': '<i class="ph ph-buildings" aria-label="office"></i>', '🏰': '<i class="ph ph-castle-turret" aria-label="castle"></i>', '🏭': '<i class="ph ph-factory" aria-label="factory"></i>', '🚗': '<i class="ph ph-car" aria-label="car"></i>', '🚌': '<i class="ph ph-bus" aria-label="bus"></i>', '🚂': '<i class="ph ph-train" aria-label="train"></i>', '🚁': '<i class="ph ph-airplane" aria-label="helicopter"></i>', '🚢': '<i class="ph ph-boat" aria-label="ship"></i>', '🎁': '<i class="ph ph-gift" aria-label="gift"></i>', '🎈': '<i class="ph ph-balloon" aria-label="celebration"></i>', '🎉': '<i class="ph ph-confetti" aria-label="party"></i>', '🏆': '<i class="ph ph-trophy" aria-label="achievement"></i>', '🥇': '<i class="ph ph-medal" aria-label="first place"></i>', '🎮': '<i class="ph ph-game-controller" aria-label="gaming"></i>', '🎲': '<i class="ph ph-dice-five" aria-label="random"></i>', '🎴': '<i class="ph ph-cards" aria-label="flower cards"></i>', // Food & Drink '☕': '<i class="ph ph-coffee" aria-label="coffee"></i>', '🍔': '<i class="ph ph-hamburger" aria-label="burger"></i>', '🍕': '<i class="ph ph-pizza" aria-label="pizza"></i>', '🍰': '<i class="ph ph-cake" aria-label="cake"></i>', '🍺': '<i class="ph ph-beer-stein" aria-label="beer"></i>', '🍷': '<i class="ph ph-wine" aria-label="wine"></i>', // Money & Commerce '💰': '<i class="ph ph-money" aria-label="money"></i>', '💵': '<i class="ph ph-currency-dollar" aria-label="dollar"></i>', '💸': '<i class="ph ph-money-wavy" aria-label="money flying"></i>', '💳': '<i class="ph ph-credit-card" aria-label="payment"></i>', '🏦': '<i class="ph ph-bank" aria-label="bank"></i>', '🏥': '<i class="ph ph-hospital" aria-label="hospital"></i>', '🏛️': '<i class="ph ph-buildings" aria-label="institution"></i>', '🛒': '<i class="ph ph-shopping-cart" aria-label="cart"></i>', '🛍️': '<i class="ph ph-shopping-bag" aria-label="shopping"></i>', '📦': '<i class="ph ph-package" aria-label="package"></i>', // Symbols '➕': '<i class="ph ph-plus" aria-label="add"></i>', '➖': '<i class="ph ph-minus" aria-label="remove"></i>', '✖️': '<i class="ph ph-x" aria-label="close"></i>', '🗑️': '<i class="ph ph-trash" aria-label="delete"></i>', '♻️': '<i class="ph ph-recycle" aria-label="recycle"></i>', '❤️': '<i class="ph ph-heart" aria-label="love"></i>', '💔': '<i class="ph ph-heart-break" aria-label="broken heart"></i>', '⏭️': '<i class="ph ph-skip-forward" aria-label="next"></i>', '⏮️': '<i class="ph ph-skip-back" aria-label="previous"></i>', '⏸️': '<i class="ph ph-pause" aria-label="pause"></i>', '▶️': '<i class="ph ph-play" aria-label="play"></i>', '⏹️': '<i class="ph ph-stop" aria-label="stop"></i>', '🔄': '<i class="ph ph-arrows-clockwise" aria-label="refresh"></i>', // Special '🌈': '<i class="ph ph-rainbow" aria-label="diversity"></i>', '🦄': '<i class="ph ph-shooting-star" aria-label="unique"></i>', '🎭': '<i class="ph ph-mask-happy" aria-label="theater"></i>', '🎪': '<i class="ph ph-tent" aria-label="circus"></i>', '🏳️': '<i class="ph ph-flag" aria-label="flag"></i>', '🏴': '<i class="ph ph-flag" aria-label="flag"></i>', '🏴‍☠️': '<i class="ph ph-skull" aria-label="danger"></i>', // Additional Characters '📡': '<i class="ph ph-broadcast" aria-label="broadcast"></i>', '🕵️': '<i class="ph ph-detective" aria-label="detective"></i>', '🏪': '<i class="ph ph-storefront" aria-label="store"></i>', '🏗️': '<i class="ph ph-crane" aria-label="construction"></i>', '🔀': '<i class="ph ph-shuffle" aria-label="shuffle"></i>', '💎': '<i class="ph ph-diamond" aria-label="diamond"></i>', '🤔': '<i class="ph ph-question" aria-label="thinking"></i>', '🧪': '<i class="ph ph-test-tube" aria-label="test"></i>', '👑': '<i class="ph ph-crown" aria-label="crown"></i>', '🔢': '<i class="ph ph-hash" aria-label="numbers"></i>', '🎓': '<i class="ph ph-graduation-cap" aria-label="graduation"></i>', '🏔️': '<i class="ph ph-mountains" aria-label="mountain"></i>', '🏞️': '<i class="ph ph-park" aria-label="nature"></i>', '🌅': '<i class="ph ph-sunrise" aria-label="sunrise"></i>', '♿': '<i class="ph ph-wheelchair" aria-label="accessibility"></i>', '🌓': '<i class="ph ph-moon-stars" aria-label="half moon"></i>', '🃏': '<i class="ph ph-cards" aria-label="joker card"></i>', '🧩': '<i class="ph ph-puzzle-piece" aria-label="puzzle"></i>', '⏳': '<i class="ph ph-hourglass" aria-label="hourglass"></i>', '👆': '<i class="ph ph-hand-point-up" aria-label="point up"></i>', '📑': '<i class="ph ph-file-text" aria-label="document"></i>', '💀': '<i class="ph ph-skull" aria-label="skull"></i>', '🔤': '<i class="ph ph-textbox" aria-label="letters"></i>', '🧱': '<i class="ph ph-wall" aria-label="brick"></i>', '🖼️': '<i class="ph ph-image" aria-label="picture"></i>', '🎂': '<i class="ph ph-cake" aria-label="birthday"></i>', '↩️': '<i class="ph ph-arrow-u-left" aria-label="return"></i>', '📜': '<i class="ph ph-scroll" aria-label="scroll"></i>', '🕰️': '<i class="ph ph-clock" aria-label="clock"></i>', '🧮': '<i class="ph ph-calculator" aria-label="calculator"></i>', '🎫': '<i class="ph ph-ticket" aria-label="ticket"></i>', '🌿': '<i class="ph ph-leaf" aria-label="leaf"></i>', '🥊': '<i class="ph ph-boxing-glove" aria-label="boxing"></i>', '🎛️': '<i class="ph ph-faders" aria-label="controls"></i>', '🗣️': '<i class="ph ph-megaphone-simple" aria-label="speaking"></i>', '💝': '<i class="ph ph-gift" aria-label="gift with bow"></i>', '🐌': '<i class="ph ph-spiral" aria-label="snail"></i>', }; /** * Replace emojis with Phosphor icons in HTML * @param {string} html - The HTML content to process * @param {object} config - Configuration options * @returns {string} - HTML with emojis replaced by icons */ function replaceEmojisWithIcons(html, config = {}) { // Check if feature is enabled - default to true if not explicitly set to false if (config.features?.phosphorIcons === false) return html; // First, protect code blocks and inline code from emoji replacement const codeBlocks = []; const codePattern = /(<code[^>]*>[\s\S]*?<\/code>|<pre[^>]*>[\s\S]*?<\/pre>)/g; // Replace code blocks with placeholders html = html.replace(codePattern, (match, p1) => { const placeholder = `CODE_BLOCK_${codeBlocks.length}`; codeBlocks.push(match); return placeholder; }); // Build regex pattern once with all emoji patterns // Sort by length to match longer emojis first (e.g., ⚠️ before ⚠) const emojiPattern = new RegExp( Object.keys(emojiToPhosphor) .sort((a, b) => b.length - a.length) .map(emoji => emoji.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) .join('|'), 'g' ); // Get weight class if custom weight is specified const weightClass = config.features?.phosphorWeight && config.features.phosphorWeight !== 'regular' ? `ph-${config.features.phosphorWeight}` : 'ph'; // Apply size styling if configured const sizeStyle = config.features?.phosphorSize ? ` style="font-size: ${config.features.phosphorSize}"` : ''; html = html.replace(emojiPattern, match => { let iconHtml = emojiToPhosphor[match]; if (!iconHtml) return match; // Update weight class if not regular if (weightClass !== 'ph') { iconHtml = iconHtml.replace('class="ph ', `class="${weightClass} `); } // Apply custom size if configured if (sizeStyle) { iconHtml = iconHtml.replace('<i class="', `<i${sizeStyle} class="`); } return iconHtml; }); // Restore code blocks codeBlocks.forEach((block, index) => { html = html.replace(`CODE_BLOCK_${index}`, block); }); return html; } module.exports = { emojiToPhosphor, replaceEmojisWithIcons };