28.10.13

Установка Arch по сети

Цель:
загрузить по сети установочный образ Арча посредством PXE, например для последующей его установки или использовать его для чего-нибудь ещё.

PXE - проще говоря это код в микросхеме ПЗУ сетевой карты который получив по сети исполняемый файл (к примеру загрузчик ОС) передаёт ему управление. Всё это работает в пределах локальной сети.

Начальные условия:
Комп1 - здесь крутится любая операционная система с установленным VirtualBox, отсюда будем проводить экспансию на Комп2.
Комп2 - железо поддерживающее загрузку по сети и которое предварительно настраиваем в BIOS.
ISO образ Арча - скачиваем с офф. сайта
Наличие сети между Комп1 и Комп2 - соединение напрямую по витой паре либо через роутер с предварительно отключённым в нём DHCP (чтобы избежать всяких непредвиденных коллизий). В принципе DHCP-сервер в роутере можно и не отключать, у меня к примеру он работал.

И так, приступим.

Фаза первая.
Настройка окружения виртуальной машины (ВМ) и её запуск на Компе1.
--------------------------------------------------------------------------------------------------
Создадим окружение ВМ. Есть два варианта, либо через консоль, либо через GUI.
Плюс консоли в том что можно, при желании, создать скрипт с помощью которого за пару секунд развернётся требуемое окружение ВМ.
Главное что нам понадобится это сеть через мост и виртуальный привод с загруженным исошником установочного образа Арча.
Вот минимально необходимая конфигурация.

nano Arch1.sh
#!/bin/sh
# Создадим новую ВМ с именем Arch1:
vboxmanage createvm --name Arch1 --ostype ArchLinux_64 --register
# Выделим подходящий объем оперативной памяти (в принципе нам по умолчанию и так хватает):
# vboxmanage modifyvm Arch1 --memory 128
# Оборудуем контроллером для подлючения CD-привода:
vboxmanage storagectl Arch1 --name "sata" --add sata
# Подключим iso образ, здесь "./archlinux-2013.10.01-dual.iso" путь задаётся относительно запуска команды, iso и sh файлы лежат у меня в одной папке:
vboxmanage storageattach Arch1 --storagectl "sata" --port 0 --type dvddrive --medium ./archlinux-2013.10.01-dual.iso
# Установим сеть в режим сетевого моста, здесь enp2s0 имя сетевого интерфейса хост системы, может отличатся:
vboxmanage modifyvm Arch1 --nic1 bridged --bridgeadapter1 enp2s0
# Запуск ВМ:
vboxmanage startvm Arch1

chmod +x Arch1.sh
./Arch1.sh

Возможно пригодятся команды выключить и удалить ВМ:
vboxmanage controlvm Arch1 poweroff
vboxmanage unregistervm Arch1 --delete

Конечно самым простым одноразовым вариантом будет создать среду ВМ через графический интерфейс виртуалбокса.
Так примерно будет выглядеть эта конфигурация.



В принципе есть и третье решение с помощью экспорта/импорта конфигурации ВМ, тогда всё сводится к паре кликов, но конечно же сначала надо эту конфигурацию подготовить с помощью одного из двух вышеперечисленных вариантов.

Возможно пригодятся команды экспорт и импорт ВМ:
vboxmanage export Arch1 -o Arch1.ova
vboxmanage import Arch1.ova

Запускаем ВМ


Фаза вторая.
Настройка ВМ Arch1 для раздачи по сети установочного образа.
-----------------------------------------------------------------------------------------
Допустим имеем локальную сеть, к примеру: 192.168.3.0/24
24 - маска сети, тоже самое что и 255.255.255.0, если не знаете как перевести то можно глянуть здесь
пусть роутер шифруется по адресу: 192.168.3.1 (если есть)
естественно у юного падавана сеть может немного отличатся, поэтому везде ставим свои настройки.

Если DHCP-сервер в роутере отключён или компы связаны напрямую то нужно сначала задать IP-адрес. К примеру такой:
ip a a 192.168.3.12/24 dev enp0s3
enp0s3 - это название моего сетевого интерфейса в Arch1, он может отличатся, посмотреть можно в выводе команды ip a.

