www-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

www/server/staging/nav-bar/test9 style.fr.css G...


From: Therese Godefroy
Subject: www/server/staging/nav-bar/test9 style.fr.css G...
Date: Tue, 04 Feb 2014 17:35:45 +0000

CVSROOT:        /webcvs/www
Module name:    www
Changes by:     Therese Godefroy <th_g> 14/02/04 17:35:45

Modified files:
        server/staging/nav-bar/test9: style.fr.css 
Added files:
        server/staging/nav-bar/test9: GNUmakefile disclaimer.fr.html 

Log message:
        PO4A addendum for trans-disclaimer and corresponding GNUmakefile; 
adjust style.fr.css.

CVSWeb URLs:
http://web.cvs.savannah.gnu.org/viewcvs/www/server/staging/nav-bar/test9/style.fr.css?cvsroot=www&r1=1.1&r2=1.2
http://web.cvs.savannah.gnu.org/viewcvs/www/server/staging/nav-bar/test9/GNUmakefile?cvsroot=www&rev=1.1
http://web.cvs.savannah.gnu.org/viewcvs/www/server/staging/nav-bar/test9/disclaimer.fr.html?cvsroot=www&rev=1.1

Patches:
Index: style.fr.css
===================================================================
RCS file: /webcvs/www/www/server/staging/nav-bar/test9/style.fr.css,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- style.fr.css        18 Jan 2014 14:12:57 -0000      1.1
+++ style.fr.css        4 Feb 2014 17:35:44 -0000       1.2
@@ -32,3 +32,11 @@
 /* No arrow in the header. It doesn't look good with FSF campaign material. */
 #header a[href^="http://"]:before, 
 a[href^="https://"]:before { content: ""; }
+#mission-statement a[href^="http://"]:before, 
+a[href^="https://"]:before { content: ""; }
+#mission-statement a[href^="http://"]:before, 
+a[href^="https://"]:before { content: ""; }
+#support-fsf a[href^="http://"]:before, 
+a[href^="https://"]:before { content: ""; }
+#fs-gang a[href^="http://"]:before, 
+a[href^="https://"]:before { content: ""; }

