notification

package
v0.6.1 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const FeedDigestLimit = 7

FeedDigestLimit caps how many recent digests appear in the RSS feed.

View Source
const ManifestFilename = "manifest.json"

ManifestFilename is the basename of the manifest checked into the Pages branch.

View Source
const RSSFilename = "rss.xml"

RSSFilename is the basename of the subscription feed written at the root of the Pages branch on every push.

Variables

This section is empty.

Functions

func BuildDigestFeeds added in v0.2.0

func BuildDigestFeeds(digests []models.Digest, outputDir, baseURL string) (rss []byte, err error)

BuildDigestFeeds renders an RSS feed for the given digests (expected newest-first). Each digest becomes one feed entry whose HTML body lists, for every article in the digest, its TLDR and key points. Links point at the published digest HTML page under baseURL/outputDir; when baseURL is empty the links are relative to the site root.

func CompileTermRegexp added in v0.5.0

func CompileTermRegexp(tags []string) *regexp.Regexp

CompileTermRegexp builds a single case-insensitive, word-bounded alternation that matches any of the given terms in prose, treating any internal run of non-alphanumeric characters as interchangeable with any other separator/punctuation (e.g. "cobalt-strike" matches "Cobalt Strike", "wscript.exe" matches "wscript-exe", "HTTP/3" matches "HTTP 3"). This separator equivalence MUST agree with NormalizeGlossaryKey (pkg/models/glossary.go) and the JS glossaryKey() normalizer in the digest template. Returns nil when there are no usable terms. Exported so digest generation matches stored glossary terms with the same semantics the rendered page highlights them with.

func DigestHTMLFilename

func DigestHTMLFilename(digest models.Digest) string

DigestHTMLFilename returns a filesystem-safe filename for the digest HTML file.

func LayoutScopedSubdir added in v0.6.1

func LayoutScopedSubdir(base, layout string, primary bool) string

LayoutScopedSubdir returns the GitHub Pages output subdir for a layout. The primary (first) layout keeps the base subdir so single-layout publishing is unchanged; additional layouts publish into "<base>-<layout>".

func OnDiskLayoutExists added in v0.4.0

func OnDiskLayoutExists(layout string) bool

OnDiskLayoutExists reports whether dir/<layout> exists under the configured layouts directory. Used to validate profile-selected layouts that are not compiled into the binary.

func ProfilesJSON added in v0.4.0

func ProfilesJSON(profiles []LandingProfile) ([]byte, error)

ProfilesJSON serializes the landing profiles for profiles.json (consumed by the in-page profile switcher and any external tooling).

func RenderDigestHTML

func RenderDigestHTML(digest models.Digest, layout, theme string, opts ...RenderOption) ([]byte, error)

RenderDigestHTML generates a self-contained HTML file for the given digest. The digest must have Articles, DigestAnalyses (with Analysis preloaded), and ProviderResults populated. layout selects the template set (a templates/<layout>/ directory); an empty string uses the default.

The provider/model switcher in the rendered page is populated client-side from manifest.json - the page itself only embeds the digest id and a hash of its article set used to filter siblings.

func RenderDigestIndex

func RenderDigestIndex(layout, theme string, opts ...RenderOption) ([]byte, error)

RenderDigestIndex generates the index HTML shell. The digest list is populated client-side by fetching manifest.json, so the rendered bytes are constant for a given template.

func RenderReportsPage added in v0.4.0

func RenderReportsPage(reports []aggregatedReport, layout, theme string, opts ...RenderOption) ([]byte, error)

RenderReportsPage generates the standalone "reports" page. Every referenced report is embedded as JSON so search, tag/category filtering, and sorting all run client-side with no fetch.

func RenderReportsPageForDigests added in v0.4.0

func RenderReportsPageForDigests(digests []models.Digest, layout, theme string, opts ...RenderOption) ([]byte, error)

RenderReportsPageForDigests aggregates the referenced reports across the given digests and renders the standalone reports page. It is the exported entry point for callers outside this package (the publisher and the dev preview server), since the aggregated report type is internal.

func RenderSourcesPage added in v0.4.0

func RenderSourcesPage(feeds []models.Feed, layout, theme string, opts ...RenderOption) ([]byte, error)

RenderSourcesPage generates the standalone "sources" page listing every enabled feed. The feeds are embedded server-side, so the rendered bytes are self-contained and need no client-side fetch. Disabled feeds are omitted.

