aboutsummaryrefslogtreecommitdiff
path: root/man/man1/rndl.1df
blob: ec44564a60f458e24b9e029571f3780a85dc697b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH RNDL 1df "August 2016" "Manual page for rndl"
.SH NAME
.B rndl
\- return a low-quality random choice of a random line from files
.SH SYNOPSIS
.B rndl
file
.br
.B rndl
file1 file2 file3
.br
command |
.B rndl
.SH DESCRIPTION
.B rndl
prints a random line from its input, using rndi(1df) to choose it. This is
probably not a high-quality source, but should differ within seconds and
between runs on most systems.
.SH SEE ALSO
rndi(1df), rnda(1df), rndf(1df), rnds(1df), rndn(6df)
.SH AUTHOR
Tom Ryder <tom@sanctum.geek.nz>
0DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# Crude m4 preprocessor
BEGIN {
    self = "mi5"

    # You can change any of these, but while changing these is still relatively
    # sane...
    open = "<%"
    shut = "%>"

    # ... changing these probably isn't, and should compel you to rethink your
    # code, or quite possibly your entire life thus far.
    quote = "`"
    unquote = "'"
    dnl = "dnl"

    # We do not start in a block
    bmac = 0
}

# Fatal error function
function fatal(str) {
    stderr = "cat >&2"
    printf "%s: %s\n", self, str | stderr
    close(stderr)
    exit(1)
}

# Print an m4 opener as the first byte
NR == 1 { printf "%s", quote }

# Blocks
NF == 1 && $1 == open && !bmac++ {
    printf "%s", unquote
    next
}
NF == 1 && $1 == shut && bmac-- {
    printf "%s", quote
    next
}

# If in a block, print each line with any content on it after stripping leading
# and trailing whitespace
bmac && NF {
    gsub(/(^ +| +$)/, "")
    print $0 dnl
}

# If not in a block, look for inlines to process
!bmac {

    # We'll parse one variable into another.
    src = $0
    dst = ""

    # Start off neither quoting nor macroing.
    iquo = imac = 0

    # Crude and slow, clansman.  Your parser was no better than that of a
    # clumsy child.
    for (i = 1; i <= length(src); ) {

        # Inline macro expansion: commented
        # Look for end of comment and tip flag accordingly
        if (iquo)
            iquo = (substr(src, i, length(unquote)) != unquote)

        # Inline macro expansion
        else if (imac) {

            # Close the current inline macro expansion if a close tag is found
            # (in m4 terms: open a new quote), looking ahead past any spaces
            # from this point first
            for (j = i; substr(src, j, 1) ~ /[ \t]/; j++)
                continue
            if (substr(src, j, length(shut)) == shut) {
                dst = dst quote
                i = j + length(shut)
                imac = 0
                continue
            }

            # Look for start of comment and tip flag accordingly
            iquo = (substr(src, i, length(quote)) == quote)
        }

        # Plain text mode
        else {

            # Open a new inline macro expansion if an open tag is found (in m4
            # terms: close the quote), and then look ahead past any spaces from
            # that point afterward
            if (substr(src, i, length(open)) == open) {
                dst = dst unquote
                imac = 1
                for (i += length(open); substr(src, i, 1) ~ /[ \t]/; i++)
                    continue
                continue
            }

            # Escape quote terminators
            if (substr(src, i, length(unquote)) == unquote) {

                # Dear Mr. President.  There are too many variables nowadays.
                # Please eliminate three.  I am NOT a crackpot.
                dst = dst unquote unquote quote

                i += length(unquote)
                continue
            }
        }

        # If we got down here, we can just add the next character and move on
        dst = dst substr(src, i++, 1)
    }

    # If we're still in a macro expansion or quote by this point, something's
    # wrong; say so and stop, rather than print anything silly.
    if (iquo)
        fatal("Unterminated inline quote")
    else if (imac)
        fatal("Unterminated inline macro")
    else
        print dst
}

# Print an m4 closer and newline deleter as the last bytes if we've correctly
# stopped all our blocks
END {
    if (bmac)
        fatal("Unterminated block macro")
    else
        print unquote dnl
}