mirror of
https://github.com/ToshioCP/Gtk4-tutorial.git
synced 2025-01-27 19:58:29 +01:00
Add turtle_doc.src.md, changed Rakefile.
This commit is contained in:
parent
e85d35543a
commit
ba35c4fc7b
5 changed files with 476 additions and 8 deletions
27
Rakefile
27
Rakefile
|
@ -31,7 +31,7 @@ CLEAN << "Readme.md"
|
|||
task default: :md
|
||||
task all: [:md, :html, :pdf]
|
||||
|
||||
task md: ["Readme.md"]
|
||||
task md: ["Readme.md", "src/turtle/turtle_doc.md"]
|
||||
|
||||
file "Readme.md" => mdfilenames do
|
||||
buf = [ "# Gtk4 Tutorial for beginners\n", "\n" ]
|
||||
|
@ -70,9 +70,13 @@ end
|
|||
end
|
||||
end
|
||||
|
||||
task html: ["html/index.html"]
|
||||
file "src/turtle/turtle_doc.md" => "src/turtle/turtle_doc.src.md" do
|
||||
src2md "src/turtle/turtle_doc.src.md", "src/turtle/turtle_doc.md"
|
||||
end
|
||||
|
||||
file "html/index.html" => htmlfilenames+["html/tfetextview_doc.html"] do
|
||||
task html: ["html/index.html", "html/tfetextview_doc.html", "html/turtle_doc.html"]
|
||||
|
||||
file "html/index.html" => htmlfilenames do
|
||||
buf = [ "# Gtk4 Tutorial for beginners\n", "\n" ]
|
||||
src2md "src/abstract.src.md", "html/abstract.md"
|
||||
File.open("html/abstract.md") do |file|
|
||||
|
@ -101,6 +105,13 @@ file "html/tfetextview_doc.html" => "src/tfetextview/tfetextview_doc.md" do
|
|||
add_head_tail_html "html/tfetextview_doc.html"
|
||||
end
|
||||
|
||||
file "html/turtle_doc.html" => "src/turtle/turtle_doc.src.md" do
|
||||
src2md "src/turtle/turtle_doc.src.md", "html/turtle_doc.md"
|
||||
sh "pandoc -o html/turtle_doc.html html/turtle_doc.md"
|
||||
File.delete "html/turtle_doc.md"
|
||||
add_head_tail_html "html/turtle_doc.html"
|
||||
end
|
||||
|
||||
0.upto(srcfiles.size - 1) do |i|
|
||||
html_md = "html/#{srcfiles[i].to_md}"
|
||||
html_html = "html/#{srcfiles[i].to_html}"
|
||||
|
@ -136,8 +147,8 @@ end
|
|||
|
||||
task latex: ["latex/main.tex"]
|
||||
|
||||
file "latex/main.tex" => ["latex/abstract.tex", "latex/tfetextview_doc.tex"] + texpathnames do
|
||||
gen_main_tex "latex", texfilenames, ["tfetextview_doc.tex"]
|
||||
file "latex/main.tex" => ["latex/abstract.tex", "latex/tfetextview_doc.tex", "latex/turtle_doc.tex"] + texpathnames do
|
||||
gen_main_tex "latex", texfilenames, ["tfetextview_doc.tex", "turtle_doc.tex"]
|
||||
end
|
||||
|
||||
file "latex/abstract.tex" => "src/abstract.src.md" do
|
||||
|
@ -150,6 +161,12 @@ file "latex/tfetextview_doc.tex" => "src/tfetextview/tfetextview_doc.md" do
|
|||
sh "pandoc --listings -o latex/tfetextview_doc.tex src/tfetextview/tfetextview_doc.md"
|
||||
end
|
||||
|
||||
file "latex/turtle_doc.tex" => "src/turtle/turtle_doc.src.md" do
|
||||
src2md "src/turtle/turtle_doc.src.md", "latex/turtle_doc.md"
|
||||
sh "pandoc --listings -o latex/turtle_doc.tex latex/turtle_doc.md"
|
||||
File.delete("latex/turtle_doc.md")
|
||||
end
|
||||
|
||||
0.upto(srcfiles.size - 1) do |i|
|
||||
file "latex/#{srcfiles[i].to_tex}" => (srcfiles[i].c_files << srcfiles[i].path) do
|
||||
src2md srcfiles[i].path, "latex/#{srcfiles[i].to_md}"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Up: [Readme.md](../Readme.md), Prev: [Section 21](sec21.md)
|
||||
Up: [Readme.md](../Readme.md), Prev: [Section 21](sec21.md), Next: [Section 23](sec23.md)
|
||||
|
||||
# Combine GtkDrawingArea and TfeTextView
|
||||
|
||||
|
@ -370,4 +370,4 @@ Probably it is more appropriate.
|
|||
Using textview is unnatural.
|
||||
It is a good practice to make such application by yourself.
|
||||
|
||||
Up: [Readme.md](../Readme.md), Prev: [Section 21](sec21.md)
|
||||
Up: [Readme.md](../Readme.md), Prev: [Section 21](sec21.md), Next: [Section 23](sec23.md)
|
||||
|
|
|
@ -16,7 +16,13 @@ So, readers can skip that part of this sections.
|
|||
|
||||
## How to use turtle
|
||||
|
||||
@@@if gfm
|
||||
The documentation of turtle is [here](turtle/turtle_doc.md).
|
||||
@@@elif html
|
||||
The documentation of turtle is [here](../html/turtle_doc.html).
|
||||
@@@if latex
|
||||
The documentation of turtle is in the appendix.
|
||||
@@@end
|
||||
I'll show you a simple example.
|
||||
|
||||
~~~
|
||||
|
|
|
@ -375,7 +375,7 @@ Comments and spaces:
|
|||
- comment: This is characters between `#` and new line inclusive.
|
||||
- white space:
|
||||
- horizontal tab: tab is recognized as eight spaces.
|
||||
- new line: This is the end of a line and denoted by '\n'.
|
||||
- new line: This is the end of a line and denoted by '\\n'.
|
||||
|
||||
These characters are used to separate tokens explicitly.
|
||||
They doesn't have any syntactic meaning and are ignored by the parser.
|
||||
|
|
445
src/turtle/turtle_doc.src.md
Normal file
445
src/turtle/turtle_doc.src.md
Normal file
|
@ -0,0 +1,445 @@
|
|||
# Turtle's manual
|
||||
|
||||
Turtle is a simple interpreter for turtle graphics.
|
||||
|
||||
## Prerequisite and compiling
|
||||
|
||||
Turtle is written in C language.
|
||||
You need:
|
||||
|
||||
- Linux. Turtle is tested on ubuntu 20.10
|
||||
- gcc, meson and ninja
|
||||
- gtk4
|
||||
|
||||
It is easy to compile the source file of turtle.
|
||||
If you have installed gtk4 with an option `--prefix=$HOME/local`, put the same option to meson so that you can install `turtle` under the directory `$HOME/local/bin`.
|
||||
The instruction is:
|
||||
|
||||
~~~
|
||||
$ meson --prefix=$HOME/local _build
|
||||
$ ninja -C _build
|
||||
$ ninja -C _build install
|
||||
~~~
|
||||
|
||||
Type the following command then turtle shows the following window.
|
||||
|
||||
~~~
|
||||
$ turtle
|
||||
~~~
|
||||
|
||||
![Screenshot just after it's executed](image/turtle1.png){width=8cm height=5.11cm}
|
||||
|
||||
The left half is a text editor and the right half is a surface.
|
||||
Surface is like a canvas to draw shapes.
|
||||
|
||||
Write turtle language in the text editor and click on `run` button, then the program will be executed and it draws shapes on the surface.
|
||||
|
||||
![Tree](image/turtle_tree.png){width=8cm height=5.11cm}
|
||||
|
||||
If you add the following line in `turtle.h`, then codes to inform the status will also be compiled.
|
||||
However, the speed will be quite slow because of the output messages.
|
||||
|
||||
~~~
|
||||
# define debug 1
|
||||
~~~
|
||||
|
||||
## Example
|
||||
|
||||
Imagine a turtle.
|
||||
The turtle has a pen and initially he is at the center of the screen, facing to the north (to the north means up on the screen).
|
||||
You can let the turtle down the pen or up the pen.
|
||||
You can order the turtle to move forward.
|
||||
|
||||
~~~
|
||||
pd
|
||||
fd 100
|
||||
~~~
|
||||
|
||||
- pd: Pen Down. The turtle put the pen down so that the turtle will draw a line if he/she moves.
|
||||
- fd 100: move ForwarD 100. The turtle goes forward 100 pixels.
|
||||
|
||||
If you click on `run` button, then a line segment appears on the screen.
|
||||
One of the endpoints of the line segment is at the center of the surface and the other is at 100 pixels up from the center.
|
||||
The point at the center is the start point of the turtle and the other endpoint is the end point of the movement.
|
||||
|
||||
If the turtle picks the pen up, then no line segment appears.
|
||||
|
||||
~~~
|
||||
pu
|
||||
fd 100
|
||||
~~~
|
||||
|
||||
The command `pu` means "Pen Up".
|
||||
|
||||
The turtle can change the direction.
|
||||
|
||||
~~~
|
||||
pd
|
||||
fd 100
|
||||
tr 90
|
||||
fd 100
|
||||
~~~
|
||||
|
||||
The command `tr` is "Turn Right".
|
||||
The argument is angle with degrees.
|
||||
Therefore, `tr 90` means "Turn right by 90 degrees".
|
||||
If you click on `run`button, then two line segment appears.
|
||||
One is vertical and the other is horizontal.
|
||||
|
||||
![Two line segments on the surface](image/turtle2.png){width=8cm height=5.11cm}
|
||||
|
||||
## Background and foreground color
|
||||
|
||||
Colors are specified by RGB.
|
||||
A vector (r, g, b) denotes RGB color.
|
||||
Each of the elements is a real number between 0 and 1.
|
||||
|
||||
- Red is (1.0, 0.0, 0.0).
|
||||
You can write (1, 0, 0) instead.
|
||||
- Green is (0.0, 1.0, 0.0)
|
||||
- Blue is (0.0, 0.0, 1.0)
|
||||
- Black is (0.0, 0.0, 0.0)
|
||||
- White is (1.0, 1.0, 1.0)
|
||||
|
||||
You can express a variety of colors by changing each element.
|
||||
|
||||
There are two commands to change colors.
|
||||
|
||||
- bc: Background Color. `bc (1,0,0)` changes the background color to red.
|
||||
This command clear the surface and change the background color.
|
||||
So, the shapes on the surface disappears.
|
||||
- fc: Foreground Color. `fc (0,1,0)` changes the foreground color to green.
|
||||
This command changes the pen color.
|
||||
The prior shapes on the surface aren't affected.
|
||||
After this command, the turtle draws lines with the new color.
|
||||
|
||||
![Change the foreground color](image/turtle3.png){width=8cm height=5.11cm}
|
||||
|
||||
## Other simple commands
|
||||
|
||||
- pw: Pen Width. This is the same as pen size or line width.
|
||||
For example, `pw 5` makes lines thick and `pw 1` makes it thin.
|
||||
- rs: ReSet. The turtle moves back to the initial position and direction.
|
||||
In addition, The command initialize the pen, line width (pen size), and foreground color.
|
||||
The pen is down, the line width is 2 and the foreground color is black.
|
||||
|
||||
An order such as `fd 100`, `pd` and so on is a statement.
|
||||
Statements are executed in the order from the top to the end
|
||||
|
||||
## Comment and spaces
|
||||
|
||||
Characters between `#` (hash mark) and `\n` (new line) inclusive are comment.
|
||||
Characters between `#` and `EOF` (end of file) are also comment.
|
||||
Comments are ignored.
|
||||
|
||||
~~~
|
||||
# draw a triangle
|
||||
fd 100 # forward 100 pixels<NEW LINE>
|
||||
tr 120 # turn right by 90 degrees<NEW LINE>
|
||||
fd 100<NEW LINE>
|
||||
tr 120<NEW LINE>
|
||||
fd 100 # Now a triangle appears.<EOF>
|
||||
~~~
|
||||
|
||||
\<NEW LINE\> and \<EOF\> are newline code and end of file respectively.
|
||||
The comments in the line 1, 2, 3 and 6 are correct syntactically.
|
||||
|
||||
Spaces (white space, tab and new line) are ignored.
|
||||
They are used only as delimiters.
|
||||
Tabs are recognized as eight spaces to calculate the column number.
|
||||
|
||||
## Variables and expressions
|
||||
|
||||
Variable begins alphabet followed by alphabet or digit except key words like `fd`, `tr` and so on.
|
||||
`Distance` and `angle5` can be variables, but `1step` isn't a variable because the first character isn't alphabet.
|
||||
Variable names are case sensitive.
|
||||
Variables keep real numbers.
|
||||
Their type is the same as `double` in C language.
|
||||
Integers are casted to real numbers automatically.
|
||||
So 1 and 1.0 are the same value.
|
||||
Numbers begins digits, not signs (`+` or `-`).
|
||||
|
||||
- 100, 20.34 and 0.01 are numbers
|
||||
- +100 isn't a number. It causes syntax error. Use 100 instead.
|
||||
- -100 isn't a number. But turtle recognizes it unary minus and a number 100.
|
||||
So turtle calculate it and the result is -100.
|
||||
- 100 + -20: This is recognized 100 + (- 20).
|
||||
However, using bracket, 100 + (-20), is better for easy reading.
|
||||
|
||||
~~~
|
||||
distance = 100
|
||||
fd distance
|
||||
~~~
|
||||
|
||||
A value 100 is assigned to the variable `distance` in the first line.
|
||||
Assignment is a statement.
|
||||
Most of statements begin with commands like `fd`.
|
||||
Assignment is the only exception.
|
||||
|
||||
This program draws a line segment of 100 pixels long.
|
||||
|
||||
You can use variables in any places in expressions.
|
||||
There are 8 kinds of calculations available.
|
||||
|
||||
- addition: x + y
|
||||
- subtraction: x - y
|
||||
- multiplication: x * y
|
||||
- division: x / y
|
||||
- unary minus: - x
|
||||
- logical equal: x = y. This symbol `=` works as `==` in C language.
|
||||
- greater than: x > y
|
||||
- less than: x < y
|
||||
|
||||
The last three symbols are mainly used in the condition of if statement.
|
||||
|
||||
Variables are registered to a symbol table when it is assigned a value for the first time.
|
||||
Evaluating a variable before the registration isn't allowed and occurs an error.
|
||||
|
||||
## If statement
|
||||
|
||||
Turtle language has very simple if statement.
|
||||
|
||||
~~~
|
||||
if (x > 50) {
|
||||
fd x
|
||||
}
|
||||
~~~
|
||||
|
||||
There is no else part.
|
||||
|
||||
## Procedures
|
||||
|
||||
Procedures are similar to functions in C language.
|
||||
The difference is that procedures don't have return values.
|
||||
|
||||
~~~
|
||||
dp triangle (side) {
|
||||
fd side
|
||||
tr 120
|
||||
fd side
|
||||
tr 120
|
||||
fd side
|
||||
}
|
||||
|
||||
triangle (100)
|
||||
~~~
|
||||
|
||||
`dp` (Define Procedure) is a key word followed by procedure name, parameters, and body.
|
||||
Procedure names start alphabet followed by alphabet or digit.
|
||||
Parameters are a list of variables.
|
||||
For example
|
||||
|
||||
~~~
|
||||
dp abc (a) { ... ... }
|
||||
dp abc (a, b) { ... ... }
|
||||
dp abc (a, b, c) { ... ... }
|
||||
~~~
|
||||
|
||||
Body is a sequence of statements.
|
||||
The statements aren't executed when the procedure is defined.
|
||||
They will be executed when the procedure is called later.
|
||||
|
||||
Procedures are called by the name followed by arguments.
|
||||
|
||||
~~~
|
||||
dp proc (a, b, c) { ... ... }
|
||||
|
||||
proc (100, 0, -20*3)
|
||||
~~~
|
||||
|
||||
The number of parameters and arguments must be the same.
|
||||
Arguments can be any expressions.
|
||||
When you call a procedure, brackets following the procedure name must exist even if the procedure has no argument.
|
||||
|
||||
Procedure names and variable names don't conflict.
|
||||
|
||||
~~~
|
||||
dp a () {fd a}
|
||||
a=100
|
||||
a ()
|
||||
~~~
|
||||
|
||||
This is a correct program.
|
||||
|
||||
- 1: Defines a procedure `a`.
|
||||
A variable `a` is in its body.
|
||||
- 2: Assigns 100 to a variable `a`.
|
||||
- 3: Procedure `a` is called.
|
||||
|
||||
However, using the same name to a procedure and variable makes confusing.
|
||||
You should avoid that.
|
||||
|
||||
## Recursive call
|
||||
|
||||
Procedures can be called recursively.
|
||||
|
||||
~~~
|
||||
dp repeat (n) {
|
||||
n = n - 1
|
||||
if (n < 0) {
|
||||
rt
|
||||
}
|
||||
fd 100
|
||||
tr 90
|
||||
repeat (n)
|
||||
}
|
||||
|
||||
repeat (4)
|
||||
~~~
|
||||
|
||||
Repeat is called in the body of repeat.
|
||||
The call to itself is a recursive call.
|
||||
Parameters are generated each time the procedure is called.
|
||||
So, parameter `n` is 4 at the first call but it is 3 at the second call.
|
||||
Each time the procedure is called, the parameter `n` decreases by one.
|
||||
Finally, it becomes less than zero, then the procedures return.
|
||||
|
||||
The program above draws a square.
|
||||
|
||||
Turtle doesn't have any primary loop statements.
|
||||
It should probably be added to the future version.
|
||||
However, the program above shows that we can program loop with a recursive call.
|
||||
|
||||
## Fractal curves
|
||||
|
||||
Recursive call can be applied to draw fractal curves.
|
||||
Fractal curves appear when a procedure is applied to it repeatedly.
|
||||
The procedure replaces a part of the curve with the contracted curve.
|
||||
|
||||
![Tree](image/turtle_tree.png){width=8cm height=5.11cm}
|
||||
|
||||
This shape is called tree.
|
||||
The basic pattern of this shape is a line segment.
|
||||
It is the first stage.
|
||||
The second stage adds two shorter line segments at the endpoint of the original segment.
|
||||
The new segment has 70 percent length to the original segment and the orientation is +30 or -30 degrees different.
|
||||
The third stage adds two shorter line segments to the second stage line segments.
|
||||
And repeats this several times.
|
||||
|
||||
This repeating is programmed by recursive call.
|
||||
Two more examples are shown here.
|
||||
They are Koch curve and Square Koch curve.
|
||||
|
||||
![Koch curve](image/turtle_koch.png){width=8cm height=5.11cm}
|
||||
|
||||
![Square Koch curve](image/turtle_square_koch.png){width=8cm height=5.11cm}
|
||||
|
||||
## Tokens and punctuations
|
||||
|
||||
The following is the list of tokens.
|
||||
|
||||
Keywords:
|
||||
|
||||
- pu: pen up
|
||||
- pd: pen down
|
||||
- pw: pen width = line width
|
||||
- fd: forward
|
||||
- tr: turn right
|
||||
- bc: background color
|
||||
- fc: foreground color
|
||||
- if: if statement
|
||||
- rt: return
|
||||
- rs: reset
|
||||
- dp: define procedure
|
||||
|
||||
identifiers and numbers:
|
||||
|
||||
- identifier: This is used for the name of variables, parameters and procedures.
|
||||
It is expressed ` [a-zA-Z][a-zA-Z0-9]*` by regular expression.
|
||||
- number: This is expressed `(0|[1-9][0-9]*)(\.[0-9]+)?` by regular expression.
|
||||
It doesn't have `+` or `-` sign because they bring some syntactic confusion.
|
||||
However negative number such as `-10` can be recognized as unary minus and a number.
|
||||
|
||||
Symbols for expression
|
||||
|
||||
- `=`
|
||||
- `>`
|
||||
- `<`
|
||||
- `+`
|
||||
- `-`
|
||||
- `*`
|
||||
- `/`
|
||||
- `(`
|
||||
- `)`
|
||||
|
||||
Delimiters
|
||||
|
||||
- `(`
|
||||
- `)`
|
||||
- `{`
|
||||
- `}`
|
||||
- `,`
|
||||
|
||||
Comments and spaces:
|
||||
|
||||
- comment: This is characters between `#` and new line inclusive.
|
||||
- white space:
|
||||
- horizontal tab: tab is recognized as eight spaces.
|
||||
- new line: This is the end of a line and denoted by '\\n'.
|
||||
|
||||
These characters are used to separate tokens explicitly.
|
||||
They doesn't have any syntactic meaning and are ignored by the parser.
|
||||
|
||||
## Grammar
|
||||
|
||||
~~~
|
||||
program:
|
||||
statement
|
||||
| program statement
|
||||
;
|
||||
|
||||
statement:
|
||||
primary_procedure
|
||||
| procedure_definition
|
||||
;
|
||||
|
||||
primary_procedure:
|
||||
PU
|
||||
| PD
|
||||
| PW expression
|
||||
| FD expression
|
||||
| TR expression
|
||||
| BC '(' expression ',' expression ',' expression ')'
|
||||
| FC '(' expression ',' expression ',' expression ')'
|
||||
| ID '=' expression
|
||||
| IF '(' expression ')' '{' primary_procedure_list '}'
|
||||
| RT
|
||||
| RS
|
||||
| ID '(' ')'
|
||||
| ID '(' argument_list ')'
|
||||
;
|
||||
|
||||
procedure_definition:
|
||||
DP ID '(' ')' '{' primary_procedure_list '}'
|
||||
| DP ID '(' parameter_list ')' '{' primary_procedure_list '}'
|
||||
;
|
||||
|
||||
parameter_list:
|
||||
ID
|
||||
| parameter_list ',' ID
|
||||
;
|
||||
|
||||
argument_list:
|
||||
expression
|
||||
| argument_list ',' expression
|
||||
;
|
||||
|
||||
primary_procedure_list:
|
||||
primary_procedure
|
||||
| primary_procedure_list primary_procedure
|
||||
;
|
||||
|
||||
expression:
|
||||
expression '=' expression
|
||||
| expression '>' expression
|
||||
| expression '<' expression
|
||||
| expression '+' expression
|
||||
| expression '-' expression
|
||||
| expression '*' expression
|
||||
| expression '/' expression
|
||||
| '-' expression %prec UMINUS
|
||||
| '(' expression ')'
|
||||
| ID
|
||||
| NUM
|
||||
;
|
||||
~~~
|
Loading…
Add table
Reference in a new issue