От текста к листингу

Публикации на околокомпьютерную тематику нередко сопровождаются фрагментами программ, макросами и прочими листингами, содержащими текст на каком-нибудь языке программирования. Так уж сложилось, что для оформления листингов программ используется моноширинный шрифт, то есть шрифт, каждый символ которого имеет одинаковую ширину. В операционной системе Windows включен моноширинный шрифт Courier New Cyr, но вы можете применять и другие.

Для оформления листинга ничто не мешает в текстовом документе выделить часть текста, а затем изменить шрифт. Этому и будет посвящена новая статья цикла, посвященная макросам Microsoft Office. Заметим, что процедура оформления программ может быть решена тремя способами: с помощью соответствующих настроек панелей инструментов или создания макроса. Первый способ достаточно прост, однако не обеспечивает должной функциональности, два другие способа оформления документа подразумевают использование макросов на Visual Basic for Application.


Рис. 1. Для того чтобы оформить листинг программы в тексте, следует воспользоваться моноширинным шрифтом Courier New.

Обойдемся пока без макросов
Задача форматирования выделенного фрагмента текста несложна и можно обойтись без макроса. Однако постоянно раскрывать список со шрифтами, выбирать в нем шрифт Courier New — операция, требующая по меньшей мере трех действий: щелкнул, прокрутил список и снова щелкнул. Word, благодаря средствам конфигурирования панелей, позволяет уменьшить число действий до одного. Для создания панели вам нужно выполнить следующие действия:
1. Активизируйте режим настройки панелей.
2. Нажмите кнопку Создать и определите название новой панели инструментов, например Листинг.
3. Перейдите на вкладку Команды. В списке Категории найдите строку Шрифты, а в списке Команды — шрифт Courier New. Переместите команду в панель инструментов и настройте при необходимости ее свойства, например, надпись, вид, значок и др.
4. Созданную панель инструментов можно протестировать, для чего выделите любой фрагмент текста и щелкните по недавно созданной кнопке. Текст будет отформатирован с помощью шрифта Courier New Cyr.

Запись макроса для форматирования текста
Существуют и другие способы форматирования фрагмента текста как листинга программы. Они подразумевают применение макросов. Word, равно как и другие приложения Microsoft Office, позволяют запоминать любые команды меню и панелей инструментов в виде макроса. По своей сути, созданный макрос мало отличается от кнопки панели инструментов, но, быть может, он покажется вам более удобным.
1. Выберите в меню команду Сервис — Макрос — Начать Запись.
2. В появившемся окне задайте имя макроса, а также способ его последующего вызова. Word позволяет связать макрос с панелью инструментов или с функциональными клавишами.
3. В режиме записи вам следует указать шрифт Courier New, а затем щелкнуть по кнопке Остановить запись.
4. Никаких внешних изменений с программой Word не произойдет, но если вы нажмете клавиши Alt-F11, а затем раскроете созданный вами макрос, то на экране появится программа на Visual Basic for Application.
5. Дальнейшие шаги по форматированию документа вам уже известны: вы выделяете фрагмент текста и щелкаете по кнопке панели инструментов или нажимаете горячую клавишу, шрифт текста автоматически изменяется.


Рис. 2. В режиме записи макроса вы можете указать название макроса, клавишу или кнопку панели инструментов, которая исполняет макрос, а также при необходимости задать описание макроса. Непосредственно во время записи Word запоминает все используемые вами команды и преобразует их в соответствующие операторы языка Visual Basic for Application.

Что будет содержать программа
Следует заметить, что генерируемый Word макрос напрямую зависит от ваших действий. Если вы в режим записи макроса установите шрифт Courier New посредством панели инструментов, то в макросе появится программа, состоящая всего из двух строчек (см. рис. 3).
Но если вы воспользуетесь командой меню Формат — Шрифт и укажите в диалоговом окне шрифт Courier New, размер шрифта 10, а также какие-то дополнительные опции, то Word запомнит все измененные параметры шрифта и запишет их в виде макроса, представленного на рис. 4.


Рис. 3. Созданный Word макрос может иметь различные операторы. Так, если вы отформатировали текст с помощью панели инструментов, то в макросе, не считая комментариев, появится всего две строки.

