gnucash unstable: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Fri Dec 29 16:49:47 EST 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/fd9474b5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a29c2db4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/aeb62724 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e6dcc0cc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/93b17214 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1ea1bcb3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/7a5f2ed4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/408f609a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3de3d3cc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/139e2aa7 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f2df1bd4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a81c3483 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/39dceb55 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/005fdb5f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/7b6ac3a0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/230493f2 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1ce2f3f6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/72576752 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e2912d1b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/00b2e76d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0854caba (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c26af85e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e8dc5c54 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/6f87138b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2e06c8fc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/aaa23dc5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/43cbe652 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/20feefe6 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3b3c0322 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ea416e16 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d9d4ffaf (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8399ee65 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/521c1624 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1be88ad1 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/fa0bcf10 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/db019ec5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1a886fac (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ef65f544 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b549dd68 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4bfd01e7 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c7f9fb1a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/68aa61a3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8044f2b0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b6c6906b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8e4d72b5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/afc6ca07 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c4089ebc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/dd222168 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d88d503b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a5306d04 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e1ba5f32 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/070c99c1 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d0c435e7 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/a2008c49 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b9390cea (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ff0d7cc2 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/02905fe3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ee01038e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/7127df58 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/fe757dbe (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e5a7660a (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8990553e (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4187cc1c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3f03cce1 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/082811b9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/809d2770 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/7e8ac532 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ba2e0c5f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/d93d4f68 (commit)
	from  https://github.com/Gnucash/gnucash/commit/bab266c3 (commit)



commit fd9474b55fb4df4607d71cface8cd00f2d7a649e
Merge: bab266c a29c2db
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Dec 29 22:47:44 2017 +0100

    Merge branch 'unstable-TR-plus' of https://github.com/christopherlam/gnucash into unstable


commit a29c2db4686cbf7159eeae5941aa4b82c467f310
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Dec 30 07:47:57 2017 +1100

    COSMETIC: amend strings in options
    
    Use more precise and concise strings in Filter options.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index f6654df..2e78ad0 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -92,10 +92,10 @@
 
 ;;Filtering
 (define pagename-filter (N_ "Filter"))
-(define optname-account-matcher (N_ "Account Matcher"))
-(define optname-account-matcher-regex (N_ "Account Matcher uses regular expressions for extended matching"))
-(define optname-transaction-matcher (N_ "Transaction Matcher"))
-(define optname-transaction-matcher-regex (N_ "Transaction Matcher uses regular expressions for extended matching"))
+(define optname-account-matcher (N_ "Account Name Filter"))
+(define optname-account-matcher-regex (N_ "Use regular expressions for account name filter"))
+(define optname-transaction-matcher (N_ "Transaction Filter"))
+(define optname-transaction-matcher-regex (N_ "Use regular expressions for transaction filter"))
 (define optname-reconcile-status (N_ "Reconcile Status"))
 (define optname-void-transactions (N_ "Void Transactions"))
 
@@ -474,16 +474,16 @@ Credit Card, and Income accounts."))
   (gnc:register-trep-option
    (gnc:make-string-option
     pagename-filter optname-account-matcher
-    "a5" (_ "Match only accounts whose fullname is matched e.g. ':Travel' will match \
+    "a5" (_ "Show only accounts whose full name matches this filter e.g. ':Travel' will match \
 Expenses:Travel:Holiday and Expenses:Business:Travel. It can be left blank, which will \
-disable the matcher.")
+disable the filter.")
     ""))
 
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
     pagename-filter optname-account-matcher-regex
     "a6"
-    (_ "By default the account matcher will search substring only. Set this to true to \
+    (_ "By default the account filter will search substring only. Set this to true to \
 enable full POSIX regular expressions capabilities. 'Car|Flights' will match both \
 Expenses:Car and Expenses:Flights. Use a period (.) to match a single character e.g. \
 '20../.' will match 'Travel 2017/1 London'. ")
@@ -492,16 +492,16 @@ Expenses:Car and Expenses:Flights. Use a period (.) to match a single character
   (gnc:register-trep-option
    (gnc:make-string-option
     pagename-filter optname-transaction-matcher
-    "i1" (_ "Match only transactions whose substring is matched e.g. '#gift' \
-will find all transactions with #gift in description, notes or memo. It can be left \
-blank, which will disable the matcher.")
+    "i1" (_ "Show only transactions where description, notes, or memo matches this filter.
+e.g. '#gift' will find all transactions with #gift in description, notes or memo. It can be left \
+blank, which will disable the filter.")
     ""))
 
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
     pagename-filter optname-transaction-matcher-regex
     "i2"
-    (_ "By default the transaction matcher will search substring only. Set this to true to \
+    (_ "By default the transaction filter will search substring only. Set this to true to \
 enable full POSIX regular expressions capabilities. '#work|#family' will match both \
 tags within description, notes or memo. ")
     #f))

commit aeb62724e57df9c7b801334a9e69eedba2f3be21
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 24 00:25:59 2017 +0800

    REFACTOR: gnc-numeric not available in scheme anymore

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index df153b2..f6654df 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1097,16 +1097,16 @@ tags within description, notes or memo. ")
                        (timespecCanonicalDayTime trans-date))))
            (split-value (lambda (s) (convert s (damount s)))) ; used for correct debit/credit
            (amount (lambda (s) (split-value s)))
-           (debit-amount (lambda (s) (and (gnc-numeric-positive-p (gnc:gnc-monetary-amount (split-value s)))
+           (debit-amount (lambda (s) (and (positive? (gnc:gnc-monetary-amount (split-value s)))
                                           (split-value s))))
-           (credit-amount (lambda (s) (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount (split-value s)))
+           (credit-amount (lambda (s) (if (positive? (gnc:gnc-monetary-amount (split-value s)))
                                           #f
                                           (gnc:monetary-neg (split-value s)))))
            (original-amount (lambda (s) (gnc:make-gnc-monetary (currency s) (damount s))))
-           (original-debit-amount (lambda (s) (if (gnc-numeric-positive-p (damount s))
+           (original-debit-amount (lambda (s) (if (positive? (damount s))
                                                   (original-amount s)
                                                   #f)))
-           (original-credit-amount (lambda (s) (if (gnc-numeric-positive-p (damount s))
+           (original-credit-amount (lambda (s) (if (positive? (damount s))
                                                    #f
                                                    (gnc:monetary-neg (original-amount s)))))
            (running-balance (lambda (s) (gnc:make-gnc-monetary (currency s) (xaccSplitGetBalance s)))))
@@ -1117,7 +1117,7 @@ tags within description, notes or memo. ")
          ;;         reverse-column?                              ;; to optionally reverse signs
          ;;         subtotal?                                    ;; subtotal? to allow subtotals (ie irrelevant for running balance)
          ;;         (vector start-dual-column?                   ;; #t for the left side of a dual column (i.e. debit/credit)
-         ;;                 merging-function))                   ;; function to apply to dual-subtotal (gnc-numeric-add/sub)
+         ;;                 merging-function))                   ;; function to apply to dual-subtotal (+ / -)
          ;;         friendly-heading-fn                          ;; retrieve friendly heading name for account debit/credit
          (if (column-uses? 'amount-single)
              (list (vector (header-commodity (_ "Amount"))
@@ -1128,11 +1128,11 @@ tags within description, notes or memo. ")
          (if (column-uses? 'amount-double)
              (list (vector (header-commodity (_ "Debit"))
                            debit-amount #f #t
-                           (vector #t gnc-numeric-add)
+                           (vector #t +)
                            friendly-debit)
                    (vector (header-commodity (_ "Credit"))
                            credit-amount #f #t
-                           (vector #f gnc-numeric-sub)
+                           (vector #f -)
                            friendly-credit))
              '())
 
@@ -1148,11 +1148,11 @@ tags within description, notes or memo. ")
                   (column-uses? 'amount-double))
              (list (vector (_ "Debit")
                            original-debit-amount #f #t
-                           (vector #t gnc-numeric-add)
+                           (vector #t +)
                            friendly-debit)
                    (vector (_ "Credit")
                            original-credit-amount #f #t
-                           (vector #f gnc-numeric-sub)
+                           (vector #f -)
                            friendly-credit))
              '())
 
@@ -1254,20 +1254,19 @@ tags within description, notes or memo. ")
 
         (define (add-columns commodity)
           (let ((start-dual-column? #f)
-                (dual-subtotal (gnc:make-gnc-numeric 0 1)))
+                (dual-subtotal 0))
             (for-each (lambda (column merge-entry)
                         (let* ((mon (retrieve-commodity column commodity))
                                (column-amount (and mon (gnc:gnc-monetary-amount mon)))
                                (merge? (vector-ref merge-entry 0))
                                (merge-fn (vector-ref merge-entry 1)))
                           (if merge?
-                              ;; We're merging. Run merge-fn (usu gnc-numeric-add or sub)
+                              ;; We're merging. Run merge-fn (usu + or -)
                               ;; and store total in dual-subtotal. Do NOT add column.
                               (begin
                                 (if column-amount
                                     (set! dual-subtotal
-                                          (merge-fn dual-subtotal column-amount
-                                                    GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
+                                          (merge-fn dual-subtotal column-amount)))
                                 (set! start-dual-column? #t))
                               (if start-dual-column?
                                   (begin
@@ -1275,9 +1274,8 @@ tags within description, notes or memo. ")
                                     ;; and add the columns.
                                     (if column-amount
                                         (set! dual-subtotal
-                                              (merge-fn dual-subtotal column-amount
-                                                        GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
-                                    (if (gnc-numeric-positive-p dual-subtotal)
+                                              (merge-fn dual-subtotal column-amount)))
+                                    (if (positive? dual-subtotal)
                                         (begin
                                           (addto! row-contents
                                                   (gnc:make-html-table-cell/markup
@@ -1291,9 +1289,9 @@ tags within description, notes or memo. ")
                                                    "total-number-cell"
                                                    (gnc:make-gnc-monetary
                                                     commodity
-                                                    (gnc-numeric-neg dual-subtotal))))))
+                                                    (- dual-subtotal))))))
                                     (set! start-dual-column? #f)
-                                    (set! dual-subtotal (gnc:make-gnc-numeric 0 1)))
+                                    (set! dual-subtotal 0))
                                   ;; Default; not merging/completed merge. Just
                                   ;; display monetary amount
                                   (addto! row-contents
@@ -1689,7 +1687,7 @@ tags within description, notes or memo. ")
               ((corresponding-acc-code) (lambda (s) (xaccSplitGetCorrAccountCode s)))
               ((reconciled-status) (lambda (s) (length (memq (xaccSplitGetReconcile s)
                                                              '(#\n #\c #\y #\f #\v)))))
-              ((amount) (lambda (s) (gnc-numeric-to-double (xaccSplitGetValue s))))
+              ((amount) (lambda (s) (gnc-numeric-to-scm (xaccSplitGetValue s))))
               ((description) (lambda (s) (xaccTransGetDescription (xaccSplitGetParent s))))
               ((number) (lambda (s)
                           (if BOOK-SPLIT-ACTION

commit e6dcc0cc1eea910d1dbad29725825954bc14dd73
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Dec 5 10:28:33 2017 +0800

    ENH: Optionally hide transactions
    
    This will hide the subheadings and the transactional data, only rendering the subtotals.
    May be useful e.g. for daily income and daily expense reports.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index e49deab..df153b2 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -74,6 +74,7 @@
 (define optname-show-account-code (N_ "Show Account Code"))
 (define optname-show-account-description (N_ "Show Account Description"))
 (define optname-show-informal-headers (N_ "Show Informal Debit/Credit Headers"))
+(define optname-show-subtotals-only (N_ "Show subtotals only (hide transactional data)"))
 (define optname-indenting (N_ "Add indenting columns"))
 (define optname-sec-sortkey (N_ "Secondary Key"))
 (define optname-sec-subtotal (N_ "Secondary Subtotal"))
@@ -612,6 +613,11 @@ tags within description, notes or memo. ")
              (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
 
         (gnc-option-db-set-option-selectable-by-name
+         options pagename-sorting optname-show-subtotals-only
+         (or (and prime-sortkey-subtotal-enabled prime-sortkey-subtotal-true)
+             (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
+
+        (gnc-option-db-set-option-selectable-by-name
          options pagename-sorting optname-show-informal-headers
          (or (member prime-sortkey (list 'account-name 'account-code))
              (member sec-sortkey (list 'account-name 'account-code))))
@@ -671,6 +677,13 @@ tags within description, notes or memo. ")
       #t))
 
     (gnc:register-trep-option
+     (gnc:make-simple-boolean-option
+      pagename-sorting optname-show-subtotals-only
+      "j6"
+      (_ "Show subtotals only, hiding transactional detail?")
+      #f))
+
+    (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       pagename-sorting optname-prime-subtotal
       "e5"
@@ -896,6 +909,9 @@ tags within description, notes or memo. ")
                 (and (opt-val gnc:pagename-general optname-common-currency)
                      (opt-val gnc:pagename-general optname-orig-currency)))
           (cons 'indenting (opt-val pagename-sorting optname-indenting))
+          (cons 'subtotals-only (and (opt-val pagename-sorting optname-show-subtotals-only)
+                                     (or (primary-get-info 'renderer-fn)
+                                         (secondary-get-info 'renderer-fn))))
           (cons 'running-balance (opt-val gnc:pagename-display (N_ "Running Balance")))
           (cons 'account-full-name (opt-val gnc:pagename-display (N_ "Use Full Account Name")))
           (cons 'memo (opt-val gnc:pagename-display (N_ "Memo")))
@@ -1206,7 +1222,8 @@ tags within description, notes or memo. ")
                         calculated-cells))
             (addto! row-contents (gnc:make-html-table-cell/size
                                     1 (+ right-indent width-left-columns width-right-columns) data)))
-        (gnc:html-table-append-row/markup! table subheading-style (reverse row-contents))))
+        (if (not (column-uses? 'subtotals-only))
+            (gnc:html-table-append-row/markup! table subheading-style (reverse row-contents)))))
 
     (define (add-subtotal-row subtotal-string subtotal-collectors subtotal-style level)
       (let* ((row-contents '())
@@ -1434,7 +1451,8 @@ tags within description, notes or memo. ")
                           (addto! row-contents (gnc:html-make-empty-cell)))))
                   cells)
 
-        (gnc:html-table-append-row/markup! table row-style (reverse row-contents))
+        (if (not (column-uses? 'subtotals-only))
+            (gnc:html-table-append-row/markup! table row-style (reverse row-contents)))
 
         (map (lambda (cell)
                (let ((cell-content (vector-ref cell 0))

commit 93b17214f39e5355d7169ad0887e2bd879f78529
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Dec 13 22:17:10 2017 +0800

    ENH: Add 'daily subtotal strategy
    
    This may be useful for 'total daily report'. e.g. total expenses per day. Perhaps more useful combined with 'hide transactional data' as the next commit.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 28b2af5..e49deab 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -244,6 +244,8 @@ options specified in the Options panels."))
 (define (time64-quarter t64) (+ (* 10 (gnc:date-get-year (gnc-localtime t64)))  (gnc:date-get-quarter (gnc-localtime t64))))
 (define (time64-month t64)   (+ (* 100 (gnc:date-get-year (gnc-localtime t64))) (gnc:date-get-month (gnc-localtime t64))))
 (define (time64-week t64)    (gnc:date-get-week (gnc-localtime t64)))
+(define (time64-day t64)     (+ (* 500 (gnc:date-get-year (gnc-localtime t64))) (gnc:date-get-year-day (gnc-localtime t64))))
+(define (time64->daily-string t) (qof-print-date t))
 (define (split->time64 s) (xaccTransGetDate (xaccSplitGetParent s)))
 
 (define date-subtotal-list
@@ -262,6 +264,12 @@ options specified in the Options panels."))
                 (cons 'tip (_ "None."))
                 (cons 'renderer-fn #f)))
 
+   (cons 'daily (list
+                  (cons 'split-sortvalue (lambda (s) (time64-day (split->time64 s))))
+                  (cons 'text (_ "Daily"))
+                  (cons 'tip (_ "Daily."))
+                  (cons 'renderer-fn (lambda (s) (time64->daily-string (split->time64 s))))))
+
    (cons 'weekly (list
                   (cons 'split-sortvalue (lambda (s) (time64-week (split->time64 s))))
                   (cons 'text (_ "Weekly"))
@@ -1654,6 +1662,7 @@ tags within description, notes or memo. ")
                 ((monthly)   (lambda (s) (time64-month (date s))))
                 ((quarterly) (lambda (s) (time64-quarter (date s))))
                 ((weekly)    (lambda (s) (time64-week (date s))))
+                ((daily)     (lambda (s) (time64-day (date s))))
                 ((none)      (lambda (s) (date s)))))
             (case key
               ((account-name) (lambda (s) (gnc-account-get-full-name (xaccSplitGetAccount s))))

commit 1ea1bcb38ebc8ad2dc2f024b7f8116a1be7eeefb
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Dec 2 17:46:31 2017 +0800

    ENH: Formalise Reconciliation Report as a new menu item.
    
    This commit offers a new item with defaults appropriate for a reconcilation report.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 382bc29..28b2af5 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -17,6 +17,7 @@
 ;; - add informational box, summarising options used, useful
 ;;   to troubleshoot reports
 ;; - add support for indenting for better grouping
+;; - add defaults suitable for a reconciliation report
 ;;
 ;; This program is free software; you can redistribute it and/or    
 ;; modify it under the terms of the GNU General Public License as   
@@ -384,6 +385,24 @@ Credit Card, and Income accounts."))
    keylist))
 
 
+;;
+;; Set defaults for reconcilation report
+;;
+(define (reconcile-report-options-generator)
+  (define options (trep-options-generator))
+  (gnc:option-set-value (gnc:lookup-option options pagename-sorting optname-prime-sortkey) 'reconciled-status)
+  (gnc:option-set-value (gnc:lookup-option options pagename-sorting optname-sec-sortkey)   'date)
+  (gnc:option-set-value (gnc:lookup-option options pagename-sorting optname-sec-date-subtotal) 'none)
+  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-general optname-startdate) (cons 'relative 'start-prev-quarter))
+  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-general optname-enddate)   (cons 'relative 'today))
+  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Reconciled Date")) #t)
+  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Running Balance")) #t)
+  (gnc:option-set-value (gnc:lookup-option options gnc:pagename-display (N_ "Memo")) #f)
+  options)
+
+;;
+;; Default Transaction Report
+;;
 (define (trep-options-generator)
 
   (define options (gnc:new-options))
@@ -1865,11 +1884,16 @@ tags within description, notes or memo. ")
 
 ;; Define the report.
 (gnc:define-report
-
  'version 1
+ 'name (_ "Reconciliation Report")
+ 'report-guid "e45218c6d76f11e7b5ef0800277ef320"
+ 'options-generator reconcile-report-options-generator
+ 'renderer trep-renderer)
 
+;; Define the report.
+(gnc:define-report
+ 'version 1
  'name reportname
  'report-guid "2fe3b9833af044abb929a88d5a59620f"
-
  'options-generator trep-options-generator
  'renderer trep-renderer)

commit 7a5f2ed49bc4c7986d0f49f268b5d74d88199915
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Nov 30 22:37:32 2017 +0800

    ENH: Add indenting for main data and subheadings/subtotals
    
    Adds between 0-2 empty columns to the left, depending on subtotal strategy.
    Option toggle added to Sorting tab

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index bafafde..382bc29 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -16,6 +16,7 @@
 ;;   and enable multiple data columns
 ;; - add informational box, summarising options used, useful
 ;;   to troubleshoot reports
+;; - add support for indenting for better grouping
 ;;
 ;; This program is free software; you can redistribute it and/or    
 ;; modify it under the terms of the GNU General Public License as   
@@ -72,6 +73,7 @@
 (define optname-show-account-code (N_ "Show Account Code"))
 (define optname-show-account-description (N_ "Show Account Description"))
 (define optname-show-informal-headers (N_ "Show Informal Debit/Credit Headers"))
+(define optname-indenting (N_ "Add indenting columns"))
 (define optname-sec-sortkey (N_ "Secondary Key"))
 (define optname-sec-subtotal (N_ "Secondary Subtotal"))
 (define optname-sec-sortorder  (N_ "Secondary Sort Order"))
@@ -264,7 +266,7 @@ options specified in the Options panels."))
                   (cons 'text (_ "Weekly"))
                   (cons 'tip (_ "Weekly."))
                   (cons 'renderer-fn (lambda (s) (gnc:date-get-week-year-string (gnc-localtime (split->time64 s)))))))
-   
+
    (cons 'monthly (list
                    (cons 'split-sortvalue (lambda (s) (time64-month (split->time64 s))))
                    (cons 'text (_ "Monthly"))
@@ -578,10 +580,15 @@ tags within description, notes or memo. ")
              (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
 
         (gnc-option-db-set-option-selectable-by-name
+         options pagename-sorting optname-indenting
+         (or (and prime-sortkey-subtotal-enabled prime-sortkey-subtotal-true)
+             (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
+
+        (gnc-option-db-set-option-selectable-by-name
          options pagename-sorting optname-show-informal-headers
          (or (member prime-sortkey (list 'account-name 'account-code))
              (member sec-sortkey (list 'account-name 'account-code))))
-        
+
         (gnc-option-db-set-option-selectable-by-name
          options pagename-sorting optname-prime-date-subtotal
          prime-date-sortingtype-enabled)
@@ -622,7 +629,6 @@ tags within description, notes or memo. ")
       (_ "Show the account description for subheadings?")
       #f))
 
-
     (gnc:register-trep-option
      (gnc:make-simple-boolean-option
       pagename-sorting optname-show-informal-headers
@@ -631,6 +637,13 @@ tags within description, notes or memo. ")
       #f))
 
     (gnc:register-trep-option
+     (gnc:make-simple-boolean-option
+      pagename-sorting optname-indenting
+      "j5"
+      (_ "Add indenting columns with grouping and subtotals?")
+      #t))
+
+    (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       pagename-sorting optname-prime-subtotal
       "e5"
@@ -855,6 +868,7 @@ tags within description, notes or memo. ")
           (cons 'amount-original-currency
                 (and (opt-val gnc:pagename-general optname-common-currency)
                      (opt-val gnc:pagename-general optname-orig-currency)))
+          (cons 'indenting (opt-val pagename-sorting optname-indenting))
           (cons 'running-balance (opt-val gnc:pagename-display (N_ "Running Balance")))
           (cons 'account-full-name (opt-val gnc:pagename-display (N_ "Use Full Account Name")))
           (cons 'memo (opt-val gnc:pagename-display (N_ "Memo")))
@@ -1119,36 +1133,61 @@ tags within description, notes or memo. ")
     (define width-left-columns (length left-columns))
     (define width-right-columns (length calculated-cells))
 
+    (define primary-indent
+      (if (and (column-uses? 'indenting)
+               (primary-get-info 'renderer-fn))
+          1 0))
+
+    (define secondary-indent
+      (if (and (column-uses? 'indenting)
+               (secondary-get-info 'renderer-fn))
+          1 0))
+
+    (define indent-level
+      (+ primary-indent secondary-indent))
+
+
     (define (add-subheading data subheading-style split level)
-      (let ((sortkey (opt-val pagename-sorting
-                           (case level
-                             ((primary) optname-prime-sortkey)
-                             ((secondary) optname-sec-sortkey)))))
+      (let* ((row-contents '())
+             (sortkey (opt-val pagename-sorting
+                               (case level
+                                 ((primary) optname-prime-sortkey)
+                                 ((secondary) optname-sec-sortkey))))
+             (left-indent (case level
+                            ((primary total) 0)
+                            ((secondary) primary-indent)))
+             (right-indent (- indent-level left-indent)))
+        (for-each (lambda (cell) (addto! row-contents cell))
+                  (gnc:html-make-empty-cells left-indent))
         (if (and (opt-val pagename-sorting optname-show-informal-headers)
                  (member sortkey SORTKEY-INFORMAL-HEADERS))
-            (let ((row-contents '()))
-              (begin
-                (if export?
-                    (begin (addto! row-contents (gnc:make-html-table-cell subheading-style data))
-                           (for-each (lambda (cell) (addto! row-contents cell))
-                                     (gnc:html-make-empty-cells (- width-left-columns 1))))
-                    (addto! row-contents (gnc:make-html-table-cell/size 1 width-left-columns data)))
-                (map (lambda (col)
-                       (addto! row-contents
-                               (gnc:make-html-table-cell
-                                "<b>"
-                                ((vector-ref col 5)
-                                 ((keylist-get-info sortkey-list sortkey 'renderer-fn) split))
-                                "</b>")))
-                     calculated-cells)
-                (gnc:html-table-append-row/markup! table subheading-style (reverse row-contents))))
-            (let ((heading-cell (gnc:make-html-table-cell data)))
-              (gnc:html-table-cell-set-colspan! heading-cell (+ width-left-columns width-right-columns))
-              (gnc:html-table-append-row/markup!
-               table subheading-style (list heading-cell))))))
-
-    (define (add-subtotal-row subtotal-string subtotal-collectors subtotal-style)
+            (begin
+              (if export?
+                  (begin
+                    (addto! row-contents (gnc:make-html-table-cell data))
+                    (for-each (lambda (cell) (addto! row-contents cell))
+                              (gnc:html-make-empty-cells (+ right-indent width-left-columns -1))))
+                  (addto! row-contents (gnc:make-html-table-cell/size
+                                        1 (+ right-indent width-left-columns) data)))
+              (for-each (lambda (cell)
+                          (addto! row-contents
+                                  (gnc:make-html-table-cell
+                                   "<b>"
+                                   ((vector-ref cell 5)
+                                    ((keylist-get-info sortkey-list sortkey 'renderer-fn) split))
+                                   "</b>")))
+                        calculated-cells))
+            (addto! row-contents (gnc:make-html-table-cell/size
+                                    1 (+ right-indent width-left-columns width-right-columns) data)))
+        (gnc:html-table-append-row/markup! table subheading-style (reverse row-contents))))
+
+    (define (add-subtotal-row subtotal-string subtotal-collectors subtotal-style level)
       (let* ((row-contents '())
+             (left-indent (case level
+                            ((total) 0)
+                            ((primary) primary-indent)
+                            ((secondary) (+ primary-indent secondary-indent))))
+             (right-indent (- indent-level left-indent))
              (merge-list (map (lambda (cell) (vector-ref cell 4)) calculated-cells))
              (columns (map (lambda (coll) (coll 'format gnc:make-gnc-monetary #f)) subtotal-collectors))
              (list-of-commodities (delete-duplicates (map gnc:gnc-monetary-commodity (concatenate columns))
@@ -1166,8 +1205,8 @@ tags within description, notes or memo. ")
               (begin
                 (addto! row-contents (gnc:make-html-table-cell/markup "total-label-cell" string))
                 (for-each (lambda (cell) (addto! row-contents cell))
-                          (gnc:html-make-empty-cells (- width-left-columns 1))))
-              (addto! row-contents (gnc:make-html-table-cell/size/markup 1 width-left-columns "total-label-cell" string))))
+                          (gnc:html-make-empty-cells (+ right-indent width-left-columns -1))))
+              (addto! row-contents (gnc:make-html-table-cell/size/markup 1 (+ right-indent width-left-columns) "total-label-cell" string))))
 
         (define (add-columns commodity)
           (let ((start-dual-column? #f)
@@ -1219,6 +1258,8 @@ tags within description, notes or memo. ")
                       merge-list)))
 
         ;;first row
+        (for-each (lambda (cell) (addto! row-contents cell))
+                  (gnc:html-make-empty-cells left-indent))
         (add-first-column subtotal-string)
         (add-columns (if (pair? list-of-commodities)
                          (car list-of-commodities)
@@ -1229,6 +1270,8 @@ tags within description, notes or memo. ")
         (if (pair? list-of-commodities)
             (for-each (lambda (commodity)
                         (set! row-contents '())
+                        (for-each (lambda (cell) (addto! row-contents cell))
+                                  (gnc:html-make-empty-cells left-indent))
                         (add-first-column "")
                         (add-columns commodity)
                         (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents)))
@@ -1301,7 +1344,7 @@ tags within description, notes or memo. ")
           (render-account sortkey split anchor?))
          ((eq? sortkey 'reconciled-status)
           (render-generic sortkey split)))))
-    
+
     (define (render-grand-total)
       (_ "Grand Total"))
 
@@ -1333,7 +1376,10 @@ tags within description, notes or memo. ")
                            reverse?
                            subtotal?)))
                cell-calculators))
-        
+
+        (for-each (lambda (cell) (addto! row-contents cell))
+                  (gnc:html-make-empty-cells indent-level))
+
         (for-each (lambda (col)
                     (addto! row-contents col))
                   left-cols)
@@ -1400,10 +1446,10 @@ tags within description, notes or memo. ")
                  table def:grand-total-style
                  (list
                   (gnc:make-html-table-cell/size
-                   1 (+ width-left-columns width-right-columns)
+                   1 (+ indent-level width-left-columns width-right-columns)
                    (gnc:make-html-text (gnc:html-markup-hr)))))
 
-                (add-subtotal-row (render-grand-total) total-collectors def:grand-total-style)))
+                (add-subtotal-row (render-grand-total) total-collectors def:grand-total-style 'total)))
 
           (let* ((current (car splits))
                  (rest (cdr splits))
@@ -1453,13 +1499,15 @@ tags within description, notes or memo. ")
                         (add-subtotal-row (total-string
                                            (render-summary current 'secondary #f))
                                           secondary-subtotal-collectors
-                                          def:secondary-subtotal-style)
+                                          def:secondary-subtotal-style
+                                          'secondary)
                         (for-each (lambda (coll) (coll 'reset #f #f))
                                   secondary-subtotal-collectors)))
                   (add-subtotal-row (total-string
                                      (render-summary current 'primary #f))
                                     primary-subtotal-collectors
-                                    def:primary-subtotal-style)
+                                    def:primary-subtotal-style
+                                    'primary)
                   (for-each (lambda (coll) (coll 'reset #f #f))
                             primary-subtotal-collectors)
                   (if next
@@ -1478,7 +1526,8 @@ tags within description, notes or memo. ")
                     (begin (add-subtotal-row (total-string
                                               (render-summary current 'secondary #f))
                                              secondary-subtotal-collectors
-                                             def:secondary-subtotal-style)
+                                             def:secondary-subtotal-style
+                                             'secondary)
                            (for-each (lambda (coll) (coll 'reset #f #f))
                                      secondary-subtotal-collectors)
                            (if next
@@ -1487,7 +1536,10 @@ tags within description, notes or memo. ")
 
             (do-rows-with-subtotals rest (not odd-row?)))))
 
-    (gnc:html-table-set-col-headers! table (concatenate (list headings-left-columns headings-right-columns)))
+    (gnc:html-table-set-col-headers! table (concatenate (list
+                                                         (gnc:html-make-empty-cells indent-level)
+                                                         headings-left-columns
+                                                         headings-right-columns)))
 
     (if (primary-get-info 'renderer-fn)
         (add-subheading (render-summary (car splits) 'primary #t)

commit 408f609a58225426e83bbc41edb9150fb258c9dc
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Nov 30 17:04:58 2017 +0800

    ENH: Add sortkey Reconciled Status
    
    Can be useful for reconcilation report.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index e2bb438..bafafde 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -116,7 +116,12 @@ options specified in the Options panels."))
 ;; The option-values of the sorting key multichoice option, for
 ;; which a subtotal should be enabled.
 (define SUBTOTAL-ENABLED (list 'account-name 'corresponding-acc-name
-                               'account-code 'corresponding-acc-code))
+                               'account-code 'corresponding-acc-code
+                               'reconciled-status))
+
+(define ACCOUNT-SORTING-TYPES (list 'account-name 'corresponding-acc-name
+                                    'account-code 'corresponding-acc-code))
+(define CUSTOM-SORTING (list 'reconciled-status))
 
 (define SORTKEY-INFORMAL-HEADERS (list 'account-name 'account-code))
 
@@ -132,6 +137,7 @@ options specified in the Options panels."))
   ;;       behaviour varies according to sortkey.
   ;;       account-types converts split->account
   ;;       #f means the sortkey cannot be subtotalled
+  ;;       otherwise it converts split->string
   ;;
   (list (cons 'account-name  (list (cons 'sortkey (list SPLIT-ACCT-FULLNAME))
                                    (cons 'split-sortvalue (lambda (a) (gnc-account-get-full-name (xaccSplitGetAccount a))))
@@ -157,6 +163,19 @@ options specified in the Options panels."))
                                      (cons 'tip (_ "Sort by the Reconciled Date."))
                                      (cons 'renderer-fn #f)))
 
+        (cons 'reconciled-status (list (cons 'sortkey #f)
+                                       (cons 'split-sortvalue (lambda (s) (length (memq (xaccSplitGetReconcile s)
+                                                                                        '(#\n #\c #\y #\f #\v)))))
+                                       (cons 'text (_ "Reconciled Status"))
+                                       (cons 'tip (_ "Sort by the Reconciled Status"))
+                                       (cons 'renderer-fn (lambda (s) (case (xaccSplitGetReconcile s)
+                                                                        ((#\y) (_ "Reconciled"))
+                                                                        ((#\c) (_ "Cleared"))
+                                                                        ((#\n) (_ "Unreconciled"))
+                                                                        ((#\f) (_ "Frozen"))
+                                                                        ((#\v) (_ "Voided"))
+                                                                        (else (_ "Unknown")))))))
+
         (cons 'register-order (list (cons 'sortkey (list QUERY-DEFAULT-SORT))
                                     (cons 'split-sortvalue #f)
                                     (cons 'text (_ "Register Order"))
@@ -1262,6 +1281,10 @@ tags within description, notes or memo. ")
              description)
             name)))
 
+    ;; generic renderer. retrieve renderer-fn which should return a str
+    (define (render-generic sortkey split)
+      ((keylist-get-info sortkey-list sortkey 'renderer-fn) split))
+
     (define (render-summary split level anchor?)
       (let ((sortkey (opt-val pagename-sorting
                               (case level
@@ -1271,9 +1294,13 @@ tags within description, notes or memo. ")
                                         (case level
                                           ((primary) optname-prime-date-subtotal)
                                           ((secondary) optname-sec-date-subtotal)))))
-        (if (member sortkey DATE-SORTING-TYPES)
-            (render-date date-subtotal-key split)
-            (render-account sortkey split anchor?))))
+        (cond
+         ((member sortkey DATE-SORTING-TYPES)
+          (render-date date-subtotal-key split))
+         ((member sortkey ACCOUNT-SORTING-TYPES)
+          (render-account sortkey split anchor?))
+         ((eq? sortkey 'reconciled-status)
+          (render-generic sortkey split)))))
     
     (define (render-grand-total)
       (_ "Grand Total"))
@@ -1538,7 +1565,9 @@ tags within description, notes or memo. ")
          (custom-sort? (or (and (member primary-key DATE-SORTING-TYPES)   ; this will remain
                                 (not (eq? primary-date-subtotal 'none)))  ; until qof-query
                            (and (member secondary-key DATE-SORTING-TYPES) ; is upgraded
-                                (not (eq? secondary-date-subtotal 'none)))))
+                                (not (eq? secondary-date-subtotal 'none)))
+                           (or (member primary-key CUSTOM-SORTING)
+                               (member secondary-key CUSTOM-SORTING))))
          (infobox-display (opt-val gnc:pagename-general optname-infobox-display))
          (query (qof-query-create-for-splits)))
 
@@ -1560,6 +1589,8 @@ tags within description, notes or memo. ")
               ((account-code) (lambda (s) (xaccAccountGetCode (xaccSplitGetAccount s))))
               ((corresponding-acc-name) (lambda (s) (xaccSplitGetCorrAccountFullName s)))
               ((corresponding-acc-code) (lambda (s) (xaccSplitGetCorrAccountCode s)))
+              ((reconciled-status) (lambda (s) (length (memq (xaccSplitGetReconcile s)
+                                                             '(#\n #\c #\y #\f #\v)))))
               ((amount) (lambda (s) (gnc-numeric-to-double (xaccSplitGetValue s))))
               ((description) (lambda (s) (xaccTransGetDescription (xaccSplitGetParent s))))
               ((number) (lambda (s)

commit 3de3d3cc9a2cd03f819551e0a660fd8473c50144
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Nov 30 16:07:27 2017 +0800

    ENH: Add debit/credit friendly names in subheading rendering
    
    Also add UI to toggle friendly headers

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index fc5ce15..e2bb438 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -71,6 +71,7 @@
 (define optname-full-account-name (N_ "Show Full Account Name"))
 (define optname-show-account-code (N_ "Show Account Code"))
 (define optname-show-account-description (N_ "Show Account Description"))
+(define optname-show-informal-headers (N_ "Show Informal Debit/Credit Headers"))
 (define optname-sec-sortkey (N_ "Secondary Key"))
 (define optname-sec-subtotal (N_ "Secondary Subtotal"))
 (define optname-sec-sortorder  (N_ "Secondary Sort Order"))
@@ -117,6 +118,7 @@ options specified in the Options panels."))
 (define SUBTOTAL-ENABLED (list 'account-name 'corresponding-acc-name
                                'account-code 'corresponding-acc-code))
 
+(define SORTKEY-INFORMAL-HEADERS (list 'account-name 'account-code))
 
 (define sortkey-list
   ;;
@@ -557,6 +559,11 @@ tags within description, notes or memo. ")
              (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
 
         (gnc-option-db-set-option-selectable-by-name
+         options pagename-sorting optname-show-informal-headers
+         (or (member prime-sortkey (list 'account-name 'account-code))
+             (member sec-sortkey (list 'account-name 'account-code))))
+        
+        (gnc-option-db-set-option-selectable-by-name
          options pagename-sorting optname-prime-date-subtotal
          prime-date-sortingtype-enabled)
 
@@ -595,7 +602,15 @@ tags within description, notes or memo. ")
       "j3"
       (_ "Show the account description for subheadings?")
       #f))
-    
+
+
+    (gnc:register-trep-option
+     (gnc:make-simple-boolean-option
+      pagename-sorting optname-show-informal-headers
+      "j4"
+      (_ "Show the informal headers for debit/credit accounts?")
+      #f))
+
     (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       pagename-sorting optname-prime-subtotal
@@ -984,6 +999,8 @@ tags within description, notes or memo. ")
            (report-currency (lambda (s) (if (column-uses? 'common-currency)
                                             (opt-val gnc:pagename-general optname-currency)
                                             (currency s))))
+           (friendly-debit (lambda (a) (gnc:get-debit-string (xaccAccountGetType a))))
+           (friendly-credit (lambda (a) (gnc:get-credit-string (xaccAccountGetType a))))
            (header-commodity (lambda (str)
                                (string-append
                                 str
@@ -1019,47 +1036,55 @@ tags within description, notes or memo. ")
            (running-balance (lambda (s) (gnc:make-gnc-monetary (currency s) (xaccSplitGetBalance s)))))
         (append
          ;; each column will be a vector
-         ;; (vector heading calculator-function reverse-column? subtotal? (vector start-dual-column? merging-function))
-         ;; (calculator-function split) to obtain amount
-         ;; reverse? to optionally reverse signs
-         ;; subtotal? to allow subtotals (ie irrelevant for running balance)
-         ;; merge? to merge with the next cell (ie for debit/credit cells)
-         ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to dual-subtotal
+         ;; (vector heading
+         ;;         calculator-function                          ;; (calculator-function split) to obtain amount
+         ;;         reverse-column?                              ;; to optionally reverse signs
+         ;;         subtotal?                                    ;; subtotal? to allow subtotals (ie irrelevant for running balance)
+         ;;         (vector start-dual-column?                   ;; #t for the left side of a dual column (i.e. debit/credit)
+         ;;                 merging-function))                   ;; function to apply to dual-subtotal (gnc-numeric-add/sub)
+         ;;         friendly-heading-fn                          ;; retrieve friendly heading name for account debit/credit
          (if (column-uses? 'amount-single)
              (list (vector (header-commodity (_ "Amount"))
                            amount #t #t
-                           (vector #f #f)))
+                           (vector #f #f)
+                           (lambda (a) "")))
              '())
          (if (column-uses? 'amount-double)
              (list (vector (header-commodity (_ "Debit"))
                            debit-amount #f #t
-                           (vector #t gnc-numeric-add))
+                           (vector #t gnc-numeric-add)
+                           friendly-debit)
                    (vector (header-commodity (_ "Credit"))
                            credit-amount #f #t
-                           (vector #f gnc-numeric-sub)))
+                           (vector #f gnc-numeric-sub)
+                           friendly-credit))
              '())
 
          (if (and (column-uses? 'amount-original-currency)
                   (column-uses? 'amount-single))
              (list (vector (_ "Amount")
                            original-amount #t #t
-                           (vector #f #f)))
+                           (vector #f #f)
+                           (lambda (a) "")))
              '())
 
          (if (and (column-uses? 'amount-original-currency)
                   (column-uses? 'amount-double))
              (list (vector (_ "Debit")
                            original-debit-amount #f #t
-                           (vector #t gnc-numeric-add))
+                           (vector #t gnc-numeric-add)
+                           friendly-debit)
                    (vector (_ "Credit")
                            original-credit-amount #f #t
-                           (vector #f gnc-numeric-sub)))
+                           (vector #f gnc-numeric-sub)
+                           friendly-credit))
              '())
 
          (if (column-uses? 'running-balance)
              (list (vector (_ "Running Balance")
                            running-balance #t #f
-                           (vector #f #f)))
+                           (vector #f #f)
+                           (lambda (a) "")))
              '()))))
 
     (define headings-left-columns
@@ -1075,11 +1100,33 @@ tags within description, notes or memo. ")
     (define width-left-columns (length left-columns))
     (define width-right-columns (length calculated-cells))
 
-    (define (add-subheading data subheading-style)
-      (let ((heading-cell (gnc:make-html-table-cell data)))
-        (gnc:html-table-cell-set-colspan! heading-cell (+ width-left-columns width-right-columns))
-        (gnc:html-table-append-row/markup!
-         table subheading-style (list heading-cell))))
+    (define (add-subheading data subheading-style split level)
+      (let ((sortkey (opt-val pagename-sorting
+                           (case level
+                             ((primary) optname-prime-sortkey)
+                             ((secondary) optname-sec-sortkey)))))
+        (if (and (opt-val pagename-sorting optname-show-informal-headers)
+                 (member sortkey SORTKEY-INFORMAL-HEADERS))
+            (let ((row-contents '()))
+              (begin
+                (if export?
+                    (begin (addto! row-contents (gnc:make-html-table-cell subheading-style data))
+                           (for-each (lambda (cell) (addto! row-contents cell))
+                                     (gnc:html-make-empty-cells (- width-left-columns 1))))
+                    (addto! row-contents (gnc:make-html-table-cell/size 1 width-left-columns data)))
+                (map (lambda (col)
+                       (addto! row-contents
+                               (gnc:make-html-table-cell
+                                "<b>"
+                                ((vector-ref col 5)
+                                 ((keylist-get-info sortkey-list sortkey 'renderer-fn) split))
+                                "</b>")))
+                     calculated-cells)
+                (gnc:html-table-append-row/markup! table subheading-style (reverse row-contents))))
+            (let ((heading-cell (gnc:make-html-table-cell data)))
+              (gnc:html-table-cell-set-colspan! heading-cell (+ width-left-columns width-right-columns))
+              (gnc:html-table-append-row/markup!
+               table subheading-style (list heading-cell))))))
 
     (define (add-subtotal-row subtotal-string subtotal-collectors subtotal-style)
       (let* ((row-contents '())
@@ -1391,10 +1438,10 @@ tags within description, notes or memo. ")
                   (if next
                       (begin
                         (add-subheading (render-summary next 'primary #t)
-                                        def:primary-subtotal-style)
+                                        def:primary-subtotal-style next 'primary)
                         (if secondary-subtotal-comparator
                             (add-subheading (render-summary next 'secondary #t)
-                                            def:secondary-subtotal-style)))))
+                                            def:secondary-subtotal-style next 'secondary)))))
 
                 (if (and secondary-subtotal-comparator
                          (or (not next)
@@ -1409,7 +1456,7 @@ tags within description, notes or memo. ")
                                      secondary-subtotal-collectors)
                            (if next
                                (add-subheading (render-summary next 'secondary #t)
-                                               def:secondary-subtotal-style)))))
+                                               def:secondary-subtotal-style next 'secondary)))))
 
             (do-rows-with-subtotals rest (not odd-row?)))))
 
@@ -1417,12 +1464,12 @@ tags within description, notes or memo. ")
 
     (if (primary-get-info 'renderer-fn)
         (add-subheading (render-summary (car splits) 'primary #t)
-                        def:primary-subtotal-style))
+                        def:primary-subtotal-style (car splits) 'primary))
 
     (if (secondary-get-info 'renderer-fn)
         (add-subheading (render-summary (car splits) 'secondary #t)
-                        def:secondary-subtotal-style))
-    
+                        def:secondary-subtotal-style (car splits) 'secondary))
+
     (do-rows-with-subtotals splits #t)
 
     table))

commit 139e2aa7f249ccef9b2dde91692936f8a82de0a9
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Nov 27 21:43:07 2017 +0800

    ENH: Add option to choose infobox display summary
    
    Options are: always/never display, or display if no splits are matched or found

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 38c7819..fc5ce15 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -83,6 +83,7 @@
 (define optname-common-currency (N_ "Common Currency"))
 (define optname-orig-currency (N_ "Show original currency amount"))
 (define optname-currency (N_ "Report's currency"))
+(define optname-infobox-display (N_ "Add options summary"))
 
 ;;Filtering
 (define pagename-filter (N_ "Filter"))
@@ -399,6 +400,24 @@ Credit Card, and Income accounts."))
     gnc:pagename-general optname-table-export
     "g" (_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))
 
+  (gnc:register-trep-option
+   (gnc:make-multichoice-option
+    gnc:pagename-general optname-infobox-display
+    "h" (_ "Add summary of options.")
+    '(no-match)
+    ;; This is an alist of conditions for displaying the infobox
+    ;; 'no-match for empty-report
+    ;; 'match for generated report
+    (list (vector '(no-match)
+                  (_ "If no transactions matched")
+                  (_ "Display summary if no transactions were matched."))
+          (vector '(no-match match)
+                  (_ "Always")
+                  (_ "Always display summary."))
+          (vector '()
+                  (_ "Never")
+                  (_ "Disable report summary.")))))
+
   ;; Filtering Options
 
   (gnc:register-trep-option
@@ -1473,6 +1492,7 @@ tags within description, notes or memo. ")
                                 (not (eq? primary-date-subtotal 'none)))  ; until qof-query
                            (and (member secondary-key DATE-SORTING-TYPES) ; is upgraded
                                 (not (eq? secondary-date-subtotal 'none)))))
+         (infobox-display (opt-val gnc:pagename-general optname-infobox-display))
          (query (qof-query-create-for-splits)))
 
     (define (generic-less? X Y key date-subtotal ascend?)
@@ -1617,10 +1637,11 @@ tags within description, notes or memo. ")
                 (gnc:html-markup-h2 NO-MATCHING-ACCT-HEADER)
                 (gnc:html-markup-p NO-MATCHING-ACCT-TEXT)))
 
-              (gnc:html-document-add-object!
-               document                 
-               (infobox))))
-            
+              (if (member 'nomatch infobox-display)
+                  (gnc:html-document-add-object!
+                   document
+                   (infobox)))))
+
         (begin
 
           (qof-query-set-book query (gnc-get-current-book))
@@ -1683,9 +1704,10 @@ tags within description, notes or memo. ")
                   (gnc:html-markup-h2 NO-MATCHING-TRANS-HEADER)
                   (gnc:html-markup-p NO-MATCHING-TRANS-TEXT)))
 
-                (gnc:html-document-add-object!
-                 document
-                 (infobox)))
+                (if (member 'no-match infobox-display)
+                    (gnc:html-document-add-object!
+                     document
+                     (infobox))))
 
               (let ((table (make-split-table splits options)))
 
@@ -1700,9 +1722,10 @@ tags within description, notes or memo. ")
                             (gnc-print-date begindate)
                             (gnc-print-date enddate)))))
 
-                (gnc:html-document-add-object!
-                 document                 
-                 (infobox))
+                (if (member 'match infobox-display)
+                    (gnc:html-document-add-object!
+                     document
+                     (infobox)))
 
                 (gnc:html-document-add-object! document table)))))
 

commit f2df1bd49cd8e651a1838711909af13cfe45847f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:42:56 2017 +0800

    COSMETIC: if grand-totals=#f then omit <hr>
    
    I think <hr> and grand-total belong together because they share
    the same style.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 39fbbe0..38c7819 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1300,16 +1300,16 @@ tags within description, notes or memo. ")
       (set! work-done (+ 1 work-done))
 
       (if (null? splits)
-          
-          (begin
-            
-            (gnc:html-table-append-row/markup!
-             table def:grand-total-style
-             (list
-              (gnc:make-html-table-cell/size
-               1 (+ width-left-columns width-right-columns) (gnc:make-html-text (gnc:html-markup-hr)))))
 
-            (if (opt-val gnc:pagename-display "Totals")
+          (if (opt-val gnc:pagename-display "Totals")
+              (begin
+                (gnc:html-table-append-row/markup!
+                 table def:grand-total-style
+                 (list
+                  (gnc:make-html-table-cell/size
+                   1 (+ width-left-columns width-right-columns)
+                   (gnc:make-html-text (gnc:html-markup-hr)))))
+
                 (add-subtotal-row (render-grand-total) total-collectors def:grand-total-style)))
 
           (let* ((current (car splits))

commit a81c348310a278f2d8a5448bb8be45ae6037a30c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Nov 29 21:21:14 2017 +0800

    REFACTOR: remove 'renderer-key lookup symbol, simplify custom sorter

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 23bef7d..39fbbe0 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -125,102 +125,101 @@ options specified in the Options panels."))
   ;;  'split-sortvalue     - function which retrieves number/string used for comparing splits
   ;;  'text                - text displayed in Display tab
   ;;  'tip                 - tooltip displayed in Display tab
-  ;;  'renderer-key        - helper symbol to select subtotal/subheading renderer
+  ;;  'renderer-fn         - helper function to select subtotal/subheading renderer
+  ;;       behaviour varies according to sortkey.
+  ;;       account-types converts split->account
+  ;;       #f means the sortkey cannot be subtotalled
   ;;
   (list (cons 'account-name  (list (cons 'sortkey (list SPLIT-ACCT-FULLNAME))
                                    (cons 'split-sortvalue (lambda (a) (gnc-account-get-full-name (xaccSplitGetAccount a))))
                                    (cons 'text (_ "Account Name"))
                                    (cons 'tip (_ "Sort & subtotal by account name."))
-                                   (cons 'renderer-key 'account)))
+                                   (cons 'renderer-fn (lambda (a) (xaccSplitGetAccount a)))))
 
         (cons 'account-code (list (cons 'sortkey (list SPLIT-ACCOUNT ACCOUNT-CODE-))
                                   (cons 'split-sortvalue (lambda (a) (xaccAccountGetCode (xaccSplitGetAccount a))))
                                   (cons 'text (_ "Account Code"))
                                   (cons 'tip (_ "Sort & subtotal by account code."))
-                                  (cons 'renderer-key 'account)))
+                                  (cons 'renderer-fn (lambda (a) (xaccSplitGetAccount a)))))
 
         (cons 'date         (list (cons 'sortkey (list SPLIT-TRANS TRANS-DATE-POSTED))
                                   (cons 'split-sortvalue #f)
                                   (cons 'text (_ "Date"))
                                   (cons 'tip (_ "Sort by date."))
-                                  (cons 'renderer-key #f)))
+                                  (cons 'renderer-fn #f)))
 
         (cons 'reconciled-date (list (cons 'sortkey (list SPLIT-DATE-RECONCILED))
                                      (cons 'split-sortvalue #f)
                                      (cons 'text (_ "Reconciled Date"))
                                      (cons 'tip (_ "Sort by the Reconciled Date."))
-                                     (cons 'renderer-key #f)))
+                                     (cons 'renderer-fn #f)))
 
         (cons 'register-order (list (cons 'sortkey (list QUERY-DEFAULT-SORT))
                                     (cons 'split-sortvalue #f)
                                     (cons 'text (_ "Register Order"))
                                     (cons 'tip (_ "Sort as in the register."))
-                                    (cons 'renderer-key #f)))
+                                    (cons 'renderer-fn #f)))
 
         (cons 'corresponding-acc-name (list (cons 'sortkey (list SPLIT-CORR-ACCT-NAME))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountFullName a)))
                                             (cons 'text (_ "Other Account Name"))
                                             (cons 'tip (_ "Sort by account transferred from/to's name."))
-                                            (cons 'renderer-key 'other-acc)))
+                                            (cons 'renderer-fn (lambda (a) (xaccSplitGetAccount (xaccSplitGetOtherSplit a))))))
 
         (cons 'corresponding-acc-code (list (cons 'sortkey (list SPLIT-CORR-ACCT-CODE))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountCode a)))
                                             (cons 'text (_ "Other Account Code"))
                                             (cons 'tip (_ "Sort by account transferred from/to's code."))
-                                            (cons 'renderer-key 'other-acct)))
+                                            (cons 'renderer-fn (lambda (a) (xaccSplitGetAccount (xaccSplitGetOtherSplit a))))))
 
         (cons 'amount        (list (cons 'sortkey (list SPLIT-VALUE))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "Amount"))
                                    (cons 'tip (_ "Sort by amount."))
-                                   (cons 'renderer-key #f)))
+                                   (cons 'renderer-fn #f)))
 
         (cons 'description   (list (cons 'sortkey (list SPLIT-TRANS TRANS-DESCRIPTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "Description"))
                                    (cons 'tip (_ "Sort by description."))
-                                   (cons 'renderer-key #f)))
+                                   (cons 'renderer-fn #f)))
 
         (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
             (cons 'number    (list (cons 'sortkey (list SPLIT-ACTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "Number/Action"))
                                    (cons 'tip (_ "Sort by check number/action."))
-                                   (cons 'renderer-key #f)))
+                                   (cons 'renderer-fn #f)))
 
             (cons 'number    (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "Number"))
                                    (cons 'tip (_ "Sort by check/transaction number."))
-                                   (cons 'renderer-key #f))))
+                                   (cons 'renderer-fn #f))))
 
         (cons 't-number      (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "Transaction Number"))
                                    (cons 'tip (_ "Sort by transaction number."))
-                                   (cons 'renderer-key #f)))
+                                   (cons 'renderer-fn #f)))
 
         (cons 'memo          (list (cons 'sortkey (list SPLIT-MEMO))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "Memo"))
                                    (cons 'tip (_ "Sort by memo."))
-                                   (cons 'renderer-key #f)))
+                                   (cons 'renderer-fn #f)))
 
         (cons 'none          (list (cons 'sortkey '())
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (_ "None"))
                                    (cons 'tip (_ "Do not sort."))
-                                   (cons 'renderer-key #f)))))
-
+                                   (cons 'renderer-fn #f)))))
 
 (define (time64-year t64)    (gnc:date-get-year (gnc-localtime t64)))
 (define (time64-quarter t64) (+ (* 10 (gnc:date-get-year (gnc-localtime t64)))  (gnc:date-get-quarter (gnc-localtime t64))))
 (define (time64-month t64)   (+ (* 100 (gnc:date-get-year (gnc-localtime t64))) (gnc:date-get-month (gnc-localtime t64))))
 (define (time64-week t64)    (gnc:date-get-week (gnc-localtime t64)))
-(define (split-week a) (time64-week (xaccTransGetDate (xaccSplitGetParent a))))
-(define (split-month a) (time64-month (xaccTransGetDate (xaccSplitGetParent a))))
-(define (split-quarter a) (time64-quarter (xaccTransGetDate (xaccSplitGetParent a))))
-(define (split-year a) (time64-year (xaccTransGetDate (xaccSplitGetParent a))))
+(define (split->time64 s) (xaccTransGetDate (xaccSplitGetParent s)))
 
 (define date-subtotal-list
   ;; List for date option.
@@ -228,41 +227,39 @@ options specified in the Options panels."))
   ;;  'split-sortvalue     - function which retrieves number/string used for comparing splits
   ;;  'text                - text displayed in Display tab
   ;;  'tip                 - tooltip displayed in Display tab
-  ;;  'renderer-key        - helper symbol to select subtotal/subheading renderer
+  ;;  'renderer-fn         - func retrieve string for subtotal/subheading renderer
+  ;;         #f means the date sortkey is not grouped
+  ;;         otherwise it converts split->string
   (list
    (cons 'none (list
                 (cons 'split-sortvalue #f)
                 (cons 'text (_ "None"))
                 (cons 'tip (_ "None."))
-                (cons 'renderer-key #f)))
+                (cons 'renderer-fn #f)))
 
    (cons 'weekly (list
-                  (cons 'split-sortvalue split-week)
+                  (cons 'split-sortvalue (lambda (s) (time64-week (split->time64 s))))
                   (cons 'text (_ "Weekly"))
                   (cons 'tip (_ "Weekly."))
-                  (cons 'renderer-key 'weekly)
-                  (cons 'renderer-fn gnc:date-get-week-year-string)))
-
+                  (cons 'renderer-fn (lambda (s) (gnc:date-get-week-year-string (gnc-localtime (split->time64 s)))))))
+   
    (cons 'monthly (list
-                   (cons 'split-sortvalue split-month)
+                   (cons 'split-sortvalue (lambda (s) (time64-month (split->time64 s))))
                    (cons 'text (_ "Monthly"))
                    (cons 'tip (_ "Monthly."))
-                   (cons 'renderer-key 'monthly)
-                   (cons 'renderer-fn gnc:date-get-month-year-string)))
+                   (cons 'renderer-fn (lambda (s) (gnc:date-get-month-year-string (gnc-localtime (split->time64 s)))))))
 
    (cons 'quarterly (list
-                     (cons 'split-sortvalue split-quarter)
+                     (cons 'split-sortvalue (lambda (s) (time64-quarter (split->time64 s))))
                      (cons 'text (_ "Quarterly"))
                      (cons 'tip (_ "Quarterly."))
-                     (cons 'renderer-key 'quarterly)
-                     (cons 'renderer-fn gnc:date-get-quarter-year-string)))
+                     (cons 'renderer-fn (lambda (s) (gnc:date-get-quarter-year-string (gnc-localtime (split->time64 s)))))))
 
    (cons 'yearly (list
-                  (cons 'split-sortvalue split-year)
+                  (cons 'split-sortvalue (lambda (s) (time64-year (split->time64 s))))
                   (cons 'text (_ "Yearly"))
                   (cons 'tip (_ "Yearly."))
-                  (cons 'renderer-key 'yearly)
-                  (cons 'renderer-fn gnc:date-get-year-string)))))
+                  (cons 'renderer-fn (lambda (s) (gnc:date-get-year-string (gnc-localtime (split->time64 s)))))))))
 
 (define filter-list
   (list
@@ -947,8 +944,8 @@ tags within description, notes or memo. ")
 
         (if (and (null? left-cols-list)
                  (or (opt-val gnc:pagename-display "Totals")
-                     (primary-get-info 'renderer-key)
-                     (secondary-get-info 'renderer-key)))
+                     (primary-get-info 'renderer-fn)
+                     (secondary-get-info 'renderer-fn)))
             (list (vector "" (lambda (s t) #f)))
             left-cols-list)))
 
@@ -1178,16 +1175,13 @@ tags within description, notes or memo. ")
                    (xaccAccountGetName account))
                ""))))
 
-    (define (render-date renderer-key split)
-      ((keylist-get-info date-subtotal-list renderer-key 'renderer-fn)
-       (gnc-localtime
-        (xaccTransGetDate
-         (xaccSplitGetParent split)))))
+    ;; retrieve date renderer from the date-subtotal-list
+    (define (render-date date-subtotal-key split)
+      ((keylist-get-info date-subtotal-list date-subtotal-key 'renderer-fn) split))
 
-    (define (render-account renderer-key split anchor?)
-      (let* ((account (case renderer-key
-                        ((account) (xaccSplitGetAccount split))
-                        ((other-acc) (xaccSplitGetAccount (xaccSplitGetOtherSplit split)))))
+    ;; generate account name, optionally with anchor to account register
+    (define (render-account sortkey split anchor?)
+      (let* ((account ((keylist-get-info sortkey-list sortkey 'renderer-fn) split))
              (name (account-namestring account
                                        (column-uses? 'sort-account-code)
                                        #t
@@ -1203,14 +1197,18 @@ tags within description, notes or memo. ")
             name)))
 
     (define (render-summary split level anchor?)
-      (let ((renderer-key (case level
-                            ((primary) (primary-get-info 'renderer-key))
-                            ((secondary) (secondary-get-info 'renderer-key)))))
-        (case renderer-key
-          ((weekly monthly quarterly yearly) (render-date renderer-key split))
-          ((account other-acc) (render-account renderer-key split anchor?))
-          (else #f))))
-
+      (let ((sortkey (opt-val pagename-sorting
+                              (case level
+                                ((primary) optname-prime-sortkey)
+                                ((secondary) optname-sec-sortkey))))
+            (date-subtotal-key (opt-val pagename-sorting
+                                        (case level
+                                          ((primary) optname-prime-date-subtotal)
+                                          ((secondary) optname-sec-date-subtotal)))))
+        (if (member sortkey DATE-SORTING-TYPES)
+            (render-date date-subtotal-key split)
+            (render-account sortkey split anchor?))))
+    
     (define (render-grand-total)
       (_ "Grand Total"))
 
@@ -1398,11 +1396,11 @@ tags within description, notes or memo. ")
 
     (gnc:html-table-set-col-headers! table (concatenate (list headings-left-columns headings-right-columns)))
 
-    (if (primary-get-info 'renderer-key)
+    (if (primary-get-info 'renderer-fn)
         (add-subheading (render-summary (car splits) 'primary #t)
                         def:primary-subtotal-style))
-    
-    (if (secondary-get-info 'renderer-key)
+
+    (if (secondary-get-info 'renderer-fn)
         (add-subheading (render-summary (car splits) 'secondary #t)
                         def:secondary-subtotal-style))
     
@@ -1480,21 +1478,16 @@ tags within description, notes or memo. ")
     (define (generic-less? X Y key date-subtotal ascend?)
       (define comparator-function
         (if (member key DATE-SORTING-TYPES)
-            (let* ((date (lambda (s)
-                           (case key
-                             ((date) (xaccTransGetDate (xaccSplitGetParent s)))
-                             ((reconciled-date) (xaccSplitGetDateReconciled s)))))
-                   (year    (lambda (s) (gnc:date-get-year (gnc-localtime (date s)))))
-                   (month   (lambda (s) (gnc:date-get-month (gnc-localtime (date s)))))
-                   (quarter (lambda (s) (gnc:date-get-quarter (gnc-localtime (date s)))))
-                   (week    (lambda (s) (gnc:date-get-week (gnc-localtime (date s)))))
-                   (secs    (lambda (s) (date s))))
+            (let ((date (lambda (s)
+                          (case key
+                            ((date) (xaccTransGetDate (xaccSplitGetParent s)))
+                            ((reconciled-date) (xaccSplitGetDateReconciled s))))))
               (case date-subtotal
-                ((yearly)    (lambda (s) (year s)))
-                ((monthly)   (lambda (s) (+ (* 100 (year s)) (month s))))
-                ((quarterly) (lambda (s) (+ (*  10 (year s)) (quarter s))))
-                ((weekly)    (lambda (s) (week s)))
-                ((none)      (lambda (s) (secs s)))))
+                ((yearly)    (lambda (s) (time64-year (date s))))
+                ((monthly)   (lambda (s) (time64-month (date s))))
+                ((quarterly) (lambda (s) (time64-quarter (date s))))
+                ((weekly)    (lambda (s) (time64-week (date s))))
+                ((none)      (lambda (s) (date s)))))
             (case key
               ((account-name) (lambda (s) (gnc-account-get-full-name (xaccSplitGetAccount s))))
               ((account-code) (lambda (s) (xaccAccountGetCode (xaccSplitGetAccount s))))

commit 39dceb55344eb07db45ab6c87d9eb2b9e2c55161
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Nov 29 18:27:30 2017 +0800

    REFACTOR: simplify num/t-num display code

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index aa64236..23bef7d 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -877,20 +877,18 @@ tags within description, notes or memo. ")
                                    (_ "Num/T-Num")
                                    (_ "Num"))
                                (lambda (split transaction-row?)
-                                 (define trans (xaccSplitGetParent split))
-                                 (if transaction-row?
-                                     (if BOOK-SPLIT-ACTION
-                                         (let* ((num (gnc-get-num-action trans split))
-                                                (t-num (if (opt-val gnc:pagename-display (N_ "Trans Number"))
-                                                           (gnc-get-num-action trans #f)
-                                                           ""))
-                                                (num-string (if (string-null? t-num)
-                                                                num
-                                                                (string-append num "/" t-num))))
-                                           (gnc:make-html-table-cell/markup "text-cell" num-string))
-                                         (gnc:make-html-table-cell/markup "text-cell"
-                                                                          (gnc-get-num-action trans split)))
-                                     ""))))
+                                 (let* ((trans (xaccSplitGetParent split))
+                                        (num (gnc-get-num-action trans split))
+                                        (t-num (if (and BOOK-SPLIT-ACTION
+                                                        (opt-val gnc:pagename-display (N_ "Trans Number")))
+                                                   (gnc-get-num-action trans #f)
+                                                   ""))
+                                        (num-string (if (string-null? t-num)
+                                                        num
+                                                        (string-append num "/" t-num))))
+                                   (if transaction-row?
+                                       (gnc:make-html-table-cell/markup "text-cell" num-string)
+                                       "")))))
 
                (add-if (column-uses? 'description)
                        (vector (_ "Description")

commit 005fdb5f43e23b069681c369fc3629b716d6c5cf
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:36:33 2017 +0800

    REFACTOR: centralize left-cols to a vector-list

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 4cd5287..aa64236 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -853,33 +853,106 @@ tags within description, notes or memo. ")
              (left-cols-list
               (append
                (add-if (column-uses? 'date)
-                       (_ "Date"))
+                       (vector (_ "Date")
+                               (lambda (split transaction-row?)
+                                 (if transaction-row?
+                                     (gnc:make-html-table-cell/markup
+                                      "date-cell"
+                                      (qof-print-date (xaccTransGetDate (xaccSplitGetParent split))))
+                                     ""))))
+
                (add-if (column-uses? 'reconciled-date)
-                       (_ "Reconciled Date"))
+                       (vector (_ "Reconciled Date")
+                               (lambda (split transaction-row?)
+                                 (gnc:make-html-table-cell/markup
+                                  "date-cell"
+                                  (let ((date (xaccSplitGetDateReconciled split)))
+                                    (if (zero? date)
+                                        ""
+                                        (qof-print-date date)))))))
+
                (add-if (column-uses? 'num)
-                       (if (and BOOK-SPLIT-ACTION
-                                (opt-val gnc:pagename-display (N_ "Trans Number")))
-                           (_ "Num/T-Num")
-                           (_ "Num")))
+                       (vector (if (and BOOK-SPLIT-ACTION
+                                        (opt-val gnc:pagename-display (N_ "Trans Number")))
+                                   (_ "Num/T-Num")
+                                   (_ "Num"))
+                               (lambda (split transaction-row?)
+                                 (define trans (xaccSplitGetParent split))
+                                 (if transaction-row?
+                                     (if BOOK-SPLIT-ACTION
+                                         (let* ((num (gnc-get-num-action trans split))
+                                                (t-num (if (opt-val gnc:pagename-display (N_ "Trans Number"))
+                                                           (gnc-get-num-action trans #f)
+                                                           ""))
+                                                (num-string (if (string-null? t-num)
+                                                                num
+                                                                (string-append num "/" t-num))))
+                                           (gnc:make-html-table-cell/markup "text-cell" num-string))
+                                         (gnc:make-html-table-cell/markup "text-cell"
+                                                                          (gnc-get-num-action trans split)))
+                                     ""))))
+
                (add-if (column-uses? 'description)
-                       (_ "Description"))
+                       (vector (_ "Description")
+                               (lambda (split transaction-row?)
+                                 (define trans (xaccSplitGetParent split))
+                                 (if transaction-row?
+                                     (gnc:make-html-table-cell/markup
+                                      "text-cell"
+                                      (xaccTransGetDescription trans))
+                                     ""))))
+
                (add-if (column-uses? 'memo)
-                       (if (column-uses? 'notes)
-                           (string-append (_ "Memo") "/" (_ "Notes"))
-                           (_ "Memo")))
-               (add-if (or (column-uses? 'account-name)
-                           (column-uses? 'account-code))
-                       (_ "Account"))
-               (add-if (or (column-uses? 'other-account-name)
-                           (column-uses? 'other-account-code))
-                       (_ "Transfer from/to"))
+                       (vector (if (column-uses? 'notes)
+                                   (string-append (_ "Memo") "/" (_ "Notes"))
+                                   (_ "Memo"))
+                               (lambda (split transaction-row?)
+                                 (define trans (xaccSplitGetParent split))
+                                 (define memo (xaccSplitGetMemo split))
+                                 (if (and (string-null? memo) (column-uses? 'notes))
+                                     (xaccTransGetNotes trans)
+                                     memo))))
+
+               (add-if (or (column-uses? 'account-name) (column-uses? 'account-code))
+                       (vector (_ "Account")
+                               (lambda (split transaction-row?)
+                                 (define account (xaccSplitGetAccount split))
+                                 (account-namestring account
+                                                     (column-uses? 'account-code)
+                                                     (column-uses? 'account-name)
+                                                     (column-uses? 'account-full-name)))))
+
+               (add-if (or (column-uses? 'other-account-name) (column-uses? 'other-account-code))
+                       (vector (_ "Transfer from/to")
+                               (lambda (split transaction-row?)
+                                 (define other-account (xaccSplitGetAccount (xaccSplitGetOtherSplit split)))
+                                 (account-namestring other-account
+                                                     (column-uses? 'other-account-code)
+                                                     (column-uses? 'other-account-name)
+                                                     (column-uses? 'other-account-full-name)))))
+
                (add-if (column-uses? 'shares)
-                       (_ "Shares"))
+                       (vector (_ "Shares")
+                               (lambda (split transaction-row?)
+                                 (gnc:make-html-table-cell/markup
+                                  "number-cell"
+                                  (xaccSplitGetAmount split)))))
+
                (add-if (column-uses? 'price)
-                       (_ "Price")))))
-        (if (null? headings-list)
-            (list "")
-            headings-list)))
+                       (vector (_ "Price")
+                               (lambda (split transaction-row?)
+                                 (define trans (xaccSplitGetParent split))
+                                 (gnc:make-html-table-cell/markup
+                                  "number-cell"
+                                  (gnc:make-gnc-monetary (xaccTransGetCurrency trans)
+                                                         (xaccSplitGetSharePrice split)))))))))
+
+        (if (and (null? left-cols-list)
+                 (or (opt-val gnc:pagename-display "Totals")
+                     (primary-get-info 'renderer-key)
+                     (secondary-get-info 'renderer-key)))
+            (list (vector "" (lambda (s t) #f)))
+            left-cols-list)))
 
     ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;;
@@ -1154,6 +1227,13 @@ tags within description, notes or memo. ")
              (trans (xaccSplitGetParent split))
              (account (xaccSplitGetAccount split)))
 
+        (define left-cols
+          (map (lambda (left-col)
+                 (let* ((col-fn (vector-ref left-col 1))
+                        (col-data (col-fn split transaction-row?)))
+                   col-data))
+               left-columns))
+
         (define cells
           (map (lambda (cell)
                  (let* ((calculator (vector-ref cell 1))
@@ -1164,87 +1244,11 @@ tags within description, notes or memo. ")
                            reverse?
                            subtotal?)))
                cell-calculators))
-
-        (if (column-uses? 'date)
-            (addto! row-contents
-                    (if transaction-row?
-                        (gnc:make-html-table-cell/markup
-                         "date-cell"
-                         (qof-print-date (xaccTransGetDate trans)))
-                        "")))
-
-        (if (column-uses? 'reconciled-date)
-            (addto! row-contents
-                    (gnc:make-html-table-cell/markup
-                     "date-cell"
-                     (let ((date (xaccSplitGetDateReconciled split)))
-                       (if (zero? date)
-                           ""
-                           (qof-print-date date))))))
-
-        (if (column-uses? 'num)
-            (addto! row-contents
-                    (if transaction-row?
-                        (if BOOK-SPLIT-ACTION
-                            (let* ((num (gnc-get-num-action trans split))
-                                   (t-num (if (if (gnc:lookup-option options
-                                                                     gnc:pagename-display
-                                                                     (N_ "Trans Number"))
-                                                  (opt-val gnc:pagename-display (N_ "Trans Number"))
-                                                  "")
-                                              (gnc-get-num-action trans #f)
-                                              ""))
-                                   (num-string (if (string-null? t-num)
-                                                   num
-                                                   (string-append num "/" t-num))))
-                              (gnc:make-html-table-cell/markup "text-cell" num-string))
-                            (gnc:make-html-table-cell/markup "text-cell"
-                                                             (gnc-get-num-action trans split)))
-                        "")))
-
-        (if (column-uses? 'description)
-            (addto! row-contents
-                    (if transaction-row?
-                        (gnc:make-html-table-cell/markup
-                         "text-cell"
-                         (xaccTransGetDescription trans))
-                        "")))
-
-        (if (column-uses? 'memo)
-            (let ((memo (xaccSplitGetMemo split)))
-              (if (and (string-null? memo) (column-uses? 'notes))
-                  (addto! row-contents (xaccTransGetNotes trans))
-                  (addto! row-contents memo))))
-
-        (if (or (column-uses? 'account-name) (column-uses? 'account-code))
-            (addto! row-contents (account-namestring account
-                                                     (column-uses? 'account-code)
-                                                     (column-uses? 'account-name)
-                                                     (column-uses? 'account-full-name))))
-
-        (if (or (column-uses? 'other-account-name) (column-uses? 'other-account-code))
-            (addto! row-contents (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
-                                                     (column-uses? 'other-account-code)
-                                                     (column-uses? 'other-account-name)
-                                                     (column-uses? 'other-account-full-name))))
-
-        (if (column-uses? 'shares)
-            (addto! row-contents (gnc:make-html-table-cell/markup
-                                  "number-cell"
-                                  (xaccSplitGetAmount split))))
-
-        (if (column-uses? 'price)
-            (addto! row-contents
-                    (gnc:make-html-table-cell/markup
-                     "number-cell"
-                     (gnc:make-gnc-monetary (xaccTransGetCurrency trans)
-                                            (xaccSplitGetSharePrice split)))))
-
-        ;; hack to ensure cell alignment is corrected when no left columns were selected
-        ;; this is needed because subtotal renderer will always insert at least 1 column
-        (if (null? row-contents)
-            (addto! row-contents (gnc:html-make-empty-cell)))
         
+        (for-each (lambda (col)
+                    (addto! row-contents col))
+                  left-cols)
+
         (for-each (lambda (cell)
                     (let ((cell-content (vector-ref cell 0))
                           ;; reverse? returns a bool - will check if the cell type has reversible sign,

commit 7b6ac3a0773c173a33b39bdd1e3b7863929f3103
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Nov 28 21:06:34 2017 +0800

    ENH: if no Display/* selected, insert empty left-column
    
    Previously, if user selected NO split header (eg Date
    Description Memo etc) the report would display the data
    columns, which means the subtotal would cause misalignment.
    This commit ensures the columns are aligned when user
    selects no split information. At least 1 left-column is
    required to allow for subtotal headers and summaries within
    the table.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 45c9857..4cd5287 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -849,33 +849,37 @@ tags within description, notes or memo. ")
       (cdr (assq param used-columns)))
 
     (define left-columns
-      (let* ((add-if (lambda pred? . items) (if pred? items '())))
-        (append
-         (add-if (column-uses? 'date)
-                 (_ "Date"))
-         (add-if (column-uses? 'reconciled-date)
-                 (_ "Reconciled Date"))
-         (add-if (column-uses? 'num)
-                 (if (and BOOK-SPLIT-ACTION
-                          (opt-val gnc:pagename-display (N_ "Trans Number")))
-                     (_ "Num/T-Num")
-                     (_ "Num")))
-         (add-if (column-uses? 'description)
-                 (_ "Description"))
-         (add-if (column-uses? 'memo)
-                 (if (column-uses? 'notes)
-                     (string-append (_ "Memo") "/" (_ "Notes"))
-                     (_ "Memo")))
-         (add-if (or (column-uses? 'account-name)
-                     (column-uses? 'account-code))
-                 (_ "Account"))
-         (add-if (or (column-uses? 'other-account-name)
-                     (column-uses? 'other-account-code))
-                 (_ "Transfer from/to"))
-         (add-if (column-uses? 'shares)
-                 (_ "Shares"))
-         (add-if (column-uses? 'price)
-                 (_ "Price"))))
+      (let* ((add-if (lambda (pred? . items) (if pred? items '())))
+             (left-cols-list
+              (append
+               (add-if (column-uses? 'date)
+                       (_ "Date"))
+               (add-if (column-uses? 'reconciled-date)
+                       (_ "Reconciled Date"))
+               (add-if (column-uses? 'num)
+                       (if (and BOOK-SPLIT-ACTION
+                                (opt-val gnc:pagename-display (N_ "Trans Number")))
+                           (_ "Num/T-Num")
+                           (_ "Num")))
+               (add-if (column-uses? 'description)
+                       (_ "Description"))
+               (add-if (column-uses? 'memo)
+                       (if (column-uses? 'notes)
+                           (string-append (_ "Memo") "/" (_ "Notes"))
+                           (_ "Memo")))
+               (add-if (or (column-uses? 'account-name)
+                           (column-uses? 'account-code))
+                       (_ "Account"))
+               (add-if (or (column-uses? 'other-account-name)
+                           (column-uses? 'other-account-code))
+                       (_ "Transfer from/to"))
+               (add-if (column-uses? 'shares)
+                       (_ "Shares"))
+               (add-if (column-uses? 'price)
+                       (_ "Price")))))
+        (if (null? headings-list)
+            (list "")
+            headings-list)))
 
     ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;;
@@ -1236,6 +1240,11 @@ tags within description, notes or memo. ")
                      (gnc:make-gnc-monetary (xaccTransGetCurrency trans)
                                             (xaccSplitGetSharePrice split)))))
 
+        ;; hack to ensure cell alignment is corrected when no left columns were selected
+        ;; this is needed because subtotal renderer will always insert at least 1 column
+        (if (null? row-contents)
+            (addto! row-contents (gnc:html-make-empty-cell)))
+        
         (for-each (lambda (cell)
                     (let ((cell-content (vector-ref cell 0))
                           ;; reverse? returns a bool - will check if the cell type has reversible sign,

commit 230493f2942dbd5ba0466b6c030134a82e356eec
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Nov 28 17:24:45 2017 +0800

    REFACTOR: simplify render-summary
    
    it's the sole user of renderer-keys. access from *-get-info directly.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 2f98ba4..45c9857 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -826,7 +826,6 @@ tags within description, notes or memo. ")
                (and (opt-val pagename-sorting optname-prime-subtotal)
                     (keylist-get-info sortkey-list sortkey info))))))
 
-  
   (define (secondary-get-info info)
     (let ((sortkey (opt-val pagename-sorting optname-sec-sortkey)))
       (if (member sortkey DATE-SORTING-TYPES)
@@ -835,18 +834,6 @@ tags within description, notes or memo. ")
                (and (opt-val pagename-sorting optname-sec-subtotal)
                     (keylist-get-info sortkey-list sortkey info))))))
 
-  (define primary-subtotal-comparator
-    (primary-get-info 'split-sortvalue))
-
-  (define primary-renderer-key
-    (primary-get-info 'renderer-key))
-
-  (define secondary-subtotal-comparator
-    (secondary-get-info 'split-sortvalue))
-
-  (define secondary-renderer-key
-    (secondary-get-info 'renderer-key))
-
   (let* ((work-to-do (length splits))
          (work-done 0)
          (table (gnc:make-html-table))
@@ -1140,11 +1127,14 @@ tags within description, notes or memo. ")
              description)
             name)))
 
-    (define (render-summary split renderer-key anchor?)
-      (case renderer-key
-        ((weekly monthly quarterly yearly) (render-date renderer-key split))
-        ((account other-acc) (render-account renderer-key split anchor?))
-        (else #f)))
+    (define (render-summary split level anchor?)
+      (let ((renderer-key (case level
+                            ((primary) (primary-get-info 'renderer-key))
+                            ((secondary) (secondary-get-info 'renderer-key)))))
+        (case renderer-key
+          ((weekly monthly quarterly yearly) (render-date renderer-key split))
+          ((account other-acc) (render-account renderer-key split anchor?))
+          (else #f))))
 
     (define (render-grand-total)
       (_ "Grand Total"))
@@ -1293,6 +1283,8 @@ tags within description, notes or memo. ")
       (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells))
 
     (define (do-rows-with-subtotals splits odd-row?)
+      (define primary-subtotal-comparator (primary-get-info 'split-sortvalue))
+      (define secondary-subtotal-comparator (secondary-get-info 'split-sortvalue))
 
       (gnc:report-percent-done (* 100 (/ work-done work-to-do)))
 
@@ -1357,23 +1349,23 @@ tags within description, notes or memo. ")
                   (if secondary-subtotal-comparator
                       (begin
                         (add-subtotal-row (total-string
-                                           (render-summary current secondary-renderer-key #f))
+                                           (render-summary current 'secondary #f))
                                           secondary-subtotal-collectors
                                           def:secondary-subtotal-style)
                         (for-each (lambda (coll) (coll 'reset #f #f))
                                   secondary-subtotal-collectors)))
                   (add-subtotal-row (total-string
-                                     (render-summary current primary-renderer-key #f))
+                                     (render-summary current 'primary #f))
                                     primary-subtotal-collectors
                                     def:primary-subtotal-style)
                   (for-each (lambda (coll) (coll 'reset #f #f))
                             primary-subtotal-collectors)
                   (if next
                       (begin
-                        (add-subheading (render-summary next primary-renderer-key #t)
+                        (add-subheading (render-summary next 'primary #t)
                                         def:primary-subtotal-style)
                         (if secondary-subtotal-comparator
-                            (add-subheading (render-summary next secondary-renderer-key #t)
+                            (add-subheading (render-summary next 'secondary #t)
                                             def:secondary-subtotal-style)))))
 
                 (if (and secondary-subtotal-comparator
@@ -1382,25 +1374,25 @@ tags within description, notes or memo. ")
                                   (not (equal? (secondary-subtotal-comparator current)
                                                (secondary-subtotal-comparator next))))))
                     (begin (add-subtotal-row (total-string
-                                              (render-summary current secondary-renderer-key #f))
+                                              (render-summary current 'secondary #f))
                                              secondary-subtotal-collectors
                                              def:secondary-subtotal-style)
                            (for-each (lambda (coll) (coll 'reset #f #f))
                                      secondary-subtotal-collectors)
                            (if next
-                               (add-subheading (render-summary next secondary-renderer-key #t)
+                               (add-subheading (render-summary next 'secondary #t)
                                                def:secondary-subtotal-style)))))
 
             (do-rows-with-subtotals rest (not odd-row?)))))
 
     (gnc:html-table-set-col-headers! table (concatenate (list headings-left-columns headings-right-columns)))
 
-    (if primary-renderer-key
-        (add-subheading (render-summary (car splits) primary-renderer-key #t)
+    (if (primary-get-info 'renderer-key)
+        (add-subheading (render-summary (car splits) 'primary #t)
                         def:primary-subtotal-style))
     
-    (if secondary-renderer-key
-        (add-subheading (render-summary (car splits) secondary-renderer-key #t)
+    (if (secondary-get-info 'renderer-key)
+        (add-subheading (render-summary (car splits) 'secondary #t)
                         def:secondary-subtotal-style))
     
     (do-rows-with-subtotals splits #t)

commit 1ce2f3f6d8639b8e073a6807efb2aca159570b44
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Nov 28 14:40:02 2017 +0800

    REFACTOR: simplify do-rows-with-subtotals

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index d811fa9..2f98ba4 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1283,11 +1283,16 @@ tags within description, notes or memo. ")
 
     ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-    (define (do-rows-with-subtotals splits
-                                    odd-row?
-                                    primary-subtotal-collectors
-                                    secondary-subtotal-collectors
-                                    total-collectors)
+    (define primary-subtotal-collectors
+      (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells))
+
+    (define secondary-subtotal-collectors
+      (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells))
+
+    (define total-collectors
+      (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells))
+
+    (define (do-rows-with-subtotals splits odd-row?)
 
       (gnc:report-percent-done (* 100 (/ work-done work-to-do)))
 
@@ -1386,26 +1391,19 @@ tags within description, notes or memo. ")
                                (add-subheading (render-summary next secondary-renderer-key #t)
                                                def:secondary-subtotal-style)))))
 
-            (do-rows-with-subtotals rest
-                                    (not odd-row?)
-                                    primary-subtotal-collectors
-                                    secondary-subtotal-collectors
-                                    total-collectors))))
+            (do-rows-with-subtotals rest (not odd-row?)))))
 
     (gnc:html-table-set-col-headers! table (concatenate (list headings-left-columns headings-right-columns)))
 
     (if primary-renderer-key
         (add-subheading (render-summary (car splits) primary-renderer-key #t)
                         def:primary-subtotal-style))
-
+    
     (if secondary-renderer-key
         (add-subheading (render-summary (car splits) secondary-renderer-key #t)
                         def:secondary-subtotal-style))
-
-    (do-rows-with-subtotals splits #t
-                            (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells)
-                            (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells)
-                            (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells))
+    
+    (do-rows-with-subtotals splits #t)
 
     table))
 

commit 725767521893023d2bc0f8ed526112ba2cde1fc3
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Nov 27 20:18:16 2017 +0800

    REFACTOR:bisect subtotal-get-info into primary/secondary

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 4dd5983..d811fa9 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -818,38 +818,34 @@ tags within description, notes or memo. ")
           (cons 'sort-account-description (opt-val pagename-sorting (N_ "Show Account Description")))
           (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
+  (define (primary-get-info info)
+    (let ((sortkey (opt-val pagename-sorting optname-prime-sortkey)))
+      (if (member sortkey DATE-SORTING-TYPES)
+          (keylist-get-info date-subtotal-list (opt-val pagename-sorting optname-prime-date-subtotal) info)
+          (and (member sortkey SUBTOTAL-ENABLED)
+               (and (opt-val pagename-sorting optname-prime-subtotal)
+                    (keylist-get-info sortkey-list sortkey info))))))
 
-  (define (subtotal-get-info name-sortkey name-subtotal name-date-subtotal info)
-    (let ((sortkey (opt-val pagename-sorting name-sortkey)))
+  
+  (define (secondary-get-info info)
+    (let ((sortkey (opt-val pagename-sorting optname-sec-sortkey)))
       (if (member sortkey DATE-SORTING-TYPES)
-          (keylist-get-info date-subtotal-list (opt-val pagename-sorting name-date-subtotal) info)
+          (keylist-get-info date-subtotal-list (opt-val pagename-sorting optname-sec-date-subtotal) info)
           (and (member sortkey SUBTOTAL-ENABLED)
-               (and (opt-val pagename-sorting name-subtotal)
+               (and (opt-val pagename-sorting optname-sec-subtotal)
                     (keylist-get-info sortkey-list sortkey info))))))
 
   (define primary-subtotal-comparator
-    (subtotal-get-info optname-prime-sortkey
-                       optname-prime-subtotal
-                       optname-prime-date-subtotal
-                       'split-sortvalue))
-
-  (define secondary-subtotal-comparator
-    (subtotal-get-info optname-sec-sortkey
-                       optname-sec-subtotal
-                       optname-sec-date-subtotal
-                       'split-sortvalue))
+    (primary-get-info 'split-sortvalue))
 
   (define primary-renderer-key
-    (subtotal-get-info optname-prime-sortkey
-                       optname-prime-subtotal
-                       optname-prime-date-subtotal
-                       'renderer-key))
+    (primary-get-info 'renderer-key))
+
+  (define secondary-subtotal-comparator
+    (secondary-get-info 'split-sortvalue))
 
   (define secondary-renderer-key
-    (subtotal-get-info optname-sec-sortkey
-                       optname-sec-subtotal
-                       optname-sec-date-subtotal
-                       'renderer-key))
+    (secondary-get-info 'renderer-key))
 
   (let* ((work-to-do (length splits))
          (work-done 0)

commit e2912d1b9c7a34f2979f176fbfba55d08f3edae9
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:22:41 2017 +0800

    REFACTOR: start refactor subtotal

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index b971627..4dd5983 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -240,25 +240,29 @@ options specified in the Options panels."))
                   (cons 'split-sortvalue split-week)
                   (cons 'text (_ "Weekly"))
                   (cons 'tip (_ "Weekly."))
-                  (cons 'renderer-key 'week)))
+                  (cons 'renderer-key 'weekly)
+                  (cons 'renderer-fn gnc:date-get-week-year-string)))
 
    (cons 'monthly (list
                    (cons 'split-sortvalue split-month)
                    (cons 'text (_ "Monthly"))
                    (cons 'tip (_ "Monthly."))
-                   (cons 'renderer-key 'month)))
+                   (cons 'renderer-key 'monthly)
+                   (cons 'renderer-fn gnc:date-get-month-year-string)))
 
    (cons 'quarterly (list
                      (cons 'split-sortvalue split-quarter)
                      (cons 'text (_ "Quarterly"))
                      (cons 'tip (_ "Quarterly."))
-                     (cons 'renderer-key 'quarter)))
+                     (cons 'renderer-key 'quarterly)
+                     (cons 'renderer-fn gnc:date-get-quarter-year-string)))
 
    (cons 'yearly (list
                   (cons 'split-sortvalue split-year)
                   (cons 'text (_ "Yearly"))
                   (cons 'tip (_ "Yearly."))
-                  (cons 'renderer-key 'year)))))
+                  (cons 'renderer-key 'yearly)
+                  (cons 'renderer-fn gnc:date-get-year-string)))))
 
 (define filter-list
   (list
@@ -776,11 +780,7 @@ tags within description, notes or memo. ")
 ;; ;;;;;;;;;;;;;;;;;;;;
 ;; Here comes the big function that builds the whole table.
 
-(define (make-split-table splits options
-                          primary-subtotal-comparator
-                          secondary-subtotal-comparator
-                          primary-renderer-key
-                          secondary-renderer-key)
+(define (make-split-table splits options)
 
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
   (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
@@ -819,6 +819,38 @@ tags within description, notes or memo. ")
           (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
 
+  (define (subtotal-get-info name-sortkey name-subtotal name-date-subtotal info)
+    (let ((sortkey (opt-val pagename-sorting name-sortkey)))
+      (if (member sortkey DATE-SORTING-TYPES)
+          (keylist-get-info date-subtotal-list (opt-val pagename-sorting name-date-subtotal) info)
+          (and (member sortkey SUBTOTAL-ENABLED)
+               (and (opt-val pagename-sorting name-subtotal)
+                    (keylist-get-info sortkey-list sortkey info))))))
+
+  (define primary-subtotal-comparator
+    (subtotal-get-info optname-prime-sortkey
+                       optname-prime-subtotal
+                       optname-prime-date-subtotal
+                       'split-sortvalue))
+
+  (define secondary-subtotal-comparator
+    (subtotal-get-info optname-sec-sortkey
+                       optname-sec-subtotal
+                       optname-sec-date-subtotal
+                       'split-sortvalue))
+
+  (define primary-renderer-key
+    (subtotal-get-info optname-prime-sortkey
+                       optname-prime-subtotal
+                       optname-prime-date-subtotal
+                       'renderer-key))
+
+  (define secondary-renderer-key
+    (subtotal-get-info optname-sec-sortkey
+                       optname-sec-subtotal
+                       optname-sec-date-subtotal
+                       'renderer-key))
+
   (let* ((work-to-do (length splits))
          (work-done 0)
          (table (gnc:make-html-table))
@@ -1089,11 +1121,7 @@ tags within description, notes or memo. ")
                ""))))
 
     (define (render-date renderer-key split)
-      ((case renderer-key
-         ((week) gnc:date-get-week-year-string)
-         ((month) gnc:date-get-month-year-string)
-         ((quarter) gnc:date-get-quarter-year-string)
-         ((year) gnc:date-get-year-string))
+      ((keylist-get-info date-subtotal-list renderer-key 'renderer-fn)
        (gnc-localtime
         (xaccTransGetDate
          (xaccSplitGetParent split)))))
@@ -1118,7 +1146,7 @@ tags within description, notes or memo. ")
 
     (define (render-summary split renderer-key anchor?)
       (case renderer-key
-        ((week month quarter year) (render-date renderer-key split))
+        ((weekly monthly quarterly yearly) (render-date renderer-key split))
         ((account other-acc) (render-account renderer-key split anchor?))
         (else #f)))
 
@@ -1394,22 +1422,6 @@ tags within description, notes or memo. ")
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
   (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
 
-  (define (subtotal-get-info name-sortkey name-subtotal name-date-subtotal info)
-    ;; The value of the sorting-key multichoice option.
-    (let ((sortkey (opt-val pagename-sorting name-sortkey)))
-      (if (member sortkey DATE-SORTING-TYPES)
-          ;; If sorting by date, look up the value of the
-          ;; date-subtotalling multichoice option and return the
-          ;; corresponding funcs in the assoc-list.
-          (keylist-get-info date-subtotal-list (opt-val pagename-sorting name-date-subtotal) info)
-          ;; For everything else: 1. check whether sortkey has
-          ;; subtotalling enabled at all, 2. check whether the
-          ;; enable-subtotal boolean option is #t, 3. look up the
-          ;; appropriate funcs in the assoc-list.
-          (and (member sortkey SUBTOTAL-ENABLED)
-               (and (opt-val pagename-sorting name-subtotal)
-                    (keylist-get-info sortkey-list sortkey info))))))
-
   (define (is-filter-member split account-list)
     (let* ((txn (xaccSplitGetParent split))
            (splitcount (xaccTransCountSplits txn))
@@ -1685,24 +1697,7 @@ tags within description, notes or memo. ")
                  document
                  (infobox)))
 
-              (let ((table (make-split-table
-                            splits options
-                            (subtotal-get-info optname-prime-sortkey
-                                               optname-prime-subtotal
-                                               optname-prime-date-subtotal
-                                               'split-sortvalue)
-                            (subtotal-get-info optname-sec-sortkey
-                                               optname-sec-subtotal
-                                               optname-sec-date-subtotal
-                                               'split-sortvalue)
-                            (subtotal-get-info optname-prime-sortkey
-                                               optname-prime-subtotal
-                                               optname-prime-date-subtotal
-                                               'renderer-key)
-                            (subtotal-get-info optname-sec-sortkey
-                                               optname-sec-subtotal
-                                               optname-sec-date-subtotal
-                                               'renderer-key))))
+              (let ((table (make-split-table splits options)))
 
                 (gnc:html-document-set-title! document report-title)
 

commit 00b2e76d352e0e531a829250b2762338d4317a90
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:21:46 2017 +0800

    BUGFIX: Reverse sign on display only

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 0b9b0fc..b971627 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1141,19 +1141,9 @@ tags within description, notes or memo. ")
                  (let* ((calculator (vector-ref cell 1))
                         (reverse? (vector-ref cell 2))
                         (subtotal? (vector-ref cell 3))
-                        (calculated (calculator split))
-                        (reverse-amount (lambda (mon)
-                                            (let ((currency (gnc:gnc-monetary-commodity mon))
-                                                  (amount (gnc:gnc-monetary-amount mon)))
-                                              (gnc:make-gnc-monetary
-                                               currency
-                                               (gnc-numeric-neg amount))))))
-                   (vector (if (and reverse?
-                                    (if account-types-to-reverse
-                                        (member (xaccAccountGetType account) account-types-to-reverse)
-                                        (gnc-reverse-balance account)))
-                               (reverse-amount calculated)
-                               calculated)
+                        (calculated (calculator split)))
+                   (vector calculated
+                           reverse?
                            subtotal?)))
                cell-calculators))
 
@@ -1234,22 +1224,23 @@ tags within description, notes or memo. ")
 
         (for-each (lambda (cell)
                     (let ((cell-content (vector-ref cell 0))
-                          (reverse? (vector-ref cell 1))
-                          (reverse-amount (lambda (mon)
-                                            (let ((currency (gnc:gnc-monetary-commodity mon))
-                                                  (amount (gnc:gnc-monetary-amount mon)))
-                                              (gnc:make-gnc-monetary
-                                               currency
-                                               (gnc-numeric-neg amount))))))
+                          ;; reverse? returns a bool - will check if the cell type has reversible sign,
+                          ;; whether the account is also reversible according to Report Option, or
+                          ;; if Report Option follows Global Settings, will retrieve bool from it.
+                          (reverse? (and (vector-ref cell 1)
+                                         (if account-types-to-reverse
+                                             (member (xaccAccountGetType account) account-types-to-reverse)
+                                             (gnc-reverse-balance account)))))
                       (if cell-content
                           (addto! row-contents
                                   (gnc:make-html-table-cell/markup
                                    "number-cell"
                                    (gnc:html-transaction-anchor
                                     trans
-                                    (if (and reverse?
-                                             (member (xaccAccountGetType account) account-types-to-reverse))
-                                        (reverse-amount cell-content)
+                                    ;; if conditions for reverse are satisfied, apply sign reverse to
+                                    ;; monetary amount
+                                    (if reverse?
+                                        (gnc:monetary-neg cell-content)
                                         cell-content))))
                           (addto! row-contents (gnc:html-make-empty-cell)))))
                   cells)

commit 0854caba95e0b163acb85442653d8ddfb8234114
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:16:27 2017 +0800

    BUGFIX: Fix incorrect N_ and _ handling

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 7ced336..0b9b0fc 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -104,8 +104,8 @@
 (define NO-MATCHING-TRANS-TEXT (_ "No transactions were found that \
 match the time interval and account selection specified \
 in the Options panel."))
-(define NO-MATCHING-ACCT-HEADER (N_ "No matching accounts found"))
-(define NO-MATCHING-ACCT-TEXT (N_ "No account were found that match the \
+(define NO-MATCHING-ACCT-HEADER (_ "No matching accounts found"))
+(define NO-MATCHING-ACCT-TEXT (_ "No account were found that match the \
 options specified in the Options panels."))
 
 
@@ -129,87 +129,87 @@ options specified in the Options panels."))
   ;;
   (list (cons 'account-name  (list (cons 'sortkey (list SPLIT-ACCT-FULLNAME))
                                    (cons 'split-sortvalue (lambda (a) (gnc-account-get-full-name (xaccSplitGetAccount a))))
-                                   (cons 'text (N_ "Account Name"))
-                                   (cons 'tip (N_ "Sort & subtotal by account name."))
+                                   (cons 'text (_ "Account Name"))
+                                   (cons 'tip (_ "Sort & subtotal by account name."))
                                    (cons 'renderer-key 'account)))
 
         (cons 'account-code (list (cons 'sortkey (list SPLIT-ACCOUNT ACCOUNT-CODE-))
                                   (cons 'split-sortvalue (lambda (a) (xaccAccountGetCode (xaccSplitGetAccount a))))
-                                  (cons 'text (N_ "Account Code"))
-                                  (cons 'tip (N_ "Sort & subtotal by account code."))
+                                  (cons 'text (_ "Account Code"))
+                                  (cons 'tip (_ "Sort & subtotal by account code."))
                                   (cons 'renderer-key 'account)))
 
         (cons 'date         (list (cons 'sortkey (list SPLIT-TRANS TRANS-DATE-POSTED))
                                   (cons 'split-sortvalue #f)
-                                  (cons 'text (N_ "Date"))
-                                  (cons 'tip (N_ "Sort by date."))
+                                  (cons 'text (_ "Date"))
+                                  (cons 'tip (_ "Sort by date."))
                                   (cons 'renderer-key #f)))
 
         (cons 'reconciled-date (list (cons 'sortkey (list SPLIT-DATE-RECONCILED))
                                      (cons 'split-sortvalue #f)
-                                     (cons 'text (N_ "Reconciled Date"))
-                                     (cons 'tip (N_ "Sort by the Reconciled Date."))
+                                     (cons 'text (_ "Reconciled Date"))
+                                     (cons 'tip (_ "Sort by the Reconciled Date."))
                                      (cons 'renderer-key #f)))
 
         (cons 'register-order (list (cons 'sortkey (list QUERY-DEFAULT-SORT))
                                     (cons 'split-sortvalue #f)
-                                    (cons 'text (N_ "Register Order"))
-                                    (cons 'tip (N_ "Sort as in the register."))
+                                    (cons 'text (_ "Register Order"))
+                                    (cons 'tip (_ "Sort as in the register."))
                                     (cons 'renderer-key #f)))
 
         (cons 'corresponding-acc-name (list (cons 'sortkey (list SPLIT-CORR-ACCT-NAME))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountFullName a)))
-                                            (cons 'text (N_ "Other Account Name"))
-                                            (cons 'tip (N_ "Sort by account transferred from/to's name."))
+                                            (cons 'text (_ "Other Account Name"))
+                                            (cons 'tip (_ "Sort by account transferred from/to's name."))
                                             (cons 'renderer-key 'other-acc)))
 
         (cons 'corresponding-acc-code (list (cons 'sortkey (list SPLIT-CORR-ACCT-CODE))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountCode a)))
-                                            (cons 'text (N_ "Other Account Code"))
-                                            (cons 'tip (N_ "Sort by account transferred from/to's code."))
+                                            (cons 'text (_ "Other Account Code"))
+                                            (cons 'tip (_ "Sort by account transferred from/to's code."))
                                             (cons 'renderer-key 'other-acct)))
 
         (cons 'amount        (list (cons 'sortkey (list SPLIT-VALUE))
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "Amount"))
-                                   (cons 'tip (N_ "Sort by amount."))
+                                   (cons 'text (_ "Amount"))
+                                   (cons 'tip (_ "Sort by amount."))
                                    (cons 'renderer-key #f)))
 
         (cons 'description   (list (cons 'sortkey (list SPLIT-TRANS TRANS-DESCRIPTION))
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "Description"))
-                                   (cons 'tip (N_ "Sort by description."))
+                                   (cons 'text (_ "Description"))
+                                   (cons 'tip (_ "Sort by description."))
                                    (cons 'renderer-key #f)))
 
         (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
             (cons 'number    (list (cons 'sortkey (list SPLIT-ACTION))
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "Number/Action"))
-                                   (cons 'tip (N_ "Sort by check number/action."))
+                                   (cons 'text (_ "Number/Action"))
+                                   (cons 'tip (_ "Sort by check number/action."))
                                    (cons 'renderer-key #f)))
 
             (cons 'number    (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "Number"))
-                                   (cons 'tip (N_ "Sort by check/transaction number."))
+                                   (cons 'text (_ "Number"))
+                                   (cons 'tip (_ "Sort by check/transaction number."))
                                    (cons 'renderer-key #f))))
 
         (cons 't-number      (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "Transaction Number"))
-                                   (cons 'tip (N_ "Sort by transaction number."))
+                                   (cons 'text (_ "Transaction Number"))
+                                   (cons 'tip (_ "Sort by transaction number."))
                                    (cons 'renderer-key #f)))
 
         (cons 'memo          (list (cons 'sortkey (list SPLIT-MEMO))
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "Memo"))
-                                   (cons 'tip (N_ "Sort by memo."))
+                                   (cons 'text (_ "Memo"))
+                                   (cons 'tip (_ "Sort by memo."))
                                    (cons 'renderer-key #f)))
 
         (cons 'none          (list (cons 'sortkey '())
                                    (cons 'split-sortvalue #f)
-                                   (cons 'text (N_ "None"))
-                                   (cons 'tip (N_ "Do not sort."))
+                                   (cons 'text (_ "None"))
+                                   (cons 'tip (_ "Do not sort."))
                                    (cons 'renderer-key #f)))))
 
 
@@ -232,61 +232,61 @@ options specified in the Options panels."))
   (list
    (cons 'none (list
                 (cons 'split-sortvalue #f)
-                (cons 'text (N_ "None"))
-                (cons 'tip (N_ "None."))
+                (cons 'text (_ "None"))
+                (cons 'tip (_ "None."))
                 (cons 'renderer-key #f)))
 
    (cons 'weekly (list
                   (cons 'split-sortvalue split-week)
-                  (cons 'text (N_ "Weekly"))
-                  (cons 'tip (N_ "Weekly."))
+                  (cons 'text (_ "Weekly"))
+                  (cons 'tip (_ "Weekly."))
                   (cons 'renderer-key 'week)))
 
    (cons 'monthly (list
                    (cons 'split-sortvalue split-month)
-                   (cons 'text (N_ "Monthly"))
-                   (cons 'tip (N_ "Monthly."))
+                   (cons 'text (_ "Monthly"))
+                   (cons 'tip (_ "Monthly."))
                    (cons 'renderer-key 'month)))
 
    (cons 'quarterly (list
                      (cons 'split-sortvalue split-quarter)
-                     (cons 'text (N_ "Quarterly"))
-                     (cons 'tip (N_ "Quarterly."))
+                     (cons 'text (_ "Quarterly"))
+                     (cons 'tip (_ "Quarterly."))
                      (cons 'renderer-key 'quarter)))
 
    (cons 'yearly (list
                   (cons 'split-sortvalue split-year)
-                  (cons 'text (N_ "Yearly"))
-                  (cons 'tip (N_ "Yearly."))
+                  (cons 'text (_ "Yearly"))
+                  (cons 'tip (_ "Yearly."))
                   (cons 'renderer-key 'year)))))
 
 (define filter-list
   (list
    (cons 'none (list
-                (cons 'text (N_ "None"))
-                (cons 'tip (N_ "Do not do any filtering."))))
+                (cons 'text (_ "None"))
+                (cons 'tip (_ "Do not do any filtering."))))
 
    (cons 'include (list
-                   (cons 'text (N_ "Include Transactions to/from Filter Accounts"))
-                   (cons 'tip (N_ "Include transactions to/from filter accounts only."))))
+                   (cons 'text (_ "Include Transactions to/from Filter Accounts"))
+                   (cons 'tip (_ "Include transactions to/from filter accounts only."))))
 
    (cons 'exclude (list
-                   (cons 'text (N_ "Exclude Transactions to/from Filter Accounts"))
-                   (cons 'tip (N_ "Exclude transactions to/from all filter accounts."))))))
+                   (cons 'text (_ "Exclude Transactions to/from Filter Accounts"))
+                   (cons 'tip (_ "Exclude transactions to/from all filter accounts."))))))
 
 (define show-void-list
   (list
    (cons 'non-void-only (list
-                         (cons 'text (N_ "Non-void only"))
-                         (cons 'tip (N_ "Show only non-voided transactions."))))
-         
+                         (cons 'text (_ "Non-void only"))
+                         (cons 'tip (_ "Show only non-voided transactions."))))
+
    (cons 'void-only (list
-                     (cons 'text (N_ "Void only"))
-                     (cons 'tip (N_ "Show only voided transactions."))))
-   
+                     (cons 'text (_ "Void only"))
+                     (cons 'tip (_ "Show only voided transactions."))))
+
    (cons 'both (list
-                (cons 'text (N_ "Both"))
-                (cons 'tip (N_ "Show both (and include void transactions in totals)."))))))
+                (cons 'text (_ "Both"))
+                (cons 'tip (_ "Show both (and include void transactions in totals)."))))))
 
 (define reconcile-status-list
   ;; value will be either #f to disable reconciled-status filter
@@ -294,30 +294,30 @@ options specified in the Options panels."))
   ;; be '(#\c #\y) to retrieve list of cleared and reconciled splits.
   (list
    (cons  #f (list
-              (cons 'text (N_ "All"))
-              (cons 'tip (N_ "Show All Transactions"))))
+              (cons 'text (_ "All"))
+              (cons 'tip (_ "Show All Transactions"))))
 
    (cons '(#\n) (list
-                 (cons 'text (N_ "Unreconciled"))
-                 (cons 'tip (N_ "Unreconciled only"))))
-   
+                 (cons 'text (_ "Unreconciled"))
+                 (cons 'tip (_ "Unreconciled only"))))
+
    (cons '(#\c) (list
-                 (cons 'text (N_ "Cleared"))
-                 (cons 'tip (N_ "Cleared only"))))
-   
+                 (cons 'text (_ "Cleared"))
+                 (cons 'tip (_ "Cleared only"))))
+
    (cons '(#\y) (list
-                 (cons 'text (N_ "Reconciled"))
-                 (cons 'tip (N_ "Reconciled only"))))))
+                 (cons 'text (_ "Reconciled"))
+                 (cons 'tip (_ "Reconciled only"))))))
 
 
 (define ascending-list
   (list
    (cons 'ascend (list
-                  (cons 'text (N_ "Ascending"))
-                  (cons 'tip (N_ "Smallest to largest, earliest to latest."))))
+                  (cons 'text (_ "Ascending"))
+                  (cons 'tip (_ "Smallest to largest, earliest to latest."))))
    (cons 'descend (list
-                   (cons 'text (N_ "Descending"))
-                   (cons 'tip (N_ "Largest to smallest, latest to earliest."))))))
+                   (cons 'text (_ "Descending"))
+                   (cons 'tip (_ "Largest to smallest, latest to earliest."))))))
 
 (define sign-reverse-list
   (list
@@ -328,18 +328,18 @@ options specified in the Options panels."))
           (cons 'acct-types #f)))
    (cons 'none
          (list
-          (cons 'text (N_ "None"))
-          (cons 'tip (N_ "Don't change any displayed amounts."))
+          (cons 'text (_ "None"))
+          (cons 'tip (_ "Don't change any displayed amounts."))
           (cons 'acct-types '())))
    (cons 'income-expense
          (list
-          (cons 'text (N_ "Income and Expense"))
-          (cons 'tip (N_ "Reverse amount display for Income and Expense Accounts."))
+          (cons 'text (_ "Income and Expense"))
+          (cons 'tip (_ "Reverse amount display for Income and Expense Accounts."))
           (cons 'acct-types (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))))
    (cons 'credit-accounts
          (list
-          (cons 'text (N_ "Credit Accounts"))
-          (cons 'tip (N_ "Reverse amount display for Liability, Payable, Equity, \
+          (cons 'text (_ "Credit Accounts"))
+          (cons 'tip (_ "Reverse amount display for Liability, Payable, Equity, \
 Credit Card, and Income accounts."))
           (cons 'acct-types (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE
                                   ACCT-TYPE-EQUITY ACCT-TYPE-CREDIT
@@ -374,7 +374,7 @@ Credit Card, and Income accounts."))
   (gnc:register-trep-option
    (gnc:make-complex-boolean-option
     gnc:pagename-general optname-common-currency
-    "e" (N_ "Convert all transactions into a common currency.") #f
+    "e" (_ "Convert all transactions into a common currency.") #f
     #f
     (lambda (x)
       (begin
@@ -391,19 +391,19 @@ Credit Card, and Income accounts."))
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
     gnc:pagename-general optname-orig-currency
-    "f1" (N_ "Also show original currency amounts") #f))
+    "f1" (_ "Also show original currency amounts") #f))
 
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
     gnc:pagename-general optname-table-export
-    "g" (N_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))
+    "g" (_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))
 
   ;; Filtering Options
 
   (gnc:register-trep-option
    (gnc:make-string-option
     pagename-filter optname-account-matcher
-    "a5" (N_ "Match only accounts whose fullname is matched e.g. ':Travel' will match \
+    "a5" (_ "Match only accounts whose fullname is matched e.g. ':Travel' will match \
 Expenses:Travel:Holiday and Expenses:Business:Travel. It can be left blank, which will \
 disable the matcher.")
     ""))
@@ -412,7 +412,7 @@ disable the matcher.")
    (gnc:make-simple-boolean-option
     pagename-filter optname-account-matcher-regex
     "a6"
-    (N_ "By default the account matcher will search substring only. Set this to true to \
+    (_ "By default the account matcher will search substring only. Set this to true to \
 enable full POSIX regular expressions capabilities. 'Car|Flights' will match both \
 Expenses:Car and Expenses:Flights. Use a period (.) to match a single character e.g. \
 '20../.' will match 'Travel 2017/1 London'. ")
@@ -421,7 +421,7 @@ Expenses:Car and Expenses:Flights. Use a period (.) to match a single character
   (gnc:register-trep-option
    (gnc:make-string-option
     pagename-filter optname-transaction-matcher
-    "i1" (N_ "Match only transactions whose substring is matched e.g. '#gift' \
+    "i1" (_ "Match only transactions whose substring is matched e.g. '#gift' \
 will find all transactions with #gift in description, notes or memo. It can be left \
 blank, which will disable the matcher.")
     ""))
@@ -430,7 +430,7 @@ blank, which will disable the matcher.")
    (gnc:make-simple-boolean-option
     pagename-filter optname-transaction-matcher-regex
     "i2"
-    (N_ "By default the transaction matcher will search substring only. Set this to true to \
+    (_ "By default the transaction matcher will search substring only. Set this to true to \
 enable full POSIX regular expressions capabilities. '#work|#family' will match both \
 tags within description, notes or memo. ")
     #f))
@@ -438,7 +438,7 @@ tags within description, notes or memo. ")
   (gnc:register-trep-option
    (gnc:make-multichoice-option
     pagename-filter optname-reconcile-status
-    "j1" (N_ "Filter by reconcile status.")
+    "j1" (_ "Filter by reconcile status.")
     #f
     (keylist->vectorlist reconcile-status-list)))
 
@@ -455,7 +455,7 @@ tags within description, notes or memo. ")
   (gnc:register-trep-option
    (gnc:make-account-list-option
     gnc:pagename-accounts optname-accounts
-    "a" (N_ "Report on these accounts.")
+    "a" (_ "Report on these accounts.")
     ;; select, by default, no accounts! Selecting all accounts will
     ;; always imply an insanely long waiting time upon opening, and it
     ;; is almost never useful. So we instead display the normal error
@@ -468,7 +468,7 @@ tags within description, notes or memo. ")
   (gnc:register-trep-option
    (gnc:make-account-list-option
     gnc:pagename-accounts optname-filterby
-    "c1" (N_ "Filter on these accounts.")
+    "c1" (_ "Filter on these accounts.")
     (lambda ()
       '())
     #f #t))
@@ -476,7 +476,7 @@ tags within description, notes or memo. ")
   (gnc:register-trep-option
    (gnc:make-multichoice-callback-option
     gnc:pagename-accounts optname-filtertype
-    "c" (N_ "Filter account.")
+    "c" (_ "Filter account.")
     'none
     (keylist->vectorlist filter-list)
     #f
@@ -548,7 +548,7 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-callback-option
       pagename-sorting optname-prime-sortkey
-      "a" (N_ "Sort by this criterion first.")
+      "a" (_ "Sort by this criterion first.")
       prime-sortkey
       key-choice-list #f
       (lambda (x)
@@ -559,28 +559,28 @@ tags within description, notes or memo. ")
      (gnc:make-simple-boolean-option
       pagename-sorting optname-full-account-name
       "j1"
-      (N_ "Show the full account name for subtotals and subheadings?")
+      (_ "Show the full account name for subtotals and subheadings?")
       #f))
 
     (gnc:register-trep-option
      (gnc:make-simple-boolean-option
       pagename-sorting optname-show-account-code
       "j2"
-      (N_ "Show the account code for subtotals and subheadings?")
+      (_ "Show the account code for subtotals and subheadings?")
       #f))
 
     (gnc:register-trep-option
      (gnc:make-simple-boolean-option
       pagename-sorting optname-show-account-description
       "j3"
-      (N_ "Show the account description for subheadings?")
+      (_ "Show the account description for subheadings?")
       #f))
     
     (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       pagename-sorting optname-prime-subtotal
       "e5"
-      (N_ "Subtotal according to the primary key?")
+      (_ "Subtotal according to the primary key?")
       prime-sortkey-subtotal-true #f
       (lambda (x)
         (set! prime-sortkey-subtotal-true x)
@@ -589,14 +589,14 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       pagename-sorting optname-prime-date-subtotal
-      "e2" (N_ "Do a date subtotal.")
+      "e2" (_ "Do a date subtotal.")
       'monthly
       date-subtotal-choice-list))
 
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       pagename-sorting optname-prime-sortorder
-      "e" (N_ "Order of primary sorting.")
+      "e" (_ "Order of primary sorting.")
       'ascend
       ascending-choice-list))
 
@@ -605,7 +605,7 @@ tags within description, notes or memo. ")
      (gnc:make-multichoice-callback-option
       pagename-sorting optname-sec-sortkey
       "f"
-      (N_ "Sort by this criterion second.")
+      (_ "Sort by this criterion second.")
       sec-sortkey
       key-choice-list #f
       (lambda (x)
@@ -616,7 +616,7 @@ tags within description, notes or memo. ")
      (gnc:make-complex-boolean-option
       pagename-sorting optname-sec-subtotal
       "i5"
-      (N_ "Subtotal according to the secondary key?")
+      (_ "Subtotal according to the secondary key?")
       sec-sortkey-subtotal-true #f
       (lambda (x)
         (set! sec-sortkey-subtotal-true x)
@@ -625,14 +625,14 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       pagename-sorting optname-sec-date-subtotal
-      "i2" (N_ "Do a date subtotal.")
+      "i2" (_ "Do a date subtotal.")
       'monthly
       date-subtotal-choice-list))
 
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       pagename-sorting optname-sec-sortorder
-      "i" (N_ "Order of Secondary sorting.")
+      "i" (_ "Order of Secondary sorting.")
       'ascend
       ascending-choice-list)))
 
@@ -677,37 +677,37 @@ tags within description, notes or memo. ")
      ;; One list per option here with: option-name, sort-tag,
      ;; help-string, default-value
      (list
-      (list (N_ "Date")                         "a"  (N_ "Display the date?") #t)
-      (list (N_ "Reconciled Date")              "a2" (N_ "Display the reconciled date?") #f)
+      (list (N_ "Date")                         "a"  (_ "Display the date?") #t)
+      (list (N_ "Reconciled Date")              "a2" (_ "Display the reconciled date?") #f)
       (if BOOK-SPLIT-ACTION
-          (list (N_ "Num/Action")               "b"  (N_ "Display the check number?") #t)
-          (list (N_ "Num")                      "b"  (N_ "Display the check number?") #t))
-      (list (N_ "Description")                  "c"  (N_ "Display the description?") #t)
-      (list (N_ "Notes")                        "d2" (N_ "Display the notes if the memo is unavailable?") #t)
+          (list (N_ "Num/Action")               "b"  (_ "Display the check number?") #t)
+          (list (N_ "Num")                      "b"  (_ "Display the check number?") #t))
+      (list (N_ "Description")                  "c"  (_ "Display the description?") #t)
+      (list (N_ "Notes")                        "d2" (_ "Display the notes if the memo is unavailable?") #t)
       ;; account name option appears here
-      (list (N_ "Use Full Account Name")        "f"  (N_ "Display the full account name?") #t)
-      (list (N_ "Account Code")                 "g"  (N_ "Display the account code?") #f)
+      (list (N_ "Use Full Account Name")        "f"  (_ "Display the full account name?") #t)
+      (list (N_ "Account Code")                 "g"  (_ "Display the account code?") #f)
       ;; other account name option appears here
-      (list (N_ "Use Full Other Account Name")  "i"  (N_ "Display the full account name?") #f)
-      (list (N_ "Other Account Code")           "j"  (N_ "Display the other account code?") #f)
-      (list (N_ "Shares")                       "k"  (N_ "Display the number of shares?") #f)
-      (list (N_ "Price")                        "l"  (N_ "Display the shares price?") #f)
+      (list (N_ "Use Full Other Account Name")  "i"  (_ "Display the full account name?") #f)
+      (list (N_ "Other Account Code")           "j"  (_ "Display the other account code?") #f)
+      (list (N_ "Shares")                       "k"  (_ "Display the number of shares?") #f)
+      (list (N_ "Price")                        "l"  (_ "Display the shares price?") #f)
       ;; note the "Amount" multichoice option in between here
-      (list (N_ "Running Balance")              "n"  (N_ "Display a running balance?") #f)
-      (list (N_ "Totals")                       "o"  (N_ "Display the totals?") #t)))
+      (list (N_ "Running Balance")              "n"  (_ "Display a running balance?") #f)
+      (list (N_ "Totals")                       "o"  (_ "Display the totals?") #t)))
 
     (if BOOK-SPLIT-ACTION
         (gnc:register-trep-option
          (gnc:make-simple-boolean-option
           gnc:pagename-display (N_ "Trans Number")
-          "b2" (N_ "Display the trans number?") #f)))
+          "b2" (_ "Display the trans number?") #f)))
 
     ;; Add an option to display the memo, and disable the notes option
     ;; when memos are not included.
     (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       gnc:pagename-display (N_ "Memo")
-      "d"  (N_ "Display the memo?") #t
+      "d"  (_ "Display the memo?") #t
       disp-memo?
       (lambda (x)
         (set! disp-memo? x)
@@ -717,7 +717,7 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       gnc:pagename-display (N_ "Account Name")
-      "e"  (N_ "Display the account name?") #t
+      "e"  (_ "Display the account name?") #t
       disp-accname?
       (lambda (x)
         (set! disp-accname? x)
@@ -727,7 +727,7 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       gnc:pagename-display (N_ "Other Account Name")
-      "h5"  (N_ "Display the other account name? (if this is a split transaction, this parameter is guessed).") #f
+      "h5"  (_ "Display the other account name? (if this is a split transaction, this parameter is guessed).") #f
       disp-other-accname?
       (lambda (x)
         (set! disp-other-accname? x)
@@ -736,14 +736,14 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-callback-option
       gnc:pagename-display optname-detail-level
-      "h" (N_ "Amount of detail to display per transaction.")
+      "h" (_ "Amount of detail to display per transaction.")
       'single
       (list (vector 'multi-line
-                    (N_ "Multi-Line")
-                    (N_ "Display all splits in a transaction on a separate line."))
+                    (_ "Multi-Line")
+                    (_ "Display all splits in a transaction on a separate line."))
             (vector 'single
-                    (N_ "Single")
-                    (N_ "Display one line per transaction, merging multiple splits where required.")))
+                    (_ "Single")
+                    (_ "Display one line per transaction, merging multiple splits where required.")))
       #f
       (lambda (x)
         (set! detail-is-single? (eq? x 'single))
@@ -752,12 +752,12 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-callback-option
       gnc:pagename-display (N_ "Amount")
-      "m" (N_ "Display the amount?")
+      "m" (_ "Display the amount?")
       'single
       (list
-       (vector 'none   (N_ "None") (N_ "No amount display."))
-       (vector 'single (N_ "Single") (N_ "Single Column Display."))
-       (vector 'double (N_ "Double") (N_ "Two Column Display.")))
+       (vector 'none   (_ "None") (_ "No amount display."))
+       (vector 'single (_ "Single") (_ "Single Column Display."))
+       (vector 'double (_ "Double") (_ "Two Column Display.")))
       #f
       (lambda (x)
         (set! amount-is-single? (eq? x 'single))
@@ -766,7 +766,7 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       gnc:pagename-display (N_ "Sign Reverses")
-      "m1" (N_ "Reverse amount display for certain account types.")
+      "m1" (_ "Reverse amount display for certain account types.")
       'global
       (keylist->vectorlist sign-reverse-list))))
 
@@ -920,15 +920,15 @@ tags within description, notes or memo. ")
          ;; merge? to merge with the next cell (ie for debit/credit cells)
          ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to dual-subtotal
          (if (column-uses? 'amount-single)
-             (list (vector (header-commodity (N_ "Amount"))
+             (list (vector (header-commodity (_ "Amount"))
                            amount #t #t
                            (vector #f #f)))
              '())
          (if (column-uses? 'amount-double)
-             (list (vector (header-commodity (N_ "Debit"))
+             (list (vector (header-commodity (_ "Debit"))
                            debit-amount #f #t
                            (vector #t gnc-numeric-add))
-                   (vector (header-commodity (N_ "Credit"))
+                   (vector (header-commodity (_ "Credit"))
                            credit-amount #f #t
                            (vector #f gnc-numeric-sub)))
              '())
@@ -951,7 +951,7 @@ tags within description, notes or memo. ")
              '())
 
          (if (column-uses? 'running-balance)
-             (list (vector (N_ "Running Balance")
+             (list (vector (_ "Running Balance")
                            running-balance #t #f
                            (vector #f #f)))
              '()))))
@@ -1545,11 +1545,11 @@ tags within description, notes or memo. ")
             (highlight
              (string-append optname-account-matcher
                             (if (opt-val pagename-filter optname-account-matcher-regex)
-                                (N_ " regex")
+                                (_ " regex")
                                 ""))
              account-matcher)
             (highlight
-             (N_ "Accounts produced")
+             (_ "Accounts produced")
              (string-join (map xaccAccountGetName c_account_1) ", "))))
        (if (eq? filter-mode 'none)
            ""
@@ -1562,7 +1562,7 @@ tags within description, notes or memo. ")
             (highlight
              (string-append optname-transaction-matcher
                             (if (opt-val pagename-filter optname-transaction-matcher-regex)
-                                (N_ " regex")
+                                (_ " regex")
                                 ""))
              transaction-matcher)))
        (if reconcile-status-filter

commit c26af85e82c37edb3ceecb3833a4f2f04c9244fc
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:15:04 2017 +0800

    ENH: Upgrade Sign Reversal to use global preference by default

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 255a05c..7ced336 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -321,6 +321,11 @@ options specified in the Options panels."))
 
 (define sign-reverse-list
   (list
+   (cons 'global
+         (list
+          (cons 'text (_ "Use Global Preference"))
+          (cons 'tip (_ "Use reversing option specified in global preference."))
+          (cons 'acct-types #f)))
    (cons 'none
          (list
           (cons 'text (N_ "None"))
@@ -762,7 +767,7 @@ tags within description, notes or memo. ")
      (gnc:make-multichoice-option
       gnc:pagename-display (N_ "Sign Reverses")
       "m1" (N_ "Reverse amount display for certain account types.")
-      'credit-accounts
+      'global
       (keylist->vectorlist sign-reverse-list))))
 
   (gnc:options-set-default-section options gnc:pagename-general)
@@ -1136,8 +1141,20 @@ tags within description, notes or memo. ")
                  (let* ((calculator (vector-ref cell 1))
                         (reverse? (vector-ref cell 2))
                         (subtotal? (vector-ref cell 3))
-                        (calculated (calculator split)))
-                   (vector calculated reverse? subtotal?)))
+                        (calculated (calculator split))
+                        (reverse-amount (lambda (mon)
+                                            (let ((currency (gnc:gnc-monetary-commodity mon))
+                                                  (amount (gnc:gnc-monetary-amount mon)))
+                                              (gnc:make-gnc-monetary
+                                               currency
+                                               (gnc-numeric-neg amount))))))
+                   (vector (if (and reverse?
+                                    (if account-types-to-reverse
+                                        (member (xaccAccountGetType account) account-types-to-reverse)
+                                        (gnc-reverse-balance account)))
+                               (reverse-amount calculated)
+                               calculated)
+                           subtotal?)))
                cell-calculators))
 
         (if (column-uses? 'date)

commit e8dc5c545d3baa5b06e69a030abac371ce61bb90
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Nov 26 17:31:05 2017 +0800

    REFACTOR: move calculated-cells to allow access from add-subtotal-row
    
    This will negate the need to zip calculated cells to call add-subtotal-row.
    Note git-diff seems to think lots of functions were moved - it's calculated-cells
    that's been moved by a few lines so that it is accessible to add-subtotal-row.
    
    Also rename a few keywords to better describe their use.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index ca112cb..255a05c 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -827,8 +827,8 @@ tags within description, notes or memo. ")
 
     (define (column-uses? param)
       (cdr (assq param used-columns)))
-    
-    (define headings
+
+    (define left-columns
       (let* ((add-if (lambda pred? . items) (if pred? items '())))
         (append
          (add-if (column-uses? 'date)
@@ -855,106 +855,7 @@ tags within description, notes or memo. ")
          (add-if (column-uses? 'shares)
                  (_ "Shares"))
          (add-if (column-uses? 'price)
-                 (_ "Price")))))
-
-    (define width (length headings))
-
-    (define (add-subheading data subheading-style)
-      (let ((heading-cell (gnc:make-html-table-cell data)))
-        (gnc:html-table-cell-set-colspan! heading-cell (+ width width-amount))
-        (gnc:html-table-append-row/markup!
-         table subheading-style
-         (list heading-cell))))
-
-
-    (define (add-subtotal-row subtotal-string subtotal-collectors-and-calculated-cells subtotal-style)
-      (let* ((row-contents '())
-             (subtotal-collectors (map car subtotal-collectors-and-calculated-cells))
-             (calculated-cells  (map cadr subtotal-collectors-and-calculated-cells))
-             (merge-list (map (lambda (cell) (vector-ref cell 4)) calculated-cells))
-             (columns (map (lambda (coll) (coll 'format gnc:make-gnc-monetary #f)) subtotal-collectors))
-             (list-of-commodities (delete-duplicates (map gnc:gnc-monetary-commodity (concatenate columns))
-                                                     gnc-commodity-equal)))
-
-        (define (retrieve-commodity list-of-monetary commodity)
-          (and (not (null? list-of-monetary))
-               (if (gnc-commodity-equal (gnc:gnc-monetary-commodity (car list-of-monetary)) commodity)
-                   (car list-of-monetary)
-                   (retrieve-commodity (cdr list-of-monetary) commodity))))
-
-        (define (add-first-column string)
-          (if export?
-              (begin
-                (addto! row-contents (gnc:make-html-table-cell/markup "total-label-cell" string))
-                (for-each (lambda (cell) (addto! row-contents cell))
-                          (gnc:html-make-empty-cells (- width 1))))
-              (addto! row-contents (gnc:make-html-table-cell/size/markup 1 width "total-label-cell" string))))
-
-        (define (add-columns commodity)
-          (let ((start-dual-column? #f)
-                (dual-subtotal (gnc:make-gnc-numeric 0 1)))
-            (for-each (lambda (column merge-entry)
-                        (let* ((mon (retrieve-commodity column commodity))
-                               (col (and mon (gnc:gnc-monetary-amount mon)))
-                               (merge? (vector-ref merge-entry 0))
-                               (merge-fn (vector-ref merge-entry 1)))
-                          (if merge?
-                              ;; We're merging. Run merge-fn (usu gnc-numeric-add or sub)
-                              ;; and store total in dual-subtotal. Do NOT add column.
-                              (begin
-                                (if column-amount
-                                    (set! dual-subtotal
-                                          (merge-fn dual-subtotal column-amount
-                                                    GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
-                                (set! start-dual-column? #t))
-                              (if start-dual-column?
-                                  (begin
-                                    ;; We've completed merging. Add this column amount
-                                    ;; and add the columns.
-                                    (if column-amount
-                                        (set! dual-subtotal
-                                              (merge-fn dual-subtotal column-amount
-                                                        GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
-                                    (if (gnc-numeric-positive-p dual-subtotal)
-                                        (begin
-                                          (addto! row-contents
-                                                  (gnc:make-html-table-cell/markup
-                                                   "total-number-cell"
-                                                   (gnc:make-gnc-monetary commodity dual-subtotal)))
-                                          (addto! row-contents ""))
-                                        (begin
-                                          (addto! row-contents "")
-                                          (addto! row-contents
-                                                  (gnc:make-html-table-cell/markup
-                                                   "total-number-cell"
-                                                   (gnc:make-gnc-monetary
-                                                    commodity
-                                                    (gnc-numeric-neg dual-subtotal))))))
-                                    (set! start-dual-column? #f)
-                                    (set! dual-subtotal (gnc:make-gnc-numeric 0 1)))
-				  ;; Default; not merging/completed merge. Just
-				  ;; display monetary amount
-                                  (addto! row-contents
-                                          (gnc:make-html-table-cell/markup "total-number-cell" mon))))))
-                      columns
-                      merge-list)))
-
-        ;;first row
-        (add-first-column subtotal-string)
-        (add-columns (and (pair? list-of-commodities)
-                          (car list-of-commodities))) ;to account for empty-row subtotals
-        (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents))
-
-        ;;subsequent rows
-        (if (pair? list-of-commodities)
-            (for-each (lambda (commodity)
-                        (set! row-contents '())
-                        (add-first-column "")
-                        (add-columns commodity)
-                        (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents)))
-                      (cdr list-of-commodities)))))
-
-    (define (total-string str) (string-append (_ "Total For ") str))
+                 (_ "Price"))))
 
     ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;;
@@ -998,11 +899,9 @@ tags within description, notes or memo. ")
                                           #f
                                           (gnc:monetary-neg (split-value s)))))
            (original-amount (lambda (s) (gnc:make-gnc-monetary (currency s) (damount s))))
-
            (original-debit-amount (lambda (s) (if (gnc-numeric-positive-p (damount s))
                                                   (original-amount s)
                                                   #f)))
-
            (original-credit-amount (lambda (s) (if (gnc-numeric-positive-p (damount s))
                                                    #f
                                                    (gnc:monetary-neg (original-amount s)))))
@@ -1052,12 +951,113 @@ tags within description, notes or memo. ")
                            (vector #f #f)))
              '()))))
 
-    (define amount-headings
+    (define headings-left-columns
+      (map (lambda (column)
+             (vector-ref column 0))
+           left-columns))
+
+    (define headings-right-columns
       (map (lambda (column)
              (vector-ref column 0))
            calculated-cells))
 
-    (define width-amount (length amount-headings))
+    (define width-left-columns (length left-columns))
+    (define width-right-columns (length calculated-cells))
+
+    (define (add-subheading data subheading-style)
+      (let ((heading-cell (gnc:make-html-table-cell data)))
+        (gnc:html-table-cell-set-colspan! heading-cell (+ width-left-columns width-right-columns))
+        (gnc:html-table-append-row/markup!
+         table subheading-style (list heading-cell))))
+
+    (define (add-subtotal-row subtotal-string subtotal-collectors subtotal-style)
+      (let* ((row-contents '())
+             (merge-list (map (lambda (cell) (vector-ref cell 4)) calculated-cells))
+             (columns (map (lambda (coll) (coll 'format gnc:make-gnc-monetary #f)) subtotal-collectors))
+             (list-of-commodities (delete-duplicates (map gnc:gnc-monetary-commodity (concatenate columns))
+                                                     gnc-commodity-equal)))
+
+        (define (retrieve-commodity list-of-monetary commodity)
+          (if (null? list-of-monetary)
+              #f
+              (if (gnc-commodity-equal (gnc:gnc-monetary-commodity (car list-of-monetary)) commodity)
+                  (car list-of-monetary)
+                  (retrieve-commodity (cdr list-of-monetary) commodity))))
+
+        (define (add-first-column string)
+          (if export?
+              (begin
+                (addto! row-contents (gnc:make-html-table-cell/markup "total-label-cell" string))
+                (for-each (lambda (cell) (addto! row-contents cell))
+                          (gnc:html-make-empty-cells (- width-left-columns 1))))
+              (addto! row-contents (gnc:make-html-table-cell/size/markup 1 width-left-columns "total-label-cell" string))))
+
+        (define (add-columns commodity)
+          (let ((start-dual-column? #f)
+                (dual-subtotal (gnc:make-gnc-numeric 0 1)))
+            (for-each (lambda (column merge-entry)
+                        (let* ((mon (retrieve-commodity column commodity))
+                               (column-amount (and mon (gnc:gnc-monetary-amount mon)))
+                               (merge? (vector-ref merge-entry 0))
+                               (merge-fn (vector-ref merge-entry 1)))
+                          (if merge?
+                              ;; We're merging. Run merge-fn (usu gnc-numeric-add or sub)
+                              ;; and store total in dual-subtotal. Do NOT add column.
+                              (begin
+                                (if column-amount
+                                    (set! dual-subtotal
+                                          (merge-fn dual-subtotal column-amount
+                                                    GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
+                                (set! start-dual-column? #t))
+                              (if start-dual-column?
+                                  (begin
+                                    ;; We've completed merging. Add this column amount
+                                    ;; and add the columns.
+                                    (if column-amount
+                                        (set! dual-subtotal
+                                              (merge-fn dual-subtotal column-amount
+                                                        GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
+                                    (if (gnc-numeric-positive-p dual-subtotal)
+                                        (begin
+                                          (addto! row-contents
+                                                  (gnc:make-html-table-cell/markup
+                                                   "total-number-cell"
+                                                   (gnc:make-gnc-monetary commodity dual-subtotal)))
+                                          (addto! row-contents ""))
+                                        (begin
+                                          (addto! row-contents "")
+                                          (addto! row-contents
+                                                  (gnc:make-html-table-cell/markup
+                                                   "total-number-cell"
+                                                   (gnc:make-gnc-monetary
+                                                    commodity
+                                                    (gnc-numeric-neg dual-subtotal))))))
+                                    (set! start-dual-column? #f)
+                                    (set! dual-subtotal (gnc:make-gnc-numeric 0 1)))
+                                  ;; Default; not merging/completed merge. Just
+                                  ;; display monetary amount
+                                  (addto! row-contents
+                                          (gnc:make-html-table-cell/markup "total-number-cell" mon))))))
+                      columns
+                      merge-list)))
+
+        ;;first row
+        (add-first-column subtotal-string)
+        (add-columns (if (pair? list-of-commodities)
+                         (car list-of-commodities)
+                         #f)) ;to account for empty-row subtotals
+        (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents))
+
+        ;;subsequent rows
+        (if (pair? list-of-commodities)
+            (for-each (lambda (commodity)
+                        (set! row-contents '())
+                        (add-first-column "")
+                        (add-columns commodity)
+                        (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents)))
+                      (cdr list-of-commodities)))))
+
+    (define (total-string str) (string-append (_ "Total For ") str))
 
     ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -1269,10 +1269,10 @@ tags within description, notes or memo. ")
              table def:grand-total-style
              (list
               (gnc:make-html-table-cell/size
-               1 (+ width width-amount) (gnc:make-html-text (gnc:html-markup-hr)))))
+               1 (+ width-left-columns width-right-columns) (gnc:make-html-text (gnc:html-markup-hr)))))
 
             (if (opt-val gnc:pagename-display "Totals")
-                (add-subtotal-row (render-grand-total) (zip total-collectors calculated-cells) def:grand-total-style)))
+                (add-subtotal-row (render-grand-total) total-collectors def:grand-total-style)))
 
           (let* ((current (car splits))
                  (rest (cdr splits))
@@ -1321,13 +1321,13 @@ tags within description, notes or memo. ")
                       (begin
                         (add-subtotal-row (total-string
                                            (render-summary current secondary-renderer-key #f))
-                                          (zip secondary-subtotal-collectors calculated-cells)
+                                          secondary-subtotal-collectors
                                           def:secondary-subtotal-style)
                         (for-each (lambda (coll) (coll 'reset #f #f))
                                   secondary-subtotal-collectors)))
                   (add-subtotal-row (total-string
                                      (render-summary current primary-renderer-key #f))
-                                    (zip primary-subtotal-collectors calculated-cells)
+                                    primary-subtotal-collectors
                                     def:primary-subtotal-style)
                   (for-each (lambda (coll) (coll 'reset #f #f))
                             primary-subtotal-collectors)
@@ -1346,7 +1346,7 @@ tags within description, notes or memo. ")
                                                (secondary-subtotal-comparator next))))))
                     (begin (add-subtotal-row (total-string
                                               (render-summary current secondary-renderer-key #f))
-                                             (zip secondary-subtotal-collectors calculated-cells)
+                                             secondary-subtotal-collectors
                                              def:secondary-subtotal-style)
                            (for-each (lambda (coll) (coll 'reset #f #f))
                                      secondary-subtotal-collectors)
@@ -1360,7 +1360,7 @@ tags within description, notes or memo. ")
                                     secondary-subtotal-collectors
                                     total-collectors))))
 
-    (gnc:html-table-set-col-headers! table (concatenate (list headings amount-headings)))
+    (gnc:html-table-set-col-headers! table (concatenate (list headings-left-columns headings-right-columns)))
 
     (if primary-renderer-key
         (add-subheading (render-summary (car splits) primary-renderer-key #t)

commit 6f87138bce21a5b13fbb08acf1967b0860c2ff6d
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 06:04:07 2017 +0800

    ENH: 'original currency amt' now shows dual columns

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 15e8e6d..ca112cb 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -998,6 +998,14 @@ tags within description, notes or memo. ")
                                           #f
                                           (gnc:monetary-neg (split-value s)))))
            (original-amount (lambda (s) (gnc:make-gnc-monetary (currency s) (damount s))))
+
+           (original-debit-amount (lambda (s) (if (gnc-numeric-positive-p (damount s))
+                                                  (original-amount s)
+                                                  #f)))
+
+           (original-credit-amount (lambda (s) (if (gnc-numeric-positive-p (damount s))
+                                                   #f
+                                                   (gnc:monetary-neg (original-amount s)))))
            (running-balance (lambda (s) (gnc:make-gnc-monetary (currency s) (xaccSplitGetBalance s)))))
         (append
          ;; each column will be a vector
@@ -1020,11 +1028,24 @@ tags within description, notes or memo. ")
                            credit-amount #f #t
                            (vector #f gnc-numeric-sub)))
              '())
-         (if (column-uses? 'amount-original-currency)
-             (list (vector (N_ "Original")
+
+         (if (and (column-uses? 'amount-original-currency)
+                  (column-uses? 'amount-single))
+             (list (vector (_ "Amount")
                            original-amount #t #t
                            (vector #f #f)))
              '())
+
+         (if (and (column-uses? 'amount-original-currency)
+                  (column-uses? 'amount-double))
+             (list (vector (_ "Debit")
+                           original-debit-amount #f #t
+                           (vector #t gnc-numeric-add))
+                   (vector (_ "Credit")
+                           original-credit-amount #f #t
+                           (vector #f gnc-numeric-sub)))
+             '())
+
          (if (column-uses? 'running-balance)
              (list (vector (N_ "Running Balance")
                            running-balance #t #f

commit 2e06c8fc33e2425a03a9c70f241033ac43e4c3a6
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 05:59:09 2017 +0800

    REFACTOR+ENH:Add common-currency mnemonic to header if enabled
    
    This requires refactoring calculated cells to centralize
    the headers and enable their modification.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 5ae12fe..15e8e6d 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -796,6 +796,7 @@ tags within description, notes or memo. ")
           (cons 'price (opt-val gnc:pagename-display (N_ "Price")))
           (cons 'amount-single (eq? amount-setting 'single))
           (cons 'amount-double (eq? amount-setting 'double))
+          (cons 'common-currency (opt-val gnc:pagename-general optname-common-currency))
           (cons 'amount-original-currency
                 (and (opt-val gnc:pagename-general optname-common-currency)
                      (opt-val gnc:pagename-general optname-orig-currency)))
@@ -854,22 +855,9 @@ tags within description, notes or memo. ")
          (add-if (column-uses? 'shares)
                  (_ "Shares"))
          (add-if (column-uses? 'price)
-                 (_ "Price"))))
-    
-    (define amount-headings
-      (let* ((add-if (lambda pred? . items) (if pred? items '())))
-        (append (add-if (column-uses? 'amount-single)
-                        (_ "Amount"))
-                (add-if (column-uses? 'amount-double)
-                        (_ "Debit")
-                        (_ "Credit"))
-                (add-if (column-uses? 'amount-original-currency)
-                        (_ "Original"))
-                (add-if (column-uses? 'running-balance)
-                        (_ "Balance")))))
+                 (_ "Price")))))
 
     (define width (length headings))
-    (define width-amount (length amount-headings))
 
     (define (add-subheading data subheading-style)
       (let ((heading-cell (gnc:make-html-table-cell data)))
@@ -981,9 +969,19 @@ tags within description, notes or memo. ")
                                     (xaccSplitGetAmount s))))
            (trans-date (lambda (s) (gnc-transaction-get-date-posted (xaccSplitGetTransaction s))))
            (currency (lambda (s) (xaccAccountGetCommodity (xaccSplitGetAccount s))))
-           (report-currency (lambda (s) (if (opt-val gnc:pagename-general optname-common-currency)
+           (report-currency (lambda (s) (if (column-uses? 'common-currency)
                                             (opt-val gnc:pagename-general optname-currency)
                                             (currency s))))
+           (header-commodity (lambda (str)
+                               (string-append
+                                str
+                                (if (column-uses? 'common-currency)
+                                    (string-append
+                                     "<br>"
+                                     (gnc-commodity-get-mnemonic
+                                      (opt-val gnc:pagename-general optname-currency)))
+                                    ""))))
+           (time64CanonicalDayTime (lambda (t64)  (gnc-tm-set-day-middle (gnc-localtime t64))))
            (convert (lambda (s num)
                       (gnc:exchange-by-pricedb-nearest
                        (gnc:make-gnc-monetary (currency s) num)
@@ -1010,19 +1008,36 @@ tags within description, notes or memo. ")
          ;; merge? to merge with the next cell (ie for debit/credit cells)
          ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to dual-subtotal
          (if (column-uses? 'amount-single)
-             (list (vector "Amount" amount #t #t (vector #f #f)))
+             (list (vector (header-commodity (N_ "Amount"))
+                           amount #t #t
+                           (vector #f #f)))
              '())
          (if (column-uses? 'amount-double)
-             (list (vector "Debit" debit-amount #f #t (vector #t gnc-numeric-add))
-                   (vector "Credit" credit-amount #f #t (vector #f gnc-numeric-sub)))
+             (list (vector (header-commodity (N_ "Debit"))
+                           debit-amount #f #t
+                           (vector #t gnc-numeric-add))
+                   (vector (header-commodity (N_ "Credit"))
+                           credit-amount #f #t
+                           (vector #f gnc-numeric-sub)))
              '())
          (if (column-uses? 'amount-original-currency)
-             (list (vector "Original" original-amount #f #t (vector #f #f)))
+             (list (vector (N_ "Original")
+                           original-amount #t #t
+                           (vector #f #f)))
              '())
          (if (column-uses? 'running-balance)
-             (list (vector "Running Balance" running-balance #t #f (vector #f #f)))
+             (list (vector (N_ "Running Balance")
+                           running-balance #t #f
+                           (vector #f #f)))
              '()))))
 
+    (define amount-headings
+      (map (lambda (column)
+             (vector-ref column 0))
+           calculated-cells))
+
+    (define width-amount (length amount-headings))
+
     ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
     ;; renderers

commit aaa23dc51e393917a38e8cff9016f1f8bcc5caa0
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 05:54:29 2017 +0800

    REFACTOR: move column-uses? location
    
    This commit moves column-uses? helper to allow access
    to used-columns instead of needing to pass this parameter
    around with every call.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 44eb8f3..5ae12fe 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -812,60 +812,11 @@ tags within description, notes or memo. ")
           (cons 'sort-account-description (opt-val pagename-sorting (N_ "Show Account Description")))
           (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
-  (define (column-uses? param columns-used)
-    (cdr (assq param columns-used)))
-
-  (define (make-heading-list columns-used)
-    (define (add-if pred? . items) (if pred? items '()))
-    (append
-     (add-if (column-uses? 'date columns-used)
-             (_ "Date"))
-     (add-if (column-uses? 'reconciled-date columns-used)
-             (_ "Reconciled Date"))
-     (add-if (column-uses? 'num columns-used)
-             (if (and (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-                      (opt-val gnc:pagename-display (N_ "Trans Number")))
-                 (_ "Num/T-Num")
-                 (_ "Num")))
-     (add-if (column-uses? 'description columns-used)
-             (_ "Description"))
-     (add-if (column-uses? 'memo columns-used)
-             (if (column-uses? 'notes columns-used)
-                 (string-append (_ "Memo") "/" (_ "Notes"))
-                 (_ "Memo")))
-     (add-if (or (column-uses? 'account-name columns-used)
-                 (column-uses? 'account-code columns-used))
-             (_ "Account"))
-     (add-if (or (column-uses? 'other-account-name columns-used)
-                 (column-uses? 'other-account-code columns-used))
-             (_ "Transfer from/to"))
-     (add-if (column-uses? 'shares columns-used)
-             (_ "Shares"))
-     (add-if (column-uses? 'price columns-used)
-             (_ "Price"))))
-
-  (define (make-amount-heading-list columns-used)
-    (define (add-if pred? . items) (if pred? items '()))
-    (append
-     (add-if (column-uses? 'amount-single columns-used)
-             (_ "Amount"))
-     ;; FIXME: Proper labels: what?
-     (add-if (column-uses? 'amount-double columns-used)
-             (_ "Debit")
-             (_ "Credit"))
-     (add-if (column-uses? 'amount-original-currency columns-used)
-             (_ "Original"))
-     (add-if (column-uses? 'running-balance columns-used)
-             (_ "Balance"))))
 
   (let* ((work-to-do (length splits))
          (work-done 0)
          (table (gnc:make-html-table))
          (used-columns (build-columns-used))
-         (headings (make-heading-list used-columns))
-         (amount-headings (make-amount-heading-list used-columns))
-         (width (length headings))
-         (width-amount (length amount-headings))
          (account-types-to-reverse
           (keylist-get-info sign-reverse-list
                             (opt-val gnc:pagename-display (N_ "Sign Reverses"))
@@ -873,6 +824,53 @@ tags within description, notes or memo. ")
          (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
          (export? (opt-val gnc:pagename-general optname-table-export)))
 
+    (define (column-uses? param)
+      (cdr (assq param used-columns)))
+    
+    (define headings
+      (let* ((add-if (lambda pred? . items) (if pred? items '())))
+        (append
+         (add-if (column-uses? 'date)
+                 (_ "Date"))
+         (add-if (column-uses? 'reconciled-date)
+                 (_ "Reconciled Date"))
+         (add-if (column-uses? 'num)
+                 (if (and BOOK-SPLIT-ACTION
+                          (opt-val gnc:pagename-display (N_ "Trans Number")))
+                     (_ "Num/T-Num")
+                     (_ "Num")))
+         (add-if (column-uses? 'description)
+                 (_ "Description"))
+         (add-if (column-uses? 'memo)
+                 (if (column-uses? 'notes)
+                     (string-append (_ "Memo") "/" (_ "Notes"))
+                     (_ "Memo")))
+         (add-if (or (column-uses? 'account-name)
+                     (column-uses? 'account-code))
+                 (_ "Account"))
+         (add-if (or (column-uses? 'other-account-name)
+                     (column-uses? 'other-account-code))
+                 (_ "Transfer from/to"))
+         (add-if (column-uses? 'shares)
+                 (_ "Shares"))
+         (add-if (column-uses? 'price)
+                 (_ "Price"))))
+    
+    (define amount-headings
+      (let* ((add-if (lambda pred? . items) (if pred? items '())))
+        (append (add-if (column-uses? 'amount-single)
+                        (_ "Amount"))
+                (add-if (column-uses? 'amount-double)
+                        (_ "Debit")
+                        (_ "Credit"))
+                (add-if (column-uses? 'amount-original-currency)
+                        (_ "Original"))
+                (add-if (column-uses? 'running-balance)
+                        (_ "Balance")))))
+
+    (define width (length headings))
+    (define width-amount (length amount-headings))
+
     (define (add-subheading data subheading-style)
       (let ((heading-cell (gnc:make-html-table-cell data)))
         (gnc:html-table-cell-set-colspan! heading-cell (+ width width-amount))
@@ -1011,17 +1009,17 @@ tags within description, notes or memo. ")
          ;; subtotal? to allow subtotals (ie irrelevant for running balance)
          ;; merge? to merge with the next cell (ie for debit/credit cells)
          ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to dual-subtotal
-         (if (column-uses? 'amount-single used-columns)
+         (if (column-uses? 'amount-single)
              (list (vector "Amount" amount #t #t (vector #f #f)))
              '())
-         (if (column-uses? 'amount-double used-columns)
+         (if (column-uses? 'amount-double)
              (list (vector "Debit" debit-amount #f #t (vector #t gnc-numeric-add))
                    (vector "Credit" credit-amount #f #t (vector #f gnc-numeric-sub)))
              '())
-         (if (column-uses? 'amount-original-currency used-columns)
-             (list (vector "Original" original-amount #t #t (vector #f #f)))
+         (if (column-uses? 'amount-original-currency)
+             (list (vector "Original" original-amount #f #t (vector #f #f)))
              '())
-         (if (column-uses? 'running-balance used-columns)
+         (if (column-uses? 'running-balance)
              (list (vector "Running Balance" running-balance #t #f (vector #f #f)))
              '()))))
 
@@ -1064,10 +1062,10 @@ tags within description, notes or memo. ")
                         ((account) (xaccSplitGetAccount split))
                         ((other-acc) (xaccSplitGetAccount (xaccSplitGetOtherSplit split)))))
              (name (account-namestring account
-                                       (column-uses? 'sort-account-code      used-columns)
+                                       (column-uses? 'sort-account-code)
                                        #t
-                                       (column-uses? 'sort-account-full-name used-columns)))
-             (description (if (and (column-uses? 'sort-account-description used-columns)
+                                       (column-uses? 'sort-account-full-name)))
+             (description (if (and (column-uses? 'sort-account-description)
                                    (not (string-null? (xaccAccountGetDescription account))))
                               (string-append ": " (xaccAccountGetDescription account))
                               "")))
@@ -1106,7 +1104,7 @@ tags within description, notes or memo. ")
                    (vector calculated reverse? subtotal?)))
                cell-calculators))
 
-        (if (column-uses? 'date used-columns)
+        (if (column-uses? 'date)
             (addto! row-contents
                     (if transaction-row?
                         (gnc:make-html-table-cell/markup
@@ -1114,7 +1112,7 @@ tags within description, notes or memo. ")
                          (qof-print-date (xaccTransGetDate trans)))
                         "")))
 
-        (if (column-uses? 'reconciled-date used-columns)
+        (if (column-uses? 'reconciled-date)
             (addto! row-contents
                     (gnc:make-html-table-cell/markup
                      "date-cell"
@@ -1123,7 +1121,7 @@ tags within description, notes or memo. ")
                            ""
                            (qof-print-date date))))))
 
-        (if (column-uses? 'num used-columns)
+        (if (column-uses? 'num)
             (addto! row-contents
                     (if transaction-row?
                         (if BOOK-SPLIT-ACTION
@@ -1143,7 +1141,7 @@ tags within description, notes or memo. ")
                                                              (gnc-get-num-action trans split)))
                         "")))
 
-        (if (column-uses? 'description used-columns)
+        (if (column-uses? 'description)
             (addto! row-contents
                     (if transaction-row?
                         (gnc:make-html-table-cell/markup
@@ -1151,30 +1149,30 @@ tags within description, notes or memo. ")
                          (xaccTransGetDescription trans))
                         "")))
 
-        (if (column-uses? 'memo used-columns)
+        (if (column-uses? 'memo)
             (let ((memo (xaccSplitGetMemo split)))
-              (if (and (string-null? memo) (column-uses? 'notes used-columns))
+              (if (and (string-null? memo) (column-uses? 'notes))
                   (addto! row-contents (xaccTransGetNotes trans))
                   (addto! row-contents memo))))
 
-        (if (or (column-uses? 'account-name used-columns) (column-uses? 'account-code used-columns))
+        (if (or (column-uses? 'account-name) (column-uses? 'account-code))
             (addto! row-contents (account-namestring account
-                                                     (column-uses? 'account-code      used-columns)
-                                                     (column-uses? 'account-name      used-columns)
-                                                     (column-uses? 'account-full-name used-columns))))
+                                                     (column-uses? 'account-code)
+                                                     (column-uses? 'account-name)
+                                                     (column-uses? 'account-full-name))))
 
-        (if (or (column-uses? 'other-account-name used-columns) (column-uses? 'other-account-code used-columns))
+        (if (or (column-uses? 'other-account-name) (column-uses? 'other-account-code))
             (addto! row-contents (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
-                                                     (column-uses? 'other-account-code      used-columns)
-                                                     (column-uses? 'other-account-name      used-columns)
-                                                     (column-uses? 'other-account-full-name used-columns))))
+                                                     (column-uses? 'other-account-code)
+                                                     (column-uses? 'other-account-name)
+                                                     (column-uses? 'other-account-full-name))))
 
-        (if (column-uses? 'shares used-columns)
+        (if (column-uses? 'shares)
             (addto! row-contents (gnc:make-html-table-cell/markup
                                   "number-cell"
                                   (xaccSplitGetAmount split))))
 
-        (if (column-uses? 'price used-columns)
+        (if (column-uses? 'price)
             (addto! row-contents
                     (gnc:make-html-table-cell/markup
                      "number-cell"

commit 43cbe65282eacc736df1e350a11b0072f614688d
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 05:50:00 2017 +0800

    REFACTOR:Move Void-status filter to filter tab
    
    Also upgrade lookup-value Void Transactions now in Filter tab

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 51a4076..44eb8f3 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -58,7 +58,6 @@
 (define optname-accounts (N_ "Accounts"))
 (define optname-filterby (N_ "Filter By..."))
 (define optname-filtertype (N_ "Filter Type"))
-(define optname-void-transactions (N_ "Void Transactions"))
 
 ;;Display
 (define optname-detail-level (N_ "Detail Level"))
@@ -92,6 +91,7 @@
 (define optname-transaction-matcher (N_ "Transaction Matcher"))
 (define optname-transaction-matcher-regex (N_ "Transaction Matcher uses regular expressions for extended matching"))
 (define optname-reconcile-status (N_ "Reconcile Status"))
+(define optname-void-transactions (N_ "Void Transactions"))
 
 ;;Styles
 (define def:grand-total-style "grand-total")
@@ -437,6 +437,13 @@ tags within description, notes or memo. ")
     #f
     (keylist->vectorlist reconcile-status-list)))
 
+  (gnc:register-trep-option
+   (gnc:make-multichoice-option
+    pagename-filter optname-void-transactions
+    "k" (N_ "How to handle void transactions.")
+    'non-void-only
+    (keylist->vectorlist show-void-list)))
+
   ;; Accounts options
 
   ;; account to do report on
@@ -474,12 +481,6 @@ tags within description, notes or memo. ")
        (not (eq? x 'none))))))
   ;;
 
-  (gnc:register-trep-option
-   (gnc:make-multichoice-option
-    gnc:pagename-accounts optname-void-transactions
-    "d" (N_ "How to handle void transactions.")
-    'non-void-only
-    (keylist->vectorlist show-void-list)))
 
   ;; Sorting options
 
@@ -1417,7 +1418,7 @@ tags within description, notes or memo. ")
          (secondary-key (opt-val pagename-sorting optname-sec-sortkey))
          (secondary-order (opt-val pagename-sorting optname-sec-sortorder))
          (secondary-date-subtotal (opt-val pagename-sorting optname-sec-date-subtotal))
-         (void-status (opt-val gnc:pagename-accounts optname-void-transactions))
+         (void-status (opt-val pagename-filter optname-void-transactions))
          (splits '())
          (custom-sort? (or (and (member primary-key DATE-SORTING-TYPES)   ; this will remain
                                 (not (eq? primary-date-subtotal 'none)))  ; until qof-query
diff --git a/libgnucash/app-utils/options.scm b/libgnucash/app-utils/options.scm
index 3bb5e96..6083a14 100644
--- a/libgnucash/app-utils/options.scm
+++ b/libgnucash/app-utils/options.scm
@@ -1708,7 +1708,8 @@
                                         "To" (cons #f "End Date")
                                         "Use Full Account Name?" (cons #f "Use Full Account Name")
                                         "Use Full Other Account Name?" (cons #f "Use Full Other Account Name")
-                                        "Void Transactions?" (cons #f "Void Transactions")
+                                        "Void Transactions?" (cons "Filter" "Void Transactions")
+                                        "Void Transactions" (cons "Filter" "Void Transactions")
                                         "Account Substring" (cons "Filter" "Account Matcher")
                                         ))
                        (name-match (member name new-names-list)))

commit 20feefe681e6c8a41f857b2c9f2414ba57fffff9
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Nov 26 13:27:29 2017 +0800

    REFACTOR:Centralise sign-reverse-list
    
    This allows us to centralise its account type list.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index d249411..51a4076 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -319,6 +319,28 @@ options specified in the Options panels."))
                    (cons 'text (N_ "Descending"))
                    (cons 'tip (N_ "Largest to smallest, latest to earliest."))))))
 
+(define sign-reverse-list
+  (list
+   (cons 'none
+         (list
+          (cons 'text (N_ "None"))
+          (cons 'tip (N_ "Don't change any displayed amounts."))
+          (cons 'acct-types '())))
+   (cons 'income-expense
+         (list
+          (cons 'text (N_ "Income and Expense"))
+          (cons 'tip (N_ "Reverse amount display for Income and Expense Accounts."))
+          (cons 'acct-types (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))))
+   (cons 'credit-accounts
+         (list
+          (cons 'text (N_ "Credit Accounts"))
+          (cons 'tip (N_ "Reverse amount display for Liability, Payable, Equity, \
+Credit Card, and Income accounts."))
+          (cons 'acct-types (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE
+                                  ACCT-TYPE-EQUITY ACCT-TYPE-CREDIT
+                                  ACCT-TYPE-INCOME))))))
+
+
 (define (keylist-get-info keylist key info)
   (cdr (assq info (cdr (assq key keylist)))))
 
@@ -461,13 +483,13 @@ tags within description, notes or memo. ")
 
   ;; Sorting options
 
-  (let ((ascending-choice-list (keylist->vectorlist ascending-list))        
+  (let ((ascending-choice-list (keylist->vectorlist ascending-list))
+        (key-choice-list (keylist->vectorlist sortkey-list))
+        (date-subtotal-choice-list (keylist->vectorlist date-subtotal-list))
         (prime-sortkey 'account-name)
         (prime-sortkey-subtotal-true #t)
         (sec-sortkey 'register-order)
-        (sec-sortkey-subtotal-true #f)
-        (key-choice-list (keylist->vectorlist sortkey-list))
-        (date-subtotal-choice-list (keylist->vectorlist date-subtotal-list)))
+        (sec-sortkey-subtotal-true #f))
 
     (define (apply-selectable-by-name-sorting-options)
       (let* ((prime-sortkey-enabled (not (eq? prime-sortkey 'none)))
@@ -740,16 +762,7 @@ tags within description, notes or memo. ")
       gnc:pagename-display (N_ "Sign Reverses")
       "m1" (N_ "Reverse amount display for certain account types.")
       'credit-accounts
-      (list (vector 'none
-                    (N_ "None")
-                    (N_ "Don't change any displayed amounts."))
-            (vector 'income-expense
-                    (N_ "Income and Expense")
-                    (N_ "Reverse amount display for Income and Expense Accounts."))
-            (vector 'credit-accounts
-                    (N_ "Credit Accounts")
-                    (N_ "Reverse amount display for Liability, Payable, Equity, \
-Credit Card, and Income accounts."))))))
+      (keylist->vectorlist sign-reverse-list))))
 
   (gnc:options-set-default-section options gnc:pagename-general)
   options)
@@ -853,12 +866,9 @@ Credit Card, and Income accounts."))))))
          (width (length headings))
          (width-amount (length amount-headings))
          (account-types-to-reverse
-          (case (opt-val gnc:pagename-display (N_ "Sign Reverses"))
-            ((none) '())
-            ((income-expense) (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))
-            ((credit-accounts)  (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE
-                                      ACCT-TYPE-EQUITY ACCT-TYPE-CREDIT
-                                      ACCT-TYPE-INCOME))))
+          (keylist-get-info sign-reverse-list
+                            (opt-val gnc:pagename-display (N_ "Sign Reverses"))
+                            'acct-types))
          (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
          (export? (opt-val gnc:pagename-general optname-table-export)))
 

commit 3b3c0322cf3020fa156ff9640e82405cdd29dbe4
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 21:49:17 2017 +0800

    ENH: add infobox to summarise options used

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 14f93b2..d249411 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -14,6 +14,8 @@
 ;; - add custom sorter in scheme
 ;; - common currency - optionally show original currency amount
 ;;   and enable multiple data columns
+;; - add informational box, summarising options used, useful
+;;   to troubleshoot reports
 ;;
 ;; This program is free software; you can redistribute it and/or    
 ;; modify it under the terms of the GNU General Public License as   
@@ -1466,6 +1468,82 @@ Credit Card, and Income accounts."))))))
       (generic-less? X Y 'date 'none #t))
 
 
+    ;; infobox
+    (define (infobox)
+      (define (highlight title . data)
+        (string-append "<b>" title "</b>: " (string-join data " ") "<br>"))
+      (define (bool->string tf)
+        (if tf
+            (_ "Enabled")
+            (_ "Disabled")))
+      (gnc:make-html-text
+       (if (string-null? account-matcher)
+           ""
+           (string-append
+            (highlight
+             (string-append optname-account-matcher
+                            (if (opt-val pagename-filter optname-account-matcher-regex)
+                                (N_ " regex")
+                                ""))
+             account-matcher)
+            (highlight
+             (N_ "Accounts produced")
+             (string-join (map xaccAccountGetName c_account_1) ", "))))
+       (if (eq? filter-mode 'none)
+           ""
+           (highlight
+            (keylist-get-info filter-list filter-mode 'text)
+            (string-join (map xaccAccountGetName c_account_2) ", ")))
+       (if (string-null? transaction-matcher)
+           ""
+           (string-append
+            (highlight
+             (string-append optname-transaction-matcher
+                            (if (opt-val pagename-filter optname-transaction-matcher-regex)
+                                (N_ " regex")
+                                ""))
+             transaction-matcher)))
+       (if reconcile-status-filter
+           (highlight
+            optname-reconcile-status
+            (keylist-get-info reconcile-status-list reconcile-status-filter 'text))
+           "")
+       (if (eq? void-status 'non-void-only)
+           ""
+           (highlight
+            optname-void-transactions
+            (keylist-get-info show-void-list void-status 'text)))
+       (if (eq? primary-key 'none)
+           ""
+           (highlight
+            optname-prime-sortkey
+            (keylist-get-info sortkey-list primary-key 'text)
+            (keylist-get-info ascending-list primary-order 'text)))
+       (if (eq? primary-key 'none)
+           ""
+           (if (member primary-key DATE-SORTING-TYPES)
+               (highlight
+                optname-prime-date-subtotal
+                (keylist-get-info date-subtotal-list primary-date-subtotal 'text))
+               (highlight
+                optname-prime-subtotal
+                (bool->string (opt-val pagename-sorting optname-prime-subtotal)))))
+       (if (eq? secondary-key 'none)
+           ""
+           (highlight
+            optname-sec-sortkey
+            (keylist-get-info sortkey-list secondary-key 'text)
+            (keylist-get-info ascending-list secondary-order 'text)))
+       (if (eq? secondary-key 'none)
+           ""
+           (if (member secondary-key DATE-SORTING-TYPES)
+               (highlight
+                optname-sec-date-subtotal
+                (keylist-get-info date-subtotal-list secondary-date-subtotal 'text))
+               (highlight
+                optname-sec-subtotal
+                (bool->string (opt-val pagename-sorting optname-sec-subtotal)))))
+       "<br>"))
 
     (if (or (null? c_account_1) (and-map not c_account_1))
 
@@ -1477,12 +1555,17 @@ Credit Card, and Income accounts."))))))
              (gnc:html-make-no-account-warning report-title (gnc:report-id report-obj)))
 
             ;; error condition: accounts were specified but none matched string/regex
-            (gnc:html-document-add-object!
-             document
-             (gnc:make-html-text
-              (gnc:html-markup-h2 NO-MATCHING-ACCT-HEADER)
-              (gnc:html-markup-p NO-MATCHING-ACCT-TEXT))))
+            (begin
+              (gnc:html-document-add-object!
+               document
+               (gnc:make-html-text
+                (gnc:html-markup-h2 NO-MATCHING-ACCT-HEADER)
+                (gnc:html-markup-p NO-MATCHING-ACCT-TEXT)))
 
+              (gnc:html-document-add-object!
+               document                 
+               (infobox))))
+            
         (begin
 
           (qof-query-set-book query (gnc-get-current-book))
@@ -1538,11 +1621,16 @@ Credit Card, and Income accounts."))))))
           (if (null? splits)
 
               ;; error condition: no splits found
-              (gnc:html-document-add-object!
-               document
-               (gnc:make-html-text
-                (gnc:html-markup-h2 NO-MATCHING-TRANS-HEADER)
-                (gnc:html-markup-p NO-MATCHING-TRANS-TEXT)))
+              (begin
+                (gnc:html-document-add-object!
+                 document
+                 (gnc:make-html-text
+                  (gnc:html-markup-h2 NO-MATCHING-TRANS-HEADER)
+                  (gnc:html-markup-p NO-MATCHING-TRANS-TEXT)))
+
+                (gnc:html-document-add-object!
+                 document
+                 (infobox)))
 
               (let ((table (make-split-table
                             splits options
@@ -1574,6 +1662,10 @@ Credit Card, and Income accounts."))))))
                             (gnc-print-date begindate)
                             (gnc-print-date enddate)))))
 
+                (gnc:html-document-add-object!
+                 document                 
+                 (infobox))
+
                 (gnc:html-document-add-object! document table)))))
 
     (gnc:report-finished)

commit ea416e16d526b79d9dc58031f34020563cb7ed2c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 15:14:21 2017 +0800

    REFACTOR: Centralize options

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index ee13b1b..14f93b2 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -211,9 +211,6 @@ options specified in the Options panels."))
                                    (cons 'renderer-key #f)))))
 
 
-(define (sortkey-get-info sortkey info)
-  (cdr (assq info (cdr (assq sortkey sortkey-list)))))
-
 (define (time64-year t64)    (gnc:date-get-year (gnc-localtime t64)))
 (define (time64-quarter t64) (+ (* 10 (gnc:date-get-year (gnc-localtime t64)))  (gnc:date-get-quarter (gnc-localtime t64))))
 (define (time64-month t64)   (+ (* 100 (gnc:date-get-year (gnc-localtime t64))) (gnc:date-get-month (gnc-localtime t64))))
@@ -261,8 +258,76 @@ options specified in the Options panels."))
                   (cons 'tip (N_ "Yearly."))
                   (cons 'renderer-key 'year)))))
 
-(define (date-subtotal-get-info sortkey info)
-  (cdr (assq info (cdr (assq sortkey date-subtotal-list)))))
+(define filter-list
+  (list
+   (cons 'none (list
+                (cons 'text (N_ "None"))
+                (cons 'tip (N_ "Do not do any filtering."))))
+
+   (cons 'include (list
+                   (cons 'text (N_ "Include Transactions to/from Filter Accounts"))
+                   (cons 'tip (N_ "Include transactions to/from filter accounts only."))))
+
+   (cons 'exclude (list
+                   (cons 'text (N_ "Exclude Transactions to/from Filter Accounts"))
+                   (cons 'tip (N_ "Exclude transactions to/from all filter accounts."))))))
+
+(define show-void-list
+  (list
+   (cons 'non-void-only (list
+                         (cons 'text (N_ "Non-void only"))
+                         (cons 'tip (N_ "Show only non-voided transactions."))))
+         
+   (cons 'void-only (list
+                     (cons 'text (N_ "Void only"))
+                     (cons 'tip (N_ "Show only voided transactions."))))
+   
+   (cons 'both (list
+                (cons 'text (N_ "Both"))
+                (cons 'tip (N_ "Show both (and include void transactions in totals)."))))))
+
+(define reconcile-status-list
+  ;; value will be either #f to disable reconciled-status filter
+  ;; or a list of xaccSplitGetReconcile values. e.g. value can
+  ;; be '(#\c #\y) to retrieve list of cleared and reconciled splits.
+  (list
+   (cons  #f (list
+              (cons 'text (N_ "All"))
+              (cons 'tip (N_ "Show All Transactions"))))
+
+   (cons '(#\n) (list
+                 (cons 'text (N_ "Unreconciled"))
+                 (cons 'tip (N_ "Unreconciled only"))))
+   
+   (cons '(#\c) (list
+                 (cons 'text (N_ "Cleared"))
+                 (cons 'tip (N_ "Cleared only"))))
+   
+   (cons '(#\y) (list
+                 (cons 'text (N_ "Reconciled"))
+                 (cons 'tip (N_ "Reconciled only"))))))
+
+
+(define ascending-list
+  (list
+   (cons 'ascend (list
+                  (cons 'text (N_ "Ascending"))
+                  (cons 'tip (N_ "Smallest to largest, earliest to latest."))))
+   (cons 'descend (list
+                   (cons 'text (N_ "Descending"))
+                   (cons 'tip (N_ "Largest to smallest, latest to earliest."))))))
+
+(define (keylist-get-info keylist key info)
+  (cdr (assq info (cdr (assq key keylist)))))
+
+(define (keylist->vectorlist keylist)
+  (map
+   (lambda (item)
+     (vector
+      (car item)
+      (keylist-get-info keylist (car item) 'text)
+      (keylist-get-info keylist (car item) 'tip)))
+   keylist))
 
 
 (define (trep-options-generator)
@@ -346,10 +411,7 @@ tags within description, notes or memo. ")
     pagename-filter optname-reconcile-status
     "j1" (N_ "Filter by reconcile status.")
     #f
-    (list (vector #f      (N_ "All")           (N_ "Show All Transactions"))
-          (vector '(#\n)  (N_ "Unreconciled")  (N_ "Unreconciled only"))
-          (vector '(#\c)  (N_ "Cleared")       (N_ "Cleared only"))
-          (vector '(#\y)  (N_ "Reconciled")    (N_ "Reconciled only")))))
+    (keylist->vectorlist reconcile-status-list)))
 
   ;; Accounts options
 
@@ -380,20 +442,12 @@ tags within description, notes or memo. ")
     gnc:pagename-accounts optname-filtertype
     "c" (N_ "Filter account.")
     'none
-    (list (vector 'none
-                  (N_ "None")
-                  (N_ "Do not do any filtering."))
-          (vector 'include
-                  (N_ "Include Transactions to/from Filter Accounts")
-                  (N_ "Include transactions to/from filter accounts only."))
-          (vector 'exclude
-                  (N_ "Exclude Transactions to/from Filter Accounts")
-                  (N_ "Exclude transactions to/from all filter accounts.")))
-   #f
-   (lambda (x)
-     (gnc-option-db-set-option-selectable-by-name
-      options gnc:pagename-accounts optname-filterby
-      (not (eq? x 'none))))))
+    (keylist->vectorlist filter-list)
+    #f
+    (lambda (x)
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-accounts optname-filterby
+       (not (eq? x 'none))))))
   ;;
 
   (gnc:register-trep-option
@@ -401,39 +455,17 @@ tags within description, notes or memo. ")
     gnc:pagename-accounts optname-void-transactions
     "d" (N_ "How to handle void transactions.")
     'non-void-only
-    (list
-     (vector 'non-void-only (N_ "Non-void only") (N_ "Show only non-voided transactions."))
-     (vector 'void-only     (N_ "Void only") (N_ "Show only voided transactions."))
-     (vector 'both          (N_ "Both") (N_ "Show both (and include void transactions in totals).")))))
+    (keylist->vectorlist show-void-list)))
 
   ;; Sorting options
-  
-
-  (let ((ascending-choice-list 
-         (list (vector 'ascend
-                       (N_ "Ascending")
-                       (N_ "Smallest to largest, earliest to latest."))
-               (vector 'descend
-                       (N_ "Descending")
-                       (N_ "Largest to smallest, latest to earliest."))))
+
+  (let ((ascending-choice-list (keylist->vectorlist ascending-list))        
         (prime-sortkey 'account-name)
         (prime-sortkey-subtotal-true #t)
         (sec-sortkey 'register-order)
-        (sec-sortkey-subtotal-true #f)       
-        (key-choice-list (map
-                          (lambda (sortpair)
-                            (vector
-                             (car sortpair)
-                             (sortkey-get-info (car sortpair) 'text)
-                             (sortkey-get-info (car sortpair) 'tip)))
-                          sortkey-list))
-        (date-subtotal-choice-list (map
-                                    (lambda (date-sortpair)
-                                      (vector
-                                       (car date-sortpair)
-                                       (date-subtotal-get-info (car date-sortpair) 'text)
-                                       (date-subtotal-get-info (car date-sortpair) 'tip)))
-                                    date-subtotal-list)))
+        (sec-sortkey-subtotal-true #f)
+        (key-choice-list (keylist->vectorlist sortkey-list))
+        (date-subtotal-choice-list (keylist->vectorlist date-subtotal-list)))
 
     (define (apply-selectable-by-name-sorting-options)
       (let* ((prime-sortkey-enabled (not (eq? prime-sortkey 'none)))
@@ -1314,14 +1346,14 @@ Credit Card, and Income accounts."))))))
           ;; If sorting by date, look up the value of the
           ;; date-subtotalling multichoice option and return the
           ;; corresponding funcs in the assoc-list.
-          (date-subtotal-get-info (opt-val pagename-sorting name-date-subtotal) info)
+          (keylist-get-info date-subtotal-list (opt-val pagename-sorting name-date-subtotal) info)
           ;; For everything else: 1. check whether sortkey has
           ;; subtotalling enabled at all, 2. check whether the
           ;; enable-subtotal boolean option is #t, 3. look up the
           ;; appropriate funcs in the assoc-list.
           (and (member sortkey SUBTOTAL-ENABLED)
                (and (opt-val pagename-sorting name-subtotal)
-                    (sortkey-get-info sortkey info))))))
+                    (keylist-get-info sortkey-list sortkey info))))))
 
   (define (is-filter-member split account-list)
     (let* ((txn (xaccSplitGetParent split))
@@ -1463,8 +1495,8 @@ Credit Card, and Income accounts."))))))
           (if (not custom-sort?)
               (begin
                 (qof-query-set-sort-order query
-                                          (sortkey-get-info primary-key 'sortkey)
-                                          (sortkey-get-info secondary-key 'sortkey)
+                                          (keylist-get-info sortkey-list primary-key 'sortkey)
+                                          (keylist-get-info sortkey-list secondary-key 'sortkey)
                                           '())
                 (qof-query-set-sort-increasing query
                                                (eq? primary-order 'ascend)

commit d9d4ffaff2fc888d26d59120d4a36d8c4523e545
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Nov 27 08:01:48 2017 +0800

    ENH: disable filter accounts selector if filter-mode=none

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index abcb03e..ee13b1b 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -370,13 +370,13 @@ tags within description, notes or memo. ")
   (gnc:register-trep-option
    (gnc:make-account-list-option
     gnc:pagename-accounts optname-filterby
-    "b" (N_ "Filter on these accounts.")
+    "c1" (N_ "Filter on these accounts.")
     (lambda ()
       '())
     #f #t))
 
   (gnc:register-trep-option
-   (gnc:make-multichoice-option
+   (gnc:make-multichoice-callback-option
     gnc:pagename-accounts optname-filtertype
     "c" (N_ "Filter account.")
     'none
@@ -388,7 +388,12 @@ tags within description, notes or memo. ")
                   (N_ "Include transactions to/from filter accounts only."))
           (vector 'exclude
                   (N_ "Exclude Transactions to/from Filter Accounts")
-                  (N_ "Exclude transactions to/from all filter accounts.")))))
+                  (N_ "Exclude transactions to/from all filter accounts.")))
+   #f
+   (lambda (x)
+     (gnc-option-db-set-option-selectable-by-name
+      options gnc:pagename-accounts optname-filterby
+      (not (eq? x 'none))))))
   ;;
 
   (gnc:register-trep-option

commit 8399ee65bda36dd66c76659ce0b327ca9b54c367
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 22:30:11 2017 +0800

    ENH: dual columns subtotals now in correct column
    
    This commit changes dual column subtotal strategy to limit
    to debit/credit columns handling only. Values are summed
    and the subtotal is displayed in the appropriate debit or
    credit column.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index dc8f7a7..abcb03e 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -855,9 +855,8 @@ Credit Card, and Income accounts."))))))
               (addto! row-contents (gnc:make-html-table-cell/size/markup 1 width "total-label-cell" string))))
 
         (define (add-columns commodity)
-          (let ((merging? #f)
-                (merging-subtotal (gnc:make-gnc-numeric 0 1))
-                (width 0))
+          (let ((start-dual-column? #f)
+                (dual-subtotal (gnc:make-gnc-numeric 0 1)))
             (for-each (lambda (column merge-entry)
                         (let* ((mon (retrieve-commodity column commodity))
                                (col (and mon (gnc:gnc-monetary-amount mon)))
@@ -868,30 +867,37 @@ Credit Card, and Income accounts."))))))
                               ;; and store total in dual-subtotal. Do NOT add column.
                               (begin
                                 (if column-amount
-                                    (set! merging-subtotal
-                                          (merge-fn merging-subtotal column-amount)))
-                                (set! merging? #t)
-                                (if col
-                                    (set! merging-subtotal
-                                          (merge-fn merging-subtotal col GNC-DENOM-AUTO GNC-RND-ROUND)))
-                                (set! width (+ width 1)))
-                              (if merging?
+                                    (set! dual-subtotal
+                                          (merge-fn dual-subtotal column-amount
+                                                    GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
+                                (set! start-dual-column? #t))
+                              (if start-dual-column?
                                   (begin
                                     ;; We've completed merging. Add this column amount
                                     ;; and add the columns.
-                                    (set! merging? #f)
-                                    (if col
-                                        (set! merging-subtotal
-                                              (merge-fn merging-subtotal column-amount)))
-                                    (set! width (+ width 1))
-                                    (addto! row-contents
-                                            (gnc:make-html-table-cell/size/markup
-                                             1 width "total-number-cell"
-                                             (gnc:make-gnc-monetary commodity merging-subtotal)))
-                                    (set! width 0)
-                                    (set! merging-subtotal (gnc:make-gnc-numeric 0 1)))
-                                  ;; Default; not merging/completed merge. Just
-                                  ;; display monetary amount
+                                    (if column-amount
+                                        (set! dual-subtotal
+                                              (merge-fn dual-subtotal column-amount
+                                                        GNC-DENOM-AUTO GNC-HOW-RND-ROUND)))
+                                    (if (gnc-numeric-positive-p dual-subtotal)
+                                        (begin
+                                          (addto! row-contents
+                                                  (gnc:make-html-table-cell/markup
+                                                   "total-number-cell"
+                                                   (gnc:make-gnc-monetary commodity dual-subtotal)))
+                                          (addto! row-contents ""))
+                                        (begin
+                                          (addto! row-contents "")
+                                          (addto! row-contents
+                                                  (gnc:make-html-table-cell/markup
+                                                   "total-number-cell"
+                                                   (gnc:make-gnc-monetary
+                                                    commodity
+                                                    (gnc-numeric-neg dual-subtotal))))))
+                                    (set! start-dual-column? #f)
+                                    (set! dual-subtotal (gnc:make-gnc-numeric 0 1)))
+				  ;; Default; not merging/completed merge. Just
+				  ;; display monetary amount
                                   (addto! row-contents
                                           (gnc:make-html-table-cell/markup "total-number-cell" mon))))))
                       columns
@@ -949,18 +955,18 @@ Credit Card, and Income accounts."))))))
            (running-balance (lambda (s) (gnc:make-gnc-monetary (currency s) (xaccSplitGetBalance s)))))
         (append
          ;; each column will be a vector
-         ;; (vector heading calculator-function reverse-column? subtotal? (vector merge? merging-function))
+         ;; (vector heading calculator-function reverse-column? subtotal? (vector start-dual-column? merging-function))
          ;; (calculator-function split) to obtain amount
          ;; reverse? to optionally reverse signs
          ;; subtotal? to allow subtotals (ie irrelevant for running balance)
          ;; merge? to merge with the next cell (ie for debit/credit cells)
-         ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to merging-subtotal
+         ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to dual-subtotal
          (if (column-uses? 'amount-single used-columns)
              (list (vector "Amount" amount #t #t (vector #f #f)))
              '())
          (if (column-uses? 'amount-double used-columns)
-             (list (vector "Debit" debit-amount #f #t (vector #t gnc-numeric-add-fixed))
-                   (vector "Credit" credit-amount #f #t (vector #f gnc-numeric-sub-fixed)))
+             (list (vector "Debit" debit-amount #f #t (vector #t gnc-numeric-add))
+                   (vector "Credit" credit-amount #f #t (vector #f gnc-numeric-sub)))
              '())
          (if (column-uses? 'amount-original-currency used-columns)
              (list (vector "Original" original-amount #t #t (vector #f #f)))

commit 521c16241ddfd2da11284d4646ff5d6d32b73c31
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Dec 11 23:48:13 2017 +0800

    REFACTOR: Use time64 instead of timepair

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 775aa46..dc8f7a7 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -214,14 +214,14 @@ options specified in the Options panels."))
 (define (sortkey-get-info sortkey info)
   (cdr (assq info (cdr (assq sortkey sortkey-list)))))
 
-(define (timepair-year tp)    (gnc:timepair-get-year tp))
-(define (timepair-quarter tp) (+ (* 10 (timepair-year tp))  (gnc:timepair-get-quarter tp)))
-(define (timepair-month tp)   (+ (* 100 (timepair-year tp)) (gnc:timepair-get-month tp)))
-(define (timepair-week tp)    (+ (* 100 (timepair-year tp)) (gnc:timepair-get-week tp)))
-(define (split-week a) (timepair-week (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
-(define (split-month a) (timepair-month (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
-(define (split-quarter a) (timepair-quarter (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
-(define (split-year a) (timepair-year (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
+(define (time64-year t64)    (gnc:date-get-year (gnc-localtime t64)))
+(define (time64-quarter t64) (+ (* 10 (gnc:date-get-year (gnc-localtime t64)))  (gnc:date-get-quarter (gnc-localtime t64))))
+(define (time64-month t64)   (+ (* 100 (gnc:date-get-year (gnc-localtime t64))) (gnc:date-get-month (gnc-localtime t64))))
+(define (time64-week t64)    (gnc:date-get-week (gnc-localtime t64)))
+(define (split-week a) (time64-week (xaccTransGetDate (xaccSplitGetParent a))))
+(define (split-month a) (time64-month (xaccTransGetDate (xaccSplitGetParent a))))
+(define (split-quarter a) (time64-quarter (xaccTransGetDate (xaccSplitGetParent a))))
+(define (split-year a) (time64-year (xaccTransGetDate (xaccSplitGetParent a))))
 
 (define date-subtotal-list
   ;; List for date option.
@@ -999,8 +999,8 @@ Credit Card, and Income accounts."))))))
          ((month) gnc:date-get-month-year-string)
          ((quarter) gnc:date-get-quarter-year-string)
          ((year) gnc:date-get-year-string))
-       (gnc:timepair->date
-        (gnc-transaction-get-date-posted
+       (gnc-localtime
+        (xaccTransGetDate
          (xaccSplitGetParent split)))))
 
     (define (render-account renderer-key split anchor?)
@@ -1055,17 +1055,17 @@ Credit Card, and Income accounts."))))))
                     (if transaction-row?
                         (gnc:make-html-table-cell/markup
                          "date-cell"
-                         (gnc-print-date (gnc-transaction-get-date-posted trans)))
+                         (qof-print-date (xaccTransGetDate trans)))
                         "")))
 
         (if (column-uses? 'reconciled-date used-columns)
             (addto! row-contents
                     (gnc:make-html-table-cell/markup
                      "date-cell"
-                     (let ((date (gnc-split-get-date-reconciled split)))
-                       (if (equal? date (cons 0 0))
+                     (let ((date (xaccSplitGetDateReconciled split)))
+                       (if (zero? date)
                            ""
-                           (gnc-print-date date))))))
+                           (qof-print-date date))))))
 
         (if (column-uses? 'num used-columns)
             (addto! row-contents

commit 1be88ad17584e048a21c3805bf59f4fdb6dd58e5
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 13:27:06 2017 +0800

    COSMETIC: Move Display>Sign reversal option

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 8a7a359..775aa46 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -699,7 +699,7 @@ tags within description, notes or memo. ")
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       gnc:pagename-display (N_ "Sign Reverses")
-      "p" (N_ "Reverse amount display for certain account types.")
+      "m1" (N_ "Reverse amount display for certain account types.")
       'credit-accounts
       (list (vector 'none
                     (N_ "None")

commit fa0bcf104a180fcc243ea8aea0d5accaf48fd20f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 13:23:36 2017 +0800

    ENH: Enable sign reversal for amount 'single only

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 365b937..8a7a359 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -574,7 +574,8 @@ tags within description, notes or memo. ")
   (let ((disp-memo? #t)
         (disp-accname? #t)
         (disp-other-accname? #f)
-        (is-single? #t))
+        (detail-is-single? #t)
+        (amount-is-single? #t))
 
     (define (apply-selectable-by-name-display-options)
       (gnc-option-db-set-option-selectable-by-name
@@ -583,15 +584,19 @@ tags within description, notes or memo. ")
 
       (gnc-option-db-set-option-selectable-by-name
        options gnc:pagename-display (N_ "Other Account Name")
-       is-single?)
+       detail-is-single?)
+
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-display (N_ "Sign Reverses")
+       amount-is-single?)
 
       (gnc-option-db-set-option-selectable-by-name
        options gnc:pagename-display (N_ "Use Full Other Account Name")
-       (and disp-other-accname? is-single?))
+       (and disp-other-accname? detail-is-single?))
 
       (gnc-option-db-set-option-selectable-by-name
        options gnc:pagename-display (N_ "Other Account Code")
-       is-single?)
+       detail-is-single?)
 
       (gnc-option-db-set-option-selectable-by-name
        options gnc:pagename-display (N_ "Notes")
@@ -674,18 +679,22 @@ tags within description, notes or memo. ")
                     (N_ "Display one line per transaction, merging multiple splits where required.")))
       #f
       (lambda (x)
-        (set! is-single? (eq? x 'single))
+        (set! detail-is-single? (eq? x 'single))
         (apply-selectable-by-name-display-options))))
 
     (gnc:register-trep-option
-     (gnc:make-multichoice-option
+     (gnc:make-multichoice-callback-option
       gnc:pagename-display (N_ "Amount")
       "m" (N_ "Display the amount?")
       'single
       (list
        (vector 'none   (N_ "None") (N_ "No amount display."))
        (vector 'single (N_ "Single") (N_ "Single Column Display."))
-       (vector 'double (N_ "Double") (N_ "Two Column Display.")))))
+       (vector 'double (N_ "Double") (N_ "Two Column Display.")))
+      #f
+      (lambda (x)
+        (set! amount-is-single? (eq? x 'single))
+        (apply-selectable-by-name-display-options))))
 
     (gnc:register-trep-option
      (gnc:make-multichoice-option
@@ -719,7 +728,7 @@ Credit Card, and Income accounts."))))))
   (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
 
   (define (build-columns-used)
-    (define is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single))
+    (define detail-is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single))
     (define amount-setting (opt-val gnc:pagename-display (N_ "Amount")))
     (list (cons 'date (opt-val gnc:pagename-display (N_ "Date")))
           (cons 'reconciled-date (opt-val gnc:pagename-display (N_ "Reconciled Date")))
@@ -728,7 +737,7 @@ Credit Card, and Income accounts."))))))
                          (opt-val gnc:pagename-display (N_ "Num"))))
           (cons 'description (opt-val gnc:pagename-display (N_ "Description")))
           (cons 'account-name (opt-val gnc:pagename-display (N_ "Account Name")))
-          (cons 'other-account-name (and is-single?
+          (cons 'other-account-name (and detail-is-single?
                                          (opt-val gnc:pagename-display (N_ "Other Account Name"))))
           (cons 'shares (opt-val gnc:pagename-display (N_ "Shares")))
           (cons 'price (opt-val gnc:pagename-display (N_ "Price")))
@@ -741,9 +750,9 @@ Credit Card, and Income accounts."))))))
           (cons 'account-full-name (opt-val gnc:pagename-display (N_ "Use Full Account Name")))
           (cons 'memo (opt-val gnc:pagename-display (N_ "Memo")))
           (cons 'account-code (opt-val gnc:pagename-display (N_ "Account Code")))
-          (cons 'other-account-code (and is-single?
+          (cons 'other-account-code (and detail-is-single?
                                          (opt-val gnc:pagename-display (N_ "Other Account Code"))))
-          (cons 'other-account-full-name (and is-single?
+          (cons 'other-account-full-name (and detail-is-single?
                                               (opt-val gnc:pagename-display (N_ "Use Full Other Account Name"))))
           (cons 'sort-account-code (opt-val pagename-sorting (N_ "Show Account Code")))
           (cons 'sort-account-full-name (opt-val pagename-sorting (N_ "Show Full Account Name")))
@@ -1029,7 +1038,8 @@ Credit Card, and Income accounts."))))))
 
     (define (add-split-row split cell-calculators row-style transaction-row?)
       (let* ((row-contents '())
-             (trans (xaccSplitGetParent split)))
+             (trans (xaccSplitGetParent split))
+             (account (xaccSplitGetAccount split)))
 
         (define cells
           (map (lambda (cell)
@@ -1092,7 +1102,7 @@ Credit Card, and Income accounts."))))))
                   (addto! row-contents memo))))
 
         (if (or (column-uses? 'account-name used-columns) (column-uses? 'account-code used-columns))
-            (addto! row-contents (account-namestring (xaccSplitGetAccount split)
+            (addto! row-contents (account-namestring account
                                                      (column-uses? 'account-code      used-columns)
                                                      (column-uses? 'account-name      used-columns)
                                                      (column-uses? 'account-full-name used-columns))))

commit db019ec51ed9e68e01df89357ba4c10320baad52
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 13:21:21 2017 +0800

    ENH: "Shares" column gets number-cell styling
    
    This commit enables styling for shares column which allows
    right-alignment of numeric amount.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 990d04d..365b937 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1104,7 +1104,9 @@ Credit Card, and Income accounts."))))))
                                                      (column-uses? 'other-account-full-name used-columns))))
 
         (if (column-uses? 'shares used-columns)
-            (addto! row-contents (xaccSplitGetAmount split)))
+            (addto! row-contents (gnc:make-html-table-cell/markup
+                                  "number-cell"
+                                  (xaccSplitGetAmount split))))
 
         (if (column-uses? 'price used-columns)
             (addto! row-contents

commit 1a886fac7d0d5cbb2b0de752f6732ad505851218
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Wed Dec 13 07:11:49 2017 +0800

    ENH: "Price" column gets number-cell styling.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 7214e9e..990d04d 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1107,8 +1107,11 @@ Credit Card, and Income accounts."))))))
             (addto! row-contents (xaccSplitGetAmount split)))
 
         (if (column-uses? 'price used-columns)
-            (addto! row-contents  (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
-                                                         (xaccSplitGetSharePrice split))))
+            (addto! row-contents
+                    (gnc:make-html-table-cell/markup
+                     "number-cell"
+                     (gnc:make-gnc-monetary (xaccTransGetCurrency trans)
+                                            (xaccSplitGetSharePrice split)))))
 
         (for-each (lambda (cell)
                     (let ((cell-content (vector-ref cell 0))

commit ef65f544aaaa58d859d278ef7987d70d9ea88fc0
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Dec 15 18:11:30 2017 +0800

    ENH: show original currency, and enable multicolumns.
    
    This commit optionally displays the original currency
    if 'common currency' is ticked. This will require
    refactoring to enable multicolumn data display and
    multiple collectors for subtotals.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 951caef..7214e9e 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -12,6 +12,8 @@
 ;; Refactored by Christopher Lam (2017)
 ;; - introduced account/transaction substring/regex matcher
 ;; - add custom sorter in scheme
+;; - common currency - optionally show original currency amount
+;;   and enable multiple data columns
 ;;
 ;; This program is free software; you can redistribute it and/or    
 ;; modify it under the terms of the GNU General Public License as   
@@ -78,6 +80,7 @@
 (define optname-enddate (N_ "End Date"))
 (define optname-table-export (N_ "Table for Exporting"))
 (define optname-common-currency (N_ "Common Currency"))
+(define optname-orig-currency (N_ "Show original currency amount"))
 (define optname-currency (N_ "Report's currency"))
 
 ;;Filtering
@@ -279,15 +282,25 @@ options specified in the Options panels."))
     gnc:pagename-general optname-common-currency
     "e" (N_ "Convert all transactions into a common currency.") #f
     #f
-    (lambda (x) (gnc-option-db-set-option-selectable-by-name
-                 options gnc:pagename-general optname-currency
-                 x))))
+    (lambda (x)
+      (begin
+        (gnc-option-db-set-option-selectable-by-name options
+                                                     gnc:pagename-general
+                                                     optname-currency x)
+        (gnc-option-db-set-option-selectable-by-name options
+                                                     gnc:pagename-general
+                                                     optname-orig-currency x)))))
 
   (gnc:options-add-currency!
    options gnc:pagename-general optname-currency "f")
 
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
+    gnc:pagename-general optname-orig-currency
+    "f1" (N_ "Also show original currency amounts") #f))
+
+  (gnc:register-trep-option
+   (gnc:make-simple-boolean-option
     gnc:pagename-general optname-table-export
     "g" (N_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))
 
@@ -721,6 +734,9 @@ Credit Card, and Income accounts."))))))
           (cons 'price (opt-val gnc:pagename-display (N_ "Price")))
           (cons 'amount-single (eq? amount-setting 'single))
           (cons 'amount-double (eq? amount-setting 'double))
+          (cons 'amount-original-currency
+                (and (opt-val gnc:pagename-general optname-common-currency)
+                     (opt-val gnc:pagename-general optname-orig-currency)))
           (cons 'running-balance (opt-val gnc:pagename-display (N_ "Running Balance")))
           (cons 'account-full-name (opt-val gnc:pagename-display (N_ "Use Full Account Name")))
           (cons 'memo (opt-val gnc:pagename-display (N_ "Memo")))
@@ -764,13 +780,19 @@ Credit Card, and Income accounts."))))))
      (add-if (column-uses? 'shares columns-used)
              (_ "Shares"))
      (add-if (column-uses? 'price columns-used)
-             (_ "Price"))
+             (_ "Price"))))
+
+  (define (make-amount-heading-list columns-used)
+    (define (add-if pred? . items) (if pred? items '()))
+    (append
      (add-if (column-uses? 'amount-single columns-used)
              (_ "Amount"))
      ;; FIXME: Proper labels: what?
      (add-if (column-uses? 'amount-double columns-used)
              (_ "Debit")
              (_ "Credit"))
+     (add-if (column-uses? 'amount-original-currency columns-used)
+             (_ "Original"))
      (add-if (column-uses? 'running-balance columns-used)
              (_ "Balance"))))
 
@@ -779,7 +801,9 @@ Credit Card, and Income accounts."))))))
          (table (gnc:make-html-table))
          (used-columns (build-columns-used))
          (headings (make-heading-list used-columns))
+         (amount-headings (make-amount-heading-list used-columns))
          (width (length headings))
+         (width-amount (length amount-headings))
          (account-types-to-reverse
           (case (opt-val gnc:pagename-display (N_ "Sign Reverses"))
             ((none) '())
@@ -792,39 +816,156 @@ Credit Card, and Income accounts."))))))
 
     (define (add-subheading data subheading-style)
       (let ((heading-cell (gnc:make-html-table-cell data)))
-        (gnc:html-table-cell-set-colspan! heading-cell width)
+        (gnc:html-table-cell-set-colspan! heading-cell (+ width width-amount))
         (gnc:html-table-append-row/markup!
          table subheading-style
          (list heading-cell))))
 
-    (define (add-subtotal-row string collector style)
-      (let ((currency-totals (collector 'format gnc:make-gnc-monetary #f)))
-        (gnc:html-table-append-row/markup!
-         table style 
-         (if export?
-             (append! (cons (gnc:make-html-table-cell/markup "total-label-cell" string)
-                            (gnc:html-make-empty-cells (- width 2)))
-                      (list (gnc:make-html-table-cell/markup 
-                             "total-number-cell"
-                             (car currency-totals))))
-             (list (gnc:make-html-table-cell/size/markup 1 (- width 1) "total-label-cell"
-                                                         string)
-                   (gnc:make-html-table-cell/markup 
-                    "total-number-cell"
-                    (car currency-totals)))))
-        (for-each (lambda (currency)
-                    (gnc:html-table-append-row/markup! 
-                     table style
-                     (append!
-                      (if export?
-                          (gnc:html-make-empty-cells (- width 1))
-                          (list (gnc:make-html-table-cell/size 1 (- width 1) #f)))
-                      (list (gnc:make-html-table-cell/markup
-                             "total-number-cell" currency)))))
-                  (cdr currency-totals))))
+
+    (define (add-subtotal-row subtotal-string subtotal-collectors-and-calculated-cells subtotal-style)
+      (let* ((row-contents '())
+             (subtotal-collectors (map car subtotal-collectors-and-calculated-cells))
+             (calculated-cells  (map cadr subtotal-collectors-and-calculated-cells))
+             (merge-list (map (lambda (cell) (vector-ref cell 4)) calculated-cells))
+             (columns (map (lambda (coll) (coll 'format gnc:make-gnc-monetary #f)) subtotal-collectors))
+             (list-of-commodities (delete-duplicates (map gnc:gnc-monetary-commodity (concatenate columns))
+                                                     gnc-commodity-equal)))
+
+        (define (retrieve-commodity list-of-monetary commodity)
+          (and (not (null? list-of-monetary))
+               (if (gnc-commodity-equal (gnc:gnc-monetary-commodity (car list-of-monetary)) commodity)
+                   (car list-of-monetary)
+                   (retrieve-commodity (cdr list-of-monetary) commodity))))
+
+        (define (add-first-column string)
+          (if export?
+              (begin
+                (addto! row-contents (gnc:make-html-table-cell/markup "total-label-cell" string))
+                (for-each (lambda (cell) (addto! row-contents cell))
+                          (gnc:html-make-empty-cells (- width 1))))
+              (addto! row-contents (gnc:make-html-table-cell/size/markup 1 width "total-label-cell" string))))
+
+        (define (add-columns commodity)
+          (let ((merging? #f)
+                (merging-subtotal (gnc:make-gnc-numeric 0 1))
+                (width 0))
+            (for-each (lambda (column merge-entry)
+                        (let* ((mon (retrieve-commodity column commodity))
+                               (col (and mon (gnc:gnc-monetary-amount mon)))
+                               (merge? (vector-ref merge-entry 0))
+                               (merge-fn (vector-ref merge-entry 1)))
+                          (if merge?
+                              ;; We're merging. Run merge-fn (usu gnc-numeric-add or sub)
+                              ;; and store total in dual-subtotal. Do NOT add column.
+                              (begin
+                                (if column-amount
+                                    (set! merging-subtotal
+                                          (merge-fn merging-subtotal column-amount)))
+                                (set! merging? #t)
+                                (if col
+                                    (set! merging-subtotal
+                                          (merge-fn merging-subtotal col GNC-DENOM-AUTO GNC-RND-ROUND)))
+                                (set! width (+ width 1)))
+                              (if merging?
+                                  (begin
+                                    ;; We've completed merging. Add this column amount
+                                    ;; and add the columns.
+                                    (set! merging? #f)
+                                    (if col
+                                        (set! merging-subtotal
+                                              (merge-fn merging-subtotal column-amount)))
+                                    (set! width (+ width 1))
+                                    (addto! row-contents
+                                            (gnc:make-html-table-cell/size/markup
+                                             1 width "total-number-cell"
+                                             (gnc:make-gnc-monetary commodity merging-subtotal)))
+                                    (set! width 0)
+                                    (set! merging-subtotal (gnc:make-gnc-numeric 0 1)))
+                                  ;; Default; not merging/completed merge. Just
+                                  ;; display monetary amount
+                                  (addto! row-contents
+                                          (gnc:make-html-table-cell/markup "total-number-cell" mon))))))
+                      columns
+                      merge-list)))
+
+        ;;first row
+        (add-first-column subtotal-string)
+        (add-columns (and (pair? list-of-commodities)
+                          (car list-of-commodities))) ;to account for empty-row subtotals
+        (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents))
+
+        ;;subsequent rows
+        (if (pair? list-of-commodities)
+            (for-each (lambda (commodity)
+                        (set! row-contents '())
+                        (add-first-column "")
+                        (add-columns commodity)
+                        (gnc:html-table-append-row/markup! table subtotal-style (reverse row-contents)))
+                      (cdr list-of-commodities)))))
 
     (define (total-string str) (string-append (_ "Total For ") str))
 
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;;
+    ;; calculated-cells
+    ;;
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    (define calculated-cells
+      (letrec
+          ((damount (lambda (s) (if (gnc:split-voided? s)
+                                    (xaccSplitVoidFormerAmount s)
+                                    (xaccSplitGetAmount s))))
+           (trans-date (lambda (s) (gnc-transaction-get-date-posted (xaccSplitGetTransaction s))))
+           (currency (lambda (s) (xaccAccountGetCommodity (xaccSplitGetAccount s))))
+           (report-currency (lambda (s) (if (opt-val gnc:pagename-general optname-common-currency)
+                                            (opt-val gnc:pagename-general optname-currency)
+                                            (currency s))))
+           (convert (lambda (s num)
+                      (gnc:exchange-by-pricedb-nearest
+                       (gnc:make-gnc-monetary (currency s) num)
+                       (report-currency s)
+                       ;; Use midday as the transaction time so it matches a price
+                       ;; on the same day.  Otherwise it uses midnight which will
+                       ;; likely match a price on the previous day
+                       (timespecCanonicalDayTime trans-date))))
+           (split-value (lambda (s) (convert s (damount s)))) ; used for correct debit/credit
+           (amount (lambda (s) (split-value s)))
+           (debit-amount (lambda (s) (and (gnc-numeric-positive-p (gnc:gnc-monetary-amount (split-value s)))
+                                          (split-value s))))
+           (credit-amount (lambda (s) (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount (split-value s)))
+                                          #f
+                                          (gnc:monetary-neg (split-value s)))))
+           (original-amount (lambda (s) (gnc:make-gnc-monetary (currency s) (damount s))))
+           (running-balance (lambda (s) (gnc:make-gnc-monetary (currency s) (xaccSplitGetBalance s)))))
+        (append
+         ;; each column will be a vector
+         ;; (vector heading calculator-function reverse-column? subtotal? (vector merge? merging-function))
+         ;; (calculator-function split) to obtain amount
+         ;; reverse? to optionally reverse signs
+         ;; subtotal? to allow subtotals (ie irrelevant for running balance)
+         ;; merge? to merge with the next cell (ie for debit/credit cells)
+         ;; merging-function - function (usually gnc-numeric-add/sub-fixed to apply to merging-subtotal
+         (if (column-uses? 'amount-single used-columns)
+             (list (vector "Amount" amount #t #t (vector #f #f)))
+             '())
+         (if (column-uses? 'amount-double used-columns)
+             (list (vector "Debit" debit-amount #f #t (vector #t gnc-numeric-add-fixed))
+                   (vector "Credit" credit-amount #f #t (vector #f gnc-numeric-sub-fixed)))
+             '())
+         (if (column-uses? 'amount-original-currency used-columns)
+             (list (vector "Original" original-amount #t #t (vector #f #f)))
+             '())
+         (if (column-uses? 'running-balance used-columns)
+             (list (vector "Running Balance" running-balance #t #f (vector #f #f)))
+             '()))))
+
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    ;; renderers
+
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
     ;; display an account name depending on the options the user has set
     (define (account-namestring account show-account-code? show-account-name? show-account-full-name?)
       ;;# on multi-line splits we can get an empty ('()) account
@@ -880,39 +1021,31 @@ Credit Card, and Income accounts."))))))
     (define (render-grand-total)
       (_ "Grand Total"))
 
-    (define (add-split-row split row-style transaction-row?)
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;;
+    ;; add-split-row
+    ;;
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+    (define (add-split-row split cell-calculators row-style transaction-row?)
       (let* ((row-contents '())
-             (parent (xaccSplitGetParent split))
-             (account (xaccSplitGetAccount split))
-             (account-type (xaccAccountGetType account))
-             (currency (if (null? account)
-                           (gnc-default-currency)
-                           (xaccAccountGetCommodity account)))
-             (report-currency (if (opt-val gnc:pagename-general optname-common-currency)
-                                  (opt-val gnc:pagename-general optname-currency)
-                                  currency))
-             (damount (if (gnc:split-voided? split)
-                          (xaccSplitVoidFormerAmount split)
-                          (xaccSplitGetAmount split)))
-             (trans-date (gnc-transaction-get-date-posted parent))
-             (split-value (gnc:exchange-by-pricedb-nearest
-                           (gnc:make-gnc-monetary
-                            currency
-                            (if (member account-type account-types-to-reverse)
-                                (gnc-numeric-neg damount)
-                                damount))
-                           report-currency
-                           ;; Use midday as the transaction time so it matches a price
-                           ;; on the same day.  Otherwise it uses midnight which will
-                           ;; likely match a price on the previous day
-                           (timespecCanonicalDayTime trans-date))))
+             (trans (xaccSplitGetParent split)))
+
+        (define cells
+          (map (lambda (cell)
+                 (let* ((calculator (vector-ref cell 1))
+                        (reverse? (vector-ref cell 2))
+                        (subtotal? (vector-ref cell 3))
+                        (calculated (calculator split)))
+                   (vector calculated reverse? subtotal?)))
+               cell-calculators))
 
         (if (column-uses? 'date used-columns)
             (addto! row-contents
                     (if transaction-row?
                         (gnc:make-html-table-cell/markup
                          "date-cell"
-                         (gnc-print-date trans-date))
+                         (gnc-print-date (gnc-transaction-get-date-posted trans)))
                         "")))
 
         (if (column-uses? 'reconciled-date used-columns)
@@ -928,19 +1061,20 @@ Credit Card, and Income accounts."))))))
             (addto! row-contents
                     (if transaction-row?
                         (if BOOK-SPLIT-ACTION
-                            (let* ((num (gnc-get-num-action parent split))
-                                   (t-num (if (if (gnc:lookup-option options gnc:pagename-display
+                            (let* ((num (gnc-get-num-action trans split))
+                                   (t-num (if (if (gnc:lookup-option options
+                                                                     gnc:pagename-display
                                                                      (N_ "Trans Number"))
                                                   (opt-val gnc:pagename-display (N_ "Trans Number"))
                                                   "")
-                                              (gnc-get-num-action parent #f)
+                                              (gnc-get-num-action trans #f)
                                               ""))
                                    (num-string (if (string-null? t-num)
                                                    num
                                                    (string-append num "/" t-num))))
                               (gnc:make-html-table-cell/markup "text-cell" num-string))
                             (gnc:make-html-table-cell/markup "text-cell"
-                                                             (gnc-get-num-action parent split)))
+                                                             (gnc-get-num-action trans split)))
                         "")))
 
         (if (column-uses? 'description used-columns)
@@ -948,17 +1082,17 @@ Credit Card, and Income accounts."))))))
                     (if transaction-row?
                         (gnc:make-html-table-cell/markup
                          "text-cell"
-                         (xaccTransGetDescription parent))
+                         (xaccTransGetDescription trans))
                         "")))
 
         (if (column-uses? 'memo used-columns)
             (let ((memo (xaccSplitGetMemo split)))
               (if (and (string-null? memo) (column-uses? 'notes used-columns))
-                  (addto! row-contents (xaccTransGetNotes parent))
+                  (addto! row-contents (xaccTransGetNotes trans))
                   (addto! row-contents memo))))
 
         (if (or (column-uses? 'account-name used-columns) (column-uses? 'account-code used-columns))
-            (addto! row-contents (account-namestring account
+            (addto! row-contents (account-namestring (xaccSplitGetAccount split)
                                                      (column-uses? 'account-code      used-columns)
                                                      (column-uses? 'account-name      used-columns)
                                                      (column-uses? 'account-full-name used-columns))))
@@ -976,51 +1110,47 @@ Credit Card, and Income accounts."))))))
             (addto! row-contents  (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
                                                          (xaccSplitGetSharePrice split))))
 
-        (if (column-uses? 'amount-single used-columns)
-            (addto! row-contents
-                    (gnc:make-html-table-cell/markup
-                     "number-cell" (gnc:html-transaction-anchor parent split-value))))
-
-        (if (column-uses? 'amount-double used-columns)
-
-            (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount split-value))
-
-                (begin
-                  (addto! row-contents
-                          (gnc:make-html-table-cell/markup
-                           "number-cell" (gnc:html-transaction-anchor
-                                          parent split-value)))
-                  (addto! row-contents ""))
-
-                (begin
-                  (addto! row-contents "")
-                  (addto! row-contents
-                          (gnc:make-html-table-cell/markup
-                           "number-cell" (gnc:html-transaction-anchor
-                                          parent (gnc:monetary-neg split-value)))))))
-
-        (if (column-uses? 'running-balance used-columns)
-            (begin
-              ;(gnc:debug "split is " split)
-              ;(gnc:debug "split get balance:" (xaccSplitGetBalance split))
-              (addto! row-contents
-                      (gnc:make-html-table-cell/markup
-                       "number-cell"
-                       (gnc:make-gnc-monetary currency
-                                              (xaccSplitGetBalance split))))))
+        (for-each (lambda (cell)
+                    (let ((cell-content (vector-ref cell 0))
+                          (reverse? (vector-ref cell 1))
+                          (reverse-amount (lambda (mon)
+                                            (let ((currency (gnc:gnc-monetary-commodity mon))
+                                                  (amount (gnc:gnc-monetary-amount mon)))
+                                              (gnc:make-gnc-monetary
+                                               currency
+                                               (gnc-numeric-neg amount))))))
+                      (if cell-content
+                          (addto! row-contents
+                                  (gnc:make-html-table-cell/markup
+                                   "number-cell"
+                                   (gnc:html-transaction-anchor
+                                    trans
+                                    (if (and reverse?
+                                             (member (xaccAccountGetType account) account-types-to-reverse))
+                                        (reverse-amount cell-content)
+                                        cell-content))))
+                          (addto! row-contents (gnc:html-make-empty-cell)))))
+                  cells)
 
         (gnc:html-table-append-row/markup! table row-style (reverse row-contents))
 
-        split-value))
+        (map (lambda (cell)
+               (let ((cell-content (vector-ref cell 0))
+                     (subtotal? (vector-ref cell 2)))
+                 (and subtotal? cell-content)))
+             cells)))
 
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+    ;; do-rows-with-subtotals
 
+    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
     (define (do-rows-with-subtotals splits
                                     odd-row?
-                                    primary-subtotal-collector
-                                    secondary-subtotal-collector
-                                    total-collector)
+                                    primary-subtotal-collectors
+                                    secondary-subtotal-collectors
+                                    total-collectors)
 
       (gnc:report-percent-done (* 100 (/ work-done work-to-do)))
 
@@ -1034,36 +1164,46 @@ Credit Card, and Income accounts."))))))
              table def:grand-total-style
              (list
               (gnc:make-html-table-cell/size
-               1 width (gnc:make-html-text (gnc:html-markup-hr)))))
+               1 (+ width width-amount) (gnc:make-html-text (gnc:html-markup-hr)))))
 
             (if (opt-val gnc:pagename-display "Totals")
-                (add-subtotal-row (render-grand-total) total-collector def:grand-total-style)))
+                (add-subtotal-row (render-grand-total) (zip total-collectors calculated-cells) def:grand-total-style)))
 
           (let* ((current (car splits))
                  (rest (cdr splits))
                  (next (if (null? rest) #f (car rest)))
-                 (split-value (add-split-row
-                               current
-                               (if is-multiline? def:normal-row-style
-                                   (if odd-row?
-                                       def:normal-row-style
-                                       def:alternate-row-style))
-                               #t)))
+                 (split-values (add-split-row
+                                current
+                                calculated-cells
+                                (if is-multiline? def:normal-row-style
+                                    (if odd-row?
+                                        def:normal-row-style
+                                        def:alternate-row-style))
+                                #t)))
 
             (if is-multiline?
                 (for-each
                  (lambda (othersplits)
-                   (add-split-row othersplits def:alternate-row-style #f))
+                   (add-split-row othersplits calculated-cells def:alternate-row-style #f))
                  (delete current (xaccTransGetSplitList (xaccSplitGetParent current)))))
 
-            (primary-subtotal-collector
-             'add (gnc:gnc-monetary-commodity split-value) (gnc:gnc-monetary-amount split-value))
+            (map (lambda (collector value)
+                   (if value
+                       (collector 'add (gnc:gnc-monetary-commodity value) (gnc:gnc-monetary-amount value))))
+                 primary-subtotal-collectors
+                 split-values)
 
-            (secondary-subtotal-collector
-             'add (gnc:gnc-monetary-commodity split-value) (gnc:gnc-monetary-amount split-value))
+            (map (lambda (collector value)
+                   (if value
+                       (collector 'add (gnc:gnc-monetary-commodity value) (gnc:gnc-monetary-amount value))))
+                 secondary-subtotal-collectors
+                 split-values)
 
-            (total-collector
-             'add (gnc:gnc-monetary-commodity split-value) (gnc:gnc-monetary-amount split-value))
+            (map (lambda (collector value)
+                   (if value
+                       (collector 'add (gnc:gnc-monetary-commodity value) (gnc:gnc-monetary-amount value))))
+                 total-collectors
+                 split-values)
 
             (if (and primary-subtotal-comparator
                      (or (not next)
@@ -1076,17 +1216,16 @@ Credit Card, and Income accounts."))))))
                       (begin
                         (add-subtotal-row (total-string
                                            (render-summary current secondary-renderer-key #f))
-                                          secondary-subtotal-collector
+                                          (zip secondary-subtotal-collectors calculated-cells)
                                           def:secondary-subtotal-style)
-                        
-                        (secondary-subtotal-collector 'reset #f #f)))
+                        (for-each (lambda (coll) (coll 'reset #f #f))
+                                  secondary-subtotal-collectors)))
                   (add-subtotal-row (total-string
                                      (render-summary current primary-renderer-key #f))
-                                    primary-subtotal-collector
+                                    (zip primary-subtotal-collectors calculated-cells)
                                     def:primary-subtotal-style)
-                  
-                  (primary-subtotal-collector 'reset #f #f)
-                  
+                  (for-each (lambda (coll) (coll 'reset #f #f))
+                            primary-subtotal-collectors)
                   (if next
                       (begin
                         (add-subheading (render-summary next primary-renderer-key #t)
@@ -1102,20 +1241,21 @@ Credit Card, and Income accounts."))))))
                                                (secondary-subtotal-comparator next))))))
                     (begin (add-subtotal-row (total-string
                                               (render-summary current secondary-renderer-key #f))
-                                             secondary-subtotal-collector
+                                             (zip secondary-subtotal-collectors calculated-cells)
                                              def:secondary-subtotal-style)
-                           (secondary-subtotal-collector 'reset #f #f)
+                           (for-each (lambda (coll) (coll 'reset #f #f))
+                                     secondary-subtotal-collectors)
                            (if next
                                (add-subheading (render-summary next secondary-renderer-key #t)
                                                def:secondary-subtotal-style)))))
 
             (do-rows-with-subtotals rest
                                     (not odd-row?)
-                                    primary-subtotal-collector
-                                    secondary-subtotal-collector
-                                    total-collector))))
+                                    primary-subtotal-collectors
+                                    secondary-subtotal-collectors
+                                    total-collectors))))
 
-    (gnc:html-table-set-col-headers! table headings)
+    (gnc:html-table-set-col-headers! table (concatenate (list headings amount-headings)))
 
     (if primary-renderer-key
         (add-subheading (render-summary (car splits) primary-renderer-key #t)
@@ -1126,9 +1266,9 @@ Credit Card, and Income accounts."))))))
                         def:secondary-subtotal-style))
 
     (do-rows-with-subtotals splits #t
-                            (gnc:make-commodity-collector)
-                            (gnc:make-commodity-collector)
-                            (gnc:make-commodity-collector))
+                            (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells)
+                            (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells)
+                            (map (lambda (x) (gnc:make-commodity-collector)) calculated-cells))
 
     table))
 

commit b549dd68fbab55f13fc4c91d7ff5dbe81c300400
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Dec 15 18:10:42 2017 +0800

    ENH: add custom sorter which can handle periodic dates

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index f5edb6e..951caef 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -11,6 +11,7 @@
 ;; <tpo_deb at sourcepole.ch> with a lot of help from "warlord"
 ;; Refactored by Christopher Lam (2017)
 ;; - introduced account/transaction substring/regex matcher
+;; - add custom sorter in scheme
 ;;
 ;; This program is free software; you can redistribute it and/or    
 ;; modify it under the terms of the GNU General Public License as   
@@ -1202,14 +1203,71 @@ Credit Card, and Income accounts."))))))
          (report-title (opt-val gnc:pagename-general gnc:optname-reportname))
          (primary-key (opt-val pagename-sorting optname-prime-sortkey))
          (primary-order (opt-val pagename-sorting optname-prime-sortorder))
+         (primary-date-subtotal (opt-val pagename-sorting optname-prime-date-subtotal))
          (secondary-key (opt-val pagename-sorting optname-sec-sortkey))
          (secondary-order (opt-val pagename-sorting optname-sec-sortorder))
+         (secondary-date-subtotal (opt-val pagename-sorting optname-sec-date-subtotal))
          (void-status (opt-val gnc:pagename-accounts optname-void-transactions))
          (splits '())
+         (custom-sort? (or (and (member primary-key DATE-SORTING-TYPES)   ; this will remain
+                                (not (eq? primary-date-subtotal 'none)))  ; until qof-query
+                           (and (member secondary-key DATE-SORTING-TYPES) ; is upgraded
+                                (not (eq? secondary-date-subtotal 'none)))))
          (query (qof-query-create-for-splits)))
 
-    ;;(gnc:warn "accts in trep-renderer:" c_account_1)
-    ;;(gnc:warn "Report Account names:" (get-other-account-names c_account_1))
+    (define (generic-less? X Y key date-subtotal ascend?)
+      (define comparator-function
+        (if (member key DATE-SORTING-TYPES)
+            (let* ((date (lambda (s)
+                           (case key
+                             ((date) (xaccTransGetDate (xaccSplitGetParent s)))
+                             ((reconciled-date) (xaccSplitGetDateReconciled s)))))
+                   (year    (lambda (s) (gnc:date-get-year (gnc-localtime (date s)))))
+                   (month   (lambda (s) (gnc:date-get-month (gnc-localtime (date s)))))
+                   (quarter (lambda (s) (gnc:date-get-quarter (gnc-localtime (date s)))))
+                   (week    (lambda (s) (gnc:date-get-week (gnc-localtime (date s)))))
+                   (secs    (lambda (s) (date s))))
+              (case date-subtotal
+                ((yearly)    (lambda (s) (year s)))
+                ((monthly)   (lambda (s) (+ (* 100 (year s)) (month s))))
+                ((quarterly) (lambda (s) (+ (*  10 (year s)) (quarter s))))
+                ((weekly)    (lambda (s) (week s)))
+                ((none)      (lambda (s) (secs s)))))
+            (case key
+              ((account-name) (lambda (s) (gnc-account-get-full-name (xaccSplitGetAccount s))))
+              ((account-code) (lambda (s) (xaccAccountGetCode (xaccSplitGetAccount s))))
+              ((corresponding-acc-name) (lambda (s) (xaccSplitGetCorrAccountFullName s)))
+              ((corresponding-acc-code) (lambda (s) (xaccSplitGetCorrAccountCode s)))
+              ((amount) (lambda (s) (gnc-numeric-to-double (xaccSplitGetValue s))))
+              ((description) (lambda (s) (xaccTransGetDescription (xaccSplitGetParent s))))
+              ((number) (lambda (s)
+                          (if BOOK-SPLIT-ACTION
+                              (xaccSplitGetAction s)
+                              (xaccTransGetNum (xaccSplitGetParent s)))))
+              ((t-number) (lambda (s) (xaccTransGetNum (xaccSplitGetParent s))))
+              ((register-order) (lambda (s) #f))
+              ((memo) (lambda (s) (xaccSplitGetMemo s)))
+              ((none) (lambda (s) #f)))))
+      (cond
+       ((string? (comparator-function X)) ((if ascend? string<? string>?) (comparator-function X) (comparator-function Y)))
+       ((comparator-function X)           ((if ascend? < >)               (comparator-function X) (comparator-function Y)))
+       (else                              #f)))
+
+    (define (primary-comparator? X Y)
+      (generic-less? X Y primary-key
+                     primary-date-subtotal
+                     (eq? primary-order 'ascend)))
+
+    (define (secondary-comparator? X Y)
+      (generic-less? X Y secondary-key
+                     secondary-date-subtotal
+                     (eq? secondary-order 'ascend)))
+
+    ;; This will, by default, sort the split list by ascending posted-date.
+    (define (date-comparator? X Y)
+      (generic-less? X Y 'date 'none #t))
+
+
 
     (if (or (null? c_account_1) (and-map not c_account_1))
 
@@ -1232,22 +1290,30 @@ Credit Card, and Income accounts."))))))
           (qof-query-set-book query (gnc-get-current-book))
           (xaccQueryAddAccountMatch query c_account_1 QOF-GUID-MATCH-ANY QOF-QUERY-AND)
           (xaccQueryAddDateMatchTS query #t begindate #t enddate QOF-QUERY-AND)
-          (qof-query-set-sort-order query
-                                    (sortkey-get-info primary-key 'sortkey)
-                                    (sortkey-get-info secondary-key 'sortkey)
-                                    '())
-          (qof-query-set-sort-increasing query
-                                         (eq? primary-order 'ascend)
-                                         (eq? secondary-order 'ascend)
-                                         #t)
           (case void-status
             ((non-void-only) (gnc:query-set-match-non-voids-only! query (gnc-get-current-book)))
             ((void-only)     (gnc:query-set-match-voids-only! query (gnc-get-current-book)))
             (else #f))
+          (if (not custom-sort?)
+              (begin
+                (qof-query-set-sort-order query
+                                          (sortkey-get-info primary-key 'sortkey)
+                                          (sortkey-get-info secondary-key 'sortkey)
+                                          '())
+                (qof-query-set-sort-increasing query
+                                               (eq? primary-order 'ascend)
+                                               (eq? secondary-order 'ascend)
+                                               #t)))
           (set! splits (qof-query-run query))
 
           (qof-query-destroy query)
 
+          (if custom-sort?
+              (begin
+                (set! splits (stable-sort! splits date-comparator?))
+                (set! splits (stable-sort! splits secondary-comparator?))
+                (set! splits (stable-sort! splits primary-comparator?))))
+
           ;; Combined Filter:
           ;; - include/exclude splits to/from selected accounts
           ;; - substring/regex matcher for Transaction Description/Notes/Memo

commit 4bfd01e70608ce39f3eddf0b65d59d3324cfc6ca
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 20:33:20 2017 +0800

    REFACTOR: simplify do-rows-with-subtotals to use fewer args

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 130b5ab..f5edb6e 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1016,19 +1016,7 @@ Credit Card, and Income accounts."))))))
 
 
     (define (do-rows-with-subtotals splits
-                                    table
-                                    used-columns
-                                    width
-                                    multi-rows?
                                     odd-row?
-                                    export?
-                                    account-types-to-reverse
-                                    primary-subtotal-pred
-                                    secondary-subtotal-pred
-                                    primary-subheading-renderer
-                                    secondary-subheading-renderer
-                                    primary-subtotal-renderer
-                                    secondary-subtotal-renderer
                                     primary-subtotal-collector
                                     secondary-subtotal-collector
                                     total-collector)
@@ -1052,55 +1040,38 @@ Credit Card, and Income accounts."))))))
 
           (let* ((current (car splits))
                  (rest (cdr splits))
-                 (next (if (null? rest) #f (car rest))))
-
-            (define split-value (add-split-row
-                                 table
-                                 current
-                                 used-columns
-                                 options
-                                 (if multi-rows? def:normal-row-style
-                                     (if odd-row?
-                                         def:normal-row-style
-                                         def:alternate-row-style))
-                                 account-types-to-reverse
-                                 #t))
-            
-            (if multi-rows?
-
-                (for-each (lambda (othersplits)
-                            (add-split-row table
-                                           othersplits
-                                           used-columns
-                                           options
-                                           def:alternate-row-style
-                                           account-types-to-reverse
-                                           #f))
-                          (delete current (xaccTransGetSplitList
-                                           (xaccSplitGetParent current)))))
-
-            (primary-subtotal-collector 'add
-                                        (gnc:gnc-monetary-commodity split-value) 
-                                        (gnc:gnc-monetary-amount split-value))
-
-            (secondary-subtotal-collector 'add
-                                          (gnc:gnc-monetary-commodity split-value)
-                                          (gnc:gnc-monetary-amount split-value))
-            
-            (total-collector 'add
-                             (gnc:gnc-monetary-commodity split-value)
-                             (gnc:gnc-monetary-amount split-value))
-            
-            (if (and primary-subtotal-pred
+                 (next (if (null? rest) #f (car rest)))
+                 (split-value (add-split-row
+                               current
+                               (if is-multiline? def:normal-row-style
+                                   (if odd-row?
+                                       def:normal-row-style
+                                       def:alternate-row-style))
+                               #t)))
+
+            (if is-multiline?
+                (for-each
+                 (lambda (othersplits)
+                   (add-split-row othersplits def:alternate-row-style #f))
+                 (delete current (xaccTransGetSplitList (xaccSplitGetParent current)))))
+
+            (primary-subtotal-collector
+             'add (gnc:gnc-monetary-commodity split-value) (gnc:gnc-monetary-amount split-value))
+
+            (secondary-subtotal-collector
+             'add (gnc:gnc-monetary-commodity split-value) (gnc:gnc-monetary-amount split-value))
+
+            (total-collector
+             'add (gnc:gnc-monetary-commodity split-value) (gnc:gnc-monetary-amount split-value))
+
+            (if (and primary-subtotal-comparator
                      (or (not next)
                          (and next
-                              (not (equal? (primary-subtotal-pred current)
-                                           (primary-subtotal-pred next))))))
+                              (not (equal? (primary-subtotal-comparator current)
+                                           (primary-subtotal-comparator next))))))
 
                 (begin
-
-                  (if secondary-subtotal-pred
-                      
+                  (if secondary-subtotal-comparator
                       (begin
                         (add-subtotal-row (total-string
                                            (render-summary current secondary-renderer-key #f))
@@ -1123,27 +1094,21 @@ Credit Card, and Income accounts."))))))
                             (add-subheading (render-summary next secondary-renderer-key #t)
                                             def:secondary-subtotal-style)))))
 
-                (if (and secondary-subtotal-pred
+                (if (and secondary-subtotal-comparator
                          (or (not next)
                              (and next
-                                  (not (equal? (secondary-subtotal-pred current)
-                                               (secondary-subtotal-pred next))))))
+                                  (not (equal? (secondary-subtotal-comparator current)
+                                               (secondary-subtotal-comparator next))))))
                     (begin (add-subtotal-row (total-string
                                               (render-summary current secondary-renderer-key #f))
                                              secondary-subtotal-collector
                                              def:secondary-subtotal-style)
-                           
                            (secondary-subtotal-collector 'reset #f #f)
-                           
                            (if next
                                (add-subheading (render-summary next secondary-renderer-key #t)
                                                def:secondary-subtotal-style)))))
 
             (do-rows-with-subtotals rest
-                                    table
-                                    used-columns
-                                    width
-                                    multi-rows?
                                     (not odd-row?)
                                     primary-subtotal-collector
                                     secondary-subtotal-collector

commit c7f9fb1a3aa5eaf1a2bb8e1810a399e97ae6291c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Dec 15 17:43:49 2017 +0800

    REFACTOR: use scheme idioms

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index db12bef..130b5ab 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1213,9 +1213,8 @@ Credit Card, and Income accounts."))))))
 
   (let* ((document (gnc:make-html-document))
          (account-matcher (opt-val pagename-filter optname-account-matcher))
-         (account-matcher-regexp (if (opt-val pagename-filter optname-account-matcher-regex)
-                                     (make-regexp account-matcher)
-                                     #f))
+         (account-matcher-regexp (and (opt-val pagename-filter optname-account-matcher-regex)
+                                      (make-regexp account-matcher)))
          (c_account_0 (opt-val gnc:pagename-accounts optname-accounts))
          (c_account_1 (filter
                        (lambda (acc)
@@ -1232,9 +1231,8 @@ Credit Card, and Income accounts."))))))
                    (gnc:date-option-absolute-time
                     (opt-val gnc:pagename-general optname-enddate))))
          (transaction-matcher (opt-val pagename-filter optname-transaction-matcher))
-         (transaction-matcher-regexp (if (opt-val pagename-filter optname-transaction-matcher-regex)
-                                         (make-regexp transaction-matcher)
-                                         #f))
+         (transaction-matcher-regexp (and (opt-val pagename-filter optname-transaction-matcher-regex)
+                                          (make-regexp transaction-matcher)))
          (reconcile-status-filter (opt-val pagename-filter optname-reconcile-status))
          (report-title (opt-val gnc:pagename-general gnc:optname-reportname))
          (primary-key (opt-val pagename-sorting optname-prime-sortkey))
@@ -1296,8 +1294,10 @@ Credit Card, and Income accounts."))))))
                                            (if transaction-matcher-regexp
                                                (regexp-exec transaction-matcher-regexp str)
                                                (string-contains str transaction-matcher)))))
-                            (and (if (eq? filter-mode 'include) (is-filter-member split c_account_2) #t)
-                                 (if (eq? filter-mode 'exclude) (not (is-filter-member split c_account_2)) #t)
+                            (and (case filter-mode
+                                   ((none) #t)
+                                   ((include) (is-filter-member split c_account_2))
+                                   ((exclude) (not (is-filter-member split c_account_2))))
                                  (or (string-null? transaction-matcher) ; null-string = ignore filters
                                      (match? (xaccTransGetDescription trans))
                                      (match? (xaccTransGetNotes trans))

commit 68aa61a37cb6ff652ebdee079e892f0d23036350
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Dec 15 17:42:58 2017 +0800

    REFACTOR: Simplify Trans Number handling
    
    Previously there was a check for the presence of "Trans Number".
    But if 'use-split-action' the options will always contain
    the toggle 'Trans Number'. Therefore remove unnecessary check.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 31674a6..db12bef 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -745,9 +745,7 @@ Credit Card, and Income accounts."))))))
              (_ "Reconciled Date"))
      (add-if (column-uses? 'num columns-used)
              (if (and (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-                      (if (gnc:lookup-option options gnc:pagename-display (N_ "Trans Number"))
-                          (opt-val gnc:pagename-display (N_ "Trans Number"))
-                          #f))
+                      (opt-val gnc:pagename-display (N_ "Trans Number")))
                  (_ "Num/T-Num")
                  (_ "Num")))
      (add-if (column-uses? 'description columns-used)

commit 8044f2b04e064fd1b799773f9a0340f10fcd87e1
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 20:30:02 2017 +0800

    COSMETIC:Rename subtitles -> subheadings in sorting/account display

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index ff510d5..31674a6 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -478,14 +478,14 @@ tags within description, notes or memo. ")
      (gnc:make-simple-boolean-option
       pagename-sorting optname-full-account-name
       "j1"
-      (N_ "Show the full account name for subtotals and subtitles?")
+      (N_ "Show the full account name for subtotals and subheadings?")
       #f))
 
     (gnc:register-trep-option
      (gnc:make-simple-boolean-option
       pagename-sorting optname-show-account-code
       "j2"
-      (N_ "Show the account code for subtotals and subtitles?")
+      (N_ "Show the account code for subtotals and subheadings?")
       #f))
 
     (gnc:register-trep-option

commit b6c6906bb10df1aaa69ddbbc7687af19def156e1
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 20:18:31 2017 +0800

    REFACTOR: initialize accounts/filter by to null list

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 7cfe8ca..ff510d5 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -358,14 +358,7 @@ tags within description, notes or memo. ")
     gnc:pagename-accounts optname-filterby
     "b" (N_ "Filter on these accounts.")
     (lambda ()
-      ;; FIXME : gnc:get-current-accounts disappeared.
-      (let* ((current-accounts '())
-             (root (gnc-get-current-root-account))
-             (num-accounts (gnc-account-n-children root))
-             (first-account (gnc-account-nth-child root 0)))
-        (cond ((not (null? current-accounts)) (list (car current-accounts)))
-              ((positive? num-accounts) (list first-account))
-              (else '()))))
+      '())
     #f #t))
 
   (gnc:register-trep-option

commit 8e4d72b5444b98dba027e6fd5ca90fd5c7574c54
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 20:17:09 2017 +0800

    REFACTOR: rewrite renderers to lookup 'renderer-key from sortlists

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index e6ef525..7cfe8ca 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -111,101 +111,100 @@ options specified in the Options panels."))
                                'account-code 'corresponding-acc-code))
 
 
-
 (define sortkey-list
   ;;
-  ;; Defines the different sorting keys, as an association-list 
-  ;; together with the subtotal functions. Each entry: 
+  ;; Defines the different sorting keys, as an association-list
+  ;; together with the subtotal functions. Each entry:
   ;;  'sortkey             - sort parameter sent via qof-query
   ;;  'split-sortvalue     - function which retrieves number/string used for comparing splits
   ;;  'text                - text displayed in Display tab
   ;;  'tip                 - tooltip displayed in Display tab
-  ;;  'renderer            - helper symbol to select subtotal/subheading renderer
+  ;;  'renderer-key        - helper symbol to select subtotal/subheading renderer
   ;;
   (list (cons 'account-name  (list (cons 'sortkey (list SPLIT-ACCT-FULLNAME))
                                    (cons 'split-sortvalue (lambda (a) (gnc-account-get-full-name (xaccSplitGetAccount a))))
                                    (cons 'text (N_ "Account Name"))
                                    (cons 'tip (N_ "Sort & subtotal by account name."))
-                                   (cons 'renderer 'account)))
-        
+                                   (cons 'renderer-key 'account)))
+
         (cons 'account-code (list (cons 'sortkey (list SPLIT-ACCOUNT ACCOUNT-CODE-))
                                   (cons 'split-sortvalue (lambda (a) (xaccAccountGetCode (xaccSplitGetAccount a))))
                                   (cons 'text (N_ "Account Code"))
                                   (cons 'tip (N_ "Sort & subtotal by account code."))
-                                  (cons 'renderer 'account)))
+                                  (cons 'renderer-key 'account)))
 
         (cons 'date         (list (cons 'sortkey (list SPLIT-TRANS TRANS-DATE-POSTED))
                                   (cons 'split-sortvalue #f)
                                   (cons 'text (N_ "Date"))
                                   (cons 'tip (N_ "Sort by date."))
-                                  (cons 'renderer #f)))
+                                  (cons 'renderer-key #f)))
 
         (cons 'reconciled-date (list (cons 'sortkey (list SPLIT-DATE-RECONCILED))
                                      (cons 'split-sortvalue #f)
                                      (cons 'text (N_ "Reconciled Date"))
                                      (cons 'tip (N_ "Sort by the Reconciled Date."))
-                                     (cons 'renderer #f)))
+                                     (cons 'renderer-key #f)))
 
         (cons 'register-order (list (cons 'sortkey (list QUERY-DEFAULT-SORT))
                                     (cons 'split-sortvalue #f)
                                     (cons 'text (N_ "Register Order"))
                                     (cons 'tip (N_ "Sort as in the register."))
-                                    (cons 'renderer #f)))                                 
+                                    (cons 'renderer-key #f)))
 
         (cons 'corresponding-acc-name (list (cons 'sortkey (list SPLIT-CORR-ACCT-NAME))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountFullName a)))
                                             (cons 'text (N_ "Other Account Name"))
                                             (cons 'tip (N_ "Sort by account transferred from/to's name."))
-                                            (cons 'renderer 'other-acc)))
+                                            (cons 'renderer-key 'other-acc)))
 
         (cons 'corresponding-acc-code (list (cons 'sortkey (list SPLIT-CORR-ACCT-CODE))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountCode a)))
                                             (cons 'text (N_ "Other Account Code"))
                                             (cons 'tip (N_ "Sort by account transferred from/to's code."))
-                                            (cons 'renderer 'other-acct)))
+                                            (cons 'renderer-key 'other-acct)))
 
         (cons 'amount        (list (cons 'sortkey (list SPLIT-VALUE))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Amount"))
                                    (cons 'tip (N_ "Sort by amount."))
-                                   (cons 'renderer #f)))
+                                   (cons 'renderer-key #f)))
 
         (cons 'description   (list (cons 'sortkey (list SPLIT-TRANS TRANS-DESCRIPTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Description"))
                                    (cons 'tip (N_ "Sort by description."))
-                                   (cons 'renderer #f)))
+                                   (cons 'renderer-key #f)))
 
         (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
             (cons 'number    (list (cons 'sortkey (list SPLIT-ACTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Number/Action"))
                                    (cons 'tip (N_ "Sort by check number/action."))
-                                   (cons 'renderer #f)))
+                                   (cons 'renderer-key #f)))
 
             (cons 'number    (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Number"))
                                    (cons 'tip (N_ "Sort by check/transaction number."))
-                                   (cons 'renderer #f))))
+                                   (cons 'renderer-key #f))))
 
         (cons 't-number      (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Transaction Number"))
                                    (cons 'tip (N_ "Sort by transaction number."))
-                                   (cons 'renderer #f)))
+                                   (cons 'renderer-key #f)))
 
         (cons 'memo          (list (cons 'sortkey (list SPLIT-MEMO))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Memo"))
                                    (cons 'tip (N_ "Sort by memo."))
-                                   (cons 'renderer #f)))
+                                   (cons 'renderer-key #f)))
 
         (cons 'none          (list (cons 'sortkey '())
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "None"))
                                    (cons 'tip (N_ "Do not sort."))
-                                   (cons 'renderer #f)))))
+                                   (cons 'renderer-key #f)))))
 
 
 (define (sortkey-get-info sortkey info)
@@ -221,40 +220,42 @@ options specified in the Options panels."))
 (define (split-year a) (timepair-year (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
 
 (define date-subtotal-list
-  ;; Extra list for date option. Each entry: (cons
-  ;; 'date-subtotal-option-value (vector subtotal-function
-  ;; subtotal-renderer))
+  ;; List for date option.
+  ;; Defines the different date sorting keys, as an association-list. Each entry:
+  ;;  'split-sortvalue     - function which retrieves number/string used for comparing splits
+  ;;  'text                - text displayed in Display tab
+  ;;  'tip                 - tooltip displayed in Display tab
+  ;;  'renderer-key        - helper symbol to select subtotal/subheading renderer
   (list
    (cons 'none (list
                 (cons 'split-sortvalue #f)
                 (cons 'text (N_ "None"))
                 (cons 'tip (N_ "None."))
-                (cons 'subheading-renderer #f)
-                (cons 'subtotal-renderer #f)))
+                (cons 'renderer-key #f)))
+
    (cons 'weekly (list
                   (cons 'split-sortvalue split-week)
                   (cons 'text (N_ "Weekly"))
                   (cons 'tip (N_ "Weekly."))
-                  (cons 'subheading-renderer render-week-subheading)
-                  (cons 'subtotal-renderer render-week-subtotal)))
+                  (cons 'renderer-key 'week)))
+
    (cons 'monthly (list
                    (cons 'split-sortvalue split-month)
                    (cons 'text (N_ "Monthly"))
                    (cons 'tip (N_ "Monthly."))
-                   (cons 'subheading-renderer render-month-subheading)
-                   (cons 'subtotal-renderer render-month-subtotal)))
+                   (cons 'renderer-key 'month)))
+
    (cons 'quarterly (list
                      (cons 'split-sortvalue split-quarter)
                      (cons 'text (N_ "Quarterly"))
                      (cons 'tip (N_ "Quarterly."))
-                     (cons 'subheading-renderer render-quarter-subheading)
-                     (cons 'subtotal-renderer render-quarter-subtotal)))
+                     (cons 'renderer-key 'quarter)))
+
    (cons 'yearly (list
                   (cons 'split-sortvalue split-year)
                   (cons 'text (N_ "Yearly"))
                   (cons 'tip (N_ "Yearly."))
-                  (cons 'subheading-renderer render-year-subheading)
-                  (cons 'subtotal-renderer render-year-subtotal)))))
+                  (cons 'renderer-key 'year)))))
 
 (define (date-subtotal-get-info sortkey info)
   (cdr (assq info (cdr (assq sortkey date-subtotal-list)))))
@@ -702,12 +703,10 @@ Credit Card, and Income accounts."))))))
 ;; Here comes the big function that builds the whole table.
 
 (define (make-split-table splits options
-                          primary-subtotal-pred
-                          secondary-subtotal-pred
-                          primary-subheading-renderer
-                          secondary-subheading-renderer
-                          primary-subtotal-renderer
-                          secondary-subtotal-renderer)
+                          primary-subtotal-comparator
+                          secondary-subtotal-comparator
+                          primary-renderer-key
+                          secondary-renderer-key)
 
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
   (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
@@ -852,81 +851,16 @@ Credit Card, and Income accounts."))))))
                    (xaccAccountGetName account))
                ""))))
 
-    ;; render an account subheading - used-columns determines what is displayed
-    (define (render-account-subheading split)
-      (let ((account (xaccSplitGetAccount split)))
-        (gnc:make-html-text
-         (gnc:html-markup-anchor
-          (gnc:account-anchor-text account)
-          (account-namestring account
-                              (column-uses? 'sort-account-code      used-columns)
-                              #t
-                              (column-uses? 'sort-account-full-name used-columns))))))                        
-
-    (define (render-corresponding-account-subheading split)
-      (let ((account (xaccSplitGetAccount (xaccSplitGetOtherSplit split))))
-        (gnc:make-html-text
-         (gnc:html-markup-anchor
-          (if (null? account)
-              ""
-              (gnc:account-anchor-text account))
-          (account-namestring account
-                              (column-uses? 'sort-account-code      used-columns)
-                              #t
-                              (column-uses? 'sort-account-full-name used-columns))))))
-
-    (define (render-week-subheading split)
-      (gnc:date-get-week-year-string
-       (gnc:timepair->date
-        (gnc-transaction-get-date-posted
-         (xaccSplitGetParent split)))))
-
-    (define (render-month-subheading split)
-      (gnc:date-get-month-year-string
-       (gnc:timepair->date
-        (gnc-transaction-get-date-posted
-         (xaccSplitGetParent split)))))
-
-    (define (render-quarter-subheading split)
-      (gnc:date-get-quarter-year-string
+    (define (render-date renderer-key split)
+      ((case renderer-key
+         ((week) gnc:date-get-week-year-string)
+         ((month) gnc:date-get-month-year-string)
+         ((quarter) gnc:date-get-quarter-year-string)
+         ((year) gnc:date-get-year-string))
        (gnc:timepair->date
         (gnc-transaction-get-date-posted
          (xaccSplitGetParent split)))))
 
-
-    (define (render-year-subheading split)
-      (gnc:date-get-year-string
-       (gnc:timepair->date
-        (gnc-transaction-get-date-posted
-         (xaccSplitGetParent split)))))
-
-    (define (render-account-subtotal split)
-      (account-namestring (xaccSplitGetAccount split)
-                          (column-uses? 'sort-account-code      used-columns)
-                          #t
-                          (column-uses? 'sort-account-full-name used-columns)))
-
-    (define (render-corresponding-account-subtotal split)
-      (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
-                          (column-uses? 'sort-account-code      used-columns)
-                          #t
-                          (column-uses? 'sort-account-full-name used-columns)))
-
-    (define (render-week-subtotal split)
-      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
-        (gnc:date-get-week-year-string tm)))
-
-    (define (render-month-subtotal split)
-      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
-        (gnc:date-get-month-year-string tm)))
-
-    (define (render-quarter-subtotal split)
-      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
-        (gnc:date-get-quarter-year-string tm)))
-
-    (define (render-year-subtotal split)
-      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
-        (strftime "%Y" tm)))
     (define (render-account renderer-key split anchor?)
       (let* ((account (case renderer-key
                         ((account) (xaccSplitGetAccount split))
@@ -954,29 +888,7 @@ Credit Card, and Income accounts."))))))
     (define (render-grand-total)
       (_ "Grand Total"))
 
-    (define (subheading-renderer split key)
-      ((case key
-         ((week)      render-week-subheading)
-         ((month)     render-month-subheading)
-         ((quarter)   render-quarter-subheading)
-         ((year)      render-year-subheading)
-         ((account)   render-account-subheading)
-         ((other-acc) render-corresponding-account-subheading))
-       split))
-
-    (define (subtotal-renderer split key)
-      ((case key
-         ((week)      render-week-subtotal)
-         ((month)     render-month-subtotal)
-         ((quarter)   render-quarter-subtotal)
-         ((year)      render-year-subtotal)
-         ((account)   render-account-subtotal)
-         ((other-acc) render-corresponding-account-subtotal))
-       split))
-
-
     (define (add-split-row split row-style transaction-row?)
-
       (let* ((row-contents '())
              (parent (xaccSplitGetParent split))
              (account (xaccSplitGetAccount split))
@@ -1199,28 +1111,25 @@ Credit Card, and Income accounts."))))))
                   (if secondary-subtotal-pred
                       
                       (begin
-                        
-                        (add-subtotal-row (secondary-subtotal-renderer current used-columns)
+                        (add-subtotal-row (total-string
+                                           (render-summary current secondary-renderer-key #f))
                                           secondary-subtotal-collector
                                           def:secondary-subtotal-style)
                         
                         (secondary-subtotal-collector 'reset #f #f)))
-                  
-                  (add-subtotal-row (primary-subtotal-renderer current used-columns)
+                  (add-subtotal-row (total-string
+                                     (render-summary current primary-renderer-key #f))
                                     primary-subtotal-collector
                                     def:primary-subtotal-style)
                   
                   (primary-subtotal-collector 'reset #f #f)
                   
                   (if next
-
                       (begin
-
-                        (add-subheading (primary-subheading-renderer next used-columns)
+                        (add-subheading (render-summary next primary-renderer-key #t)
                                         def:primary-subtotal-style)
-
-                        (if secondary-subtotal-pred
-                            (add-subheading (secondary-subheading-renderer next used-columns)
+                        (if secondary-subtotal-comparator
+                            (add-subheading (render-summary next secondary-renderer-key #t)
                                             def:secondary-subtotal-style)))))
 
                 (if (and secondary-subtotal-pred
@@ -1228,15 +1137,15 @@ Credit Card, and Income accounts."))))))
                              (and next
                                   (not (equal? (secondary-subtotal-pred current)
                                                (secondary-subtotal-pred next))))))
-                    
-                    (begin (add-subtotal-row (secondary-subtotal-renderer current used-columns)
+                    (begin (add-subtotal-row (total-string
+                                              (render-summary current secondary-renderer-key #f))
                                              secondary-subtotal-collector
                                              def:secondary-subtotal-style)
                            
                            (secondary-subtotal-collector 'reset #f #f)
                            
                            (if next
-                               (add-subheading (secondary-subheading-renderer next used-columns)
+                               (add-subheading (render-summary next secondary-renderer-key #t)
                                                def:secondary-subtotal-style)))))
 
             (do-rows-with-subtotals rest
@@ -1245,38 +1154,21 @@ Credit Card, and Income accounts."))))))
                                     width
                                     multi-rows?
                                     (not odd-row?)
-                                    export?
-                                    account-types-to-reverse
-                                    primary-subtotal-pred
-                                    secondary-subtotal-pred
-                                    primary-subheading-renderer
-                                    secondary-subheading-renderer
-                                    primary-subtotal-renderer
-                                    secondary-subtotal-renderer
                                     primary-subtotal-collector
                                     secondary-subtotal-collector
                                     total-collector))))
 
     (gnc:html-table-set-col-headers! table headings)
 
-    (if primary-subheading-renderer
-        (add-subheading (primary-subheading-renderer (car splits) used-columns)
+    (if primary-renderer-key
+        (add-subheading (render-summary (car splits) primary-renderer-key #t)
                         def:primary-subtotal-style))
 
-    (if secondary-subheading-renderer
-        (add-subheading (secondary-subheading-renderer (car splits) used-columns)
+    (if secondary-renderer-key
+        (add-subheading (render-summary (car splits) secondary-renderer-key #t)
                         def:secondary-subtotal-style))
 
-    (do-rows-with-subtotals splits table used-columns width
-                            is-multiline? #t
-                            export?
-                            account-types-to-reverse
-                            primary-subtotal-pred
-                            secondary-subtotal-pred
-                            primary-subheading-renderer
-                            secondary-subheading-renderer
-                            primary-subtotal-renderer
-                            secondary-subtotal-renderer
+    (do-rows-with-subtotals splits #t
                             (gnc:make-commodity-collector)
                             (gnc:make-commodity-collector)
                             (gnc:make-commodity-collector))
@@ -1445,20 +1337,12 @@ Credit Card, and Income accounts."))))))
                             (subtotal-get-info optname-prime-sortkey
                                                optname-prime-subtotal
                                                optname-prime-date-subtotal
-                                               'subheading-renderer)
+                                               'renderer-key)
                             (subtotal-get-info optname-sec-sortkey
                                                optname-sec-subtotal
                                                optname-sec-date-subtotal
-                                               'subheading-renderer)
-                            (subtotal-get-info   optname-prime-sortkey
-                                                 optname-prime-subtotal
-                                                 optname-prime-date-subtotal
-                                                 'subtotal-renderer)
-                            (subtotal-get-info   optname-sec-sortkey
-                                                 optname-sec-subtotal
-                                                 optname-sec-date-subtotal
-                                                 'subtotal-renderer))))
-                
+                                               'renderer-key))))
+
                 (gnc:html-document-set-title! document report-title)
 
                 (gnc:html-document-add-object!

commit afc6ca078c0592ee1c9a61c1dab0b22bd916f2fb
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 16:57:07 2017 +0800

    ENH: Show account description in subheadings

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 0330ac8..e6ef525 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -66,6 +66,7 @@
 (define optname-prime-date-subtotal (N_ "Primary Subtotal for Date Key"))
 (define optname-full-account-name (N_ "Show Full Account Name"))
 (define optname-show-account-code (N_ "Show Account Code"))
+(define optname-show-account-description (N_ "Show Account Description"))
 (define optname-sec-sortkey (N_ "Secondary Key"))
 (define optname-sec-subtotal (N_ "Secondary Subtotal"))
 (define optname-sec-sortorder  (N_ "Secondary Sort Order"))
@@ -456,6 +457,11 @@ tags within description, notes or memo. ")
              (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
 
         (gnc-option-db-set-option-selectable-by-name
+         options pagename-sorting optname-show-account-description
+         (or (and prime-sortkey-subtotal-enabled prime-sortkey-subtotal-true)
+             (and sec-sortkey-subtotal-enabled sec-sortkey-subtotal-true)))
+
+        (gnc-option-db-set-option-selectable-by-name
          options pagename-sorting optname-prime-date-subtotal
          prime-date-sortingtype-enabled)
 
@@ -489,6 +495,13 @@ tags within description, notes or memo. ")
       #f))
 
     (gnc:register-trep-option
+     (gnc:make-simple-boolean-option
+      pagename-sorting optname-show-account-description
+      "j3"
+      (N_ "Show the account description for subheadings?")
+      #f))
+    
+    (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       pagename-sorting optname-prime-subtotal
       "e5"
@@ -725,6 +738,7 @@ Credit Card, and Income accounts."))))))
                                               (opt-val gnc:pagename-display (N_ "Use Full Other Account Name"))))
           (cons 'sort-account-code (opt-val pagename-sorting (N_ "Show Account Code")))
           (cons 'sort-account-full-name (opt-val pagename-sorting (N_ "Show Full Account Name")))
+          (cons 'sort-account-description (opt-val pagename-sorting (N_ "Show Account Description")))
           (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
   (define (column-uses? param columns-used)
@@ -913,6 +927,29 @@ Credit Card, and Income accounts."))))))
     (define (render-year-subtotal split)
       (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
         (strftime "%Y" tm)))
+    (define (render-account renderer-key split anchor?)
+      (let* ((account (case renderer-key
+                        ((account) (xaccSplitGetAccount split))
+                        ((other-acc) (xaccSplitGetAccount (xaccSplitGetOtherSplit split)))))
+             (name (account-namestring account
+                                       (column-uses? 'sort-account-code      used-columns)
+                                       #t
+                                       (column-uses? 'sort-account-full-name used-columns)))
+             (description (if (and (column-uses? 'sort-account-description used-columns)
+                                   (not (string-null? (xaccAccountGetDescription account))))
+                              (string-append ": " (xaccAccountGetDescription account))
+                              "")))
+        (if (and anchor? (not (null? account))) ;html anchor for 2-split transactions only
+            (gnc:make-html-text
+             (gnc:html-markup-anchor (gnc:account-anchor-text account) name)
+             description)
+            name)))
+
+    (define (render-summary split renderer-key anchor?)
+      (case renderer-key
+        ((week month quarter year) (render-date renderer-key split))
+        ((account other-acc) (render-account renderer-key split anchor?))
+        (else #f)))
 
     (define (render-grand-total)
       (_ "Grand Total"))

commit c4089ebcc3dc7497acfcb15abbb41909e0b9de1c
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 10:42:45 2017 +0800

    REFACTOR: move add-split-row into make-split-table

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index e096ed9..0330ac8 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -259,145 +259,6 @@ options specified in the Options panels."))
   (cdr (assq info (cdr (assq sortkey date-subtotal-list)))))
 
 
-(define (add-split-row table split column-vector options
-                       row-style account-types-to-reverse transaction-row?)
-
-  (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
-
-  (let* ((row-contents '())
-         (parent (xaccSplitGetParent split))
-         (account (xaccSplitGetAccount split))
-         (account-type (xaccAccountGetType account))
-         (currency (if (null? account)
-                       (gnc-default-currency)
-                       (xaccAccountGetCommodity account)))
-         (report-currency (if (opt-val gnc:pagename-general optname-common-currency)
-                              (opt-val gnc:pagename-general optname-currency)
-                              currency))
-         (damount (if (gnc:split-voided? split)
-                      (xaccSplitVoidFormerAmount split)
-                      (xaccSplitGetAmount split)))
-         (trans-date (gnc-transaction-get-date-posted parent))
-         (split-value (gnc:exchange-by-pricedb-nearest
-                       (gnc:make-gnc-monetary
-                        currency
-                        (if (member account-type account-types-to-reverse)
-                            (gnc-numeric-neg damount)
-                            damount))
-                       report-currency
-                       ;; Use midday as the transaction time so it matches a price
-                       ;; on the same day.  Otherwise it uses midnight which will
-                       ;; likely match a price on the previous day
-                       (timespecCanonicalDayTime trans-date))))
-
-    (if (column-uses? 'date column-vector)
-        (addto! row-contents
-                (if transaction-row?
-                    (gnc:make-html-table-cell/markup
-                     "date-cell"
-                     (gnc-print-date trans-date))
-                    "")))
-    
-    (if (column-uses? 'reconciled-date column-vector)
-        (addto! row-contents
-                (gnc:make-html-table-cell/markup
-                 "date-cell"
-                 (let ((date (gnc-split-get-date-reconciled split)))
-                   (if (equal? date (cons 0 0))
-                       ""
-                       (gnc-print-date date))))))
-
-    (if (column-uses? 'num column-vector)
-        (addto! row-contents
-                (if transaction-row?
-                    (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-                        (let* ((num (gnc-get-num-action parent split))
-                               (t-num (if (if (gnc:lookup-option options gnc:pagename-display
-                                                                 (N_ "Trans Number"))
-                                              (opt-val gnc:pagename-display (N_ "Trans Number"))
-                                              "")
-                                          (gnc-get-num-action parent #f)
-                                          ""))
-                               (num-string (if (string-null? t-num)
-                                               num
-                                               (string-append num "/" t-num))))
-                          (gnc:make-html-table-cell/markup "text-cell" num-string))
-                        (gnc:make-html-table-cell/markup "text-cell"
-                                                         (gnc-get-num-action parent split)))
-                    "")))
-
-    (if (column-uses? 'description column-vector)
-        (addto! row-contents
-                (if transaction-row?
-                    (gnc:make-html-table-cell/markup
-                     "text-cell"
-                     (xaccTransGetDescription parent))
-                    "")))
-
-    (if (column-uses? 'memo column-vector)
-        (let ((memo (xaccSplitGetMemo split)))
-          (if (and (string-null? memo) (column-uses? 'notes column-vector))
-              (addto! row-contents (xaccTransGetNotes parent))
-              (addto! row-contents memo))))
-
-    (if (or (column-uses? 'account-name column-vector) (column-uses? 'account-code column-vector))
-        (addto! row-contents (account-namestring account
-                                                 (column-uses? 'account-code      column-vector)
-                                                 (column-uses? 'account-name      column-vector)
-                                                 (column-uses? 'account-full-name column-vector))))
-
-    (if (or (column-uses? 'other-account-name column-vector) (column-uses? 'other-account-code column-vector))
-        (addto! row-contents (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
-                                                 (column-uses? 'other-account-code      column-vector)
-                                                 (column-uses? 'other-account-name      column-vector)
-                                                 (column-uses? 'other-account-full-name column-vector))))
-
-    (if (column-uses? 'shares column-vector)
-        (addto! row-contents (xaccSplitGetAmount split)))
-
-    (if (column-uses? 'price column-vector)
-        (addto! row-contents  (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
-                                                     (xaccSplitGetSharePrice split))))
-    
-    (if (column-uses? 'amount-single column-vector)
-        (addto! row-contents
-                (gnc:make-html-table-cell/markup
-                 "number-cell" (gnc:html-transaction-anchor parent split-value))))
-    
-    (if (column-uses? 'amount-double column-vector)        
-
-        (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount split-value))
-
-            (begin
-              (addto! row-contents
-                      (gnc:make-html-table-cell/markup
-                       "number-cell" (gnc:html-transaction-anchor
-                                      parent split-value)))
-              (addto! row-contents ""))
-        
-            (begin
-              (addto! row-contents "")
-              (addto! row-contents
-                      (gnc:make-html-table-cell/markup
-                       "number-cell" (gnc:html-transaction-anchor
-                                      parent (gnc:monetary-neg split-value)))))))
-    
-    (if (column-uses? 'running-balance column-vector)
-        (begin
-          ;(gnc:debug "split is " split)
-          ;(gnc:debug "split get balance:" (xaccSplitGetBalance split))
-          (addto! row-contents
-                  (gnc:make-html-table-cell/markup
-                   "number-cell"
-                   (gnc:make-gnc-monetary currency
-                                          (xaccSplitGetBalance split))))))
-    
-    (gnc:html-table-append-row/markup! table row-style (reverse row-contents))
-
-    split-value))
-
-
-
 (define (trep-options-generator)
 
   (define options (gnc:new-options))
@@ -1076,6 +937,144 @@ Credit Card, and Income accounts."))))))
          ((other-acc) render-corresponding-account-subtotal))
        split))
 
+
+    (define (add-split-row split row-style transaction-row?)
+
+      (let* ((row-contents '())
+             (parent (xaccSplitGetParent split))
+             (account (xaccSplitGetAccount split))
+             (account-type (xaccAccountGetType account))
+             (currency (if (null? account)
+                           (gnc-default-currency)
+                           (xaccAccountGetCommodity account)))
+             (report-currency (if (opt-val gnc:pagename-general optname-common-currency)
+                                  (opt-val gnc:pagename-general optname-currency)
+                                  currency))
+             (damount (if (gnc:split-voided? split)
+                          (xaccSplitVoidFormerAmount split)
+                          (xaccSplitGetAmount split)))
+             (trans-date (gnc-transaction-get-date-posted parent))
+             (split-value (gnc:exchange-by-pricedb-nearest
+                           (gnc:make-gnc-monetary
+                            currency
+                            (if (member account-type account-types-to-reverse)
+                                (gnc-numeric-neg damount)
+                                damount))
+                           report-currency
+                           ;; Use midday as the transaction time so it matches a price
+                           ;; on the same day.  Otherwise it uses midnight which will
+                           ;; likely match a price on the previous day
+                           (timespecCanonicalDayTime trans-date))))
+
+        (if (column-uses? 'date used-columns)
+            (addto! row-contents
+                    (if transaction-row?
+                        (gnc:make-html-table-cell/markup
+                         "date-cell"
+                         (gnc-print-date trans-date))
+                        "")))
+
+        (if (column-uses? 'reconciled-date used-columns)
+            (addto! row-contents
+                    (gnc:make-html-table-cell/markup
+                     "date-cell"
+                     (let ((date (gnc-split-get-date-reconciled split)))
+                       (if (equal? date (cons 0 0))
+                           ""
+                           (gnc-print-date date))))))
+
+        (if (column-uses? 'num used-columns)
+            (addto! row-contents
+                    (if transaction-row?
+                        (if BOOK-SPLIT-ACTION
+                            (let* ((num (gnc-get-num-action parent split))
+                                   (t-num (if (if (gnc:lookup-option options gnc:pagename-display
+                                                                     (N_ "Trans Number"))
+                                                  (opt-val gnc:pagename-display (N_ "Trans Number"))
+                                                  "")
+                                              (gnc-get-num-action parent #f)
+                                              ""))
+                                   (num-string (if (string-null? t-num)
+                                                   num
+                                                   (string-append num "/" t-num))))
+                              (gnc:make-html-table-cell/markup "text-cell" num-string))
+                            (gnc:make-html-table-cell/markup "text-cell"
+                                                             (gnc-get-num-action parent split)))
+                        "")))
+
+        (if (column-uses? 'description used-columns)
+            (addto! row-contents
+                    (if transaction-row?
+                        (gnc:make-html-table-cell/markup
+                         "text-cell"
+                         (xaccTransGetDescription parent))
+                        "")))
+
+        (if (column-uses? 'memo used-columns)
+            (let ((memo (xaccSplitGetMemo split)))
+              (if (and (string-null? memo) (column-uses? 'notes used-columns))
+                  (addto! row-contents (xaccTransGetNotes parent))
+                  (addto! row-contents memo))))
+
+        (if (or (column-uses? 'account-name used-columns) (column-uses? 'account-code used-columns))
+            (addto! row-contents (account-namestring account
+                                                     (column-uses? 'account-code      used-columns)
+                                                     (column-uses? 'account-name      used-columns)
+                                                     (column-uses? 'account-full-name used-columns))))
+
+        (if (or (column-uses? 'other-account-name used-columns) (column-uses? 'other-account-code used-columns))
+            (addto! row-contents (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
+                                                     (column-uses? 'other-account-code      used-columns)
+                                                     (column-uses? 'other-account-name      used-columns)
+                                                     (column-uses? 'other-account-full-name used-columns))))
+
+        (if (column-uses? 'shares used-columns)
+            (addto! row-contents (xaccSplitGetAmount split)))
+
+        (if (column-uses? 'price used-columns)
+            (addto! row-contents  (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
+                                                         (xaccSplitGetSharePrice split))))
+
+        (if (column-uses? 'amount-single used-columns)
+            (addto! row-contents
+                    (gnc:make-html-table-cell/markup
+                     "number-cell" (gnc:html-transaction-anchor parent split-value))))
+
+        (if (column-uses? 'amount-double used-columns)
+
+            (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount split-value))
+
+                (begin
+                  (addto! row-contents
+                          (gnc:make-html-table-cell/markup
+                           "number-cell" (gnc:html-transaction-anchor
+                                          parent split-value)))
+                  (addto! row-contents ""))
+
+                (begin
+                  (addto! row-contents "")
+                  (addto! row-contents
+                          (gnc:make-html-table-cell/markup
+                           "number-cell" (gnc:html-transaction-anchor
+                                          parent (gnc:monetary-neg split-value)))))))
+
+        (if (column-uses? 'running-balance used-columns)
+            (begin
+              ;(gnc:debug "split is " split)
+              ;(gnc:debug "split get balance:" (xaccSplitGetBalance split))
+              (addto! row-contents
+                      (gnc:make-html-table-cell/markup
+                       "number-cell"
+                       (gnc:make-gnc-monetary currency
+                                              (xaccSplitGetBalance split))))))
+
+        (gnc:html-table-append-row/markup! table row-style (reverse row-contents))
+
+        split-value))
+
+
+
+
     (define (do-rows-with-subtotals splits
                                     table
                                     used-columns

commit dd22216845fc62a7f3affbc58161f318fee26bc9
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 10:38:23 2017 +0800

    REFACTOR: move *-choice-list into options-generator

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 65fe6c1..e096ed9 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -110,235 +110,106 @@ options specified in the Options panels."))
                                'account-code 'corresponding-acc-code))
 
 
-(define (column-uses? param columns-used)
-  (cdr (assq param columns-used)))
-
-            
-;; display an account name depending on the options the user has set
-(define (account-namestring account show-account-code? show-account-name? show-account-full-name?)
-  ;;# on multi-line splits we can get an empty ('()) account
-  (if (null? account)
-      (_ "Split Transaction")
-      (string-append
-       ;; display account code?
-       (if show-account-code?
-           (string-append (xaccAccountGetCode account) " ")
-           "")
-       ;; display account name?
-       (if show-account-name?
-           ;; display full account name?
-           (if show-account-full-name?
-               (gnc-account-get-full-name account)
-               (xaccAccountGetName account))
-           ""))))
-
-;; render an account subheading - column-vector determines what is displayed
-(define (render-account-subheading split column-vector)
-  (let ((account (xaccSplitGetAccount split)))
-    (gnc:make-html-text
-     (gnc:html-markup-anchor
-      (gnc:account-anchor-text account)
-      (account-namestring account
-                          (column-uses? 'sort-account-code      column-vector)
-                          #t
-                          (column-uses? 'sort-account-full-name column-vector))))))                        
-
-(define (render-corresponding-account-subheading split column-vector)
-  (let ((account (xaccSplitGetAccount (xaccSplitGetOtherSplit split))))
-    (gnc:make-html-text
-     (gnc:html-markup-anchor
-      (if (null? account)
-          ""
-          (gnc:account-anchor-text account))
-      (account-namestring account
-                          (column-uses? 'sort-account-code      column-vector)
-                          #t
-                          (column-uses? 'sort-account-full-name column-vector))))))
-
-(define (render-week-subheading split column-vector)
-  (gnc:date-get-week-year-string
-   (gnc:timepair->date
-    (gnc-transaction-get-date-posted
-     (xaccSplitGetParent split)))))
-
-(define (render-month-subheading split column-vector)
-  (gnc:date-get-month-year-string
-   (gnc:timepair->date
-    (gnc-transaction-get-date-posted
-     (xaccSplitGetParent split)))))
-
-(define (render-quarter-subheading split column-vector)
-  (gnc:date-get-quarter-year-string
-   (gnc:timepair->date
-    (gnc-transaction-get-date-posted
-     (xaccSplitGetParent split)))))
-
-
-(define (render-year-subheading split column-vector)
-  (gnc:date-get-year-string
-   (gnc:timepair->date
-    (gnc-transaction-get-date-posted
-     (xaccSplitGetParent split)))))
-
-(define (total-string str) (string-append (_ "Total For ") str))
-
-(define (render-account-subtotal split column-vector)
-  (total-string (account-namestring (xaccSplitGetAccount split)
-                                    (column-uses? 'sort-account-code      column-vector)
-                                    #t
-                                    (column-uses? 'sort-account-full-name column-vector))))
-
-(define (render-corresponding-account-subtotal split column-vector)
-  (total-string (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
-                                    (column-uses? 'sort-account-code      column-vector)
-                                    #t
-                                    (column-uses? 'sort-account-full-name column-vector))))
-
-(define (render-week-subtotal split column-vector)
-  (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
-                                 (xaccSplitGetParent split)))))
-    (total-string (gnc:date-get-week-year-string tm))))
-
-(define (render-month-subtotal split column-vector)
-  (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
-                                 (xaccSplitGetParent split)))))
-    (total-string (gnc:date-get-month-year-string tm))))
-
-(define (render-quarter-subtotal split column-vector)
-  (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
-                                 (xaccSplitGetParent split)))))
-    (total-string (gnc:date-get-quarter-year-string tm))))
-
-(define (render-year-subtotal split column-vector)
-  (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
-                                 (xaccSplitGetParent split)))))
-    (total-string (strftime "%Y" tm))))
-
-(define (render-grand-total)
-  (_ "Grand Total")) ; def:grand-total-style
-
-
-
 
 (define sortkey-list
+  ;;
   ;; Defines the different sorting keys, as an association-list 
   ;; together with the subtotal functions. Each entry: 
   ;;  'sortkey             - sort parameter sent via qof-query
   ;;  'split-sortvalue     - function which retrieves number/string used for comparing splits
   ;;  'text                - text displayed in Display tab
   ;;  'tip                 - tooltip displayed in Display tab
-  ;;  'subheading-renderer - function which renders the subheading
-  ;;  'subtotal-renderer   - function which renders the subtotal
+  ;;  'renderer            - helper symbol to select subtotal/subheading renderer
+  ;;
   (list (cons 'account-name  (list (cons 'sortkey (list SPLIT-ACCT-FULLNAME))
                                    (cons 'split-sortvalue (lambda (a) (gnc-account-get-full-name (xaccSplitGetAccount a))))
                                    (cons 'text (N_ "Account Name"))
                                    (cons 'tip (N_ "Sort & subtotal by account name."))
-                                   (cons 'subheading-renderer render-account-subheading)
-                                   (cons 'subtotal-renderer render-account-subtotal)))
+                                   (cons 'renderer 'account)))
         
         (cons 'account-code (list (cons 'sortkey (list SPLIT-ACCOUNT ACCOUNT-CODE-))
                                   (cons 'split-sortvalue (lambda (a) (xaccAccountGetCode (xaccSplitGetAccount a))))
                                   (cons 'text (N_ "Account Code"))
                                   (cons 'tip (N_ "Sort & subtotal by account code."))
-                                  (cons 'subheading-renderer render-account-subheading)
-                                  (cons 'subtotal-renderer render-account-subtotal)))
+                                  (cons 'renderer 'account)))
 
         (cons 'date         (list (cons 'sortkey (list SPLIT-TRANS TRANS-DATE-POSTED))
                                   (cons 'split-sortvalue #f)
                                   (cons 'text (N_ "Date"))
                                   (cons 'tip (N_ "Sort by date."))
-                                  (cons 'subheading-renderer #f)
-                                  (cons 'subtotal-renderer #f)))
+                                  (cons 'renderer #f)))
 
         (cons 'reconciled-date (list (cons 'sortkey (list SPLIT-DATE-RECONCILED))
                                      (cons 'split-sortvalue #f)
                                      (cons 'text (N_ "Reconciled Date"))
                                      (cons 'tip (N_ "Sort by the Reconciled Date."))
-                                     (cons 'subheading-renderer #f)
-                                     (cons 'subtotal-renderer #f)))
+                                     (cons 'renderer #f)))
 
         (cons 'register-order (list (cons 'sortkey (list QUERY-DEFAULT-SORT))
                                     (cons 'split-sortvalue #f)
                                     (cons 'text (N_ "Register Order"))
                                     (cons 'tip (N_ "Sort as in the register."))
-                                    (cons 'subheading-renderer #f)
-                                    (cons 'subtotal-renderer #f)))                                 
+                                    (cons 'renderer #f)))                                 
 
         (cons 'corresponding-acc-name (list (cons 'sortkey (list SPLIT-CORR-ACCT-NAME))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountFullName a)))
                                             (cons 'text (N_ "Other Account Name"))
                                             (cons 'tip (N_ "Sort by account transferred from/to's name."))
-                                            (cons 'subheading-renderer render-corresponding-account-subheading)
-                                            (cons 'subtotal-renderer render-corresponding-account-subtotal)))
+                                            (cons 'renderer 'other-acc)))
 
         (cons 'corresponding-acc-code (list (cons 'sortkey (list SPLIT-CORR-ACCT-CODE))
                                             (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountCode a)))
                                             (cons 'text (N_ "Other Account Code"))
                                             (cons 'tip (N_ "Sort by account transferred from/to's code."))
-                                            (cons 'subheading-renderer render-corresponding-account-subheading)
-                                            (cons 'subtotal-renderer render-corresponding-account-subtotal)))
+                                            (cons 'renderer 'other-acct)))
 
         (cons 'amount        (list (cons 'sortkey (list SPLIT-VALUE))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Amount"))
                                    (cons 'tip (N_ "Sort by amount."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f)))
+                                   (cons 'renderer #f)))
 
         (cons 'description   (list (cons 'sortkey (list SPLIT-TRANS TRANS-DESCRIPTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Description"))
                                    (cons 'tip (N_ "Sort by description."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f)))
+                                   (cons 'renderer #f)))
 
         (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
             (cons 'number    (list (cons 'sortkey (list SPLIT-ACTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Number/Action"))
                                    (cons 'tip (N_ "Sort by check number/action."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f)))
+                                   (cons 'renderer #f)))
 
             (cons 'number    (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Number"))
                                    (cons 'tip (N_ "Sort by check/transaction number."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f))))
+                                   (cons 'renderer #f))))
 
         (cons 't-number      (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Transaction Number"))
                                    (cons 'tip (N_ "Sort by transaction number."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f)))
+                                   (cons 'renderer #f)))
 
         (cons 'memo          (list (cons 'sortkey (list SPLIT-MEMO))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Memo"))
                                    (cons 'tip (N_ "Sort by memo."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f)))
+                                   (cons 'renderer #f)))
 
         (cons 'none          (list (cons 'sortkey '())
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "None"))
                                    (cons 'tip (N_ "Do not sort."))
-                                   (cons 'subheading-renderer #f)
-                                   (cons 'subtotal-renderer #f)))))
+                                   (cons 'renderer #f)))))
 
 
 (define (sortkey-get-info sortkey info)
   (cdr (assq info (cdr (assq sortkey sortkey-list)))))
 
-(define key-choice-list
-  (map (lambda (sortpair)
-         (vector (car sortpair)
-                 (sortkey-get-info (car sortpair) 'text)
-                 (sortkey-get-info (car sortpair) 'tip)))
-       sortkey-list))
-
 (define (timepair-year tp)    (gnc:timepair-get-year tp))
 (define (timepair-quarter tp) (+ (* 10 (timepair-year tp))  (gnc:timepair-get-quarter tp)))
 (define (timepair-month tp)   (+ (* 100 (timepair-year tp)) (gnc:timepair-get-month tp)))
@@ -387,12 +258,6 @@ options specified in the Options panels."))
 (define (date-subtotal-get-info sortkey info)
   (cdr (assq info (cdr (assq sortkey date-subtotal-list)))))
 
-(define date-subtotal-choice-list
-  (map (lambda (date-sortpair)
-         (vector (car date-sortpair)
-                 (date-subtotal-get-info (car date-sortpair) 'text)
-                 (date-subtotal-get-info (car date-sortpair) 'tip)))
-       date-subtotal-list))
 
 (define (add-split-row table split column-vector options
                        row-style account-types-to-reverse transaction-row?)
@@ -679,7 +544,21 @@ tags within description, notes or memo. ")
         (prime-sortkey 'account-name)
         (prime-sortkey-subtotal-true #t)
         (sec-sortkey 'register-order)
-        (sec-sortkey-subtotal-true #f))
+        (sec-sortkey-subtotal-true #f)       
+        (key-choice-list (map
+                          (lambda (sortpair)
+                            (vector
+                             (car sortpair)
+                             (sortkey-get-info (car sortpair) 'text)
+                             (sortkey-get-info (car sortpair) 'tip)))
+                          sortkey-list))
+        (date-subtotal-choice-list (map
+                                    (lambda (date-sortpair)
+                                      (vector
+                                       (car date-sortpair)
+                                       (date-subtotal-get-info (car date-sortpair) 'text)
+                                       (date-subtotal-get-info (car date-sortpair) 'tip)))
+                                    date-subtotal-list)))
 
     (define (apply-selectable-by-name-sorting-options)
       (let* ((prime-sortkey-enabled (not (eq? prime-sortkey 'none)))
@@ -987,6 +866,9 @@ Credit Card, and Income accounts."))))))
           (cons 'sort-account-full-name (opt-val pagename-sorting (N_ "Show Full Account Name")))
           (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
+  (define (column-uses? param columns-used)
+    (cdr (assq param columns-used)))
+
   (define (make-heading-list columns-used)
     (define (add-if pred? . items) (if pred? items '()))
     (append
@@ -1075,6 +957,125 @@ Credit Card, and Income accounts."))))))
                              "total-number-cell" currency)))))
                   (cdr currency-totals))))
 
+    (define (total-string str) (string-append (_ "Total For ") str))
+
+    ;; display an account name depending on the options the user has set
+    (define (account-namestring account show-account-code? show-account-name? show-account-full-name?)
+      ;;# on multi-line splits we can get an empty ('()) account
+      (if (null? account)
+          (_ "Split Transaction")
+          (string-append
+           ;; display account code?
+           (if show-account-code?
+               (string-append (xaccAccountGetCode account) " ")
+               "")
+           ;; display account name?
+           (if show-account-name?
+               ;; display full account name?
+               (if show-account-full-name?
+                   (gnc-account-get-full-name account)
+                   (xaccAccountGetName account))
+               ""))))
+
+    ;; render an account subheading - used-columns determines what is displayed
+    (define (render-account-subheading split)
+      (let ((account (xaccSplitGetAccount split)))
+        (gnc:make-html-text
+         (gnc:html-markup-anchor
+          (gnc:account-anchor-text account)
+          (account-namestring account
+                              (column-uses? 'sort-account-code      used-columns)
+                              #t
+                              (column-uses? 'sort-account-full-name used-columns))))))                        
+
+    (define (render-corresponding-account-subheading split)
+      (let ((account (xaccSplitGetAccount (xaccSplitGetOtherSplit split))))
+        (gnc:make-html-text
+         (gnc:html-markup-anchor
+          (if (null? account)
+              ""
+              (gnc:account-anchor-text account))
+          (account-namestring account
+                              (column-uses? 'sort-account-code      used-columns)
+                              #t
+                              (column-uses? 'sort-account-full-name used-columns))))))
+
+    (define (render-week-subheading split)
+      (gnc:date-get-week-year-string
+       (gnc:timepair->date
+        (gnc-transaction-get-date-posted
+         (xaccSplitGetParent split)))))
+
+    (define (render-month-subheading split)
+      (gnc:date-get-month-year-string
+       (gnc:timepair->date
+        (gnc-transaction-get-date-posted
+         (xaccSplitGetParent split)))))
+
+    (define (render-quarter-subheading split)
+      (gnc:date-get-quarter-year-string
+       (gnc:timepair->date
+        (gnc-transaction-get-date-posted
+         (xaccSplitGetParent split)))))
+
+
+    (define (render-year-subheading split)
+      (gnc:date-get-year-string
+       (gnc:timepair->date
+        (gnc-transaction-get-date-posted
+         (xaccSplitGetParent split)))))
+
+    (define (render-account-subtotal split)
+      (account-namestring (xaccSplitGetAccount split)
+                          (column-uses? 'sort-account-code      used-columns)
+                          #t
+                          (column-uses? 'sort-account-full-name used-columns)))
+
+    (define (render-corresponding-account-subtotal split)
+      (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
+                          (column-uses? 'sort-account-code      used-columns)
+                          #t
+                          (column-uses? 'sort-account-full-name used-columns)))
+
+    (define (render-week-subtotal split)
+      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
+        (gnc:date-get-week-year-string tm)))
+
+    (define (render-month-subtotal split)
+      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
+        (gnc:date-get-month-year-string tm)))
+
+    (define (render-quarter-subtotal split)
+      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
+        (gnc:date-get-quarter-year-string tm)))
+
+    (define (render-year-subtotal split)
+      (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted (xaccSplitGetParent split)))))
+        (strftime "%Y" tm)))
+
+    (define (render-grand-total)
+      (_ "Grand Total"))
+
+    (define (subheading-renderer split key)
+      ((case key
+         ((week)      render-week-subheading)
+         ((month)     render-month-subheading)
+         ((quarter)   render-quarter-subheading)
+         ((year)      render-year-subheading)
+         ((account)   render-account-subheading)
+         ((other-acc) render-corresponding-account-subheading))
+       split))
+
+    (define (subtotal-renderer split key)
+      ((case key
+         ((week)      render-week-subtotal)
+         ((month)     render-month-subtotal)
+         ((quarter)   render-quarter-subtotal)
+         ((year)      render-year-subtotal)
+         ((account)   render-account-subtotal)
+         ((other-acc) render-corresponding-account-subtotal))
+       split))
+
     (define (do-rows-with-subtotals splits
                                     table
                                     used-columns

commit d88d503b38989e4b008097fda6fee5f05a7d667f
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 10:33:25 2017 +0800

    REFACTOR: simplify functions, reduce arguments

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 65f17eb..65fe6c1 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -109,12 +109,6 @@ options specified in the Options panels."))
 (define SUBTOTAL-ENABLED (list 'account-name 'corresponding-acc-name
                                'account-code 'corresponding-acc-code))
 
-(define (add-subheading-row data table width subheading-style)
-  (let ((heading-cell (gnc:make-html-table-cell data)))
-    (gnc:html-table-cell-set-colspan! heading-cell width)
-    (gnc:html-table-append-row/markup!
-     table subheading-style
-     (list heading-cell))))
 
 (define (column-uses? param columns-used)
   (cdr (assq param columns-used)))
@@ -138,151 +132,90 @@ options specified in the Options panels."))
                (xaccAccountGetName account))
            ""))))
 
-                                                   
-
 ;; render an account subheading - column-vector determines what is displayed
-(define (render-account-subheading
-         split table width subheading-style column-vector)
+(define (render-account-subheading split column-vector)
   (let ((account (xaccSplitGetAccount split)))
-    (add-subheading-row (gnc:make-html-text
-                         (gnc:html-markup-anchor
-                          (gnc:account-anchor-text account)
-                          (account-namestring account
-                                              (column-uses? 'sort-account-code      column-vector)
-                                              #t
-                                              (column-uses? 'sort-account-full-name column-vector))))
-                        table width subheading-style)))
-
-(define (render-corresponding-account-subheading
-         split table width subheading-style column-vector)
+    (gnc:make-html-text
+     (gnc:html-markup-anchor
+      (gnc:account-anchor-text account)
+      (account-namestring account
+                          (column-uses? 'sort-account-code      column-vector)
+                          #t
+                          (column-uses? 'sort-account-full-name column-vector))))))                        
+
+(define (render-corresponding-account-subheading split column-vector)
   (let ((account (xaccSplitGetAccount (xaccSplitGetOtherSplit split))))
-    (add-subheading-row (gnc:make-html-text
-                         (gnc:html-markup-anchor
-                          (if (null? account)
-                              ""
-                              (gnc:account-anchor-text account))
-                          (account-namestring account
-                                              (column-uses? 'sort-account-code      column-vector)
-                                              #t
-                                              (column-uses? 'sort-account-full-name column-vector))))
-                        table width subheading-style)))
-
-(define (render-week-subheading split table width subheading-style column-vector)
-  (add-subheading-row (gnc:date-get-week-year-string
-                       (gnc:timepair->date
-                        (gnc-transaction-get-date-posted
-                         (xaccSplitGetParent split))))
-                      table width subheading-style))
-
-(define (render-month-subheading split table width subheading-style column-vector)
-  (add-subheading-row (gnc:date-get-month-year-string
-                       (gnc:timepair->date
-                        (gnc-transaction-get-date-posted
-                         (xaccSplitGetParent split))))
-                      table width subheading-style))
-
-(define (render-quarter-subheading split table width subheading-style column-vector)
-  (add-subheading-row (gnc:date-get-quarter-year-string
-                       (gnc:timepair->date
-                        (gnc-transaction-get-date-posted
-                         (xaccSplitGetParent split))))
-                      table width subheading-style))
-
-(define (render-year-subheading split table width subheading-style column-vector)
-  (add-subheading-row (gnc:date-get-year-string
-                       (gnc:timepair->date
-                        (gnc-transaction-get-date-posted
-                         (xaccSplitGetParent split))))
-                      table width subheading-style))
-
-(define (add-subtotal-row table width subtotal-string subtotal-collector
-                          subtotal-style export?)
-  (let ((currency-totals (subtotal-collector 'format gnc:make-gnc-monetary #f)))
-    (gnc:html-table-append-row/markup!
-     table
-     subtotal-style
-     (if export?
-         (append! (cons (gnc:make-html-table-cell/markup "total-label-cell" subtotal-string)
-                        (gnc:html-make-empty-cells (- width 2)))
-                  (list (gnc:make-html-table-cell/markup
-                         "total-number-cell"
-                         (car currency-totals))))
-         (list (gnc:make-html-table-cell/size/markup 1 (- width 1) "total-label-cell"
-                                                     subtotal-string)
-               (gnc:make-html-table-cell/markup
-                "total-number-cell"
-                (car currency-totals)))))
-    (for-each (lambda (currency)
-                (gnc:html-table-append-row/markup!
-                 table
-                 subtotal-style
-                 (append!
-                  (if export?
-                      (gnc:html-make-empty-cells (- width 1))
-                      (list (gnc:make-html-table-cell/size 1 (- width 1) #f)))
-                  (list (gnc:make-html-table-cell/markup
-                         "total-number-cell" currency)))))
-              (cdr currency-totals))))
+    (gnc:make-html-text
+     (gnc:html-markup-anchor
+      (if (null? account)
+          ""
+          (gnc:account-anchor-text account))
+      (account-namestring account
+                          (column-uses? 'sort-account-code      column-vector)
+                          #t
+                          (column-uses? 'sort-account-full-name column-vector))))))
+
+(define (render-week-subheading split column-vector)
+  (gnc:date-get-week-year-string
+   (gnc:timepair->date
+    (gnc-transaction-get-date-posted
+     (xaccSplitGetParent split)))))
+
+(define (render-month-subheading split column-vector)
+  (gnc:date-get-month-year-string
+   (gnc:timepair->date
+    (gnc-transaction-get-date-posted
+     (xaccSplitGetParent split)))))
+
+(define (render-quarter-subheading split column-vector)
+  (gnc:date-get-quarter-year-string
+   (gnc:timepair->date
+    (gnc-transaction-get-date-posted
+     (xaccSplitGetParent split)))))
+
+
+(define (render-year-subheading split column-vector)
+  (gnc:date-get-year-string
+   (gnc:timepair->date
+    (gnc-transaction-get-date-posted
+     (xaccSplitGetParent split)))))
 
 (define (total-string str) (string-append (_ "Total For ") str))
 
-(define (render-account-subtotal
-         table width split total-collector subtotal-style column-vector export?)
-  (add-subtotal-row table width
-                    (total-string (account-namestring (xaccSplitGetAccount split)
-                                                      (column-uses? 'sort-account-code      column-vector)
-                                                      #t
-                                                      (column-uses? 'sort-account-full-name column-vector)))
-                    total-collector subtotal-style export?))
-
-(define (render-corresponding-account-subtotal
-         table width split total-collector subtotal-style column-vector export?)
-  (add-subtotal-row table width
-                    (total-string (account-namestring (xaccSplitGetAccount
-                                                       (xaccSplitGetOtherSplit split))
-                                                      (column-uses? 'sort-account-code      column-vector)
-                                                      #t
-                                                      (column-uses? 'sort-account-full-name column-vector)))
-                    total-collector subtotal-style export?))
-
-(define (render-week-subtotal
-         table width split total-collector subtotal-style column-vector export?)
+(define (render-account-subtotal split column-vector)
+  (total-string (account-namestring (xaccSplitGetAccount split)
+                                    (column-uses? 'sort-account-code      column-vector)
+                                    #t
+                                    (column-uses? 'sort-account-full-name column-vector))))
+
+(define (render-corresponding-account-subtotal split column-vector)
+  (total-string (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
+                                    (column-uses? 'sort-account-code      column-vector)
+                                    #t
+                                    (column-uses? 'sort-account-full-name column-vector))))
+
+(define (render-week-subtotal split column-vector)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width
-                      (total-string (gnc:date-get-week-year-string tm))
-                      total-collector subtotal-style export?)))
+    (total-string (gnc:date-get-week-year-string tm))))
 
-(define (render-month-subtotal
-         table width split total-collector subtotal-style column-vector export?)
+(define (render-month-subtotal split column-vector)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width
-                      (total-string (gnc:date-get-month-year-string tm))
-                      total-collector subtotal-style export?)))
+    (total-string (gnc:date-get-month-year-string tm))))
 
-
-(define (render-quarter-subtotal
-         table width split total-collector subtotal-style column-vector export?)
+(define (render-quarter-subtotal split column-vector)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width
-                      (total-string (gnc:date-get-quarter-year-string tm))
-                      total-collector subtotal-style export?)))
+    (total-string (gnc:date-get-quarter-year-string tm))))
 
-(define (render-year-subtotal
-         table width split total-collector subtotal-style column-vector export?)
+(define (render-year-subtotal split column-vector)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width
-                      (total-string (strftime "%Y" tm))
-                      total-collector subtotal-style export?)))
+    (total-string (strftime "%Y" tm))))
 
-(define (render-grand-total
-         table width total-collector export?)
-  (add-subtotal-row table width
-                    (_ "Grand Total")
-                    total-collector def:grand-total-style export?))
+(define (render-grand-total)
+  (_ "Grand Total")) ; def:grand-total-style
 
 
 
@@ -464,7 +397,7 @@ options specified in the Options panels."))
 (define (add-split-row table split column-vector options
                        row-style account-types-to-reverse transaction-row?)
 
-  (define (opt-val section name) (gnc:option-value  (gnc:lookup-option options section name)))
+  (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
 
   (let* ((row-contents '())
          (parent (xaccSplitGetParent split))
@@ -1093,8 +1026,54 @@ Credit Card, and Income accounts."))))))
      (add-if (column-uses? 'running-balance columns-used)
              (_ "Balance"))))
 
-  (let ((work-to-do (length splits))
-        (work-done 0))
+  (let* ((work-to-do (length splits))
+         (work-done 0)
+         (table (gnc:make-html-table))
+         (used-columns (build-columns-used))
+         (headings (make-heading-list used-columns))
+         (width (length headings))
+         (account-types-to-reverse
+          (case (opt-val gnc:pagename-display (N_ "Sign Reverses"))
+            ((none) '())
+            ((income-expense) (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))
+            ((credit-accounts)  (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE
+                                      ACCT-TYPE-EQUITY ACCT-TYPE-CREDIT
+                                      ACCT-TYPE-INCOME))))
+         (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
+         (export? (opt-val gnc:pagename-general optname-table-export)))
+
+    (define (add-subheading data subheading-style)
+      (let ((heading-cell (gnc:make-html-table-cell data)))
+        (gnc:html-table-cell-set-colspan! heading-cell width)
+        (gnc:html-table-append-row/markup!
+         table subheading-style
+         (list heading-cell))))
+
+    (define (add-subtotal-row string collector style)
+      (let ((currency-totals (collector 'format gnc:make-gnc-monetary #f)))
+        (gnc:html-table-append-row/markup!
+         table style 
+         (if export?
+             (append! (cons (gnc:make-html-table-cell/markup "total-label-cell" string)
+                            (gnc:html-make-empty-cells (- width 2)))
+                      (list (gnc:make-html-table-cell/markup 
+                             "total-number-cell"
+                             (car currency-totals))))
+             (list (gnc:make-html-table-cell/size/markup 1 (- width 1) "total-label-cell"
+                                                         string)
+                   (gnc:make-html-table-cell/markup 
+                    "total-number-cell"
+                    (car currency-totals)))))
+        (for-each (lambda (currency)
+                    (gnc:html-table-append-row/markup! 
+                     table style
+                     (append!
+                      (if export?
+                          (gnc:html-make-empty-cells (- width 1))
+                          (list (gnc:make-html-table-cell/size 1 (- width 1) #f)))
+                      (list (gnc:make-html-table-cell/markup
+                             "total-number-cell" currency)))))
+                  (cdr currency-totals))))
 
     (define (do-rows-with-subtotals splits
                                     table
@@ -1119,9 +1098,9 @@ Credit Card, and Income accounts."))))))
       (set! work-done (+ 1 work-done))
 
       (if (null? splits)
-
+          
           (begin
-
+            
             (gnc:html-table-append-row/markup!
              table def:grand-total-style
              (list
@@ -1129,12 +1108,11 @@ Credit Card, and Income accounts."))))))
                1 width (gnc:make-html-text (gnc:html-markup-hr)))))
 
             (if (opt-val gnc:pagename-display "Totals")
-                (render-grand-total table width total-collector export?)))
+                (add-subtotal-row (render-grand-total) total-collector def:grand-total-style)))
 
           (let* ((current (car splits))
                  (rest (cdr splits))
-                 (next (if (null? rest) #f
-                           (car rest))))
+                 (next (if (null? rest) #f (car rest))))
 
             (define split-value (add-split-row
                                  table
@@ -1147,7 +1125,7 @@ Credit Card, and Income accounts."))))))
                                          def:alternate-row-style))
                                  account-types-to-reverse
                                  #t))
-
+            
             (if multi-rows?
 
                 (for-each (lambda (othersplits)
@@ -1168,11 +1146,11 @@ Credit Card, and Income accounts."))))))
             (secondary-subtotal-collector 'add
                                           (gnc:gnc-monetary-commodity split-value)
                                           (gnc:gnc-monetary-amount split-value))
-
+            
             (total-collector 'add
                              (gnc:gnc-monetary-commodity split-value)
                              (gnc:gnc-monetary-amount split-value))
-
+            
             (if (and primary-subtotal-pred
                      (or (not next)
                          (and next
@@ -1182,53 +1160,47 @@ Credit Card, and Income accounts."))))))
                 (begin
 
                   (if secondary-subtotal-pred
-
+                      
                       (begin
-
-                        (secondary-subtotal-renderer
-                         table width current
-                         secondary-subtotal-collector
-                         def:secondary-subtotal-style used-columns export?)
-
+                        
+                        (add-subtotal-row (secondary-subtotal-renderer current used-columns)
+                                          secondary-subtotal-collector
+                                          def:secondary-subtotal-style)
+                        
                         (secondary-subtotal-collector 'reset #f #f)))
-
-                  (primary-subtotal-renderer table width current
-                                             primary-subtotal-collector
-                                             def:primary-subtotal-style used-columns
-                                             export?)
-
+                  
+                  (add-subtotal-row (primary-subtotal-renderer current used-columns)
+                                    primary-subtotal-collector
+                                    def:primary-subtotal-style)
+                  
                   (primary-subtotal-collector 'reset #f #f)
-
+                  
                   (if next
 
                       (begin
 
-                        (primary-subheading-renderer
-                         next table width def:primary-subtotal-style used-columns)
+                        (add-subheading (primary-subheading-renderer next used-columns)
+                                        def:primary-subtotal-style)
 
                         (if secondary-subtotal-pred
-                            (secondary-subheading-renderer
-                             next
-                             table
-                             width def:secondary-subtotal-style used-columns)))))
+                            (add-subheading (secondary-subheading-renderer next used-columns)
+                                            def:secondary-subtotal-style)))))
 
                 (if (and secondary-subtotal-pred
                          (or (not next)
                              (and next
                                   (not (equal? (secondary-subtotal-pred current)
                                                (secondary-subtotal-pred next))))))
-
-                    (begin (secondary-subtotal-renderer
-                            table width current
-                            secondary-subtotal-collector
-                            def:secondary-subtotal-style used-columns export?)
-
+                    
+                    (begin (add-subtotal-row (secondary-subtotal-renderer current used-columns)
+                                             secondary-subtotal-collector
+                                             def:secondary-subtotal-style)
+                           
                            (secondary-subtotal-collector 'reset #f #f)
-
+                           
                            (if next
-                               (secondary-subheading-renderer
-                                next table width
-                                def:secondary-subtotal-style used-columns)))))
+                               (add-subheading (secondary-subheading-renderer next used-columns)
+                                               def:secondary-subtotal-style)))))
 
             (do-rows-with-subtotals rest
                                     table
@@ -1248,45 +1220,31 @@ Credit Card, and Income accounts."))))))
                                     secondary-subtotal-collector
                                     total-collector))))
 
-    (let* ((table (gnc:make-html-table))
-           (used-columns (build-columns-used))
-           (headings (make-heading-list used-columns))
-           (width (length headings))
-           (account-types-to-reverse
-            (cdr (assq (opt-val gnc:pagename-display (N_ "Sign Reverses"))
-                       (list (cons 'none '())
-                             (cons 'income-expense (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))
-                             (cons 'credit-accounts  (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE
-                                                           ACCT-TYPE-EQUITY ACCT-TYPE-CREDIT
-                                                           ACCT-TYPE-INCOME))))))
-           (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
-           (export? (opt-val gnc:pagename-general optname-table-export)))
-
-      (gnc:html-table-set-col-headers! table headings)
-
-      (if primary-subheading-renderer
-          (primary-subheading-renderer
-           (car splits) table width def:primary-subtotal-style used-columns))
-
-      (if secondary-subheading-renderer
-          (secondary-subheading-renderer
-           (car splits) table width def:secondary-subtotal-style used-columns))
-
-      (do-rows-with-subtotals splits table used-columns width
-                              is-multiline? #t
-                              export?
-                              account-types-to-reverse
-                              primary-subtotal-pred
-                              secondary-subtotal-pred
-                              primary-subheading-renderer
-                              secondary-subheading-renderer
-                              primary-subtotal-renderer
-                              secondary-subtotal-renderer
-                              (gnc:make-commodity-collector)
-                              (gnc:make-commodity-collector)
-                              (gnc:make-commodity-collector))
-
-      table)))
+    (gnc:html-table-set-col-headers! table headings)
+
+    (if primary-subheading-renderer
+        (add-subheading (primary-subheading-renderer (car splits) used-columns)
+                        def:primary-subtotal-style))
+
+    (if secondary-subheading-renderer
+        (add-subheading (secondary-subheading-renderer (car splits) used-columns)
+                        def:secondary-subtotal-style))
+
+    (do-rows-with-subtotals splits table used-columns width
+                            is-multiline? #t
+                            export?
+                            account-types-to-reverse
+                            primary-subtotal-pred
+                            secondary-subtotal-pred
+                            primary-subheading-renderer
+                            secondary-subheading-renderer
+                            primary-subtotal-renderer
+                            secondary-subtotal-renderer
+                            (gnc:make-commodity-collector)
+                            (gnc:make-commodity-collector)
+                            (gnc:make-commodity-collector))
+
+    table))
 
 ;; ;;;;;;;;;;;;;;;;;;;;
 ;; Here comes the renderer function for this report.

commit a5306d045411028b15f5ac040a1cf33c749d5432
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 10:17:06 2017 +0800

    REFACTOR: improve heading-list to handle dual headings

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 7ec875b..65f17eb 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1055,7 +1055,7 @@ Credit Card, and Income accounts."))))))
           (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
   (define (make-heading-list columns-used)
-    (define (add-if pred? item) (if pred? (list item) '()))
+    (define (add-if pred? . items) (if pred? items '()))
     (append
      (add-if (column-uses? 'date columns-used)
              (_ "Date"))
@@ -1087,11 +1087,9 @@ Credit Card, and Income accounts."))))))
      (add-if (column-uses? 'amount-single columns-used)
              (_ "Amount"))
      ;; FIXME: Proper labels: what?
-     (if (column-uses? 'amount-double columns-used)
-         (list
-          (_ "Debit")
-          (_ "Credit"))
-         '())
+     (add-if (column-uses? 'amount-double columns-used)
+             (_ "Debit")
+             (_ "Credit"))
      (add-if (column-uses? 'running-balance columns-used)
              (_ "Balance"))))
 

commit e1ba5f3248269d6843fbbe1ef6fc36a086724b22
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 10:13:40 2017 +0800

    REFACTOR: centralize BOOK-SPLIT-ACTION
    
    Centralize BOOK-SPLIT-ACTION

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 5f854d6..7ec875b 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -109,7 +109,6 @@ options specified in the Options panels."))
 (define SUBTOTAL-ENABLED (list 'account-name 'corresponding-acc-name
                                'account-code 'corresponding-acc-code))
 
-
 (define (add-subheading-row data table width subheading-style)
   (let ((heading-cell (gnc:make-html-table-cell data)))
     (gnc:html-table-cell-set-colspan! heading-cell width)
@@ -360,7 +359,7 @@ options specified in the Options panels."))
                                    (cons 'subheading-renderer #f)
                                    (cons 'subtotal-renderer #f)))
 
-        (if BOOK-SPLIT-ACTION
+        (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
             (cons 'number    (list (cons 'sortkey (list SPLIT-ACTION))
                                    (cons 'split-sortvalue #f)
                                    (cons 'text (N_ "Number/Action"))
@@ -604,7 +603,7 @@ options specified in the Options panels."))
 (define (trep-options-generator)
 
   (define options (gnc:new-options))
-
+  (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
   (define (gnc:register-trep-option new-option)
     (gnc:register-option options new-option))
 
@@ -914,7 +913,7 @@ tags within description, notes or memo. ")
      (list
       (list (N_ "Date")                         "a"  (N_ "Display the date?") #t)
       (list (N_ "Reconciled Date")              "a2" (N_ "Display the reconciled date?") #f)
-      (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
+      (if BOOK-SPLIT-ACTION
           (list (N_ "Num/Action")               "b"  (N_ "Display the check number?") #t)
           (list (N_ "Num")                      "b"  (N_ "Display the check number?") #t))
       (list (N_ "Description")                  "c"  (N_ "Display the description?") #t)
@@ -931,7 +930,7 @@ tags within description, notes or memo. ")
       (list (N_ "Running Balance")              "n"  (N_ "Display a running balance?") #f)
       (list (N_ "Totals")                       "o"  (N_ "Display the totals?") #t)))
 
-    (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
+    (if BOOK-SPLIT-ACTION
         (gnc:register-trep-option
          (gnc:make-simple-boolean-option
           gnc:pagename-display (N_ "Trans Number")
@@ -1025,15 +1024,16 @@ Credit Card, and Income accounts."))))))
                           secondary-subtotal-renderer)
 
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
+  (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
 
   (define (build-columns-used)
     (define is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single))
     (define amount-setting (opt-val gnc:pagename-display (N_ "Amount")))
     (list (cons 'date (opt-val gnc:pagename-display (N_ "Date")))
           (cons 'reconciled-date (opt-val gnc:pagename-display (N_ "Reconciled Date")))
-          (cons 'num (if (gnc:lookup-option options gnc:pagename-display (N_ "Num"))
-                         (opt-val gnc:pagename-display (N_ "Num"))
-                         (opt-val gnc:pagename-display (N_ "Num/Action"))))
+          (cons 'num (if BOOK-SPLIT-ACTION
+                         (opt-val gnc:pagename-display (N_ "Num/Action"))
+                         (opt-val gnc:pagename-display (N_ "Num"))))
           (cons 'description (opt-val gnc:pagename-display (N_ "Description")))
           (cons 'account-name (opt-val gnc:pagename-display (N_ "Account Name")))
           (cons 'other-account-name (and is-single?
@@ -1297,6 +1297,7 @@ Credit Card, and Income accounts."))))))
 (define (trep-renderer report-obj)
   (define options (gnc:report-options report-obj))
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
+  (define BOOK-SPLIT-ACTION (qof-book-use-split-action-for-num-field (gnc-get-current-book)))
 
   (define (subtotal-get-info name-sortkey name-subtotal name-date-subtotal info)
     ;; The value of the sorting-key multichoice option.

commit 070c99c1c2142317f093c5a27a1b8ce279030af0
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 09:02:51 2017 +0800

    REFACTOR: centralize DATE-SORTING-TYPES and SUBTOTAL-ENABLED
    
    Also minor whitespace changes

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 5e92334..5f854d6 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -101,12 +101,13 @@ in the Options panel."))
 (define NO-MATCHING-ACCT-TEXT (N_ "No account were found that match the \
 options specified in the Options panels."))
 
+
+(define DATE-SORTING-TYPES (list 'date 'reconciled-date))
+
 ;; The option-values of the sorting key multichoice option, for
 ;; which a subtotal should be enabled.
-(define subtotal-enabled '(account-name
-                           account-code
-                           corresponding-acc-name
-                           corresponding-acc-code))
+(define SUBTOTAL-ENABLED (list 'account-name 'corresponding-acc-name
+                               'account-code 'corresponding-acc-code))
 
 
 (define (add-subheading-row data table width subheading-style)
@@ -119,6 +120,7 @@ options specified in the Options panels."))
 (define (column-uses? param columns-used)
   (cdr (assq param columns-used)))
 
+            
 ;; display an account name depending on the options the user has set
 (define (account-namestring account show-account-code? show-account-name? show-account-full-name?)
   ;;# on multi-line splits we can get an empty ('()) account
@@ -598,7 +600,6 @@ options specified in the Options panels."))
     split-value))
 
 
-(define date-sorting-types (list 'date 'reconciled-date))
 
 (define (trep-options-generator)
 
@@ -750,11 +751,11 @@ tags within description, notes or memo. ")
 
     (define (apply-selectable-by-name-sorting-options)
       (let* ((prime-sortkey-enabled (not (eq? prime-sortkey 'none)))
-             (prime-sortkey-subtotal-enabled (member prime-sortkey subtotal-enabled))
-             (prime-date-sortingtype-enabled (member prime-sortkey date-sorting-types))
+             (prime-sortkey-subtotal-enabled (member prime-sortkey SUBTOTAL-ENABLED))
+             (prime-date-sortingtype-enabled (member prime-sortkey DATE-SORTING-TYPES))
              (sec-sortkey-enabled (not (eq? sec-sortkey 'none)))
-             (sec-sortkey-subtotal-enabled (member sec-sortkey subtotal-enabled))
-             (sec-date-sortingtype-enabled (member sec-sortkey date-sorting-types)))
+             (sec-sortkey-subtotal-enabled (member sec-sortkey SUBTOTAL-ENABLED))
+             (sec-date-sortingtype-enabled (member sec-sortkey DATE-SORTING-TYPES)))
 
         (gnc-option-db-set-option-selectable-by-name
          options pagename-sorting optname-prime-subtotal
@@ -1300,7 +1301,7 @@ Credit Card, and Income accounts."))))))
   (define (subtotal-get-info name-sortkey name-subtotal name-date-subtotal info)
     ;; The value of the sorting-key multichoice option.
     (let ((sortkey (opt-val pagename-sorting name-sortkey)))
-      (if (member sortkey date-sorting-types)
+      (if (member sortkey DATE-SORTING-TYPES)
           ;; If sorting by date, look up the value of the
           ;; date-subtotalling multichoice option and return the
           ;; corresponding funcs in the assoc-list.
@@ -1309,7 +1310,7 @@ Credit Card, and Income accounts."))))))
           ;; subtotalling enabled at all, 2. check whether the
           ;; enable-subtotal boolean option is #t, 3. look up the
           ;; appropriate funcs in the assoc-list.
-          (and (member sortkey subtotal-enabled)
+          (and (member sortkey SUBTOTAL-ENABLED)
                (and (opt-val pagename-sorting name-subtotal)
                     (sortkey-get-info sortkey info))))))
 
@@ -1377,8 +1378,7 @@ Credit Card, and Income accounts."))))))
             ;; error condition: no accounts specified
             (gnc:html-document-add-object!
              document
-             (gnc:html-make-no-account-warning
-              report-title (gnc:report-id report-obj)))
+             (gnc:html-make-no-account-warning report-title (gnc:report-id report-obj)))
 
             ;; error condition: accounts were specified but none matched string/regex
             (gnc:html-document-add-object!
@@ -1472,9 +1472,9 @@ Credit Card, and Income accounts."))))))
                  (gnc:make-html-text
                   (gnc:html-markup-h3
                    (sprintf #f
-                           (_ "From %s to %s")
-                           (gnc-print-date begindate)
-                           (gnc-print-date enddate)))))
+                            (_ "From %s to %s")
+                            (gnc-print-date begindate)
+                            (gnc-print-date enddate)))))
 
                 (gnc:html-document-add-object! document table)))))
 

commit d0c435e73d8638a2027b98655e891960e28c58e3
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 09:49:59 2017 +0800

    REFACTOR: centralize key-choice-list

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index a70bcce..5e92334 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -398,6 +398,13 @@ options specified in the Options panels."))
 (define (sortkey-get-info sortkey info)
   (cdr (assq info (cdr (assq sortkey sortkey-list)))))
 
+(define key-choice-list
+  (map (lambda (sortpair)
+         (vector (car sortpair)
+                 (sortkey-get-info (car sortpair) 'text)
+                 (sortkey-get-info (car sortpair) 'tip)))
+       sortkey-list))
+
 (define (timepair-year tp)    (gnc:timepair-get-year tp))
 (define (timepair-quarter tp) (+ (* 10 (timepair-year tp))  (gnc:timepair-get-quarter tp)))
 (define (timepair-month tp)   (+ (* 100 (timepair-year tp)) (gnc:timepair-get-month tp)))
@@ -728,71 +735,14 @@ tags within description, notes or memo. ")
 
   ;; Sorting options
   
-  (let ((key-choice-list
-         (append
-          (list (vector 'none
-                        (N_ "None")
-                        (N_ "Do not sort."))
-
-                (vector 'account-name
-                        (N_ "Account Name")
-                        (N_ "Sort & subtotal by account name."))
-
-                (vector 'account-code
-                        (N_ "Account Code")
-                        (N_ "Sort & subtotal by account code."))
-
-                (vector 'date
-                        (N_ "Date")
-                        (N_ "Sort by date."))
-
-                (vector 'reconciled-date
-                        (N_ "Reconciled Date")
-                        (N_ "Sort by the Reconciled Date."))
-
-                (vector 'register-order
-                        (N_ "Register Order")
-                        (N_ "Sort as in the register."))
-
-                (vector 'corresponding-acc-name
-                        (N_ "Other Account Name")
-                        (N_ "Sort by account transferred from/to's name."))
-
-                (vector 'corresponding-acc-code
-                        (N_ "Other Account Code")
-                        (N_ "Sort by account transferred from/to's code."))
-
-                (vector 'amount
-                        (N_ "Amount")
-                        (N_ "Sort by amount."))
-
-                (vector 'description
-                        (N_ "Description")
-                        (N_ "Sort by description."))
-
-                (vector 'number
-                        (N_ "Number/Action")
-                        (N_ "Sort by check number/action.")))
-          (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-              (list
-               (vector 't-number
-                       (N_ "Transaction Number")
-                       (N_ "Sort by transaction number.")))
-              '())
-          (list
-           (vector 'memo
-                   (N_ "Memo")
-                   (N_ "Sort by memo.")))))
-
-        (ascending-choice-list
-         (list
-          (vector 'ascend
-                  (N_ "Ascending")
-                  (N_ "Smallest to largest, earliest to latest."))
-          (vector 'descend
-                  (N_ "Descending")
-                  (N_ "Largest to smallest, latest to earliest."))))
 
+  (let ((ascending-choice-list 
+         (list (vector 'ascend
+                       (N_ "Ascending")
+                       (N_ "Smallest to largest, earliest to latest."))
+               (vector 'descend
+                       (N_ "Descending")
+                       (N_ "Largest to smallest, latest to earliest."))))
         (prime-sortkey 'account-name)
         (prime-sortkey-subtotal-true #t)
         (sec-sortkey 'register-order)

commit a2008c492d15d4c3cd1e7ed0b75f74da1e9d44b6
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 09:54:45 2017 +0800

    REFACTOR: centralize date-subtotal-list

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 0c25a5a..a70bcce 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -108,44 +108,6 @@ options specified in the Options panels."))
                            corresponding-acc-name
                            corresponding-acc-code))
 
-(define (timepair-same-year tp-a tp-b)
-  (= (gnc:timepair-get-year tp-a)
-     (gnc:timepair-get-year tp-b)))
-
-(define (timepair-same-quarter tp-a tp-b)
-  (and (timepair-same-year tp-a tp-b)
-       (= (gnc:timepair-get-quarter tp-a)
-          (gnc:timepair-get-quarter tp-b))))
-
-(define (timepair-same-month tp-a tp-b)
-  (and (timepair-same-year tp-a tp-b)
-       (= (gnc:timepair-get-month tp-a)
-          (gnc:timepair-get-month tp-b))))
-
-(define (timepair-same-week tp-a tp-b)
-  (and (timepair-same-year tp-a tp-b)
-       (= (gnc:timepair-get-week tp-a)
-          (gnc:timepair-get-week tp-b))))
-
-(define (split-same-week? a b)
-  (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
-        (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
-    (timepair-same-week tp-a tp-b)))
-
-(define (split-same-month? a b)
-  (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
-        (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
-    (timepair-same-month tp-a tp-b)))
-
-(define (split-same-quarter? a b)
-  (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
-        (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
-    (timepair-same-quarter tp-a tp-b)))
-
-(define (split-same-year? a b)
-  (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
-        (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
-    (timepair-same-year tp-a tp-b)))
 
 (define (add-subheading-row data table width subheading-style)
   (let ((heading-cell (gnc:make-html-table-cell data)))
@@ -436,6 +398,60 @@ options specified in the Options panels."))
 (define (sortkey-get-info sortkey info)
   (cdr (assq info (cdr (assq sortkey sortkey-list)))))
 
+(define (timepair-year tp)    (gnc:timepair-get-year tp))
+(define (timepair-quarter tp) (+ (* 10 (timepair-year tp))  (gnc:timepair-get-quarter tp)))
+(define (timepair-month tp)   (+ (* 100 (timepair-year tp)) (gnc:timepair-get-month tp)))
+(define (timepair-week tp)    (+ (* 100 (timepair-year tp)) (gnc:timepair-get-week tp)))
+(define (split-week a) (timepair-week (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
+(define (split-month a) (timepair-month (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
+(define (split-quarter a) (timepair-quarter (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
+(define (split-year a) (timepair-year (gnc-transaction-get-date-posted (xaccSplitGetParent a))))
+
+(define date-subtotal-list
+  ;; Extra list for date option. Each entry: (cons
+  ;; 'date-subtotal-option-value (vector subtotal-function
+  ;; subtotal-renderer))
+  (list
+   (cons 'none (list
+                (cons 'split-sortvalue #f)
+                (cons 'text (N_ "None"))
+                (cons 'tip (N_ "None."))
+                (cons 'subheading-renderer #f)
+                (cons 'subtotal-renderer #f)))
+   (cons 'weekly (list
+                  (cons 'split-sortvalue split-week)
+                  (cons 'text (N_ "Weekly"))
+                  (cons 'tip (N_ "Weekly."))
+                  (cons 'subheading-renderer render-week-subheading)
+                  (cons 'subtotal-renderer render-week-subtotal)))
+   (cons 'monthly (list
+                   (cons 'split-sortvalue split-month)
+                   (cons 'text (N_ "Monthly"))
+                   (cons 'tip (N_ "Monthly."))
+                   (cons 'subheading-renderer render-month-subheading)
+                   (cons 'subtotal-renderer render-month-subtotal)))
+   (cons 'quarterly (list
+                     (cons 'split-sortvalue split-quarter)
+                     (cons 'text (N_ "Quarterly"))
+                     (cons 'tip (N_ "Quarterly."))
+                     (cons 'subheading-renderer render-quarter-subheading)
+                     (cons 'subtotal-renderer render-quarter-subtotal)))
+   (cons 'yearly (list
+                  (cons 'split-sortvalue split-year)
+                  (cons 'text (N_ "Yearly"))
+                  (cons 'tip (N_ "Yearly."))
+                  (cons 'subheading-renderer render-year-subheading)
+                  (cons 'subtotal-renderer render-year-subtotal)))))
+
+(define (date-subtotal-get-info sortkey info)
+  (cdr (assq info (cdr (assq sortkey date-subtotal-list)))))
+
+(define date-subtotal-choice-list
+  (map (lambda (date-sortpair)
+         (vector (car date-sortpair)
+                 (date-subtotal-get-info (car date-sortpair) 'text)
+                 (date-subtotal-get-info (car date-sortpair) 'tip)))
+       date-subtotal-list))
 
 (define (add-split-row table split column-vector options
                        row-style account-types-to-reverse transaction-row?)
@@ -777,14 +793,6 @@ tags within description, notes or memo. ")
                   (N_ "Descending")
                   (N_ "Largest to smallest, latest to earliest."))))
 
-        (subtotal-choice-list
-         (list
-          (vector 'none (N_ "None") (N_ "None."))
-          (vector 'weekly (N_ "Weekly") (N_ "Weekly."))
-          (vector 'monthly (N_ "Monthly") (N_ "Monthly."))
-          (vector 'quarterly (N_ "Quarterly") (N_ "Quarterly."))
-          (vector 'yearly (N_ "Yearly") (N_ "Yearly."))))
-
         (prime-sortkey 'account-name)
         (prime-sortkey-subtotal-true #t)
         (sec-sortkey 'register-order)
@@ -872,7 +880,7 @@ tags within description, notes or memo. ")
       pagename-sorting optname-prime-date-subtotal
       "e2" (N_ "Do a date subtotal.")
       'monthly
-      subtotal-choice-list))
+      date-subtotal-choice-list))
 
     (gnc:register-trep-option
      (gnc:make-multichoice-option
@@ -908,7 +916,7 @@ tags within description, notes or memo. ")
       pagename-sorting optname-sec-date-subtotal
       "i2" (N_ "Do a date subtotal.")
       'monthly
-      subtotal-choice-list))
+      date-subtotal-choice-list))
 
     (gnc:register-trep-option
      (gnc:make-multichoice-option
@@ -1219,7 +1227,8 @@ Credit Card, and Income accounts."))))))
             (if (and primary-subtotal-pred
                      (or (not next)
                          (and next
-                              (not (primary-subtotal-pred current next)))))
+                              (not (equal? (primary-subtotal-pred current)
+                                           (primary-subtotal-pred next))))))
 
                 (begin
 
@@ -1257,7 +1266,8 @@ Credit Card, and Income accounts."))))))
                 (if (and secondary-subtotal-pred
                          (or (not next)
                              (and next
-                                  (not (secondary-subtotal-pred current next)))))
+                                  (not (equal? (secondary-subtotal-pred current)
+                                               (secondary-subtotal-pred next))))))
 
                     (begin (secondary-subtotal-renderer
                             table width current
@@ -1336,18 +1346,15 @@ Credit Card, and Income accounts."))))))
 (define (trep-renderer report-obj)
   (define options (gnc:report-options report-obj))
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
-  (define (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal
-           comp-index date-index)
+
+  (define (subtotal-get-info name-sortkey name-subtotal name-date-subtotal info)
     ;; The value of the sorting-key multichoice option.
     (let ((sortkey (opt-val pagename-sorting name-sortkey)))
       (if (member sortkey date-sorting-types)
           ;; If sorting by date, look up the value of the
           ;; date-subtotalling multichoice option and return the
           ;; corresponding funcs in the assoc-list.
-          (vector-ref
-           (cdr (assq (opt-val pagename-sorting name-date-subtotal)
-                      date-comp-funcs-assoc-list))
-           date-index)
+          (date-subtotal-get-info (opt-val pagename-sorting name-date-subtotal) info)
           ;; For everything else: 1. check whether sortkey has
           ;; subtotalling enabled at all, 2. check whether the
           ;; enable-subtotal boolean option is #t, 3. look up the
@@ -1356,18 +1363,6 @@ Credit Card, and Income accounts."))))))
                (and (opt-val pagename-sorting name-subtotal)
                     (sortkey-get-info sortkey info))))))
 
-  (define (get-query-sortkey sort-option-value)
-    (vector-ref  (cdr (assq sort-option-value comp-funcs-assoc-list)) 0))
-
-  (define (get-subtotal-pred name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal 1 0))
-
-  (define (get-subheading-renderer name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal 2 1))
-
-  (define (get-subtotal-renderer name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal 3 2))
-
   (define (is-filter-member split account-list)
     (let* ((txn (xaccSplitGetParent split))
            (splitcount (xaccTransCountSplits txn))

commit b9390cead111e9c9d8ef491970b4de83b6b7ecf2
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 09:54:20 2017 +0800

    REFACTOR: centralize sortkey-list

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 40d9f68..0c25a5a 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -322,6 +322,121 @@ options specified in the Options panels."))
                     total-collector def:grand-total-style export?))
 
 
+
+
+(define sortkey-list
+  ;; Defines the different sorting keys, as an association-list 
+  ;; together with the subtotal functions. Each entry: 
+  ;;  'sortkey             - sort parameter sent via qof-query
+  ;;  'split-sortvalue     - function which retrieves number/string used for comparing splits
+  ;;  'text                - text displayed in Display tab
+  ;;  'tip                 - tooltip displayed in Display tab
+  ;;  'subheading-renderer - function which renders the subheading
+  ;;  'subtotal-renderer   - function which renders the subtotal
+  (list (cons 'account-name  (list (cons 'sortkey (list SPLIT-ACCT-FULLNAME))
+                                   (cons 'split-sortvalue (lambda (a) (gnc-account-get-full-name (xaccSplitGetAccount a))))
+                                   (cons 'text (N_ "Account Name"))
+                                   (cons 'tip (N_ "Sort & subtotal by account name."))
+                                   (cons 'subheading-renderer render-account-subheading)
+                                   (cons 'subtotal-renderer render-account-subtotal)))
+        
+        (cons 'account-code (list (cons 'sortkey (list SPLIT-ACCOUNT ACCOUNT-CODE-))
+                                  (cons 'split-sortvalue (lambda (a) (xaccAccountGetCode (xaccSplitGetAccount a))))
+                                  (cons 'text (N_ "Account Code"))
+                                  (cons 'tip (N_ "Sort & subtotal by account code."))
+                                  (cons 'subheading-renderer render-account-subheading)
+                                  (cons 'subtotal-renderer render-account-subtotal)))
+
+        (cons 'date         (list (cons 'sortkey (list SPLIT-TRANS TRANS-DATE-POSTED))
+                                  (cons 'split-sortvalue #f)
+                                  (cons 'text (N_ "Date"))
+                                  (cons 'tip (N_ "Sort by date."))
+                                  (cons 'subheading-renderer #f)
+                                  (cons 'subtotal-renderer #f)))
+
+        (cons 'reconciled-date (list (cons 'sortkey (list SPLIT-DATE-RECONCILED))
+                                     (cons 'split-sortvalue #f)
+                                     (cons 'text (N_ "Reconciled Date"))
+                                     (cons 'tip (N_ "Sort by the Reconciled Date."))
+                                     (cons 'subheading-renderer #f)
+                                     (cons 'subtotal-renderer #f)))
+
+        (cons 'register-order (list (cons 'sortkey (list QUERY-DEFAULT-SORT))
+                                    (cons 'split-sortvalue #f)
+                                    (cons 'text (N_ "Register Order"))
+                                    (cons 'tip (N_ "Sort as in the register."))
+                                    (cons 'subheading-renderer #f)
+                                    (cons 'subtotal-renderer #f)))                                 
+
+        (cons 'corresponding-acc-name (list (cons 'sortkey (list SPLIT-CORR-ACCT-NAME))
+                                            (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountFullName a)))
+                                            (cons 'text (N_ "Other Account Name"))
+                                            (cons 'tip (N_ "Sort by account transferred from/to's name."))
+                                            (cons 'subheading-renderer render-corresponding-account-subheading)
+                                            (cons 'subtotal-renderer render-corresponding-account-subtotal)))
+
+        (cons 'corresponding-acc-code (list (cons 'sortkey (list SPLIT-CORR-ACCT-CODE))
+                                            (cons 'split-sortvalue (lambda (a) (xaccSplitGetCorrAccountCode a)))
+                                            (cons 'text (N_ "Other Account Code"))
+                                            (cons 'tip (N_ "Sort by account transferred from/to's code."))
+                                            (cons 'subheading-renderer render-corresponding-account-subheading)
+                                            (cons 'subtotal-renderer render-corresponding-account-subtotal)))
+
+        (cons 'amount        (list (cons 'sortkey (list SPLIT-VALUE))
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "Amount"))
+                                   (cons 'tip (N_ "Sort by amount."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f)))
+
+        (cons 'description   (list (cons 'sortkey (list SPLIT-TRANS TRANS-DESCRIPTION))
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "Description"))
+                                   (cons 'tip (N_ "Sort by description."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f)))
+
+        (if BOOK-SPLIT-ACTION
+            (cons 'number    (list (cons 'sortkey (list SPLIT-ACTION))
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "Number/Action"))
+                                   (cons 'tip (N_ "Sort by check number/action."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f)))
+
+            (cons 'number    (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "Number"))
+                                   (cons 'tip (N_ "Sort by check/transaction number."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f))))
+
+        (cons 't-number      (list (cons 'sortkey (list SPLIT-TRANS TRANS-NUM))
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "Transaction Number"))
+                                   (cons 'tip (N_ "Sort by transaction number."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f)))
+
+        (cons 'memo          (list (cons 'sortkey (list SPLIT-MEMO))
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "Memo"))
+                                   (cons 'tip (N_ "Sort by memo."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f)))
+
+        (cons 'none          (list (cons 'sortkey '())
+                                   (cons 'split-sortvalue #f)
+                                   (cons 'text (N_ "None"))
+                                   (cons 'tip (N_ "Do not sort."))
+                                   (cons 'subheading-renderer #f)
+                                   (cons 'subtotal-renderer #f)))))
+
+
+(define (sortkey-get-info sortkey info)
+  (cdr (assq info (cdr (assq sortkey sortkey-list)))))
+
+
 (define (add-split-row table split column-vector options
                        row-style account-types-to-reverse transaction-row?)
 
@@ -1221,62 +1336,6 @@ Credit Card, and Income accounts."))))))
 (define (trep-renderer report-obj)
   (define options (gnc:report-options report-obj))
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
-  (define comp-funcs-assoc-list
-    ;; Defines the different sorting keys, together with the
-    ;; subtotal functions. Each entry: (cons
-    ;; 'sorting-key-option-value (vector 'query-sorting-key
-    ;; subtotal-function subtotal-renderer))
-    (list (cons 'account-name  (vector
-                                (list SPLIT-ACCT-FULLNAME)
-                                (lambda (a b) (zero? (xaccSplitCompareAccountFullNames a b))) 
-                                render-account-subheading
-                                render-account-subtotal))
-          (cons 'account-code  (vector
-                                (list SPLIT-ACCOUNT ACCOUNT-CODE-)
-                                (lambda (a b) (zero? (xaccSplitCompareAccountCodes a b)))
-                                render-account-subheading
-                                render-account-subtotal))
-          (cons 'date          (vector
-                                (list SPLIT-TRANS TRANS-DATE-POSTED)
-                                #f #f #f))
-          (cons 'reconciled-date (vector
-                                  (list SPLIT-DATE-RECONCILED)
-                                  #f #f #f))
-          (cons 'register-order (vector
-                                 (list QUERY-DEFAULT-SORT)
-                                 #f #f #f))
-          (cons 'corresponding-acc-name
-                (vector
-                 (list SPLIT-CORR-ACCT-NAME)
-                 (lambda (a b) (zero? (xaccSplitCompareOtherAccountFullNames a b))) 
-                 render-corresponding-account-subheading
-                 render-corresponding-account-subtotal))
-          (cons 'corresponding-acc-code
-                (vector
-                 (list SPLIT-CORR-ACCT-CODE)
-                 (lambda (a b) (zero? (xaccSplitCompareOtherAccountCodes a b)))
-                 render-corresponding-account-subheading
-                 render-corresponding-account-subtotal))
-          (cons 'amount        (vector (list SPLIT-VALUE) #f #f #f))
-          (cons 'description   (vector (list SPLIT-TRANS TRANS-DESCRIPTION) #f #f #f))
-          (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-              (cons 'number    (vector (list SPLIT-ACTION) #f #f #f))
-              (cons 'number    (vector (list SPLIT-TRANS TRANS-NUM) #f #f #f)))
-          (cons 't-number      (vector (list SPLIT-TRANS TRANS-NUM) #f #f #f))
-          (cons 'memo          (vector (list SPLIT-MEMO) #f #f #f))
-          (cons 'none          (vector '() #f #f #f))))
-
-  (define date-comp-funcs-assoc-list
-    ;; Extra list for date option. Each entry: (cons
-    ;; 'date-subtotal-option-value (vector subtotal-function
-    ;; subtotal-renderer))
-    (list
-     (cons 'none (vector #f #f #f))
-     (cons 'weekly (vector split-same-week? render-week-subheading render-week-subtotal))
-     (cons 'monthly (vector split-same-month? render-month-subheading render-month-subtotal))
-     (cons 'quarterly (vector split-same-quarter? render-quarter-subheading render-quarter-subtotal))
-     (cons 'yearly (vector split-same-year? render-year-subheading render-year-subtotal))))
-
   (define (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal
            comp-index date-index)
     ;; The value of the sorting-key multichoice option.
@@ -1295,7 +1354,7 @@ Credit Card, and Income accounts."))))))
           ;; appropriate funcs in the assoc-list.
           (and (member sortkey subtotal-enabled)
                (and (opt-val pagename-sorting name-subtotal)
-                    (vector-ref (cdr (assq sortkey comp-funcs-assoc-list)) comp-index))))))
+                    (sortkey-get-info sortkey info))))))
 
   (define (get-query-sortkey sort-option-value)
     (vector-ref  (cdr (assq sort-option-value comp-funcs-assoc-list)) 0))
@@ -1389,8 +1448,8 @@ Credit Card, and Income accounts."))))))
           (xaccQueryAddAccountMatch query c_account_1 QOF-GUID-MATCH-ANY QOF-QUERY-AND)
           (xaccQueryAddDateMatchTS query #t begindate #t enddate QOF-QUERY-AND)
           (qof-query-set-sort-order query
-                                    (get-query-sortkey primary-key)
-                                    (get-query-sortkey secondary-key)
+                                    (sortkey-get-info primary-key 'sortkey)
+                                    (sortkey-get-info secondary-key 'sortkey)
                                     '())
           (qof-query-set-sort-increasing query
                                          (eq? primary-order 'ascend)
@@ -1436,25 +1495,31 @@ Credit Card, and Income accounts."))))))
 
               (let ((table (make-split-table
                             splits options
-                            (get-subtotal-pred optname-prime-sortkey
+                            (subtotal-get-info optname-prime-sortkey
                                                optname-prime-subtotal
-                                               optname-prime-date-subtotal)
-                            (get-subtotal-pred optname-sec-sortkey
+                                               optname-prime-date-subtotal
+                                               'split-sortvalue)
+                            (subtotal-get-info optname-sec-sortkey
                                                optname-sec-subtotal
-                                               optname-sec-date-subtotal)
-                            (get-subheading-renderer optname-prime-sortkey
-                                                     optname-prime-subtotal
-                                                     optname-prime-date-subtotal)
-                            (get-subheading-renderer optname-sec-sortkey
-                                                     optname-sec-subtotal
-                                                     optname-sec-date-subtotal)
-                            (get-subtotal-renderer   optname-prime-sortkey
-                                                     optname-prime-subtotal
-                                                     optname-prime-date-subtotal)
-                            (get-subtotal-renderer   optname-sec-sortkey
-                                                     optname-sec-subtotal
-                                                     optname-sec-date-subtotal))))
-
+                                               optname-sec-date-subtotal
+                                               'split-sortvalue)
+                            (subtotal-get-info optname-prime-sortkey
+                                               optname-prime-subtotal
+                                               optname-prime-date-subtotal
+                                               'subheading-renderer)
+                            (subtotal-get-info optname-sec-sortkey
+                                               optname-sec-subtotal
+                                               optname-sec-date-subtotal
+                                               'subheading-renderer)
+                            (subtotal-get-info   optname-prime-sortkey
+                                                 optname-prime-subtotal
+                                                 optname-prime-date-subtotal
+                                                 'subtotal-renderer)
+                            (subtotal-get-info   optname-sec-sortkey
+                                                 optname-sec-subtotal
+                                                 optname-sec-date-subtotal
+                                                 'subtotal-renderer))))
+                
                 (gnc:html-document-set-title! document report-title)
 
                 (gnc:html-document-add-object!

commit ff0d7cc2c46c415781d341b1696a7196a7f0fb8b
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 09:52:42 2017 +0800

    REFACTOR: centralize numerous used-* into column-uses? helper function

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 45422ca..40d9f68 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -154,6 +154,9 @@ options specified in the Options panels."))
      table subheading-style
      (list heading-cell))))
 
+(define (column-uses? param columns-used)
+  (cdr (assq param columns-used)))
+
 ;; display an account name depending on the options the user has set
 (define (account-namestring account show-account-code? show-account-name? show-account-full-name?)
   ;;# on multi-line splits we can get an empty ('()) account
@@ -172,6 +175,8 @@ options specified in the Options panels."))
                (xaccAccountGetName account))
            ""))))
 
+                                                   
+
 ;; render an account subheading - column-vector determines what is displayed
 (define (render-account-subheading
          split table width subheading-style column-vector)
@@ -180,9 +185,9 @@ options specified in the Options panels."))
                          (gnc:html-markup-anchor
                           (gnc:account-anchor-text account)
                           (account-namestring account
-                                              (used-sort-account-code      column-vector)
+                                              (column-uses? 'sort-account-code      column-vector)
                                               #t
-                                              (used-sort-account-full-name column-vector))))
+                                              (column-uses? 'sort-account-full-name column-vector))))
                         table width subheading-style)))
 
 (define (render-corresponding-account-subheading
@@ -194,9 +199,9 @@ options specified in the Options panels."))
                               ""
                               (gnc:account-anchor-text account))
                           (account-namestring account
-                                              (used-sort-account-code      column-vector)
+                                              (column-uses? 'sort-account-code      column-vector)
                                               #t
-                                              (used-sort-account-full-name column-vector))))
+                                              (column-uses? 'sort-account-full-name column-vector))))
                         table width subheading-style)))
 
 (define (render-week-subheading split table width subheading-style column-vector)
@@ -262,9 +267,9 @@ options specified in the Options panels."))
          table width split total-collector subtotal-style column-vector export?)
   (add-subtotal-row table width
                     (total-string (account-namestring (xaccSplitGetAccount split)
-                                                      (used-sort-account-code      column-vector)
+                                                      (column-uses? 'sort-account-code      column-vector)
                                                       #t
-                                                      (used-sort-account-full-name column-vector)))
+                                                      (column-uses? 'sort-account-full-name column-vector)))
                     total-collector subtotal-style export?))
 
 (define (render-corresponding-account-subtotal
@@ -272,9 +277,9 @@ options specified in the Options panels."))
   (add-subtotal-row table width
                     (total-string (account-namestring (xaccSplitGetAccount
                                                        (xaccSplitGetOtherSplit split))
-                                                      (used-sort-account-code      column-vector)
+                                                      (column-uses? 'sort-account-code      column-vector)
                                                       #t
-                                                      (used-sort-account-full-name column-vector)))
+                                                      (column-uses? 'sort-account-full-name column-vector)))
                     total-collector subtotal-style export?))
 
 (define (render-week-subtotal
@@ -348,95 +353,99 @@ options specified in the Options panels."))
                        ;; likely match a price on the previous day
                        (timespecCanonicalDayTime trans-date))))
 
-    (if (used-date column-vector)
+    (if (column-uses? 'date column-vector)
         (addto! row-contents
                 (if transaction-row?
-                    (gnc:make-html-table-cell/markup "date-cell"
-                                                     (gnc-print-date (gnc-transaction-get-date-posted parent)))
-                    " ")))
-
-    (if (used-reconciled-date column-vector)
+                    (gnc:make-html-table-cell/markup
+                     "date-cell"
+                     (gnc-print-date trans-date))
+                    "")))
+    
+    (if (column-uses? 'reconciled-date column-vector)
         (addto! row-contents
-                (gnc:make-html-table-cell/markup "date-cell"
-                                                 (let ((date (gnc-split-get-date-reconciled split)))
-                                                   (if (equal? date (cons 0 0))
-                                                       " "
-                                                       (gnc-print-date date))))))
-    (if (used-num column-vector)
+                (gnc:make-html-table-cell/markup
+                 "date-cell"
+                 (let ((date (gnc-split-get-date-reconciled split)))
+                   (if (equal? date (cons 0 0))
+                       ""
+                       (gnc-print-date date))))))
+
+    (if (column-uses? 'num column-vector)
         (addto! row-contents
                 (if transaction-row?
-                    (if (qof-book-use-split-action-for-num-field
-                         (gnc-get-current-book))
+                    (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
                         (let* ((num (gnc-get-num-action parent split))
                                (t-num (if (if (gnc:lookup-option options gnc:pagename-display
                                                                  (N_ "Trans Number"))
                                               (opt-val gnc:pagename-display (N_ "Trans Number"))
-                                              #f)
+                                              "")
                                           (gnc-get-num-action parent #f)
                                           ""))
                                (num-string (if (string-null? t-num)
                                                num
                                                (string-append num "/" t-num))))
-                          (gnc:make-html-table-cell/markup "text-cell"
-                                                           num-string))
+                          (gnc:make-html-table-cell/markup "text-cell" num-string))
                         (gnc:make-html-table-cell/markup "text-cell"
                                                          (gnc-get-num-action parent split)))
-                    " ")))
+                    "")))
 
-    (if (used-description column-vector)
+    (if (column-uses? 'description column-vector)
         (addto! row-contents
                 (if transaction-row?
-                    (gnc:make-html-table-cell/markup "text-cell"
-                                                     (xaccTransGetDescription parent))
-                    " ")))
+                    (gnc:make-html-table-cell/markup
+                     "text-cell"
+                     (xaccTransGetDescription parent))
+                    "")))
 
-    (if (used-memo column-vector)
+    (if (column-uses? 'memo column-vector)
         (let ((memo (xaccSplitGetMemo split)))
-          (if (and (equal? memo "") (used-notes column-vector))
+          (if (and (string-null? memo) (column-uses? 'notes column-vector))
               (addto! row-contents (xaccTransGetNotes parent))
               (addto! row-contents memo))))
 
-    (if (or (used-account-name column-vector) (used-account-code column-vector))
+    (if (or (column-uses? 'account-name column-vector) (column-uses? 'account-code column-vector))
         (addto! row-contents (account-namestring account
-                                                 (used-account-code      column-vector)
-                                                 (used-account-name      column-vector)
-                                                 (used-account-full-name column-vector))))
-
-    (if (or (used-other-account-name column-vector) (used-other-account-code column-vector))
-        (addto! row-contents (account-namestring (xaccSplitGetAccount
-                                                  (xaccSplitGetOtherSplit split))
-                                                 (used-other-account-code      column-vector)
-                                                 (used-other-account-name      column-vector)
-                                                 (used-other-account-full-name column-vector))))
-
-    (if (used-shares column-vector)
+                                                 (column-uses? 'account-code      column-vector)
+                                                 (column-uses? 'account-name      column-vector)
+                                                 (column-uses? 'account-full-name column-vector))))
+
+    (if (or (column-uses? 'other-account-name column-vector) (column-uses? 'other-account-code column-vector))
+        (addto! row-contents (account-namestring (xaccSplitGetAccount (xaccSplitGetOtherSplit split))
+                                                 (column-uses? 'other-account-code      column-vector)
+                                                 (column-uses? 'other-account-name      column-vector)
+                                                 (column-uses? 'other-account-full-name column-vector))))
+
+    (if (column-uses? 'shares column-vector)
         (addto! row-contents (xaccSplitGetAmount split)))
+
+    (if (column-uses? 'price column-vector)
+        (addto! row-contents  (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
+                                                     (xaccSplitGetSharePrice split))))
     
-    (if (used-price column-vector)
-        (addto! row-contents
-                (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
-                                (xaccSplitGetSharePrice split))))
-    
-    (if (used-amount-single column-vector)
+    (if (column-uses? 'amount-single column-vector)
         (addto! row-contents
-                (gnc:make-html-table-cell/markup "number-cell"
-                                                 (gnc:html-transaction-anchor parent split-value))))
+                (gnc:make-html-table-cell/markup
+                 "number-cell" (gnc:html-transaction-anchor parent split-value))))
     
-    (if (used-amount-double-positive column-vector)
+    (if (column-uses? 'amount-double column-vector)        
+
         (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount split-value))
-            (addto! row-contents
-                    (gnc:make-html-table-cell/markup "number-cell"
-                                                     (gnc:html-transaction-anchor parent split-value)))
-            (addto! row-contents " ")))
-    
-    (if (used-amount-double-negative column-vector)
-        (if (gnc-numeric-negative-p (gnc:gnc-monetary-amount split-value))
-            (addto! row-contents
-                    (gnc:make-html-table-cell/markup
-                     "number-cell" (gnc:html-transaction-anchor parent (gnc:monetary-neg split-value))))
-            (addto! row-contents " ")))
+
+            (begin
+              (addto! row-contents
+                      (gnc:make-html-table-cell/markup
+                       "number-cell" (gnc:html-transaction-anchor
+                                      parent split-value)))
+              (addto! row-contents ""))
+        
+            (begin
+              (addto! row-contents "")
+              (addto! row-contents
+                      (gnc:make-html-table-cell/markup
+                       "number-cell" (gnc:html-transaction-anchor
+                                      parent (gnc:monetary-neg split-value)))))))
     
-    (if (used-running-balance column-vector)
+    (if (column-uses? 'running-balance column-vector)
         (begin
           ;(gnc:debug "split is " split)
           ;(gnc:debug "split get balance:" (xaccSplitGetBalance split))
@@ -943,92 +952,73 @@ Credit Card, and Income accounts."))))))
 
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
 
-  (define (used-date columns-used) (vector-ref columns-used 0))
-  (define (used-reconciled-date columns-used) (vector-ref columns-used 1))
-  (define (used-num columns-used) (vector-ref columns-used 2))
-  (define (used-description columns-used) (vector-ref columns-used 3))
-  (define (used-account-name columns-used) (vector-ref columns-used 4))
-  (define (used-other-account-name columns-used) (vector-ref columns-used 5))	
-  (define (used-shares columns-used) (vector-ref columns-used 6))	
-  (define (used-price columns-used) (vector-ref columns-used 7))	
-  (define (used-amount-single columns-used) (vector-ref columns-used 8))	
-  (define (used-amount-double-positive columns-used) (vector-ref columns-used 9))	
-  (define (used-amount-double-negative columns-used) (vector-ref columns-used 10))	
-  (define (used-running-balance columns-used) (vector-ref columns-used 11))
-  (define (used-account-full-name columns-used) (vector-ref columns-used 12))
-  (define (used-memo columns-used) (vector-ref columns-used 13))
-  (define (used-account-code columns-used) (vector-ref columns-used 14))
-  (define (used-other-account-code columns-used) (vector-ref columns-used 15))
-  (define (used-other-account-full-name columns-used) (vector-ref columns-used 16))
-  (define (used-sort-account-code columns-used) (vector-ref columns-used 17))
-  (define (used-sort-account-full-name columns-used) (vector-ref columns-used 18))
-  (define (used-notes columns-used) (vector-ref columns-used 19))
-
   (define (build-columns-used)
     (define is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single))
     (define amount-setting (opt-val gnc:pagename-display (N_ "Amount")))
-    (vector
-     (opt-val gnc:pagename-display (N_ "Date"))
-     (opt-val gnc:pagename-display (N_ "Reconciled Date"))
-     (if (gnc:lookup-option options gnc:pagename-display (N_ "Num"))
-         (opt-val gnc:pagename-display (N_ "Num"))
-         (opt-val gnc:pagename-display (N_ "Num/Action")))
-     (opt-val gnc:pagename-display (N_ "Description"))
-     (opt-val gnc:pagename-display (N_ "Account Name"))
-     (and is-single? (opt-val gnc:pagename-display (N_ "Other Account Name")))
-     (opt-val gnc:pagename-display (N_ "Shares"))
-     (opt-val gnc:pagename-display (N_ "Price"))
-     (eq? amount-setting 'single)
-     (eq? amount-setting 'double)
-     (eq? amount-setting 'double)
-     (opt-val gnc:pagename-display (N_ "Running Balance"))
-     (opt-val gnc:pagename-display (N_ "Use Full Account Name"))
-     (opt-val gnc:pagename-display (N_ "Memo"))
-     (opt-val gnc:pagename-display (N_ "Account Code"))
-     (and is-single? (opt-val gnc:pagename-display (N_ "Other Account Code")))
-     (and is-single? (opt-val gnc:pagename-display (N_ "Use Full Other Account Name")))
-     (opt-val pagename-sorting (N_ "Show Account Code"))
-     (opt-val pagename-sorting (N_ "Show Full Account Name"))
-     (opt-val gnc:pagename-display (N_ "Notes"))))
+    (list (cons 'date (opt-val gnc:pagename-display (N_ "Date")))
+          (cons 'reconciled-date (opt-val gnc:pagename-display (N_ "Reconciled Date")))
+          (cons 'num (if (gnc:lookup-option options gnc:pagename-display (N_ "Num"))
+                         (opt-val gnc:pagename-display (N_ "Num"))
+                         (opt-val gnc:pagename-display (N_ "Num/Action"))))
+          (cons 'description (opt-val gnc:pagename-display (N_ "Description")))
+          (cons 'account-name (opt-val gnc:pagename-display (N_ "Account Name")))
+          (cons 'other-account-name (and is-single?
+                                         (opt-val gnc:pagename-display (N_ "Other Account Name"))))
+          (cons 'shares (opt-val gnc:pagename-display (N_ "Shares")))
+          (cons 'price (opt-val gnc:pagename-display (N_ "Price")))
+          (cons 'amount-single (eq? amount-setting 'single))
+          (cons 'amount-double (eq? amount-setting 'double))
+          (cons 'running-balance (opt-val gnc:pagename-display (N_ "Running Balance")))
+          (cons 'account-full-name (opt-val gnc:pagename-display (N_ "Use Full Account Name")))
+          (cons 'memo (opt-val gnc:pagename-display (N_ "Memo")))
+          (cons 'account-code (opt-val gnc:pagename-display (N_ "Account Code")))
+          (cons 'other-account-code (and is-single?
+                                         (opt-val gnc:pagename-display (N_ "Other Account Code"))))
+          (cons 'other-account-full-name (and is-single?
+                                              (opt-val gnc:pagename-display (N_ "Use Full Other Account Name"))))
+          (cons 'sort-account-code (opt-val pagename-sorting (N_ "Show Account Code")))
+          (cons 'sort-account-full-name (opt-val pagename-sorting (N_ "Show Full Account Name")))
+          (cons 'notes (opt-val gnc:pagename-display (N_ "Notes")))))
 
   (define (make-heading-list columns-used)
     (define (add-if pred? item) (if pred? (list item) '()))
     (append
-     (add-if (used-date columns-used)
+     (add-if (column-uses? 'date columns-used)
              (_ "Date"))
-     (add-if (used-reconciled-date columns-used)
+     (add-if (column-uses? 'reconciled-date columns-used)
              (_ "Reconciled Date"))
-     (add-if (used-num columns-used)
+     (add-if (column-uses? 'num columns-used)
              (if (and (qof-book-use-split-action-for-num-field (gnc-get-current-book))
                       (if (gnc:lookup-option options gnc:pagename-display (N_ "Trans Number"))
                           (opt-val gnc:pagename-display (N_ "Trans Number"))
                           #f))
                  (_ "Num/T-Num")
                  (_ "Num")))
-     (add-if (used-description columns-used)
+     (add-if (column-uses? 'description columns-used)
              (_ "Description"))
-     (add-if (used-memo columns-used)
-             (if (used-notes columns-used)
+     (add-if (column-uses? 'memo columns-used)
+             (if (column-uses? 'notes columns-used)
                  (string-append (_ "Memo") "/" (_ "Notes"))
                  (_ "Memo")))
-     (add-if (or (used-account-name columns-used)
-                 (used-account-code columns-used))
+     (add-if (or (column-uses? 'account-name columns-used)
+                 (column-uses? 'account-code columns-used))
              (_ "Account"))
-     (add-if (or (used-other-account-name columns-used)
-                 (used-other-account-code columns-used))
+     (add-if (or (column-uses? 'other-account-name columns-used)
+                 (column-uses? 'other-account-code columns-used))
              (_ "Transfer from/to"))
-     (add-if (used-shares columns-used)
+     (add-if (column-uses? 'shares columns-used)
              (_ "Shares"))
-     (add-if (used-price columns-used)
+     (add-if (column-uses? 'price columns-used)
              (_ "Price"))
-     (add-if (used-amount-single columns-used)
+     (add-if (column-uses? 'amount-single columns-used)
              (_ "Amount"))
      ;; FIXME: Proper labels: what?
-     (add-if (used-amount-double-positive columns-used)
-             (_ "Debit"))
-     (add-if (used-amount-double-negative columns-used)
-             (_ "Credit"))
-     (add-if (used-running-balance columns-used)
+     (if (column-uses? 'amount-double columns-used)
+         (list
+          (_ "Debit")
+          (_ "Credit"))
+         '())
+     (add-if (column-uses? 'running-balance columns-used)
              (_ "Balance"))))
 
   (let ((work-to-do (length splits))

commit 02905fe38f504f5c6e61d20cf8b2512f7ffc442e
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Dec 22 17:40:11 2017 +0800

    REFACTOR: combine 2 key-choice-list into 1
    
    Previously key-choice-list was selected from 2 lists depending
    on use-split-action setting. This commit combines to 1 list
    with suitable (if) clause in the middle.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 6f9d900..45422ca 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -587,108 +587,62 @@ tags within description, notes or memo. ")
      (vector 'both          (N_ "Both") (N_ "Show both (and include void transactions in totals).")))))
 
   ;; Sorting options
-
-  (let ((key-choice-list
-         (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-             (list (vector 'none
-                           (N_ "None")
-                           (N_ "Do not sort."))
-
-                   (vector 'account-name
-                           (N_ "Account Name")
-                           (N_ "Sort & subtotal by account name."))
-
-                   (vector 'account-code
-                           (N_ "Account Code")
-                           (N_ "Sort & subtotal by account code."))
-
-                   (vector 'date
-                           (N_ "Date")
-                           (N_ "Sort by date."))
-
-                   (vector 'reconciled-date
-                           (N_ "Reconciled Date")
-                           (N_ "Sort by the Reconciled Date."))
-
-                   (vector 'register-order
-                           (N_ "Register Order")
-                           (N_ "Sort as in the register."))
-
-                   (vector 'corresponding-acc-name
-                           (N_ "Other Account Name")
-                           (N_ "Sort by account transferred from/to's name."))
-
-                   (vector 'corresponding-acc-code
-                           (N_ "Other Account Code")
-                           (N_ "Sort by account transferred from/to's code."))
-
-                   (vector 'amount
-                           (N_ "Amount")
-                           (N_ "Sort by amount."))
-
-                   (vector 'description
-                           (N_ "Description")
-                           (N_ "Sort by description."))
-
-                   (vector 'number
-                           (N_ "Number/Action")
-                           (N_ "Sort by check number/action."))
   
-                   (vector 't-number
-                           (N_ "Transaction Number")
-                           (N_ "Sort by transaction number."))
-
-                   (vector 'memo
-                           (N_ "Memo")
-                           (N_ "Sort by memo.")))
-
-             (list (vector 'none
-                           (N_ "None")
-                           (N_ "Do not sort."))
-
-                   (vector 'account-name
-                           (N_ "Account Name")
-                           (N_ "Sort & subtotal by account name."))
-
-                   (vector 'account-code
-                           (N_ "Account Code")
-                           (N_ "Sort & subtotal by account code."))
-
-                   (vector 'date
-                           (N_ "Date")
-                           (N_ "Sort by date."))
-
-                   (vector 'reconciled-date
-                           (N_ "Reconciled Date")
-                           (N_ "Sort by the Reconciled Date."))
-
-                   (vector 'register-order
-                           (N_ "Register Order")
-                           (N_ "Sort as in the register."))
-
-                   (vector 'corresponding-acc-name
-                           (N_ "Other Account Name")
-                           (N_ "Sort by account transferred from/to's name."))
-
-                   (vector 'corresponding-acc-code
-                           (N_ "Other Account Code")
-                           (N_ "Sort by account transferred from/to's code."))
-
-                   (vector 'amount
-                           (N_ "Amount")
-                           (N_ "Sort by amount."))
-
-                   (vector 'description
-                           (N_ "Description")
-                           (N_ "Sort by description."))
-
-                   (vector 'number
-                           (N_ "Number")
-                           (N_ "Sort by check/transaction number."))
-
-                   (vector 'memo
-                           (N_ "Memo")
-                           (N_ "Sort by memo.")))))
+  (let ((key-choice-list
+         (append
+          (list (vector 'none
+                        (N_ "None")
+                        (N_ "Do not sort."))
+
+                (vector 'account-name
+                        (N_ "Account Name")
+                        (N_ "Sort & subtotal by account name."))
+
+                (vector 'account-code
+                        (N_ "Account Code")
+                        (N_ "Sort & subtotal by account code."))
+
+                (vector 'date
+                        (N_ "Date")
+                        (N_ "Sort by date."))
+
+                (vector 'reconciled-date
+                        (N_ "Reconciled Date")
+                        (N_ "Sort by the Reconciled Date."))
+
+                (vector 'register-order
+                        (N_ "Register Order")
+                        (N_ "Sort as in the register."))
+
+                (vector 'corresponding-acc-name
+                        (N_ "Other Account Name")
+                        (N_ "Sort by account transferred from/to's name."))
+
+                (vector 'corresponding-acc-code
+                        (N_ "Other Account Code")
+                        (N_ "Sort by account transferred from/to's code."))
+
+                (vector 'amount
+                        (N_ "Amount")
+                        (N_ "Sort by amount."))
+
+                (vector 'description
+                        (N_ "Description")
+                        (N_ "Sort by description."))
+
+                (vector 'number
+                        (N_ "Number/Action")
+                        (N_ "Sort by check number/action.")))
+          (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
+              (list
+               (vector 't-number
+                       (N_ "Transaction Number")
+                       (N_ "Sort by transaction number.")))
+              '())
+          (list
+           (vector 'memo
+                   (N_ "Memo")
+                   (N_ "Sort by memo.")))))
 
         (ascending-choice-list
          (list

commit ee01038ee5b4c9932ca923f66b396d46334de023
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Fri Dec 22 17:39:38 2017 +0800

    REFACTOR: move some funcs to refactor later

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index d0e5b47..6f9d900 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -108,18 +108,6 @@ options specified in the Options panels."))
                            corresponding-acc-name
                            corresponding-acc-code))
 
-(define (split-account-fullname-same? a b)
-  (= (xaccSplitCompareAccountFullNames a b) 0))
-
-(define (split-account-code-same? a b)
-  (= (xaccSplitCompareAccountCodes a b) 0))
-
-(define (split-otheracct-fullname-same? a b)
-  (= (xaccSplitCompareOtherAccountFullNames a b) 0))
-
-(define (split-otheracct-code-same? a b)
-  (= (xaccSplitCompareOtherAccountCodes a b) 0))
-
 (define (timepair-same-year tp-a tp-b)
   (= (gnc:timepair-get-year tp-a)
      (gnc:timepair-get-year tp-b)))
@@ -163,8 +151,7 @@ options specified in the Options panels."))
   (let ((heading-cell (gnc:make-html-table-cell data)))
     (gnc:html-table-cell-set-colspan! heading-cell width)
     (gnc:html-table-append-row/markup!
-     table
-     subheading-style
+     table subheading-style
      (list heading-cell))))
 
 ;; display an account name depending on the options the user has set
@@ -242,8 +229,7 @@ options specified in the Options panels."))
 
 (define (add-subtotal-row table width subtotal-string subtotal-collector
                           subtotal-style export?)
-  (let ((currency-totals (subtotal-collector 'format gnc:make-gnc-monetary #f))
-        (blanks (gnc:make-html-table-cell/size 1 (- width 1) #f)))
+  (let ((currency-totals (subtotal-collector 'format gnc:make-gnc-monetary #f)))
     (gnc:html-table-append-row/markup!
      table
      subtotal-style
@@ -265,7 +251,7 @@ options specified in the Options panels."))
                  (append!
                   (if export?
                       (gnc:html-make-empty-cells (- width 1))
-                      (list blanks))
+                      (list (gnc:make-html-table-cell/size 1 (- width 1) #f)))
                   (list (gnc:make-html-table-cell/markup
                          "total-number-cell" currency)))))
               (cdr currency-totals))))
@@ -330,168 +316,6 @@ options specified in the Options panels."))
                     (_ "Grand Total")
                     total-collector def:grand-total-style export?))
 
-(define account-types-to-reverse-assoc-list
-  (list (cons 'none '())
-        (cons 'income-expense
-              (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))
-        (cons 'credit-accounts
-              (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE ACCT-TYPE-EQUITY
-                    ACCT-TYPE-CREDIT ACCT-TYPE-INCOME))))
-
-(define (used-date columns-used)
-  (vector-ref columns-used 0))
-(define (used-reconciled-date columns-used)
-  (vector-ref columns-used 1))
-(define (used-num columns-used)
-  (vector-ref columns-used 2))
-(define (used-description columns-used)
-  (vector-ref columns-used 3))
-(define (used-account-name columns-used)
-  (vector-ref columns-used 4))
-(define (used-other-account-name columns-used)
-  (vector-ref columns-used 5))
-(define (used-shares columns-used)
-  (vector-ref columns-used 6))
-(define (used-price columns-used)
-  (vector-ref columns-used 7))
-(define (used-amount-single columns-used)
-  (vector-ref columns-used 8))
-(define (used-amount-double-positive columns-used)
-  (vector-ref columns-used 9))
-(define (used-amount-double-negative columns-used)
-  (vector-ref columns-used 10))
-(define (used-running-balance columns-used)
-  (vector-ref columns-used 11))
-(define (used-account-full-name columns-used)
-  (vector-ref columns-used 12))
-(define (used-memo columns-used)
-  (vector-ref columns-used 13))
-(define (used-account-code columns-used)
-  (vector-ref columns-used 14))
-(define (used-other-account-code columns-used)
-  (vector-ref columns-used 15))
-(define (used-other-account-full-name columns-used)
-  (vector-ref columns-used 16))
-(define (used-sort-account-code columns-used)
-  (vector-ref columns-used 17))
-(define (used-sort-account-full-name columns-used)
-  (vector-ref columns-used 18))
-(define (used-notes columns-used)
-  (vector-ref columns-used 19))
-
-(define columns-used-size 20)
-
-(define (num-columns-required columns-used)
-  (do ((i 0 (+ i 1))
-       (col-req 0 col-req))
-    ((>= i columns-used-size) col-req)
-    ; If column toggle is true, increase column count. But attention:
-    ; some toggles only change the meaning of another toggle. Don't count these modifier toggles
-    (if (and (not (= i 12)) ; Skip Account Full Name toggle - modifies Account Name column
-             (not (= i 16)) ; Skip Other Account Full Name toggle - modifies Other Account Name column
-             (not (= i 17)) ; Skip Sort Account Code - modifies Account Name subheading
-             (not (= i 18)) ; Skip Sort Account Full Name - modifies Account Name subheading
-             (not (= i 19)) ; Skip Note toggle - modifies Memo column
-             (vector-ref columns-used i))
-        (set! col-req (+ col-req 1)))
-    ; Account Code and Account Name share one column so if both were ticked the
-    ; the check above would have set up one column too much. The check below
-    ; will compensate these again.
-    (if (or (and (= i 14) (vector-ref columns-used 14) (vector-ref columns-used 4)) ; Account Code and Name
-            (and (= i 15) (vector-ref columns-used 15) (vector-ref columns-used 5))) ; Other Account Code and Name
-        (set! col-req (- col-req 1)))))
-
-(define (build-column-used options)
-  (define (opt-val section name) (gnc:option-value  (gnc:lookup-option options section name)))
-  (let ((column-list (make-vector columns-used-size #f))
-        (is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single)))
-    (if (opt-val gnc:pagename-display (N_ "Date"))
-        (vector-set! column-list 0 #t))
-    (if (opt-val gnc:pagename-display (N_ "Reconciled Date"))
-        (vector-set! column-list 1 #t))
-    (if (if (gnc:lookup-option options gnc:pagename-display (N_ "Num"))
-            (opt-val gnc:pagename-display (N_ "Num"))
-            (opt-val gnc:pagename-display (N_ "Num/Action")))
-        (vector-set! column-list 2 #t))
-    (if (opt-val gnc:pagename-display (N_ "Description"))
-        (vector-set! column-list 3 #t))
-    (if (opt-val gnc:pagename-display (N_ "Account Name"))
-        (vector-set! column-list 4 #t))
-    (if (and is-single? (opt-val gnc:pagename-display (N_ "Other Account Name")))
-        (vector-set! column-list 5 #t))
-    (if (opt-val gnc:pagename-display (N_ "Shares"))
-        (vector-set! column-list 6 #t))
-    (if (opt-val gnc:pagename-display (N_ "Price"))
-        (vector-set! column-list 7 #t))
-    (let ((amount-setting (opt-val gnc:pagename-display (N_ "Amount"))))
-      (if (eq? amount-setting 'single)
-          (vector-set! column-list 8 #t))
-      (if (eq? amount-setting 'double)
-          (begin (vector-set! column-list 9 #t)
-                 (vector-set! column-list 10 #t))))
-    (if (opt-val gnc:pagename-display (N_ "Running Balance"))
-        (vector-set! column-list 11 #t))
-    (if (opt-val gnc:pagename-display  (N_ "Use Full Account Name"))
-        (vector-set! column-list 12 #t))
-    (if (opt-val gnc:pagename-display (N_ "Memo"))
-        (vector-set! column-list 13 #t))
-    (if (opt-val gnc:pagename-display (N_ "Account Code"))
-        (vector-set! column-list 14 #t))
-    (if (and is-single? (opt-val gnc:pagename-display (N_ "Other Account Code")))
-        (vector-set! column-list 15 #t))
-    (if (and is-single? (opt-val gnc:pagename-display (N_ "Use Full Other Account Name")))
-        (vector-set! column-list 16 #t))
-    (if (opt-val pagename-sorting (N_ "Show Account Code"))
-        (vector-set! column-list 17 #t))
-    (if (opt-val pagename-sorting (N_ "Show Full Account Name"))
-        (vector-set! column-list 18 #t))
-    (if (opt-val gnc:pagename-display (N_ "Notes"))
-        (vector-set! column-list 19 #t))
-    column-list))
-
-(define (make-heading-list column-vector options)
-
-  (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
-
-  (let ((heading-list '()))
-    (if (used-date column-vector)
-        (addto! heading-list (_ "Date")))
-    (if (used-reconciled-date column-vector)
-        (addto! heading-list (_ "Reconciled Date")))
-    (if (used-num column-vector)
-        (addto! heading-list (if (and (qof-book-use-split-action-for-num-field
-                                       (gnc-get-current-book))
-                                      (if (gnc:lookup-option options
-                                                             gnc:pagename-display
-                                                             (N_ "Trans Number"))
-                                          (opt-val gnc:pagename-display (N_ "Trans Number"))
-                                          #f))
-                                 (_ "Num/T-Num")
-                                 (_ "Num"))))
-    (if (used-description column-vector)
-        (addto! heading-list (_ "Description")))
-    (if (used-memo column-vector)
-        (if (used-notes column-vector)
-            (addto! heading-list (string-append (_ "Memo") "/" (_ "Notes")))
-            (addto! heading-list (_ "Memo"))))
-    (if (or (used-account-name column-vector) (used-account-code column-vector))
-        (addto! heading-list (_ "Account")))
-    (if (or (used-other-account-name column-vector) (used-other-account-code column-vector))
-        (addto! heading-list (_ "Transfer from/to")))
-    (if (used-shares column-vector)
-        (addto! heading-list (_ "Shares")))
-    (if (used-price column-vector)
-        (addto! heading-list (_ "Price")))
-    (if (used-amount-single column-vector)
-        (addto! heading-list (_ "Amount")))
-    ;; FIXME: Proper labels: what?
-    (if (used-amount-double-positive column-vector)
-        (addto! heading-list (_ "Debit")))
-    (if (used-amount-double-negative column-vector)
-        (addto! heading-list (_ "Credit")))
-    (if (used-running-balance column-vector)
-        (addto! heading-list (_ "Balance")))
-    (reverse heading-list)))
 
 (define (add-split-row table split column-vector options
                        row-style account-types-to-reverse transaction-row?)
@@ -1138,15 +962,15 @@ tags within description, notes or memo. ")
       gnc:pagename-display (N_ "Sign Reverses")
       "p" (N_ "Reverse amount display for certain account types.")
       'credit-accounts
-      (list        (vector 'none
-                           (N_ "None")
-                           (N_ "Don't change any displayed amounts."))
-                   (vector 'income-expense
-                           (N_ "Income and Expense")
-                           (N_ "Reverse amount display for Income and Expense Accounts."))
-                   (vector 'credit-accounts
-                           (N_ "Credit Accounts")
-                           (N_ "Reverse amount display for Liability, Payable, Equity, \
+      (list (vector 'none
+                    (N_ "None")
+                    (N_ "Don't change any displayed amounts."))
+            (vector 'income-expense
+                    (N_ "Income and Expense")
+                    (N_ "Reverse amount display for Income and Expense Accounts."))
+            (vector 'credit-accounts
+                    (N_ "Credit Accounts")
+                    (N_ "Reverse amount display for Liability, Payable, Equity, \
 Credit Card, and Income accounts."))))))
 
   (gnc:options-set-default-section options gnc:pagename-general)
@@ -1165,26 +989,96 @@ Credit Card, and Income accounts."))))))
 
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
 
+  (define (used-date columns-used) (vector-ref columns-used 0))
+  (define (used-reconciled-date columns-used) (vector-ref columns-used 1))
+  (define (used-num columns-used) (vector-ref columns-used 2))
+  (define (used-description columns-used) (vector-ref columns-used 3))
+  (define (used-account-name columns-used) (vector-ref columns-used 4))
+  (define (used-other-account-name columns-used) (vector-ref columns-used 5))	
+  (define (used-shares columns-used) (vector-ref columns-used 6))	
+  (define (used-price columns-used) (vector-ref columns-used 7))	
+  (define (used-amount-single columns-used) (vector-ref columns-used 8))	
+  (define (used-amount-double-positive columns-used) (vector-ref columns-used 9))	
+  (define (used-amount-double-negative columns-used) (vector-ref columns-used 10))	
+  (define (used-running-balance columns-used) (vector-ref columns-used 11))
+  (define (used-account-full-name columns-used) (vector-ref columns-used 12))
+  (define (used-memo columns-used) (vector-ref columns-used 13))
+  (define (used-account-code columns-used) (vector-ref columns-used 14))
+  (define (used-other-account-code columns-used) (vector-ref columns-used 15))
+  (define (used-other-account-full-name columns-used) (vector-ref columns-used 16))
+  (define (used-sort-account-code columns-used) (vector-ref columns-used 17))
+  (define (used-sort-account-full-name columns-used) (vector-ref columns-used 18))
+  (define (used-notes columns-used) (vector-ref columns-used 19))
+
+  (define (build-columns-used)
+    (define is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single))
+    (define amount-setting (opt-val gnc:pagename-display (N_ "Amount")))
+    (vector
+     (opt-val gnc:pagename-display (N_ "Date"))
+     (opt-val gnc:pagename-display (N_ "Reconciled Date"))
+     (if (gnc:lookup-option options gnc:pagename-display (N_ "Num"))
+         (opt-val gnc:pagename-display (N_ "Num"))
+         (opt-val gnc:pagename-display (N_ "Num/Action")))
+     (opt-val gnc:pagename-display (N_ "Description"))
+     (opt-val gnc:pagename-display (N_ "Account Name"))
+     (and is-single? (opt-val gnc:pagename-display (N_ "Other Account Name")))
+     (opt-val gnc:pagename-display (N_ "Shares"))
+     (opt-val gnc:pagename-display (N_ "Price"))
+     (eq? amount-setting 'single)
+     (eq? amount-setting 'double)
+     (eq? amount-setting 'double)
+     (opt-val gnc:pagename-display (N_ "Running Balance"))
+     (opt-val gnc:pagename-display (N_ "Use Full Account Name"))
+     (opt-val gnc:pagename-display (N_ "Memo"))
+     (opt-val gnc:pagename-display (N_ "Account Code"))
+     (and is-single? (opt-val gnc:pagename-display (N_ "Other Account Code")))
+     (and is-single? (opt-val gnc:pagename-display (N_ "Use Full Other Account Name")))
+     (opt-val pagename-sorting (N_ "Show Account Code"))
+     (opt-val pagename-sorting (N_ "Show Full Account Name"))
+     (opt-val gnc:pagename-display (N_ "Notes"))))
+
+  (define (make-heading-list columns-used)
+    (define (add-if pred? item) (if pred? (list item) '()))
+    (append
+     (add-if (used-date columns-used)
+             (_ "Date"))
+     (add-if (used-reconciled-date columns-used)
+             (_ "Reconciled Date"))
+     (add-if (used-num columns-used)
+             (if (and (qof-book-use-split-action-for-num-field (gnc-get-current-book))
+                      (if (gnc:lookup-option options gnc:pagename-display (N_ "Trans Number"))
+                          (opt-val gnc:pagename-display (N_ "Trans Number"))
+                          #f))
+                 (_ "Num/T-Num")
+                 (_ "Num")))
+     (add-if (used-description columns-used)
+             (_ "Description"))
+     (add-if (used-memo columns-used)
+             (if (used-notes columns-used)
+                 (string-append (_ "Memo") "/" (_ "Notes"))
+                 (_ "Memo")))
+     (add-if (or (used-account-name columns-used)
+                 (used-account-code columns-used))
+             (_ "Account"))
+     (add-if (or (used-other-account-name columns-used)
+                 (used-other-account-code columns-used))
+             (_ "Transfer from/to"))
+     (add-if (used-shares columns-used)
+             (_ "Shares"))
+     (add-if (used-price columns-used)
+             (_ "Price"))
+     (add-if (used-amount-single columns-used)
+             (_ "Amount"))
+     ;; FIXME: Proper labels: what?
+     (add-if (used-amount-double-positive columns-used)
+             (_ "Debit"))
+     (add-if (used-amount-double-negative columns-used)
+             (_ "Credit"))
+     (add-if (used-running-balance columns-used)
+             (_ "Balance"))))
+
   (let ((work-to-do (length splits))
-        (work-done 0)
-        (used-columns (build-column-used options))
-        (account-types-to-reverse
-         (cdr (assq
-               (opt-val gnc:pagename-display (N_ "Sign Reverses"))
-               account-types-to-reverse-assoc-list)))
-        (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
-        (export? (opt-val gnc:pagename-general optname-table-export)))
-
-    (define (add-other-split-rows
-             split table used-columns row-style account-types-to-reverse)
-
-      (let* ((txn (xaccSplitGetParent split))
-             (other-splits (delete split (xaccTransGetSplitList txn))))
-
-        (for-each (lambda (s)
-                    (add-split-row table s used-columns options
-                                   row-style account-types-to-reverse #f))
-                  other-splits)))
+        (work-done 0))
 
     (define (do-rows-with-subtotals splits
                                     table
@@ -1222,24 +1116,34 @@ Credit Card, and Income accounts."))))))
                 (render-grand-total table width total-collector export?)))
 
           (let* ((current (car splits))
-                 (current-row-style (if multi-rows? def:normal-row-style
-                                        (if odd-row? def:normal-row-style
-                                            def:alternate-row-style)))
                  (rest (cdr splits))
                  (next (if (null? rest) #f
-                           (car rest)))
-                 (split-value (add-split-row
-                               table
-                               current
-                               used-columns
-                               options
-                               current-row-style
-                               account-types-to-reverse
-                               #t)))
+                           (car rest))))
+
+            (define split-value (add-split-row
+                                 table
+                                 current
+                                 used-columns
+                                 options
+                                 (if multi-rows? def:normal-row-style
+                                     (if odd-row?
+                                         def:normal-row-style
+                                         def:alternate-row-style))
+                                 account-types-to-reverse
+                                 #t))
+
             (if multi-rows?
-                (add-other-split-rows
-                 current table used-columns def:alternate-row-style
-                 account-types-to-reverse))
+
+                (for-each (lambda (othersplits)
+                            (add-split-row table
+                                           othersplits
+                                           used-columns
+                                           options
+                                           def:alternate-row-style
+                                           account-types-to-reverse
+                                           #f))
+                          (delete current (xaccTransGetSplitList
+                                           (xaccSplitGetParent current)))))
 
             (primary-subtotal-collector 'add
                                         (gnc:gnc-monetary-commodity split-value) 
@@ -1294,8 +1198,7 @@ Credit Card, and Income accounts."))))))
                 (if (and secondary-subtotal-pred
                          (or (not next)
                              (and next
-                                  (not (secondary-subtotal-pred
-                                        current next)))))
+                                  (not (secondary-subtotal-pred current next)))))
 
                     (begin (secondary-subtotal-renderer
                             table width current
@@ -1328,10 +1231,20 @@ Credit Card, and Income accounts."))))))
                                     total-collector))))
 
     (let* ((table (gnc:make-html-table))
-           (width (num-columns-required used-columns)))
-
-      (gnc:html-table-set-col-headers! table
-       (make-heading-list used-columns options))
+           (used-columns (build-columns-used))
+           (headings (make-heading-list used-columns))
+           (width (length headings))
+           (account-types-to-reverse
+            (cdr (assq (opt-val gnc:pagename-display (N_ "Sign Reverses"))
+                       (list (cons 'none '())
+                             (cons 'income-expense (list ACCT-TYPE-INCOME ACCT-TYPE-EXPENSE))
+                             (cons 'credit-accounts  (list ACCT-TYPE-LIABILITY ACCT-TYPE-PAYABLE
+                                                           ACCT-TYPE-EQUITY ACCT-TYPE-CREDIT
+                                                           ACCT-TYPE-INCOME))))))
+           (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
+           (export? (opt-val gnc:pagename-general optname-table-export)))
+
+      (gnc:html-table-set-col-headers! table headings)
 
       (if primary-subheading-renderer
           (primary-subheading-renderer
@@ -1369,47 +1282,45 @@ Credit Card, and Income accounts."))))))
     ;; subtotal functions. Each entry: (cons
     ;; 'sorting-key-option-value (vector 'query-sorting-key
     ;; subtotal-function subtotal-renderer))
-    ;;  (let* ((used-columns (build-column-used options))) ;; tpo: gives unbound variable options?
-    (let* ((used-columns (build-column-used (gnc:report-options report-obj))))
-      (list (cons 'account-name  (vector
-                                  (list SPLIT-ACCT-FULLNAME)
-                                  split-account-fullname-same?
-                                  render-account-subheading
-                                  render-account-subtotal))
-            (cons 'account-code  (vector
-                                  (list SPLIT-ACCOUNT ACCOUNT-CODE-)
-                                  split-account-code-same?
-                                  render-account-subheading
-                                  render-account-subtotal))
-            (cons 'date          (vector
-                                  (list SPLIT-TRANS TRANS-DATE-POSTED)
+    (list (cons 'account-name  (vector
+                                (list SPLIT-ACCT-FULLNAME)
+                                (lambda (a b) (zero? (xaccSplitCompareAccountFullNames a b))) 
+                                render-account-subheading
+                                render-account-subtotal))
+          (cons 'account-code  (vector
+                                (list SPLIT-ACCOUNT ACCOUNT-CODE-)
+                                (lambda (a b) (zero? (xaccSplitCompareAccountCodes a b)))
+                                render-account-subheading
+                                render-account-subtotal))
+          (cons 'date          (vector
+                                (list SPLIT-TRANS TRANS-DATE-POSTED)
+                                #f #f #f))
+          (cons 'reconciled-date (vector
+                                  (list SPLIT-DATE-RECONCILED)
                                   #f #f #f))
-            (cons 'reconciled-date (vector
-                                    (list SPLIT-DATE-RECONCILED)
-                                    #f #f #f))
-            (cons 'register-order (vector
-                                   (list QUERY-DEFAULT-SORT)
-                                   #f #f #f))
-            (cons 'corresponding-acc-name
-                  (vector
-                   (list SPLIT-CORR-ACCT-NAME)
-                   split-otheracct-fullname-same?
-                   render-corresponding-account-subheading
-                   render-corresponding-account-subtotal))
-            (cons 'corresponding-acc-code
-                  (vector
-                   (list SPLIT-CORR-ACCT-CODE)
-                   split-otheracct-code-same?
-                   render-corresponding-account-subheading
-                   render-corresponding-account-subtotal))
-            (cons 'amount        (vector (list SPLIT-VALUE) #f #f #f))
-            (cons 'description   (vector (list SPLIT-TRANS TRANS-DESCRIPTION) #f #f #f))
-            (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-                (cons 'number    (vector (list SPLIT-ACTION) #f #f #f))
-                (cons 'number    (vector (list SPLIT-TRANS TRANS-NUM) #f #f #f)))
-            (cons 't-number      (vector (list SPLIT-TRANS TRANS-NUM) #f #f #f))
-            (cons 'memo          (vector (list SPLIT-MEMO) #f #f #f))
-            (cons 'none          (vector '() #f #f #f)))))
+          (cons 'register-order (vector
+                                 (list QUERY-DEFAULT-SORT)
+                                 #f #f #f))
+          (cons 'corresponding-acc-name
+                (vector
+                 (list SPLIT-CORR-ACCT-NAME)
+                 (lambda (a b) (zero? (xaccSplitCompareOtherAccountFullNames a b))) 
+                 render-corresponding-account-subheading
+                 render-corresponding-account-subtotal))
+          (cons 'corresponding-acc-code
+                (vector
+                 (list SPLIT-CORR-ACCT-CODE)
+                 (lambda (a b) (zero? (xaccSplitCompareOtherAccountCodes a b)))
+                 render-corresponding-account-subheading
+                 render-corresponding-account-subtotal))
+          (cons 'amount        (vector (list SPLIT-VALUE) #f #f #f))
+          (cons 'description   (vector (list SPLIT-TRANS TRANS-DESCRIPTION) #f #f #f))
+          (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
+              (cons 'number    (vector (list SPLIT-ACTION) #f #f #f))
+              (cons 'number    (vector (list SPLIT-TRANS TRANS-NUM) #f #f #f)))
+          (cons 't-number      (vector (list SPLIT-TRANS TRANS-NUM) #f #f #f))
+          (cons 'memo          (vector (list SPLIT-MEMO) #f #f #f))
+          (cons 'none          (vector '() #f #f #f))))
 
   (define date-comp-funcs-assoc-list
     ;; Extra list for date option. Each entry: (cons
@@ -1422,8 +1333,7 @@ Credit Card, and Income accounts."))))))
      (cons 'quarterly (vector split-same-quarter? render-quarter-subheading render-quarter-subtotal))
      (cons 'yearly (vector split-same-year? render-year-subheading render-year-subtotal))))
 
-  (define (get-subtotalstuff-helper
-           name-sortkey name-subtotal name-date-subtotal
+  (define (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal
            comp-index date-index)
     ;; The value of the sorting-key multichoice option.
     (let ((sortkey (opt-val pagename-sorting name-sortkey)))
@@ -1441,32 +1351,19 @@ Credit Card, and Income accounts."))))))
           ;; appropriate funcs in the assoc-list.
           (and (member sortkey subtotal-enabled)
                (and (opt-val pagename-sorting name-subtotal)
-                    (vector-ref
-                     (cdr (assq sortkey comp-funcs-assoc-list))
-                     comp-index))))))
+                    (vector-ref (cdr (assq sortkey comp-funcs-assoc-list)) comp-index))))))
 
   (define (get-query-sortkey sort-option-value)
-    (vector-ref
-     (cdr (assq sort-option-value comp-funcs-assoc-list))
-     0))
-
-  (define (get-subtotal-pred
-           name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper
-     name-sortkey name-subtotal name-date-subtotal
-     1 0))
-
-  (define (get-subheading-renderer
-           name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper
-     name-sortkey name-subtotal name-date-subtotal
-     2 1))
-
-  (define (get-subtotal-renderer
-           name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper
-     name-sortkey name-subtotal name-date-subtotal
-     3 2))
+    (vector-ref  (cdr (assq sort-option-value comp-funcs-assoc-list)) 0))
+
+  (define (get-subtotal-pred name-sortkey name-subtotal name-date-subtotal)
+    (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal 1 0))
+
+  (define (get-subheading-renderer name-sortkey name-subtotal name-date-subtotal)
+    (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal 2 1))
+
+  (define (get-subtotal-renderer name-sortkey name-subtotal name-date-subtotal)
+    (get-subtotalstuff-helper name-sortkey name-subtotal name-date-subtotal 3 2))
 
   (define (is-filter-member split account-list)
     (let* ((txn (xaccSplitGetParent split))
@@ -1489,11 +1386,11 @@ Credit Card, and Income accounts."))))))
   (gnc:report-starting reportname)
 
   (let* ((document (gnc:make-html-document))
-         (c_account_0 (opt-val gnc:pagename-accounts optname-accounts))
          (account-matcher (opt-val pagename-filter optname-account-matcher))
          (account-matcher-regexp (if (opt-val pagename-filter optname-account-matcher-regex)
                                      (make-regexp account-matcher)
                                      #f))
+         (c_account_0 (opt-val gnc:pagename-accounts optname-accounts))
          (c_account_1 (filter
                        (lambda (acc)
                          (if account-matcher-regexp
@@ -1544,7 +1441,6 @@ Credit Card, and Income accounts."))))))
 
         (begin
 
-          ;;(gnc:warn "query is:" query)
           (qof-query-set-book query (gnc-get-current-book))
           (xaccQueryAddAccountMatch query c_account_1 QOF-GUID-MATCH-ANY QOF-QUERY-AND)
           (xaccQueryAddDateMatchTS query #t begindate #t enddate QOF-QUERY-AND)

commit 7127df58dabda5338d81895d450db25dbb36abff
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 14:12:13 2017 +0800

    REFACTOR: always run qof-query-destroyer
    
    Formerly the qof-query-destroyer is only called upon completion
    of a successful report. This commit moves this destroyer to be
    nearer the query call, thereby the destroyer is always called.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index a85d6eb..d0e5b47 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1562,7 +1562,7 @@ Credit Card, and Income accounts."))))))
             (else #f))
           (set! splits (qof-query-run query))
 
-          ;;(gnc:warn "Splits in trep-renderer:" splits)
+          (qof-query-destroy query)
 
           ;; Combined Filter:
           ;; - include/exclude splits to/from selected accounts
@@ -1626,9 +1626,7 @@ Credit Card, and Income accounts."))))))
                            (gnc-print-date begindate)
                            (gnc-print-date enddate)))))
 
-                (gnc:html-document-add-object! document table)
-
-                (qof-query-destroy query)))))
+                (gnc:html-document-add-object! document table)))))
 
     (gnc:report-finished)
 

commit fe757dbe6a924589b484961cfbbe632eae51cf57
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Dec 9 22:28:00 2017 +0800

    ENH: Optimise Transaction Matcher filter
    
    This commit will trigger the transaction matcher only if the search string is not empty. Will speed up filtering.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 686ca8e..a85d6eb 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -1577,7 +1577,8 @@ Credit Card, and Income accounts."))))))
                                                (string-contains str transaction-matcher)))))
                             (and (if (eq? filter-mode 'include) (is-filter-member split c_account_2) #t)
                                  (if (eq? filter-mode 'exclude) (not (is-filter-member split c_account_2)) #t)
-                                 (or (match? (xaccTransGetDescription trans))
+                                 (or (string-null? transaction-matcher) ; null-string = ignore filters
+                                     (match? (xaccTransGetDescription trans))
                                      (match? (xaccTransGetNotes trans))
                                      (match? (xaccSplitGetMemo split)))
                                  (or (not reconcile-status-filter) ; #f = ignore next filter

commit e5a7660ac0b14062cc016f6f6dfe87510c6c3863
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 14:39:33 2017 +0800

    ENH: add reconciled status filtering

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 894f267..686ca8e 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -695,6 +695,16 @@ enable full POSIX regular expressions capabilities. '#work|#family' will match b
 tags within description, notes or memo. ")
     #f))
 
+  (gnc:register-trep-option
+   (gnc:make-multichoice-option
+    pagename-filter optname-reconcile-status
+    "j1" (N_ "Filter by reconcile status.")
+    #f
+    (list (vector #f      (N_ "All")           (N_ "Show All Transactions"))
+          (vector '(#\n)  (N_ "Unreconciled")  (N_ "Unreconciled only"))
+          (vector '(#\c)  (N_ "Cleared")       (N_ "Cleared only"))
+          (vector '(#\y)  (N_ "Reconciled")    (N_ "Reconciled only")))))
+
   ;; Accounts options
 
   ;; account to do report on
@@ -1554,9 +1564,10 @@ Credit Card, and Income accounts."))))))
 
           ;;(gnc:warn "Splits in trep-renderer:" splits)
 
-          ; Combined Filter:
-          ; - include/exclude splits to/from selected accounts
-          ; - substring/regex matcher for Transaction Description/Notes/Memo
+          ;; Combined Filter:
+          ;; - include/exclude splits to/from selected accounts
+          ;; - substring/regex matcher for Transaction Description/Notes/Memo
+          ;; - by reconcile status
           (set! splits (filter
                         (lambda (split)
                           (let* ((trans (xaccSplitGetParent split))
@@ -1568,7 +1579,9 @@ Credit Card, and Income accounts."))))))
                                  (if (eq? filter-mode 'exclude) (not (is-filter-member split c_account_2)) #t)
                                  (or (match? (xaccTransGetDescription trans))
                                      (match? (xaccTransGetNotes trans))
-                                     (match? (xaccSplitGetMemo split))))))
+                                     (match? (xaccSplitGetMemo split)))
+                                 (or (not reconcile-status-filter) ; #f = ignore next filter
+                                     (member (xaccSplitGetReconcile split) reconcile-status-filter)))))
                         splits))
 
           (if (null? splits)

commit 8990553e2eaf453f454480eb54f370f98f4849ac
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 07:10:03 2017 +0800

    ENH: Move Account matcher to Filter tab
    
    This commit moves the Account matcher into the Filtering tab in preparation for further options

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 75caba4..894f267 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -658,6 +658,26 @@ options specified in the Options panels."))
     gnc:pagename-general optname-table-export
     "g" (N_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))
 
+  ;; Filtering Options
+
+  (gnc:register-trep-option
+   (gnc:make-string-option
+    pagename-filter optname-account-matcher
+    "a5" (N_ "Match only accounts whose fullname is matched e.g. ':Travel' will match \
+Expenses:Travel:Holiday and Expenses:Business:Travel. It can be left blank, which will \
+disable the matcher.")
+    ""))
+
+  (gnc:register-trep-option
+   (gnc:make-simple-boolean-option
+    pagename-filter optname-account-matcher-regex
+    "a6"
+    (N_ "By default the account matcher will search substring only. Set this to true to \
+enable full POSIX regular expressions capabilities. 'Car|Flights' will match both \
+Expenses:Car and Expenses:Flights. Use a period (.) to match a single character e.g. \
+'20../.' will match 'Travel 2017/1 London'. ")
+    #f))
+
   (gnc:register-trep-option
    (gnc:make-string-option
     pagename-filter optname-transaction-matcher
@@ -692,23 +712,6 @@ tags within description, notes or memo. ")
     #f #t))
 
   (gnc:register-trep-option
-   (gnc:make-string-option
-    gnc:pagename-accounts optname-account-matcher
-    "a5" (N_ "Match only above accounts whose fullname is matched e.g. ':Travel' will match \
-Expenses:Travel:Holiday and Expenses:Business:Travel. It can be left blank, which will disable \
-the matcher.")
-    ""))
-
-  (gnc:register-trep-option
-   (gnc:make-simple-boolean-option
-    gnc:pagename-accounts optname-account-matcher-regex
-    "a6"
-    (N_ "By default the account matcher will search substring only. Set this to true to enable full \
-POSIX regular expressions capabilities. 'Car|Flights' will match both Expenses:Car and Expenses:Flights. \
-Use a period (.) to match a single character e.g. '20../.' will match 'Travel 2017/1 London'. ")
-    #f))
-
-  (gnc:register-trep-option
    (gnc:make-account-list-option
     gnc:pagename-accounts optname-filterby
     "b" (N_ "Filter on these accounts.")
diff --git a/libgnucash/app-utils/options.scm b/libgnucash/app-utils/options.scm
index 2a8adbf..3bb5e96 100644
--- a/libgnucash/app-utils/options.scm
+++ b/libgnucash/app-utils/options.scm
@@ -1709,6 +1709,7 @@
                                         "Use Full Account Name?" (cons #f "Use Full Account Name")
                                         "Use Full Other Account Name?" (cons #f "Use Full Other Account Name")
                                         "Void Transactions?" (cons #f "Void Transactions")
+                                        "Account Substring" (cons "Filter" "Account Matcher")
                                         ))
                        (name-match (member name new-names-list)))
 

commit 4187cc1cd2d195dd7b127595b780aea5429f18f4
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Dec 9 22:24:58 2017 +0800

    REFACTOR: Delete unused functions
    
    These functions were probably deprecated from prior work

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 4d03d3c..75caba4 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -159,13 +159,6 @@ options specified in the Options panels."))
         (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
     (timepair-same-year tp-a tp-b)))
 
-(define (set-last-row-style! table tag . rest)
-  (let ((arg-list
-         (cons table
-               (cons (- (gnc:html-table-num-rows table) 1)
-                     (cons tag rest)))))
-    (apply gnc:html-table-set-row-style! arg-list)))
-
 (define (add-subheading-row data table width subheading-style)
   (let ((heading-cell (gnc:make-html-table-cell data)))
     (gnc:html-table-cell-set-colspan! heading-cell width)
@@ -803,7 +796,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                    (vector 'number
                            (N_ "Number/Action")
                            (N_ "Sort by check number/action."))
-
+  
                    (vector 't-number
                            (N_ "Transaction Number")
                            (N_ "Sort by transaction number."))
@@ -1146,40 +1139,9 @@ Credit Card, and Income accounts."))))))
   (gnc:options-set-default-section options gnc:pagename-general)
   options)
 
-
-(define (get-primary-subtotal-style options)
-  (let ((bgcolor (gnc:lookup-option options
-                                    (N_ "Colors")
-                                    (N_ "Primary Subtotals/headings"))))
-    (list 'attribute (list "bgcolor" (gnc:color-option->html bgcolor)))))
-
-(define (get-secondary-subtotal-style options)
-  (let ((bgcolor (gnc:lookup-option options
-                                    (N_ "Colors")
-                                    (N_ "Secondary Subtotals/headings"))))
-    (list 'attribute (list "bgcolor" (gnc:color-option->html bgcolor)))))
-
-(define (get-grand-total-style options)
-  (let ((bgcolor (gnc:lookup-option options
-                                    (N_ "Colors")
-                                    (N_ "Grand Total"))))
-    (list 'attribute (list "bgcolor" (gnc:color-option->html bgcolor)))))
-
-(define (get-odd-row-style options)
-  (let ((bgcolor (gnc:lookup-option options
-                                    (N_ "Colors")
-                                    (N_ "Split Odd"))))
-    (list 'attribute (list "bgcolor" (gnc:color-option->html bgcolor)))))
-
-(define (get-even-row-style options)
-  (let ((bgcolor (gnc:lookup-option options
-                                    (N_ "Colors")
-                                    (N_ "Split Even"))))
-    (list 'attribute (list "bgcolor" (gnc:color-option->html bgcolor)))))
-
-
 ;; ;;;;;;;;;;;;;;;;;;;;
 ;; Here comes the big function that builds the whole table.
+
 (define (make-split-table splits options
                           primary-subtotal-pred
                           secondary-subtotal-pred
@@ -1384,6 +1346,8 @@ Credit Card, and Income accounts."))))))
 
 ;; ;;;;;;;;;;;;;;;;;;;;
 ;; Here comes the renderer function for this report.
+
+
 (define (trep-renderer report-obj)
   (define options (gnc:report-options report-obj))
   (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))

commit 3f03cce164ca4896e2ce4ef95a3d8cab46cf4895
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 07:39:57 2017 +0800

    REFACTOR: rename funcs, centralize strings

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index ed50685..4d03d3c 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -9,6 +9,8 @@
 ;; Michael T. Garrison Stuber
 ;; Modified account names display by Tomas Pospisek
 ;; <tpo_deb at sourcepole.ch> with a lot of help from "warlord"
+;; Refactored by Christopher Lam (2017)
+;; - introduced account/transaction substring/regex matcher
 ;;
 ;; This program is free software; you can redistribute it and/or    
 ;; modify it under the terms of the GNU General Public License as   
@@ -37,7 +39,6 @@
 (use-modules (ice-9 regex))
 (use-modules (gnucash gnc-module))
 (use-modules (gnucash gettext))
-
 (use-modules (gnucash printf))
 
 (gnc:module-load "gnucash/report/report-system" 0)
@@ -46,9 +47,18 @@
   `(set! ,alist (cons ,element ,alist)))
 
 ;; Define the strings here to avoid typos and make changes easier.
-
 (define reportname (N_ "Transaction Report"))
+
+;;Accounts
+(define optname-accounts (N_ "Accounts"))
+(define optname-filterby (N_ "Filter By..."))
+(define optname-filtertype (N_ "Filter Type"))
+(define optname-void-transactions (N_ "Void Transactions"))
+
+;;Display
 (define optname-detail-level (N_ "Detail Level"))
+
+;;Sorting
 (define pagename-sorting (N_ "Sorting"))
 (define optname-prime-sortkey (N_ "Primary Key"))
 (define optname-prime-subtotal (N_ "Primary Subtotal"))
@@ -60,22 +70,37 @@
 (define optname-sec-subtotal (N_ "Secondary Subtotal"))
 (define optname-sec-sortorder  (N_ "Secondary Sort Order"))
 (define optname-sec-date-subtotal (N_ "Secondary Subtotal for Date Key"))
-(define optname-void-transactions (N_ "Void Transactions"))
+
+;;General
+(define optname-startdate (N_ "Start Date"))
+(define optname-enddate (N_ "End Date"))
 (define optname-table-export (N_ "Table for Exporting"))
 (define optname-common-currency (N_ "Common Currency"))
 (define optname-currency (N_ "Report's currency"))
-(define optname-account-matcher (N_ "Account Matcher"))
-(define optname-account-matcher-regex (N_ "Account Matcher uses regular expressions for extended matching"))
 
+;;Filtering
 (define pagename-filter (N_ "Filter"))
+(define optname-account-matcher (N_ "Account Matcher"))
+(define optname-account-matcher-regex (N_ "Account Matcher uses regular expressions for extended matching"))
 (define optname-transaction-matcher (N_ "Transaction Matcher"))
 (define optname-transaction-matcher-regex (N_ "Transaction Matcher uses regular expressions for extended matching"))
+(define optname-reconcile-status (N_ "Reconcile Status"))
 
+;;Styles
 (define def:grand-total-style "grand-total")
 (define def:normal-row-style "normal-row")
 (define def:alternate-row-style "alternate-row")
 (define def:primary-subtotal-style "primary-subheading")
 (define def:secondary-subtotal-style "secondary-subheading")
+
+(define NO-MATCHING-TRANS-HEADER (_ "No matching transactions found"))
+(define NO-MATCHING-TRANS-TEXT (_ "No transactions were found that \
+match the time interval and account selection specified \
+in the Options panel."))
+(define NO-MATCHING-ACCT-HEADER (N_ "No matching accounts found"))
+(define NO-MATCHING-ACCT-TEXT (N_ "No account were found that match the \
+options specified in the Options panels."))
+
 ;; The option-values of the sorting key multichoice option, for
 ;; which a subtotal should be enabled.
 (define subtotal-enabled '(account-name
@@ -83,16 +108,16 @@
                            corresponding-acc-name
                            corresponding-acc-code))
 
-(define (split-account-full-name-same-p a b)
+(define (split-account-fullname-same? a b)
   (= (xaccSplitCompareAccountFullNames a b) 0))
 
-(define (split-account-code-same-p a b)
+(define (split-account-code-same? a b)
   (= (xaccSplitCompareAccountCodes a b) 0))
 
-(define (split-same-corr-account-full-name-p a b)
+(define (split-otheracct-fullname-same? a b)
   (= (xaccSplitCompareOtherAccountFullNames a b) 0))
 
-(define (split-same-corr-account-code-p a b)
+(define (split-otheracct-code-same? a b)
   (= (xaccSplitCompareOtherAccountCodes a b) 0))
 
 (define (timepair-same-year tp-a tp-b)
@@ -114,22 +139,22 @@
        (= (gnc:timepair-get-week tp-a)
           (gnc:timepair-get-week tp-b))))
 
-(define (split-same-week-p a b)
+(define (split-same-week? a b)
   (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
         (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
     (timepair-same-week tp-a tp-b)))
 
-(define (split-same-month-p a b)
+(define (split-same-month? a b)
   (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
         (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
     (timepair-same-month tp-a tp-b)))
 
-(define (split-same-quarter-p a b)
+(define (split-same-quarter? a b)
   (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
         (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
     (timepair-same-quarter tp-a tp-b)))
 
-(define (split-same-year-p a b)
+(define (split-same-year? a b)
   (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
         (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
     (timepair-same-year tp-a tp-b)))
@@ -150,19 +175,19 @@
      (list heading-cell))))
 
 ;; display an account name depending on the options the user has set
-(define (account-namestring account show-account-code show-account-name show-account-full-name)
+(define (account-namestring account show-account-code? show-account-name? show-account-full-name?)
   ;;# on multi-line splits we can get an empty ('()) account
   (if (null? account)
       (_ "Split Transaction")
       (string-append
        ;; display account code?
-       (if show-account-code
+       (if show-account-code?
            (string-append (xaccAccountGetCode account) " ")
            "")
        ;; display account name?
-       (if show-account-name
+       (if show-account-name?
            ;; display full account name?
-           (if show-account-full-name
+           (if show-account-full-name?
                (gnc-account-get-full-name account)
                (xaccAccountGetName account))
            ""))))
@@ -185,9 +210,9 @@
   (let ((account (xaccSplitGetAccount (xaccSplitGetOtherSplit split))))
     (add-subheading-row (gnc:make-html-text
                          (gnc:html-markup-anchor
-                          (if (not (null? account))
-                              (gnc:account-anchor-text account)
-                              "")
+                          (if (null? account)
+                              ""
+                              (gnc:account-anchor-text account))
                           (account-namestring account
                                               (used-sort-account-code      column-vector)
                                               #t
@@ -222,11 +247,9 @@
                          (xaccSplitGetParent split))))
                       table width subheading-style))
 
-
 (define (add-subtotal-row table width subtotal-string subtotal-collector
                           subtotal-style export?)
-  (let ((currency-totals (subtotal-collector
-                          'format gnc:make-gnc-monetary #f))
+  (let ((currency-totals (subtotal-collector 'format gnc:make-gnc-monetary #f))
         (blanks (gnc:make-html-table-cell/size 1 (- width 1) #f)))
     (gnc:html-table-append-row/markup!
      table
@@ -308,7 +331,6 @@
                       (total-string (strftime "%Y" tm))
                       total-collector subtotal-style export?)))
 
-
 (define (render-grand-total
          table width total-collector export?)
   (add-subtotal-row table width
@@ -387,9 +409,7 @@
         (set! col-req (- col-req 1)))))
 
 (define (build-column-used options)
-  (define (opt-val section name)
-    (gnc:option-value
-     (gnc:lookup-option options section name)))
+  (define (opt-val section name) (gnc:option-value  (gnc:lookup-option options section name)))
   (let ((column-list (make-vector columns-used-size #f))
         (is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single)))
     (if (opt-val gnc:pagename-display (N_ "Date"))
@@ -437,6 +457,9 @@
     column-list))
 
 (define (make-heading-list column-vector options)
+
+  (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
+
   (let ((heading-list '()))
     (if (used-date column-vector)
         (addto! heading-list (_ "Date")))
@@ -448,10 +471,7 @@
                                       (if (gnc:lookup-option options
                                                              gnc:pagename-display
                                                              (N_ "Trans Number"))
-                                          (gnc:option-value
-                                           (gnc:lookup-option options
-                                                              gnc:pagename-display
-                                                              (N_ "Trans Number")))
+                                          (opt-val gnc:pagename-display (N_ "Trans Number"))
                                           #f))
                                  (_ "Num/T-Num")
                                  (_ "Num"))))
@@ -483,18 +503,15 @@
 (define (add-split-row table split column-vector options
                        row-style account-types-to-reverse transaction-row?)
 
-  (define (opt-val section name)
-    (gnc:option-value
-     (gnc:lookup-option options section name)))
+  (define (opt-val section name) (gnc:option-value  (gnc:lookup-option options section name)))
 
   (let* ((row-contents '())
-         (dummy  (gnc:debug "split is originally" split))
          (parent (xaccSplitGetParent split))
          (account (xaccSplitGetAccount split))
          (account-type (xaccAccountGetType account))
-         (currency (if (not (null? account))
-                       (xaccAccountGetCommodity account)
-                       (gnc-default-currency)))
+         (currency (if (null? account)
+                       (gnc-default-currency)
+                       (xaccAccountGetCommodity account)))
          (report-currency (if (opt-val gnc:pagename-general optname-common-currency)
                               (opt-val gnc:pagename-general optname-currency)
                               currency))
@@ -520,6 +537,7 @@
                     (gnc:make-html-table-cell/markup "date-cell"
                                                      (gnc-print-date (gnc-transaction-get-date-posted parent)))
                     " ")))
+
     (if (used-reconciled-date column-vector)
         (addto! row-contents
                 (gnc:make-html-table-cell/markup "date-cell"
@@ -533,15 +551,13 @@
                     (if (qof-book-use-split-action-for-num-field
                          (gnc-get-current-book))
                         (let* ((num (gnc-get-num-action parent split))
-                               (t-num (if (if (gnc:lookup-option options
-                                                                 gnc:pagename-display
+                               (t-num (if (if (gnc:lookup-option options gnc:pagename-display
                                                                  (N_ "Trans Number"))
-                                              (opt-val gnc:pagename-display
-                                                       (N_ "Trans Number"))
+                                              (opt-val gnc:pagename-display (N_ "Trans Number"))
                                               #f)
                                           (gnc-get-num-action parent #f)
                                           ""))
-                               (num-string (if (equal? t-num "")
+                               (num-string (if (string-null? t-num)
                                                num
                                                (string-append num "/" t-num))))
                           (gnc:make-html-table-cell/markup "text-cell"
@@ -578,54 +594,59 @@
 
     (if (used-shares column-vector)
         (addto! row-contents (xaccSplitGetAmount split)))
+    
     (if (used-price column-vector)
-        (addto!
-         row-contents
-         (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
+        (addto! row-contents
+                (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
                                 (xaccSplitGetSharePrice split))))
+    
     (if (used-amount-single column-vector)
         (addto! row-contents
                 (gnc:make-html-table-cell/markup "number-cell"
                                                  (gnc:html-transaction-anchor parent split-value))))
+    
     (if (used-amount-double-positive column-vector)
         (if (gnc-numeric-positive-p (gnc:gnc-monetary-amount split-value))
             (addto! row-contents
                     (gnc:make-html-table-cell/markup "number-cell"
                                                      (gnc:html-transaction-anchor parent split-value)))
             (addto! row-contents " ")))
+    
     (if (used-amount-double-negative column-vector)
         (if (gnc-numeric-negative-p (gnc:gnc-monetary-amount split-value))
             (addto! row-contents
                     (gnc:make-html-table-cell/markup
                      "number-cell" (gnc:html-transaction-anchor parent (gnc:monetary-neg split-value))))
             (addto! row-contents " ")))
+    
     (if (used-running-balance column-vector)
         (begin
-          (gnc:debug "split is " split)
-          (gnc:debug "split get balance:" (xaccSplitGetBalance split))
+          ;(gnc:debug "split is " split)
+          ;(gnc:debug "split get balance:" (xaccSplitGetBalance split))
           (addto! row-contents
                   (gnc:make-html-table-cell/markup
                    "number-cell"
                    (gnc:make-gnc-monetary currency
                                           (xaccSplitGetBalance split))))))
-    (gnc:html-table-append-row/markup! table row-style
-                                       (reverse row-contents))
+    
+    (gnc:html-table-append-row/markup! table row-style (reverse row-contents))
+
     split-value))
 
 
 (define date-sorting-types (list 'date 'reconciled-date))
 
 (define (trep-options-generator)
-  (define gnc:*transaction-report-options* (gnc:new-options))
+
+  (define options (gnc:new-options))
+
   (define (gnc:register-trep-option new-option)
-    (gnc:register-option gnc:*transaction-report-options* new-option))
+    (gnc:register-option options new-option))
 
   ;; General options
 
   (gnc:options-add-date-interval!
-   gnc:*transaction-report-options*
-   gnc:pagename-general (N_ "Start Date") (N_ "End Date") "a")
-
+   options gnc:pagename-general optname-startdate optname-enddate "a")
 
   (gnc:register-trep-option
    (gnc:make-complex-boolean-option
@@ -633,14 +654,11 @@
     "e" (N_ "Convert all transactions into a common currency.") #f
     #f
     (lambda (x) (gnc-option-db-set-option-selectable-by-name
-                 gnc:*transaction-report-options*
-                 gnc:pagename-general
-                 optname-currency
-                 x))
-    ))
+                 options gnc:pagename-general optname-currency
+                 x))))
 
   (gnc:options-add-currency!
-   gnc:*transaction-report-options* gnc:pagename-general optname-currency "f")
+   options gnc:pagename-general optname-currency "f")
 
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
@@ -669,7 +687,7 @@ tags within description, notes or memo. ")
   ;; account to do report on
   (gnc:register-trep-option
    (gnc:make-account-list-option
-    gnc:pagename-accounts (N_ "Accounts")
+    gnc:pagename-accounts optname-accounts
     "a" (N_ "Report on these accounts.")
     ;; select, by default, no accounts! Selecting all accounts will
     ;; always imply an insanely long waiting time upon opening, and it
@@ -699,7 +717,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
 
   (gnc:register-trep-option
    (gnc:make-account-list-option
-    gnc:pagename-accounts (N_ "Filter By...")
+    gnc:pagename-accounts optname-filterby
     "b" (N_ "Filter on these accounts.")
     (lambda ()
       ;; FIXME : gnc:get-current-accounts disappeared.
@@ -707,15 +725,14 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
              (root (gnc-get-current-root-account))
              (num-accounts (gnc-account-n-children root))
              (first-account (gnc-account-nth-child root 0)))
-        (cond ((not (null? current-accounts))
-               (list (car current-accounts)))
-              ((> num-accounts 0) (list first-account))
+        (cond ((not (null? current-accounts)) (list (car current-accounts)))
+              ((positive? num-accounts) (list first-account))
               (else '()))))
     #f #t))
 
   (gnc:register-trep-option
    (gnc:make-multichoice-option
-    gnc:pagename-accounts (N_ "Filter Type")
+    gnc:pagename-accounts optname-filtertype
     "c" (N_ "Filter account.")
     'none
     (list (vector 'none
@@ -726,9 +743,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                   (N_ "Include transactions to/from filter accounts only."))
           (vector 'exclude
                   (N_ "Exclude Transactions to/from Filter Accounts")
-                  (N_ "Exclude transactions to/from all filter accounts."))
-          )))
-
+                  (N_ "Exclude transactions to/from all filter accounts.")))))
   ;;
 
   (gnc:register-trep-option
@@ -736,24 +751,14 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
     gnc:pagename-accounts optname-void-transactions
     "d" (N_ "How to handle void transactions.")
     'non-void-only
-    (list (vector
-           'non-void-only
-           (N_ "Non-void only")
-           (N_ "Show only non-voided transactions."))
-          (vector
-           'void-only
-           (N_ "Void only")
-           (N_ "Show only voided transactions."))
-          (vector
-           'both
-           (N_ "Both")
-           (N_ "Show both (and include void transactions in totals).")))))
+    (list
+     (vector 'non-void-only (N_ "Non-void only") (N_ "Show only non-voided transactions."))
+     (vector 'void-only     (N_ "Void only") (N_ "Show only voided transactions."))
+     (vector 'both          (N_ "Both") (N_ "Show both (and include void transactions in totals).")))))
 
   ;; Sorting options
 
-  (let ((options gnc:*transaction-report-options*)
-
-        (key-choice-list
+  (let ((key-choice-list
          (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
              (list (vector 'none
                            (N_ "None")
@@ -806,6 +811,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                    (vector 'memo
                            (N_ "Memo")
                            (N_ "Sort by memo.")))
+
              (list (vector 'none
                            (N_ "None")
                            (N_ "Do not sort."))
@@ -1005,8 +1011,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
 
   ;; Display options
 
-  (let ((options gnc:*transaction-report-options*)
-        (disp-memo? #t)
+  (let ((disp-memo? #t)
         (disp-accname? #t)
         (disp-other-accname? #f)
         (is-single? #t))
@@ -1071,7 +1076,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
      (gnc:make-complex-boolean-option
       gnc:pagename-display (N_ "Memo")
       "d"  (N_ "Display the memo?") #t
-      #f
+      disp-memo?
       (lambda (x)
         (set! disp-memo? x)
         (apply-selectable-by-name-display-options))))
@@ -1081,7 +1086,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
      (gnc:make-complex-boolean-option
       gnc:pagename-display (N_ "Account Name")
       "e"  (N_ "Display the account name?") #t
-      #f
+      disp-accname?
       (lambda (x)
         (set! disp-accname? x)
         (apply-selectable-by-name-display-options))))
@@ -1091,7 +1096,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
      (gnc:make-complex-boolean-option
       gnc:pagename-display (N_ "Other Account Name")
       "h5"  (N_ "Display the other account name? (if this is a split transaction, this parameter is guessed).") #f
-      #f
+      disp-other-accname?
       (lambda (x)
         (set! disp-other-accname? x)
         (apply-selectable-by-name-display-options))))
@@ -1118,7 +1123,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
       "m" (N_ "Display the amount?")
       'single
       (list
-       (vector 'none (N_ "None") (N_ "No amount display."))
+       (vector 'none   (N_ "None") (N_ "No amount display."))
        (vector 'single (N_ "Single") (N_ "Single Column Display."))
        (vector 'double (N_ "Double") (N_ "Two Column Display.")))))
 
@@ -1127,25 +1132,20 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
       gnc:pagename-display (N_ "Sign Reverses")
       "p" (N_ "Reverse amount display for certain account types.")
       'credit-accounts
-      (list
-       (vector 'none (N_ "None") (N_ "Don't change any displayed amounts."))
-       (vector 'income-expense (N_ "Income and Expense")
-               (N_ "Reverse amount display for Income and Expense Accounts."))
-       (vector 'credit-accounts (N_ "Credit Accounts")
-               (N_ "Reverse amount display for Liability, Payable, Equity, \
+      (list        (vector 'none
+                           (N_ "None")
+                           (N_ "Don't change any displayed amounts."))
+                   (vector 'income-expense
+                           (N_ "Income and Expense")
+                           (N_ "Reverse amount display for Income and Expense Accounts."))
+                   (vector 'credit-accounts
+                           (N_ "Credit Accounts")
+                           (N_ "Reverse amount display for Liability, Payable, Equity, \
 Credit Card, and Income accounts."))))))
 
+  (gnc:options-set-default-section options gnc:pagename-general)
+  options)
 
-  (gnc:options-set-default-section gnc:*transaction-report-options*
-                                   gnc:pagename-general)
-
-  gnc:*transaction-report-options*)
-
-
-(define (display-date-interval begin end)
-  (let ((begin-string (gnc-print-date begin))
-        (end-string (gnc-print-date end)))
-    (sprintf #f (_ "From %s To %s") begin-string end-string)))
 
 (define (get-primary-subtotal-style options)
   (let ((bgcolor (gnc:lookup-option options
@@ -1188,42 +1188,28 @@ Credit Card, and Income accounts."))))))
                           primary-subtotal-renderer
                           secondary-subtotal-renderer)
 
+  (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
+
   (let ((work-to-do (length splits))
         (work-done 0)
-        (used-columns (build-column-used options)))
-    (define (get-account-types-to-reverse options)
-      (cdr (assq (gnc:option-value
-                  (gnc:lookup-option options
-                                     gnc:pagename-display
-                                     (N_ "Sign Reverses")))
-                 account-types-to-reverse-assoc-list)))
-
-
-    (define (transaction-report-multi-rows-p options)
-      (eq? (gnc:option-value
-            (gnc:lookup-option options gnc:pagename-display optname-detail-level))
-           'multi-line))
-
-    (define (transaction-report-export-p options)
-      (gnc:option-value
-       (gnc:lookup-option options gnc:pagename-general
-                          optname-table-export)))
-
-    (define (add-other-split-rows split table used-columns
-                                  row-style account-types-to-reverse)
-      (define (other-rows-driver split parent table used-columns i)
-        (let ((current (xaccTransGetSplit parent i)))
-          (cond ((null? current) #f)
-                ((equal? current split)
-                 (other-rows-driver split parent table used-columns (+ i 1)))
-                (else (begin
-                        (add-split-row table current used-columns options
-                                       row-style account-types-to-reverse #f)
-                        (other-rows-driver split parent table used-columns
-                                           (+ i 1)))))))
-
-      (other-rows-driver split (xaccSplitGetParent split)
-                         table used-columns 0))
+        (used-columns (build-column-used options))
+        (account-types-to-reverse
+         (cdr (assq
+               (opt-val gnc:pagename-display (N_ "Sign Reverses"))
+               account-types-to-reverse-assoc-list)))
+        (is-multiline? (eq? (opt-val gnc:pagename-display optname-detail-level) 'multi-line))
+        (export? (opt-val gnc:pagename-general optname-table-export)))
+
+    (define (add-other-split-rows
+             split table used-columns row-style account-types-to-reverse)
+
+      (let* ((txn (xaccSplitGetParent split))
+             (other-splits (delete split (xaccTransGetSplitList txn))))
+
+        (for-each (lambda (s)
+                    (add-split-row table s used-columns options
+                                   row-style account-types-to-reverse #f))
+                  other-splits)))
 
     (define (do-rows-with-subtotals splits
                                     table
@@ -1244,16 +1230,20 @@ Credit Card, and Income accounts."))))))
                                     total-collector)
 
       (gnc:report-percent-done (* 100 (/ work-done work-to-do)))
+
       (set! work-done (+ 1 work-done))
+
       (if (null? splits)
+
           (begin
+
             (gnc:html-table-append-row/markup!
-             table
-             def:grand-total-style
+             table def:grand-total-style
              (list
               (gnc:make-html-table-cell/size
                1 width (gnc:make-html-text (gnc:html-markup-hr)))))
-            (if (gnc:option-value (gnc:lookup-option options "Display" "Totals"))
+
+            (if (opt-val gnc:pagename-display "Totals")
                 (render-grand-total table width total-collector export?)))
 
           (let* ((current (car splits))
@@ -1277,15 +1267,13 @@ Credit Card, and Income accounts."))))))
                  account-types-to-reverse))
 
             (primary-subtotal-collector 'add
-                                        (gnc:gnc-monetary-commodity
-                                         split-value)
-                                        (gnc:gnc-monetary-amount
-                                         split-value))
+                                        (gnc:gnc-monetary-commodity split-value) 
+                                        (gnc:gnc-monetary-amount split-value))
+
             (secondary-subtotal-collector 'add
-                                          (gnc:gnc-monetary-commodity
-                                           split-value)
-                                          (gnc:gnc-monetary-amount
-                                           split-value))
+                                          (gnc:gnc-monetary-commodity split-value)
+                                          (gnc:gnc-monetary-amount split-value))
+
             (total-collector 'add
                              (gnc:gnc-monetary-commodity split-value)
                              (gnc:gnc-monetary-amount split-value))
@@ -1294,14 +1282,18 @@ Credit Card, and Income accounts."))))))
                      (or (not next)
                          (and next
                               (not (primary-subtotal-pred current next)))))
+
                 (begin
+
                   (if secondary-subtotal-pred
 
                       (begin
+
                         (secondary-subtotal-renderer
                          table width current
                          secondary-subtotal-collector
                          def:secondary-subtotal-style used-columns export?)
+
                         (secondary-subtotal-collector 'reset #f #f)))
 
                   (primary-subtotal-renderer table width current
@@ -1312,7 +1304,9 @@ Credit Card, and Income accounts."))))))
                   (primary-subtotal-collector 'reset #f #f)
 
                   (if next
+
                       (begin
+
                         (primary-subheading-renderer
                          next table width def:primary-subtotal-style used-columns)
 
@@ -1327,11 +1321,14 @@ Credit Card, and Income accounts."))))))
                              (and next
                                   (not (secondary-subtotal-pred
                                         current next)))))
+
                     (begin (secondary-subtotal-renderer
                             table width current
                             secondary-subtotal-collector
                             def:secondary-subtotal-style used-columns export?)
+
                            (secondary-subtotal-collector 'reset #f #f)
+
                            (if next
                                (secondary-subheading-renderer
                                 next table width
@@ -1356,51 +1353,40 @@ Credit Card, and Income accounts."))))))
                                     total-collector))))
 
     (let* ((table (gnc:make-html-table))
-           (width (num-columns-required used-columns))
-           (multi-rows? (transaction-report-multi-rows-p options))
-           (export? (transaction-report-export-p options))
-           (account-types-to-reverse
-            (get-account-types-to-reverse options)))
-
-      (gnc:html-table-set-col-headers!
-       table
+           (width (num-columns-required used-columns)))
+
+      (gnc:html-table-set-col-headers! table
        (make-heading-list used-columns options))
-      ;;     (gnc:warn "Splits:" splits)
-      (if (not (null? splits))
-          (begin
-            (if primary-subheading-renderer
-                (primary-subheading-renderer
-                 (car splits) table width def:primary-subtotal-style used-columns))
-            (if secondary-subheading-renderer
-                (secondary-subheading-renderer
-                 (car splits) table width def:secondary-subtotal-style used-columns))
-
-            (do-rows-with-subtotals splits table used-columns width
-                                    multi-rows? #t
-                                    export?
-                                    account-types-to-reverse
-                                    primary-subtotal-pred
-                                    secondary-subtotal-pred
-                                    primary-subheading-renderer
-                                    secondary-subheading-renderer
-                                    primary-subtotal-renderer
-                                    secondary-subtotal-renderer
-                                    (gnc:make-commodity-collector)
-                                    (gnc:make-commodity-collector)
-                                    (gnc:make-commodity-collector))))
+
+      (if primary-subheading-renderer
+          (primary-subheading-renderer
+           (car splits) table width def:primary-subtotal-style used-columns))
+
+      (if secondary-subheading-renderer
+          (secondary-subheading-renderer
+           (car splits) table width def:secondary-subtotal-style used-columns))
+
+      (do-rows-with-subtotals splits table used-columns width
+                              is-multiline? #t
+                              export?
+                              account-types-to-reverse
+                              primary-subtotal-pred
+                              secondary-subtotal-pred
+                              primary-subheading-renderer
+                              secondary-subheading-renderer
+                              primary-subtotal-renderer
+                              secondary-subtotal-renderer
+                              (gnc:make-commodity-collector)
+                              (gnc:make-commodity-collector)
+                              (gnc:make-commodity-collector))
 
       table)))
 
 ;; ;;;;;;;;;;;;;;;;;;;;
 ;; Here comes the renderer function for this report.
 (define (trep-renderer report-obj)
-
   (define options (gnc:report-options report-obj))
-
-  (define (opt-val section name)
-    (gnc:option-value
-     (gnc:lookup-option options section name)))
-
+  (define (opt-val section name) (gnc:option-value (gnc:lookup-option options section name)))
   (define comp-funcs-assoc-list
     ;; Defines the different sorting keys, together with the
     ;; subtotal functions. Each entry: (cons
@@ -1410,12 +1396,12 @@ Credit Card, and Income accounts."))))))
     (let* ((used-columns (build-column-used (gnc:report-options report-obj))))
       (list (cons 'account-name  (vector
                                   (list SPLIT-ACCT-FULLNAME)
-                                  split-account-full-name-same-p
+                                  split-account-fullname-same?
                                   render-account-subheading
                                   render-account-subtotal))
             (cons 'account-code  (vector
                                   (list SPLIT-ACCOUNT ACCOUNT-CODE-)
-                                  split-account-code-same-p
+                                  split-account-code-same?
                                   render-account-subheading
                                   render-account-subtotal))
             (cons 'date          (vector
@@ -1430,13 +1416,13 @@ Credit Card, and Income accounts."))))))
             (cons 'corresponding-acc-name
                   (vector
                    (list SPLIT-CORR-ACCT-NAME)
-                   split-same-corr-account-full-name-p
+                   split-otheracct-fullname-same?
                    render-corresponding-account-subheading
                    render-corresponding-account-subtotal))
             (cons 'corresponding-acc-code
                   (vector
                    (list SPLIT-CORR-ACCT-CODE)
-                   split-same-corr-account-code-p
+                   split-otheracct-code-same?
                    render-corresponding-account-subheading
                    render-corresponding-account-subtotal))
             (cons 'amount        (vector (list SPLIT-VALUE) #f #f #f))
@@ -1454,14 +1440,10 @@ Credit Card, and Income accounts."))))))
     ;; subtotal-renderer))
     (list
      (cons 'none (vector #f #f #f))
-     (cons 'weekly (vector split-same-week-p render-week-subheading
-                           render-week-subtotal))
-     (cons 'monthly (vector split-same-month-p render-month-subheading
-                            render-month-subtotal))
-     (cons 'quarterly (vector split-same-quarter-p render-quarter-subheading
-                              render-quarter-subtotal))
-     (cons 'yearly (vector split-same-year-p render-year-subheading
-                           render-year-subtotal))))
+     (cons 'weekly (vector split-same-week? render-week-subheading render-week-subtotal))
+     (cons 'monthly (vector split-same-month? render-month-subheading render-month-subtotal))
+     (cons 'quarterly (vector split-same-quarter? render-quarter-subheading render-quarter-subtotal))
+     (cons 'yearly (vector split-same-year? render-year-subheading render-year-subtotal))))
 
   (define (get-subtotalstuff-helper
            name-sortkey name-subtotal name-date-subtotal
@@ -1509,52 +1491,30 @@ Credit Card, and Income accounts."))))))
      name-sortkey name-subtotal name-date-subtotal
      3 2))
 
-  ;;(define (get-other-account-names account-list)
-  ;;  ( map (lambda (acct)  (gnc-account-get-full-name acct)) account-list))
-
   (define (is-filter-member split account-list)
     (let* ((txn (xaccSplitGetParent split))
-           (splitcount (xaccTransCountSplits txn)))
-
+           (splitcount (xaccTransCountSplits txn))
+           (other-account (xaccSplitGetAccount (xaccSplitGetOtherSplit split)))
+           (splits-equal? (lambda (s1 s2) (xaccSplitEqual s1 s2 #t #f #f)))
+           (other-splits (delete split (xaccTransGetSplitList txn) splits-equal?))
+           (other-accounts (map xaccSplitGetAccount other-splits))
+           (is-in-account-list? (lambda (acc) (member acc account-list))))
       (cond
         ;; A 2-split transaction - test separately so it can be optimized
         ;; to significantly reduce the number of splits to traverse
         ;; in guile code
-        ((= splitcount 2)
-         (let* ((other      (xaccSplitGetOtherSplit split))
-                (other-acct (xaccSplitGetAccount other)))
-           (member other-acct account-list)))
-
+        ((= splitcount 2) (is-in-account-list? other-account))
         ;; A multi-split transaction - run over all splits
-        ((> splitcount 2)
-         (let ((splits (xaccTransGetSplitList txn)))
-
-           ;; Walk through the list of splits.
-           ;; if we reach the end, return #f
-           ;; if the 'this' != 'split' and the split->account is a member
-           ;; of the account-list, then return #t, else recurse
-           (define (is-member splits)
-             (if (null? splits)
-                 #f
-                 (let* ((this (car splits))
-                        (rest (cdr splits))
-                        (acct (xaccSplitGetAccount this)))
-                   (if (and (not (eq? this split))
-                            (member acct account-list))
-                       #t
-                       (is-member rest)))))
-
-           (is-member splits)))
-
+        ((> splitcount 2) (or-map is-in-account-list? other-accounts))
         ;; Single transaction splits
         (else #f))))
 
-
   (gnc:report-starting reportname)
+
   (let* ((document (gnc:make-html-document))
-         (c_account_0 (opt-val gnc:pagename-accounts "Accounts"))
-         (account-matcher (opt-val gnc:pagename-accounts optname-account-matcher))
-         (account-matcher-regexp (if (opt-val gnc:pagename-accounts optname-account-matcher-regex)
+         (c_account_0 (opt-val gnc:pagename-accounts optname-accounts))
+         (account-matcher (opt-val pagename-filter optname-account-matcher))
+         (account-matcher-regexp (if (opt-val pagename-filter optname-account-matcher-regex)
                                      (make-regexp account-matcher)
                                      #f))
          (c_account_1 (filter
@@ -1563,25 +1523,24 @@ Credit Card, and Income accounts."))))))
                              (regexp-exec account-matcher-regexp (gnc-account-get-full-name acc))
                              (string-contains (gnc-account-get-full-name acc) account-matcher)))
                        c_account_0))
-         (c_account_2 (opt-val gnc:pagename-accounts "Filter By..."))
-         (filter-mode (opt-val gnc:pagename-accounts "Filter Type"))
+         (c_account_2 (opt-val gnc:pagename-accounts optname-filterby))
+         (filter-mode (opt-val gnc:pagename-accounts optname-filtertype))
          (begindate (gnc:timepair-start-day-time
                      (gnc:date-option-absolute-time
-                      (opt-val gnc:pagename-general "Start Date"))))
+                      (opt-val gnc:pagename-general optname-startdate))))
          (enddate (gnc:timepair-end-day-time
                    (gnc:date-option-absolute-time
-                    (opt-val gnc:pagename-general "End Date"))))
+                    (opt-val gnc:pagename-general optname-enddate))))
          (transaction-matcher (opt-val pagename-filter optname-transaction-matcher))
          (transaction-matcher-regexp (if (opt-val pagename-filter optname-transaction-matcher-regex)
                                          (make-regexp transaction-matcher)
                                          #f))
-         (report-title (opt-val
-                        gnc:pagename-general
-                        gnc:optname-reportname))
+         (reconcile-status-filter (opt-val pagename-filter optname-reconcile-status))
+         (report-title (opt-val gnc:pagename-general gnc:optname-reportname))
          (primary-key (opt-val pagename-sorting optname-prime-sortkey))
-         (primary-order (opt-val pagename-sorting "Primary Sort Order"))
+         (primary-order (opt-val pagename-sorting optname-prime-sortorder))
          (secondary-key (opt-val pagename-sorting optname-sec-sortkey))
-         (secondary-order (opt-val pagename-sorting "Secondary Sort Order"))
+         (secondary-order (opt-val pagename-sorting optname-sec-sortorder))
          (void-status (opt-val gnc:pagename-accounts optname-void-transactions))
          (splits '())
          (query (qof-query-create-for-splits)))
@@ -1589,32 +1548,41 @@ Credit Card, and Income accounts."))))))
     ;;(gnc:warn "accts in trep-renderer:" c_account_1)
     ;;(gnc:warn "Report Account names:" (get-other-account-names c_account_1))
 
-    (if (not (or (null? c_account_1) (and-map not c_account_1)))
+    (if (or (null? c_account_1) (and-map not c_account_1))
+
+        (if (null? c_account_0)
+
+            ;; error condition: no accounts specified
+            (gnc:html-document-add-object!
+             document
+             (gnc:html-make-no-account-warning
+              report-title (gnc:report-id report-obj)))
+
+            ;; error condition: accounts were specified but none matched string/regex
+            (gnc:html-document-add-object!
+             document
+             (gnc:make-html-text
+              (gnc:html-markup-h2 NO-MATCHING-ACCT-HEADER)
+              (gnc:html-markup-p NO-MATCHING-ACCT-TEXT))))
+
         (begin
-          (qof-query-set-book query (gnc-get-current-book))
+
           ;;(gnc:warn "query is:" query)
-          (xaccQueryAddAccountMatch query
-                                    c_account_1
-                                    QOF-GUID-MATCH-ANY QOF-QUERY-AND)
-          (xaccQueryAddDateMatchTS
-           query #t begindate #t enddate QOF-QUERY-AND)
+          (qof-query-set-book query (gnc-get-current-book))
+          (xaccQueryAddAccountMatch query c_account_1 QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+          (xaccQueryAddDateMatchTS query #t begindate #t enddate QOF-QUERY-AND)
           (qof-query-set-sort-order query
                                     (get-query-sortkey primary-key)
                                     (get-query-sortkey secondary-key)
                                     '())
-
           (qof-query-set-sort-increasing query
                                          (eq? primary-order 'ascend)
                                          (eq? secondary-order 'ascend)
                                          #t)
-
           (case void-status
-            ((non-void-only)
-             (gnc:query-set-match-non-voids-only! query (gnc-get-current-book)))
-            ((void-only)
-             (gnc:query-set-match-voids-only! query (gnc-get-current-book)))
+            ((non-void-only) (gnc:query-set-match-non-voids-only! query (gnc-get-current-book)))
+            ((void-only)     (gnc:query-set-match-voids-only! query (gnc-get-current-book)))
             (else #f))
-
           (set! splits (qof-query-run query))
 
           ;;(gnc:warn "Splits in trep-renderer:" splits)
@@ -1636,71 +1604,53 @@ Credit Card, and Income accounts."))))))
                                      (match? (xaccSplitGetMemo split))))))
                         splits))
 
-          (if (not (null? splits))
-              (let ((table
-                     (make-split-table
-                      splits
-                      options
-                      (get-subtotal-pred optname-prime-sortkey
-                                         optname-prime-subtotal
-                                         optname-prime-date-subtotal)
-                      (get-subtotal-pred optname-sec-sortkey
-                                         optname-sec-subtotal
-                                         optname-sec-date-subtotal)
-                      (get-subheading-renderer optname-prime-sortkey
+          (if (null? splits)
+
+              ;; error condition: no splits found
+              (gnc:html-document-add-object!
+               document
+               (gnc:make-html-text
+                (gnc:html-markup-h2 NO-MATCHING-TRANS-HEADER)
+                (gnc:html-markup-p NO-MATCHING-TRANS-TEXT)))
+
+              (let ((table (make-split-table
+                            splits options
+                            (get-subtotal-pred optname-prime-sortkey
                                                optname-prime-subtotal
                                                optname-prime-date-subtotal)
-                      (get-subheading-renderer optname-sec-sortkey
+                            (get-subtotal-pred optname-sec-sortkey
                                                optname-sec-subtotal
                                                optname-sec-date-subtotal)
-                      (get-subtotal-renderer   optname-prime-sortkey
-                                               optname-prime-subtotal
-                                               optname-prime-date-subtotal)
-                      (get-subtotal-renderer   optname-sec-sortkey
-                                               optname-sec-subtotal
-                                               optname-sec-date-subtotal))))
+                            (get-subheading-renderer optname-prime-sortkey
+                                                     optname-prime-subtotal
+                                                     optname-prime-date-subtotal)
+                            (get-subheading-renderer optname-sec-sortkey
+                                                     optname-sec-subtotal
+                                                     optname-sec-date-subtotal)
+                            (get-subtotal-renderer   optname-prime-sortkey
+                                                     optname-prime-subtotal
+                                                     optname-prime-date-subtotal)
+                            (get-subtotal-renderer   optname-sec-sortkey
+                                                     optname-sec-subtotal
+                                                     optname-sec-date-subtotal))))
+
+                (gnc:html-document-set-title! document report-title)
 
-                (gnc:html-document-set-title! document
-                                              report-title)
                 (gnc:html-document-add-object!
                  document
                  (gnc:make-html-text
                   (gnc:html-markup-h3
-                   (display-date-interval begindate enddate))))
-                (gnc:html-document-add-object!
-                 document
-                 table)
-                (qof-query-destroy query))
-              ;; error condition: no splits found
-              (let ((p (gnc:make-html-text)))
-                (gnc:html-text-append!
-                 p
-                 (gnc:html-markup-h2
-                  (_ "No matching transactions found"))
-                 (gnc:html-markup-p
-                  (_ "No transactions were found that \
-match the time interval and account selection specified \
-in the Options panel.")))
-                (gnc:html-document-add-object! document p))))
-
-        (if (null? c_account_0)
+                   (sprintf #f
+                           (_ "From %s to %s")
+                           (gnc-print-date begindate)
+                           (gnc-print-date enddate)))))
 
-            ;; error condition: no accounts specified
-            (gnc:html-document-add-object!
-             document
-             (gnc:html-make-no-account-warning
-              report-title (gnc:report-id report-obj)))
+                (gnc:html-document-add-object! document table)
 
-            ;; error condition: accounts were specified but none matcher string/regex
-            (gnc:html-document-add-object!
-             document
-             (gnc:make-html-text
-              (gnc:html-markup-h2
-               (N_ "No accounts were matched"))
-              (gnc:html-markup-p
-               (N_ "The account matcher specified in the report options did not match any accounts."))))))
+                (qof-query-destroy query)))))
 
     (gnc:report-finished)
+
     document))
 
 ;; Define the report.
@@ -1712,5 +1662,4 @@ in the Options panel.")))
  'report-guid "2fe3b9833af044abb929a88d5a59620f"
 
  'options-generator trep-options-generator
-
  'renderer trep-renderer)

commit 082811b909c66429157e72688445ec1b541a0f17
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sun Dec 10 06:51:24 2017 +0800

    ***reindent and remove trailing whitespace***

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 4957d2f..ed50685 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -79,7 +79,7 @@
 ;; The option-values of the sorting key multichoice option, for
 ;; which a subtotal should be enabled.
 (define subtotal-enabled '(account-name
-                           account-code 
+                           account-code
                            corresponding-acc-name
                            corresponding-acc-code))
 
@@ -100,23 +100,23 @@
      (gnc:timepair-get-year tp-b)))
 
 (define (timepair-same-quarter tp-a tp-b)
-  (and (timepair-same-year tp-a tp-b) 
+  (and (timepair-same-year tp-a tp-b)
        (= (gnc:timepair-get-quarter tp-a)
           (gnc:timepair-get-quarter tp-b))))
 
 (define (timepair-same-month tp-a tp-b)
-  (and (timepair-same-year tp-a tp-b) 
+  (and (timepair-same-year tp-a tp-b)
        (= (gnc:timepair-get-month tp-a)
           (gnc:timepair-get-month tp-b))))
 
 (define (timepair-same-week tp-a tp-b)
   (and (timepair-same-year tp-a tp-b)
        (= (gnc:timepair-get-week tp-a)
-	  (gnc:timepair-get-week tp-b))))
+          (gnc:timepair-get-week tp-b))))
 
 (define (split-same-week-p a b)
   (let ((tp-a (gnc-transaction-get-date-posted (xaccSplitGetParent a)))
-	(tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
+        (tp-b (gnc-transaction-get-date-posted (xaccSplitGetParent b))))
     (timepair-same-week tp-a tp-b)))
 
 (define (split-same-month-p a b)
@@ -135,8 +135,8 @@
     (timepair-same-year tp-a tp-b)))
 
 (define (set-last-row-style! table tag . rest)
-  (let ((arg-list 
-         (cons table 
+  (let ((arg-list
+         (cons table
                (cons (- (gnc:html-table-num-rows table) 1)
                      (cons tag rest)))))
     (apply gnc:html-table-set-row-style! arg-list)))
@@ -153,19 +153,19 @@
 (define (account-namestring account show-account-code show-account-name show-account-full-name)
   ;;# on multi-line splits we can get an empty ('()) account
   (if (null? account)
-        (_ "Split Transaction")
-        (string-append 
-           ;; display account code?
-           (if show-account-code
-                 (string-append (xaccAccountGetCode account) " ")
-                 "")
-           ;; display account name?
-           (if show-account-name
-                 ;; display full account name?
-                 (if show-account-full-name
-                      (gnc-account-get-full-name account)
-                      (xaccAccountGetName account))
-                 ""))))
+      (_ "Split Transaction")
+      (string-append
+       ;; display account code?
+       (if show-account-code
+           (string-append (xaccAccountGetCode account) " ")
+           "")
+       ;; display account name?
+       (if show-account-name
+           ;; display full account name?
+           (if show-account-full-name
+               (gnc-account-get-full-name account)
+               (xaccAccountGetName account))
+           ""))))
 
 ;; render an account subheading - column-vector determines what is displayed
 (define (render-account-subheading
@@ -173,121 +173,121 @@
   (let ((account (xaccSplitGetAccount split)))
     (add-subheading-row (gnc:make-html-text
                          (gnc:html-markup-anchor
-                           (gnc:account-anchor-text account)
-                           (account-namestring account
-                                               (used-sort-account-code      column-vector)
-                                               #t
-                                               (used-sort-account-full-name column-vector))))
+                          (gnc:account-anchor-text account)
+                          (account-namestring account
+                                              (used-sort-account-code      column-vector)
+                                              #t
+                                              (used-sort-account-full-name column-vector))))
                         table width subheading-style)))
 
-(define (render-corresponding-account-subheading 
+(define (render-corresponding-account-subheading
          split table width subheading-style column-vector)
   (let ((account (xaccSplitGetAccount (xaccSplitGetOtherSplit split))))
     (add-subheading-row (gnc:make-html-text
                          (gnc:html-markup-anchor
                           (if (not (null? account))
-                           (gnc:account-anchor-text account)
-                           "")
-                           (account-namestring account
-                                               (used-sort-account-code      column-vector)
-                                               #t
-                                               (used-sort-account-full-name column-vector))))
+                              (gnc:account-anchor-text account)
+                              "")
+                          (account-namestring account
+                                              (used-sort-account-code      column-vector)
+                                              #t
+                                              (used-sort-account-full-name column-vector))))
                         table width subheading-style)))
 
 (define (render-week-subheading split table width subheading-style column-vector)
   (add-subheading-row (gnc:date-get-week-year-string
-		       (gnc:timepair->date
-			(gnc-transaction-get-date-posted
-			 (xaccSplitGetParent split))))
-		      table width subheading-style))
+                       (gnc:timepair->date
+                        (gnc-transaction-get-date-posted
+                         (xaccSplitGetParent split))))
+                      table width subheading-style))
 
 (define (render-month-subheading split table width subheading-style column-vector)
   (add-subheading-row (gnc:date-get-month-year-string
-                      (gnc:timepair->date 
-                       (gnc-transaction-get-date-posted
-                        (xaccSplitGetParent split))))
-                     table width subheading-style))
+                       (gnc:timepair->date
+                        (gnc-transaction-get-date-posted
+                         (xaccSplitGetParent split))))
+                      table width subheading-style))
 
 (define (render-quarter-subheading split table width subheading-style column-vector)
-  (add-subheading-row (gnc:date-get-quarter-year-string 
-                      (gnc:timepair->date 
-                       (gnc-transaction-get-date-posted
-                        (xaccSplitGetParent split))))
-                     table width subheading-style))
+  (add-subheading-row (gnc:date-get-quarter-year-string
+                       (gnc:timepair->date
+                        (gnc-transaction-get-date-posted
+                         (xaccSplitGetParent split))))
+                      table width subheading-style))
 
 (define (render-year-subheading split table width subheading-style column-vector)
-  (add-subheading-row (gnc:date-get-year-string 
-                      (gnc:timepair->date 
-                       (gnc-transaction-get-date-posted
-                        (xaccSplitGetParent split))))
+  (add-subheading-row (gnc:date-get-year-string
+                       (gnc:timepair->date
+                        (gnc-transaction-get-date-posted
+                         (xaccSplitGetParent split))))
                       table width subheading-style))
 
 
-(define (add-subtotal-row table width subtotal-string subtotal-collector 
+(define (add-subtotal-row table width subtotal-string subtotal-collector
                           subtotal-style export?)
   (let ((currency-totals (subtotal-collector
                           'format gnc:make-gnc-monetary #f))
         (blanks (gnc:make-html-table-cell/size 1 (- width 1) #f)))
     (gnc:html-table-append-row/markup!
      table
-     subtotal-style 
+     subtotal-style
      (if export?
-      (append! (cons (gnc:make-html-table-cell/markup "total-label-cell" subtotal-string)
-                     (gnc:html-make-empty-cells (- width 2)))
-               (list (gnc:make-html-table-cell/markup 
-                      "total-number-cell"
-                      (car currency-totals))))
-     (list (gnc:make-html-table-cell/size/markup 1 (- width 1) "total-label-cell"
-                                          subtotal-string)
-           (gnc:make-html-table-cell/markup 
-            "total-number-cell"
-             (car currency-totals)))))
+         (append! (cons (gnc:make-html-table-cell/markup "total-label-cell" subtotal-string)
+                        (gnc:html-make-empty-cells (- width 2)))
+                  (list (gnc:make-html-table-cell/markup
+                         "total-number-cell"
+                         (car currency-totals))))
+         (list (gnc:make-html-table-cell/size/markup 1 (- width 1) "total-label-cell"
+                                                     subtotal-string)
+               (gnc:make-html-table-cell/markup
+                "total-number-cell"
+                (car currency-totals)))))
     (for-each (lambda (currency)
-                (gnc:html-table-append-row/markup! 
+                (gnc:html-table-append-row/markup!
                  table
                  subtotal-style
                  (append!
                   (if export?
-                   (gnc:html-make-empty-cells (- width 1))
-                   (list blanks))
-                         (list (gnc:make-html-table-cell/markup
-                                "total-number-cell" currency)))))
+                      (gnc:html-make-empty-cells (- width 1))
+                      (list blanks))
+                  (list (gnc:make-html-table-cell/markup
+                         "total-number-cell" currency)))))
               (cdr currency-totals))))
 
 (define (total-string str) (string-append (_ "Total For ") str))
 
-(define (render-account-subtotal 
+(define (render-account-subtotal
          table width split total-collector subtotal-style column-vector export?)
-    (add-subtotal-row table width 
-                      (total-string (account-namestring (xaccSplitGetAccount split)
-                                                        (used-sort-account-code      column-vector)
-                                                        #t
-                                                        (used-sort-account-full-name column-vector)))
-                      total-collector subtotal-style export?))
+  (add-subtotal-row table width
+                    (total-string (account-namestring (xaccSplitGetAccount split)
+                                                      (used-sort-account-code      column-vector)
+                                                      #t
+                                                      (used-sort-account-full-name column-vector)))
+                    total-collector subtotal-style export?))
 
 (define (render-corresponding-account-subtotal
          table width split total-collector subtotal-style column-vector export?)
-    (add-subtotal-row table width
-                      (total-string (account-namestring (xaccSplitGetAccount
-                                                          (xaccSplitGetOtherSplit split))
-                                                        (used-sort-account-code      column-vector)
-                                                        #t
-                                                        (used-sort-account-full-name column-vector)))
+  (add-subtotal-row table width
+                    (total-string (account-namestring (xaccSplitGetAccount
+                                                       (xaccSplitGetOtherSplit split))
+                                                      (used-sort-account-code      column-vector)
+                                                      #t
+                                                      (used-sort-account-full-name column-vector)))
                     total-collector subtotal-style export?))
 
 (define (render-week-subtotal
-	 table width split total-collector subtotal-style column-vector export?)
+         table width split total-collector subtotal-style column-vector export?)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
-				 (xaccSplitGetParent split)))))
+                                 (xaccSplitGetParent split)))))
     (add-subtotal-row table width
-		      (total-string (gnc:date-get-week-year-string tm))
-		      total-collector subtotal-style export?)))
+                      (total-string (gnc:date-get-week-year-string tm))
+                      total-collector subtotal-style export?)))
 
 (define (render-month-subtotal
          table width split total-collector subtotal-style column-vector export?)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width 
+    (add-subtotal-row table width
                       (total-string (gnc:date-get-month-year-string tm))
                       total-collector subtotal-style export?)))
 
@@ -296,15 +296,15 @@
          table width split total-collector subtotal-style column-vector export?)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width 
+    (add-subtotal-row table width
                       (total-string (gnc:date-get-quarter-year-string tm))
-                     total-collector subtotal-style export?)))
+                      total-collector subtotal-style export?)))
 
 (define (render-year-subtotal
          table width split total-collector subtotal-style column-vector export?)
   (let ((tm (gnc:timepair->date (gnc-transaction-get-date-posted
                                  (xaccSplitGetParent split)))))
-    (add-subtotal-row table width 
+    (add-subtotal-row table width
                       (total-string (strftime "%Y" tm))
                       total-collector subtotal-style export?)))
 
@@ -334,17 +334,17 @@
 (define (used-account-name columns-used)
   (vector-ref columns-used 4))
 (define (used-other-account-name columns-used)
-  (vector-ref columns-used 5))	
+  (vector-ref columns-used 5))
 (define (used-shares columns-used)
-  (vector-ref columns-used 6))	
+  (vector-ref columns-used 6))
 (define (used-price columns-used)
-  (vector-ref columns-used 7))	
+  (vector-ref columns-used 7))
 (define (used-amount-single columns-used)
-  (vector-ref columns-used 8))	
+  (vector-ref columns-used 8))
 (define (used-amount-double-positive columns-used)
-  (vector-ref columns-used 9))	
+  (vector-ref columns-used 9))
 (define (used-amount-double-negative columns-used)
-  (vector-ref columns-used 10))	
+  (vector-ref columns-used 10))
 (define (used-running-balance columns-used)
   (vector-ref columns-used 11))
 (define (used-account-full-name columns-used)
@@ -366,10 +366,10 @@
 
 (define columns-used-size 20)
 
-(define (num-columns-required columns-used)  
-  (do ((i 0 (+ i 1)) 
-       (col-req 0 col-req)) 
-      ((>= i columns-used-size) col-req)
+(define (num-columns-required columns-used)
+  (do ((i 0 (+ i 1))
+       (col-req 0 col-req))
+    ((>= i columns-used-size) col-req)
     ; If column toggle is true, increase column count. But attention:
     ; some toggles only change the meaning of another toggle. Don't count these modifier toggles
     (if (and (not (= i 12)) ; Skip Account Full Name toggle - modifies Account Name column
@@ -378,17 +378,17 @@
              (not (= i 18)) ; Skip Sort Account Full Name - modifies Account Name subheading
              (not (= i 19)) ; Skip Note toggle - modifies Memo column
              (vector-ref columns-used i))
-      (set! col-req (+ col-req 1)))
+        (set! col-req (+ col-req 1)))
     ; Account Code and Account Name share one column so if both were ticked the
     ; the check above would have set up one column too much. The check below
     ; will compensate these again.
     (if (or (and (= i 14) (vector-ref columns-used 14) (vector-ref columns-used 4)) ; Account Code and Name
             (and (= i 15) (vector-ref columns-used 15) (vector-ref columns-used 5))) ; Other Account Code and Name
-      (set! col-req (- col-req 1)))))
+        (set! col-req (- col-req 1)))))
 
-(define (build-column-used options)   
+(define (build-column-used options)
   (define (opt-val section name)
-    (gnc:option-value 
+    (gnc:option-value
      (gnc:lookup-option options section name)))
   (let ((column-list (make-vector columns-used-size #f))
         (is-single? (eq? (opt-val gnc:pagename-display optname-detail-level) 'single)))
@@ -444,14 +444,14 @@
         (addto! heading-list (_ "Reconciled Date")))
     (if (used-num column-vector)
         (addto! heading-list (if (and (qof-book-use-split-action-for-num-field
-                                                        (gnc-get-current-book))
+                                       (gnc-get-current-book))
                                       (if (gnc:lookup-option options
-                                                    gnc:pagename-display
-                                                    (N_ "Trans Number"))
-                                          (gnc:option-value 
-                                            (gnc:lookup-option options
-                                                    gnc:pagename-display
-                                                    (N_ "Trans Number")))
+                                                             gnc:pagename-display
+                                                             (N_ "Trans Number"))
+                                          (gnc:option-value
+                                           (gnc:lookup-option options
+                                                              gnc:pagename-display
+                                                              (N_ "Trans Number")))
                                           #f))
                                  (_ "Num/T-Num")
                                  (_ "Num"))))
@@ -484,7 +484,7 @@
                        row-style account-types-to-reverse transaction-row?)
 
   (define (opt-val section name)
-    (gnc:option-value 
+    (gnc:option-value
      (gnc:lookup-option options section name)))
 
   (let* ((row-contents '())
@@ -495,92 +495,92 @@
          (currency (if (not (null? account))
                        (xaccAccountGetCommodity account)
                        (gnc-default-currency)))
-	 (report-currency (if (opt-val gnc:pagename-general optname-common-currency)
-			       (opt-val gnc:pagename-general optname-currency)
-			       currency))
+         (report-currency (if (opt-val gnc:pagename-general optname-common-currency)
+                              (opt-val gnc:pagename-general optname-currency)
+                              currency))
          (damount (if (gnc:split-voided? split)
-					 (xaccSplitVoidFormerAmount split)
-					 (xaccSplitGetAmount split)))
-	 (trans-date (gnc-transaction-get-date-posted parent))
-	 (split-value (gnc:exchange-by-pricedb-nearest
-		       (gnc:make-gnc-monetary 
-			currency
-			(if (member account-type account-types-to-reverse) 
-			    (gnc-numeric-neg damount)
-			    damount))
-		       report-currency
-		       ;; Use midday as the transaction time so it matches a price
-		       ;; on the same day.  Otherwise it uses midnight which will
-		       ;; likely match a price on the previous day
-		       (timespecCanonicalDayTime trans-date))))
-    
+                      (xaccSplitVoidFormerAmount split)
+                      (xaccSplitGetAmount split)))
+         (trans-date (gnc-transaction-get-date-posted parent))
+         (split-value (gnc:exchange-by-pricedb-nearest
+                       (gnc:make-gnc-monetary
+                        currency
+                        (if (member account-type account-types-to-reverse)
+                            (gnc-numeric-neg damount)
+                            damount))
+                       report-currency
+                       ;; Use midday as the transaction time so it matches a price
+                       ;; on the same day.  Otherwise it uses midnight which will
+                       ;; likely match a price on the previous day
+                       (timespecCanonicalDayTime trans-date))))
+
     (if (used-date column-vector)
         (addto! row-contents
                 (if transaction-row?
                     (gnc:make-html-table-cell/markup "date-cell"
-                        (gnc-print-date (gnc-transaction-get-date-posted parent)))
+                                                     (gnc-print-date (gnc-transaction-get-date-posted parent)))
                     " ")))
     (if (used-reconciled-date column-vector)
         (addto! row-contents
                 (gnc:make-html-table-cell/markup "date-cell"
-		    (let ((date (gnc-split-get-date-reconciled split)))
-		      (if (equal? date (cons 0 0))
-		          " "
-		          (gnc-print-date date))))))
+                                                 (let ((date (gnc-split-get-date-reconciled split)))
+                                                   (if (equal? date (cons 0 0))
+                                                       " "
+                                                       (gnc-print-date date))))))
     (if (used-num column-vector)
         (addto! row-contents
                 (if transaction-row?
                     (if (qof-book-use-split-action-for-num-field
-                                                        (gnc-get-current-book))
+                         (gnc-get-current-book))
                         (let* ((num (gnc-get-num-action parent split))
                                (t-num (if (if (gnc:lookup-option options
-                                                    gnc:pagename-display
-                                                    (N_ "Trans Number"))
+                                                                 gnc:pagename-display
+                                                                 (N_ "Trans Number"))
                                               (opt-val gnc:pagename-display
-                                                    (N_ "Trans Number"))
+                                                       (N_ "Trans Number"))
                                               #f)
                                           (gnc-get-num-action parent #f)
                                           ""))
                                (num-string (if (equal? t-num "")
                                                num
                                                (string-append num "/" t-num))))
-                              (gnc:make-html-table-cell/markup "text-cell"
-                                   num-string))
+                          (gnc:make-html-table-cell/markup "text-cell"
+                                                           num-string))
                         (gnc:make-html-table-cell/markup "text-cell"
-                            (gnc-get-num-action parent split)))
+                                                         (gnc-get-num-action parent split)))
                     " ")))
 
     (if (used-description column-vector)
         (addto! row-contents
                 (if transaction-row?
                     (gnc:make-html-table-cell/markup "text-cell"
-                        (xaccTransGetDescription parent))
+                                                     (xaccTransGetDescription parent))
                     " ")))
-    
+
     (if (used-memo column-vector)
         (let ((memo (xaccSplitGetMemo split)))
           (if (and (equal? memo "") (used-notes column-vector))
               (addto! row-contents (xaccTransGetNotes parent))
               (addto! row-contents memo))))
-    
+
     (if (or (used-account-name column-vector) (used-account-code column-vector))
-       (addto! row-contents (account-namestring account
-                                                (used-account-code      column-vector)
-                                                (used-account-name      column-vector)
-                                                (used-account-full-name column-vector))))
-    
+        (addto! row-contents (account-namestring account
+                                                 (used-account-code      column-vector)
+                                                 (used-account-name      column-vector)
+                                                 (used-account-full-name column-vector))))
+
     (if (or (used-other-account-name column-vector) (used-other-account-code column-vector))
-       (addto! row-contents (account-namestring (xaccSplitGetAccount
-                                                   (xaccSplitGetOtherSplit split))
-                                                (used-other-account-code      column-vector)
-                                                (used-other-account-name      column-vector)
-                                                (used-other-account-full-name column-vector))))
-    
+        (addto! row-contents (account-namestring (xaccSplitGetAccount
+                                                  (xaccSplitGetOtherSplit split))
+                                                 (used-other-account-code      column-vector)
+                                                 (used-other-account-name      column-vector)
+                                                 (used-other-account-full-name column-vector))))
+
     (if (used-shares column-vector)
         (addto! row-contents (xaccSplitGetAmount split)))
     (if (used-price column-vector)
-        (addto! 
-         row-contents 
+        (addto!
+         row-contents
          (gnc:make-gnc-monetary (xaccTransGetCurrency parent)
                                 (xaccSplitGetSharePrice split))))
     (if (used-amount-single column-vector)
@@ -600,15 +600,15 @@
                      "number-cell" (gnc:html-transaction-anchor parent (gnc:monetary-neg split-value))))
             (addto! row-contents " ")))
     (if (used-running-balance column-vector)
-	(begin
-	  (gnc:debug "split is " split)
-	  (gnc:debug "split get balance:" (xaccSplitGetBalance split))
-	  (addto! row-contents
-		  (gnc:make-html-table-cell/markup
-		   "number-cell"
-		   (gnc:make-gnc-monetary currency
-					  (xaccSplitGetBalance split))))))
-	(gnc:html-table-append-row/markup! table row-style
+        (begin
+          (gnc:debug "split is " split)
+          (gnc:debug "split get balance:" (xaccSplitGetBalance split))
+          (addto! row-contents
+                  (gnc:make-html-table-cell/markup
+                   "number-cell"
+                   (gnc:make-gnc-monetary currency
+                                          (xaccSplitGetBalance split))))))
+    (gnc:html-table-append-row/markup! table row-style
                                        (reverse row-contents))
     split-value))
 
@@ -619,24 +619,24 @@
   (define gnc:*transaction-report-options* (gnc:new-options))
   (define (gnc:register-trep-option new-option)
     (gnc:register-option gnc:*transaction-report-options* new-option))
-  
+
   ;; General options
-  
+
   (gnc:options-add-date-interval!
    gnc:*transaction-report-options*
    gnc:pagename-general (N_ "Start Date") (N_ "End Date") "a")
-  
-  
+
+
   (gnc:register-trep-option
    (gnc:make-complex-boolean-option
     gnc:pagename-general optname-common-currency
     "e" (N_ "Convert all transactions into a common currency.") #f
     #f
     (lambda (x) (gnc-option-db-set-option-selectable-by-name
-		 gnc:*transaction-report-options*
-		 gnc:pagename-general
-		 optname-currency
-		 x))
+                 gnc:*transaction-report-options*
+                 gnc:pagename-general
+                 optname-currency
+                 x))
     ))
 
   (gnc:options-add-currency!
@@ -645,7 +645,7 @@
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
     gnc:pagename-general optname-table-export
-    "g" (N_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))  
+    "g" (N_ "Formats the table suitable for cut & paste exporting with extra cells.") #f))
 
   (gnc:register-trep-option
    (gnc:make-string-option
@@ -665,7 +665,7 @@ tags within description, notes or memo. ")
     #f))
 
   ;; Accounts options
-  
+
   ;; account to do report on
   (gnc:register-trep-option
    (gnc:make-account-list-option
@@ -704,13 +704,13 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
     (lambda ()
       ;; FIXME : gnc:get-current-accounts disappeared.
       (let* ((current-accounts '())
-	     (root (gnc-get-current-root-account))
-	     (num-accounts (gnc-account-n-children root))
-	     (first-account (gnc-account-nth-child root 0)))
-	(cond ((not (null? current-accounts))
-	       (list (car current-accounts)))
-	      ((> num-accounts 0) (list first-account))
-	      (else '()))))
+             (root (gnc-get-current-root-account))
+             (num-accounts (gnc-account-n-children root))
+             (first-account (gnc-account-nth-child root 0)))
+        (cond ((not (null? current-accounts))
+               (list (car current-accounts)))
+              ((> num-accounts 0) (list first-account))
+              (else '()))))
     #f #t))
 
   (gnc:register-trep-option
@@ -719,15 +719,15 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
     "c" (N_ "Filter account.")
     'none
     (list (vector 'none
-		  (N_ "None")
-		  (N_ "Do not do any filtering."))
-	  (vector 'include
-		  (N_ "Include Transactions to/from Filter Accounts")
-		  (N_ "Include transactions to/from filter accounts only."))
-	  (vector 'exclude
-		  (N_ "Exclude Transactions to/from Filter Accounts")
-		  (N_ "Exclude transactions to/from all filter accounts."))
-	  )))
+                  (N_ "None")
+                  (N_ "Do not do any filtering."))
+          (vector 'include
+                  (N_ "Include Transactions to/from Filter Accounts")
+                  (N_ "Include transactions to/from filter accounts only."))
+          (vector 'exclude
+                  (N_ "Exclude Transactions to/from Filter Accounts")
+                  (N_ "Exclude transactions to/from all filter accounts."))
+          )))
 
   ;;
 
@@ -737,23 +737,23 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
     "d" (N_ "How to handle void transactions.")
     'non-void-only
     (list (vector
-	   'non-void-only
-	   (N_ "Non-void only")
-	   (N_ "Show only non-voided transactions."))
-	  (vector
-	   'void-only
-	   (N_ "Void only")
-	   (N_ "Show only voided transactions."))
-	  (vector 
-	   'both
-	   (N_ "Both")
-	   (N_ "Show both (and include void transactions in totals).")))))
+           'non-void-only
+           (N_ "Non-void only")
+           (N_ "Show only non-voided transactions."))
+          (vector
+           'void-only
+           (N_ "Void only")
+           (N_ "Show only voided transactions."))
+          (vector
+           'both
+           (N_ "Both")
+           (N_ "Show both (and include void transactions in totals).")))))
 
   ;; Sorting options
-      
+
   (let ((options gnc:*transaction-report-options*)
 
-        (key-choice-list 
+        (key-choice-list
          (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
              (list (vector 'none
                            (N_ "None")
@@ -779,22 +779,22 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                            (N_ "Register Order")
                            (N_ "Sort as in the register."))
 
-                   (vector 'corresponding-acc-name 
+                   (vector 'corresponding-acc-name
                            (N_ "Other Account Name")
                            (N_ "Sort by account transferred from/to's name."))
 
                    (vector 'corresponding-acc-code
                            (N_ "Other Account Code")
                            (N_ "Sort by account transferred from/to's code."))
-               
+
                    (vector 'amount
                            (N_ "Amount")
                            (N_ "Sort by amount."))
-               
+
                    (vector 'description
                            (N_ "Description")
                            (N_ "Sort by description."))
-               
+
                    (vector 'number
                            (N_ "Number/Action")
                            (N_ "Sort by check number/action."))
@@ -802,7 +802,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                    (vector 't-number
                            (N_ "Transaction Number")
                            (N_ "Sort by transaction number."))
-               
+
                    (vector 'memo
                            (N_ "Memo")
                            (N_ "Sort by memo.")))
@@ -830,22 +830,22 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                            (N_ "Register Order")
                            (N_ "Sort as in the register."))
 
-                   (vector 'corresponding-acc-name 
+                   (vector 'corresponding-acc-name
                            (N_ "Other Account Name")
                            (N_ "Sort by account transferred from/to's name."))
 
                    (vector 'corresponding-acc-code
                            (N_ "Other Account Code")
                            (N_ "Sort by account transferred from/to's code."))
-               
+
                    (vector 'amount
                            (N_ "Amount")
                            (N_ "Sort by amount."))
-               
+
                    (vector 'description
                            (N_ "Description")
                            (N_ "Sort by description."))
-               
+
                    (vector 'number
                            (N_ "Number")
                            (N_ "Sort by check/transaction number."))
@@ -854,7 +854,7 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                            (N_ "Memo")
                            (N_ "Sort by memo.")))))
 
-        (ascending-choice-list 
+        (ascending-choice-list
          (list
           (vector 'ascend
                   (N_ "Ascending")
@@ -928,21 +928,21 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
       (lambda (x)
         (set! prime-sortkey x)
         (apply-selectable-by-name-sorting-options))))
-    
+
     (gnc:register-trep-option
      (gnc:make-simple-boolean-option
       pagename-sorting optname-full-account-name
       "j1"
       (N_ "Show the full account name for subtotals and subtitles?")
       #f))
-    
+
     (gnc:register-trep-option
      (gnc:make-simple-boolean-option
       pagename-sorting optname-show-account-code
       "j2"
       (N_ "Show the account code for subtotals and subtitles?")
       #f))
-    
+
     (gnc:register-trep-option
      (gnc:make-complex-boolean-option
       pagename-sorting optname-prime-subtotal
@@ -959,14 +959,14 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
       "e2" (N_ "Do a date subtotal.")
       'monthly
       subtotal-choice-list))
-    
+
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       pagename-sorting optname-prime-sortorder
       "e" (N_ "Order of primary sorting.")
       'ascend
       ascending-choice-list))
-    
+
     ;; Secondary sorting criterion
     (gnc:register-trep-option
      (gnc:make-multichoice-callback-option
@@ -995,144 +995,144 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
       "i2" (N_ "Do a date subtotal.")
       'monthly
       subtotal-choice-list))
-    
+
     (gnc:register-trep-option
      (gnc:make-multichoice-option
       pagename-sorting optname-sec-sortorder
       "i" (N_ "Order of Secondary sorting.")
       'ascend
       ascending-choice-list)))
-  
-  ;; Display options
-  
-    (let ((options gnc:*transaction-report-options*)
-          (disp-memo? #t)
-          (disp-accname? #t)
-          (disp-other-accname? #f)
-          (is-single? #t))
-
-      (define (apply-selectable-by-name-display-options)
-        (gnc-option-db-set-option-selectable-by-name
-         options gnc:pagename-display (N_ "Use Full Account Name")
-         disp-accname?)
 
-        (gnc-option-db-set-option-selectable-by-name
-         options gnc:pagename-display (N_ "Other Account Name")
-         is-single?)
-
-        (gnc-option-db-set-option-selectable-by-name
-         options gnc:pagename-display (N_ "Use Full Other Account Name")
-         (and disp-other-accname? is-single?))
+  ;; Display options
 
-        (gnc-option-db-set-option-selectable-by-name
-         options gnc:pagename-display (N_ "Other Account Code")
-         is-single?)
+  (let ((options gnc:*transaction-report-options*)
+        (disp-memo? #t)
+        (disp-accname? #t)
+        (disp-other-accname? #f)
+        (is-single? #t))
+
+    (define (apply-selectable-by-name-display-options)
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-display (N_ "Use Full Account Name")
+       disp-accname?)
+
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-display (N_ "Other Account Name")
+       is-single?)
+
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-display (N_ "Use Full Other Account Name")
+       (and disp-other-accname? is-single?))
+
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-display (N_ "Other Account Code")
+       is-single?)
+
+      (gnc-option-db-set-option-selectable-by-name
+       options gnc:pagename-display (N_ "Notes")
+       disp-memo?))
+
+    (for-each
+     (lambda (l)
+       (gnc:register-trep-option
+        (gnc:make-simple-boolean-option
+         gnc:pagename-display (car l) (cadr l) (caddr l) (cadddr l))))
+     ;; One list per option here with: option-name, sort-tag,
+     ;; help-string, default-value
+     (list
+      (list (N_ "Date")                         "a"  (N_ "Display the date?") #t)
+      (list (N_ "Reconciled Date")              "a2" (N_ "Display the reconciled date?") #f)
+      (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
+          (list (N_ "Num/Action")               "b"  (N_ "Display the check number?") #t)
+          (list (N_ "Num")                      "b"  (N_ "Display the check number?") #t))
+      (list (N_ "Description")                  "c"  (N_ "Display the description?") #t)
+      (list (N_ "Notes")                        "d2" (N_ "Display the notes if the memo is unavailable?") #t)
+      ;; account name option appears here
+      (list (N_ "Use Full Account Name")        "f"  (N_ "Display the full account name?") #t)
+      (list (N_ "Account Code")                 "g"  (N_ "Display the account code?") #f)
+      ;; other account name option appears here
+      (list (N_ "Use Full Other Account Name")  "i"  (N_ "Display the full account name?") #f)
+      (list (N_ "Other Account Code")           "j"  (N_ "Display the other account code?") #f)
+      (list (N_ "Shares")                       "k"  (N_ "Display the number of shares?") #f)
+      (list (N_ "Price")                        "l"  (N_ "Display the shares price?") #f)
+      ;; note the "Amount" multichoice option in between here
+      (list (N_ "Running Balance")              "n"  (N_ "Display a running balance?") #f)
+      (list (N_ "Totals")                       "o"  (N_ "Display the totals?") #t)))
 
-        (gnc-option-db-set-option-selectable-by-name
-         options gnc:pagename-display (N_ "Notes")
-         disp-memo?))
-
-  (for-each
-   (lambda (l)
-     (gnc:register-trep-option
-      (gnc:make-simple-boolean-option
-       gnc:pagename-display (car l) (cadr l) (caddr l) (cadddr l))))
-   ;; One list per option here with: option-name, sort-tag,
-   ;; help-string, default-value
-   (list
-    (list (N_ "Date")                         "a"  (N_ "Display the date?") #t)
-    (list (N_ "Reconciled Date")              "a2" (N_ "Display the reconciled date?") #f)
     (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-        (list (N_ "Num/Action")               "b"  (N_ "Display the check number?") #t)
-        (list (N_ "Num")                      "b"  (N_ "Display the check number?") #t))
-    (list (N_ "Description")                  "c"  (N_ "Display the description?") #t)
-    (list (N_ "Notes")                        "d2" (N_ "Display the notes if the memo is unavailable?") #t)
-    ;; account name option appears here
-    (list (N_ "Use Full Account Name")        "f"  (N_ "Display the full account name?") #t)
-    (list (N_ "Account Code")                 "g"  (N_ "Display the account code?") #f)
-    ;; other account name option appears here
-    (list (N_ "Use Full Other Account Name")  "i"  (N_ "Display the full account name?") #f)
-    (list (N_ "Other Account Code")           "j"  (N_ "Display the other account code?") #f)
-    (list (N_ "Shares")                       "k"  (N_ "Display the number of shares?") #f)
-    (list (N_ "Price")                        "l"  (N_ "Display the shares price?") #f)
-    ;; note the "Amount" multichoice option in between here
-    (list (N_ "Running Balance")              "n"  (N_ "Display a running balance?") #f)
-    (list (N_ "Totals")                       "o"  (N_ "Display the totals?") #t)))
-
-  (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
-      (gnc:register-trep-option
-       (gnc:make-simple-boolean-option
-        gnc:pagename-display (N_ "Trans Number")
-                                    "b2" (N_ "Display the trans number?") #f)))
-
-  ;; Add an option to display the memo, and disable the notes option
-  ;; when memos are not included.
-  (gnc:register-trep-option
-   (gnc:make-complex-boolean-option
-    gnc:pagename-display (N_ "Memo")
-    "d"  (N_ "Display the memo?") #t
-    #f
-    (lambda (x)
+        (gnc:register-trep-option
+         (gnc:make-simple-boolean-option
+          gnc:pagename-display (N_ "Trans Number")
+          "b2" (N_ "Display the trans number?") #f)))
+
+    ;; Add an option to display the memo, and disable the notes option
+    ;; when memos are not included.
+    (gnc:register-trep-option
+     (gnc:make-complex-boolean-option
+      gnc:pagename-display (N_ "Memo")
+      "d"  (N_ "Display the memo?") #t
+      #f
+      (lambda (x)
         (set! disp-memo? x)
         (apply-selectable-by-name-display-options))))
 
-  ;; Ditto for Account Name #t -> Use Full Account Name is selectable
-  (gnc:register-trep-option
-   (gnc:make-complex-boolean-option
-    gnc:pagename-display (N_ "Account Name")
-    "e"  (N_ "Display the account name?") #t
-    #f
-    (lambda (x)
+    ;; Ditto for Account Name #t -> Use Full Account Name is selectable
+    (gnc:register-trep-option
+     (gnc:make-complex-boolean-option
+      gnc:pagename-display (N_ "Account Name")
+      "e"  (N_ "Display the account name?") #t
+      #f
+      (lambda (x)
         (set! disp-accname? x)
         (apply-selectable-by-name-display-options))))
 
-  ;; Ditto for Other Account Name #t -> Use Full Other Account Name is selectable
-  (gnc:register-trep-option
-   (gnc:make-complex-boolean-option
-    gnc:pagename-display (N_ "Other Account Name")
-    "h5"  (N_ "Display the other account name? (if this is a split transaction, this parameter is guessed).") #f
-    #f
-    (lambda (x)
+    ;; Ditto for Other Account Name #t -> Use Full Other Account Name is selectable
+    (gnc:register-trep-option
+     (gnc:make-complex-boolean-option
+      gnc:pagename-display (N_ "Other Account Name")
+      "h5"  (N_ "Display the other account name? (if this is a split transaction, this parameter is guessed).") #f
+      #f
+      (lambda (x)
         (set! disp-other-accname? x)
         (apply-selectable-by-name-display-options))))
 
-  (gnc:register-trep-option
-   (gnc:make-multichoice-callback-option
-    gnc:pagename-display optname-detail-level
-    "h" (N_ "Amount of detail to display per transaction.")
-    'single
-    (list (vector 'multi-line
-                  (N_ "Multi-Line")
-                  (N_ "Display all splits in a transaction on a separate line."))
-          (vector 'single
-                  (N_ "Single")
-                  (N_ "Display one line per transaction, merging multiple splits where required.")))
-    #f
-    (lambda (x)
+    (gnc:register-trep-option
+     (gnc:make-multichoice-callback-option
+      gnc:pagename-display optname-detail-level
+      "h" (N_ "Amount of detail to display per transaction.")
+      'single
+      (list (vector 'multi-line
+                    (N_ "Multi-Line")
+                    (N_ "Display all splits in a transaction on a separate line."))
+            (vector 'single
+                    (N_ "Single")
+                    (N_ "Display one line per transaction, merging multiple splits where required.")))
+      #f
+      (lambda (x)
         (set! is-single? (eq? x 'single))
         (apply-selectable-by-name-display-options))))
 
-  (gnc:register-trep-option
-   (gnc:make-multichoice-option
-    gnc:pagename-display (N_ "Amount")
-    "m" (N_ "Display the amount?")  
-    'single
-    (list
-     (vector 'none (N_ "None") (N_ "No amount display."))
-     (vector 'single (N_ "Single") (N_ "Single Column Display."))
-     (vector 'double (N_ "Double") (N_ "Two Column Display.")))))
-  
-  (gnc:register-trep-option
-   (gnc:make-multichoice-option
-    gnc:pagename-display (N_ "Sign Reverses")
-    "p" (N_ "Reverse amount display for certain account types.")
-    'credit-accounts
-    (list 
-     (vector 'none (N_ "None") (N_ "Don't change any displayed amounts."))
-     (vector 'income-expense (N_ "Income and Expense")
-             (N_ "Reverse amount display for Income and Expense Accounts."))
-     (vector 'credit-accounts (N_ "Credit Accounts")
-             (N_ "Reverse amount display for Liability, Payable, Equity, \
+    (gnc:register-trep-option
+     (gnc:make-multichoice-option
+      gnc:pagename-display (N_ "Amount")
+      "m" (N_ "Display the amount?")
+      'single
+      (list
+       (vector 'none (N_ "None") (N_ "No amount display."))
+       (vector 'single (N_ "Single") (N_ "Single Column Display."))
+       (vector 'double (N_ "Double") (N_ "Two Column Display.")))))
+
+    (gnc:register-trep-option
+     (gnc:make-multichoice-option
+      gnc:pagename-display (N_ "Sign Reverses")
+      "p" (N_ "Reverse amount display for certain account types.")
+      'credit-accounts
+      (list
+       (vector 'none (N_ "None") (N_ "Don't change any displayed amounts."))
+       (vector 'income-expense (N_ "Income and Expense")
+               (N_ "Reverse amount display for Income and Expense Accounts."))
+       (vector 'credit-accounts (N_ "Credit Accounts")
+               (N_ "Reverse amount display for Liability, Payable, Equity, \
 Credit Card, and Income accounts."))))))
 
 
@@ -1148,7 +1148,7 @@ Credit Card, and Income accounts."))))))
     (sprintf #f (_ "From %s To %s") begin-string end-string)))
 
 (define (get-primary-subtotal-style options)
-  (let ((bgcolor (gnc:lookup-option options 
+  (let ((bgcolor (gnc:lookup-option options
                                     (N_ "Colors")
                                     (N_ "Primary Subtotals/headings"))))
     (list 'attribute (list "bgcolor" (gnc:color-option->html bgcolor)))))
@@ -1187,209 +1187,209 @@ Credit Card, and Income accounts."))))))
                           secondary-subheading-renderer
                           primary-subtotal-renderer
                           secondary-subtotal-renderer)
-  
- (let ((work-to-do (length splits))
-       (work-done 0)
-       (used-columns (build-column-used options)))
-  (define (get-account-types-to-reverse options)
-    (cdr (assq (gnc:option-value 
-                (gnc:lookup-option options
-                                   gnc:pagename-display
-                                   (N_ "Sign Reverses")))
-               account-types-to-reverse-assoc-list)))
-  
-
-  (define (transaction-report-multi-rows-p options)
-    (eq? (gnc:option-value
-          (gnc:lookup-option options gnc:pagename-display optname-detail-level))
-         'multi-line))
-
-  (define (transaction-report-export-p options)
-    (gnc:option-value
-     (gnc:lookup-option options gnc:pagename-general
-       optname-table-export)))
-
-  (define (add-other-split-rows split table used-columns
-                                row-style account-types-to-reverse)
-    (define (other-rows-driver split parent table used-columns i)
-      (let ((current (xaccTransGetSplit parent i)))
-        (cond ((null? current) #f)
-              ((equal? current split)
-               (other-rows-driver split parent table used-columns (+ i 1)))
-              (else (begin
-                      (add-split-row table current used-columns options
-                                     row-style account-types-to-reverse #f)
-                      (other-rows-driver split parent table used-columns
-                                         (+ i 1)))))))
-
-    (other-rows-driver split (xaccSplitGetParent split)
-                       table used-columns 0))
-
-  (define (do-rows-with-subtotals splits 
-                                  table 
-                                  used-columns
-                                  width
-                                  multi-rows?
-                                  odd-row?
-                                  export?
-                                  account-types-to-reverse
-                                  primary-subtotal-pred
-                                  secondary-subtotal-pred 
-                                  primary-subheading-renderer
-                                  secondary-subheading-renderer
-                                  primary-subtotal-renderer
-                                  secondary-subtotal-renderer
-                                  primary-subtotal-collector 
-                                  secondary-subtotal-collector 
-                                  total-collector)
-
-    (gnc:report-percent-done (* 100 (/ work-done work-to-do)))
-    (set! work-done (+ 1 work-done))
-    (if (null? splits)
-        (begin
-          (gnc:html-table-append-row/markup!
-           table
-           def:grand-total-style
-           (list
-            (gnc:make-html-table-cell/size
-             1 width (gnc:make-html-text (gnc:html-markup-hr)))))
-	  (if (gnc:option-value (gnc:lookup-option options "Display" "Totals"))
-	      (render-grand-total table width total-collector export?)))
-	
-        (let* ((current (car splits))
-               (current-row-style (if multi-rows? def:normal-row-style
-                                      (if odd-row? def:normal-row-style 
-                                          def:alternate-row-style)))
-               (rest (cdr splits))
-               (next (if (null? rest) #f
-                         (car rest)))
-               (split-value (add-split-row 
-                             table 
-                             current 
-                             used-columns
-			     options
-                             current-row-style
-                             account-types-to-reverse
-                             #t)))
-          (if multi-rows?
-              (add-other-split-rows
-               current table used-columns def:alternate-row-style
-               account-types-to-reverse))
-
-          (primary-subtotal-collector 'add 
-                                      (gnc:gnc-monetary-commodity
-                                       split-value) 
-                                      (gnc:gnc-monetary-amount
-                                       split-value))
-          (secondary-subtotal-collector 'add
+
+  (let ((work-to-do (length splits))
+        (work-done 0)
+        (used-columns (build-column-used options)))
+    (define (get-account-types-to-reverse options)
+      (cdr (assq (gnc:option-value
+                  (gnc:lookup-option options
+                                     gnc:pagename-display
+                                     (N_ "Sign Reverses")))
+                 account-types-to-reverse-assoc-list)))
+
+
+    (define (transaction-report-multi-rows-p options)
+      (eq? (gnc:option-value
+            (gnc:lookup-option options gnc:pagename-display optname-detail-level))
+           'multi-line))
+
+    (define (transaction-report-export-p options)
+      (gnc:option-value
+       (gnc:lookup-option options gnc:pagename-general
+                          optname-table-export)))
+
+    (define (add-other-split-rows split table used-columns
+                                  row-style account-types-to-reverse)
+      (define (other-rows-driver split parent table used-columns i)
+        (let ((current (xaccTransGetSplit parent i)))
+          (cond ((null? current) #f)
+                ((equal? current split)
+                 (other-rows-driver split parent table used-columns (+ i 1)))
+                (else (begin
+                        (add-split-row table current used-columns options
+                                       row-style account-types-to-reverse #f)
+                        (other-rows-driver split parent table used-columns
+                                           (+ i 1)))))))
+
+      (other-rows-driver split (xaccSplitGetParent split)
+                         table used-columns 0))
+
+    (define (do-rows-with-subtotals splits
+                                    table
+                                    used-columns
+                                    width
+                                    multi-rows?
+                                    odd-row?
+                                    export?
+                                    account-types-to-reverse
+                                    primary-subtotal-pred
+                                    secondary-subtotal-pred
+                                    primary-subheading-renderer
+                                    secondary-subheading-renderer
+                                    primary-subtotal-renderer
+                                    secondary-subtotal-renderer
+                                    primary-subtotal-collector
+                                    secondary-subtotal-collector
+                                    total-collector)
+
+      (gnc:report-percent-done (* 100 (/ work-done work-to-do)))
+      (set! work-done (+ 1 work-done))
+      (if (null? splits)
+          (begin
+            (gnc:html-table-append-row/markup!
+             table
+             def:grand-total-style
+             (list
+              (gnc:make-html-table-cell/size
+               1 width (gnc:make-html-text (gnc:html-markup-hr)))))
+            (if (gnc:option-value (gnc:lookup-option options "Display" "Totals"))
+                (render-grand-total table width total-collector export?)))
+
+          (let* ((current (car splits))
+                 (current-row-style (if multi-rows? def:normal-row-style
+                                        (if odd-row? def:normal-row-style
+                                            def:alternate-row-style)))
+                 (rest (cdr splits))
+                 (next (if (null? rest) #f
+                           (car rest)))
+                 (split-value (add-split-row
+                               table
+                               current
+                               used-columns
+                               options
+                               current-row-style
+                               account-types-to-reverse
+                               #t)))
+            (if multi-rows?
+                (add-other-split-rows
+                 current table used-columns def:alternate-row-style
+                 account-types-to-reverse))
+
+            (primary-subtotal-collector 'add
                                         (gnc:gnc-monetary-commodity
                                          split-value)
                                         (gnc:gnc-monetary-amount
                                          split-value))
-          (total-collector 'add
-                           (gnc:gnc-monetary-commodity split-value)
-                           (gnc:gnc-monetary-amount split-value))
-
-          (if (and primary-subtotal-pred
-                   (or (not next)
-                       (and next
-                            (not (primary-subtotal-pred current next)))))
-              (begin 
-                (if secondary-subtotal-pred
-
-                    (begin
-                      (secondary-subtotal-renderer
-                       table width current
-                       secondary-subtotal-collector
-                       def:secondary-subtotal-style used-columns export?)
-                      (secondary-subtotal-collector 'reset #f #f)))
-
-                (primary-subtotal-renderer table width current
-                                           primary-subtotal-collector
-                                           def:primary-subtotal-style used-columns
-                                           export?)
-
-                (primary-subtotal-collector 'reset #f #f)
-
-                (if next
-                    (begin 
-                      (primary-subheading-renderer
-                       next table width def:primary-subtotal-style used-columns)
-
-                      (if secondary-subtotal-pred
-                          (secondary-subheading-renderer
-                           next 
-                           table 
-                           width def:secondary-subtotal-style used-columns)))))
-
-              (if (and secondary-subtotal-pred
-                       (or (not next)
-                           (and next
-                                (not (secondary-subtotal-pred
-                                      current next)))))
-                  (begin (secondary-subtotal-renderer
-                          table width current
-                          secondary-subtotal-collector
-                          def:secondary-subtotal-style used-columns export?)
-                         (secondary-subtotal-collector 'reset #f #f)
-                         (if next
-                             (secondary-subheading-renderer
-                              next table width
-                              def:secondary-subtotal-style used-columns)))))
-
-          (do-rows-with-subtotals rest 
-                                  table 
-                                  used-columns
-                                  width 
-                                  multi-rows?
-                                  (not odd-row?)
-                                  export?
-                                  account-types-to-reverse
-                                  primary-subtotal-pred 
-                                  secondary-subtotal-pred
-                                  primary-subheading-renderer 
-                                  secondary-subheading-renderer
-                                  primary-subtotal-renderer
-                                  secondary-subtotal-renderer
-                                  primary-subtotal-collector 
-                                  secondary-subtotal-collector 
-                                  total-collector))))
-
-  (let* ((table (gnc:make-html-table))
-         (width (num-columns-required used-columns))
-         (multi-rows? (transaction-report-multi-rows-p options))
-	 (export? (transaction-report-export-p options))
-         (account-types-to-reverse
-          (get-account-types-to-reverse options)))
-
-    (gnc:html-table-set-col-headers!
-     table
-     (make-heading-list used-columns options))
-    ;;     (gnc:warn "Splits:" splits)
-    (if (not (null? splits))
-        (begin
-          (if primary-subheading-renderer 
-              (primary-subheading-renderer
-               (car splits) table width def:primary-subtotal-style used-columns))
-          (if secondary-subheading-renderer
-              (secondary-subheading-renderer
-               (car splits) table width def:secondary-subtotal-style used-columns))
-
-          (do-rows-with-subtotals splits table used-columns width
-                                  multi-rows? #t
-                                  export?
-                                  account-types-to-reverse
-                                  primary-subtotal-pred
-                                  secondary-subtotal-pred
-                                  primary-subheading-renderer
-                                  secondary-subheading-renderer
-                                  primary-subtotal-renderer
-                                  secondary-subtotal-renderer
-                                  (gnc:make-commodity-collector)
-                                  (gnc:make-commodity-collector)
-                                  (gnc:make-commodity-collector))))
-    
-    table)))
+            (secondary-subtotal-collector 'add
+                                          (gnc:gnc-monetary-commodity
+                                           split-value)
+                                          (gnc:gnc-monetary-amount
+                                           split-value))
+            (total-collector 'add
+                             (gnc:gnc-monetary-commodity split-value)
+                             (gnc:gnc-monetary-amount split-value))
+
+            (if (and primary-subtotal-pred
+                     (or (not next)
+                         (and next
+                              (not (primary-subtotal-pred current next)))))
+                (begin
+                  (if secondary-subtotal-pred
+
+                      (begin
+                        (secondary-subtotal-renderer
+                         table width current
+                         secondary-subtotal-collector
+                         def:secondary-subtotal-style used-columns export?)
+                        (secondary-subtotal-collector 'reset #f #f)))
+
+                  (primary-subtotal-renderer table width current
+                                             primary-subtotal-collector
+                                             def:primary-subtotal-style used-columns
+                                             export?)
+
+                  (primary-subtotal-collector 'reset #f #f)
+
+                  (if next
+                      (begin
+                        (primary-subheading-renderer
+                         next table width def:primary-subtotal-style used-columns)
+
+                        (if secondary-subtotal-pred
+                            (secondary-subheading-renderer
+                             next
+                             table
+                             width def:secondary-subtotal-style used-columns)))))
+
+                (if (and secondary-subtotal-pred
+                         (or (not next)
+                             (and next
+                                  (not (secondary-subtotal-pred
+                                        current next)))))
+                    (begin (secondary-subtotal-renderer
+                            table width current
+                            secondary-subtotal-collector
+                            def:secondary-subtotal-style used-columns export?)
+                           (secondary-subtotal-collector 'reset #f #f)
+                           (if next
+                               (secondary-subheading-renderer
+                                next table width
+                                def:secondary-subtotal-style used-columns)))))
+
+            (do-rows-with-subtotals rest
+                                    table
+                                    used-columns
+                                    width
+                                    multi-rows?
+                                    (not odd-row?)
+                                    export?
+                                    account-types-to-reverse
+                                    primary-subtotal-pred
+                                    secondary-subtotal-pred
+                                    primary-subheading-renderer
+                                    secondary-subheading-renderer
+                                    primary-subtotal-renderer
+                                    secondary-subtotal-renderer
+                                    primary-subtotal-collector
+                                    secondary-subtotal-collector
+                                    total-collector))))
+
+    (let* ((table (gnc:make-html-table))
+           (width (num-columns-required used-columns))
+           (multi-rows? (transaction-report-multi-rows-p options))
+           (export? (transaction-report-export-p options))
+           (account-types-to-reverse
+            (get-account-types-to-reverse options)))
+
+      (gnc:html-table-set-col-headers!
+       table
+       (make-heading-list used-columns options))
+      ;;     (gnc:warn "Splits:" splits)
+      (if (not (null? splits))
+          (begin
+            (if primary-subheading-renderer
+                (primary-subheading-renderer
+                 (car splits) table width def:primary-subtotal-style used-columns))
+            (if secondary-subheading-renderer
+                (secondary-subheading-renderer
+                 (car splits) table width def:secondary-subtotal-style used-columns))
+
+            (do-rows-with-subtotals splits table used-columns width
+                                    multi-rows? #t
+                                    export?
+                                    account-types-to-reverse
+                                    primary-subtotal-pred
+                                    secondary-subtotal-pred
+                                    primary-subheading-renderer
+                                    secondary-subheading-renderer
+                                    primary-subtotal-renderer
+                                    secondary-subtotal-renderer
+                                    (gnc:make-commodity-collector)
+                                    (gnc:make-commodity-collector)
+                                    (gnc:make-commodity-collector))))
+
+      table)))
 
 ;; ;;;;;;;;;;;;;;;;;;;;
 ;; Here comes the renderer function for this report.
@@ -1406,14 +1406,14 @@ Credit Card, and Income accounts."))))))
     ;; subtotal functions. Each entry: (cons
     ;; 'sorting-key-option-value (vector 'query-sorting-key
     ;; subtotal-function subtotal-renderer))
-;;  (let* ((used-columns (build-column-used options))) ;; tpo: gives unbound variable options?
+    ;;  (let* ((used-columns (build-column-used options))) ;; tpo: gives unbound variable options?
     (let* ((used-columns (build-column-used (gnc:report-options report-obj))))
-      (list (cons 'account-name  (vector 
+      (list (cons 'account-name  (vector
                                   (list SPLIT-ACCT-FULLNAME)
-                                  split-account-full-name-same-p 
+                                  split-account-full-name-same-p
                                   render-account-subheading
                                   render-account-subtotal))
-            (cons 'account-code  (vector 
+            (cons 'account-code  (vector
                                   (list SPLIT-ACCOUNT ACCOUNT-CODE-)
                                   split-account-code-same-p
                                   render-account-subheading
@@ -1422,23 +1422,23 @@ Credit Card, and Income accounts."))))))
                                   (list SPLIT-TRANS TRANS-DATE-POSTED)
                                   #f #f #f))
             (cons 'reconciled-date (vector
-                                  (list SPLIT-DATE-RECONCILED)
-                                  #f #f #f))
+                                    (list SPLIT-DATE-RECONCILED)
+                                    #f #f #f))
             (cons 'register-order (vector
-                                  (list QUERY-DEFAULT-SORT)
-                                  #f #f #f))
+                                   (list QUERY-DEFAULT-SORT)
+                                   #f #f #f))
             (cons 'corresponding-acc-name
-                                 (vector
-                                  (list SPLIT-CORR-ACCT-NAME)
-                                  split-same-corr-account-full-name-p 
-                                  render-corresponding-account-subheading
-                                  render-corresponding-account-subtotal))
+                  (vector
+                   (list SPLIT-CORR-ACCT-NAME)
+                   split-same-corr-account-full-name-p
+                   render-corresponding-account-subheading
+                   render-corresponding-account-subtotal))
             (cons 'corresponding-acc-code
-                                 (vector
-                                  (list SPLIT-CORR-ACCT-CODE)
-                                  split-same-corr-account-code-p 
-                                  render-corresponding-account-subheading
-                                  render-corresponding-account-subtotal))
+                  (vector
+                   (list SPLIT-CORR-ACCT-CODE)
+                   split-same-corr-account-code-p
+                   render-corresponding-account-subheading
+                   render-corresponding-account-subtotal))
             (cons 'amount        (vector (list SPLIT-VALUE) #f #f #f))
             (cons 'description   (vector (list SPLIT-TRANS TRANS-DESCRIPTION) #f #f #f))
             (if (qof-book-use-split-action-for-num-field (gnc-get-current-book))
@@ -1455,15 +1455,15 @@ Credit Card, and Income accounts."))))))
     (list
      (cons 'none (vector #f #f #f))
      (cons 'weekly (vector split-same-week-p render-week-subheading
-			   render-week-subtotal))
-     (cons 'monthly (vector split-same-month-p render-month-subheading 
+                           render-week-subtotal))
+     (cons 'monthly (vector split-same-month-p render-month-subheading
                             render-month-subtotal))
-     (cons 'quarterly (vector split-same-quarter-p render-quarter-subheading 
-                            render-quarter-subtotal))
+     (cons 'quarterly (vector split-same-quarter-p render-quarter-subheading
+                              render-quarter-subtotal))
      (cons 'yearly (vector split-same-year-p render-year-subheading
                            render-year-subtotal))))
 
-  (define (get-subtotalstuff-helper 
+  (define (get-subtotalstuff-helper
            name-sortkey name-subtotal name-date-subtotal
            comp-index date-index)
     ;; The value of the sorting-key multichoice option.
@@ -1474,32 +1474,32 @@ Credit Card, and Income accounts."))))))
           ;; corresponding funcs in the assoc-list.
           (vector-ref
            (cdr (assq (opt-val pagename-sorting name-date-subtotal)
-                      date-comp-funcs-assoc-list)) 
+                      date-comp-funcs-assoc-list))
            date-index)
           ;; For everything else: 1. check whether sortkey has
           ;; subtotalling enabled at all, 2. check whether the
           ;; enable-subtotal boolean option is #t, 3. look up the
           ;; appropriate funcs in the assoc-list.
-          (and (member sortkey subtotal-enabled) 
+          (and (member sortkey subtotal-enabled)
                (and (opt-val pagename-sorting name-subtotal)
-                    (vector-ref 
-                     (cdr (assq sortkey comp-funcs-assoc-list)) 
+                    (vector-ref
+                     (cdr (assq sortkey comp-funcs-assoc-list))
                      comp-index))))))
-  
+
   (define (get-query-sortkey sort-option-value)
-    (vector-ref 
-     (cdr (assq sort-option-value comp-funcs-assoc-list)) 
+    (vector-ref
+     (cdr (assq sort-option-value comp-funcs-assoc-list))
      0))
 
-  (define (get-subtotal-pred 
+  (define (get-subtotal-pred
            name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper 
+    (get-subtotalstuff-helper
      name-sortkey name-subtotal name-date-subtotal
      1 0))
 
   (define (get-subheading-renderer
            name-sortkey name-subtotal name-date-subtotal)
-    (get-subtotalstuff-helper 
+    (get-subtotalstuff-helper
      name-sortkey name-subtotal name-date-subtotal
      2 1))
 
@@ -1523,28 +1523,28 @@ Credit Card, and Income accounts."))))))
         ((= splitcount 2)
          (let* ((other      (xaccSplitGetOtherSplit split))
                 (other-acct (xaccSplitGetAccount other)))
-               (member other-acct account-list)))
+           (member other-acct account-list)))
 
         ;; A multi-split transaction - run over all splits
         ((> splitcount 2)
          (let ((splits (xaccTransGetSplitList txn)))
 
-                ;; Walk through the list of splits.
-                ;; if we reach the end, return #f
-                ;; if the 'this' != 'split' and the split->account is a member
-                ;; of the account-list, then return #t, else recurse
-                (define (is-member splits)
-                  (if (null? splits)
-                      #f
-                      (let* ((this (car splits))
-                             (rest (cdr splits))
-                             (acct (xaccSplitGetAccount this)))
-                        (if (and (not (eq? this split))
-                                 (member acct account-list))
-                            #t
-                            (is-member rest)))))
-
-                (is-member splits)))
+           ;; Walk through the list of splits.
+           ;; if we reach the end, return #f
+           ;; if the 'this' != 'split' and the split->account is a member
+           ;; of the account-list, then return #t, else recurse
+           (define (is-member splits)
+             (if (null? splits)
+                 #f
+                 (let* ((this (car splits))
+                        (rest (cdr splits))
+                        (acct (xaccSplitGetAccount this)))
+                   (if (and (not (eq? this split))
+                            (member acct account-list))
+                       #t
+                       (is-member rest)))))
+
+           (is-member splits)))
 
         ;; Single transaction splits
         (else #f))))
@@ -1552,39 +1552,39 @@ Credit Card, and Income accounts."))))))
 
   (gnc:report-starting reportname)
   (let* ((document (gnc:make-html-document))
-        (c_account_0 (opt-val gnc:pagename-accounts "Accounts"))
-        (account-matcher (opt-val gnc:pagename-accounts optname-account-matcher))
-        (account-matcher-regexp (if (opt-val gnc:pagename-accounts optname-account-matcher-regex)
-                                    (make-regexp account-matcher)
-                                    #f))
-        (c_account_1 (filter
-                      (lambda (acc)
-                        (if account-matcher-regexp
-                            (regexp-exec account-matcher-regexp (gnc-account-get-full-name acc))
-                            (string-contains (gnc-account-get-full-name acc) account-matcher)))
-                     c_account_0))
-        (c_account_2 (opt-val gnc:pagename-accounts "Filter By..."))
-	(filter-mode (opt-val gnc:pagename-accounts "Filter Type"))
-        (begindate (gnc:timepair-start-day-time
-                    (gnc:date-option-absolute-time
-                     (opt-val gnc:pagename-general "Start Date"))))
-        (enddate (gnc:timepair-end-day-time
-                  (gnc:date-option-absolute-time
-                   (opt-val gnc:pagename-general "End Date"))))
-        (transaction-matcher (opt-val pagename-filter optname-transaction-matcher))
-        (transaction-matcher-regexp (if (opt-val pagename-filter optname-transaction-matcher-regex)
-                                        (make-regexp transaction-matcher)
-                                        #f))
-        (report-title (opt-val 
-                       gnc:pagename-general
-                       gnc:optname-reportname))
-        (primary-key (opt-val pagename-sorting optname-prime-sortkey))
-        (primary-order (opt-val pagename-sorting "Primary Sort Order"))
-        (secondary-key (opt-val pagename-sorting optname-sec-sortkey))
-        (secondary-order (opt-val pagename-sorting "Secondary Sort Order"))
-        (void-status (opt-val gnc:pagename-accounts optname-void-transactions))
-        (splits '())
-        (query (qof-query-create-for-splits)))
+         (c_account_0 (opt-val gnc:pagename-accounts "Accounts"))
+         (account-matcher (opt-val gnc:pagename-accounts optname-account-matcher))
+         (account-matcher-regexp (if (opt-val gnc:pagename-accounts optname-account-matcher-regex)
+                                     (make-regexp account-matcher)
+                                     #f))
+         (c_account_1 (filter
+                       (lambda (acc)
+                         (if account-matcher-regexp
+                             (regexp-exec account-matcher-regexp (gnc-account-get-full-name acc))
+                             (string-contains (gnc-account-get-full-name acc) account-matcher)))
+                       c_account_0))
+         (c_account_2 (opt-val gnc:pagename-accounts "Filter By..."))
+         (filter-mode (opt-val gnc:pagename-accounts "Filter Type"))
+         (begindate (gnc:timepair-start-day-time
+                     (gnc:date-option-absolute-time
+                      (opt-val gnc:pagename-general "Start Date"))))
+         (enddate (gnc:timepair-end-day-time
+                   (gnc:date-option-absolute-time
+                    (opt-val gnc:pagename-general "End Date"))))
+         (transaction-matcher (opt-val pagename-filter optname-transaction-matcher))
+         (transaction-matcher-regexp (if (opt-val pagename-filter optname-transaction-matcher-regex)
+                                         (make-regexp transaction-matcher)
+                                         #f))
+         (report-title (opt-val
+                        gnc:pagename-general
+                        gnc:optname-reportname))
+         (primary-key (opt-val pagename-sorting optname-prime-sortkey))
+         (primary-order (opt-val pagename-sorting "Primary Sort Order"))
+         (secondary-key (opt-val pagename-sorting optname-sec-sortkey))
+         (secondary-order (opt-val pagename-sorting "Secondary Sort Order"))
+         (void-status (opt-val gnc:pagename-accounts optname-void-transactions))
+         (splits '())
+         (query (qof-query-create-for-splits)))
 
     ;;(gnc:warn "accts in trep-renderer:" c_account_1)
     ;;(gnc:warn "Report Account names:" (get-other-account-names c_account_1))
@@ -1592,28 +1592,28 @@ Credit Card, and Income accounts."))))))
     (if (not (or (null? c_account_1) (and-map not c_account_1)))
         (begin
           (qof-query-set-book query (gnc-get-current-book))
-	      ;;(gnc:warn "query is:" query)
+          ;;(gnc:warn "query is:" query)
           (xaccQueryAddAccountMatch query
-                                       c_account_1
-                                       QOF-GUID-MATCH-ANY QOF-QUERY-AND)
+                                    c_account_1
+                                    QOF-GUID-MATCH-ANY QOF-QUERY-AND)
           (xaccQueryAddDateMatchTS
            query #t begindate #t enddate QOF-QUERY-AND)
           (qof-query-set-sort-order query
-				    (get-query-sortkey primary-key)
-				    (get-query-sortkey secondary-key)
-				    '())
+                                    (get-query-sortkey primary-key)
+                                    (get-query-sortkey secondary-key)
+                                    '())
 
           (qof-query-set-sort-increasing query
                                          (eq? primary-order 'ascend)
                                          (eq? secondary-order 'ascend)
                                          #t)
 
-	  (case void-status
-	   ((non-void-only) 
-	    (gnc:query-set-match-non-voids-only! query (gnc-get-current-book)))
-	   ((void-only)
-	    (gnc:query-set-match-voids-only! query (gnc-get-current-book)))
-	   (else #f))
+          (case void-status
+            ((non-void-only)
+             (gnc:query-set-match-non-voids-only! query (gnc-get-current-book)))
+            ((void-only)
+             (gnc:query-set-match-voids-only! query (gnc-get-current-book)))
+            (else #f))
 
           (set! splits (qof-query-run query))
 
@@ -1637,20 +1637,20 @@ Credit Card, and Income accounts."))))))
                         splits))
 
           (if (not (null? splits))
-              (let ((table 
-                     (make-split-table 
-                      splits 
+              (let ((table
+                     (make-split-table
+                      splits
                       options
-                      (get-subtotal-pred optname-prime-sortkey 
+                      (get-subtotal-pred optname-prime-sortkey
                                          optname-prime-subtotal
                                          optname-prime-date-subtotal)
-                      (get-subtotal-pred optname-sec-sortkey 
+                      (get-subtotal-pred optname-sec-sortkey
                                          optname-sec-subtotal
                                          optname-sec-date-subtotal)
-                      (get-subheading-renderer optname-prime-sortkey 
+                      (get-subheading-renderer optname-prime-sortkey
                                                optname-prime-subtotal
                                                optname-prime-date-subtotal)
-                      (get-subheading-renderer optname-sec-sortkey 
+                      (get-subheading-renderer optname-sec-sortkey
                                                optname-sec-subtotal
                                                optname-sec-date-subtotal)
                       (get-subtotal-renderer   optname-prime-sortkey
@@ -1662,20 +1662,20 @@ Credit Card, and Income accounts."))))))
 
                 (gnc:html-document-set-title! document
                                               report-title)
-                (gnc:html-document-add-object! 
+                (gnc:html-document-add-object!
                  document
                  (gnc:make-html-text
-                  (gnc:html-markup-h3 
+                  (gnc:html-markup-h3
                    (display-date-interval begindate enddate))))
                 (gnc:html-document-add-object!
-                 document 
+                 document
                  table)
                 (qof-query-destroy query))
               ;; error condition: no splits found
               (let ((p (gnc:make-html-text)))
-                (gnc:html-text-append! 
-                 p 
-                 (gnc:html-markup-h2 
+                (gnc:html-text-append!
+                 p
+                 (gnc:html-markup-h2
                   (_ "No matching transactions found"))
                  (gnc:html-markup-p
                   (_ "No transactions were found that \
@@ -1684,11 +1684,11 @@ in the Options panel.")))
                 (gnc:html-document-add-object! document p))))
 
         (if (null? c_account_0)
-            
+
             ;; error condition: no accounts specified
             (gnc:html-document-add-object!
-             document 
-             (gnc:html-make-no-account-warning 
+             document
+             (gnc:html-make-no-account-warning
               report-title (gnc:report-id report-obj)))
 
             ;; error condition: accounts were specified but none matcher string/regex
@@ -1705,12 +1705,12 @@ in the Options panel.")))
 
 ;; Define the report.
 (gnc:define-report
- 
+
  'version 1
- 
+
  'name reportname
  'report-guid "2fe3b9833af044abb929a88d5a59620f"
- 
+
  'options-generator trep-options-generator
- 
+
  'renderer trep-renderer)

commit 809d27709785be60691624b4b901146e94ab9869
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Sat Dec 9 22:12:30 2017 +0800

    ENH: Move Transaction Matcher to new Filter tab

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 231c2ae..4957d2f 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -66,8 +66,11 @@
 (define optname-currency (N_ "Report's currency"))
 (define optname-account-matcher (N_ "Account Matcher"))
 (define optname-account-matcher-regex (N_ "Account Matcher uses regular expressions for extended matching"))
+
+(define pagename-filter (N_ "Filter"))
 (define optname-transaction-matcher (N_ "Transaction Matcher"))
 (define optname-transaction-matcher-regex (N_ "Transaction Matcher uses regular expressions for extended matching"))
+
 (define def:grand-total-style "grand-total")
 (define def:normal-row-style "normal-row")
 (define def:alternate-row-style "alternate-row")
@@ -646,7 +649,7 @@
 
   (gnc:register-trep-option
    (gnc:make-string-option
-    gnc:pagename-general optname-transaction-matcher
+    pagename-filter optname-transaction-matcher
     "i1" (N_ "Match only transactions whose substring is matched e.g. '#gift' \
 will find all transactions with #gift in description, notes or memo. It can be left \
 blank, which will disable the matcher.")
@@ -654,7 +657,7 @@ blank, which will disable the matcher.")
 
   (gnc:register-trep-option
    (gnc:make-simple-boolean-option
-    gnc:pagename-general optname-transaction-matcher-regex
+    pagename-filter optname-transaction-matcher-regex
     "i2"
     (N_ "By default the transaction matcher will search substring only. Set this to true to \
 enable full POSIX regular expressions capabilities. '#work|#family' will match both \
@@ -1568,8 +1571,8 @@ Credit Card, and Income accounts."))))))
         (enddate (gnc:timepair-end-day-time
                   (gnc:date-option-absolute-time
                    (opt-val gnc:pagename-general "End Date"))))
-        (transaction-matcher (opt-val gnc:pagename-general optname-transaction-matcher))
-        (transaction-matcher-regexp (if (opt-val gnc:pagename-general optname-transaction-matcher-regex)
+        (transaction-matcher (opt-val pagename-filter optname-transaction-matcher))
+        (transaction-matcher-regexp (if (opt-val pagename-filter optname-transaction-matcher-regex)
                                         (make-regexp transaction-matcher)
                                         #f))
         (report-title (opt-val 

commit 7e8ac532bf7009e6f31ddab31d9c1a985b4ce244
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Dec 12 00:13:44 2017 +0800

    BUGFIX: change date-sorting-types
    
    This commit changes date sorting types.
    
    'date is posted-date and belongs to this list.
    'reconciled-date is also date and may benefit from periodic subtotals.
    'register-order is register default and may not be date.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index 21340a3..231c2ae 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -610,7 +610,7 @@
     split-value))
 
 
-(define date-sorting-types (list 'date 'register-order))
+(define date-sorting-types (list 'date 'reconciled-date))
 
 (define (trep-options-generator)
   (define gnc:*transaction-report-options* (gnc:new-options))

commit ba2e0c5ff668c5de4bcbb20f2a6c7ce65fcc0f75
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Tue Dec 12 00:15:31 2017 +0800

    OBSOLETE: 'exact-time removed
    
    This sortkey is handled identically to 'date and must be removed.

diff --git a/gnucash/report/standard-reports/transaction.scm b/gnucash/report/standard-reports/transaction.scm
index bd3445c..21340a3 100644
--- a/gnucash/report/standard-reports/transaction.scm
+++ b/gnucash/report/standard-reports/transaction.scm
@@ -610,7 +610,7 @@
     split-value))
 
 
-(define date-sorting-types (list 'date 'exact-time 'register-order))
+(define date-sorting-types (list 'date 'register-order))
 
 (define (trep-options-generator)
   (define gnc:*transaction-report-options* (gnc:new-options))
@@ -768,10 +768,6 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                            (N_ "Date")
                            (N_ "Sort by date."))
 
-                   (vector 'exact-time
-                           (N_ "Exact Time")
-                           (N_ "Sort by exact time."))
-
                    (vector 'reconciled-date
                            (N_ "Reconciled Date")
                            (N_ "Sort by the Reconciled Date."))
@@ -823,10 +819,6 @@ Use a period (.) to match a single character e.g. '20../.' will match 'Travel 20
                            (N_ "Date")
                            (N_ "Sort by date."))
 
-                   (vector 'exact-time
-                           (N_ "Exact Time")
-                           (N_ "Sort by exact time."))
-
                    (vector 'reconciled-date
                            (N_ "Reconciled Date")
                            (N_ "Sort by the Reconciled Date."))
@@ -1423,9 +1415,6 @@ Credit Card, and Income accounts."))))))
                                   split-account-code-same-p
                                   render-account-subheading
                                   render-account-subtotal))
-            (cons 'exact-time    (vector
-                                  (list SPLIT-TRANS TRANS-DATE-POSTED)
-                                  #f #f #f))
             (cons 'date          (vector
                                   (list SPLIT-TRANS TRANS-DATE-POSTED)
                                   #f #f #f))

commit d93d4f68b0df61700a1d6bfe52896d8079fe180b
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Thu Dec 21 20:19:15 2017 +0800

    options.scm: upgrade lookup-value to learn section changes

diff --git a/libgnucash/app-utils/options.scm b/libgnucash/app-utils/options.scm
index b0e7b0e..2a8adbf 100644
--- a/libgnucash/app-utils/options.scm
+++ b/libgnucash/app-utils/options.scm
@@ -1681,32 +1681,48 @@
           (let ((option-hash (hash-ref section-hash name)))
             (if option-hash
                 option-hash
-                ; Option name was not found. Perhaps it was renamed ?
-                ; Let's try to map it to a known new name
+                ;; Option name was not found. Perhaps it was renamed ?
+                ;; Let's try to map it to a known new name.
+                ;; This list will try match names - if one is found
+                ;; the next item will describe a pair.
+                ;; (cons newsection newname)
+                ;; If newsection is #f then reuse previous section name.
+                ;;
+                ;; Please note the rename list currently supports renaming
+                ;; individual option names, or individual option names moved
+                ;; to another section. It does not currently support renaming
+                ;; whole sections.
                 (let* ((new-names-list (list
-                        "Accounts to include" "Accounts"
-                        "Exclude transactions between selected accounts?" "Exclude transactions between selected accounts"
-                        "Filter Accounts" "Filter By..."
-                        "Flatten list to depth limit?" "Flatten list to depth limit"
-                        "From" "Start Date"
-                        "Report Accounts" "Accounts"
-                        "Report Currency" "Report's currency"
-                        "Show Account Code?" "Show Account Code"
-                        "Show Full Account Name?" "Show Full Account Name"
-                        "Show Multi-currency Totals?" "Show Multi-currency Totals"
-                        "Show zero balance items?" "Show zero balance items"
-                        "Sign Reverses?" "Sign Reverses"
-                        "To" "End Date"
-                        "Use Full Account Name?" "Use Full Account Name"
-                        "Use Full Other Account Name?" "Use Full Other Account Name"
-                        "Void Transactions?" "Void Transactions"
-                        ))
+                                        "Accounts to include" (cons #f "Accounts")
+                                        "Exclude transactions between selected accounts?" (cons #f "Exclude transactions between selected accounts")
+                                        "Filter Accounts" (cons #f "Filter By...")
+                                        "Flatten list to depth limit?" (cons #f "Flatten list to depth limit")
+                                        "From" (cons #f "Start Date")
+                                        "Report Accounts" (cons #f "Accounts")
+                                        "Report Currency" (cons #f "Report's currency")
+                                        "Show Account Code?" (cons #f "Show Account Code")
+                                        "Show Full Account Name?" (cons #f "Show Full Account Name")
+                                        "Show Multi-currency Totals?" (cons #f "Show Multi-currency Totals")
+                                        "Show zero balance items?" (cons #f "Show zero balance items")
+                                        "Sign Reverses?" (cons #f "Sign Reverses")
+                                        "To" (cons #f "End Date")
+                                        "Use Full Account Name?" (cons #f "Use Full Account Name")
+                                        "Use Full Other Account Name?" (cons #f "Use Full Other Account Name")
+                                        "Void Transactions?" (cons #f "Void Transactions")
+                                        ))
                        (name-match (member name new-names-list)))
 
-                      (if name-match 
-                        (let ((new-name (cadr name-match)))
-                             (lookup-option section new-name))
-                        #f))))
+                  (and name-match
+                       (let ((new-section (car (cadr name-match)))
+                             (new-name (cdr (cadr name-match))))
+                         ;; compare if new-section name exists.
+                         (if new-section
+                             ;; if so, if it's different to current section name
+                             ;; then try new section name
+                             (and (not (string=? new-section section))
+                                  (lookup-option new-section new-name))
+                             ;; else reuse section-name with new-name
+                             (lookup-option section new-name)))))))
           #f)))
 
   (define (option-changed section name)



Summary of changes:
 gnucash/report/standard-reports/transaction.scm | 3052 ++++++++++++-----------
 libgnucash/app-utils/options.scm                |   64 +-
 2 files changed, 1667 insertions(+), 1449 deletions(-)



More information about the gnucash-changes mailing list