[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[no subject]
From: |
Patrice Dumas |
Date: |
Thu, 4 Jan 2024 10:19:39 -0500 (EST) |
branch: master
commit 8b8f24f89e7faabad058c01f33e22fd258511a50
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Thu Jan 4 16:19:35 2024 +0100
* tp/Texinfo/Convert/HTML.pm (_preformatted_class): fix prototype.
* tp/Texinfo/Convert/HTML.pm (_convert_preformatted_type): rearrange
code.
* tp/Texinfo/XS/convert/convert_html.c (trim_trailing_content): add
from convert_tab_command.
* tp/Texinfo/XS/convert/convert_html.c (convert_paragraph_type):
change code to use a TEXT and free memory in all the situations.
* tp/Texinfo/XS/convert/convert_html.c (preformatted_class)
(convert_preformatted_type, types_internal_conversion_table):
add preformatted_class, implement convert_preformatted_type.
---
ChangeLog | 17 +++
tp/Texinfo/Convert/HTML.pm | 16 +--
tp/Texinfo/XS/convert/convert_html.c | 234 ++++++++++++++++++++++++++++++-----
3 files changed, 228 insertions(+), 39 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 68cf583fb5..e70a041cde 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2024-01-04 Patrice Dumas <pertusus@free.fr>
+
+ * tp/Texinfo/Convert/HTML.pm (_preformatted_class): fix prototype.
+
+ * tp/Texinfo/Convert/HTML.pm (_convert_preformatted_type): rearrange
+ code.
+
+ * tp/Texinfo/XS/convert/convert_html.c (trim_trailing_content): add
+ from convert_tab_command.
+
+ * tp/Texinfo/XS/convert/convert_html.c (convert_paragraph_type):
+ change code to use a TEXT and free memory in all the situations.
+
+ * tp/Texinfo/XS/convert/convert_html.c (preformatted_class)
+ (convert_preformatted_type, types_internal_conversion_table):
+ add preformatted_class, implement convert_preformatted_type.
+
2024-01-04 Patrice Dumas <pertusus@free.fr>
* tp/Texinfo/XS/convert/convert_html.c (convert_paragraph_type),
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index 376f5bf61f..860b4b3410 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -6828,7 +6828,7 @@ $default_types_open{'paragraph'} =
\&_open_inline_container_type;
$default_types_open{'preformatted'} = \&_open_inline_container_type;
-sub _preformatted_class()
+sub _preformatted_class($)
{
my $self = shift;
my $pre_class;
@@ -6857,13 +6857,16 @@ sub _convert_preformatted_type($$$$)
return '' if ($content eq '');
- my $pre_class = $self->_preformatted_class();
-
if (top_block_command($self) eq 'multitable') {
$content =~ s/^\s*//;
$content =~ s/\s*$//;
}
+ if (in_string($self)) {
+ return $content;
+ }
+
+ my $pre_class;
# menu_entry_description is always in a preformatted container
# in the tree, as the whole menu is meant to be an
# environment where spaces and newlines are preserved.
@@ -6881,10 +6884,9 @@ sub _convert_preformatted_type($$$$)
}
}
- if (in_string($self)) {
- return $content;
- }
$content =~ s/^\n/\n\n/; # a newline immediately after a <pre> is ignored.
+
+ $pre_class = _preformatted_class($self) if (!defined($pre_class));
my $result = $self->html_attribute_class('pre', [$pre_class]).'>'
. $content . '</pre>';
@@ -7286,7 +7288,7 @@ sub _convert_menu_entry_type($$$)
}
if (not $in_string) {
- my $pre_class = $self->_preformatted_class();
+ my $pre_class = _preformatted_class($self);
$result_name_node = $self->html_attribute_class('pre', [$pre_class]).'>'
. $result_name_node . '</pre>';
}
diff --git a/tp/Texinfo/XS/convert/convert_html.c
b/tp/Texinfo/XS/convert/convert_html.c
index c82fd3a3d4..0a89cf8924 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -10966,6 +10966,27 @@ convert_item_command (CONVERTER *self, const enum
command_id cmd,
}
}
+static char *
+trim_trailing_content (const char *content)
+{
+ char *trimmed_content = strdup (content);
+ size_t str_len = strlen (trimmed_content);
+ if (str_len > 0)
+ {
+ char *q = trimmed_content + str_len - 1;
+ while (q > trimmed_content)
+ {
+ if (!strchr (whitespace_chars, *q))
+ {
+ break;
+ }
+ q--;
+ }
+ *(q +1) = '\0';
+ }
+ return trimmed_content;
+}
+
void
convert_tab_command (CONVERTER *self, const enum command_id cmd,
const ELEMENT *element,
@@ -10983,23 +11004,8 @@ convert_tab_command (CONVERTER *self, const enum
command_id cmd,
if (content)
{
const char *p = content;
- size_t str_len;
p += strspn (p, whitespace_chars);
- trimmed_content = strdup (p);
- str_len = strlen (trimmed_content);
- if (str_len > 0)
- {
- char *q = trimmed_content + str_len - 1;
- while (q > trimmed_content)
- {
- if (!strchr (whitespace_chars, *q))
- {
- break;
- }
- q--;
- }
- *(q +1) = '\0';
- }
+ trimmed_content = trim_trailing_content (p);
}
else
trimmed_content = strdup ("");
@@ -12720,10 +12726,27 @@ convert_paragraph_type (CONVERTER *self, const enum
element_type type,
const ELEMENT *element, const char *content,
TEXT *result)
{
+ TEXT content_text;
enum command_id align_cmd;
char *associated_content
= html_get_associated_formatted_inline_content (self, element, 0);
+ text_init (&content_text);
+
+ if (associated_content)
+ {
+ text_append (&content_text, associated_content);
+ free (associated_content);
+ }
+ if (content)
+ text_append (&content_text, content);
+
+ if (content_text.end <= 0)
+ {
+ free (content_text.text);
+ return;
+ }
+
if (html_paragraph_number (self) == 1)
{
enum command_id in_format_cmd = html_top_block_command (self);
@@ -12737,10 +12760,8 @@ convert_paragraph_type (CONVERTER *self, const enum
element_type type,
there are no paragraphs, but preformatted */
|| in_format_cmd == CM_menu)
{
- if (associated_content)
- text_append (result, associated_content);
- if (content)
- text_append (result, content);
+ text_append (result, content_text.text);
+ free (content_text.text);
return;
}
}
@@ -12748,18 +12769,16 @@ convert_paragraph_type (CONVERTER *self, const enum
element_type type,
if (html_in_string (self))
{
- if (associated_content)
- text_append (result, associated_content);
- if (content)
- text_append (result, content);
+ text_append (result, content_text.text);
+ free (content_text.text);
return;
}
- if ((!content || content[strspn (content, whitespace_chars)] == '\0')
- && (!associated_content
- || associated_content[strspn
- (associated_content, whitespace_chars)] == '\0'))
- return;
+ if (content_text.text[strspn (content_text.text, whitespace_chars)] == '\0')
+ {
+ free (content_text.text);
+ return;
+ }
align_cmd = html_in_align (self);
@@ -12783,12 +12802,162 @@ convert_paragraph_type (CONVERTER *self, const enum
element_type type,
else
text_append_n (result, "<p>", 3);
+ text_append (result, content_text.text);
+ free (content_text.text);
+
+ text_append_n (result, "</p>", 4);
+}
+
+static char *
+preformatted_class (CONVERTER *self)
+{
+ COMMAND_OR_TYPE *cur_pre_class = 0;
+ COMMAND_OR_TYPE_STACK *pre_classes
+ = html_preformatted_classes_stack (self);
+ size_t i;
+ for (i = 0; i < pre_classes->top; i++)
+ {
+ COMMAND_OR_TYPE *cmd_or_type = &pre_classes->stack[i];
+ if (!(cur_pre_class
+ && (cur_pre_class->variety == CTV_type_command
+ && builtin_command_data[cur_pre_class->cmd].flags
+ & CF_preformatted_code)
+ && (!((cmd_or_type->variety == CTV_type_command
+ && builtin_command_data[cmd_or_type->cmd].flags
+ & CF_preformatted_code)
+ || cmd_or_type->cmd == CM_menu))))
+ cur_pre_class = cmd_or_type;
+ }
+ if (cur_pre_class)
+ {
+ char *pre_class = 0;
+ if (cur_pre_class->variety == CTV_type_command)
+ {
+ xasprintf (&pre_class, "%s-preformatted",
+ builtin_command_name (cur_pre_class->cmd));
+ }
+ else if (cur_pre_class->variety == CTV_type_type)
+
+ {
+ xasprintf (&pre_class, "%s-preformatted",
+ self->pre_class_types[cur_pre_class->type]);
+ }
+ if (pre_class)
+ return pre_class;
+ }
+ /* shold not happen */
+ return 0;
+}
+
+void
+convert_preformatted_type (CONVERTER *self, const enum element_type type,
+ const ELEMENT *element, const char *content,
+ TEXT *result)
+{
+ TEXT content_text;
+ char *trimmed_content;
+ enum command_id in_format_cmd;
+ char *pre_class = 0;
+ int in_def = 0;
+ char *attribute_class;
+ STRING_LIST *classes;
+
+ char *associated_content
+ = html_get_associated_formatted_inline_content (self, element, 0);
+
+ text_init (&content_text);
+
if (associated_content)
- text_append (result, associated_content);
+ {
+ text_append (&content_text, associated_content);
+ free (associated_content);
+ }
if (content)
- text_append (result, content);
+ text_append (&content_text, content);
- text_append_n (result, "</p>", 4);
+ if (content_text.end <= 0)
+ {
+ free (content_text.text);
+ return;
+ }
+
+ in_format_cmd = html_top_block_command (self);
+ if (in_format_cmd == CM_multitable)
+ {
+ const char *p = content_text.text;
+ p += strspn (p, whitespace_chars);
+ trimmed_content = trim_trailing_content (p);
+ free (content_text.text);
+ }
+ else
+ trimmed_content = content_text.text;
+
+ if (html_in_string (self))
+ {
+ text_append (result, trimmed_content);
+ free (trimmed_content);
+ return;
+ }
+
+ /* menu_entry_description is always in a preformatted container
+ in the tree, as the whole menu is meant to be an
+ environment where spaces and newlines are preserved. */
+ if (element->parent && element->parent->type == ET_menu_entry_description)
+ {
+ if (!html_inside_preformatted (self))
+ {
+ /* If not in preformatted block command,
+ we don't preserve spaces and newlines in menu_entry_description,
+ instead the whole menu_entry is in a table, so no <pre> in that situation
+ */
+ text_append (result, trimmed_content);
+ free (trimmed_content);
+ return;
+ }
+ else
+ {
+ /* if directly in description, we want to avoid the linebreak that
+ comes with pre being a block level element, so set a special class */
+ pre_class = strdup ("menu-entry-description-preformatted");
+ }
+ }
+
+ if (!pre_class)
+ pre_class = preformatted_class (self);
+
+ /* this may happen with lines without textual content
+ between a def* and def*x. */
+ if (element->parent
+ && (builtin_command_data[element->parent->cmd].flags & CF_def
+ || element->parent->cmd == CM_defblock))
+ {
+ in_def = 1;
+ text_append_n (result, "<dd>", 4);
+ }
+
+ classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+ memset (classes, 0, sizeof (STRING_LIST));
+ if (pre_class)
+ {
+ add_string (pre_class, classes);
+ free (pre_class);
+ }
+ attribute_class = html_attribute_class (self, "pre", classes);
+ text_append (result, attribute_class);
+ text_append_n (result, ">", 1);
+ free (attribute_class);
+ destroy_strings_list (classes);
+
+ /* a newline immediately after a <pre> is ignored. */
+ if (trimmed_content[0] == '\n')
+ text_append_n (result, "\n", 1);
+ text_append (result, trimmed_content);
+ free (trimmed_content);
+
+ text_append_n (result, "</pre>", 6);
+
+ if (in_def)
+ text_append_n (result, "</dd>", 5);
}
#define static_class(name, class) \
@@ -13205,6 +13374,7 @@ convert_row_type (CONVERTER *self, const enum
element_type type,
static TYPE_INTERNAL_CONVERSION types_internal_conversion_table[] = {
{ET_def_line, &convert_def_line_type},
{ET_paragraph, &convert_paragraph_type},
+ {ET_preformatted, &convert_preformatted_type},
{ET_row, &convert_row_type},
{ET_table_term, &convert_table_term_type},
{ET_text, &convert_text},