## Screem Development Manual

2000
Matthew Colyer
2001
David A Knight

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, 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 here.

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.

This is version 0.2 of Screem Development manual.

## Introduction

Screem is a program for editing, uploading and managing websites. Screem is currently under active development at Sourceforge.

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.

## Contacts

- Main Author / Project Admin: David A Knight david@screem.org

- Webmaster: Matthew J Gardner matthew@screem.org

- Screem Mailing List: http://sourceforge.net/mail/?group_id=142

## Scripting

Screem supports scripting, via the use of Guile (http://www.gnu.org/software/guile/guile.html), in a number of ways:

- At load time:

  Screem will load the scripts when it starts up. For this to happen a script must provide a script-register function of the form:

      (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)
      )

  The callback variable is the name of the function which performs the scripts action when the user selects it from the editor popup menu.

- While running via the Guile console:

  Simple type/load the script into the console and click execute

For details of which internal Screem functions are available read:

- `editor_guile.h`
- `page_guile.h`
- `site_guile.h`

## Plugins

To aid modularisation of the code Screem supports "plugins". 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.

### Plugin Development

Plugins must be coded in C / C++. If C++ is used then make sure the required functions are wrapped up with:

    extern "C" {
    <code here>
    }

Adding a plugin to screem is very simple. All a basic plugin needs to provide are 3 functions:

    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;
    }

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.

    G_MODULE_EXPORT void g_module_unload( GModule *module )
    {
    	g_print( "plugin name: unloaded\n" );  /* just so we know the plugin has unloaded */
    }

This second function is never actually called as Screem currently doesn't support unloading of plugins while running

    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" );
    }

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 "callback" 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.

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.

## Helpers

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.

A very simple helper application can be written to perform the same task that the PSGML mode for emacs does with respect to modifying the displayed "Last Updated" time and data. The example is written in Perl but they can be written in any language.

    #!/usr/bin/perl

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

    $t = 0;

    while (<STDIN>) {
      if( $t != 1 )
        {
          print;
          if( /<!-- hhmts start -->/ )
    	{
    		print "Last Updated: ";
    		print  `date`;
    		$t = 1;
    	}
        }

      if( /<!-- hhmts end -->/ )
        {
          print;
          $t = 0;
        }

    }

## Tag Tree

All the code dealing with the tag tree is located in `tagtree.c` 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.

Currently the tag tree populates itself from two types of sources:

- *.tagtree files (mime-type: application/x-screem-tag-tree)

- bluefish function files

### application/x-screem-tag-tree

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.

    <!ELEMENT TagTree (node)*	--  The root element which must always be present -- >

    <!ELEMENT node (node)*		-- An actual item to appear in the tree -- >
    <!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 --
    >

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.

The tag tree files themselves are read from two different locations:

- The Global files: `$prefix/share/screem`

- User specific files: `~/.screem`

### Bluefish Function Files

bluefish 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.

## Coding Conventions

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.

It should be noted that these do not follow the GNU guidelines, I prefer a little more spacing for readability purposes.

The following are the intended coding style guidelines for screem, I probably haven't stuck to them everywhere though.

### Indentation & Formating

- tabs should be 8 characters.

- spaces should follow brackets:

      this_is_a_function( parameter, paramter );

      i = array_element[ 3 ];

- spaces should follow arithmetic symbols / operators:

      i ++;

      i += 3;

- spaces should follow commas:

      this_is_a_function( parameter, parameter, parameter, parameter );

### Naming Conventions

- words in variable and function names are separated with an underscore:

      int this_is_a_very_long_variable_name;

      void this_is_a_function_name( parameter );

- New types, eg structs and enums should begin with a capital letter:

      struct Type my_struct;

- words in type names are separated by starting the new words with a capital letter:

      struct MyTypeName my_struct;

### Braces

- function braces are as follows

      function()
      {

      }

- block statement braces, and brackets are as follows

      if( TRUE ) {

      } else {

      }

      while( TRUE ) {

      }

  etc.

### Line length

- lines should be no longer than 80 characters. If a function call is longer then break it up as follows

      function_call_that_wont_fit( parameter, parameter,
      			     paramter_that_would_go_over_80_chars )

  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.