File size: 1,688 Bytes
4f3bb9d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// Wrap plain-text content inside <section class="code-outputs"> into a <pre>
export default function rehypeWrapOutput() {
  return (tree) => {
    const isWhitespace = (value) => typeof value === 'string' && !/\S/.test(value);
    const extractText = (node) => {
      if (!node) return '';
      if (node.type === 'text') return String(node.value || '');
      const kids = Array.isArray(node.children) ? node.children : [];
      return kids.map(extractText).join('');
    };
    const visit = (node) => {
      if (!node || typeof node !== 'object') return;
      const children = Array.isArray(node.children) ? node.children : [];
      if (node.type === 'element' && node.tagName === 'section') {
        const className = node.properties?.className || [];
        const classes = Array.isArray(className) ? className : [className].filter(Boolean);
        if (classes.includes('code-output')) {
          const meaningful = children.filter((c) => !(c.type === 'text' && isWhitespace(c.value)));
          if (meaningful.length === 1) {
            const only = meaningful[0];
            const isPlainParagraph = only.type === 'element' && only.tagName === 'p' && (only.children || []).every((c) => c.type === 'text');
            const isPlainText = only.type === 'text';
            if (isPlainParagraph || isPlainText) {
              const text = isPlainText ? String(only.value || '') : extractText(only);
              node.children = [
                { type: 'element', tagName: 'pre', properties: {}, children: [ { type: 'text', value: text } ] }
              ];
            }
          }
        }
      }
      children.forEach(visit);
    };
    visit(tree);
  };
}