From c070ac6d3a99cdeb4ac68656b2e2d78fef7eb1b6 Mon Sep 17 00:00:00 2001 From: Kolan Sh Date: Wed, 7 Dec 2016 19:36:43 +0300 Subject: [PATCH 1/2] Initial commit. --- .gitmodules | 6 + AUTHORS | 1 + CMakeLists.txt | 22 + COPYING | 165 +++ INSTALL | 86 ++ MAINTAINERS | 2 + cmake/backbone | 1 + config/CMakeLists.txt | 5 + config/Config.vapi | 6 + config/config.h.in | 3 + config/ws.backbone.laview.core.gschema.xml | 47 + cpack/CMakeLists.txt | 10 + pkg-config/CMakeLists.txt | 17 + po/CMakeLists.txt | 1 + po/laview-core.pot | 114 ++ po/ru/CMakeLists.txt | 1 + po/ru/laview-core.po | 115 ++ src/CMakeLists.txt | 9 + src/conv/CMakeLists.txt | 9 + src/conv/main.vala | 112 ++ src/core-iface/CMakeLists.txt | 8 + src/core-iface/CoreInterface.vala | 99 ++ src/core/AppDirs.vala | 41 + src/core/CMakeLists.txt | 17 + src/core/Core.vala | 791 ++++++++++ src/core/FileUtils.vala | 16 + src/core/Templates.vala | 92 ++ test/CMakeLists.txt | 7 + test/conv-test/CMakeLists.txt | 36 + test/conv-test/ConvTest.vala | 106 ++ test/conv-test/templates/pic/lyx.png | Bin 0 -> 1623 bytes test/conv-test/templates/templ_ex1.lyx | 187 +++ test/core-test/templates/example.lyx | 1295 +++++++++++++++++ .../templates/pics/laview-desktop.png | Bin 0 -> 13754 bytes test/host-test/CMakeLists.txt | 1 + test/host-test/plugins/CMakeLists.txt | 2 + test/host-test/plugins/data/CMakeLists.txt | 0 .../host-test/plugins/protocol/CMakeLists.txt | 0 util/backbone | 1 + valadoc_env | 2 + 40 files changed, 3433 insertions(+) create mode 100644 .gitmodules create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 MAINTAINERS create mode 160000 cmake/backbone create mode 100644 config/CMakeLists.txt create mode 100644 config/Config.vapi create mode 100644 config/config.h.in create mode 100644 config/ws.backbone.laview.core.gschema.xml create mode 100644 cpack/CMakeLists.txt create mode 100644 pkg-config/CMakeLists.txt create mode 100644 po/CMakeLists.txt create mode 100644 po/laview-core.pot create mode 100644 po/ru/CMakeLists.txt create mode 100644 po/ru/laview-core.po create mode 100644 src/CMakeLists.txt create mode 100644 src/conv/CMakeLists.txt create mode 100644 src/conv/main.vala create mode 100644 src/core-iface/CMakeLists.txt create mode 100644 src/core-iface/CoreInterface.vala create mode 100644 src/core/AppDirs.vala create mode 100644 src/core/CMakeLists.txt create mode 100644 src/core/Core.vala create mode 100644 src/core/FileUtils.vala create mode 100644 src/core/Templates.vala create mode 100644 test/CMakeLists.txt create mode 100644 test/conv-test/CMakeLists.txt create mode 100644 test/conv-test/ConvTest.vala create mode 100644 test/conv-test/templates/pic/lyx.png create mode 100644 test/conv-test/templates/templ_ex1.lyx create mode 100644 test/core-test/templates/example.lyx create mode 100644 test/core-test/templates/pics/laview-desktop.png create mode 100644 test/host-test/CMakeLists.txt create mode 100644 test/host-test/plugins/CMakeLists.txt create mode 100644 test/host-test/plugins/data/CMakeLists.txt create mode 100644 test/host-test/plugins/protocol/CMakeLists.txt create mode 160000 util/backbone create mode 100644 valadoc_env diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..50bba8b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "cmake/backbone"] + path = cmake/backbone + url = git@git.backbone.ws:cmake/backbone.git +[submodule "util/backbone-utils"] + path = util/backbone + url = git@git.backbone.ws:cmake/backbone-utils.git diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..609258d --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Kolan Sh diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5a652c9 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,22 @@ +PROJECT (LAviewCore C) + +CMAKE_MINIMUM_REQUIRED (VERSION 2.8) + +SET (PROJECT_LOWERCASE_NAME "laview-core") +SET (PROJECT_DESCRIPTION "LAview Core Libraries.") + +SET (MAJOR 0) +SET (MINOR 0) +SET (PATCH 0) + +LIST (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/backbone) + +ADD_SUBDIRECTORY (config) +ADD_SUBDIRECTORY (src) +ADD_SUBDIRECTORY (po) +ADD_SUBDIRECTORY (pkg-config) +ADD_SUBDIRECTORY (test) +ADD_SUBDIRECTORY (cpack) + +# enable testing +ENABLE_TESTING () diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..87a4559 --- /dev/null +++ b/INSTALL @@ -0,0 +1,86 @@ + Requirements + ------------ + + Build-Time Dependencies + +Vala: https://wiki.gnome.org/Projects/Vala +LAview-LaTeX-Struct: https://redmine.backbone.ws/projects/latex-struct +GObject-Plugin: https://redmine.backbone.ws/projects/plugin +CMake: http://www.cmake.org +NSIS (W32): http://nsis.sourceforge.net + + Run-Time Dependencies + +LAview-LaTeX-Struct: https://redmine.backbone.ws/projects/latex-struct +GObject-Plugin: https://redmine.backbone.ws/projects/plugin + + Operation Systems + + * GNU/Linux (Gentoo, Debian, etc.) + * MS Windows (Windows 5.1 aka XP) + * BSD-based (FreeBSD, OpenBSD, NetBSD, Mac OS X) + +If you need support of one more OS, be free in writing of patches and sending +pull-requests to the mainstream. + + + Compilation + ----------- + + Compilation under GNU/Linux + +$ mkdir build-gcc && cd build-gcc +$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr +$ make -j$((`getconf _NPROCESSORS_ONLN`+1)) + + Compilation under MS Windows + +$ mkdir build-mingw && cd build-mingw +$ cmake -G "MSYS Makefiles" .. -DCMAKE_BUILD_TYPE=Release +$ make -j$((NUMBER_OF_PROCESSORS + 1)) + + Compilation under BSD-based Systems. + +TODO: add description here. + + + Packing/Installation + -------------------- + + Packing/Installation under GNU/Linux + +$ cpack +Install using System Package Manager. + + Packing/Installation under MS Windows + +$ cpack +Install using generated by NSIS executable. + + Packing/Installation under BSD-based + +$ cpack +Install using System Package Manager. + + + Testing + ------- + + Testing under GNU/Linux + +$ ctest -j$((`getconf _NPROCESSORS_ONLN`+1)) + +Automated tests for memory leaks: +$ ctest -j$((NUMBER_OF_PROCESSORS + 1)) -D NightlyMemCheck && grep definitely Testing/Temporary/LastDynamicAnalysis_*.log + + Testing under MS Windows + +$ ctest -j$((NUMBER_OF_PROCESSORS + 1)) +Automated tests for memory leaks are not available as far as Valgrind not +present on this platform. + + Testing under BSD-based + +$ ctest +Automated tests for memory leaks are not available as far as Valgrind not +present on this platform. diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..f2b408a --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,2 @@ +Kolan Sh +email: backbone@backbone.ws diff --git a/cmake/backbone b/cmake/backbone new file mode 160000 index 0000000..784ca10 --- /dev/null +++ b/cmake/backbone @@ -0,0 +1 @@ +Subproject commit 784ca10a530e629885236e9df7fdf5647ddffa7c diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt new file mode 100644 index 0000000..82ab607 --- /dev/null +++ b/config/CMakeLists.txt @@ -0,0 +1,5 @@ +SET (GSchemaFile "ws.backbone.laview.core") +INCLUDE (GSchemaCommonRules) + +CONFIGURE_FILE ("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h") diff --git a/config/Config.vapi b/config/Config.vapi new file mode 100644 index 0000000..5158417 --- /dev/null +++ b/config/Config.vapi @@ -0,0 +1,6 @@ +[CCode (cheader_filename = "config.h")] +namespace Config { + const int VERSION_MAJOR; + const int VERSION_MINOR; + const int VERSION_PATCH; +} diff --git a/config/config.h.in b/config/config.h.in new file mode 100644 index 0000000..3c66f33 --- /dev/null +++ b/config/config.h.in @@ -0,0 +1,3 @@ +#define CONFIG_VERSION_MAJOR @MAJOR@ +#define CONFIG_VERSION_MINOR @MINOR@ +#define CONFIG_VERSION_PATCH @PATCH@ diff --git a/config/ws.backbone.laview.core.gschema.xml b/config/ws.backbone.laview.core.gschema.xml new file mode 100644 index 0000000..0f03529 --- /dev/null +++ b/config/ws.backbone.laview.core.gschema.xml @@ -0,0 +1,47 @@ + + + + + [] + Templates + Loaded templates. + + + + "lyx" + Path to LyX binary (win32 only). + Microsoft doesn't follow any file hierarchy standarts. + + + + "latexmk" + Path to latexmk script (win32 only). + Microsoft doesn't follow any file hierarchy standarts. + + + + "perl" + Path to Perl (win32 only). + Microsoft doesn't follow any file hierarchy standarts. + + + + "Hello, earthlings" + A greeting + Greeting of the invading martians + + + + 99 + Bottles of beer + Number of bottles of beer on the wall + + + + false + Is the light switched on? + State of an imaginary light switch. + + + + diff --git a/cpack/CMakeLists.txt b/cpack/CMakeLists.txt new file mode 100644 index 0000000..c784d4e --- /dev/null +++ b/cpack/CMakeLists.txt @@ -0,0 +1,10 @@ +SET (CONTACT "backbone@backbone.ws") +SET (DEBIAN_DEPENDENCIES "laview-latex-struct-0 (>= 0.1.0), gobject-plugin-0 (>= 0.1.0)") +SET (DEBIAN_SECTION "Libraries") +SET (REDHAT_DEPENDENCIES "laview-latex-struct-0 >= 0.1.0, gobject-plugin-0 >= 0.1.0") +SET (REDHAT_SECTION "Applications/Text") +SET (LICENSE "LGPLv3+") +SET (WIN32_UNINSTALL_NAME "LAvCore") # <= 8 symbols for the name +SET (CPACK_NSIS_MENU_LINKS "https://redmine.backbone.ws/projects/laview-core" + "Homepage for ${PROJECT_DESCRIPTION}") +INCLUDE (CPackCommonRules) diff --git a/pkg-config/CMakeLists.txt b/pkg-config/CMakeLists.txt new file mode 100644 index 0000000..de0f431 --- /dev/null +++ b/pkg-config/CMakeLists.txt @@ -0,0 +1,17 @@ +INCLUDE (PkgConfigCommonRules) + +SET (PkgConfigLibs "-L\${libdir}") +IF (WIN32) + SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}-${MAJOR}") + SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}") + SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}-conv-${MAJOR}") +ELSE (WIN32) + SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}.so.${MAJOR}") + SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}-iface.so.${MAJOR}") + SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}-conv.so.${MAJOR}") +ENDIF (WIN32) + +CONFIGURE_FILE ( + "${CMAKE_SOURCE_DIR}/cmake/backbone/templates/pkg-config.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_LOWERCASE_NAME}-${MAJOR}.pc" +) diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 0000000..c191c1b --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1 @@ +INCLUDE (GettextCommonRules) diff --git a/po/laview-core.pot b/po/laview-core.pot new file mode 100644 index 0000000..ef8f53f --- /dev/null +++ b/po/laview-core.pot @@ -0,0 +1,114 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the laview-core package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: laview-core\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-06-23 22:28+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: config/ws.backbone.laview.core.gschema.xml.h:1 +msgid "Templates" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:2 +msgid "Loaded templates." +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:3 +msgid "Path to LyX binary (win32 only)." +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:4 +msgid "Microsoft doesn't follow any file hierarchy standarts." +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:5 +msgid "Path to latexmk.pl script (win32 only)." +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:6 +msgid "Path to Perl (win32 only)." +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:7 +msgid "\"Hello, earthlings\"" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:8 +msgid "A greeting" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:9 +msgid "Greeting of the invading martians" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:10 +msgid "Bottles of beer" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:11 +msgid "Number of bottles of beer on the wall" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:12 +msgid "Is the light switched on?" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:13 +msgid "State of an imaginary light switch." +msgstr "" + +#: src/conv/main.vala:37 src/conv/main.vala:52 src/conv/main.vala:71 +#: src/conv/main.vala:86 src/core/Core.vala:220 +msgid " not found" +msgstr "" + +#: src/conv/main.vala:37 src/conv/main.vala:52 src/conv/main.vala:71 +#: src/conv/main.vala:86 +msgid "File " +msgstr "" + +#: src/conv/main.vala:39 src/conv/main.vala:54 src/conv/main.vala:73 +#: src/conv/main.vala:88 +msgid " does not exists" +msgstr "" + +#: src/conv/main.vala:39 src/conv/main.vala:54 src/conv/main.vala:73 +#: src/conv/main.vala:88 +msgid "Target directory for " +msgstr "" + +#: src/conv/main.vala:56 +msgid "Cann't find tex2lyx command" +msgstr "" + +#: src/core/Core.vala:161 +msgid "Error running lyx2tex subprocess for " +msgstr "" + +#: src/core/Core.vala:204 src/core/Core.vala:213 src/core/Core.vala:533 +msgid "Prepare document first." +msgstr "" + +#: src/core/Core.vala:220 +msgid "PDF file " +msgstr "" + +#: src/core/Core.vala:544 +msgid "Error running tex2lyx subprocess." +msgstr "" + +#: src/core/Core.vala:546 +msgid "Cann't create lyx document for editing." +msgstr "" diff --git a/po/ru/CMakeLists.txt b/po/ru/CMakeLists.txt new file mode 100644 index 0000000..0b6020c --- /dev/null +++ b/po/ru/CMakeLists.txt @@ -0,0 +1 @@ +INCLUDE (GettextLangRules) diff --git a/po/ru/laview-core.po b/po/ru/laview-core.po new file mode 100644 index 0000000..39f7a9e --- /dev/null +++ b/po/ru/laview-core.po @@ -0,0 +1,115 @@ +# Russian translations for laview-core package. +# Copyright (C) 2015 THE laview-core'S COPYRIGHT HOLDER +# This file is distributed under the same license as the laview-core package. +# , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: laview-core\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-06-23 22:28+0300\n" +"PO-Revision-Date: 2015-08-30 12:46+0300\n" +"Last-Translator: \n" +"Language-Team: Russian\n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: config/ws.backbone.laview.core.gschema.xml.h:1 +msgid "Templates" +msgstr "Шаблоны" + +#: config/ws.backbone.laview.core.gschema.xml.h:2 +msgid "Loaded templates." +msgstr "Загруженные шаблоны." + +#: config/ws.backbone.laview.core.gschema.xml.h:3 +msgid "Path to LyX binary (win32 only)." +msgstr "Путь к исполняемому файлу LyX (только win32)." + +#: config/ws.backbone.laview.core.gschema.xml.h:4 +msgid "Microsoft doesn't follow any file hierarchy standarts." +msgstr "Микрософт не следует каким-либо стандартам файловой иерархии." + +#: config/ws.backbone.laview.core.gschema.xml.h:5 +msgid "Path to latexmk.pl script (win32 only)." +msgstr "Путь к скрипту latexmk.pl (только win32)." + +#: config/ws.backbone.laview.core.gschema.xml.h:6 +msgid "Path to Perl (win32 only)." +msgstr "Путь к исполняемому файлу Perl (только win32)." + +#: config/ws.backbone.laview.core.gschema.xml.h:7 +msgid "\"Hello, earthlings\"" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:8 +msgid "A greeting" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:9 +msgid "Greeting of the invading martians" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:10 +msgid "Bottles of beer" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:11 +msgid "Number of bottles of beer on the wall" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:12 +msgid "Is the light switched on?" +msgstr "" + +#: config/ws.backbone.laview.core.gschema.xml.h:13 +msgid "State of an imaginary light switch." +msgstr "" + +#: src/conv/main.vala:37 src/conv/main.vala:52 src/conv/main.vala:71 +#: src/conv/main.vala:86 src/core/Core.vala:220 +msgid " not found" +msgstr " не найден" + +#: src/conv/main.vala:37 src/conv/main.vala:52 src/conv/main.vala:71 +#: src/conv/main.vala:86 +msgid "File " +msgstr "Файл " + +#: src/conv/main.vala:39 src/conv/main.vala:54 src/conv/main.vala:73 +#: src/conv/main.vala:88 +msgid " does not exists" +msgstr " отсутствует" + +#: src/conv/main.vala:39 src/conv/main.vala:54 src/conv/main.vala:73 +#: src/conv/main.vala:88 +msgid "Target directory for " +msgstr "Целевая директория для " + +#: src/conv/main.vala:56 +msgid "Cann't find tex2lyx command" +msgstr "Не удаётся найти команду tex2lyx" + +#: src/core/Core.vala:161 +msgid "Error running lyx2tex subprocess for " +msgstr "Ошибка запуска подпроцесса lyx2tex для " + +#: src/core/Core.vala:204 src/core/Core.vala:213 src/core/Core.vala:533 +msgid "Prepare document first." +msgstr "Сначала подготовьте документ." + +#: src/core/Core.vala:220 +msgid "PDF file " +msgstr "PDF файл " + +#: src/core/Core.vala:544 +msgid "Error running tex2lyx subprocess." +msgstr "Ошибка запуска подпроцесса tex2lyx." + +#: src/core/Core.vala:546 +msgid "Cann't create lyx document for editing." +msgstr "Невозможно создать lyx документ для редактирования." diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..4c62d12 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,9 @@ +IF (WIN32) + SET (LibValaOpts -D WINDOWS) +ELSE (WIN32) + SET (LibValaOpts -D UNIX) +ENDIF (WIN32) + +ADD_SUBDIRECTORY (conv) +ADD_SUBDIRECTORY (core) +ADD_SUBDIRECTORY (core-iface) diff --git a/src/conv/CMakeLists.txt b/src/conv/CMakeLists.txt new file mode 100644 index 0000000..062e0c7 --- /dev/null +++ b/src/conv/CMakeLists.txt @@ -0,0 +1,9 @@ +SET (LibName ${PROJECT_LOWERCASE_NAME}-conv) +FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala) +SET (LibPackages laview-latex-struct-0 gobject-plugin-iface-0 gee-0.8 gio-2.0 posix) +SET (LibPkgModules laview-latex-struct-0 gobject-plugin-0 gee-0.8 gio-2.0) +SET (LibInstall ON) +SET (LibExtraSources ${CMAKE_CURRENT_BINARY_DIR}/library_constructor.c) +SET (LC_RELATIVE_PREFIX "..") +CONFIGURE_FILE ( "${CMAKE_SOURCE_DIR}/cmake/backbone/templates/library_constructor.c.in" "${LibExtraSources}") +INCLUDE (ValaLibCommonRules) diff --git a/src/conv/main.vala b/src/conv/main.vala new file mode 100644 index 0000000..6af19a4 --- /dev/null +++ b/src/conv/main.vala @@ -0,0 +1,112 @@ +/** + * LaTeX view. + * + * Public system of data view in the LaTeX format. + */ +namespace LAview { + + /** + * LAview conversion methods. + * + * Supported formats: TeX, LyX, PDF, etc... + */ + namespace Conv { + + /** + * File format converter (lyx, tex, pdf). + */ + public class Converter : Object { + public string lyx_path { get; construct; } + public string latexmk_pl_path { get; construct; } + public string perl_path { get; construct; } + + /** + * Constructs a new ``Converter``. + */ + public Converter () { Object(lyx_path: "lyx", latexmk_pl_path: "latexmk", perl_path: "perl"); } + public Converter.new_with_paths (string lyx_path, string latexmk_pl_path, string perl_path) { + Object(lyx_path: lyx_path, latexmk_pl_path: latexmk_pl_path, perl_path: perl_path); + } + + /** + * LyX->TeX conversion. + */ + public Subprocess lyx2tex (string lyx_file, string tex_path) throws Error { + /* check paths */ + if (!File.new_for_path(lyx_file).query_exists()) + throw new IOError.NOT_FOUND(_("File ")+lyx_file+_(" not found")); + if (!File.new_for_path(tex_path).get_parent().query_exists()) + throw new IOError.NOT_FOUND(_("Target directory for ")+tex_path+_(" does not exists")); + return (new SubprocessLauncher( SubprocessFlags.STDIN_PIPE + | SubprocessFlags.STDOUT_PIPE + | SubprocessFlags.STDERR_PIPE)) + .spawnv({ lyx_path, "-batch", "--force-overwrite", "all", + "--export-to", "latex", tex_path, lyx_file }); + } + + /** + * TeX->LyX conversion. + */ + public Subprocess tex2lyx (string tex_file, string lyx_file_path) throws Error { + /* check paths */ + if (!File.new_for_path(tex_file).query_exists()) + throw new IOError.NOT_FOUND(_("File ")+tex_file+_(" not found")); + if (!File.new_for_path(lyx_file_path).get_parent().query_exists()) + throw new IOError.NOT_FOUND(_("Target directory for ")+lyx_file_path+_(" does not exists")); + var last_index_of = lyx_path.last_index_of ("lyx"); + if (last_index_of == -1) throw new IOError.NOT_FOUND(_("Cann't find tex2lyx command")); + var tex2lyx_path = lyx_path.substring(0, last_index_of) + + "tex2" + lyx_path.offset(last_index_of); + return (new SubprocessLauncher( SubprocessFlags.STDIN_PIPE + | SubprocessFlags.STDOUT_PIPE + | SubprocessFlags.STDERR_PIPE)) + .spawnv({ tex2lyx_path, "-f", /*"-copyfiles",*/ tex_file, lyx_file_path }); + } + + /** + * LyX->PDF conversion. + */ + public Subprocess lyx2pdf (string lyx_file, string pdf_path) throws Error { + /* check paths */ + if (!File.new_for_path(lyx_file).query_exists()) + throw new IOError.NOT_FOUND(_("File ")+lyx_file+_(" not found")); + if (!File.new_for_path(pdf_path).get_parent().query_exists()) + throw new IOError.NOT_FOUND(_("Target directory for ")+pdf_path+_(" does not exists")); + return (new SubprocessLauncher( SubprocessFlags.STDIN_PIPE + | SubprocessFlags.STDOUT_PIPE + | SubprocessFlags.STDERR_PIPE)) + .spawnv({ lyx_path, "-batch", "--force-overwrite", "all", + "--export-to", "pdf", pdf_path, lyx_file }); + } + + /** + * TeX->PDF conversion. + */ + public Subprocess tex2pdf (string tex_file, string pdf_path) throws Error { + /* check paths */ + if (!File.new_for_path(tex_file).query_exists()) + throw new IOError.NOT_FOUND(_("File ")+tex_file+_(" not found")); + if (!File.new_for_path(pdf_path).get_parent().query_exists()) + throw new IOError.NOT_FOUND(_("Target directory for ")+pdf_path+_(" does not exists")); + + var pdf_dir = File.new_for_path(pdf_path).get_parent().get_path(); + var pdf_name = File.new_for_path(pdf_path).get_basename(); + pdf_name = /.pdf$/i.replace(pdf_name, -1, 0, ""); + + var sl = new SubprocessLauncher( SubprocessFlags.STDIN_PIPE + | SubprocessFlags.STDOUT_PIPE + | SubprocessFlags.STDERR_PIPE); + sl.set_cwd(File.new_for_path(tex_file).get_parent().get_path()); + #if (UNIX) + return sl.spawnv({ "latexmk", "-output-directory="+pdf_dir, + "-jobname="+pdf_name, "-pdf", tex_file }); + #elif (WINDOWS) + return sl.spawnv({ perl_path, latexmk_pl_path, "-output-directory="+pdf_dir, + "-jobname="+pdf_name, "-pdf", tex_file }); + #else + assert_not_reached (); + #endif + } + } + } +} diff --git a/src/core-iface/CMakeLists.txt b/src/core-iface/CMakeLists.txt new file mode 100644 index 0000000..a146187 --- /dev/null +++ b/src/core-iface/CMakeLists.txt @@ -0,0 +1,8 @@ +SET (LibName ${PROJECT_LOWERCASE_NAME}-iface) +FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CoreInterface.vala) +SET (LibPackages gee-0.8 gmodule-2.0 gio-2.0 gobject-plugin-iface-0) +SET (LibInstall ON) +SET (LibExtraSources ${CMAKE_CURRENT_BINARY_DIR}/library_constructor.c) +SET (LC_RELATIVE_PREFIX "..") +CONFIGURE_FILE ( "${CMAKE_SOURCE_DIR}/cmake/backbone/templates/library_constructor.c.in" "${LibExtraSources}") +INCLUDE (ValaLibCommonRules) diff --git a/src/core-iface/CoreInterface.vala b/src/core-iface/CoreInterface.vala new file mode 100644 index 0000000..56cdb76 --- /dev/null +++ b/src/core-iface/CoreInterface.vala @@ -0,0 +1,99 @@ +using GObject.Plugins; + +/** + * LaTeX view. + * + * Public system of data view in the LaTeX format. + */ +namespace LAview.Core { + + /** + * Core Host Interface. + */ + public interface IHostCore : IHost { + + /** + * Get cache directory path. + */ + public abstract string get_cache_dir (); + + /** + * Get data object. + */ + public abstract PluginData get_data_object (string name); + } + + /** + * Abstract plugin of type Data. + */ + public abstract class PluginData: Plugin { + + /** + * Get Plugin name. + */ + public abstract string get_name (); + + /** + * Get Plugin readable name. + */ + public abstract string get_readable_name (); + } + + /** + * Abstract plugin of type Protocol. + */ + public abstract class PluginObject : Plugin { + + /** + * Get Plugin name. + */ + public abstract string get_name (); + + /** + * Get Plugin readable name. + */ + public abstract string get_readable_name (); + + /** + * Compose the object. + */ + public abstract bool compose (Object parent, Gee.HashMap answers) throws Error; + } + + /** + * Request Answer Value. + */ + public abstract class AnswerValue : Object { + } + + /** + * String. + */ + public class AnswerString : AnswerValue { + public string value; + + public AnswerString (string value = "") { + this.value = value; + } + } + + /** + * 1D Array. + */ + public class AnswerArray1D : AnswerValue { + public string[] value; + } + + /** + * 2D Array; + */ + public class AnswerArray2D : AnswerValue { + public string[,] value; + } + + /** + * Picture Buffer (Currently path (String) is enough). + */ + /*public class AnswerPicBuffer : AnswerValue { + }*/ +} diff --git a/src/core/AppDirs.vala b/src/core/AppDirs.vala new file mode 100644 index 0000000..3eb8a95 --- /dev/null +++ b/src/core/AppDirs.vala @@ -0,0 +1,41 @@ +extern void get_library_path (string so_path, void *addr); + +namespace LAview.Core { + + class AppDirs { + + public static File so_path; + public static File exec_dir; + public static File common_dir; + public static string data_plugins_dir; + public static string object_plugins_dir; + public static string ui_dir; + public static string settings_dir; + public static string temp_dir; + public static string cache_dir; + + public static void init () throws FileError { + char _so_path[256]; + get_library_path ((string)_so_path, (void*)init); + so_path = File.new_for_path ((string)_so_path); + exec_dir = so_path.get_parent (); + common_dir = exec_dir.get_parent (); + ui_dir = Path.build_path (Path.DIR_SEPARATOR_S, common_dir.get_path(), + "share/laview-core-"+Config.VERSION_MAJOR.to_string()+"/ui"); + settings_dir = Path.build_path (Path.DIR_SEPARATOR_S, common_dir.get_path(), "share/glib-2.0/schemas"); + string w32dhack_sdir = settings_dir+"/laview-core-"+Config.VERSION_MAJOR.to_string(); + if (File.new_for_path(w32dhack_sdir+"/gschemas.compiled").query_exists ()) + settings_dir = w32dhack_sdir; + data_plugins_dir = Path.build_path (Path.DIR_SEPARATOR_S, exec_dir.get_path(), + "laview-core-"+Config.VERSION_MAJOR.to_string()+"/data-plugins"); + object_plugins_dir = Path.build_path (Path.DIR_SEPARATOR_S, exec_dir.get_path(), + "laview-core-"+Config.VERSION_MAJOR.to_string()+"/object-plugins"); + temp_dir = DirUtils.make_tmp ("laview-core-XXXXXX.temp"); + cache_dir = Path.build_path (Path.DIR_SEPARATOR_S, AppDirs.temp_dir, "cache"); + } + + public static void terminate () throws Error { + rm_rf (File.new_for_path(temp_dir)); + } + } +} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt new file mode 100644 index 0000000..18e83cd --- /dev/null +++ b/src/core/CMakeLists.txt @@ -0,0 +1,17 @@ +SET (LibName ${PROJECT_LOWERCASE_NAME}) +FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala) +SET (LibPackages laview-latex-struct-0 gobject-plugin-iface-0 gobject-plugin-loader-0 gee-0.8 gio-2.0 gmodule-2.0 posix) +SET (LibCustomVapis + ${CMAKE_BINARY_DIR}/src/core-iface/${PROJECT_LOWERCASE_NAME}-iface-${MAJOR}.vapi + ${CMAKE_BINARY_DIR}/src/conv/${PROJECT_LOWERCASE_NAME}-conv-${MAJOR}.vapi + ${CMAKE_SOURCE_DIR}/config/Config.vapi) +INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/config") +SET (LibLinkLibs ${PROJECT_LOWERCASE_NAME}-iface ${PROJECT_LOWERCASE_NAME}-conv) +INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/core-iface") +INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/conv") +SET (LibPkgModules laview-latex-struct-0 gobject-plugin-0 gee-0.8 gio-2.0 gmodule-2.0) +SET (LibInstall ON) +SET (LibExtraSources ${CMAKE_CURRENT_BINARY_DIR}/library_constructor.c) +SET (LC_RELATIVE_PREFIX "..") +CONFIGURE_FILE ( "${CMAKE_SOURCE_DIR}/cmake/backbone/templates/library_constructor.c.in" "${LibExtraSources}") +INCLUDE (ValaLibCommonRules) diff --git a/src/core/Core.vala b/src/core/Core.vala new file mode 100644 index 0000000..ee9d167 --- /dev/null +++ b/src/core/Core.vala @@ -0,0 +1,791 @@ +using GObject, Plugins; + +namespace LAview.Core { + + /** + * LAview Core. + */ + public class Core : Object, IHost, IHostCore { + + /** ** + * --- I N T E R F A C E --- * + */ /**/ + + public string lyx_path { + get { return _lyx_path; } + set { + if (settings != null) settings.set_string ("lyx-path", value); + _lyx_path = value; + } + default = "lyx"; + } + + public string latexmk_pl_path { + get { return _latexmk_pl_path; } + set { + if (settings != null) settings.set_string ("latexmk-pl-path", value); + _latexmk_pl_path = value; + } + default = "latexmk"; + } + + public string perl_path { + get { return _perl_path; } + set { + if (settings != null) settings.set_string ("perl-path", value); + _perl_path = value; + } + default = "perl"; + } + + public Gee.HashMap data_plugins = new Gee.HashMap(); + public Gee.HashMap object_plugins = new Gee.HashMap(); + + /** + * Load Data Modules. + */ + public void load_data_modules (string dir_path) { + Gee.ArrayList tmp_modules = null; + GObject.Plugins.load_modules (dir_path, ref tmp_modules); + foreach (var m in tmp_modules) { + if (!data_modules.contains(m)) { + data_modules.add(m); + var plugin_data = m.create_instance (this) as PluginData; + data_plugins[m.get_type()] = plugin_data; + data_plugins2[plugin_data.get_name()] = plugin_data; + } + } + } + + /** + * Load Protocol Objects Modules. + */ + public void load_object_modules (string dir_path) { + Gee.ArrayList tmp_modules = null; + GObject.Plugins.load_modules (dir_path, ref tmp_modules); + foreach (var m in tmp_modules) { + if (!object_modules.contains(m)) { + object_modules.add(m); + var plugin_object = m.create_instance (this) as PluginObject; + object_plugins[m.get_type()] = plugin_object; + object_plugins2[plugin_object.get_name()] = plugin_object; + } + } + } + + /** + * Unload all Modules. + */ + public void unload_modules () { + GObject.Plugins.unload_modules (data_modules); + GObject.Plugins.unload_modules (object_modules); + } + + public Core () throws Error { + + /* Initialization */ + AppDirs.init (); + load_data_modules (AppDirs.data_plugins_dir); + load_object_modules (AppDirs.object_plugins_dir); + settings_init (); + load_templates_list (); + _lyx_path = settings.get_string("lyx-path"); + settings.changed["lyx-path"].connect (() => { + _lyx_path = settings.get_string("lyx-path"); + }); + _latexmk_pl_path = settings.get_string("latexmk-pl-path"); + settings.changed["latexmk-pl-path"].connect (() => { + _latexmk_pl_path = settings.get_string("latexmk-pl-path"); + }); + _perl_path = settings.get_string("perl-path"); + settings.changed["perl-path"].connect (() => { + _perl_path = settings.get_string("perl-path"); + }); + clear_cache (); + } + + public string get_cache_dir () { + return AppDirs.cache_dir; + } + + public string[] get_templates_readable_names () { + string[] names = {}; + foreach (var t in templates) + names += t.get_readable_name (); + return names; + } + + public string get_template_path_by_index (int index) { + return templates[index].get_path (); + } + + public void add_template (string path) { + var file = File.new_for_path (path); + if (!file.query_exists() || file.query_file_type(FileQueryInfoFlags.NONE) != FileType.REGULAR) + return; + if (path.has_suffix ("lyx")) { + var t = new LyxTemplate(path); + if (!templates.contains (t)) + templates.add (t); + } else if (path.has_suffix ("tex")) { + var t = new TexTemplate(path); + if (!templates.contains (t)) + templates.add (t); + } + save_templates_list (); + } + + public void remove_template (int index) { + if (index < templates.size) + templates.remove_at (index); + save_templates_list (); + } + + public string[] get_objects_list (int template_index) throws Error { + if (template_index == last_template_index) return objects_list; + last_template_index = template_index; + + /* clear */ + clear_cache (); + requests = new Gee.HashMap> (); + objects_list = { }; + composed_objects = { }; + + var converter = new Conv.Converter.new_with_paths (_lyx_path, _latexmk_pl_path, _perl_path); + var t_path = Path.build_path (Path.DIR_SEPARATOR_S, AppDirs.cache_dir, "template.tex"); + var lyx_file_path = templates[template_index].get_path(); + try { + var sp = converter.lyx2tex (lyx_file_path, t_path); + #if (UNIX) + if (sp.wait_check() == false) throw new IOError.FAILED(""); + #elif (WINDOWS) + sp.wait(); + if (!File.new_for_path(t_path).query_exists()) throw new IOError.FAILED(""); + #else + assert_not_reached (); + #endif + } catch (Error e) { + throw new IOError.FAILED(_("Error running lyx2tex subprocess for ")+lyx_file_path+"."); + } + + /* parse TeX */ + string contents; + FileUtils.get_contents (t_path, out contents); + document = LAview.parse (contents); + + var doc_stack = new Queue (); + doc_stack.push_tail (document); + recursive_walk (doc_stack, requests, Stage.ANALYSE); + + // Return readable objects names by requests and objects plugins readable names + foreach (var req in requests.entries) { + string object_suffix, object_cmd; + var plugin = find_plugin (req.key, out object_suffix, out object_cmd); + if (plugin != null) { + objects_list += plugin.get_readable_name() + " " + object_suffix; + composed_objects += false; + } + } + + return objects_list; + } + + public bool compose_object (Object parent, int object_index) throws Error { + var cnt = object_index; + foreach (var req in requests.entries) + if (cnt-- == 0) { + string object_suffix, object_cmd; + var plugin = find_plugin (req.key, out object_suffix, out object_cmd); + var result = object_plugins2[plugin.get_name()].compose(parent, req.value); + if (composed_objects[object_index] == false && result == true) { + composed_objects[object_index] = true; + objects_list[object_index] = "✔ " + objects_list[object_index]; + } + } + return composed_objects[object_index];; + } + + public Subprocess print_document () throws Error { + foreach (var c in composed_objects) + if (c == false) + throw new IOError.FAILED (_("Prepare document first.")); + generate_document_tex (); + var converter = new Conv.Converter.new_with_paths (_lyx_path, _latexmk_pl_path, _perl_path); + return converter.tex2pdf (doc_tex_path(), doc_pdf_path()); + } + + public string get_lyx_file_path () throws Error { + foreach (var c in composed_objects) + if (c == false) + throw new IOError.FAILED (_("Prepare document first.")); + return generate_document_lyx(); + } + + public string get_pdf_file_path () throws Error { + var pdf_path = Path.build_path (Path.DIR_SEPARATOR_S, AppDirs.cache_dir, "document.pdf"); + if (!File.new_for_path(pdf_path).query_exists()) + throw new IOError.FAILED(_("PDF file ")+@"$pdf_path"+_(" not found")); + return pdf_path; + } + + public PluginData get_data_object (string name) { + return data_plugins2[name]; + } + + /** ** + * --- I M P L E M E N T A T I O N --- * + */ /**/ + + string _lyx_path; + string _latexmk_pl_path; + string _perl_path; + Gee.HashMap data_plugins2 = new Gee.HashMap(); + Gee.HashMap object_plugins2 = new Gee.HashMap(); + Settings settings; + TemplateList templates = new TemplateList (); + static Gee.ArrayList data_modules = new Gee.ArrayList(); + static Gee.ArrayList object_modules = new Gee.ArrayList(); + Gee.HashMap> requests; + Glob document = null; + Glob out_document = null; + string[] objects_list = { }; + bool[] composed_objects = {}; + int last_template_index = -1; + + void settings_init () throws Error { + string schema_file = AppDirs.settings_dir+"/gschemas.compiled"; + if (!File.new_for_path (schema_file).query_exists ()) + throw new IOError.NOT_FOUND ("File "+schema_file+" not found"); + SettingsSchemaSource sss = new SettingsSchemaSource.from_directory (AppDirs.settings_dir, null, false); + string schema_name = "ws.backbone.laview.core-"+Config.VERSION_MAJOR.to_string(); + SettingsSchema schema = sss.lookup (schema_name, false); + if (schema == null) { + throw new IOError.NOT_FOUND ("Schema "+schema_name+" not found in "+schema_file); + } + settings = new Settings.full (schema, null, null); + } + + void load_templates_list () { + var templates_strv = settings.get_strv("templates"); + templates.clear (); + foreach (var ts in templates_strv) + add_template (ts); + } + + void save_templates_list () { + string[] templates_strv = {}; + foreach (var t in templates) { + templates_strv += (t.get_path ()); + } + settings.set_strv("templates", templates_strv); + } + + ~Core () { + AppDirs.terminate (); + } + + PluginObject? find_plugin (string request, out string object_suffix, out string object_cmd) { + object_suffix = null; + object_cmd = null; + var first_ = request.split_set(":?.", 2)[0]; + foreach (var p in object_plugins.entries) { + if (first_.has_prefix (p.value.get_name())) { + object_suffix = first_.substring (p.value.get_name().length); + object_cmd = request.offset (first_.length + 1); + return p.value; + } + } + return null; + } + + bool in_table (Queue doc_stack) { + var len = doc_stack.length; + return (len >= 6 + && doc_stack.peek_nth(len - 6) is Table.ATable + && doc_stack.peek_nth(len - 5) is Table.Subtable + && doc_stack.peek_nth(len - 4) is Table.Row + && doc_stack.peek_nth(len - 3) is Table.Cell + && doc_stack.peek_nth(len - 2) is Glob + ) ? true : false; + } + + bool check_for_addrows (Table.Cell cell, bool remove = false) { + var ret = false; + foreach (var doc in cell.contents) + if (doc is Text) { + var t = doc as Text; + if (/#\baddrows\b/.match(t.text)) { + if (remove) { + t.text = t.text.replace("#addrows", ""); + } + ret = true; + } + } + return ret; + } + + bool check_for_addcols (Table.Cell cell, out int max_cols, bool remove = false) { + max_cols = 0; + var ret = false; + foreach (var doc in cell.contents) + if (doc is Text) { + var t = doc as Text; + if (/\\#\baddcols\b/.match(t.text)) { + try { + var regex = new Regex ("\\\\#addcols\\\\#[0-9]+"); + MatchInfo match_info; + regex.match (t.text, 0, out match_info); + while (match_info.matches ()) { + var word = match_info.fetch (0).substring(11); + max_cols = int.max(max_cols, int.parse(word)); + match_info.next(); + } + if (remove) + t.text = regex.replace_literal (t.text, -1, 0, ""); + } catch (RegexError e) {} + ret = true; + } + } + return ret; + } + + // current row contains #addrows => ++dimension + bool row_has_addrows (Table.Row row) { + foreach (var cell in row) + if (check_for_addrows(cell)) + return true; + return false; + } + + bool row_has_addcols (Table.Row row, uint col_index) { + uint index = 0; + foreach (var cell in row) { + if (index >= col_index) + if (check_for_addcols(cell, null)) + return true; + else + return false; + else + index += cell.multitype == Table.Cell.Multitype.MULTICOL ? cell.ncells : 1; + } + return false; + } + + bool subtable_has_addcols (Table.Subtable subtable, uint col_index) { + foreach (var row in subtable) + if (row_has_addcols (row, col_index)) return true; + return false; + } + + // one of 5 subtables contains #addcols in current column => ++dimension + bool atable_has_addcols (Table.ATable table, Table.Row row, Table.Cell cell) { + uint col_index = 0; + foreach (var c in row) { + if (cell == c) break; + col_index += c.multitype == Table.Cell.Multitype.MULTICOL ? c.ncells : 1; + } + switch (table.get_type().name()) { + case "LAviewTableTabular": + if (subtable_has_addcols ((table as Table.Tabular).table, col_index)) return true; + break; + case "LAviewTableLongtable": + var longtable = table as Table.Longtable; + if (subtable_has_addcols (longtable.first_header, col_index)) return true; + if (subtable_has_addcols (longtable.header, col_index)) return true; + if (subtable_has_addcols (longtable.table, col_index)) return true; + if (subtable_has_addcols (longtable.footer, col_index)) return true; + if (subtable_has_addcols (longtable.last_footer, col_index)) return true; + break; + } + return false; + } + + enum Stage { + ANALYSE, + FILL + } + + void resize_table (Table.ATable table, ResizeInfo resize_info) { + Table.Subtable tables[] = { table.first_header, table.header, table.table, + table.footer, table.last_footer }; + var ncols = table.params.size; + int nrows = 0; + foreach (var subtable in tables) + if (nrows < subtable.size) + nrows = subtable.size; + + + var rowsvv_b = new bool[5,nrows]; // has #addrows + var colsv_b = new bool[ncols]; // has #addcols + resize_info.colsv_max = new int[ncols]; // cols per subtable when splitting + + for (var t = 0; t < 5; ++t) { + for (var i = 0; i < tables[t].size; ++i) { + for (uint j = 0, col_cnt = 0; j < tables[t][i].size; ++j) { + var cell = tables[t][i][(int)j]; + + if (check_for_addrows(cell)) { + rowsvv_b[t,i] = true; + check_for_addrows(cell, true); + } + + int max_cols; + if (check_for_addcols(cell, out max_cols)) { + colsv_b[col_cnt] = true; + resize_info.colsv_max[col_cnt] = max_cols; + check_for_addcols(cell, null, true); + } + + col_cnt += ( cell.multitype == Table.Cell.Multitype.MULTICOL + || cell.multitype == Table.Cell.Multitype.MULTICOLROW) ? + cell.ncells : 1; + } + } + } + + resize_info.colsv = new int[ncols]; // X grow size + resize_info.rowsvv = new int[5,nrows]; // Y grow size + + for (var t = 0; t < 5; ++t) { + for (var i = 0; i < tables[t].size; ++i) { + for (var j = 0; j < tables[t][i].size; ++j) { + var cell = tables[t][i][j]; + + foreach (var subdoc in cell.contents) { + try { + var regex = new Regex ("{\\[}[^][}{]*{\\]}"); + MatchInfo match_info; + regex.match ((subdoc as Text).text, 0, out match_info); + while (match_info.matches ()) { + string object_suffix, object_cmd; + var word = match_info.fetch (0); + var request = word.substring (3, word.length - 6); + var plugin = find_plugin (request, out object_suffix, out object_cmd); + if (plugin == null) { match_info.next(); continue; } + var req = requests[plugin.get_name() + object_suffix][object_cmd]; + if (req is AnswerArray1D) { + if (rowsvv_b[t,i] && ! colsv_b[j]) + resize_info.rowsvv[t,i] = int.max(resize_info.rowsvv[t,i], (req as AnswerArray1D).value.length); + else if (colsv_b[j] && !rowsvv_b[t,i]) + resize_info.colsv[j] = int.max(resize_info.colsv[j], (req as AnswerArray1D).value.length); + } else if (req is AnswerArray2D) { + if (colsv_b[j] && rowsvv_b[t,i]) { + resize_info.rowsvv[t,i] = int.max(resize_info.rowsvv[t,i], (req as AnswerArray2D).value.length[0]); + resize_info.colsv[j] = int.max(resize_info.colsv[j], (req as AnswerArray2D).value.length[1]); + } + } + match_info.next(); + } + } catch (RegexError e) {} + } + } + } + } + + // add cols + for (int i = ncols - 1; i >= 0; --i) + if (colsv_b[i]) + for (var j = 1; j < resize_info.colsv[i]; ++j) + table.clone_col (i, i, true); + + // add rows + for (var t = 0; t < 5; ++t) + for (int r = tables[t].size; r >=0; --r) + if (rowsvv_b[t, r]) + for (var j = 1; j < resize_info.rowsvv[t, r]; ++j) + tables[t].insert(r, tables[t][r].copy() as Table.Row); + } + + uint split_table (Glob glob, Table.ATable table, ResizeInfo resize_info) { + try { + var limits = new List (); + if (resize_info.colsv.length != resize_info.colsv_max.length) return 1; + uint f = 0, l = 0; + for (var i = 0; i < resize_info.colsv.length; ++i) { + var colsv_i = resize_info.colsv[i] == 0 ? 1 : resize_info.colsv[i]; + l = f + colsv_i - 1; + if (f != l) + limits.append(Table.ATable.SplitLimit() + { first = f, last = l, max_cols = resize_info.colsv_max[i] }); + f += colsv_i; + l = f; + } + if (limits.length() != 0) { + var delimiter = (table is Table.Tabular) ? "\\\\" : ""; + return table.split(glob, limits, delimiter); + } + } catch (Error e) { + } + return 1; + } + + class ResizeInfo { + public int[] colsv; + public int[] colsv_max; + public int[,] rowsvv; + } + + // TODO #102: get subtable, row, col indexes by doc_stack + resize_info + void get_relative_indexes (Queue doc_stack, ResizeInfo resize_info, out int row_idx, out int col_idx) { + row_idx = col_idx = 0; + var subtable_idx = 0, ridx = 0, cidx = 0; + + var len = doc_stack.get_length(); + var c = doc_stack.peek_nth(len - 3); + var r = doc_stack.peek_nth(len - 4); + var s = doc_stack.peek_nth(len - 5); + var tab = doc_stack.peek_nth(len - 6); + + if (!(c is Table.Cell && r is Table.Row && s is Table.Subtable)) return; + + var row = r as Table.Row; + cidx = row.index_of(c as Table.Cell); + var subtable = s as Table.Subtable; + ridx = subtable.index_of(row); + + var atable = tab as Table.ATable; + if (subtable == atable.first_header) + subtable_idx = 0; + else if (subtable == atable.header) + subtable_idx = 1; + else if (subtable == atable.table) + subtable_idx = 2; + else if (subtable == atable.footer) + subtable_idx = 3; + else if (subtable == atable.last_footer) + subtable_idx = 4; + + for (int i = 0, sum = 0; i < resize_info.rowsvv.length[1]; ++i) { + var rowsvv_i = resize_info.rowsvv[subtable_idx,i]; + if (rowsvv_i == 0) rowsvv_i = 1; + if (ridx >= sum && ridx < sum + rowsvv_i) { + row_idx = ridx - sum; + break; + } else { + sum += rowsvv_i; + } + } + for (int i = 0, sum = 0; i < resize_info.colsv.length; ++i) { + var colsv_i = resize_info.colsv[i]; + if (colsv_i == 0) colsv_i = 1; + if (cidx >= sum && cidx < sum + colsv_i) { + col_idx = cidx - sum; + break; + } else { + sum += colsv_i; + } + } + } + + uint recursive_walk (Queue doc_stack, + // Plugin name // Object suffix + Gee.HashMap> requests, + Stage stage, ResizeInfo? resize_info = null) { + uint ret = 1; + var doc = doc_stack.peek_tail (); + var stack_len = doc_stack.get_length(); + switch (doc.get_type().name()) { + case "LAviewTableTabular": + var tabular = doc as Table.Tabular; + var resize_info_new = new ResizeInfo(); + if (stage == Stage.FILL) resize_table (tabular, resize_info_new); + doc_stack.push_tail ((doc as Table.Tabular).table); + recursive_walk (doc_stack, requests, stage, resize_info_new); + doc_stack.pop_tail (); + if (stage == Stage.FILL && stack_len > 1) + ret = split_table (doc_stack.peek_nth (stack_len - 2) as Glob, tabular, resize_info_new); + break; + case "LAviewTableLongtable": + var longtable = doc as Table.Longtable; + var resize_info_new = new ResizeInfo(); + if (stage == Stage.FILL) resize_table (longtable, resize_info_new); + doc_stack.push_tail (longtable.first_header); + recursive_walk (doc_stack, requests, stage, resize_info_new); + doc_stack.pop_tail (); + doc_stack.push_tail (longtable.header); + recursive_walk (doc_stack, requests, stage, resize_info_new); + doc_stack.pop_tail (); + doc_stack.push_tail (longtable.table); + recursive_walk (doc_stack, requests, stage, resize_info_new); + doc_stack.pop_tail (); + doc_stack.push_tail (longtable.footer); + recursive_walk (doc_stack, requests, stage, resize_info_new); + doc_stack.pop_tail (); + doc_stack.push_tail (longtable.last_footer); + recursive_walk (doc_stack, requests, stage, resize_info_new); + doc_stack.pop_tail (); + if (stage == Stage.FILL && stack_len > 1) + ret = split_table (doc_stack.peek_nth (stack_len - 2) as Glob, longtable, resize_info_new); + break; + case "LAviewTableSubtable": + doc_stack.push_tail ((doc as Table.Subtable).caption); + recursive_walk (doc_stack, requests, stage, resize_info); + doc_stack.pop_tail (); + foreach (var subdoc in doc as Table.Subtable) { + doc_stack.push_tail (subdoc); + recursive_walk (doc_stack, requests, stage, resize_info); + doc_stack.pop_tail (); + } + break; + case "LAviewTableCell": + doc_stack.push_tail ((doc as Table.Cell).contents); + recursive_walk (doc_stack, requests, stage, resize_info); + doc_stack.pop_tail (); + break; + case "LAviewGraphics": + var path = (doc as Graphics).path; + string object_suffix, object_cmd; + var plugin = find_plugin (path, out object_suffix, out object_cmd); + if (plugin == null) break; + switch (stage) { + case Stage.ANALYSE: + if (!requests.has_key(plugin.get_name() + object_suffix)) + requests[plugin.get_name() + object_suffix] = new Gee.HashMap(); + requests[plugin.get_name() + object_suffix][object_cmd] = new AnswerString(); + break; + case Stage.FILL: + (doc as Graphics).path = + (requests[plugin.get_name() + object_suffix][object_cmd] as AnswerString).value; + break; + } + break; + + case "LAviewText": + try { + /* Replace requests with answers */ + var regex = new Regex ("{\\[}[^][}{]*{\\]}"); + MatchInfo match_info; + regex.match ((doc as Text).text, 0, out match_info); + var out_text = (doc as Text).text; + + while (match_info.matches ()) { + var word = match_info.fetch (0); + var request = word.substring (3, word.length - 6); + + // Find plugin which name conforms to request + string object_suffix, object_cmd; + var plugin = find_plugin (request, out object_suffix, out object_cmd); + if (plugin == null) { match_info.next(); continue; } + + switch (stage) { + case Stage.ANALYSE: + AnswerValue answer; + + var dimension = 0; + if (in_table(doc_stack)) { + // Determine answer type (text, vector, matrix). + dimension += row_has_addrows (doc_stack.peek_nth(doc_stack.length - 4) as Table.Row) ? 1 : 0; + var len = doc_stack.length; + var table = doc_stack.peek_nth(len - 6) as Table.ATable; + var row = doc_stack.peek_nth(len - 4) as Table.Row; + var cell = doc_stack.peek_nth(len - 3) as Table.Cell; + dimension += atable_has_addcols (table, row, cell) ? 1 : 0; + } + switch (dimension) { + case 1: answer = new AnswerArray1D(); break; + case 2: answer = new AnswerArray2D(); break; + default: answer = new AnswerString(); break; + } + if (!requests.has_key(plugin.get_name() + object_suffix)) + requests[plugin.get_name() + object_suffix] = new Gee.HashMap(); + requests[plugin.get_name() + object_suffix][object_cmd] = answer; + break; + case Stage.FILL: + var answer = requests[plugin.get_name() + object_suffix].get(object_cmd); + var dimension = 0; + if (answer is AnswerArray1D) dimension = 1; + if (answer is AnswerArray2D) dimension = 2; + + switch (dimension) { + case 1: // Array 1D + var arr = answer as AnswerArray1D; + var row_idx = 0, col_idx = 0; + get_relative_indexes(doc_stack, resize_info, out row_idx, out col_idx); + var max_idx = int.max(row_idx, col_idx); + if (max_idx < arr.value.length) + out_text = arr.value[max_idx]; + else + out_text = _("IdxError"); + break; + case 2: // Array 2D + var arr = answer as AnswerArray2D; + var row_idx = 0, col_idx = 0; + get_relative_indexes(doc_stack, resize_info, out row_idx, out col_idx); + if (row_idx < arr.value.length[0] && col_idx < arr.value.length[1]) + out_text = arr.value[row_idx, col_idx]; + else + out_text = _("IdxError"); + break; + default: // Text/String + out_text = out_text.replace("{[}"+request+"{]}", (answer as AnswerString).value); + break; + } + break; + } + + match_info.next(); + } + + /* Replace ViewName */ + regex = new Regex ("@LAview\\.ViewName=[^@]+@"); + regex.match (out_text, 0, out match_info); + if (match_info.matches ()) { + var word = match_info.fetch (0); + out_text = out_text.replace(word, ""); + } + + (doc as Text).text = out_text ; + } catch (RegexError e) {} + break; + default: + if (doc is ADocList) { + var d = doc as ADocList; + for (var i = 0; i < d.size; ) { + var subdoc = d[i]; + doc_stack.push_tail (subdoc); + i += (int)recursive_walk (doc_stack, requests, stage, resize_info); + doc_stack.pop_tail (); + } + } + break; + } + return 1; + } + + string doc_tex_path () { + return Path.build_path (Path.DIR_SEPARATOR_S, AppDirs.cache_dir, "document.tex"); + } + string doc_lyx_path () { + return Path.build_path (Path.DIR_SEPARATOR_S, AppDirs.cache_dir, "document.lyx"); + } + string doc_pdf_path () { + return Path.build_path (Path.DIR_SEPARATOR_S, AppDirs.cache_dir, "document.pdf"); + } + void generate_document_tex () throws Error { + if (document == null) + throw new IOError.FAILED (_("Prepare document first.")); + var doc_stack = new Queue (); + out_document = document.copy () as Glob; + doc_stack.push_tail (out_document); + recursive_walk (doc_stack, requests, Stage.FILL); + FileUtils.set_contents (doc_tex_path (), out_document.generate ()); + } + string generate_document_lyx () throws Error { + generate_document_tex (); + var converter = new Conv.Converter.new_with_paths (_lyx_path, _latexmk_pl_path, _perl_path); + var sp = converter.tex2lyx (doc_tex_path(), doc_lyx_path()); + if (sp.wait_check() == false) throw new IOError.FAILED(_("Error running tex2lyx subprocess.")); + if (!File.new_for_path(doc_lyx_path()).query_exists()) + throw new IOError.FAILED(_("Cann't create lyx document for editing.")); + return doc_lyx_path(); + } + + void clear_cache () throws Error { + try { + rm_rf (File.new_for_path (AppDirs.cache_dir)); + } catch (Error e) { + } + File.new_for_path (AppDirs.cache_dir).make_directory(); + } + } +} diff --git a/src/core/FileUtils.vala b/src/core/FileUtils.vala new file mode 100644 index 0000000..1226650 --- /dev/null +++ b/src/core/FileUtils.vala @@ -0,0 +1,16 @@ +namespace LAview.Core { + void rm_rf (File directory) throws Error { + var children = directory.enumerate_children ("standard::*", + FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null); + FileInfo fileinfo = null; + while ((fileinfo = children.next_file (null)) != null ) { + File child = directory.resolve_relative_path (fileinfo.get_name ()); + if (fileinfo.get_file_type () == FileType.DIRECTORY) { + rm_rf (child); + } else { + child.delete(); + } + } + directory.delete(); + } +} diff --git a/src/core/Templates.vala b/src/core/Templates.vala new file mode 100644 index 0000000..ab7eda4 --- /dev/null +++ b/src/core/Templates.vala @@ -0,0 +1,92 @@ +using GObject, Plugins; + +namespace LAview.Core { + + /** + * Template Interface. + */ + public abstract interface ITemplate : Object { + public abstract string get_readable_name (); + public abstract string get_path (); + public abstract bool is_equal_to (ITemplate template); + } + + /** + * LyX File Template. + */ + public class LyxTemplate : Object, ITemplate { + + File file; + string _readable_name = null; + + public LyxTemplate (string file) { + this.file = File.new_for_path (file); + } + + public string get_readable_name () { + if (_readable_name == null) { + string contents; + + try { + FileUtils.get_contents (file.get_path(), out contents); + + var regex = new Regex ("@LAview\\.ViewName=[^@]+@"); + MatchInfo match_info; + regex.match (contents, 0, out match_info); + + if (match_info.matches ()) { + var word = match_info.fetch (0); + _readable_name = word.substring(17, word.length - 17 - 1).strip(); + } + } catch (Error e) { + _readable_name = file.get_basename(); + } + } + + return _readable_name; + } + + public bool is_equal_to (ITemplate template) { + if (template is LyxTemplate) + return (template as LyxTemplate).file.get_path() == file.get_path(); + + return false; + } + + public string get_path () { return file.get_path(); } + } + + /** + * LyX File Template. + */ + public class TexTemplate : Object, ITemplate { + + File file; + + public TexTemplate (string file) { + this.file = File.new_for_path (file); + } + + public string get_readable_name () { + return file.get_basename(); + } + + public bool is_equal_to (ITemplate template) { + if (template is TexTemplate) + return (template as TexTemplate).file.get_path() == file.get_path(); + + return false; + } + + public string get_path () { return file.get_path(); } + } + + public class TemplateList : Gee.ArrayList { + public override bool contains (ITemplate template) { + foreach (var t in this) + if (t.is_equal_to (template)) + return true; + return false; + } + } +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..4ad6e63 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,7 @@ +ADD_SUBDIRECTORY (conv-test) +ADD_SUBDIRECTORY (host-test) + +INSTALL (DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/core-test/templates + DESTINATION share/${PROJECT_LOWERCASE_NAME}-${MAJOR}) + +INCLUDE (CTest) diff --git a/test/conv-test/CMakeLists.txt b/test/conv-test/CMakeLists.txt new file mode 100644 index 0000000..e36ba10 --- /dev/null +++ b/test/conv-test/CMakeLists.txt @@ -0,0 +1,36 @@ +SET (BinName conv_test) +FILE (GLOB_RECURSE BinSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ConvTest.vala) +SET (BinPackages gee-0.8 gio-2.0) +SET (BinCustomVapis ${CMAKE_BINARY_DIR}/src/conv/${PROJECT_LOWERCASE_NAME}-conv-${MAJOR}.vapi) +SET (BinLinkLibs ${PROJECT_LOWERCASE_NAME}-conv) +INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src/conv") +INCLUDE (ValaBinCommonRules) + +## Parse tests +#MACRO (do_parse_test testname table_path etalon_path regexp) +# IF ("${etalon_path}" STREQUAL "") +# SET (extra_args "") +# ELSE () +# SET (extra_args --etalon ${etalon_path}) +# ENDIF () +# ADD_TEST (ParseTest-${testname} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/parse_test --table ${table_path} ${extra_args}) +# SET_TESTS_PROPERTIES (ParseTest-${testname} +# PROPERTIES PASS_REGULAR_EXPRESSION ${regexp} +# FAIL_REGULAR_EXPRESSION "CRITICAL;WARNING") +#ENDMACRO (do_parse_test) +# +## test throttle.tex +#do_parse_test (throttleList ${PROJECT_SOURCE_DIR}/test/tex/throttle.tex "" +#"list all objects +#LAviewText +#LAviewTableLongtable +#LAviewText +#LAviewTableTabular +#LAviewText +#end of objects +# +#") +#SET_TESTS_PROPERTIES(ParseTest-throttleList PROPERTIES ENVIRONMENT "LANG=en") +# +## enable testing +#ENABLE_TESTING () diff --git a/test/conv-test/ConvTest.vala b/test/conv-test/ConvTest.vala new file mode 100644 index 0000000..057c4f4 --- /dev/null +++ b/test/conv-test/ConvTest.vala @@ -0,0 +1,106 @@ +/** + * LyX->PDF test + */ +void lyx2pdf_test (string[] args) { + Subprocess sp = null; + try { + sp = (new LAview.Conv.Converter()).lyx2pdf(Path.build_path (Path.DIR_SEPARATOR_S, + File.new_for_path(args[0]).get_parent().get_parent().get_parent().get_path(), + "test/conv-test/templates/templ_ex1.lyx"), "templ_ex1.pdf"); + + if (sp.wait_check() == false) throw new IOError.FAILED("Error running subprocess."); + + stdout.puts("=== Converting LyX->PDF... ===\n"); + var ds_out = new DataInputStream(sp.get_stdout_pipe()); + try { + for (string s = ds_out.read_line(); s != null; s = ds_out.read_line()) + stdout.printf("%s\n", s); + } catch (IOError err) { + assert_not_reached(); + } + } catch (Error err) { + stdout.printf("Error: %s\n", err.message); + if (sp != null) { + var ds_err = new DataInputStream(sp.get_stderr_pipe()); + try { + for (string s = ds_err.read_line(); s != null; s = ds_err.read_line()) + stdout.printf("%s\n", s); + } catch (IOError err) { + assert_not_reached(); + } + } + } +} + +/** + * LyX->TeX test + */ +void lyx2tex_test (string[] args) { + Subprocess sp = null; + try { + sp = (new LAview.Conv.Converter()).lyx2tex(Path.build_path (Path.DIR_SEPARATOR_S, + File.new_for_path(args[0]).get_parent().get_parent().get_parent().get_path(), + "test/conv-test/templates/templ_ex1.lyx"), "templ_ex1.tex"); + + if (sp.wait_check() == false) throw new IOError.FAILED("Error running subprocess."); + + stdout.puts("=== Converting LyX->TeX... ===\n"); + var ds_out = new DataInputStream(sp.get_stdout_pipe()); + try { + for (string s = ds_out.read_line(); s != null; s = ds_out.read_line()) + stdout.printf("%s\n", s); + } catch (IOError err) { + assert_not_reached(); + } + } catch (Error err) { + stdout.printf("Error: %s\n", err.message); + if (sp != null) { + var ds_err = new DataInputStream(sp.get_stderr_pipe()); + try { + for (string s = ds_err.read_line(); s != null; s = ds_err.read_line()) + stdout.printf("%s\n", s); + } catch (IOError err) { + assert_not_reached(); + } + } + } +} + +/** + * TeX->PDF test + */ +void tex2pdf_test (string[] args) { + Subprocess sp = null; + try { + sp = (new LAview.Conv.Converter()).tex2pdf("templ_ex1.tex", "templ_ex1.latexmk.pdf"); + + if (sp.wait_check() == false) throw new IOError.FAILED("Error running subprocess."); + + stdout.puts("=== Converting TeX->PDF... ===\n"); + var ds_out = new DataInputStream(sp.get_stdout_pipe()); + try { + for (string s = ds_out.read_line(); s != null; s = ds_out.read_line()) + stdout.printf("%s\n", s); + } catch (IOError err) { + assert_not_reached(); + } + } catch (Error err) { + stdout.printf("Error: %s\n", err.message); + if (sp != null) { + var ds_err = new DataInputStream(sp.get_stderr_pipe()); + try { + for (string s = ds_err.read_line(); s != null; s = ds_err.read_line()) + stdout.printf("%s\n", s); + } catch (IOError err) { + assert_not_reached(); + } + } + } +} + + +void main(string[] args) { + lyx2pdf_test(args); + lyx2tex_test(args); + tex2pdf_test(args); +} diff --git a/test/conv-test/templates/pic/lyx.png b/test/conv-test/templates/pic/lyx.png new file mode 100644 index 0000000000000000000000000000000000000000..36afbd8fbfdf2e00e299662c529f2396c4a2ac05 GIT binary patch literal 1623 zcmV-d2B`UoP)n+a8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H11=LAIK~!jg?U-q7R8<&;pL6e>>2#mA(iZ6`6m2k|1wq_?5K&P{ z+}PYV5>YUsB>2aKsDBh=SPO{}wBUjwT5-cA5{VWgs9;N31T09QNMX87r!#Z!+hw zqv+-_;#H?YwJAAZ!Tx~G{&tm}4>icPv&|*aaTeNKEv6MZ*bvQG60^hLnOhp=N`MVQ zsOAVf_wJR4ljZ7n1jJKK9(2DhS6zMLoK#1l6~4-obg6>E2&V|tY>g?vN`R7TmgZ^9 z**aDnwj@mw_Jk~UcbhaeHPQ5floliz0Wqtg3b$ttuKb7SIkiYG9{h5u3;@)R6?HDb z-O-#WF^(Es;TB9PaIjQ>h>bHPoqvb98BiM|9n0s&xITt)l`N(@vv>X7ka_$p? zSEM9m^G!GT)}{3|pb8vrl~?jrZnYCHLHC(F5fKkDBOvBBKS0sYT7=?=3+-s0B9{&S zB*N6M6jhfDW|gMW8n$TBgS7ZVv~=j~x^5QDko@DSs}>a%8hLw_7Xgo??cPJATB!CUMCk8PmQM9J{2F9x|tr$8DVH^=er@(<;@YU@jX#dh{+LdNFFtwGTt0DoNvZm!jbMx;&|tm;+J8wDRqqQUwlxqam!Ag zwQGyt$hzBBVTFzOo(>o83m=Q7s%Oe?+kJc=+f`Lj$_tqdaCp6Vrr6D0XAC+}3UVoT z=P|Chf(r9!a`7R_wst=cM^>GF4anC=HlX{yw#}yH+$&~m=rd=%U97R2>_vs#y6Y|R zczH1k;=V>se<26Hpw~K;SbSLG?-0zmW1sXT>SKSD2z9K%ZozTp4rRzS_eWD79Ae$^ zPS@_(u9}Kg zhQH`Pxne={igz)eLhZ{SkJ}Dghh}en3}9T@kaLC@n^{$yd~r;}fH z1FphHP@Dx>1lU$Rit6I#eg&BpW@9aF<{kzQ#DF3B`)C`L(_3V~u08Q-^sm-hj6nSH zL8vOFmwiOepr=us1ppzkdAs$&f#~7Tb`IEyH!MyX7VWXTLr`8&!n8#B5*m;nj_tzm zud{6wYFu2ccMgYrr3r-tba?rzVBe zix#_hmtsGS`n?axWtE%6^Se}7TMqzsM`HI~UZMWGN$kvN^)tq88#G)jz~+$8%f?*qG12K{Ss=8wlRdeM8| z!SF7Yiz@f?-+crCRpBDL@Ia8>V_xb<4xrRcJLPM3{1T7IF4E$s!oUoiYFvw=RuSl4 zAy*DR7%TitG8K;`uJpC81q)HLbbX42o^@cJpz`?K0t7 zelAGavx-_wRkkZ$Jb)fzf2!)lB4q}Ob1C!n(qe>(TZwx0|Ia|m-i1cal-~mv{jgYg zN{bntm&33u7sE7#%FZ5sOI4j%q~%>Gl{oL87BdFYjf{bGBV!=l$QVdBG6vF(e*l8L VIgp1uBwPRh002ovPDHLkV1jJ?|Jncm literal 0 HcmV?d00001 diff --git a/test/conv-test/templates/templ_ex1.lyx b/test/conv-test/templates/templ_ex1.lyx new file mode 100644 index 0000000..6e99f44 --- /dev/null +++ b/test/conv-test/templates/templ_ex1.lyx @@ -0,0 +1,187 @@ +#LyX 2.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 474 +\begin_document +\begin_header +\textclass article +\use_default_options true +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding auto +\fontencoding global +\font_roman default +\font_sans default +\font_typewriter default +\font_math auto +\font_default_family default +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize default +\use_hyperref false +\papersize default +\use_geometry false +\use_package amsmath 1 +\use_package amssymb 1 +\use_package cancel 1 +\use_package esint 1 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stackrel 1 +\use_package stmaryrd 1 +\use_package undertilde 1 +\cite_engine basic +\cite_engine_type default +\biblio_style plain +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\justification true +\use_refstyle 1 +\index Index +\shortcut idx +\color #008000 +\end_index +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 1 +\paperpagestyle default +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Standard +Some text +\end_layout + +\begin_layout Standard +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset Graphics + filename pic/lyx.png + scale 10 + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/test/core-test/templates/example.lyx b/test/core-test/templates/example.lyx new file mode 100644 index 0000000..d2a4719 --- /dev/null +++ b/test/core-test/templates/example.lyx @@ -0,0 +1,1295 @@ +#LyX 2.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 474 +\begin_document +\begin_header +\textclass article +\begin_preamble +\renewcommand{\headrulewidth}{0pt} +\usepackage{lastpage} + +\usepackage{background} +\usetikzlibrary{calc} +\usepackage{lipsum}% just to generate some text + +\SetBgScale{1} +\SetBgColor{black} +\SetBgAngle{0} +\SetBgOpacity{1} +\SetBgVshift{-2} +\SetBgContents{ +\begin{tikzpicture}[thick] +\draw (-283bp,5bp) -- (284bp,5bp); % top line +\draw (-283bp,-801bp) -- (284bp,-801bp); % bottom line +\draw (-283bp,5bp) -- (-283bp,-801bp); % left line +\draw (284bp,5bp) -- (284bp,-801bp); % right line +\end{tikzpicture} +} +\end_preamble +\use_default_options true +\begin_modules +customHeadersFooters +\end_modules +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding utf8x +\fontencoding global +\font_roman default +\font_sans default +\font_typewriter default +\font_math auto +\font_default_family default +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize default +\spacing single +\use_hyperref false +\papersize a4paper +\use_geometry true +\use_package amsmath 1 +\use_package amssymb 1 +\use_package cancel 1 +\use_package esint 1 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stackrel 1 +\use_package stmaryrd 1 +\use_package undertilde 1 +\cite_engine basic +\cite_engine_type default +\biblio_style plain +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\justification true +\use_refstyle 0 +\index Index +\shortcut idx +\color #008000 +\end_index +\leftmargin 0.5cm +\topmargin 2.1cm +\rightmargin 0.5cm +\bottommargin 2.1cm +\headheight 65pt +\headsep 5mm +\footskip 40pt +\secnumdepth -1 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 1 +\paperpagestyle fancy +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Standard +@LAview.ViewName=Protocol Example@ +\end_layout + +\begin_layout Center Header +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout +Anything +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +in +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +the +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +header +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Center Footer +\begin_inset Tabular + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout +Something +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +in the +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +footer +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Enumerate +Just a label: [ProtObjEx1.SampleRequest] +\end_layout + +\begin_layout Enumerate +Another label: [ProtObjEx1.AnotherRequest] +\end_layout + +\begin_layout Enumerate +Manual input label: [ProtObjEx1.Manual.SampleRequest] +\end_layout + +\begin_layout Enumerate +Picture/Image/Chart: +\begin_inset Newline newline +\end_inset + + +\begin_inset Note Comment +status open + +\begin_layout Plain Layout +\begin_inset Graphics + filename ProtObjEx1.MainChart + width 75page% + +\end_inset + + +\end_layout + +\end_inset + + +\end_layout + +\begin_layout Enumerate +Static picture: +\begin_inset Newline newline +\end_inset + + +\begin_inset Graphics + filename pics/laview-desktop.png + +\end_inset + + +\end_layout + +\begin_layout Enumerate +\align left +A table +\end_layout + +\begin_layout Standard +\align left +\begin_inset Tabular + + + + + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +#addcols#2 +\series bold +f +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +k +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +p +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +u +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +#addcols#2 +\series bold +z +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +E +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +[ProtObjEx1.arr1d] g +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +l +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +q +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +v +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +A +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +F +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +#addrows +\series bold +c +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +h +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +m +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +r +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +w +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +[ProtObjEx1.arr2d] B +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +G +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +#addrows +\series bold +d +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +i +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +n +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +[ProtObjEx1.arr1d] s +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +x +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +C +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +H +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +e +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +j +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +o +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +t +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +y +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +D +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +I +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\begin_layout Standard +\begin_inset space ~ +\end_inset + + +\end_layout + +\begin_layout Standard +\align left +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + + +\begin_inset space ~ +\end_inset + +7. + Longtable: +\begin_inset Newline newline +\end_inset + + +\begin_inset Tabular + + + + + + + + + + + +\begin_inset Text + +\begin_layout Plain Layout +1st Head +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +Head +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +a +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +#addcols#2 +\series bold +f +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +k +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +p +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +u +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +#addcols#2 +\series bold +z +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +E +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +b +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +[ProtObjEx1.arr1d] g +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +l +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +q +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +v +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +A +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +F +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +#addrows +\series bold +c +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +h +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +m +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +r +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +w +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +[ProtObjEx1.arr2d] B +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +G +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +#addrows +\series bold +d +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +i +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +n +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +[ProtObjEx1.arr1d] s +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +x +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +C +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +H +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout + +\series bold +e +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +j +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +o +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +t +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +y +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +D +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout +I +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +Foot +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\begin_inset Text + +\begin_layout Plain Layout +Last Foot +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + +\begin_inset Text + +\begin_layout Plain Layout + +\end_layout + +\end_inset + + + + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/test/core-test/templates/pics/laview-desktop.png b/test/core-test/templates/pics/laview-desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..157c4bd0a2196b7f395223ade538f862fffe9578 GIT binary patch literal 13754 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 E55{+|+5i9m literal 0 HcmV?d00001 diff --git a/test/host-test/CMakeLists.txt b/test/host-test/CMakeLists.txt new file mode 100644 index 0000000..734d9e8 --- /dev/null +++ b/test/host-test/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY (plugins) diff --git a/test/host-test/plugins/CMakeLists.txt b/test/host-test/plugins/CMakeLists.txt new file mode 100644 index 0000000..3debcf4 --- /dev/null +++ b/test/host-test/plugins/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY (data) +ADD_SUBDIRECTORY (protocol) diff --git a/test/host-test/plugins/data/CMakeLists.txt b/test/host-test/plugins/data/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/host-test/plugins/protocol/CMakeLists.txt b/test/host-test/plugins/protocol/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/util/backbone b/util/backbone new file mode 160000 index 0000000..11c998a --- /dev/null +++ b/util/backbone @@ -0,0 +1 @@ +Subproject commit 11c998aca2aa1b787286b336e579e5a4e31f471a diff --git a/valadoc_env b/valadoc_env new file mode 100644 index 0000000..15980e5 --- /dev/null +++ b/valadoc_env @@ -0,0 +1,2 @@ +BASEDIR=src config +PKGS=gobject-plugin-iface-0 gobject-plugin-loader-0 laview-latex-struct-0 gee-0.8 gmodule-2.0 gio-2.0 posix From cc960c381e72b5ab8c4a40ba16458d305857d9d1 Mon Sep 17 00:00:00 2001 From: Kolan Sh Date: Wed, 7 Dec 2016 19:43:23 +0300 Subject: [PATCH 2/2] Bump version number to 0.1.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a652c9..d5b887b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ SET (PROJECT_LOWERCASE_NAME "laview-core") SET (PROJECT_DESCRIPTION "LAview Core Libraries.") SET (MAJOR 0) -SET (MINOR 0) +SET (MINOR 1) SET (PATCH 0) LIST (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/backbone)