Index: GNUmakefile
===================================================================
RCS file: GNUmakefile
diff -N GNUmakefile
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ GNUmakefile 4 Feb 2014 17:35:44 -0000       1.1
@@ -0,0 +1,1312 @@
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software
+#   Foundation, Inc.
+
+# This file is part of GNUnited Nations.
+
+# GNUnited Nations is free software: you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+
+# GNUnited Nations is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNUnited Nations.  If not, see <http://www.gnu.org/licenses/>.
+
+_have-Makefile := $(shell test -f Makefile && echo yes)
+_have-Makefile.in := $(shell test -f Makefile.in && echo yes)
+
+ifeq ($(_have-Makefile.in),yes)
+ifeq ($(_have-Makefile),)
+$(error Please run "./configure" first)
+endif
+endif
+
+include config.mk
+
+rootdir := ../..
+
+include gnun.mk
+
+ifdef TEAM
+-include priorities.mk
+endif
+
+VALIDATE-HTML-NOTIFY := $(pkglibexecdir)/validate-html-notify
+MAILFAIL := $(pkglibexecdir)/mailfail
+MAKE-PROTOTYPE := $(AWK) -f $(pkglibexecdir)/make-prototype.awk
+UPDATE-LOCALIZED-URLS := $(pkglibexecdir)/update-localized-urls
+ADD-FUZZY-DIFF := $(pkglibexecdir)/add-fuzzy-diff
+COPY-MSGID := $(pkglibexecdir)/copy-msgid
+
+PO4A-GETTEXTIZEFLAGS := -o porefs=none
+PO4A-TRANSLATEFLAGS := --keep=0
+
+PO4A-XHTMLFLAGS := --format=xhtml --master-charset=utf-8 \
+                   -o ontagerror=silent \
+                   -o "attributes=<meta>content" \
+                   -o "untranslated=W<gnun> W<script>" \
+                   -o "translated=W<pre>"
+
+# The lower limit of the number of repeating msgids to include in compendium.
+COMMONALITY := 10
+
+# Default period to delay notice about translation being out of date
+ifdef GRACE
+  OUTDATED-GRACE := 60
+else
+# no OUTDATED-GRACE by default when there is no GRACE
+  OUTDATED-GRACE := -1
+endif
+
+# Determine the VCS to use.  The conditional is for efficiency --
+# there's no need to spawn a shell to determine the value when all VCS
+# operations will be skipped anyway.  For the time being, Bzr is used
+# as a fallback since gnu.org is expected to switch soon.
+ifneq (,$(findstring yes,$(VCS)))
+vcs := $(shell (test -d CVS && echo cvs) \
+         || (test -d .svn && echo svn) || echo bzr)
+endif
+
+# By default, do not add any files to the repository unless VCS=yes.
+ifneq (,$(findstring yes,$(VCS)))
+VCSSKIP :=
+else
+VCSSKIP := echo "SKIP:"
+endif
+
+# Assume VALIDATE=yes when unspecified.
+ifeq (,$(VALIDATE))
+VALIDATE := yes
+endif
+
+# Do not validate any files when VALIDATE doesn't contain `yes'.
+ifneq (,$(findstring yes,$(VALIDATE)))
+VALIDATESKIP :=
+else
+VALIDATESKIP := echo "SKIP:"
+endif
+
+# Do not send warning mails by default unless NOTIFY=yes.
+ifneq (,$(findstring yes,$(NOTIFY)))
+NOTIFYSKIP :=
+else
+NOTIFYSKIP := --dry-run
+endif
+
+# FIXME: footer-short and footer-min are remnants from the old-new
+# design; they should go at some point.
+localized-includes := server/header server/head-include-1 \
+                     server/head-include-2 server/banner \
+                     server/html5-header server/html5-head-include-1 \
+                     server/body-include-1 server/body-include-2 \
+                     server/footer server/footer-short server/footer-min \
+                     $(extra-templates) $(optional-templates)
+
+# Issue a command to substitute localized includes in a HTML file.
+# Usage: $(call substitute-localized-includes,$(lang)) file.$(lang).html
+define substitute-localized-includes
+$(SED) --in-place $(foreach inc, $(localized-includes), \
+  -e 's%\(<!--#include virtual=\"/$(inc)\)\(.html\" -->\)%\1.$(1)\2%g')
+endef
+
+# Issue a command to add some SSI variable definitions at the beginning of
+# a HTML file produced with make-proto; template files don't contain
+# the comment about being automatically generated by GNUN, so they are
+# not affected.
+# Usage: $(call insert-ssi-vars,file.$(lang).html)
+define insert-ssi-vars
+$(SED) --in-place \
+  's%<!-- This file is automatically generated by GNUnited Nations! -->%&\n\
+<!--#set var="ENGLISH_PAGE"\
+value="$(strip\
+  $(subst /po/,/,$(subst ${rootdir},,\
+  $(basename $(basename \
+$(1)))$(if $(findstring no, $(MULTIVIEWS)),,.en))).html)" -->\n%' $(1)
+endef
+
+### Special variables for the `www' master templates ###
+template-dir := $(rootdir)/server
+template-translated-base := $(addprefix $(rootdir)/,$(extra-templates) \
+                                                    $(optional-templates))
+# Guard with a conditional to avoid silent `ls' failures during
+# variables' computation when only the package is being built.
+ifneq ($(_have-Makefile),yes)
+template-pots := $(addsuffix .pot, \
+                  $(foreach template,$(extra-templates), \
+                    $(dir $(addprefix $(rootdir)/, \
+                            $(template)))po/$(notdir $(template)))) \
+                 $(addsuffix .pot.opt, \
+                  $(foreach template,$(optional-templates), \
+                    $(dir $(addprefix $(rootdir)/, \
+                            $(template)))po/$(notdir $(template))))
+endif
+template-lang = $(addsuffix .$(1).html,$(template-translated-base))
+template-translated := $(foreach t-lang,$(TEMPLATE_LINGUAS), \
+                        $(call template-lang,$(t-lang)))
+ifeq ($(VERBOSE),yes)
+$(info template-pots = $(template-pots))
+$(info template-translated = $(template-translated))
+endif
+### End of variables declaration (templates) ###
+
+### Special variables for whatsnew (a.k.a. gnunews) ###
+# Compute everything based on the present PO files.
+wn-po := $(wildcard $(template-dir)/po/whatsnew.*.po)
+wn-html := $(wn-po:%.po=%.html)
+gnusfl := $(subst $(template-dir)/po/whatsnew,$(rootdir)/gnusflashes, \
+           $(wn-po:%.po=%.include))
+gnunews := $(template-dir)/po/whatsnew.pot $(wn-html) $(gnusfl)
+ifeq ($(VERBOSE),yes)
+$(info gnunews = $(gnunews))
+endif
+### End of variables declaration (whatsnew) ###
+
+transfer-to-po = \
+  $(patsubst ./%,%,$(join $(patsubst %,%po/,$(dir $(1))),$(notdir $(1))))
+find-po = $(wildcard $(1).*.po)
+### Special variables for `no-grace' items ###
+no-grace-items := \
+$(addprefix $(rootdir)/,$(call transfer-to-po,$(no-grace-articles)))
+no-grace-pot := $(no-grace-items:%=%.pot)
+no-grace-po := $(foreach base,$(no-grace-items),$(call find-po,$(base)))
+no-grace-translated := $(subst /po/,/,$(no-grace-po:%.po=%.html))
+### End of variables declaration (`no-grace' items) ###
+
+### Special variables for sitemap
+ifneq ($(sitemap),)
+sitemap-base := $(addprefix $(rootdir)/,$(call transfer-to-po,$(sitemap)))
+sitemap-pots := $(addsuffix .pot,$(sitemap-base))
+sitemap-pos := $(foreach base,$(sitemap-base),$(call find-po,$(base)))
+sitemap-translated := $(subst /po/,/,$(sitemap-pos:%.po=%.html))
+endif
+### End of variables for sitemap
+
+no-validate-items := \
+$(addprefix $(rootdir)/,$(call transfer-to-po,$(no-validate-articles)))
+### Special variables for all other articles ###
+# FIXME: Variables' computation could be optimized, but in any event
+# it is much better if translators do not have to add manually anything.
+articles := $(foreach dir,$(ALL_DIRS),$(addprefix $(dir)/po/,$(value $(dir))))
+articles-pot := $(addprefix $(rootdir)/,$(articles:%=%.pot))
+root-articles := $(foreach root-article,$(ROOT), \
+                  $(addprefix $(rootdir)/po/,$(root-article)))
+root-articles-pot := $(root-articles:%=%.pot)
+ALL_POTS := $(articles-pot) $(root-articles-pot)
+ALL_BASE := $(ALL_POTS:%.pot=%)
+ALL_POS := $(foreach base,$(ALL_BASE),$(call find-po,$(base)))
+ALL_POS_BASE := $(ALL_POS:%.po=%)
+articles-translated := $(subst /po/,/,$(ALL_POS:%.po=%.html))
+ifeq ($(VERBOSE),yes)
+$(info ALL_POTS = $(ALL_POTS))                         
+$(info articles-translated = $(articles-translated))
+endif
+### End of variables declaration (all articles) ###
+
+.PHONY: all vcs-add-always no-grace-items
+ifeq ($(_have-Makefile),yes)
+include Makefile
+else
+all: compendia $(template-pots) $(template-translated) $(gnunews) \
+     $(ALL_POTS) \
+     $(articles-translated) $(patsubst %.pot,%.translist,$(ALL_POTS)) \
+     final-stage
+endif
+no-grace-items: $(template-pots) $(template-translated) \
+               $(no-grace-translated) \
+               $(patsubst %.pot,%.translist,$(no-grace-pot)) final-stage
+
+.PHONY: substitute-localized-urls update-localized-URLs final-stage
+
+# Unconditional actions to run at the end of build process.
+final-stage: substitute-localized-urls vcs-add-always
+
+# Regenerate lists of localized URLs in localized-urls.mk
+update-localized-URLs:
+       $(UPDATE-LOCALIZED-URLS)
+-include localized-urls.mk
+
+# Substitute and unsubstitute localised URLs in translations.
+substitute-localized-urls: $(articles-translated)
+       $(foreach source, ${localized-url-sources}, \
+         langs=$$(echo ${rootdir}/${source}.*.html | \
+                  $(SED) 's%${rootdir}/${source}\.%%g;s/\.html//g;s/\*//'); \
+         test -z "$${langs}" \
+           || for l in $${langs}; do \
+                article=${source}; \
+                po=${rootdir}/$${article%/*}/po/$${article##*/}.$${l}.po; \
+                 test -f "$${po}" || continue; \
+                script=; \
+                for url in ${${source}-localized-urls}; do \
+                  base=$${url%.*}; ext=$${url##*.}; \
+                  escaped_url=$$(echo $${url} | $(SED) 's/\./\\./g'); \
+                  escaped_localized_url=$$(echo $${url%.*}.$${l}.$${url##*.} \
+                                           | $(SED) 's/\./\\./g'); \
+                  if test -f ${rootdir}$${url%.*}.$${l}.$${url##*.}; then \
+                    script="address@hidden@address@hidden; \
+                            $${script}"; \
+                  else \
+                    script="address@hidden@address@hidden; \
+                            $${script}"; \
+                  fi; \
+                done; \
+                script=$$(echo $${script} | $(SED) "s/^ *//g"); \
+                file=${rootdir}/${source}.$${l}.html; \
+                if test -n "$${script}"; then \
+                  $(SED) "$${script}" $${file} \
+                    > $${file}.tmp; \
+                  if ! cmp -s $${file} $${file}.tmp; then \
+                    cp $${file}.tmp $${file}; \
+                  fi; \
+                  $(RM) $${file}.tmp; \
+                fi;\
+              done;)
+
+# The command to add a file to the repository.
+define add-file
+[ -f $(1) ] || (touch $(1) $(2) ; $(VCSSKIP) $(vcs) add $(1))
+endef
+
+# Specific case of add-file invocation used in many places
+define addfile 
+$(call add-file,$@)
+endef
+
+# Check whether the changes in the PO file are not trivial;
+# update the PO when needed and remove the temporary file.
+# It is assumed that the old file is $(1), and the new one is $(1).tmp.
+define check-new-po
+if ([ ! -f $(1) ] || [ "`diff -U 0 $(1) $(1).tmp \
+     | $(GREP) -v "^\(---\|+++\|@@\)" \
+     | $(GREP) -v '^[-+]"\(POT-Creation-Date\|PO-Revision-Date\|Language\):' \
+     | wc -c`" -ne 0 ]); then \
+  mv $(1).tmp $(1) ; \
+else \
+  $(RM) $(1).tmp; \
+fi
+endef
+
+### Declarations for compendia ###
+#
+# All files specifically processed here shall live in compendia/.
+# The manually maintained files are:
+#
+## exclude.pot
+#
+# Strings that shouldn't go to compendia, like GNUN slots.
+#
+## master.${lang}.po
+#
+# Translations that should be used when the specified msgid appears in
+# an article; in other words, this file overrides the translations from
+# other files.  Other PO files will be rebuilt whenever this file
+# changes.
+#
+# The generated files are:
+#
+## compendium.pot
+#
+# Compiled from all POT files; a msgid is included when it appears
+# more than $(COMMONALITY) times.
+#
+## compendium.${lang}.po
+#
+# Translations of strings from compendium.pot collected
+# from all ${lang} PO files.
+# 
+# This file can be used by the human editor to update master.${lang}.po.
+#
+## fuzzified-compendium.${lang}.po
+#
+# Translations from compendium.${lang}.po marked fuzzy even if they
+# are not, "previous" msgid is added when absent.
+#
+# This file is used as a source for missing msgstrs when merging
+# the translations; it is not kept in CVS.
+#
+## master-translated.${lang}.po
+#
+# Translated current messages from master.${lang}.po.
+#
+# This file is used to actually update the translations in ${lang};
+# it is not kept in CVS.
+
+# Target to rebuild compendia.
+.PHONY: compendia
+
+compendia: $(foreach lang,$(TEMPLATE_LINGUAS), \
+             compendia/fuzzified-compendium.$(lang).po)
+
+compendia/compendium.pot: $(filter-out %.pot.opt,$(template-pots)) $(ALL_POTS)
+       $(addfile)
+# The `--use-first' option is needed to avoid stacked "translations"
+# of the header (msgid="").
+       $(MSGCAT) --use-first --more-than=$(COMMONALITY) -o address@hidden $^
+# msgcat produces an error when handling files with Charset "CHARSET"
+# unless all files have .pot extention, so we can't just use .tmp.
+       $(MSGCAT) --use-first --less-than=3 -o address@hidden address@hidden \
+         compendia/exclude.pot
+       $(MSGCAT) --use-first --unique -o address@hidden address@hidden \
+         compendia/exclude.pot
+       mv address@hidden address@hidden
+       $(call check-new-po,$@)
+
+define compendium-rules
+ALL_$(1)_POS := \
+  $(shell ls -t $(filter %.$(1).po,$(ALL_POS) $(template-pots:.pot=.$(1).po)))
+
+MASTER-$(1) :=
+MASTER-$(1)-OPTION :=
+
+# Define rules for compendia if there are any translations.
+ifneq ($$(ALL_$(1)_POS),)
+
+ifeq ($$(shell test -s compendia/master.$(1).po && echo yes),yes)
+
+# Extract current translations from master compendium.
+compendia/master-translated.$(1).po: compendia/master.$(1).po
+       -$(MSGATTRIB) --no-fuzzy --translated -o $$@ $$<
+
+MASTER-$(1) := compendia/master-translated.$(1).po
+MASTER-$(1)-OPTION := -C $$(MASTER-$(1))
+
+endif # eq ($$(shell test -s compendia/master.$(1).po && echo yes),yes)
+
+compendia/compendium.$(1).po: compendia/compendium.pot $$(ALL_$(1)_POS)
+       -$(MSGCAT) --use-first -o address@hidden $$(ALL_$(1)_POS)
+       addfile=no; prev_comp=$$@; \
+  test -s $$@ || { addfile=yes; prev_comp=/dev/null; } ; \
+  if test -s address@hidden; then \
+    $(MSGMERGE) --previous -C address@hidden -o address@hidden $$$${prev_comp} 
$$<; \
+  fi; \
+  $(RM) address@hidden; \
+  if test -s address@hidden; then \
+    test $$$${addfile} = no || $$(addfile); \
+    $(call check-new-po,$$@); \
+  else \
+    $(RM) address@hidden; \
+  fi
+
+compendia/fuzzified-compendium.$(1).po: compendia/compendium.$(1).po
+       $(MSGATTRIB) --translated --clear-obsolete --set-fuzzy $$< \
+  | $(COPY-MSGID) > $$@
+
+COMPENDIUM-$(1)-OPTION := \
+  $$(shell test -s compendia/fuzzified-compendium.$(1).po \
+    && echo -C compendia/fuzzified-compendium.$(1).po)
+
+endif # ifneq ($$(ALL_$(1)_POS),)
+## Check for sitemap compendium.
+ifneq ($(sitemap),)
+sitemap-compendium-$(1) := $(shell test -f 
compendia/sitemap-compendium.$(1).po \
+ && $(MSGFMT) -c -o /dev/null compendia/sitemap-compendium.$(1).po \
+ && echo -C compendia/sitemap-compendium.$(1).po)
+ifneq ($$(sitemap-compendium-$(1)),)
+$$(addprefix $(rootdir)/,\
+   $$(addsuffix .$(1).po,$$(call transfer-to-po,$$(sitemap)))): \
+   $$(filter-out -C,$$(sitemap-compendium-$(1)))
+endif # neq ($(sitemap-compendium-$(1),)
+endif # neq ($(sitemap),)
+endef # compendium-rules
+
+$(foreach lang,$(TEMPLATE_LINGUAS),$(eval $(call compendium-rules,$(lang))))
+
+### End declarations for compendia ###
+
+# Compile translations list
+define generate-translinks
+$(call add-file,$(1).translist); \
+file=$(1).translist; cp translist-head.html $$$${file}; \
+$(GREP) -v "^#" languages.txt \
+  | while read language; do \
+      code=$$$${language%%     *}; class=""; \
+      case $$$${code} in \
+        en ) suffix=""; class=' class="original"'; \
+             url_suffix=$(if $(findstring no, $(MULTIVIEWS)),"",".en") ;; \
+        * ) suffix=.$$$${code}; url_suffix="$$$${suffix}" ;; \
+      esac; \
+      lang=$$$${language%      *}; lang=$$$${lang#*    }; \
+      name=$$$${language##*    }; \
+      name=`echo $$$${name} | sed 
's,'"'"',\\\\\\\'"'"',g;s,[[:space:]],\&nbsp;,g'`; \
+      url_stem=$(subst /po/,/,$(subst $(rootdir),,$(1))); \
+      article=$(subst /po/,/,$(1)); \
+      if test -f $$$${article}$$$${suffix}.html; then \
+        echo -n '<span dir="ltr"'$$$$class'><a lang="'$$$$code'"\
+hreflang="'$$$$code'" href="'$$$${url_stem}$$$${url_suffix}.html'">' \
+      >> $$$${file}; \
+        echo $$$${name}'</a>&nbsp;['$$$${code}']</span>&nbsp;&nbsp;' >> 
$$$${file}; \
+      fi; \
+    done; \
+cat translist-tail.html >> $$$${file};
+endef
+
+# Replace SSI directives to include initial translations list with
+# directives to include the generated translist file.
+define update-translinks-include
+if $(GREP) \
+       '<!--#include virtual="/server/gnun/initial-translations-list\.html" ' \
+       $(subst /po/,/,$(1).html); then \
+  $(SED) --in-place \
+    '/^<!--#set var="article_name"/d;\
+     s/<!--#include virtual="\/server\/gnun\/initial-translations-list\.html/\
+     <!--#include virtual="$(subst /,\/,$(subst $(rootdir),,$(1))).translist/' 
\
+    $(subst /po/,/,$(1).html); \
+fi
+endef
+
+# The command to generate pot file which performs additional checks
+# whether the changes are not substantial (e.g. regarding only
+# POT-Creation-Date), in which case the changes are ignored.
+define generate-pot
+$(MAILFAIL) $(NOTIFYSKIP) $(web-addr) \
+  "[GNUN Error] POT generation of $(subst $(rootdir)/,,$@) failed" \
+  $(PO4A_GETTEXTIZE) $(PO4A-XHTMLFLAGS) $(PO4A-GETTEXTIZEFLAGS) \
+  --master $< --po address@hidden
+$(SED) --in-place \
+ '1,/^$$$$/{\
+ address@hidden SOME DESCRIPTIVE address@hidden LANGUAGE translation of \
+http://www.gnu.org$(subst /po/,/,$(subst $(rootdir),,$(<:.proto=.html)))@;\
+ s/^\(# This file is distributed under the same license as the\) \
+PACKAGE package./\1 original article./;\
+ address@hidden("Project-Id-Version:\) PACKAGE VERSION\\n"@\1 \
+$(<F:.proto=.html)\\n"@;}' address@hidden
+$(call check-new-po,$@)
+touch $@
+endef
+
+# The command to generate the translated article $(3) in language $(1)
+# in HTML format from a PO file $(2).  The result is further manipulated
+# in the recipes. $(4) when supplied is the name of the POT.
+#
+# If a translator commits a PO file based on an old version of the
+# POT, it is not msgmerge'd as `make' considers the corresponding
+# $(2) target up-to-date.  As a result, the generated HTML
+# translations have English strings (but no fuzzy strings in the PO)
+# since there's no match between msgid/msgstr.  Invoke update-po
+# unconditionally to cope with that (valid) scenario.
+define generate-html
+$(call update-po,$(2),$(if $(4),$(4),$(2:.$(1).po=.pot)),$(1)); \
+$(PO4A_TRANSLATE) $(PO4A-XHTMLFLAGS) $(PO4A-TRANSLATEFLAGS) \
+  --master $$< --po $(2) -a disclaimer.$(1).html --localized $(3); \
+  $(call insert-ssi-vars,$(3)); \
+  $(call substitute-localized-includes,$(1)) $(3)
+endef
+
+# Eliminate more than 1 subsequent empty lines before comments in file $(1).
+define merge-empty-lines
+$(SED) --in-place \
+  ':egin;N;$$$$!begin;s/\([ \t]*\n[ \t]*\)\{3,\}<!--/\n\n<!--/g' $(1)
+endef
+
+# Prepare the intermediate file $(1) generated by `generate-html' for $(M4).
+# $(2) is language code.
+define post-generate-html
+$(SED) --in-place \
+  "s/\(<gnun>m4_include(\`.*\)\([.]html')<\/gnun>\)/\1.$(2)\2/g" $(1); \
+  $(SED) --in-place "s/<gnun>\(.*\)<\/gnun>/\1/g" $(1); \
+  $(call merge-empty-lines,$(1))
+endef
+
+comma := ,
+# Generate diff file against latest translated revision
+# when available.
+# Add notice about the translation being out of date.
+# The notice is inserted after every line beginning with
+# "<!--GNUN: OUT-OF-DATE NOTICE-->"
+# If no such lines are found in the file, the notice
+# is inserted after <!--#include virtual="/server/banner"-->.
+# Limitation: it doesn't notice that GRACE is expired
+# unless the POT file is updated at least once after
+# the HTML file is marked outdated. In practice this doesn't
+# matter since GRACE value is very high.
+define mark-outdated
+marker='GNUN: OUT-OF-DATE NOTICE'; \
+$(GREP) -q '^<!--'"$$$${marker}-->" $(1) \
+ || marker='#include virtual="\/server\/banner'; \
+original=$(1); original=$$$${original%$(2).html}html; \
+$(if $(WDIFF), \
+  saved_file=$$$${original%/*.html}/po/$$$${original##*/}; \
+  saved_file=$$$${saved_file%html}$(2);\
+  diff_file=$$$${saved_file}-diff.html; \
+  saved_file=$$$${saved_file}-en.html; \
+  if test -f $$$${saved_file}; then \
+    $$(call add-file $(comma) $$$${diff_file}); \
+    $(SED) "s/</\&lt;/g;s/>/\&gt;/g" < $$$${saved_file} \
+          > $$$${saved_file}.tmp; \
+    $(SED) "s/</\&lt;/g;s/>/\&gt;/g" < $$$${original} \
+          > $$$${saved_file}.tmp1; \
+    $(SED) "s%<title></title>%<title>$$$${original#$(rootdir)}-diff</title>%" \
+          < diff-page-head.html > $$$${diff_file}; \
+    $(WDIFF) --start-delete '<span class="removed"><del><strong>' \
+            --end-delete '</strong></del></span>' \
+            --start-insert '<span class="inserted"><ins><em>' \
+            --end-insert '</em></ins></span>' \
+           $$$${saved_file}.tmp $$$${saved_file}.tmp1 \
+           >> $$$${diff_file}; \
+    cat diff-page-tail.html >> $$$${diff_file}; \
+    $(RM) $$$${saved_file}.tmp $$$${saved_file}.tmp1; \
+  fi; \
+  test -f "$$$${diff_file}" || diff_file=""; \
+ , diff_file=""; \
+ ) \
+$(SED) --in-place \
+'/^<!--#set var="PO_FILE"/,/<!--#include virtual="\/server\/outdated/d;\
+ /^<!--'"$$$${marker}"'/a\
+  <!--#set var="PO_FILE"\n \
+    value='"'<a href=\"http://www.gnu.org$$$${PO#$(rootdir)}\">\n\
+           http://www.gnu.org$$$${PO#$(rootdir)}</a>'"' -->\n\
+  <!--#set var="ORIGINAL_FILE" value="'"$$$${original#$(rootdir)}"'" -->\n \
+  <!--#set var="DIFF_FILE" value="'"$$$${diff_file#$(rootdir)}"'" -->\n \
+  <!--#set var="OUTDATED_SINCE"\
+ value="'"`$(call extract-outdated-date,$$$$PO) | $(SED) 's/ .*//'`"'" -->\n \
+<!--#include virtual="/server/outdated.$(2).html" -->' $(1) \
+ || true
+endef
+
+# The command to check the validity of a PO file $(1).
+define check-po
+$(MAILFAIL) $(NOTIFYSKIP) $(transl-addr) \
+  "[GNUN Error] $(patsubst $(rootdir)/%,%,$(1)) is not a valid PO file" \
+  $(VALIDATESKIP) $(MSGFMT) --check --verbose --output-file=/dev/null $1
+endef
+
+# Get the generation date of the oldest POT with incomplete
+# translation stored in `Outdated-Since' field of the header.
+define extract-outdated-date
+($(SED) --quiet \
+   '1,/^msgstr/d;/^$$$$/q 0;/^"Outdated-Since:/{s/^"Outdated-Since: 
\(.*\).."$$$$/\1/;p;q 1;}' $(1); \
+ test $$$$? != 0 \
+)
+endef
+
+# Copy POT generation date to `Outdated-Since' field
+# unless the latter is already present.
+# Insert the field after `Content-Transfer-Encoding'
+# whither msgmerge would move it.
+define insert-outdated-date
+($(call extract-outdated-date,$(1)) > /dev/null \
+ || $(SED) --in-place \
+      '1,/^"POT-Creation-Date:/{\
+           p;s/^"POT-Creation-Date:/"Outdated-Since:/;h;d};\
+       1,/^"Content-Transfer-Encoding:/{\
+         s/^\("Content-Transfer-Encoding: \)/\1/;p;t insert;d;\
+         :insert x}' $(1))
+endef
+
+# Remove `Outdated-Since' field from the header.
+define remove-outdated-date
+$(SED) --in-place \
+  '/^msgid ""$$$$/,/^$$$$/{s/^"Outdated-Since: //;t rm;p;:rm d}' $(1)
+endef
+
+define update-po-status
+if LC_ALL=C $(MSGFMT) --statistics -o /dev/null $(1) 2>&1 \
+    | $(EGREP) '(fuzzy|untranslated)[^:]*$$$$' > /dev/null; then \
+  $(call insert-outdated-date,$(1)); \
+else \
+  $(call remove-outdated-date,$(1)); \
+fi
+endef
+
+# Check whether language code $(1) is present in list $(2)
+# It assumes that language codes can't contain `.';
+# it takes into account possibility of partial matches like
+# `br' vs. `pt-br'.
+define find-language
+$(findstring .$(1).,$(addsuffix .,$(addprefix .,$(2))))
+endef
+
+# The command to update a PO file ($(1)) from the POT ($(2)).
+# $(3) is the language code.
+#
+# The target is `touched' in order to make `make' to consider it
+# up-to-date even if there is nothing to merge.  The default values of
+# Content-Type and Content-Transfer-Encoding are replaced with commonly
+# used values (or added if the fields are absent).  When appropriate,
+# $(ADD-FUZZY-DIFF) is invoked.
+#
+# When compendia/master-translated.$(3).po is present, its translations 
override
+# the translations from $(1); when compendia/fuzzy-compendium.$(3).po is
+# present, it is checked for missing translations.
+#
+# For sitemaps the special compendium is used when available and fuzzy matching
+# is suppressed (it proved to do more harm than good for sitemaps).
+define update-po
+$(SED) \
+  '1{ \
+      :egin; /\nmsgstr /b msgstr; N; begin; \
+      :msgstr; N; /\nmsgstr .*\n\n/b process; b msgstr; \
+      :process; \
+      address@hidden(\nmsgstr.*\n"Content-Type: text/plain; 
charset\)=CHARSET\\n"address@hidden
+\1=UTF-8\\n"\n@; \
+      /\nmsgstr .*\n"Content-Type:/! \
+        address@hidden(\nmsgstr .*\n\)address@hidden"Content-Type: text/plain; 
charset=UTF-8\\n"\n\n@; \
+      s/\(\n"Content-Transfer-Encoding:\) ENCODING\\n"\n/\1 8bit\\n"\n/; \
+      /\nmsgstr .*\n"Content-Transfer-Encoding:/! \
+       s/\(\nmsgstr .*\n\)\n/\1"Content-Transfer-Encoding: 8bit\\n"\n\n/; \
+    }' $(1) \
+  $(if $(MASTER-$(3)), \
+     | $(MSGATTRIB) --clear-obsolete \
+     | $(MSGCAT) --use-first --more-than=1 $(MASTER-$(3)) - \
+     | $(MSGCAT) --use-first --less-than=2 $(1) -) \
+  $(if $(findstring $(1), $(sitemap-pos)), | $(MSGATTRIB) --no-fuzzy) \
+  | $(MSGMERGE) --previous $(MASTER-$(3)-OPTION) $(COMPENDIUM-$(3)-OPTION) \
+    $(if $(findstring $(1), $(sitemap-pos)), $(sitemap-compendium-$(3))) \
+    -o $(1).tmp - $(2) \
+  && $(call check-new-po,$(1)) && touch $(1) \
+  && ($(call update-po-status,$(1)); \
+      $(if $(and $(WDIFF),$(call find-language,$(3),$(FUZZY_DIFF_LINGUAS))), \
+           $(ADD-FUZZY-DIFF) --in-place $(1);) \
+     )
+endef
+
+# The command to add "<gnun>" tags in a prototype ($@) where needed.
+define add-gnun-tags
+$(SED) --in-place -e '/<span[[:space:]]*$$/{:egin;N; />[^\n]*$$/! begin};\
+s,<span[[:space:]]\+class="gnun-split"></span>,<gnun></gnun>,g' \
+                  -e "s/\$$Date.*\$$/<gnun>\0<\/gnun>/g" $@
+endef
+
+# The command to generate a prototype for a page.
+define generate-proto
+$(MAILFAIL) $(NOTIFYSKIP) $(web-addr),$(devel-addr) \
+  "[GNUN Error] Incompatible change in $(subst $(rootdir)/,,$<)" \
+  $(MAKE-PROTOTYPE) < $< > $@ || ($(RM) $@ ; exit 1)
+$(add-gnun-tags)
+endef
+
+# The command to restore the necessary write permissions of the
+# target.  This is a workaround for a CVS quirk that affects only the
+# `www' repository.
+# 
http://lists.gnu.org/archive/html/savannah-hackers-public/2008-06/msg00046.html
+define fixperm
+chmod +w $@
+endef
+
+# The command to touch the prerequisite $PO if HTML validation fails.
+# Unfortunately, merely touching it does not work for the automatic
+# build, because `cvs commit' is invoked after `make' and it resets
+# the `Date' keyword of the faulty target (thus resetting its
+# timestamp), so it becomes newer than the prerequisite.  `touch-hook'
+# creates an unique file in $(CURDIR) based on the target, which is
+# then processed by the `triggers' rule.  In a normal situation, the
+# filename shouldn't be unique as `make' fails on the first
+# encountered error.  However, this is necessary for `make -j' so it
+# has to be parallel safe like all the rules.  Also for `make -k'.
+# Touching the prerequisite is still needed for local non-VCS builds
+# to DTRT and halt when $PO is not rectified.
+# After a commit, cvs updates the working copy expanding all keywords
+# on the way and sets the timestamp as per the server time.  When the
+# client is not synchronized -- i.e. fencepost is currently lagging 2
+# minutes -- the timestamp is in the future so touching it after `cvs
+# commit' does not work.  The solution is to record a command sequence
+# that will update the timestamp based on the timestamp of the target.
+define touch-hook
+sleep 1 ; touch $$PO ; \
+if test -f $@ ; then \
+  echo "touch --reference=$@ --date='+1 seconds' $$PO" > $(@F).hook ; \
+else \
+  echo "echo; echo $@ has never been built." > $(@F).hook ; \
+fi; \
+exit 1
+endef
+
+# The command to filter out HTML comments
+define skip-comments
+ $(SED) \
+  ':b;/<!--/{:l;/<!--.*-->/!{N;bl};:n;s/<!---->//;tb;s/<!---\?[^-]*/<!--/;bn}'
+endef
+# The command to extract a meaningful human-readable title from a
+# .LANG.html.  Some HTML entities that are sometimes used in titles
+# are transformed, to avoid annoying stuff in email subjects.  When
+# the title doesn't fit into single line, the first line with
+# an ellipsis is used.
+#
+# The title is base64-encoded as the Subject header must comply with
+# RFC 2822, otherwise the message is rejected by the gnu.org servers
+# (sysadmin RT #600797).  Used only in article-rules, and only if
+# ANNOUNCE=yes.
+define extract-title
+title_tag='h2'; \
+if ! $(skip-comments) $$@ | $(GREP) -q "<$$$$title_tag"; \
+then title_tag='title'; fi; \
+echo -n \`$(skip-comments) $$@ | $(GREP) --max-count=1 "<$$$$title_tag"\` \
+  | $(SED) '/<\/'$$$$title_tag'>/!s/$$$$/.../;\
+            s/.*<'$$$$title_tag'[^>]*>//;s/<\/'$$$$title_tag'>.*//' \
+  | $(SED) 's/\&[mn]dash;/--/g; s/\&nbsp;/ /g' \
+  | $(SED) 's/\&..quo;/"/g' | base64 --wrap=0
+endef
+
+# Construct a command sequence suitable for `mail', if the .hook-ann
+# file exists.  Only applicable for article-rules, if ANNOUNCE=yes.
+# The .hook-ann files are treated differently in the `triggers' rule,
+# because it is a valid (and often occurring in practice) scenario to
+# have a new translation which is invalid HTML.
+define announce
+if test -f $$(@F).hook-ann; then \
+  echo "echo '<URL:$$(subst $(rootdir),http://www.gnu.org,$$@)>' \
+  | mail -s '[$(2)] New translation: =?utf-8?B?`$(extract-title)`?=' \
+    -a Keywords:$(2)-ann $(ann-addr)" > $$(@F).hook-ann; \
+fi
+endef
+
+# Suffix for preliminarily generated HTML files.
+draft-suffix := .humbly-drafted-by-GNUN
+
+# The command to validate an ordinary article; remove the generated file
+# (when VCS operations are enabled) and create a hook in case validation
+# fails.
+define validate-article
+$(VALIDATESKIP) $(VALIDATE-HTML-NOTIFY) $(NOTIFYSKIP) $(transl-addr) \
+  address@hidden || ($(VCSSKIP) $(RM) address@hidden; \
+                        PO=$(1).po ; $$(touch-hook))
+endef
+
+# Ensure that generic.LANG.html is always present for articles' generation.
+
+define generic-var
+GENERIC_LINGUAS += $(1)
+endef
+
+define generic-rules
+generic.$(1).html:
+       $$(addfile)
+endef
+
+$(foreach h-lang,$(TEMPLATE_LINGUAS),$(eval $(call generic-var,$(h-lang))))
+$(foreach po-base,$(ALL_POS_BASE), \
+  $(eval $(call generic-var,$(subst .,,$(suffix $(po-base))))))
+$(foreach g-lang,$(sort $(GENERIC_LINGUAS)), \
+  $(eval $(call generic-rules,$(g-lang))))
+
+### Specific rules for extra templates ###
+# Essentially duplicate rules for templates, but define per-template
+# rules rather than use static patterns
+define extra-template-lang-rules
+.PRECIOUS: $(1).$(2).po
+$(1).$(2).po: $(1).pot $(MASTER-$(2))
+       [ -f $$@ ] || (cp $$< $$@ ; $(VCSSKIP) $(vcs) add $$@)
+       $$(call check-po, $$@)
+       $(call update-po,$$@,$$<,$(2))
+
+$(subst /po/,/,$(1)).$(2).html: $(subst /po/,/,$(1)).html \
+                            $(1).$(2).po
+       $$(call check-po, $(1).$(2).po) || (touch $(1).$(2).po ; exit 1)
+       $$(addfile)
+       $(call generate-html,$(2),$(1).$(2).po,$$@)
+       $(call merge-empty-lines,$$@)
+endef
+
+define extra-template-rules
+.PRECIOUS: $(1).pot $(1).proto
+
+$(1).pot: $(1).proto
+       $$(addfile)
+       $$(generate-pot)
+
+$(1).proto: $(subst /po/,/,$(1)).html
+       cp $$< $$@
+       $$(add-gnun-tags)
+
+$(foreach t-lang,$(TEMPLATE_LINGUAS),\
+  $(eval $(call extra-template-lang-rules,$(strip $(1)),$(t-lang))))
+endef
+
+define optional-template-lang-rules
+ifeq ($(wildcard $(1).$(2).po),)
+$(subst /po/,/,$(1)).$(2).html: $(subst /po/,/,$(1)).html
+       $$(addfile)
+       cp $$< $$@
+else
+.PRECIOUS: $(1).$(2).po
+$(1).$(2).po: $(1).pot.opt $(MASTER-$(2))
+       $$(call check-po, $$@)
+       $(call update-po,$$@,$$<,$(2))
+
+$(subst /po/,/,$(1)).$(2).html: $(subst /po/,/,$(1)).html \
+                            $(1).$(2).po
+       $$(call check-po, $(1).$(2).po) || (touch $(1).$(2).po ; exit 1)
+       $(call generate-html,$(2),$(1).$(2).po,$$@,$(1).pot.opt)
+       $(call merge-empty-lines,$$@)
+endif #eq ($(wildcard $(1).$(2).po),)
+endef
+
+define optional-template-rules
+.PRECIOUS: $(1).pot.opt $(1).proto
+$(1).pot.opt: $(1).proto
+       $$(addfile)
+       $$(generate-pot)
+
+$(1).proto: $(subst /po/,/,$(1)).html
+       cp $$< $$@
+       $$(add-gnun-tags)
+
+$(foreach t-lang,$(TEMPLATE_LINGUAS),\
+  $(eval $(call optional-template-lang-rules,$(strip $(1)),$(t-lang))))
+endef
+
+$(foreach template, $(extra-templates),\
+  $(eval $(call extra-template-rules, \
+          $(dir $(addprefix $(rootdir)/, \
+                  $(template)))po/$(notdir $(template)))))
+
+$(foreach template, $(optional-templates),\
+  $(eval $(call optional-template-rules, \
+          $(dir $(addprefix $(rootdir)/, \
+                  $(template)))po/$(notdir $(template)))))
+
+### End of rules for extra templates ###
+
+### Specific rules for the What's New system (a.k.a. GNU news) ###
+# There is a lot of duplication with article-rules, but at least one
+# command in every recipe has to be different.  Also, we don't want
+# whatsnew to be in gnun.mk as if it is it will be built by the
+# article-rules anyway.
+$(template-dir)/po/whatsnew.proto: $(template-dir)/whatsnew.html
+       $(VALIDATESKIP) $(VALIDATE-HTML-NOTIFY) $(NOTIFYSKIP) $(web-addr) $<
+       $(generate-proto)
+
+$(template-dir)/po/whatsnew.pot: $(template-dir)/po/whatsnew.proto \
+                                $(template-dir)/whatsnew.include
+       $(addfile)
+# The generation of whatsnew.pot is special, as it contains all
+# strings for building whatsnew.LANG.html and whatsnew.LANG.include.
+       $(MAILFAIL) $(NOTIFYSKIP) $(web-addr) \
+         "[GNUN Error] POT generation of $(subst $(rootdir)/,,$@) failed" \
+         $(PO4A_GETTEXTIZE) $(PO4A-XHTMLFLAGS) $(PO4A-GETTEXTIZEFLAGS) \
+         --master $< --master $(template-dir)/whatsnew.include --po 
address@hidden
+       if ([ ! -f $@ ] \
+         || [ "`diff -U 0 $@ address@hidden | $(GREP) -v "^\(---\|+++\|@@\)" \
+         | $(EGREP) -v '^[-+]"(POT-Creation-Date|PO-Revision-Date|Language):' \
+         | wc -c`" -ne 0 ]); then \
+         mv address@hidden $@; \
+         fi; \
+         touch $@
+       $(RM) address@hidden
+
+# Reordering the prerequisites would save the redundant usage of the
+# $* automatic variable but $(addfile) wouldn't work.
+.PRECIOUS: $(template-dir)/whatsnew.%.include
+$(template-dir)/whatsnew.%.include: $(template-dir)/whatsnew.include \
+                                   $(template-dir)/po/whatsnew.%.po
+       PO=$(template-dir)/po/whatsnew.$*.po ; \
+         $(MAILFAIL) $(NOTIFYSKIP) $(transl-addr) \
+         "[GNUN Error] $${PO#../../} is not a valid PO file" \
+         $(VALIDATESKIP) $(MSGFMT) --check --verbose \
+         --output-file=/dev/null $$PO || (touch $$PO ; exit 1)
+       $(addfile)
+# The <dd> element is not wrapped on purpose, for easy generation of
+# gnusflashes.LANG.include.
+# FIXME: Unfortunately, if the translator wraps the msgstr with M-q,
+# then grep in the gnusflashes recipe skips all those wrapped news as
+# there is no match.  Figure out how to avoid this problem or
+# alternatively, say louder that wrapping of msgstr is a BAD thing.
+       PO=$(template-dir)/po/whatsnew.$*.po OUT=$@ ; \
+         $(PO4A_TRANSLATE) $(PO4A-XHTMLFLAGS) $(PO4A-TRANSLATEFLAGS) \
+         -o "translated=W<dd>" --master $< --po $$PO --localized $$OUT
+
+# Derive the targets from whatsnew.LANG.include.  Pattern rules rule.
+$(rootdir)/gnusflashes.%.include: $(template-dir)/whatsnew.%.include
+       [ -f $@ ] || (touch $@ ; $(VCSSKIP) $(vcs) add $@)
+       $(fixperm)
+       echo "<!--Automatically generated by GNUN; do not edit!-->" > $@
+       $(GREP) --max-count=3 '<dd>.*</dd>' $< >> $@
+       $(SED) --in-place "s/\(\/\?\)dd>/\1p>/g" $@ || (touch $< ; exit 1)
+
+# This target is deliberately generated in the wrong sub-directory,
+# otherwise it will be built by template-rules which we want to avoid
+# at all cost.
+$(template-dir)/po/whatsnew.%.html: $(template-dir)/po/whatsnew.proto \
+                                   $(template-dir)/po/whatsnew.%.po \
+                                   $(template-dir)/whatsnew.%.include \
+                                   generic.%.html
+       $(if $(call find-language,$*,$(TEMPLATE_LINGUAS)),, \
+         echo 'The "$*" language code is not defined in TEMPLATE_LINGUAS.' \
+           $(if $(NOTIFYSKIP),, | mail $(transl-addr) -s \
+             "[GNUN Error] Could not build $(subst $(rootdir)/,,$@)"); \
+         exit 1)
+       PO=$(template-dir)/po/whatsnew.$*.po ; $(MAILFAIL) \
+         $(NOTIFYSKIP) $(transl-addr) \
+         "[GNUN Error] $${PO#../../} is not a valid PO file" \
+         $(VALIDATESKIP) $(MSGFMT) --check --verbose --output-file=/dev/null \
+         $$PO || (touch $$PO ; exit 1)
+       [ -f $(template-dir)/$(@F) ] \
+         || (touch $(template-dir)/$(@F) ; \
+            $(VCSSKIP) $(vcs) add $(template-dir)/$(@F))
+# Unconditionally update the PO file; see the comment in `generate-html'.
+# Do _not_ touch the PO file if it doesn't change; this workaround is needed
+# because we are too lazy to provide a rule for the PO file.
+       cp -a $(template-dir)/po/whatsnew.$*.po \
+         $(template-dir)/po/whatsnew.$*.po1
+       $(call update-po,$(template-dir)/po/whatsnew.$*.po,\
+         $(template-dir)/po/whatsnew.pot,$*)
+       if diff $(template-dir)/po/whatsnew.$*.po \
+            $(template-dir)/po/whatsnew.$*.po1 > /dev/null; then \
+         touch --reference=$(template-dir)/po/whatsnew.$*.po1 \
+           $(template-dir)/po/whatsnew.$*.po; \
+       fi
+       $(RM) $(template-dir)/po/whatsnew.$*.po1
+       $(PO4A_TRANSLATE) $(PO4A-XHTMLFLAGS) $(PO4A-TRANSLATEFLAGS) \
+           --master $< --po $(template-dir)/po/whatsnew.$*.po \
+           --localized $(template-dir)/po/whatsnew.$*.m4
+       $(SED) --in-place \
+         "s/\(<gnun>m4_include(\`.*\)\([.]html')<\/gnun>\)/\1.$*\2/g" \
+         $(template-dir)/po/whatsnew.$*.m4
+       $(SED) --in-place "s/<gnun>\(.*\)<\/gnun>/\1/g" \
+         $(template-dir)/po/whatsnew.$*.m4
+       $(SED) --in-place \
+         ':egin;N;$$!begin;s/\([ \t]*\n[ \t]*\)\{3,\}<!--/\n\n<!--/g' \
+         $(template-dir)/po/whatsnew.$*.m4
+       $(call substitute-localized-includes,$*) \
+         $(template-dir)/po/whatsnew.$*.m4
+       $(SED) --in-place \
+         "s/\(<!--#include virtual=\".*whatsnew\)\(.include\" -->\)/\1.$*\2/g" 
\
+         $(template-dir)/po/whatsnew.$*.m4
+       $(M4) $(template-dir)/po/whatsnew.$*.m4 > $@
+       $(VALIDATESKIP) $(VALIDATE-HTML-NOTIFY) $(NOTIFYSKIP) $(transl-addr) \
+         $@ || (PO=$(template-dir)/po/whatsnew.$*.po ; $(touch-hook))
+# Copy the target where it belongs.
+       cp $@ $(template-dir)
+### End of the whatsnew-specific rules ###
+
+### Rules for all other articles ###
+define article-pot-rules
+$(1).proto: $(subst /po/,/,$(1).html)
+# Skip the validation step if the article is in `no-validate-articles'.
+ifneq ($(1), $(findstring $(1),$(no-validate-items)))
+       $(VALIDATESKIP) $(VALIDATE-HTML-NOTIFY) $(NOTIFYSKIP) $(web-addr) $$<
+endif
+       test -f $(1).translist || $(call generate-translinks,$(1))
+       $(call update-translinks-include,$(1)) 
+       $$(generate-proto)
+
+$(1).pot: $(1).proto
+       $$(addfile)
+       $$(fixperm)
+       $$(generate-pot)
+
+# We assume that updating the .translist doesn't affect the validity
+# of the HTML files that include it; if this is not the case,
+# validate-all will complain.
+# It might depend on the POs, but then it could be rebuilt too early,
+# before some HTML, and therefore contain a wrong list.
+$(1).translist: $(filter $(subst /po/,/,$1).%.html,$(articles-translated))
+       $(call generate-translinks,$1)
+endef
+
+# Produce article HTML file and validate it if needed.
+define output-article-html
+$(M4) $(1).m4 > address@hidden \
+$(if $(findstring $(basename $(1)),$(no-validate-items)), , \
+  && $(call validate-article,$(1)))
+endef
+
+define grace-is-over
+(timestamp="`$(call extract-outdated-date,$(1))`"; \
+  test -n "$$$${timestamp}" \
+  && test "`date --date="$(2) days ago" +%s`" \
+       -ge "`date --date="$$$${timestamp}" +%s`" \
+)
+endef
+
+define article-rules
+$(1).po: $(basename $(1)).pot $(MASTER-$(2))
+       $$(call check-po, $$@)
+       $$(fixperm)
+       $(call update-po,$$@,$$<,$(2))
+
+$(subst /po/,/,$(1).html): $(basename $(1)).proto \
+                          $(1).po generic.$(2).html
+# If the server templates are missing, assume the worst and exit with
+# an error to prevent the generation of broken translations -- even if
+# validation is not enforced there will be Apache error.  The case
+# when the templates are present but not built by GNUN is valid in
+# practice, but not recommended.
+ifeq (,$(call find-language,$(2),$(TEMPLATE_LINGUAS)))
+ifndef NOTIFYSKIP
+       echo 'The "$(2)" language code is not defined in TEMPLATE_LINGUAS.' \
+         | mail $(transl-addr) -s \
+         "[GNUN Error] Could not build $$(subst $$(rootdir)/,,$$@)"  
+else
+       @echo 'The "$(2)" language code is not defined in TEMPLATE_LINGUAS.'
+endif
+       exit 1
+endif
+       $$(call check-po,$(1).po) || (touch $(1).po; exit 1)
+       $(call generate-html,$(2),$(1).po,$(1).m4)
+       $(call post-generate-html,$(1).m4,$(2))
+       -$(RM) address@hidden
+# If GRACE is not defined, which is the usual case for local manual
+# builds, update the target and validate the result.
+ifndef GRACE
+       $(output-article-html)
+# Check if the article is not in `no-grace-items'.
+else ifneq ($(basename $(1)), \
+           $(findstring $(basename $(1)),$(no-grace-items)))
+# If there are no fuzzy strings, there might be untranslated or
+# obsolete, so proceed as usual.  If there are fuzzy strings, compare
+# the Outdated-Since in the $(1).po with the current time shifted by value
+# of the $(GRACE) period and invoke regeneration only if the grace period
+# is over. Likewise, check against $(OUTDATED-GRACE) and insert a notice
+# into the HTML file when the grace period is over.
+       if ! $(call extract-outdated-date,$(1).po) > /dev/null ; then \
+         $(output-article-html); \
+       elif $(call grace-is-over,$(1).po,$(GRACE)) ; then \
+         $(output-article-html); \
+       else \
+         sleep 1; touch $(1).po; \
+       fi
+else
+       @echo 'Ignoring grace period for article "$(notdir $(basename $(1)))"'
+       $(output-article-html)
+endif
+       if test -f address@hidden ; then \
+           $(if $(and $(findstring $(ANNOUNCE),yes), \
+                      $(findstring yes,$(ANNOUNCE))), \
+             $(call add-file,$$@,$$(@F).hook-ann), \
+             $(call add-file,$$@)); \
+             $$(fixperm); \
+             mv address@hidden $$@; \
+        fi
+       $(announce) 
+       $(if $(findstring $(basename $(1)),$(no-grace-items)), \
+           echo 'Ignoring delay for article "$(notdir $(basename $(1)))"', \
+           if test -f $$@ \
+                && $(call grace-is-over,$(1).po,$(OUTDATED-GRACE)); then \
+             PO=$(1).po; $(call mark-outdated,$$@,$(2)); \
+           fi)
+       $(call extract-outdated-date,$(1).po) > /dev/null \
+       || ($(call add-file,$(1)-en.html); \
+           cp $(subst /po/,/,$(1:.$(2)=).html) $(1)-en.html)
+endef
+
+$(foreach base,$(ALL_BASE),$(eval $(call article-pot-rules,$(base))))
+$(foreach po-base,$(ALL_POS_BASE), \
+  $(eval $(call article-rules,$(po-base),$(subst .,,$(suffix $(po-base))))))
+### End of all articles' rules ###
+
+# If VCS=always, add all necessary files.  The templates' POT are not
+# handled for the moment, but they are more or less stable.
+# WARNING: This is implemented just in case, rarely used and probably broken.
+ifneq (,$(findstring always,$(VCS)))
+vcs-add-always: $(template-translated) $(ALL_POTS) \
+               $(articles-translated) $(gnunews) $(wildcard generic.*.html) \
+               substitute-localized-urls
+         -$(vcs) add $(filter-out substitute-localized-urls,$^)
+else
+vcs-add-always: ;
+endif
+
+# Special target to sync the original English articles from the `www'
+# repository.  It is intended to be invoked by a fencepost cron job
+# and will be useful even when GNUN is deployed.  Automatic adding and
+# removal is not implemented (except adding `verbatim-templates'), so
+# make sure to `cvs add'/`cvs remove' and commit the article when
+# editing gnun.mk.
+wwwdir := $(rootdir)/$(rootdir)/www
+orig-templates := $(addsuffix .html,$(template-translated-base))
+orig-articles := $(addsuffix .html,$(subst /po/,/,$(ALL_BASE)))
+files-to-sync := $(orig-templates) $(orig-articles)
+abs-files-to-sync := $(subst $(rootdir)/,,$(files-to-sync))
+# Templates that are not gettextized, but are necessary to reside in
+# trans-coord for HTML validation at build time.
+verbatim-templates-set := header head-include-1 html5-header \
+  html5-head-include banner footer
+verbatim-templates := $(addprefix server/, \
+  $(foreach template,$(verbatim-templates-set), \
+     $(foreach temp-lang,$(TEMPLATE_LINGUAS),$(template).$(temp-lang).html) \
+   ) \
+  whatsnew.html whatsnew.include)
+
+.PHONY: sync
+sync: 
+# Synchronize all articles and report if an article has been deleted
+# from the master repository.
+       for file in $(abs-files-to-sync) ; do \
+         if [ ! -f $(wwwdir)/$$file ] ; then \
+           echo "Warning: $$file missing in www; update the variable?" \
+           | $(VCSSKIP) mail -s "sync: missing file" $(devel-addr) ; \
+         else \
+           cp -p --update $(wwwdir)/$$file $(rootdir)/$$file ; \
+         fi ; done
+# Copy all necessary templates that are not under GNUN's control and
+# add them if VCS=yes.
+       for t in $(verbatim-templates) ; do \
+         if [ ! -f $(rootdir)/$$t ] ; then \
+           cp -p $(wwwdir)/$$t $(rootdir)/$$t \
+             && $(VCSSKIP) $(vcs) add $(rootdir)/$$t ; \
+         else \
+           cp -p --update $(wwwdir)/$$t $(rootdir)/$$t ; \
+         fi ; done
+       cd $(rootdir) ; \
+         $(VCSSKIP) $(vcs) commit -m \
+         "Automatic sync from the master www repository."
+
+# Assign priorities to translations for report.
+ifdef TEAM
+TEAM-POS := $(sort $(filter %.${TEAM}.po,${ALL_POS}))
+# UnGNUNified translations
+TEAM-HTMLS := $(shell echo $(subst /po/,/,$(ALL_POTS:%.pot=%.$(TEAM).html)) \
+  | $(SED) "s/[[:space:]]\+/\n/g" \
+  | while read f; do \
+      po_base=$${f\#\#*/}; po_base=$${po_base%html}po; po_dir=$${f%/*}/po; \
+      test -f $$f && { test -f $$po_dir/$$po_base || echo $$f; } done)
+priority-articles-pos := \
+  $(filter \
+    $(foreach article,${priority-articles},\
+      ${rootdir}/$(filter-out ./,\
+                   $(dir ${article}))po/$(notdir ${article}).${TEAM}.po), \
+    ${TEAM-POS})
+priority-articles-htmls := \
+  $(sort $(filter \
+    $(foreach article,${priority-articles},\
+      ${rootdir}/$(filter-out ./,\
+                   $(dir ${article}))/$(notdir ${article}).${TEAM}.html), \
+    ${TEAM-HTMLS}))
+important-articles-pos := \
+  $(filter \
+     $(foreach article,${important-articles},\
+       ${rootdir}/$(filter-out ./,\
+                    $(dir ${article}))po/$(notdir ${article}).${TEAM}.po), \
+     ${TEAM-POS})
+important-articles-htmls := \
+  $(sort $(filter \
+     $(foreach article,${important-articles},\
+       ${rootdir}/$(filter-out ./,\
+                    $(dir ${article}))/$(notdir ${article}).${TEAM}.html), \
+     ${TEAM-HTMLS}))
+important-dir-pos := \
+$(filter-out ${priority-articles-pos} ${important-articles-pos},\
+  $(filter $(addsuffix /%, \
+             $(addprefix ${rootdir}/,${important-directories})), \
+    ${TEAM-POS}))
+important-dir-htmls := \
+$(sort $(filter-out ${priority-articles-htmls} ${important-articles-htmls},\
+  $(filter $(addsuffix /%, \
+             $(addprefix ${rootdir}/,${important-directories})), \
+    ${TEAM-HTMLS})))
+other-pos := \
+  $(filter-out ${priority-articles-pos} ${important-articles-pos} \
+    ${important-dir-pos}, \
+    $(shell find $(rootdir) -name '*.$(TEAM).po' \
+              ! -path '$(template-dir)/gnun/*'))
+other-htmls := \
+  $(sort $(filter-out ${priority-articles-htmls} ${important-articles-htmls} \
+    ${important-dir-htmls}, ${TEAM-HTMLS}))
+
+# Function to report a group of PO files.
+define report-pos
address@hidden(if $(1)$(strip $(3)), $(if $(2), echo "  "$(strip $(2)); echo;)) 
\
+ $(if $(1), \
+    for i in $(1); do \
+      echo -n "$${i#${rootdir}/}: "; \
+      LC_ALL=C $(MSGFMT) --statistics -o /dev/null $$i 2>&1 \
+                 | $(SED) ':egin;$$s/\n[[:space:]]*/; /g;N;begin'; \
+    done | $(EGREP) '(fuzzy|untranslated)[^:]*$$' \
+    || echo "All translations seem to be up-to-date."; $(if $(2), echo;) \
+   )\
+ $(if $(strip $(3)), echo Translations to convert to PO files:; echo; \
+   for html in $(3); do echo $${html#${rootdir}/}; done; echo)
+endef
+endif # def TEAM
+
+# Special target to check which translations need updating.
+.PHONY: report
+report: 
+ifndef TEAM
+       $(error Please specify a language code, for example TEAM=fr)
+endif
+ifeq (,$(call find-language,$(TEAM),$(sort $(GENERIC_LINGUAS))))
+       @echo "There are no translations for language $(TEAM)."
+else
+ifeq (,${priority-articles}${important-articles}${important-directories})
+       $(call report-pos,${other-pos},,${other-htmls})
+else #!eq (,${priority-articles}${important-articles}${important-directories})
+       $(call report-pos,${priority-articles-pos},Priority Articles,\
+                          ${priority-articles-htmls})
+       $(call report-pos,${important-articles-pos},Important Articles,\
+                         ${important-articles-htmls})
+       $(call report-pos,${important-dir-pos},\
+         Other Articles from Important Directories,\
+                         ${important-dir-htmls})
+       $(call report-pos,${other-pos},Other Translations,${other-htmls})
+endif #!eq (,${priority-articles}${important-articles}${important-directories})
+endif # !eq (,$(call find-language,$(TEAM),$(sort $(GENERIC_LINGUAS))))
+
+# Special target to compile report about number of outdated translations
+# for all languages.
+.PHONY: reports-summary
+reports-summary:
+       @echo Outdated translations:
+       @$(foreach lang,$(TEMPLATE_LINGUAS), echo -n "$(lang): "; \
+          $(MAKE) report TEAM=$(lang) \
+          | $(EGREP) '(fuzzy|untranslated)[^:]*$$' \
+          | $(EGREP) -v 'html$$' | wc -l; )
+       @echo; echo UnGNUNified translations:
+       @$(foreach lang,$(TEMPLATE_LINGUAS), echo -n "$(lang): "; \
+          $(MAKE) report TEAM=$(lang) \
+          | $(EGREP) 'html$$' | wc -l; )
+
+# Special target to touch all the prerequisites of the targets that
+# failed HTML validation and thus to trigger a rebuild in the next
+# run.
+.PHONY: triggers
+triggers:
+ifeq (,$(wildcard *.hook))
+       @echo "No triggers to process; build apparently successful."
+else
+# Execute the command recorded in every .hook file.
+       @for t in *.hook; do \
+         echo -n "Processing $$t... " && bash $$t && echo done.; \
+       done
+# Delete all *.hook files, or else there will be useless rebuilds
+# every time updating the `Date' timestamp in .LANG.html.
+       $(RM) *.hook
+endif
+# Handle announcements of new translations.
+ifeq (,$(wildcard *.hook-ann))
+       @echo "No new translations."
+else
+# If the .hook-ann file contains "gnun-do-not-delete-me", it means
+# that the build failed in article-rules while checking the PO file.
+# The .LANG.html is empty, not suitable to be announced, so do nothing
+# in this case.
+       @for t in *.hook-ann; do \
+         if ! $(GREP) --quiet 'gnun-do-not-delete-me' $$t; then \
+           echo -n "Sending announcement for $$t... " \
+           && bash $$t && echo done.; $(RM) $$t; \
+         fi; \
+       done
+endif
+# Validate all articles under GNUN's control.
+# This is needed because GNUN doesn't track included files,
+# and the page may become invalid in an included file changes.
+.PHONY: validate-all
+validate-all:
+       for html in $(subst /po/,/,$(ALL_POTS:%.pot=%.html)); do \
+          echo Validating $${html}...; \
+          $(VALIDATE-HTML-NOTIFY) $(NOTIFYSKIP) ${web-addr} $${html} \
+          || exit 1; \
+        done
+# Note that the HTML file with translation may or may not exist yet,
+# so we should test it; also, if the HTML file is not newer than PO,
+# it may be a very old translation whose format validation is not supported.
+       for html in $(articles-translated); do \
+          po=$${html%html}po; po=$${po%/*}/po/$${po##*/}; \
+          if test -f $${html} && test $${html} -nt $${po}; then \
+            echo Validating $${html}...; \
+            $(VALIDATE-HTML-NOTIFY) $(NOTIFYSKIP) ${transl-addr} $${html} \
+            || exit 1; \
+          else \
+            if test -f $${html} ; then \
+              echo File $${html} is not newer than $${po}.; \
+            else \
+              echo No $${html} exist.; \
+            fi; \
+          fi; \
+        done
+
+### Everything that has a beginning has an end. ###

Index: disclaimer.fr.html
===================================================================
RCS file: disclaimer.fr.html
diff -N disclaimer.fr.html
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ disclaimer.fr.html  4 Feb 2014 17:35:44 -0000       1.1
@@ -0,0 +1,21 @@
+PO4A-HEADER:mode=before;position=<h2;beginboundary=^
+
+<!--#if expr="${DISABLE_TOP_ADDENDUM} == yes" -->
+<!--#else -->
+<!--#set var='link_to_english_page' value='' -->
+<!--#if expr="${ENGLISH_PAGE}" -->
+<!--#set var='link_to_english_page' 
+         value='<a href="${ENGLISH_PAGE}">' -->
+<!--#endif -->
+<p class="trans-disclaimer">
+<!--#echo encoding="none" var="link_to_english_page" -->
+L'original de cette page est en anglais.
+<br />
+
+<!--#if expr="${ENGLISH_PAGE}" -->
+</a>
+
+<!--#endif -->
+</p>
+
+<!--#endif -->



reply via email to

[Prev in Thread] Current Thread [Next in Thread]