Правда о регистре символов, которую должны знать программисты
На конференции North Bay Python в 2018 году я делал доклад об именах пользователей. Информация из доклада по большей части была собрана мною за 12 лет поддержки django-registration. Этот опыт дал мне гораздо больше знаний, чем я планировал получить, о том, насколько сложными могут быть «простые» вещи.
В начале доклада я, правда, упомянул, что это не будет очередное разоблачение из серии «заблуждения по поводу Х, в которые верят программисты». Таких разоблачений можно найти сколько угодно. Однако мне подобные статьи не нравятся. В них перечисляются разные вещи, якобы являющиеся ложными, однако очень редко объясняется – почему это так, и что нужно делать вместо этого. Подозреваю, что люди просто прочтут такие статьи, поздравят себя с этим достижением, и потом пойдут находить новые интересные способы делать ошибки, не упомянутые в этих статьях. Всё потому, что они на самом деле не поняли проблем, порождающих этих ошибки.
Поэтому в своём докладе я постарался как можно лучше объяснить некоторые проблемы и пояснить, как их решать – такой подход мне нравится гораздо больше. Одна из тем, которой я коснулся лишь вскользь (это был всего один слайд и пара упоминаний на других слайдах) – это сложности, которые могут быть связаны с регистром символов. Для задачи, которую я обсуждал – сравнение идентификаторов без учёта регистра – есть официальный Правильный Ответ™, и в докладе я дал лучшее из известных мне решений, использующее только стандартную библиотеку Python.
Однако я кратко упомянул о более глубоких сложностях с регистром символов в Unicode, и хочу посвятить некоторое время описанию подробностей. Это интересно, и понимание этого может помочь вам принимать решения при проектировании и написании кода, обрабатывающего текст. Поэтому предлагаю вам нечто противоположное статьям «заблуждения по поводу Х, в которые верят программисты» – «правда, которую должны знать программисты».
И ещё одно: в Unicode полно терминологии. В данной статье я буду использовать в основном определения «верхний регистр» и «нижний регистр», поскольку стандарт Unicode использует эти термины. Если вам нравятся другие термины, вроде строчная/прописная буквы – всё нормально. Также я часто буду использовать термин «символ», который некоторые могут счесть некорректным. Да, в Unicode концепция «символа» не всегда совпадает с ожиданиями людей, поэтому часто лучше избегать её, используя другие термины. Однако в данной статье я буду использовать этот термин так, как он используется в Unicode – для описания абстрактной сущности, о которой можно делать заявления. Когда это важно, для уточнения я буду использовать более конкретные термины типа «кодовой позиции» [code point].
Регистров бывает больше двух
Носители европейских языков привыкли к тому, что в их языках регистр символов используется для обозначения конкретных вещей. К примеру, в английском [и русском] языках мы обычно начинаем предложения с буквы в верхнем регистре, а продолжаем чаще всего буквами в нижнем регистре. Также имена собственные начинаются с букв в верхнем регистре, и многие акронимы и аббревиатуры записываются в верхнем регистре.
И мы обычно считаем, что регистров существует всего два. Есть буква «А», и есть буква «а». Одна в верхнем, другая в нижнем регистре – не правда ли?
Однако в Unicode есть три регистра. Есть верхний, есть нижний, и есть титульный регистр [titlecase]. В английском языке так записываются названия. Например, «Avengers: Infinity War». Обычно для этого первая буква каждого слова просто пишется в верхнем регистре (и в зависимости от разных правил и стилей, некоторые слова, например, артикли, не пишутся с заглавных букв).
В стандарте Unicode дан такой пример символа в титульном регистре: U+01F2 LATIN CAPITAL LETTER D WITH SMALL Z. Выглядит он так: Dz.
Подобные символы иногда требуются для обработки негативных последствий одного из ранних решений разработки стандарта Unicode: совместимости с существующими текстовыми кодировками в обе стороны. Для Unicode было бы удобнее составлять последовательности при помощи имеющихся у стандарта возможностей по комбинированию символов. Однако во многих уже существующих системах уже были отведены места для готовых последовательностей. К примеру, в стандарте ISO-8859-1 («latin-1») у символа «é» есть готовая форма, имеющая номер 0xe9. В Unicode предпочтительнее было бы писать эту букву при помощи отдельной «е» и знака ударения. Но для обеспечения полной совместимости в обе стороны с такими существующими кодировками, как latin-1, в Unicode также назначены кодовые позиции для готовых символов. К примеру, U+00E9 LATIN SMALL LETTER E WITH ACUTE.
Хотя кодовая позиция этого символа совпадает с его байтовым значением из latin-1, полагаться на это не стоит. Вряд ли кодирование символов в Unicode сохранит эти позиции. К примеру, в UTF-8 кодовая позиция U+00E9 записана в виде байтовой последовательности 0xc3 0xa9.
И, конечно, в уже существующих кодировках есть символы, которым требовалось особое обхождение при использовании титульного регистра, из-за чего они были включены в Unicode «как есть». Если хотите посмотреть на них, поищите в своей любимой базе Unicode символы из категории Lt («Letter, titlecase»).
Есть несколько способов определить регистр
- Символ находится в верхнем регистре, если он принадлежит к категории Lu («Letter, uppercase»), и в нижнем регистре, если принадлежит к категории Ll («Letter, lowercase»). В стандарте признаётся ограниченность этого определения: каждый конкретный символ приходится относить только к одной из категорий. Из-за этого многие символы, которые «должны находиться» в верхнем или нижнем регистре не удовлетворят этому требованию потому, что принадлежат к какой-то другой категории.
- Символ находится в верхнем регистре, если он унаследовал свойство Uppercase, и в нижнем регистре, если унаследовал свойство Lowercase. Это комбинация определения один с другими свойствами символов, среди которых может быть и регистр.
- Символ находится в верхнем регистре, если после применения к нему регистрового отображения в верхний регистр он не меняется. Символ находится в нижнем регистре, если после применения к нему регистрового отображения в нижний регистр он не меняется. Довольно общее определение, однако и оно может вести себя неинутитивно.
Если вы работаете с ограниченным подмножеством символов (конкретно, с буквами), то вам может хватить и 1-го определения. Если ваш репертуар шире – в него входят похожие на буквы символы, не являющиеся буквами, вам может подойти 2-е определение. Его рекомендует и стандарт Unicode, §4.2:
Программистам, манипулирующим строками в Unicode, стоит работать с такими строковыми функциями, как isLowerCase (и её функциональным родственником toLowerCase), если они не работают со свойствами символов напрямую.
Упомянутая здесь функция определяется в §3.13 стандарта Unicode. Формально в 3-м определении используются функции isLowerCase и isUpperCase из §3.13, определяемые в терминах фиксированных позиций в toLowerCase и toUpperCase соответственно.
Если в вашем языке программирования есть функции для проверки или преобразования регистра строк или отдельных символов, стоит изучить, какие из упомянутых определений используются в реализации. Если вам интересно, то методы isupper() и islower() в Python используют 2-е определение.
Нельзя понять регистр символа по его внешнему виду или названию
По внешнему виду многих символов можно понять, в каком они регистре. К примеру, «А» находится в верхнем регистре. Это понятно и по названию символа: «LATIN CAPITAL LETTER A». Однако иногда такой метод не работает. Возьмём кодовую позицию U+1D34. Выглядит она так: ᴴ. В Unicode ей назначено имя: MODIFIER LETTER CAPITAL H. Значит, она в верхнем регистре, так?
На самом же деле она наследует свойство Lowercase, поэтому по определению №2 она находится в нижнем регистре, несмотря на то, что визуально напоминает заглавную Н, а в названии есть слово «CAPITAL».
У некоторых символов вообще нет регистра
Определение 135 в §3.13 стандарта Unicode гласит:
Символ С имеет регистр тогда и только тогда, когда у С есть свойство Lowercase или Uppercase, или значение параметра General_Category равно Titlecase_Letter.
Значит, очень много символов из Unicode – на самом деле, большая их часть – регистра не имеет. Не имеют смысла вопросы об их регистре, а изменения регистра на них не действуют. Однако мы можем получить ответ на этот вопрос по определению №3.
Некоторые символы ведут себя так, будто у них несколько регистров
Из этого следует, что если вы используете определение №3, и задаёте вопрос, находится ли символ без регистра в верхнем или нижнем регистре, вы получите ответ «да».
В стандарте Unicode даётся пример (таблица 4-1, строка 7) символа U+02BD MODIFIER LETTER REVERSED COMMA (который выглядит так: ʽ). У него нет унаследованных свойств Lowercase или Uppercase, он не принадлежит к категории Lt, поэтому регистра у него нет. При этом преобразование в верхний регистр его не меняет, и преобразование в нижний регистр его не меняет, поэтому по 3-му определению он отвечает «да» на оба вопроса: «принадлежишь ли ты к верхнему регистру?» и «принадлежишь ли ты к нижнему регистру?»
Кажется, что из-за этого может возникнуть никому не нужная путаница, однако смысл в том, что определение №3 работает с любой последовательностью символов Unicode, и позволяет упростить алгоритмы преобразования регистра (символы без регистра просто превращаются сами в себя).
Регистр зависит от контекста
Можно подумать, что если таблицы преобразования регистра в Unicode покрывают все символы, то это преобразование заключается просто в поиске нужного места в таблице. К примеру, в базе данных Unicode записано, что для символа U+0041 LATIN CAPITAL LETTER A нижним регистром будет U+0061 LATIN SMALL LETTER A. Просто, не так ли?
Один из примеров, в котором этот подход не работает – греческий язык. Символ Σ — то есть, U+03A3 GREEK CAPITAL LETTER SIGMA — сопоставлен двум разным символам при преобразовании в нижний регистр, в зависимости от того, где он находится в слове. Если он стоит на конце слова, тогда в нижнем регистре он будет ς (U+03C2 GREEK SMALL LETTER FINAL SIGMA). В любом другом месте это будет σ (U+03C3 GREEK SMALL LETTER SIGMA).
А это значит, что у регистра нет взаимной однозначности или транзитивности. Ещё один пример — ß (U+00DF LATIN SMALL LETTER SHARP S, или эсцет). В верхнем регистре это будет «SS», хотя теперь существует и другая его форма в верхнем регистре (ẞ, U+1E9E LATIN CAPITAL LETTER SHARP S). А при переводе «SS» в нижний регистр получается «ss», поэтому (используя терминологию стандарта Unicode для преобразования регистра): toLowerCase(toUpperCase(ß)) != ß.
Регистр зависит от локали
В разных языках правила преобразования регистра разные. Самый популярный пример: i (U+0069 LATIN SMALL LETTER I) и I (U+0049 LATIN CAPITAL LETTER I) в большинстве локалей преобразовываются друг в друга – в большинстве, но не во всех. В локалях az и tr (тюркские языки), i в верхнем регистре будет İ (U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE), а I в нижнем регистре будет ı (U+0131 LATIN SMALL LETTER DOTLESS I). Иногда правильная запись реально означает разницу между жизнью и смертью.
Сам Unicode не обрабатывает все возможные правила преобразования регистра для всех локалей. В базе данных Unicode есть только общие правила преобразования всех символов, не зависящие от локали. Также там есть особые правила для некоторых языков и составных форм – литовского языка, тюркских языков, некоторых особенностей греческого. Всего остального там нет. §3.13 стандарта упоминает это и рекомендует при необходимости вводить правила преобразования, зависящие от локали.
Один пример будет знаком англоговорящим – это титульный регистр определённых имён. «o’brian» нужно преобразовывать в «O’Brian» (а не в «O’brian»). Однако при этом «it’s» нужно преобразовывать в «It’s», а не в «It’S». Ещё один пример, который не обрабатывается в Unicode – это голландское буквосочетание «ij», которое при преобразовании в титульный регистр должно переходить в верхний регистр целиком, если стоит в начале слова. Таким образом, большой залив в Нидерландах в титульном регистре будет «IJsselmeer», а не «Ijsselmeer». В Unicode есть символы IJ U+0132 LATIN CAPITAL LIGATURE IJ и ij U+0133 LATIN SMALL LIGATURE IJ, если они вам нужны. По умолчанию преобразование регистра преобразует их друг в друга (хотя формы нормализации Unicode, использующие эквивалентность совместимости, разделят их на два отдельных символа).
Сравнение без учёта регистра требует приведения к сложенному регистру
Возвращаясь к материалу, представленному в докладе. Сложность работы с регистром в Unicode означает, что регистронезависимое сравнение нельзя проводить при помощи стандартных функций приведения к нижнему или верхнему регистру, имеющихся во многих языках программирования. Для таких сравнений в Unicode есть концепция приведения к сложенному регистру [case folding], а в §3.13 стандарта определяются функции toCaseFold и isCaseFolded.
Можно решить, что приведение к сложенному регистру похоже на приведение к нижнему регистру – но это не так. Стандарт Unicode предупреждает, что строка в сложенном регистре не обязательно будет находиться в нижнем регистре. В качестве примера приводится язык чероки – там в строке, находящейся в сложенном регистре, будут попадаться и символы в верхнем регистре.
На одном из слайдов моего доклада рекомендации Unicode Technical Report #36 реализуются на Python настолько полно, насколько это возможно. Проводится нормализация NFKC и потом для полученной строки вызывается метод casefold() (доступный только в Python 3+). И даже при этом некоторые крайние случаи выпадают, и это не совсем то, что рекомендуется для сравнения идентификаторов. Сначала плохие новости: Python не выдаёт наружу достаточно свойств Unicode для того, чтобы отфильтровать символы, которых нет в XID_Start или XID_Continue или символы, имеющие свойство Default_Ignorable_Code_Point. Насколько мне известно, он не поддерживает отображение NFKC_Casefold. Также в нём нет простого способа использовать модифицированный NFKC UAX #31§5.1.
Хорошие новости: большинство этих крайних случаев не связано с какими-либо реальными рисками безопасности, создаваемыми рассматриваемыми символами. И складывание регистра в принципе не определяется как операция, сохраняющая нормализацию (отсюда и отображение NFKC_Casefold, которое повторно нормализуется до NFC после складывания регистра). Как правило, при сравнении вас не волнует, будут ли обе строки нормализованы после предварительной обработки. Вас заботит, не противоречива ли предварительная обработка, и гарантирует ли она, что только строки, которые «должны» отличаться впоследствии, будут отличаться впоследствии. Если вас это беспокоит, вы можете вручную выполнить повторную нормализацию после сложения регистра.
Пока достаточно
Эта статья, как и предыдущий доклад, не является исчерпывающей, и вряд ли можно уложить весь этот материал в единственный пост. Надеюсь, что это был полезный обзор сложностей, связанных с этой темой, и вы найдёте в нём достаточно отправных точек для того, чтобы искать дальнейшую информацию. Поэтому в принципе, можно остановиться и тут.
Не будет ли наивной моя надежда на то, что другие люди перестанут писать разоблачения из серии «заблуждения по поводу Х, в которые верят программисты», и начнут уже писать статьи типа «правда, которую должны знать программисты»?
- Unicode
- регистр символов
- верхний регистр
- нижний регистр
- титульный регистр
- кодовая позиция
Мира с помощью клавиатуры
В современном мире виртуальная работа стала неотъемлемой частью нашей повседневности. С появлением специализированных программ и технологий, многие задачи теперь можно выполнять удаленно, не покидая своего дома или офиса. Клавиатура стала основным инструментом коммуникации и работы, которая позволяет нам оперативно общаться, создавать и редактировать документы, искать информацию и многое другое.
Однако, чтобы быть эффективным в виртуальной работе, необходимо знать не только основные комбинации клавиш, но и уметь правильно использовать различные программы и сервисы. В этой статье мы подробно рассмотрим различные технологии, советы и секреты, которые помогут вам с легкостью ориентироваться в виртуальном пространстве и повысят вашу продуктивность.
Одним из ключевых аспектов виртуальной работы является умение эффективно управлять временем. Как часто мы теряем ценные минуты, просто затрачивая их на поиск нужной информации или выполнение повторяющихся задач! Однако, с помощью специальных программ и инструментов, вы можете автоматизировать большую часть этих задач и сэкономить значительное количество времени. В этой статье мы расскажем вам о некоторых из них и поделимся полезными советами.
Кроме того, мы рассмотрим вопросы безопасности данных и конфиденциальности в виртуальной среде. Как защитить свои данные от несанкционированного доступа или утечки информации? Какие существуют самые надежные методы шифрования данных и как их использовать? Ответы на эти вопросы вы найдете в нашей статье.
Офис без офиса: перспективы виртуальной работы
Перспективы виртуальной работы огромны и многообразны. Это означает, что сотрудникам предоставляется гибкость в выборе места и времени работы. Они могут работать из дома, кафе, библиотеки или любого другого места, где есть доступ к интернету. Кроме того, виртуальная работа позволяет сотрудникам сократить время на дорогу, что повышает их продуктивность и уровень удовлетворенности работой.
Работать в виртуальном офисе также означает большую гибкость в выборе проектов и клиентов. Сотрудникам есть возможность работать со всего мира, что позволяет им работать над самыми интересными и перспективными задачами. Виртуальная работа также позволяет общаться с коллегами и клиентами из разных стран и культур, что расширяет кругозор и позволяет находить новые идеи и решения.
Однако, следует отметить, что виртуальная работа также имеет свои сложности и вызовы. Отсутствие физического присутствия коллег и руководства может создавать ощущение изоляции и неопределенности. Кроме того, необходимо быть самостоятельным и организованным, чтобы эффективно управлять своим временем и задачами. Но справившись с этими вызовами, возможность работать в виртуальном офисе открывает перед нами новые горизонты и перспективы в карьерном росте и развитии.
Основные технологии для эффективной виртуальной работы
В современном мире виртуальная работа стала неотъемлемой частью нашей жизни. Это позволяет нам работать из любой точки мира и сохранять связь с нашей командой в реальном времени. Но чтобы быть максимально эффективными в виртуальном рабочем окружении, мы должны использовать определенные технологии.
- Видеоконференции: С помощью программ, таких как Skype, Zoom или Microsoft Teams, мы можем визуально общаться с нашей командой и клиентами. Это помогает установить более тесный контакт и улучшить взаимопонимание.
- Совместная работа в режиме реального времени: Платформы для совместной работы, такие как Google Документы или Microsoft Office 365, позволяют нам одновременно изменять и синхронизировать документы с другими участниками команды. Это значительно ускоряет процесс совместной работы и повышает эффективность.
- Управление проектами: Использование инструментов для управления проектами, таких как Trello или Asana, помогает нам организовывать и отслеживать выполнение задач, устанавливать сроки и сообщать о прогрессе наших проектов.
- Облачное хранение: Сервисы облачного хранения данных, такие как Google Диск, Dropbox или OneDrive, позволяют нам сохранять и синхронизировать наши файлы и документы на разных устройствах. Это обеспечивает доступность информации в любой момент и с любого места.
- Коллаборативные платформы: Сервисы, такие как Slack или Microsoft Teams, обеспечивают непрерывную коммуникацию внутри команды. Мы можем обмениваться сообщениями, делиться файлами, создавать общие каналы и комментировать задачи. Это помогает улучшить командную работу и сократить время на обмен информацией.
Использование этих основных технологий поможет нам работать более эффективно, улучшить коммуникацию и продуктивность нашей виртуальной работы.
Секреты управления временем для успешной виртуальной работы
1. Создайте расписание
Один из самых важных секретов управления временем – создание расписания. Определите, сколько времени вы хотите потратить на каждую задачу или проект, и запланируйте их в своем расписании. Будьте реалистичными и убедитесь, что у вас достаточно времени для выполнения всех задач.
2. Установите приоритеты
Определите, какие задачи наиболее важны и срочны для достижения ваших целей. Установите приоритеты и начните работать с самых важных задач. Уделите им максимум времени и внимания, чтобы обеспечить их успешное выполнение.
3. Создайте рабочее пространство
Организуйте удобное и эргономичное рабочее пространство, где вам будет комфортно работать. Это поможет вам сосредоточиться и улучшить свою продуктивность. Убедитесь, что у вас есть все необходимые инструменты и ресурсы, чтобы успешно выполнять свою работу.
4. Используйте технологии и инструменты для управления временем
Современные технологии предоставляют множество инструментов, которые помогут вам управлять своим временем. Используйте приложения для управления задачами, планирования, отслеживания времени и организации вашего рабочего процесса. Эти инструменты помогут вам структурировать свою работу и эффективно использовать время.
5. Установите границы между работой и личной жизнью
Одной из главных проблем виртуальной работы является смешение рабочего времени и личного времени. Установите строгие границы между ними, чтобы избежать перегрузки работой и выгорания. Определите определенные часы работы и придерживайтесь их. Помните, что здоровье и отдых также важны для успешной работы.
6. Запланируйте перерывы и время для отдыха
Не забывайте запланировать перерывы и время для отдыха. Регулярные перерывы помогут вам снять стресс, свести к минимуму усталость и восстановить энергию. Поставьте перед собой цель сделать десяти минутный перерыв каждый час или пятнадцати минутный перерыв каждые два часа.
Следуя этим секретам управления временем, вы сможете эффективно работать в виртуальной среде и достигнуть большего успеха в своей профессии.
Как обеспечить безопасность и конфиденциальность виртуальной работы
В современном мире виртуальная работа становится все более распространенной. Однако, вместе с удобствами и преимуществами этого способа работы, существуют и определенные угрозы для безопасности и конфиденциальности информации.
Вот несколько полезных советов, которые помогут обеспечить безопасность вашей виртуальной работы:
1. Сильные пароли
Всегда используйте сложные и уникальные пароли для своих учетных записей. Пароли должны быть длинными и содержать различные символы, цифры и буквы в верхнем и нижнем регистре. Никогда не используйте один и тот же пароль для разных учетных записей.
2. Двухфакторная аутентификация
Активируйте двухфакторную аутентификацию для своих учетных записей, где это возможно. Это добавит дополнительный уровень безопасности, так как для входа потребуется не только пароль, но и дополнительный код или подтверждение через мобильное устройство.
3. Защита от вредоносных программ
Установите надежное антивирусное программное обеспечение на свое устройство, чтобы защититься от вредоносных программ и потенциальных угроз для вашей информации.
4. Обновления программного обеспечения
Регулярно обновляйте все программное обеспечение на своем устройстве. Это включает операционную систему, браузеры, а также другие используемые программы. Обновления содержат исправления ошибок и патчи безопасности, что делает ваше устройство менее уязвимым для атак.
5. Безопасная сеть
Используйте защищенную сеть Wi-Fi при работе удаленно. Никогда не подключайтесь к общедоступным или ненадежным Wi-Fi сетям, так как они могут быть подвержены атакам и перехвату данных.
Следуя этим простым и эффективным советам, вы можете гарантировать безопасность и конфиденциальность вашей виртуальной работы.
Советы для поддержания здоровья и баланса при виртуальной работе
Виртуальная работа стала неотъемлемой частью современной жизни. Она имеет свои преимущества, но также может повлечь за собой негативные последствия для здоровья. Для поддержания здоровья и баланса во время виртуальной работы рекомендуется следовать следующим советам:
- Установите регулярный график работы. Работая из дома или в удаленном режиме, легко потерять рабочий и личный баланс. Установите конкретные часы работы и придерживайтесь их. Это поможет вам избежать переутомления и снизит риск развития стресса.
- Разделите рабочее пространство от личного. Если у вас есть возможность, оборудуйте себе отдельное рабочее место. Это поможет установить границу между работой и личной жизнью, что в свою очередь способствует улучшению концентрации и повышению продуктивности.
- Постоянно мониторьте свое положение тела. Сидячая работа может привести к проблемам со спиной и мышцами. Обеспечьте правильную эргономику рабочего места, используйте правильный стул и положение пальцев на клавиатуре. Регулярно делайте паузы и проводите упражнения для разогрева и растяжки.
- Создайте режим физической активности. Виртуальная работа часто связана с длительным сидением. Постарайтесь уделить время физическим упражнениям: занимайтесь спортом, делайте зарядку или просто прогуливайтесь на свежем воздухе. Физическая активность поможет вам поддержать здоровье и повысить уровень энергии.
- Установите границы между работой и личной жизнью. Виртуальная работа может сделать работу доступной 24/7, но это не означает, что нужно быть в режиме работы круглосуточно. Принимайте регулярные перерывы, уделяйте время своим хобби и семье. Не забывайте заботиться о своем физическом и психическом благополучии.
Следуя этим советам, вы сможете поддерживать здоровье и баланс во время виртуальной работы. Помните, что забота о себе является важным фактором успеха и продуктивности в любом виде работы.
Руководство по созданию символов gEDA/gaf
Последняя версия оригинала настоящего документа находится по адресу http://www.geda-project.org/wiki/geda:gschem_symbol_creation.
Настоящий документ выпущен под лицензией GNU Free Documentation License (GFDL).
Обзор
В настоящем документе описывается создание символов компонентов, в том числе соглашения по стилю, советы/подсказки и то, чего стоит остерегаться при вычерчивании символов для системы gEDA/gaf.
Создание символа компонента
Символы компонентов (называемые далее просто «символами») вычерчиваются в gschem. Можно начать с пустой страницы или с заведомо хорошего символа, похожего на создаваемый вами.
Подготовка
Прежде, чем открыть gschem и начать чертить символ, задайте себе несколько вопросов, ответы на которые повлияют на то, как это делать:
Создаётся ли символ чисто из эстетических соображений (просто как рисунок)? Если так, несколько шагов упрощаются.
Нужно ли будет потом использовать этот компонент для моделирования, например в SPICE?
Нужно ли будет использовать этот символ в схеме, где производится разводка питания? Это будет важно при решении вопроса о том, какие выводы нужно чертить.
Представляет ли этот символ компонент, которых по несколько штук в одном корпусе? Это на языке gEDA называется назначением логических секций и на этот счёт имеются особые правила.
Когда вы сами для себя ответите на эти вопросы, дальнейшая часть руководства станет для вас гораздо полезней.
Итак, приступим к созданию символа:
Откройте gschem.
По умолчанию на новых пустых страницах выводятся рамки. Выберите инструмент выделения (в виде чёрной стрелки мыши на панели инструментов) и выделите всё на странице. Нажмите клавишу Delete , чтобы всё удалить.
Увеличьте хотя бы раз масштаб (Вид → Увеличить [View → Zoom In], или нажмите клавишу Z ).
Удостоверьтесь, что привязка к сетке ВКЛЮЧЕНА (Настройки → Переключить сетку привязки [Options → Toggle Snap On/Off] или O S ).
Убедитесь, что шаг сетки привязки установлен в 100 (Настройки → Шаг сетки привязки… [Options → Snap Grid Spacing…] или O Shift + S ).
Черчение символа
С помощью инструментов Линия , Прямоугольник , Окружность , Дуга (которые можно выбрать в меню Добавить [Add]) создайте условное графическое обозначение своего устройства. Убедитесь, что единственный цвет, который вы использовали, это ‘Graphic’ (зелёный). Не помещайте никаких выводов устройства до следующего шага.
Для проверки того, какой цвет используется для черчения, откройте меню Правка → Цвет… [Edit → Color…] (или нажмите E O ).
Размещение выводов
Если вы решили, что ваш символ будет графическим (т. е. не будет ни к чему подключаться, а будет просто картинкой), то этот шаг можно пропустить.
Добавьте свой первый вывод.
Выберите Добавить → Вывод [Add → Pin], или нажмите A P . После этого щёлкните в том месте, где должен быть конец вывода, и переместите мышь к краю своего символа. Около вашего нового вывода должны появиться ‘0’ и слово ‘unknown’. Обратите внимание, что направление вычерчивания выводов важно. Если их чертить от края символа наружу, то текст окажется снаружи символа!
Щёлкните по инструменту выделения и выделите им вывод, который вы только что нарисовали. Цвет самого вывода и относящегося к нему текста должен измениться, а на концах вывода должны появиться квадратики.
Выберите Правка → Правка… [Edit → Edit…] или нажмите E E (или щёлкните правой кнопкой и выберите Правка… [Edit…]). Тогда для вывода появится диалоговое окно редактирования.
В диалоговом окне редактирования своего нового вывода вы должны увидеть четыре атрибута (четыре пары имя=значение ), уже прикреплённых к нему. Эти атрибуты можно отредактировать, щёлкая сначала по атрибуту в списке вверху окна редактирования, затем по полю, которое вы хотите изменить. Учтите, что когда что-то выделено, это не отражается в разделе диалогового окна Добавить атрибут, так как этот раздел предназначен только для добавления, а не для редактирования уже имеющихся атрибутов.
Давайте взглянем на каждый из атрибутов, уже прикреплённых к вашему выводу, и изменим некоторые значения. Я предлагаю увеличить размер окна редактирования так, чтобы было видно все атрибуты.
У каждого вывода должен быть атрибут pinseq . Это число, определяющее порядок работы программы gnetlist с атрибутами. Для нашего первого вывода начнём эту последовательность с ‘1’ и будем последовательно увеличивать этот номер по мере добавления выводов.
У каждого вывода должен быть атрибут pinnumber . Это номер вывода на корпусе компонента, для которого создаётся этот символ. Номер вывода может быть буквенным или цифровым (то есть можно использовать, например, E или C ).
У каждого вывода должен быть также атрибут pinlabel . Данный атрибут является названием или меткой вывода (а не номером вывода).
У каждого вывода должен быть также атрибут pintype . Данный атрибут определяет тип вывода.
Атрибуты pinseq и pinnumber нескольких выводов сразу можно пронумеровать автоматически с помощью Атрибуты → Автонумерация… [Attributes → Autonumber Text…].
Допустимыми значениями pintype являются: in , out , io , oc , oe , pas , tp , tri , clk , pwr . Более подробную информацию о нём см. в Перечне основных атрибутов.
Добавление атрибутов к символу
Чтобы использовать символ с пользой в gschem и других программах, он должен содержать несколько атрибутов (в виде пар имя=значение ).
Сначала мы добавим все нужные нам атрибуты, а затем отключим видимость тех из них, которые должны быть невидимыми.
В символ нужно добавить атрибут device=НАЗВАНИЕ_УСТРОЙСТВА . Название устройства не должно содержать ничего, кроме прописных букв, дефисов, чисел и символов подчёркивания. Если символ определяет чисто графический объект, то значение атрибута device= должно быть none ( device=none ).
В чисто графический символ (такой как, например, рамка формата основной надписи или символ decon ) следует добавить атрибут graphical=1 . Этот атрибут показывает, что содержащий его символ не имеет электрического или схемотехнического назначения. Не забывайте согласно предыдущему требованию устанавливать вместе с данным атрибутом device=none .
В символе должен быть атрибут description=ТЕКСТ . ТЕКСТ должен представлять собой однострочное описание символа.
В символе должен быть атрибут footprint=ИМЯ_КОРПУСА , он может использоваться генератором списка соединений для pcb. ИМЯ_КОРПУСА представляет собой посадочное место для pcb или тип корпуса, такой как DIP14 или DIP40. Подробности см. в Соглашениях по именованию посадочных мест. Если вы используете gEDA в связке с pcb, то более подробную информацию по данному атрибуту и о том, как его использовать, вы найдёте в документации по pcb и в gnetlist/docs/README.pcb .
Атрибут refdes= должен помещаться во все символы, не являющиеся чисто графическими. Значение данного атрибута по умолчанию для микросхем должно быть U? , а для транзисторов T? . Видимым следует сделать только его значение и, когда символ будет помещён в схему, данный атрибут будет вынесен (прикреплён вне символа для обеспечения возможности его редактирования).
Атрибут numslots= нужно добавлять во все символы, чтобы предотвратить предупреждения, выдаваемые программой gsymcheck при их проверке. Вполне достаточно добавить numslots=1 .
Теперь, когда все эти атрибуты добавлены, сделайте numslots , footprint , description , graphical и device невидимыми. Оставьте видимым только значение атрибута refdes и расположите его где-нибудь над символом.
Завершение
Добавьте к своему символу обозначение, выбрав Добавить → Текст… [Add → Text…] или нажав A T . Наберите своё обозначение и переместите его в верхнюю часть символа.
Сместите символ в начало координат из меню Правка → Смещение символа…
[Edit → Symbol Translate…] или нажмите E T .
Введите 0 в поле ввода и нажмите OK.
Сохраните символ с помощью Файл → Сохранить [File → Save] или Файл → Сохранить как… [File → Save As…].
Поместите символ в один из каталогов, заданных как библиотека символов в файле настроек gEDA suite (в одном из файлов gafrc ). Объяснение того, как настроить библиотеки символов см. в Руководстве пользователя gEDA gschem. Как только это сделано, символ должен немедленно стать видимым и может быть выбран и помещён в схему из меню Добавить → Компонент… [Add → Select Component…]. В Debian помещение файлов в /usr/share/gEDA/sym/local/ работать будет, но потребует настройки привилегий.
Примечание
Смещение символа в начало координат — шаг необходимый. Для смещения символа в другое место введите величину смещения (в милах), кратную 100. Убедитесь, что все выводы привязаны к точкам сетки.
Общие соглашения об именовании символов
Символы именуются следующим образом: symbolname-#.sym
Имена символов имеют расширение .sym .
Названия символов содержат число, обозначенное выше знаком # . Обычно оно равно 1, но если для устройства имеется несколько символов, данное число просто увеличивается.
Обычно имена символов задаются в нижнем регистре, но буквы, составляющие часть типа прибора, указываются в верхнем регистре.
Последнее правило может быть нарушено, если имя файла выглядит некорректно или ошибочно.
Требования к символам
В данном разделе описываются различные требования, которые необходимо соблюдать для создания правильного символа в плане отображения его на экране и создания для него списков соединений в системе gEDA/gaf.
Выводы
К каждому выводу должен быть прикреплён атрибут pinseq . Это число, определяющее порядок работы программы gnetlist с атрибутами. Это просто порядковый номер, последовательно увеличивающийся, начиная с 1.
К каждому выводу должен быть прикреплён атрибут pinnumber . Это номер вывода на корпусе компонента, для которого создаётся этот символ. Номер вывода может быть буквенным или цифровым (то есть можно использовать, например, E или C ).
К каждому выводу должен быть также прикреплён атрибут pinlabel . Данный атрибут является названием или меткой вывода (а не номером вывода). Данный атрибут применяется также при использовании символа в иерархической схеме.
К каждому выводу должен быть также прикреплён атрибут pintype . Данный атрибут определяет тип вывода. Допустимыми значениями являются: in , out , io , oc , oe , pas , tp , tri , clk , pwr . Более подробную информацию о нём см. в Перечне основных атрибутов.
Атрибуты
Более подробную информацию о представленных здесь атрибутах можно найти в Перечне основных атрибутов.
В символе должен находиться невидимый атрибут device=НАЗВАНИЕ_УСТРОЙСТВА . Обычно название устройства задаётся в верхнем регистре (прописными буквами). Данный атрибут не должен использоваться в качестве обозначения. Для этого следует использовать отдельный текстовый объект. Если символ определяет чисто графический объект, то device= должен иметь значение none ( device=none ).
Если символ является полностью графическим (как, например, рамка формата основной надписи или символ decon ) в нём должен быть атрибут graphical=1 . Символы с данным атрибутом не имеют электрического или схемотехнического назначения. Не забывайте согласно предыдущему требованию устанавливать вместе с данным атрибутом device=none .
В символе должен быть атрибут description=ТЕКСТ . ТЕКСТ должен представлять собой однострочное описание символа.
В символе должен быть атрибут footprint=ИМЯ_КОРПУСА , он может использоваться генератором списка соединений для pcb. ИМЯ_КОРПУСА представляет собой посадочное место для pcb или тип корпуса, такой как DIP14 или DIP40. Подробности см. в Соглашениях по именованию посадочных мест. Если вы используете gEDA в связке с pcb, то более подробную информацию по данному атрибуту и о том, как его использовать, вы найдёте в документации по pcb и в gnetlist/docs/README.pcb .
Атрибут refdes=U? должен помещаться во все символы, не являющиеся чисто графическими. Видимым следует сделать только его значение и, когда символ будет помещён в схему, данный атрибут будет вынесен (прикреплён вне символа для обеспечения возможности его редактирования).
Атрибуты label= и name= не должны использоваться в символах, так как это устаревшие атрибуты.
Атрибут netname= не должен использоваться в символах. Он используется только в схемах.
Многосекционные компоненты
Если компонент содержит несколько элементов (секций) в одном физическом корпусе (как, например, 7400, имеющий 4 элемента 2И-НЕ в одном корпусе), то необходим атрибут numslots=# . Число # задаёт количество элементов в физическом устройстве. В этом случае в символе должен быть атрибут numslots= и его следует сделать невидимым. Другие обязательные атрибуты, относящиеся к многосекционным компонентам, описываются ниже.
Если компонент содержит несколько элементов (секций) в одном физическом корпусе, то для каждой секции необходимо также задать атрибут slotdef=#:#,#,#… Первое число # соответствует номеру секции. Если устройство содержит 4 элемента, то в символе должны быть атрибуты slotdef=1:… , slotdef=2:… , slotdef=3:… и slotdef=4:… , их следует сделать невидимыми. Последующие числа # один к одному соответствуют атрибутам pinseq=# и определяют номер вывода pinnumber=# , который должен устанавливаться при назначении данной секции. В качестве примера того, как всё это должно работать, см. приведённый ниже символ 7400-1.sym.
В символы многосекционных компонентов рекомендуется добавлять атрибут slot=1 .
Проверка символа
Соответствие всем указанным требованиям проверяется запуском gsymcheck. gsymcheck выдаст фатальные ошибки, довольно серьёзные и требующие исправления. gsymcheck также выдаст предупреждения о требующих исправления, но не фатальных ошибках.
Стиль
В данном разделе описывается стиль, используемый в стандартной библиотеке символов gEDA/gaf.
Текстовые объекты
Все текстовые обозначения должны быть размером 10 пунктов.
Текст (текстовые обозначения, но не атрибуты) должен иметь цветовой индекс 9 (text | зелёный).
Для указания инверсных логических уровней используйте специальное кодирование черты над текстом (например, pinlabel=\_Reset\_ ).
Атрибуты
В качестве номеров выводов должны отображаться атрибуты pinnumber (не pinseq ), и их размер должен составлять 8 пунктов.
Цветовой индекс прикреплённых атрибутов должен быть равен 5 (attributes | жёлтый). Цвет автоматически устанавливается в жёлтый при прикреплении текстового элемента.
Единственным исключением из данного правила являются атрибуты pinlabel= , цветовой индекс которых должен быть равен 9 (text | зелёный). Если каждый текстовый элемент внутри символа будет жёлтым, символ выглядит чересчур жёлтым.
Атрибуты могут прикрепляться к некоторой части символа. Раньше, для того чтобы атрибуты верхнего уровня (такие как device= или net= ) считались атрибутами, их требовалось к чему-либо прикреплять, но сейчас достаточно, чтобы они находились в файле символа в виде имя_атрибута=значение .
Раскрывая немного последнее предложение, добавим, что атрибутом считается любой текстовый элемент вида имя_атрибута=значение . Атрибуты внутри символа не обязательно прикреплять к чему-либо. Чтобы увидеть скрытые атрибуты в gschem, выберите Правка → Показать/Скрыть невидимый текст [Edit → Show/Hide Inv Text].
В библиотеке libgeda есть система работы с версиями содержимого символа на основе оценки атрибута symversion= . Подробности использования этой схемы работы с версиями см. в Перечне основных атрибутов.
Графические примитивы
Цветовой индекс линий, прямоугольников, дуг и других графических объектов должен быть равен 3 (graphic | зелёный).
Цветовой индекс знаков логической инверсии в виде окружностей должен быть равен 6 (logic bubble | голубой).
Если вы не уверены в том, как должен выглядеть новый символ или какой он должен быть величины, то, чтобы получить представление о подходящем виде и размере, взгляните на существующие символы.
Выводы
Длина выводов должна составлять 300 милов (3 интервала сетки).
Длина выводов, располагаемых рядом со знаком логической инверсии, должна составлять 200 милов (2 интервала сетки), окружность знака логической инверсии должна иметь диаметр 100 милов. Чтобы начертить окружность диаметром 100 милов, нужно изменить размер сетки на 50.
Вывод имеет два конца: один помечен красной точкой, другой — нет. Красная точка означает место подключения соединений. Для правильного размещения активного конца можно либо поворачивать сам вывод, либо вручную отредактировать файл символа, изменив параметр «whichend» нужного вывода. Подробности см. в документации по Формату файлов.
Все концы выводов, предназначенные для соединений, должны размещаться по сетке размером 100 милов. Другие, неактивные концы могут быть при необходимости расположены не по сетке.
Цветовой индекс для выводов должен быть равен 1 (pins | белый).
Выводы (по вертикали) следует размещать на расстоянии 400 милов (4 интервала сетки) за исключением вычерчивания специальных символов, в таких случаях просто старайтесь, чтобы символ хорошо выглядел.
Номера выводов должны располагаться на 50 милов выше вывода, к которому они прикреплены (или ниже; то есть более подходящим по смыслу образом).
Входные выводы размещаются с левой стороны символа, выходные — с правой.
Пожалуйста, не помещайте входы и выходы на одну и ту же сторону символа, если в этом нет абсолютной необходимости.
Можно располагать выводы сверху или снизу символа.
Порядок последовательности выводов (для шин) должен быть от младшего значащего разряда (МЗР) к старшему (СЗР). При вычерчивании выводов, являющихся частью шины, обеспечьте, чтобы МЗР на шине был расположен наверху (или для выводов, которые располагаются вверху или внизу символа, слева от других выводов). Пример правильного порядка вы найдёте в символе 74/74181-1.sym (сверху вниз от A0 до A3 и от B0 до B3). Нарушение данного правила сильно затруднит подключение к шинам.
При размещении выводов логических элементов обязательно располагайте выводы начиная с наименьших порядковых номеров сверху вниз (или слева направо) в порядке их увеличения.
Схемотехника
Не чертите выводы питания. Такая информация обычно передаётся посредством атрибутов (смотрите Мини-HOWTO по атрибуту net=).
Вышеуказанное правило при необходимости может быть нарушено, но имейте в виду, что в большинстве символов стандартной библиотеки выводы питания не показаны.
Имейте в виду, что символы должны быть символическими, они не изображают физический корпус устройства.
По вышеуказанным вопросам есть некоторые разногласия, поэтому следующее тоже будет нормально: располагайте выводы символа логически, так, чтобы они способствовали созданию понятных, незапутанных схем. Заметьте, что часто это не тождественно физическому расположению выводов устройства.
Советы и подсказки
В данном разделе приводится несколько советов и подсказок, чтобы облегчить вам труд по созданию символов.
Выводы ДОЛЖНЫ быть выровнены по сетке размером 100.
Избегайте черчения объектов вне сетки. В противном случае вы не сможете перемещать их командой перемещения (если сетка включена), так как объекты будут прилипать к сетке. [Это старая программная ошибка, которая, думаю, уже исправлена, но всё равно остерегайтесь так делать.] Вместо этого используйте команду смещения символа (или перемещайте объект, отключив сетку).
При создании символов нормально устанавливать размер сетки меньше 100 (скажем, 10 или 25), только надо помнить, что его надо вернуть обратно в 100, когда вы будете готовы к смещению символа в начало координат.
Если вы хотите сместить символ куда-то из начала координат, используйте команду Правка → Смещение символа… [Edit→Symbol Translate…] и введите число, не равное нулю. Это число должно быть кратным 100 (например, 1000 или 1100).
Помните, что выводы являются специальными объектами; если вы хотите добавить вывод, убедитесь, что вводите именно вывод, а не линию или соединение. Используйте команду Добавить → Вывод [Add → Pin] для черчения вывода.
Не используйте внутри символа соединений и шин. Это не поддерживается и не имеет особого смысла.
Для выводов должен быть видимым атрибут pinnumber , может быть вместе с pinlabel , если таковой имеется.
Пример
В данном разделе приведён простой пример, в котором мы стараемся следовать всем вышеуказанным правилам. Это символ 7400 (И-НЕ).
v 20031231 1 L 300 200 300 800 3 0 0 0 -1 -1 T 300 0 9 8 1 0 0 0 1 7400 L 300 800 700 800 3 0 0 0 -1 -1 T 500 900 5 10 0 0 0 0 1 device=7400 T 500 1100 5 10 0 0 0 0 1 slot=1 T 500 1300 5 10 0 0 0 0 1 numslots=4 T 500 1500 5 10 0 0 0 0 1 slotdef=1:1,2,3 T 500 1700 5 10 0 0 0 0 1 slotdef=2:4,5,6 T 500 1900 5 10 0 0 0 0 1 slotdef=3:9,10,8 T 500 2100 5 10 0 0 0 0 1 slotdef=4:12,13,11 L 300 200 700 200 3 0 0 0 -1 -1 A 700 500 300 270 180 3 0 0 0 -1 -1 V 1050 500 50 6 0 0 0 -1 -1 0 -1 -1 -1 -1 -1 P 1100 500 1300 500 1 0 1 < T 1100 550 5 8 1 1 0 0 1 pinnumber=3 T 1100 450 5 8 0 1 0 2 1 pinseq=3 T 950 500 9 8 0 1 0 6 1 pinlabel=Y T 950 500 5 8 0 1 0 8 1 pintype=out >P 300 300 0 300 1 0 1 < T 200 350 5 8 1 1 0 6 1 pinnumber=2 T 200 250 5 8 0 1 0 8 1 pinseq=2 T 350 300 9 8 0 1 0 0 1 pinlabel=B T 350 300 5 8 0 1 0 2 1 pintype=in >P 300 700 0 700 1 0 1 < T 200 750 5 8 1 1 0 6 1 pinnumber=1 T 200 650 5 8 0 1 0 8 1 pinseq=1 T 350 700 9 8 0 1 0 0 1 pinlabel=A T 350 700 5 8 0 1 0 2 1 pintype=in >T 300 900 8 10 1 1 0 0 1 refdes=U? T 500 2250 5 10 0 0 0 0 1 footprint=DIP14 T 500 2450 5 10 0 0 0 0 1 description=4 NAND gates with 2 inputs T 500 2850 5 10 0 0 0 0 1 net=Vcc:14 T 500 3050 5 10 0 0 0 0 1 net=GND:7 T 500 2650 5 10 0 0 0 0 1 documentation=http://www-s.ti.com/sc/ds/sn74hc00.pdf
Результат, полученный в данном примере, выглядит в gschem следующим образом:
Вот тот же самый символ, весь скрытый текст которого видим (меню Правка → Показать/Скрыть невидимый текст [Edit → Show/Hide Inv Text]):
Где находится верхний регистр на клавиатуре

