
<!DOCTYPE Article PUBLIC "-//GNOME//DTD DocBook PNG Variant V1.1//EN" [
<!ENTITY version "0.4.0">
]>

<!-- =============Document Header ============================= -->


<article id="development"> <!-- please do not change the id-->

  <artheader> 
    <title>Screem Development Manual</title>
    <copyright>
      <year>2000</year>
      <holder>Matthew Colyer</holder>
    </copyright>   
 <copyright>
      <year>2001</year>
      <holder>David A Knight</holder>
    </copyright>

    <legalnotice id="legalnotice">
     <para>
     	Permission is granted to copy, distribute and/or modify
		   this document under the terms of the <ulink type="help"
			url="gnome-help:fdl"><citetitle>GNU Free Documentation
			License</citetitle></ulink>, Version 1.1 or any later version 
			published by the Free Software Foundation with no Invariant Sections, 
			no Front-Cover Texts, and no Back-Cover Texts.  A copy of the license
			can be found <ulink type="help" url="gnome-help:fdl">here</ulink>.
      </para>
      
      <para>
         Many of the names used by companies to distinguish their products and
			services are claimed as trademarks. Where those names appear in any
			GNOME documentation, and those trademarks are made aware to the members
			of the GNOME Documentation Project, the names have been printed in caps
			or initial caps.
      </para> 
     </legalnotice>  
    <releaseinfo>
		  This is version 0.2 of Screem Development manual.
     </releaseinfo> 
  </artheader>

<!-- =============Document Body ============================= -->

<!-- =============Section:Introduction ============================= -->
  <sect1 id="intro">
      <title>Introduction</title> 

    <para>
      <application>Screem</application> is a program for editing, uploading and managing websites.
      <application>Screem</application> is currently under active development at Sourceforge.
    </para>

    <para>
    	This manual is for developers. It contains information about the architecture of Screem, its coding
    	standards, and how to develop for the main application, plugins, helpers, and scripting.
    </para>

  </sect1>
<!-- =============Section:Contacts============================= --> 
<sect1 id="contact">
	<title>Contacts</title>
	<itemizedlist>
		<listitem>
			<para>
				Main Author / Project Admin:   David A Knight  <email>david@screem.org</email>
			</para>
		</listitem>
		<listitem>
			<para>
				Webmaster: Matthew J Gardner <email>matthew@screem.org</email>
			</para>
		</listitem>
		<listitem>
			<para>
				Screem Mailing List:  <ulink url="http://sourceforge.net/mail/?group_id=142">http://sourceforge.net/mail/?group_id=142</ulink>
			</para>
		</listitem>
	</itemizedlist>
