Browse Source

First development version.

develop
Kolan Sh 7 years ago
parent
commit
b97c70b48f
102 changed files with 24753 additions and 31 deletions
  1. +123
    -9
      CMakeLists.txt
  2. +1
    -1
      README
  3. +20
    -0
      cmake/CPackDetectArch.cmake
  4. +31
    -0
      cmake/MacroOptionalAddSubdirectory.cmake
  5. +11
    -0
      laview-latex-struct.pc.in
  6. +9
    -0
      po/CMakeLists.txt
  7. +61
    -0
      po/laview-latex-struct-0.pot
  8. +2
    -0
      po/ru/CMakeLists.txt
  9. +67
    -0
      po/ru/laview-latex-struct-0.po
  10. +45
    -0
      src/AddSpace.vala
  11. +61
    -0
      src/AddSpaces.vala
  12. +29
    -11
      src/CMakeLists.txt
  13. +168
    -0
      src/Cell.vala
  14. +65
    -0
      src/ColParam.vala
  15. +18
    -0
      src/ColParams.vala
  16. +0
    -0
      src/Doc.vala
  17. +75
    -0
      src/DocIfaces.vala
  18. +15
    -0
      src/Glob.vala
  19. +191
    -0
      src/GlobParser.vala
  20. +0
    -0
      src/GlobScanner.vala
  21. +93
    -0
      src/Graphics.vala
  22. +153
    -0
      src/GraphicsParser.vala
  23. +0
    -0
      src/GraphicsScanner.vala
  24. +64
    -0
      src/Longtable.vala
  25. +119
    -0
      src/LongtableParser.vala
  26. +0
    -0
      src/LongtableScanner.vala
  27. +0
    -0
      src/Object.vala
  28. +0
    -0
      src/ObjectList.vala
  29. +358
    -0
      src/Parser.vala
  30. +55
    -0
      src/ParserFactory.vala
  31. +439
    -0
      src/Row.vala
  32. +0
    -0
      src/Scanner.vala
  33. +353
    -0
      src/Subtable.vala
  34. +181
    -0
      src/Table.vala
  35. +674
    -0
      src/TableParser.vala
  36. +63
    -0
      src/Tabular.vala
  37. +137
    -0
      src/TabularParser.vala
  38. +0
    -0
      src/TabularScanner.vala
  39. +36
    -0
      src/Text.vala
  40. +21
    -0
      src/TextParser.vala
  41. +0
    -0
      src/TextScanner.vala
  42. +11
    -0
      src/gettext-config.h.in
  43. +94
    -10
      src/main.vala
  44. +34
    -0
      src/vala_unsupported.c
  45. +390
    -0
      test/CMakeLists.txt
  46. +122
    -0
      test/LTableTest.vala
  47. +141
    -0
      test/ParseTest.vala
  48. BIN
      test/tex/151.bmp
  49. BIN
      test/tex/174.jpg
  50. +386
    -0
      test/tex/CMakeLists.txt
  51. +1124
    -0
      test/tex/all_subtables.lyx
  52. +129
    -0
      test/tex/all_subtables.tex
  53. +48
    -0
      test/tex/back_slashes_in_a_table.etalon.tex
  54. +50
    -0
      test/tex/back_slashes_in_a_table.tex
  55. +4377
    -0
      test/tex/formular.lyx
  56. +359
    -0
      test/tex/formular.tex
  57. +220
    -0
      test/tex/formular_err1.tex
  58. +220
    -0
      test/tex/formular_err2.tex
  59. +3
    -0
      test/tex/get_tags.sh
  60. +225
    -0
      test/tex/graph_in_ltable.tex
  61. +4
    -0
      test/tex/includegraphics.tex
  62. +262
    -0
      test/tex/lines.etalon.tex
  63. +648
    -0
      test/tex/lines.lyx
  64. +289
    -0
      test/tex/lines.tex
  65. +389
    -0
      test/tex/ltable_clone_0_0.tex
  66. +389
    -0
      test/tex/ltable_clone_0_1.tex
  67. +359
    -0
      test/tex/ltable_clone_0_1000.tex
  68. +389
    -0
      test/tex/ltable_clone_0_last.tex
  69. +389
    -0
      test/tex/ltable_clone_0_lastp1.tex
  70. +359
    -0
      test/tex/ltable_clone_1000_0.tex
  71. +387
    -0
      test/tex/ltable_clone_1_0.tex
  72. +364
    -0
      test/tex/ltable_clone_last_0.tex
  73. +359
    -0
      test/tex/ltable_clone_lastp1_0.tex
  74. +11
    -0
      test/tex/ltable_double_embedded.tex
  75. +3
    -0
      test/tex/ltable_embedded.tex
  76. +357
    -0
      test/tex/ltable_rm0row.tex
  77. +359
    -0
      test/tex/ltable_rm1000row.tex
  78. +359
    -0
      test/tex/ltable_rm1row.tex
  79. +357
    -0
      test/tex/ltable_rm_last_row.tex
  80. +126
    -0
      test/tex/ltable_square_arg.lyx
  81. +27
    -0
      test/tex/ltable_square_arg.tex
  82. +177
    -0
      test/tex/ltable_test.c
  83. +47
    -0
      test/tex/old_tex_parser.geany
  84. +161
    -0
      test/tex/table_in_table.tex
  85. +55
    -0
      test/tex/table_rows.etalon.tex
  86. +49
    -0
      test/tex/table_rows.tex
  87. +4609
    -0
      test/tex/throttle.lyx
  88. +232
    -0
      test/tex/throttle.tex
  89. +135
    -0
      test/tex/throttle_VK2500.tex
  90. +144
    -0
      test/tex/throttle_VK2500PS.tex
  91. +144
    -0
      test/tex/throttle_VK2500PS_dos_newlines.tex
  92. +139
    -0
      test/tex/throttle_err1.tex
  93. +139
    -0
      test/tex/throttle_err2.tex
  94. +140
    -0
      test/tex/throttle_err3.tex
  95. +139
    -0
      test/tex/throttle_err4.tex
  96. +139
    -0
      test/tex/throttle_err5.tex
  97. +140
    -0
      test/tex/throttle_err6.tex
  98. +219
    -0
      test/tex/txr_parse_test.c
  99. +19
    -0
      test/tex/unary_quotes.tex
  100. +48
    -0
      util/update-po.sh

+ 123
- 9
CMakeLists.txt View File

