<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook EBNF Module V1.1CR1//EN"
               "http://www.oasis-open.org/docbook/xml/ebnf/1.1CR1/dbebnf.dtd">
<!--
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" []>
-->
<article>
<articleinfo>
  <title>arbtt – The Automatic Rule-Base Time Tracker</title>
  <authorgroup>
    <author>
      <firstname>Joachim</firstname>
      <surname>Breitner</surname>
      <contrib>Main author of arbtt</contrib>
      <email>mail@joachim-breitner.de</email>
    </author>
    <author id="sergey">
      <firstname>Sergey</firstname>
      <surname>Astanin</surname>
      <contrib>Contributor</contrib>
      <email>s.astanin@gmail.com</email>
    </author>
    <author id="martin">
      <firstname>Martin</firstname>
      <surname>Kiefel</surname>
      <contrib>Contributor</contrib>
      <email>mk@nopw.de</email>
    </author>
    <author id="muharem">
      <firstname>Muharem</firstname>
      <surname>Hrnjadovic</surname>
      <contrib>Contributor</contrib>
      <email>muharem@linux.com</email>
    </author>
    <author id="hauck">
      <firstname>Markus</firstname>
      <surname>Hauck</surname>
      <contrib>Contributor</contrib>
      <email>markus1189@gmail.com</email>
    </author>
    <author id="thomasz">
      <firstname>Thomasz</firstname>
      <surname>Miąsko</surname>
      <contrib>Contributor</contrib>
      <email>tomasz.miasko@gmail.com</email>
    </author>
    <author id="waldir">
      <firstname>Waldir</firstname>
      <surname>Pimenta</surname>
      <contrib>Documentation writer</contrib>
      <email>waldyrious@gmail.com</email>
    </author>
    <author id="gwern">
      <firstname>Gwern</firstname>
      <surname>Branwen</surname>
      <contrib>Documentation writer</contrib>
      <email>gwern@gwern.net</email>
    </author>
    <author id="paolo">
      <firstname>Paolo G.</firstname>
      <surname>Giarrusso</surname>
      <contrib>Contributor</contrib>
      <email>p.giarrusso@gmail.com</email>
    </author>
    <author id="michal">
      <firstname>Michal J.</firstname>
      <surname>Gajda</surname>
      <contrib>Contributor</contrib>
      <email>migamake@migamake.com</email>
    </author>
  </authorgroup>
</articleinfo>
<abstract>
  <para>
    arbtt is a background daemon that stores which windows are open, which one
    has the focus and how long since your last action (and possibly more sources
    later), and stores this. It is also a program that will, based on
    expressive rules you specify, derive what you were doing, and what for.
  </para>
  <para>
    It is comparable to the window trackers  <ulink
    url="https://www.rescuetime.com/">RescueTime</ulink>, <ulink
    url="https://github.com/gurgeh/selfspy">selfspy</ulink>, <ulink
    url="http://www.timesnapper.com/">TimeSnapper</ulink>, and
    <ulink url="https://etopian.com/software/automatic-screenshots-windows-mac-linux/">
    Productive Peach</ulink>; but it differs from the manual timetrackers like <ulink
    url="http://projecthamster.wordpress.com/about/">Project Hamster</ulink> which require
    the user to type a description of their activities.

    <warning><para>The log file might contain very sensitive private data. Make sure
    you understand the consequences of a full-time logger and be careful with this
    data.</para></warning>
  </para>
</abstract>

<sect1 id="installation">
  <title>Installation</title>
  <sect2>
    <title>Building with <command>cabal-install</command></title>
    <para>
    arbtt comes in the form of a Cabalized<footnote><para>Cabal is the common software
    packaging for Haskell programs and libraries, see <ulink
    url="http://www.haskell.org/cabal/"/>.</para></footnote> package, and is
    available from hackage. The easiest way of obtaining and installing arbtt is
    via <command>cabal-install</command>. If you have
    <command>cabal-install</command> available, just run
    <screen>$ cabal install arbtt</screen>
    to download, build and install arbtt.
    </para>
  </sect2>

  <sect2>
    <title>Building without <command>cabal-install</command></title>
    <para>
    You can fetch the latest arbtt source tarball from hackage, at
    <ulink url="http://hackage.haskell.org/package/arbtt"/>. Extract the tarball
    and run the following commands to build and install the arbtt binaries:
    <screen>$ runhaskell Setup.hs configure
$ runhaskell Setup.hs build
$ runhaskell Setup.hs install</screen>
    </para>
  </sect2>

  <sect2>
    <title>Setting up the capture program</title>
    <para>
    To have arbtt gather useful data, you need to make sure that
    <command>arbtt-capture</command> is started with your X session. If you use
    GNOME or KDE, you can copy the file
    <filename>arbtt-capture.desktop</filename> to
    <filename>~/.config/autostart/</filename>. You might need to put the full
    path to <command>arbtt-capture</command> in the Exec line there, if you did
    not do a system wide installation.
    </para>
    <para>
    By default, <command>arbtt-capture</command> will save one data sample per
    minute. If you want to change that, you can pass <option>--sample-rate
    <replaceable>RATE</replaceable></option> to <command>arbtt-capture</command>, where
    <replaceable>RATE</replaceable> specifies the sample rate in seconds.
    </para>
  </sect2>

  <sect2>
    <title>Building the documentation</title>
    <para>
    Obviously, you can already read the documentation. If you still want to
    build it yourself, enter the directory <filename>doc/</filename> and run
    <command>make</command> for the documentation in HTML and PDF format.
    </para>
  </sect2>


  <sect2>
    <title>Development version</title>
    <para>
      If you want to try the latest unreleased state of the code, or want to
      contribute to arbtt, you can fetch the code with
      <screen>darcs get <ulink url="http://darcs.nomeata.de/arbtt"/></screen>
    </para>
  </sect2>

</sect1>

