cdesktopenv/cde/programs/dtdocbook/infolib/TableTask.C

338 lines
5.6 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: TableTask.C /main/3 1996/08/21 15:47:46 drk $ */
/* exported interfaces... */
#include "TableTask.h"
/* imported interfaces... */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "FlexBuffer.h"
#include "Token.h"
#include "SGMLName.h"
#include "dbug.h"
#define NAMECASE 1
int TableTask::TGroup;
int TableTask::ColSpec;
int TableTask::Row;
int TableTask::TBody;
int TableTask::Entry;
TableTask::TableTask(const Token& t)
{
static int inited = 0;
if(!inited){
TGroup = SGMLName::intern("TGroup", NAMECASE);
ColSpec = SGMLName::intern("ColSpec", NAMECASE);
Row = SGMLName::intern("Row", NAMECASE);
TBody = SGMLName::intern("TBody", NAMECASE);
Entry = SGMLName::intern("Entry", NAMECASE);
inited = 1;
}
f_base = t.level();
f_buf = new FlexBuffer();
state = Start;
markup(t);
}
TableTask::~TableTask()
{
delete f_buf;
}
void
TableTask::markup(const Token& t)
{
int again = 0;
if(t.type() == END && t.level() == f_base){
write_record();
delete this; /* this object deletes itself when it's done. */
return;
}
do{
switch(state){
case Start:
if(t.type() == START && t.Gi() == TGroup){
// @@ attributes?
/*
* _@Tab
* @Fmta {_
*/
puts("@Tab\n"
" @Fmta {");
f_cols = 0;
state = Fmt_;
}
else{
expected("TGROUP", t);
}
case Fmt_:
if(t.Gi() == ColSpec){
// @@ attributes?
if(f_cols < 26){
/*
* @Tab
* @Fmta_ { @Col A_
*/
if(f_cols > 0) puts(" ! ");
puts(" @Col ");
putC('A' + f_cols);
f_cols++;
}else{
error("Too many columns. Maximum is 26.");
}
}
else if(t.Gi() == Row){
/*
* @Tab
* @Fmta { @Col A ! @Col B ! ..._ }
* {
* _
*/
puts(" }\n"
"{\n");
state = _Row;
}
else{
error("Expected <COLSPEC> or <ROW>; found <%s%s>",
t.type() == END ? "/" : "", t.giName());
}
break;
case _Row:
if(t.type() == START && t.Gi() == Row){
// @@ attributes?
/*
* @Tab
* @Fmta { @Col A ! @Col B ! ..._ }
* {
* _ @Rowa _
*/
puts(" @Rowa ");
f_col = 0;
state = _Entry;
}
else if(t.type() == END && t.Gi() == TBody){
/*
* @Tab
* @Fmta { @Col A ! @Col B ! ... }
* {
* @Rowa A { abc } B { def }
* _}
* _
*/
puts("}\n");
state = End;
}
else{
expected("ROW", t); /*@@ or </TBODY> */
}
break;
case _Entry:
if(t.type() == START && t.Gi() == Entry){
// @@ attributes?
if(f_col < f_cols){
/*
* @Tab
* @Fmta { @Col A ! @Col B ! ... }
* {
* @Rowa _A { _
*/
putC('A' + f_col);
f_col ++;
puts(" { ");
f_entryBase = t.level();
state = Object;
}else{
error("Too many entries in row: only %s columns specified",
f_cols);
}
}
if(t.type() == END && t.Gi() == Row){
/*
* @Tab
* @Fmta { @Col A ! @Col B ! ... }
* {
* @Rowa A { abc } B { def } _
* _
*/
puts("\n");
f_col = 0;
state = _Row;
}
else{
expected("ENTRY", t);
}
break;
case Object:
if(t.type() == END && t.level() == f_entryBase){
/*
* @Tab
* @Fmta { @Col A ! @Col B ! ... }
* {
* @Rowa A { object } _
*/
puts(" } ");
state = _Entry;
}
else{
putC(' '); /* @# put whitespace in for markup to make
* "a<tag>b" come out as "a b" in stead of "ab"
*/
/* @@ markup within an entry ignored ?!!? */
}
break;
case End:
break;
default:
abort();
}
}while(again);
}
void
TableTask::expected(const char *right, const Token& wrong)
{
error("Expected <%s>; found <%s%s>",
right, wrong.type() == END ? "/" : "", wrong.giName());
}
void
TableTask::error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
/* @# more info here? */
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void
TableTask::putC(char c)
{
f_buf->put(c);
}
void
TableTask::puts(const char *s)
{
f_buf->writeStr(s);
}
void
TableTask::write(const char *buf, size_t len)
{
f_buf->write(buf, len);
}
void
TableTask::data(const char *chars, size_t len)
{
while(len--){
char c = *chars++;
switch(c){
case '/':
case '|':
case '&':
case '{':
case '}':
case '#':
case '@':
case '^':
case '"':
case '\\':
putC('\\');
putC(c);
break;
default:
putC(c);
}
}
}
SearchableTableTask::SearchableTableTask(SearchEngine *s, const Token& t)
: TableTask(t)
{
f_search = s;
}
void
SearchableTableTask::write_record()
{
DBUG_PRINT("Table", ("Lout table: `%s'", f_buf->GetBuffer()));
/*@@ write to BookCaseDB? Convert to PS? */
}