DNSMASQ - это DHCP, TFTP и DNS в одном флаконе.
Настраиваем его:
rm /etc/dnsmasq.conf
nano /etc/dnsmasq.conf
port=0
interface=enp0s3
bind-interfaces
dhcp-range=192.168.3.20,192.168.3.40,255.255.255.0,2h
dhcp-boot=/arch/boot/syslinux/pxelinux.0
dhcp-option-force=209,boot/syslinux/archiso.cfg
dhcp-option-force=210,/arch/
enable-tftp
tftp-root=/run/archiso/bootmnt/

здесь может поменяться только:
interface - это интерфейс виртуальной сетевой карты Arch1.
dhcp-range - диапазон адресов, маска сети и время аренды адреса. Из этого диапазона будет выдан IP-адрес Arch2, диапазон можно указать любой, главное чтобы Arch1 и Arch2 находились в одной сети.

Запускаем dnsmasq:
systemctl start dnsmasq.service

если что то не заладилось смотрим:
journalctl -xn
(можно запустить во втором терминале Alt+F2 чтобы мониторить)
будет указан номер строки конфига dnsmasq где допустили ошибку.

если что-то поменяли или исправили в конфиге то сервис нада перезапустить:
systemctl restart dnsmasq.service

Теперь осталось познать тёмную сторону силы:
darkhttpd /run/archiso/bootmnt/

оно не зависло, оставляем в таком состоянии, это заработал наш веб-сервер :)

Фаза третья.Заключительная.
Загрузка по сети установочного образа Arch2 на Компе2 и выход в мировую паутину.
-------------------------------------------------------------------------------
Время пришло юный джедай, пора отправляться в путь.

Запускаем Комп2, не забыв предварительно поставить загрузку по сети в Биосе.

Если что-то пошло не так то на Арч1 проследим за событиями dnsmasq:
journalctl -u dnsmasq -f

Пошла жара.



Мы используем для загрузки образа HTTP протокол.



Если всё ОК то мы увидим строку приглашения Арч2. Звезду смерти Арч1 можно тушить.



Как видим пинг будет работать в пределах нашей локальной сети.
Чтобы иметь выход в интернет перекинем шлюз с Арч1 на роутер (это конечно если сам роутер имеет выход в интернет):
ip route change via 192.168.3.1 dev eth0
где eth0 это сетевой интерфейс Arch2, посмотреть можно командой ip a



Напоследок пощекочем корпорацию добра:
ping 8.8.8.8 -i 0.01

Всё теперь можно устанавливать Арч3 на Комп2, или использовать Arch2 для чего-нибудь ещё :)

12.10.13

Печать документа pdf буклетом

В процессе подготовки автореферата диссертации я обнаружил, что okular не умеет печатать pdf буклетом, то есть пересортировывая странички для получения книжечки размера A5. Всё что я нашёл по этому вопросу заключалось в использовании утилит psbook и psnup, что меня не устраивало по причине того, что приходилось перегонять pdf в ps. Почему-то в результате этого преобразования получался ps файл размером в 50 мегабайт и меня это не устраивало.

Но я нашёл замечательный пакет для LaTeX, который называется pdfpages. С его помощью можно вставлять станицы в теховый документ из сторонних pdf файлов преобразовывая их всяческим образом. Я создал ещё один теховый файл с очень простым содержимым:


\documentclass[letterpaper, 11pt]{article}
\pagestyle{plain}
\usepackage{pdfpages}
\usepackage[a4paper,nohead,includefoot,mag=1000]{geometry}
\begin{document}
 \includepdf[pages={-}, signature=24, landscape]{autoref}
\end{document}


При компиляции это файл берёт страницы из файла autoref.pdf, пересортировывает их нужным образом и ставит по 2 на страницу. Добавив одну строчку к Makefile я сразу же получаю готовый pdf, можно смело печатать с двух сторон (по длинной стороне) и получить заветную книжку.

Надо заметить, что таким образом превратить в буклет можно любой pdf файл, не обязательно сгенерированный pdftex'ом.

Как быстро поднять простой HTTP-сервер