<sect1 id="configuration">
  <title>Configuring the arbtt categorizer (<command>arbtt-stats</command>)</title>
  <para>
  Once <command>arbtt-capture</command> is running, it will record data without
  any configuration. And only to analyze the recorded data, one needs to
  configure the categorizer. Everytime the categorizer
  (<command>arbtt-stats</command>) runs, it applies categorization rules to all
  recorded data and tags it accordingly.  Thus, if you improve your
  categorization rules later, they will apply also to all previous data
  samples!
  </para>

  <sect2>
  <title>Configuration example</title>
  <para>
  The configuration file needs to be placed in
  <filename>~/.arbtt/categorize.cfg</filename>. An
  example is included in the source distribution, and it is reproduced here:
  see <xref linkend="catex"/>.
  It should be more enlightening than a formal description.
  </para>

  <example id="catex">
  <title><filename>categorize.cfg</filename></title>
    <programlisting><xi:include  href="../categorize.cfg"  parse="text"
      xmlns:xi="http://www.w3.org/2001/XInclude" /></programlisting>
  </example>
  </sect2>

  <sect2>
    <title>The semantics (informal)</title>
    <para>
      A data sample consists of the time of recording, the time passed since the
      user’s last action, the name of the current workspace and the list of
      windows. For each window this information is available:
      <itemizedlist>
        <listitem><simpara>the window title</simpara></listitem>
        <listitem><simpara>the program name</simpara></listitem>
        <listitem><simpara>whether the window was the active window</simpara></listitem>
      </itemizedlist>
      Based on this information and on the rules in
      <filename>categorize.cfg</filename>, the categorizer
      (<command>arbtt-stats</command>) assigns <emphasis>tags</emphasis> to
      each sample.
    </para>

    <para>
      A simple rule consists of a condition followed by an arrow
      (<literal>==></literal>) and a tag expression
      (<literal>tag</literal> keyword followed by tag name).
      The rule ends with a coma (<literal>,</literal>).
    </para>

    <para>
      The keyword <literal>tag</literal>, usually preceded with a condition,
      assigns a <emphasis>tag</emphasis> to the sample; <literal>tag</literal>
      keyword is followed by a tag name (any sequence of alphanumeric symbols,
      underscores and hyphens). If tag name contains a colon
      (<literal>:</literal>), the first part of the name before the colon, is
      considered to be tag <emphasis>category</emphasis>.
    </para>

    <para>
      For example, this rule
      <programlisting>month $date == 1 ==> tag month:January,</programlisting>
      if it succeeds, assigns a the tag <literal>January</literal> in the
      category <literal>month</literal>.
    </para>

    <para>If the tag has a <emphasis>category</emphasis>, it will only be
      assigned if no other tag of that category has been assigned. This means
      that for each sample and each category, there can be at most only one tag
      in that category. Tags can contain references to group matches in the
      regular expressions used in conditions (<literal>$1</literal>,
      <literal>$2</literal>)...). Tags can also reference some
      variables such as window title (<literal>$current.title</literal>) or
      program name (<literal>$current.program</literal>).
    </para>

    <para>
      The variable <literal>$idle</literal> contains the idle time of the user,
      measured in seconds. Usually, it is used to assign the tag
      <literal>inactive</literal>, which is handled specially by
      <command>arbtt-stats</command>, as can be seen in <xref linkend="catex"/>.
    </para>

    <para>
      When applying the rules, the categorizer has a notion of
      the <emphasis>window in scope</emphasis>, and the variables
      <literal>$title</literal>, <literal>$program</literal> and
      <literal>$active</literal> always refer to the window in scope.
      By default, there is no window is in scope. Condition should be prefixed
      with either <literal>current window</literal> or <literal>any
      window</literal>, to define scope of these variables.
    </para>

    <para>
      The name of the current desktop (or workspace) is available as
      <literal>$desktop</literal>.
    </para>

    <para>
      For <literal>current window</literal>, the currently active window is in
      scope. If there is no such window, the condition is false.
    </para>

    <para>
      For <literal>any window</literal>, the condition is applied to each
      window, in turn, and if any of the windows matches, the result is true. If
      more than one window matches it is not defined from which match the
      variables <literal>$1</literal>... are taken from (see more about regular
      expressions below).
    </para>

    <para>
      The variable <literal>$time</literal> refers to the time-of-day of the
      sample (i.e. the time since 00:00 that day, local time), while
      <literal>$sampleage</literal> refers to the
      time span from when the sample was recored until now, the time of
      evaluating the statistics. The latter variable is especially useful when
      passed to the <option>--filter</option> option of
      <command>arbtt-stats</command>. They can be compared with expressions
      like "hh:mm", for example
      <programlisting>$time >=  8:00 &amp;&amp; $time &lt; 12:00 ==> tag time-of-day:morning</programlisting>
    </para>

    <para>
      The variable <literal>$date</literal> refers to the date and time of the
      recorded sample. It can be compared with date literals in the form
      YYYY-MM-DD (which stand for midnight, so <programlisting>$date ==
      2001-01-01</programlisting> will not do what you want, but
      <programlisting>$date >= 2001-01-01 &amp;&amp; $date &lt;= 2001-01-02</programlisting>
      would).  All dates are evaluated in local time.
    </para>
    <para>
      Expression <literal>format $date</literal> evaluates to a string with
      a date formatted according to ISO 8601, i.e. like "YYYY-MM-DD". The 19th
      of March 2010 is formatted as "2010-03-19". Formatted date can be compared
      to strings. Formatted dates may be useful to tag particular date ranges. But
      also note that this is a rather expensive operation that can slow down your
      data processing.
    </para>
    <para>
      Expression <literal>month $date</literal> evaluates to an integer, from 1
      to 12, corresponding to the month number. Expression <literal>year
      $date</literal> evaluates to an integer which is a year number.
      Expression <literal>day of month $date</literal> evaluates to an integer,
      from 1 to 31, corresponding to the day of month.
      Expression <literal>day of week $date</literal> evaluates to an integer,
      from 1 to 7, corresponding to the day of week, Monday is 1, Sunday is 7.
      These expressions can be compared to integers.
    </para>

    <para>
      Expressions can be compared to literal values with <literal>==</literal>
      (equal), <literal>/=</literal> (not equal), <literal>&lt;</literal>,
      <literal>&lt;=</literal>, <literal>&gt;=</literal>,
      <literal>&gt;</literal> operators. String expressions
      (<literal>$program</literal>, <literal>$title</literal>) can be matched
      against regular expressions with <literal>=~</literal> operator. With these
      operatorions, the right hand side can be a comma-separated list of
      literals enclosed in square brackets (<literal>[</literal>
      <emphasis>...</emphasis>, <emphasis>...</emphasis>, <literal>]</literal>), which
      succeeds if any of them succeeds.
    </para>

    <para>Regular expressions are written either between slashes
       (<literal>/</literal> regular expression <literal>/</literal>),
       or after a letter <literal>m</literal> followed by any symbol
       (<literal>m</literal> <emphasis>c</emphasis> regular expression <emphasis>c</emphasis>, where <emphasis>c</emphasis> is any symbol).
       The second appearance of that symbol ends the expression.
       You can find both variants in <xref linkend="catex"/>.
    </para>

    <para>Complex conditions may be constructed from the simpler ones,
      using Boolean AND (<literal>&amp;&amp;</literal>), OR
      (<literal>||</literal>), and NOT (<literal>!</literal>) functions and
      parentheses.
    </para>

    <para>
      You can define short-hand names for conditions using
      <literal>condition</literal>:
      <programlisting>
        condition arbtt = current window $title =~ m/arbtt/ in {
          $arbtt &amp;&amp; $time &lt; 14:00 ==&gt; tag arbtt-morning,
          $arbtt &amp;&amp; $time &gt; 14:00 ==&gt; tag arbtt-afternoon
        }
      </programlisting>
      Everything that is a valid condition is assignable and you can
      reference bound variables in rules by prefixing them with a
      dollar (<literal>$</literal>).
    </para>

  </sect2>

  <sect2>
    <title>The syntax</title>
    <para>
    <filename>categorize.cfg</filename> is a plain text file.
    Whitespace is insignificant and Haskell-style comments are allowed.
    A formal grammar is provided in <xref linkend="grammar"/>.
    </para>

    <figure id="grammar">
        <title>The formal grammar of <filename>categorize.cfg</filename></title>
    <productionset>
      <production id="g-rules">
        <lhs>Rules</lhs>
        <rhs>
          [ <nonterminal def="#g-aliasspec"/> ]
          <nonterminal def="#g-rule"/> ( (<quote>,</quote>
          <nonterminal def="#g-rule"/>)* | ( <quote>;</quote>
          <nonterminal def="#g-rule"/>)* )
        </rhs>
      </production>

          <production id="g-aliasspec">
            <lhs>AliasSpec</lhs>
            <rhs><quote>aliases</quote> <quote>(</quote> <nonterminal
              def="#g-alias"/> (<quote>,</quote> <nonterminal def="#g-alias"/>)*
              <quote>)</quote> </rhs>
          </production>

          <production id="g-alias">
            <lhs>Alias</lhs>
            <rhs>Literal <quote>-&gt;</quote> Literal</rhs>
          </production>

      <production id="g-rule">
        <lhs>Rule</lhs>
        <rhs><quote>{</quote> <nonterminal def="#g-rules"/>
                 <quote>}</quote>
            </rhs>
            <rhs>
              <nonterminal def="#g-cond"/> <quote>==&gt;</quote>
              <nonterminal def="#g-rule"/> | <quote>if</quote>
              <nonterminal def="#g-cond"/> <quote>then</quote>
              <nonterminal def="#g-rule"/> <quote>else</quote>
              <nonterminal def="#g-rule"/>
            </rhs>
            <rhs>
              <quote>tag</quote> <nonterminal def="#g-tag"/>
            </rhs>
            <rhs><nonterminal def="#g-condition"/></rhs>
      </production>

      <production id="g-cond">
        <lhs>Cond</lhs>
        <rhs><quote>(</quote> <nonterminal def="#g-cond"/>
                 <quote>)</quote>
            </rhs>
            <rhs><quote>!</quote> <nonterminal def="#g-cond"/> |
                 <nonterminal def="#g-cond"/> <quote>&amp;&amp;</quote>
                 <nonterminal def="#g-cond"/> |
                 <nonterminal def="#g-cond"/> <quote>||</quote> <nonterminal
                 def="#g-cond"/>
            </rhs>
        <rhs> <quote>$active</quote> </rhs>
            <rhs> <nonterminal def="#g-string"/> <nonterminal def="#g-cmpop"/>
         <nonterminal def="#g-string"/> </rhs>
            <rhs> <nonterminal def="#g-string"/> <nonterminal def="#g-cmpop"/>
         <quote>[</quote> <nonterminal def="#g-listofstring"/>
                 <quote>]</quote>
                 </rhs>
            <rhs> <nonterminal def="#g-string"/> <quote>=~</quote>
             <nonterminal def="#g-regex"/></rhs>
            <rhs> <nonterminal def="#g-string"/> <quote>=~</quote>
         <quote>[</quote> <nonterminal def="#g-listofregex"/>
                 <quote>]</quote>
                 </rhs>
            <rhs> <nonterminal def="#g-number"/> <nonterminal def="#g-cmpop"/>
         <nonterminal def="#g-number"/> </rhs>
            <rhs> <nonterminal def="#g-timediff"/> <nonterminal def="#g-cmpop"/>
         <nonterminal def="#g-timediff"/> </rhs>
            <rhs> <nonterminal def="#g-date"/> <nonterminal def="#g-cmpop"/>
         <nonterminal def="#g-date"/> </rhs>
            <rhs> <quote>current window</quote> <nonterminal def="#g-cond"/> </rhs>
            <rhs> <quote>any window</quote> <nonterminal def="#g-cond"/> </rhs>
            <rhs> <quote>$</quote> Literal </rhs>
      </production>

      <production id="g-string">
        <lhs>String</lhs>
        <rhs> <quote>$title</quote> </rhs>
        <rhs> <quote>$program</quote> </rhs>
        <rhs> <quote>$desktop</quote> </rhs>
        <rhs> <quote>format</quote> <nonterminal def="#g-date" /> </rhs>
        <rhs> <quote>"</quote> string literal <quote>"</quote> </rhs>
      </production>

      <production id="g-listofstring">
        <lhs>
        ListOfString</lhs>
        <rhs> <quote>"</quote> string literal <quote>"</quote> </rhs>
        <rhs> <quote>"</quote> string literal <quote>"</quote> , <nonterminal def="#g-listofstring"/> </rhs>
      </production>

      <production id="g-number">
        <lhs>Number</lhs>
        <rhs> <quote>$idle</quote> </rhs>
        <rhs> <quote>day of week</quote> <nonterminal def="#g-date" /> </rhs>
        <rhs> <quote>day of month</quote> <nonterminal def="#g-date" /> </rhs>
        <rhs> <quote>month</quote> <nonterminal def="#g-date" /> </rhs>
        <rhs> <quote>year</quote> <nonterminal def="#g-date" /> </rhs>
        <rhs> number literal </rhs>
      </production>

      <production id="g-date">
        <lhs>Date</lhs>
        <rhs> <quote>$date</quote> </rhs>
        <rhs> <quote>$now</quote> </rhs>
      </production>

      <production id="g-timediff">
        <lhs>TimeDiff</lhs>
        <rhs> <quote>$time</quote> </rhs>
        <rhs> <quote>$sampleage</quote> </rhs>
        <!-- <rhs> <nonterminal def="#g-date"/> <quote>-</quote> <nonterminal def="#g-date"/></rhs> -->
            <rhs>( Digit )* Digit <quote>:</quote> Digit Digit</rhs>
      </production>

          <production id="g-tag">
            <lhs>Tag</lhs>
            <rhs> [ Literal <quote>:</quote> ] Literal </rhs>
          </production>

          <production id="g-regex">
            <lhs>RegEx</lhs>
            <rhs>  <quote>/</quote> Literal <quote>/</quote> |
              <quote>m</quote> <replaceable>c</replaceable> Literal
              <replaceable>c</replaceable><lineannotation>Where
              <replaceable>c</replaceable> can be any
              character.</lineannotation> </rhs>
          </production>

      <production id="g-listofregex">
        <lhs>ListOfRegex</lhs>
        <rhs> <quote>"</quote> <nonterminal def="#g-regex"/> <quote>"</quote> </rhs>
        <rhs> <quote>"</quote> <nonterminal def="#g-regex"/> <quote>"</quote> , <nonterminal def="#g-listofregex"/> </rhs>
      </production>

      <production id="g-cmpop">
        <lhs>CmpOp</lhs>
        <rhs><quote>&lt;=</quote> | <quote>&lt;</quote> |
        <quote>==</quote> | <quote>!=</quote>
        | <quote>&gt;</quote> | <quote>&gt;=</quote></rhs>
      </production>

      <production id="g-condition">
        <lhs>ConditionBinding</lhs>
        <rhs><quote>condition</quote> Literal <quote>=</quote> <nonterminal def="#g-cond"/> <quote>in</quote> <nonterminal def="#g-rule"/></rhs>
      </production>

    </productionset>
      </figure>
      <para>
        A <literal>String</literal> refers to a double-quoted string of
        characters, while a <literal>Literal</literal> is not quoted.
        <nonterminal def="#g-tag">Tags</nonterminal> may only consist of
        letters, dashes and underscores, or variable interpolations. A Tag maybe
        be optionally prepended with a category, separated by a colon. The
        category itself follows he same lexical rules as the tag. A variable
        interpolation can be one of the following:
        <variablelist>
          <varlistentry>
            <term><literal>$1</literal>, <literal>$2</literal>,...</term>
            <listitem><simpara> will be replaced by the respective group in the last
              successfully applied regular expression in the conditions enclosing the
              current rule.
            </simpara></listitem>
          </varlistentry>
          <varlistentry>
            <term><literal>$current.title</literal></term>
            <term><literal>$current.program</literal></term>
            <listitem><simpara> will be replaced by title the currently active
              window, resp. by the name of the currently active program.
              If no window happens to be active, this tag will be ignored.
            </simpara></listitem>
          </varlistentry>
        </variablelist>
      </para>

      <para>
        A regular expression is, like in perl, either enclosed in forward
        slashes or, alternatively, in any character of your choice with an
        <literal>m</literal> (for <quote>match</quote>) in front. This is handy if you need
        to use regular expressions that match directory names. Otherwise, the
        syntax of the regular expressions is that of perl-compatible regular
        expressions.
      </para>
  </sect2>
