Seems the move of the wiki grabber didn't delete the original.

This commit is contained in:
Mark de Wever 2008-04-24 17:54:14 +00:00
parent 2ca2486a65
commit 584df8c958
3 changed files with 261 additions and 389 deletions

View file

@ -1,254 +0,0 @@
#!/usr/bin/env python
# vim: tabstop=4: shiftwidth=4: expandtab: softtabstop=4: autoindent:
# $Id$
"""
Copyright (C) 2007 by Mark de Wever <koraq@xs4all.nl>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
"""
import operator, os, re
if __name__ == "__main__":
# contains all output generated:
# - key filename
# - value node list
#
# every node is a list with 2 items
# - first the sorting order
# - second the actual data
file_map = {}
# default directory to dump the output in with trailing /.
output_directory = "/tmp/"
# default directory to find the source files in, no trailing /.
src_directory = "../../src/gui"
def reindent( data):
"""Converts the raw input to an easier to use format.
Lines starting with 8 spaces are concatenated with the previous line.
The start of line ' *' are removed and if another space exists it's also
removed."""
# concatenate
data = re.sub(r'\n \*(?: ){8,}', " ", data)
# strip
data = re.sub(" \*(?: |)", "", data)
return data
def get_value(data, key):
"""Extracts data from a key value pair, a key must start at the start of a line."""
key1 = "^" + key
sep = "(?: )*=(?: )"
value = "(.*)$"
res = re.compile("^" + key + " *= *(.*)$", re.M).search(data)
if(res != None):
res = res.group(1)
return res
def process_header(data):
"""Processes the header."""
page = get_value(data, "@page")
order = get_value(data, "@order")
if(order == None):
order = 10000
return [page, order]
def create_config_table(data):
"""Creates a table for data in a config table.
A config table is a table with info about WML configuration key value pairs.
"""
# matches a line like
# x1 (f_unsigned = 0) The x coordinate of the startpoint.
# x1 (f_unsigned) The x coordinate of the startpoint.
variable = "(?:[a-z]|[A-Z])(?:[a-z]|[A-Z]|[0-9]|_)*"
regex = re.compile(" *(" + variable + ") \((" + variable + ") *(?:(?:= *(.*))|)\) +(.*)\n")
res = regex.findall(data)
# empty table
if(len(res) == 0):
return "Empty table."
result = '{| border="1"'
result += "\n!key\n!type\n!default\n!description\n"
for i in range(len(res)):
result += "|-\n"
result += "|" + res[i][0] + "\n"
result += "|[[GUIVariable#" + res[i][1] + "|" + res[i][1] + "]]\n"
if(res[i][2] == ""):
result += "|mandatory\n"
else:
result += "|" + res[i][2] + "\n"
result += "|" + res[i][3] + "\n"
result += "|}"
return result
def create_formula_table(data):
"""Creates a table for data in a formula table.
A formula table is a table with info about which function parameters
are available for processing in WML formulas.
"""
#matches a line like
#width unsigned The width of the canvas.
variable = "(?:[a-z]|[A-Z])(?:[a-z]|[A-Z]|[0-9]|_)*"
regex = re.compile(" *(" + variable + ") (" + variable + ") +(.*)\n")
res = regex.findall(data)
# empty table
if(len(res) == 0):
return "Empty table."
result = '{| border="1"'
result += "\n!Variable\n!type\n!description\n"
for i in range(len(res)):
result += "|-\n"
result += "|" + res[i][0] + "\n"
result += "|" + res[i][1] + "\n"
result += "|" + res[i][2] + "\n"
result += "|}"
return result
def create_variable_types_table(data):
"""Creates a table for the variable types."""
#matches a line like
# int Signed number (whole numbers).
variable = "(?:[a-z]|[A-Z])(?:[a-z]|[A-Z]|[0-9]|_)*"
regex = re.compile(" *(" + variable + ") +(.*)\n")
res = regex.findall(data)
# empty table
if(len(res) == 0):
return "Empty table."
result = '{| border="1"'
result += "\n!Variable\n!description\n"
for i in range(len(res)):
result += "|-\n"
result += "|<span id=\"" + res[i][0] + "\">" + res[i][0] + "</span>\n"
result += "|" + res[i][1] + "\n"
result += "|}"
return result
def create_table(table) :
"""Wrapper for creating tables."""
type = table.group(1)
if(type == "config"):
return create_config_table(table.group(2))
elif(type == "formula"):
return create_formula_table(table.group(2))
elif(type == "variable_types"):
return create_variable_types_table(table.group(2))
else:
return "unknown table definition '" + type + "'."
def process_body(data):
"""Process the body.
The body needs to be stripped of known markup values.
"""
table_regex = re.compile("^@start_table *= *(.*?)\n(.*?)\n@end_table.*?$", re.M | re.S)
data = table_regex.sub(lambda match: create_table(match), data)
return data
def process(data):
"""Processes a wiki block."""
res = re.compile("(.*?)\n\n(.*)", re.S).findall(data);
if(res != None and len(res) != 0):
header = process_header(res[0][0])
body = process_body(res[0][1])
else:
print "Invalid wiki block, discarded."
return
if(header[0] == None):
print "No page defined, dropped."
return
if(file_map.has_key(header[0]) == False):
file_map[header[0]] = []
file_map[header[0]].append([header[1], body])
def create_output():
"""Generates the output"""
for file, data_list in file_map.iteritems():
data_list.sort(key=operator.itemgetter(0))
fd = open(output_directory + file, "w")
for i in range(len(data_list)):
fd.write(data_list[i][1])
fd.close()
def process_file(name):
"""Processes all wiki blocks (if any) of a file."""
file = open(name, "r")
data = file.read()
file.close()
regex = re.compile("(/\*WIKI($.*?)^ \*/)", re.M | re.S)
res = regex.findall(data)
if(res != None):
for i in range(len(res)):
section = reindent(res[i][1])
wiki_info = process(section)
else:
print "No Wiki block found."
def process_directory(dir):
"""Processes a directory.
Recurses into the sub directory, ignoring hidden directories.
Processes every .cpp file.
"""
items = os.listdir(dir)
for item in items:
# Ignore .svn dirs.
if(item.startswith(".")):
continue
if(os.path.isdir(dir + "/" + item)):
process_directory(dir + "/" + item)
elif(item.endswith(".cpp")):
process_file(dir + "/" + item)
##### ##### ##### MAIN ##### ##### #####
process_directory(src_directory)
create_output()