Иногда нужно очень быстро поднять HTTP-сервер с минимальным функционалом. Например, нужно проверить HTML+JavaScript, который работает только через веб-сервер. Я, конечно понимаю, что у меня под рукой всегда есть, как минимум nginx, и поднять на нем сайт, который будет раздавать статические фалы, делов на 5-10 минут. Но, во-первых, это долго, а во-вторых, этот самый nginx у меня находится на виртуалке, пусть и включенной в 90% времени на ноутбуке. А тут прийдется не только веб-сервер настроить, но и расшаренные папки в VirtualBox-е, и так далее...
Единственное, что у меня действительно всегда есть под рукой, это Python (уже несколько лет не пользуюсь ОС Windows, а на всех *nix он есть из коробки). Поднять простой тестовый веб-сервер на питоне можно всего одной командой:
$ python -m SimpleHTTPServer 8100
После этой команды, у вас локально запустится веб-сервер на 8100-м порту, который покажет содержимое текущей папки.
Работает это благодаря ключу -m, который указывает интерпритатору о том, что необходимо выполнить модуль как скрипт. Это идентично команде "$ python /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SimpleHTTPServer.py", но писать значительно проще. Единственное ограничение, что этот модуль должен быть доступен в sys.path

Для python3 команда выглядит так python -m http.server 8888

11.10.13

Sopcast

sp-sc sop://yoursopchannel 3908 8908
then in another console open a media player (vlc , totem , mplayer...) with:
vlc/mplayer/totem http://localhost:8908

06.10.13

Configuring anonymous public shares with Samba 3

On the fileserver I run, I use samba to conveniently access my files. I like Samba. I can mount it on any machine I run and access my files like it’s any other filesystem, but when it comes to sharing files to other (anonymous) users, Samba has to cope with some ugly Windows legacy. After all, Samba is just an open source implementation of SMB/CIFS which Windows calls “Windows File Sharing”. Let’s look at the differences and how to cope with them.

The Windows way

When a Windows client tries to access a share on a Windows server, it requests the given share using username and password of the current user on the client. The Windows server will then look for this username/password combination and if it exists, grants the user access to the share with the proper rights assigned. If it can’t find the username, it falls back to an anonymous user and grants access anyway (if this is policy).

How Samba handles it

This is where Samba differs. If set to security=user (which is a good idea anyway), when a user requests access to a share, it too looks up the credentials in a backend. However, if the user is unknown to the system, the default behaviour is to deny access. This is kind of unfriendly to Windows users, since they aren’t used to type in “guest” as a username and refuse to understand how to log in a way different from what they are used. This is how to set up your public shares to imitate Windows behaviour.

How to imitate Windows behavior using Samba

In my example, I’ve got one public share, on which I want to have full rights for myself and limited (read-only) access to all anonymous users. The name of the share will be “public”:
#/etc/samba/smb.conf
[public]
        comment = Public Shares
        browsable = yes
        path = /data/pub
        public = yes
        writable = no
        write list = dawuss
        guest ok = yes

This sets up a share named “public” which is shown when browsing the server to any user with rights to do so. You can see it is public, but not writable except for “dawuss” (which is me) and that it is ok for guests to login.
Next, we need to set up the guest access itself. In the global section:
[global]
        #...
        guest account = nobody

Which defines the account to use when authenticating guests. Don’t forget to create this user using
# smbpasswd -an nobody
This will create the user with no password.
Now we have a perfectly valid Samba setup with a public share, but every time a user wants to access this share as a guest, he will have to do so by logging in as “nobody”. To complete our setup and imitate Windows behaviour, add the following line to the smb.conf global section:
[global]
        #...
        map to guest = bad user

This maps any unknown username to the specified guest user, so login always succeeds.
We’re done! Remember, this will only work for unknown usernames. If an unhappy user called “pete” tries to login while there already exists a pete on the server with a different password, he will be denied access. This is normal behaviour when imitating Windows, so we’ll just have to live with that.

03.10.13

Emmet - полезный инструмент для создания HTML разметки. Часть 1

Emmet (ранее известный как Zen Coding) является инструментом для веб-разработки, который может значительно улучшить и облегчить работу с HTML и CSS. Эта статья посвящена возможностям Emmet, которые он предоставляет для быстрого создания разметки  HTML.

Содержание


