<commit_before># -*- coding: utf-8 -*-
# See LICENSE.txt for licensing terms

import os
import sys
import re
from copy import copy
from os.path import abspath, dirname, join

import docutils.nodes

import reportlab
import reportlab.lib.colors as colors
import reportlab.lib.units as units
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.fonts import addMapping
from reportlab.lib.styles import StyleSheet1
from reportlab.pdfbase import pdfmetrics
import reportlab.lib.pagesizes as pagesizes
import reportlab.rl_config

import six

from rst2pdf.rson import loads as rson_loads

from . import findfonts
from .log import log

from .opt_imports import ParagraphStyle, wordaxe, wordaxe_version

HAS_WORDAXE = wordaxe is not None

unit_separator = re.compile('(-?[0-9.]*)')


class StyleSheet(object):
    '''Class to handle a collection of stylesheets'''

    @staticmethod
    def stylepairs(data):
        ''' Allows pairs of style information to be expressed
            in canonical reportlab list of two-item list/tuple,
            or in a more human-readable dictionary.
        '''
        styles = data.get('styles', {})
        try:
            if six.PY2:
                stylenames = styles.keys()
            if six.PY3:
                stylenames = list(styles.keys())
        except AttributeError:
            for style in styles:
                yield style
            return

        # Traditional reportlab styles are in ordered (key, value)
        # tuples.  We also support dictionary lookup.  This is not
        # necessarily ordered.

        # The only problem with dictionary lookup is that
        # we need to insure that parents are processed before
        # their children.  This loop is a little ugly, but
        # gets the job done.

        while stylenames:
            name = stylenames.pop()
            parent = styles[name].get('parent')
            if parent not in stylenames:
                yield name, styles[name]
                continue
            names = [name]
            while parent in stylenames:
                stylenames.remove(parent)
                names.append(parent)
                parent = styles[names[-1]].get('parent')
            while names:
                name = names.pop()
                yield name, styles[name]

    def __init__(self, flist, font_path=None, style_path=None, def_dpi=300):
        log.info('Using stylesheets: %s' % ','.join(flist))
        # find base path
        if hasattr(sys, 'frozen'):
            self.PATH = abspath(dirname(sys.executable))
        else:
            self.PATH = abspath(dirname(__file__))

        # flist is a list of stylesheet filenames.
        # They will be loaded and merged in order.
        # but the two default stylesheets will always
        # be loaded first
        flist = [
            join(self.PATH, 'styles', 'styles.style'),
            join(self.PATH, 'styles', 'default.style')
        ] + flist

        self.def_dpi = def_dpi
        if font_path is None:
            font_path = []
        font_path += ['.', os.path.join(self.PATH, 'fonts')]
        self.FontSearchPath = map(os.path.expanduser, font_path)

        if style_path is None:
            style_path = []
        style_path += [
            '.', os.path.join(self.PATH, 'styles'), '~/.rst2pdf/styles'
        ]
        self.StyleSearchPath = map(os.path.expanduser, style_path)
        self.FontSearchPath = list(set(self.FontSearchPath))
        self.StyleSearchPath = list(set(self.StyleSearchPath))

        log.info('FontPath:%s' % self.FontSearchPath)
        log.info('StylePath:%s' % self.StyleSearchPath)

        findfonts.flist = self.FontSearchPath<commit_msg>Preserve order in style/font search path when removing duplicates<commit_after># -*- coding: utf-8 -*-
# See LICENSE.txt for licensing terms

import os
import sys
import re
from copy import copy
from os.path import abspath, dirname, join

import docutils.nodes

import reportlab
import reportlab.lib.colors as colors
import reportlab.lib.units as units
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.fonts import addMapping
from reportlab.lib.styles import StyleSheet1
from reportlab.pdfbase import pdfmetrics
import reportlab.lib.pagesizes as pagesizes
import reportlab.rl_config

import six

from rst2pdf.rson import loads as rson_loads

from . import findfonts
from .log import log

from .opt_imports import ParagraphStyle, wordaxe, wordaxe_version

HAS_WORDAXE = wordaxe is not None

unit_separator = re.compile('(-?[0-9.]*)')


class StyleSheet(object):
    '''Class to handle a collection of stylesheets'''

    @staticmethod
    def stylepairs(data):
        ''' Allows pairs of style information to be expressed
            in canonical reportlab list of two-item list/tuple,
            or in a more human-readable dictionary.
        '''
        styles = data.get('styles', {})
        try:
            if six.PY2:
                stylenames = styles.keys()
            if six.PY3:
                stylenames = list(styles.keys())
        except AttributeError:
            for style in styles:
                yield style
            return

        # Traditional reportlab styles are in ordered (key, value)
        # tuples.  We also support dictionary lookup.  This is not
        # necessarily ordered.

        # The only problem with dictionary lookup is that
        # we need to insure that parents are processed before
        # their children.  This loop is a little ugly, but
        # gets the job done.

        while stylenames:
            name = stylenames.pop()
            parent = styles[name].get('parent')
            if parent not in stylenames:
                yield name, styles[name]
                continue
            names = [name]
            while parent in stylenames:
                stylenames.remove(parent)
                names.append(parent)
                parent = styles[names[-1]].get('parent')
            while names:
                name = names.pop()
                yield name, styles[name]

    def __init__(self, flist, font_path=None, style_path=None, def_dpi=300):
        log.info('Using stylesheets: %s' % ','.join(flist))
        # find base path
        if hasattr(sys, 'frozen'):
            self.PATH = abspath(dirname(sys.executable))
        else:
            self.PATH = abspath(dirname(__file__))

        # flist is a list of stylesheet filenames.
        # They will be loaded and merged in order.
        # but the two default stylesheets will always
        # be loaded first
        flist = [
            join(self.PATH, 'styles', 'styles.style'),
            join(self.PATH, 'styles', 'default.style')
        ] + flist

        self.def_dpi = def_dpi
        if font_path is None:
            font_path = []
        font_path += ['.', os.path.join(self.PATH, 'fonts')]
        self.FontSearchPath = list(map(os.path.expanduser, font_path))

        if style_path is None:
            style_path = []
        style_path += [
            '.', os.path.join(self.PATH, 'styles'), '~/.rst2pdf/styles'
        ]
        self.StyleSearchPath = list(map(os.path.expanduser, style_path))

        # Remove duplicates but preserve order. Not very efficient, but these are short lists
        self.FontSearchPath = [x for (i,x) in enumerate(self.FontSearchPath) if self.FontSearchPath.index(x) == i]
        self.StyleSearchPath = [x for (i,x) in enumerate(self.StyleSearchPath) if self.StyleSearchPath.index(x) == i]

        log.info('FontPath:%s' % self.FontSearchPath)
        log.info('StylePath:%s' % self.StyleSearchPath)

        findfonts.flist = self.FontSearchPath
{'fraction_non_alphanumeric': 0.09226346053319394, 'fraction_numerical': 0.0031364349189754314, 'mean_word_length': 2.202092050209205, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5958264', 'n_tokens_mistral': 2205, 'n_tokens_neox': 2129, 'n_words': 652}