]> git.donarmstrong.com Git - lilypond.git/commitdiff
Merge branch 'master' of ssh://jomand@git.sv.gnu.org/srv/git/lilypond into dev/texi2html
authorJohn Mandereau <john.mandereau@gmail.com>
Tue, 2 Sep 2008 10:23:03 +0000 (12:23 +0200)
committerJohn Mandereau <john.mandereau@gmail.com>
Tue, 2 Sep 2008 10:23:03 +0000 (12:23 +0200)
* 'master' of ssh://jomand@git.sv.gnu.org/srv/git/lilypond:
  Phrasing_slur_engraver: acknowledge tuplet numbers.
  Docs: Add web links in Meta(Post|Font) requirements
  Update translations status
  Fetch POs from Free Translation Project
  Docs: Translate converters.itely to German
  Docs: Update command line options of the converters
  Further German updates
  Updates to German fundamental.itely
  Add spaces after comma in C code
  Compile fix
  New snippet for dotted harmonics.
  flags regression test: better formatting
  Layout tweaks for flags-default.ly regression test.
  NR 1.2.4.3 Manual beams
  German translation updates
  Updates to the music glossary
  Add the Scheme flags to the NEWS
  Change flag creation to use the 'flag prop (function returning the stencil)
  LM Index Introduction
  Doc-es: Update of tutorial

56 files changed:
Documentation/GNUmakefile
Documentation/bibliography/GNUmakefile
Documentation/de/user/GNUmakefile
Documentation/de/user/macros.itexi
Documentation/es/index.html.in
Documentation/es/user/GNUmakefile
Documentation/es/user/lilypond-learning.tely
Documentation/es/user/macros.itexi
Documentation/fr/user/GNUmakefile
Documentation/fr/user/macros.itexi
Documentation/index.html.in
Documentation/lilypond-ie-fixes.css [new file with mode: 0644]
Documentation/lilypond.css [new file with mode: 0644]
Documentation/misc/GNUmakefile
Documentation/pictures/GNUmakefile
Documentation/topdocs/GNUmakefile
Documentation/topdocs/NEWS.tely
Documentation/user/GNUmakefile
Documentation/user/macros.itexi
Documentation/user/music-glossary.tely
GNUmakefile.in
buildscripts/add_html_footer.py [deleted file]
buildscripts/check_translation.py
buildscripts/extract_texi_filenames.py [new file with mode: 0755]
buildscripts/html-gettext.py
buildscripts/postprocess_html.py [new file with mode: 0644]
buildscripts/tely-gettext.py [new file with mode: 0755]
buildscripts/translations-status.py
buildscripts/www_post.py
config.make.in
configure.in
input/lsr/GNUmakefile
input/lsr/lilypond-snippets.tely
lilypond-texi2html.init [new file with mode: 0644]
make/doc-i18n-root-targets.make
make/doc-i18n-user-rules.make [new file with mode: 0644]
make/doc-i18n-user-targets.make [new file with mode: 0644]
make/doc-i18n-user-vars.make [new file with mode: 0644]
make/doclang-rules.make [deleted file]
make/doclang-targets.make [deleted file]
make/doclang-vars.make [deleted file]
make/generic-vars.make
make/ly-rules.make
make/lysdoc-rules.make
make/lysdoc-targets.make
make/lysdoc-vars.make
make/mutopia-targets.make
scm/document-backend.scm
scm/documentation-generate.scm
scm/documentation-lib.scm
stepmake/stepmake/documentation-targets.make
stepmake/stepmake/generic-targets.make
stepmake/stepmake/texinfo-rules.make
stepmake/stepmake/texinfo-targets.make
stepmake/stepmake/texinfo-vars.make
stepmake/stepmake/topdocs-targets.make

index d265a1ee96fc1bc1a3f3c3f576e24c7a1cc5218d..53243aa542c618657ac9313d83d455a6b1478d73 100644 (file)
@@ -16,7 +16,7 @@ OUT_HTML_FILES= $(HTML_PAGE_NAMES:%=$(outdir)/%.html)
 
 default: local-doc
 
-local-WWW: txt-to-html $(OUT_HTML_FILES)
+local-WWW-2: txt-to-html $(OUT_HTML_FILES)
 
 local-WWW-clean: deep-WWW-clean
 
@@ -86,14 +86,14 @@ fix-xrefs:
        $(DOCUMENTS_INCLUDES) $(buildscript-dir)/manuals_definitions.py
 
 check-translation:
-       $(PYTHON) $(buildscript-dir)/check_translation.py $(buildscript-dir) $(CHECKED_FILES)
+       $(PYTHON) $(buildscript-dir)/check_translation.py $(CHECKED_FILES)
 
 update-translation:
-       $(PYTHON) $(buildscript-dir)/check_translation.py --update $(buildscript-dir) $(CHECKED_FILES)
+       $(PYTHON) $(buildscript-dir)/check_translation.py --update $(CHECKED_FILES)
 
 translation-status:
        make -C po out=www messages
-       $(PYTHON) $(buildscript-dir)/translations-status.py $(buildscript-dir)
+       $(PYTHON) $(buildscript-dir)/translations-status.py
 
 local-help: extra-local-help
 
index 4a7bab0111c2d95cbecf46a17422039dce875ece..89eb2d0bcbdde74bedc256b49a832e3edb5bbebd 100644 (file)
@@ -1,4 +1,4 @@
-# Documentation/tex/Makefile
+# Documentation/bibliography/Makefile
 
 depth=../..
 
@@ -18,10 +18,10 @@ ps: $(PS_FILES)
 # urg
 default:
 
-GENHTMLS = engraving colorado  computer-notation
+GENHTMLS = engraving colorado computer-notation
 OUTGENHTMLS = $(addprefix $(outdir)/, $(GENHTMLS:%=%.html))
 
-local-WWW: $(addprefix $(outdir)/, $(BIB_FILES:.bib=.html) index.html)
+local-WWW-2: $(addprefix $(outdir)/, $(BIB_FILES:.bib=.html) index.html)
 
 $(outdir)/%.bib: %.bib
        ln -f $< $@
index 662d176be1211627d892f31f916b79908d9b5a6a..50042f40cbe0c94b2b39495b192c1710d006dc86 100644 (file)
@@ -1,5 +1,4 @@
 ISOLANG = de
 depth = ../../..
-LOCALSTEPMAKE_TEMPLATES = lilypond ly doclang
+LOCALSTEPMAKE_TEMPLATES = lilypond ly doc-i18n-user
 include $(depth)/make/stepmake.make
-
index 9114eea63908a4028c31e1d82b2c02850e091fac..05db816617075e12e39f188a8e91085a013d531a 100644 (file)
 
 @macro rinternals{TEXT}
 @vindex \TEXT\
-@code{\TEXT\}
+@ref{\TEXT\,,,lilypond-internals,Programmreferenz}
 @end macro
 
 @macro rinternalsnamed{TEXT,DISPLAY}
 @vindex \TEXT\
-@code{\DISPLAY\}
+@ref{\TEXT\,,\DISPLAY\,lilypond-internals,Programmreferenz}
 @end macro
 
 @end iftex
index ca25d52ad07c7ffb9a660aee655b15788cd6ac0b..98ced1df05af54978f44bcf74f8e142b37f58bd7 100644 (file)
@@ -49,8 +49,8 @@
          <ul>
             <li>
               <a class="title" href="user/lilypond-learning/index.es.html">Manual de aprendizaje</a><br>
-              (también en <a class="title" href="user/lilypond-learning-big-page.html">una sola
-              página</a> [en inglés] ~ 1.5 Mb, o en <a class="title" href="user/lilypond-learning.es.pdf">PDF</a>)<br>
+              (también en <a class="title" href="user/lilypond-learning-big-page.es.html">una sola
+              página</a> ~ 1.5 Mb, o en <a class="title" href="user/lilypond-learning.es.pdf">PDF</a>)<br>
               (comience por aquí)
 
             <li>
index 4928d752525e7bf3553c786c4d6931fec19ea5da..06916b973377df5fbfe9885380825ca12ad368a9 100644 (file)
@@ -1,5 +1,5 @@
 ISOLANG = es
 depth = ../../..
-LOCALSTEPMAKE_TEMPLATES = lilypond ly doclang
+LOCALSTEPMAKE_TEMPLATES = lilypond ly doc-i18n-user
+BIG_PAGE_MANUALS = lilypond-learning
 include $(depth)/make/stepmake.make
-
index aa40da765c69b4c5704ddae1f6dc9b183da8f293..2bc817d8cfe6827ec3b207b566d7360511822900 100644 (file)
@@ -36,7 +36,7 @@
 @ifhtml
 Este documento también está disponible como
 @uref{source/Documentation/user/lilypond-learning.es.pdf,PDF} y como
-@uref{source/Documentation/user/lilypond-learning-big-page.html,una sola página enorme}.
+@uref{source/Documentation/user/lilypond-learning-big-page.es.html,una sola página enorme}.
 @end ifhtml
 
 
index a4d2e178909d9cb943cb6db481c5b7a8f82dddbf..cd0a574efda6286838b3243cebca5ec1eb135df5 100644 (file)
 
 @macro rinternals{TEXT}
 @vindex \TEXT\
-@code{\TEXT\}
+@ref{\TEXT\,,,lilypond-internals,Referencia de Funcionamiento Interno}
 @end macro
 
 @macro rinternalsnamed{TEXT,DISPLAY}
 @vindex \TEXT\
-@code{\DISPLAY\}
+@ref{\TEXT\,,\DISPLAY\,lilypond-internals,Referencia de Funcionamiento Interno}
 @end macro
 
 @end iftex
index e492cfeb9c1166f13a2e75d8c556133bb901fc49..a7defa6c44509a5a8d71096b0f8c8e7e5aa18891 100644 (file)
@@ -1,5 +1,4 @@
 ISOLANG = fr
 depth = ../../..
-LOCALSTEPMAKE_TEMPLATES = lilypond ly doclang
+LOCALSTEPMAKE_TEMPLATES = lilypond ly doc-i18n-user
 include $(depth)/make/stepmake.make
-
index 78c4e03c1dd1141fb1e49cea1dc2e69f2a802f36..096dcf59cf2e8c446a78875b2199052354453384 100644 (file)
 
 @macro rinternals{TEXT}
 @vindex \TEXT\
-@code{\TEXT\}
+@ref{\TEXT\,,,lilypond-internals,Référence des propriétés internes}
 @end macro
 
 @macro rinternalsnamed{TEXT,DISPLAY}
 @vindex \TEXT\
-@code{\DISPLAY\}
+@ref{\TEXT\,,,lilypond-internals,Référence des propriétés internes}
 @end macro
 
 @end iftex
index 3822b3a2bfa9721a2020e2658c3666fb304413b8..3e8439017b975355ab5e793b9706d4b012c4bfb6 100644 (file)
@@ -88,9 +88,10 @@ in <a class="title" href="user/lilypond.pdf">PDF</a>)
        <li>
  <a  class="title"
 href="user/lilypond-internals/index.html">Internals Reference</a>
- (in <a class="title" href="user/lilypond-internals-big-page.html">one big page</a> ~ 1 MB)
+ (in <a class="title" href="user/lilypond-internals-big-page.html">one big page</a> ~ 1 MB,
+  in <a class="title" href="user/lilypond-internals.pdf">PDF</a>)
      <br>(definitions for tweaking)
-        
+
   </ul>
          </td>
          <td valign="baseline" class="right-column">
diff --git a/Documentation/lilypond-ie-fixes.css b/Documentation/lilypond-ie-fixes.css
new file mode 100644 (file)
index 0000000..8a06890
--- /dev/null
@@ -0,0 +1,28 @@
+/***********************************************************/
+/*                    TOC SIDEBAR                          */
+/***********************************************************/
+body {
+  height: 100%;
+  font-size: 100%;
+  min-height: 0;
+}
+
+/***********************************************************/
+/*                    MAIN CONTENT                         */
+/***********************************************************/
+
+div#main {
+  min-height: 0;
+  height: 100%;
+  width: 73%;
+  overflow-x: auto;
+}
+
+/***********************************************************/
+/*                    TOC SIDEBAR                          */
+/***********************************************************/
+
+div#tocframe {
+  height: 100%;
+  width: 27%;
+}  
diff --git a/Documentation/lilypond.css b/Documentation/lilypond.css
new file mode 100644 (file)
index 0000000..3fd59d3
--- /dev/null
@@ -0,0 +1,183 @@
+/***********************************************************/
+/*                  PAGE-WIDE SETTINGS                     */
+/**********************************************************/
+
+html {
+  height:100%;
+}
+
+body {
+  margin: 0;
+  padding: 0;
+  height: 100%;
+  font-size: 100%;
+  margin-right: auto;
+  margin-left: auto;
+}
+
+/***********************************************************/
+/*                      HEADERS                            */
+/***********************************************************/
+h2 {
+  font-size: x-large;
+  color: #1d7b85;
+}
+.unnumberedsubsubsec, .subsubheading {
+  font-size: large;
+  color: #1d7b85;
+}
+
+/***********************************************************/
+/*                       LINKS                             */
+/***********************************************************/
+a {
+  color: #344242;
+}
+a:visited {
+  color: #666666;
+}
+a:active {
+  color: #00cccc;
+}
+a:hover {
+  color: #1d7b85;
+  text-decoration:underline;
+}
+
+/***********************************************************/
+/*                  BLOCK FORMATTING                       */
+/***********************************************************/
+blockquote {
+  border: 1px solid #cccccc;
+  padding: 3px;
+  width: 40em;
+}
+.verbatim, .example {
+  font-family: "Courier New",Courier,monospace;
+}
+hr {
+  border:  none;
+  height: 1px;
+  color: #666666;
+  background-color: #666666;
+}
+table.cartouche {
+  border: 2px dotted #cccccc;
+  margin-left: auto;
+  margin-right: auto;
+  width: 85%;
+}
+table.cartouche td {
+  border: none;
+}
+
+/***********************************************************/
+/*                    MAIN CONTENT                         */
+/***********************************************************/
+
+div#main {
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 27%;
+  padding: 0 1em;
+  margin: 0;
+  overflow: auto;
+}
+
+#languages {
+  padding-bottom: 1em;
+}
+
+/***********************************************************/
+/*                    TOC SIDEBAR                          */
+/***********************************************************/
+
+div#tocframe {
+  position:      absolute;
+  top:           0;
+  right: 73%;
+  bottom: 0;
+  left:          0;
+  padding:       5px;
+  padding-bottom: 0;
+  margin: 0;
+  overflow:      auto;
+  background-color: #FFFACD;
+  z-index:100;
+  list-style-type: none;
+}
+
+@media screen {
+  body>div#tocframe {
+    position: fixed
+    }
+  }
+
+#tocframe .contents {
+  width: 100%;
+  padding-bottom: 0.25em;
+  border: none;
+  margin: 0em;
+  background-color: transparent;
+  list-style-type: none;
+}
+
+#tocframe ul.toc {
+  padding-left: 0px;
+  margin-left: 0px;
+}
+#tocframe ul.toc li {
+ padding-left: 0px;
+  margin-left: 0px;
+  list-style-type: none;
+}
+#tocframe ul.toc > li {
+  font-size: 12px;
+}
+#tocframe ul.toc li li {
+  padding-left: 15px;
+}
+li.toc_current {
+  font-weight: bold;
+  font-style: italic;
+}
+
+li.toc_current ul {
+  font-weight: normal;
+  font-style: normal;
+  background: transparent;
+}
+
+
+
+
+/***********************************************************/
+/*                     NAVIGATION                          */
+/***********************************************************/
+
+.nav_table {
+  width: 100%;
+  background-color: #CCC;
+  border: 0;
+  margin-top: 4px;
+  left: auto;
+  right: auto;
+  font-size: 0.8em;
+}
+
+
+
+
+
+
+/***********************************************************/
+/*               OVERRIDES FOR PRINTING...                 */
+/***********************************************************/
+@media print {
+  /* Hide the sidebar: */
+  body { padding-left: 0; }
+  #tocframe { display: none; }
+  .nav_table { display: none; }
+}
\ No newline at end of file
index b84aa786b88b3e0e7c9cd72bd6e7adf1f34131e5..bb3beb4998c5b63018cc8d6bd322ef457452b74d 100644 (file)
@@ -14,7 +14,7 @@ default: local-doc
 #urg default local-WWW target uses footify before its time;
 # must add footify with txt-to-html target
 OUT_TXT_FILES = $(addprefix $(outdir)/, $(addsuffix .txt, $(TEXTS)))
-##local-WWW: $(OUT_TXT_FILES) $(OUT_HTMLFILES) txt-to-html
+##local-WWW-2: $(OUT_TXT_FILES) $(OUT_HTMLFILES) txt-to-html
 
 copy-for-me:
        $(foreach a, $(README_TOP_FILES), cp ../$(a) $(outdir)/$(a).txt && ) true
index 6665721085fd801f3c05c859c171f22d1ee13c0b..438389f944b8e088354abf71a7cd64f126b7b8d6 100644 (file)
@@ -21,5 +21,4 @@ endif # PLATFORM_WINDOWS
 local-dist: $(icon) 
 xgifs: $(OUTGIF_FILES)
 pngs: $(OUTPNG_FILES)
-local-WWW: $(OUTPNG_FILES)
-
+local-WWW-1: $(OUTPNG_FILES)
index 7e2d2641d936b38afdf1f685d541f6588d7f532c..537f761b0a8f847f578e16c0a8f99f12d664dad1 100644 (file)
@@ -3,6 +3,7 @@ depth = ../..
 
 STEPMAKE_TEMPLATES=documentation tex texinfo topdocs
 LOCALSTEPMAKE_TEMPLATES=lilypond ly
+OUT_TEXI_FILES = $(TELY_FILES:%.tely=$(outdir)/%.texi)
 HTML_FILES=$(TEXI_FILES:%.texi=$(outdir)/%.html) $(TELY_FILES:%.tely=$(outdir)/%.html)
 PDF_FILES=$(outdir)/NEWS.pdf
 README_TOP_FILES=NEWS AUTHORS INSTALL README
@@ -11,6 +12,9 @@ OUTTXT_FILES= $(outdir)/NEWS.txt
 include $(depth)/make/stepmake.make
 
 MAKEINFO_FLAGS += -I $(top-src-dir)/Documentation/user
