Макрокоманды
Руководство по использованию макрокоманд easyChem
В данной статье даётся обзор всех возможностей макрокоманд CharChem и приводятся примеры. Краткий справочник / ОглавлениеШпаргалка - в сжатом виде основные синтаксические конструкции. Плюс ссылки на более подробное объяснение.
Создание простейшего макроса и его использованиеДопустим, нужно описать взаимодействие уксусной кислоты с щёлочью.
$C()H3C-C<//O>\O-H + NaOH -> $C()H3C-C<//O>\O-Na + H2O <=> H3C-C<//O>\O^- + Na^+ + H2O
Несложно заметить, что здесь три раза повторяется изрядный кусок молекулы уксусной кислоты. Давайте вынесем его описание в виде макроса.
@:Ac()$C()H3C-C<//O>\O@;
@Ac()-H + NaOH -> @Ac()-Na + H2O <=> @Ac()^- + Na^+ + H2O Здесь мы видим, что макрокоманда описывается при помощи конструкции @:Name() . . . @; Объявленный макрос можно использовать далее в тексте. Он является глобальным определением. Например, мы можем использовать его в другой формуле:
@Ac()-CH3
Одновременное объявление и использование макросаСуществует способ одновременно описать и использовать макроопределение. Для этого нужно в конце определения вместо@; использовать @() .Наш предыдущий пример может быть переписан так:
@:Ac()$C()H3C-C<//O>\O@()-H + NaOH -> @Ac()-Na + H2O <=> @Ac()^- + Na^+ + H2O
Использование параметровСледующим естественным шагом использования макросов является применение параметров. Пример с уксусной кислотой может быть переписан так:
@:Ac(x)$C()H3C-C<//O>\O&x@(-H) + NaOH -> @Ac(-Na) + H2O <=> @Ac(^-) + Na^+ + H2O
Здесь мы видим параметр x. Он объявлен в скобках, а используется с помощью &x.
Названием параметра может быть имя, начинающееся с латинской буквы, далее могут следовать другие буквы или цифры.Впрочем, в этом примере мы мало что выиграли от использования параметра. Зато здесь иллюстрируется переопределение макроса. Мы создали новый макрос с тем же именем. Он заменил собой старый макрос. Те обращения, которые использовали вариант без параметра, не могут применяться после объявления нового макроса. Рассмотрим пример посложнее, где потребуется два параметра. Пусть нужно изобразить нечто похожее на кристаллическую решетку, где два элемента чередуются в шахматном порядке. Для дополнительной выразительности раскрасим элементы в красный и синий цвет. Сначала делаем прототип, где элементами являются натрий и хлор:
{}_(x.8,H)$color(red)Na$color()_(x1.4,H)$color(blue)Cl$color()_(x.8,H)"";
Описание вышло довольно громоздким.
Но тем больше причин для того, чтобы его автоматизировать для дальнейшего использования.
Превратим прототип в макрос, заменив Na и Cl на параметры. Назовём их a и b.
А сам макрос пусть называется Cross.""_(x.8,H)$color(blue)Cl$color()_(x1.4,H)$color(red)Na$color()_(x.8,H)""; ""|h#-8|h#-4|h"";""|h#-9|h#-5|h""
@:Cross(a,b){}_(x.8,H)$color(red)&a$color()_(x1.4,H)$color(blue)&b$color()_(x.8,H)"";
Зато теперь мы получили довольно мощную конструкцию:""_(x.8,H)$color(blue)&b$color()_(x1.4,H)$color(red)&a$color()_(x.8,H)""; ""|h#-8|h#-4|h"";""|h#-9|h#-5|h""@; {Cross demo:}_(x2,h,N0)""@Cross(Na,Cl)
@Cross(K,Br) @Cross(Li,F) @Cross(Ga,As)
Позиционные и именованные параметрыДопустим мы хотим создать макрос, определяющий производные бензола. Для этого в узлах расставим параметры с номерами, соответствующими номенклатуре IUPAC.
@:Ph(n1,n2,n3,n4,n5,n6)&n1\\&n2|&n3`//&n4`\&n5`||&n6/@()
Хотя мы объявили целых 6 параметров, но для первой демонстрации мы не использовали ни одного. В результате получился просто бензол.
Зато теперь мы можем из этой конструкции сделать толуол, указав в первой позиции метильную группу.
@Ph(CH3|)
Но это лишь малая часть того, как можно использовать полученный макрос.
Изобразим орто-, мета- и пара-крезол, подключив гидроксильную группу в позиции 2, 3 и 4 соответственно:
@Ph(CH3|,</OH>) @Ph(CH3|,,<\OH>) @Ph(CH3|,,,<|OH>)
Здесь мы использовали позиционную подстановку, пропуская те узлы, которые не нужно заполнять.
Но можно сразу указать название того параметра, который нужен:
@Ph(CH3|,n6:<`\HO>) @Ph(CH3|,n5:<`/HO>) @Ph(CH3|,n4:<|HO>) @Ph(n6:<`\H3C>,n2:</CH3>,n4:<|CH3>)
Для первых трех молекул первый параметр задан позиционно. Потому что он и так первый, зачем писать лишнее?
А второй параметр указан по названию. Следует уточнить, что при описании макроса мы получили некоторую особенность, связанную с использованием параметров. Первый параметр является началом цепочки, а остальные должны образовывать ответвления. Поэтому конструкции < > используются для всех параметров, кроме первого. Впрочем, мы можем описать пиридин, указав азот в 4-м параметре. В этом случае ветка не нужна:
@Ph(n4:N)
Использование значений по-умолчаниюДальнейшим улучшением описания макроса служит использование параметров с заранее заданными значениями (значениями по-умолчанию). Это позволяет описать достаточно сложные структуры с удобным способом внесения небольших изменений. В качестве примера выполним усовершенствование описанного выше макроса Cross. Дадим пользователю возможность влиять на цвет элементов и длину связей. Для этого добавим параметры colorA и colorB, которым через знак : заданы желаемые значения red и blue. Длину центральной связи зададим параметром len1:1.4, а боковой связи - len2:0.8.
@:Cross(a,b,colorA:red,colorB:blue,len1:1.4,len2:0.8)#
Обратите внимание, что после произведенного улучшения осталась возможность использовать макрос точно так же, как и раньше.
Это гарантирует, что вся ранее проделанная работа, где содержится обращение к макросу, не потребует переделки.
Зато можно пользоваться новыми возможностями там, где это потребуется:{}_(x&len2,H)$itemColor(&colorA)&a$itemColor()_(x&len1,H)$itemColor(&colorB)&b$itemColor()_(x&len2,H)""; ""_(x&len2,H)$itemColor(&colorB)&b$itemColor()_(x&len1,H)$itemColor(&colorA)&a$itemColor()_(x&len2,H)""; ""_(y&len2,H)#-8_(y&len1,H)#-4_(y&len2,H)""; ""_(y&len2,H)#-9_(H)#-5_(y&len2,H)""@; @Cross(Na,Cl)
@Cross(K,Br,colorB:darkmagenta,len1:2,len2:1.5)
$color(blue)@Cross(Fe,Cl,len2:1,colorA:black,colorB:darkgreen)$color() $color(#888)@Cross({[+]},{[-]},len2:0.1,colorA:,colorB:)$color() Первая структура демонстрирует расширенные возможности использования макроса при помощи дополнительных параметров. Рассмотрим более простой, но вполне практичный пример. Допустим, мы работаем над статьёй, посвященной аминокислотам. В ней нужно демонстрировать различные реакции, в том числе образование пептидной связи. Желательно обеспечить некий общий стиль для отображения аминокислот, чтобы читатель сразу обращал внимание на важные особенности, не тратя времени на мелкие детали. Для этого разработаем макрос, где будет возможно определить радикал и при необходимости модифицировать аминогруппу, изображаемую слева, и карбоксильную группу, изображаемую справа.
@:AminoAcid(r:{R},a:H-,c:OH,rcol:blue)&a$C()N<`|H&>-C<`|H><|$color(&rcol)&r$color()>-C<`||O>-&c@()
Мы получили мощный инструмент, которым можно легко оперировать. (Хотя конечно под эту схему не подходит пролин).Нарисуем несколько аминокислот: аланин, метионин и глутамин:
@AminoAcid(CH3) @AminoAcid(CH2|CH2|S|CH3) @AminoAcid(CH2|CH2|C`/O/\NH2)
Теперь изобразим для этих молекул реакцию с образованием пептидной связи.
@AminoAcid(CH3) + @AminoAcid(CH2|CH2|S|CH3) + @AminoAcid(CH2|CH2|C`/O/\NH2) ->
@AminoAcid(CH3,c:)@AminoAcid(CH2|CH2|S|CH3,a:,c:)@AminoAcid(CH2|CH2|C`/O/\NH2,a:) + 2H2O
Вложенное использование макросовИз последнего примера видно, что неплохо бы ввести отдельное описание для аминокислот, чтобы не перечислять каждый раз их радикалы в параметрах. Опишем макросы для трёх упоминавшихся выше аминокислот.
@:Ala(a,c)@AminoAcid(CH3,&a,&c)@;
И перепишем уравнение с образованием пептидной связи@:Met(a,c)@AminoAcid(CH2|CH2|S|CH3,&a,&c)@; @:Gln(a,c)@AminoAcid(CH2|CH2|C`/O/\NH2,&a,&c)@;
@Ala() + @Met() + @Gln() -> @Ala(c:# )@Met(# ,# )@Gln(a:# )
Тут пришлось явно указать, что в местах стыковки аминогруппа и карбоксильная группа задана пустым местом.
Для этого используется #(пробел). Это компромиссное решение, связанное с конкретным способом объявления макроса.
Чтобы получить описание @Ala, аналогичное по поведению @AminoAcid, нужно было бы использовать более сложную запись:
@:Ala(a:H-,c:OH)@AminoAcid(CH3,a:&a,c:&c)@;
Здесь всё в руках автора макроса. Он может выбирать, где какой способ применить.:@Ala() -> {R1}-@Ala(a:,c:){R2} Попробуем совместить разработанные макросы @AminoAcid и @Ph для описания ароматических аминокислот: фенилаланин и тирозин. У обеих метильная группа стыкуется к узлу 1, а у тирозина гидроксильная группа - к узлу 4.
@:Phe(a,c)@AminoAcid(@Ph(CH2|),&a,&c)@()
+ @:Tyr(a,c)@AminoAcid(@Ph(CH2|,n4:<|OH>),&a,&c)@() = @Phe(c:# )@Tyr(a:# ) + H2O Ну и ещё один пример, где используем вложенный вызов @Cross для создания увеличенной структуры.
@:Cross1(a,b,colorA:red,colorB:blue)@Cross(&a,&b,colorA:&colorA,colorB:&colorB,len1:2,len2:1)@;
@:Cross2(a,b,colorA:red,colorB:blue)@Cross1(&a,&b,colorA:&colorA,colorB:&colorB)_(x1,y-3,N0)# @Cross1(&a,&b,colorA:&colorA,colorB:&colorB)@; @:Cross4(a,b,colorA:red,colorB:blue)@Cross2(&a,&b,colorA:&colorA,colorB:&colorB)_(x-7,y1,N0)# @Cross2(&a,&b,colorA:&colorA,colorB:&colorB)@; @Cross1(Na,Cl) -> @Cross2(Na,Cl,colorB:green) -> @Cross4(Na,Cl) ЗаключениеПодведём итоги. Применение макроопределений позволяет:
|