</sect1>

<sect1 id="effective-use">
  <title>Effective Use of Arbtt</title>
  <para>
    Now that the syntax has been described and the toolbox laid out,
    how do you practically go about using and configuring arbtt?
  </para>
  <sect2>
    <title>Enabling data collection</title>
    <para>
      After installing arbtt, you need to configure it to run. There
      are many ways you can run the <literal>arbtt-capture</literal>
      daemon. One standard way is to include the command
      <programlisting>
arbtt-capture &amp;
      </programlisting>
      in your desktop environments startup script, e.g.
      <filename>~/.xinitrc</filename> or similar.
    </para>
    <para>
      Another trick is add it as a <ulink
      url="https://en.wikipedia.org/wiki/Cron"><literal>cron</literal></ulink>
      job. To do so, edit your crontab file (<literal>crontab -e</literal>) and
      add a line like this:
    </para>
    <programlisting>
DISPLAY=:0
@reboot arbtt-capture --logfile=/home/username/doc/arbtt/capture.log
</programlisting>
    <para>
      At boot, <literal>arbtt-capture</literal> will be run in the
      background and will capture a snapshot of the X metadata for
      active windows every 60 seconds (the default). If you want more
      fine-grained time data at the expense of doubling storage use,
      you could increase the sampling rate with an option like
      <literal>--sample-rate=30</literal>. To be resilient to any errors
      or segfaults, you could also wrap it in an infinite loop to restart
      the daemon should it ever crash, with a command like
    </para>
    <programlisting>
DISPLAY=:0
@reboot while true; do arbtt-capture --sample-rate=30; sleep 1m; done
</programlisting>
  </sect2>
  <sect2>
    <title>Checking data availability</title>
    <para>
      arbtt tracks <ulink url="https://en.wikipedia.org/wiki/X_Window_System_protocols_and_architecture#Attributes_and_properties"
      >X</ulink> properties like window title, class, and running
      program, and you write rules to classify those strings as
      you wish; but this assumes that the necessary data is present in
      those properties.
    </para>
    <para>
      For some programs, this is the case. For example, web browsers
      like Firefox typically set the X title to the
      HTML <literal>&lt;title&gt;</literal> element of the web page in the
      currently-focused tab, which is enough for classification.
    </para>
    <para>
      Some programs have title-setting available as plugins. The IRC client <ulink url="http://www.irssi.org/">irssi</ulink>
      in a GNU screen or X terminal usually sets the title to just "<literal>irssi</literal>",
      which blocks more accurate time-classification based on IRC channel (one channel may be for
      recreation, another for programming, and yet another for work), but can be easily configured
      to set the title using the extension
      <ulink url="http://scripts.irssi.org/scripts/title.pl"><literal>title.pl</literal></ulink>.
    </para>
    <para>
      Some programs do not set titles or class, and all arbtt sees is
      empty strings like <literal>&quot;&quot;</literal>; or they may set the title/class
      to a constant like <literal>&quot;Liferea&quot;</literal>, which may be acceptable if
      that program is used for only one purpose, but if it is used for
      many purposes, then you cannot write a rule matching it without
      producing highly-misleading time analyses. (For example, a web
      browser may be used for countless purposes, ranging from work to
      research to music to writing to programming; but if the web
      browser's title/class were always just <literal>&quot;Web browser&quot;</literal>,
      how would you classify 5 hours spent using the web browser? If the
      5 hours are classified as any or all of those purposes, then the
      results will be misleading garbage - you probably did not spend 5
      hours just listening to music, but a mixture of those purposes,
      which changes from day to day.)
    </para>
    <para>
      You should check for such problematic programs upon starting using
      arbtt. It would be unfortunate if you were to log for a few
      months, go back for a detailed report for some reason, and
      discover that the necessary data was never available for
      arbtt to log!
    </para>
    <para>
      These programs can sometimes be customized internally, a bug
      report filed with the maintainers, or their titles can be
      externally set by
      <ulink url="https://en.wikipedia.org/wiki/Wmctrl"><literal>wmctrl</literal></ulink>
      or
      <ulink url="http://jonisalonen.com/2014/setting-x11-window-properties-with-xprop/"><literal>xprop</literal></ulink>.
    </para>
    <sect3>
      <title><literal>xprop</literal></title>
      <para>
        You can check the X properties of a running window by running
        the command
        <ulink url="http://www.xfree86.org/current/xprop.1.html"><literal>xprop</literal></ulink>
        and clicking on the window; <literal>xprop</literal> will print
        out all the relevant X information. For example, the output for
        Emacs might look like this
      </para>
      <programlisting>
$ xprop | tail -5
WM_CLASS(STRING) = &quot;emacs&quot;, &quot;Emacs&quot;
WM_ICON_NAME(STRING) = &quot;emacs@elan&quot;
_NET_WM_ICON_NAME(UTF8_STRING) = &quot;emacs@elan&quot;
WM_NAME(STRING) = &quot;emacs@elan&quot;
_NET_WM_NAME(UTF8_STRING) = &quot;emacs@elan&quot;
</programlisting>
      <para>
        This is not very helpful: it does not tell us the filename being
        edited, the mode being used, or anything. You could classify
        time spent in Emacs as &quot;programming&quot; or
        &quot;writing&quot;, but this would be imperfect, especially if
        you do both activities regularly. However, Emacs can be
        customized by editing <literal>~/.emacs</literal>, and after
        some searching with queries like &quot;setting Emacs window
        title&quot;, the
        <ulink url="http://www.emacswiki.org/emacs-en/FrameTitle">Emacs
        wiki</ulink> and
        <ulink url="https://www.gnu.org/software/emacs/manual/html_node/efaq/Displaying-the-current-file-name-in-the-titlebar.html">manual</ulink>
        advise us to put something like this Elisp in our
        <literal>.emacs</literal> file:
      </para>
      <programlisting>
(setq frame-title-format &quot;%f&quot;)
</programlisting>
      <para>
        Now the output looks different:
      </para>
      <programlisting>
$ xprop | tail -5
WM_CLASS(STRING) = &quot;emacs&quot;, &quot;Emacs&quot;
WM_ICON_NAME(STRING) = &quot;/home/gwern/arbtt.page&quot;
_NET_WM_ICON_NAME(UTF8_STRING) = &quot;/home/gwern/arbtt.page&quot;
WM_NAME(STRING) = &quot;/home/gwern/arbtt.page&quot;
_NET_WM_NAME(UTF8_STRING) = &quot;/home/gwern/arbtt.page&quot;
</programlisting>
      <para>
        With this, we can usefully classify all such time samples as
        being “writing”:
      </para>
<programlisting>
current window $title == &quot;/home/gwern/arbtt.page&quot; ==> tag Writing,
</programlisting>
      <para>
        Another common gap is terminals/shells: they often do not
        include information in the title like the current working
        directory or last shell command. For example, urxvt/Bash:
      </para>
      <programlisting>
WM_COMMAND(STRING) = { &quot;urxvt&quot; }
_NET_WM_ICON_NAME(UTF8_STRING) = &quot;urxvt&quot;
WM_ICON_NAME(STRING) = &quot;urxvt&quot;
_NET_WM_NAME(UTF8_STRING) = &quot;urxvt&quot;
WM_NAME(STRING) = &quot;urxvt&quot;
</programlisting>
      <para>
        Programmers may spend many hours in the shell doing a variety of
        things (like Emacs), so this is a problem. Fortunately, this is
        also solvable by customizing one's <literal>.bashrc</literal> to
        set the prompt to emit an escape code interpreted by the
        terminal (baroque, but it works). The following will include the
        working directory, a timestamp, and the last command:
      </para>
      <programlisting>
trap 'echo -ne &quot;\033]2;$(pwd); $(history 1 | sed &quot;s/^[ ]*[0-9]*[ ]*//g&quot;)\007&quot;' DEBUG
</programlisting>
      <para>
        Now the urxvt samples are useful:
      </para>
      <programlisting>
_NET_WM_NAME(UTF8_STRING) = &quot;/home/gwern/wiki; 2014-09-03 13:39:32 arbtt-stats --help&quot;
</programlisting>
      <para>
    Some distributions (e.g. Debian) already provide the relevant
    configuration for this to happen. If it does not work for you, you can try to add
    <programlisting>. /etc/profile.d/vte.sh</programlisting>
    to your <filename>~/.bashrc</filename>.
      </para>
      <para>
        A rule could classify based on the directory you are working in,
        the command one ran, or both. Other shells like zsh can be fixed
        this way too but the exact command may differ; you will need to
        research and experiment.
      </para>
      <para>
        Some programs can be tricky to set. The
        <ulink url="http://feh.finalrewind.org/">X image viewer
        feh</ulink> has a <literal>--title</literal> option but it
        cannot be set in the configuration file,
        <literal>.config/feh/themes</literal>, because it needs to be
        specified dynamically; so you need to set up a shell alias or
        script to wrap the command like
        <literal>feh --title &quot;$(pwd) / %f / %n&quot;</literal>.
      </para>
    </sect3>
    <sect3>
      <title>Raw samples</title>
      <para>
        <literal>xprop</literal> can be tedious to use on every running
        window and you may forget to check seldomly used programs. A better
        approach is to use <literal>arbtt-stats</literal>’s
        <literal>--dump-samples</literal> option: this option will print
        out the collected data for specified time periods, allowing you
        to examine the X properties en masse. This option can be used
        with the <literal>--exclude=</literal>
        option to print the samples for <emphasis>samples not matched
        by existing rules</emphasis> as well, which is indispensable for
        improving coverage and suggesting ideas for new rules. A good
        way to figure out what customizations to make is to run arbtt as
        a daemon for a day or so, and then begin examining the raw
        samples for problems.
      </para>
      <example>
      <title>An initial configuration session</title>
      <para>
        An example: suppose I create a simple category file named
        <literal>foo</literal> with just the line
      </para>
      <programlisting>