View file

@ -122,18 +122,55 @@ void load_settings()
const std::string& tgui_definition::read(const config& cfg)
{
/*WIKI
* [gui]
* @page = GUIToolkitWML
* @order = 1
*
* = GUI =
*
* The gui class contains the definitions of all widgets and windows used in
* the game. The standard gui has the id 'default' and used as fallback it
* another gui doesn't define a specific item. NOTE things might look odd when
* that happens.
* the game. This can be seen as a skin and it allows the user to define the
* visual aspect of the various items. The visual aspect can be determined
* depending on the size of the game window.
*
* Widgets have a definition and an instance, the definition contains the
* general info/looks of a widget and the instance the actual looks. Eg the
* where the button text is placed is the same for every button, but the
* text of every button might differ.
*
* The default gui has the id ''default'' and must exist, in the default gui
* there must a definition of every widget with the id ''default'' and every
* window needs to be defined. If the definition of a widget with a certain
* id doesn't exist it will fall back to default in the current gui, if it's
* not defined there either it will fall back to the default widget in the
* default theme. That way it's possible to slowly create your own gui and
* test it.
*
* id = (string = "") Unique id for this gui (theme).
* description = (t_string = "") Unique translatable name for this gui.
* The gui has the following data:
* @start_table = config
* id (string) Unique id for this gui (theme).
* description (t_string) Unique translatable name for this gui.
*
* widget_definitions (section) The defintions of all
* [[#widget_list|widgets]].
* window_definitions (section) The defintions of all
* [[#window_list|windows]].
* @end_table
*
* <span id="widget_list"></span>List of available widgets:
* @start_table = widget_definition
* button_definition A push button.
* label_definition A label.
* text_box_definition A single line text box.
* tooltip_definition A small tooltip with help.
* window_definition A window.
* @end_table
*
* <span id="widget_list"></span>List of available widgets:
* @start_table = window_definition
* addon_connect The dialog to connect to the addon server
* and maintain locally installed addons.
* @end_table
*
* [button_definition] The definitions of the buttons in this gui.
* [/gui]
*/
id = cfg["id"];
description = cfg["description"];
@ -205,13 +242,22 @@ tcontrol_definition::tcontrol_definition(const config& cfg) :
resolutions()
{
/*WIKI
* The general defintion of a control.
* @page = GUIToolkitWML
* @order = 1_widget
*
* id = (string = "") Unique id for this gui (theme).
* description = (t_string = "") Unique translatable name for this gui.
* = Widget defintion =
*
* [resolution] The definitions of the button in various
* Every widget has some parts in common, first of all every definition has the
* following fields.
*
* @start_table = config
* id (string) Unique id for this gui (theme).
* description (t_string) Unique translatable name for this gui.
*
* resolution (section) The definitions of the widget in various
* resolutions.
* @end_table
*
*/
VALIDATE(!id.empty(), missing_mandatory_wml_key("gui", "id"));
@ -219,86 +265,6 @@ tcontrol_definition::tcontrol_definition(const config& cfg) :
}
template<class T>
void tcontrol_definition::load_resolutions(const config::child_list& resolution_list)
{
VALIDATE(!resolution_list.empty(), _("No resolution defined."));
for(std::vector<config*>::const_iterator itor = resolution_list.begin();
itor != resolution_list.end(); ++itor) {
resolutions.push_back(new T(**itor));
}
}
tbutton_definition::tbutton_definition(const config& cfg) :
tcontrol_definition(cfg)
{
/*WIKI
* The definition of a normal push button.
* See control_definition.
*/
DBG_G_P << "Parsing button " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tbutton_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* [button_definition][resolution]
* [state_enabled] Settings for the enabled state.
* [state_disabled] Settings for the disabled state.
* [state_pressed] Settings for the pressed state.
* [state_focussed] Settings for the focussed state (happens
* when the mouse moves over the button).
* [/resolution][/button_definition]
*/
// Note the order should be the same as the enum tstate is button.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
state.push_back(tstate_definition(cfg.child("state_disabled")));
state.push_back(tstate_definition(cfg.child("state_pressed")));
state.push_back(tstate_definition(cfg.child("state_focussed")));
}
tlabel_definition::tlabel_definition(const config& cfg) :
tcontrol_definition(cfg)
{
/*WIKI
* The definition of a normal label.
* See control_definition.
*/
DBG_G_P << "Parsing label " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tstate_definition::tstate_definition(const config* cfg) :
full_redraw(cfg ? utils::string_bool((*cfg)["full_redraw"]) : false),
canvas()
{
/*WIKI
* [state]
* Definition of a state. A state contains the info what to do in a state.
* Atm this is rather focussed on the drawing part, might change later.
* Keys:
* full_redraw (bool = false) Does this state need a full redraw when
* it's being drawn? Normally only required
* if the widget is (partly) transparent.
* [draw] Section with drawing directions for a canvas.
* [/state]
*/
const config* draw = cfg ? cfg->child("draw") : 0;
VALIDATE(draw, _("No state or draw section defined."));
canvas.set_cfg(*draw);
}
tresolution_definition_::tresolution_definition_(const config& cfg) :
window_width(lexical_cast_default<unsigned>(cfg["window_width"])),
window_height(lexical_cast_default<unsigned>(cfg["window_height"])),
@ -315,7 +281,11 @@ tresolution_definition_::tresolution_definition_(const config& cfg) :
state()
{
/*WIKI
* [resolution]
* @page = GUIToolkitWML
* @order = 1_widget
*
* == Resolution ==
*
* Depending on the resolution a widget can look different. Resolutions are
* evaluated in order of appearance. The ''window_width'' and ''window_height''
* are the upper limit this resolution is valid for. When one of the sizes
@ -328,33 +298,36 @@ tresolution_definition_::tresolution_definition_(const config& cfg) :
* the wanted default size and the size needed for the text. The size of the
* text differs per used widget so needs to be determined per button.
*
* window_width = (unsigned = 0) Width of the application window.
* window_height = (unsigned = 0)
* @start_table = config
* window_width (unsigned = 0) Width of the application window.
* window_height (unsigned = 0)
* Height of the application window.
* min_width = (unsigned = 0) The minimum width of the widget.
* min_height = (unsigned = 0) The minimum height of the widget.
* min_width (unsigned = 0) The minimum width of the widget.
* min_height (unsigned = 0) The minimum height of the widget.
*
* default_width = (unsigned = 0)
* The default width of the widget.
* default_height = (unsigned = 0)
* The default height of the widget.
* default_width (unsigned = 0) The default width of the widget.
* default_height (unsigned = 0) The default height of the widget.
*
* max_width = (unsigned = 0) The maximum width of the widget.
* max_height = (unsigned = 0) The maximum height of the widget.
* max_width (unsigned = 0) The maximum width of the widget.
* max_height (unsigned = 0) The maximum height of the widget.
*
* text_extra_width = (unsigned = 0)
* text_extra_width (unsigned = 0)
* The extra width needed to determine the
* minimal size for the text.
* text_extra_height = (unsigned = 0)
* text_extra_height (unsigned = 0)
* The extra height needed to determine the
* minimal size for the text.
* text_font_size = (unsigned) The font size, which needs to be used to
* text_font_size (unsigned) The font size, which needs to be used to
* determine the minimal size for the text.
* text_font_style (font_style = "")
* The font style, which needs to be used to
* determine the minimal size for the text.
*
* [/resolution]
* state (section) Every widget has one or more state sections.
* Note they aren't called state but state_xxx
* the exact names are listed per widget.
* @end_table
*
*/
VALIDATE(text_font_size, missing_mandatory_wml_key("resolution", "text_font_size"));
@ -363,14 +336,119 @@ tresolution_definition_::tresolution_definition_(const config& cfg) :
<< window_width << ", " << window_height << '\n';
}
template<class T>
void tcontrol_definition::load_resolutions(const config::child_list& resolution_list)
{
VALIDATE(!resolution_list.empty(), _("No resolution defined."));
for(std::vector<config*>::const_iterator itor = resolution_list.begin();
itor != resolution_list.end(); ++itor) {
resolutions.push_back(new T(**itor));
}
}
tstate_definition::tstate_definition(const config* cfg) :
full_redraw(cfg ? utils::string_bool((*cfg)["full_redraw"]) : false),
canvas()
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget
*
* == State ==
*
* Definition of a state. A state contains the info what to do in a state.
* Atm this is rather focussed on the drawing part, might change later.
* Keys:
* @start_table = config
* full_redraw (bool = false) Does this state need a full redraw when
* it's being drawn? Normally only required
* if the widget is (partly) transparent.
* draw (section) Section with drawing directions for a canvas.
* @end_table
*
*/
const config* draw = cfg ? cfg->child("draw") : 0;
VALIDATE(draw, _("No state or draw section defined."));
canvas.set_cfg(*draw);
}
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget
*
* = Example =
*
* FIXME add a example here.
*
* = List of widgets =
*
* Below the list of available widgets.
*
*/
tbutton_definition::tbutton_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing button " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tbutton_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget_button
*
* == Button ==
*
* The definition of a normal push button.
*
* The following states exist:
* * state_enabled, the button is enabled.
* * state_disabled, the button is disabled.
* * state_pressed, the left mouse button is down.
* * state_focussed, the mouse is over the button.
*
*/
// Note the order should be the same as the enum tstate is button.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
state.push_back(tstate_definition(cfg.child("state_disabled")));
state.push_back(tstate_definition(cfg.child("state_pressed")));
state.push_back(tstate_definition(cfg.child("state_focussed")));
}
tlabel_definition::tlabel_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing label " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tlabel_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* [label_definition][resolution]
* [state_enabled] Settings for the enabled state.
* [state_disabled] Settings for the disabled state.
* [/resolution][/label_definition]
* @page = GUIToolkitWML
* @order = 1_widget_label
*
* == Label ==
*
* The definition of a normal label.
*
* The following states exist:
* * state_enabled, the label is enabled.
* * state_disabled, the label is disabled.
*
*/
// Note the order should be the same as the enum tstate is label.hpp.
@ -381,11 +459,6 @@ tlabel_definition::tresolution::tresolution(const config& cfg) :
ttext_box_definition::ttext_box_definition(const config& cfg) :
tcontrol_definition(cfg)
{
/*WIKI
* The definition of a normal text box.
* See control_definition.
*/
DBG_G_P << "Parsing text_box " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
@ -393,16 +466,33 @@ ttext_box_definition::ttext_box_definition(const config& cfg) :
ttext_box_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg),
text_x_offset(cfg["text_x_offset"]), //FIXME document
text_y_offset(cfg["text_y_offset"]) //FIXME document
text_x_offset(cfg["text_x_offset"]),
text_y_offset(cfg["text_y_offset"])
{
/*WIKI
* [label_definition][resolution]
* [state_enabled] Settings for the enabled state.
* [state_disabled] Settings for the disabled state.
* [state_focussed] Settings for the focussed state (happens
* when the it captures the keyboard).
* [/resolution][/label_definition]
* @page = GUIToolkitWML
* @order = 1_widget_text_box
*
* == Text box ==
*
* The definition of a text box.
*
* The resolution for a text box also contains the following keys:
* @start_table = config
* text_x_offset (f_unsigned = "") The x offset of the text in the text
* box. This is needed for the code to
* determine where in the text the mouse
* clicks, so it can set the cursor
* properly.
* text_y_offset (f_unsigned = "") The y offset of the text in the text
* box.
* @end_table
*
* The following states exist:
* * state_enabled, the text box is enabled.
* * state_disabled, the text box is disabled.
* * state_focussed, the text box has the focus of the keyboard.
*
*/
// Note the order should be the same as the enum tstate is text_box.hpp.
@ -414,11 +504,6 @@ ttext_box_definition::tresolution::tresolution(const config& cfg) :
ttooltip_definition::ttooltip_definition(const config& cfg) :
tcontrol_definition(cfg)
{
/*WIKI
* The definition of a tooltip.
* See control_definition.
*/
DBG_G_P << "Parsing tooltip " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
@ -428,19 +513,25 @@ ttooltip_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* [label_definition][resolution]
* [state_enabled] Settings for the enabled state.
* [/resolution][/label_definition]
* @page = GUIToolkitWML
* @order = 1_widget_tooltip
*
* == Tooltip ==
*
* The definition of a tooltip.
*
* The following states exist:
* * state_enabled, the tooltip has only one state, it's either shown or hidden.
*
*/
// Note only one state for a tooltip.
state.push_back(tstate_definition(cfg.child("state_enabled")));
}
const std::string& twindow_definition::read(const config& cfg)
{
/*WIKI
/*WIKI (FIXME cleanup)
* [window_definition]
* The definition of a normal push window.
*
@ -482,7 +573,7 @@ twindow_definition::tresolution::tresolution(const config& cfg) :
background(cfg.child("background")),
foreground(cfg.child("foreground"))
{
/*WIKI
/*WIKI (FIXME cleanup)
* [resolution]
* window_width = (unsigned = 0) Width of the application window.
* window_height = (unsigned = 0)

View file

@ -159,6 +159,37 @@ if __name__ == "__main__":
return result
def create_widget_definition_table(data):
"""Creates a table for a widget definition."""
#matches a line like
# button_definition A push button.
variable = "(?:[a-z]|[A-Z])(?:[a-z]|[A-Z]|[0-9]|_)*"
regex = re.compile(" *(" + variable + ") +(.*)\n")
res = regex.findall(data)
# empty table
if(len(res) == 0):
return "Empty table."
result = '{| border="1"'
result += "\n!Section\n!description\n"
for i in range(len(res)):
result += "|-\n"
result += "|" + res[i][0] + "\n"
result += "|" + res[i][1] + "\n"
result += "|}"
return result
def create_window_definition_table(data):
"""Creates a table for a window definition."""
#matches a line like
# addon_connect The dialog to connect to the addon server
# atm we look the same as the widget table
return create_widget_definition_table(data)
def create_table(table) :
"""Wrapper for creating tables."""
@ -170,6 +201,10 @@ if __name__ == "__main__":
return create_formula_table(table.group(2))
elif(type == "variable_types"):
return create_variable_types_table(table.group(2))
elif(type == "widget_definition"):
return create_widget_definition_table(table.group(2))
elif(type == "window_definition"):
return create_window_definition_table(table.group(2))
else:
return "unknown table definition '" + type + "'."