+TEXI2HTML_FLAGS += -I $(top-src-dir)/Documentation/user
+
+local-WWW-1: $(OUT_TEXI_FILES)
 
 .SECONDARY:
 
index 5c9629593c1a16f9ddd0fa404e8c283997e88d7e..a676c2d699f29214288f6f338d9158a449d8852c 100644 (file)
@@ -250,7 +250,7 @@ performance, page layout, MIDI results and warnings.  This helps to
 reduce the number of regression errors during development, resulting
 in more stable releases.
 
-See @uref{INSTALL.html#testing} for more information.
+See @uref{INSTALL.html#Testing-LilyPond} for more information.
 @item
 Nested properties, such as @code{details} in @code{Slur}, can be
 reverted as well.  The syntax for this is
index 243c16441354cd0d6c9181f61a6cb2da186a8e40..eacbf70f241df48627a285b1a31a702d309b514c 100644 (file)
@@ -16,11 +16,16 @@ OUT_PNG_IMAGES=$(OUT_PDF_IMAGES:%.pdf=%.png)
 
 OUT_TEXI_FILES=$(ITEXI_FILES:%.itexi=$(outdir)/%.texi)\
  $(ITELY_FILES:%.itely=$(outdir)/%.texi)
+
+MASTER_TEXI_FILES = $(TELY_FILES:%.tely=$(outdir)/%.texi)\
+ $(outdir)/lilypond-internals.texi
+
 HTML_FILES = $(TELY_FILES:%.tely=$(outdir)/%-big-page.html)\
  $(outdir)/lilypond-internals-big-page.html
 
 # todo: add latex.
-PDF_FILES = $(TELY_FILES:%.tely=$(outdir)/%.pdf)
+PDF_FILES = $(TELY_FILES:%.tely=$(outdir)/%.pdf)\
+ $(outdir)/lilypond-internals.pdf
 
 MAIN_INFO_DOC = lilypond
 INFO_DOCS = lilypond lilypond-internals music-glossary lilypond-program lilypond-learning
@@ -58,8 +63,6 @@ extra-local-help:
   xml        update Docbook xml documentation\n\
 "
 
-# Generic rule using % twice not possible?
-# $(outdir)/%/%.html: $(outdir)/%.texi
 $(outdir)/lilypond.texi: $(outdir)/lilypond-internals.texi
 
 #
@@ -107,7 +110,7 @@ DEEP_HTML_FILES =\
 
 # Symlinks to refer to external source documents from split and non-split HTML
 source-links = $(outdir)/source $(outdir)/lilypond/source $(outdir)/music-glossary/source \
- $(outdir)/lilypond-program/source $(outdir)/lilypond-learning/source
+ $(outdir)/lilypond-program/source $(outdir)/lilypond-learning/source $(outdir)/lilypond-internals/source
 
 $(outdir)/source:
        @rm -f $(@)
@@ -118,13 +121,13 @@ $(outdir)/%/source:
        mkdir -p $(dir $@)
        ln -sf $(depth)/.. $(@)
 
-local-WWW: $(HTML_FILES) $(DEEP_HTML_FILES)\
- $(datafiles) $(PDF_FILES) $(source-links) info
+local-WWW-1: $(MASTER_TEXI_FILES) $(PDF_FILES) info
+
+local-WWW-2: $(HTML_FILES) $(DEEP_HTML_FILES) $(source-links)
 
 $(outdir)/%.bib: %.bib
        ln -f $< $@
 
-
 # lilypond.texi deps
 $(top-build-dir)/mf/$(outconfbase)/feta16list.ly:
        $(MAKE) -C $(top-src-dir)/mf
@@ -141,9 +144,4 @@ $(outdir)/lilypond.texi $(outdir)/lilypond-program.texi $(outdir)/lilypond-learn
 $(outdir)/lilypond-internals.texi: $(LILYPOND_BINARY)
        cd $(outdir) && $(LILYPOND_BINARY) --verbose $(top-src-dir)/ly/generate-documentation
 
-
-## unused
-$(outdir)/interfaces.itexi: dummy
-       cd $(outdir) && lilypond $(top-src-dir)/ly/generate-interface-doc
-
 .SECONDARY:
index 07cf74a547fc187bf6d24aac8b3cdbcfee89369b..6801ff4f340e70543408206944b9c2c95680e163 100644 (file)
 @ref{\TEXT\,,\DISPLAY\,lilypond-learning,Learning Manual}
 @end macro
 
+@macro rlearningnamed{TEXT,DISPLAY}
+learning manual, @ref{\TEXT\,,\DISPLAY\,lilypond-learning,Learning Manual}
+@end macro
+
 @macro ruser{TEXT}
 @ref{\TEXT\,,,lilypond,Notation Reference}
 @end macro
 @ref{\TEXT\,,\DISPLAY\,lilypond,Notation Reference}
 @end macro
 
+@macro rusernamed{TEXT,DISPLAY,DISPLAY}
+notation reference, @ref{\TEXT\,,\DISPLAY\,lilypond,Notation Reference}
+@end macro
+
 @macro rprogram{TEXT}
 @ref{\TEXT\,,,lilypond-program,Application Usage}
 @end macro
 @ref{\TEXT\,,\DISPLAY\,lilypond-program,Application Usage}
 @end macro
 
+@macro rprogramnamed{TEXT,DISPLAY}
+program usage manual, @ref{\TEXT\,,\DISPLAY\,lilypond-program,Application Usage}
+@end macro
+
 @macro rlsr{TEXT}
 @ref{\TEXT\,,,lilypond-snippets,Snippets}
 @end macro
 
 @macro rinternals{TEXT}
 @vindex \TEXT\
-@code{\TEXT\}
+@ref{\TEXT\,,,lilypond-internals,Internals Reference}
 @end macro
 
 @macro rinternalsnamed{TEXT,DISPLAY}
 @vindex \TEXT\
-@code{\DISPLAY\}
+@ref{\TEXT\,,\DISPLAY\,lilypond-internals,Internals Reference}
 @end macro
 
 @end iftex
index d3ccb660705bf63f4bcb9da459679eb6379f0a1b..b33d3fc2fc053169e3636604d76670d029495725 100644 (file)
@@ -129,6 +129,9 @@ documentation, see @rlearning{About the documentation}.
 * Pitch names::                 
 @end menu
 
+@contents
+
+
 @node Musical terms A-Z
 @chapter Musical terms A-Z
 
index 146d3af083ca3611ce9e53c3dfd005d346a55264..0e30f80d3c5c8618ff019dead2226fb96bee37a4 100644 (file)
@@ -86,12 +86,12 @@ final-install:
 # For both online and offline docs, issue `make web WEB_TARGETS="offline online"'
 WEB_TARGETS = offline
 
-local-WWW-post:
+WWW-post:
 # need UTF8 setting in case this is hosted on a website. 
        echo -e 'AddDefaultCharset utf-8\nAddCharset utf-8 .html\nAddCharset utf-8 .en\nAddCharset utf-8 .nl\nAddCharset utf-8 .txt\n' > $(top-build-dir)/.htaccess
        $(PYTHON) $(buildscript-dir)/mutopia-index.py -o $(outdir)/examples.html input/
        find $(outdir) -name '*-root' | xargs rm -rf
-       $(PYTHON) $(buildscript-dir)/www_post.py $(PACKAGE_NAME) $(TOPLEVEL_VERSION) $(buildscript-dir) $(outdir) "$(WEB_TARGETS)"
+       $(PYTHON) $(buildscript-dir)/www_post.py $(PACKAGE_NAME) $(TOPLEVEL_VERSION) $(outdir) "$(WEB_TARGETS)"
        find $(outdir)/offline-root -type l -delete
 
 
diff --git a/buildscripts/add_html_footer.py b/buildscripts/add_html_footer.py
deleted file mode 100644 (file)
index f063132..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-#!@PYTHON@
-
-"""
-Print a nice footer.
-"""
-import re
-import os
-import time
-
-import langdefs
-
-# This is to try to make the docball not too big with almost duplicate files
-# see process_links()
-non_copied_pages = ['Documentation/user/out-www/lilypond-big-page',
-                    'Documentation/user/out-www/lilypond-internals-big-page',
-                    'Documentation/user/out-www/lilypond-learning-big-page',
-                    'Documentation/user/out-www/lilypond-program-big-page',
-                    'Documentation/user/out-www/music-glossary-big-page',
-                    'out-www/examples',
-                    'Documentation/topdocs',
-                    'Documentation/bibliography',
-                    'Documentation/out-www/THANKS',
-                    'Documentation/out-www/DEDICATION',
-                    'Documentation/out-www/devel',
-                    'input/']
-
-def _doc (s):
-    return s
-
-header = r"""
-"""
-
-footer = '''
-<div style="background-color: #e8ffe8; padding: 2; border: #c0ffc0 1px solid;">
-<p>
-<font size="-1">
-%(footer_name_version)s
-<br>
-<address>
-%(footer_report_errors)s </address>
-<br>
-%(footer_suggest_docs)s
-</font>
-</p>
-</div>
-'''
-footer_name_version = _doc ('This page is for %(package_name)s-%(package_version)s (%(branch_str)s).')
-footer_report_errors = _doc ('Report errors to <a href="%(mail_address_url)s">%(mail_address)s</a>.')
-# ugh, must not have "_doc" in strings because it is naively replaced with "_" in hacked gettext process
-footer_suggest_docs = _doc ('Your <a href="%(suggest_Docs_url)s">suggestions for the documentation</a> are welcome.')
-
-mail_address = 'http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs'
-suggest_Docs_url = 'http://lilypond.org/web/devel/participating/documentation-adding'
-
-header_tag = '<!-- header_tag -->'
-footer_tag = '<!-- footer_tag -->'
-
-lang_available = _doc ("Other languages: %s.")
-browser_lang = _doc ('About <A HREF="%s">automatic language selection</A>.')
-browser_language_url = "/web/about/browser-language"
-
-LANGUAGES_TEMPLATE = '''
-<P>
- %(language_available)s
- <BR>
- %(browser_language)s
-</P>
-'''
-
-
-html_re = re.compile ('(.*?)(?:[.]([^/.]*))?[.]html$')
-pages_dict = {}
-
-def build_pages_dict (filelist):
-    """Build dictionary of available translations of each page"""
-    global pages_dict
-    for f in filelist:
-        m = html_re.match (f)
-        if m:
-            g = m.groups()
-            if len (g) <= 1 or g[1] == None:
-                e = ''
-            else:
-                e = g[1]
-            if not g[0] in pages_dict:
-                pages_dict[g[0]] = [e]
-            else:
-                pages_dict[g[0]].append (e)
-
-def source_links_replace (m, source_val):
-    return 'href="' + os.path.join (source_val, m.group (1)) + '"'
-
-splitted_docs_re = re.compile ('(input/lsr/out-www/lilypond-snippets|Documentation/user/out-www/(lilypond|music-glossary|lilypond-program|lilypond-learning))/')
-
-snippets_ref_re = re.compile (r'href="(\.\./)?lilypond-snippets')
-user_ref_re = re.compile (r'href="(?:\.\./)?lilypond(|-internals|-learning|-program)')
-
-## Windows does not support symlinks.
-# This function avoids creating symlinks for splitted HTML manuals
-# Get rid of symlinks in GNUmakefile.in (local-WWW-post)
-# this also fixes missing PNGs only present in translated docs
-def hack_urls (s, prefix):
-    if splitted_docs_re.match (prefix):
-        s = re.sub ('(href|src)="(../lily-.*?|.*?[.]png)"', '\\1="../\\2"', s)
-
-    # fix xrefs between documents in different directories ad hoc
-    if 'user/out-www/lilypond' in prefix:
-        s = snippets_ref_re.sub ('href="source/input/lsr/lilypond-snippets', s)
-    elif 'input/lsr' in prefix:
-        s = user_ref_re.sub ('href="source/Documentation/user/lilypond\\1', s)
-
-    source_path = os.path.join (os.path.dirname (prefix), 'source')
-    if not os.path.islink (source_path):
-        return s
-    source_val = os.readlink (source_path)
-    return re.sub ('href="source/(.*?)"', lambda m: source_links_replace (m, source_val), s)
-
-def add_header (s):
-    """Add header (<BODY> and doctype)"""
-    if re.search (header_tag, s) == None:
-        body = '<BODY BGCOLOR=WHITE TEXT=BLACK>'
-        s = re.sub ('(?i)<body>', body, s)
-        if re.search ('(?i)<BODY', s):
-            s = re.sub ('(?i)<body[^>]*>', body + header, s, 1)
-        elif re.search ('(?i)<html', s):
-            s = re.sub ('(?i)<html>', '<HTML>' + header, s, 1)
-        else:
-            s = header + s
-
-        s = header_tag + '\n' + s
-
-        if re.search ('(?i)<!DOCTYPE', s) == None:
-            doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n'
-            s = doctype + s
-        return s
-
-def add_title (s):
-    # urg
-    # maybe find first node?
-    fallback_web_title = '-- --'
-    m = re.match ('.*?<title>(.*?)</title>', s, re.DOTALL)
-    if m:
-        fallback_web_title = m.group (1)
-    s = re.sub ('@WEB-TITLE@', fallback_web_title, s)
-    return s
-
-info_nav_bar = re.compile (r'<div class="node">\s*<p>\s*<a name=".+?"></a>(.+?)<hr>\s*</div>', re.M | re.S)
-info_footnote_hr = re.compile (r'<hr>\s*(</div>)?\s*</body>', re.M | re.I)
-
-def add_footer (s):
-    """add footer
-
-also add navigation bar to bottom of Info HTML pages"""
-    m = info_nav_bar.search (s)
-    if m:
-        # avoid duplicate <hr> in case there are footnotes at the end of the Info HTML page
-        if info_footnote_hr.search (s):
-            custom_footer = '<div class="node">\n<p>' + m.group (1) + '</div>\n' + footer
-        else:
-            custom_footer = '<br><hr>\n<div class="node">\n<p>' + m.group (1) + '</div>\n' + footer
-    else:
-        custom_footer = footer
-    if re.search ('(?i)</body', s):
-        s = re.sub ('(?i)</body>', footer_tag + custom_footer + '\n' + '</BODY>', s, 1)
-    elif re.search ('(?i)</html', s):                
-        s = re.sub ('(?i)</html>', footer_tag + custom_footer + '\n' + '</HTML>', s, 1)
-    else:
-        s += footer_tag + custom_footer + '\n'
-    return s
-
-def find_translations (prefix, lang_ext):
-    """find available translations of a page"""
-    available = []
-    missing = []
-    for l in langdefs.LANGUAGES:
-        e = l.webext
-        if lang_ext != e:
-            if e in pages_dict[prefix]:
-                available.append (l)
-            elif lang_ext == '' and l.enabled and reduce (lambda x, y: x and y, [not prefix.startswith (s) for s in non_copied_pages]):
-                # English version of missing translated pages will be written
-                missing.append (e)
-    return available, missing
-
-def process_links (s, prefix, lang_ext, file_name, missing, target):
-    page_flavors = {}
-    if target == 'online':
-        # Strip .html, .png suffix for auto language selection (content
-        # negotiation).  The menu must keep the full extension, so do
-        # this before adding the menu.
-        page_flavors[file_name] = [lang_ext, re.sub (
-            '''(href|src)=[\'"]([^/][.]*[^.:\'"]*)(.html|.png)(#[^"\']*|)[\'"]''',
-            '\\1="\\2\\4"', s)]
-    elif target == 'offline':
-        # in LANG doc index: don't rewrite .html suffixes as not all .LANG.html pages exist
-        # the doc index should be translated and contain the right links
-        if prefix == 'Documentation/out-www/index':
-            page_flavors[file_name] = [lang_ext, s]
-        elif lang_ext == '':
-            page_flavors[file_name] = [lang_ext, s]
-            for e in missing:
-                page_flavors[langdefs.lang_file_name (prefix, e, '.html')] = [e, re.sub (
-                    '''href=[\'"]([^/][.]*[^.:\'"]*)(.html)(#[^"\']*|)[\'"]''',
-                    'href="\\1.' + e + '\\2\\3"', s)]
-        else:
-            page_flavors[file_name] = [lang_ext, re.sub (
-                '''href=[\'"]([^/][.]*[^.:\'"]*)(.html)(#[^"\']*|)[\'"]''',
-                'href="\\1.' + lang_ext + '\\2\\3"', s)]
-    return page_flavors
-
-def add_menu (page_flavors, prefix, available, target, translation):
-    for k in page_flavors:
-        language_menu = ''
-        languages = ''
-        if page_flavors[k][0] != '':
-            t = translation[page_flavors[k][0]]
-        else:
-            t = _doc
-        for lang in available:
-            lang_file = lang.file_name (os.path.basename (prefix), '.html')
-            if language_menu != '':
-                language_menu += ', '
-            language_menu += '<a href="%s">%s</a>' % (lang_file, t (lang.name))
-        if target == 'offline':
-            browser_language = ''
-        elif target == 'online':
-            browser_language = t (browser_lang) % browser_language_url
-        if language_menu:
-            language_available = t (lang_available) % language_menu
-            languages = LANGUAGES_TEMPLATE % vars ()
-        # put language menu before '</body>' and '</html>' tags
-        if re.search ('(?i)</body', page_flavors[k][1]):
-            page_flavors[k][1] = re.sub ('(?i)</body>', languages + '</BODY>', page_flavors[k][1], 1)
-        elif re.search ('(?i)</html', page_flavors[k][1]):
-            page_flavors[k][1] = re.sub ('(?i)</html>', languages + '</HTML>', page_flavors[k][1], 1)
-        else:
-            page_flavors[k][1] += languages
-    return page_flavors
-
-
-def add_html_footer (package_name = '',
-                     package_version = '',
-                     target = 'offline',
-                     name_filter = lambda s: s):
-    """Add header, footer to a number of HTML files
-
-    Arguments:
-     package_name=NAME         set package_name to NAME
-     package_version=VERSION   set package version to VERSION
-     targets=offline|online    set page processing depending on the target
-          offline is for reading HTML pages locally
-          online is for hosting the HTML pages on a website with content
-            negotiation
-     name_filter               a HTML file name filter
-    """
-    translation = langdefs.translation
-    localtime = time.strftime ('%c %Z', time.localtime (time.time ()))
-
-    if "http://" in mail_address:
-        mail_address_url = mail_address
-    else:
-        mail_address_url= 'mailto:' + mail_address
-
-    versiontup = package_version.split ('.')
-    branch_str = _doc ('stable-branch')
-    if int (versiontup[1]) %  2:
-        branch_str = _doc ('development-branch')
-
-    # Initialize dictionaries for string formatting
-    subst = {}
-    subst[''] = dict ([i for i in globals ().items() if type (i[1]) is str])
-    subst[''].update (dict ([i for i in locals ().items() if type (i[1]) is str]))
-    for l in translation:
-        e = langdefs.LANGDICT[l].webext
-        if e:
-            subst[e] = {}
-            for name in subst['']:
-                subst[e][name] = translation[l] (subst[''][name])
-    # Do deeper string formatting as early as possible,
-    # so only one '%' formatting pass is needed later
-    for e in subst:
-        subst[e]['footer_name_version'] = subst[e]['footer_name_version'] % subst[e]
-        subst[e]['footer_report_errors'] = subst[e]['footer_report_errors'] % subst[e]
-        subst[e]['footer_suggest_docs'] = subst[e]['footer_suggest_docs'] % subst[e]
-
-    for prefix, ext_list in pages_dict.items ():
-        for lang_ext in ext_list:
-            file_name = langdefs.lang_file_name (prefix, lang_ext, '.html')
-            in_f = open (file_name)
-            s = in_f.read()
-            in_f.close()
-
-            s = re.sub ('%', '%%', s)
-            s = hack_urls (s, prefix)
-            s = add_header (s)
-
-            ### add footer
-            if re.search (footer_tag, s) == None:
-                s = add_footer (s)
-                
-                available, missing = find_translations (prefix, lang_ext)
-                page_flavors = process_links (s, prefix, lang_ext, file_name, missing, target)
-                # Add menu after stripping: must not have autoselection for language menu.
-                page_flavors = add_menu (page_flavors, prefix, available, target, translation)
-            for k in page_flavors:
-                page_flavors[k][1] = page_flavors[k][1] % subst[page_flavors[k][0]]
-                out_f = open (name_filter (k), 'w')
-                out_f.write (page_flavors[k][1])
-                out_f.close()
-        # if the page is translated, a .en.html symlink is necessary for content negotiation
-        if target == 'online' and ext_list != ['']:
-            os.symlink (os.path.basename (prefix) + '.html', name_filter (prefix + '.en.html'))
index a0ac7d48cc844da23a80c64217912d51ebdbdb4e..887e7c210b18ff031397760cd4ec24ac2afb2345 100755 (executable)
@@ -5,6 +5,9 @@ import optparse
 import os
 import sys
 
+import langdefs
+import buildlib
+
 verbose = 0
 lang = 'C'
 C = lang
@@ -53,7 +56,7 @@ def do_file (file_name, lang_codes, buildlib):
 def usage ():
     sys.stdout.write (r'''
 Usage:
-check-translation [--language=LANG] [--verbose] [--update] BUILDSCRIPT-DIR FILE...
+check-translation [--language=LANG] [--verbose] [--update] FILE...
 
 This script is licensed under the GNU GPL.
 ''')
@@ -83,20 +86,17 @@ def do_options ():
     lang = options.language
     update_mode = options.update_mode
     
-    return (files[0], files[1:])
+    return files
 
 def main ():
     global update_mode, text_editor
 
-    import_path, files = do_options ()
+    files = do_options ()
     if 'EDITOR' in os.environ:
         text_editor = os.environ['EDITOR']
     else:
         update_mode = False
     
-    sys.path.append (import_path)
-    import langdefs
-    import buildlib
     buildlib.verbose = verbose
 
     for i in files:
diff --git a/buildscripts/extract_texi_filenames.py b/buildscripts/extract_texi_filenames.py
new file mode 100755 (executable)
index 0000000..c85a18f
--- /dev/null
@@ -0,0 +1,168 @@
+#!@PYTHON@
+# -*- coding: utf-8 -*-
+# extract_texi_filenames.py
+
+# USAGE:  extract_texi_filenames.py [-o OUTDIR] FILES
+#
+# -o OUTDIR specifies that output files should rather be written in OUTDIR
+#
+# Description:
+# This script parses the .texi file given and creates a file with the
+# nodename <=> filename/anchor map.
+# The idea behind: Unnumbered subsections go into the same file as the
+# previous numbered section, @translationof gives the original node name,
+# which is then used for the filename/anchor.
+#
+# If this script is run on a file texifile.texi, it produces a file
+# texifile[.LANG].xref-map with tab-separated entries of the form
+#        NODE\tFILENAME\tANCHOR
+# LANG is the document language in case it's not 'en'
+# Note: The filename does not have any extension appended!
+# This file can then be used by our texi2html init script to determine 
+# the correct file name and anchor for external refs
+
+import sys
+import re
+import os
+import getopt
+
+optlist, args = getopt.getopt (sys.argv[1:],'o:')
+files = args
+
+outdir = '.'
+for x in optlist:
+    if x[0] == '-o':
+        outdir = x[1]
+
+if not os.path.isdir (outdir):
+    if os.path.exists (outdir):
+        os.unlink (outdir)
+    os.makedirs (outdir)
+
+include_re = re.compile (r'@include ((?!../lily-).*?)\.texi$', re.M)
+whitespaces = re.compile (r'\s+')
+section_translation_re = re.compile (r'^@(node|(?:unnumbered|appendix)(?:(?:sub){0,2}sec)?|top|chapter|(?:sub){0,2}section|(?:major|chap|(?:sub){0,2})heading|translationof) (.*?)\s*$', re.MULTILINE)
+
+def expand_includes (m, filename):
+    filepath = os.path.join (os.path.dirname (filename), m.group(1)) + '.texi'
+    if os.path.exists (filepath):
+        return extract_sections (filepath)[1]
+    else:
+        print "Unable to locate include file " + filepath
+        return ''
+
+lang_re = re.compile (r'^@documentlanguage (.+)', re.M)
+
+def extract_sections (filename):
+    result = ''
+    f = open (filename, 'r')
+    page = f.read ()
+    f.close()
+    # Search document language
+    m = lang_re.search (page)
+    if m and m.group (1) != 'en':
+        lang_suffix = '.' + m.group (1)
+    else:
+        lang_suffix = ''
+    # Replace all includes by their list of sections and extract all sections
+    page = include_re.sub (lambda m: expand_includes (m, filename), page)
+    sections = section_translation_re.findall (page)
+    for sec in sections:
+        result += "@" + sec[0] + " " + sec[1] + "\n"
+    return (lang_suffix, result)
+
+# Convert a given node name to its proper file name (normalization as explained
+# in the texinfo manual:
+# http://www.gnu.org/software/texinfo/manual/texinfo/html_node/HTML-Xref-Node-Name-Expansion.html
+def texinfo_file_name(title):
+    # exception: The top node is always mapped to index.html
+    if title == "Top":
+        return "index"
+    # File name normalization by texinfo (described in the texinfo manual):
+    # 1/2: letters and numbers are left unchanged
+    # 3/4: multiple, leading and trailing whitespace is removed
+    title = title.strip ();
+    title = whitespaces.sub (' ', title)
+    # 5:   all remaining spaces are converted to '-'
+    # 6:   all other 7- or 8-bit chars are replaced by _xxxx (xxxx=ascii character code)
+    result = ''
+    for index in range(len(title)):
+        char = title[index]
+        if char == ' ': # space -> '-'
+            result += '-'
+        elif ( ('0' <= char and char <= '9' ) or
+               ('A' <= char and char <= 'Z' ) or
+               ('a' <= char and char <= 'z' ) ):  # number or letter
+            result += char
+        else:
+            ccode = ord(char)
+            if ccode <= 0xFFFF:
+                result += "_%04x" % ccode
+            else:
+                result += "__%06x" % ccode
+    # 7: if name begins with number, prepend 't_g' (so it starts with a letter)
+    if (result != '') and (ord(result[0]) in range (ord('0'), ord('9'))):
+        result = 't_g' + result
+    return result
+
+texinfo_re = re.compile (r'@.*{(.*)}')
+def remove_texinfo (title):
+    return texinfo_re.sub (r'\1', title)
+
+def create_texinfo_anchor (title):
+    return texinfo_file_name (remove_texinfo (title))
+
+unnumbered_re = re.compile (r'unnumbered.*')
+def process_sections (filename, lang_suffix, page):
+    sections = section_translation_re.findall (page)
+    basename = os.path.splitext (os.path.basename (filename))[0]
+    p = os.path.join (outdir, basename) + lang_suffix + '.xref-map'
+    f = open (p, 'w')
+
+    this_title = ''
+    this_filename = 'index'
+    this_anchor = ''
+    this_unnumbered = False
+    had_section = False
+    for sec in sections:
+        if sec[0] == "node":
+            # Write out the cached values to the file and start a new section:
+            if this_title != '' and this_title != 'Top':
+                    f.write (this_title + "\t" + this_filename + "\t" + this_anchor + "\n")
+            had_section = False
+            this_title = remove_texinfo (sec[1])
+            this_anchor = create_texinfo_anchor (sec[1])
+        elif sec[0] == "translationof":
+            anchor = create_texinfo_anchor (sec[1])
+            # If @translationof is used, it gives the original node name, which
+            # we use for the anchor and the file name (if it is a numbered node)
+            this_anchor = anchor
+            if not this_unnumbered:
+                this_filename = anchor
+        else:
+            # Some pages might not use a node for every section, so treat this
+            # case here, too: If we already had a section and encounter enother
+            # one before the next @node, we write out the old one and start
+            # with the new values
+            if had_section and this_title != '':
+                f.write (this_title + "\t" + this_filename + "\t" + this_anchor + "\n")
+                this_title = remove_texinfo (sec[1])
+                this_anchor = create_texinfo_anchor (sec[1])
+            had_section = True
+
+            # unnumbered nodes use the previously used file name, only numbered
+            # nodes get their own filename! However, top-level @unnumbered
+            # still get their own file.
+            this_unnumbered = unnumbered_re.match (sec[0])
+            if not this_unnumbered or sec[0] == "unnumbered":
+                this_filename = this_anchor
+
+    if this_title != '' and this_title != 'Top':
+        f.write (this_title + "\t" + this_filename + "\t" + this_anchor + "\n")
+    f.close ()
+
+
+for filename in files:
+    print "extract_texi_filenames.py: Processing %s" % filename
+    (lang_suffix, sections) = extract_sections (filename)
+    process_sections (filename, lang_suffix, sections)
index 7d32879a4112b0d0e81e1faf9fc6b034c3831854..aaa8888a3fdac88bcc92052a88a52aa34d17c0ab 100644 (file)
@@ -27,12 +27,21 @@ double_punct_char_separator = langdefs.LANGDICT[lang].double_punct_char_sep
 my_gettext = langdefs.translation[lang]
 
 html_codes = ((' -- ', ' &ndash; '),
-              (' --- ', ' &mdash; '))
-html2texi = {'command': (re.compile (r'<samp><span class="command">(.*?)</span></samp>'), r'@command{\1}'),
-             'code': (re.compile (r'<code>(.*?)</code>'), r'@code{\1}')
+              (' --- ', ' &mdash; '),
+              ("'", '&rsquo;'))
+html2texi = {'command':
+                 (re.compile (r'<samp><span class="command">(.*?)</span></samp>'),
+                  r'@command{\1}'),
+             'code':
+                 (re.compile (r'<code>(.*?)</code>'),
+                  r'@code{\1}')
              }
-texi2html = {'command': (re.compile (r'@command{(.*?)}'), r'<samp><span class="command">\1</span></samp>'),
-             'code': (re.compile (r'@code{(.*?)}'), r'<code>\1</code>')
+texi2html = {'command':
+                 (re.compile (r'@command{(.*?)}'),
+                  r'<samp><span class="command">\1</span></samp>'),
+             'code':
+                 (re.compile (r'@code{(.*?)}'),
+                  r'<code>\1</code>')
              }
 whitespaces = re.compile (r'\s+')
 
@@ -52,46 +61,58 @@ def _ (s):
         s = s.replace (c[0], c[1])
     return s
 
+link_re =  re.compile (r'<link rel="(up|prev|next)" (.*?) title="([^"]*?)">')
+
 def link_gettext (m):
-    return '<link rel="' + m.group(1) + '" ' + m.group(2) + ' title="' + _(m.group(3)) + '">'
+    return '<link rel="' + m.group (1) + '" ' + m.group (2) \
+        + ' title="' + _ (m.group (3)) + '">'
+
+makeinfo_title_re = re.compile (r'<title>([^<]*?) - ([^<]*?)</title>')
+
+def makeinfo_title_gettext (m):
+    return '<title>' + _ (m.group (1)) + ' - ' + m.group (2) + '</title>'
+
+texi2html_title_re = re.compile (r'<title>(.+?): ([A-Z\d.]+ |)(.+?)</title>')
 
-def title_gettext (m):
-    return '<title>' + _(m.group(1)) + ' - ' + m.group(2) + '</title>'
+def texi2html_title_gettext (m):
+    return '<title>' + _ (m.group (1)) + double_punct_char_separator + ': ' \
+        + m.group (2) + _ (m.group (3)) + '</title>'
+
+a_href_re = re.compile ('(?s)<a ([^>]*?href="[\\w.#-_]+"[^>]*>(?:<code>|))\
+(Appendix |)([A-Z0-9.]+ | (?:&lt;){1,2} |&nbsp;[^:<]+?:&nbsp;|&nbsp;|)\
+(.+?)(</code>| (?:&gt;){1,2} |&nbsp;|)</a>:?')
 
 def a_href_gettext (m):
     s = ''
     if m.group(0)[-1] == ':':
         s = double_punct_char_separator + ':'
     t = ''
-    if m.lastindex == 7:
-        t = m.group(7)
-    return '<a ' + (m.group(1) or '') + m.group(2) + (m.group(3) or '') + _(m.group(4)) + m.group(5) + _(m.group(6)) + t + '</a>' + s
+    if m.group (2):
+        t = _ (m.group (2))
+    return '<a ' + m.group (1) + t + m.group (3) + _ (m.group (4)) + \
+        m.group (5) + '</a>' + s
+
+h_re = re.compile (r'<h(\d)( class="\w+"|)>\s*(Appendix |)([A-Z\d.]+ |)?([^<]+)\s*</h\1>')
 
 def h_gettext (m):
     if m.group (3):
-        s = _(m.group(3))
+        s = _ (m.group (3))
     else:
         s= ''
-    return '<h' + m.group(1) + m.group(2) + '>' + s +\
-           m.group(4) + _(m.group(5)) + '</h' + m.group(1) + '>'
-
-def crossmanual_ref_gettext (m):
-    return '<a href="' + m.group(1) + '">' + _(m.group(2)) + '</a>'
+    return '<h' + m.group (1) + m.group (2) + '>' + s +\
+           m.group (4) + _ (m.group (5)) + '</h' + m.group (1) + '>'
 
 for filename in files:
     f = open (filename, 'r')
     page = f.read ()
-    f.close()
-    page = re.sub (r'<link rel="(up|prev|next)" (.*?) title="([^"]*?)">', link_gettext, page)
-    page = re.sub (r'<title>([^<]*?) - ([^<]*?)</title>', title_gettext, page)
-    # ugh
-    page = re.sub (r'(?ms)<a ((?:rel="\w+")? ?(?:accesskey="[^"]+?")? ?(?:name=".*?")? ?)(href=".+?">)(<code>)?(Appendix )?([A-Z\d.]+ |)(.+?)(?(3)</code>)</a>:?', a_href_gettext, page)
-    page = re.sub (r'<h(\d)( class="\w+"|)>(Appendix |)([A-Z\d.]+ |)?([^<]+)</h\1>', h_gettext, page)
-    page = re.sub (r'<a href="(\.\./(?:music-glossary|lilypond-program/)?(?:.+?))">(.+?)</a>', crossmanual_ref_gettext, page)
-    # this is necessary for entries not translated by a_href_gettext
-    page = re.sub (r'<a href="(.+?)">(.+?)</a>', crossmanual_ref_gettext, page)
+    f.close ()
+    page = link_re.sub (link_gettext, page)
+    page = makeinfo_title_re.sub (makeinfo_title_gettext, page)
+    page = texi2html_title_re.sub (texi2html_title_gettext, page)
+    page = a_href_re.sub (a_href_gettext, page)
+    page = h_re.sub (h_gettext, page)
     for w in ('Next:', 'Previous:', 'Up:'):
-        page = re.sub (w, _(w), page)
+        page = page.replace (w, _ (w))
     page = langdefs.LANGDICT[lang].html_filter (page)
     f = open (os.path.join (outdir, filename), 'w')
     f.write (page)
diff --git a/buildscripts/postprocess_html.py b/buildscripts/postprocess_html.py
new file mode 100644 (file)
index 0000000..6ebe31a
--- /dev/null
@@ -0,0 +1,328 @@
+#!@PYTHON@
+
+"""
+Postprocess HTML files.
+"""
+import re
+import os
+import time
+import operator
+
+import langdefs
+
+# This is to try to make the docball not too big with almost duplicate files
+# see process_links()
+non_copied_pages = ['Documentation/user/out-www/lilypond-big-page',
+                    'Documentation/user/out-www/lilypond-internals-big-page',
+                    'Documentation/user/out-www/lilypond-learning-big-page',
+                    'Documentation/user/out-www/lilypond-program-big-page',
+                    'Documentation/user/out-www/music-glossary-big-page',
+                    'out-www/examples',
+                    'Documentation/topdocs',
+                    'Documentation/bibliography',
+                    'Documentation/out-www/THANKS',
+                    'Documentation/out-www/DEDICATION',
+                    'Documentation/out-www/devel',
+                    'input/']
+
+def _doc (s):
+    return s
+
+header = r"""
+"""
+
+footer = '''
+<div style="background-color: #e8ffe8; padding: 2; border: #c0ffc0 1px solid;">
+<p>
+<font size="-1">
+%(footer_name_version)s
+<br>
+<address>
+%(footer_report_errors)s </address>
+<br>
+%(footer_suggest_docs)s
+</font>
+</p>
+</div>
+'''
+footer_name_version = _doc ('This page is for %(package_name)s-%(package_version)s (%(branch_str)s).')
+footer_report_errors = _doc ('Report errors to <a href="%(mail_address_url)s">%(mail_address)s</a>.')
+# ugh, must not have "_doc" in strings because it is naively replaced with "_" in hacked gettext process
+footer_suggest_docs = _doc ('Your <a href="%(suggest_Docs_url)s">suggestions for the documentation</a> are welcome.')
+
+mail_address = 'http://post.gmane.org/post.php?group=gmane.comp.gnu.lilypond.bugs'
+suggest_Docs_url = 'http://lilypond.org/web/devel/participating/documentation-adding'
+
+header_tag = '<!-- header_tag -->'
+header_tag_re = re.compile (header_tag)
+
+footer_tag = '<!-- footer_tag -->'
+footer_tag_re = re.compile (footer_tag)
+
+lang_available = _doc ("Other languages: %s.")
+browser_lang = _doc ('About <A HREF="%s">automatic language selection</A>.')
+browser_language_url = "/web/about/browser-language"
+
+LANGUAGES_TEMPLATE = '''
+<p id="languages">
+ %(language_available)s
+ <br/>
+ %(browser_language)s
+</p>
+'''
+
+
+html_re = re.compile ('(.*?)(?:[.]([^/.]*))?[.]html$')
+pages_dict = {}
+
+def build_pages_dict (filelist):
+    """Build dictionary of available translations of each page"""
+    global pages_dict
+    for f in filelist:
+        m = html_re.match (f)
+        if m:
+            g = m.groups()
+            if len (g) <= 1 or g[1] == None:
+                e = ''
+            else:
+                e = g[1]
+            if not g[0] in pages_dict:
+                pages_dict[g[0]] = [e]
+            else:
+                pages_dict[g[0]].append (e)
+
+def source_links_replace (m, source_val):
+    return 'href="' + os.path.join (source_val, m.group (1)) + '"'
+
+splitted_docs_re = re.compile ('(input/lsr/out-www/lilypond-snippets|Documentation/user/out-www/(lilypond|music-glossary|lilypond-program|lilypond-learning))/')
+
+snippets_ref_re = re.compile (r'href="(\.\./)?lilypond-snippets')
+user_ref_re = re.compile (r'href="(?:\.\./)?lilypond(-internals|-learning|-program|(?!-snippets))')
+
+## Windows does not support symlinks.
+# This function avoids creating symlinks for splitted HTML manuals
+# Get rid of symlinks in GNUmakefile.in (local-WWW-post)
+# this also fixes missing PNGs only present in translated docs
+def hack_urls (s, prefix):
+    if splitted_docs_re.match (prefix):
+        s = re.sub ('(href|src)="(../lily-.*?|.*?[.]png)"', '\\1="../\\2"', s)
+
+    # fix xrefs between documents in different directories ad hoc
+    if 'user/out-www/lilypond' in prefix:
+        s = snippets_ref_re.sub ('href="source/input/lsr/lilypond-snippets', s)
+    elif 'input/lsr' in prefix:
+        s = user_ref_re.sub ('href="source/Documentation/user/lilypond\\1', s)
+
+    source_path = os.path.join (os.path.dirname (prefix), 'source')
+    if not os.path.islink (source_path):
+        return s
+    source_val = os.readlink (source_path)
+    return re.sub ('href="source/(.*?)"', lambda m: source_links_replace (m, source_val), s)
+
+body_tag_re = re.compile ('(?i)<body([^>]*)>')
+html_tag_re = re.compile ('(?i)<html>')
+doctype_re = re.compile ('(?i)<!DOCTYPE')
+doctype = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n'
+
+def add_header (s):
+    """Add header (<body> and doctype)"""
+    if header_tag_re.search (s) == None:
+        body = '<body bgcolor="white" text="black" \\1>'
+        (s, n) = body_tag_re.subn (body + header, s, 1)
+        if not n:
+            (s, n) = html_tag_re.subn ('<html>' + header, s, 1)
+            if not n:
+                s = header + s
+
+        s = header_tag + '\n' + s
+
+        if doctype_re.search (s) == None:
+            s = doctype + s
+        return s
+
+title_tag_re = re.compile ('.*?<title>(.*?)</title>', re.DOTALL)
+AT_web_title_re = re.compile ('@WEB-TITLE@')
+
+def add_title (s):
+    # urg
+    # maybe find first node?
+    fallback_web_title = '-- --'
+    m = title_tag_re.match (s)
+    if m:
+        fallback_web_title = m.group (1)
+    s = AT_web_title_re.sub (fallback_web_title, s)
+    return s
+
+footer_insert_re = re.compile ('<!--\s*FOOTER\s*-->')
+end_body_re = re.compile ('(?i)</body>')
+end_html_re = re.compile ('(?i)</html>')
+
+def add_footer (s, footer_text):
+    """add footer"""
+    (s, n) = footer_insert_re.subn (footer_text + '\n' + '<!-- FOOTER -->', s, 1)
+    if not n:
+        (s, n) = end_body_re.subn (footer_text + '\n' + '</body>', s, 1)
+    if not n:
+        (s, n) = end_html_re.subn (footer_text + '\n' + '</html>', s, 1)
+    if not n:
+        s += footer_text + '\n'
+    return s
+
+def find_translations (prefix, lang_ext):
+    """find available translations of a page"""
+    available = []
+    missing = []
+    for l in langdefs.LANGUAGES:
+        e = l.webext
+        if lang_ext != e:
+            if e in pages_dict[prefix]:
+                available.append (l)
+            elif lang_ext == '' and l.enabled and reduce (operator.and_, [not prefix.startswith (s) for s in non_copied_pages]):
+                # English version of missing translated pages will be written
+                missing.append (e)
+    return available, missing
+
+online_links_re = re.compile ('''(href|src)=['"]([^/][.]*[^.:'"]*)([.]html|[.]png)(#[^"']*|)['"]''')
+offline_links_re = re.compile ('''href=['"]([^/][.]*[^.:'"]*)([.]html)(#[^"']*|)['"]''')
+big_page_name_re = re.compile ('''(.+?)-big-page''')
+
+def process_i18n_big_page_links (match, prefix, lang_ext):
+    big_page_name = big_page_name_re.match (match.group (1))
+    if big_page_name:
+        destination_path = os.path.normpath (os.path.join (os.path.dirname (prefix),
+                                                           big_page_name.group (0)))
+        if not lang_ext in pages_dict[destination_path]:
+            return match.group (0)
+    return 'href="' + match.group (1) + '.' + lang_ext \
+        + match.group (2) + match.group (3) + '"'
+
+def process_links (s, prefix, lang_ext, file_name, missing, target):
+    page_flavors = {}
+    if target == 'online':
+        # Strip .html, .png suffix for auto language selection (content
+        # negotiation).  The menu must keep the full extension, so do
+        # this before adding the menu.
+        page_flavors[file_name] = \
+            [lang_ext, online_links_re.sub ('\\1="\\2\\4"', s)]
+    elif target == 'offline':
+        # in LANG doc index: don't rewrite .html suffixes
+        # as not all .LANG.html pages exist;
+        # the doc index should be translated and contain links with the right suffixes
+        if prefix == 'Documentation/out-www/index':
+            page_flavors[file_name] = [lang_ext, s]
+        elif lang_ext == '':
+            page_flavors[file_name] = [lang_ext, s]
+            for e in missing:
+                page_flavors[langdefs.lang_file_name (prefix, e, '.html')] = \
+                    [e, offline_links_re.sub ('href="\\1.' + e + '\\2\\3"', s)]
+        else:
+            # For saving bandwidth and disk space, we don't duplicate big pages
+            # in English, so we must process translated big pages links differently.
+            if 'big-page' in prefix:
+                page_flavors[file_name] = \
+                    [lang_ext,
+                     offline_links_re.sub \
+                         (lambda match: process_i18n_big_page_links (match, prefix, lang_ext),
+                          s)]
+            else:
+                page_flavors[file_name] = \
+                    [lang_ext,
+                     offline_links_re.sub ('href="\\1.' + lang_ext + '\\2\\3"', s)]
+    return page_flavors
+
+def add_menu (page_flavors, prefix, available, target, translation):
+    for k in page_flavors:
+        language_menu = ''
+        languages = ''
+        if page_flavors[k][0] != '':
+            t = translation[page_flavors[k][0]]
+        else:
+            t = _doc
+        for lang in available:
+            lang_file = lang.file_name (os.path.basename (prefix), '.html')
+            if language_menu != '':
+                language_menu += ', '
+            language_menu += '<a href="%s">%s</a>' % (lang_file, t (lang.name))
+        if target == 'offline':
+            browser_language = ''
+        elif target == 'online':
+            browser_language = t (browser_lang) % browser_language_url
+        if language_menu:
+            language_available = t (lang_available) % language_menu
+            languages = LANGUAGES_TEMPLATE % vars ()
+        page_flavors[k][1] = add_footer (page_flavors[k][1], languages)
+    return page_flavors
+
+
+def process_html_files (package_name = '',
+                        package_version = '',
+                        target = 'offline',
+                        name_filter = lambda s: s):
+    """Add header, footer and tweak links to a number of HTML files
+
+    Arguments:
+     package_name=NAME         set package_name to NAME
+     package_version=VERSION   set package version to VERSION
+     targets=offline|online    set page processing depending on the target
+          offline is for reading HTML pages locally
+          online is for hosting the HTML pages on a website with content
+            negotiation
+     name_filter               a HTML file name filter
+    """
+    translation = langdefs.translation
+    localtime = time.strftime ('%c %Z', time.localtime (time.time ()))
+
+    if "http://" in mail_address:
+        mail_address_url = mail_address
+    else:
+        mail_address_url= 'mailto:' + mail_address
+
+    versiontup = package_version.split ('.')
+    branch_str = _doc ('stable-branch')
+    if int (versiontup[1]) %  2:
+        branch_str = _doc ('development-branch')
+
+    # Initialize dictionaries for string formatting
+    subst = {}
+    subst[''] = dict ([i for i in globals ().items() if type (i[1]) is str])
+    subst[''].update (dict ([i for i in locals ().items() if type (i[1]) is str]))
+    for l in translation:
+        e = langdefs.LANGDICT[l].webext
+        if e:
+            subst[e] = {}
+            for name in subst['']:
+                subst[e][name] = translation[l] (subst[''][name])
+    # Do deeper string formatting as early as possible,
+    # so only one '%' formatting pass is needed later
+    for e in subst:
+        subst[e]['footer_name_version'] = subst[e]['footer_name_version'] % subst[e]
+        subst[e]['footer_report_errors'] = subst[e]['footer_report_errors'] % subst[e]
+        subst[e]['footer_suggest_docs'] = subst[e]['footer_suggest_docs'] % subst[e]
+
+    for prefix, ext_list in pages_dict.items ():
+        for lang_ext in ext_list:
+            file_name = langdefs.lang_file_name (prefix, lang_ext, '.html')
+            in_f = open (file_name)
+            s = in_f.read()
+            in_f.close()
+
+            s = s.replace ('%', '%%')
+            s = hack_urls (s, prefix)
+            s = add_header (s)
+
+            ### add footer
+            if footer_tag_re.search (s) == None:
+                s = add_footer (s, footer_tag + footer)
+                
+                available, missing = find_translations (prefix, lang_ext)
+                page_flavors = process_links (s, prefix, lang_ext, file_name, missing, target)
+                # Add menu after stripping: must not have autoselection for language menu.
+                page_flavors = add_menu (page_flavors, prefix, available, target, translation)
+            for k in page_flavors:
+                page_flavors[k][1] = page_flavors[k][1] % subst[page_flavors[k][0]]
+                out_f = open (name_filter (k), 'w')
+                out_f.write (page_flavors[k][1])
+                out_f.close()
+        # if the page is translated, a .en.html symlink is necessary for content negotiation
+        if target == 'online' and ext_list != ['']:
+            os.symlink (os.path.basename (prefix) + '.html', name_filter (prefix + '.en.html'))
diff --git a/buildscripts/tely-gettext.py b/buildscripts/tely-gettext.py
new file mode 100755 (executable)
index 0000000..b4e5660
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# tely-gettext.py
+
+# Temporary script that helps translated docs sources conversion
+# for texi2html processing
+
+# USAGE:  tely-gettext.py BUILDSCRIPT-DIR LOCALEDIR LANG FILES
+
+print "tely_gettext.py"
+
+import sys
+import re
+import os
+import gettext
+
+if len (sys.argv) > 3:
+    buildscript_dir, localedir, lang = sys.argv[1:4]
+else:
+    print """USAGE:  tely-gettext.py BUILDSCRIPT-DIR LOCALEDIR LANG FILES
+  For example buildscripts/tely-gettext.py buildscripts Documentation/po/out-www de Documentation/de/user/*.tely"""
+    sys.exit (1)
+
+sys.path.append (buildscript_dir)
+import langdefs
+
+double_punct_char_separator = langdefs.LANGDICT[lang].double_punct_char_sep
+t = gettext.translation('lilypond-doc', localedir, [lang])
+_doc = t.gettext
+
+include_re = re.compile (r'@include (.*?)$', re.M)
+whitespaces = re.compile (r'\s+')
+ref_re = re.compile (r'(?ms)@(ruser|rprogram|ref|rlearning)\{(.*?)\}')
+node_section_re = re.compile (r'@node (.*?)\n@((?:unnumbered|appendix)(?:(?:sub){0,2}sec)?|top|chapter|(?:sub){0,2}section|(?:major|chap|(?:sub){0,2})heading) (.*?)\n')
+menu_entry_re = re.compile (r'\* (.*?)::')
+
+def ref_gettext (m):
+    r = whitespaces.sub (' ', m.group (2))
+    return '@' + m.group (1) + '{' + _doc (r) + '}'
+
+def node_gettext (m):
+    return '@node ' + _doc (m.group (1)) + '\n@' + \
+        m.group (2) + ' ' + _doc (m.group (3)) + \
+       '\n@translationof ' + m.group (1) + '\n'
+
+def menu_entry_gettext (m):
+    return '* ' + _doc (m.group (1)) + '::'
+
+def process_file (filename):
+    print "Processing %s" % filename
+    f = open (filename, 'r')
+    page = f.read ()
+    f.close()
+    page = node_section_re.sub (node_gettext, page)
+    page = ref_re.sub (ref_gettext, page)
+    page = menu_entry_re.sub (menu_entry_gettext, page)
+    page = page.replace ("""-- SKELETON FILE --
+When you actually translate this file, please remove these lines as
+well as all `UNTRANSLATED NODE: IGNORE ME' lines.""", """@c -- SKELETON FILE --""")
+    page = page.replace ('UNTRANSLATED NODE: IGNORE ME', "@c UNTRANSLATED NODE: IGNORE ME")
+    includes = [whitespaces.sub ('', f) for f in include_re.findall (page)]
+    f = open (filename, 'w')
+    f.write (page)
+    f.close ()
+    dir = os.path.dirname (filename)
+    for file in includes:
+        p = os.path.join (dir, file)
+        if os.path.exists (p):
+            process_file (p)
+
+for filename in sys.argv[4:]:
+    process_file (filename)
index 1c62ee56d200b9a94e987a710ef5552a0c68ccb4..4180ea86722c925bc4250e61311a4832735a0c34 100755 (executable)
@@ -19,19 +19,15 @@ import string
 import os
 
 import langdefs
+import buildlib
 
 def progress (str):
     sys.stderr.write (str + '\n')
 
 progress ("translations-status.py")
 
-buildscript_dir = sys.argv[1]
-
 _doc = lambda s: s
 
-sys.path.append (buildscript_dir)
-import buildlib
-
 # load gettext messages catalogs
 translation = langdefs.translation
 
index b2d7ca510cb9bf663e3697d958709bce57acb96d..6fdb84f6609e61c35bbd90fbf5aec2fa8cfc547a 100644 (file)
@@ -10,7 +10,12 @@ import sys
 import os
 import re
 
-package_name, package_version, buildscript_dir, outdir, targets = sys.argv[1:]
+import langdefs
+
+import mirrortree
+import postprocess_html
+
+package_name, package_version, outdir, targets = sys.argv[1:]
 targets = targets.split (' ')
 outdir = os.path.normpath (outdir)
 doc_dirs = ['input', 'Documentation', outdir]
@@ -29,8 +34,6 @@ static_files = {
 <html><body>Redirecting to the documentation index...</body></html>\n'''
     }
 
-import langdefs
-
 for l in langdefs.LANGUAGES:
     static_files[os.path.join ('Documentation', 'user', outdir, l.file_name ('index', '.html'))] = \
                                   '<META HTTP-EQUIV="refresh" content="0;URL=../' + l.file_name ('index', '.html') + \
@@ -39,17 +42,12 @@ for l in langdefs.LANGUAGES:
 for f, contents in static_files.items ():
     open (f, 'w').write (contents)
 
-
-sys.path.append (buildscript_dir)
-import mirrortree
-import add_html_footer
-
 sys.stderr.write ("Mirrorring...\n")
 dirs, symlinks, files = mirrortree.walk_tree (
     tree_roots = doc_dirs,
     process_dirs = outdir,
     exclude_dirs = '(^|/)(' + r'|po|out|out-test|.*?[.]t2d|\w*?-root)(/|$)|Documentation/(' + '|'.join ([l.code for l in langdefs.LANGUAGES]) + ')',
-    find_files = r'.*?\.(?:midi|html|pdf|png|txt|ly|signature)$|VERSION',
+    find_files = r'.*?\.(?:midi|html|pdf|png|txt|ly|signature|css)$|VERSION',
     exclude_files = r'lily-[0-9a-f]+.*\.(pdf|txt)')
 
 # actual mirrorring stuff
@@ -91,10 +89,10 @@ if 'online' in targets:
     f.write ('#.htaccess\nDirectoryIndex index\n')
     f.close ()
 
-add_html_footer.build_pages_dict (html_files)
+postprocess_html.build_pages_dict (html_files)
 for t in targets:
     sys.stderr.write ("Processing HTML pages for %s target...\n" % t)
-    add_html_footer.add_html_footer (
+    postprocess_html.process_html_files (
         package_name = package_name,
         package_version = package_version,
         target = t,
index 4d714c3d3f235e62ac8b87bb9635df4f0ce5f808..da0123311f405c6f5d2a378eadd52a50398de12f 100644 (file)
@@ -126,6 +126,7 @@ LINK_GXX_STATICALLY = @LINK_GXX_STATICALLY@
 LN = @LN@
 LN_S = @LN_S@
 MAKEINFO_PROGRAM = @MAKEINFO@
+TEXI2HTML_PROGRAM = @TEXI2HTML@
 METAFONT = @METAFONT@ -progname=mf
 MFMODE = @MFMODE@
 MSGFMT = @MSGFMT@
index 1f3040a93f1c1469a9f34349e8c07756d32a8daf..be353c500e6095c1f822c861cee5159cdb0a8188 100644 (file)
@@ -126,7 +126,8 @@ AC_MSG_RESULT(Must have patched GUILE rational support. See INSTALL.txt))
 CPPFLAGS="$save_CPPFLAGS"
 
 
-STEPMAKE_MAKEINFO(REQUIRED, 4.11)
+# We check for makeinfo below, too. Really duplicate that check?
+## STEPMAKE_MAKEINFO(REQUIRED, 4.11)
 STEPMAKE_PYTHON_DEVEL(REQUIRED)
 
 STEPMAKE_PATH_PROG(GHOSTSCRIPT, gs, OPTIONAL, 8.15)
@@ -176,6 +177,7 @@ STEPMAKE_GUILE(OPTIONAL)
 STEPMAKE_PERL(OPTIONAL)
 
 STEPMAKE_PROGS(MAKEINFO, makeinfo, REQUIRED, 4.11)
+STEPMAKE_PROGS(TEXI2HTML, texi2html, OPTIONAL, 1.79)
 
 AC_DEFINE_UNQUOTED(FLOWER_VERSION, "${FULL_FLOWER_VERSION}")
 
index eacbcb922006ffe6ff457aac10c26537383e5548..f91dacd38d76370acdd7c6f70adcbacb75f3ffbc 100644 (file)
@@ -56,8 +56,10 @@ local-uninstall-WWW: local-uninstall-info
 local-clean:
        rm -f $(INFO_IMAGES_DIR)
 
-local-WWW: info $(outdir)/lilypond-snippets.pdf \
-  $(outdir)/lilypond-snippets/index.html \
+local-WWW-1: info $(outdir)/lilypond-snippets.pdf \
+  $(outdir)/lilypond-snippets.texi
+
+local-WWW-2: $(outdir)/lilypond-snippets/index.html \
   $(outdir)/lilypond-snippets-big-page.html \
   $(source-links)
 
index 29d814ab571e125a19e8da8b79a5a2848a5df196..678d93b87cdb4d3f1988411bd904b1e16b89db9f 100644 (file)
 @unnumberedsec \TEXT\
 @end macro
 
-@ifnottex
+@ifhtml
+
+@ifset bigpage
+
+@macro rlearning{NAME}
+See also Learning Manual, section
+@ref{\NAME\,,,lilypond-learning-big-page,Learning Manual}.
+@end macro
+
 @macro ruser{NAME}
 These snippets illustrate the Notation Reference,
-section @ref{\NAME\,,,lilypond,Notation Reference}.
+section @ref{\NAME\,,,lilypond-big-page,Notation Reference}.
 @end macro
 
+@end ifset
+
+
+@ifclear bigpage
+
 @macro rlearning{NAME}
 See also Learning Manual, section
 @ref{\NAME\,,,lilypond-learning,Learning Manual}.
 @end macro
-@end ifnottex
 
-@iftex
 @macro ruser{NAME}
-These snippets illustrate @ref{\NAME\,,,lilypond,Notation Reference}.
+These snippets illustrate the Notation Reference,
+section @ref{\NAME\,,,lilypond,Notation Reference}.
 @end macro
 
+@end ifclear
+
+@end ifhtml
+
+
+@ifnothtml
+
 @macro rlearning{NAME}
 See also @ref{\NAME\,,,lilypond-learning,Learning Manual}.
 @end macro
-@end iftex
+
+@macro ruser{NAME}
+These snippets illustrate @ref{\NAME\,,,lilypond,Notation Reference}.
+@end macro
+
+@end ifnothtml
 
 @dircategory GNU LilyPond --- the music typesetter
 @direntry
@@ -136,6 +160,8 @@ Other collections
 * Templates::
 @end menu
 
+@contents
+
 
 @c Please take care of naming every .itely
 @c with an existing tag name.
diff --git a/lilypond-texi2html.init b/lilypond-texi2html.init
new file mode 100644 (file)
index 0000000..66c269b
--- /dev/null
@@ -0,0 +1,1008 @@
+#!/usr/bin/env perl
+
+### texi2html customization script for Lilypond
+### Author: Reinhold Kainhofer <reinhold@kainhofer.com>, 2008.
+###         Some code parts copied from texi2html and adapted. These functions
+###         were written mainly by Patrice Dumas
+### License: GPLv2+
+###
+###
+### Features implemented here:
+### -) For split manuals, the main page is index.html.
+### -) All @unnumbered* sections are placed into the same file
+###    (implemented by split_at_numbered_sections)
+### -) Use our custom CSS file, with IE-specific fixes in another CSS file,
+###    impelmented by lilypond_css_lines
+### -) TOC (folded, with the current page highlighted) in an overflown <div>
+###    is added to every page; implemented by:
+###           lilypond_print_element_header -- building of the TOC
+###           lilypond_toc_body -- generation of customized TOC output
+###           lilypond_print_page_head -- start <div id="main">
+###           print_lilypond_page_foot -- closing id=main, output of footer & TOC
+### -) External refs are formatted only as "Text of the node" (not as >>see
+###    "NODE" section "SECTION" in "BOOK"<< like with default texi2html). Also,
+###    the leading "(book-name)" is removed.
+###    Implemented by overriding lilypond_external_ref
+### -) Navigation bars on top/bottom of the page and between sections are not
+###    left-aligned, but use a combination of left/center/right aligned table
+###    cells; For this, I heavily extend the texi2html code to allow for
+###    differently aligned cells and for multi-line tables);
+###    Implemented in lilypond_print_navigation
+### -) Different formatting than the default: example uses the same formatting
+###    as quote.
+### -) Allow translated section titles: All section titles can be translated,
+###    the original (English) title is associated with @translationof. This is
+###    needed, because the file name / anchor is generated from the original
+###    English title, since otherwise language-autoselection would break with
+###    posted links.
+###    Since it is then no longer possible to obtain the file name from the
+###    section title, I keep a sectionname<=>filename/anchor around. This way,
+###    xrefs from other manuals can simply load that map and retrieve the
+###    correct file name for the link. Implemented in:
+###           lilypond_unknown (handling of @translationof, in case
+###                             extract_texi_filenames.py messes up...)
+###           lilypond_element_file_name (correct file name: use the map)
+###           lilypond_element_target_name (correct anchor: use the map)
+###           lilypond_init_map (read in the externally created map from disk)
+###           lilypond_external_href (load the map for xrefs, use the correct
+###                                   link target)
+### -) The HTML anchors for all sections are derived from the node name /
+###    section title (pre-generated in the .xref-map file). Implemented by:
+###           lilypond_element_target_name (adjust section anchors)
+### -) Use the standard footnote format "<sup>nr</sup> text" instead of the
+###    ugly format of texi2html (<h3>(nr)</h3><p>text</p>). Implemented in
+###           makeinfo_like_foot_line_and_ref
+###           makeinfo_like_foot_lines
+###           makeinfo_like_paragraph
+###
+###
+### Useful helper functions:
+### -) texinfo_file_name($node_name): returns a texinfo-compatible file name
+###    for the given string $node_name (whitespace trimmed/replaced by -,
+###    non-standard chars replaced by _xxxx (ascii char code) and forced to
+###    start with a letter by prepending t_g if necessary)
+
+
+package Texi2HTML::Config;
+
+
+
+
+
+#############################################################################
+###  SETTINGS FOR TEXI2HTML
+#############################################################################
+
+@Texi2HTML::Config::CSS_REFS      = ("lilypond.css");
+$Texi2HTML::Config::USE_ACCESSKEY = 1;
+$Texi2HTML::Config::USE_LINKS     = 1;
+$Texi2HTML::Config::USE_REL_REV   = 1;
+$Texi2HTML::Config::SEPARATED_FOOTNOTES = 0; # Print footnotes on same page, not separated
+$Texi2HTML::Config::element_file_name    = \&lilypond_element_file_name;
+$Texi2HTML::Config::element_target_name  = \&lilypond_element_target_name;
+$Texi2HTML::Config::print_element_header = \&lilypond_print_element_header;
+$Texi2HTML::Config::print_page_foot      = \&print_lilypond_page_foot;
+$Texi2HTML::Config::print_navigation     = \&lilypond_print_navigation;
+$Texi2HTML::Config::external_ref         = \&lilypond_external_ref;
+$Texi2HTML::Config::external_href        = \&lilypond_external_href;
+$Texi2HTML::Config::toc_body             = \&lilypond_toc_body;
+$Texi2HTML::Config::css_lines            = \&lilypond_css_lines;
+$Texi2HTML::Config::unknown              = \&lilypond_unknown;
+$Texi2HTML::Config::print_page_head      = \&lilypond_print_page_head;
+# $Texi2HTML::Config::foot_line_and_ref    = \&lilypond_foot_line_and_ref;
+$Texi2HTML::Config::foot_line_and_ref  = \&makeinfo_like_foot_line_and_ref;
+$Texi2HTML::Config::foot_lines         = \&makeinfo_like_foot_lines;
+$Texi2HTML::Config::paragraph          = \&makeinfo_like_paragraph;
+
+
+
+# Examples should be formatted similar to quotes:
+$Texi2HTML::Config::complex_format_map->{'example'} = {
+  'begin' => q{"<blockquote><pre class=\"example\">"},
+  'end' => q{"</pre></blockquote>\n"},
+ };
+
+%Texi2HTML::config::misc_pages_targets = (
+   'Overview' => 'Overview',
+   'Contents' => 'Contents',
+   'About' => 'About'
+);
+
+
+my @section_to_filename;
+
+
+
+
+#############################################################################
+###  DEBUGGING
+#############################################################################
+
+use Data::Dumper;
+$Data::Dumper::Maxdepth = 2;
+
+sub print_element_info($)
+{
+  my $element = shift;
+  print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
+  print "Element: $element\n";
+  print Dumper($element);
+}
+
+
+
+
+
+#############################################################################
+###  HELPER FUNCTIONS
+#############################################################################
+
+# Convert a given node name to its proper file name (normalization as explained
+# in the texinfo manual:
+# http://www.gnu.org/software/texinfo/manual/texinfo/html_node/HTML-Xref-Node-Name-Expansion.html
+sub texinfo_file_name($)
+{
+  my $text = shift;
+  my $result = '';
+  # File name normalization by texinfo:
+  # 1/2: letters and numbers are left unchanged
+  # 3/4: multiple, leading and trailing whitespace is removed
+  $text = main::normalise_space($text);
+  # 5/6: all remaining spaces are converted to '-', all other 7- or 8-bit
+  #      chars are replaced by _xxxx (xxxx=ascii character code)
+  while ($text ne '') {
+    if ($text =~ s/^([A-Za-z0-9]+)//o) { # number or letter stay unchanged
+      $result .= $1;
+    } elsif ($text =~ s/^ //o) { # space -> '-'
+      $result .= '-';
+    } elsif ($text =~ s/^(.)//o) { # Otherwise use _xxxx (ascii char code)
+      my $ccode = ord($1);
+      if ( $ccode <= 0xFFFF ) {
+        $result .= sprintf("_%04x", $ccode);
+      } else {
+        $result .= sprintf("__%06x", $ccode);
+      }
+    }
+  }
+  # 7: if name does not begin with a letter, prepend 't_g' (so it starts with a letter)
+  if ($result !~ /^[a-zA-Z]/) {
+    $result = 't_g' . $result;
+  }
+  # DONE
+  return $result
+}
+
+
+# Load a file containing a nodename<=>filename map (tab-sepatared, i.e.
+# NODENAME\tFILENAME\tANCHOR
+# Returns a ref to a hash "Node title" => ["FilenameWithoutExt", "Anchor"]
+sub load_map_file ($)
+{
+    my $mapfile = shift;
+    my $node_map = ();
+
+    if (open(XREFFILE, $mapfile)) {
+        my $line;
+        while ( $line = <XREFFILE> ) {
+            # parse the tab-separated entries and insert them into the map:
+            chomp($line);
+            my @entries = split(/\t/, $line);
+            if (scalar (@entries) == 3) {
+              $node_map->{$entries[0]} = [$entries[1], $entries[2]];
+            } else {
+              print STDERR "Invalid entry in the node file $mapfile: $line\n";
+            }
+        }
+        close (XREFFILE);
+    } else {
+        print STDERR "WARNING: Unable to load the map file $mapfile\n";
+    }
+    return $node_map;
+}
+
+
+# Split the given path into dir and basename (with .texi removed). Used mainly
+# to get the path/basename of the original texi input file
+sub split_texi_filename ($)
+{
+  my $docu = shift;
+  my $docu_dir, $docu_name;
+  if ($docu =~ /(.*\/)/) {
+    chop($docu_dir = $1);
+    $docu_name = $docu;
+    $docu_name =~ s/.*\///;
+  } else {
+     $docu_dir = '.';
+     $docu_name = $docu;
+  }
+  $docu_name =~ s/\.te?x(i|info)?$//;
+  return ($docu_dir, $docu_name);
+}
+
+
+
+
+
+#############################################################################
+###  CSS HANDLING
+#############################################################################
+
+# Include our standard CSS file, not hard-coded CSS code directly in the HTML!
+# For IE, conditionally include the lilypond-ie-fixes.css style sheet
+sub lilypond_css_lines ($$)
+{
+    my $import_lines = shift;
+    my $rule_lines = shift;
+    return if (defined($CSS_LINES));
+    if (@$rule_lines or @$import_lines)
+    {
+        $CSS_LINES = "<style type=\"text/css\">\n<!--\n";
+        $CSS_LINES .= join('',@$import_lines) . "\n" if (@$import_lines);
+        $CSS_LINES .= join('',@$rule_lines) . "\n" if (@$rule_lines);
+        $CSS_LINES .= "-->\n</style>\n";
+    }
+    foreach my $ref (@CSS_REFS)
+    {
+        $CSS_LINES .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$ref\">\n";
+    }
+    $CSS_LINES .= "<!--[if lte IE 7]>\n<link href=\"lilypond-ie-fixes.css\" rel=\"stylesheet\" type=\"text/css\">\n<![endif]-->\n";
+}
+
+
+
+
+
+#############################################################################
+###  SPLITTING BASED ON NUMBERED SECTIONS
+#############################################################################
+
+my $lastfilename;
+my $docnr = 0;
+my $node_to_filename_map = ();
+
+
+# This function makes sure that files are only generated for numbered sections,
+# but not for unnumbered ones. It is called after texi2html has done its own
+# splitting and simply returns the filename for the node given as first argument
+# Nodes with the same filename will be printed out to the same filename, so
+# this really all we need. Also, make sure that the file names for sections
+# are derived from the section title. We also might want to name the anchors
+# according to node titles, which works by simply overriding the id element of
+# the $element hash.
+# If an external nodename<=>filename/anchor map file is found (loaded in
+# lilypond_init_out, use the externally created values, otherwise use the
+# same logic here.
+sub lilypond_element_file_name($$$)
+{
+  my $element = shift;
+  my $type = shift;
+  my $docu_name = shift;
+  my $docu_ext = $Texi2HTML::Config::EXTENSION;
+
+  my $node_name = main::remove_texi($element->{'node_ref'}->{'texi'});
+  # the snippets page does not use nodes for the snippets, so in this case
+  # we'll have to use the section name!
+  if ($node_name eq '') {
+    $node_name = main::remove_texi($element->{'texi'});
+  }
+
+  # If we have an entry in the section<=>filename map, use that one, otherwise
+  # generate the filename/anchor here. In the latter case, external manuals
+  # will not be able to retrieve the file name for xrefs!!! Still, I already
+  # had that code, so I'll leave it in in case something goes wrong with the
+  # extract_texi_filenames.py script in the lilypond build process!
+  if (exists ($node_to_filename_map->{$node_name})) {
+    (my $filename, my $anchor) = @{$node_to_filename_map->{$node_name}};
+    $filename .= ".$docu_ext" if (defined($docu_ext));
+
+    # unnumbered sections (except those at top-level!) always go to the same
+    # file as the previous numbered section
+    if (not ($element->{number}) and not ($lastfilename eq '') and ($element->{level} > 1)) {
+      $filename = $lastfilename;
+    }
+    if (($filename eq $lastfilename)) {
+      $$element{doc_nr} = $docnr;
+    } else {
+      $docnr += 1;
+      $$element{doc_nr} = $docnr;
+      $lastfilename = $filename;
+    }
+    return $filename;
+
+  } elsif ($type eq "top" or $type eq "toc" or $type eq "doc" or $type eq "stoc" or $type eq "foot" or $type eq "about") {
+    return;
+  } else {
+    print STDERR "WARNING: Node '$node_name' was NOT found in the map\n"
+        unless ($node_name eq '') or ($element->{'tag'} eq 'unnumberedsec')
+               or ($node_name =~ /NOT REALLY USED/);
+
+    # Numbered sections will get a filename Node_title, unnumbered sections will use
+    # the file name of the previous numbered section:
+    if (($element->{number}) or ($lastfilename eq '') or ($element->{level} == 1)) {
+      # normalize to the same file name as texinfo
+      if ($element->{translationof}) {
+        $node_name = main::remove_texi($element->{translationof});
+      }
+      my $filename = texinfo_file_name($node_name);
+      $filename .= ".$docu_ext" if (defined($docu_ext));
+      $docnr += 1;
+      $$element{doc_nr} = $docnr;
+      $lastfilename = $filename;
+      return $filename;
+    } else {
+      $$element{doc_nr} = $docnr;
+      return $lastfilename;
+    }
+  }
+
+  return;
+}
+
+sub lilypond_element_target_name($$$)
+{
+  my $element = shift;
+  my $target = shift;
+  my $id = shift;
+  # Target is based on node name (or sec name for secs without node attached)
+  my $node_name = main::remove_texi($element->{'node_ref'}->{'texi'});
+  if ($node_name eq '') {
+    $node_name = main::remove_texi($element->{'texi'});
+  }
+
+  # If we have an entry in the section<=>filename map, use that one, otherwise
+  # generate the anchor here. 
+  if (exists ($node_to_filename_map->{$node_name})) {
+    (my $filename, $target) = @{$node_to_filename_map->{$node_name}};
+  } else {
+    my $anchor = $node_name;
+    if ($element->{translationof}) {
+      $anchor = main::remove_texi($element->{translationof});
+    }
+    # normalize to the same file name as texinfo
+    $target = texinfo_file_name($anchor);
+  }
+  # TODO: Once texi2html correctly prints out the target and not the id for
+  #       the sections, change this back to ($id, $target)
+  return ($target, $target);
+}
+
+
+## Load the map file for the corrently processed texi file. We do this
+#  using a command init handler, since texi2html does not have any
+#  other hooks that are called after THISDOC is filled but before phase 2
+#  of the texi2html conversion.
+sub lilypond_init_map ()
+{
+    my ($docu_dir, $docu_name) = split_texi_filename ($Texi2HTML::THISDOC{'input_file_name'});
+    my $map_filename = main::locate_include_file ("${docu_name}.$Texi2HTML::THISDOC{current_lang}.xref-map")
+       || main::locate_include_file ("${docu_name}.xref-map");
+    $node_to_filename_map = load_map_file ($map_filename);
+}
+push @Texi2HTML::Config::command_handler_init, \&lilypond_init_map;
+
+
+
+#############################################################################
+###  CLEANER LINK TITLE FOR EXTERNAL REFS
+#############################################################################
+
+# The default formatting of external refs returns e.g.
+# "(lilypond-internals)Timing_translator", so we remove all (...) from the
+# file_and_node argument. Also, we want only a very simple format, so we don't
+# even call the default handler!
+sub lilypond_external_ref($$$$$$)
+{
+  my $type = shift;
+  my $section = shift;
+  my $book = shift;
+  my $file_node = shift;
+  my $href = shift;
+  my $cross_ref = shift;
+
+  my $displaytext = '';
+
+  # 1) if we have a cross ref name, that's the text to be displayed:
+  # 2) For the top node, use the (printable) name of the manual, unless we
+  #    have an explicit cross ref name
+  # 3) In all other cases use the section name
+  if ($cross_ref ne '') {
+    $displaytext = $cross_ref;
+  } elsif (($section eq '') or ($section eq 'Top')) {
+    $displaytext = $book;
+  } else {
+    $displaytext = $section;
+  }
+
+  $displaytext = &$anchor('', $href, $displaytext) if ($displaytext ne '');
+  return &$I('%{node_file_href}', { 'node_file_href' => $displaytext });
+
+#  Default: format as "see <a ..>NODE</a> section 'SECTION' in BOOK". We don't want this!
+#   return t2h_default_external_ref($type, $section, $book, $file_node, $href, $cross_ref);
+}
+
+
+
+
+
+#############################################################################
+###  HANDLING TRANSLATED SECTIONS: handle @translationof, secname<->filename
+###                  map stored on disk, xrefs in other manuals load that map
+#############################################################################
+
+
+# Try to make use of @translationof to generate files according to the original
+# English section title...
+sub lilypond_unknown($$$$$)
+{
+    my $macro = shift;
+    my $line = shift;
+    my $pass = shift;
+    my $stack = shift;
+    my $state = shift;
+
+    # the @translationof macro provides the original English section title,
+    # which should be used for file/anchor naming, while the title will be
+    # translated to each language
+    # It is already used by extract_texi_filenames.py, so this should not be
+    # necessary here at all. Still, I'll leave the code in just in case the
+    # python script messed up ;-)
+    if ($pass == 1 and $macro eq "translationof") {
+      if (ref($state->{'element'}) eq 'HASH') {
+        $state->{'element'}->{'translationof'} = main::normalise_space($line);
+      }
+      return ('', true, undef, undef);
+    } else {
+      return t2h_default_unknown($macro, $line, $pass, $stack, $state);
+    }
+}
+
+
+
+
+my %translated_books = ();
+# Construct a href to an external source of information.
+# node is the node with texinfo @-commands
+# node_id is the node transliterated and transformed as explained in the
+#         texinfo manual
+# node_xhtml_id is the node transformed such that it is unique and can
+#     be used to make an html cross ref as explained in the texinfo manual
+# file is the file in '(file)node'
+sub lilypond_external_href($$$)
+{
+  my $node = shift;
+  my $node_id = shift;
+  my $node_hxmlt_id = shift;
+  my $file = shift;
+  my $original_func = \&t2h_default_external_href;
+
+  # 1) Keep a hash of book->section_map
+  # 2) if not file in keys hash => try to load the map (assign empty map if
+  #    non-existent => will load only once!)
+  # 3) if node in the section=>(file, anchor) map, replace node_id and
+  #    node_xhtml_id by the map's values
+  # 4) call the t2h_default_external_href with these values (or the old ones if not found)
+
+  if (($node_id ne '') and defined($file) and ($node_id ne 'Top')) {
+    my $map_name = $file;
+    $map_name =~ s/-big-page//;
+
+    # Load the map if we haven't done so already
+    if (!exists($translated_books{$map_name})) {
+      my ($docu_dir, $docu_name) = split_texi_filename ($Texi2HTML::THISDOC{'input_file_name'});
+      my $map_filename = main::locate_include_file ("${map_name}.$Texi2HTML::THISDOC{current_lang}.xref-map")
+         || main::locate_include_file ("${map_name}.xref-map");
+      $translated_books{$map_name} = load_map_file ($map_filename);
+    }
+
+    # look up translation. use these values instead of the old filename/anchor
+    my $section_name_map = $translated_books{$map_name};
+    my $node_text = main::remove_texi($node);
+    if (defined($section_name_map->{$node_text})) {
+      ($node_id, $node_hxmlt_id) = @{$section_name_map->{$node_text}};
+    } else {
+      print STDERR "WARNING: Unable to find node '$node_text' in book $map_name.\n";
+    }
+  }
+
+  if (defined $file) {
+    return &$original_func($node, $node_id, $node_hxmlt_id, $file);
+  } else {
+    return &$original_func($node, $node_id, $node_hxmlt_id);
+  }
+}
+
+
+
+
+
+#############################################################################
+###  CUSTOM TOC FOR EACH PAGE (in a frame on the left)
+#############################################################################
+
+my $page_toc_depth = 2;
+my @default_toc = [];
+
+# recursively generate the TOC entries for the element and its children (which
+# are only shown up to maxlevel. All ancestors of the current element are also
+# shown with their immediate children, irrespective of their level.
+# Unnumbered entries are only printed out if they are at top-level or their
+# parent element is an ancestor of the currently viewed node.
+sub generate_ly_toc_entries($$$$)
+{
+  my $element = shift;
+  my $element_path = shift;
+  my $maxlevel = shift;
+  my $always_show_unnumbered_children = shift;
+  # Skip undefined sections, plus all sections generated by index splitting
+  return() if (not defined($element) or exists($element->{'index_page'}));
+  my @result = ();
+  my $level = $element->{'toc_level'};
+  my $is_parent_of_current = $element->{'id'} && $element_path->{$element->{'id'}};
+  my $print_children = ( ($level < $maxlevel) or $is_parent_of_current );
+  my $ind = '  ' x $level;
+  my $this_css_class = $is_parent_of_current ? " class=\"toc_current\"" : "";
+
+  my $entry = "$ind<li$this_css_class>" . &$anchor ($element->{'tocid'}, "$element->{'file'}#$element->{'target'}",$element->{'text'});
+
+  my $children = $element->{'section_childs'};
+  # Don't add unnumbered entries, unless they are at top-level or a parent of the current!
+  if (not ($element->{'number'} or $always_show_unnumbered_children)) {
+    return @result;
+  }
+  if ( $print_children and defined($children) and (ref($children) eq "ARRAY") ) {
+    push (@result, $entry);
+    my @child_result = ();
+    foreach (@$children) {
+      push (@child_result, generate_ly_toc_entries($_, $element_path, $maxlevel, $is_parent_of_current));
+    }
+    # if no child nodes were generated, e.g. for the index, where expanded pages
+    # are ignored, don't generate a list at all...
+    if (@child_result) {
+      push (@result, "\n$ind<ul$NO_BULLET_LIST_ATTRIBUTE>\n");
+      push (@result, @child_result);
+      push (@result, "$ind</ul></li>\n");
+    }
+  } else {
+    push (@result, $entry . "</li>\n");
+  }
+  return @result;
+}
+
+
+# Print a customized TOC, containing only the first two levels plus the whole
+# path to the current page
+sub lilypond_generate_page_toc_body($)
+{
+    my $element = shift;
+    my $current_element = $element;
+    my %parentelements;
+    $parentelements{$element->{'id'}} = 1;
+    # Find the path to the current element
+    while ( defined($current_element->{'sectionup'}) and
+           ($current_element->{'sectionup'} ne $current_element) )
+    {
+      $parentelements{$current_element->{'sectionup'}->{'id'}} = 1
+              if ($current_element->{'sectionup'}->{'id'} ne '');
+      $current_element = $current_element->{'sectionup'};
+    }
+    return () if not defined($current_element);
+    # Create the toc entries recursively
+    my @toc_entries = ("<div class=\"contents\">\n", "<ul$NO_BULLET_LIST_ATTRIBUTE>\n");
+    my $children = $current_element->{'section_childs'};
+    foreach ( @$children ) {
+      push (@toc_entries, generate_ly_toc_entries($_, \%parentelements, $page_toc_depth, False));
+    }
+    push (@toc_entries, "</ul>\n");
+    push (@toc_entries, "</div>\n");
+    return @toc_entries;
+}
+
+sub lilypond_print_toc_div ($$)
+{
+  my $fh = shift;
+  my $tocref = shift;
+  my @lines = @$tocref;
+  # use default TOC if no custom lines have been generated
+  @lines = @default_toc if (not @lines);
+  if (@lines) {
+    print $fh "\n\n<div id=\"tocframe\">\n";
+    print $fh '<h4> ' . $Texi2HTML::NAME{'Contents'}  . "</h4>\n";
+    foreach my $line (@lines) {
+      print $fh $line;
+    }
+    print $fh "</div>\n\n";
+  }
+}
+
+# Create the custom TOC for this page (partially folded, current page is
+# highlighted) and store it in a global variable. The TOC is written out after
+# the html contents (but positioned correctly using CSS), so that browsers with
+# css turned off still show the contents first.
+our @this_page_toc = ();
+sub lilypond_print_element_header
+{
+  my $fh = shift;
+  my $first_in_page = shift;
+  my $previous_is_top = shift;
+  if ($first_in_page and not @this_page_toc) {
+    if (defined($Texi2HTML::THIS_ELEMENT)) {
+      # Create the TOC for this page
+      @this_page_toc = lilypond_generate_page_toc_body($Texi2HTML::THIS_ELEMENT);
+    }
+  }
+  return T2H_DEFAULT_print_element_header( $fh, $first_in_page, $previous_is_top);
+}
+
+# Generate the HTML output for the TOC
+sub lilypond_toc_body($)
+{
+    my $elements_list = shift;
+    # Generate a default TOC for pages without THIS_ELEMENT
+    @default_toc = lilypond_generate_page_toc_body(@$elements_list[0]);
+    return T2H_GPL_toc_body($elements_list);
+}
+
+# Print out the TOC in a <div> at the beginning of the page
+sub lilypond_print_page_head($)
+{
+    my $fh = shift;
+    T2H_DEFAULT_print_page_head($fh);
+    print $fh "<div id=\"main\">\n";
+}
+
+# Print out the TOC in a <div> at the end of th page, which will be formatted as a
+# sidebar mimicking a TOC frame
+sub print_lilypond_page_foot($)
+{
+  my $fh = shift;
+  my $program_string = &$program_string();
+  print $fh "<p><font size='-1'>$program_string</font><br>$PRE_BODY_CLOSE</p>\n";
+  print $fh "<!-- FOOTER -->\n\n";
+  print $fh "<!-- end div#main here -->\n</div>\n\n";
+
+  # Print the TOC frame and reset the TOC:
+  lilypond_print_toc_div ($fh, \@this_page_toc);
+  @this_page_toc = ();
+
+  # Close the page:
+  print $fh "</body>\n</html>\n";
+}
+
+
+
+
+
+#############################################################################
+###  NICER / MORE FLEXIBLE NAVIGATION PANELS
+#############################################################################
+
+sub get_navigation_text
+{
+  my $button = shift;
+  my $text = $NAVIGATION_TEXT{$button};
+  if ( ($button eq 'Back') or ($button eq 'FastBack') ) {
+    $text = $text . $Texi2HTML::NODE{$button} . "&nbsp;";
+  } elsif ( ($button eq 'Forward') or ($button eq 'FastForward') ) {
+    $text = "&nbsp;" . $Texi2HTML::NODE{$button} . $text;
+  } elsif ( $button eq 'Up' ) {
+    $text = "&nbsp;".$text.":&nbsp;" . $Texi2HTML::NODE{$button} . "&nbsp;";
+  }
+  return $text;
+}
+
+
+# Don't automatically create left-aligned table cells for every link, but
+# instead create a <td> only on an appropriate '(left|right|center)-aligned-cell-n'
+# button text. It's alignment as well as the colspan will be taken from the
+# name of the button. Also, add 'newline' button text to create a new table
+# row. The texts of the buttons are generated by get_navigation_text and
+# will contain the name of the next/previous section/chapter.
+sub lilypond_print_navigation
+{
+    my $fh = shift;
+    my $buttons = shift;
+    my $vertical = shift;
+    my $spacing = 1;
+#     print $fh '<table cellpadding="', $spacing, '" cellspacing="', $spacing,
+#       "\" border=\"0\" class=\"nav_table\">\n";
+    print $fh "<table class=\"nav_table\">\n";
+
+    print $fh "<tr>" unless $vertical;
+    my $beginofline = 1;
+    foreach my $button (@$buttons)
+    {
+        print $fh qq{<tr valign="top" align="left">\n} if $vertical;
+        # Allow (left|right|center)-aligned-cell and newline as buttons!
+        if ( $button =~ /^(.*)-aligned-cell-(.*)$/ )
+        {
+          print $fh qq{</td>} unless $beginofline;
+          print $fh qq{<td valign="middle" align="$1" colspan="$2">};
+          $beginofline = 0;
+        }
+        elsif ( $button eq 'newline' )
+        {
+          print $fh qq{</td>} unless $beginofline;
+          print $fh qq{</tr>};
+          print $fh qq{<tr>};
+          $beginofline = 1;
+
+        }
+        elsif (ref($button) eq 'CODE')
+        {
+            &$button($fh, $vertical);
+        }
+        elsif (ref($button) eq 'SCALAR')
+        {
+            print $fh "$$button" if defined($$button);
+        }
+        elsif (ref($button) eq 'ARRAY')
+        {
+            my $text = $button->[1];
+            my $button_href = $button->[0];
+            # verify that $button_href is simple text and text is a reference
+            if (defined($button_href) and !ref($button_href)
+               and defined($text) and (ref($text) eq 'SCALAR') and defined($$text))
+            {             # use given text
+                if ($Texi2HTML::HREF{$button_href})
+                {
+                  my $anchor_attributes = '';
+                  if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$button_href})) and ($BUTTONS_ACCESSKEY{$button_href} ne ''))
+                  {
+                      $anchor_attributes = "accesskey=\"$BUTTONS_ACCESSKEY{$button_href}\"";
+                  }
+                  if ($USE_REL_REV and (defined($BUTTONS_REL{$button_href})) and ($BUTTONS_REL{$button_href} ne ''))
+                  {
+                      $anchor_attributes .= " rel=\"$BUTTONS_REL{$button_href}\"";
+                  }
+                  print $fh "" .
+                        &$anchor('',
+                                    $Texi2HTML::HREF{$button_href},
+                                    get_navigation_text($$text),
+                                    $anchor_attributes
+                                   );
+                }
+                else
+                {
+                  print $fh get_navigation_text($$text);
+                }
+            }
+        }
+        elsif ($button eq ' ')
+        {                       # handle space button
+            print $fh
+                ($ICONS && $ACTIVE_ICONS{' '}) ?
+                    &$button_icon_img($BUTTONS_NAME{$button}, $ACTIVE_ICONS{' '}) :
+                        $NAVIGATION_TEXT{' '};
+            #next;
+        }
+        elsif ($Texi2HTML::HREF{$button})
+        {                       # button is active
+            my $btitle = $BUTTONS_GOTO{$button} ?
+                'title="' . $BUTTONS_GOTO{$button} . '"' : '';
+            if ($USE_ACCESSKEY and (defined($BUTTONS_ACCESSKEY{$button})) and ($BUTTONS_ACCESSKEY{$button} ne ''))
+            {
+                $btitle .= " accesskey=\"$BUTTONS_ACCESSKEY{$button}\"";
+            }
+            if ($USE_REL_REV and (defined($BUTTONS_REL{$button})) and ($BUTTONS_REL{$button} ne ''))
+            {
+                $btitle .= " rel=\"$BUTTONS_REL{$button}\"";
+            }
+            if ($ICONS && $ACTIVE_ICONS{$button})
+            {                   # use icon
+                print $fh '' .
+                    &$anchor('',
+                        $Texi2HTML::HREF{$button},
+                        &$button_icon_img($BUTTONS_NAME{$button},
+                                   $ACTIVE_ICONS{$button},
+                                   $Texi2HTML::SIMPLE_TEXT{$button}),
+                        $btitle
+                      );
+            }
+            else
+            {                   # use text
+                print $fh
+                    '[' .
+                        &$anchor('',
+                                    $Texi2HTML::HREF{$button},
+                                    get_navigation_text ($button),
+                                    $btitle
+                                   ) .
+                                       ']';
+            }
+        }
+        else
+        {                       # button is passive
+            print $fh
+                $ICONS && $PASSIVE_ICONS{$button} ?
+                    &$button_icon_img($BUTTONS_NAME{$button},
+                                          $PASSIVE_ICONS{$button},
+                                          $Texi2HTML::SIMPLE_TEXT{$button}) :
+
+                                              "[" . get_navigation_text($button) . "]";
+        }
+        print $fh "</td>\n" if $vertical;
+        print $fh "</tr>\n" if $vertical;
+    }
+    print $fh "</td>" unless $beginofline;
+    print $fh "</tr>" unless $vertical;
+    print $fh "</table>\n";
+}
+
+
+@Texi2HTML::Config::SECTION_BUTTONS =
+    ('left-aligned-cell-1', 'FastBack',
+     'center-aligned-cell-3', 'Top', 'Contents', 'Index', 'About',
+     'right-aligned-cell-1', 'FastForward',
+     'newline',
+     'left-aligned-cell-2', 'Back',
+     'center-aligned-cell-1', 'Up',
+     'right-aligned-cell-2', 'Forward'
+    );
+
+# buttons for misc stuff
+@Texi2HTML::Config::MISC_BUTTONS = ('center-aligned-cell-3', 'Top', 'Contents', 'Index', 'About');
+
+# buttons for chapter file footers
+# (and headers but only if SECTION_NAVIGATION is false)
+@Texi2HTML::Config::CHAPTER_BUTTONS =
+    ('left-aligned-cell-1', 'FastBack',
+     'center-aligned-cell-3', 'Top', 'Contents', 'Index', 'About',
+     'right-aligned-cell-1', 'FastForward',
+    );
+
+# buttons for section file footers
+@Texi2HTML::Config::SECTION_FOOTER_BUTTONS =
+    ('left-aligned-cell-1', 'FastBack',
+     'center-aligned-cell-3', 'Top', 'Contents', 'Index', 'About',
+     'right-aligned-cell-1', 'FastForward',
+     'newline',
+     'left-aligned-cell-2', 'Back',
+     'center-aligned-cell-1', 'Up',
+     'right-aligned-cell-2', 'Forward'
+    );
+
+@Texi2HTML::Config::NODE_FOOTER_BUTTONS =
+    ('left-aligned-cell-1', 'FastBack',
+     'center-aligned-cell-3', 'Top', 'Contents', 'Index', 'About',
+     'right-aligned-cell-1', 'FastForward',
+     'newline',
+     'left-aligned-cell-2', 'Back',
+     'center-aligned-cell-1', 'Up',
+     'right-aligned-cell-2', 'Forward'
+    );
+
+
+
+
+
+#############################################################################
+###  FOOTNOTE FORMATTING
+#############################################################################
+
+# Format footnotes in a nicer way: Instead of printing the number in a separate
+# (nr) heading line, use the standard way of prepending <sup>nr</sup> immediately
+# before the fn text.
+
+
+# The following code is copied from texi2html's examples/makeinfo.init and 
+# should be updated when texi2html makes some changes there!
+
+my $makekinfo_like_footnote_absolute_number = 0;
+
+sub makeinfo_like_foot_line_and_ref($$$$$$$$)
+{
+    my $foot_num = shift;
+    my $relative_num = shift;
+    my $footid = shift;
+    my $docid = shift;
+    my $from_file = shift;
+    my $footnote_file = shift;
+    my $lines = shift;
+    my $state = shift;
+    
+    $makekinfo_like_footnote_absolute_number++;
+
+    # this is a bit obscure, this allows to add an anchor only if formatted
+    # as part of the document.
+    $docid = '' if ($state->{'outside_document'} or $state->{'multiple_pass'});
+
+    if ($from_file eq $footnote_file)
+    { 
+        $from_file = $footnote_file = '';
+    }
+
+    my $foot_anchor = "<sup>" . &$anchor($docid, "$footnote_file#$footid", $relative_num) . "</sup>";
+    $foot_anchor = &$anchor($docid, "$footnote_file#$footid", "($relative_num)") if ($state->{'preformatted'});
+
+#    unshift @$lines, "<li>";
+#    push @$lines, "</li>\n";
+    return ($lines, $foot_anchor);
+}
+
+sub makeinfo_like_foot_lines($)
+{
+    my $lines = shift;
+    unshift @$lines, "<hr>\n<h4>$Texi2HTML::I18n::WORDS->{'Footnotes_Title'}</h4>\n";
+#<ol type=\"1\">\n";
+#    push @$lines, "</ol>";
+    return $lines;
+}
+
+my %makekinfo_like_paragraph_in_footnote_nr;
+
+sub makeinfo_like_paragraph ($$$$$$$$$$$$$)
+{
+    my $text = shift;
+    my $align = shift;
+    my $indent = shift;
+    my $paragraph_command = shift;
+    my $paragraph_command_formatted = shift;
+    my $paragraph_number = shift;
+    my $format = shift;
+    my $item_nr = shift;
+    my $enumerate_style = shift;
+    my $number = shift;
+    my $command_stack_at_end = shift;
+    my $command_stack_at_begin = shift;
+    my $state = shift;
+#print STDERR "format: $format\n" if (defined($format));
+#print STDERR "paragraph @$command_stack_at_end; @$command_stack_at_begin\n";
+    $paragraph_command_formatted = '' if (!defined($paragraph_command_formatted) or
+          exists($special_list_commands{$format}->{$paragraph_command}));
+    return '' if ($text =~ /^\s*$/);
+    foreach my $style(t2h_collect_styles($command_stack_at_begin))
+    {
+       $text = t2h_begin_style($style, $text);
+    }
+    foreach my $style(t2h_collect_styles($command_stack_at_end))
+    {
+       $text = t2h_end_style($style, $text);
+    }
+    if (defined($paragraph_number) and defined($$paragraph_number))
+    {
+         $$paragraph_number++;
+         return $text  if (($format eq 'itemize' or $format eq 'enumerate') and
+            ($$paragraph_number == 1));
+    }
+    my $open = '<p';
+    if ($align)
+    {
+        $open .= " align=\"$paragraph_style{$align}\"";
+    }
+    my $footnote_text = '';
+    if (defined($command_stack_at_begin->[0]) and $command_stack_at_begin->[0] eq 'footnote')
+    {
+        my $state = $Texi2HTML::THISDOC{'state'};
+        $makekinfo_like_paragraph_in_footnote_nr{$makekinfo_like_footnote_absolute_number}++;
+        if ($makekinfo_like_paragraph_in_footnote_nr{$makekinfo_like_footnote_absolute_number} <= 1)
+        {
+           $open.=' class="footnote"';
+           my $document_file = $state->{'footnote_document_file'};
+           if ($document_file eq $state->{'footnote_footnote_file'})
+           {
+               $document_file = '';
+           }
+           my $docid = $state->{'footnote_place_id'};
+           my $doc_state = $state->{'footnote_document_state'};
+           $docid = '' if ($doc_state->{'outside_document'} or $doc_state->{'multiple_pass'});
+           my $foot_label = &$anchor($state->{'footnote_footnote_id'}, 
+                 $document_file . "#$state->{'footnote_place_id'}", 
+                 "$state->{'footnote_number_in_page'}");
+           $footnote_text = "<small>[${foot_label}]</small> ";
+        }
+    }
+    return $open.'>'.$footnote_text.$text.'</p>';
+}
+
+
+#############################################################################
+###  OTHER SETTINGS
+#############################################################################
+
+# For split pages, use index.html as start page!
+if ($Texi2HTML::Config::SPLIT eq 'section') {
+  $Texi2HTML::Config::TOP_FILE = 'index.html';
+}
+
+
+return 1;
index 4e917c5da066399a5ade18c9957739c3ac5942bb..8afe50af8442ffd541fc05052c3e00fead754aa0 100644 (file)
@@ -1,4 +1,4 @@
 default:
 
-local-WWW: $(OUT_HTML_FILES)
+local-WWW-2: $(OUT_HTML_FILES)
        $(PYTHON) $(buildscript-dir)/mass-link.py --prepend-suffix .$(ISOLANG) hard $(outdir) $(top-build-dir)/Documentation/$(outdir) $(HTML_FILES)
diff --git a/make/doc-i18n-user-rules.make b/make/doc-i18n-user-rules.make
new file mode 100644 (file)
index 0000000..41a0539
--- /dev/null
@@ -0,0 +1,42 @@
+ifeq (,$(findstring texi2html,$(MISSING_OPTIONAL)))
+$(outdir)/%/index.html: $(outdir)/%.texi $(XREF_MAPS_DIR)/%.$(ISOLANG).xref-map $(OUT_PNG_IMAGES) $(outdir)/version.itexi
+       mkdir -p $(dir $@)
+       $(TEXI2HTML) --I=$(outdir) $(TEXI2HTML_FLAGS) --output=$(dir $@) --prefix=index --split=section $(TEXI2HTML_INIT) $<
+       cp $(top-src-dir)/Documentation/lilypond*.css $(dir $@)
+
+$(outdir)/%-big-page.html: $(outdir)/%.texi $(XREF_MAPS_DIR)/%.$(ISOLANG).xref-map $(OUT_PNG_IMAGES) $(outdir)/version.itexi
+       $(TEXI2HTML) --I=$(outdir) -D bigpage $(TEXI2HTML_FLAGS) --output=$@ $(TEXI2HTML_INIT) $<
+       cp $(top-src-dir)/Documentation/lilypond*.css $(dir $@)
+else # Rules using makeinfo follow
+$(outdir)/%/index.html: $(outdir)/%.texi $(outdir)/version.itexi
+       mkdir -p $(dir $@)
+       $(MAKEINFO) -P $(outdir) --output=$(outdir)/$* --css-include=$(top-src-dir)/Documentation/texinfo.css --html $<
+
+$(outdir)/%-big-page.html: $(outdir)/%.texi $(outdir)/version.itexi
+       $(MAKEINFO) -P $(outdir) --output=$@ --css-include=$(top-src-dir)/Documentation/texinfo.css --html --no-split --no-headers $< 
+endif
+
+$(outdir)/%.pdftexi: $(outdir)/%.texi $(outdir)/version.itexi
+       $(PYTHON) $(buildscript-dir)/texi-gettext.py $(ISOLANG) $<
+
+$(outdir)/%.pdf: $(outdir)/%.pdftexi $(outdir)/version.itexi
+       cd $(outdir); texi2pdf $(TEXI2PDF_FLAGS) $(TEXINFO_PAPERSIZE_OPTION) $(notdir $*).pdftexi
+
+$(outdir)/version.%: $(top-src-dir)/VERSION
+       echo '@macro version'> $@
+       echo $(TOPLEVEL_VERSION)>> $@
+       echo '@end macro'>> $@
+
+$(outdir)/%.png: $(top-build-dir)/Documentation/user/$(outdir)/%.png
+       ln -f $< $@
+
+$(XREF_MAPS_DIR)/%.$(ISOLANG).xref-map: $(outdir)/%.texi
+       $(PYTHON) $(buildscript-dir)/extract_texi_filenames.py -o $(XREF_MAPS_DIR) $<
+
+# This makes sure lilypond-doc gettext domain has been compiled
+# before lilypond-book runs
+$(TELY_FILES): doc-po
+
+$(MASTER_TEXI_FILES): $(ITELY_FILES) $(ITEXI_FILES)
+
+.SECONDARY:
diff --git a/make/doc-i18n-user-targets.make b/make/doc-i18n-user-targets.make
new file mode 100644 (file)
index 0000000..7f8f679
--- /dev/null
@@ -0,0 +1,14 @@
+default:
+
+local-WWW-1: $(MASTER_TEXI_FILES) $(PDF_FILES) $(XREF_MAPS_FILES)
+
+# BIG_PAGE_HTML_FILES is defined differently in each language makefile
+local-WWW-2: $(DEEP_HTML_FILES) $(BIG_PAGE_HTML_FILES)
+       find $(outdir) -name '*.html' | xargs grep -L 'UNTRANSLATED NODE: IGNORE ME' | xargs $(PYTHON) $(buildscript-dir)/html-gettext.py $(ISOLANG)
+       find $(outdir) -name '*.html' | xargs grep -L --label="" 'UNTRANSLATED NODE: IGNORE ME' | sed 's!$(outdir)/!!g' | xargs $(PYTHON) $(buildscript-dir)/mass-link.py --prepend-suffix .$(ISOLANG) hard $(outdir) $(top-build-dir)/Documentation/user/$(outdir) $(TELY_FILES:%.tely=%.pdf)
+       find $(outdir) \( -name 'lily-*.png' -o -name 'lily-*.ly' \) | sed 's!$(outdir)/!!g' | xargs $(PYTHON) $(buildscript-dir)/mass-link.py hard $(outdir) $(top-build-dir)/Documentation/user/$(outdir)
+
+doc-po:
+       $(MAKE) -C $(depth)/Documentation/po out=www messages
+
+.PHONY: doc-po
diff --git a/make/doc-i18n-user-vars.make b/make/doc-i18n-user-vars.make
new file mode 100644 (file)
index 0000000..bee28ee
--- /dev/null
@@ -0,0 +1,36 @@
+# ISOLANG must be defined
+
+LANGS = $(shell $(PYTHON) $(buildscript-dir)/langdefs.py)
+
+SOURCE_PNG_IMAGES=$(shell ls $(top-src-dir)/Documentation/user/*.png)
+OUT_PNG_IMAGES=$(SOURCE_PNG_IMAGES:$(top-src-dir)/Documentation/user/%.png=$(outdir)/%.png) $(outdir)/context-example.png
+
+TELY_FILES := $(call src-wildcard,*.tely)
+MASTER_TEXI_FILES := $(TELY_FILES:%.tely=$(outdir)/%.texi)
+BIG_PAGE_HTML_FILES := $(BIG_PAGE_MANUALS:%=$(outdir)/%-big-page.html)
+DEEP_HTML_FILES := $(TELY_FILES:%.tely=$(outdir)/%/index.html)
+PDF_FILES := $(TELY_FILES:%.tely=$(outdir)/%.pdf)
+
+ITELY_FILES := $(call src-wildcard,*.itely)
+ITEXI_FILES := $(call src-wildcard,*.itexi)
+
+DOCUMENTATION_INCLUDES = \
+  -I $(top-src-dir)/Documentation/user \
+  -I $(top-build-dir)/Documentation/user/$(outdir)
+
+LILYPOND_BOOK_INCLUDES += $(DOCUMENTATION_INCLUDES)
+MAKEINFO_FLAGS += --force --enable-encoding $(DOCUMENTATION_INCLUDES)
+MAKEINFO = LANG= $(MAKEINFO_PROGRAM) $(MAKEINFO_FLAGS)
+
+# texi2html xref map files
+XREF_MAPS_DIR=$(top-build-dir)/out/xref-maps
+XREF_MAPS_FILES=$(TELY_FILES:%.tely=$(XREF_MAPS_DIR)/%.$(ISOLANG).xref-map)
+
+# texi2html flags
+TEXI2HTML_INIT= --init-file=$(top-src-dir)/lilypond-texi2html.init
+TEXI2HTML_LANG=--lang=$(ISOLANG)
+TEXI2HTML_FLAGS += $(TEXI2HTML_LANG) $(DOCUMENTATION_INCLUDES) \
+  -I $(XREF_MAPS_DIR)
+TEXI2HTML = LANG= $(TEXI2HTML_PROGRAM)
+
+TEXI2PDF_FLAGS += -q --batch $(DOCUMENTATION_INCLUDES)
diff --git a/make/doclang-rules.make b/make/doclang-rules.make
deleted file mode 100644 (file)
index 10fa6ef..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-$(outdir)/%/index.html: $(outdir)/%.texi $(outdir)/version.itexi
-       mkdir -p $(dir $@)
-       $(MAKEINFO) -P $(outdir) --output=$(outdir)/$* --css-include=$(top-src-dir)/Documentation/texinfo.css --html $<
-
-$(outdir)/%-big-page.html: $(outdir)/%.texi $(outdir)/version.itexi
-       $(MAKEINFO) -P $(outdir) --output=$@ --css-include=$(top-src-dir)/Documentation/texinfo.css --html --no-split --no-headers $< 
-
-$(outdir)/%.pdftexi: $(outdir)/%.texi doc-po $(outdir)/version.itexi
-       $(PYTHON) $(buildscript-dir)/texi-gettext.py $(ISOLANG) $<
-
-$(outdir)/%.pdf: $(outdir)/%.pdftexi
-       cd $(outdir); texi2pdf $(TEXI2PDF_FLAGS) $(TEXINFO_PAPERSIZE_OPTION) $(notdir $*).pdftexi
-
-$(outdir)/version.%: $(top-src-dir)/VERSION
-       echo '@macro version'> $@
-       echo $(TOPLEVEL_VERSION)>> $@
-       echo '@end macro'>> $@
-
-# This makes sure lilypond-doc gettext domain has been compiled
-# before lilypond-book runs
-%.tely: doc-po
-
-$(OUT_TEXI_FILES): $(ITELY_FILES) $(ITEXI_FILES)
-
-$(DEEP_HTML_FILES) $(PDF_FILES): $(ITELY_FILES) $(ITEXI_FILES)
-
-.SECONDARY:
diff --git a/make/doclang-targets.make b/make/doclang-targets.make
deleted file mode 100644 (file)
index 4fd4bad..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-default:
-
-# BIG_PAGE_HTML_FILES is defined differently in each language makefile
-local-WWW: $(DEEP_HTML_FILES) $(PDF_FILES) doc-po $(BIG_PAGE_HTML_FILES)
-       find $(outdir) -name '*.html' | xargs grep -L 'UNTRANSLATED NODE: IGNORE ME' | xargs $(PYTHON) $(buildscript-dir)/html-gettext.py $(ISOLANG)
-       find $(outdir) -name '*.html' | xargs grep -L --label="" 'UNTRANSLATED NODE: IGNORE ME' | sed 's!$(outdir)/!!g' | xargs $(PYTHON) $(buildscript-dir)/mass-link.py --prepend-suffix .$(ISOLANG) hard $(outdir) $(top-build-dir)/Documentation/user/$(outdir) $(TELY_FILES:%.tely=%.pdf)
-       find $(outdir) \( -name 'lily-*.png' -o -name 'lily-*.ly' \) | sed 's!$(outdir)/!!g' | xargs $(PYTHON) $(buildscript-dir)/mass-link.py hard $(outdir) $(top-build-dir)/Documentation/user/$(outdir)
-
-doc-po:
-       $(MAKE) -C $(depth)/Documentation/po out=www messages
diff --git a/make/doclang-vars.make b/make/doclang-vars.make
deleted file mode 100644 (file)
index 08d17b9..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# ISOLANG must be defined
-
-LANGS = $(shell $(PYTHON) $(buildscript-dir)/langdefs.py)
-
-DOCUMENTATION_INCLUDES = \
-  -I $(top-src-dir)/Documentation/user \
-  -I $(top-build-dir)/Documentation/user/$(outdir)
-
-LILYPOND_BOOK_INCLUDES += $(DOCUMENTATION_INCLUDES)
-MAKEINFO_FLAGS += --force --enable-encoding $(DOCUMENTATION_INCLUDES)
-MAKEINFO = LANG= $(MAKEINFO_PROGRAM) $(MAKEINFO_FLAGS)
-
-TEXI2PDF_FLAGS += -q --batch $(DOCUMENTATION_INCLUDES)
-
-TELY_FILES = $(call src-wildcard,*.tely)
-OUT_TEXI_FILES = $(TELY_FILES:%.tely=$(outdir)/%.texi)
-DEEP_HTML_FILES = $(TELY_FILES:%.tely=$(outdir)/%/index.html)
-PDF_FILES = $(TELY_FILES:%.tely=$(outdir)/%.pdf)
-
-ITELY_FILES := $(call src-wildcard,*.itely)
-ITEXI_FILES := $(call src-wildcard,*.itexi)
index 201a9ea7a4e5c5b2d81aab5f3e91e3a68a4112f2..428e5b900a939f4441e78c79710bc56ad64f9012 100644 (file)
@@ -18,6 +18,7 @@ mi2mu-dir = $(src-depth)/mi2mu
 make-dir = $(src-depth)/make
 include-flower = $(src-depth)/flower/include
 
+export PYTHONPATH:=$(buildscript-dir):$(PYTHONPATH)
 
 LILYPOND_INCLUDES = $(include-flower) $(depth)/flower/$(outdir)
 
index bc9e47b963da2713c0c238c20396a5e9c1c93c94..fe849db405729d138aae85bc6de929d523145dfc 100644 (file)
@@ -12,14 +12,11 @@ $(outdir)/%.latex:  %.doc
 # don't do ``cd $(outdir)'', and assume that $(outdir)/.. is the src dir.
 # it is not, for --srcdir builds
 $(outdir)/%.texi: %.tely $(outdir)/version.itexi
-       $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BOOK_PROCESS) $(LILYPOND_BOOK_LILYPOND_FLAGS)' --output=$(outdir)  --format=$(LILYPOND_BOOK_FORMAT) $(LILYPOND_BOOK_FLAGS) $<
+       $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BOOK_PROCESS) $(LILYPOND_BOOK_LILYPOND_FLAGS)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) $(LILYPOND_BOOK_FLAGS) $<
 
 
 $(outdir)/%.texi: $(outdir)/%.tely $(outdir)/version.itexi
        $(PYTHON) $(LILYPOND_BOOK) $(LILYPOND_BOOK_INCLUDES) --process='$(LILYPOND_BOOK_PROCESS) $(LILYPOND_BOOK_INCLUDES) $(LILYPOND_BOOK_LILYPOND_FLAGS)' --output=$(outdir) --format=$(LILYPOND_BOOK_FORMAT) $(LILYPOND_BOOK_FLAGS) $<
-#
-# DON'T REMOVE SOURCE FILES, otherwise the .TEXI ALWAYS OUT OF DATE.
-#      rm -f $<
 
 $(outdir)/%.html.omf: %.tely
        $(call GENERATE_OMF,html)
index b4655018836878f4b5b5e2945ecd2a650dd991fa..be960222b784b92c7b5a7fa382453bf562848be0 100644 (file)
@@ -1,4 +1,3 @@
-
 $(outdir)/collated-files.tely: $(LY_FILES) $(OUT_LY_FILES)
        $(PYTHON) $(buildscript-dir)/lys-to-tely.py --name=$(outdir)/collated-files.tely --title="$(TITLE)" $^
 
index c2d08b5fec312cd2ac4c3263b06fd197ca0dc0ea..0b5d6ec2ed493d57143ccedf53fa3d524772e7e5 100644 (file)
@@ -1,8 +1,6 @@
+local-WWW-1: $(outdir)/collated-files.texi $(outdir)/collated-files.pdf
 
-
-local-WWW: $(outdir)/collated-files.html $(outdir)/collated-files.pdf
-
-#.PRECIOUS: $(outdir)/$(NAME).texi
+local-WWW-2: $(outdir)/collated-files.html
 
 local-test-baseline:
        rm -rf $(outdir)-baseline
index e6532133637deee579e3bc14f8c3d6f54433bdd6..96d44b12f3855a5746be979e11b8330e08c5ea7d 100644 (file)
@@ -1,4 +1,2 @@
 TITLE=LYs Doc
 
-NAME=collated-files
-
index 4a12833a556621119315215f2bdd2ad783abdebb..deaf2408616932a5375971f2ae79596ba559d91d 100644 (file)
@@ -1,14 +1,12 @@
 .PHONY: download mutopia png ps scores tar
 
 .PRECIOUS: $(outdir)/%.ps $(outdir)/%-book.ps
-.PRECIOUS: $(outdir)-letter/%.dvi $(outdir)-letter/%.ps
+.PRECIOUS: $(outdir)-letter/%.ps
 
 
 all: $(OUT_FILES)
 
-# we want dvi_examples as well, because they get thrown away otherwise
-# incurring another costly lilypond run.
-local-WWW: $(ly_examples) $(pdf_examples) $(png_examples)
+local-WWW-1: $(ly_examples) $(pdf_examples) $(png_examples)
 
 tar:
        mkdir -p $(outdir)/$(tarball)
@@ -24,7 +22,7 @@ scores: $(score_ps)
        $(MAKE) ps_examples="$<" ps
 
 local-mutopia:
-       $(MAKE) examples="$(mutopia-examples)" PAPERSIZE=letter local-WWW $(mutopia-letter)
+       $(MAKE) examples="$(mutopia-examples)" PAPERSIZE=letter local-WWW-1 $(mutopia-letter)
 
 mutopia: local-mutopia
        $(LOOP)
index 02a09736b0927715bde6dfe74458599d14d300e8..8d7bb3bc25c001b99634efb1e47298ebd6843bf3 100644 (file)
 
      (if (pair? uprops)
         (string-append
-         "\n\n@unnumberedsubsubsec User settable properties:\n"
+         "\n\n@subsubheading User settable properties:\n"
          (description-list->texi user-propdocs #t))
         "")
 
      (if (pair? iprops)
         (string-append
-         "\n\n@unnumberedsubsubsec Internal properties:\n"
+         "\n\n@subsubheading Internal properties:\n"
          (description-list->texi internal-propdocs #t))
         ""))))
 
index 7f87df80fd6b80c66d21ca517fb96f7b5795a236..36af5b3a698baf16b83c714350e2783101ba7c8e 100644 (file)
                  "(lilypond/lilypond-internals.info)")
   "
 
-@c NOTE: This is documentation-generate.scm, not macros.itexi
+@include macros.texi
 
+@ignore
+@omftitle LilyPond internals
+@omfcreator Han-Wen Nienhuys and Jan Nieuwenhuizen
+@omfdescription Programmer's reference of the LilyPond music engraving system
+@omftype user's guide
+@omflanguage English
+@omfcategory Applications|Publishing
+@end ignore
 
-@macro q{TEXT}
-@quoteleft{}\\TEXT\\@quoteright{}
-@end macro
-
-@macro qq{TEXT}
-@quotedblleft{}\\TEXT\\@quotedblright{}
-@end macro
-
+@iftex
+@afourpaper
+@c don't replace quotes with directed quotes
+@tex
+\\gdef\\SETtxicodequoteundirected{Foo}
+\\gdef\\SETtxicodequotebacktick{Bla}
+@end tex
+@end iftex
 
 @ifhtml
-@c ***** HTML *****
-
-@ifset bigpage
-
-@macro ruser{TEXT}
-@ref{\\TEXT\\,,,lilypond-big-page,Notation Reference}
-@cindex \\TEXT\\
-@end macro
-
-@end ifset
-
-@ifclear bigpage
-
-@macro ruser{NAME}
-@ref{\\NAME\\,,,lilypond,Notation Reference}
-@cindex \\NAME\\
-@end macro
-
-@end ifclear
-
-@macro inputfileref{DIR,NAME}
-@uref{source/\\DIR\\/out-www/collated-files.html#\\NAME\\,@file{\\DIR\\/\\NAME\\}}@c
-@end macro
-
+This document is also available as a
+@uref{source/Documentation/user/lilypond-internals.pdf,PDF} and as
+@uref{source/Documentation/user/lilypond-internals-big-page.html,one big page}.
 @end ifhtml
 
+@finalout
 
-@ifinfo
-@c ***** info *****
+@titlepage
+@title LilyPond
+@subtitle The music typesetter
+@titlefont{Internals Reference}
+@author The LilyPond development team
 
-@macro ruser{NAME}
-@ref{\\NAME\\,,,lilypond,Notation Reference}
-@cindex \\NAME\\
-@end macro
+Copyright @copyright{} 1999--2008 by the authors
 
-@macro inputfileref{DIR,NAME}
-@file{\\DIR\\/\\NAME\\}
-@end macro
+@vskip 20pt
 
-@end ifinfo
-
-
-@iftex
-@c ***** TeX *****
-
-@macro ruser{NAME}
-@ref{\\NAME\\}@c
-@end macro
-
-@macro inputfileref{DIR,NAME}@c
-@file{\\DIR\\/\\NAME\\}@c
-@end macro
-
-@end iftex
-
-
-@macro rinternals{NAME}
-@ref{\\NAME\\}
-@end macro
-
-
-@ignore
-@omftitle LilyPond internals
-@omfcreator Han-Wen Nienhuys and Jan Nieuwenhuizen
-@omfdescription Programmer's reference of the LilyPond music engraving system
-@omftype user's guide
-@omflanguage English
-@omfcategory Applications|Publishing
-@end ignore
+For LilyPond version @version{}
+@end titlepage
 
+@contents
 
+@ifnottex
 ")
  out-port)
 
 (define top-node
   (make <texi-node>
     #:name "Top"
-    #:text 
-    (string-append  "This is the program reference for version "
+    #:text
+    (string-append  "
+@end ifnottex
+This is the program reference for version "
                    (lilypond-version)
                    " of LilyPond, the GNU music typesetter.")
 
index bd824aebc9baa63e50f560056a074b329189cab0..4a25f5420c633a9320d6c4d53dd8e67efe13dac5 100644 (file)
@@ -63,9 +63,9 @@
   (cdr (assoc level '(
                      ;; Hmm, texinfo doesn't have ``part''
                      (0 . "@top")
-                     (1 . "@unnumbered")
-                     (2 . "@unnumberedsec")
-                     (3 . "@unnumberedsubsec")
+                     (1 . "@chapter")
+                     (2 . "@section")
+                     (3 . "@subsection")
                      (4 . "@unnumberedsubsubsec")
                      (5 . "@unnumberedsubsubsec")))))
 
index 8bcb8223fc018a0bc08e07e5dfb67ccd338b1b12..0f63330a210764038c4b195bbdd52f56b7d396a9 100644 (file)
@@ -1,5 +1 @@
-# do we need this?
 default:
-
-local-WWW: $(OUTHTML_FILES)
-
index 2fe267ed44f180de2f311f0b4e7e788f88e212f6..b73dfa56b05423981b66104d1ffb195854578560 100644 (file)
@@ -1,5 +1,6 @@
-.PHONY : all clean bin-clean config default dist doc exe help\
-         html lib TAGS po
+.PHONY : all clean bin-clean config default dist doc exe help html lib TAGS\
+        po web web-1 WWW-1 WWW-2 WWW-post local-WWW-1 local-WWW-2\
+        web-install
 
 all:    default
        $(LOOP)
@@ -169,21 +170,30 @@ $(config_make): $(top-src-dir)/configure
        touch $@                # do something for multiple simultaneous configs.
 
 
-################ website.
+#### Documentation (website and tarball)
 
-local-WWW:
-local-WWW-post:
+# documentation is built in two stages,
+# plus WWW-post (only at toplevel)
+# see INSTALL for more information.
+
+local-WWW-1:
+local-WWW-2:
 web-install:
+WWW-post:
 
-WWW: local-WWW
+WWW-1: local-WWW-1
        $(LOOP)
 
-WWW-post: local-WWW-post
+WWW-2: local-WWW-2
        $(LOOP)
 
 web:
-       $(MAKE) out=www WWW
+       $(MAKE) out=www WWW-1
+       $(MAKE) out=www WWW-2
        $(MAKE) out=www WWW-post
 
+web-1:
+       $(MAKE) out=www WWW-1
+
 web-clean:
        $(MAKE) out=www clean
index 328ef02412861c61cd746d32d0559e4c95a7ffe1..00435f2f2c4948b7d8d48f4f23fc5b368d2e40a4 100644 (file)
@@ -26,12 +26,32 @@ endif
 $(outdir)/%.info: $(outdir)/%.texi $(outdir)/$(INFO_IMAGES_DIR).info-images-dir-dep $(outdir)/version.itexi
        $(MAKEINFO) -I$(outdir) --output=$@ $<
 
+ifeq (,$(findstring texi2html,$(MISSING_OPTIONAL)))
+$(outdir)/%-big-page.html: $(outdir)/%.texi $(XREF_MAPS_DIR)/%.xref-map $(outdir)/version.itexi
+       $(TEXI2HTML) --I=$(outdir) -D bigpage --output=$@ $(TEXI2HTML_INIT) $< 
+       cp $(top-src-dir)/Documentation/lilypond*.css $(dir $@)
+
+$(outdir)/%.html: $(outdir)/%.texi $(XREF_MAPS_DIR)/%.xref-map $(outdir)/version.itexi
+       $(TEXI2HTML) --I=$(outdir) --output=$@ $(TEXI2HTML_INIT) $<
+       cp $(top-src-dir)/Documentation/lilypond*.css $(dir $@)
+
+$(outdir)/%/index.html: $(outdir)/%.texi $(XREF_MAPS_DIR)/%.xref-map $(outdir)/version.itexi
+       mkdir -p $(dir $@)
+       $(TEXI2HTML) --I=$(outdir) --output=$(dir $@) --prefix=index --split=section $(TEXI2HTML_INIT) $<
+       cp $(top-src-dir)/Documentation/lilypond*.css $(dir $@)
+
+else # Rules using makeinfo follow
 $(outdir)/%-big-page.html: $(outdir)/%.texi $(outdir)/version.itexi
        $(MAKEINFO) -I $(outdir) --output=$@ --css-include=$(top-src-dir)/Documentation/texinfo.css --html --no-split -D bigpage --no-headers $<
 
 $(outdir)/%.html: $(outdir)/%.texi $(outdir)/version.itexi
        $(MAKEINFO) -I $(outdir) --output=$@ --css-include=$(top-src-dir)/Documentation/texinfo.css --html --no-split --no-headers $<
 
+$(outdir)/%/index.html: $(outdir)/%.texi $(outdir)/version.itexi
+       mkdir -p $(dir $@)
+       $(MAKEINFO) -I $(outdir) --output=$(dir $@) --css-include=$(top-src-dir)/Documentation/texinfo.css --html $<
+endif
+
 $(outdir)/%.html.omf: %.texi
        $(call GENERATE_OMF,html)
 
@@ -41,10 +61,6 @@ $(outdir)/%.pdf.omf: %.texi
 $(outdir)/%.ps.gz.omf: %.texi
        $(call GENERATE_OMF,ps.gz)
 
-$(outdir)/%/index.html: $(outdir)/%.texi $(outdir)/version.itexi
-       mkdir -p $(dir $@)
-       $(MAKEINFO) -I $(outdir) --output=$(dir $@) --css-include=$(top-src-dir)/Documentation/texinfo.css --html $<
-
 $(outdir)/%.pdf: $(outdir)/%.texi $(outdir)/version.itexi
        cd $(outdir); texi2pdf $(TEXI2PDF_FLAGS) --batch $(TEXINFO_PAPERSIZE_OPTION) $(<F)
 
@@ -55,6 +71,10 @@ $(outdir)/%.texi: %.texi
        rm -f $@
        cp $< $@
 
+$(XREF_MAPS_DIR)/%.xref-map: $(outdir)/%.texi
+       $(PYTHON) $(buildscript-dir)/extract_texi_filenames.py -o $(XREF_MAPS_DIR) $<
+
+
 $(outdir)/version.%: $(top-src-dir)/VERSION
        echo '@macro version'> $@
        echo $(TOPLEVEL_VERSION)>> $@
index a202bea7b976986c49d2f21a4af7c8d8ebb4cbe6..492e1f636621a137c5687a030bf25664a5fac420 100644 (file)
@@ -2,7 +2,7 @@
 
 default: $(INFO_FILES)
 
-local-WWW: $(addprefix $(outdir)/,$(TEXI_FILES:.texi=.html))
+local-WWW-1: $(XREF_MAPS_FILES)
 
 local-doc: $(OUTTXT_FILES)
 
index a3d706f1f794aaa6811fba6d9121b502a39a7788..dcfa5e63b947758070ce6ffdf9959fe8575464ac 100644 (file)
@@ -1,4 +1,3 @@
-
 TEXI_FILES = $(call src-wildcard,*.texi)
 
 ALL_SOURCES += $(TEXI_FILES)
@@ -14,6 +13,19 @@ TEXINFO_PAPERSIZE_OPTION= $(if $(findstring $(PAPERSIZE),a4),,-t @afourpaper)
 MAKEINFO_FLAGS = --enable-encoding
 MAKEINFO = LANG= $(MAKEINFO_PROGRAM) $(MAKEINFO_FLAGS)
 
+# texi2html xref map files
+XREF_MAPS_DIR=$(top-build-dir)/out/xref-maps
+XREF_MAPS_FILES=$(INFO_DOCS:%=$(XREF_MAPS_DIR)/%.xref-map)
+
+# texi2html flags
+ifneq ($(ISOLANG),) 
+TEXI2HTML_LANG = --lang=$(ISOLANG)
+endif
+TEXI2HTML_FLAGS += --css-ref=lilypond.css $(DOCUMENTATION_INCLUDES) \
+  --I=$(XREF_MAPS_DIR)
+TEXI2HTML_INIT = --init-file=$(top-src-dir)/lilypond-texi2html.init
+TEXI2HTML = $(TEXI2HTML_PROGRAM) $(TEXI2HTML_FLAGS) $(TEXI2HTML_LANG)
+
 ifdef QUIET_BUILD
 TEXI2PDF_FLAGS += -q
 endif
index 5c4777ec92f7382b0e88db531dc9eb27110ecb4a..93d2f9cccf3c3d6b05c22a52c0f41811630ff890 100644 (file)
@@ -1,6 +1,8 @@
 
 default: local-doc
 
-local-WWW: $(HTML_FILES) $(PDF_FILES)
+local-WWW-1: $(PDF_FILES)
+
+local-WWW-2: $(HTML_FILES)
 
 make-txt-files: $(TO_TOP_FILES)