.t Atividade de Laboratrio no. 10
.p MC 202 EF - Segundo semestre de 2008
.p Gerao de Pgina HTML
.s Descrio do Problema
Ao se desenvolver uma aplicao disponibilizada aos usurios atravs da web, normalmente se depara com o problema de
 construir pginas HTML cujo contedo  definido dinmicamente pela aplicao. Essas pginas so chamadas pginas de 
contedo dinmico ou simplesmente 'pginas dinmicas'. Diversas solues tm sido usadas para o problema, sendo que as mais usadas 
se baseiam em combinar texto HTML com a linguagem de programao usada. Esse  o caso de solues como JSP e ASP 
(JSP mistura HTML com Java e ASP mistura HTML com VisualBasic).
.n
Essas solues, embora produzam resultados rpidos, levam  construo de um software difcil de ser mantido uma vez que 
tendem a misturar a lgica da aplicao com a apresentao. Isso vai contra as prticas modernas de engenharia de 
software, que propem justamente a organizao da arquitetura em camadas, onde 'lgica de negcios' e 'apresentao' 
tipicamente so colocadas em camadas distintas.
.n
Uma alternativa  a usar uma estrutura de dados que represente a 'pgina dinmica' sendo construda e que  
modificada pela aplicao atravs de funes especficas. Uma vez que essa estrutura esteja representando a pgina 
na sua forma final, ela  percorrida para que a pgina seja efetivamente gerada (a pgina HTML gerada nada mais  que 
um arquivo texto).
.s Uma pgina HTML
Uma pgina HTML  formada por elementos delimitados por marcadores (etiquetas ou, em ingles, tags), da forma
.c
		&lt;marcador&gt; ... contedo ... &lt;/marcador&gt;
.n
	Os marcadores so indicaes para o navegador sobre a forma pela qual o contedo deve ser apresentado. 
A linguagem HTML define um conjunto de marcadores, cada um com um significado especfico.  
.n
O contedo de um marcador  uma seqncia de elementos que podem ser

.i texto
.i comentrio
.i marcador(tag)
.n
Um exemplo simples de pgina HTML:
.c
&lt;HTML&gt;
  &lt;HEAD&gt;
     &lt;TITLE&gt;
        Exemplo de Pgina HTML
     &lt;/TITLE&gt;
  &lt;/HEAD&gt;
  &lt;BODY&gt;
     Este  apenas um exemplo de pgina 
     HTML muito simples. Experimente copi-lo num
     arquivo "exemplo1.html" e abri-lo num
     navegador para ver o efeito.
  &lt;/BODY&gt;
&lt;/HTML&gt;
.n
Neste exemplo so usados os principais elementos de uma pgina HTML:
.i descrio da pgina:
  delimitada pelos marcadores &lt;HTML&gt; e &lt;/HTML&gt;
.i cabealho:
   a pgina contm um cabealho delimitado por &lt;HEAD&gt; e &lt;/HEAD&gt;  
e um 'corpo' delimitado por &lt;BODY&gt; e &lt;/BODY&gt;
.i 'corpo da pgina':
   deve conter a parte da pgina que ser apresentada na tela principal do navegador. 
Neste caso, ele contm apenas um texto.
.i ttulo:
   o cabealho contm o ttulo da pgina, delimitado por &lt;TITLE&gt; e &lt;/TITLE&gt;.  
Na apresentao da pgina pelo navegador, esse ttulo ser apresentado na barra superior da tela do navegador.
.i formatao: 
   a formatao do texto da pgina  irrelevante na apresentao da pgina. 
Indentao, fins de linha, espaos em branco, so ignorados pelo navegador, que  usa apenas os marcadores como orientao para apresentar a pgina.
.i marcadores fechados e abertos:
  alguns marcadores, como por exemplo &lt;BR&gt;,  no tm o marcador de fechamento correspondente 
(nesse caso, &lt;/BR&gt;).
.i atributos:
   um marcador pode ainda ter um conjunto de atributos, como por exemplo 
.c
 &lt;FONT  name=arial size=24 colour=black &gt;
.n
Se voc no estiver familiarizado com HTML, muitos tutoriais esto disponveis na rede, como por exemplo
.n
.h http://www.icmc.usp.br/ensino/material/html/basico.html
.n
.h http://members.tripod.com/~shibolete/Passo1.html
.n
.h http://www.w3schools.com/html/default.asp
.s Representao de uma pgina 
Considerando a estrutura de uma pgina HTML, a representao natural para a mesma seria uma rvore geral: cada 'elemento' 
da pgina pode ter vrios filhos, dos cada um pode ser uma tag. 
No caso de ser uma tag,  ele pode ter vrios filhos, cada um por sua vez podendo ser uma tag. 
Nessa linha a pgina do exemplo acima poderia ser representada de forma simplificada por uma rvore como mostrada abaixo:
.f image002.gif
.s A rvore
Conforme explicado acima, cada n da rvore ir representar um 'elemento' da pgina que pode ser
.i um texto 
.i um comentrio
.i um marcador

