Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

docs/how-it-works/ru.md

  • Loading branch information...
commit d8cc1925a3c698f798e130d06a4a86d410c8322d 1 parent bd80846
@deepsweet deepsweet authored
Showing with 216 additions and 8 deletions.
  1. +8 −8 docs/how-it-works/en.md
  2. +208 −0 docs/how-it-works/ru.md
View
16 docs/how-it-works/en.md
@@ -51,7 +51,7 @@ It's important to note that every plugin:
- - -
### 2. svg2js
-SVGO converts SVG-as-XML data into SVG-as-JS representation. Something like this:
+SVGO converts SVG-as-XML data into SVG-as-JS AST representation. Something like this:
```xml
<?xml version="1.0" standalone="no"?>
@@ -118,15 +118,15 @@ It's important to note that:
- - -
### 3. plugins
-SVGO applies all plugins from the config to SVG-as-JS data. See a lot of examples in the [plugins directory](https://github.com/svg/svgo/tree/master/plugins) above.
+SVGO applies all plugins from the config to AST data. See a lot of examples in the [plugins directory](https://github.com/svg/svgo/tree/master/plugins) above.
#### 3.1 types
-In the simplest case plugins process can be represented as "each plugin runs over all SVG-as-JS data items and perform some actions". But 90% of typical optimizations requires some actions only on one (current) item from the data, so there is no sense to copypaste a recursive per-item loop every time on every plugin. And that's why we have a three types of plugins:
+In the simplest case plugins applying process can be represented as "each plugin runs over all AST data items and perform some actions". But 90% of typical optimizations requires some actions only on one (current) item from the data, so there is no sense to copypaste a recursive per-item loop every time on every plugin. And that's why we have a three types of plugins:
* `perItem` - plugin works only with one current item, inside a "from the outside into the depths" recursive loop (default)
* `perItemReverse` - plugin works only with one current item, inside a "from the depths to the outside" recursive loop (useful when you need to collapse elements one after other)
-* `full` - plugin works with the full SVG-as-JS data and must returns the same
+* `full` - plugin works with the full AST and must returns the same
`perItem` and `perItemReverse` plugins runs inside the recursive `Array.prototype.filter` loop, so if a plugin wants to remove current item then it should just `return false`.
@@ -182,9 +182,10 @@ And of course, writing plugins would not have been so cool without some sugar AP
* @param {Object} attr attribute object
* @return {Object} created attribute
-##### eachAttr(callback)
+##### eachAttr(callback, [context])
* Iterates over all attributes.
* @param {Function} callback
+ * @param {Object} [context] callback context
* @return {Boolean} false if there are no any attributes
#### 3.3 tests
@@ -200,9 +201,8 @@ You can see a lot of examples in the [test/plugins directory](https://github.com
- - -
### 4. js2svg
-SVGO converts SVG-as-JS representation into SVG-as-XML data string.
+SVGO converts AST back into SVG-as-XML data string.
## What's next
1. Write your own plugin :) or
-2. Give me an idea of new plugin or API method
-3. Pull request my crooked english
+2. Give me an idea of new optimization or API method
View
208 docs/how-it-works/ru.md
@@ -0,0 +1,208 @@
+## TOC
+* [Введение](#введение)
+* [Как это работает](#как-это-работает)
+ * [конфиг](#1-конфиг)
+ * [svg2js](#2-svg2js)
+ * [плагины](#3-плагины)
+ * [типы](#31-типы)
+ * [API](#32-api)
+ * [тесты](#33-тесты)
+ * [js2svg](#4-js2svg)
+* [Что дальше](#что-дальше)
+
+
+## Введение
+Итак, как уже было [сказано ранеее](https://github.com/svg/svgo#what-it-can-do), SVGO SVGO имеет плагинную архитектуру, в которой практически каждая оптимизация является отдельным плагином.
+
+Плагины могут удалять и изменять SVG элементы, схлопывать контент, перемещать атрибуты и выполнять любые другие действия, которые вы захотите.
+
+## Как это работает
+### 1. конфиг
+SVGO читает, парсит и/или расширяет [конфиг по умолчанию](https://github.com/svg/svgo/blob/master/.svgo.yml), который содержит все настройки, включая плагины. Что-то вроде этого:
+
+```yaml
+plugins:
+
+ - name: myTestPlugin
+ active: true
+ type: perItem
+ params:
+ testParam: true
+ testParam2: 3
+
+ - name: myTestPlugin2
+ active: false
+ type: perItemReverse
+
+ - name: myTestPlugin3
+ active: true
+ type: full
+
+
+```
+
+Важно отметить, что каждый плагин:
+
+ * находится в определённой позиции в массиве плагинов
+ * может быть включён через `"active": true` и выключен через `"active": false`
+ * может иметь свои собственные параметры `params`, которые будут доступны позже в коде плагина
+ * должен быть одного из трёх типов: `perItem`, `perItemReverse` и `full` (мы вернёмся к этому позже)
+
+- - -
+
+### 2. svg2js
+SVGO конвертирует SVG-как-XML данные в SVG-как-JS AST-представление. Что-то вроде этого:
+
+```xml
+<?xml version="1.0" standalone="no"?>
+<!-- Generator: Adobe Illustrator 16.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <text>test</text>
+ <script><![CDATA[ alert('hello'); ]]></script>
+</svg>
+```
+
+```js
+{
+ content: [
+ {
+ processinginstruction: { name: 'xml', body: 'version="1.0" standalone="no"' }
+ },{
+ doctype: ' svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"'
+ },{
+ comment: 'Generator: Adobe Illustrator 16.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)'
+ },{
+ elem: 'svg',
+ prefix: '',
+ local: 'svg',
+ attrs: {
+ version: {
+ name: 'version',
+ value: '1.1',
+ prefix: '',
+ local: 'version'
+ },
+ xmlns: {
+ name: 'xmlns',
+ value: 'http://www.w3.org/2000/svg',
+ prefix: 'xmlns',
+ local: ''
+ }
+ },
+ content: [
+ {
+ elem: 'text',
+ prefix: '',
+ local: 'text',
+ content: [ { text: 'test' } ]
+ },{
+ elem: 'script',
+ prefix: '',
+ local: 'script',
+ content: [ { cdata: ' alert(\'hello\'); ' } ]
+ }
+ ]
+
+ }
+ ]
+}
+```
+
+Важно отметить, что:
+
+ * для представления различных узлов SVG в объектах есть специальные поля: `elem`, `processinginstruction`, `doctype`, `comment`, `cdata` и `text`
+ * `content` – это всегда массив
+ * в поле `attrs` имя атрибута всегда полное, вместе с пространством имён, если оно есть, а все детали разбиты на части в специальных полях `prefix` и `local`
+
+- - -
+
+### 3. плагины
+SVGO применяет все плагины из конфига на данные из AST. Можно посмотреть на множество примеров в [директории плагинов](https://github.com/svg/svgo/tree/master/plugins) выше.
+
+
+#### 3.1 типы
+В самом простом случае процесс применения плагинов можно представить как «каждый плагин пробегается по дереву AST и выполняет какие-то действия». Но 90% обычных оптимизаций требуют каких-либо действий только на одном (текущем) элементе из дерева данных, и нет смысла копипастить рекурсивный цикл по всем элементам в каждом плагине. Это объясняет, почему у нас есть три типа плагинов:
+
+* `perItem` - плагин работает только с текущим элементом внутри рекурсивного цикла «снаружи внутрь» (по умолчанию)
+* `perItemReverse` - плагин работает только с текущим элементом внутри рекурсивного цикла «изнутри наружу» (полезно, например, в случае необходимости схлопывать вложенные элементы один за другим)
+* `full` - плагин работает с полным деревом AST и должен вернуть его же
+
+`perItem` и `perItemReverse` плагины выполняются внутри цикла `Array.prototype.filter`, поэтому можно удалить текущий элемент просто вернув `false`.
+
+Но это ещё не всё ;) Мы избавились от копипаста рекурсивного цикла, но каждый плагин по-прежнему пробегается по всему дереву AST, что не слишком оптимально. На самом деле, на первом шаге, где мы получаем итоговый конфиг, происходит группировка идущих подряд плагинов одного типа и один цикл обрабатывает целую такую группу:
+
+```yaml
+plugins
+
+ - [perItem group],
+ - [perItemReverse group],
+ -
+ - [perItem group],
+ -
+ - [full group]
+ -
+
+
+```
+
+#### 3.2 API
+
+И конечно же, написание плагинов не было бы таким клёвым без удобного API:
+
+##### isElem([param])
+ * Determine if item is an element (any, with a specific name or in a names array).
+ * @param {String|Array} [param] element name or names arrays
+ * @return {Boolean}
+
+##### isEmpty()
+ * Determine if element is empty.
+ * @return {Boolean}
+
+##### hasAttr([attr], [val])
+ * Determine if element has an attribute (any, or by name or by name + value).
+ * @param {String} [name] attribute name
+ * @param {String} [val] attribute value (will be toString()'ed)
+ * @return {Boolean}
+
+##### attr(name, [val])
+ * Get a specific attribute from an element (by name or name + value).
+ * @param {String} name attribute name
+ * @param {String} [val] attribute value (will be toString()'ed)
+ * @return {Object|Undefined}
+
+##### removeAttr(name, [val])
+ * Remove a specific attribute (by name or name + val).
+ * @param {String} name attribute name
+ * @param {String} [val] attribute value
+ * @return {Boolean}
+
+##### addAttr(attr)
+ * Add an attribute.
+ * @param {Object} attr attribute object
+ * @return {Object} created attribute
+
+##### eachAttr(callback, [context])
+ * Iterates over all attributes.
+ * @param {Function} callback
+ * @param {Object} [context] callback context
+ * @return {Boolean} false if there are no any attributes
+
+#### 3.3 тесты
+
+Нет ничего проще, чем протестировать ваш плагин:
+
+1. создайте `myPlugin.01.orig.svg` и `myPlugin.01.should.svg` в `test/plugins`
+2. запустите `npm test`
+3. PROFIT!
+
+Можно увидеть множество примеров в [test/plugins directory](https://github.com/svg/svgo/tree/master/test/plugins).
+
+- - -
+
+### 4. js2svg
+SVGO конвертирует обратно AST в SVG-как-XML строку.
+
+## Что дальше
+1. Напишите свой собственный плагин :) или
+2. Или подскажите идею новой оптимизации или метода API
Please sign in to comment.
Something went wrong with that request. Please try again.