$idle &gt; 30 ==&gt; tag inactive
</programlisting>
      <para>
        I can then dump all my arbtt samples for the past day with a
        command like this:
      </para>
      <programlisting>
arbtt-stats --categorizefile=foo --m=0 --filter='$sampleage &lt;24:00' --dump-samples
</programlisting>
      <para>
        Because there are so many open windows, this produces a large
        amount (26586 lines) of hard-to-read output:
      </para>
      <programlisting>
...
( ) Navigator:      /r/Touhou's Favorite Arranges! Part 71: Retribution for the Eternal Night ~ Imperishable Night : touhou - Iceweasel
( ) Navigator:      Configuring the arbtt categorizer (arbtt-stats) - Iceweasel
( ) evince:         ATTACHMENT02
( ) evince:         2009-geisler.pdf — Heart rate variability predicts self-control in goal pursuit
( ) urxvt:          /home/gwern; arbtt-stats --categorizefile=foo --m=0 --filter='$sampleage &lt;24:00' --dump-samples
( ) mnemosyne:      Mnemosyne
( ) urxvt:          /home/gwern; 2014-09-03 13:11:45 xprop
( ) urxvt:          /home/gwern; 2014-09-03 13:42:17 history 1 | cut --delimiter=' ' --fields=5-
( ) urxvt:          /home/gwern; 2014-09-03 13:12:21 git log -p .emacs
(*) emacs:          emacs@elan
( ) urxvt:          /home/gwern; 2014-09-01 14:50:30 while true; do cd ~/ &amp;&amp; getmail_fetch --ssl pop.gmail.com gwern0 'ugaozoumbhwcijxb' ./mail/; done
( ) urxvt:          /home/gwern/blackmarket-mirrors/silkroad2-forums; 2014-08-31 23:20:10 mv /home/gwern/cookies.txt ./; http_proxy=&quot;localhost:8118&quot; wget...
( ) urxvt:          /home/gwern/blackmarket-mirrors/agora; 2014-08-31 23:15:50 mv /home/gwern/cookies.txt ./; http_proxy=&quot;localhost:8118&quot; wget --mirror ...
( ) urxvt:          /home/gwern/blackmarket-mirrors/evolution-forums; 2014-08-31 23:04:10 mv ~/cookies.txt ./; http_proxy=&quot;localhost:8118&quot; wget --mirror ...
( ) puddletag:      puddletag: /home/gwern/music
</programlisting>
      <para>
        Active windows are denoted by an asterisk, so I can focus &amp;
        simplify by adding a pipe like <literal>| fgrep '(*)'</literal>,
        producing more manageable output like
      </para>
      <programlisting>
(*) urxvt:          irssi
(*) urxvt:          irssi
(*) urxvt:          irssi
(*) Navigator:      Pyramid of Technology - NextNature.net - Iceweasel
(*) Navigator:      Search results - gwern0@gmail.com - Gmail - Iceweasel
(*) Navigator:      [New comment] The Wrong Path - gwern0@gmail.com - Gmail - Iceweasel
(*) Navigator:      Iceweasel
(*) Navigator:      Litecoin Exchange Rate - $4.83 USD - litecoinexchangerate.org - Iceweasel
(*) Navigator:      PredictionBook: LiteCoin will trade at &gt;=10 USD per ltc in 2 years, - Iceweasel
(*) urxvt:          irssi
(*) Navigator:      Bug#691547 closed by Mikhail Gusarov &lt;dottedmag@dottedmag.net&gt; (Re: s3cmd: Man page: --default-mime-type documentation incomplete...)
(*) Navigator:      Bug#691547 closed by Mikhail Gusarov &lt;dottedmag@dottedmag.net&gt; (Re: s3cmd: Man page: --default-mime-type documentation incomplete...)
(*) Navigator:      Bug#691547 closed by Mikhail Gusarov &lt;dottedmag@dottedmag.net&gt; (Re: s3cmd: Man page: --default-mime-type documentation incomplete...)
(*) urxvt:          /home/gwern; 2014-09-02 14:25:17 man s3cmd
(*) evince:         bayesiancausality.pdf
(*) evince:         bayesiancausality.pdf
(*) puddletag:      puddletag: /home/gwern/music
(*) puddletag:      puddletag: /home/gwern/music
(*) evince:         bayesiancausality.pdf
(*) Navigator:      ▶ Umineko no Naku Koro ni Music Box 4 - オルガン小曲 第2億番 ハ短調 - YouTube - Iceweasel
...
</programlisting>
      <para>
        This is better. We can see a few things: the windows all now
        produce enough information to be usefully classified (Gmail can
        be classified under email, irssi can be classified as IRC, the
        urxvt usage can clearly be classified as programming, the PDF
        being read is statistics, etc) in part because of customizations
        to bash/urxvt. The duplication still impedes focus, and we don't
        know what's most common. We can use another pipeline to sort,
        count duplicates, and sort by number of duplicates
        (<literal>| sort | uniq --count | sort --general-numeric-sort</literal>),
        yielding:
      </para>
      <programlisting>
 ...
 14     (*) Navigator:      A Bluer Shade of White Chapter 4, a frozen fanfic | FanFiction - Iceweasel
 14     (*) Navigator:      Iceweasel
 15     (*) evince:         2009-geisler.pdf — Heart rate variability predicts self-control in goal pursuit
 15     (*) Navigator:      Tool use by animals - Wikipedia, the free encyclopedia - Iceweasel
 16     (*) Navigator:      Hacker News | Add Comment - Iceweasel
 17     (*) evince:         bayesiancausality.pdf
 17     (*) Navigator:      Comments - Less Wrong Discussion - Iceweasel
 17     (*) Navigator:      Keith Gessen · Why not kill them all?: In Donetsk · LRB 11 September 2014 - Iceweasel
 17     (*) Navigator:      Notes on the Celebrity Data Theft | Hacker News - Iceweasel
 18     (*) Navigator:      A Bluer Shade of White Chapter 1, a frozen fanfic | FanFiction - Iceweasel
 19     (*) gl:             mplayer2
 19     (*) Navigator:      Neural networks and deep learning - Iceweasel
 20     (*) Navigator:      Harry Potter and the Philosopher's Zombie, a harry potter fanfic | FanFiction - Iceweasel
 20     (*) Navigator:      [OBNYC] Time tracking app - gwern0@gmail.com - Gmail - Iceweasel
 25     (*) evince:         ps2007.pdf — untitled
 35     (*) emacs:          /home/gwern/arbtt.page
 43     (*) Navigator:      CCC comments on The Octopus, the Dolphin and Us: a Great Filter tale - Less Wrong - Iceweasel
 62     (*) evince:         The physics of information processing superobjects - Anders Sandberg - 1999.pdf — Brains2
 69     (*) liferea:        Liferea
 82     (*) evince:         BMS_raftery.pdf — untitled
 84     (*) emacs:          emacs@elan
 87     (*) Navigator:      overview for gwern - Iceweasel
109     (*) puddletag:      puddletag: /home/gwern/music
150     (*) urxvt:          irssi
</programlisting>
      <para>
        Put this way, we can see what rules we should write to
        categorize: we could categorize the activities here into a few
        categories of &quot;recreational&quot;, &quot;statistics&quot;,
        &quot;music&quot;, &quot;email&quot;, &quot;IRC&quot;,
        &quot;research&quot;, and &quot;writing&quot;; and add to the
        <literal>categorize.cfg</literal> some rules like thus:
      </para>
      <programlisting>
$idle &gt; 30 ==&gt; tag inactive,

current window $title =~ [/.*Hacker News.*/, /.*Less Wrong.*/, /.*overview for gwern.*/, /.*[fF]an[fF]ic.*/, /.* LRB .*/]
  || current window $program == &quot;liferea&quot; ==&gt; tag Recreation,
current window $title =~ [/.*puddletag.*/, /.*mplayer2.*/] ==&gt; tag Music,
current window $title =~ [/.*[bB]ayesian.*/, /.*[nN]eural [nN]etworks.*/, /.*ps2007.pdf.*/, /.*[Rr]aftery.*/] ==&gt; tag Statistics,
current window $title =~ [/.*Wikipedia.*/, /.*Heart rate variability.*/, /.*Anders Sandberg.*/] ==&gt; tag Research,
current window $title =~ [/.*Gmail.*/] ==&gt; tag Email,
current window $title =~ [/.*arbtt.*/] ==&gt; tag Writing,
current window $title == &quot;irssi&quot; ==&gt; tag IRC,
</programlisting>
      <para>
        If we reran the command, we'd see the same output, so we need to
        leverage our new rules and <emphasis>exclude</emphasis> any
        samples matching our current tags, so now we run a command like:
      </para>
      <programlisting>
arbtt-stats --categorizefile=foo --filter='$sampleage &lt;24:00' --dump-samples --exclude=Recreation --exclude=Music --exclude=Statistics
             --exclude=Research --exclude=Email --exclude=Writing --exclude=IRC |
             fgrep '(*)' | sort | uniq --count | sort --general-numeric-sort
</programlisting>
      <para>
        Now the previous samples disappear, leaving us with a fresh
        batch of unclassified samples to work with:
      </para>
      <programlisting>
  9     (*) Navigator:      New Web Order &gt; Nik Cubrilovic - - Notes on the Celebrity Data Theft - Iceweasel
  9     ( ) urxvt:          /home/gwern; arbtt-stats --categorizefile=foo --filter='$sampleage &lt;24:00' --dump-samples | fgrep '(*)' | less
 10     (*) evince:         ATTACHMENT02
 10     (*) Navigator:      These Giant Copper Orbs Show Just How Much Metal Comes From a Mine | Design | WIRED - Iceweasel
 12     (*) evince:         [Jon_Elster]_Alchemies_of_the_Mind_Rationality_an(BookFi.org).pdf — Alchemies of the mind
 12     (*) Navigator:      Morality Quiz/Test your Morals, Values &amp; Ethics - YourMorals.Org - Iceweasel
 33     ( ) urxvt:          /home/gwern; arbtt-stats --categorizefile=foo --filter='$sampleage &lt;24:00' --dump-samples | fgrep '(*)'...
