Documentation
¶
Overview ¶
Package themecore implements the Umono theme engine. This file defines the v0.9 media-feature dictionary, the media types, accepted length and resolution units, and the helpers that validate a media feature's parenthesised content.
Package themecore is the shared static analysis package of the Umono theme system. The Umono runtime and the Umono CLI use it to check theme packages.
Index ¶
- Variables
- func Builtins() []string
- func CheckSource(dir string, contract []byte) (Package, BuildReport, error)
- func Checksums(p Package) ([]byte, error)
- func DetectorCorpus() error
- func FallbackCSS() []byte
- func FallbackSource() []byte
- func MarkdownElements() []string
- func TOMLConformance() error
- func ThemeAPICurrent() int
- func ThemeAPIMin() int
- func Transform(css []byte) (out []byte, err error)
- func Verify(css []byte) error
- func VerifyChecksums(p Package) error
- type AttributeTable
- type Author
- type Break
- type BuildReport
- type Built
- type Component
- type Contract
- type DetectorFunc
- type DevResult
- type Feature
- type Layout
- type Manifest
- type Package
- type Result
- type Signal
- type Warning
Constants ¶
This section is empty.
Variables ¶
var Breaks = []Break{
{At: 1, Reason: "First Theme API version"},
}
Breaks are the break rows of the ledger.
var ErrOutdated = errors.New("themecore is older than the contract")
ErrOutdated is wrapped by the error for a contract that uses Compono syntax or a component that this themecore does not know. A published contract has neither, so the program is older than the contract: CLI reports that CLI is out of date, Umono that Umono is out of date.
var Features = []Feature{
{ID: "pkg.attributes", IntroducedIn: 1, Detect: detectFile("attributes.toml")},
{ID: "attr.class", IntroducedIn: 1, Detect: detectAddress(hasClass)},
{ID: "attr.sizes", IntroducedIn: 1, Detect: detectAddress(hasSizes)},
{ID: "attr.address.layout", IntroducedIn: 1, Detect: detectAddress(layoutAddress)},
{ID: "attr.address.layout-builtin", IntroducedIn: 1, Detect: detectAddress(layoutBuiltinAddress)},
{ID: "attr.address.layout-component-builtin", IntroducedIn: 1, Detect: detectAddress(layoutComponentBuiltinAddress)},
{ID: "pkg.license", IntroducedIn: 1, Detect: detectFile("LICENSE")},
{ID: "assets.woff2", IntroducedIn: 1, Detect: detectAsset(".woff2")},
{ID: "assets.woff", IntroducedIn: 1, Detect: detectAsset(".woff")},
{ID: "assets.png", IntroducedIn: 1, Detect: detectAsset(".png")},
{ID: "assets.jpeg", IntroducedIn: 1, Detect: detectAsset(".jpeg")},
{ID: "assets.jpg", IntroducedIn: 1, Detect: detectAsset(".jpg")},
{ID: "assets.webp", IntroducedIn: 1, Detect: detectAsset(".webp")},
{ID: "assets.avif", IntroducedIn: 1, Detect: detectAsset(".avif")},
{ID: "assets.gif", IntroducedIn: 1, Detect: detectAsset(".gif")},
{ID: "css.at.media", IntroducedIn: 1, Detect: detectAtRule("media")},
{ID: "css.at.supports", IntroducedIn: 1, Detect: detectAtRule("supports")},
{ID: "css.at.layer", IntroducedIn: 1, Detect: detectAtRule("layer")},
{ID: "css.at.font-face", IntroducedIn: 1, Detect: detectAtRule("font-face")},
{ID: "css.at.keyframes", IntroducedIn: 1, Detect: detectAtRule("keyframes")},
{ID: "compono.builtin.link", IntroducedIn: 1, Detect: detectBuiltin("LINK")},
{ID: "compono.builtin.image", IntroducedIn: 1, Detect: detectBuiltin("IMAGE")},
{ID: "compono.builtin.nav", IntroducedIn: 1, Detect: detectBuiltin("NAV")},
{ID: "compono.builtin.list", IntroducedIn: 1, Detect: detectBuiltin("LIST")},
{ID: "compono.builtin.details", IntroducedIn: 1, Detect: detectBuiltin("DETAILS")},
{ID: "compono.builtin.header", IntroducedIn: 1, Detect: detectBuiltin("HEADER")},
{ID: "compono.builtin.main", IntroducedIn: 1, Detect: detectBuiltin("MAIN")},
{ID: "compono.builtin.footer", IntroducedIn: 1, Detect: detectBuiltin("FOOTER")},
{ID: "compono.builtin.article", IntroducedIn: 1, Detect: detectBuiltin("ARTICLE")},
{ID: "compono.builtin.aside", IntroducedIn: 1, Detect: detectBuiltin("ASIDE")},
{ID: "compono.markdown.heading", IntroducedIn: 1, Detect: detectMarkdown("heading")},
{ID: "compono.markdown.p", IntroducedIn: 1, Detect: detectMarkdown("p")},
{ID: "compono.markdown.br", IntroducedIn: 1, Detect: detectMarkdown("br")},
{ID: "compono.markdown.em", IntroducedIn: 1, Detect: detectMarkdown("em")},
{ID: "compono.markdown.strong", IntroducedIn: 1, Detect: detectMarkdown("strong")},
{ID: "compono.markdown.link", IntroducedIn: 1, Detect: detectMarkdown("link")},
{ID: "compono.markdown.inline-code", IntroducedIn: 1, Detect: detectMarkdown("inline-code")},
{ID: "compono.markdown.code-block", IntroducedIn: 1, Detect: detectMarkdown("code-block")},
{ID: "compono.markdown.list", IntroducedIn: 1, Detect: detectMarkdown("list")},
{ID: "compono.markdown.blockquote", IntroducedIn: 1, Detect: detectMarkdown("blockquote")},
{ID: "compono.markdown.hr", IntroducedIn: 1, Detect: detectMarkdown("hr")},
{ID: "compono.markdown.table", IntroducedIn: 1, Detect: detectMarkdown("table")},
}
Features are the feature rows of the ledger.
Functions ¶
func Builtins ¶
func Builtins() []string
Builtins returns the names of the built-ins open to themes, from the compono.builtin.* rows of Features in ledger order: the last segment of the ID in upper case, with "-" as "_". Address validation, the detectors and the undefined call rule look only at this set, not at Compono's list. It returns a new slice on every call.
func CheckSource ¶
func CheckSource(dir string, contract []byte) (Package, BuildReport, error)
CheckSource runs the checks of build and of the dev proxy on the development directory dir. contract is the file of the contract that theme.toml refers to, from the CLI's cache; themecore does not know the cache layout. The order is that of the static check table: the package limits and content, theme.toml, contract.toml, the assets, Transform, the files the CSS URLs point to, attributes.toml against the contract and LICENSE. The returned package is what goes into the built file, the canonical CSS included; the CLI adds built.toml and then checksums.json.
func Checksums ¶
Checksums returns the content of checksums.json for p: the sha256 of every file except checksums.json itself. The output is deterministic: the same files give the same bytes, and so the same release.
func DetectorCorpus ¶
func DetectorCorpus() error
DetectorCorpus runs the detectors on every case of the detector corpus and returns an error for the first case whose signals differ from its golden file or whose contract does not parse. The detectors read contracts with Compono, so Umono and CLI call it in their tests: a Compono version that changes the signals fails there.
func FallbackCSS ¶
func FallbackCSS() []byte
FallbackCSS returns the canonical CSS of the fallback theme: the Transform output of FallbackSource. Umono serves it at /_theme/fallback-{release}/theme.css.
func FallbackSource ¶
func FallbackSource() []byte
FallbackSource returns the source of the fallback theme, the default look of pages without an active theme, in the author grammar. It is also the starting assets/theme.css of umono theme create.
func MarkdownElements ¶
func MarkdownElements() []string
MarkdownElements returns the names of the Markdown elements open to themes, from the compono.markdown.* rows of Features in ledger order: the last segment of the ID, the name of the element's spec. It returns a new slice on every call.
func TOMLConformance ¶
func TOMLConformance() error
TOMLConformance returns an error if the TOML decoder of this binary accepts a document that is not TOML v1.0.0 or rejects one that is. The go-toml version in a binary is chosen by the whole build, so Umono and CLI call it in their tests to check the decoder they are built with.
func ThemeAPICurrent ¶
func ThemeAPICurrent() int
ThemeAPICurrent is the newest Theme API version: the largest IntroducedIn of Features and At of Breaks.
func ThemeAPIMin ¶
func ThemeAPIMin() int
ThemeAPIMin is the oldest Theme API version still accepted: the largest At of Breaks.
func Transform ¶
Transform turns the theme author's assets/theme.css into the canonical CSS that goes into the package (themecore, CSS Scoping). It drops a leading byte order mark and a leading @charset "UTF-8"; statement, parses the CSS strictly, checks the author grammar and serializes the canonical grammar, in which every style rule is inside an @scope (umono-root) block. The output always passes Verify; if it does not, Transform returns an error instead of the output, because that is a bug in themecore (Karar 11).
func Verify ¶
Verify checks that css, the assets/theme.css of a package, is in the canonical grammar (themecore, Karar 9). It is structural: it does not compare bytes with Transform's output, so the serialization format is not part of the Theme API (Karar 10).
func VerifyChecksums ¶
VerifyChecksums checks p against its checksums.json. It looks at the values, not the format: a reformatted file with the right values is accepted.
Types ¶
type AttributeTable ¶
type AttributeTable struct {
// contains filtered or unexported fields
}
AttributeTable is attributes.toml compiled against a contract: the attributes of every address. It is a plain value; rendering reads no file.
func CompileAttributes ¶
func CompileAttributes(b []byte, c Contract) (AttributeTable, error)
CompileAttributes validates attributes.toml against the contract c and compiles it into an AttributeTable. Every address is layout, layout BUILTIN or layout COMPONENT BUILTIN with parts separated by a single space, and its names are layouts and exposed components of c and built-ins of Builtins. A name c defines as a component is never a built-in. Only class and sizes are allowed, sizes only on an address that ends with IMAGE.
func (AttributeTable) Lookup ¶
Lookup returns the attributes of the built-in rendered with the frame chain chain on a page bound to layout, or nil. The scope is the innermost global frame whose scope path is [UMONO_LAYOUT] and whose name is an exposed component, otherwise the layout; the address is layout [SCOPE] BUILTIN. It fits compono.AttributeHookFunc once layout is bound, and returns a new map on every call.
type Break ¶
Break is a narrowing of the Theme API. It raises both ThemeAPICurrent and ThemeAPIMin to At.
type BuildReport ¶
type BuildReport struct {
// Version is theme-api-version, from DetectThemeAPIVersion. The CLI
// writes it to built.toml.
Version int
Evidence []Signal
// Warnings are those of Lint. They do not stop the build.
Warnings []Warning
}
BuildReport is the outcome of CheckSource.
type Built ¶
type Built struct {
Manifest
ThemeAPIVersion int `toml:"theme-api-version"`
BuiltAt time.Time `toml:"built-at"`
}
Built is built.toml, the manifest of a package. The CLI writes it from theme.toml during build: the keys of theme.toml are copied unchanged and theme-api-version and built-at are added.
func ParseBuilt ¶
ParseBuilt parses and validates built.toml.
func (Built) CheckInstallDir ¶
CheckInstallDir checks that the install path dir, themes/{org}/{id}/{version} or themes-pending/{org}/{id}/{version}, matches id and version (built.toml, Karar 5). Only the last three elements of dir are compared.
type Component ¶
type Component struct {
Name string `toml:"name"`
Source string `toml:"source"`
Expose bool `toml:"expose"`
}
Component is an entry of the components array. Expose tells whether the component is a scope for addressing.
type Contract ¶
type Contract struct {
Schema string `toml:"schema"`
ID string `toml:"id"`
Version string `toml:"version"`
Description *string `toml:"description"`
Layouts []Layout `toml:"layouts"`
Components []Component `toml:"components"`
}
Contract is contract.toml. Contracts are published on umono.dev and copied into every theme package unchanged.
func ParseContract ¶
ParseContract parses and validates contract.toml: the structural layer (types, required keys, grammars and uniqueness), then the sources, which are parsed with Compono. A source with a grammar error, or a call that resolves to no local, contract component or built-in, is rejected with an error that wraps ErrOutdated.
type DetectorFunc ¶
DetectorFunc reports whether a package uses a feature. where is the first place in the package that shows it, for example "assets/icons/cart.svg". Detectors look at the package itself: the canonical CSS and the package's own contract.toml, never the author's sources.
type DevResult ¶
type DevResult struct {
// Built is the built.toml CheckDev validated, with the id dev/dev,
// which ParseBuilt rejects.
Built Built
// ContractSource is the unchanged bytes of contract.toml. Umono adds
// its contract record from it.
ContractSource []byte
Contract Contract
// Floor is DetectFeatureFloor of the dev package.
Floor int
Evidence []Signal
// CSS is the Transform output of assets/theme.css, nil if CSSErr is set.
// Umono answers the theme.css request with an error status then.
CSS []byte
CSSErr error
// Attributes is the compiled attributes.toml, an empty table if there is
// none or AttributesErr is set. Pages are rendered without injection then.
Attributes AttributeTable
AttributesErr error
// AssetErrs maps the path of every file under assets/ that breaks the
// rules to its error. Umono answers its request with 404.
AssetErrs map[string]error
}
DevResult is the outcome of CheckDev. The errors of one check are returned here and do not stop dev mode; Umono handles each on its own.
func CheckDev ¶
CheckDev runs the checks of activation on the dev directory dir of Umono's dev mode, themes/dev/dev/0.0.0/, with the privileges of dev/dev, which exist only here. root is the theme project, UMONO_THEME_DEV. There is no checksums.json; assets/, attributes.toml and contract.toml may be symlinks into root; theme.css goes through Transform instead of Verify; built.toml has the id dev/dev and the version 0.0.0. The other checks run as in CheckPackage. The package limits and content, built.toml, contract.toml, LICENSE and the feature floor are fatal: the returned error. CheckDev keeps no cache; Umono calls it on every request.
type Feature ¶
type Feature struct {
ID string
IntroducedIn int
Detect DetectorFunc
}
Feature is a capability of the Theme API and the version that introduced it. Every feature has a detector.
type Layout ¶
type Layout struct {
ID string `toml:"id"`
Description *string `toml:"description"`
Source string `toml:"source"`
}
Layout is an entry of the layouts array.
type Manifest ¶
type Manifest struct {
Schema string `toml:"schema"`
ID string `toml:"id"`
Contract string `toml:"contract"`
Name string `toml:"name"`
Version string `toml:"version"`
Description *string `toml:"description"`
License *string `toml:"license"`
Homepage *string `toml:"homepage"`
Repository *string `toml:"repository"`
Authors []Author `toml:"authors"`
}
Manifest is theme.toml, the manifest the theme author writes. The CLI reads it; it does not go into the package. Optional keys are nil when absent.
func ParseManifest ¶
ParseManifest parses and validates theme.toml.
type Package ¶
type Package struct {
// Files maps the path of each file to its content. Paths are relative to
// the package root and use "/" as the separator. Directories are not
// listed; they follow from the paths.
Files map[string][]byte
}
Package is the content of a theme package. During build it is the state that goes into the built file, canonical CSS included. During install and activation it is the package itself, read from the built file or from the installed directory.
func ReadDir ¶
ReadDir reads the installed form of a package from dir. The package limits are checked with the sizes from the file system's metadata before any file is read. Symlinks are not followed: anything that is not a regular file or a directory is rejected, and so are hard links. Hard links can only be detected on Unix, so ReadDir fails on other platforms.
func ReadZip ¶
ReadZip reads a built file. size is the file's size from the file system's metadata. The package limits are checked before anything is read: the built file's size first, then the sizes the entries declare. While an entry is decompressed its real bytes are counted, and reading stops as soon as a limit is exceeded. Entry names, types, encryption and compression methods are checked before any entry is decompressed.
type Result ¶
type Result struct {
Contract Contract
// Attributes is the compiled attributes.toml, an empty table if the
// package has none.
Attributes AttributeTable
// Floor is DetectFeatureFloor of the package.
Floor int
Evidence []Signal
}
Result is the outcome of CheckPackage.
func CheckPackage ¶
CheckPackage runs the checks of install and activation on p, a package read with ReadZip or ReadDir, which check the package limits and content. The order is that of the static check table: the required files, built.toml, contract.toml and its match with built.toml, the assets, Verify of the canonical CSS, the files its URLs point to, attributes.toml against the contract, LICENSE and, last, the feature floor: a theme-api-version lower than the features the package uses is rejected. checksums.json and the Theme API range are checked by the caller before.
type Signal ¶
type Signal struct {
Feature string // "assets.svg"
IntroducedIn int // 3
Where string // "assets/icons/cart.svg"
}
Signal is the evidence that a package uses a feature: the feature's ID, the version that introduced it and the first place in the package that shows it.
func DetectFeatureFloor ¶
DetectFeatureFloor is the first term of theme-api-version: the largest IntroducedIn of the features the package uses, or 0 if it uses none. evidence has one signal per detected feature, in ledger order. Install and activation call it to verify the version that built.toml declares.
type Warning ¶
Warning is a finding of Lint. Where is a selector or an address, for example ".layout-post h1" or "post-list MAIN_MENU LINK".
func Lint ¶
Lint returns warnings for mistakes that are valid CSS but never match. Only development tools call it; it is not part of the Theme API, and install and activation do not call it. It reports root classes used without :scope and addresses whose component the layout never renders (themecore, Kök Sınıfı Uyarısı and Ölü Adres Uyarısı). A package whose attributes.toml, contract.toml or assets/theme.css cannot be read gets no warnings; those errors are reported by the checks.
Source Files
¶
- assets.go
- attributes.go
- attributes_class.go
- built.go
- check.go
- check_dev.go
- checksums.go
- content.go
- contract.go
- contract_sources.go
- css.go
- css_grammar.go
- css_lex.go
- css_media.go
- css_parse.go
- css_selector.go
- css_selector_rules.go
- css_serialize.go
- css_sizes.go
- css_supports.go
- css_text.go
- css_url.go
- css_values.go
- detect.go
- detector_corpus.go
- detectors.go
- detectors_compono.go
- doc.go
- fallback.go
- fields.go
- hardlink_unix.go
- ledger.go
- license.go
- limits.go
- lint.go
- lint_dead.go
- manifest.go
- package.go
- read.go
- read_dev.go
- read_source.go
- schema.go
- spdx.go
- toml.go
- toml_conformance.go