## Using the !RANGE special directive

In circumstances where one wishes to allow clients to view selected portions of a long document, one can always have multiple versions available. For example, you could have a set of small files, each containing a chapter, as well as a larger file containing the entire document.

This can be somewhat inconvenient, especially if one has dynamic documents that change frequently -- since one would have to change both the "chapters" and the "entire document". To alleviate this necessity, SRE-http can be instructed to extract, and send to the client, selected portions of a larger document. This can be done using the `!RANGE` special directive.

### Syntax of the !RANGE special directive

The syntax of a `!RANGE` special directive is:
- `!range:range_info/selector`

- where:
  - `!range` is placed at the beginning of the "selector" portion of a URL.
  - `range_info` contains instructions on what bytes, lines, or sections to extract.
  - `/selector` is the selector from which to extract the specified bytes, etc.
- Examples:
  - `<a href="foo.bar.com/!range:lines=0-100,1000-2000/docs/intro.txt" > Get the intro and 2nd chapter? </a>`

    When the client selects the above, SRE-http will return lines 0-100 and lines 1000-2000 of the /docs/intro.txt file.

  - `<a href="moo.car.com/!range:bytes=90000-/price.lst"` > Get the latest entries in the price list? </a>

    SRE-http will return all bytes after the 90,000.

#### The range_info

The `range_info` has the following basic syntax:

`type=range1-range2,range3-range4,...;type=....;`

Note that for each type you can specify several ranges (seperated by commas); and you can specify several types (seperated by semi-colons).

- `type` can be:
  - `BYTES`: a range of bytes
  - `LINES`: a range of lines (where a line ends in a carriage return/line feed)
  - `LINENUMBERS`: Same as lines, but the line number (of each line) is added to the output (at the beginning of the line).
  - `SEARCH:` strings to search for, with bytes between a "beginning" and "ending" string returned.
  - `SECTIONS:` sections to return, where sections are defined in special section files that you create.
- The ranges depend on the type:
  - BYTES: range1 and range2 are numeric offsets. Thus, to obtain bytes 100 to 200, specify `99-199`.
  - LINES and LINENUMBERS: range1 and range2 are numeric offsets. Thus, to obtain lines 1 to 55, and lines 1201 to the end, specify `0-54,1200-`.

    Note for BYTES, LINES, and LINENUMBERS: a range of -nnn means get the first nnn-1 bytes (or lines). Similarly, mmm- means get all bytes (or lines) from the (mmm+1)th to the end. /

  - SEARCH: range1 and range2 are quoted strings, possibly preceded by a match count. The syntax is:
    `SEARCH:m"string1"-n"string2"`
    where SRE-http will search for the (case insensitive) byte containing the `m'th` occurrence of `string1`, and the byte containing the `n'th` occurrence of `string2`. In particular, all bytes from string1 (including string1) to just before string2 will be extracted. Note that `m` and `n` are optional -- if not specified, the first occurrence (of string1 or string2, respectively) is used.
  - SECTION: sections are specially defined bytes, lines, and search ranges. These are defined in special section files . The syntax is: `SECTION:secfile:sectionA,sectionB,secfile2:sectionD-sectionE`
    where `secfile` is the name of a section file, and sectionX refers to one of the sections defined in this file. The first section must be preceded by a secfile:; subsequent sections will use this secfile by default (or until anothe secfile is specified).

  #### An alternate syntax

  Instead of using a `!RANGE:type=range1-range,.../selector` syntax, you can use:
  `selector;type=range1-range2,..;...`

  > Caution: Although this may be a somewhat more natural means of specifying a range, on occasion it may cause problems (such as when a semi-colon is a legitimate argument to an aliased SRE-http addon; for example, the BBS addon). Furthermore, SEARCH ranges must not contain semi-colons, question marks, or / characters (you can use URL encoding if need be).

  #### Section Files

  Section files are used to define `SECTIONS`. Typically, one would define sections to correspond to particular lines (or bytes) of a file. If these lines (or bytes) change from time to time, it can be tedious to change the URLS in the possibly numerous HTML documents that refer to these sections. By defining these "sections" in one file, this can be avoided -- you just change the definition in the section file.

  Section files are simple text files that you create with your favorite text editor. They should be located relative to the SRE-http "data" directory (say; \GOSERVE\DATA). They should (but need not) have a `.SEC` extension.

  For example, assuming that your SRE-http data directory is D:\GOSERVE\DATA:

- `!RANGE:section=dogs:chap1,chap2,chap10-chap15`
  refers to D:\GOSERVE\DATA\DOGS.SEC.
  Note that the `chap10-chap15` means all sections between the chap10 and chap15 section definitions (inclusively) in D:\GOSERVE\DATA\DOGS.SEC. .
- `!RANGE:section=critters/tigers.x:care,feeding`
  refers to D:\GOSERVE\DATA\CRITTERS\TIGERS.X. The structure of a section file is:

      ; lines beginning with semi-colons are quotes

      SECTION_LABEL:  type=range1-range2, range3-range4 ;
                      type=range1-range ;

      SECTION2_label: ....

  Note that
  - Sections are defined by the `type=range1-range2` syntax described above.
  - Section definitions start with a label ending with a colon.
  - Section definitions end with a blank line
  - For improved readability, you can embed spaces and line feeds anywhere. Since these spaces and lines will be removed....
  - ... when specifying SEARCH strings, you must use + to signify a space, and URL encoding for &, " and other such charactes.

  #### Example of a section file

  The following is an example of a section file.

      ; this is a sample "SECTION" file t

      chap1: linenumbers=0-20,
                40-80

      section1: search="2a"-"2b"

      section2: search="2d"-"2e","2g"-"2h"

      chap2: lines=100-140, 160-180

      chap3: linenumbers= 200-250

      chap4: lines=300-350

      chap5: linenumbers=450-500

      ;all done