[yelp] Spacing changes to fix horizontal spacing for perl(1) and man(1).
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp] Spacing changes to fix horizontal spacing for perl(1) and man(1).
- Date: Mon, 20 Dec 2010 15:47:13 +0000 (UTC)
commit 2337a58a8a1ec110c83803745451209b76714a8e
Author: Rupert Swarbrick <rswarbrick gmail com>
Date: Thu Dec 16 00:32:54 2010 +0000
Spacing changes to fix horizontal spacing for perl(1) and man(1).
libyelp/yelp-man-parser.c | 122 +++++++++++++++++++++++++++----------------
stylesheets/man2html.xsl.in | 18 ++----
2 files changed, 82 insertions(+), 58 deletions(-)
---
diff --git a/libyelp/yelp-man-parser.c b/libyelp/yelp-man-parser.c
index 645d9fd..03507ac 100644
--- a/libyelp/yelp-man-parser.c
+++ b/libyelp/yelp-man-parser.c
@@ -73,7 +73,7 @@ struct _YelpManParser {
guint char_height;
/* Count the number of lines we've parsed (needed to get prologue) */
- guint lines_parsed;
+ guint line_no;
/* The x f k name command sets the k'th register to be name. */
gchar* font_registers[MAN_FONTS];
@@ -113,6 +113,13 @@ struct _YelpManParser {
* parse_h.
*/
guint N_count;
+
+ /* Keep track of whether the last character was a space. We can't
+ * just do this by looking at the last char of accumulator,
+ * because if there's a font change, it gets zeroed. This gets set
+ * to TRUE by parse_w and is FALSE the rest of the time.
+ */
+ gboolean last_char_was_space;
};
static gboolean parser_parse_line (YelpManParser *parser, GError **error);
@@ -160,6 +167,7 @@ static struct LineParsePair line_parsers[] = {
static void finish_span (YelpManParser *parser);
static guint dx_to_em_count (YelpManParser *parser, guint dx);
static void append_nbsps (YelpManParser *parser, guint k);
+static void deal_with_newlines (YelpManParser *parser);
/******************************************************************************/
/* Translations for the 'C' command. This is indeed hackish, but the
@@ -358,6 +366,7 @@ yelp_man_parser_parse_file (YelpManParser *parser,
NULL, NULL);
if (parser->buffer == NULL) break;
+ parser->line_no++;
ret = parser_parse_line (parser, error);
g_free (parser->buffer);
@@ -440,7 +449,7 @@ get_font (const YelpManParser *parser)
static gboolean
parser_parse_line (YelpManParser *parser, GError **error)
{
- if (parser->lines_parsed < 3)
+ if (parser->line_no <= 3)
return parse_prologue_line (parser, error);
const struct LineParsePair *p = line_parsers;
@@ -456,8 +465,7 @@ parser_parse_line (YelpManParser *parser, GError **error)
static gboolean
parse_prologue_line (YelpManParser *parser, GError **error)
{
- parser->lines_parsed++;
- if (parser->lines_parsed != 2) return TRUE;
+ if (parser->line_no != 2) return TRUE;
/* This is the interesting line, which should look like
x res 240 24 40
@@ -516,7 +524,6 @@ parse_h (YelpManParser *parser, GError **error)
{
guint dx;
int k;
- const gchar *str;
if (SSCANF ("h%u", 1, &dx)) {
RAISE_PARSE_ERROR ("Invalid h line from troff: %s");
@@ -529,21 +536,29 @@ parse_h (YelpManParser *parser, GError **error)
* insert nonbreaking spaces (eugh!)
*
* Of course we don't want to do this when chained from wh24 or
- * whatever, so check that accumulator is nonempty and the last
- * character isn't ' '.
+ * whatever, so use the last_char_was_space flag
+ * but... unfortunately some documents actually use stuff like
+ * wh96 for spacing (eg the lists in perl(1)). So (very hackish!),
+ * ignore double spaces, since that's probably just been put in to
+ * make the text justified (eugh), but allow bigger jumps.
+ *
+ * Incidentally, the perl manual here has bizarre gaps in the
+ * synopsis section. God knows why, but man displays them too so
+ * it's not our fault! :-)
*/
- str = parser->accumulator->str;
+ k = dx_to_em_count (parser, dx);
+
if ((parser->sheet_node) &&
- (str[0] != '\0') &&
- (str[strlen (str)-1] != ' ')) {
+ ((!parser->last_char_was_space) || (k > 2))) {
- k = dx_to_em_count (parser, dx) - parser->N_count;
- parser->N_count = 0;
+ k -= parser->N_count;
if (k < 0) k = 0;
append_nbsps (parser, k);
}
+ parser->N_count = 0;
+
return TRUE;
}
@@ -649,7 +664,10 @@ parse_w (YelpManParser *parser, GError **error)
}
parser->buffer++;
+ parser->last_char_was_space = TRUE;
+
ret = parser_parse_line (parser, error);
+
parser->buffer--;
return ret;
}
@@ -657,8 +675,6 @@ parse_w (YelpManParser *parser, GError **error)
static gboolean
parse_body_text (YelpManParser *parser, GError **error)
{
- gchar tmp[64];
-
/*
It's this function which is responsible for trying to get *some*
semantic information back out of the manual page.
@@ -682,44 +698,16 @@ parse_body_text (YelpManParser *parser, GError **error)
xmlAddChild (xmlDocGetRootElement (parser->doc),
xmlNewNode (NULL, BAD_CAST "section"));
}
- if (parser->section_state == SECTION_TITLE) goto do_append;
- /*
- Here we've got real body text! If newline is true, this is the
- first word on a line.
-
- In which case, we check to see whether hpos agrees with the
- current sheet's indent. If so (or if there isn't a sheet yet!),
- we just add to the accumulator. If not, start a new sheet with
- the correct indent.
+ if (parser->section_state != SECTION_TITLE)
+ deal_with_newlines (parser);
- If we aren't the first word on the line, just add to the
- accumulator.
- */
- if ((!parser->sheet_node) ||
- (parser->newline && (parser->hpos != parser->sheet_indent))) {
- /* We don't need to worry about finishing the current sheet,
- since the accumulator etc. get cleared on newlines and we
- know we're at the start of a line.
- */
- parser->sheet_node =
- xmlAddChild (parser->section_node,
- xmlNewNode (NULL, BAD_CAST "sheet"));
- parser->sheet_indent = parser->hpos;
-
- /* The indent is specified in em's. */
- snprintf (tmp, 64, "%d",
- (int)(dx_to_em_count (parser, parser->hpos) / 1.5));
- xmlNewProp (parser->sheet_node, BAD_CAST "indent", tmp);
- }
-
- do_append:
g_string_append (parser->accumulator, parser->buffer+1);
/* Move hpos forward per char */
parser->hpos += strlen (parser->buffer+1) * parser->char_width;
-
- parser->newline = FALSE;
+ parser->last_char_was_space = FALSE;
+ parser->N_count = 0;
return TRUE;
}
@@ -755,6 +743,7 @@ parse_n (YelpManParser *parser, GError **error)
}
parser->newline = TRUE;
+ parser->last_char_was_space = FALSE;
return TRUE;
}
@@ -793,6 +782,9 @@ parse_N (YelpManParser *parser, GError **error)
RAISE_PARSE_ERROR ("Bizarrely many nbsps in N line: %s");
}
+ deal_with_newlines (parser);
+ parser->last_char_was_space = FALSE;
+
if (n < 0) {
append_nbsps (parser, -n);
parser->N_count += -n;
@@ -843,6 +835,9 @@ parse_C (YelpManParser *parser, GError **error)
code = 65533; /* Unicode replacement character */
}
+ deal_with_newlines (parser);
+ parser->last_char_was_space = FALSE;
+
/* Output buffer must be length >= 6. 16 >= 6, so we're ok. */
len = g_unichar_to_utf8 (code, name);
name[len] = '\0';
@@ -852,3 +847,38 @@ parse_C (YelpManParser *parser, GError **error)
return TRUE;
}
+
+static void
+deal_with_newlines (YelpManParser *parser)
+{
+ /*
+ If newline is true, this is the first word on a line.
+
+ In which case, we check to see whether hpos agrees with the
+ current sheet's indent. If so (or if there isn't a sheet yet!),
+ we just add to the accumulator. If not, start a new sheet with
+ the correct indent.
+
+ If we aren't the first word on the line, just add to the
+ accumulator.
+ */
+ gchar tmp[64];
+
+ if ((!parser->sheet_node) ||
+ (parser->newline && (parser->hpos != parser->sheet_indent))) {
+ /* We don't need to worry about finishing the current sheet,
+ since the accumulator etc. get cleared on newlines and we
+ know we're at the start of a line.
+ */
+ parser->sheet_node =
+ xmlAddChild (parser->section_node,
+ xmlNewNode (NULL, BAD_CAST "sheet"));
+ parser->sheet_indent = parser->hpos;
+ }
+
+ if (parser->newline) {
+ append_nbsps (parser, dx_to_em_count (parser, parser->hpos));
+ }
+
+ parser->newline = FALSE;
+}
diff --git a/stylesheets/man2html.xsl.in b/stylesheets/man2html.xsl.in
index 90dbc05..14a26c9 100644
--- a/stylesheets/man2html.xsl.in
+++ b/stylesheets/man2html.xsl.in
@@ -51,22 +51,16 @@
<xsl:value-of select="title"/>
</h2>
- <xsl:apply-templates select="sheet"/>
+ <div class="section-contents" style="font-family: monospace;">
+ <xsl:apply-templates select="sheet"/>
+ </div>
</div>
</xsl:template>
<xsl:template match="sheet">
- <xsl:element name="div">
- <xsl:attribute name="style">
- <xsl:text>padding-left: </xsl:text>
- <xsl:value-of select="@indent"/>
- <xsl:text>em; font-family: monospace;</xsl:text>
- </xsl:attribute>
-
- <p>
- <xsl:apply-templates select="span|br"/>
- </p>
- </xsl:element>
+ <div style="margin: 0px;">
+ <p><xsl:apply-templates select="span|br"/></p>
+ </div>
</xsl:template>
<xsl:template match="span">
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]