Сложное форматирование листинга программы
Третий способ форматирования текста наиболее трудоемок, но вместе с этим он предоставляет наибольшее количество возможностей. Так, вы с помощью макроса, текст которого приводится ниже, сможете не только отформатировать текст программы моноширинным шрифтом Courier New, но и выделить все зарезервированные слова языка программирования так, как это делается в современных средах программирования. Программа достаточно проста, но имеет одну проблему (скоро вы поймете, отчего так происходит): если в комментариях или строковых выражениях используются зарезервированные слова, они тоже выделяются полужирным. Более детальный анализ текста программ средствами Visual Basic for Application затруднен из-за невысокой производительности работы — да это и не нужно, поскольку исправить несколько ошибок в уже отформатированной программе гораздо проще, чем пословно просматривать программу и форматировать вручную.
В программе использованы два алгоритма преобразования. Первый алгоритм основан на том факте, что выделенный фрагмент текста в Word представляет собой по сути коллекцию слов, и если очередное слово является зарезервированным, то оно выделяется полужирным начертанием. Второй алгоритм использует средства поиска и замены, достаточно подробно рассмотренные в прошлый раз.
Для первого необходимы четыре процедуры:
— WordInKeyWords — функция возвращает True, если указанное слово содержится в массиве KeyWords. Массив KeyWord содержит список слов, которые выделяются полужирным начертанием.
— ConvertingMethod1 — преобразование в тексте путем перебора каждого слова.
— JavaModuleMethod1 — подготовка массивов для преобразования программ на Java.
— DelphiModuleMethod1 — подготовка массивов для преобразования программ на Delphi.
Для второго способа форматирования необходимы три процедуры:
— ConvertingMethod2 — преобразование в тексте при помощи объектов Find, Replacement.
— JavaModuleMethod2 — подготовка массивов для преобразования программ на Java.
— DelphiModuleMethod2 — подготовка массивов для преобразования программ на Delphi.
Программа, текст которой приводится в листинге, позволяет форматировать программы на Java и объектном Паскале. Вам следует связать процедуры JavaModuleMethod1, JavaModuleMethod2 или DelphiModuleMethod1, DelphiModuleMethod2 с командами панели инструментов или горячими клавишами и форматировать фрагменты текста, как программные модули. В начале этих процедур происходит подготовка массива KeyWords. Вы можете адаптировать их и к любым другим языкам программирования, предварительно составив перечень зарезервированных слов.


Рис. 4. В том случае, если вы, создавая макрос, использовали диалоговое окно для форматирования шрифта, Word запомнит все измененные параметры и добавит их в программу.

Как ввести текст программы
Поскольку задача была решена двумя способами, программа получилась довольно большой. Вы можете попробовать применять и тот, и другой способ, но впоследствии отказаться от одного варианта в пользу другого. В этом случае размеры программы сократятся вдвое.
При вводе используйте стандартную последовательность, то есть сначала создайте в шаблоне Normal.DOT новый модуль, а затем в нем определяйте процедуры. При добавлении макроса к шаблону Normal.dot, вы делаете его доступным в любых документах. Если это не желательно, создайте обычный документ, введите в него соответствующие процедуры, а затем сохраните его как шаблон. При желании вы также можете определить новую панель инструментов и связать ее с соответствующими процедурами модуля.

Другие применения макросов
Идеи, заложенные в макросе, не обязательно использовать только для форматирования листингов программ. Предложенные алгоритмы прекрасно подойдут и для выделения дат в тексте по истории чего-либо или для выделения названий компаний и фирм, их сотрудников в отчете по итогам работы за квартал, финансовый год и так далее. Словом, предложенные программы позволяют выделять любые фрагменты текста нужным вам способом — главное, составить список слов и определить способы их форматирования.
Тексты макросов приводятся в листинге
— Модуль в документе Doc1 предназначен для форматирования текста программ, подготавливаемых для книг, журнальных статей, рефератов или каких-то иных целей.
— При этом в тексте выполняются следующие преобразования: устанавливается гарнитура Courier New и все ключевые слова форматируются полужирным начертанием.
— Программа чрезвычайно проста и имеет одно проблему: если в комментариях или в строковых выражениях используются зарезервированные слова, они тоже выделяются полужирным.
— Более детальный анализ текста программ средствами Visual Basic for Application затруднен из-за невысокой производительности работы.
— WordInKeyWords — функция возвращает True, если указанное слово содержится в массиве KeyWords.
— ConvertingMethod1 — преобразование в тексте путем перебора каждого слова.
— JavaModuleMethod1 — подготовка для преобразования программ на Java.
— DelphiModuleMethod1 — подготовка для преобразования программ на Delphi.
— ConvertingMethod2 — преобразование в тексте при помощи объектов Find, Replacement.
— JavaModuleMethod2 — подготовка для преобразования программ на Java.
— DelphiModuleMethod2— подготовка для преобразования программ на Delphi.

Dim KeyWords