func RenderSwipeHTML

func RenderSwipeHTML(digest models.Digest, digestFilename string, layout, theme string, opts ...RenderOption) ([]byte, error)

RenderSwipeHTML generates the self-contained Tinder-style triage page for a digest. digestFilename is the filename of the companion list-view page (used for the back link).

func SampleDigest added in v0.2.0

func SampleDigest(id string, createdAt time.Time) models.Digest

SampleDigest builds a small, fully-populated digest fixture for rendering without a database. It backs both the test suite and the digest dev server.

article-b scores 95 (Must Read) with full analysis and a referenced report; article-a scores 80 (Should Read) with minimal analysis.

func SendDiscordMessage

func SendDiscordMessage(webhookURL, content string) error

SendDiscordMessage posts a plain-text message to a Discord webhook URL. Intended for lightweight one-line notifications (e.g. "new page published").

func SetAssetDir added in v0.4.0

func SetAssetDir(dir string)

SetAssetDir switches built-asset loading to read from dir on disk. Pass an empty string to fall back to the embedded assets. Intended for the dev preview server.

func SetLayoutsDir added in v0.4.0

func SetLayoutsDir(dir string)

SetLayoutsDir registers an on-disk directory holding custom layouts. Pass an empty string to use only the embedded layouts.

func SetTemplateDir added in v0.2.0

func SetTemplateDir(dir string)

SetTemplateDir switches template loading to read from dir on disk. Pass an empty string to fall back to the embedded templates. Intended for the dev preview server.

func SwipeHTMLFilename

func SwipeHTMLFilename(digest models.Digest) string

SwipeHTMLFilename returns the filename for the swipe triage view of a digest.

Types

type ArticleEntry

type ArticleEntry struct {
	Id                  string
	Title               string
	Source              string
	Link                string
	PublishedAt         string
	Category            string   // article category (one of the fixed set), empty if unset
	Tags                []string // entity tags (actors/tools/techniques/country/stakeholders), without '#'
	ImportanceScore     int
	ReadTag             string
	DuplicateGroup      string
	IsMostComprehensive bool
	HasAnalysis         bool
	AnalysisError       string // non-empty when HasAnalysis is false and a classified error is available
	Analysis            *RenderedAnalysis
}

ArticleEntry holds enriched article data for template rendering

type DigestLister added in v0.2.0

type DigestLister func(limit int) ([]models.Digest, error)

DigestLister returns up to limit newest digests with full payload (provider results + analyses). It lets the publisher build the RSS feed without depending on the store: callers that have DB or client access supply it via SetDigestLister. A nil lister disables feed generation.

type DiscordEmbed

type DiscordEmbed struct {
	Title       string              `json:"title,omitempty"`
	Description string              `json:"description,omitempty"`
	Color       int                 `json:"color,omitempty"`
	Fields      []DiscordEmbedField `json:"fields,omitempty"`
	Timestamp   string              `json:"timestamp,omitempty"`
	Footer      *DiscordEmbedFooter `json:"footer,omitempty"`
	Image       *DiscordEmbedImage  `json:"image,omitempty"`
}

DiscordEmbed represents a Discord embed

type DiscordEmbedField

type DiscordEmbedField struct {
	Name   string `json:"name"`
	Value  string `json:"value"`
	Inline bool   `json:"inline,omitempty"`
}

DiscordEmbedField represents a field in a Discord embed

type DiscordEmbedFooter

type DiscordEmbedFooter struct {
	Text string `json:"text"`
}

DiscordEmbedFooter represents a footer in a Discord embed

type DiscordEmbedImage

type DiscordEmbedImage struct {
	URL string `json:"url"`
}

DiscordEmbedImage represents an image in a Discord embed

type DiscordNotifier

type DiscordNotifier struct {
	// contains filtered or unexported fields
}

DiscordNotifier implements the Notifier interface for Discord webhooks

func NewDiscordNotifier

func NewDiscordNotifier(webhookURL string) *DiscordNotifier

NewDiscordNotifier creates a new Discord notifier

func (*DiscordNotifier) SendDigest

func (d *DiscordNotifier) SendDigest(digest models.Digest) error

SendDigest sends a digest to Discord

func (*DiscordNotifier) SendHTMLFile

