# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- # BEGIN LICENSE # Copyright (C) 2019, Wolf Vollprecht # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License version 3, as published # by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranties of # MERCHANTABILITY, SATISFACTORY QUALITY, 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 . # END LICENSE ### DO NOT EDIT THIS FILE ### """Helpers for the application.""" import logging import os import shutil from contextlib import contextmanager import gi import pypandoc from gi.overrides.Pango import Pango from apostrophe.settings import Settings gi.require_version('Gtk', '3.0') from gi.repository import Gtk # pylint: disable=E0611 from apostrophe.config import get_data_file from apostrophe.builder import Builder @contextmanager def user_action(text_buffer): text_buffer.begin_user_action() yield text_buffer text_buffer.end_user_action() def path_to_file(path): """Return a file path (file:///) for the given path""" return "file://" + path def get_media_file(media_file_path): """Return the full path of a given filename under the media dir (starts with file:///) """ return path_to_file(get_media_path(media_file_path)) def get_media_path(media_file_name): """Return the full path of a given filename under the media dir (doesn't start with file:///) """ media_path = get_data_file('media', '%s' % (media_file_name,)) if not os.path.exists(media_path): media_path = None return media_path def get_css_path(css_file_name): """Return the full path of a given filename under the css dir (doesn't start with file:///) """ return get_media_path("css/{}".format(css_file_name)) def get_script_path(script_file_name): """Return the full path of a given filename under the script dir """ script_path = get_data_file('lua', '%s' % (script_file_name,)) if not os.path.exists(script_path): script_path = None return script_path def get_reference_files_path(reference_file_name): """Return the full path of a given filename under the reference_files dir """ refs_path = get_data_file('reference_files', '%s' % (reference_file_name,)) if not os.path.exists(refs_path): refs_path = "" return refs_path class NullHandler(logging.Handler): def emit(self, record): pass def set_up_logging(opts): # add a handler to prevent basicConfig root = logging.getLogger() null_handler = NullHandler() root.addHandler(null_handler) formatter = logging.Formatter( "%(levelname)s:%(name)s: %(funcName)s() '%(message)s'") logger = logging.getLogger('apostrophe') logger_sh = logging.StreamHandler() logger_sh.setFormatter(formatter) logger.addHandler(logger_sh) lib_logger = logging.getLogger('apostrophe') lib_logger_sh = logging.StreamHandler() lib_logger_sh.setFormatter(formatter) lib_logger.addHandler(lib_logger_sh) # Set the logging level to show debug messages. if opts.verbose: logger.setLevel(logging.DEBUG) logger.debug('logging enabled') if opts.verbose and opts.verbose > 1: lib_logger.setLevel(logging.DEBUG) def get_help_uri(page=None): # help_uri from source tree - default language here = os.path.dirname(__file__) help_uri = os.path.abspath(os.path.join(here, '..', 'help', 'C')) if not os.path.exists(help_uri): # installed so use gnome help tree - user's language help_uri = 'apostrophe' # unspecified page is the index.page if page is not None: help_uri = '%s#%s' % (help_uri, page) return help_uri def show_uri(parent, link): screen = parent.get_screen() Gtk.show_uri(screen, link, Gtk.get_current_event_time()) def alias(alternative_function_name): '''see http://www.drdobbs.com/web-development/184406073#l9''' def decorator(function): '''attach alternative_function_name(s) to function''' if not hasattr(function, 'aliases'): function.aliases = [] function.aliases.append(alternative_function_name) return function return decorator def exist_executable(command): """return if a command can be executed in the SO Arguments: command {str} -- a command Returns: {bool} -- if the given command exists in the system """ return shutil.which(command) is not None def get_descendant(widget, child_name, level, doPrint=False): if widget is not None: if doPrint: print("-" * level + str(Gtk.Buildable.get_name(widget)) + " :: " + widget.get_name()) else: if doPrint: print("-" * level + "None") return None # /*** If it is what we are looking for ***/ if Gtk.Buildable.get_name(widget) == child_name: # not widget.get_name() ! return widget # /*** If this widget has one child only search its child ***/ if (hasattr(widget, 'get_child') and callable(getattr(widget, 'get_child')) and child_name != ""): child = widget.get_child() if child is not None: return get_descendant(child, child_name, level + 1, doPrint) # /*** Ity might have many children, so search them ***/ elif (hasattr(widget, 'get_children') and callable(getattr(widget, 'get_children')) and child_name != ""): children = widget.get_children() # /*** For each child ***/ found = None for child in children: if child is not None: found = get_descendant(child, child_name, level + 1, doPrint) # //search the child if found: return found def get_char_width(widget): return Pango.units_to_double( widget.get_pango_context().get_metrics().get_approximate_char_width()) def pandoc_convert(text, to="html5", args=[], outputfile=None): fr = Settings.new().get_value('input-format').get_string() or "markdown" args.extend(["--quiet"]) return pypandoc.convert_text(text, to, fr, extra_args=args, outputfile=outputfile)