Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
46 changes: 30 additions & 16 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -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
<?php

require __DIR__.'/vendor/autoload.php';

use Alto\Scale\Scale;

$spacing = Scale::linear(base: 0, increment: 8);

echo $spacing->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).
14 changes: 12 additions & 2 deletions docs/guessing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
37 changes: 13 additions & 24 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 5 additions & 5 deletions docs/scales/index.md → docs/scales.md
Original file line number Diff line number Diff line change
@@ -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()`.
Expand Down
Loading