[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Groff] HTML output in Mozilla
From: |
Gaius Mulley |
Subject: |
Re: [Groff] HTML output in Mozilla |
Date: |
Thu, 12 Apr 2001 14:09:16 +0100 |
Hi Werner,
here are the improved patches together with the inline image fixes.
These patches generate better equation handling, fix alot of image
bugs, produce better html tables and fix a html glyph translation
bug.
Can I ask the members of the list to examine:
troff_output_file::check_charinfo
in particular and see whether this is correct in evaluating the
miny/maxy limits for a character. The images it generates seem
to suggest that the veryical region defined by miny and maxy
is too large.
Thanks
Gaius
2001-04-12 Gaius Mulley <address@hidden>
* src/devices/grohtml/grohtml.man: updated manual page regarding simple
anchor.
* src/preproc/html/pre-html.cc (createImage): fixed right hand cropping
of images.
* src/preproc/html/pre-html.cc (removeTempFiles): new function to tidy
up
temporary files.
* src/preproc/html/pre-html.cc (main): calls removeTempFiles.
* src/preproc/html/pre-html.cc: many fixes to do with the new inline
suppress node and image regions are much tighter.
* src/devices/grohtml/post-html.cc: new method is_auto_img.
* src/devices/grohtml/post-html.cc (generate_img_src): new function.
* src/devices/grohtml/post-html.cc (html_printer::do_auto_image):
utilizes it.
* src/devices/grohtml/post-html.cc (do_heading) (do_title):
include inline images within their contents.
* src/devices/grohtml/post-html.cc (html_printer::begin_page):
tidied up comments that are issued to the html output file.
* src/devices/grohtml/post-html.cc (html_printer::do_fill):
fixed so that .nf works with fonts other than courier.
* src/devices/grohtml/post-html.cc (text_glob::is_br): new method
used by do_heading.
* tmac/s.tmac: if -Thtml then emit $1 in .IP rather than its
equivalent diversion.
* src/include/html-strings.h: altered image tags to reflect the
inline image node.
* src/include/htmlindicate.h (html_end_suppress): added is_inline
parameter
* src/preproc/eqn/main.cc: will suppress generation of image
tags if it is already inside a pic image. Only emit tags if
the argument -Tps:html is present.
* src/preproc/tbl/main.cc: changes to reflect additional
html_end_suppress parameter.
* src/roff/troff/env.cc: only emit eol tag if a node has been
emitted since the last eol tag was written.
* src/roff/troff/env.h: new boolean emitted_node.
* src/roff/troff/input.cc (do_suppress): handles extra suppress nodes
O3, O4, O5. No longer use output_low_mark_miny.
* src/roff/troff/node.cc (check_charinfo): new method.
* src/roff/troff/node.cc (troff_output_file::determine_line_limits):
Alterations to limit checking.
* tmac/www.tmac: changes to reflect new suppress nodes.
2001-04-08 Bruno Haible <address@hidden>
* src/devices/grohtml/post-html.cc (html_printer::add_to_sbuf): Escape
the html_glyph in the buffer.
(str_translate_to_html): Output the unescaped escaped_char.
* src/devices/grohtml/html-text.cc (issue_table_begin): Set
frame=void, not frame=none. Add border=0.
--- groff-cvs/src/devices/grohtml/grohtml.man Mon Mar 19 15:33:03 2001
+++ groff-html/src/devices/grohtml/grohtml.man Thu Apr 12 12:59:42 2001
@@ -90,6 +90,7 @@
Generate simple heading anchors whenever a section/number heading is found.
Without the option the anchor value is the textual heading. This can cause
problems
when a heading contains a `?' on some brousers (netscape).
+This flag is automatically turned on if a heading contains an image.
.TP
.BI \-F dir
Prepend directory
--- groff-cvs/src/devices/grohtml/html-text.cc Mon Mar 19 15:33:03 2001
+++ groff-html/src/devices/grohtml/html-text.cc Thu Apr 12 12:59:42 2001
@@ -140,7 +140,7 @@
int width=current_indentation*100/linelength;
if (width > 0) {
- out->put_string("<table width=\"100%\" rules=\"none\" frame=\"none\"\n
cols=\"2\" cellspacing=\"0\" cellpadding=\"0\">").nl();
+ out->put_string("<table width=\"100%\" border=0 rules=\"none\"
frame=\"void\"\n cols=\"2\" cellspacing=\"0\" cellpadding=\"0\">").nl();
out->put_string("<tr valign=\"top\" align=\"left\">").nl();
if ((t->arg1 == 0) || (strcmp(t->arg1, "") == 0))
out->put_string("<td
width=\"").put_number(width).put_string("%\"></td>");
@@ -612,7 +612,11 @@
void html_text::do_space (void)
{
- do_para(done_para());
+ if (is_in_pre()) {
+ do_emittext("", 0);
+ } else {
+ do_para(done_para());
+ }
space_emitted = TRUE;
}
--- groff-cvs/src/devices/grohtml/post-html.cc Thu Apr 12 12:51:10 2001
+++ groff-html/src/devices/grohtml/post-html.cc Thu Apr 12 12:59:42 2001
@@ -340,16 +340,19 @@
class text_glob {
public:
text_glob (style *s, char *string, unsigned int length,
- int min_vertical, int min_horizontal,
- int max_vertical, int max_horizontal,
- int is_html , int is_troff_command,
- int is_a_line , int thickness);
+ int min_vertical , int min_horizontal,
+ int max_vertical , int max_horizontal,
+ int is_html , int is_troff_command,
+ int is_auto_image,
+ int is_a_line , int thickness);
text_glob (void);
~text_glob (void);
- int is_a_line (void);
- int is_a_tag (void);
- int is_raw (void);
- int is_eol (void);
+ int is_a_line (void);
+ int is_a_tag (void);
+ int is_raw (void);
+ int is_eol (void);
+ int is_auto_img (void);
+ int is_br (void);
style text_style;
char *text_string;
@@ -358,6 +361,7 @@
int is_raw_command; // should the text be sent directly to
the device?
int is_tag; // is this a .br, .sp, .tl etc
int is_line; // is the command a <line>?
+ int is_img_auto; // image created by eqn delim
int thickness; // the thickness of a line
};
@@ -365,11 +369,12 @@
int min_vertical, int min_horizontal,
int max_vertical, int max_horizontal,
int is_html, int is_troff_command,
+ int is_auto_image,
int is_a_line, int line_thickness)
: text_style(*s), text_string(string), text_length(length),
minv(min_vertical), minh(min_horizontal), maxv(max_vertical),
maxh(max_horizontal),
- is_raw_command(is_html), is_tag(is_troff_command), is_line(is_a_line),
- thickness(line_thickness)
+ is_raw_command(is_html), is_tag(is_troff_command),
is_img_auto(is_auto_image),
+ is_line(is_a_line), thickness(line_thickness)
{
}
@@ -420,6 +425,25 @@
}
/*
+ * is_auto_img - returns TRUE if the glob contains an automatically
+ * generated image.
+ */
+
+int text_glob::is_auto_img (void)
+{
+ return( is_img_auto );
+}
+
+/*
+ * is_br - returns TRUE if the glob is a tag containing a .br
+ */
+
+int text_glob::is_br (void)
+{
+ return( is_a_tag() && (strcmp("html-tag:.br", text_string) == 0) );
+}
+
+/*
* the class and methods used to construct ordered double linked lists.
* In a previous implementation we used templates via #include
"ordered-list.h",
* but this does assume that all C++ compilers can handle this feature.
Pragmatically
@@ -748,7 +772,7 @@
if (length > 0) {
text_glob *g=new text_glob(s, buffer.add_string(string, length), length,
min_vertical, min_horizontal, max_vertical,
max_horizontal,
- FALSE, FALSE, FALSE, 0);
+ FALSE, FALSE, FALSE, FALSE, 0);
glyphs.add(g, line_number, min_vertical, min_horizontal, max_vertical,
max_horizontal);
}
}
@@ -765,7 +789,7 @@
if (length > 0) {
text_glob *g=new text_glob(s, buffer.add_string(string, length), length,
min_vertical, min_horizontal, max_vertical,
max_horizontal,
- TRUE, FALSE, FALSE, 0);
+ TRUE, FALSE, FALSE, FALSE, 0);
glyphs.add(g, line_number, min_vertical, min_horizontal, max_vertical,
max_horizontal);
}
}
@@ -782,7 +806,9 @@
if (length > 0) {
text_glob *g=new text_glob(s, buffer.add_string(string, length), length,
min_vertical, min_horizontal, max_vertical,
max_horizontal,
- FALSE, TRUE, FALSE, 0);
+ FALSE, TRUE,
+ (strncmp(string, "html-tag:.auto-image", 20) ==
0),
+ FALSE, 0);
glyphs.add(g, line_number, min_vertical, min_horizontal, max_vertical,
max_horizontal);
}
}
@@ -799,7 +825,7 @@
if (y1 == y2) {
text_glob *g = new text_glob(s, "", 0,
min(y1, y2), min(x1, y2), max(y1, y2), max(x1,
x2),
- FALSE, TRUE, FALSE, thickness);
+ FALSE, TRUE, FALSE, FALSE, thickness);
glyphs.add(g, line_number, min(y1, y2), min(x1, y2), max(y1, y2), max(x1,
x2));
}
}
@@ -1196,6 +1222,30 @@
}
/*
+ * generate_img_src - returns a html image tag for the filename
+ * providing that the image exists.
+ */
+
+static char *generate_img_src (const char *filename)
+{
+ static char buffer[MAX_STRING_LENGTH];
+
+ while (filename && (filename[0] == ' ')) {
+ filename++;
+ }
+ if (exists(filename)) {
+ strcpy(buffer, "<img src=\"");
+ strncat(buffer, filename, MAX_STRING_LENGTH-strlen("<img src=\"")-1);
+ if (strlen(buffer) < MAX_STRING_LENGTH-3) {
+ strncat(buffer, "\">", 3);
+ }
+ return( (char *)&buffer );
+ } else {
+ return( 0 );
+ }
+}
+
+/*
* do_auto_image - tests whether the image, indicated by filename,
* is present, if so then it emits an html image tag.
* An image tag may be passed through from pic, eqn
@@ -1205,24 +1255,17 @@
void html_printer::do_auto_image (text_glob *g, const char *filename)
{
- while (filename && (filename[0] == ' ')) {
- filename++;
- }
- if (exists(filename)) {
+ char *buffer = generate_img_src(filename);
+
+ if (buffer) {
/*
* utilize emit_raw by creating a new text_glob.
*/
text_glob h = *g;
- char buffer[MAX_STRING_LENGTH];
- strcpy(buffer, "<img src=\"");
- strncat(buffer, filename, MAX_STRING_LENGTH-strlen("<img src=\"")-1);
- if (strlen(buffer) < MAX_STRING_LENGTH-3) {
- strncat(buffer, "\">", 3);
- h.text_string = (char *)&buffer;
- h.text_length = strlen(buffer);
- emit_raw(&h);
- }
+ h.text_string = buffer;
+ h.text_length = strlen(buffer);
+ emit_raw(&h);
} else {
next_tag = INLINE;
}
@@ -1245,7 +1288,21 @@
do {
t = page_contents->glyphs.get_data();
removed_from_head = FALSE;
- if (t->is_raw_command) {
+ if (t->is_auto_img()) {
+ char *img=generate_img_src((char *)(t->text_string + 20));
+
+ if (img) {
+ if (found_title_start) {
+ strcat(title.text, " ");
+ }
+ found_title_start = TRUE;
+ title.has_been_found = TRUE;
+ strcat(title.text, img);
+ }
+ page_contents->glyphs.sub_move_right(); /* move onto next
word */
+ removed_from_head = ((!page_contents->glyphs.is_empty()) &&
+ (page_contents->glyphs.is_equal_to_head()));
+ } else if (t->is_raw_command) {
/* skip raw commands
*/
page_contents->glyphs.sub_move_right(); /* move onto next
word */
@@ -1304,7 +1361,7 @@
strlen(header.header_buffer),
header.no_of_headings, header.header_level,
header.no_of_headings, header.header_level,
- FALSE, FALSE, FALSE, FALSE);
+ FALSE, FALSE, FALSE, FALSE, FALSE);
header.headers.add(h,
header.no_of_headings,
header.no_of_headings, header.no_of_headings,
@@ -1368,7 +1425,18 @@
if (! page_contents->glyphs.is_equal_to_head()) {
g = page_contents->glyphs.get_data();
do {
- if (! (g->is_a_line() || g->is_a_tag() || g->is_raw())) {
+ if (g->is_auto_img()) {
+ char *img=generate_img_src((char *)(g->text_string + 20));
+
+ if (img) {
+ simple_anchors = TRUE; // we cannot use full heading anchors with
images
+ if (l != 0) {
+ strcat(header.header_buffer, " ");
+ }
+ l = g;
+ strcat(header.header_buffer, img);
+ }
+ } else if (! (g->is_a_line() || g->is_a_tag() || g->is_raw())) {
/*
* we ignore raw commands when constructing a heading
*/
@@ -1382,7 +1450,7 @@
page_contents->glyphs.move_right();
g = page_contents->glyphs.get_data();
} while ((! page_contents->glyphs.is_equal_to_head()) &&
- (! g->is_a_tag()));
+ (! g->is_br()));
}
determine_header_level(level);
@@ -1505,7 +1573,18 @@
do {
t = page_contents->glyphs.get_data();
removed_from_head = FALSE;
- if (t->is_raw_command) {
+ if (t->is_auto_img()) {
+ char *img=generate_img_src((char *)(t->text_string + 20));
+
+ if (img) {
+ if (found_indent_start) {
+ strcat(indent.text, " ");
+ }
+ found_indent_start = TRUE;
+ strcat(indent.text, img);
+ }
+ page_contents->glyphs.sub_move_right(); /* move onto next
word */
+ } else if (t->is_raw_command) {
/* skip raw commands
*/
page_contents->glyphs.sub_move_right(); /* move onto next
word */
@@ -1568,12 +1647,10 @@
supress_sub_sup = TRUE;
if (fill_on != on) {
- if (is_font_courier(output_style.f) && (is_courier_until_eol())) {
- if (on) {
- current_paragraph->do_pre();
- } else {
- current_paragraph->done_pre();
- }
+ if (on) {
+ current_paragraph->done_pre();
+ } else {
+ current_paragraph->do_pre();
}
}
fill_on = on;
@@ -2276,9 +2353,14 @@
int l = strlen(html_glyph);
int i;
+ // Escape the name, so that "&" doesn't get expanded to "&"
+ // later during translate_to_html.
+ add_char_to_sbuf('\\'); add_char_to_sbuf('(');
+
for (i=0; i<l; i++) {
add_char_to_sbuf(html_glyph[i]);
}
+ add_char_to_sbuf('\\'); add_char_to_sbuf(')');
}
}
}
@@ -2632,7 +2714,9 @@
void html_printer::begin_page(int n)
{
page_number = n;
+#if defined(DEBUGGING)
html.begin_comment("Page: ").put_string(i_to_a(page_number)).end_comment();;
+#endif
no_of_printed_pages++;
output_style.f = 0;
@@ -2700,10 +2784,13 @@
#endif
t = time(0);
html.begin_comment("CreationDate: ")
- .put_string(ctime(&t))
+ .put_string(ctime(&t), strlen(ctime(&t))-1)
.end_comment();
}
+#if defined(DEBUGGING)
html.begin_comment("Total number of pages:
").put_string(i_to_a(no_of_printed_pages)).end_comment();
+#endif
+ html.end_line();
html.end_line();
/*
* now run through the file list copying each temporary file in turn and
emitting the links.
--- groff-cvs/src/include/html-strings.h Wed Jan 17 14:17:23 2001
+++ groff-html/src/include/html-strings.h Thu Apr 12 12:59:42 2001
@@ -23,8 +23,9 @@
* and later detected by pre-html.cc
*/
-#define HTML_IMAGE_INLINE ".HTML-IMAGE-INLINE"
-#define HTML_IMAGE_CENTERED ".HTML-IMAGE"
-#define HTML_IMAGE_RIGHT ".HTML-IMAGE-RIGHT"
-#define HTML_IMAGE_LEFT ".HTML-IMAGE-LEFT"
-#define HTML_IMAGE_END ".HTML-IMAGE-END"
+#define HTML_IMAGE_INLINE_BEGIN "\\O[HTML-IMAGE-INLINE-BEGIN]"
+#define HTML_IMAGE_INLINE_END "\\O[HTML-IMAGE-INLINE-END]"
+#define HTML_IMAGE_CENTERED ".HTML-IMAGE"
+#define HTML_IMAGE_RIGHT ".HTML-IMAGE-RIGHT"
+#define HTML_IMAGE_LEFT ".HTML-IMAGE-LEFT"
+#define HTML_IMAGE_END ".HTML-IMAGE-END"
--- groff-cvs/src/include/htmlindicate.h Wed Jan 17 14:17:23 2001
+++ groff-html/src/include/htmlindicate.h Thu Apr 12 12:59:42 2001
@@ -61,7 +61,7 @@
* html_end_suppress - end the suppression of output.
*/
-extern void html_end_suppress (void);
+extern void html_end_suppress (int is_inline);
#endif
--- groff-cvs/src/libs/libgroff/htmlindicate.cc Wed Jan 17 14:17:24 2001
+++ groff-html/src/libs/libgroff/htmlindicate.cc Thu Apr 12 12:59:42 2001
@@ -39,29 +39,36 @@
*/
static int is_in_graphic_start = 0;
+static int is_inline_image = 0;
/*
- * html_begin_suppress -
+ * html_begin_suppress - emit a start of image tag which will be seen
+ * by pre-html.
*/
void html_begin_suppress (int is_inline)
{
if (is_inline) {
- put_string(HTML_IMAGE_INLINE, stdout);
+ put_string(HTML_IMAGE_INLINE_BEGIN, stdout);
} else {
put_string(HTML_IMAGE_CENTERED, stdout);
+ put_string("\n", stdout);
}
- put_string("\n", stdout);
}
/*
- * html_end_suppress -
+ * html_end_suppress - emit an end of image tag which will be seen
+ * by pre-html.
*/
-void html_end_suppress (void)
+void html_end_suppress (int is_inline)
{
- put_string(HTML_IMAGE_END, stdout);
- put_string("\n", stdout);
+ if (is_inline)
+ put_string(HTML_IMAGE_INLINE_END, stdout);
+ else {
+ put_string(HTML_IMAGE_END, stdout);
+ put_string("\n", stdout);
+ }
}
/*
@@ -74,8 +81,9 @@
void graphic_start (int is_inline)
{
if (! is_in_graphic_start) {
- put_string(".if '\\*(.T'html-old' \\X(graphic-start(\\c\n", stdout);
+ // put_string(".if '\\*(.T'html-old' \\X(graphic-start(\\c\n", stdout);
html_begin_suppress(is_inline);
+ is_inline_image = is_inline;
is_in_graphic_start = 1;
}
}
@@ -87,8 +95,8 @@
void graphic_end (void)
{
if (is_in_graphic_start) {
- html_end_suppress();
- put_string(".if '\\*(.T'html-old' \\X(graphic-end(\\c\n", stdout);
+ html_end_suppress(is_inline_image);
+ // put_string(".if '\\*(.T'html-old' \\X(graphic-end(\\c\n", stdout);
is_in_graphic_start = 0;
}
}
--- groff-cvs/src/preproc/eqn/main.cc Thu Apr 12 12:51:31 2001
+++ groff-html/src/preproc/eqn/main.cc Thu Apr 12 13:46:00 2001
@@ -25,6 +25,7 @@
#include "searchpath.h"
#include "macropath.h"
#include "htmlindicate.h"
+#include "pbox.h"
#define STARTUP_FILE "eqnrc"
@@ -41,7 +42,13 @@
int one_size_reduction_flag = 0;
int compatible_flag = 0;
int no_newline_in_delim_flag = 0;
-
+int html = 0;
+/*
+ * if we encounter a region marked as an image then we
+ * do not mark up inline equations.
+ */
+int suppress_html = 0;
+
int read_line(FILE *fp, string *p)
{
@@ -75,12 +82,31 @@
if (interpret_lf_args(linebuf.contents() + 3))
current_lineno--;
}
+ else if (linebuf.length() >= 12
+ && linebuf[0] == '.' && linebuf[1] == 'H' && linebuf[2] == 'T'
+ && linebuf[3] == 'M' && linebuf[4] == 'L' && linebuf[5] == '-'
+ && linebuf[6] == 'I' && linebuf[7] == 'M' && linebuf[8] == 'A'
+ && linebuf[9] == 'G' && linebuf[10] == 'E' && linebuf[11] == '\n')
{
+ put_string(linebuf, stdout);
+ suppress_html++;
+ }
+ else if (linebuf.length() >= 16
+ && linebuf[0] == '.' && linebuf[1] == 'H' && linebuf[2] == 'T'
+ && linebuf[3] == 'M' && linebuf[4] == 'L' && linebuf[5] == '-'
+ && linebuf[6] == 'I' && linebuf[7] == 'M' && linebuf[8] == 'A'
+ && linebuf[9] == 'G' && linebuf[10] == 'E' && linebuf[11] == '-'
+ && linebuf[12] == 'E' && linebuf[13] == 'N' && linebuf[14] == 'D'
+ && linebuf[15] == '\n') {
+ put_string(linebuf, stdout);
+ suppress_html--;
+ }
else if (linebuf.length() >= 4
&& linebuf[0] == '.'
&& linebuf[1] == 'E'
&& linebuf[2] == 'Q'
&& (linebuf[3] == ' ' || linebuf[3] == '\n' || compatible_flag)) {
- graphic_start(0);
+ if (html && (suppress_html == 0))
+ graphic_start(0);
put_string(linebuf, stdout);
int start_lineno = current_lineno + 1;
str.clear();
@@ -112,7 +138,8 @@
restore_compatibility();
printf(".lf %d\n", current_lineno);
put_string(linebuf, stdout);
- graphic_end();
+ if (html && (suppress_html == 0))
+ graphic_end();
}
else if (start_delim != '\0' && linebuf.search(start_delim) >= 0
&& inline_equation(fp, linebuf, str))
@@ -168,9 +195,17 @@
ptr = &linebuf[0];
}
str += '\0';
- graphic_start(1);
+ if (html && (suppress_html == 0)) {
+ printf(".as %s ", LINE_STRING); graphic_start(1);
+ printf("\n");
+ }
init_lex(str.contents(), current_filename, start_lineno);
yyparse();
+ if (html && (suppress_html == 0)) {
+ printf(".as %s ", LINE_STRING); graphic_end();
+ printf("\n");
+ }
+
start = delim_search(ptr, start_delim);
if (start == 0) {
char *nl = strchr(ptr, '\n');
@@ -183,7 +218,6 @@
printf(".lf %d\n", current_lineno);
output_string();
restore_compatibility();
- graphic_end();
printf(".lf %d\n", current_lineno + 1);
return 1;
}
@@ -290,6 +324,10 @@
break;
case 'T':
device = optarg;
+ if (strcmp(device, "ps:html") == 0) {
+ device = "ps";
+ html = 1;
+ }
break;
case 's':
if (!set_gsize(optarg))
--- groff-cvs/src/preproc/html/pre-html.cc Thu Apr 12 12:51:35 2001
+++ groff-html/src/preproc/html/pre-html.cc Thu Apr 12 12:59:42 2001
@@ -55,13 +55,17 @@
#define POSTSCRIPTRES 72000 // maybe there is a better way to find
this? --fixme--
#define DEFAULT_IMAGE_RES 80 // 80 pixels per inch resolution
-#define DEFAULT_VERTICAL_OFFSET 40 // 40/72 of an inch
-#define IMAGE_BOARDER_PIXELS 10
+#define DEFAULT_VERTICAL_OFFSET 45 // DEFAULT_VERTICAL_OFFSET/72 of an inch
+#define IMAGE_BOARDER_PIXELS 0
+#define MAX_WIDTH 8 // inches
+#define INLINE_LEADER_CHAR '\\'
#define TRANSPARENT "-background \"#FFF\" -transparent \"#FFF\""
-// #define DEBUGGING
-// #define DEBUG_HTML
+#if 0
+# define DEBUGGING
+# define DEBUG_HTML
+#endif
#if !defined(TRUE)
# define TRUE (1==1)
@@ -146,7 +150,7 @@
int do_image(int argc, char *argv[]);
void write_file_html(void);
void write_file_troff(void);
- void write_upto_newline (char_block **t, int *i);
+ void write_upto_newline (char_block **t, int *i, int is_html);
int can_see(char_block **t, int *i, char *string);
int skip_spaces(char_block **t, int *i);
void skip_to_newline(char_block **t, int *i);
@@ -258,19 +262,17 @@
static void write_end_image (int is_html)
{
- writeString(".end \\{\\\n");
if (is_html) {
/*
* emit image name and enable output
*/
- writeString("\\O2\\O1\n");
+ writeString("\\O2\\O1\\O4\n");
} else {
/*
* postscript, therefore emit image boundaries
*/
- writeString("\\O2\n");
+ writeString("\\O2\\O4\n");
}
- writeString(".\\}\n");
}
/*
@@ -283,57 +285,77 @@
static void write_start_image (IMAGE_ALIGNMENT pos, int is_html)
{
- writeString(".begin \\{\\\n");
- switch (pos) {
+ if (pos == INLINE) {
+ writeString("\\O3\\O5'");
+ writeString(image_template); writeString(".png'");
+ } else {
+ writeString(".begin \\{\\\n");
+ switch (pos) {
- case LEFT:
- writeString(". image l ");
- break;
- case RIGHT:
- writeString(". image r ");
- break;
- case INLINE:
- writeString(". image i ");
- break;
- case CENTERED:
- default:
- writeString(". image c ");
+ case LEFT:
+ writeString(". image l ");
+ break;
+ case RIGHT:
+ writeString(". image r ");
+ break;
+ case CENTERED:
+ default:
+ writeString(". image c ");
+ }
+ writeString(image_template); writeString(".png\n");
+ if (! is_html) {
+ writeString(".bp\n");
+ writeString(".tl ''''\n");
+ }
+ writeString("\\}\n");
}
- writeString(image_template); writeString(".png\n");
if (is_html) {
writeString("\\O0\n");
} else {
- writeString(".bp\n");
- writeString(".tl ''''\n");
// reset min/max registers
writeString("\\O0\\O1\n");
}
- writeString("\\}\n");
}
/*
* write_upto_newline - writes the contents of the buffer until a newline is
seen.
+ * It checks for HTML_IMAGE_INLINE_BEGIN and
HTML_IMAGE_INLINE_END
+ * and if they are present it processes them.
*/
-void char_buffer::write_upto_newline (char_block **t, int *i)
+void char_buffer::write_upto_newline (char_block **t, int *i, int is_html)
{
int j=*i;
if (*t) {
- while ((j < (*t)->used) && ((*t)->buffer[j] != '\n')) {
+ while ((j < (*t)->used) && ((*t)->buffer[j] != '\n') &&
+ ((*t)->buffer[j] != INLINE_LEADER_CHAR)) {
j++;
}
if ((j < (*t)->used) && ((*t)->buffer[j] == '\n')) {
j++;
}
writeNbytes((*t)->buffer+(*i), j-(*i));
+ if ((*t)->buffer[j] == INLINE_LEADER_CHAR) {
+ if (can_see(t, &j, HTML_IMAGE_INLINE_BEGIN))
+ write_start_image(INLINE, is_html);
+ else if (can_see(t, &j, HTML_IMAGE_INLINE_END))
+ write_end_image(is_html);
+ else {
+ if (j < (*t)->used) {
+ *i = j;
+ j++;
+ writeNbytes((*t)->buffer+(*i), j-(*i));
+ }
+ }
+ }
if (j == (*t)->used) {
*i = 0;
if ((*t)->buffer[j-1] == '\n') {
*t = (*t)->next;
} else {
*t = (*t)->next;
- write_upto_newline(t, i);
+ write_upto_newline(t, i, is_html);
}
} else {
// newline was seen
@@ -451,14 +473,11 @@
} else if (can_see(&t, &i, HTML_IMAGE_RIGHT)) {
write_start_image(RIGHT, FALSE);
skip_to_newline(&t, &i);
- } else if (can_see(&t, &i, HTML_IMAGE_INLINE)) {
- write_start_image(INLINE, FALSE);
- skip_to_newline(&t, &i);
} else if (can_see(&t, &i, HTML_IMAGE_CENTERED)) {
write_start_image(CENTERED, FALSE);
skip_to_newline(&t, &i);
} else {
- write_upto_newline(&t, &i);
+ write_upto_newline(&t, &i, FALSE);
}
} while (t != 0);
}
@@ -582,13 +601,14 @@
static void removeAllPages (void)
{
+#if !defined(DEBUGGING)
char buffer[4096];
+ int i=1;
-#if !defined(DEBUGGING)
- sprintf(buffer,
- "/bin/rm -f %s* \n",
- imagePageStem);
- system(buffer);
+ do {
+ sprintf(buffer, "%s%d", imagePageStem, i);
+ i++;
+ } while (remove(buffer) == 0);
#endif
}
@@ -640,13 +660,13 @@
if (i->X1 != -1) {
char buffer[4096];
int x1 = max(min(i->X1,
i->X2)*image_res/POSTSCRIPTRES-1*IMAGE_BOARDER_PIXELS, 0);
- int y1 = max((image_res*vertical_offset/72)+min(i->Y1,
i->Y2)*image_res/POSTSCRIPTRES, 0);
- int x2 = min(max(i->X1,
i->X2)*image_res/POSTSCRIPTRES+1*IMAGE_BOARDER_PIXELS,
i->maxx*image_res/POSTSCRIPTRES);
- int y2 = (image_res*vertical_offset/72)+max(i->Y1,
i->Y2)*image_res/POSTSCRIPTRES+2*IMAGE_BOARDER_PIXELS;
+ int y1 = max((image_res*vertical_offset/72)+min(i->Y1,
i->Y2)*image_res/POSTSCRIPTRES-IMAGE_BOARDER_PIXELS, 0);
+ int x2 = max(i->X1, i->X2)*image_res/POSTSCRIPTRES+1*IMAGE_BOARDER_PIXELS;
+ int y2 = (image_res*vertical_offset/72)+max(i->Y1,
i->Y2)*image_res/POSTSCRIPTRES+1*IMAGE_BOARDER_PIXELS;
sprintf(buffer,
"pnmcut %d %d %d %d < %s%d | pnmtopng %s > %s \n",
- x1, y1, x2-x1, y2-y1,
+ x1, y1, x2-x1+1, y2-y1+1,
imagePageStem,
i->pageNo,
TRANSPARENT,
@@ -710,16 +730,12 @@
} else if (can_see(&t, &i, HTML_IMAGE_RIGHT)) {
write_start_image(RIGHT, TRUE);
skip_to_newline(&t, &i);
- } else if (can_see(&t, &i, HTML_IMAGE_INLINE)) {
- stop();
- write_start_image(INLINE, TRUE);
- skip_to_newline(&t, &i);
} else if (can_see(&t, &i, HTML_IMAGE_CENTERED)) {
stop();
write_start_image(CENTERED, TRUE);
skip_to_newline(&t, &i);
} else {
- write_upto_newline(&t, &i);
+ write_upto_newline(&t, &i, TRUE);
}
} while (t != 0);
}
@@ -753,7 +769,7 @@
int y1 = f->readInt();
int x2 = f->readInt();
int y2 = f->readInt();
- int maxx = f->readInt();
+ int maxx = max(f->readInt(), MAX_WIDTH*image_res);
char *name = f->readString();
int res = POSTSCRIPTRES; // --fixme-- prefer (f->readInt())
providing that troff can discover the value
listOfImages.add(x1, y1, x2, y2, page, res, maxx, name);
@@ -1053,6 +1069,18 @@
}
/*
+ * removeTempFiles - remove the temporary files
+ */
+
+static void removeTempFiles (void)
+{
+#if !defined(DEBUGGING)
+ remove(psFileName);
+ remove(regionFileName);
+#endif
+}
+
+/*
* findPrefix - finds the optional prefix to the groff utilities.
* It also builds the 'troff' executable name.
*/
@@ -1103,6 +1131,7 @@
ok = inputFile.do_html(argc, argv);
removeAllPages();
}
+ removeTempFiles();
return ok;
}
--- groff-cvs/src/roff/groff/groff.cc Thu Apr 12 12:51:41 2001
+++ groff-html/src/roff/groff/groff.cc Thu Apr 12 12:59:42 2001
@@ -348,7 +348,7 @@
commands[TROFF_INDEX].append_arg("-T", device);
// html renders equations as images via ps
if (strcmp(device, "html") == 0)
- commands[EQN_INDEX].append_arg("-Tps");
+ commands[EQN_INDEX].append_arg("-Tps:html");
else
commands[EQN_INDEX].append_arg("-T", device);
--- groff-cvs/src/preproc/tbl/main.cc Thu Apr 12 12:51:40 2001
+++ groff-html/src/preproc/tbl/main.cc Thu Apr 12 12:59:42 2001
@@ -243,7 +243,7 @@
while ((c = getc(fp)) != '\n') {
if (c == EOF) {
printf(".if '\\*(.T'html' \\X(table-end(\n");
- html_end_suppress();
+ html_end_suppress(0);
putchar('\n');
return;
}
@@ -251,7 +251,7 @@
}
putchar('\n');
printf(".if '\\*(.T'html' \\X(table-end(\n");
- html_end_suppress();
+ html_end_suppress(0);
current_lineno++;
}
}
--- groff-cvs/src/roff/troff/env.cc Thu Apr 12 12:51:47 2001
+++ groff-html/src/roff/troff/env.cc Thu Apr 12 12:59:42 2001
@@ -133,9 +133,10 @@
#ifdef WIDOW_CONTROL
&& (!widow_control || no_fill)
#endif /* WIDOW_CONTROL */
- )
+ ) {
curdiv->output(nd, no_fill, vs, post_vs, width);
- else {
+ emitted_node = 1;
+ } else {
pending_output_line **p;
for (p = &pending_lines; *p; p = &(*p)->next)
;
@@ -598,6 +599,7 @@
#endif /* WIDOW_CONTROL */
need_eol(0),
ignore_next_eol(0),
+ emitted_node(0),
name(nm),
control_char('.'),
no_break_control_char('\''),
@@ -2023,8 +2025,9 @@
need_eol--;
add_html_tag("eol");
}
- else if (!fill) {
+ else if (!fill && emitted_node) {
add_html_tag("eol");
+ emitted_node = 0;
}
}
}
--- groff-cvs/src/roff/troff/env.h Thu Apr 12 12:51:48 2001
+++ groff-html/src/roff/troff/env.h Thu Apr 12 12:59:42 2001
@@ -183,6 +183,7 @@
#endif /* WIDOW_CONTROL */
int need_eol;
int ignore_next_eol;
+ int emitted_node; // have we emitted a node since the last html eol tag?
tab_type distance_to_next_tab(hunits *);
void start_line();
--- groff-cvs/src/roff/troff/input.cc Thu Apr 12 12:51:57 2001
+++ groff-html/src/roff/troff/input.cc Thu Apr 12 13:43:58 2001
@@ -4274,14 +4274,37 @@
tok.next();
int c = tok.ch();
- if (c == '0')
- return new suppress_node(0, 0);
- else if (c == '1')
- return new suppress_node(1, 0);
- else if (c == '2')
- return new suppress_node(1, 1);
- else
- error("invalid argument to \\O");
+ switch (c) {
+
+ case '0':
+ if (begin_level == 1)
+ return new suppress_node(0, 0);
+ break;
+ case '1':
+ if (begin_level == 1)
+ return new suppress_node(1, 0);
+ break;
+ case '2':
+ if (begin_level == 1)
+ return new suppress_node(1, 1);
+ break;
+ case '3':
+ begin_level++;
+ break;
+ case '4':
+ begin_level--;
+ break;
+ case '5': {
+ symbol filename = get_delim_name();
+
+ if (begin_level == 1)
+ return( new suppress_node(filename, 'i') );
+ return 0;
+ break;
+ }
+ default:
+ error("`%1' is an invalid argument to \\O", char(c));
+ }
return 0;
}
@@ -4567,12 +4590,10 @@
error("l, r, c, or i expected (got %1)", tok.description());
position = 'c';
}
- else {
- tok.next();
- symbol filename = get_long_name(1);
- if (!filename.is_null())
- curenv->add_node(new suppress_node(filename, position));
- }
+ tok.next();
+ symbol filename = get_long_name(1);
+ if (!filename.is_null())
+ curenv->add_node(new suppress_node(filename, position));
}
skip_line();
}
@@ -6285,7 +6306,6 @@
static int output_reg_miny_contents = -1;
static int output_reg_maxx_contents = -1;
static int output_reg_maxy_contents = -1;
-static int output_low_mark_miny = -1; // internal only (limits miny)
void check_output_limits(int x, int y)
{
@@ -6293,8 +6313,7 @@
output_reg_minx_contents = x;
if (x > output_reg_maxx_contents)
output_reg_maxx_contents = x;
- if (((output_reg_miny_contents == -1) || (y < output_reg_miny_contents))
- && (y >= output_low_mark_miny))
+ if ((output_reg_miny_contents == -1) || (y < output_reg_miny_contents))
output_reg_miny_contents = y;
if (y > output_reg_maxy_contents)
output_reg_maxy_contents = y;
@@ -6303,7 +6322,6 @@
void reset_output_registers(int miny)
{
// fprintf(stderr, "reset_output_registers\n");
- output_low_mark_miny = miny;
output_reg_minx_contents = -1;
output_reg_miny_contents = -1;
output_reg_maxx_contents = -1;
--- groff-cvs/src/roff/troff/node.cc Thu Apr 12 12:52:03 2001
+++ groff-html/src/roff/troff/node.cc Thu Apr 12 13:35:54 2001
@@ -765,6 +765,7 @@
void really_off();
void draw(char, hvpair *, int, font_size);
void determine_line_limits (char code, hvpair *point, int npoints);
+ void check_charinfo(tfont *tf, charinfo *ci);
int get_hpos() { return hpos; }
int get_vpos() { return vpos; }
};
@@ -928,8 +929,8 @@
put(tbuf_kern);
put(' ');
}
-
- check_output_limits(output_hpos, output_vpos);
+ check_output_limits(hpos, vpos);
+ check_output_limits(hpos, vpos+current_size+current_height);
for (int i = 0; i < tbuf_len; i++)
put(tbuf[i]);
@@ -937,6 +938,17 @@
tbuf_len = 0;
}
+void troff_output_file::check_charinfo(tfont *tf, charinfo *ci)
+{
+ int size =tf->get_size().to_scaled_points();
+ int height=tf->get_char_height(ci).to_units();
+ int width
=tf->get_width(ci).to_units()+tf->get_italic_correction(ci).to_units();
+ int depth =tf->get_char_depth(ci).to_units();
+
+ check_output_limits(output_hpos , output_vpos-height);
+ check_output_limits(output_hpos+width, output_vpos+current_size+depth);
+}
+
void troff_output_file::put_char_width(charinfo *ci, tfont *tf, hunits w,
hunits k)
{
@@ -949,6 +961,7 @@
if (c == '\0') {
flush_tbuf();
do_motion();
+ check_charinfo(tf, ci);
if (ci->numbered()) {
put('N');
put(ci->get_number());
@@ -970,6 +983,7 @@
if (tbuf_len > 0 && hpos == output_hpos && vpos == output_vpos
&& kk == tbuf_kern
&& tbuf_len < TBUF_SIZE) {
+ check_charinfo(tf, ci);
tbuf[tbuf_len++] = c;
output_hpos += w.to_units() + kk;
hpos = output_hpos;
@@ -977,6 +991,7 @@
}
flush_tbuf();
do_motion();
+ check_charinfo(tf, ci);
tbuf[tbuf_len++] = c;
output_hpos += w.to_units() + kk;
tbuf_kern = kk;
@@ -985,6 +1000,8 @@
else {
// flush_tbuf();
int n = hpos - output_hpos;
+ check_charinfo(tf, ci);
+ // check_output_limits(output_hpos, output_vpos);
if (vpos == output_vpos && n > 0 && n < 100 && !force_motion) {
put(char(n/10 + '0'));
put(char(n%10 + '0'));
@@ -1110,17 +1127,37 @@
case 'c':
case 'C':
/* only the h field is used when defining a circle */
- check_output_limits(output_hpos, output_vpos-point[0].h.to_units()/2);
+ check_output_limits(output_hpos ,
output_vpos-point[0].h.to_units()/2);
check_output_limits(output_hpos+point[0].h.to_units(),
output_vpos+point[0].h.to_units()/2);
break;
case 'E':
case 'e':
- check_output_limits(output_hpos, output_vpos-point[1].v.to_units()/2);
- check_output_limits(output_hpos+point[0].h.to_units(),
output_vpos+point[1].v.to_units()/2);
+ check_output_limits(output_hpos ,
output_vpos-point[0].v.to_units()/2);
+ check_output_limits(output_hpos+point[0].h.to_units(),
output_vpos+point[0].v.to_units()/2);
+ break;
+ case 'P':
+ case 'p':
+ x=output_hpos;
+ y=output_vpos;
+ check_output_limits(x, y);
+ for (i=0; i<npoints; i++) {
+ x += point[i].h.to_units();
+ y += point[i].v.to_units();
+ check_output_limits(x, y);
+ }
+ break;
+ case 't':
+ x=output_hpos;
+ y=output_vpos;
+ for (i=0; i<npoints; i++) {
+ x += point[i].h.to_units();
+ y += point[i].v.to_units();
+ check_output_limits(x, y);
+ }
break;
default:
/*
- * remember this doesn't work for arc..
+ * remember this doesn't work for arc.. yet
*/
x=output_hpos;
y=output_vpos;
@@ -3523,8 +3560,7 @@
"grohtml-info:page %d %d %d %d %d %d %s %d %d %s\n",
current_page,
get_reg_int("opminx"), get_reg_int("opminy"),
- get_reg_int("opmaxx"), min(get_reg_int("opmaxy"),
- out->get_vpos()),
+ get_reg_int("opmaxx"), get_reg_int("opmaxy"),
// page offset + line length
get_reg_int(".o") + get_reg_int(".l"),
name, hresolution, vresolution, get_reg_str(".F"));
--- groff-cvs/tmac/html.tmac Wed Jan 17 14:17:26 2001
+++ groff-html/tmac/html.tmac Thu Apr 12 12:59:42 2001
@@ -39,7 +39,6 @@
.if d eh .eh ''''
.tl ''''
.\" it doesn't make sense to use hyphenation with html, so we turn it off.
-.\" avoid line breaks after hyphen-like characters.
.hy 0
.nr HY 0
.\" avoid line breaks after hyphen-like characters.
--- groff-cvs/tmac/s.tmac Mon Mar 19 15:33:04 2001
+++ groff-html/tmac/s.tmac Thu Apr 12 12:59:42 2001
@@ -1156,7 +1156,7 @@
. ie '\*(.T'html' \{\
. if \\n[dl]+1n<=\\n[\\n[.ev]:ai] .HTML-TAG ".ip"
. ti 0
-\\*[par*label]
+\&\\$1
. br
. \}
. el \{\
--- groff-cvs/tmac/www.tmac Fri Mar 30 13:52:03 2001
+++ groff-html/tmac/www.tmac Thu Apr 12 12:59:42 2001
@@ -160,7 +160,7 @@
. if r ps4html .begin \{\
. image \\$2 \\$1.png
. bp
-. tl '''
+. tl ''''
\O0\O1
. \}
. if '\*(.T'html' .begin \{
@@ -172,12 +172,8 @@
.\" HTML-IMAGE-END - terminates an image for html
.\"
.de HTML-IMAGE-END
-. if r ps4html .end \{\
-\O2\O1
-. \}
-. if '\*(.T'html' .end \{
-\O2\O1
-. \}
+. if r ps4html \O2\O1\O4
+. if '\*(.T'html' \O2\O1\O4
..
.nr png-no 0
.\"
- [Groff] HTML output in Mozilla, Bruno Haible, 2001/04/09
- Re: [Groff] HTML output in Mozilla, Gaius Mulley, 2001/04/10
- Re: [Groff] HTML output in Mozilla, Werner LEMBERG, 2001/04/11
- Re: [Groff] HTML output in Mozilla, Werner LEMBERG, 2001/04/13
- Re: [Groff] HTML output in Mozilla, Gaius Mulley, 2001/04/13
- Re: [Groff] HTML output in Mozilla, Werner LEMBERG, 2001/04/14
- Re: [Groff] HTML output in Mozilla, Werner LEMBERG, 2001/04/14