diff options
-rw-r--r-- | docs/manual/libsigc_manual.xml | 120 | ||||
-rw-r--r-- | docs/manual/meson.build | 13 | ||||
-rw-r--r-- | meson.build | 5 | ||||
-rwxr-xr-x | tools/tutorial-custom-cmd.py | 63 |
4 files changed, 109 insertions, 92 deletions
diff --git a/docs/manual/libsigc_manual.xml b/docs/manual/libsigc_manual.xml index 30645c4..aabdb93 100644 --- a/docs/manual/libsigc_manual.xml +++ b/docs/manual/libsigc_manual.xml @@ -1,26 +1,26 @@ -<?xml version="1.0"?> -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" > -<book id="index" lang="en"> - -<bookinfo> - <title>libsigc++</title> - <author> - <firstname>Ainsley</firstname> - <surname>Pereira</surname> - </author> - - <pubdate>September 2002. Updated January 2004 by Murray Cumming</pubdate> - - <abstract> - <para>libsigc++ is a C++ template library implementing typesafe callbacks. This is an intro to libsigc++.</para> - </abstract> -</bookinfo> - -<chapter id="chapter-introduction"> -<title>Introduction</title> - -<sect1 id="sect-motivation"> -<title>Motivation</title> +<?xml version="1.0" encoding="utf-8"?> +<book xmlns="http://docbook.org/ns/docbook" + xmlns:xlink="http://www.w3.org/1999/xlink" + version="5.0" xml:id="index" xml:lang="en"> + +<info> + <title>libsigc++</title> + <author><personname> + <firstname>Ainsley</firstname> + <surname>Pereira</surname> + </personname></author> + <date>September 2002</date> + <pubdate>September 2002. Updated January 2004 by Murray Cumming</pubdate> + <abstract> + <para>libsigc++ is a C++ template library implementing typesafe callbacks. This is an intro to libsigc++.</para> + </abstract> +</info> + +<chapter xml:id="chapter-introduction"> +<info><title>Introduction</title></info> + +<section xml:id="sect-motivation"> +<info><title>Motivation</title></info> <para>There are many situations in which it is desirable to decouple code that detects an event, and the code that deals with it. This is especially common in @@ -69,14 +69,15 @@ register_click_handler(okbutton, clicked, somedata); <para>For the other side of the fence, libsigc++ provides <literal remap="tt">signal</literal>s, to which the client can attach <literal remap="tt">slot</literal>s. When the <literal remap="tt">signal</literal> is emitted, all the connected <literal remap="tt">slot</literal>s are called.</para> -</sect1> +</section> </chapter> -<chapter id="chapter-connecting"> -<title>Connecting your code to signals</title> +<chapter xml:id="chapter-connecting"> +<info><title>Connecting your code to signals</title></info> + +<section xml:id="sect-simple-ex"> +<info><title>A simple example</title></info> -<sect1 id="sect-simple-ex"> -<title>A simple example</title> <para>So to get some experience, lets look at a simple example...</para> <para>Lets say you and I are writing an application which informs the user when @@ -138,10 +139,10 @@ int main() <programlisting>./example1</programlisting> <para>(Try not to panic when the aliens land!)</para> -</sect1> +</section> -<sect1 id="sect-using-mem-func"> -<title>Using a member function</title> +<section xml:id="sect-using-mem-func"> +<info><title>Using a member function</title></info> <para>Suppose you found a more sophisticated alien alerter class on the web, such as this:</para> @@ -187,10 +188,10 @@ int main() With a lambda expression you would lose the automatic disconnection that the combination of <literal remap="tt">sigc::trackable</literal> and sigc::mem_fun() offers.</para> -</sect1> +</section> -<sect1 id="sect-signals-with-pars"> -<title>Signals with parameters</title> +<section xml:id="sect-signals-with-pars"> +<info><title>Signals with parameters</title></info> <para>Functions taking no parameters and returning void are quite useful, especially when they're members of classes that can store unlimited amounts of @@ -252,10 +253,10 @@ int main() </programlisting> <para>Easy.</para> -</sect1> +</section> -<sect1 id="sect-disconnecting"> -<title>Disconnecting</title> +<section xml:id="sect-disconnecting"> +<info><title>Disconnecting</title></info> <para>If you decide you no longer want your code to be called whenever a signal is emitted, you must remember the return value of <literal remap="tt">connect()</literal>, which we've been @@ -263,14 +264,15 @@ int main() <para><literal remap="tt">connect()</literal> returns a <literal remap="tt">sigc::connection</literal> object, which has a <literal remap="tt">disconnect()</literal> member method. This does just what you think it does.</para> -</sect1> +</section> </chapter> -<chapter id="chapter-writing"> -<title>Writing your own signals</title> +<chapter xml:id="chapter-writing"> +<info><title>Writing your own signals</title></info> + +<section xml:id="sect-quick-recap"> +<info><title>Quick recap</title></info> -<sect1 id="sect-quick-recap"> -<title>Quick recap</title> <para>If all you want to do is use gtkmm, and connect your functionality to its signals, you can probably stop reading here.</para> @@ -315,10 +317,11 @@ void AlienDetector::run() // they landed in the carpark after all. } </programlisting> -</sect1> +</section> + +<section xml:id="sect-return-values"> +<info><title>What about return values?</title></info> -<sect1 id="sect-return-values"> -<title>What about return values?</title> <para>If you only ever have one slot connected to a signal, or if you only care about the return value of the last registered one, it's quite straightforward:</para> @@ -328,14 +331,15 @@ int a_return_value; a_return_value = somesignal.emit(); </programlisting> -</sect1> +</section> </chapter> -<chapter id="chapter-advanced"> -<title>Advanced topics</title> +<chapter xml:id="chapter-advanced"> +<info><title>Advanced topics</title></info> + +<section xml:id="sect-rebinding"> +<info><title>Rebinding</title></info> -<sect1 id="sect-rebinding"> -<title>Rebinding</title> <para>Suppose you already have a function that you want to be called when a signal is emitted, but it takes the wrong argument types. For example, lets try to attach the <literal remap="tt">warn_people(std::string)</literal> function to the detected signal @@ -398,10 +402,11 @@ myaliendetector.signal_detected.connect( sigc::hide<std::string>( sigc::pt hide the first argument of 3, for example, only the last).</para> <para><literal remap="tt">sigc::hide_return</literal> effectively makes the return type void.</para> -</sect1> +</section> + +<section xml:id="sect-retyping"> +<info><title>Retyping</title></info> -<sect1 id="sect-retyping"> -<title>Retyping</title> <para>A similar topic is retyping. Perhaps you have a signal that takes an <literal remap="tt">int</literal>, but you want to connect a function that takes a <literal remap="tt">double</literal>.</para> @@ -420,11 +425,12 @@ asignal.connect( sigc::retype( sigc::ptr_fun(&dostuff) ) ); <para>If you only want to change the return type, you can use <literal remap="tt">sigc::retype_return()</literal>. <literal remap="tt">retype_return()</literal> needs one template argument, the new return type.</para> -</sect1> +</section> </chapter> -<chapter id="chapter-reference"> -<title>Reference</title> - <para>See the reference documentation <ulink url="http://library.gnome.org/devel/libsigc++/unstable/">online</ulink></para> +<chapter xml:id="chapter-reference"> +<info><title>Reference</title></info> + + <para>See the reference documentation <link xlink:href="http://library.gnome.org/devel/libsigc++/2.10/">online</link></para> </chapter> </book> diff --git a/docs/manual/meson.build b/docs/manual/meson.build index 63ac751..bc98af9 100644 --- a/docs/manual/meson.build +++ b/docs/manual/meson.build @@ -1,21 +1,18 @@ # docs/manual # input: install_datadir, sigcxx_pcname, tutorial_custom_cmd, python3, -# build_documentation, install_docdir, can_add_dist_script +# build_documentation, install_docdir, can_add_dist_script, xsltproc # output: can_parse_and_validate, build_pdf_by_default, can_build_pdf, # install_tutorialdir -# xsltproc is required by tutorial_custom_cmd html. -xsltproc = find_program('xsltproc', required: build_documentation) xmllint = find_program('xmllint', required: false) - can_parse_and_validate = xmllint.found() validate = get_option('validation') ? 'true' : 'false' dblatex = find_program('dblatex', required: false) -can_build_pdf = dblatex.found() or (xmllint.found() and \ - find_program('docbook2pdf', required: false).found()) +can_build_pdf = dblatex.found() or (xsltproc.found() and \ + find_program('fop', required: false).found()) build_pdf_by_default = get_option('build-pdf') # Installation directories are relative to {prefix}. @@ -68,13 +65,13 @@ endif if can_build_pdf # Create a PDF file of the DocBook. - # Prefer dblatex, if both dblatex and docbook2pdf are available. + # Prefer dblatex, if both dblatex and fop are available. custom_target('manual_pdf', input: sigc_manual_xml, output: sigc_manual_pdf, command: [ python3, tutorial_custom_cmd, - dblatex.found() ? 'dblatex' : 'docbook2pdf', + dblatex.found() ? 'dblatex' : 'fop', '@INPUT@', '@OUTPUT@' ], diff --git a/meson.build b/meson.build index c75394a..bc8d264 100644 --- a/meson.build +++ b/meson.build @@ -141,7 +141,6 @@ sys.exit(os.path.isfile("@0@")) endif # Check if perl is required and available. -# Done now, when the doc_reference script is available. doc_perl_prop = run_command( python3, doc_reference, 'get_script_property', '', # MMDOCTOOLDIR is not used @@ -298,11 +297,9 @@ endif build_pdf = build_pdf_by_default and can_build_pdf explain_pdf = '' if build_pdf_by_default and not build_pdf - explain_pdf = ' (requires dblatex or (xmllint and docbook2pdf))' + explain_pdf = ' (requires dblatex or (xsltproc and fop))' endif - - summary = [ '', '------', diff --git a/tools/tutorial-custom-cmd.py b/tools/tutorial-custom-cmd.py index f0a8a18..50b6a5b 100755 --- a/tools/tutorial-custom-cmd.py +++ b/tools/tutorial-custom-cmd.py @@ -8,7 +8,6 @@ import os import sys import subprocess -from pathlib import Path import shutil subcommand = sys.argv[1] @@ -29,7 +28,7 @@ def html(): '--stringparam', 'chunker.output.indent', 'yes', '--stringparam', 'chunker.output.encoding', 'UTF-8', '--stringparam', 'toc.list.type', 'ul', - '--stringparam', 'use.id.as.filename', '1', + '--param', 'use.id.as.filename', '1', ] xslt_stylesheet = 'http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl' @@ -56,6 +55,8 @@ def html(): return result.returncode def xmllint(): + from pathlib import Path + # argv[2] argv[3] argv[4] # <validate> <input_xml_file> <stamp_file_path> @@ -63,6 +64,8 @@ def xmllint(): input_xml_file = sys.argv[3] stamp_file_path = sys.argv[4] + relax_ng_schema = 'http://docbook.org/xml/5.0/rng/docbook.rng' + cmd = [ 'xmllint', '--noout', @@ -70,7 +73,7 @@ def xmllint(): '--xinclude', ] if validate == 'true': - cmd += ['--postvalid'] + cmd += ['--relaxng', relax_ng_schema] cmd += [input_xml_file] result = subprocess.run(cmd) if result.returncode: @@ -79,6 +82,9 @@ def xmllint(): Path(stamp_file_path).touch(exist_ok=True) return 0 +# dblatex and xsltproc+fop generate a PDF file. +# docbook2pdf can generate PDF files from DocBook4 files, but not from DocBook5 files. +# xsltproc+xmlroff (version 0.6.3) does not seem to work acceptably. def dblatex(): # argv[2] argv[3] # <input_xml_file> <output_pdf_file> @@ -89,40 +95,51 @@ def dblatex(): # For a list of available parameters, see http://dblatex.sourceforge.net/doc/manual/ dblatex_params = [ - '-P', 'toc.section.depth=2', + '-P', 'toc.section.depth=1', '-P', 'paper.type=a4paper', + '-P', 'doc.collab.show=1', + '-P', 'latex.output.revhistory=0', ] cmd = [ 'dblatex', ] + dblatex_params + [ '-o', output_pdf_file, - '--pdf', input_xml_file, + '--pdf', + input_xml_file, ] return subprocess.run(cmd).returncode -def docbook2pdf(): +def fop(): # argv[2] argv[3] # <input_xml_file> <output_pdf_file> - # Create a PDF file, using docbook2pdf. + # Create a PDF file, using fop. input_xml_file = sys.argv[2] output_pdf_file = sys.argv[3] - output_dir = os.path.dirname(output_pdf_file) - if not output_dir: - output_dir = '.' - output_basename = os.path.basename(output_pdf_file) - if output_basename.endswith('.pdf'): - output_basename = output_basename[:-4] - xml_file = os.path.join(output_dir, output_basename + '.xml') + fo_file = os.path.splitext(output_pdf_file)[0] + '.fo' + + # For a list of available parameters, see http://docbook.sourceforge.net/release/xsl/current/doc/fo/ + # For a list of available paper types, see the description of the page.width.portrait parameter. + xslt_params = [ + '--param', 'toc.section.depth', '1', + '--stringparam', 'fop1.extensions', '1', + '--stringparam', 'page.orientation', 'portrait', + '--stringparam', 'paper.type', 'A4', + ] + + xslt_stylesheet = 'http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl' - # We need to produce an XML file with all of the XIncludes done. + # Generate a .fo (formatting object) file. + # fop can take an xslt stylesheet parameter, but it can only read local files. + # xsltproc is necessary if you want to read the stylesheet from the internet. cmd = [ - 'xmllint', + 'xsltproc', + ] + xslt_params + [ + '-o', fo_file, '--xinclude', - '--postvalid', - '--output', xml_file, + xslt_stylesheet, input_xml_file, ] result = subprocess.run(cmd) @@ -130,9 +147,9 @@ def docbook2pdf(): return result.returncode cmd = [ - 'docbook2pdf', - '--output', output_dir, - xml_file, + 'fop', + '-fo', fo_file, + '-pdf', output_pdf_file, ] return subprocess.run(cmd).returncode @@ -177,8 +194,8 @@ if subcommand == 'xmllint': sys.exit(xmllint()) if subcommand == 'dblatex': sys.exit(dblatex()) -if subcommand == 'docbook2pdf': - sys.exit(docbook2pdf()) +if subcommand == 'fop': + sys.exit(fop()) if subcommand == 'dist_doc': sys.exit(dist_doc()) print(sys.argv[0], ': illegal subcommand,', subcommand) |