<?xml version="1.0" encoding="UTF-8"?>
<sect1 id="Filters">
  <title>Filters</title>

  <para>There are two kinds of filters in WinMerge: file filters for filtering
  files and directories in directory compare and line filters for ignoring
  lines from files before comparing.</para>

  <sect2>
    <title>Regular expressions</title>

    <para>Filters are based on regular expressions (regexps). Each line filter
    or file filter rule is regexp which is matched against file/directory name
    or line.</para>

    <para>Regexps can be very complex to read. Luckily most file filtering
    needs are for file extensions. Filters installed with WinMerge show how to
    filter file extensions.</para>

    <sect3>
      <title>Help with regexps</title>

      <para>There are many guides and help sites in Web:</para>

      <variablelist>
        <varlistentry>
          <term>Good site devoted for regexps:</term>

          <listitem>
            <para><ulink
            url="http://www.regular-expressions.info/">http://www.regular-expressions.info/</ulink></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>Good HOWTO document for regexps:</term>

          <listitem>
            <para><ulink
            url="http://www.amk.ca/python/howto/regex/">http://www.amk.ca/python/howto/regex/</ulink></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>Tutorial:</term>

          <listitem>
            <para><ulink
            url="http://www.zvon.org/other/PerlTutorial/Output/index.html">http://www.zvon.org/other/PerlTutorial/Output/index.html</ulink></para>
          </listitem>
        </varlistentry>

        <varlistentry>
          <term>PDF quick reference:</term>

          <listitem>
            <para><ulink
            url="http://gmckinney.info/resources/regex.pdf">http://gmckinney.info/resources/regex.pdf</ulink></para>
          </listitem>
        </varlistentry>
      </variablelist>
    </sect3>
  </sect2>

  <sect2>
    <title>File filters</title>

    <para>A file filter is a set of rules saved to one file. Every file and
    directory is tested against all these rules before comparing. Files and
    directories that match the rules are excluded if it is an inclusive
    filter, or included if it is an exclusive filter.</para>

    <tip>
      <para>Ignored items have "<guilabel>Skipped</guilabel>" status in
      directory compare. User can select them to visible or hidden from
      <guimenu>View</guimenu> menu. Usually its wise to keep skipped items
      hidden.</para>
    </tip>

    <para>WinMerge's filtering system allows only one filter set to be active
    at a time. Active filter set can be selected from Open-dialog or from
    menu: <menuchoice>
        <guimenu>Tools</guimenu>

        <guimenuitem>Filters</guimenuitem>
      </menuchoice>. Also empty filter can be selected when no directories or
    files are ignored.</para>

    <sect3>
      <title>Filter files</title>

      <para>Filter files are normal text files, with an extension of <filename
      class="extension">.flt</filename>. Filter files must be placed in
      either:</para>

      <itemizedlist>
        <listitem>
          <para>"<filename class="directory">Filters</filename>" subdirectory
          in the WinMerge program directory. This is the recommended
          place.</para>
        </listitem>

        <listitem>
          <para>"<filename class="directory">Winmerge/Filters</filename>"
          subdirectory in user profile. Under Windows XP, this might be
          <filename class="directory">C:\Documents And Settings\username\Local
          Settings\Application Data\WinMerge\Filters</filename> or <filename
          class="directory">C:\Documents And Settings\username\Application
          Data\WinMerge\Filters</filename>. This can be used to store personal
          filters for the individual user, or for a user who lacks the ability
          to write to the WinMerge program directory. This also is appropriate
          if backup &amp; restore from an individual profile directory is
          desired.</para>
        </listitem>
      </itemizedlist>

      <para>First part of filter file defines name and basic functionality of
      the filter:</para>

      <para><screen>name: Example filter
def: include</screen>where <constant>def</constant>: is:<itemizedlist>
          <listitem>
            <para><constant>include</constant> - inclusive filter. This filter
            type filters out files and directories that match rules in
            filter.</para>
          </listitem>

          <listitem>
            <para><constant>exclude</constant> - exclusive filter. This filter
            type lets through files and directories that match rules in
            filter.</para>
          </listitem>
        </itemizedlist>When using exclusive filter its worth noting that the
      filter must contain rule to include all wanted subdirectories. Usually
      its wise to use this rule to include all subdirectories:</para>

      <screen>d: \\*$ ## Subdirectories</screen>

      <para>There can be one filter rule in one line. And rule cannot be split
      to several lines. Common format for one filter line is like this:</para>

      <screen>f: \.ext$ ## Match files *.ext</screen>

      <para>or</para>

      <screen>d: \\directory$ ## Match given directory name</screen>

      <para>Rule begins with "<constant>f:</constant>" if it matches for
      filenames and "<constant>d:</constant>" if it matches for directory
      names. Filenames are given to filter as is, there are no special
      characters added. But for directory names there must be
      "<constant>\\</constant>" in begin of directory name. This is done
      clearly to separate directory names and filenames.
      "<constant>##</constant>" is a comment separator, all characters in line
      after that are ignored by WinMerge.</para>

      <para><note>
          <para>File filter rules are case-insensitive. Rule
          <constant>.\bat$</constant> matches to
          <filename>winmerge.bat</filename> and
          <filename>compare.BAT</filename>.</para>
        </note></para>

      <para>So simple filters can be for example:</para>

      <example>
        <title>Simple filefilter rules</title>

        <screen>f: \.cpp$ ## Match *.cpp files
