示例#1
0
    def Transaction(self, entry, oss):
        # Compute the string for the payee and narration line.
        strings = []
        if entry.payee:
            strings.append('"{}"'.format(misc_utils.escape_string(
                entry.payee)))
        if entry.narration:
            strings.append('"{}"'.format(
                misc_utils.escape_string(entry.narration)))
        elif entry.payee:
            # Ensure we append an empty string for narration if we have a payee.
            strings.append('""')

        if entry.tags:
            for tag in sorted(entry.tags):
                strings.append('#{}'.format(tag))
        if entry.links:
            for link in sorted(entry.links):
                strings.append('^{}'.format(link))

        oss.write('{e.date} {flag} {}\n'.format(' '.join(strings),
                                                e=entry,
                                                flag=render_flag(entry.flag)))
        self.write_metadata(entry.meta, oss)

        rows = [
            self.render_posting_strings(posting) for posting in entry.postings
        ]
        strs_account = [row[0] for row in rows]
        width_account = (max(
            len(flag_account)
            for flag_account in strs_account) if strs_account else 1)
        strs_position, width_position = align_position_strings(row[1]
                                                               for row in rows)
        strs_weight, width_weight = align_position_strings(row[2]
                                                           for row in rows)

        if self.min_width_account and self.min_width_account > width_account:
            width_account = self.min_width_account

        non_trivial_balance = (any(
            map(interpolate.has_nontrivial_balance, entry.postings))
                               if self.render_weight else False)
        if non_trivial_balance:
            for posting, account, position, weight in zip(
                    entry.postings, strs_account, strs_position, strs_weight):
                oss.write(f"{self.prefix}{account:{width_account}}  "
                          f"{position:{width_position}}  "
                          f"; {weight:{max(1, width_weight)}}".rstrip() + '\n')
                if posting.meta:
                    self.write_metadata(posting.meta, oss, '    ')
        else:
            for posting, account, position in zip(entry.postings, strs_account,
                                                  strs_position):
                oss.write(f"{self.prefix}{account:{width_account}}  "
                          f"{position:{max(1, width_position)}}".rstrip() +
                          '\n')
                if posting.meta:
                    self.write_metadata(posting.meta, oss, '    ')
示例#2
0
    def Transaction(self, entry, oss):
        # Compute the string for the payee and narration line.
        strings = []
        if entry.payee:
            strings.append('"{}"'.format(misc_utils.escape_string(entry.payee)))
        if entry.narration:
            strings.append('"{}"'.format(misc_utils.escape_string(entry.narration)))
        elif entry.payee:
            # Ensure we append an empty string for narration if we have a payee.
            strings.append('""')

        if entry.tags:
            for tag in sorted(entry.tags):
                strings.append('#{}'.format(tag))
        if entry.links:
            for link in sorted(entry.links):
                strings.append('^{}'.format(link))

        oss.write('{e.date} {e.flag} {}\n'.format(' '.join(strings), e=entry))
        self.write_metadata(entry.meta, oss)

        rows = [self.render_posting_strings(posting)
                for posting in entry.postings]
        strs_account = [row[0] for row in rows]
        width_account = (max(len(flag_account) for flag_account in strs_account)
                         if strs_account
                         else 1)
        strs_position, width_position = align_position_strings(row[1] for row in rows)
        strs_weight, width_weight = align_position_strings(row[2] for row in rows)

        if self.min_width_account and self.min_width_account > width_account:
            width_account = self.min_width_account

        non_trivial_balance = (any(map(interpolate.has_nontrivial_balance, entry.postings))
                               if self.render_weight
                               else False)
        if non_trivial_balance:
            fmt = "  {{:{0}}}  {{:{1}}}  ; {{:{2}}}\n".format(
                width_account, width_position, width_weight).format
            for posting, account, position_str, weight_str in zip(entry.postings,
                                                                  strs_account,
                                                                  strs_position,
                                                                  strs_weight):
                oss.write(fmt(account,
                              position_str,
                              weight_str if non_trivial_balance else ''))
                if posting.meta:
                    self.write_metadata(posting.meta, oss, '    ')
        else:
            fmt_str = "  {{:{0}}}  {{:{1}}}\n".format(width_account, max(1, width_position))
            fmt = fmt_str.format
            for posting, account, position_str in zip(entry.postings,
                                                      strs_account,
                                                      strs_position):
                # pylint: disable=too-many-format-args
                oss.write(fmt(account, position_str))
                if posting.meta:
                    self.write_metadata(posting.meta, oss, '    ')
示例#3
0
    def write_metadata(self, meta, oss, prefix=None):
        """Write metadata to the file object, excluding filename and line number.

        Args:
          meta: A dict that contains the metadata for this directive.
          oss: A file object to write to.
        """
        if meta is None:
            return
        if prefix is None:
            prefix = self.prefix
        for key, value in sorted(meta.items()):
            if key not in self.META_IGNORE:
                value_str = None
                if isinstance(value, str):
                    value_str = '"{}"'.format(misc_utils.escape_string(value))
                elif isinstance(value, (Decimal, datetime.date, amount.Amount, enum.Enum)):
                    value_str = str(value)
                elif isinstance(value, bool):
                    value_str = 'TRUE' if value else 'FALSE'
                elif isinstance(value, (dict, inventory.Inventory)):
                    pass # Ignore dicts, don't print them out.
                elif value is None:
                    value_str = ''  # Render null metadata as empty, on purpose.
                else:
                    if self.stringify_invalid_types:
                        # This is only intended to be used during development,
                        # when debugging for custom values of data types
                        # attached directly and not coming from the parser.
                        value_str = str(value)
                    else:
                        raise ValueError("Unexpected value: '{!r}'".format(value))
                if value_str is not None:
                    oss.write("{}{}: {}\n".format(prefix, key, value_str))
示例#4
0
    def write_metadata(self, meta, oss, prefix='  '):
        """Write metadata to the file object, excluding filename and line number.

        Args:
          meta: A dict that contains the metadata for this directive.
          oss: A file object to write to.
        """
        if meta is None:
            return
        for key, value in sorted(meta.items()):
            if key not in self.META_IGNORE:
                value_str = None
                if isinstance(value, str):
                    value_str = '"{}"'.format(misc_utils.escape_string(value))
                elif isinstance(value, (Decimal, datetime.date, amount.Amount)):
                    value_str = str(value)
                elif isinstance(value, bool):
                    value_str = 'TRUE' if value else 'FALSE'
                elif isinstance(value, (dict, inventory.Inventory)):
                    pass # Ignore dicts, don't print them out.
                else:
                    raise ValueError("Unexpected value: '{!r}'".format(value))
                if value_str is not None:
                    oss.write("{}{}: {}\n".format(prefix, key, value_str))
示例#5
0
 def test_escape_string(self):
     assert misc_utils.escape_string("Entry with escaped \"symbols\" \\ \r \n") == \
         'Entry with escaped \\"symbols\\" \\\\ \r \n'