Uma possvel representao para um n da rvore seria a seguinte:
.c
/* tipos possveis para um n da rvore */
typedef enum {TEXT, COMMENT, TAG } NodeType;

/* apontador para um n da rvore */
typedef struct HTMLNode *NodePtr;

/* estrutura para cada n da rvore */
typedef struct HTMLNode {
            		  NodeType type;         /* tipo do n               */
                          HTMLContent content;   /* contedo do n           */
                          NodePtr next;          /* apontador para o prximo */
                        } HTMLNode;

.n
O campo type ser usado para indicar o tipo do n. O campo content pode ser uma estrutura com partes variantes (union), 
definida como a seguir:
.c
/* descrio de uma tag */
typedef struct { 
                 char *name;         /* nome da tag */
                 int  closed;        /* 0 = 'aberta',  1 = 'fechada' */
                 AttribPtr attrList; /* lista de atributos */
                 NodePtr childList;  /* lista de 'filhos'
               } TagType;
                 
               
typedef union { 
                char *text;         /* texto         */
                char *comment;      /* comentario    */
                TagType tag;        /* tag           */
              } DadosComplem;

.n
	A lista de atributos pode ser descrita por ns do seguinte tipo:
.c
typedef struct AttrType *AttrPtr;
typedef struct { 
                 char *name;  /* nome do atributo  */
                 char *value; /* valor do atributo */
               } AttrType;
.s Localizao das tags
A construo da pgina HTML baseada numa estrutura que a representa vai exigir que se localize as  partes da pgina. 
Felizmente HTML tem um recurso que pode ajudar nesse caso: o atributo 'id', que
no interfere na apresentao da pgina pelo navegador.  
Esse atributo pode ser usado para localizar os elementos da pgina aos quais se deseja agregar novos elementos dinamicamente.
 Para isso,  necessrio que cada tag tenha uma identificao nica. 
Uma vez que as tags tenham essa identificao, a sua localizao pode ser feita por meio de um mecanismo de busca como por 
exemplo rvore de busca ou tabela de 'hashing'.  
Nesta atividade, dever ser usada uma tabela de hashing. 
A tabela de hashing far referncias aos ns da rvore que representa a pgina, conforme mostrado na figura abaixo.
.n
.f image004.gif
.n
As definies necessrias ao uso de hashing so as seguintes:
.c
/* apontador para um n da tabela de hashing */
typedef struct HashNode *HashNodePtr;

/* n da tabela de hashing */
typedef struct HashNode {
                          char *key;           /* chave de busca      */
                          void *valueptr;      /* valor associado     */
                          HashNodePtr next;    /* apontado p/ prximo */
                        } HashNode;

/* tamanho da tabela de hashing */
#define HASHSIZE 128        

/* inicia uma tabela de hashing */
void initHashTable(HashTable);      

/* tipo da tabela de hashing */         
typedef HashNodePtr HashTable[HASHSIZE]; 

/* insere (chave,valor) numa tabela de hashing */
void hashInsert(char*, void*, HashTable);


/* busca pelo valor associado a uma chave */
void *hashSearch(char *, HashTable);

