Warning, /DD4hep/cmake/PANDOC.cmake is written in an unsupported language. File is not indexed.
0001 ################################################################################
0002 ##
0003 ## Provide Pandoc compilation support for the CMake build system
0004 ##
0005 ## Version: 0.0.1
0006 ## Author: Jeet Sukumatan (jeetsukumaran@gmail.com)
0007 ##
0008 ## Copyright 2015 Jeet Sukumaran.
0009 ##
0010 ## This software is released under the BSD 3-Clause License.
0011 ##
0012 ## Redistribution and use in source and binary forms, with or without
0013 ## modification, are permitted provided that the following conditions are
0014 ## met:
0015 ##
0016 ## 1. Redistributions of source code must retain the above copyright notice,
0017 ## this list of conditions and the following disclaimer.
0018 ##
0019 ## 2. Redistributions in binary form must reproduce the above copyright
0020 ## notice, this list of conditions and the following disclaimer in the
0021 ## documentation and/or other materials provided with the distribution.
0022 ##
0023 ## 3. Neither the name of the copyright holder nor the names of its
0024 ## contributors may be used to endorse or promote products derived from this
0025 ## software without specific prior written permission.
0026 ##
0027 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
0028 ## IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0029 ## THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0030 ## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
0031 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0032 ## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0033 ## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0034 ## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0035 ## LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0036 ## NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0037 ## SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0038 ##
0039 ################################################################################
0040
0041 include(CMakeParseArguments)
0042
0043 if(NOT EXISTS ${PANDOC_EXECUTABLE})
0044 # find_program(PANDOC_EXECUTABLE NAMES pandoc)
0045 find_program(PANDOC_EXECUTABLE pandoc)
0046 mark_as_advanced(PANDOC_EXECUTABLE)
0047 if(NOT EXISTS ${PANDOC_EXECUTABLE})
0048 unset(PANDOC_EXECUTABLE)
0049 return()
0050 endif()
0051 endif()
0052
0053 ###############################################################################
0054 # Based on code from UseLATEX
0055 # Author: Kenneth Moreland <kmorel@sandia.gov>
0056 # Copyright 2004 Sandia Corporation.
0057 # Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
0058 # license for use of this work by or on behalf of the
0059 # U.S. Government. Redistribution and use in source and binary forms, with
0060 # or without modification, are permitted provided that this Notice and any
0061 # statement of authorship are reproduced on all copies.
0062
0063 # Adds command to copy file from the source directory to the destination
0064 # directory: used to move source files from source directory into build
0065 # directory before main build
0066 function(pandocology_add_input_file source_path dest_dir dest_filelist_var)
0067 set(dest_filelist)
0068 file(GLOB globbed_source_paths "${source_path}")
0069 foreach(globbed_source_path ${globbed_source_paths})
0070 # MESSAGE(FATAL_ERROR "${globbed_source_path}")
0071 if(NOT IS_ABSOLUTE ${globbed_source_path})
0072 get_filename_component(filename ${globbed_source_path} NAME)
0073 get_filename_component(absolute_dest_path ${dest_dir}/${filename} ABSOLUTE)
0074 file(RELATIVE_PATH relative_dest_path ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_path})
0075 list(APPEND dest_filelist ${absolute_dest_path})
0076
0077 add_custom_command(
0078 OUTPUT ${relative_dest_path}
0079 COMMAND ${CMAKE_COMMAND} -E copy ${globbed_source_path} ${dest_dir}/${filename}
0080 DEPENDS ${globbed_source_path}
0081 )
0082 else()
0083 list(APPEND dest_filelist ${globbed_source_path})
0084 endif()
0085 set(${dest_filelist_var} ${${dest_filelist_var}} ${dest_filelist} PARENT_SCOPE)
0086 endforeach()
0087 endfunction()
0088
0089 # A version of GET_FILENAME_COMPONENT that treats extensions after the last
0090 # period rather than the first.
0091 function(pandocology_get_file_stemname varname filename)
0092 SET(result)
0093 GET_FILENAME_COMPONENT(name ${filename} NAME)
0094 STRING(REGEX REPLACE "\\.[^.]*\$" "" result "${name}")
0095 SET(${varname} "${result}" PARENT_SCOPE)
0096 endfunction()
0097
0098 function(pandocology_get_file_extension varname filename)
0099 SET(result)
0100 GET_FILENAME_COMPONENT(name ${filename} NAME)
0101 STRING(REGEX MATCH "\\.[^.]*\$" result "${name}")
0102 SET(${varname} "${result}" PARENT_SCOPE)
0103 endfunction()
0104 ###############################################################################
0105
0106 function(pandocology_add_input_dir source_dir dest_parent_dir dir_dest_filelist_var)
0107 set(dir_dest_filelist)
0108 get_filename_component(dir_name ${source_dir} NAME)
0109 get_filename_component(absolute_dest_dir ${dest_parent_dir}/${dir_name} ABSOLUTE)
0110 file(RELATIVE_PATH relative_dest_dir ${CMAKE_CURRENT_BINARY_DIR} ${absolute_dest_dir})
0111 add_custom_command(
0112 OUTPUT ${relative_dest_dir}
0113 COMMAND ${CMAKE_COMMAND} -E make_directory ${absolute_dest_dir}
0114 DEPENDS ${source_dir}
0115 )
0116 file(GLOB source_files "${source_dir}/*")
0117 foreach(source_file ${source_files})
0118 # get_filename_component(absolute_source_path ${CMAKE_CURRENT_SOURCE_DIR}/${source_file} ABSOLUTE)
0119 pandocology_add_input_file(${source_file} ${absolute_dest_dir} dir_dest_filelist)
0120 endforeach()
0121 set(${dir_dest_filelist_var} ${${dir_dest_filelist_var}} ${dir_dest_filelist} PARENT_SCOPE)
0122 endfunction()
0123
0124 function(add_to_make_clean filepath)
0125 get_directory_property(make_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
0126 set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${make_clean_files};${filepath}")
0127 endfunction()
0128
0129 function(disable_insource_build)
0130 IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE )
0131 MESSAGE(FATAL_ERROR "The build directory must be different from the main project source "
0132 "directory. Please create a directory such as '${CMAKE_SOURCE_DIR}/build', "
0133 "and run CMake from there, passing the path to this source directory as "
0134 "the path argument. E.g.:
0135 $ cd ${CMAKE_SOURCE_DIR}
0136 $ mkdir build
0137 $ cd build
0138 $ cmake .. && make && sudo make install
0139 This process created the file `CMakeCache.txt' and the directory `CMakeFiles'.
0140 Please delete them:
0141 $ rm -r CMakeFiles/ CmakeCache.txt
0142 ")
0143 ENDIF()
0144 endfunction()
0145
0146 # This builds a document
0147 #
0148 # Usage:
0149 #
0150 #
0151 # INCLUDE(pandocology)
0152 #
0153 # add_document(
0154 # figures.tex
0155 # SOURCES figures.md
0156 # RESOURCE_DIRS figs
0157 # PANDOC_DIRECTIVES -t latex
0158 # NO_EXPORT_PRODUCT
0159 # )
0160 #
0161 # add_document(
0162 # opus.pdf
0163 # SOURCES opus.md
0164 # RESOURCE_FILES opus.bib systbiol.template.latex systematic-biology.csl
0165 # RESOURCE_DIRS figs
0166 # PANDOC_DIRECTIVES -t latex
0167 # --smart
0168 # --template systbiol.template.latex
0169 # --filter pandoc-citeproc
0170 # --csl systematic-biology.csl
0171 # --bibliography opus.bib
0172 # --include-after-body=figures.tex
0173 # DEPENDS figures.tex
0174 # EXPORT_ARCHIVE
0175 # )
0176 #
0177 function(add_document target_name)
0178 set(options EXPORT_ARCHIVE NO_EXPORT_PRODUCT EXPORT_PDF DIRECT_TEX_TO_PDF VERBOSE)
0179 set(oneValueArgs PRODUCT_DIRECTORY)
0180 set(multiValueArgs SOURCES RESOURCE_FILES RESOURCE_DIRS PANDOC_DIRECTIVES DEPENDS)
0181 cmake_parse_arguments(ADD_DOCUMENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
0182
0183 # this is because `make clean` will dangerously clean up source files
0184 disable_insource_build()
0185
0186 # get the stem of the target name
0187 pandocology_get_file_stemname(target_stemname ${target_name})
0188 pandocology_get_file_extension(target_extension ${target_name})
0189 if (${ADD_DOCUMENT_EXPORT_PDF})
0190 if (NOT "${target_extension}" STREQUAL ".tex" AND NOT "${target_extension}" STREQUAL ".latex")
0191 # if (NOT "${target_extension}" STREQUAL ".tex")
0192 MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'EXPORT_PDF' for target of type '${target_extension}': target type must be '.tex' or '.latex'")
0193 endif()
0194 endif()
0195 if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF})
0196 list(LENGTH ${ADD_DOCUMENT_SOURCES} SOURCE_LEN)
0197 if (SOURCE_LEN GREATER 1)
0198 MESSAGE(FATAL_ERROR "Target '${target_name}': Only one source can be specified when using the 'DIRECT_TEX_TO_PDF' option")
0199 endif()
0200 # set(ADD_DOCUMENT_SOURCES, list(GET ${ADD_DOCUMENT_SOURCES} 1))
0201 pandocology_get_file_stemname(source_stemname ${ADD_DOCUMENT_SOURCES})
0202 pandocology_get_file_extension(source_extension ${ADD_DOCUMENT_SOURCES})
0203 if (NOT "${source_extension}" STREQUAL ".tex" AND NOT "${source_extension}" STREQUAL ".latex")
0204 MESSAGE(FATAL_ERROR "Target '${target_name}': Cannot use 'DIRECT_TEX_TO_PDF' for source of type '${source_extension}': source type must be '.tex' or '.latex'")
0205 endif()
0206 SET(check_target ${source_stemname}.pdf)
0207 IF (NOT ${check_target} STREQUAL ${target_name})
0208 MESSAGE(FATAL_ERROR "Target '${target_name}': Must use target name of '${check_target}' if using 'DIRECT_TEX_TO_PDF'")
0209 endif()
0210 endif()
0211
0212 ## set up output directory
0213 if ("${ADD_DOCUMENT_PRODUCT_DIRECTORY}" STREQUAL "")
0214 set(ADD_DOCUMENT_PRODUCT_DIRECTORY "product")
0215 endif()
0216 get_filename_component(product_directory ${CMAKE_BINARY_DIR}/${ADD_DOCUMENT_PRODUCT_DIRECTORY} ABSOLUTE)
0217 # get_filename_component(absolute_product_path ${product_directory}/${target_name} ABSOLUTE)
0218
0219 ## get primary source
0220 set(build_sources)
0221 foreach(input_file ${ADD_DOCUMENT_SOURCES} )
0222 if(NOT IS_ABSOLUTE ${input_file})
0223 set(input_file ${CMAKE_CURRENT_SOURCE_DIR}/${input_file})
0224 endif()
0225 pandocology_add_input_file(${input_file} ${CMAKE_CURRENT_BINARY_DIR} build_sources)
0226 endforeach()
0227
0228 ## get resource files
0229 set(build_resources)
0230 foreach(resource_file ${ADD_DOCUMENT_RESOURCE_FILES})
0231 if(NOT IS_ABSOLUTE ${resource_file})
0232 set(resource_file ${CMAKE_CURRENT_SOURCE_DIR}/${resource_file})
0233 endif()
0234 pandocology_add_input_file(${resource_file} ${CMAKE_CURRENT_BINARY_DIR} build_resources)
0235 endforeach()
0236
0237 ## get resource dirs
0238 set(exported_resources)
0239 foreach(resource_dir ${ADD_DOCUMENT_RESOURCE_DIRS})
0240 if(NOT IS_ABSOLUTE ${resource_file})
0241 set(resource_dir ${CMAKE_CURRENT_SOURCE_DIR}/${resource_dir})
0242 endif()
0243 pandocology_add_input_dir(${resource_dir} ${CMAKE_CURRENT_BINARY_DIR} build_resources)
0244 if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
0245 pandocology_add_input_dir(${resource_dir} ${product_directory} exported_resources)
0246 endif()
0247 endforeach()
0248
0249 ## primary command
0250 if (${ADD_DOCUMENT_DIRECT_TEX_TO_PDF})
0251 if (${ADD_DOCUMENT_VERBOSE})
0252 add_custom_command(
0253 OUTPUT ${target_name} # note that this is in the build directory
0254 DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0255 # WORKING_DIRECTORY ${working_directory}
0256 COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
0257 # we produce the target in the source directory, in case other build targets require it as a source
0258 COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources}
0259 )
0260 else()
0261 add_custom_command(
0262 OUTPUT ${target_name} # note that this is in the build directory
0263 DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0264 # WORKING_DIRECTORY ${working_directory}
0265 COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
0266 # we produce the target in the source directory, in case other build targets require it as a source
0267 COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${build_sources} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false)
0268 )
0269 endif()
0270 add_to_make_clean(${target_name})
0271 else()
0272 add_custom_command(
0273 OUTPUT ${target_name} # note that this is in the build directory
0274 DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0275 # WORKING_DIRECTORY ${working_directory}
0276 COMMAND ${CMAKE_COMMAND} -E make_directory ${product_directory}
0277 # we produce the target in the source directory, in case other build targets require it as a source
0278 COMMAND ${PANDOC_EXECUTABLE} ${build_sources} ${ADD_DOCUMENT_PANDOC_DIRECTIVES} -o ${target_name}
0279 )
0280 add_to_make_clean(${target_name})
0281 endif()
0282
0283 ## figure out what all is going to be produced by this build set, and set
0284 ## those as dependencies of the primary target
0285 set(primary_target_dependencies)
0286 set(primary_target_dependencies ${primary_target_dependencies} ${target_name})
0287 if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT})
0288 set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_name})
0289 endif()
0290 if (${ADD_DOCUMENT_EXPORT_PDF})
0291 set(primary_target_dependencies ${primary_target_dependencies} ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf)
0292 set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.pdf)
0293 endif()
0294 if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
0295 set(primary_target_dependencies ${primary_target_dependencies} ${product_directory}/${target_stemname}.tbz)
0296 endif()
0297
0298 # run post-pdf
0299 if (${ADD_DOCUMENT_EXPORT_PDF})
0300 # get_filename_component(target_stemname ${target_name} NAME_WE)
0301 add_custom_command(
0302 OUTPUT ${product_directory}/${target_stemname}.pdf ${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf
0303 DEPENDS ${target_name} ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0304
0305 # Does not work: custom template used to generate tex is ignored
0306 # COMMAND ${PANDOC_EXECUTABLE} ${target_name} -f latex -o ${target_stemname}.pdf
0307
0308 # (1) Apparently, both nonstopmode and batchmode produce an output file
0309 # even if there was an error. This tricks latexmk into believing
0310 # the file is actually up-to-date.
0311 # So we use `-halt-on-error` or `-interaction=errorstopmode`
0312 # instead.
0313 # (2) `grep` returns a non-zero error code if the pattern is not
0314 # found. So, in our scheme below to filter the output of
0315 # `pdflatex`, it is precisely when there is NO error that
0316 # grep returns a non-zero code, which fools CMake into thinking
0317 # tex'ing failed.
0318 # Hence the need for `| grep ...| cat` or `| grep || true`.
0319 # But we can go better:
0320 # latexmk .. || (grep .. && false)
0321 # So we can have our cake and eat it too: here we want to
0322 # re-raise the error after a successful grep if there was an
0323 # error in `latexmk`.
0324 # COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>&1 | grep -A8 ".*:[0-9]*:.*" || true
0325 COMMAND latexmk -gg -halt-on-error -interaction=nonstopmode -file-line-error -pdf ${target_name} 2>/dev/null >/dev/null || (grep --no-messages -A8 ".*:[0-9]*:.*" ${target_stemname}.log && false)
0326
0327 COMMAND ${CMAKE_COMMAND} -E copy ${target_stemname}.pdf ${product_directory}
0328 )
0329 add_to_make_clean(${CMAKE_CURRENT_BINARY_DIR}/${target_stemname}.pdf)
0330 add_to_make_clean(${product_directory}/${target_stemname}.pdf)
0331 endif()
0332
0333 ## copy products
0334 if (NOT ${ADD_DOCUMENT_NO_EXPORT_PRODUCT})
0335 add_custom_command(
0336 OUTPUT ${product_directory}/${target_name}
0337 DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0338 COMMAND ${CMAKE_COMMAND} -E copy ${target_name} ${product_directory}
0339 )
0340 add_to_make_clean(${product_directory}/${target_name})
0341 endif()
0342
0343 ## copy resources
0344 if (${ADD_DOCUMENT_EXPORT_ARCHIVE})
0345 # get_filename_component(target_stemname ${target_name} NAME_WE)
0346 # add_custom_command(
0347 # TARGET ${target_name} POST_BUILD
0348 # DEPENDS ${build_sources} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0349 # # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory}
0350 # COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0351 # )
0352 add_custom_command(
0353 OUTPUT ${product_directory}/${target_stemname}.tbz
0354 DEPENDS ${target_name}
0355 # COMMAND cp ${build_resources} ${ADD_DOCUMENT_DEPENDS} ${product_directory}
0356 COMMAND ${CMAKE_COMMAND} -E tar cjf ${product_directory}/${target_stemname}.tbz ${target_name} ${build_resources} ${ADD_DOCUMENT_DEPENDS}
0357 )
0358 add_to_make_clean(${product_directory}/${target_stemname}.tbz)
0359 # add_custom_target(
0360 # ${target_stemname}.ARCHIVE
0361 # ALL
0362 # DEPENDS ${product_directory}/${target_stemname}.tbz
0363 # )
0364 endif()
0365
0366 endfunction(add_document)
0367
0368 function(add_pandoc_document)
0369 add_document(${ARGV})
0370 endfunction()