Re: Draft of presentation documentation.

Pedro Szekely ([email protected])
Wed, 14 Jun 1995 08:37:04 PDT

Kurt,

Let me respond to each of your messages in sequence.

> That is quite cool. I take it the program that generated this is a model
> server client?
>
Yes, it is a server client. The source is at the end of this message. It is
one file, and it has to be compiled with the object system files (as in the
demo_idlcpp directory). I will keep modofying it, but at least you can use it
to preview your documentation. I will make a package and Makefile for it
later.

> Are you refering to the 'index' attribute here? I'm not too pleased with
> that either, but it is an artifact of the decision that was made to use
> the names of attributes as variable names in C++. To get around it, maybe
> we could do something like prepend an MM_ or something like that?
>
> Were there any other things you had to change that you didn't like?
>
I had no complaints about the index attribute. I had other bugs, with
init_index being misspelt.

Yes, I think we should pre-pend mm_ on every symbol to avoid conflicts with
other programs. I prefer mm_ to MM_ because it is less overpowering.

We still have the problem of not being able to have attributes with the same
name in different classes. In the presentation mrl I quickly changed some
attributes so they would be unique, but not in a consitent way. I am waiting
to see what the best solution to this problem is. I propose two solutions:

1- Avoid naming attributes with the same name.
2- Prepend the object name to the attribute name.

I don't like either solution much. What do you guys think.

Source of HTML generator
-------------------------------
#include <srv_impl.h>
#include <pres_sym.h>
#include <task_sym.h>
#include <appl_sym.h>
#include <pres_clt.h>
#include <task_clt.h>
#include <appl_clt.h>
#include <pres_srv.h>
#include <task_srv.h>
#include <appl_srv.h>
#include <srv_ext.h>
#include <pool.h>
#ifndef NO_POOL
#include <amulet/amulet.h>
#include <amulet/debugger.h>
#endif
#include <stdlib.h>

// #include <LEDA/string.h>

MM_Object *guide1;
MM_Object *guide2;
MM_Object *button;
MM_Object *button1;

// Probably should go in types.h
//
char * type_names[] = {"Undefined",
"Boolean",
"Octet",
"Char",
"Double",
"Float",
"Long",
"Short",
"String",
"Unsigned_Long",
"Unsigned_Short",
"Collection",
"Enum",
"Expression",
"Object"
};

// Probably should go in types.h
//
char * rule_names[] = {"Rule_None",
"Rule_Role",
"Rule_Like",
"Rule_Both"
};

string substitute_href (string des, string key) {
// Substitute /ob{XXX} by <A HREF="#XXX">XXX</A>
int ob_pos = des.pos(key, 0);
while (ob_pos > -1) {
int close_delim_pos = des.pos("}", ob_pos);
string object = des(ob_pos, close_delim_pos);
string real_object = object.del(key, 0).del("}", 0);
des = des.replace(object,
(string) "<A HREF=\"#" +
real_object +
(string) "\">" +
real_object +
(string) "</A>");
ob_pos = des.pos(key, ob_pos);
}
return des;
}

string substitute_newline (string des) {
int newline_pos = des.pos ("\n\n");
while (newline_pos > -1) {
des = des.replace((string) "\n\n", (string) "\n\n<P>\n");
newline_pos = des.pos ("\n\n", newline_pos + 7);
}
return des;
}

string substitute_markup (string des) {

// Substitute /em{XXX} by <EM>XXX</EM>
int em_pos = des.pos("/em", 0);

while (em_pos > -1) {
int close_delim_pos = des.pos("}", em_pos);
string emphasize = des(em_pos, close_delim_pos);
des = des.replace(emphasize,
(string) "<EM>" +
emphasize.del("/em{", 0).del("}", 0) +
(string) "</EM>");
em_pos = des.pos("/em", em_pos);
}

// Substitute /ob{XXX} by <A HREF="#XXX">XXX</A>
des = substitute_href (des, (string) "/ob{");

// Substitute /at{XXX} by <A HREF="#XXX">XXX</A>
des = substitute_href (des, (string) "/at{");

// Substitute /enum{XXX} by <A HREF="#XXX">XXX</A>
des = substitute_href (des, (string) "/enum{");

des = substitute_newline (des);

return des;
}

