Class: RVGP::Journal
- Inherits:
-
Object
- Object
- RVGP::Journal
- Defined in:
- lib/rvgp/journal/journal.rb,
lib/rvgp/journal/pricer.rb,
lib/rvgp/journal/posting.rb,
lib/rvgp/journal/currency.rb,
lib/rvgp/journal/commodity.rb,
lib/rvgp/journal/complex_commodity.rb
Overview
This class parses a pta journal, and offers that journal in its constitutent parts. See the Journal.parse for the typical entry point, into this class. This class itself, really only offers the one method, .parse, to parse a pta journal’s contents. Most of the functionality in this class, is provided by the classes contained within it.
Defined Under Namespace
Classes: Commodity, ComplexCommodity, Currency, Posting, Pricer
Instance Attribute Summary collapse
-
#postings ⇒ Array<RVGP::Journal::Posting>
readonly
The postings that were encountered in this journal.
Class Method Summary collapse
-
.parse(contents) ⇒ RVGP::Journal
Given a pta journal, already read from the filesystem, return a parsed representation of its contents.
Instance Method Summary collapse
-
#initialize(postings) ⇒ Journal
constructor
Declare and initialize this Journal.
-
#to_s ⇒ String
Unparse this journal, and return the parsed objects in their serialized form.
Constructor Details
#initialize(postings) ⇒ Journal
Declare and initialize this Journal.
36 37 38 |
# File 'lib/rvgp/journal/journal.rb', line 36 def initialize(postings) @postings = postings end |
Instance Attribute Details
#postings ⇒ Array<RVGP::Journal::Posting> (readonly)
The postings that were encountered in this journal
10 11 12 |
# File 'lib/rvgp/journal/journal.rb', line 10 def postings @postings end |
Class Method Details
.parse(contents) ⇒ RVGP::Journal
Given a pta journal, already read from the filesystem, return a parsed representation of its contents.
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/rvgp/journal/journal.rb', line 49 def self.parse(contents) postings = [] posting = nil cite = nil contents.lines.each_with_index do |line, i| line_number = i + 1 cite = [line_number, line.inspect] # in case we run into an error line_comment = nil # Here, we separate the line into non-comment lvalue and comment rvalue: # NOTE: We're not supporting escaped semicolons, at this time case line when /\A.*[^\\];.*[^\\];.*\Z/ raise StandardError, format(MSG_TOO_MANY_SEMICOLONS, cite) when /\A( *.*?) *;[ \t]*(.*)\Z/ line = ::Regexp.last_match(1) line_comment = ::Regexp.last_match(2) end # This case parses anything to the left of a comment: case line when /\A([^ \n].*)\Z/ # This is a post declaration line raise StandardError, MSG_MISSING_POSTING_SEPARATOR % cite if posting unless %r{\A(\d{4})[/-](\d{2})[/-](\d{2}) +(.+?) *\Z}.match ::Regexp.last_match(1) raise StandardError, MSG_UNRECOGNIZED_HEADER % cite end begin date = Date.new ::Regexp.last_match(1).to_i, ::Regexp.last_match(2).to_i, ::Regexp.last_match(3).to_i rescue Date::Error raise StandardError, MSG_INVALID_DATE % cite end posting = Posting.new date, ::Regexp.last_match(4), line_number: line_number when /\A[ \t]+([^ ].+)\Z/ # This is a transfer line, to be appended to the current posting raise StandardError, MSG_UNEXPECTED_TRANSFER % cite unless posting # NOTE: We chose 2 or more spaces as the separator between # the account and the commodity, mostly because this was the smallest # we could find in the official ledger documentation unless /\A(.+?)(?: {2,}([^ ].+)| *)\Z/.match ::Regexp.last_match(1) raise StandardError, format(MSG_UNPARSEABLE_TRANSFER, cite) end begin posting.append_transfer ::Regexp.last_match(1), ::Regexp.last_match(2) rescue RVGP::Journal::Commodity::Error raise StandardError, MSG_INVALID_TRANSFER_COMMODITY % cite end when /\A[ \t]*\Z/ if line_comment.nil? && posting unless posting.valid? posting.transfers.each do |transfer| puts format(' - Not valid. account %<acct>s commodity: %<commodity>s complex_commodity: %<complex>s', acct: transfer.account.inspect, commodity: transfer.commodity.inspect, complex: transfer.complex_commodity.inspect) end end raise StandardError, MSG_INVALID_POSTING % cite unless posting.valid? # This is a blank line postings << posting posting = nil end else raise StandardError, MSG_UNEXPECTED_LINE % cite unless posting end next unless line_comment && posting = line_comment.scan(/(?:[^ ]+: *[^,]*|:[^ \t]+:)/).map do |declaration| /\A:?(.+):\Z/.match(declaration) ? ::Regexp.last_match(1).split(':') : declaration end.flatten .each { |tag| posting.append_tag tag } end # The last line could be \n, which, makes this unnecessary if posting raise StandardError, MSG_INVALID_POSTING % cite unless posting.valid? postings << posting end new postings end |
Instance Method Details
#to_s ⇒ String
Unparse this journal, and return the parsed objects in their serialized form.
42 43 44 |
# File 'lib/rvgp/journal/journal.rb', line 42 def to_s @postings.map(&:to_ledger).join "\n\n" end |