@ -1,16 +1,130 @@
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
PROJECT (LAviewLatexStruct C)
PROJECT (LAview C)
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
SET (LAVIEW_VERSION_MAJOR 0)
SET (LAVIEW_VERSION_MINOR 0)
SET (LAVIEW_VERSION_PATCH 1)
SET (LAVIEW_VERSION
${LAVIEW_VERSION_MAJOR}.${LAVIEW_VERSION_MINOR}.${LAVIEW_VERSION_PATCH})
SET (MAJOR 0)
SET (MINOR 0)
SET (PATCH 0)
SET (VERSION ${MAJOR}.${MINOR}.${PATCH})
LIST (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
INCLUDE (MacroOptionalAddSubdirectory)
INCLUDE (CPackDetectArch)
SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w") # supress Gcc warnings
# configure a header file for Gettext
SET (GETTEXT_PACKAGE "laview-latex-struct")
ADD_DEFINITIONS (-DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}")
IF (WIN32)
SET (LOCALEDIR "")
ELSE ()
SET (LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale")
ENDIF ()
SET (CUSTOM_LOCALEDIR "" CACHE STRING "Directory to install l10n files into")
IF (NOT CUSTOM_LOCALEDIR STREQUAL "")
SET (LOCALEDIR "${CUSTOM_LOCALEDIR}")
MESSAGE(STATUS "Using LOCALEDIR=${LOCALEDIR}")
ENDIF ()
ADD_DEFINITIONS (-DLOCALEDIR="${LOCALEDIR}")
SET (LOCALE_INSTALL_DIR "share/locale")
MACRO_OPTIONAL_ADD_SUBDIRECTORY (po)
# Avoid of "dll not found" messages
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/run")
# configure a header file for Gettext
CONFIGURE_FILE (
"${PROJECT_SOURCE_DIR}/src/gettext-config.h.in"
"${PROJECT_BINARY_DIR}/src/gettext-config.h"
)
IF ( CMAKE_BUILD_TYPE STREQUAL "Debug" )
SET (VALA_DEBUG "-g")
ENDIF ()
# configure pkg-config file
IF (WIN32)
SET (prefix "")
ELSE ()
SET (prefix ${CMAKE_INSTALL_PREFIX})
ENDIF ()
SET (exec_prefix "\${prefix}")
SET (libdir "\${exec_prefix}/lib")
SET (prefincludedir "\${prefix}/include")
SET (link_lib1 "\${libdir}")
SET (link_lib2 "laview-latex-struct")
CONFIGURE_FILE (
"${PROJECT_SOURCE_DIR}/laview-latex-struct.pc.in"
"${PROJECT_BINARY_DIR}/laview-latex-struct-${MAJOR}.pc"
)
INCLUDE (FindVala)
INCLUDE (UseVala)
SET (CMAKE_C_FLAGS_DEBUG "-ggdb3 -O0 -ftest-coverage -Wcoverage-mismatch ${CMAKE_C_FLAGS_DEBUG}")
SET (CMAKE_C_FLAGS_RELEASE "-O2 ${CMAKE_C_FLAGS_RELEASE}")
ADD_SUBDIRECTORY (src)
ADD_SUBDIRECTORY (test)
## CPack configuration ##
SET (CPACK_PACKAGE_CONTACT "backbone@backbone.ws")
SET (CPACK_PACKAGE_VENDOR "backbone@backbone.ws")
SET (CPACK_NSIS_MODIFY_PATH ON)
SET (CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
INCLUDE (InstallRequiredSystemLibraries)
SET (CPACK_RESOURCE_FILE_LICENSE
"${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
SET (CPACK_PACKAGE_DESCRIPTION_FILE
"${CMAKE_CURRENT_SOURCE_DIR}/README")
INSTALL (FILES "${PROJECT_BINARY_DIR}/laview-latex-struct-${MAJOR}.pc"
DESTINATION lib/pkgconfig)
INSTALL (FILES "${PROJECT_BINARY_DIR}/src/laview-latex-struct-${MAJOR}.vapi"
DESTINATION share/vala/vapi)
#SET (CPACK_NSIS_PACKAGE_NAME "${PROJECT_NAME}")
#SET (CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME}")
SET (CPACK_PACKAGE_VERSION_MAJOR "${MAJOR}")
SET (CPACK_PACKAGE_VERSION_MINOR "${MINOR}")
SET (CPACK_PACKAGE_VERSION_PATCH "${PATCH}")
SET (CPACK_PACKAGE_VERSION "${VERSION}")
IF (UNIX)
SET (CPACK_GENERATOR "DEB;RPM;STGZ;TBZ2;TGZ;TZ;ZIP")
SET (CPACK_SOURCE_GENERATOR "DEB;RPM;STGZ;TBZ2;TGZ;TZ;ZIP")
SET (CPACK_PACKAGE_NAME "laview-latex-struct")
SET (CPACK_PACKAGE_DESCRIPTION_SUMMARY "LaTeX representation in the memory")
SET (CPACK_PACKAGE_DESCRIPTION "LaTeX representation in the memory "
"Scanner + Generator + Operations on document objects.")
# Debian specific options
SET (CPACK_DEBIAN_PACKAGE_DEPENDS "valac (>= 0.24), libglib2.0-bin (>= 2.33)")
SET (CPACK_DEBIAN_PACKAGE_SECTION "Libraries")
# SET (CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${ARCHITECTURE}")
# SET (CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
SET (CPACK_DEBIAN_PACKAGE_RECOMMENDS "")
SET (CPACK_DEBIAN_PACKAGE_SUGGESTS "")
# RPM specific options
# SET (CPACK_RPM_PACKAGE_ARCHITECTURE "${ARCHITECTURE}")
SET (CPACK_RPM_PACKAGE_LICENSE "LGPLv3+")
SET (CPACK_RPM_PACKAGE_GROUP "Applications/Text")
SET (CPACK_RPM_PACKAGE_REQUIRES "vala >= 0.24, glib >= 2.33")
SET (CPACK_RPM_PACKAGE_PROVIDES "laview-latex-struct")
# http://public.kitware.com/Bug/view.php?id=12997
SET(CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}_${ARCHITECTURE}")
ELSEIF (WIN32)
SET (CPACK_GENERATOR "NSIS")
SET (CPACK_SOURCE_GENERATOR "NSIS")
SET (CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CMAKE_PROJECT_NAME}-${MAJOR}")
#SET (CPACK_NSIS_MENU_LINKS "${EWS_WEBSITE}" "Homepage for ${EWS_APP_NAME}")
#SET (CPACK_NSIS_INSTALLED_ICON_NAME bin\\\\${EXE_TARGET_NAME}.exe)
#SET (CPACK_NSIS_URL_INFO_ABOUT "${EWS_WEBSITE}")
#SET (CPACK_NSIS_HELP_LINK "${EWS_WEBSITE}")
SET (CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}-${MAJOR}")
SET (CPACK_UNINSTALL_NAME "LVLatStr-${MAJOR}") # <=10 symbols: https://redmine.backbone.ws/issues/83
ENDIF ()
INCLUDE (CPack)
INCLUDE (CTest)

+ 1
- 1
README View File

@ -1,4 +1,4 @@
LaTeX representation in the memory + Parser (GScanner) + Generator.
Git repo: https://git.backbone.ws/laview/latex-struct
Issue tracker: https://chili.backbone.ws/projects/latex-struct
Issue tracker: https://chili.backbone.ws/projects/latex-struct/issues

+ 20
- 0
cmake/CPackDetectArch.cmake View File

@ -0,0 +1,20 @@
# Kernel of Operation System
EXECUTE_PROCESS (COMMAND uname -s COMMAND tr -d '\n' OUTPUT_VARIABLE OSKERNEL)
MESSAGE ("OSKERNEL = ${OSKERNEL}")
STRING (TOLOWER "${OSKERNEL}" OSKERNEL)
# CPU Architecture
SET (CUSTOM_ARCHITECTURE "" CACHE STRING "Specify custom target architecutre")
SET (ARCHITECTURE "${CUSTOM_ARCHITECTURE}")
IF (ARCHITECTURE STREQUAL "")
# SET (ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}")
# SET (ARCHITECTURE "${CMAKE_HOST_SYSTEM_PROCESSOR}")
EXECUTE_PROCESS(COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE)
# Replacements
STRING (REGEX REPLACE "^x86_64$" "amd64" ARCHITECTURE "${ARCHITECTURE}")
STRING (REGEX REPLACE "^i.86$" "i386" ARCHITECTURE "${ARCHITECTURE}")
STRING (REGEX REPLACE "^armv7l$" "armel" ARCHITECTURE "${ARCHITECTURE}")
ENDIF ()
MESSAGE ("ARCHITECTURE = ${ARCHITECTURE}")

+ 31
- 0
cmake/MacroOptionalAddSubdirectory.cmake View File

@ -0,0 +1,31 @@
# - MACRO_OPTIONAL_ADD_SUBDIRECTORY() combines ADD_SUBDIRECTORY() with an OPTION()
# MACRO_OPTIONAL_ADD_SUBDIRECTORY( <dir> )
# If you use MACRO_OPTIONAL_ADD_SUBDIRECTORY() instead of ADD_SUBDIRECTORY(),
# this will have two effects
# 1 - CMake will not complain if the directory doesn't exist
# This makes sense if you want to distribute just one of the subdirs
# in a source package, e.g. just one of the subdirs in kdeextragear.
# 2 - If the directory exists, it will offer an option to skip the
# subdirectory.
# This is useful if you want to compile only a subset of all
# directories.
# Copyright (c) 2007, Alexander Neundorf, <neundorf@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
MACRO (MACRO_OPTIONAL_ADD_SUBDIRECTORY _dir )
GET_FILENAME_COMPONENT(_fullPath ${_dir} ABSOLUTE)
IF(EXISTS ${_fullPath})
IF(${ARGC} EQUAL 2)
OPTION(BUILD_${_dir} "Build directory ${_dir}" ${ARGV1})
ELSE(${ARGC} EQUAL 2)
OPTION(BUILD_${_dir} "Build directory ${_dir}" TRUE)
ENDIF(${ARGC} EQUAL 2)
IF(BUILD_${_dir})
ADD_SUBDIRECTORY(${_dir})
ENDIF(BUILD_${_dir})
ENDIF(EXISTS ${_fullPath})
ENDMACRO (MACRO_OPTIONAL_ADD_SUBDIRECTORY)

+ 11
- 0
laview-latex-struct.pc.in View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@prefincludedir@
Name: LaTeX-Struct
Description: LaTeX representation in the memory + Scanner + Generator + Operations on document objects.
Version: @VERSION@
Libs: -L@link_lib1@ -l@link_lib2@
Libs.private:
Cflags:

+ 9
- 0
po/CMakeLists.txt View File

@ -0,0 +1,9 @@
find_package(Gettext REQUIRED)
if (NOT GETTEXT_MSGMERGE_EXECUTABLE)
MESSAGE(FATAL_ERROR "Please install msgmerge binary")
endif (NOT GETTEXT_MSGMERGE_EXECUTABLE)
if (NOT GETTEXT_MSGFMT_EXECUTABLE)
MESSAGE(FATAL_ERROR "Please install msgmerge binary")
endif (NOT GETTEXT_MSGFMT_EXECUTABLE)
add_subdirectory(ru)
#add_subdirectory(de)

+ 61
- 0
po/laview-latex-struct-0.pot View File

@ -0,0 +1,61 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: laview-latex-struct-0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-07-18 18:10+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: /home/kolan/projects/LAview/LaTeX-Struct/src/GlobParser.vala:58
#, c-format
msgid "Begin tag sequence '%s' without end tag pair."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/GlobParser.vala:127
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:582
#, c-format
msgid ": Unexpected end tag sequence '%s' without begin tag pair."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/GlobParser.vala:148
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:148
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:179
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:188
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:205
msgid "Error parsing subdoc."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/LongtableParser.vala:44
#, c-format
msgid "Incorrect longtable parameters doesn't match '%s' regexp."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:413
#, c-format
msgid "Unexpected end external tag sequence '%s' without begin tag pair."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:449
#, c-format
msgid "Begin tag sequence '%s':%d:%d without end tag pair."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:612
msgid "\\cline parameters doesn't match {number-number} regexp."
msgstr ""
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TabularParser.vala:43
#, c-format
msgid "Incorrect tabular parameters doesn't match '%s' regexp."
msgstr ""

+ 2
- 0
po/ru/CMakeLists.txt View File

@ -0,0 +1,2 @@
file(GLOB _po_files *.po)
GETTEXT_PROCESS_PO_FILES(ru ALL INSTALL_DESTINATION ${LOCALE_INSTALL_DIR} PO_FILES ${_po_files} )

+ 67
- 0
po/ru/laview-latex-struct-0.po View File

@ -0,0 +1,67 @@
# Russian translations for laview-latex-struct package.
# Copyright (C) 2014 THE laview-latex-struct'S COPYRIGHT HOLDER
# This file is distributed under the same license as the laview-latex-struct package.
# <backbone@backbone.ws>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: laview-latex-struct-0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-07-18 18:10+0400\n"
"PO-Revision-Date: 2014-05-28 10:50+0400\n"
"Last-Translator: <backbone@backbone.ws>\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"
#: /home/kolan/projects/LAview/LaTeX-Struct/src/GlobParser.vala:58
#, c-format
msgid "Begin tag sequence '%s' without end tag pair."
msgstr "Стартовая последовательность тегов '%s' без соответствующей стоп-пары."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/GlobParser.vala:127
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:582
#, c-format
msgid ": Unexpected end tag sequence '%s' without begin tag pair."
msgstr ""
": Неожиданная завершающая последовательность тегов '%s' без соответствующей "
"старт-пары."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/GlobParser.vala:148
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:148
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:179
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:188
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:205
msgid "Error parsing subdoc."
msgstr "Ошибка разбора поддокумента."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/LongtableParser.vala:44
#, c-format
msgid "Incorrect longtable parameters doesn't match '%s' regexp."
msgstr "Неверные параметры longtable не удовлетворяют рег. выражению '%s'."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:413
#, c-format
msgid "Unexpected end external tag sequence '%s' without begin tag pair."
msgstr ""
": Неожиданная завершающая последовательность внешних тегов '%s' без "
"соответствующей старт-пары."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:449
#, c-format
msgid "Begin tag sequence '%s':%d:%d without end tag pair."
msgstr ""
"Стартовая последовательность тегов '%s':%d:%d без соответствующей стоп-пары."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TableParser.vala:612
msgid "\\cline parameters doesn't match {number-number} regexp."
msgstr "Параметры \\cline не соответствует рег. выражению {число-число}."
#: /home/kolan/projects/LAview/LaTeX-Struct/src/TabularParser.vala:43
#, c-format
msgid "Incorrect tabular parameters doesn't match '%s' regexp."
msgstr "Неверные параметры tabular не удовлетворяют рег. выражению '%s'."

+ 45
- 0
src/AddSpace.vala View File

@ -0,0 +1,45 @@
namespace LAview {
namespace Table {
/**
* Vertical Space in any {@link ATable}
*/
public class AddSpace : ADoc {
/**
* Value of the vertical space.
*
* Possible values: [0-9]+{bp,cc,cm,dd,em,ex,in,mm,pc,pt,sp} <<BR>>
* or [0-9]+.[0-9][0-9]{\textwidth,columnwidth,paperwidth,linewidth,textheight,paperheight}
*/
public string height = "";
/**
* Constructs a new //AddSpace// based on value.
*
* @param height [0-9]+{bp,cc,cm,dd,em,ex,in,mm,pc,pt,sp} <<BR>>
* or [0-9]+.[0-9][0-9]{\textwidth,columnwidth,paperwidth,linewidth,textheight,paperheight}
*/
public AddSpace.with_params (string height) {
this.height = height;
}
private AddSpace () {}
/**
* Gets a copy of the //AddSpace//.
*/
public override IDoc copy () {
return new AddSpace.with_params (height);
}
/**
* Generates LaTeX string for the //AddSpace//.
*/
public override string generate () {
return height;
}
}
}
}

+ 61
- 0
src/AddSpaces.vala View File

@ -0,0 +1,61 @@
namespace LAview {
namespace Table {
/**
* List of {@link AddSpace}-s.
*/
public class AddSpaces : ADocList {
/**
* Style of the {@link AddSpace}/{@link Subtable}.
*/
public enum Style {
/**
* Default style.
*/
DEFAULT = 0,
/**
* Formal style.
*/
FORMAL
}
/**
* Style of the {@link AddSpace}/{@link Subtable}.
*/
public Style style = Style.DEFAULT;
/**
* Constructs a new empty //AddSpaces//.
*/
public AddSpaces () {}
protected override ADocList create_default_instance () { return new AddSpaces (); }
/**
* Gets a copy of the //AddSpaces//.
*/
public override IDoc copy () {
var clone = base.copy () as AddSpaces;
clone.style = style;
return clone;
}
/**
* Generates LaTeX string for the //AddSpaces//.
*/
public override string generate () {
var result = new StringBuilder ();
foreach (IDoc dociface in this)
result.append_printf (style == Style.FORMAL ? "\n\\addlinespace[%s]"
: "\n\\noalign{\\vskip%s}", dociface.generate ());
return result.str;
}
}
}
}

+ 29
- 11
src/CMakeLists.txt View File

@ -1,18 +1,36 @@
INCLUDE (FindVala)
INCLUDE (UseVala)
FIND_PACKAGE (PkgConfig REQUIRED)
PKG_CHECK_MODULES (GLIB REQUIRED glib-2.0)
INCLUDE_DIRECTORIES (${GLIB_INCLUDE_DIRS})
LINK_DIRECTORIES (${GLIB_LIBRARY_DIRS})
PKG_CHECK_MODULES (GEE REQUIRED gee-0.8)
INCLUDE_DIRECTORIES (${GEE_INCLUDE_DIRS})
FILE (GLOB_RECURSE LAviewSources RELATIVE ${CMAKE_SOURCE_DIR}/src *.vala)
VALA_PRECOMPILE (VALA_C ${LAviewSources}
PACKAGES
OPTIONS --thread
PACKAGES gee-0.8 posix
OPTIONS --thread ${VALA_DEBUG}
CUSTOM_VAPIS
GENERATE_VAPI laview
GENERATE_HEADER laview
GENERATE_VAPI laview-latex-struct-${MAJOR}
GENERATE_HEADER laview-latex-struct-${MAJOR}
)
ADD_LIBRARY (laview SHARED ${VALA_C})
TARGET_LINK_LIBRARIES (laview ${GLIB2_LIBRARIES})
SET_TARGET_PROPERTIES (laview PROPERTIES VERSION ${LAVIEW_VERSION})
SET_TARGET_PROPERTIES (laview PROPERTIES SOVERSION ${LAVIEW_VERSION_MAJOR})
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}")
ADD_LIBRARY (laview-latex-struct SHARED ${VALA_C} ${PROJECT_SOURCE_DIR}/src/vala_unsupported.c)
TARGET_LINK_LIBRARIES (laview-latex-struct ${GEE_LIBRARIES})
SET_TARGET_PROPERTIES (laview-latex-struct PROPERTIES VERSION ${VERSION})
SET_TARGET_PROPERTIES (laview-latex-struct PROPERTIES SOVERSION ${MAJOR})
IF (WIN32)
SET_TARGET_PROPERTIES (laview-latex-struct PROPERTIES PREFIX "" IMPORT_PREFIX "" SUFFIX "-${MAJOR}.dll")
ENDIF (WIN32)
IF (UNIX)
INSTALL (TARGETS laview-latex-struct DESTINATION lib)
ELSEIF (WIN32)
INSTALL (TARGETS laview-latex-struct
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
ENDIF (UNIX)
INSTALL (FILES ${CMAKE_BINARY_DIR}/src/laview-latex-struct-${MAJOR}.h DESTINATION include)

+ 168
- 0
src/Cell.vala View File

@ -0,0 +1,168 @@
namespace LAview {
namespace Table {
/**
* Cell of any table.
*/
public class Cell : ADoc {
/**
* Number of occupied cells.
*/
public uint ncells = 1;
/**
* Cell's alignment.
*
* Possible values: "c", "r", "l", ">{\centering}p{0.07\paperwidth}", etc.
*/
public string align = "";
/**
* Number of left lines.
*/
public uint nllines;
/**
* Number of right lines.
*/
public uint nrlines;
/**
* Number of top lines.
*/
public uint noverlines;
/**
* Number of bottom lines.
*/
public uint nunderlines;
/**
* Contents of the cell.
*/
public Glob contents = new Glob ();
/**
* Any text before the cell.
*/
public string before = "";
/**
* Any text after the cell.
*/
public string after = "";
/**
* Type of a cell indicates how much columns/rows does it occupy.
*/
public enum Multitype {
/**
* Standard cell.
*/
SIMPLE = 0,
/**
* Cell occupies several columns.
*/
MULTICOL,
/**
* Cell occupies several rows.
*/
MULTIROW,
/**
* Cell occupies several columns and rows.
*/
MULTICOLROW
}
Multitype _multitype;
/**
* Type of a cell indicates how much columns/rows does it occupy.
*/
public Multitype multitype {
set {
if (value != Multitype.MULTICOL && value != Multitype.MULTICOLROW)
nllines = nrlines = 0;
_multitype = value;
}
get {
return _multitype;
}
}
/**
* Constructs a new //Cell// based on it's properties.
*/
public Cell.with_params (Multitype multitype, uint ncells, uint nllines, string align,
uint nrlines, uint noverlines, uint nunderlines,
Glob contents, string before, string after) {
this.ncells = ncells;
this.nllines = nllines;
this.align = align;
this.nrlines = nrlines;
this.noverlines = noverlines;
this.nunderlines = nunderlines;
this.contents = contents.copy () as Glob;
this.before = before;
this.after = after;
this.multitype = multitype;
}
private Cell () {}
/**
* Gets a copy of the //Cell//.
*/
public override IDoc copy () {
return new Cell.with_params (multitype, ncells, nllines, align, nrlines,
noverlines, nunderlines, contents, before, after);
}
/**
* Generates LaTeX string for the //Cell//.
*/
public override string generate () {
var result = new StringBuilder (before),
params = new StringBuilder (),
contents = this.contents.generate ();
if (align != "") {
for (uint i = 0; i < nllines; ++i) params.append_c ('|');
params.append (align);
for (uint i = 0; i < nrlines; ++i) params.append_c ('|');
}
switch (multitype) {
case Multitype.SIMPLE:
result.append (contents);
break;
case Multitype.MULTICOL:
result.append_printf ("\\multicolumn{%u}{%s}{%s}",
ncells, params.str, contents);
break;
case Multitype.MULTIROW:
result.append_printf ("\\multirow{%u}{%s}{%s}",
ncells, params.str, contents);
break;
case Multitype.MULTICOLROW:
result.append_printf ("\\multicolumn{1}{%s}{\\multirow{%u}{*}{%s}}",
params.str, ncells, contents);
break;
default:
assert (multitype == Multitype.SIMPLE);
break;
}
result.append (after);
return result.str;
}
}
}
}

+ 65
- 0
src/ColParam.vala View File

@ -0,0 +1,65 @@
namespace LAview {
namespace Table {
/**
* Parameter of the table's column.
*/
public class ColParam : ADoc {
/**
* Column's alignment.
*
* Possible values: "c", "r", "l", ">{\centering}p{0.07\paperwidth}", etc.
*/
public string align = "c";
/**
* Number of left lines.
*/
public uint nllines = 1;
/**
* Number of right lines.
*/
public uint nrlines;
/**
* Constructs a new //ColParam// by it's properties.
*/
public ColParam.with_params (uint nllines = 1,
string align = "c",
uint nrlines = 0) {
this.nllines = nllines;
this.align = align;
this.nrlines = nrlines;
}
private ColParam () {}
/**
* Gets a copy of the //ColParam//.
*/
public override IDoc copy () {
return new ColParam.with_params (nllines, align, nrlines);
}
/**
* Generates LaTeX string for the //ColParam//.
*/
public override string generate () {
var result = new StringBuilder ();
for (uint i = 0; i < nllines; ++i)
result.append_c ('|');
result.append (align);
for (uint i = 0; i < nrlines; ++i)
result.append_c ('|');
return result.str;
}
}
}
}

+ 18
- 0
src/ColParams.vala View File

@ -0,0 +1,18 @@
namespace LAview {
namespace Table {
/**
* List of Column Parameters.
*/
public class ColParams : ADocList {
protected override ADocList create_default_instance () { return new ColParams (); }
/**
* Constructs a new empty //ColParams//.
*/
public ColParams () {}
}
}
}

+ 0
- 0
src/Doc.vala View File


+ 75
- 0
src/DocIfaces.vala View File

@ -0,0 +1,75 @@
namespace LAview {
/**
* Interface of any LaTeX Document.
*/
public interface IDoc : Object {
/**
* Gets a copy of the //IDoc//.
*/
public abstract IDoc copy ();
/**
* Generates LaTeX string for the //IDoc//.
*/
public abstract string generate ();
}
/**
* Any non-iterable LaTeX Document.
*/
public abstract class ADoc : Object, IDoc {
protected ADoc () {}
/**
* Gets a copy of the //ADoc//.
*/
public virtual IDoc copy () {
return Object.new (this.get_type ()) as IDoc;
}
/**
* Generates LaTeX string for the //ADoc//.
*/
public virtual string generate () { return ""; }
}
/**
* Any iterable LaTeX Document.
*/
public abstract class ADocList : Gee.ArrayList<IDoc>, IDoc {
protected ADocList () {}
/**
* Object.new (this.get_type ()) doesn't work for me for ArrayList.
*/
protected abstract ADocList create_default_instance ();
/**
* Gets a copy of the //ADocList//.
*/
public virtual IDoc copy () {
var clone = create_default_instance ();
foreach (IDoc dociface in this)
clone.add (dociface.copy () as IDoc);
return clone;
}
/**
* Generates LaTeX string for the //ADocList//.
*/
public virtual string generate () {
var result = new StringBuilder ();
foreach (IDoc dociface in this)
result.append (dociface.generate ());
return result.str;
}
}
}

+ 15
- 0
src/Glob.vala View File

@ -0,0 +1,15 @@
namespace LAview {
/**
* List of any LaTeX documents except Glob documents.
*/
public class Glob : ADocList {
protected override ADocList create_default_instance () { return new Glob (); }
/**
* Constructs a new empty //Glob//.
*/
public Glob () {}
}
}

+ 191
- 0
src/GlobParser.vala View File

@ -0,0 +1,191 @@
namespace LAview {
namespace Parsers {
class GlobParser : Parser {
public GlobParser (Array<Link> links) {
base (links);
}
enum TagKind {
NONE = 0,
START,
STOP
}
TokenType scan_tex_symbol (Glob document) throws ParseError {
uint tag;
var matched_tag_length = fifo_is_tag (tokens, out tag);
TagKind tag_kind = TagKind.NONE;
if (matched_tag_length != 0) {
tag_kind = TagKind.START;
} else {
matched_tag_length = fifo_is_tag (stop_tokens, out tag);
if (matched_tag_length != 0) {
tag_kind = TagKind.STOP;
} else if (in_child_params) {
count_branches ();
if (!in_child_params) {
tag_kind = TagKind.STOP;
tag = child_tag;
matched_tag_length = 1;
}
}
}
var token = TokenType.NONE;
uint matched_tag_abspos_left;
uint matched_tag_abspos_right;
uint matched_tag_line;
long matched_tag_pos;
switch (tag_kind) {
case TagKind.NONE:
fifo_pop ();
if (fifo_peek_head().token == TokenType.EOF) {
/* without end pair */
if (child_tag != 0 || child_level != 0) {
assert (child_tag != 0 && child_level != 0);
string message = string.joinv (null, links.index (child_tag).begin);
/// Translators: please leave the '%s' construction without any changes.
prefix_error (subdoc_start, _("Begin tag sequence '%s' without end tag pair."), message);
token = TokenType.ERROR;
throw new ParseError.ORPHAN_BEGIN (err_str);
} else {
var subcontents = contents.offset (subdoc_start.abspos);
var subparser = links.index (0).create (links);
var subdoc = subparser.parse (subcontents, subdoc_start.line, subdoc_start.pos);
document.add (subdoc);
token = TokenType.EOF;
}
}
break;
case TagKind.START:
matched_tag_abspos_left = fifo_peek_head ().abspos;
matched_tag_abspos_right = fifo_peek_nth (matched_tag_length - 1).abspos
+ fifo_peek_nth (matched_tag_length - 1).length;
matched_tag_line = fifo_peek_head ().line;
matched_tag_pos = fifo_peek_head ().pos;
for (var i = 0; i < matched_tag_length; ++i)
fifo_pop ();
if (child_tag != 0 || child_level != 0) {
assert (child_tag != 0 && child_level != 0);
if (links.index (tag).end.length != 0)
++child_level;
} else {
assert (child_tag == 0 && child_level == 0);
var subcontents = contents[subdoc_start.abspos:matched_tag_abspos_left];
var subparser = links.index (0).create (links);
var subdoc = subparser.parse (subcontents, subdoc_start.line, subdoc_start.pos);
document.add (subdoc);
if (links.index (tag).end.length != 0) {
child_tag = tag;
child_level = 1;
} else if (fifo_peek_head ().token == TokenType.LEFT_CURLY
|| fifo_peek_head ().token == TokenType.LEFT_BRACE) {
in_child_params = true;
child_tag = tag;
child_level = 1;
}
subdoc_start.abspos = matched_tag_abspos_right;
subdoc_start.line = matched_tag_line;
subdoc_start.pos = matched_tag_pos;
}
break;
case TagKind.STOP:
matched_tag_abspos_left = fifo_peek_head ().abspos;
matched_tag_abspos_right = fifo_peek_nth (matched_tag_length - 1).abspos
+ fifo_peek_nth (matched_tag_length - 1).length;
matched_tag_line = fifo_peek_head ().line;
matched_tag_pos = fifo_peek_head ().pos;
if (links.index (tag).end.length == 0)
++matched_tag_abspos_left;
for (var i = 0; i < matched_tag_length; ++i)
fifo_pop ();
/* without begin pair */
if (child_tag == 0 || child_level == 0) {
assert (child_tag == 0 && child_level == 0);
var message = string.joinv (null, links.index (tag).end);
/// Translators: please leave the '%s' construction without any changes.
prefix_error (last_symb_pos,
_(": Unexpected end tag sequence '%s' without begin tag pair."),
message);
token = TokenType.ERROR;
throw new ParseError.ORPHAN_END (err_str);
} else {
assert (child_level != 0);
--child_level;
if (tag == child_tag) {
if (child_level == 0) {
child_tag = 0;
var subcontents = contents[subdoc_start.abspos:matched_tag_abspos_left];
var subparser = links.index (tag).create (links);
/* parse subdoc */
var subdoc = subparser.parse (subcontents, subdoc_start.line,
subdoc_start.pos);
if (subdoc != null) {
document.add (subdoc);
} else {
prefix_error (subdoc_start,
_("Error parsing subdoc."));
token = TokenType.ERROR;
}
subdoc_start.abspos = matched_tag_abspos_right;
subdoc_start.line = matched_tag_line;
subdoc_start.pos = matched_tag_pos;
}
}
}
break;
}
return token;
}
public override IDoc parse (string contents, size_t line, long position) throws ParseError {
this.contents = contents;
this.line = line;
this.position = position;
scanner.input_text (contents, contents.length);
TokenType expected_token = 0;
var doc = new Glob ();
do {
expected_token = scan_tex_symbol (doc);
} while (expected_token == TokenType.NONE
&& fifo_peek_head().token != TokenType.EOF
&& fifo_peek_head().token != TokenType.ERROR);
if (expected_token == TokenType.ERROR)
scanner.unexp_token (expected_token, null, "symbol", null, null, true);
return doc;
}
}
}
}

+ 0
- 0
src/GlobScanner.vala View File


+ 93
- 0
src/Graphics.vala View File

@ -0,0 +1,93 @@
namespace LAview {
/**
* Graphics in the LaTeX document.
*
* Specified by '\includegraphics' tag in the LaTeX code.
*/
public class Graphics : ADoc {
/**
* All unknown parameters.
*/
public string rest_params = "";
/**
* Path to the image on the disk.
*/
public string path = "";
/**
* Width of the image.
*
* For ex: 3.22, 128
*/
public double width;
/**
* Width units of the image.
*
* For ex: bp, cc, cm, dd, em, ex, in, mm, pc, pt, sp <<BR>>
* or \textwidth, \columnwidth, \pagewidth,
* \linewidth, \textwidth, \paperwidth
*/
public string width_unit = "";
/**
* Height of the image.
*
* For ex: 3.22, 128
*/
public double height;
/**
* Height units of the image.
*
* For ex: bp, cc, cm, dd, em, ex, in, mm, pc, pt, sp <<BR>>
* or \textwidth, \columnwidth, \pagewidth,
* \linewidth, \textwidth, \paperwidth
*/
public string height_unit = "";
/**
* Constructs a new //Graphics// by it's properties.
*
* @param path path to the image on the disk.
*/
public Graphics.with_params (string path = "") {
this.path = path;
}
private Graphics () {}
/**
* Gets a copy of the //Graphics//.
*/
public override IDoc copy () {
var clone = new Graphics.with_params (path);
clone.width = width;
clone.height = height;
clone.width_unit = width_unit;
clone.height_unit = height_unit;
clone.rest_params = rest_params;
return clone;
}
/**
* Generates LaTeX string for the //Graphics//.
*/
public override string generate () {
var str = new StringBuilder ("\\includegraphics[");
if (width != 0)
str.append_printf ("width=%f%s,", width, width_unit);
if (height != 0)
str.append_printf ("height=%f%s,", height, height_unit);
if (rest_params != "")
str.append_printf ("%s,", rest_params);
if (str.str[str.len - 1] == ',')
str.len -= 1;
str.append_printf ("]{%s}", path);
return str.str;
}
}
}

+ 153
- 0
src/GraphicsParser.vala View File

@ -0,0 +1,153 @@
namespace LAview {
namespace Parsers {
class GraphicsParser : Parser {
public GraphicsParser (Array<Link> links) {
base (links);
}
void remove_duplicate_params (List<string> parlist) {
for (unowned List<string> elem1 = parlist.first (); elem1 != null; elem1 = elem1.next)
for (unowned List<string> elem2 = elem1.next; elem2 != null; elem2 = elem2.next) {
var eq_pos1 = elem1.data.index_of_char ('='),
eq_pos2 = elem2.data.index_of_char ('=');
size_t min_len = 0;
if (-1 != eq_pos1)
min_len = eq_pos1;
if (-1 != eq_pos2)
min_len = size_t.min (min_len, eq_pos2);
if (0 != min_len && 0 == Posix.strncmp (elem1.data, elem2.data, min_len)) {
elem2.delete_link (elem2);
if (elem2 == null) break;
}
}
}
string param_get_nvalue (string param) {
int i;
for (i = 0; param[i] != '\0' && param[i] != '='; ++i);
if (param[i] == '\0') return "";
while (param[++i].isspace ());
if (!param[i].isdigit ()) return "";
return param.offset (i);
}
string param_get_units (string param) {
int i;
for (i = 0; param[i] != '\0' && param[i] != '='; ++i);
if (param[i] == '\0') return "";
while (param[++i].isspace ());
if (!param[i].isdigit ()) return "";
while (param[++i].isdigit ());
if (param[i] == '.')
while (param[++i].isdigit ());
while (param[i].isspace ()) ++i;
if (param[i] == '\0') return "";
return param.offset (i);
}
List<string> split_params (string param_str) {
var parlist = new List<string> ();
var vstr = param_str.split (",");
foreach (var str in vstr) {
str = str.strip ();
if (str != "")
parlist.prepend (str);
}
parlist.reverse ();
remove_duplicate_params (parlist);
return parlist;
}
string concat_rest_params (List<string> parlist) {
var str = new StringBuilder ();
for (unowned List<string> elem = parlist.first (); elem != null; elem = elem.next) {
str.append (elem.data);
if (elem.next != null)
str.append_c (',');
}
return str.str;
}
static int find_param_delegate (string a, string b) {
return Posix.strncmp (a, b, int.min (a.length, b.length));
}
void fill_known_params (Graphics graphics, string param_str) {
var parlist = split_params (param_str);
unowned List<string> elem;
if (null != (elem = parlist.find_custom ("width", find_param_delegate))) {
string tmps1 = param_get_nvalue (elem.data);
string tmps2 = param_get_units (elem.data);
if (tmps1 != "" && tmps2 != "") {
graphics.width = double.parse (tmps1);
graphics.width_unit = tmps2;
}
parlist.delete_link (elem);
}
if (null != (elem = parlist.find_custom ("height", find_param_delegate))) {
string tmps1 = param_get_nvalue (elem.data);
string tmps2 = param_get_units (elem.data);
if (tmps1 != "" && tmps2 != "") {
graphics.height = double.parse (tmps1);
graphics.height_unit = tmps2;
}
parlist.delete_link (elem);
}
graphics.rest_params = concat_rest_params (parlist);
}
public override IDoc parse (string contents, size_t line, long position) throws ParseError {
/* set TeX graphics contents */
this.contents = contents;
this.line = line;
this.position = position;
var graphics = new Graphics.with_params ();
try {
var regex = new Regex ("\\[[^[\\]{}]+\\]");
MatchInfo match_info;
regex.match (contents, 0, out match_info);
if (match_info.matches ()) {
var word = match_info.fetch (0);
fill_known_params (graphics, word[1:word.length - 1]);
}
} catch (RegexError e) {}
try {
var regex = new Regex ("\\{[^[\\]{}]+\\}");
MatchInfo match_info;
regex.match (contents, 0, out match_info);
if (match_info.matches ()) {
var word = match_info.fetch (0);
graphics.path = word[1:word.length - 1].compress ();
}
} catch (RegexError e) {}
return graphics;
}
}
}
}

+ 0
- 0
src/GraphicsScanner.vala View File


+ 64
- 0
src/Longtable.vala View File

@ -0,0 +1,64 @@
namespace LAview {
namespace Table {
/**
* Longtable in the LaTeX document.
*
* Specified by '\begin{longtable}' tag in the LaTeX code.
*/
public class Longtable : ATable {
/**
* Constructs a new //Longtable// with default parameters.
*/
public Longtable () {}
/**
* Gets a copy of the //Longtable//.
*/
public override IDoc copy () {
return base.copy ();
}
/**
* Generates LaTeX string for the //Longtable//.
*/
public override string generate () {
var s = new StringBuilder ();
if (params.size == 0) return "";
s.append ("\\begin{longtable}");
if (align != '\0')
s.append_printf ("[%c]", align);
s.append_c ('{');
s.append (params.generate ());
s.append_c ('}');
first_header.style = style;
header.style = style;
footer.style = style;
last_footer.style = style;
table.style = style;
string tmps;
tmps = first_header.generate ();
if (tmps != "") s.append (tmps + "\\endfirsthead");
tmps = header.generate ();
if (tmps != "") s.append (tmps + "\\endhead");
tmps = footer.generate ();
if (tmps != "") s.append (tmps + "\\endfoot");
tmps = last_footer.generate ();
if (tmps != "") s.append (tmps + "\\endlastfoot");
s.append (table.generate ());
s.append ("\\end{longtable}");
return s.str;
}
}
}
}

+ 119
- 0
src/LongtableParser.vala View File

@ -0,0 +1,119 @@
namespace LAview {
namespace Parsers {
using Table;
class LongtableParser : TableParser {
public LongtableParser (Array<Link> links) {
base (links);
}
public override IDoc parse (string contents, size_t line, long position) throws ParseError {
/* create empty longtable */
var longtable = new Longtable ();
/* set TeX longtable contents */
this.contents = contents;
this.line = line;
this.position = position;
/* get parameters string */
var param_regex = "^(\\[(c|l|r)])?\\{[^{}]*([^{}]*\\{[^{}]*\\}[^{}]*)*\\}";
string params = "";
try {
var regex = new Regex (param_regex);
MatchInfo match_info;
regex.match (contents, 0, out match_info);
uint start_pos = 0, stop_pos = 0;
if (match_info.matches ()) {
match_info.fetch_pos (0, out start_pos, out stop_pos);
/* set TeX document contents */
this.contents = contents.offset (stop_pos);
params = match_info.fetch (0);
} else {
/// Translators: please leave the '%s' construction without any changes.
prefix_error (subdoc_start,
_("Incorrect longtable parameters doesn't match '%s' regexp."),
param_regex);
throw new ParseError.SUBDOC (err_str);
}
} catch (RegexError e) {}
/* longtable align: [c], [l], [r] */
if (params[0] == '[') {
longtable.align = params[1];
params = params.offset (3);
}
/* remove bound '{' '}' from params */
params = params.substring (1, params.length - 2).reverse ();
var col_params = new ColParams ();
/* match reversed params so '|' will be snapped to the right column */
try {
var regex = new Regex ("("
+ "\\|*}[^{}]+{(p\\|*|m\\|*|b\\|*)(}[^{}]+{>(\\|+$|\\||)|\\|)?"
+ "|"
+ "\\|*(r|c|l)(}[^{}]+{@(p\\|*|m\\|*|b\\|*) (r|c|l))?(\\|+$|\\||)"
+ ")");
MatchInfo match_info;
regex.match_full (params, -1, 0, 0, out match_info);
while (match_info.matches ()) {
var col_param = new ColParam.with_params (0, "", 0);
var word = match_info.fetch (0).reverse ().compress ();
int nllines, nrlines;
for (nllines = 0; '|' == word[nllines]; ++nllines);
for (nrlines = word.length - 1; nrlines != 0 && '|' == word[nrlines]; --nrlines);
var wlen = word.length;
word = word[0:nrlines + 1];
col_param.align = word.offset (nllines);
col_param.nllines = nllines;
col_param.nrlines = wlen - 1 - nrlines;
col_params.insert (0, col_param);
match_info.next ();
}
} catch (RegexError e) {}
longtable.params = col_params;
/* === Parsing subtables === */
/* feed in the text */
scanner.input_text (this.contents, this.contents.length);
row_abs_pos = 0;
row = new Row ();
subtable = new Subtable ();
in_caption = false;
cell_abs_pos = 0;
TokenType expected_token = TokenType.NONE;
/* scanning loop, we scan the input until it's end is reached,
* the self encountered a lexing err, or our sub routine came
* across invalid syntax
*/
do {
expected_token = scan_tex_symbol (longtable);
} while (expected_token == TokenType.NONE
&& fifo_peek_head ().token != TokenType.EOF
&& fifo_peek_head ().token != TokenType.ERROR);
/* give an err message upon syntax errors */
if (expected_token == TokenType.ERROR)
scanner.unexp_token (expected_token, null, "symbol", null, null, true);
return longtable;
}
}
}
}

+ 0
- 0
src/LongtableScanner.vala View File


+ 0
- 0
src/Object.vala View File


+ 0
- 0
src/ObjectList.vala View File


+ 358
- 0
src/Parser.vala View File

@ -0,0 +1,358 @@
namespace LAview {
/**
* LaTeX Parsers.
*/
namespace Parsers {
/**
* LaTeX Parser Error Type.
*/
public errordomain ParseError {
/**
* Undefined Error.
*/
UNDEFINED,
/**
* Cann't find end of subdoc.
*/
ORPHAN_BEGIN,
/**
* End tag without begin tag.
*/
ORPHAN_END,
/**
* Error in subdoc parsing.
*/
SUBDOC,
}
abstract class Parser : Object {
protected string err_str = "";
/* links to group of scanners */
protected unowned Array<Link> links = null;
/* escaped TeX document */
protected unowned string contents = null;
/* standard GLib Scanner */
protected Scanner scanner = new Scanner (null);
/* tokens_sequence->class table */
protected Node<uint> tokens = new Node<uint> ();
protected Node<uint> stop_tokens = new Node<uint> ();
/* local tokens_sequence->class table */
protected Node<uint> local_tokens_to_class_start = new Node<uint> ();
protected Node<uint> local_tokens_to_class_stop = new Node<uint> ();
/* contents location in global document */
protected size_t line = 0;
protected long position = 0;
/* fifo-queue of tokens */
protected Queue<SymbPos?> symb_fifo = new Queue<SymbPos?> ();
protected struct SymbPos {
public TokenType token;
public uint line;
public long pos;
public uint abspos;
public uint length;
}
/* Last symbol position pushed to fifo */
protected SymbPos last_symb_pos;
/* Last symbol position pushed to fifo */
protected SymbPos subdoc_start;
/* child class and level */
protected uint child_tag = 0;
protected uint child_level = 0;
protected bool in_child_params = false;
protected uint child_param_branch_level = 0;
/* back-slash counter for one-line comments */
protected uint back_slash_counter = 0;
public Parser (Array<Link> links) {
/* initializing scanner links */
this.links = links;
/* adjust lexing behaviour to suit our needs */
scanner.config.cset_skip_characters = "";
scanner.config.cset_identifier_first = CharacterSet.a_2_z + CharacterSet.DIGITS + "\\";
scanner.config.cset_identifier_nth = CharacterSet.a_2_z + CharacterSet.A_2_Z + CharacterSet.DIGITS;
scanner.config.cpair_comment_single = "%\n";
scanner.config.scan_float = false;
scanner.config.symbol_2_token = true;
scanner.config.scan_string_sq = false; // See bug #448
scanner.config.scan_string_dq = false; // See bug #448
/* set custom error message handler */
scanner.msg_handler = null;
/* load symbols into the self using GLib Quarks */
load_symbols (links);
/* generate tokens table (tree) */
build_tree (ref tokens, links, false);
/* generate stop_tokens table (tree) */
build_tree (ref stop_tokens, links, true);
/* give the error handler an idea on how the input is named */
scanner.input_name = "TeX text";
}
public abstract IDoc parse (string contents, size_t line, long position) throws ParseError;
void vprefix_error (SymbPos symb_pos, string format, va_list args) {
err_str = "\n" + err_str;
var line = symb_pos.line;
long position = symb_pos.pos;
if (line == 0)
position += this.position;
size_t nlines; long i;
for (i = 0, nlines = 0; contents[i] != '\0' && nlines < line; ++i)
if ('\n' == contents[i] || '\r' == contents[i])
++nlines;
var unparsed_str = contents[i:contents.length].split ("\n"); // FIXME: MacOS newline '\r' characters...
var str = unparsed_str[0][0:position];
var compressed = str.compress ();
position = compressed.length + 1;
var arrow_str = string.nfill (position - 1, ' ') + "^";
compressed = unparsed_str[0].compress ();
str = format.vprintf (args);
err_str = "%s:%lu:%lu: %s\n%s\n%s\n%s".printf (get_type().name(),
this.line + line + 1,
position,
str,
compressed,
arrow_str,
err_str);
}
protected void prefix_error (SymbPos symb_pos, string format, ...) {
var list = va_list ();
vprefix_error (symb_pos, format, list);
}
protected void load_symbols (Array<Link> links) {
for (var i = 1; i < links.length; ++i) {
for (var j = 0; j < links.index (i).begin.length; ++j)
if (links.index (i).begin[j].length > 1)
scanner.scope_add_symbol (0, links.index (i).begin[j], (void*)(Quark.from_string (links.index (i).begin[j]) + TokenType.LAST));
for (var j = 0; j < links.index (i).end.length; ++j)
if (links.index (i).end[j].length > 1)
scanner.scope_add_symbol (0, links.index (i).end[j], (void*)(Quark.from_string (links.index (i).end[j]) + TokenType.LAST));
}
}
protected void build_tree (ref Node<uint> tokens, Array<Link> links, bool stop_tree) {
/* generate tokens table (tree) */
tokens = new Node<uint> ();
for (var i = 1; i < links.length; ++i) {
/* if current class has no begin tags */
if (!stop_tree && links.index (i).begin.length == 0
|| stop_tree && links.index (i).end.length == 0)
continue;
unowned Node<uint> parent_node = tokens;
unowned string[] symb_seq = stop_tree ? links.index (i).end: links.index (i).begin;
Quark symb_quark;
unowned Node child_node;
/* insert begin tags of all links into tree */
for (var j = 0; j < symb_seq.length; ++j) {
assert (symb_seq[j] != null && symb_seq.length != 0);
if (symb_seq[j].length > 1)
symb_quark = Quark.from_string(symb_seq[j]) + TokenType.LAST;
else
symb_quark = symb_seq[j][0];
child_node = parent_node.find_child (TraverseFlags.NON_LEAVES, symb_quark);
/* append node with symb_quark token */
if (child_node == null)
child_node = parent_node.append_data (symb_quark);
parent_node = child_node;
}
/* check for identical tokens lists and be shure that we create leaf for class id */
assert (parent_node.first_child () == null);
/* append leaf with class id */
parent_node.append_data (i);
}
}
protected void count_branches () {
if (in_child_params) {
switch (fifo_peek_head ().token) {
case TokenType.LEFT_CURLY:
case TokenType.LEFT_BRACE:
++child_param_branch_level;
break;
case TokenType.RIGHT_CURLY:
case TokenType.RIGHT_BRACE:
--child_param_branch_level;
break;
default:
break;
}
if (child_param_branch_level == 0
&& TokenType.LEFT_CURLY != fifo_peek_nth(1).token
&& TokenType.LEFT_BRACE != fifo_peek_nth(1).token)
in_child_params = false;
}
}
protected uint fifo_is_tag (Node<uint> tokens, out uint tag) {
uint match_length;
tag = 0;
/* search for tokens subsequence in tokens tree */
for (match_length = 0; ; ++match_length) {
if (tokens == null
|| TokenType.ERROR == fifo_peek_nth (match_length).token
|| TokenType.EOF == fifo_peek_nth (match_length).token) {
match_length = 0;
break;
}
tokens = tokens.find_child (TraverseFlags.NON_LEAVES,
fifo_peek_nth (match_length).token);
if (tokens != null && tokens.first_child().is_leaf()) {
tag = tokens.first_child().data;
++match_length;
break;
}
}
return match_length;
}
protected void fifo_pop () {
var ret = fifo_peek_head ();
if (ret.token != TokenType.ERROR && ret.token != TokenType.EOF)
symb_fifo.pop_head ();
}
protected SymbPos fifo_peek_head () {
if (symb_fifo.length == 0)
fifo_push ();
return symb_fifo.peek_head();
}
protected SymbPos fifo_peek_nth (uint n) {
unowned SymbPos ret;
while (n >= symb_fifo.length && fifo_push ());
if (n < symb_fifo.length)
ret = symb_fifo.peek_nth (n);
else
ret = symb_fifo.peek_tail ();
return ret;
}
bool fifo_push () {
var p = contents.offset (last_symb_pos.abspos);
scanner.get_next_token ();
if ('\\' == scanner.token) {
++back_slash_counter;
if (back_slash_counter % 4 == 0)
scanner.config.cpair_comment_single = "%\n";
else if (back_slash_counter % 2 == 0)
scanner.config.cpair_comment_single = null;
} else {
back_slash_counter = 0;
}
scanner.peek_next_token ();
if (scanner.token == TokenType.ERROR
|| scanner.token == TokenType.EOF) {
if (symb_fifo.length == 0) {
var sp = SymbPos ();
sp.token = scanner.token;
symb_fifo.push_tail (sp);