//
// Generate HTML for an attribute.
//
void attr_generate_html (MM_Model_Server* server, MM_Attribute_Def& ai)
{
cout
<< endl << endl
<< "<DT><B>"
<< "<A NAME=\"" << ai.name () << "\">" << ai.name () << "</A>"
<< "</B>" << endl;

cout
<< "<DD><I>type: </I>" << type_names[ai.type ()];

if (ai.type () == MM_Type_Object) {
MM_Object_Def * type_def = server->get_object_def(ai.object_type ());
cout
<< "[<A HREF=\"#" << type_def->name () << "\">"
<< type_def->name () << "</A>]";
};

if (ai.type () == MM_Type_Enum) {
char * enum_name = "Fake String";
// szekely: to do.
// server->get_enum_string(ai.object_type ());
cout
<< "[<A HREF=\"#" << enum_name << "\">" << enum_name<< "</A>]";
};

if (ai.is_multi_value ()) {
cout
<< ", <EM>multi valued </EM>";
};

if (ai.is_part ()) {
cout
<< ", <EM>part </EM>";
};

if (ai.inheritance () != MM_Rule_None)
cout
<< ", <EM>" << rule_names[ai.inheritance ()] << "</EM>";

if (strcmp (ai.description (), "")) {
cout
<< "<DD>" << substitute_markup ((const char *)ai.description ()) << endl;
};
}

//
// Generate HTML for an object.
//
void ob_generate_html (MM_Model_Server* server, MM_Object_Def* oi)
{
cout
<< endl
<< "<H2> <A NAME=\"" << oi->name () << "\"> <EM>Object</EM> "
<< oi->name () << "</A></H2>" << endl;

cout
<< substitute_markup ((const char *)oi->description ()) << endl;

cout
<< "<H3>Attributes</H3>" << endl;

cout
<< "<P>" << endl << "<DL>" << endl;

for (int i = 0; i < oi->num_attributes(); i++) {
attr_generate_html (server, oi->attributes()[i]);
};

cout
<< "</DL>" << endl << "<HR>" << endl << endl;
}

void generate_object_index_html (MM_Model_Server* server)
{
cout
<< "<H1>Object Index</H1>" << endl << "<UL>" << endl;

for (int i = 0; i < server->get_num_object_defs (); i++) {
MM_Object_Def* oi = server->get_object_def (i);
cout
<< endl << "<LI> <A HREF=\"#" << oi->name() << "\">"
<< oi->name() << "</A>";
};

cout
<< "</UL>" << endl << "<HR>" << endl;
}

void generate_all_object_html (MM_Model_Server* server)
{
for (int i = 0; i < server->get_num_object_defs (); i++) {
MM_Object_Def* oi = server->get_object_def (i);
ob_generate_html (server, oi);
};
}

int main ()
{

#ifndef NO_POOL
Am_Initialize ();
#endif

//----------------------------------------------------------------------
// Creating Definitions - the "Server"
//----------------------------------------------------------------------

// out << "\n\n ##### #####\n";
// out << " ##### Creating Definitions - the \"Server\" #####\n";
// out << " ##### #####\n\n\n";

MM_Model_Server_Internal* server = new MM_Model_Server_Internal
("Model-Server");

pres_srv_init (server);
task_srv_init (server);
appl_srv_init (server);

// server->print_def (Presentation);

// Obsolete for the C++ version.
CORBA::BOA::impl_is_ready ();


//----------------------------------------------------------------------
// Creating Objects - the "Client"
//----------------------------------------------------------------------

// out << "\n\n ##### #####\n";
// out << " ##### Creating Objects - the \"Client\" #####\n";
// out << " ##### #####\n\n\n";

// Obsolete for the C++ version. You can use "server" from above.
MM_Model_Server* s = MM_Model_Server::_bind ("Model-Server");
if (s == NULL) {
out << "Bind to Model Server failed!\n";
exit (1);
}

pres_clt_init (s);
task_clt_init (s);
appl_clt_init (s);

generate_object_index_html (s);
generate_all_object_html (s);

return 0;
}