В принципе, большинство текстовых редакторов позволяют хранить и повторно использовать часто используемые фрагменты кода, называемые "сниппеты". Хотя сниппеты и являются хорошим способом повышения производительности, все их реализации имеют общие недостатки: вы должны сначала определить сниппет и вы не можете расширить их при исполнении.
Emmet выводит идею сниппетов на совершенно новый уровень: вы вводите CSS-подобные выражения, которые динамически анализируются, и получаете результат в зависимости от введённой аббревиатуры. Emmet разработан и оптимизирован для HTML/XML и CSS, но может использоваться и для языков программирования.
Вы можете скачать Emmet в виде плагина для одного из редакторов, которых поддерживается не мало:
download-emmet-for-editors

Аббревиатуры

Аббревиатуры являются сердцем Emmet: эти специальные выражения обрабатываются во время выполнения и превращаются в структурированный блок кода, например HTML. Синтаксис аббревиатур похож на селекторы CSS, за исключением нескольких особых расширений для генерации кода. Таким образом, каждый веб-разработчик уже знает как его использовать.
Вот пример: эта аббревиатура
#page>div.logo+ul#navigation>li*5>a{Item $}
превращается в
<div id="page">
<div class="logo"></div>
<ul id="navigation">
<li><a href="">Item 1</a></li>
<li><a href="">Item 2</a></li>
<li><a href="">Item 3</a></li>
<li><a href="">Item 4</a></li>
<li><a href="">Item 5</a></li>
</ul>
</div>
... с помощью всего одного нажатия клавиши. Во многих редакторах (например, Eclipse, Sublime Text 2, Espresso и т.д.) плагины также будут генерировать надлежащие позиции tabstop, что даст вам возможность пройти между важными местами сгенерированного кода с помощью клавиши табуляции.
Аббревиатуры оптимизированы для HTML и XML, но не ограничиваются ими, и делают утомительное написание кода разметки сверхбыстрым. Изучите синтаксис аббревиатур, чтобы раскрыть всю мощь Emmet.

Синтаксис аббревиатур

Emmet использует аналогичный CSS-селекторам синтаксис, для описания позиций внутри генерируемого дерева и атрибутов элемента.

Элементы

Вы можете использовать имена элементов, как p или div для генерации HTML-тегов. Emmet не имеет предопределенного набора доступных имен тегов, поэтому вы можете написать любое слово и превратить его в тег: сdiv<div></div>, foo<foo></foo> и так далее.

Операторы вложения

Вложенные операторы используются для позиционирования элементов аббревиатуры внутри генерируемого дерева: должны ли они размещаться внутри или рядом с элементом контекста.

Вложение: >

Вы можете использовать оператор > для вложения элементов друг в друга:
div>ul>li
...станет
<div>
<ul>
<li></li>
</ul>
</div>

Добавление: +

Используйте оператор + для размещения элементов рядом друг с другом на том же уровне:
div+p+bq
...выведет
<div></div>
<p></p>
<blockquote></blockquote>

На уровень вверх: ^

С оператором > вы спускаетесь по сгенерированному дереву и позиции всех родственных элементов будут определятся в отношении самого глубокого элемента:
div+div>p>span+em
...будет преобразована в
<div></div>
<div>
<p><span></span><em></em></p>
</div>   
С оператором ^ вы можете подняться на один уровень вверх в дереве и изменить контекст, в котором должны отображаться следующие элементы:
div+div>p>span+em^bq
выведет ...
<div></div>
<div>
<p><span></span><em></em></p>
<blockquote></blockquote>
</div>
Вы можете использовать столько угодно операторов ^, каждый из них будет перемещать на один уровень вверх:
div+div>p>span+em^^^bq
...будет выводить
<div></div>
<div>
<p><span></span><em></em></p>
</div>
<blockquote></blockquote>

Повторение: *

С оператором * вы можете определить сколько раз должен быть выведен элемент:
ul>li*5
выведет ...
<ul>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>

Группировка: ()

