3 个版本 (有破坏性)

0.2.0 2021 年 11 月 4 日
0.1.0 2021 年 7 月 29 日
0.0.1 2021 年 4 月 23 日

#163金融

MIT/Apache

1MB
4K SLoC

包含 (WOFF 字体, 99KB) fontawesome-webfont.woff, (WOFF 字体, 78KB) fontawesome-webfont.woff2, (WOFF 字体, 45KB) open-sans-v17-all-charsets-300.woff2, (WOFF 字体, 41KB) open-sans-v17-all-charsets-300italic.woff2, (WOFF 字体, 45KB) open-sans-v17-all-charsets-600.woff2, (WOFF 字体, 43KB) open-sans-v17-all-charsets-600italic.woff2 以及更多.

Billig

命令行 DSL 预算管理器

哲学

Billig 的核心特性是将开支分散到相关的期间。仅对发生的当天进行登记的开支管理器,由于变化很大,无法提供准确的见解。

Billig 通过让所有交易都登记在相关的期间内来消除这种限制。

Billig 是将我的另一个项目从 Python 重写到 Rust 的;Billig 现在提供了图形表示和表格摘要,因此已达到功能一致性。原始项目使用 Python 字典来存储数据,Billig 通过使用专门设计的 DSL 来提供更好的体验。

使用方法

正在进行中:Billig 的命令行界面可能会更改

运行 billig -h 以获取帮助。

Complete form:
$ billig --plot day,week --table week,month,year expenses.bil
         ^               ^                       ^--- source file
         |               |
         |               '--- which tables to show: weekly + monthly + yearly
         '--- which plots to show : daily + weekly

Shortened:
$ billig -pd,w -tw,m,y
         ^     ^         ^--- default source is expenses.bil
         |     |
         |     '--- -t short for --table, m for month, y for year
         '--- -p short for --plot, d for day, w for week

表格在终端中以彩色打印,图表以 .svg 格式生成

语法

数据存储在 .bil 文件中,这些文件使用 pest.rs 解析

以下示例概述了可用的结构。

2020:
    Sep:
        01: val -300, type Mov, span Year<Post> 1, tag "Train pass";
            // the above expense will be registered for one year from
            // 2020-Sep-01 to 2021-Sep-01
            val -3.5, type Food, span Day, tag "Sandwich";
            // several entries can be registered for a single day
            // this one will last only a day, Day is the contracted form
            // of Day<Curr> 1
        02: -40, Food, period ..Oct-15, "Misc";
            // labels 'val', 'type', 'span', 'tag' can be omitted
            // the 'period' construct allows for more fine-grained control
            // over timeframes

// this is a template
!food_supplies value { // it takes a single positional argument
    val @Neg *value, // expands to an amount
    type Food,
    span Month<Post>,
    tag @Concat "Food " @Year "-" @Month, // date is passed to the template as
                                          // an implicit argument
}

!restaurant value tip=0 { // tip is an optional argument
    val @Neg @Sum *value *tip, // total value is the sum of the two
    type Food,
    span Day,
    tag @Concat "Restaurant " @Weekday ". " @Date " at " *place,
                                            // this forces place to be 
                                            // passed as a named argument
}

2020:
    Dec:
        15: !food_supplies 69.42;
            // expands to:
            //   val -69.42, type Food, span Month<Post>,
            //   tag "Food 2020-Dec";
        20: !restaurant 30 place="Foo";
            // expands to:
            //   val -30, type Food, span Day,
            //   tag "Restaurant Sun. 2020-Dec-20 at Foo";
        25: !restaurant 50 place="Bar" tip=5;
            // expands to:
            //   val -55, type Food, span Day,
            //   tag "Restaurant Fri. 2020-Dec-25 at Bar";

import ../other.bil
// either relative or absolute path, parses the contents of the
// imported file in the context of the current one: local template definitions
// are available in other.bil, but definitions from other.bil do not pollute the
// current namespace

依赖关系

~4MB
~67K SLoC