В данной статье рассмотрим пример использования классов wxWidgets для экспорта в формат LaTeX. Мы создадим файл содержащий формулы, таблицу и цветной график. Цель - продемонстрировать возможность программного создания LaTeX файла для научных и учебных целей, например, для диссертаций, лабораторных или отчетов. Либо если вы захотите расширить набор форматов экспорта вашей программы (в силу простоты формата LaTeX, возможно, это будет самый простой способ создания файла отчета для расчетных и научных программ). Таблица и график создаются средствами LaTeX, что позволяет добиться высокого качества изображения при минимуме размера файла. Классы wxTextFile и wxString позволяют это сделать максимально комфортно.
На картинке ниже показан результат скомпилированного LaTeX файла созданного с помощью нашей программы (собранная программа и LaTeX файл прилагаются в конце статьи).
Подключаем библиотеки:
#include <wx/string.h> #include <wx/textfile.h> #include <math.h>
Далее пишем функцию main()
. Наша задача - создать файл, содержимое которого будет соответствовать формату LaTeX. Создание файла с именем output.tex
(если файл сузествует, то открываем его, если нет, то создаем; после очищаем):
wxTextFile file(wxT("output.tex")); if (file.Exists()) file.Open(); else file.Create(); file.Clear();
Создаем шапку документа с подключанием необходимых пакетов (обратите внимание, на то, что мы указываем уникодную кодировку для файла utf8x, т.к. используется уникодная сборка wxWidgets, если у вас ASCII сборка библиотеки, то указывайте для LaTeX-документа кодировку cp1251 /хотя этот вариант нами не тестировался/). Здесь же добавляем заголовок.
\documentclass[10pt,a4paper]{article} \usepackage[utf8x]{inputenc} \usepackage[english,russian]{babel} \usepackage{xcolor} \begin{document} \begin{center}График функции $f(x) = {\color{olive}2 \sin^3 x \cdot \cos x}$\end{center}
Эти строчки записываются с помощью функции AddLine
. Для экранирования escape-последовательностей обратную дробную черту мы ставим двойную. Например, для первой строчки (аналогично для остальных) пишем:
file.AddLine(wxT("\\documentclass[10pt,a4paper]{article}"));
Для поцизионирования элементов (таблицы и графика) мы используем окружение minipage
. Для запрета отступа красной строки используем команду \noindent
. Для таблицы LaTeX код будет примерно следующим (приведены только три строки таблицы, первая - с заголовками):
\noindent \begin{minipage}[c]{4cm} \begin{tabular}{|c|c|} \hline $x$&$f(x)$\\ \hline 0.00$\pi$&0.000000\\ \hline 0.12$\pi$&0.103553\\ \hline .................. \end{tabular} \end{minipage}
Далее идет блок с командами для создания графика внутри окружения minipage
. Сам график создается графическими командами в окружении picture
. Рисуем оси, сетку, подпись к графику и значениям на осях и сам график. В полном тексте программы в конце статьи лугко определить как это делается.
\begin{minipage}[c]{10cm}
\begin{picture}(230,210)
Всякие разные команды рисования
\end{picture}
\end{minipage}
В приведенном ниже коде пустая строка оставлена не случайно, в силу специфики окружения picture
для правильного расположения картинки перед ней должна быть пустая строка (если ее не будет, то получим более сложный и интересный случай, но это предмет для другой статьи). Пустая строка создается в программе командой
file.AddLine(wxEmptyString);
И в самом конце на забываем записать команду завершение LaTeX-документа:
\end{document}
Результат сохраняем в файл:
file.Write();
Вот собственно и все. Удачного программирования LaTeX-документов.
/* * Название: wxtextfile_latex.cpp * Описание: Пример экспорта в формат LaTeX * Дата: 19 апреля 2009 года * Автор: Ильдар Насибуллаев * Требования: g++, wxWidgets, GTK+ * Компиляция: g++ wxtextfile_latex.cpp `wx-config --libs --cxxflags` * Распространение: свободное и бесплатное с ссылкой на автора * Подробности: http://fsweb.info/programming/wxwidgets/wxtextfile_latex.html */ #include <wx/string.h> #include <wx/textfile.h> #include <math.h> int main() { int i; const size_t N = 16; wxDouble x; wxString string; wxTextFile file(wxT("output.tex")); if (file.Exists()) file.Open(); else file.Create(); file.Clear(); file.AddLine(wxT("\\documentclass[10pt,a4paper]{article}")); file.AddLine(wxT("\\usepackage[utf8x]{inputenc}")); file.AddLine(wxT("\\usepackage[english,russian]{babel}")); file.AddLine(wxT("\\usepackage{xcolor}")); file.AddLine(wxT("\\begin{document}")); file.AddLine(wxT("\\begin{center}График функции $f(x) = {\\color{olive}2 \\sin^3 x \\cdot \\cos x}$\\end{center}")); file.AddLine(wxT("")); file.AddLine(wxT("\\noindent")); file.AddLine(wxT("\\begin{minipage}[c]{4cm}")); file.AddLine(wxT("\\begin{tabular}{|c|c|}")); file.AddLine(wxT("\\hline")); file.AddLine(wxT("$x$&$f(x)$\\\\")); for (i = 0; i <= N; i++) { x = 2. * M_PI * i / N; string.Clear(); string << wxString::Format(wxT("%*.*f"), 4, 2, 2. * i / N) << wxT("$\\pi$&") << wxString::Format(wxT("%.*f"), 6, 2. * pow(sin(x),3) * cos(x)) << wxT("\\\\"); file.AddLine(wxT("\\hline")); file.AddLine(string); } file.AddLine(wxT("\\hline")); file.AddLine(wxT("\\end{tabular}")); file.AddLine(wxT("\\end{minipage}")); //file.AddLine(wxT("\\hfill")); file.AddLine(wxT("\\begin{minipage}[c]{10cm}")); file.AddLine(wxEmptyString); file.AddLine(wxT("\\begin{picture}(230,210)")); file.AddLine(wxT("\\thinlines")); file.AddLine(wxT("\\multiput(70,0)(50,0){4}{{\\color{gray}\\line(0,1){210}}}")); file.AddLine(wxT("\\multiput(20,0)(0,50){5}{{\\color{gray}\\line(1,0){210}}}")); file.AddLine(wxT("\\put(20,100){\\vector(1,0){210}}")); file.AddLine(wxT("\\put(20,0){\\vector(0,1){210}}")); file.AddLine(wxT("\\multiput(25,99)(5,0){40}{\\line(0,1){2}}")); file.AddLine(wxT("\\multiput(19,0)(0,5){40}{\\line(1,0){2}}")); file.AddLine(wxT("\\thicklines")); file.AddLine(wxT("\\multiput(70,98)(50,0){4}{\\line(0,1){4}}")); file.AddLine(wxT("\\multiput(18,0)(0,50){2}{\\line(1,0){4}}")); file.AddLine(wxT("\\multiput(18,150)(0,50){2}{\\line(1,0){4}}")); file.AddLine(wxT("\\thinlines")); file.AddLine(wxT("\\put(20,100){\\circle*{2}}")); for (i = 1; i <= 4; i++) { string.Clear(); string << wxT("\\put(") << 20 + i * 50 << wxT(",") << 95 << wxT("){\\makebox(0,0)[tc]{$") << wxString::Format(wxT("%*.*f"), 2, 1, .5 * i) << wxT("\\pi$}}"); file.AddLine(string); } for (i = -2; i <= 2; i++) { string.Clear(); string << wxT("\\put(") << 15 << wxT(",") << 100 + i * 50 << wxT("){\\makebox(0,0)[cr]{$") << wxString::Format(wxT("%*.*f"), 2, 1, .5 * i) << wxT("$}}"); file.AddLine(string); } file.AddLine(wxT("\\put(95,185){{\\linethickness{25pt}\\color{white}\\line(1,0){120}}}")); file.AddLine(wxT("\\put(100,182){\\fbox{${\\color{blue}\\cdots}\\;f(x) = 2 \\sin^3 x \\cdot \\cos x$}}")); file.AddLine(wxT("{\\color{blue}")); for (i = 0; i <= 200; i++) { x = 2. * M_PI * i / 200; string.Clear(); string << wxT("\\put(") << 20 + i << wxT(",") << 100 + 200 * pow(sin(x),3) * cos(x) << wxT("){\\circle*{1}}"); file.AddLine(string); } file.AddLine(wxT("}")); file.AddLine(wxT("\\end{picture}")); file.AddLine(wxT("\\end{minipage}")); file.AddLine(wxT("\\end{document}")); file.Write(); return 0; }