Скобки используются в Emmet для группировки поддеревьев в сложные аббревиатуры:
div>(header>ul>li*2>a)+footer>p
...будет развёрнуто в
<div>
<header>
<ul>
<li><a href=""></a></li>
<li><a href=""></a></li>
</ul>
</header>
<footer>
<p></p>
</footer>
</div>
Если вы работаете с деревом DOM браузера, то думайте о группах как о фрагментах документа: каждая группа содержит аббревиатуру поддерево и все следующие элементы вставляются на том же уровне, в качестве первого элемента в группе.
Вы можете создавать группы внутри друг друга и объединять их с помощью оператора *:
(div>dl>(dt+dd)*3)+footer>p
...превратится
<div>
<dl>
<dt></dt>
<dd></dd>
<dt></dt>
<dd></dd>
<dt></dt>
<dd></dd>
</dl>
</div>
<footer>
<p></p>
</footer>
С группами, вы в буквальном смысле можете написать полную разметку страницы с помощью одной аббревиатуры, но пожалуйста, не делайте этого.

Операторы атрибутов

Операторы атрибутов используются для изменения атрибутов выводимых элементов. Например, в HTML и XML вы можете быстро добавить атрибут class к создаваемому элементу.

ID и CLASS

В CSS вы используете elem#id и elem.class , чтобы выбрать элементы с заданным id или атрибутом class. В Emmet вы можете использовать тот же синтаксис, чтобы добавить эти атрибуты к указанному элементу:
div#header+div.page+div#footer.class1.class2.class3
...выведет
<div id="header"></div>
<div class="page"></div>
<div id="footer" class="class1 class2 class3"></div>

Пользовательские атрибуты

Для добавления к элементу пользовательских атрибутов вы можете использовать нотацию [attr] (как в CSS):
td[title="Hello world!" colspan=3]
...выведет
<td title="Hello world!" colspan="3"></td>
  • Вы можете размещать внутри квадратных скобок неограниченное количество атрибутов.
  • Вам не обязательно указывать значения атрибутов: td[colspan title] сгенерирует <td colspan="" title=""> с табстопами внутри каждого пустого атрибута (если ваш редактор поддерживает их).
  • Для заключения в кавычки значений атрибутов вы можете использовать как одинарные, так и двойные кавычки.
  • Не надо заключать в кавычки значения, если они не содержат пробелы: td[title=hello colspan=3] будет работать.

Нумерация элементов: $

С помощью оператора * вы можете повторять элементы, но с $ их можно нумеровать. Оператор $ должен располагаться в имени элемента, имени атрибута или в значении атрибута, чтобы выводился порядковый номер повторяющихся элементов:
ul>li.item1*5
выведет ...
<ul>
<li class="item1"></li>
<li class="item2"></li>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
</ul>
Вы можете использовать несколько $ подряд, чтобы получить номер с нулями:
ul>li.item001*5
выведет ...
<ul>
<li class="item001"></li>
<li class="item002"></li>
<li class="item003"></li>
<li class="item004"></li>
<li class="item005"></li>
</ul>

Изменение начала и направления нумерации

С модификатором @ вы можете изменить направление нумерации (по возрастанию или по убыванию) и начальное значение.
Например, чтобы изменить направление, добавьте @- после $:
ul>li.item1*5
...даст результат
<ul>
<li class="item5"></li>
<li class="item4"></li>
<li class="item3"></li>
<li class="item2"></li>
<li class="item1"></li>
</ul>
Для изменения начального значения счетчика добавьте модификатор @N:
ul>li.item3*5
...преобразуется в
<ul>
<li class="item3"></li>
<li class="item4"></li>
<li class="item5"></li>
<li class="item6"></li>
<li class="item7"></li>
</ul>
Вы можете использовать эти модификаторы вместе:
ul>li.item3*5
...преобразуется в
<ul>
<li class="item7"></li>
<li class="item6"></li>
<li class="item5"></li>
<li class="item4"></li>
<li class="item3"></li>
</ul>

Текст: {}

Для добавления текста в элемент используйте фигурные скобки:
a{Click me}
...выведет
<a href="">Click me</a>
Обратите внимание, что {текст} используется и обрабатывается как отдельный элемент (как div, p и др.), но имеет особое значение, когда написан сразу после элемента. Например, a{click} и a>{click} дадут одинаковый результат, но a{click}+b{here} и a>{click}+b{here} нет:
<!-- a{click}+b{here} -->
<a href="">click</a><b>here</b>
 
