This is an overview of version 2 of AWL (Andrew's Weaving Language) for Luminescence. You can learn more about the ideas behind AWL and how it's used in Luminescence in the general Help File.
The commands are all case insensitive, so you can use any mix of upper and lower case that you like. In the usage summaries, A and B refer to lists of one or more elements, c and d refer to single numbers. If a command is marked with Wraps output it means that the values it produces depend on, and will be strictly within, the current domain. If a command is marked Resizes inputs, it means the shorter list is repeated until it is at least as long as the longer list, then excess elements are removed. If this entry is marked with a solid star, it means that the command resizes the lists in a special way that is described in its notes.
Note for programmers: Following the convention
of weaving drafts,
we use 1-origin indexing into arrays,
not 0 as is more common when programming.
For example, if we have the list 5 6 4
,
then element 1 is 5, elmeent 2 is 6, and element 3 is 4.
There is no element 0.
A binary0
b0
Produce a list of 0's and 1's, usually for the tie-up.
The elements of A tell how many times each digit
should be repated.
The list starts with 0's
(compare to binary1
which starts with 1's).
Entries in A that are less than zero
are considered to be zero.
This command is primarily used to create patterns for the tie-up.
A binary1
b1
Produce a list of 0's and 1's, usually for the tie-up.
The elements of A tell how many times each digit
should be repated.
The list starts with 1's
(compare to binary0
which starts with 0's).
Entries in A that are less than zero
are considered to be zero.
This command is primarily used to create patterns for the tie-up.
A B block
#
Expand list A by repeating each element Ai a total of Bi times. Note that if Bi is 0, then that element of A is not repeated at all. Entries in B that are less than zero are considered to be zero.
A B blockpal
#p
Similar to block
,
but the input list is considered a near-palindrome.
That is, the input list is extended with a reversed
copy of itself, only without the first element.
The appended elements are repeated as many times as the
originals.
The first part is the same as
that produced by block
:
the elements of A were each
repeated by the corresponding number in B.
But then that whole result is reversed
and appended, except for the first element of A.
Note that this result is subtly different than using
block
followed by palindrome
.
A B cipher
Work your way through list A, taking one element at a time. Let's say that this element has a value of a. Replace it with the element at position a in list B. So if a is 1 we use the first element of B, if a is 3 we use the third element of B, and so on. This is like the first "secret code" you came up with your friends in school to pass notes, where (say) A goes to F, B goes to G, C goes to H, and so on.
clear
This erases the entire stack, leaving nothing behind.
A B concat
,
This simply appends list B to the end of list A.
c d domain
The domain is the range of numbers that are used by the commands that produce ascending or descending lists of numbers, typically joining two given numbers at the ends. A special type of such list is a run, which starts at some value and either ascends, wrapping around the top of the domain, to a value one less than the start, or descends, wrapping around the bottom of the domain, to a value one greater than the start.
For example,ramp
produces a new
list by counting upwards from one number to another.
When any of the counting programs produce a number
that goes outside of the domain,
that number "wraps around" to the other end.
The command summary lets you which commands do this
with a solid dot after Wraps output: in their summary.
The domain starts with a minimum value of 1
and a maximum of 8.
So if you ask ramp
to count
upwards from 5 to 3, it would produce the numbers
6, 7, 8, and then 9.
But 9 is outside the domain [1,8],
so it wraps around to 1.
The counting continues from there,
so the whole list (including the 5
at the start and the 3 at the end) would be
5 6 7 8 9 1 2 3
.
The same thing happens when you're counting
down: if a value goes below the minimum,
it wraps around to the maximum.
Again, using the default values of 1 and 8,
if you counted down from 2 to 6 you'd get
the list 2 1 8 7 6
.
Each AWL input box always starts with the domain set to [1,8]. If you change it, that change stays in effect for the rest of that expression. Changing the domain is useful when you want to make little patterns (say using only the values from 2 to 5) within a larger pattern that uses a larger domain.
The domain
command enforces
the domain minimum to be at least 1,
and the maximum value will always be
at least 1 more than the minimum.
A B down
>
This produces the list A followed by the list B, but in between there's a sequence of numbers that count down from the last element of A to the first element of B.
A B c downrun
>r
Like down
,
but after counting down to the start of B
it inserts c complete downward runs through
the domain.
The following example assumes the default domain of [0,7].
A B downup
>u
Create an alternating series of up and down runs.
Start with the first element of A,
then count down to the first element of B
(wrapping around the domain as necessary).
Now count back up to the second element of A,
then back down to the second element of B,
and so on.
Normally downup
will resize the inputs
to have the same length,
but an exception to that rule is if A is 1
element longer than B.
That allows you to make up/down patterns that repeat
nicely.
The following example assumes the default domain of [0,7].
A B c downuprun
>ur
This is just like downup
,
but after each generated run it inserts
c full runs through the domain
in the same direction.
Like downup
,
the two lists will be resized unless
A is exactly 1 element longer than B.
dup
Whatever is on top of the stack gets duplicated and pushed back on top, resulting in two identical copies on top of the stack.
A c extend
+
We force list A to have exacty c elements. If it's too short, we append copies of A to itself over and over until it has a length of c or more. If the original list, or the result of repeating it, is too long, we throw away the extra elements at the end.
A B growblock
=
This is somewhat of a specialty command, inspired by a monograph by Ralph Griswold. It makes really nice up and down triangle waves of changing size. The idea is that we build a new list with ramps from elements of A to ever-growing palindromes of the first few elements of B.
To describe just what's going on would take a lot of words and would be hard to understand. It's much easier for both you and me to instead just consider a picture ofgrowblock
in action.
Here's an example where both lists have 4 elements. Each little group of dots indicates a run between the elements on either side; the run goes either up or down to keep it within the domain.
A0 B0 A1 B0 B1 B0 A2 B0 B1 B2 B1 B0 A3 B0 B1 B2 B3 B2 B1 B0
A iblock
i#
This does the same job as block
,
but the values are interleaved in one just one list.
The first element of A,
A0,
is repeated
A1 times,
then the next element
A2
is repeated
A3 times,
and so on.
A iblockpal
i#p
Works like blockpal
,
only the entries are interleaved like iblock
.
A B interleave
%
The two input lists are turned into one by taking
elements from each in turn.
The new list is the first element of A,
the first element of B,
the second element of A,
the second element of B,
and so on.
Thiis is useful for producing lists that can
be used with commands like iblock
or tartan
.
A B c d interleaveSteps
%s
The two input lists are turned into one by taking the first c elements from A, followed by the first d elements from B, then the next c elements from A, followed by the next d elements from B, and so on. If one list runs out before the other, the remaining elements from the longer list are placed at the end of the result.
A palindrome
|
(vertical bar)The list A is followed by the reverse of A, except that the first and last elements of A aren't included in the reversed version. This makes repeated palindromes line up nicely without duplicated values.
A B pbox
This is a shortcut for
A B A vlen extend permute
In words,
call permute
using
A,
and a version of B that is either trimmed
or repeated so that it's the same length as A.
A B permute
&
This operation gives us a way of building a new list by picking out elements of list A using a version of list B. The mechanics are a little busy, but the results are patterns that are very nice for weaving.
The first step is to resize both A and B, but we don't use the usual rule of just repeating the shorter one and then cutting it off. Instead, we first make a new version of A, and then a new version of B, using different rules.
To make the new A, which I'll call A', we repeat A over and over until its length is an integer multiple of the length of B. For example, if A has length 4, and B has length 6, then we'll repeat A a total of 3 times. That gives us a length of 12, which is the length of B times 2.
To find the length of B we just repeat it until it has the same length as A, but with a twist. Each time we repeat B, we'll add to its values a number equal to the number of repeats we've added so far. For example, suppose B has the value 2 0 1, and we need to repeat it 4 times. When we start building our new version of B, which I'll call B', we've done no repeating yet, so we add 0 to each value of B. At this point, B' is just 2 0 1. Now we append B onto B' again, but since we've already repeated once, we add 1 to each value, giving us 3 1 2. So now B' is 2 0 1 3 1 2. The next time we add 2, giving us a B' of 2 0 1 3 1 2 4 2 3, and finally we repeat once more but add 3 to each element of B, giving us the final version of B', with the list 2 0 1 3 1 2 4 2 3 5 3 4.
Now comes the last step, using list B' to pick out elements from A' to build up a new list. To do this, we take the first element of B', and treat that as an index into A', wrapping it around the length of A' if necessary. So if the first element of B' is, say, 3, then we take the third element from list A', and that becomes the first element in our new list. We repeat this for every element in B'.
For example, suppose A is 3 4 5, and B is 1 2. We'll make A' by repeating A twice, giving it a length of 6, which is 3 times the length of B. So A' is 3 4 5 3 4 5. Now we make B' by repeating it 3 times, to give it a length of 6, adding 0 to the first repeat, 1 to the next, and 2 to the third, so B' is then 1 2 2 3 3 4. Now we use the elements of B' to pull out elements of A'. The first element of B' is 1, so we take first element from A', which is 3. The next element of B' is 2, so we take the second element from A', giving us 4. We continue this process to get the final result 3 4 4 5 5 4.
pop
The top list on the stack is popped off and thrown away. Do not call this on an empty stack.
A push
/
The list that is currently being built on top of the
stack is considered to be done.
Any elements entered immediately after push
are considered the start of a new list.
If there is no growing list on top of the stack
(that is, the most recent element pushed wasn't a
number of a color), then push
has no effect.
A B ramp
-
(minus sign)The result is list A, followed by a run from the last element of A to the first element of B, followed by list B. The direction of the ramp is chosen to prevent the need to wrap around (that is, if the first element of B is greater than the last element of A, the run goes up, otherwise it goes down).
A B c ramprun
-r
(minus sign followed by lower-case L)
Like ramp
,
but after the run has been built it inserts
c complete more runs through the domain,
in the same direction as the original run.
A c repeat
*
List A is repeated a total of c times.
A reverse
@
List A is reversed.
A c rotatel
<<
Rotate the elements of A left by c steps. That is, element c+1 now becomes the start of A, and everything before it now comes at the end of the list.
A c rotater
>>
Rotate the elements of A right by c steps. That is, the element c entries before the end now becomes the start of the list, with everything before it now at the end.
showStack
The complete stack is displayed in a popup window. This is very useful for debugging AWL expressions, since you can put it anywhere in an expression. The pop-up will display the stack at the moment the command is encountered, and then the system will continue processing the expression as usual. Each element on the stack is numbered, with 0 on the bottom of the stack. The type of each element is also displayed; this is typically either clist or olist. You can ignore this information, but it's useful to me in debugging if there's a crash.
A c d skipkeep
][
Skip the first c entries of A,
then keep the next d entries.
Repeat until the end of A.
Note that if you want to start skipping somewhere
other than the start of the list,
you can use rotater
or rotatel
first, to get it into position.
A c split
The first c elements of A are pushed onto the stack as a list, the the remaining elements of A are pushed on top of that as a second list. Thus after A is popped from the stack, two new lists are pushed back on.
If the split point is before the beginning of
the list (that is, c is less than 1),
or if the split point is past the end of the list,
then no splitting occurs and your original list
is pushed back onto the stack.
Note that in this case,
split
pushes only one new list
onto the stack, not two.
A swap
Starting with B on top of the stack and A beneath it, push B back on followed by A, thereby reversing their order on the stack.
A tartan
Identical to iblock
,
except that the counts are halved before use
(this is a convenience for
entering the warp and weft colors for
some published tartan drafts
which use doubled thread counts).
A tartanpal
Just like tartan
,
but concludes with a near-palindrome
(that is, the first pair in the list
of value-repeat pairs is not duplicated
again at the end).
A B template
:
Each element of A is replaced with the list B, except the value of that element of A is added to each value of B. For example, if A is 2 3 and B is 3 1 2, then the new list would be 2+(3 1 2) 3+(3 1 2), or 5 3 4 6 4 5. If your values go outside of the domain, they will be wrapped around the ends as usual.
Note that some weavers don't use list B as given, but subtract the first element of B from every element in the list. Thus if B was given as 3 4 1 5 it would be replaced with 0 1 -2 2 when used in the command. AWL does not adopt this convention. If you want your template to start with 0, simply start it with 0!
Weavers also call this process subarticulation.
A c d twilll
t<<
Make d copies of A,
each time rotating it to the left by c steps.
This command gets its name because it's very useful for
making tie-up patterns that are characteristic of
twill weaves.
To make a twill tie-up,
create a pattern that is as wide as one row
of the tie-up, then use twilll
to rotate it
successively rotate it 1 step for each row of the tie-up,
working up from the bottom.
A c d twillr
t>>
Make d copies of A,
each time rotating it to the left by c steps.
This is the counterpart of
twilll
, but rotates right instead of left.
As discussed in twilll
,
this command makes it easy to create tie-ups
that are like those used in twills.
A B up
<
This produces the list A followed by the list B, but in between there's a sequence of numbers that count up from the last element of A to the first element of B.
A B c uprun
<r
Like up
,
but after counting up to the start of B
it inserts c complete upward runs through
the domain.
The following example assumes the default domain of [1,8].
A B updown
<d
Create an alternating series of up and down runs.
Start with the first element of A,
then count up to the first element of B
(wrapping around the domain as necessary).
Now count back down to the second element of A,
then back up to the second element of B,
and so on.
Normally downup
will resize the inputs
to have the same length,
but an exception to that rule is if A is 1
element longer than B.
That allows you to make up/down patterns that repeat
nicely.
The following example assumes the default domain of [0,7].
A B c updownrun
<dr
This is just like updown
,
but after each generated ascending or
descending section it inserts
c full runs through the domain
in the same direction.
Like updown
,
the two lists will be resized unless
A is exactly 1 element longer than B.
A vlen
Finds the length of list A (that is, the number of elements in the list).
A vmax
Finds the largest value in list A.
A vmin
Finds the smallest value in list A.