</programlisting>
      <para>
        We can add rules categorizing these as 'Recreational',
        'Writing', 'Research', 'Recreational', 'Research', 'Writing',
        and 'Writing' respectively; and we might decide at this point
        that 'Writing' is starting to become overloaded, so we'll split
        it into two tags, 'Writing' and 'Programming'. And then after
        tossing another <literal>--exclude=Programming</literal> into
        our rules, we can repeat the process.
      </para>
      <para>
        As we refine our rules, we will quickly spot instances where the
        title/class/program are insufficient to allow accurate
        classification, and we will figure out the best collection of
        tags for our particular purposes. A few iterations is enough for
        most purposes.
      </para>
      </example>
    </sect3>
  </sect2>
  <sect2>
    <title>Categorizing advice</title>
    <para>
      When building up rules, a few rules of thumb should be kept in
      mind:
    </para>
    <sect3>
        <title>
          Categorize by purpose, not by program
        </title>
        <para>
          This leads to misleading time reports. Avoid, for example,
          lumping all web browser time into a single category named
          'Internet'; this is more misleading than helpful. Good
          categories describe an activity or goal, such as 'Work' or
          'Recreation', not a tool, like 'Emacs' or 'Vim'.
        </para>
    </sect3>
    <sect3>
        <title>
          When in doubt, write narrow rules and generalize later
        </title>
        <para>
          Regexps are tricky and it can be easy to write rules far
          broader than one intended. The <literal>--exclude</literal>
          filters mean that one will never see samples which are matched
          accidentally. If one is in doubt, it can be helpful to take a
          specific sample one wants to match and several similar strings
          and look at how well one's regexp rule works in Emacs's
          <ulink url="http://www.emacswiki.org/emacs/ReBuilder">regexp-builder</ulink>
          or online regexp-testers like
          <ulink url="http://regexpal.com/">regexpal</ulink>.
        </para>
    </sect3>
    <sect3>
        <title>
          Don't try to classify everything
        </title>
        <para>
          You will never classify 100% of samples because sometimes
          programs do not include useful X properties and cannot be
          fixed, you have samples from before you fixed them, or they
          are too transient (like popups and dialogues) to be worth
          fixing. It is not necessary to classify 100% of your time,
          since as long as the most common programs and, say,
          <ulink url="https://en.wikipedia.org/wiki/Pareto_principle">80%</ulink>
          of your time is classified, then you have most of the value.
          It is easy to waste more time tweaking arbtt than one gains
          from increased accuracy or more finely-grained tags.
        </para>
    </sect3>
    <sect3>
    <title>
      Avoid large and microscopic tags
    </title>
    <para>
      If a tag takes up more than a third or so of your time, it is
      probably too large, masks variation, and can be broken down into more
      meaningful tags. Conversely, a tag too narrow to show up regularly in
      reports (because it is below the default 1% filter) may not be
      helpful because it is usually tiny, and can be combined with the most
      similar tag to yield more compact and easily interpreted reports.
    </para>
    </sect3>
  </sect2>
  <sect2>
    <title>Long-term storage</title>
    <para>
      Each halving of the sampling rate doubles the number of samples
      taken and hence the storage requirement; sampling rates below 20s
      are probably wasteful. But even the default 60s can accumulate
      into a nontrivial amount of data over a year. A
      constantly-changing binary file can interact poorly with backup
      systems, may make arbtt analyses slower, and if one's system
      occasionally crashes or experiences other problems, cause some
      corruption of the log and be a nuisance in having to run
      <literal>arbtt-recover</literal>.
    </para>
    <para>
      Thus it may be a good idea to archive one's
      <literal>capture.log</literal> on an annual basis. If one needs to
      query the historical data, the particular log file can be
      specified as an option like
      <literal>--logfile=/home/gwern/doc/arbtt/2013-2014.log</literal>
    </para>
  </sect2>
  <sect2 id="external-processing">
    <title>External processing of arbtt statistics</title>
    <para>
      arbtt supports CSV export of time by category in various levels of
      granularity in a 'long' format (multiple rows for each day, with
      <emphasis>n</emphasis> row specifying a category's value for that
      day). These CSV exports can be imported into statistical programs
      like R or Excel and manipulated as desired.
    </para>
    <para>
      R users may prefer to have their time data in a 'wide' format
      (each row is 1 day, with <emphasis>n</emphasis> columns for each
      possible category); this can be done with the
      <literal>reshape</literal> default library. After reading in the
      CSV, the time-intervals can be converted to counts and the data to
      a wide data-frame with R code like the following:
    </para>
    <programlisting>
arbtt &lt;- read.csv(&quot;arbtt.csv&quot;)
interval &lt;- function(x) { if (!is.na(x)) { if (grepl(&quot; s&quot;,x)) as.integer(sub(&quot; s&quot;,&quot;&quot;,x))
                                          else { y &lt;- unlist(strsplit(x, &quot;:&quot;));
                                                 as.integer(y[[1]])*3600 + as.integer(y[[2]])*60 + as.integer(y[[3]]); }
                                                 }
                         else NA
                         }
arbtt$Time &lt;- sapply(as.character(arbtt$Time), interval)
library(reshape)
arbtt &lt;- reshape(arbtt, v.names=&quot;Time&quot;, timevar=&quot;Tag&quot;, idvar=&quot;Day&quot;, direction=&quot;wide&quot;)
</programlisting>
  </sect2>
  <sect2 id="current-day">
    <title>Selecting the current day</title>
    <para>
      This can be done easily with a bit of help from the command line:
    </para>
    <programlisting>arbtt-stats  --filter='$date>='`date +"%Y-%m-%d"`</programlisting>
  </sect2>
</sect1>
<sect1 id="contributed">
  <title>Contributed tools</title>
  <para>
    Due to the import and export facilities of arbtt (as explained in <xref
    linkend="external-processing"/>), tools producing and analyzing arbtt’s
    data can be developed independently. This section lists those that we are
    aware of. If you create a tool of your own, or find one somewhere, please
    tell us on the mailing list (see <xref linkend="copyright"/>).
  </para>
  <sect2>
    <title>arbtt-graph</title>
    <para>
      Jayesh Kumar Gupta created a nice d3-based visualization of your arbtt
      data, including daily pie charts and barcode graphs.
    </para>
    <para>
      You can find his tool on <ulink url="https://github.com/rejuvyesh/arbtt-graph">https://github.com/rejuvyesh/arbtt-graph</ulink>.
    </para>
  </sect2>
  <sect2>
    <title>arbtt-capture for GNOME Shell</title>
    <para>
      An arbtt-capture implemented as a GNOME Shell extension. Its main value
      proposition is compatibility with Wayland (but it is compatible with
      traditional X Window System as well). You can find it on
      <ulink url="https://github.com/tmiasko/arbtt-capture">https://github.com/tmiasko/arbtt-capture</ulink>.
    </para>
  </sect2>
