diff --git a/README.md b/README.md index 96d5f50..53dc579 100644 --- a/README.md +++ b/README.md @@ -43,13 +43,25 @@ use Alto\Scale\Scale; $spacing = Scale::linear(base: 0, increment: 8); -echo $spacing->get(3); // 24 -echo $spacing->snap(19); // 16 +printf("step 3: %g; snapped: %g\n", $spacing->get(3), $spacing->snap(19)); ``` +The example prints `step 3: 24; snapped: 16`. + All scales expose `get()`, `stepOf()`, `snap()`, and `range()` and can be iterated over steps zero through ten. +## Documentation + +- [Installation](docs/installation.md) +- [Getting started](docs/getting-started.md) +- [Scales](docs/scales.md) +- [Guessing](docs/guessing.md) +- [Linting](docs/linting.md) + +The [documentation index](docs/index.md) lists these pages in site navigation +order. + ## Scale Types | Scale | Progression | Typical use | @@ -68,7 +80,7 @@ $golden = Scale::golden(1); ``` Custom ratios are available through `Scale::modular()`. See the -[scale guide](docs/scales/index.md) for every progression and its constraints. +[scale guide](docs/scales.md) for every progression and its constraints. ## Guessing @@ -101,7 +113,7 @@ $fixed = $linter->fix([8, 15, 24]); // [8.0, 16.0, 24.0] ``` Read [Linting values](docs/linting.md) for the report format and inferred-scale behavior. The -[complete documentation](docs/index.md) also covers installation, the shared API, and each scale +[complete documentation](docs/index.md) also covers installation, shared operations, and each scale type. ## Contributing diff --git a/docs/getting-started.md b/docs/getting-started.md index 5b6555d..5cb9cef 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,33 +1,47 @@ # Getting started -Create a scale through the `Scale` facade, then ask it for the values required -by the current design system. +Create spacing tokens separated by eight units. After [installation](installation.md), +save this complete script as `spacing.php` beside `vendor/`: ```php +get(1); // 8 -echo $spacing->get(3); // 24 +printf("%g\n%g\n", $spacing->get(1), $spacing->get(3)); +foreach ($spacing->range(1, 4) as $step => $value) { + printf("%d: %g\n", $step, $value); +} ``` -All scales share four operations: +Run `php spacing.php`. It prints: -```php -$spacing->get(4); // 32.0: value at step 4 -$spacing->stepOf(30); // 4: nearest step to 30 -$spacing->snap(30); // 32.0: nearest scale value -$spacing->range(1, 4); // [1 => 8.0, 2 => 16.0, 3 => 24.0, 4 => 32.0] +```text +8 +24 +1: 8 +2: 16 +3: 24 +4: 32 ``` -Scales are also iterable. Iteration yields steps 0 through 10: +## Align an existing value + +Using the same `$spacing` object: ```php -foreach ($spacing as $step => $value) { - printf("%d: %g\n", $step, $value); -} +printf("Step: %d; value: %g\n", $spacing->stepOf(30), $spacing->snap(30)); ``` -Choose a progression from [All scales](scales/index.md). If values already -exist, use [Guessing](guessing.md) or [Linting](linting.md). +This prints `Step: 4; value: 32`. `get()` reads one step; `range()` includes +both endpoints and preserves step numbers as keys. Iterating a scale directly +yields steps 0 through 10. + +Choose a progression from [Scales](scales.md). The common operations +do not imply identical domains: modular lookup needs positive values, while +linear spacing can cross zero. To work with an existing collection, continue +with [Guessing](guessing.md) or [Linting](linting.md). diff --git a/docs/guessing.md b/docs/guessing.md index e0b71d5..e15b175 100644 --- a/docs/guessing.md +++ b/docs/guessing.md @@ -10,10 +10,12 @@ use Alto\Scale\ScaleGuesser; $guesser = new ScaleGuesser(tolerance: 0.05); $scale = $guesser->guess([15.9, 20.1, 24.8, 31.5]); -echo $scale->base; -echo $scale->multiplier; +printf("Base: %.3f; ratio: %.2f\n", $scale->base, $scale->multiplier); ``` +With Composer's autoloader loaded, this prints `Base: 15.995; ratio: 1.25`. +The inferred base is an estimate, not necessarily one of the original values. + Use the facade for the default tolerance: ```php @@ -26,10 +28,18 @@ $scale = Scale::guess([16, 20, 25, 31.25]); ```php $aligned = $guesser->align([15.9, 20.1, 24.8, 31.5], $scale); +echo implode(', ', array_map(static fn (float $value): string => sprintf('%.2f', $value), $aligned)); ``` +After the facade example, `$scale` has base 16 and ratio 1.25, so this +prints `16.00, 20.00, 25.00, 31.25`. + `align()` snaps positive values and preserves zero or negative values. Omit the second argument to infer the target scale from the same dataset. Guessing is an estimate, not statistical model selection. Check the returned base and ratio before making it part of a design-system contract. + +If guessing fails, provide at least two positive values and check the +configured tolerance. Keep zeros and negative values out of the inferred +dataset; use a linear scale directly for progressions crossing zero. diff --git a/docs/index.md b/docs/index.md index 042719f..30effc2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,34 +1,23 @@ -# ALTO Scale +# Alto Scale -ALTO Scale computes mathematical progressions for typography, spacing, grids, -and other design values. Every scale can return a step, find the nearest step, -snap an arbitrary value, and generate a range. +Alto Scale turns mathematical progressions into predictable values for +typography, spacing, grids, and rhythmic design systems. ```php use Alto\Scale\Scale; $type = Scale::majorThird(16); - -$type->get(-1); // 12.8 -$type->get(0); // 16.0 -$type->get(1); // 20.0 -Scale::majorThird(16)->snap(19.8); // 20.0 +echo $type->snap(19.8); ``` -## Introduction - -- [Installation](installation.md): install the package and verify the runtime. -- [Getting started](getting-started.md): create and use a first scale. - -## Scales - -- [All scales](scales/index.md): choose a progression for the values you need. -- [Modular](scales/modular.md): generate a geometric progression from a base and ratio. -- [Linear](scales/linear.md): generate values separated by a constant increment. -- [Fibonacci](scales/fibonacci.md): generate a scaled Fibonacci sequence. -- [Multi-strand](scales/multi-strand.md): interleave several modular progressions. +The result is `20`. Every scale can return a step, find the nearest step, snap +an arbitrary value, and generate a keyed range. Modular, linear, Fibonacci, +and multi-strand progressions keep their own domain and inverse behavior. -## Analysis +## Documentation -- [Guessing](guessing.md): infer a modular scale from existing positive values. -- [Linting](linting.md): audit values and align them to a scale. +- [Installation](installation.md) +- [Getting started](getting-started.md) +- [Scales](scales.md) +- [Guessing](guessing.md) +- [Linting](linting.md) diff --git a/docs/scales/index.md b/docs/scales.md similarity index 62% rename from docs/scales/index.md rename to docs/scales.md index ee7791f..e253b36 100644 --- a/docs/scales/index.md +++ b/docs/scales.md @@ -1,14 +1,14 @@ -# Scale types +# Scales Choose the progression according to the relationship between consecutive values. | Scale | Relationship | Typical use | | --- | --- | --- | -| [Modular](modular.md) | Multiply by one ratio | Type sizes, proportional spacing | -| [Linear](linear.md) | Add one increment | Baseline grids, fixed spacing | -| [Fibonacci](fibonacci.md) | Follow Fibonacci numbers | Integer rhythms and counts | -| [Multi-strand](multi-strand.md) | Interleave several modular scales | Multiple coordinated bases | +| [Modular](scales/modular.md) | Multiply by one ratio | Type sizes, proportional spacing | +| [Linear](scales/linear.md) | Add one increment | Baseline grids, fixed spacing | +| [Fibonacci](scales/fibonacci.md) | Follow Fibonacci numbers | Integer rhythms and counts | +| [Multi-strand](scales/multi-strand.md) | Interleave several modular scales | Multiple coordinated bases | Every type implements `ScaleInterface`, so application code can accept any scale while using `get()`, `stepOf()`, `snap()`, and `range()`.