1# clib
2
3C implementations of performance-critical operations, integrated via [cgo](https://pkg.go.dev/cmd/cgo).
4
5## Why C?
6
7Some operations in Matcha benefit from dropping into C for speed and lower memory usage. The biggest wins are in image dimension queries (30,000x faster than Go's stdlib) and base64 wrapping for large attachments (3-4x faster).
8
9## Components
10
11### base64wrap
12
13MIME-compliant base64 line-wrapping (RFC 2045). Wraps base64-encoded strings at 76 characters with `\r\n` separators. Used by `sender/` for every attachment, inline image, and S/MIME signature.
14
15Files: `base64wrap.c`, `base64wrap.h`, `base64wrap.go`
16
17### imgconv
18
19Image decoding and PNG re-encoding using [stb_image](https://github.com/nothings/stb) (vendored single-header C libraries). No external system dependencies required.
20
21- `DecodeToPNG()` — decodes any image format (JPEG, PNG, BMP, GIF) and re-encodes to PNG. Used by `view/html.go` for inline email images.
22- `ImageDimensions()` — reads image width and height from the header only, without decoding pixel data. Used to calculate terminal row spacing for inline images.
23
24Files: `imgconv.c`, `imgconv.h`, `imgconv.go`, `stb_image.h`, `stb_image_write.h`
25
26### htmlconv
27
28Single-pass HTML-to-structured-elements parser. Takes raw HTML and returns a slice of `HTMLElement` values representing headings, links, images, blockquotes, tables, and text. Used by the email view to render HTML emails in the terminal without a full DOM.
29
30- `HTMLToElements()` — parses HTML into structured elements with type, text, and up to two attributes (e.g., `href`/`src`, `alt`/`cite`).
31
32Files: `htmlconv.c`, `htmlconv.h`, `htmlconv.go`
33
34### markdown
35
36Markdown-to-HTML conversion using [md4c](https://github.com/mity/md4c) (vendored). Supports GitHub-flavored features: tables, strikethrough, task lists, and permissive autolinks.
37
38- `MarkdownToHTML()` — converts Markdown bytes to HTML bytes.
39
40Files: `md4c.c`, `md4c.h`, `md4c-html.c`, `md4c-html.h`, `markdown.go`
41
42## Pure Go fallbacks
43
44Every function has a `_nocgo.go` counterpart (build tag `!cgo`) that provides the same API using pure Go libraries:
45
46| C implementation | Go fallback |
47|-----------------|-------------|
48| `base64wrap.go` | Manual string builder |
49| `imgconv.go` (stb_image) | `image/png`, `image/jpeg`, `image/gif` |
50| `htmlconv.go` | `goquery` DOM parsing |
51| `markdown.go` (md4c) | `goldmark` |
52
53## Adding new C code
54
551. Create `yourmodule.c` and `yourmodule.h` in this directory
562. Create `yourmodule.go` with cgo bindings (see `base64wrap.go` for a minimal example)
573. Add tests in `yourmodule_test.go`
584. If your C code uses `libm` or other system libraries, add `#cgo LDFLAGS: -lm` in the Go file