</sect1>
<sect1 id="references">
  <title>Program references</title>
  <para>arbtt consists of a few command line tools, the most important one is
  <command>arbtt-stats</command>. This overview is followed by their manual
  pages.
  </para>

  <!-- <sect2>
    <title>Generating statistics</title> -->
    <para>To generate statistics about the data that
    <command>arbtt-capture</command> has gathered, use the program
    <command>arbtt-stats</command>. A detailed description of the possible
    options is given in <xref linkend="arbtt-stats"/>.</para>
  <!--
  </sect2>

  <sect2>
    <title>Gathering data</title>
  -->
    <para>The collection of data is done by <command>arbtt-capture</command>.
    Usually, you only set it up once to run automatically, as described in <xref
    linkend="installation"/>, and do not have to
    worry about it again. Its command line reference is given in <xref
    linkend="arbtt-capture"/>.</para>
  <!--
  </sect2>

  <sect2>
    <title>Dumping data</title>
  -->
    <para>Because the data log file is binary, a tool names
    <command>arbtt-dump</command> can bee used to dump the data in
    various textual formats. Its command line reference is given in <xref
    linkend="arbtt-dump"/>.</para>

    <para>The textual form can be imported back using
    <command>arbtt-import</command>. Its command line reference is given in
    <xref linkend="arbtt-import"/>.</para>

    <para>If <command>arbtt-capture</command> crashes it might be that the log
    file is not readable any more. In some cases, this can be fixed using the
    (relatively raw) <command>arbtt-recover</command> tool. Its command line
    reference is given in <xref linkend="arbtt-recover"/>.</para>
  <!--
  </sect2>
  -->


  <refentry id="arbtt-stats">
    <refmeta>
      <refentrytitle>arbtt-stats</refentrytitle>
      <manvolnum>1</manvolnum>
      <refmiscinfo class="source">arbtt manual</refmiscinfo>
    </refmeta>

    <refnamediv>
      <refname>arbtt-stats</refname>
      <refpurpose>generate statistics from the arbtt data samples</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
      <cmdsynopsis>
        <command>arbtt-stats</command>
        <arg rep="repeat">OPTION</arg>
      </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1><title>Description</title>
      <para>
      <command>arbtt-stats</command> reads the samples that were recorded so far
      by <command>arbtt-capture</command> from the log file, filters them
      according to the users specifications and generates one or more reports
      from the data.
      </para>
      <para>
      When run without any options, <option>--total-time</option> is assumed.
      </para>
      <para>
      The order in which filters (<option>--exclude</option>,
      <option>--only</option>, <option>--also-inactive</option> and
      <option>--filter</option>) and reports are passed to the program is
      irrelevant: All filters given on the command line are active for all
      reports.
      </para>
    </refsect1>

    <refsect1><title>Options</title>
      <variablelist>
        <varlistentry>
          <term><option>-h</option></term>
          <term><option>-?</option></term>
          <term><option>--help</option></term>
          <listitem><simpara>shows a short summary of the available
          options, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-V</option></term>
        <term><option>--version</option></term>
        <listitem><simpara>shows the version number, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>--logfile</option> <replaceable>FILE</replaceable></term>
        <listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>--categorizefile</option></term>
        <listitem><simpara>categorize file to use instead of <filename>~/.arbtt/categorize.cfg</filename></simpara></listitem>
        </varlistentry>
      </variablelist>
      <refsect2><title>Filtering options</title>
        <variablelist>
          <varlistentry>
            <term><option>-x</option> <replaceable>TAG</replaceable></term>
            <term><option>--exclude</option> <replaceable>TAG</replaceable></term>
            <listitem><simpara>Ignore any data samples that have
            been assigned this tag or category. To distinguish tags and categories, the latter have to be
            entered followed by a colon. Can be given more than once.</simpara></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>-o</option> <replaceable>TAG</replaceable></term>
            <term><option>--only</option> <replaceable>TAG</replaceable></term>
            <listitem><simpara>Ignore any data samples that have
            not been assigned this tag. To distinguish tags and categories, the latter have to be
            entered followed by a colon. Can be given more than once.</simpara></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--also-inactive</option></term>
            <listitem><simpara>by default, <command>arbtt-stats</command> ignores
            any samples which have been assigned the tag
            <literal>inactive</literal>. This flag disables this behaviour.</simpara></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>-f</option> <replaceable>CONDITION</replaceable></term>
            <term><option>--filter</option> <replaceable>CONDITION</replaceable></term>
            <listitem><simpara>Only consider samples matching
            the given condition, which follows the same syntax as in
            <filename>categorize.cfg</filename> (Nonterminal <nonterminal def="#g-cond"/> in
            <phrase condition="html"><xref linkend="grammar"/></phrase><phrase condition="man">the formal grammar specification found in the user guide</phrase>).</simpara></listitem>
          </varlistentry>
        </variablelist>
      </refsect2>
      <refsect2><title>Report options</title>
        <variablelist>
          <varlistentry>
            <term><option>-m</option> <replaceable>PERCENTAGE</replaceable></term>
            <term><option>--min-percentage</option> <replaceable>PERCENTAGE</replaceable></term>
            <listitem><para>
              Ignore tags whose percentage is less than the value specified
              here. Default percentage: 1%.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--output-exclude</option> <replaceable>TAG</replaceable></term>
            <listitem><para>
              Skip this tag or category when printing statistics. Only affects
              the reports <option>--total-time</option> and
              <option>--category</option>. To distinguish tags and categories,
              the latter have to be entered followed by a colon. Can be given
              more than once.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--output-only</option> <replaceable>TAG</replaceable></term>
            <listitem><para>
              Prints statistics only for the specified tag or category. Only
              affects the reports <option>--total-time</option> and
              <option>--category</option>. To distinguish tags and categories,
              the latter have to be entered followed by a colon. Can be given
              more than once.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--output-format</option> <replaceable>FORMAT</replaceable></term>
            <listitem><para>
              Specify the report output format, may be one of: text, csv
              (comma-separated values), tsv (TAB-separated values).
              Default format: text.
            </para></listitem>
          </varlistentry>
        </variablelist>
      </refsect2>
      <refsect2><title>Reports</title>
        <variablelist>
          <varlistentry>
            <term><option>-i</option></term>
            <term><option>--information</option></term>
            <listitem><para>
              Various bits of information about the recorded data, such as total
              time recorded, number of records etc. In this report, <quote>time
              recorded</quote> is the sum of <emphasis>all</emphasis>
              samples, including inactive and those that are disabled by the
              filter, while <quote>time selected</quote> is the sum of the
              samples that are matched by the given filters.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>-t</option></term>
            <term><option>--total-time</option></term>
            <listitem><para>For all tags, print the part of the selected time
            with this tag applied to, both as an absolute value and a percentage
            of the selected time.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>-c</option> <replaceable>CATEGORY</replaceable></term>
            <term><option>--category</option> <replaceable>CATEGORY</replaceable></term>
            <listitem><para>For the given category, give the textual equivalent
            of a pie chart: For each possible value of the category, including
            one for <quote>no tag of this category present</quote>, give the absolute time and
            fraction. Entries which are not displayed because of the option
            <option>--min-percentage</option> are aggregated.</para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--each-category</option></term>
            <listitem><para>This is just a shortcut for a series of
            <option>--category</option> options, one for each category found in
            the data.
            </para></listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--intervals</option> [<replaceable>TAG</replaceable>|<replaceable>CATEGORY</replaceable>:] </term>
            <listitem><para>This report lists all periods of consecutive time
            intervals where the given tag has been applied to, or where the
            given category has the same value.
            </para>

            <para>To distinguish tags and categories, the latter have to be
            entered followed by a colon.</para>

            <para>This report will give wrong results if an activity has been
            carried out at the end of a session and right at the beginning, as
            the intermediate time is thought to be part of the interval.
            Inactive times while <command>arbtt-capture</command> is running
            will separate the results as expected.</para>

            </listitem>
          </varlistentry>
          <varlistentry>
            <term><option>--for-each</option> <replaceable>PERIOD</replaceable></term>
            <listitem><para>This is not a report of its own, but causes the selected
            report to be executed for each of the given PERIOD (which can be
            minute, hour,day, month or year) where there exist selected
            samples. All the reports will then be printed one after another or,
            in the case of CSV output, with an additional column.</para>

            <para>Note that if this option is enabled, samples that are filtered out
            are completely ignored (to avoid empty reports for periods with
            only filtered samples). Therefore, the
            <option>--information</option> report will print the numbers for
            the samples selected also for the totals.</para>

            </listitem>
          </varlistentry>
        </variablelist>
      </refsect2>
    </refsect1>

    <refsect1><title>Examples</title>
      <para>Some useful examples of what you can do with
      <command>arbtt-stats</command> are provided here:</para>
      <screen># Only consider the time when I was programming in Haskell
arbtt-stats -o Editing-Haskell

# Tell me what evolution folders I spend my time in when I actually do
# work with e-Mail
arbtt-stats -o Program:evolution -c Evo-Folder

# Generate statistics about the last hour
arbtt-stats -f '$sampleage &lt; 1:00'</screen>
    </refsect1>

    <refsect1><title>Files</title>
      <variablelist>
        <varlistentry>
          <term><filename>~/.arbtt/capture.log</filename></term>
          <listitem><para>binary file, storing the arbtt data samples</para></listitem>
        </varlistentry>
        <varlistentry>
          <term><filename>~/.arbtt/categorize.cfg</filename></term>
          <listitem><para>specification of the arbtt categorizer syntax. A
          detailed description is given in <xref linkend="configuration"/></para></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>

    <refsect1><title>See also</title>
      <para>See the arbtt manual for more information and the <ulink
      url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
      newer versions of arbtt.</para>
    </refsect1>
  </refentry>

  <refentry id="arbtt-capture">
    <refmeta>
      <refentrytitle>arbtt-capture</refentrytitle>
      <manvolnum>1</manvolnum>
      <refmiscinfo class="source">arbtt manual</refmiscinfo>
    </refmeta>

    <refnamediv>
      <refname>arbtt-capture</refname>
      <refpurpose>collect data samples for arbtt</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
      <cmdsynopsis>
        <command>arbtt-capture</command>
        <arg rep="repeat">OPTION</arg>
      </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1><title>Description</title>
      <para>
      <command>arbtt-capture</command> runs continuously and saves at the given
      sample rate, usually once per minute, the collected data to
      <filename>~/.arbtt/capture.log</filename>.
      </para>
    </refsect1>

    <refsect1><title>Options</title>
      <variablelist>
        <varlistentry>
          <term><option>-h</option></term>
          <term><option>-?</option></term>
          <term><option>--help</option></term>
          <listitem><simpara>shows a short summary of the available
          options, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-V</option></term>
        <term><option>--version</option></term>
        <listitem><simpara>shows the version number, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-r</option> <replaceable>RATE</replaceable></term>
        <term><option>--sample-rate</option> <replaceable>RATE</replaceable></term>
        <listitem><simpara>sets the sample rate in seconds (default: 60)</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-f</option> <replaceable>FILE</replaceable></term>
        <term><option>--logfile</option> <replaceable>FILE</replaceable></term>
        <listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-d</option></term>
        <term><option>--dump</option></term>
        <listitem><simpara>dump one current sample instead of modifying the logfile</simpara></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>
    <refsect1><title>Files</title>
      <variablelist>
        <varlistentry>
          <term><filename>~/.arbtt/capture.log</filename></term>
          <listitem><para>binary file, storing the arbtt data samples</para></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>


    <refsect1><title>See also</title>
      <para>See the arbtt manual for more information and the <ulink
      url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
      newer versions of arbtt.</para>
    </refsect1>
  </refentry>

  <refentry id="arbtt-dump">
    <refmeta>
      <refentrytitle>arbtt-dump</refentrytitle>
      <manvolnum>1</manvolnum>
      <refmiscinfo class="source">arbtt manual</refmiscinfo>
    </refmeta>

    <refnamediv>
      <refname>arbtt-dump</refname>
      <refpurpose>dumps arbtt data samples</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
      <cmdsynopsis>
        <command>arbtt-dump</command>
        <arg rep="repeat">OPTION</arg>
      </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1><title>Description</title>
      <para>
      <command>arbtt-dump</command> reads the data samples recorded by <xref
      linkend="arbtt-capture"/> and writes them so the standard output in an
      ascii based format.
      </para>
    </refsect1>

    <refsect1><title>Options</title>
      <variablelist>
        <varlistentry>
          <term><option>-h</option></term>
          <term><option>-?</option></term>
          <term><option>--help</option></term>
          <listitem><simpara>shows a short summary of the available
          options, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-V</option></term>
        <term><option>--version</option></term>
        <listitem><simpara>shows the version number, and exists.</simpara></listitem>
    </varlistentry>
        <varlistentry>
        <term><option>-f</option> <replaceable>FILE</replaceable></term>
        <term><option>--logfile</option> <replaceable>FILE</replaceable></term>
        <listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-t</option> <replaceable>FORMAT</replaceable></term>
        <term><option>--format</option> <replaceable>FORMAT</replaceable></term>
        <listitem><simpara>dumping format to use, where <replaceable>FORMAT</replaceable> is one of <literal>human</literal> (the default), <literal>show</literal> or <literal>JSON</literal>. Case in-sensitive.</simpara></listitem>
    </varlistentry>
        <varlistentry>
        <term><option>-l</option> <replaceable>NUMBER</replaceable></term>
        <term><option>--last</option> <replaceable>NUMBER</replaceable></term>
        <listitem><simpara>dump only the last <replaceable>NUMBER</replaceable> of samples.</simpara></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>

    <refsect1><title>Files</title>
      <variablelist>
        <varlistentry>
          <term><filename>~/.arbtt/capture.log</filename></term>
          <listitem><para>binary file, storing the arbtt data samples</para></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>

    <refsect1><title>Formats</title>
      <refsect2><title>Human</title>
      <para>This format is intended for human inspection, but not for further
      processing. Hence, it may change in new versions of arbtt without notice.
      Example output:</para>
      <screen>2013-06-20 14:53:50 (48ms inactive):
    ( ) Navigator:      arbtt-dump - Iceweasel
    ( ) gnome-terminal-server: jojo@kirk:~/projekte/programming/arbtt/doc
    (*) gvim:           arbtt.xml + (~/projekte/programming/arbtt/doc) - GVIM2
