importFromMarkdown method

Root importFromMarkdown(
  1. String md
)

Implementation

Root importFromMarkdown(String md) {
  try {
    final lines = md.split('\n');
    final nodes = <FNode>[];
    int i = 0;

    while (i < lines.length) {
    final line = lines[i];
    final trimmed = line.trim();

    if (trimmed.isEmpty) {
      i++;
      continue;
    }

    // Horizontal rule
    if (RegExp(r'^(---|\*\*\*|___)\s*$').hasMatch(trimmed)) {
      nodes.add(HorizontalRule());
      i++;
      continue;
    }

    // Heading
    if (trimmed.startsWith('#')) {
      final match = RegExp(r'^(#{1,6})\s+(.*)$').firstMatch(trimmed);
      if (match != null) {
        final level = match.group(1)!.length;
        final text = match.group(2)!;
        nodes.add(Paragraph(
          text: '',
          styleName: 'heading$level',
        )..fragments = _parseInline(text));
        i++;
        continue;
      }
    }

    // Blockquote
    if (trimmed.startsWith('>')) {
      final buffer = StringBuffer();
      while (i < lines.length && lines[i].trimLeft().startsWith('>')) {
        buffer.writeln(lines[i].trimLeft().substring(1).trimLeft());
        i++;
      }
      nodes.add(Paragraph(
        text: '',
        styleName: 'quote',
      )..fragments = _parseInline(buffer.toString().trim()));
      continue;
    }

    // Code block
    if (trimmed.startsWith('```')) {
      i++;
      final buffer = StringBuffer();
      while (i < lines.length && !lines[i].trim().startsWith('```')) {
        buffer.writeln(lines[i]);
        i++;
      }
      i++;
      nodes.add(Paragraph(
        text: '',
        styleName: 'code',
      )..fragments = [Fragment(buffer.toString().trimRight())]);
      continue;
    }

    // Table
    if (line.trim().startsWith('|')) {
      final table = _parseTable(lines, i);
      if (table != null) {
        nodes.add(table.node);
        i = table.nextIndex;
        continue;
      }
    }

    // Checkbox list
    if (RegExp(r'^(\s*)-\s\[[ x~]\]\s').hasMatch(line)) {
      final list = _parseCheckboxList(lines, i);
      nodes.add(list.node);
      i = list.nextIndex;
      continue;
    }

    // Unordered list
    if (RegExp(r'^(\s*)[-*+]\s').hasMatch(line)) {
      final list = _parseList(lines, i, 'bullet');
      nodes.add(list.node);
      i = list.nextIndex;
      continue;
    }

    // Ordered list
    if (RegExp(r'^(\s*)\d+\.\s').hasMatch(line)) {
      final list = _parseList(lines, i, 'ordered');
      nodes.add(list.node);
      i = list.nextIndex;
      continue;
    }

    // Regular paragraph
    final buffer = StringBuffer();
    while (i < lines.length && lines[i].trim().isNotEmpty) {
      buffer.write(lines[i].trim());
      if (i < lines.length - 1 && lines[i + 1].trim().isNotEmpty) {
        buffer.write(' ');
      }
      i++;
    }
    nodes.add(Paragraph(text: '')..fragments = _parseInline(buffer.toString()));
  }

    return Root(nodes: nodes.isEmpty ? [Paragraph(text: '')] : nodes);
  } catch (e) {
    // Gracefully return a document with the error as a paragraph
    return Root(nodes: [Paragraph(text: 'Import error: $e')]);
  }
}