Возможно вы сочтете это глупостью, но я не люблю IDE. Обычно всю работу проделываю в vim+tmux+терминал. Я признаю все преимущества IDE, просто мне удобнее в хорошем текстовом редакторе. Но речь не об этом.
Когда я пишу что-нибудь под андроид — я часто правлю XML (разметку, стили, строки, ...). Так вот в текстовом редакторе это делать не очень удобно. И я решил потратить пару часов и написать генератор XML на основе упрощенного языка разметки (типа lesscss или stylus для CSS). Все-таки NIH — очень уж соблазнительный стимул.
Язык AAML (another android markup language) получился с очень простым синтаксисом. Элементы начинаются с двоеточий. Запятые (или переносы строк) разделяют атрибуты. Табами (или пробелами, или и тем и другим) определяется вложенность элементов. Комментарии начинаются с решетки. Какой-нибудь простенький layout выглядит так:
# Main layout
:LinearLayout layout fill, padding 0dp 16dp, orientation vertical
:EditText
layout fill wrap
hint @string/to
:EditText
layout fill wrap
hint @string/subject
:EditText
layout fill 0dp 1
gravity top
hint @string/message
:Button#btn_send
layout 100dp wrap
gravity right
text @string/send
Такая AAML-разметка компилируется в:
<?xml version="1.0" encoding="utf-8"?>
<!-- Main layout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="0dp"
android:paddingRight="16dp"
android:paddingBottom="0dp"
android:paddingLeft="16dp"
android:orientation="vertical">
<EditText
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:hint="@string/to" />
<EditText
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:hint="@string/subject" />
<EditText
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="top"
android:hint="@string/message" />
<Button
android:id="@+id/btn_send"
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="right"
android:text="@string/send" />
</LinearLayout>
Еще по принципу DRY есть поддержка макросов и алиасов. Алиасы позволяют задать новое имя чему-либо — атрибуту (чтобы писать «wrap» вместо «wrap_content»), значению (чтобы определить цвет или размер шрифта один раз и использовать алиас как имя переменной) и т.д.
Макросы же принимают ряд аргументов. Аргументам имена правда давать нельзя (да и макросы предполагаются только самые простые). Вместо этого используются позиционные аргументы, как в Bash ($1, $2, $3 и т.д.). Вот макросы и алиасы, используемые в примере выше:
# Алиасы
:def wrap wrap_content
:def fill match_parent
:def match match_parent
# Макросы
:def layout:3 layout_widht $1, layout_height $2, layout_weight $3
:def layout:2 layout_widht $1, layout_height $2
:def layout:1 layout $1 $1
:def padding:4 paddingTop $1, paddingRight $2, paddingBottom $3, paddingLeft $4
:def padding:2 padding $1 $2 $1 $2
:def padding:1 padding $1 $1
Наверное, подобные макросы следует сделать стандартными для разных видов XML (для layout — одни, для strings — другие и т.д.)
Написан AAML на python. Никаких зависимостей не имеет, кода там всего строк на 200. Работает в двух режимах — конвертирует файл *.aaml в *.xml или рекурсивно обрабатывает все файлы из одной папки и помещает полученные xml в другую. Это удобно, если создать aaml/layout, aaml/values, aaml/xml и полученные результаты складывать в res/layout и т.д.
Чтобы автоматизировать этот процесс можно создать custom_rules.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<target name="-pre-build">
<exec executable="aaml">
<arg value="aaml"/>
<arg value="res"/>
</exec>
</target>
</project>
Теперь aaml будет конвертироваться в xml при каждой сборке проекта автоматически.
Исходники находятся на bitbucket: bitbucket.org/zserge/aaml
Лицензия — MIT.
В завершение поста у меня вопрос кам — стоит ли развивать этот проект? Есть ли еще фрики, которые пишут XML вручную? Если да — то любые предложения, фича-реквесты, замечания, баги, критика приветствуются.
Автор: zserge