</screen>
      <para>The line with a star indicates the currently active window.</para>
      </refsect2>

      <refsect2><title>Show</title>
      <para>This is the default serialization format of Haskell's
      <literal>Show</literal> type class, one entry per line. This can be
      useful if the data is to be processed by further Haskell code. Example
      output, with indentation added manually:</para>
      <screen>TimeLogEntry
    { tlTime = 2013-06-20 14:53:50.957763 UTC
    , tlRate = 60000
    , tlData = CaptureData
        { cWindows =
            [ (False,"arbtt-dump - Iceweasel","Navigator")
            , (False,"jojo@kirk:~/projekte/programming/arbtt/doc","gnome-terminal-server")
            , (True,"arbtt.xml + (~/projekte/programming/arbtt/doc) - GVIM2","gvim")
            ]
        , cLastActivity = 48
        }
    }</screen>
      </refsect2>

      <refsect2><title>JSON</title>
      <para>For interoperability, arbtt supports dumping its data to JSON, which can
      easily be parsed by many different programming languages. Some level of
      backward-compatibility will be provided, as far as possible. Default
      output, again with indentation and spacing added manually:</para>
      <screen>[ ...,
  { "windows": [
      { "program": "arbtt-dump - Iceweasel",
        "title": "Navigator",
        "active": false},
      { "program": "jojo@kirk:~/projekte/programming/arbtt/doc",
        "title":" gnome-terminal-server",
        "active": false},
      { "program": "arbtt.xml + (~/projekte/programming/arbtt/doc) - GVIM2",
        "title": "gvim",
        "active":true
      }],
    "inactive": 48,
    "date": "2013-06-20T14:53:50.957Z",
    "rate": 60000},
  ...
]</screen>
      </refsect2>
    </refsect1>

    <refsect1><title>See also</title>
      <para>See the arbtt manual for more information and the <ulink
      url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
      newer versions of arbtt.</para>
    </refsect1>
  </refentry>

  <refentry id="arbtt-import">
    <refnamediv>
      <refname>arbtt-import</refname>
      <refpurpose>imports dumped arbtt data samples</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
      <cmdsynopsis>
        <command>arbtt-import</command>
        <arg rep="repeat">OPTION</arg>
      </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1><title>Description</title>
      <para>
      <command>arbtt-import</command> reads data from standard input and adds
      the entries to the logfile. It supports the <literal>Show</literal>
      format as well as the <literal>JSON</literal> format, and can be used in
      a streaming fashion (i.e. it will write entries as they are read from
      standard input).
      </para>

      <para>
      By default, this program completely overrides the existing file, therefore it
      will refuse to work if the log file already exists. If you want to
      overwrite a file, please delete it before running
      <command>arbtt-import</command>. If you want to extend an existing file,
      use the <option>--append</option> option.
      </para>
    </refsect1>

    <refsect1><title>Options</title>
      <variablelist>
        <varlistentry>
          <term><option>-h</option></term>
          <term><option>-?</option></term>
          <term><option>--help</option></term>
          <listitem><simpara>shows a short summary of the available
          options, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-V</option></term>
        <term><option>--version</option></term>
        <listitem><simpara>shows the version number, and exists.</simpara></listitem>
    </varlistentry>
    <varlistentry>
        <term><option>-f</option> <replaceable>FILE</replaceable></term>
        <term><option>--logfile</option> <replaceable>FILE</replaceable></term>
        <listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
    </varlistentry>
    <varlistentry>
        <term><option>-a</option></term>
	<term><option>--append</option></term>
        <listitem><simpara>append the log file, if it already exists</simpara></listitem>
    </varlistentry>
    <varlistentry>
        <term><option>-t</option> <replaceable>FORMAT</replaceable></term>
        <term><option>--format</option> <replaceable>FORMAT</replaceable></term>
        <listitem><simpara>format to use, where <replaceable>FORMAT</replaceable> is one of <literal>show</literal> (the default) or <literal>JSON</literal>. The JSON format can either be a list of records (as dumped by <xref linkend="arbtt-dump"/>), or just one record after another (useful in streaming mode).</simpara></listitem>
    </varlistentry>
    </variablelist>
    </refsect1>
    <refsect1><title>Files</title>
      <variablelist>
        <varlistentry>
          <term><filename>~/.arbtt/capture.log</filename></term>
          <listitem><para>binary file, storing the arbtt data samples</para></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>

    <refsect1><title>See also</title>
      <para>See the arbtt manual for more information and the <ulink
      url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
      newer versions of arbtt.</para>
    </refsect1>
  </refentry>

  <refentry id="arbtt-recover">
    <refmeta>
      <refentrytitle>arbtt-recover</refentrytitle>
      <manvolnum>1</manvolnum>
      <refmiscinfo class="source">arbtt manual</refmiscinfo>
    </refmeta>

    <refnamediv>
      <refname>arbtt-recover</refname>
      <refpurpose>tries to recover a broken arbtt data log</refpurpose>
    </refnamediv>

    <refsynopsisdiv>
      <cmdsynopsis>
        <command>arbtt-recover</command>
        <arg rep="repeat">OPTION</arg>
      </cmdsynopsis>
    </refsynopsisdiv>

    <refsect1><title>Description</title>
      <para>
      <command>arbtt-recover</command> tries to read the data samples recorded
      by <xref linkend="arbtt-capture"/>, skipping over possible broken entries. A fixed log file is written to <filename>~/.arbtt/capture.log.recovered</filename>. If the recovery was successful, you should stop <command>arbtt-capture</command> and move the file to <filename>~/.arbtt/capture.log</filename>.
      </para>
      <para>
      As a side effect, <command>arbtt-recover</command> applies the log compression method implemented in version 0.4.5 to the samples created by an earlier version. If you have a large logfile written by older versions, running <command>arbtt-recover</command> is recommended.
      </para>
    </refsect1>

    <refsect1><title>Options</title>
      <variablelist>
        <varlistentry>
          <term><option>-h</option></term>
          <term><option>-?</option></term>
          <term><option>--help</option></term>
          <listitem><simpara>shows a short summary of the available
          options, and exists.</simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-V</option></term>
        <term><option>--version</option></term>
        <listitem><simpara>shows the version number, and exists.</simpara></listitem>
    </varlistentry>
        <varlistentry>
        <term><option>-i</option></term>
        <term><option>--infile</option></term>
        <listitem><simpara>logfile to use instead of <filename>~/.arbtt/capture.log</filename></simpara></listitem>
        </varlistentry>
        <varlistentry>
        <term><option>-o</option></term>
        <term><option>--outfile</option></term>
        <listitem><simpara>where to save the recovered file, instead of <filename>~/.arbtt/capture.log.recovered</filename></simpara></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>
    <refsect1><title>Files</title>
      <variablelist>
        <varlistentry>
          <term><filename>~/.arbtt/capture.log</filename></term>
          <listitem><para>binary file, storing the arbtt data samples</para></listitem>
        </varlistentry>
        <varlistentry>
          <term><filename>~/.arbtt/capture.log.recovered</filename></term>
          <listitem><para>binary file, storing the fixed arbtt data samples</para></listitem>
        </varlistentry>
      </variablelist>
    </refsect1>

    <refsect1><title>See also</title>
      <para>See the arbtt manual for more information and the <ulink
      url="http://hackage.haskell.org/package/arbtt">arbtt hackage page</ulink> for
      newer versions of arbtt.</para>
    </refsect1>
  </refentry>
</sect1>

<sect1 id="troubleshooting">
  <title>Troubleshooting</title>
  <sect2>
    <title>arbtt and xmonad</title>
    <para>
      If you are using the <ulink url="http://xmonad.org">xmonad</ulink> window manager and arbtt does ont record any windows, ensure that your xmonad configuration includes the EWMH-Hints extensions in the module <ulink url="http://hackage.haskell.org/packages/archive/xmonad-contrib/latest/doc/html/XMonad-Hooks-EwmhDesktops.html">XMonad.Hooks.EwmhDesktops</ulink>.
    </para>
  </sect2>
</sect1>

<sect1 id="copyright">
  <title>Copyright and Contact</title>
  <para>
  arbtt is Copyright © 2009-2010 Joachim Breitner
  </para>

  <para>
    arbtt does not have a bug tracker yet. If you have bug reports, suggestions
    or questions, please send an email to the arbtt mailing list at <ulink url="mailto:arbtt@lists.nomeata.de">arbtt@lists.nomeata.de</ulink>, which you can subscribe at <ulink url="http://lists.nomeata.de/mailman/listinfo/arbtt">http://lists.nomeata.de/mailman/listinfo/arbtt</ulink>.
  </para>

  <sect2>
    <title>arbtt License</title>
    <para>
    <literallayout>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    </literallayout>
    </para>
  </sect2>
</sect1>