func (d *DiscordNotifier) SendHTMLFile(filename string, data []byte) error

SendHTMLFile uploads a digest HTML file to the Discord webhook as an attachment.

type DiscordWebhookPayload

type DiscordWebhookPayload struct {
	Content string         `json:"content,omitempty"`
	Embeds  []DiscordEmbed `json:"embeds,omitempty"`
}

DiscordWebhookPayload represents the Discord webhook message structure

type GitHubPagesPublisher

type GitHubPagesPublisher struct {
	// contains filtered or unexported fields
}

GitHubPagesPublisher publishes digest HTML files to a GitHub Pages repository.

Each publish writes the new digest HTML and updates a manifest.json that lists every published digest. Both the per-digest switcher and the index page are static shells that read manifest.json in the browser, so old HTML files are never rewritten on subsequent publishes.

func NewGitHubPagesPublisher

func NewGitHubPagesPublisher(cfg models.GitHubPagesNotificationConfig) *GitHubPagesPublisher

NewGitHubPagesPublisher creates a new GitHubPagesPublisher.

func (*GitHubPagesPublisher) InitPages

func (p *GitHubPagesPublisher) InitPages(reinit bool) error

InitPages sets up (or re-initialises) the GitHub Pages repository.

It creates the remote branch as a clean orphan if it is absent, optionally configures the GitHub Pages source via the API (when configure_pages is true), clones the branch locally, and seeds the initial static files (manifest.json and index pages). Files that already exist are not overwritten; the operation is idempotent.

When reinit is true the remote branch and the local clone directory are deleted before re-creating them from scratch.

func (*GitHubPagesPublisher) ManifestTitles

func (p *GitHubPagesPublisher) ManifestTitles() ([]string, error)

ManifestTitles clones (or updates) the repo and returns the list of digest titles from the manifest, newest-first. Returns an empty slice when the manifest has no entries.

func (*GitHubPagesPublisher) PublishAndWait added in v0.4.0

func (p *GitHubPagesPublisher) PublishAndWait(digest models.Digest) error

PublishAndWait publishes the digest and blocks until the pushed commit's GitHub Pages build deploys. It is the deploy-aware counterpart to SendDigest.

func (*GitHubPagesPublisher) RemoveDigest

func (p *GitHubPagesPublisher) RemoveDigest(title string) (string, error)

RemoveDigest removes the digest identified by title from the archive. It resolves the title to a filename via the manifest, deletes both the digest and swipe HTML files, updates manifest.json, commits, and pushes. It returns the SHA of the pushed commit so callers can wait for the corresponding GitHub Pages build to deploy (see WaitForPagesBuild).

func (*GitHubPagesPublisher) Republish added in v0.2.0

func (p *GitHubPagesPublisher) Republish(digest models.Digest, wait bool) error

Republish removes a single digest from the archive and re-publishes it with the current templates (equivalent to remove followed by add). The removal is always awaited before the re-add is pushed: GitHub cancels an in-flight Pages build when a newer commit lands, so pushing the re-add immediately would skip deploying the removal. The final deploy is only awaited when wait is true.

func (*GitHubPagesPublisher) RepublishAll

func (p *GitHubPagesPublisher) RepublishAll(digests []models.Digest, layout string, dryRun, wait, rebase bool) error

func (*GitHubPagesPublisher) RepublishAllLayouts added in v0.6.1

func (p *GitHubPagesPublisher) RepublishAllLayouts(digests []models.Digest, layouts []string, dryRun, wait, rebase bool) error

RepublishAll re-renders every digest with the current templates and pushes the result as a single commit. The manifest is rebuilt from scratch so stale entries are removed. Pass dryRun=true to render and stage locally without committing or pushing. When wait is true (and not a dry run) it blocks until the resulting GitHub Pages build deploys.

When rebase is true (and not a dry run) the branch is rebuilt as a single orphan commit and force-pushed, discarding all prior history. The rendered tree is complete on its own, so this keeps the Pages branch from accumulating a commit per publish — at the cost of an unrecoverable history rewrite. RepublishAllLayouts re-renders every published digest in each of the given layouts. The primary (first) layout keeps the base output subdir; each additional layout publishes into its own "<base>-<layout>" subdir, and every page gets the layout-switch UI so readers can move between coexisting layouts.

