Skip to content

Commit

Permalink
Merge pull request #137 from tbela99/php56-cli-backport
Browse files Browse the repository at this point in the history
cli tools
  • Loading branch information
tbela99 committed Jul 19, 2022
2 parents 2cf6e07 + 83864f0 commit ac8752b
Show file tree
Hide file tree
Showing 162 changed files with 1,520 additions and 66 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: CI

on:
push:
branches: [ master ]
branches: [ master, php56-backport ]
pull_request:
branches: [ master ]
branches: [ master, php56-backport ]

jobs:
build:
Expand Down
89 changes: 86 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ A CSS parser, beautifier and minifier written in PHP. It supports the following
- remove @charset directive
- query api with xpath like or class name syntax
- traverser api to transform the css and ast
- command line utility

## Installation

Expand All @@ -34,7 +35,10 @@ $ composer require "tbela99/css:dev-php56-backport"

## Requirements

This library requires PHP version >= 5.6
This library requires:
- PHP version >= 5.6
- mbstring extension
-

## Usage:

Expand Down Expand Up @@ -318,8 +322,7 @@ table.colortable {
}


& th {
text-align:center;
& th {text-align:center;
background:black;
color:white;
}
Expand Down Expand Up @@ -613,6 +616,86 @@ echo $renderer->render($parser->parse());
- allow_duplicate_declarations: allow duplicate declarations.
- legacy_rendering: convert nesting css. default false

## Command line utility

the command line utility is located at './cli/css-parser'

```bash

$ ./cli/css-parser -h

Usage:
$ css-parser [OPTIONS] [PARAMETERS]

-h print help
--help print extended help

parse options:

-e, --capture-errors ignore parse error

-f, --file css file or url

-m, --flatten-import process @import

-d, --parse-allow-duplicate-declarations allow duplicate declaration

-p, --parse-allow-duplicate-rules allow duplicate rule

render options:

-a, --ast dump ast as JSON

-S, --charset remove @charset

-c, --compress minify output

-u, --compute-shorthand compute shorthand properties

-l, --css-level css color module

-G, --legacy-rendering legacy rendering

-o, --output output file name

-L, --preserve-license preserve license comments

-C, --remove-comments remove comments

-E, --remove-empty-nodes remove empty nodes

-r, --render-duplicate-declarations render duplicate declarations

-s, --sourcemap generate sourcemap, require -o

```

### Minify inline css

```bash
$ ./cli/css-parser 'a, div {display:none} b {}' -c
#
$ echo 'a, div {display:none} b {}' | ./cli/css-parser -c
```

### Minify css file

```bash
$ ./cli/css-parser -f nested.css -c
#
$ ./cli/css-parser -f 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/brands.min.css' -c
```

### Dump ast

```bash
$ ./cli/css-parser -f nested.css -f 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css' -c -a
#
$ ./cli/css-parser 'a, div {display:none} b {}' -c -a
#
$ echo 'a, div {display:none} b {}' | ./cli/css-parser -c -a
```

The full [documentation](https://tbela99.github.io/css) can be found [here](https://tbela99.github.io/css)

---
Expand Down
185 changes: 185 additions & 0 deletions cli/css-parser
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#!/bin/php
<?php

use TBela\CSS\Cli\Args;
use TBela\CSS\Cli\Exceptions\MissingParameterException;
use TBela\CSS\Parser;

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

// only use from the cli
if (php_sapi_name() != 'cli') {

fwrite(STDERR, 'this program must be run from the cli');
exit(1);
}

spl_autoload_register(function ($name) {

$parts = explode('\\', $name);

if ($parts[0] == 'TBela' && isset($parts[1]) && $parts[1] == 'CSS') {

array_splice($parts, 0, 2);
array_unshift($parts, 'src');
}

$path = __DIR__ . '/../' . implode('/', $parts) . '.php';

if (is_file($path)) {

require($path);
}
});

$exe = basename($argv[0]);
$cli = new Args($argv);

try {

$cli->
setStrict(true);

$cli->addGroup('parse', "parse options:\n");
$cli->add('capture-errors', 'ignore parse error', 'bool', 'e', false, false, null, null, 'parse');
$cli->add('flatten-import', 'process @import', 'bool', 'm', false, false, null, null, 'parse');
$cli->add('parse-allow-duplicate-rules', 'allow duplicate rule', 'bool', 'p',false, false, null, null, 'parse');
$cli->add('parse-allow-duplicate-declarations', 'allow duplicate declaration', 'auto', 'd',false, false, null, null,'parse');
$cli->add('file', 'css file or url', 'string', 'f', true, false, null, null, 'parse');

$cli->addGroup('render', "render options:\n");
$cli->add('css-level', 'css color module', 'int', 'l', false, false, 4, [3, 4], 'render');
$cli->add('charset', 'remove @charset', 'bool', 'S',false, false, true, null, 'render');
$cli->add('compress', 'minify output', 'bool', 'c',false, false, null, null, 'render');
$cli->add('sourcemap', 'generate sourcemap, require -o', 'bool', 's',false, false, null, null, 'render');
$cli->add('remove-comments', 'remove comments', 'bool', 'C',false, false, null, null, 'render');
$cli->add('preserve-license', 'preserve license comments', 'bool', 'L',false, false, null, null, 'render');
$cli->add('legacy-rendering', 'legacy rendering', 'bool', 'G',false, false, null, null, 'render');
$cli->add('compute-shorthand', 'compute shorthand properties', 'bool', 'u',false, false, null, null, 'render');
$cli->add('remove-empty-nodes', 'remove empty nodes', 'bool', 'E',false, false, null, null, 'render');
$cli->add('render-duplicate-declarations', 'render duplicate declarations', 'bool', 'r',false, false, null, null, 'render');
$cli->add('output', 'output file name', 'string', 'o',false, false, null, null, 'render');
$cli->add('ast', 'dump ast as JSON', 'bool', 'a',false, false, null, null, 'render');

$cli->parse();

$parseOptions = [];
$renderOptions = [];

$groups = $cli->getGroups();
$args = $cli->getArguments();

$pipeIn = !posix_isatty(STDIN);
$pipeOut = !posix_isatty(STDOUT);

$inFile = $pipeIn ? STDIN : (isset($args['file']) ? $args['file'] : null);
$outFile = $pipeOut ? STDOUT : (isset($args['output']) ? $args['output'] : STDOUT);

if ($inFile == STDIN) {

if (!empty($args['file'])) {

fwrite(STDERR, "> notice: ignoring parameter --file\n");
}

if (!empty($args['_'])) {

fwrite(STDERR, "> notice: ignoring inline css\n");
}
}

if ($outFile == STDOUT && !empty($args['output'])) {

fwrite(STDERR, "> notice: ignoring parameter --output\n");
}

if (isset($args['sourcemap']) && $outFile == STDOUT) {

throw new InvalidArgumentException(sprintf("%s: --sourcemap requires --file parameter\nTry '%s --help'", $exe, $exe));
}

foreach (array_keys($groups['parse']['arguments']) as $key) {

if (isset($args[$key])) {

$parseOptions[str_replace(['parse-', '-'], ['', '_'], $key)] = $args[$key];
}
}

foreach (array_keys($groups['render']['arguments']) as $key) {

if (isset($args[$key])) {

$renderOptions[str_replace(['parse-', '-'], ['', '_'], $key)] = $args[$key];
}
}

$parser = new Parser('', $parseOptions);

if ($inFile) {

if ($inFile == STDIN) {

$parser->appendContent(file_get_contents('php://stdin'));
} else {

foreach ((array)$inFile as $file) {

$parser->load($file);
}
}
} else if (!empty($args['_'])) {

$parser->appendContent(implode('', $args['_']));
} else {

// no input
exit(0);
}

if ($outFile) {

if (!empty($args['ast'])) {

if ($outFile == STDOUT) {

fwrite($outFile, json_encode($parser->getAst(), empty($renderOptions['compress']) ? JSON_PRETTY_PRINT : 0));
} else {

file_put_contents($outFile, json_encode($parser->getAst(), empty($renderOptions['compress']) ? JSON_PRETTY_PRINT : 0));
}

} else {

$renderer = new \TBela\CSS\Renderer($renderOptions);

if ($outFile == STDOUT) {

fwrite($outFile, $renderer->renderAst($parser));
} else {

$renderer->save($parser, $outFile);
}
}
}
} catch (ValueError $e) {

fwrite(STDERR, $e->getMessage() . "\n");
exit($e->getCode());
} catch (UnexpectedValueException $e) {

fwrite(STDERR, $e->getMessage() . "\n");
exit($e->getCode());
} catch (InvalidArgumentException $e) {

fwrite(STDERR, $e->getMessage() . "\n");
exit($e->getCode());
} catch (MissingParameterException $e) {

fwrite(STDERR, sprintf("%s: %s\nTry '%s --help'\n", $exe, $e->getMessage(), $exe));
exit($e->getCode());
} catch (Exception $e) {

fwrite(STDERR, $e->getMessage() . "\n");
exit(1);
}
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
},
"autoload": {
"psr-4": {
"TBela\\CSS\\": "src/TBela/CSS"
"TBela\\CSS\\": "src"
}
},
"require": {
"php": ">=5.6.40",
"ext-json": "*",
"ext-curl": "*",
"ext-mbstring": "*",
"symfony/polyfill-mbstring": "v1.19.0",
"axy/sourcemap": "^0.1.5"
"axy/sourcemap": "^0.1.5",
"symfony/polyfill-mbstring": "^1.19"
},
"scripts": {
"test": "./bin/runtest.sh"
Expand Down
Loading

0 comments on commit ac8752b

Please sign in to comment.