Dynamically adding reports
Chris Dennis
cgdennis at btinternet.com
Sun Jun 14 17:53:10 EDT 2009
Derek Atkins wrote:
> Quoting Phil Longstaff <plongstaff at rogers.com>:
>
>> I played around last night with how reports are loaded in the system.
>> I basically replaced:
>>
>> (use-module (gnucash report report-A))
>> (use-module (gnucash report report-B))
>>
>> which appears in standard-reports.scm, with
>>
>> (define (get-report-list) (list
>> 'report-A
>> 'report-B
>> ))
>> (for-each (lambda (x) (resolve-module (append '(gnucash report) x)))
>> (get-report-list))
>>
>> which does nothing new, but does allow me to replace (get-report-list)
>> with a function which returns the names of all .scm files. This will
>> then allow a user/developer to just drop a new report file into the
>> reports directory, restart gnucash, and it will be picked up. Or,
>> (get-report-list) could read the list of report file names from a
>> standard-report-names.txt file, which would allow the user/developer
>> to drop a report file into the reports directory, add the file name to
>> the standard-report-names.txt, then restart. My preference is for the
>> former (fewer steps), but a little more difficult.
>>
>> The reports directory currently holds all of the report files (both
>> standard and business) as well as some support files. I think what I
>> will do is create a 'standard-reports' subdirectory to the reports
>> directory, and put the standard reports (or symlinks) there.
>> get-report-list will then have a single directory from which to get
>> all of the file names.
>>
>> Comments?
>
> How do you determine the runtime location of this directory?
> So long as it can be determined at runtime (and not a compile-time
> constant) I think this is a perfectly reasonable idea.
Is the following any help? It's a function I came up with to allow
eguile-based reports to find their corresponding template file, but in
fact it's not that specific -- it will look for any file in ~/.gnucash
or <any-dir-in-the-search-path>/gnucash/report. It could easily be
adapted or made more general-purpose.
(define (find-template fname)
;; Find the eguile template file 'fname', and return its full path.
;; First look in the user's .gnucash directory.
;; Then look in Gnucash's standard report directory.
;; This is complicated because of the need to cater for
;; various operating systems; so it takes a fairly heuristic,
;; 'best guess' approach.
;; If no file is found, returns just 'fname' for use in error
;; messages.
;; Note: this has been tested on Linux and Windows Vista so far...
(let* ((userdir (sub-vicinity (user-vicinity) ".gnucash"))
(sysdir (sub-vicinity (sub-vicinity (user-vicinity)
"gnucash") "report"))
(home (or (home-vicinity)
(getenv "USERPROFILE")
(user-vicinity)
"")))
; make sure there's a trailing delimiter
(set! home (sub-vicinity (user-vicinity) home))
(let ((home-template (in-vicinity
(in-vicinity home userdir) fname)))
(if (access? home-template R_OK)
home-template
(or (%search-load-path (in-vicinity sysdir fname))
fname)))))
cheers
Chris
--
Chris Dennis cgdennis at btinternet.com
Fordingbridge, Hampshire, UK
More information about the gnucash-devel
mailing list