Represent immutable code snippets with source lines, selections, and presentation-neutral annotations.
CodeSnippet turns source code into a portable model with original line numbers, selected lines, and generic byte-range annotations. Renderers can consume that model without coupling this package to HTML, SVG, terminals, slides, or a syntax highlighter.
use Alto\Code\Snippet\CodeSnippet;
$snippet = CodeSnippet::fromCode($code, 'php', startLine: 24)
->selectLines(3);
echo $snippet->lines()[2]->number; // 26Install ALTO CodeSnippet with Composer:
composer require alto/code-snippetCodeSnippet requires PHP 8.4 or later and alto/language.
Create a snippet, select a line, and attach an application-defined annotation:
use Alto\Code\Snippet\CodeAnnotation;
use Alto\Code\Snippet\CodeSnippet;
$snippet = CodeSnippet::fromCode(
"public function run(): void\n{\n execute();\n}",
'php',
sourceName: 'src/Runner.php',
startLine: 24,
)
->selectLines(3)
->annotate(new CodeAnnotation(
offset: 0,
length: 6,
type: 'syntax',
data: ['scope' => 'keyword'],
));
echo json_encode($snippet, JSON_THROW_ON_ERROR);Every transformation returns a new value. The original snippet remains unchanged.
lines() returns CodeLine values with both coordinate systems:
indexis one-based and relative to the snippet;numberrefers to the original source;codeexcludes the line break;selectedcarries line-level emphasis;annotations()contains line-relative annotations.
$line = $snippet->lines()[2];
$line->index; // 3
$line->number; // 26
$line->code; // " execute();"
$line->selected; // true
$line->annotations();
$line->segments();Source content and LF, CRLF, or CR line endings remain byte-for-byte identical.
CodeAnnotation describes a byte range relative to code(), an application-defined type, and
optional generic data:
$annotated = $snippet->annotate(
new CodeAnnotation(0, 6, 'syntax', ['scope' => 'keyword']),
new CodeAnnotation(16, 3, 'emphasis', ['name' => 'primary']),
);Annotations may overlap or cross line breaks. Each CodeLine clips and shifts them to its own
content. segments() derives contiguous text regions with stable annotation sets.
slice() projects an already annotated snippet onto a half-open byte range:
$projected = $annotatedSource
->slice($range->start, $range->end)
->dedent();This lets a consumer analyze a complete source before projecting the selected region. Crossing annotations are clipped and shifted, while source line numbers and selections are retained.
Use dedent() or its unindent() alias to remove common indentation. indent() adds spaces to
non-empty lines. These explicit transformations update annotation offsets and preserve the original
line-ending style.
CodeSnippet, CodeLine, CodeAnnotation, and CodeSegment implement JsonSerializable.
toArray() exports code, provenance, selections, and annotations:
$payload = $snippet->toArray();
$json = json_encode($snippet, JSON_THROW_ON_ERROR);CodeSnippet does not read files, detect languages, locate declarations, tokenize code, or render output. It only owns the immutable, presentation-neutral data model passed between those steps.
See the documentation for installation, a guided example, and the public API.
Contributions of all kinds are welcome. Visit the project on GitHub to report a bug, suggest a feature, or open a pull request. Before submitting code, run:
# Runs PHP CS Fixer, PHPStan, and PHPUnit
composer qaChanges to public behavior should include tests and documentation.
ALTO CodeSnippet is open source. You can support its continued development through GitHub Sponsors.
Sharing this package with others or starring it on GitHub is also much appreciated.
ALTO CodeSnippet is released by ALTO PHP under the MIT License.