Function WordInKeyWords(aWord As String) As Boolean
WordInKeyWords = False

For I = LBound(KeyWords) To UBound(KeyWords)
If LCase(Trim(KeyWords(I))) = LCase(Trim(aWord)) Then WordInKeyWords = True: Exit Function
Next
End Function

Sub ConvertingMethod1()
— процедура выполняет преобразование указанных в массиве KeyWords слов.
— При этом последовательно перебираются слова текста — такой способ очень долог.
On Error Resume Next ' необязательная строка, поскольку в процедуре отсутствуют инструкции, которые могут привести к ошибкам.
Dim MyRange As Range
Set MyRange = Selection.Range
MyRange.Font.Name = "Courier New"
MyRange.Font.Size = 8
For I = 1 To MyRange.Words.Count
If WordInKeyWords(MyRange.Words(I)) Then
MyRange.Words(I).Bold = True
End If
Next I
End Sub

Sub JavaModuleMethod1()
' подготавливает массив KeyWords для программ на Java и вызывает процедуру ConvertingVeryOld
KeyWords = Array("abstract", "boolean", "break", "byte", "byvalue", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchrinized", "this", "threadsafe", "throw", "throws", "transient", "true", "try", "void", "while")
Application.ScreenUpdating = False
ConvertingMethod1
Application.ScreenUpdating = True
Application.ScreenRefresh
End Sub

Sub DelphiModuleMethod1()
' подготавливает массив KeyWords для программ на Java и вызывает процедуру ConvertingVeryOld
KeyWords = Array("and", "array", "as", "asm", "begin", "case", "class", "const", "constructor", "destructor", "dispinterface", "div", "do", "downto", "else", "end", "except", "exports", "file", "finalization", "finally", "for", "function", "goto", "if", "implementation", "in", "inherited", "initialization", "inline", "interface", "is", "Label", "library", "Mod", "nil", "not", "object", "of", "or", "out", "packed", "procedure", "program", "property", "raise", "record", "repeat", "resourcestring", "set", "shl", "shr", "string", "then", "threadvar", "to", "try", "type", "unit", "until", "uses", "var", "while", "with", "xor")
Application.ScreenUpdating = False
ConvertingMethod1
Application.ScreenUpdating = True
Application.ScreenRefresh
End Sub

Sub ConvertingMethod2()
— процедура выполняет преобразование указанных в массиве KeyWords слов.
— При этом используются объекты Find, Replacement для контекстной замены, поскольку это наиболее быстрый способ для обработки текста
On Error Resume Next ' необязательная строка, поскольку в процедуре отсутствуют инструкции, которые могут привести к ошибкам
Dim MyRange As Range
Set MyRange = Selection.Range
MyRange.Font.Name = "Courier New"
MyRange.Font.Size = 8
For I = LBound(KeyWords) To UBound(KeyWords)
MyRange.Find.Text = KeyWords(I)
MyRange.Find.Replacement.Text = KeyWords(I)
MyRange.Find.Replacement.Font.Bold = True
MyRange.Find.Execute Replace:=wdReplaceAll, Format:=True, MatchWholeWord:=True
Next I
End Sub

Sub JavaModuleMethod2()
' подготавливает массив KeyWords для программ на Java и вызывает процедуру Converting
KeyWords = Array("abstract", "boolean", "break", "byte", "byvalue", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchrinized", "this", "threadsafe", "throw", "throws", "transient", "true", "try", "void", "while")
Application.ScreenUpdating = False
ConvertingMethod2
Application.ScreenUpdating = True
Application.ScreenRefresh
End Sub

Sub DelphiModuleMethod2()
' подготавливает массив KeyWords для программ на Delphi и вызывает процедуру Converting
KeyWords = Array("and", "array", "as", "asm", "begin", "case", "class", "const", "constructor", "destructor", "dispinterface", "div", "do", "downto", "else", "end", "except", "exports", "file", "finalization", "finally", "for", "function", "goto", "if", "implementation", "in", "inherited", "initialization", "inline", "interface", "is", "Label", "library", "Mod", "nil", "not", "object", "of", "or", "out", "packed", "procedure", "program", "property", "raise", "record", "repeat", "resourcestring", "set", "shl", "shr", "string", "then", "threadvar", "to", "try", "type", "unit", "until", "uses", "var", "while", "with", "xor")
Application.ScreenUpdating = False
ConvertingMethod2
Application.ScreenUpdating = True
Application.ScreenRefresh
End Sub

Сергей Лосев


Компьютерная газета. Статья была опубликована в номере 47 за 1999 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета