diff --git a/.github/scripts/build-docs.py b/.github/scripts/build-docs.py index 11269e4..d7a56ef 100644 --- a/.github/scripts/build-docs.py +++ b/.github/scripts/build-docs.py @@ -29,6 +29,74 @@ def save_code(m): text = text.replace(f'\x00CODE{i}\x00', f'{cs}') return text +def normalize_hyphenated_links(item_html): + if not re.fullmatch(r'(?:]*>.*?)(?:\s*-\s*]*>.*?)+', item_html): + return item_html + parts = re.findall(r']*>.*?', item_html) + return '
'.join(parts) + +def parse_list_block(lines, i, parent_indent=0): + if i >= len(lines): + return '', i + line = lines[i] + stripped = line.lstrip() + indent = len(line) - len(stripped) + if re.match(r'^[-*+]\s+', stripped): + list_tag = 'ul' + marker_re = r'^[-*+]\s+' + else: + olm = re.match(r'^\d+\.\s+', stripped) + if olm: + list_tag = 'ol' + marker_re = r'^\d+\.\s+' + else: + return '', i + + base_indent = indent + items = [] + while i < len(lines): + line = lines[i] + stripped = line.lstrip() + if stripped == '': + i += 1 + continue + indent = len(line) - len(stripped) + if indent < base_indent: + break + if not re.match(marker_re, stripped): + break + item_text = re.sub(marker_re, '', stripped) + item_html = inline_format(item_text) + i += 1 + + nested_html_parts = [] + while i < len(lines): + next_line = lines[i] + stripped2 = next_line.lstrip() + if stripped2 == '': + i += 1 + continue + indent2 = len(next_line) - len(stripped2) + if indent2 <= base_indent: + break + if stripped2.startswith('```'): + code_html, new_i = consume_code(lines, i) + nested_html_parts.append(code_html) + i = new_i + continue + nested_block, new_i = parse_list_block(lines, i, parent_indent=indent2) + if nested_block: + nested_html_parts.append(nested_block) + i = new_i + continue + nested_html_parts.append(f'

{inline_format(stripped2)}

') + i += 1 + + nested_html = ''.join(nested_html_parts) + items.append(f'
  • {item_html}{nested_html}
  • ') + + return f'<{list_tag}>\n' + '\n'.join(items) + f'\n', i + def consume_code(lines, i): lang = lines[i].lstrip()[3:].strip() indent = len(lines[i]) - len(lines[i].lstrip()) @@ -139,71 +207,15 @@ def md_to_html(md): continue # Ordered lists - olm = re.match(r'^\s*\d+\.\s+(.+)$', line) - if olm: - items = [] - while i < len(lines) and re.match(r'^\s*\d+\.\s+', lines[i]): - item_text = re.sub(r'^\s*\d+\.\s+', '', lines[i]) - item_html = inline_format(item_text) - i += 1 - extra = [] - while i < len(lines): - s = lines[i].lstrip() - indent = len(lines[i]) - len(s) - if indent >= 3 and s.startswith('```'): - ch, i = consume_code(lines, i) - extra.append(ch) - elif indent >= 3 and s.startswith('> '): - extra.append(f'
    {inline_format(s[2:])}
    ') - i += 1 - elif lines[i].strip() == '': - i += 1 - continue - elif indent >= 3 and s.strip(): - extra.append(inline_format(s)) - i += 1 - else: - break - items.append(f'
  • {" ".join(extra) if item_html == "" else item_html}{"".join(extra) if item_html != "" else ""}
  • ') - # Fix: combine item_html with extra - fixed_items = [] - for item in items: - fixed_items.append(item) - html.append('
      \n' + '\n'.join(items) + '\n
    ') + if re.match(r'^\s*\d+\.\s+', line): + list_html, i = parse_list_block(lines, i) + html.append(list_html) continue # Unordered lists - ulm = re.match(r'^[\s]*[-*+]\s+', line) - if ulm: - items = [] - while i < len(lines) and re.match(r'^[\s]*[-*+]\s+', lines[i]): - item_text = re.sub(r'^[\s]*[-*+]\s+', '', lines[i]) - item_html = inline_format(item_text) - i += 1 - extra = [] - while i < len(lines): - s = lines[i].lstrip() - indent = len(lines[i]) - len(s) - if indent >= 3 and s.startswith('```'): - ch, i = consume_code(lines, i) - extra.append(ch) - elif indent >= 3 and s.startswith('> '): - extra.append(f'
    {inline_format(s[2:])}
    ') - i += 1 - elif lines[i].strip() == '': - i += 1 - continue - elif indent >= 3 and s.strip(): - extra.append(inline_format(s)) - i += 1 - else: - break - items.append(f'
  • {" ".join(extra) if item_html == "" else item_html}{"".join(extra) if item_html != "" else ""}
  • ') - # Fix the combine - combined = [] - for item in items: - combined.append(item) - html.append('
      \n' + '\n'.join(items) + '\n
    ') + if re.match(r'^[\s]*[-*+]\s+', line): + list_html, i = parse_list_block(lines, i) + html.append(list_html) continue # Paragraph @@ -497,14 +509,12 @@ def make_page(title, body, slug, nav_template, footer_template, pages, is_index= .sidebar-content strong {{ color: var(--text); }} .sidebar-content a {{ color: var(--accent2); text-decoration: none; - word-break: break-word; overflow-wrap: anywhere; }} .sidebar-content a:hover {{ text-decoration: underline; }} .sidebar-content code {{ font-family: var(--mono); font-size: 0.82rem; background: var(--bg3); padding: 0.15rem 0.4rem; border-radius: 4px; color: var(--accent2); - word-break: break-word; overflow-wrap: anywhere; }} .sidebar-content pre {{ background: var(--bg2); border: 1px solid var(--border); @@ -535,6 +545,11 @@ def make_page(title, body, slug, nav_template, footer_template, pages, is_index= }} @media (max-width: 768px) {{ .copy-btn {{ opacity: 1; }} + .sidebar-content a {{ word-break: break-word; }} + .sidebar-content code {{ word-break: break-word; }} + .table-wrap {{ overflow-x: auto; -webkit-overflow-scrolling: touch; }} + .sidebar-content th {{ white-space: normal; word-break: break-word; }} + .sidebar-content td {{ word-break: break-word; }} }} .sidebar-content ul, .sidebar-content ol {{ color: var(--muted); line-height: 1.7; @@ -568,13 +583,11 @@ def make_page(title, body, slug, nav_template, footer_template, pages, is_index= text-transform: uppercase; letter-spacing: 0.06em; padding: 0.75rem 1rem; text-align: left; color: var(--muted); border-bottom: 1px solid var(--border); background: var(--bg3); - white-space: normal; - word-break: break-word; overflow-wrap: anywhere; + white-space: nowrap; }} .sidebar-content td {{ padding: 0.75rem 1rem; border-bottom: 1px solid var(--border); color: var(--muted); - word-break: break-word; }} .sidebar-content img {{ max-width: 100%; border-radius: 8px; border: 1px solid var(--border); @@ -703,6 +716,11 @@ def make_page(title, body, slug, nav_template, footer_template, pages, is_index= padding: 0.5rem 0.5rem; font-size: 0.78rem; }} + .sidebar-content a {{ word-break: break-word; }} + .sidebar-content code {{ word-break: break-word; }} + .table-wrap {{ overflow-x: auto; -webkit-overflow-scrolling: touch; }} + .sidebar-content th {{ white-space: normal; word-break: break-word; }} + .sidebar-content td {{ word-break: break-word; }} }}