]> git.saurik.com Git - apt.git/blob - CMake/Documentation.cmake
CMake: Discover docbook stylesheet in other locations
[apt.git] / CMake / Documentation.cmake
1 # po4a/docbook documentation support for CMake
2 # - see documentation of add_docbook()
3 #
4 # Copyright (C) 2016 Julian Andres Klode <jak@debian.org>.
5 #
6 # Permission is hereby granted, free of charge, to any person
7 # obtaining a copy of this software and associated documentation files
8 # (the "Software"), to deal in the Software without restriction,
9 # including without limitation the rights to use, copy, modify, merge,
10 # publish, distribute, sublicense, and/or sell copies of the Software,
11 # and to permit persons to whom the Software is furnished to do so,
12 # subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be
15 # included in all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 # SOFTWARE.
25
26
27 find_path(DOCBOOK_XSL manpages/docbook.xsl
28 # Debian
29 /usr/share/xml/docbook/stylesheet/docbook-xsl
30 /usr/share/xml/docbook/stylesheet/nwalsh
31 # OpenSUSE
32 /usr/share/xml/docbook/stylesheet/nwalsh/current
33 # Arch
34 /usr/share/xml/docbook/xsl-stylesheets
35 # Fedora
36 /usr/share/sgml/docbook/xsl-stylesheets
37 # Fink
38 ${CMAKE_INSTALL_PREFIX}/share/xml/xsl/docbook-xsl
39 # FreeBSD
40 ${CMAKE_INSTALL_PREFIX}/share/xsl/docbook/
41 NO_DEFAULT_PATH)
42
43 if(NOT DOCBOOK_XSL)
44 message(FATAL_ERROR "Could not find docbook xsl")
45 endif()
46
47 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docbook-text-style.xsl.cmake.in
48 ${CMAKE_CURRENT_BINARY_DIR}/docbook-text-style.xsl)
49 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/docbook-html-style.xsl.cmake.in
50 ${CMAKE_CURRENT_BINARY_DIR}/docbook-html-style.xsl)
51 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/manpage-style.xsl.cmake.in
52 ${CMAKE_CURRENT_BINARY_DIR}/manpage-style.xsl)
53
54
55 # Split up a string of the form DOCUMENT[.DOCUMENT][.LANGUAGE][.SECTION].EXTENSION
56 #
57 # There might be up to two parts in the document name. The language must be
58 # a two char language code like de, or a 5 char code of the form de_DE.
59 function(po4a_components doc lang sec ext translated_full_document)
60 get_filename_component(name ${translated_full_document} NAME)
61 string(REPLACE "." ";" name "${name}") # Make it a list
62
63 list(GET name 0 _doc) # First element is always the document
64 list(GET name 1 _lang) # Second *might* be a language
65 list(GET name -2 _sec) # Second-last *might* be a section
66 list(GET name -1 _ext) # Last element is always the file type
67
68 # If the language code is neither a file type, nor a section, nor a language
69 # assume it is part of the file name and use the next component as the lang.
70 if(_lang AND NOT _lang MATCHES "^(xml|dbk|[0-9]|[a-z][a-z]|[a-z][a-z]_[A-Z][A-Z])$")
71 set(_doc "${_doc}.${_lang}")
72 list(GET name 2 _lang)
73 endif()
74 # If no language is present, we get a section; both not present => type
75 if(_lang MATCHES "xml|dbk|[0-9]")
76 set(_lang "")
77 endif()
78 if(NOT _sec MATCHES "^[0-9]$") # A (manpage) section must be a number
79 set(_sec "")
80 endif()
81
82 set(${doc} ${_doc} PARENT_SCOPE)
83 set(${lang} ${_lang} PARENT_SCOPE)
84 set(${sec} ${_sec} PARENT_SCOPE)
85 set(${ext} ${_ext} PARENT_SCOPE)
86 endfunction()
87
88
89 # Process one document
90 function(po4a_one stamp_out out full_document language deps)
91 path_join(full_path "${CMAKE_CURRENT_SOURCE_DIR}" "${full_document}")
92 po4a_components(document _ section ext "${full_document}")
93
94 # Calculate target file name
95 set(dest "${language}/${document}.${language}")
96 if(section)
97 set(dest "${dest}.${section}")
98 endif()
99
100 # po4a might drop files not translated enough, so build a stamp file
101 set(stamp ${CMAKE_CURRENT_BINARY_DIR}/${dest}.po4a-stamp)
102 add_custom_command(
103 OUTPUT ${stamp}
104 COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${language}
105 COMMAND po4a --previous --no-backups
106 --package-name='${PROJECT_NAME}-doc'
107 --package-version='${PACKAGE_VERSION}'
108 --msgid-bugs-address='${PACKAGE_MAIL}'
109 --translate-only ${dest}.${ext}
110 --srcdir ${CMAKE_CURRENT_SOURCE_DIR}
111 --destdir ${CMAKE_CURRENT_BINARY_DIR}
112 ${CMAKE_CURRENT_SOURCE_DIR}/po4a.conf
113 COMMAND ${CMAKE_COMMAND} -E touch ${stamp}
114 COMMENT "Generating ${dest}.${ext} (or dropping it)"
115 DEPENDS ${full_document} ${deps} po/${language}.po
116 )
117 # Return result
118 set(${stamp_out} ${stamp} PARENT_SCOPE)
119 set(${out} ${CMAKE_CURRENT_BINARY_DIR}/${dest}.${ext} PARENT_SCOPE)
120 endfunction()
121
122 function(xsltproc_one)
123 set(generated "")
124 set(options HTML TEXT MANPAGE)
125 set(oneValueArgs STAMP STAMP_OUT FULL_DOCUMENT)
126 set(multiValueArgs INSTALL DEPENDS)
127 cmake_parse_arguments(DOC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
128
129 po4a_components(document language section ext "${DOC_FULL_DOCUMENT}")
130
131 # Default parameters
132 set(params
133 --nonet
134 --xinclude
135 --stringparam chunk.quietly yes
136 --stringparam man.output.quietly yes
137 --path ${PROJECT_SOURCE_DIR}/vendor/${CURRENT_VENDOR}/
138 --path ${CMAKE_CURRENT_SOURCE_DIR}/
139 )
140
141 # Parameters if localized
142 if(language)
143 list(APPEND params -stringparam l10n.gentext.default.language ${language})
144 endif()
145
146 path_join(full_input_path ${CMAKE_CURRENT_SOURCE_DIR} ${DOC_FULL_DOCUMENT})
147
148 if (DOC_MANPAGE)
149 if (language)
150 set(manpage_output "${CMAKE_CURRENT_BINARY_DIR}/${language}/${document}.${section}")
151 else()
152 set(manpage_output "${CMAKE_CURRENT_BINARY_DIR}/${document}.${section}")
153 endif()
154 set(manpage_stylesheet "${CMAKE_CURRENT_BINARY_DIR}/manpage-style.xsl")
155 set(manpage_params)
156
157 install(FILES ${manpage_output}
158 DESTINATION ${CMAKE_INSTALL_MANDIR}/${language}/man${section}
159 OPTIONAL)
160 endif()
161 if (DOC_HTML)
162 if (language)
163 set(html_output "${CMAKE_CURRENT_BINARY_DIR}/${language}/${document}.${language}.html")
164 else()
165 set(html_output "${CMAKE_CURRENT_BINARY_DIR}/${document}.html")
166 endif()
167 set(html_params --stringparam base.dir ${html_output})
168 set(html_stylesheet "${CMAKE_CURRENT_BINARY_DIR}/docbook-html-style.xsl")
169 install(DIRECTORY ${html_output}
170 DESTINATION ${DOC_INSTALL}
171 OPTIONAL)
172
173 endif()
174 if (DOC_TEXT)
175 if (language)
176 set(text_output "${CMAKE_CURRENT_BINARY_DIR}/${language}/${document}.${language}.text")
177 else()
178 set(text_output "${CMAKE_CURRENT_BINARY_DIR}/${document}.text")
179 endif()
180 set(text_params --stringparam base.dir ${text_output})
181 set(text_stylesheet "${CMAKE_CURRENT_BINARY_DIR}/docbook-text-style.xsl")
182
183 file(RELATIVE_PATH text_output_relative ${CMAKE_CURRENT_BINARY_DIR} ${text_output})
184
185 add_custom_command(OUTPUT ${text_output}.w3m-stamp
186 COMMAND ${PROJECT_SOURCE_DIR}/CMake/run_if_exists.sh
187 --stdout ${text_output}
188 ${text_output}.html
189 env LC_ALL=C.UTF-8 w3m -cols 78 -dump
190 -o display_charset=UTF-8
191 -no-graph -T text/html ${text_output}.html
192 COMMAND ${CMAKE_COMMAND} -E touch ${text_output}.w3m-stamp
193 COMMENT "Generating ${text_output_relative} (if not dropped by po4a)"
194 DEPENDS "${text_output}.html.xsltproc-stamp"
195 )
196 list(APPEND generated ${text_output}.w3m-stamp)
197
198 install(FILES ${text_output}
199 DESTINATION ${DOC_INSTALL}
200 OPTIONAL)
201 set(text_output "${text_output}.html")
202 endif()
203
204 foreach(type in manpage html text)
205 if (NOT ${type}_output)
206 continue()
207 endif()
208
209 set(output ${${type}_output})
210 set(stylesheet ${${type}_stylesheet})
211 set(type_params ${${type}_params})
212 file(RELATIVE_PATH output_relative ${CMAKE_CURRENT_BINARY_DIR} ${output})
213
214 add_custom_command(OUTPUT ${output}.xsltproc-stamp
215 COMMAND ${PROJECT_SOURCE_DIR}/CMake/run_if_exists.sh
216 ${full_input_path}
217 xsltproc ${params} ${type_params} -o ${output}
218 ${stylesheet}
219 ${full_input_path}
220 COMMAND ${CMAKE_COMMAND} -E touch ${output}.xsltproc-stamp
221 COMMENT "Generating ${output_relative} (if not dropped by po4a)"
222 DEPENDS ${DOC_STAMP} ${DOC_DEPENDS})
223
224 list(APPEND generated ${output}.xsltproc-stamp)
225 endforeach()
226
227 set(${DOC_STAMP_OUT} ${generated} PARENT_SCOPE)
228 endfunction()
229
230
231 # add_docbook(Name [ALL] [HTML] [TEXT] [MANPAGE]
232 # [INSTALL install dir]
233 # [DEPENDS depend ...]
234 # [DOCUMENTS documents ...]
235 # [LINGUAS lingua ...])
236 #
237 # Generate a target called name with all the documents being converted to
238 # the chosen output formats and translated to the chosen languages using po4a.
239 #
240 # For the translation support, the po4a.conf must be written so that
241 # translations for a document guide.xml are written to LANG/guide.LANG.xml,
242 # and for a manual page man.5.xml to a file called LANG/man.LANG.5.xml.
243 #
244 # The guide and manual page names may also contain a second component separated
245 # by a dot, it must however not be a valid language code.
246 #
247 # Note that po4a might chose not to generate a translated manual page for a
248 # given language if the translation rate is not high enough. We deal with this
249 # by creating stamp files.
250 function(add_docbook target)
251 set(generated "")
252 set(options HTML TEXT MANPAGE ALL)
253 set(oneValueArgs)
254 set(multiValueArgs INSTALL DOCUMENTS LINGUAS DEPENDS)
255 cmake_parse_arguments(DOC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
256
257 if (DOC_HTML)
258 list(APPEND formats HTML)
259 endif()
260 if (DOC_TEXT)
261 list(APPEND formats TEXT)
262 endif()
263 if (DOC_MANPAGE)
264 list(APPEND formats MANPAGE)
265 endif()
266
267 foreach(document ${DOC_DOCUMENTS})
268 foreach(lang ${DOC_LINGUAS})
269 po4a_one(po4a_stamp po4a_out ${document} "${lang}" "${DOC_DEPENDS}")
270 xsltproc_one(STAMP_OUT xslt_stamp
271 STAMP ${po4a_stamp}
272 FULL_DOCUMENT ${po4a_out}
273 INSTALL ${DOC_INSTALL}
274 ${formats})
275
276 list(APPEND stamps ${xslt_stamp})
277 endforeach()
278 xsltproc_one(STAMP_OUT xslt_stamp
279 STAMP ${document}
280 FULL_DOCUMENT ${document}
281 INSTALL ${DOC_INSTALL}
282 ${formats})
283
284 list(APPEND stamps ${xslt_stamp})
285 endforeach()
286
287 if (DOC_ALL)
288 add_custom_target(${target} ALL DEPENDS ${stamps})
289 else()
290 add_custom_target(${target} DEPENDS ${stamps})
291 endif()
292 endfunction()
293
294 # Add an update-po4a target
295 function(add_update_po4a target pot header)
296 set(WRITE_HEADER "")
297
298 if (header)
299 set(WRITE_HEADER
300 COMMAND sed -n "/^\#$/,$p" ${pot} > ${pot}.headerfree
301 COMMAND cat ${header} ${pot}.headerfree > ${pot}
302 COMMAND rm ${pot}.headerfree
303 )
304 endif()
305 add_custom_target(${target}
306 COMMAND po4a --previous --no-backups --force --no-translations
307 --msgmerge-opt --add-location=file
308 --porefs noline,wrap
309 --package-name=${PROJECT_NAME}-doc --package-version=${PACKAGE_VERSION}
310 --msgid-bugs-address=${PACKAGE_MAIL} po4a.conf
311 ${WRITE_HEADER}
312 VERBATIM
313 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
314 )
315 endfunction()