With zero or one effective layout it delegates to RepublishAll, leaving the single-layout path unchanged. Each layout is published independently (its own manifest, commit, and push) against the shared clone dir, mirroring how the server publishes multi-layout digests.

func (*GitHubPagesPublisher) RepublishIndex

func (p *GitHubPagesPublisher) RepublishIndex(dryRun, wait bool) error

RepublishIndex re-renders the archive index pages with the current templates and pushes the result as a single commit. The manifest and digest HTML files are not touched. Pass dryRun=true to write locally without committing. When wait is true (and not a dry run) it blocks until the resulting GitHub Pages build deploys.

func (*GitHubPagesPublisher) SendDigest

func (p *GitHubPagesPublisher) SendDigest(digest models.Digest) error

SendDigest renders the digest HTML, updates manifest.json, and pushes the result to the GitHub Pages repo. Old digest pages are not touched.

func (*GitHubPagesPublisher) SetDigestLister added in v0.2.0

func (p *GitHubPagesPublisher) SetDigestLister(fn DigestLister)

SetDigestLister attaches the lister used to fetch recent digests when building the RSS feed on each push. Passing nil disables feed generation.

func (*GitHubPagesPublisher) SetLanding added in v0.4.0

func (p *GitHubPagesPublisher) SetLanding(profiles []LandingProfile)

SetLanding supplies the public profile list. When more than one profile is given, the repo-root index.html becomes a landing page that links into each profile's section (plus a profiles.json), instead of mirroring a single profile's archive. With zero or one profile the historical single-site root index is kept.

func (*GitHubPagesPublisher) SetLayoutPeers added in v0.6.0

func (p *GitHubPagesPublisher) SetLayoutPeers(peers []LayoutPeer)

