diff options
author | Sebastien Helleu <flashcode@flashtux.org> | 2011-07-03 15:47:50 +0200 |
---|---|---|
committer | Sebastien Helleu <flashcode@flashtux.org> | 2011-07-03 15:47:50 +0200 |
commit | 5250b68d0a1d9871b9d89ff1253290372a747cf6 (patch) | |
tree | dece3a33776db56c8b878a3832f7ca5e0cae9ca4 | |
parent | 0f5b4dbecbbcc413edbda5d0c3decefaf03683d2 (diff) | |
download | weechat-5250b68d0a1d9871b9d89ff1253290372a747cf6.zip |
doc: convert script docgen.pl to docgen.py
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | doc/docgen.pl | 892 | ||||
-rw-r--r-- | doc/docgen.py | 528 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | po/srcfiles.cmake | 2 |
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 ) |