f: \.h$ ## Match *.h files
f: ^My ## Match My*.* files
f: Dlg\. ## Match *Dlg.* files
d: \\test$ ## Match 'test' directories</screen>
      </example>

      <para>Line begin or -end marker (<constant>"^"</constant> or
      <constant>"$"</constant>) is usually required filter to work correctly.
      Dot in filename must be "escaped" with <constant>"\"</constant> so
      <constant>"\."</constant> means dot in filename.</para>

      <note>
        <para>Don't forget "<constant>$</constant>" at end. It marks end of
        directory- or filename and without it rule may not work like expected.
        While "<literal>\.c$</literal>" matches with only filenames having
        extension <filename class="extension">.c</filename>
        "<literal>\.c</literal>" matches all extensions beginning with
        "<literal>c</literal>" (<filename class="extension">.cpp</filename>,
        <filename class="extension">.com</filename>, etc).</para>
      </note>

      <para>Since file filter rules are regular expressions more complex rules
      are also possible. Following few rules show some possibilities for more
      complex rules:</para>

      <example>
        <title>More complex file filter rules</title>

        <screen format="linespecific">f: ^\.#.*$ ## .#filename.version files
f: Dlg\.c(pp)?$ ## *Dlg.c &amp; *Dlg.cpp files
f: ^I.*\.h$ ## I*.h files
f: Srv[1-9]\.def$ ## *Srv1.def - *Srv9.def files
f: ^[h,k,m] ## h*.* &amp; k*.* &amp; m*.* files</screen>
      </example>

      <para>WinMerge ignores most whitespace characters in rules definition
      lines. However comment must always start with one or more whitespace
      character (space or tabulator) and comment-marker
      (<constant>##</constant>). <constant>##</constant> can be used as part
      of rule if there is no whitespace character before it.</para>
    </sect3>
  </sect2>

  <sect2>
    <title>Line filters</title>

    <para>Line filters can be used to ignore single lines from compared files.
    Line filters are handy when user doesn't want to compare comments or
    certain generated code. For example version control system
    (time)stamps.</para>

    <important>
      <para>Line filter rule ignores single line it matches. It is not
      possible to ignore partial lines or several lines with file filter
      rule.</para>
    </important>

    <para>In file compare ignored lines are shown with own colors to
    differentiate them from other differences. User can see these differences
    but cannot select or merge them.</para>

    <para>Line filter rules are regular expressions like file filter rules.
    Since filter matches if any part of line matches it is usually recommended
    to add begin (<constant>"^"</constant>) or end (<constant>"$"</constant>)
    marker to rule. Or both markers if exact line is wanted to
    filtered.</para>

    <tip>
      <para>There are some troubles with "$" and end-of-line. One way to
      work-around these troubles is to use "\W$" when possible.</para>
    </tip>

    <para>Rules can be added and edited in Filters-dialog (Menu: <menuchoice>
        <guimenu>Tools</guimenu>

        <guimenuitem>Filters</guimenuitem>
      </menuchoice>). In editbox, give one rule per line. Compare results are
    not updated automatically after changing line filter rules. User can
    update compare results by selecting <menuchoice>
        <guimenu>Edit</guimenu>

        <guimenuitem>Refresh</guimenuitem>
      </menuchoice> or <keycap>F5</keycap>.</para>

    <para>Maximum length for linefilter (all lines in dialog) is 255
    characters.</para>

    <example>
      <title>Some example line filters</title>

      <screen format="linespecific">^MYTAG$</screen>

      <para>- Filters out lines being exactly
      <constant>"MYTAG"</constant></para>

      <screen format="linespecific">^::</screen>

      <para>- Filters out lines beginning with
      <constant>"::"</constant></para>

      <screen format="linespecific">^/\**.\*/$</screen>

      <para>- Filters out lines beginning with <constant>"/*"</constant> and
      ending with <constant>"*/"</constant></para>

      <screen format="linespecific">^[1-5]00</screen>

      <para>- Filters out lines beginning with numbers 100, 200, 300, 400
      &amp; 500</para>
    </example>

    <example>
      <title>Line filter rule matching CVS "Id:" -lines:</title>

      <para>Id-lines are like this:</para>

      <screen>// $Id: Filters.xml,v 1.14.2.2 2005/10/29 17:21:16 kimmov Exp $</screen>

      <para>And they can be filtered with rule:</para>

      <screen>^// \WId: .*\$</screen>
    </example>

    <example>
      <title>Filter out line number comments in po files:</title>

      <para>po line number comments are like this:</para>

      <screen>#: src/filename.c:766</screen>

      <para>And they can be filtered out with rule:</para>

      <screen>^#</screen>
    </example>
  </sect2>
</sect1>