</sect1>
<!-- =============Section:Scripting============================= --> 
<sect1 id="scripting">
	<title>Scripting</title>
	<para>
		Screem supports scripting, via the use of Guile (<ulink url="http://www.gnu.org/software/guile/guile.html">http://www.gnu.org/software/guile/guile.html</ulink>), in a number of ways:
	</para>
	<itemizedlist>
		<listitem>
			<para>
				At load time:
			</para>
			<para>
				Screem will load the scripts when it starts up.  For this to happen a script must provide a script-register
				function of the form:
<screen>
(define (script-register)
	(define author "David A Knight")
	(define callback "(callback)")
	(define label    "Test Script")
	(define menupath "/Test/" )
	
	(screem-script-register author callback label menupath)
)
</screen>
				The callback variable is the name of the function which performs the scripts action when the user
				selects it from the editor popup menu.
			</para>
		</listitem>
		<listitem>
			<para>
				While running via the Guile console:
			</para>
			<para>
				Simple type/load the script into the console and click execute
			</para>
		</listitem>
	</itemizedlist>
	<para>
		For details of which internal Screem functions are available read:
		<itemizedlist>
			<listitem>
				<filename class="headerfile">editor_guile.h</filename>
			</listitem>
			<listitem>
				<filename class="headerfile">page_guile.h</filename>
			</listitem>
			<listitem>
				<filename class="headerfile">site_guile.h</filename>
			</listitem>
		</itemizedlist>
	</para>
</sect1>

<!-- =============Section:plugins============================= --> 
<sect1 id="plugins">
	<title>Plugins</title>
	<para>	
		To aid modularisation of the code Screem supports &quot;plugins&quot;.  These are essentially shared libraries
		which are loaded at runtime, and in general add a toolbar and/or a menuitem from which they can be accessed.
	</para>
	<sect2>
		<title>Plugin Development</title>
	<para>
		Plugins must be coded in C / C++.  If C++ is used then make sure the required functions are wrapped up with:
<screen>
extern &quot;C&quot; {
&lt;code here&gt;
}
</screen>
<para> </para>
		Adding a plugin to screem is very simple.  All a basic plugin needs to provide are 3 functions:
<para> </para>

<screen>
G_MODULE_EXPORT const gchar* g_module_check_init( GModule *module )
{
	g_print("plugin name: check-init\n");   /* just so we know the plugin has been started */
	return NULL;
}
</screen>

<para>	</para>
This first function is called when screem attempts to load the plugin, and currently doesn't do anything other than
output to the terminal that it has been called.
<para>	</para>

<screen>
G_MODULE_EXPORT void g_module_unload( GModule *module )
{
	g_print( "plugin name: unloaded\n" );  /* just so we know the plugin has unloaded */
}
</screen>
	
<para> </para>
This second function is never actually called as Screem currently doesn't support unloading of plugins while running
<para> </para>

<screen>
G_MODULE_EXPORT void init() 
{
	GtkWidget *button;
	GtkWidget *toolbar;

	toolbar = gtk_object_get_data( GTK_OBJECT( app ), "wizardbar" );

	/* place a button on the wizards toolbar */
	button = gnome_pixmap_new_from_xpm_d( IMAGE_XPM );
	gtk_toolbar_append_item( GTK_TOOLBAR( toolbar ), "", _("New Wizard"), "", button , callback, 0 );

	g_print( "plugin name: initialised\n" );
}
</screen>

<para> </para>
The final function is responisble for adding a method of accessing the plugin.  The code above simply adds a button to the
wizards toolbar.  The parameter called &quot;callback&quot; passed to gtk_toolbar_append_item() is the function that will
provide the interface for the plugin when the button is clicked.  This function can do anything you like.
<para> </para>
<para>
All of Screem's functions are available to the plugin.  Please use them rather than rolling your own, this especially applies to inserting text into the editor.
 </para>
	
		</para>
	</sect2>
</sect1>

<!-- =============Section:Helpers============================= --> 
<sect1 id="helpers">
	<title>Helpers</title>
	<para>
		Helpers are small helper applications which are used as filters by Screem.  When executed via the editor popup
		menu the current contents of the editor is piped to the chosen helper, and the output of that helper replaces
		what was there previously.  Currently there is no error checking, so this may result in an empty editor if the
		helper failed to output any data.
	</para>
	<para> </para>
	<para>
		A very simple helper application can be written to perform the same task that the PSGML mode for 
		<application>emacs</application> does with respect to modifying the displayed &quot;Last Updated&quot; time and
		data.  The example is written in <application>Perl</application> but they can be written in any language.
	<para></para>
<screen>
#!/usr/bin/perl

# support for emacs html mode last updated comments
# the &lt;!-- hhmts start --&gt; and the actual date must be on separate lines
# as must the &lt;!-- hhmts end --&gt;
# there must be no other data on these lines for it to work

$t = 0;

while (&lt;STDIN&gt;) {
  if( $t != 1 )
    {
      print;
      if( /&lt;!-- hhmts start --&gt;/ ) 
	{
		print &quot;Last Updated: &quot;;
		print  `date`; 
		$t = 1;
	}
    }

  if( /&lt;!-- hhmts end --&gt;/ )
    {
      print;
      $t = 0;
    }
  
}
</screen>
	<para> </para>
	</para>
</sect1>

<!-- =============Section:Tag Tree============================= --> 
<sect1 id="tagtree">
	<title>Tag Tree</title>
	<para>
		All the code dealing with the tag tree is located in <filename>tagtree.c</filename>  The code contained there
		simply loads the data files and adds nodes to the GtkCTree, and handles the callback when a node is clicked on.
		The callback inserts the data associated with a node, which is either an open element and/or a close element.
		If the data to insert is not markup then the data is set as the open element to insert.
	</para>
	<para>
		Currently the tag tree populates itself from two types of sources:
		<itemizedlist>
			<listitem>
				<para>
					*.tagtree files (mime-type: application/x-screem-tag-tree)
				</para>
			</listitem>	
			<listitem>
				<para>
					<application>bluefish</application> function files
				</para>
			</listitem>
		</itemizedlist>
	</para>
	<sect2 id="tagtree_files">
		<title>application/x-screem-tag-tree</title>
		<para>
			Screem installs a mime-type of application/x-screem-tag-tree for files with the extension tagtree.  The
			files themselves are an XML document with a simple DTD.
		</para>
<screen>

&lt;!ELEMENT TagTree (node)*	--  The root element which must always be present -- &gt;

&lt;!ELEMENT node (node)*		-- An actual item to appear in the tree -- &gt;
&lt;!ATTLIST node
	name	CDATA		#REQUIRED	-- the label to show for the node in the tree --
	open	CDATA		#IMPLIED	-- The open tag to insert when clicked --
	close	CDATA		#IMPLIED	-- The close tag to insert when clicked --
&gt;

</screen>
		<para>
			If a node has subnodes then it should not have open and close attributes.  If a parent node already exists with
			the specified name then child nodes will be added to the existing one, rather than creating a new node.
		</para>
		<para>
			The tag tree files themselves are read from two different locations:
			<itemizedlist>
				<listitem>
					<para>
						The Global files: <filename Class="Directory">$prefix/share/screem</filename>
					</para>
				</listitem>
				<listitem>
					<para>
						User specific files: <filename Class="Directory">~/.screem</filename>
					</para>
				</listitem>
			</itemizedlist>
		</para>
	</sect2>

	<sect2 id="Bluefish_function_files">
		<title>Bluefish Function Files</title>
		<para>
			<application>bluefish</application> is a GTK html editor.  A nice feature it has is the ability to insert
			functions from different groups, such as RXML, PHP and SSI.  Screem can load the data files for these
			functions, and adds them to the tag tree, with a parent node labeled with the group name.
		</para>
	</sect2>

</sect1>

<!-- =============Section:Conventions============================= --> 
<sect1 id="conventions">
	<title>Coding Conventions</title>
	<para>
		In order to try and keep the Screem code base as readable as possible the following style guidelines have been
		set and should be followed when contributing code.
	</para>
	
	<para>
		It should be noted that these do not follow the <ulink url="http://www.gnu.org">GNU</ulink> guidelines, I prefer a little more spacing for readability
		purposes.
	</para>

	<para>
	The following are the intended coding style guidelines for screem,
	I probably haven't stuck to them everywhere though.
	</para>
	<sect2>
		<title>Indentation &amp; Formating</title>
	
	<itemizedlist>
	
	<listitem><para>
		tabs should be 8 characters.
	
	</para></listitem>
		<listitem><para>
		spaces should follow brackets:
<screen>

this_is_a_function( parameter, paramter );

i = array_element[ 3 ];

</screen>
	
	</para></listitem>
		<listitem><para>
		spaces should follow arithmetic symbols / operators:
<screen>

i ++;

i += 3;

</screen>
	
	</para></listitem>
		<listitem><para>
		spaces should follow commas:
<screen>

this_is_a_function( parameter, parameter, parameter, parameter );

</screen>
	
	</para></listitem>
		</itemizedlist>

	</sect2>
	<sect2>
		<title>Naming Conventions</title>

	<itemizedlist>
	<listitem><para>
	words in variable and function names are separated with an underscore:

<screen>

int this_is_a_very_long_variable_name;

void this_is_a_function_name( parameter );

</screen>

	</para></listitem>
	<listitem><para>

	New types, eg structs and enums should begin with a capital letter:
<screen>

struct Type my_struct;

</screen>


	</para></listitem>
	<listitem><para>
	words in type names are separated by starting the new words with a capital
	letter:
<screen>

struct MyTypeName my_struct;

</screen>


	</para></listitem>
	</itemizedlist>

	</sect2>

	<sect2>
		<title>Braces</title>
<itemizedlist>
<listitem>
<para>
function braces are as follows
<screen>

function()
{

}

</screen>
</para>
</listitem>
<listitem>
<para>
block statement braces, and brackets are as follows
<screen>

if( TRUE ) {

} else {

}

while( TRUE ) {

}

</screen>

etc.
</para>
</listitem>
</itemizedlist>

</sect2>

<sect2>
<title>Line length</title>
<itemizedlist>
<listitem>
<para>
lines should be no longer than 80 characters.  If a function call is longer
then break it up as follows
<screen>

function_call_that_wont_fit( parameter, parameter,
			     paramter_that_would_go_over_80_chars )

</screen>
If it can't be broken up try removing the spaces after brakets and commas.
If it still isn't possible put the entire call on one line.
</para>
</listitem>
</itemizedlist>
</sect2>

</sect1>

</article>
