Help us shape the future of Go! Take the 2026 Go Developer Survey

htmlcheck

package
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 7, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package htmlcheck implements the email-client compatibility report served at GET /api/v1/message/{id}/html_check.

Contract: takes an HTML body, returns an HtmlCheckReport with per-rule "issues" (lines + affected clients) and per-family support statistics weighted by market share.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CategoryCounts

type CategoryCounts struct {
	Desktop int `json:"desktop"`
	Mobile  int `json:"mobile"`
	Web     int `json:"web"`
}

CategoryCounts is the {desktop, mobile, web} triple used both for version counts and per-category support percents.

type Client

type Client struct {
	Family   string `json:"family"   yaml:"family"`
	Platform string `json:"platform" yaml:"platform"`
	Category string `json:"category" yaml:"category"`
	Support  string `json:"support"  yaml:"support"` // yes | no | partial
	//nolint:tagliatelle // embedded yaml data uses snake_case keys
	NoteNumbers []int    `json:"note_numbers,omitempty" yaml:"note_numbers"`
	Versions    Versions `json:"versions"               yaml:"versions"`

	// Filled in at response time:
	DisplayName string `json:"display_name,omitempty" yaml:"-"`
	FamilyGroup string `json:"family_group,omitempty" yaml:"-"`
}

Client is one mail-client/version row inside a rule's clients[]. The JSON shape (PascalCase-ish, snake_case keys) is what the SPA's HtmlCheckClient interface expects, so it's preserved exactly.

type FamilyReport

type FamilyReport struct {
	Family             string         `json:"family"`
	Label              string         `json:"label"`
	MarketShare        int            `json:"market_share"`
	SupportPercent     int            `json:"support_percent"`
	SupportPerCategory CategoryCounts `json:"support_per_category"`
	VersionCounts      CategoryCounts `json:"version_counts"`
}

FamilyReport mirrors HtmlCheckFamily on the SPA side.

type Issue

type Issue struct {
	RuleName      string            `json:"rule_name"`
	URL           string            `json:"url,omitempty"`
	ErrorLines    []int             `json:"error_lines"`
	Clients       []Client          `json:"clients"`
	NumberedNotes map[string]string `json:"numbered_notes"`
}

Issue is the per-rule report row the API returns. Builds during validation; merges multiple matches into one entry per rule.

type Report

type Report struct {
	Status               string         `json:"status"`
	MarketSupportPercent float64        `json:"market_support_percent"`
	Families             []FamilyReport `json:"families"`
	Issues               []Issue        `json:"issues"`
}

Report is the top-level shape returned by Service.Call.

func Run

func Run(htmlBody string) Report

Run is the package entrypoint: HTML body → Report.

Empty body returns {status: "no_html"}; everything else attempts a success report. Five-stage pipeline:

  1. Validate — run HTML XPath rules + inline-CSS rules; collect (line, rule) tuples.
  2. Group — merge multiple matches of the same rule into one Issue with a sorted ErrorLines list.
  3. Decorate — fill in client display names + family groups.
  4. Aggregate — compute per-family per-category support %.
  5. Roll up — market-share-weighted overall %.

type Rule

type Rule struct {
	Title         string            `yaml:"title"`
	ParserKey     string            `yaml:"parser_key"`  //nolint:tagliatelle // embedded yaml uses snake_case
	ParserType    string            `yaml:"parser_type"` //nolint:tagliatelle // embedded yaml uses snake_case
	URL           string            `yaml:"url"`
	Clients       []Client          `yaml:"clients"`
	NumberedNotes map[string]string `yaml:"numbered_notes"` //nolint:tagliatelle // embedded yaml uses snake_case
}

Rule is a single entry from html.yml or css.yml. ParserType selects the matching strategy; ParserKey is its argument.

type Versions

type Versions struct {
	Yes     []string `json:"yes,omitempty"     yaml:"yes"`
	No      []string `json:"no,omitempty"      yaml:"no"`
	Partial []string `json:"partial,omitempty" yaml:"partial"`
}

Versions is the {yes:[], no:[], partial:[]} block on each client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL