root/src/viewer/nroff.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. mcview_nroff_get_char
  2. mcview__get_nroff_real_len
  3. mcview_nroff_seq_new_num
  4. mcview_nroff_seq_new
  5. mcview_nroff_seq_free
  6. mcview_nroff_seq_info
  7. mcview_nroff_seq_next
  8. mcview_nroff_seq_prev

   1 /*
   2    Internal file viewer for the Midnight Commander
   3    Functions for searching in nroff-like view
   4 
   5    Copyright (C) 1994-2025
   6    Free Software Foundation, Inc.
   7 
   8    Written by:
   9    Miguel de Icaza, 1994, 1995, 1998
  10    Janne Kukonlehto, 1994, 1995
  11    Jakub Jelinek, 1995
  12    Joseph M. Hinkle, 1996
  13    Norbert Warmuth, 1997
  14    Pavel Machek, 1998
  15    Roland Illig <roland.illig@gmx.de>, 2004, 2005
  16    Slava Zanko <slavazanko@google.com>, 2009
  17    Andrew Borodin <aborodin@vmail.ru>, 2009
  18    Ilia Maslakov <il.smind@gmail.com>, 2009
  19 
  20    This file is part of the Midnight Commander.
  21 
  22    The Midnight Commander is free software: you can redistribute it
  23    and/or modify it under the terms of the GNU General Public License as
  24    published by the Free Software Foundation, either version 3 of the License,
  25    or (at your option) any later version.
  26 
  27    The Midnight Commander is distributed in the hope that it will be useful,
  28    but WITHOUT ANY WARRANTY; without even the implied warranty of
  29    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  30    GNU General Public License for more details.
  31 
  32    You should have received a copy of the GNU General Public License
  33    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  34  */
  35 
  36 #include <config.h>
  37 
  38 #include "lib/global.h"
  39 #include "lib/tty/tty.h"
  40 #include "lib/skin.h"
  41 #ifdef HAVE_CHARSET
  42 #    include "lib/charsets.h"
  43 #endif
  44 
  45 #include "internal.h"
  46 
  47 /*** global variables ****************************************************************************/
  48 
  49 /*** file scope macro definitions ****************************************************************/
  50 
  51 /*** file scope type declarations ****************************************************************/
  52 
  53 /*** forward declarations (file scope functions) *************************************************/
  54 
  55 /*** file scope variables ************************************************************************/
  56 
  57 /* --------------------------------------------------------------------------------------------- */
  58 /*** file scope functions ************************************************************************/
  59 /* --------------------------------------------------------------------------------------------- */
  60 
  61 static gboolean
  62 mcview_nroff_get_char (mcview_nroff_t *nroff, int *ret_val, off_t nroff_index)
     /* [previous][next][first][last][top][bottom][index][help]  */
  63 {
  64     int c = 0;
  65 
  66 #ifdef HAVE_CHARSET
  67     if (nroff->view->utf8)
  68     {
  69         if (!mcview_get_utf (nroff->view, nroff_index, &c, &nroff->char_length))
  70         {
  71             // we need got symbol in any case
  72             nroff->char_length = 1;
  73             if (!mcview_get_byte (nroff->view, nroff_index, &c) || !g_ascii_isprint (c))
  74                 return FALSE;
  75         }
  76     }
  77     else
  78 #endif
  79     {
  80         nroff->char_length = 1;
  81         if (!mcview_get_byte (nroff->view, nroff_index, &c))
  82             return FALSE;
  83     }
  84 
  85     *ret_val = c;
  86 
  87     return g_unichar_isprint (c);
  88 }
  89 
  90 /* --------------------------------------------------------------------------------------------- */
  91 /*** public functions ****************************************************************************/
  92 /* --------------------------------------------------------------------------------------------- */
  93 
  94 int
  95 mcview__get_nroff_real_len (WView *view, off_t start, off_t length)
     /* [previous][next][first][last][top][bottom][index][help]  */
  96 {
  97     mcview_nroff_t *nroff;
  98     int ret = 0;
  99     off_t i = 0;
 100 
 101     if (!view->mode_flags.nroff)
 102         return 0;
 103 
 104     nroff = mcview_nroff_seq_new_num (view, start);
 105     if (nroff == NULL)
 106         return 0;
 107     while (i < length)
 108     {
 109         switch (nroff->type)
 110         {
 111         case NROFF_TYPE_BOLD:
 112             ret += 1 + nroff->char_length;  // real char length and 0x8
 113             break;
 114         case NROFF_TYPE_UNDERLINE:
 115             ret += 2;  // underline symbol and ox8
 116             break;
 117         default:
 118             break;
 119         }
 120         i += nroff->char_length;
 121         mcview_nroff_seq_next (nroff);
 122     }
 123 
 124     mcview_nroff_seq_free (&nroff);
 125     return ret;
 126 }
 127 
 128 /* --------------------------------------------------------------------------------------------- */
 129 
 130 mcview_nroff_t *
 131 mcview_nroff_seq_new_num (WView *view, off_t lc_index)
     /* [previous][next][first][last][top][bottom][index][help]  */
 132 {
 133     mcview_nroff_t *nroff;
 134 
 135     nroff = g_try_malloc0 (sizeof (mcview_nroff_t));
 136     if (nroff != NULL)
 137     {
 138         nroff->index = lc_index;
 139         nroff->view = view;
 140         mcview_nroff_seq_info (nroff);
 141     }
 142     return nroff;
 143 }
 144 
 145 /* --------------------------------------------------------------------------------------------- */
 146 
 147 mcview_nroff_t *
 148 mcview_nroff_seq_new (WView *view)
     /* [previous][next][first][last][top][bottom][index][help]  */
 149 {
 150     return mcview_nroff_seq_new_num (view, (off_t) 0);
 151 }
 152 
 153 /* --------------------------------------------------------------------------------------------- */
 154 
 155 void
 156 mcview_nroff_seq_free (mcview_nroff_t **nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 157 {
 158     if (nroff == NULL || *nroff == NULL)
 159         return;
 160     MC_PTR_FREE (*nroff);
 161 }
 162 
 163 /* --------------------------------------------------------------------------------------------- */
 164 
 165 nroff_type_t
 166 mcview_nroff_seq_info (mcview_nroff_t *nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 167 {
 168     int next, next2;
 169 
 170     if (nroff == NULL)
 171         return NROFF_TYPE_NONE;
 172     nroff->type = NROFF_TYPE_NONE;
 173 
 174     if (!mcview_nroff_get_char (nroff, &nroff->current_char, nroff->index))
 175         return nroff->type;
 176 
 177     if (!mcview_get_byte (nroff->view, nroff->index + nroff->char_length, &next) || next != '\b')
 178         return nroff->type;
 179 
 180     if (!mcview_nroff_get_char (nroff, &next2, nroff->index + 1 + nroff->char_length))
 181         return nroff->type;
 182 
 183     if (nroff->current_char == '_' && next2 == '_')
 184     {
 185         nroff->type =
 186             (nroff->prev_type == NROFF_TYPE_BOLD) ? NROFF_TYPE_BOLD : NROFF_TYPE_UNDERLINE;
 187     }
 188     else if (nroff->current_char == next2)
 189     {
 190         nroff->type = NROFF_TYPE_BOLD;
 191     }
 192     else if (nroff->current_char == '_')
 193     {
 194         nroff->current_char = next2;
 195         nroff->type = NROFF_TYPE_UNDERLINE;
 196     }
 197     else if (nroff->current_char == '+' && next2 == 'o')
 198     {
 199         // ???
 200     }
 201     return nroff->type;
 202 }
 203 
 204 /* --------------------------------------------------------------------------------------------- */
 205 
 206 int
 207 mcview_nroff_seq_next (mcview_nroff_t *nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 208 {
 209     if (nroff == NULL)
 210         return -1;
 211 
 212     nroff->prev_type = nroff->type;
 213 
 214     switch (nroff->type)
 215     {
 216     case NROFF_TYPE_BOLD:
 217         nroff->index += 1 + nroff->char_length;
 218         break;
 219     case NROFF_TYPE_UNDERLINE:
 220         nroff->index += 2;
 221         break;
 222     default:
 223         break;
 224     }
 225 
 226     nroff->index += nroff->char_length;
 227 
 228     mcview_nroff_seq_info (nroff);
 229     return nroff->current_char;
 230 }
 231 
 232 /* --------------------------------------------------------------------------------------------- */
 233 
 234 int
 235 mcview_nroff_seq_prev (mcview_nroff_t *nroff)
     /* [previous][next][first][last][top][bottom][index][help]  */
 236 {
 237     int prev;
 238     off_t prev_index, prev_index2;
 239 
 240     if (nroff == NULL)
 241         return -1;
 242 
 243     nroff->prev_type = NROFF_TYPE_NONE;
 244 
 245     if (nroff->index == 0)
 246         return -1;
 247 
 248     prev_index = nroff->index - 1;
 249 
 250     while (prev_index != 0)
 251     {
 252         if (mcview_nroff_get_char (nroff, &nroff->current_char, prev_index))
 253             break;
 254         prev_index--;
 255     }
 256     if (prev_index == 0)
 257     {
 258         nroff->index--;
 259         mcview_nroff_seq_info (nroff);
 260         return nroff->current_char;
 261     }
 262 
 263     prev_index--;
 264 
 265     if (!mcview_get_byte (nroff->view, prev_index, &prev) || prev != '\b')
 266     {
 267         nroff->index = prev_index;
 268         mcview_nroff_seq_info (nroff);
 269         return nroff->current_char;
 270     }
 271     prev_index2 = prev_index - 1;
 272 
 273     while (prev_index2 != 0)
 274     {
 275         if (mcview_nroff_get_char (nroff, &prev, prev_index))
 276             break;
 277         prev_index2--;
 278     }
 279 
 280     nroff->index = (prev_index2 == 0) ? prev_index : prev_index2;
 281     mcview_nroff_seq_info (nroff);
 282     return nroff->current_char;
 283 }
 284 
 285 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */