Skip to content

Output Formats

The HTML library supports outputting extraction results as Markdown or JSON format.

Markdown Output

Extract HTML content and convert to Markdown format. Internally it sets both InlineImageFormat and InlineLinkFormat to markdown before extracting, and ultimately returns Result.Text.

WARNING

ExtractToMarkdown neither hits nor writes to the main Processor's cache. It builds a transient Processor via buildFormatProcessor:

  • It performs a value copy of the current configuration (config is immutable after New(), so the copy needs no lock) and then overrides the two format fields — the format settings are never written back to the shared config
  • Cache is disabled (MaxCacheEntries = 0): it neither reads from nor writes to the main Processor's cache, preventing format-specific results from polluting the main cache
  • It reuses the main Processor's Scorer but uses an independent, disabled audit collector, ensuring that the main Processor's Close() does not race with an in-flight extraction
  • This mechanism is thread-safe

If you want extraction to go through the cache, use the regular Extract instead and configure InlineImageFormat/InlineLinkFormat yourself.

Package Functions

go
func ExtractToMarkdown(htmlBytes []byte, cfg ...Config) (string, error)
func ExtractToMarkdownFromFile(filePath string, cfg ...Config) (string, error)
func ExtractToMarkdownWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) (string, error)
func ExtractToMarkdownFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) (string, error)

Processor Methods

go
func (p *Processor) ExtractToMarkdown(htmlBytes []byte) (string, error)
func (p *Processor) ExtractToMarkdownFromFile(filePath string) (string, error)
func (p *Processor) ExtractToMarkdownWithContext(ctx context.Context, htmlBytes []byte) (string, error)
func (p *Processor) ExtractToMarkdownFromFileWithContext(ctx context.Context, filePath string) (string, error)

Example

go
package main

import (
	"fmt"
	"log"

	"github.com/cybergodev/html"
)

func main() {
	data := []byte(`<html><head><title>Example Document</title></head><body>
<p>A body paragraph that contains an image.</p>
<p><img src="/img/photo.png" alt="Example image"></p>
<p>Visit <a href="https://example.com">example site</a> to learn more.</p>
</body></html>`)

	md, err := html.ExtractToMarkdown(data, html.MarkdownConfig())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(md)
	// Output: Markdown text containing the image and the link,
	//         e.g. ![Example image](/img/photo.png) and [example site](https://example.com)
}

Format Options

ExtractToMarkdown always uses the markdown format. If you need other inline formats, use the regular Extract together with the following Config fields:

FieldOptional valuesEffect
InlineImageFormatnone (default)Images are not inlined into the text
markdownOutputs ![alt](url)
htmlOutputs <img src="url" alt="alt">
placeholderOutputs a placeholder [IMAGE:N]
InlineLinkFormatnone (default)Links are not inlined into the text
markdownOutputs [text](url)
htmlOutputs <a href="url">text</a>

Markdown Formatting Mechanism

Inline images and links are produced via placeholder replacement in two steps:

  1. Text extraction phase: each <img> inserts a placeholder [IMAGE:N] in the text stream, and each <a> inserts a paired [LINK:N]...[/LINK] (N is a positional index that corresponds one-to-one with the Position in the Images/Links slices)
  2. Formatting phase: according to InlineImageFormat/InlineLinkFormat, the placeholders are replaced with the target format (markdown/html) or removed outright (none)

To prevent literal [/] in the source text from being mistaken for placeholders, the extraction phase escapes them (\[, \], \\), and the formatting phase restores them.

JSON Output

Serialize the extraction result to JSON bytes. Unlike Markdown, this method goes through the main Processor's normal Extract (hitting/writing the cache when enabled) and then serializes via json.Marshal.

Package Functions

go
func ExtractToJSON(htmlBytes []byte, cfg ...Config) ([]byte, error)
func ExtractToJSONFromFile(filePath string, cfg ...Config) ([]byte, error)
func ExtractToJSONWithContext(ctx context.Context, htmlBytes []byte, cfg ...Config) ([]byte, error)
func ExtractToJSONFromFileWithContext(ctx context.Context, filePath string, cfg ...Config) ([]byte, error)

Processor Methods

go
func (p *Processor) ExtractToJSON(htmlBytes []byte) ([]byte, error)
func (p *Processor) ExtractToJSONFromFile(filePath string) ([]byte, error)
func (p *Processor) ExtractToJSONWithContext(ctx context.Context, htmlBytes []byte) ([]byte, error)
func (p *Processor) ExtractToJSONFromFileWithContext(ctx context.Context, filePath string) ([]byte, error)

Example

go
package main

import (
	"fmt"
	"log"

	"github.com/cybergodev/html"
)

func main() {
	data := []byte(`<html><head><title>Example Document</title></head><body>
<p>This is a body paragraph.</p>
<p><img src="/img/photo.png" alt="Example image"></p>
<a href="https://example.com">example site</a>
</body></html>`)

	jsonBytes, err := html.ExtractToJSON(data)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(jsonBytes))
	// Output: a JSON string containing fields such as text/title/images/links
}

JSON Output Structure

JSON serialization is a custom implementation via Result.MarshalJSON(), corresponding to the internal structure jsonResult:

JSON fieldTypeSource
textstringResult.Text (extracted body)
titlestringResult.Title (document title)
imagesarrayResult.Images (omitempty, omitted when empty)
linksarrayResult.Links (omitempty)
videosarrayResult.Videos (omitempty)
audiosarrayResult.Audios (omitempty)
processing_time_msintResult.ProcessingTime converted to milliseconds
word_countintResult.WordCount
reading_time_msintResult.ReadingTime converted to milliseconds

Note that ProcessingTime and ReadingTime carry a json:"-" tag on the Result struct (standard serialization skips them); the custom MarshalJSON is what includes them as millisecond values in the output. The JSON format is intended for external consumption and does not implement UnmarshalJSON, so it cannot be deserialized back into a Result as-is.

TIP

Result implements the json.Marshaler interface. The ProcessingTime and ReadingTime fields have json:"-" tags (standard serialization skips them), but the custom MarshalJSON() method includes them as millisecond values in the output.