commands.c 16.7 KB
Newer Older
Moritz Lipp's avatar
Moritz Lipp committed
1 2
/* See LICENSE file for license and copyright information */

Moritz Lipp's avatar
Moritz Lipp committed
3
#include <string.h>
4
#include <stdlib.h>
5
#include <glib/gi18n.h>
Moritz Lipp's avatar
Moritz Lipp committed
6

Moritz Lipp's avatar
Moritz Lipp committed
7
#include "commands.h"
Moritz Lipp's avatar
Moritz Lipp committed
8
#include "shortcuts.h"
9 10
#include "bookmarks.h"
#include "database.h"
Moritz Lipp's avatar
Moritz Lipp committed
11
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
12
#include "zathura.h"
13
#include "print.h"
14
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
15
#include "utils.h"
16
#include "page-widget.h"
Moritz Lipp's avatar
Moritz Lipp committed
17
#include "page.h"
Moritz Lipp's avatar
Moritz Lipp committed
18
#include "plugin.h"
19
#include "internal.h"
Moritz Lipp's avatar
Moritz Lipp committed
20
#include "render.h"
Moritz Lipp's avatar
Moritz Lipp committed
21

22
#include <girara/session.h>
Moritz Lipp's avatar
Moritz Lipp committed
23
#include <girara/settings.h>
Moritz Lipp's avatar
Moritz Lipp committed
24
#include <girara/commands.h>
25
#include <girara/datastructures.h>
Sebastian Ramacher's avatar
Sebastian Ramacher committed
26
#include <girara/utils.h>
27

Moritz Lipp's avatar
Moritz Lipp committed
28
bool
29
cmd_bookmark_create(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
30
{
31 32 33 34
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  if (zathura->document == NULL) {
35
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
36 37 38 39 40
    return false;
  }

  const unsigned int argc = girara_list_size(argument_list);
  if (argc != 1) {
41
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
42 43 44 45 46 47
    return false;
  }

  const char* bookmark_name = girara_list_nth(argument_list, 0);
  zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name);
  if (bookmark != NULL) {
48
    bookmark->page = zathura_document_get_current_page_number(zathura->document) + 1;
49
    girara_notify(session, GIRARA_INFO, _("Bookmark successfuly updated: %s"), bookmark_name);
50 51 52
    return true;
  }

53
  bookmark = zathura_bookmark_add(zathura, bookmark_name, zathura_document_get_current_page_number(zathura->document) + 1);
54
  if (bookmark == NULL) {
55
    girara_notify(session, GIRARA_ERROR, _("Could not create bookmark: %s"), bookmark_name);
56 57 58
    return false;
  }

59
  girara_notify(session, GIRARA_INFO, _("Bookmark successfuly created: %s"), bookmark_name);
Moritz Lipp's avatar
Moritz Lipp committed
60 61 62 63
  return true;
}

bool
Moritz Lipp's avatar
Moritz Lipp committed
64
cmd_bookmark_delete(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
65
{
66 67 68 69
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  if (zathura->document == NULL) {
70
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
71 72 73 74 75
    return false;
  }

  const unsigned int argc = girara_list_size(argument_list);
  if (argc != 1) {
76
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
77 78 79 80 81
    return false;
  }

  const char* bookmark = girara_list_nth(argument_list, 0);
  if (zathura_bookmark_remove(zathura, bookmark)) {
82
    girara_notify(session, GIRARA_INFO, _("Removed bookmark: %s"), bookmark);
83
  } else {
84
    girara_notify(session, GIRARA_ERROR, _("Failed to remove bookmark: %s"), bookmark);
85 86
  }

Moritz Lipp's avatar
Moritz Lipp committed
87 88 89 90
  return true;
}

bool
Sebastian Ramacher's avatar
Sebastian Ramacher committed
91
cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
92
{
Sebastian Ramacher's avatar
Sebastian Ramacher committed
93 94 95 96
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  if (zathura->document == NULL) {
97
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
98 99 100 101 102
    return false;
  }

  const unsigned int argc = girara_list_size(argument_list);
  if (argc != 1) {
103
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
104 105 106 107 108 109
    return false;
  }

  const char* bookmark_name = girara_list_nth(argument_list, 0);
  zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name);
  if (bookmark == NULL) {
110
    girara_notify(session, GIRARA_ERROR, _("No such bookmark: %s"), bookmark_name);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
111 112 113
    return false;
  }

114
  return page_set(zathura, bookmark->page - 1);
Moritz Lipp's avatar
Moritz Lipp committed
115 116 117
}

