| 79 | * Adds a bar above code blocks that shows the language and a copy button |
| 80 | */ |
| 81 | export default function addCodeHeader(node) { |
| 82 | // Check if the language matches `lang{:copy}` |
| 83 | const hasCopy = node.lang && COPY_REGEX.test(node.lang) |
| 84 | |
| 85 | if (hasCopy) { |
| 86 | // js{:copy} => js |
| 87 | node.lang = node.lang.replace(COPY_REGEX, '') |
| 88 | } else { |
| 89 | // It doesn't have the copy annotation, so don't add the header |
| 90 | return |
| 91 | } |
| 92 | |
| 93 | // Display the language using the above map of `{ [shortCode]: language }` |
| 94 | const language = LANGUAGE_MAP[node.lang] || node.lang || 'Code' |
| 95 | |
| 96 | const btnIconHtml = octicons.copy.toSVG() |
| 97 | const btnIconAst = parse(String(btnIconHtml), { sourceCodeLocationInfo: true }) |
| 98 | const btnIcon = fromParse5(btnIconAst, { file: btnIconHtml }) |
| 99 | |
| 100 | // Need to create the header using Markdown AST utilities, to fit |
| 101 | // into the Unified processor ecosystem. |
| 102 | const header = h( |
| 103 | 'header', |
| 104 | { |
| 105 | class: [ |
| 106 | 'd-flex', |
| 107 | 'flex-items-center', |
| 108 | 'flex-justify-between', |
| 109 | 'p-2', |
| 110 | 'text-small', |
| 111 | 'rounded-top-1', |
| 112 | 'border', |
| 113 | ], |
| 114 | }, |
| 115 | [ |
| 116 | h('span', language), |
| 117 | h( |
| 118 | 'button', |
| 119 | { |
| 120 | class: ['js-btn-copy', 'btn', 'btn-sm', 'tooltipped', 'tooltipped-nw'], |
| 121 | 'data-clipboard-text': node.value, |
| 122 | 'aria-label': 'Copy code to clipboard', |
| 123 | }, |
| 124 | btnIcon |
| 125 | ), |
| 126 | ] |
| 127 | ) |
| 128 | |
| 129 | return { |
| 130 | before: [header], |
| 131 | } |
| 132 | } |