allow vendord
All checks were successful
Build, Push and Deploy / build-and-push (push) Successful in 3m3s
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 16s
Build, Push and Deploy / deploy-staging (push) Successful in 32s
Build, Push and Deploy / deploy-production (push) Has been skipped
Build, Push and Deploy / cleanup (push) Successful in 1s

This commit is contained in:
2026-03-30 14:54:57 +07:00
parent 66aed7c4e8
commit b5e3a778ce
21316 changed files with 2777892 additions and 13 deletions

View File

@@ -0,0 +1,753 @@
<?php
declare(strict_types=1);
namespace Sabberworm\CSS;
final class OutputFormat
{
/**
* Value format: `"` means double-quote, `'` means single-quote
*
* @var non-empty-string
*/
private $stringQuotingType = '"';
/**
* Output RGB colors in hash notation if possible
*
* @var bool
*/
private $usesRgbHashNotation = true;
/**
* Declaration format
*
* Semicolon after the last rule of a declaration block can be omitted. To do that, set this false.
*
* @var bool
*/
private $renderSemicolonAfterLastRule = true;
/**
* Spacing
* Note that these strings are not sanity-checked: the value should only consist of whitespace
* Any newline character will be indented according to the current level.
* The triples (After, Before, Between) can be set using a wildcard
* (e.g. `$outputFormat->set('Space*Rules', "\n");`)
*
* @var string
*/
private $spaceAfterRuleName = ' ';
/**
* @var string
*/
private $spaceBeforeRules = '';
/**
* @var string
*/
private $spaceAfterRules = '';
/**
* @var string
*/
private $spaceBetweenRules = '';
/**
* @var string
*/
private $spaceBeforeBlocks = '';
/**
* @var string
*/
private $spaceAfterBlocks = '';
/**
* @var string
*/
private $spaceBetweenBlocks = "\n";
/**
* Content injected in and around at-rule blocks.
*
* @var string
*/
private $contentBeforeAtRuleBlock = '';
/**
* @var string
*/
private $contentAfterAtRuleBlock = '';
/**
* This is whats printed before and after the comma if a declaration block contains multiple selectors.
*
* @var string
*/
private $spaceBeforeSelectorSeparator = '';
/**
* @var string
*/
private $spaceAfterSelectorSeparator = ' ';
/**
* This is whats inserted before the separator in value lists, by default.
*
* @var string
*/
private $spaceBeforeListArgumentSeparator = '';
/**
* Keys are separators (e.g. `,`). Values are the space sequence to insert, or an empty string.
*
* @var array<non-empty-string, string>
*/
private $spaceBeforeListArgumentSeparators = [];
/**
* This is whats inserted after the separator in value lists, by default.
*
* @var string
*/
private $spaceAfterListArgumentSeparator = '';
/**
* Keys are separators (e.g. `,`). Values are the space sequence to insert, or an empty string.
*
* @var array<non-empty-string, string>
*/
private $spaceAfterListArgumentSeparators = [];
/**
* @var string
*/
private $spaceBeforeOpeningBrace = ' ';
/**
* Content injected in and around declaration blocks.
*
* @var string
*/
private $contentBeforeDeclarationBlock = '';
/**
* @var string
*/
private $contentAfterDeclarationBlockSelectors = '';
/**
* @var string
*/
private $contentAfterDeclarationBlock = '';
/**
* Indentation character(s) per level. Only applicable if newlines are used in any of the spacing settings.
*
* @var string
*/
private $indentation = "\t";
/**
* Output exceptions.
*
* @var bool
*/
private $shouldIgnoreExceptions = false;
/**
* Render comments for lists and RuleSets
*
* @var bool
*/
private $shouldRenderComments = false;
/**
* @var OutputFormatter|null
*/
private $outputFormatter;
/**
* @var OutputFormat|null
*/
private $nextLevelFormat;
/**
* @var int<0, max>
*/
private $indentationLevel = 0;
/**
* @return non-empty-string
*
* @internal
*/
public function getStringQuotingType(): string
{
return $this->stringQuotingType;
}
/**
* @param non-empty-string $quotingType
*
* @return $this fluent interface
*/
public function setStringQuotingType(string $quotingType): self
{
$this->stringQuotingType = $quotingType;
return $this;
}
/**
* @internal
*/
public function usesRgbHashNotation(): bool
{
return $this->usesRgbHashNotation;
}
/**
* @return $this fluent interface
*/
public function setRGBHashNotation(bool $usesRgbHashNotation): self
{
$this->usesRgbHashNotation = $usesRgbHashNotation;
return $this;
}
/**
* @internal
*/
public function shouldRenderSemicolonAfterLastRule(): bool
{
return $this->renderSemicolonAfterLastRule;
}
/**
* @return $this fluent interface
*/
public function setSemicolonAfterLastRule(bool $renderSemicolonAfterLastRule): self
{
$this->renderSemicolonAfterLastRule = $renderSemicolonAfterLastRule;
return $this;
}
/**
* @internal
*/
public function getSpaceAfterRuleName(): string
{
return $this->spaceAfterRuleName;
}
/**
* @return $this fluent interface
*/
public function setSpaceAfterRuleName(string $whitespace): self
{
$this->spaceAfterRuleName = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceBeforeRules(): string
{
return $this->spaceBeforeRules;
}
/**
* @return $this fluent interface
*/
public function setSpaceBeforeRules(string $whitespace): self
{
$this->spaceBeforeRules = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceAfterRules(): string
{
return $this->spaceAfterRules;
}
/**
* @return $this fluent interface
*/
public function setSpaceAfterRules(string $whitespace): self
{
$this->spaceAfterRules = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceBetweenRules(): string
{
return $this->spaceBetweenRules;
}
/**
* @return $this fluent interface
*/
public function setSpaceBetweenRules(string $whitespace): self
{
$this->spaceBetweenRules = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceBeforeBlocks(): string
{
return $this->spaceBeforeBlocks;
}
/**
* @return $this fluent interface
*/
public function setSpaceBeforeBlocks(string $whitespace): self
{
$this->spaceBeforeBlocks = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceAfterBlocks(): string
{
return $this->spaceAfterBlocks;
}
/**
* @return $this fluent interface
*/
public function setSpaceAfterBlocks(string $whitespace): self
{
$this->spaceAfterBlocks = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceBetweenBlocks(): string
{
return $this->spaceBetweenBlocks;
}
/**
* @return $this fluent interface
*/
public function setSpaceBetweenBlocks(string $whitespace): self
{
$this->spaceBetweenBlocks = $whitespace;
return $this;
}
/**
* @internal
*/
public function getContentBeforeAtRuleBlock(): string
{
return $this->contentBeforeAtRuleBlock;
}
/**
* @return $this fluent interface
*/
public function setBeforeAtRuleBlock(string $content): self
{
$this->contentBeforeAtRuleBlock = $content;
return $this;
}
/**
* @internal
*/
public function getContentAfterAtRuleBlock(): string
{
return $this->contentAfterAtRuleBlock;
}
/**
* @return $this fluent interface
*/
public function setAfterAtRuleBlock(string $content): self
{
$this->contentAfterAtRuleBlock = $content;
return $this;
}
/**
* @internal
*/
public function getSpaceBeforeSelectorSeparator(): string
{
return $this->spaceBeforeSelectorSeparator;
}
/**
* @return $this fluent interface
*/
public function setSpaceBeforeSelectorSeparator(string $whitespace): self
{
$this->spaceBeforeSelectorSeparator = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceAfterSelectorSeparator(): string
{
return $this->spaceAfterSelectorSeparator;
}
/**
* @return $this fluent interface
*/
public function setSpaceAfterSelectorSeparator(string $whitespace): self
{
$this->spaceAfterSelectorSeparator = $whitespace;
return $this;
}
/**
* @internal
*/
public function getSpaceBeforeListArgumentSeparator(): string
{
return $this->spaceBeforeListArgumentSeparator;
}
/**
* @return $this fluent interface
*/
public function setSpaceBeforeListArgumentSeparator(string $whitespace): self
{
$this->spaceBeforeListArgumentSeparator = $whitespace;
return $this;
}
/**
* @return array<non-empty-string, string>
*
* @internal
*/
public function getSpaceBeforeListArgumentSeparators(): array
{
return $this->spaceBeforeListArgumentSeparators;
}
/**
* @param array<non-empty-string, string> $separatorSpaces
*
* @return $this fluent interface
*/
public function setSpaceBeforeListArgumentSeparators(array $separatorSpaces): self
{
$this->spaceBeforeListArgumentSeparators = $separatorSpaces;
return $this;
}
/**
* @internal
*/
public function getSpaceAfterListArgumentSeparator(): string
{
return $this->spaceAfterListArgumentSeparator;
}
/**
* @return $this fluent interface
*/
public function setSpaceAfterListArgumentSeparator(string $whitespace): self
{
$this->spaceAfterListArgumentSeparator = $whitespace;
return $this;
}
/**
* @return array<non-empty-string, string>
*
* @internal
*/
public function getSpaceAfterListArgumentSeparators(): array
{
return $this->spaceAfterListArgumentSeparators;
}
/**
* @param array<non-empty-string, string> $separatorSpaces
*
* @return $this fluent interface
*/
public function setSpaceAfterListArgumentSeparators(array $separatorSpaces): self
{
$this->spaceAfterListArgumentSeparators = $separatorSpaces;
return $this;
}
/**
* @internal
*/
public function getSpaceBeforeOpeningBrace(): string
{
return $this->spaceBeforeOpeningBrace;
}
/**
* @return $this fluent interface
*/
public function setSpaceBeforeOpeningBrace(string $whitespace): self
{
$this->spaceBeforeOpeningBrace = $whitespace;
return $this;
}
/**
* @internal
*/
public function getContentBeforeDeclarationBlock(): string
{
return $this->contentBeforeDeclarationBlock;
}
/**
* @return $this fluent interface
*/
public function setBeforeDeclarationBlock(string $content): self
{
$this->contentBeforeDeclarationBlock = $content;
return $this;
}
/**
* @internal
*/
public function getContentAfterDeclarationBlockSelectors(): string
{
return $this->contentAfterDeclarationBlockSelectors;
}
/**
* @return $this fluent interface
*/
public function setAfterDeclarationBlockSelectors(string $content): self
{
$this->contentAfterDeclarationBlockSelectors = $content;
return $this;
}
/**
* @internal
*/
public function getContentAfterDeclarationBlock(): string
{
return $this->contentAfterDeclarationBlock;
}
/**
* @return $this fluent interface
*/
public function setAfterDeclarationBlock(string $content): self
{
$this->contentAfterDeclarationBlock = $content;
return $this;
}
/**
* @internal
*/
public function getIndentation(): string
{
return $this->indentation;
}
/**
* @return $this fluent interface
*/
public function setIndentation(string $indentation): self
{
$this->indentation = $indentation;
return $this;
}
/**
* @internal
*/
public function shouldIgnoreExceptions(): bool
{
return $this->shouldIgnoreExceptions;
}
/**
* @return $this fluent interface
*/
public function setIgnoreExceptions(bool $ignoreExceptions): self
{
$this->shouldIgnoreExceptions = $ignoreExceptions;
return $this;
}
/**
* @internal
*/
public function shouldRenderComments(): bool
{
return $this->shouldRenderComments;
}
/**
* @return $this fluent interface
*/
public function setRenderComments(bool $renderComments): self
{
$this->shouldRenderComments = $renderComments;
return $this;
}
/**
* @return int<0, max>
*
* @internal
*/
public function getIndentationLevel(): int
{
return $this->indentationLevel;
}
/**
* @param int<1, max> $numberOfTabs
*
* @return $this fluent interface
*/
public function indentWithTabs(int $numberOfTabs = 1): self
{
return $this->setIndentation(\str_repeat("\t", $numberOfTabs));
}
/**
* @param int<1, max> $numberOfSpaces
*
* @return $this fluent interface
*/
public function indentWithSpaces(int $numberOfSpaces = 2): self
{
return $this->setIndentation(\str_repeat(' ', $numberOfSpaces));
}
/**
* @internal since V8.8.0
*/
public function nextLevel(): self
{
if ($this->nextLevelFormat === null) {
$this->nextLevelFormat = clone $this;
$this->nextLevelFormat->indentationLevel++;
$this->nextLevelFormat->outputFormatter = null;
}
return $this->nextLevelFormat;
}
public function beLenient(): void
{
$this->shouldIgnoreExceptions = true;
}
/**
* @internal since 8.8.0
*/
public function getFormatter(): OutputFormatter
{
if ($this->outputFormatter === null) {
$this->outputFormatter = new OutputFormatter($this);
}
return $this->outputFormatter;
}
/**
* Creates an instance of this class without any particular formatting settings.
*/
public static function create(): self
{
return new OutputFormat();
}
/**
* Creates an instance of this class with a preset for compact formatting.
*/
public static function createCompact(): self
{
$format = self::create();
$format
->setSpaceBeforeRules('')
->setSpaceBetweenRules('')
->setSpaceAfterRules('')
->setSpaceBeforeBlocks('')
->setSpaceBetweenBlocks('')
->setSpaceAfterBlocks('')
->setSpaceAfterRuleName('')
->setSpaceBeforeOpeningBrace('')
->setSpaceAfterSelectorSeparator('')
->setSemicolonAfterLastRule(false)
->setRenderComments(false);
return $format;
}
/**
* Creates an instance of this class with a preset for pretty formatting.
*/
public static function createPretty(): self
{
$format = self::create();
$format
->setSpaceBeforeRules("\n")
->setSpaceBetweenRules("\n")
->setSpaceAfterRules("\n")
->setSpaceBeforeBlocks("\n")
->setSpaceBetweenBlocks("\n\n")
->setSpaceAfterBlocks("\n")
->setSpaceAfterListArgumentSeparators([',' => ' '])
->setRenderComments(true);
return $format;
}
}