bool
118
cmd_close(girara_session_t* session, girara_list_t* UNUSED(argument_list))
Moritz Lipp's avatar
Moritz Lipp committed
119
{
120 121 122
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
123 124 125
  if (zathura->document == NULL) {
    return true;
  }
126

Moritz Lipp's avatar
Moritz Lipp committed
127
  document_close(zathura, false);
Moritz Lipp's avatar
Moritz Lipp committed
128

Moritz Lipp's avatar
Moritz Lipp committed
129 130 131 132
  return true;
}

bool
Moritz Lipp's avatar
Moritz Lipp committed
133
cmd_info(girara_session_t* session, girara_list_t* UNUSED(argument_list))
Moritz Lipp's avatar
Moritz Lipp committed
134
{
Moritz Lipp's avatar
Moritz Lipp committed
135 136 137 138
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  if (zathura->document == NULL) {
139
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Moritz Lipp's avatar
Moritz Lipp committed
140 141 142 143 144
    return false;
  }

  struct meta_field {
    char* name;
145
    zathura_document_information_type_t field;
Moritz Lipp's avatar
Moritz Lipp committed
146 147 148
  };

  struct meta_field meta_fields[] = {
149 150 151 152 153 154 155 156
    { "Title",            ZATHURA_DOCUMENT_INFORMATION_TITLE },
    { "Author",           ZATHURA_DOCUMENT_INFORMATION_AUTHOR },
    { "Subject",          ZATHURA_DOCUMENT_INFORMATION_SUBJECT },
    { "Keywords",         ZATHURA_DOCUMENT_INFORMATION_KEYWORDS },
    { "Creator",          ZATHURA_DOCUMENT_INFORMATION_CREATOR },
    { "Producer",         ZATHURA_DOCUMENT_INFORMATION_PRODUCER },
    { "Creation date",    ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE },
    { "Modiciation date", ZATHURA_DOCUMENT_INFORMATION_MODIFICATION_DATE }
Moritz Lipp's avatar
Moritz Lipp committed
157 158
  };

159 160 161 162
  girara_list_t* information = zathura_document_get_information(zathura->document, NULL);
  if (information == NULL) {
    girara_notify(session, GIRARA_INFO, _("No information available."));
    return false;
Moritz Lipp's avatar
Moritz Lipp committed
163 164
  }

165
  GString* string = g_string_new(NULL);
Moritz Lipp's avatar
Moritz Lipp committed
166

167
  GIRARA_LIST_FOREACH(information, zathura_document_information_entry_t*, iter, entry)
Moritz Lipp's avatar
Moritz Lipp committed
168 169 170 171 172 173
  if (entry != NULL) {
    for (unsigned int i = 0; i < LENGTH(meta_fields); i++) {
      if (meta_fields[i].field == entry->type) {
        char* text = g_strdup_printf("<b>%s:</b> %s\n", meta_fields[i].name, entry->value);
        g_string_append(string, text);
        g_free(text);
174
      }
Moritz Lipp's avatar
Moritz Lipp committed
175
    }
Moritz Lipp's avatar
Moritz Lipp committed
176
  }
177
  GIRARA_LIST_FOREACH_END(information, zathura_document_information_entry_t*, iter, entry);
Moritz Lipp's avatar
Moritz Lipp committed
178 179 180

  if (strlen(string->str) > 0) {
    g_string_erase(string, strlen(string->str) - 1, 1);
181
    girara_notify(session, GIRARA_INFO, "%s", string->str);
182 183
  } else {
    girara_notify(session, GIRARA_INFO, _("No information available."));
Moritz Lipp's avatar
Moritz Lipp committed
184 185 186 187 188
  }

  g_string_free(string, TRUE);

  return false;
Moritz Lipp's avatar
Moritz Lipp committed
189 190
}

Sebastian Ramacher's avatar
Sebastian Ramacher committed
191
bool
192
cmd_help(girara_session_t* UNUSED(session), girara_list_t*
Moritz Lipp's avatar
Moritz Lipp committed
193
         UNUSED(argument_list))
