parse method Null safety

void parse(
  1. BuildMetadata meta
)

Parses meta for build ops and text styles.

Implementation

void parse(BuildMetadata meta) {
  final attrs = meta.element.attributes;

  switch (meta.element.localName) {
    case kTagA:
      _tagA ??= TagA(this).buildOp;
      meta.register(_tagA!);

      meta.tsb.enqueue(
        _tagAColor ??= (tsh, _) => tsh.copyWith(
              style: tsh.style.copyWith(
                color: tsh.getDependency<ThemeData>().colorScheme.primary,
              ),
            ),
      );

      final name = attrs[kAttributeAName];
      if (name != null) {
        meta.register(_anchorOp(name));
      }
      break;

    case 'abbr':
    case 'acronym':
      meta[kCssTextDecorationLine] = kCssTextDecorationUnderline;
      meta[kCssTextDecorationStyle] = kCssTextDecorationStyleDotted;
      break;

    case 'address':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..tsb.enqueue(TextStyleOps.fontStyle, FontStyle.italic);
      break;

    case 'article':
    case 'aside':
    case 'div':
    case 'figcaption':
    case 'footer':
    case 'header':
    case 'main':
    case 'nav':
    case 'section':
      meta[kCssDisplay] = kCssDisplayBlock;
      break;

    case 'blockquote':
    case 'figure':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '1em 40px';
      break;

    case 'b':
    case 'strong':
      meta.tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;

    case 'big':
      meta.tsb.enqueue(TextStyleOps.fontSizeTerm, kCssFontSizeLarger);
      break;
    case 'small':
      meta.tsb.enqueue(TextStyleOps.fontSizeTerm, kCssFontSizeSmaller);
      break;

    case kTagBr:
      meta.register(_tagBr ??= TagBr(this).buildOp);
      break;

    case kTagCenter:
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssTextAlign] = kCssTextAlignWebkitCenter;
      break;

    case 'cite':
    case 'dfn':
    case 'em':
    case 'i':
    case 'var':
      meta.tsb.enqueue(TextStyleOps.fontStyle, FontStyle.italic);
      break;

    case kTagCode:
    case kTagKbd:
    case kTagSamp:
    case kTagTt:
      meta.tsb.enqueue(
        TextStyleOps.fontFamily,
        const [kTagCodeFont1, kTagCodeFont2],
      );
      break;
    case kTagPre:
      _tagPre ??= BuildOp(
        onWidgets: (meta, widgets) => listOrNull(
          buildColumnPlaceholder(meta, widgets)
              ?.wrapWith((_, w) => buildHorizontalScrollView(meta, w)),
        ),
      );
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssWhitespace] = kCssWhitespacePre
        ..tsb.enqueue(
          TextStyleOps.fontFamily,
          const [kTagCodeFont1, kTagCodeFont2],
        )
        ..register(_tagPre!);
      break;

    case kTagDetails:
      meta.register(TagDetails(this, meta).op);
      break;

    case 'dd':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '0 0 1em 40px';
      break;
    case 'dl':
      meta[kCssDisplay] = kCssDisplayBlock;
      break;
    case 'dt':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;

    case 'del':
    case 's':
    case 'strike':
      meta[kCssTextDecorationLine] = kCssTextDecorationLineThrough;
      break;

    case kTagFont:
      _tagFont ??= BuildOp(
        defaultStyles: (element) {
          final attrs = element.attributes;
          final color = attrs[kAttributeFontColor];
          final fontFace = attrs[kAttributeFontFace];
          final fontSize = kCssFontSizes[attrs[kAttributeFontSize] ?? ''];
          return {
            if (color != null) kCssColor: color,
            if (fontFace != null) kCssFontFamily: fontFace,
            if (fontSize != null) kCssFontSize: fontSize,
          };
        },
      );
      meta.register(_tagFont!);
      break;

    case 'hr':
      _tagHr ??=
          BuildOp(onWidgets: (meta, _) => listOrNull(buildDivider(meta)));
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin + kSuffixBottom] = '1em'
        ..register(_tagHr!);
      break;

    case 'h1':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '0.67em 0'
        ..tsb.enqueue(TextStyleOps.fontSizeEm, 2.0)
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;
    case 'h2':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '0.83em 0'
        ..tsb.enqueue(TextStyleOps.fontSizeEm, 1.5)
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;
    case 'h3':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '1em 0'
        ..tsb.enqueue(TextStyleOps.fontSizeEm, 1.17)
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;
    case 'h4':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '1.33em 0'
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;
    case 'h5':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '1.67em 0'
        ..tsb.enqueue(TextStyleOps.fontSizeEm, .83)
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;
    case 'h6':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '2.33em 0'
        ..tsb.enqueue(TextStyleOps.fontSizeEm, .67)
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;

    case kTagImg:
      _tagImg ??= TagImg(this).buildOp;
      meta.register(_tagImg!);
      break;

    case 'ins':
    case 'u':
      meta[kCssTextDecorationLine] = kCssTextDecorationUnderline;
      break;

    case kTagOrderedList:
    case kTagUnorderedList:
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..register(TagLi(this, meta).op);
      break;

    case 'mark':
      meta
        ..[kCssBackgroundColor] = '#ff0'
        ..[kCssColor] = '#000';
      break;

    case 'p':
      meta
        ..[kCssDisplay] = kCssDisplayBlock
        ..[kCssMargin] = '1em 0';
      break;

    case kTagQ:
      _tagQ ??= TagQ(this).buildOp;
      meta.register(_tagQ!);
      break;

    case kTagRuby:
      meta.register(TagRuby(this, meta).op);
      break;

    case 'script':
    case 'style':
      meta[kCssDisplay] = kCssDisplayNone;
      break;

    case 'sub':
      meta
        ..[kCssVerticalAlign] = kCssVerticalAlignSub
        ..tsb.enqueue(TextStyleOps.fontSizeTerm, kCssFontSizeSmaller);
      break;
    case 'sup':
      meta
        ..[kCssVerticalAlign] = kCssVerticalAlignSuper
        ..tsb.enqueue(TextStyleOps.fontSizeTerm, kCssFontSizeSmaller);
      break;

    case kTagTable:
      meta
        ..[kCssDisplay] = kCssDisplayTable
        ..register(
          TagTable.borderOp(
            tryParseDoubleFromMap(attrs, kAttributeBorder) ?? 0.0,
            tryParseDoubleFromMap(attrs, kAttributeCellSpacing) ?? 2.0,
          ),
        )
        ..register(
          TagTable.cellPaddingOp(
            tryParseDoubleFromMap(attrs, kAttributeCellPadding) ?? 1.0,
          ),
        );
      break;
    case kTagTableCell:
      meta[kCssVerticalAlign] = kCssVerticalAlignMiddle;
      break;
    case kTagTableHeaderCell:
      meta
        ..[kCssVerticalAlign] = kCssVerticalAlignMiddle
        ..tsb.enqueue(TextStyleOps.fontWeight, FontWeight.bold);
      break;
    case kTagTableCaption:
      meta[kCssTextAlign] = kCssTextAlignCenter;
      break;
  }

  for (final attribute in attrs.entries) {
    switch (attribute.key) {
      case kAttributeAlign:
        meta[kCssTextAlign] = attribute.value;
        break;
      case kAttributeDir:
        meta[kCssDirection] = attribute.value;
        break;
      case kAttributeId:
        meta.register(_anchorOp(attribute.value));
        break;
    }
  }
}