.s A atividade
Para esta atividade de laboratrio j esto definidos
.i 'htmlib.h':
arquivo contendo as definies dos tipos de dados a serem usados e os cabealhos das funes para manipular a 
representao da pgina que voc deve  implementar.
.i 'hashlib.h':
arquivo contendo as definies dos tipos de dados e os cabealhos das funes para operar com a tabela de hashing,
que devem ser implementadas em 'hashlib.c'.
.i 'exemplo1.c' e 'exemplo2.c':
'programas de aplicao' exemplo, que fazem uso das funes definidas em 'htmlib.h', e que voc dever implementar, 
para gerar pginas HTML.
.n
A sua tarefa consiste em implementar, num arquivo 'htmlib.c', as funes que realizam as operaes definidas em
'htmlib.h' e num arquivo 'hashlib.c', as funes que realizam as operaes definidas em 'hashlib.h'.
.s As Funes
As funes a serem implementadas so as seguintes
.c
HTMLPagePtr newPage(char *);
.n
Cria um descritor de pgina HTML contendo uma tabela de hashing vazia e um descritor para a tag
&lt;HTML&gt;, com atributo "id", cujo valor  passado como parmeetro para a funo.
.c
void insertElement(HTMLPagePtr, char *, NodePtr);
.n
Insere um elemento numa pgina HTML, como 'filho' da tag cuja identificao  passada como parmetro.
Os parmetros so:
.i apontador para a pgina (HTMLPagePtr)
.i identificao da tag  qual o novo elemento ser agregado (char *)
.i apontador para o elemento a ser inserido (NodePtr).
.n
Ateno: o elemento sendo insererido pode ser uma tag que tem o atributo "id". Nesse caso, o
valor do atributo deve ser inserido na tabela de hashing da pgina, associado ao elemento.
.c
void addAttrib(NodePtr, char *, char*);
.n
Agrega um atributo a um elemento (s faz sentido se esse elemento for uma tag). Parmetros:
.i Apontador para o elemento
.i Nome do atributo (char *)
.i Valor do Atributo (char *)
.c
void appendChild(NodePtr, NodePtr);
.n
Agrega um 'filho' a um elemento (s faz sentido se for uma tag). Parmetros:
.i Apontador para a tag  qual o elemento ser agregado (NodePtr)
.i Apontador para o elemento a ser agregado como filho.
.c
NodePtr newTag(char *name, int closed);
.n
Cria um elemento que descreve uma tag HTML. Parmetros:
.i nome da tag (char *)
.i indicao de tag fechada ou aberta (int)
.c
NodePtr newComment(char *);
.n
Cria um elemento do tipo comentrio. Parmetro:
.i texto a ser associado ao comentrio (char *)
.c
NodePtr newText(char *);
.n
Cria um elemento do tipo texto. Parmetro:
.i contedo do texto (char *);
.c
void writePage(HTMLPagePtr, char *);
.n
Escreve o texto correspondente a uma pgina HTML descrita por um 'descritor de pgina'. Parmetros:
.i apontador para o descritor de pgina (HTMLPagePtr).
.i nome do arquivo de sada.
.n
Para escrever como HTML o contedo de um elemento de uma pgina, se esse elemento for do tipo 
.i TEXT: copiar o texto correspondente na sada
.i COMMENT: copiar o texto correspondente na sada entre '&lt;!--'  e '--&gt;'
.i TAG:
Escrever o nome da tag entre '&lt;' e '&gt;'. Para cada filho da tag, escrever o texto HTML correspondente (recursivamente).
Se a tag for uma tag fechada, fechar a tag com '&lt;/nome da tag &gt;'.
.s Exemplos de uso
O cdigo abaixo mostra como a biblioteca 'htmlib' pode ser usada para gerar uma pgina 
simples, 'exemplo1.c'.
.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "htmlib.h"

/* insere uma referncia (hyperlink) numa pgina */
NodePtr insertRef(HTMLPagePtr page, char *id, char *url, char *text){
  NodePtr p = newTag("a",true);
  addAttrib(p,"href",url);
  appendChild(p,newText(text));
  insertElement(page,id,p);
  return p;
}    


/* monta uma pgina contendo o conjunto mnimo de elementos */
HTMLPagePtr makeTemplate(){
  HTMLPagePtr myPage = newPage("page");
  NodePtr myHead = newTag("HEAD",true);
  NodePtr myTitle = newTag("TITLE",true);
  NodePtr myBody = newTag("BODY",true);
  addAttrib(myHead,"id","head");
  addAttrib(myBody,"id","body");
  addAttrib(myTitle,"id","title");
  insertElement(myPage,"page",myHead);
  insertElement(myPage,"page",myBody);
  insertElement(myPage,"head",myTitle);
  return myPage;
}
               

/* monta uma pgina exemplo */
HTMLPagePtr makePage1(){
  HTMLPagePtr myPage = makeTemplate();
  insertElement(myPage,"title",newText("Pgina exemplo"));
  insertHeader(myPage,"body","h1","MC 202 - turmas E e F");
  insertHeader(myPage,"body","h2","Segundo semestre de 2004");
  insertHeader(myPage,"body","h3","Atividade de Laboratrio no. 9");
  insertElement(myPage,"body",
                newText("Este  apenas um exemplo de pgina HTML gerada por programa. ")
               );
  insertElement(myPage,"body",newTag("BR",false));
  insertElement(myPage,"body",newText("Benvindo ao "));
  insertRef(myPage,"body","http://www.ic.unicamp.br","IC-UNICAMP");
  return myPage;
}
               
int main(int argc, char *argv[])
{ 
  HTMLPagePtr p = makePage1();
  writePage(p,"pagina1.html");
  system("PAUSE");	
  return 0;
}
.n
O programa 'exemplo2.c' mostra um cdigo mais completo.
.s Exemplo de Entrada para 'exemplo2.c'
O arquivo de entrada, 'ativ10.txt', usado por 'main.c' para gerar uma pgina HTML,  um exemplo de entrada possvel para 
a aplicao de testes 'exemplo2.c'.
.s Exemplo de Sada
Esta pgina HTML que voc est lendo, foi gerada pelo programa 'exemplo2.c' e constitui assim um bom exemplo de sada.
.s Cdigo
O cdigo para esta atividade est disponvel em 
.h http://www.ic.unicamp.br/~vanini/codAtiv10.zip
.s Data de Entrega
A tarefa dever ser entregue at 10/11/2008