Sebastian Ramacher's avatar
Sebastian Ramacher committed
194 195 196 197
{
  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211
bool
cmd_hlsearch(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  document_draw_search_results(zathura, true);
  render_all(zathura);

  return true;
}


212 213 214
bool
cmd_open(girara_session_t* session, girara_list_t* argument_list)
{
Sebastian Ramacher's avatar
Sebastian Ramacher committed
215 216 217 218 219 220
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  const int argc = girara_list_size(argument_list);
  if (argc > 2) {
221
    girara_notify(session, GIRARA_ERROR, _("Too many arguments."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
222
    return false;
Moritz Lipp's avatar
Moritz Lipp committed
223
  } else if (argc >= 1) {
Moritz Lipp's avatar
Moritz Lipp committed
224 225
    if (zathura->document != NULL) {
      document_close(zathura, false);
226 227
    }

Sebastian Ramacher's avatar
Sebastian Ramacher committed
228
    document_open(zathura, girara_list_nth(argument_list, 0), (argc == 2) ? girara_list_nth(argument_list, 1) :  NULL);
Moritz Lipp's avatar
Moritz Lipp committed
229
  } else {
230
    girara_notify(session, GIRARA_ERROR, _("No arguments given."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
231 232 233
    return false;
  }

234 235 236
  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
237 238 239 240 241 242 243 244
bool
cmd_quit(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  sc_quit(session, NULL, NULL, 0);

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
245
bool
246
cmd_print(girara_session_t* session, girara_list_t* UNUSED(argument_list))
Moritz Lipp's avatar
Moritz Lipp committed
247
{
248 249 250 251
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Pavel Borzenkov's avatar
Pavel Borzenkov committed
252
  if (zathura->document == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
253
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Pavel Borzenkov's avatar
Pavel Borzenkov committed
254 255
    return false;
  }
256

Moritz Lipp's avatar
Moritz Lipp committed
257
  print(zathura);
258

Moritz Lipp's avatar
Moritz Lipp committed
259 260 261
  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
262 263 264 265 266 267 268 269 270 271 272 273 274
bool
cmd_nohlsearch(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  document_draw_search_results(zathura, false);
  render_all(zathura);

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
275
bool
Moritz Lipp's avatar
Moritz Lipp committed
276
cmd_save(girara_session_t* session, girara_list_t* argument_list)
Moritz Lipp's avatar
Moritz Lipp committed
277
{
278 279 280 281
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Pavel Borzenkov's avatar
Pavel Borzenkov committed
282
  if (zathura->document == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
283
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Pavel Borzenkov's avatar
Pavel Borzenkov committed
284 285
    return false;
  }
286 287

  if (girara_list_size(argument_list) == 1) {
288
    if (document_save(zathura, girara_list_nth(argument_list, 0), false) == true) {
289
      girara_notify(session, GIRARA_INFO, _("Document saved."));
290
    } else {
291
      girara_notify(session, GIRARA_INFO, _("Failed to save document."));
292
    }
Moritz Lipp's avatar
Moritz Lipp committed
293
  } else {
294
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments."));
295 296 297 298 299 300 301 302 303 304 305 306 307
    return false;
  }

  return true;
}

bool
cmd_savef(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Pavel Borzenkov's avatar
Pavel Borzenkov committed
308
  if (zathura->document == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
309
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
310
    return false;
Pavel Borzenkov's avatar
Pavel Borzenkov committed
311
  }
312 313

  if (girara_list_size(argument_list) == 1) {
314
    if (document_save(zathura, girara_list_nth(argument_list, 0), true) == true) {
315
      girara_notify(session, GIRARA_INFO, _("Document saved."));
316
    } else {
317
      girara_notify(session, GIRARA_INFO, _("Failed to save document."));
318
    }
Moritz Lipp's avatar
Moritz Lipp committed
319
  } else {
320
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments."));
321 322 323
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
324 325
  return true;
}
Moritz Lipp's avatar
Moritz Lipp committed
326 327

bool
Sebastian Ramacher's avatar
Sebastian Ramacher committed
328
cmd_search(girara_session_t* session, const char* input, girara_argument_t* argument)
Moritz Lipp's avatar
Moritz Lipp committed
329 330 331 332 333 334 335
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(input != NULL, false);
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Sebastian Ramacher's avatar
Sebastian Ramacher committed
336
  if (zathura->document == NULL || strlen(input) == 0) {
Moritz Lipp's avatar
Moritz Lipp committed
337 338 339
    return false;
  }

340
  bool firsthit = true;
341
  zathura_error_t error = ZATHURA_ERROR_OK;
342

343 344
  /* set search direction */
  zathura->global.search_direction = argument->n;
345 346 347 348

  unsigned int number_of_pages     = zathura_document_get_number_of_pages(zathura->document);
  unsigned int current_page_number = zathura_document_get_current_page_number(zathura->document);

Moritz Lipp's avatar
Moritz Lipp committed
349 350 351 352 353 354 355 356 357
  /* reset search highlighting */
  bool nohlsearch = false;
  girara_setting_get(session, "nohlsearch", &nohlsearch);

  if (nohlsearch == false) {
    document_draw_search_results(zathura, true);
  }

  /* search pages */
358
  for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
359
    unsigned int index = (page_id + current_page_number) % number_of_pages;
360
    zathura_page_t* page = zathura_document_get_page(zathura->document, index);
361
    if (page == NULL) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
362 363 364
      continue;
    }

365
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Moritz Lipp's avatar
Moritz Lipp committed
366
    g_object_set(page_widget, "draw-links", FALSE, NULL);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
367

368
    render_lock(zathura->sync.render_thread);
369
    girara_list_t* result = zathura_page_search_text(page, input, &error);
370 371
    render_unlock(zathura->sync.render_thread);

Sebastian Ramacher's avatar
Sebastian Ramacher committed
372 373
    if (result == NULL || girara_list_size(result) == 0) {
      girara_list_free(result);
Moritz Lipp's avatar
Moritz Lipp committed
374
      g_object_set(page_widget, "search-results", NULL, NULL);
375

376
      if (error == ZATHURA_ERROR_NOT_IMPLEMENTED) {
377 378 379 380
        break;
      } else {
        continue;
      }
Sebastian Ramacher's avatar
Sebastian Ramacher committed
381 382
    }

Moritz Lipp's avatar
Moritz Lipp committed
383
    g_object_set(page_widget, "search-results", result, NULL);
384 385
    if (firsthit == true) {
      if (page_id != 0) {
386
        page_set_delayed(zathura, zathura_page_get_index(page));
387
      }
388 389 390 391 392 393
      if (argument->n == BACKWARD) {
        /* start at bottom hit in page */
        g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL);
      } else {
        g_object_set(page_widget, "search-current", 0, NULL);
      }
394 395
      firsthit = false;
    }
Sebastian Ramacher's avatar
Sebastian Ramacher committed
396 397
  }

Moritz Lipp's avatar
Moritz Lipp committed
398 399
  return true;
}
Sebastian Ramacher's avatar
Sebastian Ramacher committed
400 401 402 403 404 405 406 407

bool
cmd_export(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  if (zathura->document == NULL) {
408
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
409 410 411
    return false;
  }

412
  if (girara_list_size(argument_list) != 2) {
413
    girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given."));
Sebastian Ramacher's avatar
Sebastian Ramacher committed
414 415 416
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
417
  const char* file_identifier = girara_list_nth(argument_list, 0);
418 419
  const char* file_name       = girara_list_nth(argument_list, 1);

Moritz Lipp's avatar
Moritz Lipp committed
420
  if (file_name == NULL || file_identifier == NULL) {
421 422 423
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
424 425 426 427 428 429 430 431 432 433 434 435
  char* export_path = girara_fix_path(file_name);
  if (export_path == NULL) {
    return false;
  }

  /* attachment */
  if (strncmp(file_identifier, "attachment-", strlen("attachment-")) == 0) {
    if (zathura_document_attachment_save(zathura->document, file_identifier + strlen("attachment-"), export_path) == false) {
      girara_notify(session, GIRARA_ERROR, _("Couldn't write attachment '%s' to '%s'."), file_identifier, file_name);
    } else {
      girara_notify(session, GIRARA_INFO, _("Wrote attachment '%s' to '%s'."), file_identifier, export_path);
    }
Moritz Lipp's avatar
Moritz Lipp committed
436
    /* image */
Moritz Lipp's avatar
Moritz Lipp committed
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
  } else if (strncmp(file_identifier, "image-p", strlen("image-p")) == 0 && strlen(file_identifier) >= 10) {
    /* parse page id */
    const char* input = file_identifier + strlen("image-p");
    int page_id = atoi(input);
    if (page_id == 0) {
      goto image_error;
    }

    /* parse image id */
    input = strstr(input, "-");
    if (input == NULL) {
      goto image_error;
    }

    int image_id = atoi(input + 1);
    if (image_id == 0) {
      goto image_error;
    }

    /* get image */
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id - 1);
    if (page == NULL) {
      goto image_error;
    }

    girara_list_t* images = zathura_page_images_get(page, NULL);
    if (images == NULL) {
      goto image_error;
    }

    zathura_image_t* image = girara_list_nth(images, image_id - 1);
    if (image == NULL) {
      goto image_error;
    }

    cairo_surface_t* surface = zathura_page_image_get_cairo(page, image, NULL);
    if (surface == NULL) {
      goto image_error;
    }

    if (cairo_surface_write_to_png(surface, export_path) == CAIRO_STATUS_SUCCESS) {
      girara_notify(session, GIRARA_INFO, _("Wrote image '%s' to '%s'."), file_identifier, export_path);
    } else {
      girara_notify(session, GIRARA_ERROR, _("Couldn't write image '%s' to '%s'."), file_identifier, file_name);
    }

    goto error_ret;

image_error:

    girara_notify(session, GIRARA_ERROR, _("Unknown image '%s'."), file_identifier);
    goto error_ret;
Moritz Lipp's avatar
Moritz Lipp committed
489
    /* unknown */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
490
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
491
    girara_notify(session, GIRARA_ERROR, _("Unknown attachment or image '%s'."), file_identifier);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
492 493
  }

Moritz Lipp's avatar
Moritz Lipp committed
494 495 496
error_ret:

  g_free(export_path);
497

Sebastian Ramacher's avatar
Sebastian Ramacher committed
498 499
  return true;
}
500

Moritz Lipp's avatar
Moritz Lipp committed
501 502 503 504 505 506 507 508 509 510 511
bool
cmd_exec(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  if (zathura->document != NULL) {
    const char* path = zathura_document_get_path(zathura->document);

    GIRARA_LIST_FOREACH(argument_list, char*, iter, value)
Moritz Lipp's avatar
Moritz Lipp committed
512 513 514 515
    char* r = NULL;
    if ((r = replace_substring(value, "$FILE", path)) != NULL) {
      girara_list_iterator_set(iter, r);
    }
Moritz Lipp's avatar
Moritz Lipp committed
516 517 518 519 520 521
    GIRARA_LIST_FOREACH_END(argument_list, char*, iter, value);
  }

  return girara_exec_with_argument_list(session, argument_list);
}

522 523 524 525 526 527 528 529 530 531 532 533
bool
cmd_offset(girara_session_t* session, girara_list_t* argument_list)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  if (zathura->document == NULL) {
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
    return false;
  }

  /* no argument: take current page as offset */
534
  unsigned int page_offset = zathura_document_get_current_page_number(zathura->document);
535 536 537 538 539 540 541 542 543 544 545 546 547

  /* retrieve offset from argument */
  if (girara_list_size(argument_list) == 1) {
    const char* value = girara_list_nth(argument_list, 0);
    if (value != NULL) {
      page_offset = atoi(value);
      if (page_offset == 0 && strcmp(value, "0") != 0) {
        girara_notify(session, GIRARA_WARNING, _("Argument must be a number."));
        return false;
      }
    }
  }

548 549
  if (page_offset < zathura_document_get_number_of_pages(zathura->document)) {
    zathura_document_set_page_offset(zathura->document, page_offset);
550 551 552 553
  }

  return true;
}
Moritz Lipp's avatar
Moritz Lipp committed
554 555 556 557 558 559 560 561

bool
cmd_version(girara_session_t* session, girara_list_t* UNUSED(argument_list))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

562
  char* string = zathura_get_version_string(zathura, true);
Moritz Lipp's avatar
Moritz Lipp committed
563 564 565
  if (string == NULL) {
    return false;
  }
Moritz Lipp's avatar
Moritz Lipp committed
566 567

  /* display information */
568
  girara_notify(session, GIRARA_INFO, "%s", string);
Moritz Lipp's avatar
Moritz Lipp committed
569

570
  g_free(string);
Moritz Lipp's avatar
Moritz Lipp committed
571 572 573

  return true;
}