<!-- a>{click}+b{here} -->
<a href="">click<b>here</b></a>
Во втором примере элемент <b> расположен внутри элемента <a>. И вот в чем разница: когда {текст} пишется сразу после элемента, то это не изменяет родительского контекста. Вот более сложный пример, показывающий, почему это важно:
p>{Click }+a{here}+{ to continue}
...даст результат
<p>Click <a href="">here</a> to continue</p>
В этом примере, чтобы написать Click here to continue внутри элемента <p>, мы четко движемся вниз по дереву, используя оператор > после p, но для элемента <a> мы его не используем, так как в нём нам нужно только слово, без изменения родительского контекста.
Для сравнения, та же самая аббревиатура, написанная без вложенного оператора >:
p{Click }+a{here}+{ to continue}
...выводит
<p>Click </p>
<a href="">here</a> to continue

Совет по форматированию аббревиатур

Когда вы ознакомитесь с синтаксисом аббревиатур Emmet, вы возможно захотите использовать некоторые элементы форматирования, чтобы сделать ваши аббревиатуры более читаемыми. Например, использовать пробелы между элементами и операторами, вроде этого:
(header > ul.nav > li*5) + footer
Но она не будет работать, потому что пробел - это символ остановки, на котором Emmet прекращает разбор аббревиатуры.
Многие пользователи ошибочно полагают, что каждая аббревиатура должна быть написана с новой строки, но они ошибаются: вы можете вводить и выполнять аббревиатуры где-угодно в тексте.

Типы элементов

в HTML- и XML-документах, при развертывании аббревиатур все их части трансформируются "на лету" в HTML/XML-теги. Но некоторые элементы, как например a или img, превращаются в элементы с предопределенными атрибутами: <a href=""></a> и <img src="" alt="" />. Откуда Emmet знает когда следует добавлять атрибуты?
Все описания элементов Emmet хранятся в файле snippets.json в следующем формате:
{
"html": {
"abbreviations": {
"a": "<a href=\"\">",
"link": "<link rel=\"stylesheet\" href=\"\" />"
...
},
"snippets": {
"cc:ie6": "<!--[if lte IE 6]>\n\t${child}|\n<![endif]-->"
...
}
},
 
"css": {
...
}
}
Как вы можете видеть, на первом уровне размещаются языки разметки, для которых определены элементы. Внутри этой секции расположены определения элементов, разделённые на две части: snippets и abbreviations.

Сниппеты

Сниппеты - это просто куски обычного кода, как и в большинстве редакторов. Вы можете напечатать здесь что угодно и оно будет выводится “как есть”, без каких-либо преобразований.

Аббревиатуры

Аббревиатуры - это на самом деле блоки с некоторыми подсказками. Emmet, в основном, используется для написания HTML/XML-тегов, объявление аббревиатуры использует XML-формат для описания элемента.
Emmet анализирует определение аббревиатуры и получает следующие данные:
  • имя элемента;
  • атрибуты по умолчанию;
  • порядок атрибутов;
  • значения по умолчанию атрибутов;
  • должен элемент содержать закрывающий тег или нет.
Давайте внимательнее посмотрим на объявления аббревиатур HTML на примере выше. Элемент link определяется как <link rel="stylesheet" href="" /> (двойные кавычки должны быть экранированы в JSON; или используйте одинарные кавычки). Это определение говорит, что этот тег, созданный для аббревиатуры link, должен быть назван link и должен содержать два атрибута: rel со значением по умолчанию “stylesheet” и href с пустым значением (именно в этом порядке), а также сгенерированный элемент не должен содержать закрывающий тег.
После раскрытия аббревиатуры link вы получите следующий результат в HTML:
<link rel="stylesheet" href="">
Вы можете переопределить значения атрибутов по умолчанию и добавить новые:
link[rel=prefetch title="Hello world"]
...преобразуется в
<link rel="prefetch" href="" title="Hello world">
Вы можете добавлять дочерние элементы:
link>xsl:apply-templates
...выведет
<link rel="stylesheet" href="">
<xsl:apply-templates></xsl:apply-templates>
</link>

Псевдонимы