<sect1 id="release-notes">
  <title>Release Notes</title>
  <para>
  The version history with changes relevant for the user is documented here.
  </para>

  <sect2 id="release-notes-0.10.2">
    <title>Version 0.10.2</title>
    <itemizedlist>
      <listitem>
        <para>
	  The category report now also has an entry <literal>(total time)</literal>, especially useful with <option>--for-each</option>.
	</para>
      </listitem>
      <listitem>
        <para>
	  Support for GHC-8.0 and older has been dropped.
	</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2 id="release-notes-0.10.1">
    <title>Version 0.10.1</title>
    <itemizedlist>
      <listitem>
        <para>
	  Rodney Lorrimar contributed fixed to build against newer versions of dependencies.
	</para>
      </listitem>
      <listitem>
        <para>
	  Michal J. Gajda ensured that intervals are also printed as local times.
	</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2 id="release-notes-0.10">
    <title>Version 0.10</title>
    <itemizedlist>
      <listitem>
        <para>
	  Markus Hauck contributed the <literal>!=</literal> operator, the
	  <quote>$now</quote> variable and the <literal>condition</literal>
	  construct (as well as other code cleanup).
         </para>
      </listitem>
      <listitem>
        <para>
	  The development repository migrated from darcs to git.
	</para>
      </listitem>
      <listitem>
        <para>
	  The command <xref linkend="arbtt-import"/> now supports reading JSON
	  records, and can be used to append to an exising log file in a
	  steaming fasion.
	</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2 id="release-notes-0.9">
    <title>Version 0.9</title>
    <itemizedlist>
      <listitem>
    <para>
          The <option>--for-each</option> option of
          <command>arbtt-stats</command> now supports grouping results by
          minute or hour.
    </para>
      </listitem>
      <listitem>
    <para>
      Gwern Branwen contributed the <xref linkend="effective-use"/>.
    </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2 id="release-notes-0.8.1">
    <title>Version 0.8.1</title>
    <itemizedlist>
      <listitem>
    <para>
      The syntax now allows for time differences larger than 99:99.
          (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/14/improve-time-categorization-directives">issue #14</ulink>)
    </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2 id="release-notes-0.8">
    <title>Version 0.8</title>
    <itemizedlist>
      <listitem>
    <para>
      <command>arbtt-dump</command> can now show the data in other formats
      as well, as suggested by Waldir Pimenta (option
      <option>--format</option>). This includes a human-readale output and
      JSON.
    </para>
      </listitem>
      <listitem>
        <para>New option <option>--last</option> of <command>arbtt-dump</command>.</para>
      </listitem>
      <listitem>
        <para><command>arbtt-recover</command> can handle larger datasets with a reasonable amount of memory.</para>
      </listitem>
      <listitem>
        <para>When dumping samples with <command>arbtt-stats</command> or <command>arbtt-dump</command> (in human-readable mode), times are printed in the local time zone, as suggested by Oren Gampel.</para>
      </listitem>
      <listitem>
        <para><command>arbtt-capture</command> now supports the option <option>--dump</option> for development and debugging purposes.</para>
      </listitem>
      <listitem>
        <para>The name of the current desktop (or workspace) is also recorded, and available as <literal>$desktop</literal> (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/1/track-active-workspace-name">issue #1</ulink>).</para>
      </listitem>
      <listitem>
        <para>Two bugs in the parser were fixed (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/4/parsing-of-if-then-else-fails">issue #4</ulink> and <ulink url="https://bitbucket.org/nomeata/arbtt/issue/5/parsing-of-fails">issue #5</ulink>).</para>
      </listitem>
      <listitem>
        <para><command>arbtt-stats</command> can print reports split by time interval, using the <option>--for-each</option> option.</para>
      </listitem>
      <listitem>
        <para><command>arbtt-stats</command> can print the actual samples selected, with <option>--dump-samples</option>.</para>
      </listitem>
      <listitem>
        <para>Support for GHC-7.8 was added, with help from Jayesh Kumar Gupta (<ulink url="https://bitbucket.org/nomeata/arbtt/issue/8/update-base-bounds-for-newer-ghc">issue #8</ulink>).</para>
      </listitem>
      <listitem>
        <para>Arbtt now has a proper testsuite integrated into Cabal, and an <ulink url="https://travis-ci.org/nomeata/darcs-mirror-arbtt">automated test infrastructure</ulink> on Travis.</para>
      </listitem>
      <listitem>
        <para>Waldir Pimenta contributed a new web page, hosted at <ulink url="http://arbtt.nomeata.de/">arbtt.nomeata.de</ulink>.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.7</title>
    <itemizedlist>
      <listitem>
        <para>Make sure that the log file is only readable by the current user. Thanks to Joey Hess for pointing that out.</para>
      </listitem>
      <listitem>
        <para>Show a progress bar in <command>arbtt-stats</command>.</para>
      </listitem>
      <listitem>
        <para>GHC-7.6 compatibility, thanks to Isaac Dupree.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.6.4.1</title>
    <itemizedlist>
      <listitem>
        <para>
        Added missing module to the packages.
        </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.6.4</title>
    <itemizedlist>
      <listitem>
        <para>Massive memory footprint reduction, due to processing the data in one run. See <ulink url="http://www.joachim-breitner.de/blog/archives/560-The-might-applicative-left-fold.html">my blog post for technical information</ulink>.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.6.3</title>
    <itemizedlist>
      <listitem>
        <para>Performance improvements.</para>
      </listitem>
      <listitem>
        <para>Support comparing a string to a list of strings, or matching it against a list ofregular expressions.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.6.2</title>
    <itemizedlist>
      <listitem>
        <para>Add a warning whtn the system locale is not supported.</para>
      </listitem>
      <listitem>
        <para>Allwo RTS options to be passed to the arbtt binaries.</para>
      </listitem>
      <listitem>
        <para>GHC 7.4 compatibility.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.6.1</title>
    <itemizedlist>
      <listitem>
        <para>Performance improvements.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.6</title>
    <itemizedlist>
      <listitem>
        <para>The command <command>arbtt-capture</command> now supports the
        <option>--logfile</option>.
        </para>
      </listitem>
      <listitem>
        <para>New report “intervals”, available using <command>arbtt-stats</command> <option>--intervals</option>.
        </para>
      </listitem>
      <listitem>
        <para>The paramters <option>--exclude</option> and
        <option>--include</option> of <command>arbtt-stats</command> can match
        categories as well as tags.
        </para>
      </listitem>
      <listitem>
        <para>Bugfix: Numbers in tag names are no longer replaced by an underscore.</para>
      </listitem>
      <listitem>
        <para>New paramters <option>--output-exclude</option> and
        <option>--output-include</option> of <command>arbtt-stats</command>.
        </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.5 (The ZuriHac-Release)</title>
    <itemizedlist>
      <listitem>
    <para>New command <command>arbtt-import</command>, which imports the output from <command>arbtt-dump</command>.
        </para>
      </listitem>
      <listitem>
        <para>The command <command>arbtt-stats</command> now supports the
        <option>--logfile</option> and <option>--categorizefile</option> as well.
        (<xref linkend="martin"/>)
        </para>
      </listitem>
      <listitem>
        <para>
          The command <command>arbtt-stats</command> now supports the csv
          (comma-separated values) and tsv (TAB-separated values) report output
          formats in addition to text.
          (<xref linkend="muharem"/>)
        </para>
      </listitem>
      <listitem>
        <para>
      Unicode is handled correctly in regular expressions.
    </para>
      </listitem>
      <listitem>
        <para>
      Improved date-handling functions for <filename>categorize.cfg</filename>.
          (<xref linkend="sergey"/>)
    </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.4.5.1</title>
    <itemizedlist>
      <listitem>
        <para>Bugfix: Added missing modules to the cabal file.
    </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.4.5</title>
    <itemizedlist>
      <listitem>
        <para>Implement a custom compression method greatly reduce the file size of the log file. Run <command>arbtt-capture</command> to compress the previous samples as well.
    </para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.4.4</title>
    <itemizedlist>
      <listitem>
        <para>Bugfix: Correctly parse a tag name containing a colon when passed to <command>arbtt-stats</command> <option>--exclude</option>.</para>
      </listitem>
      <listitem>
        <para>Bugfix: Only warn once when the <token>_NET_CLIENT_LIST</token> X property is not set for the root window.</para>
      </listitem>
    </itemizedlist>
  </sect2>


  <sect2>
    <title>Version 0.4.3</title>
    <itemizedlist>
      <listitem>
        <para>Use fetchName from xmonad instead of xFetchName, as it works with unicode characters in window titles.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.4.2</title>
    <itemizedlist>
      <listitem>
        <para>Implement option <option>--logfile</option> to
        <command>arbtt-dump</command>.</para>
      </listitem>
      <listitem>
    <para>New command <command>arbtt-recover</command> to rescue data from
    a proken data log file.</para>
      </listitem>
      <listitem>
    <para>Actually include this documentation in the released tarball.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.4.1</title>
    <itemizedlist>
      <listitem>
        <para>Write this documentation</para>
      </listitem>
      <listitem>
        <para>Drop dependency on setlocale: Copy the SetLocale module.</para>
      </listitem>
      <listitem>
        <para>Drop dependency on tabular: Implement custom table rendering code.</para>
      </listitem>
      <listitem>
        <para>In the absence of _NET_CLIENT_LIST, look for application windows as children of the root windows. This should work for users of window managers like i3 without EWHM support.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.4</title>
    <itemizedlist>
      <listitem>
        <para>Implement option <option>--each-categories</option> to
        <command>arbtt-stats</command></para>
      </listitem>
      <listitem>
        <para>Eliminate one possible cause for crashes of
        <command>arbtt-capture</command>.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.3.0</title>
    <itemizedlist>
      <listitem>
        <para>Switch to binary log file format, for greatly increased speed</para>
      </listitem>
      <listitem>
        <para><command>arbtt-capture</command> will automatically detect and
        convert log files in the old format.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.2.0</title>
    <itemizedlist>
      <listitem>
        <para>Add option <option>--filter</option> to
        <command>arbtt-stats</command></para>
      </listitem>
      <listitem>
        <para>Add option <option>--sample-rate</option> to
        <command>arbtt-capture</command></para>
      </listitem>
      <listitem>
        <para>Introduce time-base variables <literal>$time</literal> and
        <literal>$sampleage</literal></para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.1.5</title>
    <itemizedlist>
      <listitem>
        <para>Use <function>setlocale</function> to get umlauts in window titles correctly</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.1.4</title>
    <itemizedlist>
      <listitem>
        <para>Be smarter when figuring out what window is active. Thanks to CJ
        van den Berg for investigating the issue.</para>
      </listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.1.3</title>
    <itemizedlist>
      <listitem><para>Read <literal>_NET_CLIENT_LIST</literal> for the list of
      applications, for compatibility with window managers such as metacity</para></listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.1.2</title>
    <itemizedlist>
      <listitem><para>Off-By-Ten error in the time display</para></listitem>
      <listitem><para>Correctly show total number of records in
      <option>--information</option></para></listitem>
    </itemizedlist>
  </sect2>

  <sect2>
    <title>Version 0.1.1</title>
    <para>
    Rename files to allow building on MacOS.
    </para>
  </sect2>

  <sect2>
    <title>Version 0.1</title>
    <para>
    Initial release of arbtt
    </para>
  </sect2>
</sect1>

</article>