SetLayoutPeers records every layout published for this profile in the current run (including this publisher's own layout) with its output subdir. When two or more layouts coexist, the layout-switch snippet is injected so readers can move between them; with fewer than two peers switching stays inert.

func (*GitHubPagesPublisher) SetProfileContext added in v0.4.0

func (p *GitHubPagesPublisher) SetProfileContext(slug, theme string)

SetProfileContext records which profile is being published: its slug (for the switcher's active state) and its first-paint theme. Empty values keep today's defaults (no active highlight, dark theme).

func (*GitHubPagesPublisher) SetProgress added in v0.2.0

func (p *GitHubPagesPublisher) SetProgress(pr PublishProgress)

SetProgress attaches a PublishProgress sink so callers can render live step progress for publish/republish operations. Passing nil disables reporting.

func (*GitHubPagesPublisher) SetReportLister added in v0.4.0

func (p *GitHubPagesPublisher) SetReportLister(fn ReportLister)

SetReportLister attaches the lister used to gather referenced reports when building the reports page on each push. Passing nil disables the reports page.

func (*GitHubPagesPublisher) SetSourceLister added in v0.4.0

func (p *GitHubPagesPublisher) SetSourceLister(fn SourceLister)

SetSourceLister attaches the lister used to fetch the feed list when building the sources page on each push. Passing nil disables sources page generation.

func (*GitHubPagesPublisher) WaitForPagesBuild

func (p *GitHubPagesPublisher) WaitForPagesBuild(commitSHA string) error

WaitForPagesBuild blocks until the GitHub Pages build for commitSHA has finished deploying. It is a thin wrapper over waitForDeploy that does not emit step progress; kept for callers that only need the sequencing behaviour.

type GlossaryPanelEntry added in v0.4.0

type GlossaryPanelEntry struct {
	Term       string
	Type       string
	Definition string
	Aliases    []string // similar surface forms grouped under this term, shown as "also: …"
	Lvl        int      // help tier: 1=advanced, 2=intermediate, 3=beginner
}

GlossaryPanelEntry is one deduplicated term shown in the right-side glossary drawer (term + semantic type + general definition; no per-article context).

type Headline added in v0.4.0

type Headline struct {
	Title    string `json:"title"`
	Priority string `json:"priority,omitempty"`
}

Headline is one article headline in a manifest entry, paired with its importance priority ("must"/"should"/"may"/"opt").

type LandingProfile added in v0.4.0

type LandingProfile struct {
	Slug        string `json:"slug"`
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
	Icon        string `json:"icon,omitempty"`
	Subdir      string `json:"subdir"`
}

LandingProfile is one profile shown on the public root landing page and listed in profiles.json. Subdir is the (resolved) output directory the profile publishes under, used as the relative link target.

type LayoutPeer added in v0.6.0

type LayoutPeer struct {
	Layout string // layout name, e.g. "default" or "v2"
	Subdir string // output subdir the layout is published under, e.g. "digests-v2"
}

LayoutPeer is one layout published for the current profile in this run, paired with the output subdir it lives in. The layout-switch snippet uses the set of peers to move a reader between coexisting layouts (e.g. default <-> v2) by swapping the subdir segment in the URL.

type Manifest

type Manifest struct {
	GeneratedAt string          `json:"generated_at"`
	SourceRepo  string          `json:"source_repo"`
	Digests     []ManifestEntry `json:"digests"`
}

Manifest is the JSON document checked into the Pages branch listing every published digest. The digest index reads it directly in the browser.

func LoadManifest

func LoadManifest(path string) (Manifest, error)

LoadManifest reads the manifest at path. When the file is missing, it returns an empty manifest in the current schema.

func (*Manifest) FindByTitle

func (m *Manifest) FindByTitle(title string) (ManifestEntry, bool)

FindByTitle returns the first entry whose Title matches title (case-insensitive). The second return value is false when no match is found.

func (*Manifest) Prune added in v0.4.0

func (m *Manifest) Prune(cutoff time.Time) int

Prune removes entries whose PeriodStart is before cutoff, returning the count removed. Entries with a missing or unparseable PeriodStart are kept.

func (*Manifest) Remove

func (m *Manifest) Remove(filename string) bool

Remove removes the entry with the given filename from the manifest. Returns true if an entry was found and removed.

func (*Manifest) Upsert

func (m *Manifest) Upsert(entry ManifestEntry)

Upsert inserts entry or replaces an existing entry with the same filename, then re-sorts newest-first by filename timestamp.

func (Manifest) Write

func (m Manifest) Write(path string) error

Write atomically serializes the manifest to path.

type ManifestEntry

type ManifestEntry struct {
	Filename string `json:"filename"`
	// PeriodStart and PeriodEnd are the canonical, honestly-named bounds of the
	// digest's article-selection window (ISO "2006-01-02 15:04 UTC", machine-readable).
	PeriodStart string `json:"period_start,omitempty"`
	PeriodEnd   string `json:"period_end,omitempty"`
	// StartedAt is a deprecated legacy alias that holds the window END (not the
	// start). It is still written so entries published before period_end existed
	// keep round-tripping and the archive index can fall back to it. Prefer
	// PeriodEnd; remove once all historical entries have aged out.
	StartedAt    string     `json:"started_at"`
	TimeWindow   string     `json:"time_window"`
	ArticleCount int        `json:"article_count"`
	MustCount    int        `json:"must_count"`
	ShouldCount  int        `json:"should_count"`
	MayCount     int        `json:"may_count"`
	OptCount     int        `json:"opt_count"`
	Provider     string     `json:"provider"`
	Model        string     `json:"model"`
	Models       []string   `json:"models,omitempty"` // all unique model names across summary + article analysis
	Title        string     `json:"title,omitempty"`
	Headlines    []Headline `json:"headlines"`
	Summary      string     `json:"summary"`
}

ManifestEntry describes a single published digest in the manifest.

func ManifestEntryFromDigest

func ManifestEntryFromDigest(d models.Digest) ManifestEntry

ManifestEntryFromDigest builds a ManifestEntry for the given digest using the archive-index manifest schema.

type Notifier

type Notifier interface {
	SendDigest(digest models.Digest) error
}

Notifier defines the interface for sending digests to notification platforms

type OverviewSection

type OverviewSection struct {
	Tag   string        // e.g. "EXEC", "01", "02"
	Title string        // section heading
	Body  template.HTML // rendered markdown body
}

OverviewSection is a single cell in the Intelligence Brief 2-column grid.

type PublishProgress added in v0.2.0

type PublishProgress interface {
	Start(step, label string)                   // begin a step (spinner row)
	Update(step, label string)                  // relabel an in-flight step
	Complete(step string, ok bool, note string) // finish a step (✓ / ✗)
}

PublishProgress receives coarse step updates during publish/republish so a CLI front-end can render live progress. A nil PublishProgress disables reporting (used by the automatic server publish path).

type RenderOption added in v0.4.0

type RenderOption func(*renderConfig)

RenderOption tunes how a page is rendered. The zero set of options produces a fully self-contained page (CSS and JS inlined) — the default that Discord HTML attachments and the dev preview server rely on. The gh-pages publisher passes WithExternalCSS to link external assets instead.

func WithExternalCSS added in v0.4.0

func WithExternalCSS() RenderOption

WithExternalCSS makes a render link sibling .css/.js files (via <link> and <script src>) instead of inlining them. Only the published GitHub Pages site uses this; the files are written alongside the pages by the publisher. The small theme-dynamic palette and the blocking pre-paint scripts stay inline either way. The name is historical (it now covers scripts too).

type RenderedAnalysis

type RenderedAnalysis struct {
	ProviderType           string
	ModelName              string
	Tldr                   template.HTML
	PlainWords             template.HTML
	Justification          template.HTML
	BriefOverview          template.HTML
	StandardSynthesis      template.HTML
	ComprehensiveSynthesis template.HTML
	KeyPoints              []template.HTML
	Insights               []template.HTML
	ReferencedReports      []RenderedReport
	Rubric                 []RubricDimension // per-dimension 0-4 scores, for the v2 rubric grid; nil for legacy analyses
}

RenderedAnalysis holds markdown-converted HTML versions of analysis text fields. Text fields are template.HTML because matched entity tags are wrapped in <mark class="tag-hl"> at build time (see highlight* helpers).

type RenderedReport

type RenderedReport struct {
	Title     string
	URL       string
	Publisher string
	Category  string
	Primary   bool
	Context   template.HTML
}

RenderedReport is a referenced report prepared for the digest template, with its context prose tag-highlighted.

type ReportLister added in v0.4.0

type ReportLister func(since time.Time) ([]models.Digest, error)

ReportLister returns every digest created on/after since, newest first, with its Articles (incl. Tags) and DigestAnalyses (incl. Analysis) populated — the raw material the reports page aggregates. It lets the publisher build the reports page without depending on the store. A nil lister disables the page.

type RubricDimension added in v0.6.0

type RubricDimension struct {
	Label string // uppercased dimension name, e.g. "SEVERITY"
	Value int    // 0-4
}

RubricDimension is one scoring dimension surfaced to the template as a labelled 0-4 value, so a layout can render the rubric as a small bar grid. The set and order mirror the digest score rubric (see scoring.Dimensions / scoreTooltip).

type SourceLister added in v0.4.0

type SourceLister func() ([]models.Feed, error)

SourceLister returns every configured feed. It lets the publisher build the "sources" page without depending on the store: callers that have DB or client access supply it via SetSourceLister. A nil lister disables the sources page.

type TOCEntry

type TOCEntry struct {
	Id                  string
	Title               string
	Category            string // article category (one of the fixed set), empty if unset
	ImportanceScore     int
	ScoreTip            string // rubric dimension breakdown shown on hover, empty if no dimensions
	ReadTag             string
	DuplicateGroup      string
	IsMostComprehensive bool
}

TOCEntry holds data for a single article row in the table of contents.

type TOCGroup

type TOCGroup struct {
	Label string
	Rows  []TOCRow
}

TOCGroup is a labelled section in the table of contents.

type TOCRow

type TOCRow struct {
	IsCluster    bool
	Entry        TOCEntry        // used when IsCluster == false
	Canonical    TOCEntry        // used when IsCluster == true: the most-comprehensive article
	Others       []TOCEntry      // used when IsCluster == true: remaining members
	Group        string          // duplicate group key, used for colour
	Detail       *ArticleEntry   // full detail for non-cluster row
	CanonDetail  *ArticleEntry   // full detail for cluster canonical
	OtherDetails []*ArticleEntry // full detail for each cluster member
}

TOCRow is a single rendered row in a TOC group: either a plain article entry or a duplicate cluster (one canonical article + its alternates in a <details> block).

type TagCount

type TagCount struct {
	Name  string
	Count int
}

TagCount is a tag and the number of TOC rows that carry it (matching the row-level tag filter), used to render per-tag match counts in the filter cloud.

Directories

Path Synopsis
Package devserver runs a local HTTP preview of the digest HTML templates with browser live-reload.
Package devserver runs a local HTTP preview of the digest HTML templates with browser live-reload.

Jump to

Keyboard shortcuts

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