Первое, что попадает в руки пользователя компьютерной техникой – это клавиатура и мышка. Умение использовать различные функции с помощью этих атрибутов, позволяют быстро решать поставленные задачи. Если спросить новичка о том, что такое верхний регистр, то он, возможно, укажет на клавиши, расположенные вверху. На самом деле – это далеко не так.
Что такое верхний и нижний регистр на клавиатуре
Эти понятия дошли до нас со времён печатных машинок. При наборе текстов, обычный шрифт написания выполняли в стандартном положении оборудования, которое называли нижним, а заглавные буквы наносились на бумагу при изменении положения печатных штанг, путём перевода их в верхнее положение. Именно подобной функцией наделены клавиатуры современных мобильных и стационарных печатных устройств.

С помощью кнопки функционального перевода «Shift» из одного режима в другой, пользователь ПК может переходить на прописные или заглавные буквы при написании текстов, в зависимости от требований к содержанию. Цифры при этом обозначают знаки препинания или другую символику, которую используют при распечатке документов. Иными словами, верхний регистр – это такой режим печати, в котором буквы становятся заглавными, а цифры меняются на символы. Нижний – это обычное изображение цифровых и буквенных обозначений.
Где находится верхний регистр
Две клавиши перевода из одного режима печати в другой расположены на клавиатуре: одна слева внизу, а другая справа – тоже в нижней части. Это сделано для удобства быстрого набора текстов. Если буква, которую нужно написать заглавной находится справа, то используют левую сторону. При переходе нажимают одновременно, сначала «Shift», а затем требуемый знак. А при расположении нужного символа слева – наоборот. Если пользователю удобно одной рукой нажимать обе клавиши, то он делает именно так, например, чтобы отобразить запятую!
ВНИМАНИЕ! Клавиатура некоторых мобильных устройств может иметь только одну клавишу «Shift». Это связано с компактностью размеров оргтехники.