В разделе abbreviations файла snippets.json вы можете также определять псевдонимы: сокращения для широко используемых аббревиатур. Псевдонимы могут использоваться для определения:
  • коротких названий для длинных имен тегов;
  • ссылок на часто используемые аббревиатуры.
В файле snippets.json вы можете найти следующие определения:
...
"html": {
"abbreviations": {
"bq": "blockquote",
"ol+": "ol>li"
}
}
В примере выше, при преобразование аббревиатуры bq, Emmet будет искать определение аббревиатуры blockquote. Если его не существует, он выведет просто <blockquote></blockquote>. Аббревиатура ol+ фактически даёт такой же результат как и ol>li.
Определение ol+, возможно, выглядят неоднозначно, поскольку оно содержит + в конце, который также является оператором добавления. Emmet корректно выполняет такие аббревиатуры и знак "плюс" оставлен по историческим причинам. Просто помните, что вам не нужно использовать +, чтобы создать псевдоним аббревиатуры.

Неявные имена тегов

Даже с таким мощным движком аббревиатур, который может развернуть большую HTML-конструкцию из короткой аббревиатуры, написание имен тегов может быть очень утомительным.
Во многих случаях вы можете пропускать ввод имён тегов и Emmet будет подставлять их за вас. Например, вместо div.content вы можете просто написать .content и получите <div class="content"></div>.

Как это работает

Когда вы разворачиваете аббревиатуру, Emmet пытается захватить родительский контекст, например элемента HTML, внутри которого вы выполняете аббревиатуру. Если контекст был схвачен успешно, Emmet использует его имя для решения неявных имён:
Emmet смотрит на имя родительского тега каждый раз, когда вы разворачиваете аббревиатуру с неявным именем. Вот как он разрешает имена для некоторых родительских элементов:
  • li для ul и ol
  • tr для table, tbody, thead и tfoot
  • td для tr
  • option для select и optgroup
Взгляните на некоторые эквиваленты аббревиатур с явными и неявными именами тегов:
.wrap>.content div.wrap>div.content
em>.info em>span.info
ul>.item*3 ul>li.item*3
table>#row$*4>[colspan=2] table>tr#row$*4>td[colspan=2]

Генератор “Lorem Ipsum”

Текст “Lorem ipsum” используется многими веб-разработчикам для тестирования того, как их шаблоны в формате HTML будут выглядеть с реальными данными. Часто разработчики используют услуги третьих сторон для создания текста “Lorem ipsum”, но теперь вы можете сделать это прямо в вашем редакторе. Просто выполните аббревиатуры lorem или lipsum, чтобы получить следующий сниппет:
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eligendi non quis exercitationem culpa nesciunt nihil aut nostrum explicabo reprehenderit optio amet ab temporibus asperiores quasi cupiditate. Voluptatum ducimus voluptates voluptas?
lorem не просто обычный сниппет - это на самом деле генератор. Каждый раз, когда вы выполняете его, он будет генерировать 30 слов фиктивного текста, разделённого на несколько предложений.
Вы можете указать, сколько слов должно быть сгенерировано. Например, lorem100 создаст 100 слов.
Вы можете использовать генератор lorem внутри повторяющихся элементов, чтобы создать теги, полностью заполненные случайными предложениями. Например, аббревиатура p*4&gt;lorem сгенерирует следующее:
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Qui dicta minus molestiae vel beatae natus eveniet ratione temporibus aperiam harum alias officiis assumenda officia quibusdam deleniti eos cupiditate dolore doloribus!</p>
<p>Ad dolore dignissimos asperiores dicta facere optio quod commodi nam tempore recusandae. Rerum sed nulla eum vero expedita ex delectus voluptates rem at neque quos facere sequi unde optio aliquam!</p>
<p>Tenetur quod quidem in voluptatem corporis dolorum dicta sit pariatur porro quaerat autem ipsam odit quam beatae tempora quibusdam illum! Modi velit odio nam nulla unde amet odit pariatur at!</p>
<p>Consequatur rerum amet fuga expedita sunt et tempora saepe? Iusto nihil explicabo perferendis quos provident delectus ducimus necessitatibus reiciendis optio tempora unde earum doloremque commodi laudantium ad nulla vel odio?</p>