summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Helleu <flashcode@flashtux.org>2011-07-03 15:47:50 +0200
committerSebastien Helleu <flashcode@flashtux.org>2011-07-03 15:47:50 +0200
commit5250b68d0a1d9871b9d89ff1253290372a747cf6 (patch)
treedece3a33776db56c8b878a3832f7ca5e0cae9ca4
parent0f5b4dbecbbcc413edbda5d0c3decefaf03683d2 (diff)
downloadweechat-5250b68d0a1d9871b9d89ff1253290372a747cf6.zip
doc: convert script docgen.pl to docgen.py
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/docgen.pl892
-rw-r--r--doc/docgen.py528
-rw-r--r--po/POTFILES.in2
-rw-r--r--po/srcfiles.cmake2
5 files changed, 531 insertions, 895 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 0c92cd420..27ebf2648 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -22,4 +22,4 @@ SUBDIRS = . en fr pl de ru ja it
man_MANS = weechat-curses.1
-EXTRA_DIST = $(man_MANS) docgen.pl CMakeLists.txt asciidoc.conf asciidoc.css
+EXTRA_DIST = $(man_MANS) docgen.py CMakeLists.txt asciidoc.conf asciidoc.css
diff --git a/doc/docgen.pl b/doc/docgen.pl
deleted file mode 100644
index 45ecb63b4..000000000
--- a/doc/docgen.pl
+++ /dev/null
@@ -1,892 +0,0 @@
-#
-# Copyright (C) 2008-2011 Sebastien Helleu <flashcode@flashtux.org>
-#
-# This file is part of WeeChat, the extensible chat client.
-#
-# WeeChat 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.
-#
-# WeeChat 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 WeeChat. If not, see <http://www.gnu.org/licenses/>.
-#
-
-#
-# Documentation generator for WeeChat: build include files with commands,
-# options, infos and completions for WeeChat core and plugins.
-#
-# Instructions to build config files yourself in WeeChat directories (replace
-# all paths with your path to WeeChat):
-# 1. run WeeChat and load this script, with following command:
-# /perl load ~/src/weechat/doc/docgen.pl
-# 2. change path to build in your doc/ directory:
-# /set plugins.var.perl.docgen.path "~/src/weechat/doc"
-# 3. run docgen command:
-# /docgen
-# Files should be in ~/src/weechat/doc/xx/autogen/ (where xx is language)
-#
-
-use strict;
-
-use POSIX; # needed for setlocale()
-use Locale::gettext;
-use File::Basename;
-
-my $version = "0.1";
-
-# -------------------------------[ config ]------------------------------------
-
-# default path where doc files will be written (should be doc/ in sources
-# package tree)
-# path must have subdirectories with languages and autogen directory:
-# path
-# |-- en
-# | |-- autogen
-# |-- fr
-# | |-- autogen
-# ...
-my $default_path = "~/src/weechat/doc";
-
-# list of locales for which we want to build doc files to include
-my @all_locale_list = qw(en_US fr_FR it_IT de_DE);
-
-# all commands/options/.. of following plugins will produce a file
-# non-listed plugins will be ignored
-# value: "c" = plugin may have many commands
-# "o" = write config options for plugin
-# if plugin is listed without "c", that means plugin has only one command
-# /name (where "name" # is name of plugin)
-# Note: we consider core is a plugin called "weechat"
-my %plugin_list = ("weechat" => "co", "alias" => "",
- "aspell" => "o", "charset" => "co",
- "demo" => "co", "fifo" => "co",
- "irc" => "co", "logger" => "co",
- "relay" => "co", "rmodifier" => "co",
- "perl" => "", "python" => "",
- "ruby" => "", "lua" => "",
- "tcl" => "", "xfer" => "co");
-
-# options to ignore
-my @ignore_options = ("aspell\\.dict\\..*",
- "aspell\\.option\\..*",
- "charset\\.decode\\..*",
- "charset\\.encode\\..*",
- "irc\\.msgbuffer\\..*",
- "irc\\.ctcp\\..*",
- "irc\\.ignore\\..*",
- "irc\\.server\\..*",
- "jabber\\.server\\..*",
- "logger\\.level\\..*",
- "logger\\.mask\\..*",
- "relay\\.port\\..*",
- "rmodifier\\.modifier\\..*",
- "weechat\\.palette\\..*",
- "weechat\\.proxy\\..*",
- "weechat\\.bar\\..*",
- "weechat\\.debug\\..*",
- "weechat\\.notify\\..*");
-
-# infos to ignore
-my @ignore_infos_plugins = ();
-
-# infos (hashtable) to ignore
-my @ignore_infos_hashtable_plugins = ();
-
-# infolists to ignore
-my @ignore_infolists_plugins = ();
-
-# hdata to ignore
-my @ignore_hdata_plugins = ();
-
-# completions to ignore
-my @ignore_completions_plugins = ();
-my @ignore_completions_items = ("docgen.*",
- "jabber.*",
- "weeget.*");
-
-# for gettext
-my $d;
-
-# -------------------------------[ init ]--------------------------------------
-
-weechat::register("docgen", "Sebastien Helleu <flashcode\@flashtux.org>", $version,
- "GPL3", "Doc generator for WeeChat 0.3.x", "", "");
-weechat::hook_command("docgen", "Doc generator",
- "[locales]",
- "locales: list of locales to build (by default build all locales)",
- "%(docgen_locales)|%*", "docgen", "");
-weechat::hook_completion("docgen_locales", "locales for docgen", "docgen_completion", "");
-weechat::config_set_plugin("path", $default_path)
- if (weechat::config_get_plugin("path") eq "");
-
-# -----------------------------------------------------------------------------
-
-# gettext
-sub weechat_gettext
-{
- return $d->get($_[0]);
-}
-
-# get list of commands in a hash with 3 indexes: plugin, command, xxx
-sub get_commands
-{
- my %commands;
-
- my $infolist = weechat::infolist_get("hook", "", "command");
- while (weechat::infolist_next($infolist))
- {
- my $command = weechat::infolist_string($infolist, "command");
- my $plugin = weechat::infolist_string($infolist, "plugin_name");
- $plugin = "weechat" if ($plugin eq "");
- if (exists($plugin_list{$plugin}))
- {
- if (($command eq $plugin) || ($plugin_list{$plugin} =~ /c/))
- {
- $commands{$plugin}{$command}{"description"} = weechat::infolist_string($infolist, "description");
- $commands{$plugin}{$command}{"args"} = weechat::infolist_string($infolist, "args");
- $commands{$plugin}{$command}{"args_description"} = weechat::infolist_string($infolist, "args_description");
- $commands{$plugin}{$command}{"completion"} = weechat::infolist_string($infolist, "completion");
- }
- }
- }
- weechat::infolist_free($infolist);
-
- return %commands;
-}
-
-# get list of config options in a hash with 4 indexes: config, section, option, xxx
-sub get_options
-{
- my %options;
-
- my $infolist = weechat::infolist_get("option", "", "");
- while (weechat::infolist_next($infolist))
- {
- my $full_name = weechat::infolist_string($infolist, "full_name");
-
- # check if option is ignored or not
- my $ignore = 0;
- foreach my $mask (@ignore_options)
- {
- $ignore = 1 if ($full_name =~ /${mask}/);
- }
-
- if ($ignore ne 1)
- {
- my $config = weechat::infolist_string($infolist, "config_name");
- my $section = weechat::infolist_string($infolist, "section_name");
- my $option = weechat::infolist_string($infolist, "option_name");
- if (defined $plugin_list{$config} && ($plugin_list{$config} =~ /o/))
- {
- $options{$config}{$section}{$option}{"type"} = weechat::infolist_string($infolist, "type");
- $options{$config}{$section}{$option}{"string_values"} = weechat::infolist_string($infolist, "string_values");
- $options{$config}{$section}{$option}{"default_value"} = weechat::infolist_string($infolist, "default_value");
- $options{$config}{$section}{$option}{"min"} = weechat::infolist_integer($infolist, "min");
- $options{$config}{$section}{$option}{"max"} = weechat::infolist_integer($infolist, "max");
- $options{$config}{$section}{$option}{"null_value_allowed"} = weechat::infolist_integer($infolist, "null_value_allowed");
- $options{$config}{$section}{$option}{"description"} = weechat::infolist_string($infolist, "description");
- }
- }
- }
- weechat::infolist_free($infolist);
-
- return %options;
-}
-
-# get list of infos hooked by plugins in a hash with 3 indexes: plugin, name, xxx
-sub get_infos
-{
- my %infos;
-
- # get infos hooked
- my $infolist = weechat::infolist_get("hook", "", "info");
- while (weechat::infolist_next($infolist))
- {
- my $info_name = weechat::infolist_string($infolist, "info_name");
- my $plugin = weechat::infolist_string($infolist, "plugin_name");
- $plugin = "weechat" if ($plugin eq "");
-
- # check if info is ignored or not
- my $ignore = 0;
- foreach my $mask (@ignore_infos_plugins)
- {
- $ignore = 1 if ($plugin =~ /${mask}/);
- }
-
- if ($ignore ne 1)
- {
- $infos{$plugin}{$info_name}{"description"} = weechat::infolist_string($infolist, "description");
- $infos{$plugin}{$info_name}{"args_description"} = weechat::infolist_string($infolist, "args_description");
- }
- }
- weechat::infolist_free($infolist);
-
- return %infos;
-}
-
-# get list of infos (hashtable) hooked by plugins in a hash with 3 indexes: plugin, name, xxx
-sub get_infos_hashtable
-{
- my %infos_hashtable;
-
- # get infos hooked
- my $infolist = weechat::infolist_get("hook", "", "info_hashtable");
- while (weechat::infolist_next($infolist))
- {
- my $info_name = weechat::infolist_string($infolist, "info_name");
- my $plugin = weechat::infolist_string($infolist, "plugin_name");
- $plugin = "weechat" if ($plugin eq "");
-
- # check if info_hashtable is ignored or not
- my $ignore = 0;
- foreach my $mask (@ignore_infos_hashtable_plugins)
- {
- $ignore = 1 if ($plugin =~ /${mask}/);
- }
-
- if ($ignore ne 1)
- {
- $infos_hashtable{$plugin}{$info_name}{"description"} = weechat::infolist_string($infolist, "description");
- $infos_hashtable{$plugin}{$info_name}{"args_description"} = weechat::infolist_string($infolist, "args_description");
- $infos_hashtable{$plugin}{$info_name}{"output_description"} = weechat::infolist_string($infolist, "output_description");
- }
- }
- weechat::infolist_free($infolist);
-
- return %infos_hashtable;
-}
-
-# get list of infolists hooked by plugins in a hash with 3 indexes: plugin, name, xxx
-sub get_infolists
-{
- my %infolists;
-
- # get infolists hooked
- my $infolist = weechat::infolist_get("hook", "", "infolist");
- while (weechat::infolist_next($infolist))
- {
- my $infolist_name = weechat::infolist_string($infolist, "infolist_name");
- my $plugin = weechat::infolist_string($infolist, "plugin_name");
- $plugin = "weechat" if ($plugin eq "");
-
- # check if infolist is ignored or not
- my $ignore = 0;
- foreach my $mask (@ignore_infolists_plugins)
- {
- $ignore = 1 if ($plugin =~ /${mask}/);
- }
-
- if ($ignore ne 1)
- {
- $infolists{$plugin}{$infolist_name}{"description"} = weechat::infolist_string($infolist, "description");
- $infolists{$plugin}{$infolist_name}{"pointer_description"} = weechat::infolist_string($infolist, "pointer_description");
- $infolists{$plugin}{$infolist_name}{"args_description"} = weechat::infolist_string($infolist, "args_description");
- }
- }
- weechat::infolist_free($infolist);
-
- return %infolists;
-}
-
-# get list of hdata hooked by plugins in a hash with 3 indexes: plugin, name, xxx
-sub get_hdata
-{
- my %hdata;
-
- # get hdata hooked
- my $infolist = weechat::infolist_get("hook", "", "hdata");
- while (weechat::infolist_next($infolist))
- {
- my $hdata_name = weechat::infolist_string($infolist, "hdata_name");
- my $plugin = weechat::infolist_string($infolist, "plugin_name");
- $plugin = "weechat" if ($plugin eq "");
-
- # check if hdata is ignored or not
- my $ignore = 0;
- foreach my $mask (@ignore_hdata_plugins)
- {
- $ignore = 1 if ($plugin =~ /${mask}/);
- }
-
- if ($ignore ne 1)
- {
- $hdata{$plugin}{$hdata_name}{"description"} = weechat::infolist_string($infolist, "description");
-
- my $vars = "";
- my $lists = "";
- my $ptr_hdata = weechat::hdata_get($hdata_name);
- if ($ptr_hdata ne "")
- {
- my $str = weechat::hdata_get_string($ptr_hdata, "var_keys_values");
- my @items = split(/,/, $str);
- my %hdata2;
- foreach my $item (@items)
- {
- my ($key, $value) = split(/:/, $item);
- my $type = int($value) >> 16;
- my $offset = int($value) & 0xFFFF;
- my $stroffset = sprintf("%08d", $offset);
- my $var_hdata = weechat::hdata_get_var_hdata($ptr_hdata, $key);
- $var_hdata = ", hdata: '".$var_hdata."'" if ($var_hdata ne "");
- $hdata2{$stroffset} = "'".$key."' (".weechat::hdata_get_var_type_string($ptr_hdata, $key).$var_hdata.")";
- }
- foreach my $offset (sort keys %hdata2)
- {
- $vars .= " +\n" if ($vars ne "");
- $vars .= " ".$hdata2{$offset};
- }
- $hdata{$plugin}{$hdata_name}{"vars"} = "\n".$vars;
-
- $str = weechat::hdata_get_string($ptr_hdata, "list_keys");
- if ($str ne "")
- {
- my @items = split(/,/, $str);
- @items = sort(@items);
- foreach my $item (@items)
- {
- $lists .= " +\n" if ($lists ne "");
- $lists .= " '".$item."'";
- }
- $lists = "\n".$lists;
- }
- else
- {
- $lists = "\n -";
- }
- $hdata{$plugin}{$hdata_name}{"lists"} = $lists;
- }
- }
- }
- weechat::infolist_free($infolist);
-
- return %hdata;
-}
-
-# get list of completions hooked by plugins in a hash with 3 indexes: plugin, item, xxx
-sub get_completions
-{
- my %completions;
-
- # get completions hooked
- my $infolist = weechat::infolist_get("hook", "", "completion");
- while (weechat::infolist_next($infolist))
- {
- my $completion_item = weechat::infolist_string($infolist, "completion_item");
- my $plugin = weechat::infolist_string($infolist, "plugin_name");
- $plugin = "weechat" if ($plugin eq "");
-
- # check if completion item is ignored or not
- my $ignore = 0;
- foreach my $mask (@ignore_completions_plugins)
- {
- $ignore = 1 if ($plugin =~ /${mask}/);
- }
- foreach my $mask (@ignore_completions_items)
- {
- $ignore = 1 if ($completion_item =~ /${mask}/);
- }
-
- if (($ignore ne 1) && ($completion_item ne ""))
- {
- $completions{$plugin}{$completion_item}{"description"} = weechat::infolist_string($infolist, "description");
- }
- }
- weechat::infolist_free($infolist);
-
- return %completions;
-}
-
-sub escape_string
-{
- my $str = $_[0];
- $str =~ s/"/\\"/g;
- return $str;
-}
-
-sub escape_table
-{
- my $str = $_[0];
- $str =~ s/\|/\\|/g;
- return $str;
-}
-
-# build doc files (command /docgen)
-sub docgen
-{
- my ($data, $buffer, $args) = ($_[0], $_[1], $_[2]);
-
- my @locale_list = @all_locale_list;
- @locale_list = split(/ /, $args) if ($args ne "");
-
- my %plugin_commands = get_commands();
- my %plugin_options = get_options();
- my %plugin_infos = get_infos();
- my %plugin_infos_hashtable = get_infos_hashtable();
- my %plugin_infolists = get_infolists();
- my %plugin_hdata = get_hdata();
- my %plugin_completions = get_completions();
-
- # get path and replace ~ by home if needed
- my $path = weechat::config_get_plugin("path");
- $path =~ s/^~\//$ENV{"HOME"}\//;
-
- my $old_locale = setlocale(LC_MESSAGES);
-
- # write to doc files, by locale
- my $num_files = 0;
- my $num_files_updated = 0;
- my $filename = "";
-
- foreach my $locale (@locale_list)
- {
- my $num_files_commands = 0;
- my $num_files_commands_updated = 0;
- my $num_files_options = 0;
- my $num_files_options_updated = 0;
- my $num_files_infos = 0;
- my $num_files_infos_updated = 0;
- my $num_files_infos_hashtable = 0;
- my $num_files_infos_hashtable_updated = 0;
- my $num_files_infolists = 0;
- my $num_files_infolists_updated = 0;
- my $num_files_hdata = 0;
- my $num_files_hdata_updated = 0;
- my $num_files_completions = 0;
- my $num_files_completions_updated = 0;
-
- setlocale(LC_MESSAGES, $locale.".UTF-8");
- $d = Locale::gettext->domain_raw("weechat");
- $d->codeset("UTF-8");
- $d->dir(weechat::info_get("weechat_localedir", ""));
-
- my $dir = $path."/".substr($locale, 0, 2)."/autogen/";
- if (-d $dir)
- {
- # write commands
- foreach my $plugin (keys %plugin_commands)
- {
- $filename = $dir."user/".$plugin."_commands.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- foreach my $command (sort keys %{$plugin_commands{$plugin}})
- {
- my $args = $plugin_commands{$plugin}{$command}{"args"};
- $args = $d->get($args) if ($args ne "");
- my @args_formats = split(/ \|\| /, $args);
- my $description = $plugin_commands{$plugin}{$command}{"description"};
- $description = $d->get($description) if ($description ne "");
- my $args_description = $plugin_commands{$plugin}{$command}{"args_description"};
- $args_description = $d->get($args_description) if ($args_description ne "");
-
- print FILE "[command]*`".$command."`* ".$description."::\n";
- print FILE "........................................\n";
- my $prefix = "/".$command." ";
- foreach my $format (@args_formats)
- {
- print FILE $prefix.$format."\n";
- $prefix = " " x length($prefix);
- }
- if ($args_description ne "")
- {
- print FILE "\n";
- my @lines = split(/\n/, $args_description);
- foreach my $line (@lines)
- {
- print FILE $line."\n";
- }
- }
- print FILE "........................................\n\n";
-
- }
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_commands_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_commands++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
- }
-
- # write config options
- foreach my $config (keys %plugin_options)
- {
- $filename = $dir."user/".$config."_options.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- foreach my $section (sort keys %{$plugin_options{$config}})
- {
- foreach my $option (sort keys %{$plugin_options{$config}{$section}})
- {
- my $type = $plugin_options{$config}{$section}{$option}{"type"};
- my $string_values = $plugin_options{$config}{$section}{$option}{"string_values"};
- my $default_value = $plugin_options{$config}{$section}{$option}{"default_value"};
- my $min = $plugin_options{$config}{$section}{$option}{"min"};
- my $max = $plugin_options{$config}{$section}{$option}{"max"};
- my $null_value_allowed = $plugin_options{$config}{$section}{$option}{"null_value_allowed"};
- my $description = $plugin_options{$config}{$section}{$option}{"description"};
- $description = $d->get($description) if ($description ne "");
- my $type_nls = $type;
- $type_nls = $d->get($type_nls) if ($type_nls ne "");
- my $values = "";
- if ($type eq "boolean")
- {
- $values = "on, off";
- }
- if ($type eq "integer")
- {
- if ($string_values ne "")
- {
- $string_values =~ s/\|/, /g;
- $values = $string_values;
- }
- else
- {
- $values = $min." .. ".$max;
- }
- }
- if ($type eq "string")
- {
- $values = weechat_gettext("any string") if ($max <= 0);
- $values = weechat_gettext("any char") if ($max == 1);
- $values = weechat_gettext("any string")." (".weechat_gettext("max chars").": ".$max.")" if ($max > 1);
- $default_value = "\"".escape_string($default_value)."\"";
- }
- if ($type eq "color")
- {
- $values = weechat_gettext("a WeeChat color name (default, black, "
- ."(dark)gray, white, (light)red, (light)green, "
- ."brown, yellow, (light)blue, (light)magenta, "
- ."(light)cyan), a terminal color number or "
- ."an alias; attributes are allowed before "
- ."color (for text color only, not "
- ."background): \"*\" for bold, \"!\" for "
- ."reverse, \"_\" for underline");
- }
-
- print FILE "* *".$config.".".$section.".".$option."*\n";
- print FILE "** ".weechat_gettext("description").": `".$description."`\n";
- print FILE "** ".weechat_gettext("type").": ".$type_nls."\n";
- print FILE "** ".weechat_gettext("values").": ".$values." "
- ."(".weechat_gettext("default value").": `".$default_value."`)\n";
- if ($null_value_allowed eq 1)
- {
- print FILE "** ".weechat_gettext("undefined value allowed (null)")."\n";
- }
- print FILE "\n";
- }
- }
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_options_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_options++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
- }
-
- # write infos hooked
- $filename = $dir."plugin_api/infos.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- print FILE "[width=\"100%\",cols=\"^1,^2,6,6\",options=\"header\"]\n";
- print FILE "|========================================\n";
- print FILE "| ".weechat_gettext("Plugin")." | ".weechat_gettext("Name")
- ." | ".weechat_gettext("Description")." | ".weechat_gettext("Arguments")."\n\n";
- foreach my $plugin (sort keys %plugin_infos)
- {
- foreach my $info (sort keys %{$plugin_infos{$plugin}})
- {
- my $description = $plugin_infos{$plugin}{$info}{"description"};
- $description = $d->get($description) if ($description ne "");
- my $args_description = $plugin_infos{$plugin}{$info}{"args_description"};
- $args_description = $d->get($args_description) if ($args_description ne "");
- $args_description = "-" if ($args_description eq "");
-
- print FILE "| ".escape_table($plugin)." | ".escape_table($info)
- ." | ".escape_table($description)." | ".escape_table($args_description)."\n\n";
- }
- }
- print FILE "|========================================\n";
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_infos_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_infos++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
-
- # write infos (hashtable) hooked
- $filename = $dir."plugin_api/infos_hashtable.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- print FILE "[width=\"100%\",cols=\"^1,^2,6,6,6\",options=\"header\"]\n";
- print FILE "|========================================\n";
- print FILE "| ".weechat_gettext("Plugin")." | ".weechat_gettext("Name")
- ." | ".weechat_gettext("Description")." | ".weechat_gettext("Hashtable (input)")
- ." | ".weechat_gettext("Hashtable (output)")."\n\n";
- foreach my $plugin (sort keys %plugin_infos_hashtable)
- {
- foreach my $info (sort keys %{$plugin_infos_hashtable{$plugin}})
- {
- my $description = $plugin_infos_hashtable{$plugin}{$info}{"description"};
- $description = $d->get($description) if ($description ne "");
- my $args_description = $plugin_infos_hashtable{$plugin}{$info}{"args_description"};
- $args_description = $d->get($args_description) if ($args_description ne "");
- $args_description = "-" if ($args_description eq "");
- my $output_description = $plugin_infos_hashtable{$plugin}{$info}{"output_description"};
- $output_description = $d->get($output_description) if ($output_description ne "");
- $output_description = "-" if ($output_description eq "");
-
- print FILE "| ".escape_table($plugin)." | ".escape_table($info)
- ." | ".escape_table($description)." | ".escape_table($args_description)
- ." | ".escape_table($output_description)."\n\n";
- }
- }
- print FILE "|========================================\n";
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_infos_hashtable_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_infos_hashtable++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
-
- # write infolists hooked
- $filename = $dir."plugin_api/infolists.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- print FILE "[width=\"100%\",cols=\"^1,^2,5,5,5\",options=\"header\"]\n";
- print FILE "|========================================\n";
- print FILE "| ".weechat_gettext("Plugin")." | ".weechat_gettext("Name")
- ." | ".weechat_gettext("Description")." | ".weechat_gettext("Pointer")
- ." | ".weechat_gettext("Arguments")."\n\n";
- foreach my $plugin (sort keys %plugin_infolists)
- {
- foreach my $infolist (sort keys %{$plugin_infolists{$plugin}})
- {
- my $description = $plugin_infolists{$plugin}{$infolist}{"description"};
- $description = $d->get($description) if ($description ne "");
- my $pointer_description = $plugin_infolists{$plugin}{$infolist}{"pointer_description"};
- $pointer_description = $d->get($pointer_description) if ($pointer_description ne "");
- $pointer_description = "-" if ($pointer_description eq "");
- my $args_description = $plugin_infolists{$plugin}{$infolist}{"args_description"};
- $args_description = $d->get($args_description) if ($args_description ne "");
- $args_description = "-" if ($args_description eq "");
-
- print FILE "| ".escape_table($plugin)." | ".escape_table($infolist)
- ." | ".escape_table($description)." | ".escape_table($pointer_description)
- ." | ".escape_table($args_description)."\n\n";
- }
- }
- print FILE "|========================================\n";
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_infolists_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_infolists++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
-
- # write hdata hooked
- $filename = $dir."plugin_api/hdata.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- print FILE "[width=\"100%\",cols=\"^1,^2,5,5,5\",options=\"header\"]\n";
- print FILE "|========================================\n";
- print FILE "| ".weechat_gettext("Plugin")." | ".weechat_gettext("Name")
- ." | ".weechat_gettext("Description")." | ".weechat_gettext("Variables")
- ." | ".weechat_gettext("Lists")."\n\n";
- foreach my $plugin (sort keys %plugin_hdata)
- {
- foreach my $hdata (sort keys %{$plugin_hdata{$plugin}})
- {
- my $description = $plugin_hdata{$plugin}{$hdata}{"description"};
- $description = $d->get($description) if ($description ne "");
- my $vars = $plugin_hdata{$plugin}{$hdata}{"vars"};
- my $lists = $plugin_hdata{$plugin}{$hdata}{"lists"};
- print FILE "| ".escape_table($plugin)." | ".escape_table($hdata)
- ." | ".escape_table($description)." |".escape_table($vars)
- ." |".escape_table($lists)."\n\n";
- }
- }
- print FILE "|========================================\n";
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_hdata_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_hdata++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
-
- # write completions hooked
- $filename = $dir."plugin_api/completions.txt";
- if (open(FILE, ">".$filename.".tmp"))
- {
- print FILE "[width=\"65%\",cols=\"^1,^2,8\",options=\"header\"]\n";
- print FILE "|========================================\n";
- print FILE "| ".weechat_gettext("Plugin")." | ".weechat_gettext("Name")
- ." | ".weechat_gettext("Description")."\n\n";
- foreach my $plugin (sort keys %plugin_completions)
- {
- foreach my $completion_item (sort keys %{$plugin_completions{$plugin}})
- {
- my $description = $plugin_completions{$plugin}{$completion_item}{"description"};
- $description = $d->get($description) if ($description ne "");
-
- print FILE "| ".escape_table($plugin)." | ".escape_table($completion_item)
- ." | ".escape_table($description)."\n\n";
- }
- }
- print FILE "|========================================\n";
- #weechat::print("", "docgen: file ok: '$filename'");
- my $rc = system("diff ".$filename." ".$filename.".tmp >/dev/null 2>&1");
- if ($rc != 0)
- {
- system("mv -f ".$filename.".tmp ".$filename);
- $num_files_updated++;
- $num_files_completions_updated++;
- }
- else
- {
- system("rm ".$filename.".tmp");
- }
- $num_files++;
- $num_files_completions++;
- close(FILE);
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: unable to write file '$filename'");
- }
- }
- else
- {
- weechat::print("", weechat::prefix("error")."docgen error: directory '$dir' does not exist");
- }
- my $total_files = $num_files_commands + $num_files_options
- + $num_files_infos + $num_files_infos_hashtable
- + $num_files_infolists + $num_files_hdata + $num_files_completions;
- my $total_files_updated = $num_files_commands_updated
- + $num_files_options_updated + $num_files_infos_updated
- + $num_files_infos_hashtable_updated + $num_files_infolists_updated
- + $num_files_hdata_updated + $num_files_completions_updated;
- weechat::print("",
- sprintf ("docgen: %s: %3d files (%2d cmd, %2d opt, %2d infos, "
- ."%2d infos_hash, %2d infolists, %2d hdata, "
- ."%2d complt)",
- $locale, $total_files, $num_files_commands,
- $num_files_options, $num_files_infos, $num_files_infos,
- $num_files_infolists, $num_files_hdata,
- $num_files_completions));
- weechat::print("",
- sprintf (" %3d updated (%2d cmd, %2d opt, %2d infos, "
- ."%2d infos_hash, %2d infolists, %2d hdata, "
- ."%2d complt)",
- $total_files_updated, $num_files_commands_updated,
- $num_files_options_updated, $num_files_infos_updated,
- $num_files_infos_updated, $num_files_infolists_updated,
- $num_files_hdata_updated, $num_files_completions_updated));
- }
- weechat::print("",
- sprintf ("docgen: total: %d files, %d updated",
- $num_files, $num_files_updated));
-
- setlocale(LC_MESSAGES, $old_locale);
-
- return weechat::WEECHAT_RC_OK;
-}
-
-sub docgen_completion
-{
- my ($data, $completion_item, $buffer, $completion) = ($_[0], $_[1], $_[2], $_[3]);
-
- foreach my $locale (@all_locale_list)
- {
- weechat::hook_completion_list_add($completion, $locale, 0, weechat::WEECHAT_LIST_POS_SORT);
- }
- return weechat::WEECHAT_RC_OK;
-}
diff --git a/doc/docgen.py b/doc/docgen.py
new file mode 100644
index 000000000..689802546
--- /dev/null
+++ b/doc/docgen.py
@@ -0,0 +1,528 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2008-2011 Sébastien Helleu <flashcode@flashtux.org>
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Documentation generator for WeeChat: build include files with commands,
+# options, infos, infolists, hdata and completions for WeeChat core and plugins.
+#
+# Instructions to build config files yourself in WeeChat directories (replace
+# all paths with your path to WeeChat):
+# 1. run WeeChat and load this script, with following command:
+# /python load ~/src/weechat/doc/docgen.py
+# 2. change path to build in your doc/ directory:
+# /set plugins.var.python.docgen.path "~/src/weechat/doc"
+# 3. run docgen command:
+# /docgen
+# (it is recommended to load only this script when building doc)
+# Files should be in ~/src/weechat/doc/xx/autogen/ (where xx is language)
+#
+
+SCRIPT_NAME = 'docgen'
+SCRIPT_AUTHOR = 'Sébastien Helleu <flashcode@flashtux.org>'
+SCRIPT_VERSION = '0.1'
+SCRIPT_LICENSE = 'GPL3'
+SCRIPT_DESC = 'Documentation generator for WeeChat'
+
+SCRIPT_COMMAND = 'docgen'
+
+import_ok = True
+
+try:
+ import weechat
+except ImportError:
+ print('This script must be run under WeeChat.')
+ print('Get WeeChat now at: http://www.weechat.org/')
+ import_ok = False
+
+try:
+ import os, gettext, re, hashlib
+ from collections import defaultdict
+ from operator import itemgetter
+except ImportError, message:
+ print('Missing package(s) for %s: %s' % (SCRIPT_NAME, message))
+ import_ok = False
+
+# default path where doc files will be written (should be doc/ in sources
+# package tree)
+# path must have subdirectories with languages and autogen directory:
+# path
+# |-- en
+# | |-- autogen
+# |-- fr
+# | |-- autogen
+# ...
+DEFAULT_PATH = '~/src/weechat/doc'
+
+# list of locales for which we want to build doc files to include
+locale_list = ('en_US', 'fr_FR', 'it_IT', 'de_DE')
+
+# all commands/options/.. of following plugins will produce a file
+# non-listed plugins will be ignored
+# value: "c" = plugin may have many commands
+# "o" = write config options for plugin
+# if plugin is listed without "c", that means plugin has only one command
+# /name (where "name" is name of plugin)
+# Note: we consider core is a plugin called "weechat"
+plugin_list = { 'weechat' : 'co',
+ 'alias' : '',
+ 'aspell' : 'o',
+ 'charset' : 'co',
+ 'demo' : 'co',
+ 'fifo' : 'co',
+ 'irc' : 'co',
+ 'logger' : 'co',
+ 'relay' : 'co',
+ 'rmodifier': 'co',
+ 'perl' : '',
+ 'python' : '',
+ 'ruby' : '',
+ 'lua' : '',
+ 'tcl' : '',
+ 'xfer' : 'co' }
+
+# options to ignore
+ignore_options = ( 'aspell\.dict\..*',
+ 'aspell\.option\..*',
+ 'charset\.decode\..*',
+ 'charset\.encode\..*',
+ 'irc\.msgbuffer\..*',
+ 'irc\.ctcp\..*',
+ 'irc\.ignore\..*',
+ 'irc\.server\..*',
+ 'jabber\.server\..*',
+ 'logger\.level\..*',
+ 'logger\.mask\..*',
+ 'relay\.port\..*',
+ 'rmodifier\.modifier\..*',
+ 'weechat\.palette\..*',
+ 'weechat\.proxy\..*',
+ 'weechat\.bar\..*',
+ 'weechat\.debug\..*',
+ 'weechat\.notify\..*' )
+
+# completions to ignore
+ignore_completions_items = ( 'docgen.*',
+ 'jabber.*',
+ 'weeget.*' )
+
+def get_commands():
+ """Get list of commands in a dict with 3 indexes: plugin, command, xxx."""
+ global plugin_list
+ commands = defaultdict(lambda: defaultdict(defaultdict))
+ infolist = weechat.infolist_get('hook', '', 'command')
+ while weechat.infolist_next(infolist):
+ plugin = weechat.infolist_string(infolist, 'plugin_name') or 'weechat'
+ if plugin in plugin_list:
+ command = weechat.infolist_string(infolist, 'command')
+ if command == plugin or 'c' in plugin_list[plugin]:
+ for key in ('description', 'args', 'args_description', 'completion'):
+ commands[plugin][command][key] = weechat.infolist_string(infolist, key)
+ weechat.infolist_free(infolist)
+ return commands
+
+def get_options():
+ """Get list of config options in a dict with 4 indexes: config, section, option, xxx."""
+ global plugin_list, ignore_options
+ options = defaultdict(lambda: defaultdict(lambda: defaultdict(defaultdict)))
+ infolist = weechat.infolist_get('option', '', '')
+ while weechat.infolist_next(infolist):
+ full_name = weechat.infolist_string(infolist, 'full_name')
+ if not re.search('|'.join(ignore_options), full_name):
+ config = weechat.infolist_string(infolist, 'config_name')
+ if config in plugin_list and 'o' in plugin_list[config]:
+ section = weechat.infolist_string(infolist, 'section_name')
+ option = weechat.infolist_string(infolist, 'option_name')
+ for key in ('type', 'string_values', 'default_value', 'description'):
+ options[config][section][option][key] = weechat.infolist_string(infolist, key)
+ for key in ('min', 'max', 'null_value_allowed'):
+ options[config][section][option][key] = weechat.infolist_integer(infolist, key)
+ weechat.infolist_free(infolist)
+ return options
+
+def get_infos():
+ """Get list of infos hooked by plugins in a dict with 3 indexes: plugin, name, xxx."""
+ infos = defaultdict(lambda: defaultdict(defaultdict))
+ infolist = weechat.infolist_get('hook', '', 'info')
+ while weechat.infolist_next(infolist):
+ info_name = weechat.infolist_string(infolist, 'info_name')
+ plugin = weechat.infolist_string(infolist, 'plugin_name') or 'weechat'
+ for key in ('description', 'args_description'):
+ infos[plugin][info_name][key] = weechat.infolist_string(infolist, key)
+ weechat.infolist_free(infolist)
+ return infos
+
+def get_infos_hashtable():
+ """Get list of infos (hashtable) hooked by plugins in a dict with 3 indexes: plugin, name, xxx."""
+ infos_hashtable = defaultdict(lambda: defaultdict(defaultdict))
+ infolist = weechat.infolist_get('hook', '', 'info_hashtable')
+ while weechat.infolist_next(infolist):
+ info_name = weechat.infolist_string(infolist, 'info_name')
+ plugin = weechat.infolist_string(infolist, 'plugin_name') or 'weechat'
+ for key in ('description', 'args_description', 'output_description'):
+ infos_hashtable[plugin][info_name][key] = weechat.infolist_string(infolist, key)
+ weechat.infolist_free(infolist)
+ return infos_hashtable
+
+def get_infolists():
+ """Get list of infolists hooked by plugins in a dict with 3 indexes: plugin, name, xxx."""
+ infolists = defaultdict(lambda: defaultdict(defaultdict))
+ infolist = weechat.infolist_get('hook', '', 'infolist')
+ while weechat.infolist_next(infolist):
+ infolist_name = weechat.infolist_string(infolist, 'infolist_name')
+ plugin = weechat.infolist_string(infolist, 'plugin_name') or 'weechat'
+ for key in ('description', 'pointer_description', 'args_description'):
+ infolists[plugin][infolist_name][key] = weechat.infolist_string(infolist, key)
+ weechat.infolist_free(infolist)
+ return infolists
+
+def get_hdata():
+ """Get list of hdata hooked by plugins in a dict with 3 indexes: plugin, name, xxx."""
+ hdata = defaultdict(lambda: defaultdict(defaultdict))
+ infolist = weechat.infolist_get('hook', '', 'hdata')
+ while weechat.infolist_next(infolist):
+ hdata_name = weechat.infolist_string(infolist, 'hdata_name')
+ plugin = weechat.infolist_string(infolist, 'plugin_name') or 'weechat'
+ hdata[plugin][hdata_name]['description'] = weechat.infolist_string(infolist, 'description')
+ variables = ''
+ lists = ''
+ ptr_hdata = weechat.hdata_get(hdata_name)
+ if ptr_hdata:
+ hdata2 = []
+ string = weechat.hdata_get_string(ptr_hdata, 'var_keys_values')
+ if string:
+ for item in string.split(','):
+ (key, value) = item.split(':')
+ var_type = int(value) >> 16
+ var_offset = int(value) & 0xFFFF
+ var_hdata = weechat.hdata_get_var_hdata(ptr_hdata, key)
+ if var_hdata:
+ var_hdata = ', hdata: \'%s\'' % var_hdata
+ hdata2.append({'offset': var_offset,
+ 'text': '\'%s\' (%s%s)' % (key,
+ weechat.hdata_get_var_type_string(ptr_hdata, key),
+ var_hdata)})
+ hdata2 = sorted(hdata2, key=itemgetter('offset'))
+ for item in hdata2:
+ if variables:
+ variables += ' +\n'
+ variables += ' %s' % item['text']
+ hdata[plugin][hdata_name]['vars'] = '\n%s' % variables
+
+ string = weechat.hdata_get_string(ptr_hdata, 'list_keys')
+ if string:
+ for item in sorted(string.split(',')):
+ if lists:
+ lists += ' +\n'
+ lists += ' \'%s\'' % item
+ lists = '\n%s' % lists
+ else:
+ lists = '\n -'
+ hdata[plugin][hdata_name]['lists'] = lists
+ weechat.infolist_free(infolist)
+ return hdata
+
+def get_completions():
+ """Get list of completions hooked by plugins in a dict with 3 indexes: plugin, item, xxx."""
+ global ignore_completions_items
+ completions = defaultdict(lambda: defaultdict(defaultdict))
+ infolist = weechat.infolist_get('hook', '', 'completion')
+ while weechat.infolist_next(infolist):
+ completion_item = weechat.infolist_string(infolist, 'completion_item')
+ if not re.search('|'.join(ignore_completions_items), completion_item):
+ plugin = weechat.infolist_string(infolist, 'plugin_name') or 'weechat'
+ completions[plugin][completion_item]['description'] = weechat.infolist_string(infolist, 'description')
+ weechat.infolist_free(infolist)
+ return completions
+
+def update_file(oldfile, newfile, num_files, num_files_updated, obj):
+ """Update a doc file."""
+ shaold = hashlib.sha224(open(oldfile, 'r').read()).hexdigest()
+ shanew = hashlib.sha224(open(newfile, 'r').read()).hexdigest()
+ if shaold != shanew:
+ os.unlink(oldfile)
+ os.rename(newfile, oldfile)
+ num_files_updated['total1'] += 1
+ num_files_updated['total2'] += 1
+ num_files_updated[obj] += 1
+ else:
+ os.unlink(newfile)
+ num_files['total1'] += 1
+ num_files['total2'] += 1
+ num_files[obj] += 1
+
+def docgen_cmd_cb(data, buffer, args):
+ """Callback for /docgen command."""
+ global locale_list
+ if args:
+ locales = args.split(' ')
+ else:
+ locales = locale_list
+ commands = get_commands()
+ options = get_options()
+ infos = get_infos()
+ infos_hashtable = get_infos_hashtable()
+ infolists = get_infolists()
+ hdata = get_hdata()
+ completions = get_completions()
+
+ # get path and replace ~ by home if needed
+ path = weechat.config_get_plugin('path')
+ if path.startswith('~'):
+ path = '%s%s' % (os.environ['HOME'], path[1:])
+
+ # write to doc files, by locale
+ num_files = defaultdict(int)
+ num_files_updated = defaultdict(int)
+
+ translate = lambda s: (s and _(s)) or s
+ escape = lambda s: s.replace('|', '\\|')
+
+ for locale in locales:
+ for key in num_files:
+ if key != 'total2':
+ num_files[key] = 0
+ num_files_updated[key] = 0
+ t = gettext.translation('weechat', weechat.info_get('weechat_localedir', ''),
+ languages=['%s.UTF-8' % locale], fallback=True)
+ t.install()
+ directory = '%s/%s/autogen' % (path, locale[0:2])
+ if not os.path.isdir(directory):
+ weechat.prnt('', '%sdocgen error: directory "%s" does not exist' % (weechat.prefix('error'),
+ directory))
+ continue
+ # write commands
+ for plugin in commands:
+ filename = '%s/user/%s_commands.txt' % (directory, plugin)
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ for command in sorted(commands[plugin]):
+ args = translate(commands[plugin][command]['args'])
+ args_formats = args.split(' || ')
+ description = translate(commands[plugin][command]['description'])
+ args_description = translate(commands[plugin][command]['args_description'])
+ f.write('[command]*`%s`* %s::\n' % (command, description))
+ f.write('........................................\n')
+ prefix = '/%s ' % command
+ if args_formats != ['']:
+ for fmt in args_formats:
+ f.write('%s%s\n' % (prefix, fmt))
+ prefix = ' ' * len(prefix)
+ if args_description:
+ f.write('\n')
+ for line in args_description.split('\n'):
+ f.write('%s\n' % line)
+ f.write('........................................\n\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'commands')
+
+ # write config options
+ for config in options:
+ filename = '%s/user/%s_options.txt' % (directory, config)
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ for section in sorted(options[config]):
+ for option in sorted(options[config][section]):
+ opt_type = options[config][section][option]['type']
+ string_values = options[config][section][option]['string_values']
+ default_value = options[config][section][option]['default_value']
+ opt_min = options[config][section][option]['min']
+ opt_max = options[config][section][option]['max']
+ null_value_allowed = options[config][section][option]['null_value_allowed']
+ description = translate(options[config][section][option]['description'])
+ type_nls = translate(opt_type)
+ values = ''
+ if opt_type == 'boolean':
+ values = 'on, off'
+ elif opt_type == 'integer':
+ if string_values:
+ values = string_values.replace('|', ', ')
+ else:
+ values = '%d .. %d' % (opt_min, opt_max)
+ elif opt_type == 'string':
+ if opt_max <= 0:
+ values = _('any string')
+ elif opt_max == 1:
+ values = _('any char')
+ elif opt_max > 1:
+ values = '%s (%s: %d)' % (_('any string'),
+ _('max chars'),
+ opt_max)
+ else:
+ values = _('any string')
+ default_value = '"%s"' % default_value.replace('"', '\\"')
+ elif opt_type == 'color':
+ values = _('a WeeChat color name (default, black, '
+ '(dark)gray, white, (light)red, (light)green, '
+ 'brown, yellow, (light)blue, (light)magenta, '
+ '(light)cyan), a terminal color number or '
+ 'an alias; attributes are allowed before '
+ 'color (for text color only, not '
+ 'background): \"*\" for bold, \"!\" for '
+ 'reverse, \"_\" for underline')
+ f.write('* *%s.%s.%s*\n' % (config, section, option))
+ f.write('** %s: `%s`\n' % (_('description'), description))
+ f.write('** %s: %s\n' % (_('type'), type_nls))
+ f.write('** %s: %s (%s: `%s`)\n' % (_('values'), values,
+ _('default value'), default_value))
+ if null_value_allowed:
+ f.write('** %s\n' % _('undefined value allowed (null)'))
+ f.write('\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'options')
+
+ # write infos hooked
+ filename = '%s/plugin_api/infos.txt' % directory
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ f.write('[width="100%",cols="^1,^2,6,6",options="header"]\n')
+ f.write('|========================================\n')
+ f.write('| %s | %s | %s | %s\n\n' % (_('Plugin'), _('Name'), _('Description'), _('Arguments')))
+ for plugin in sorted(infos):
+ for info in sorted(infos[plugin]):
+ description = translate(infos[plugin][info]['description'])
+ args_description = translate(infos[plugin][info]['args_description']) or '-'
+ f.write('| %s | %s | %s | %s\n\n' % (escape(plugin),
+ escape(info),
+ escape(description),
+ escape(args_description)))
+ f.write('|========================================\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'infos')
+
+ # write infos (hashtable) hooked
+ filename = '%s/plugin_api/infos_hashtable.txt' % directory
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ f.write('[width="100%",cols="^1,^2,6,6,6",options="header"]\n')
+ f.write('|========================================\n')
+ f.write('| %s | %s | %s | %s | %s\n\n' % (_('Plugin'), _('Name'), _('Description'),
+ _('Hashtable (input)'), _('Hashtable (output)')))
+ for plugin in sorted(infos_hashtable):
+ for info in sorted(infos_hashtable[plugin]):
+ description = translate(infos_hashtable[plugin][info]['description'])
+ args_description = translate(infos_hashtable[plugin][info]['args_description'])
+ output_description = translate(infos_hashtable[plugin][info]['output_description']) or '-'
+ f.write('| %s | %s | %s | %s | %s\n\n' % (escape(plugin),
+ escape(info),
+ escape(description),
+ escape(args_description),
+ escape(output_description)))
+ f.write('|========================================\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'infos_hashtable')
+
+ # write infolists hooked
+ filename = '%s/plugin_api/infolists.txt' % directory
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ f.write('[width="100%",cols="^1,^2,5,5,5",options="header"]\n')
+ f.write('|========================================\n')
+ f.write('| %s | %s | %s | %s | %s\n\n' % (_('Plugin'), _('Name'), _('Description'),
+ _('Pointer'), _('Arguments')))
+ for plugin in sorted(infolists):
+ for infolist in sorted(infolists[plugin]):
+ description = translate(infolists[plugin][infolist]['description'])
+ pointer_description = translate(infolists[plugin][infolist]['pointer_description']) or '-'
+ args_description = translate(infolists[plugin][infolist]['args_description']) or '-'
+ f.write('| %s | %s | %s | %s | %s\n\n' % (escape(plugin),
+ escape(infolist),
+ escape(description),
+ escape(pointer_description),
+ escape(args_description)))
+ f.write('|========================================\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'infolists')
+
+ # write hdata hooked
+ filename = '%s/plugin_api/hdata.txt' % directory
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ f.write('[width="100%",cols="^1,^2,5,5,5",options="header"]\n')
+ f.write('|========================================\n')
+ f.write('| %s | %s | %s | %s | %s\n\n' % (_('Plugin'), _('Name'), _('Description'),
+ _('Variables'), _('Lists')))
+ for plugin in sorted(hdata):
+ for hdata_name in sorted(hdata[plugin]):
+ description = translate(hdata[plugin][hdata_name]['description'])
+ variables = hdata[plugin][hdata_name]['vars']
+ lists = hdata[plugin][hdata_name]['lists']
+ f.write('| %s | %s | %s |%s |%s\n\n' % (escape(plugin),
+ escape(hdata_name),
+ escape(description),
+ escape(variables),
+ escape(lists)))
+ f.write('|========================================\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'hdata')
+
+ # write completions hooked
+ filename = '%s/plugin_api/completions.txt' % directory
+ tmpfilename = '%s.tmp' % filename
+ f = open(tmpfilename, 'w')
+ f.write('[width="65%",cols="^1,^2,8",options="header"]\n')
+ f.write('|========================================\n')
+ f.write('| %s | %s | %s\n\n' % (_('Plugin'), _('Name'), _('Description')))
+ for plugin in sorted(completions):
+ for completion_item in sorted(completions[plugin]):
+ description = translate(completions[plugin][completion_item]['description'])
+ f.write('| %s | %s | %s\n\n' % (escape(plugin),
+ escape(completion_item),
+ escape(description)))
+ f.write('|========================================\n')
+ f.close()
+ update_file(filename, tmpfilename, num_files, num_files_updated, 'completions')
+
+ # write counters
+ weechat.prnt('',
+ 'docgen: %s: %3d files (%2d cmd, %2d opt, %2d infos, '
+ '%2d infos_hash, %2d infolists, %2d hdata, %2d complt)'
+ % (locale, num_files['total1'],
+ num_files['commands'], num_files['options'],
+ num_files['infos'], num_files['infos_hashtable'],
+ num_files['infolists'], num_files['hdata'],
+ num_files['completions']))
+ weechat.prnt('',
+ ' %3d updated (%2d cmd, %2d opt, %2d infos, '
+ '%2d infos_hash, %2d infolists, %2d hdata, %2d complt)'
+ % (num_files_updated['total1'], num_files_updated['commands'],
+ num_files_updated['options'], num_files_updated['infos'],
+ num_files_updated['infos_hashtable'], num_files_updated['infolists'],
+ num_files_updated['hdata'], num_files_updated['completions']))
+ weechat.prnt('',
+ 'docgen: total: %d files, %d updated' % (num_files['total2'], num_files_updated['total2']))
+ return weechat.WEECHAT_RC_OK
+
+def docgen_completion_cb(data, completion_item, buffer, completion):
+ """Callback for completion."""
+ global locale_list
+ for locale in locale_list:
+ weechat.hook_completion_list_add(completion, locale, 0, weechat.WEECHAT_LIST_POS_SORT)
+ return weechat.WEECHAT_RC_OK
+
+if __name__ == '__main__' and import_ok:
+ if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
+ SCRIPT_DESC, '', ''):
+ weechat.hook_command(SCRIPT_COMMAND,
+ 'Documentation generator.',
+ '[locales]',
+ 'locales: list of locales to build (by default build all locales)',
+ '%(docgen_locales)|%*',
+ 'docgen_cmd_cb', '')
+ weechat.hook_completion('docgen_locales', 'locales for docgen', 'docgen_completion_cb', '')
+ if not weechat.config_is_set_plugin('path'):
+ weechat.config_set_plugin('path', DEFAULT_PATH)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a3d2137cb..0cde426c7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -254,4 +254,4 @@
./src/plugins/xfer/xfer-network.h
./src/plugins/xfer/xfer-upgrade.c
./src/plugins/xfer/xfer-upgrade.h
-./doc/docgen.pl
+./doc/docgen.py
diff --git a/po/srcfiles.cmake b/po/srcfiles.cmake
index a80424fa1..6d5be3fe9 100644
--- a/po/srcfiles.cmake
+++ b/po/srcfiles.cmake
@@ -255,5 +255,5 @@ SET(WEECHAT_SOURCES
./src/plugins/xfer/xfer-network.h
./src/plugins/xfer/xfer-upgrade.c
./src/plugins/xfer/xfer-upgrade.h
-./doc/docgen.pl
+./doc/docgen.py
)