summaryrefslogtreecommitdiffstats
path: root/src/viewer/nroff.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/viewer/nroff.c')
-rw-r--r--src/viewer/nroff.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/src/viewer/nroff.c b/src/viewer/nroff.c
new file mode 100644
index 0000000..14dacd5
--- /dev/null
+++ b/src/viewer/nroff.c
@@ -0,0 +1,287 @@
+/*
+ Internal file viewer for the Midnight Commander
+ Functions for searching in nroff-like view
+
+ Copyright (C) 1994-2023
+ Free Software Foundation, Inc.
+
+ Written by:
+ Miguel de Icaza, 1994, 1995, 1998
+ Janne Kukonlehto, 1994, 1995
+ Jakub Jelinek, 1995
+ Joseph M. Hinkle, 1996
+ Norbert Warmuth, 1997
+ Pavel Machek, 1998
+ Roland Illig <roland.illig@gmx.de>, 2004, 2005
+ Slava Zanko <slavazanko@google.com>, 2009
+ Andrew Borodin <aborodin@vmail.ru>, 2009
+ Ilia Maslakov <il.smind@gmail.com>, 2009
+
+ This file is part of the Midnight Commander.
+
+ The Midnight Commander is free software: you can redistribute it
+ and/or modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ The Midnight Commander is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lib/global.h"
+#include "lib/tty/tty.h"
+#include "lib/skin.h"
+#ifdef HAVE_CHARSET
+#include "lib/charsets.h"
+#endif
+
+#include "internal.h"
+
+/*** global variables ****************************************************************************/
+
+/*** file scope macro definitions ****************************************************************/
+
+/*** file scope type declarations ****************************************************************/
+
+/*** forward declarations (file scope functions) *************************************************/
+
+/*** file scope variables ************************************************************************/
+
+/* --------------------------------------------------------------------------------------------- */
+/*** file scope functions ************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+static gboolean
+mcview_nroff_get_char (mcview_nroff_t * nroff, int *ret_val, off_t nroff_index)
+{
+ int c = 0;
+
+#ifdef HAVE_CHARSET
+ if (nroff->view->utf8)
+ {
+ if (!mcview_get_utf (nroff->view, nroff_index, &c, &nroff->char_length))
+ {
+ /* we need got symbol in any case */
+ nroff->char_length = 1;
+ if (!mcview_get_byte (nroff->view, nroff_index, &c) || !g_ascii_isprint (c))
+ return FALSE;
+ }
+ }
+ else
+#endif
+ {
+ nroff->char_length = 1;
+ if (!mcview_get_byte (nroff->view, nroff_index, &c))
+ return FALSE;
+ }
+
+ *ret_val = c;
+
+ return g_unichar_isprint (c);
+}
+
+/* --------------------------------------------------------------------------------------------- */
+/*** public functions ****************************************************************************/
+/* --------------------------------------------------------------------------------------------- */
+
+int
+mcview__get_nroff_real_len (WView * view, off_t start, off_t length)
+{
+ mcview_nroff_t *nroff;
+ int ret = 0;
+ off_t i = 0;
+
+ if (!view->mode_flags.nroff)
+ return 0;
+
+ nroff = mcview_nroff_seq_new_num (view, start);
+ if (nroff == NULL)
+ return 0;
+ while (i < length)
+ {
+ switch (nroff->type)
+ {
+ case NROFF_TYPE_BOLD:
+ ret += 1 + nroff->char_length; /* real char length and 0x8 */
+ break;
+ case NROFF_TYPE_UNDERLINE:
+ ret += 2; /* underline symbol and ox8 */
+ break;
+ default:
+ break;
+ }
+ i += nroff->char_length;
+ mcview_nroff_seq_next (nroff);
+ }
+
+ mcview_nroff_seq_free (&nroff);
+ return ret;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+mcview_nroff_t *
+mcview_nroff_seq_new_num (WView * view, off_t lc_index)
+{
+ mcview_nroff_t *nroff;
+
+ nroff = g_try_malloc0 (sizeof (mcview_nroff_t));
+ if (nroff != NULL)
+ {
+ nroff->index = lc_index;
+ nroff->view = view;
+ mcview_nroff_seq_info (nroff);
+ }
+ return nroff;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+mcview_nroff_t *
+mcview_nroff_seq_new (WView * view)
+{
+ return mcview_nroff_seq_new_num (view, (off_t) 0);
+
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+void
+mcview_nroff_seq_free (mcview_nroff_t ** nroff)
+{
+ if (nroff == NULL || *nroff == NULL)
+ return;
+ MC_PTR_FREE (*nroff);
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+nroff_type_t
+mcview_nroff_seq_info (mcview_nroff_t * nroff)
+{
+ int next, next2;
+
+ if (nroff == NULL)
+ return NROFF_TYPE_NONE;
+ nroff->type = NROFF_TYPE_NONE;
+
+ if (!mcview_nroff_get_char (nroff, &nroff->current_char, nroff->index))
+ return nroff->type;
+
+ if (!mcview_get_byte (nroff->view, nroff->index + nroff->char_length, &next) || next != '\b')
+ return nroff->type;
+
+ if (!mcview_nroff_get_char (nroff, &next2, nroff->index + 1 + nroff->char_length))
+ return nroff->type;
+
+ if (nroff->current_char == '_' && next2 == '_')
+ {
+ nroff->type = (nroff->prev_type == NROFF_TYPE_BOLD)
+ ? NROFF_TYPE_BOLD : NROFF_TYPE_UNDERLINE;
+
+ }
+ else if (nroff->current_char == next2)
+ {
+ nroff->type = NROFF_TYPE_BOLD;
+ }
+ else if (nroff->current_char == '_')
+ {
+ nroff->current_char = next2;
+ nroff->type = NROFF_TYPE_UNDERLINE;
+ }
+ else if (nroff->current_char == '+' && next2 == 'o')
+ {
+ /* ??? */
+ }
+ return nroff->type;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+int
+mcview_nroff_seq_next (mcview_nroff_t * nroff)
+{
+ if (nroff == NULL)
+ return -1;
+
+ nroff->prev_type = nroff->type;
+
+ switch (nroff->type)
+ {
+ case NROFF_TYPE_BOLD:
+ nroff->index += 1 + nroff->char_length;
+ break;
+ case NROFF_TYPE_UNDERLINE:
+ nroff->index += 2;
+ break;
+ default:
+ break;
+ }
+
+ nroff->index += nroff->char_length;
+
+ mcview_nroff_seq_info (nroff);
+ return nroff->current_char;
+}
+
+/* --------------------------------------------------------------------------------------------- */
+
+int
+mcview_nroff_seq_prev (mcview_nroff_t * nroff)
+{
+ int prev;
+ off_t prev_index, prev_index2;
+
+ if (nroff == NULL)
+ return -1;
+
+ nroff->prev_type = NROFF_TYPE_NONE;
+
+ if (nroff->index == 0)
+ return -1;
+
+ prev_index = nroff->index - 1;
+
+ while (prev_index != 0)
+ {
+ if (mcview_nroff_get_char (nroff, &nroff->current_char, prev_index))
+ break;
+ prev_index--;
+ }
+ if (prev_index == 0)
+ {
+ nroff->index--;
+ mcview_nroff_seq_info (nroff);
+ return nroff->current_char;
+ }
+
+ prev_index--;
+
+ if (!mcview_get_byte (nroff->view, prev_index, &prev) || prev != '\b')
+ {
+ nroff->index = prev_index;
+ mcview_nroff_seq_info (nroff);
+ return nroff->current_char;
+ }
+ prev_index2 = prev_index - 1;
+
+ while (prev_index2 != 0)
+ {
+ if (mcview_nroff_get_char (nroff, &prev, prev_index))
+ break;
+ prev_index2--;
+ }
+
+ nroff->index = (prev_index2 == 0) ? prev_index : prev_index2;
+ mcview_nroff_seq_info (nroff);
+ return nroff->current_char;
+}
+
+/* --------------------------------------------------------------------------------------------- */