Удобство применения верхнего режима позволяет быстро переключить функцию нужного символа из одного положения – в другое. Кроме того, слева, над кнопкой «Shift» расположена клавиша с надписью «Caps Lock», которая имеет такое же функциональное назначение, но другой принцип работы.
Способы переключения регистра на клавиатуре
При наборе текстов используют два режима переключения:
- кратковременный;
- длительный.
Первый из перечисленных способов переключает клавиатуру только в момент нажатия на клавишу «Shift». Как только пользователь её отпускает, печать продолжается в обычном режиме – прописными буквами.
Второй способ позволяет, после нажатия кнопки «Caps Lock», перейти в верхний регистр и печатать заглавные буквы до тех пор, пока не отпадёт необходимость в использовании таковых. Отдельный индикатор клавиатуры загорается при включении такого режима и гаснет только при повторном нажатии указанной клавиши, что подтверждает переход на прописные обозначения.
ВАЖНО! При включении «Caps Lock», использование кнопки «Shift» будет иметь противоположное действие: при нажатии – обычные символы, а после отпускания – заглавные буквы.
Длительный режим используют при написании заголовков или выделения названий статей.
Наличие навыков быстрого перехода из одного регистра в другой, позволяет пользователям ПК с удобством набирать требуемые тексты, быстро вставляя необходимые символы и заглавные буквы.
