Bug fixed. Copy image files into docs/image.

This commit is contained in:
Toshio Sekiya 2022-04-22 12:04:27 +09:00
parent d1755d2005
commit f73a287be8
85 changed files with 134 additions and 112 deletions

View file

@ -4,6 +4,7 @@ require_relative 'lib/lib_src_file.rb'
require_relative 'lib/lib_src2md.rb'
require_relative 'lib/lib_gen_main_tex.rb'
require_relative 'lib/lib_mk_html_template.rb'
require_relative 'lib/lib_cp_images.rb'
secfiles = Sec_files.new(FileList['src/sec*.src.md'].to_a.map{|file| Sec_file.new(file)})
secfiles.renum!
@ -27,6 +28,7 @@ abstract_tex = "latex/"+abstract.to_tex
CLEAN.append(FileList["latex/*.tex", "latex/*.aux", "latex/*.log", "latex/*.toc"])
CLOBBER.append("Readme.md").append(*mdfiles)
CLOBBER.append(FileList["docs/*.html"])
CLOBBER.append(FileList["docs/image/*"])
CLOBBER.append(FileList["latex/*.pdf"])
def pair array1, array2
@ -73,7 +75,9 @@ pair(srcfiles, mdfiles).each do |src, dst, i|
end
end
task html: %W[#{html_dir}/index.html] + htmlfiles
task html: %W[#{html_dir}/index.html] + htmlfiles do
cp_images srcfiles, "docs/image"
end
file "#{html_dir}/index.html" => [abstract] + secfiles do
abstract_md = "#{html_dir}/#{abstract.to_md}"

View file

@ -272,7 +272,7 @@ Refer to tfetextview API reference in appendix.
<p>Other type of conditions may be available in the future version.</p>
<p>The code analyzing @@<span class="citation" data-cites="if">@if</span> series command is rather complicated. It is based on the state diagram below.</p>
<figure>
<img src="../image/state_diagram.png" alt="" /><figcaption>state diagram</figcaption>
<img src="image/state_diagram.png" alt="" /><figcaption>state diagram</figcaption>
</figure>
<h3 id="table">@@<span class="citation" data-cites="table">@table</span></h3>
<p>This type of @@@ command starts with a line begins with “@@<span class="citation" data-cites="table">@table</span>”. The contents of this command is a table of GFM or pandocs markdown. The command makes a table easy to read. For example, a text file <code>sample.md</code> has a table like this:</p>

BIN
docs/image/TfeTextView.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
docs/image/box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
docs/image/cairo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/image/child.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/image/color.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/image/column.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
docs/image/column_view.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
docs/image/da1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/image/expression.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/image/list.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/image/list3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/image/list4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
docs/image/menu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/image/menu1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
docs/image/menu2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
docs/image/menu3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
docs/image/open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
docs/image/proc_call.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/image/rectangle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
docs/image/refcount.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
docs/image/saveas.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/image/stack.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
docs/image/table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
docs/image/tfe6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
docs/image/tree2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
docs/image/turtle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/image/turtle1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/image/turtle2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
docs/image/turtle3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
docs/image/turtle_koch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
docs/image/turtle_tree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -113,7 +113,7 @@
</div>
</nav>
<h1 id="initialization-and-destruction-of-instances">Initialization and destruction of instances</h1>
<p>A new version of the text file editor (<code>tfe</code>) will be made in this section and the following four sections. It is <code>tfe5</code>. There are many changes from the prior version. All the sources are listed in <a href="sec16.html">Section 16</a>. They are located in two directories, <a href="../src/tfe5">src/tfe5</a> and <a href="../src/tfetextview">src/tfetextview</a>.</p>
<p>A new version of the text file editor (<code>tfe</code>) will be made in this section and the following four sections. It is <code>tfe5</code>. There are many changes from the prior version. All the sources are listed in <a href="sec16.html">Section 16</a>. They are located in two directories, src/tfe5 and src/tfetextview.</p>
<h2 id="encapsulation">Encapsulation</h2>
<p>Weve divided C source file into two parts. But it is not enough in terms of encapsulation.</p>
<ul>
@ -172,7 +172,7 @@
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true"></a>};</span></code></pre></div>
<p>In each structure, its parent is declared at the top of the members. So, every ancestors is included in the child instance. This is very important. It guarantees a child widget to inherit all the features from ancestors. The structure of <code>TfeTextView</code> is like the following diagram.</p>
<figure>
<img src="../image/TfeTextView.png" alt="" /><figcaption>The structure of the instance TfeTextView</figcaption>
<img src="image/TfeTextView.png" alt="" /><figcaption>The structure of the instance TfeTextView</figcaption>
</figure>
<h2 id="initialization-of-a-tfetextview-instance">Initialization of a TfeTextView instance</h2>
<p>The function <code>tfe_text_view_new</code> creates a new TfeTextView instance.</p>
@ -387,13 +387,13 @@
</ul>
<p>TfeTextViewClass includes its ancestors class in it. It is illustrated in the following diagram.</p>
<figure>
<img src="../image/TfeTextViewClass.png" alt="" /><figcaption>The structure of TfeTextView Class</figcaption>
<img src="image/TfeTextViewClass.png" alt="" /><figcaption>The structure of TfeTextView Class</figcaption>
</figure>
<h2 id="destruction-of-tfetextview">Destruction of TfeTextView</h2>
<p>Every Object derived from GObject has a reference count. If an object A refers to an object B, then A keeps a pointer to B in A and at the same time increases the reference count of B by one with the function <code>g_object_ref (B)</code>. If A doesnt need B any longer, then A discards the pointer to B (usually it is done by assigning NULL to the pointer) and decreases the reference count of B by one with the function <code>g_object_unref (B)</code>.</p>
<p>If two objects A and B refer to C, then the reference count of C is two. If A no longer needs C, A discards the pointer to C and decreases the reference count in C by one. Now the reference count of C is one. In the same way, if B no longer needs C, B discards the pointer to C and decreases the reference count in C by one. At this moment, no object refers to C and the reference count of C is zero. This means C is no longer useful. Then C destructs itself and finally the memories allocated to C is freed.</p>
<figure>
<img src="../image/refcount.png" alt="" /><figcaption>Reference count of B</figcaption>
<img src="image/refcount.png" alt="" /><figcaption>Reference count of B</figcaption>
</figure>
<p>The idea above is based on an assumption that an object referred by nothing has reference count of zero. When the reference count drops to zero, the object starts its destruction process. The destruction process is split into two phases: disposing and finalizing. In the disposing process, the object invokes the function pointed by <code>dispose</code> in its class to release all references to other objects. In the finalizing process, it invokes the function pointed by <code>finalize</code> in its class to complete the destruction process. These functions are also called handlers or methods. For example, dispose handler or dispose method.</p>
<p>In the destruction process of TfeTextView, the reference count of widgets related to TfeTextView is automatically decreased. But GFile pointed by <code>tv-&gt;file</code> needs to decrease its reference count by one. You must write the code in the dispose handler <code>tfe_text_view_dispose</code>.</p>
@ -420,7 +420,7 @@
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true"></a>}</span></code></pre></div>
<p>Each ancestors class has been created before TfeTextViewClass is created. Therefore, there are four classes and each class has a pointer to each dispose handler. Look at the following diagram. There are four classes GObjectClass (GInitiallyUnownedClass), GtkWidgetClass, GtkTextViewClass and TfeTextViewClass. Each class has its own dispose handler <code>dh1</code>, <code>dh2</code>, <code>dh3</code> and <code>tfe_text_view_dispose</code>.</p>
<figure>
<img src="../image/dispose_handler.png" alt="" /><figcaption>dispose handlers</figcaption>
<img src="image/dispose_handler.png" alt="" /><figcaption>dispose handlers</figcaption>
</figure>
<p>Now, look at the <code>tfe_text_view_dispose</code> program above. It first releases the reference to GFile object pointed by <code>tv-&gt;file</code>. Then it invokes its parents dispose handler in line 8.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true"></a>G_OBJECT_CLASS (tfe_text_view_parent_class)-&gt;dispose (gobject);</span></code></pre></div>

View file

@ -325,7 +325,7 @@
<li>78: Shows the dialog.</li>
</ul>
<figure>
<img src="../image/saveas.png" alt="" /><figcaption>Saveas process</figcaption>
<img src="image/saveas.png" alt="" /><figcaption>Saveas process</figcaption>
</figure>
<p>When you use GtkFileChooserDialog, you need to divide the program into two parts. One is a function which creates GtkFileChooserDialog and the other is a signal handler. The function just creates and shows GtkFileChooserDialog. The rest is done by the handler. It gets Gfile from GtkFileChooserDialog and saves the buffer to the file by calling <code>save_file</code>.</p>
<h2 id="open-function">Open function</h2>
@ -397,7 +397,7 @@
</ul>
<p>Now lets think about the whole process between the caller and TfeTextView. It is shown in the following diagram and you would think that it is really complicated. Because signal is the only way for GtkFileChooserDialog to communicate with others. In Gtk3, <code>gtk_dialog_run</code> function is available. It simplifies the process. However, in Gtk4, <code>gtk_dialog_run</code> is unavailable any more.</p>
<figure>
<img src="../image/open.png" alt="" /><figcaption>Caller and TfeTextView</figcaption>
<img src="image/open.png" alt="" /><figcaption>Caller and TfeTextView</figcaption>
</figure>
<ol type="1">
<li>A caller gets a pointer <code>tv</code> to a TfeTextView instance by calling <code>tfe_text_view_new</code>.</li>
@ -420,8 +420,8 @@
<span id="cb11-9"><a href="#cb11-9"></a>}</span></code></pre></div>
<p>The important thing is to duplicate <code>tv-&gt;file</code>. Otherwise, if the caller frees the GFile object, <code>tv-&gt;file</code> is no more guaranteed to point the GFile. Another reason to use <code>g_file_dup</code> is that GFile isnt thread-safe. If you use GFile in the different thread, the duplication is necessary. See <a href="https://docs.gtk.org/gio/method.File.dup.html">Gio API Reference, g_file_dup</a>.</p>
<h2 id="the-api-document-and-source-file-of-tfetextview.c">The API document and source file of tfetextview.c</h2>
<p>Refer <a href="../html/tfetextview_doc.html">API document of TfeTextView</a>. Its original markdown file is under the directory <code>src/tfetextview</code>.</p>
<p>All the source files are listed in <a href="sec16.html">Section 16</a>. You can find them under <a href="../src/tfe5">src/tfe5</a> and <a href="../src/tfetextview">src/tfetextview</a> directories.</p>
<p>Refer API document of TfeTextView. Its original markdown file is under the directory <code>src/tfetextview</code>.</p>
<p>All the source files are listed in <a href="sec16.html">Section 16</a>. You can find them under src/tfe5 and src/tfetextview directories.</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>

View file

@ -317,7 +317,7 @@ $</code></pre>
<span id="cb10-10"><a href="#cb10-10"></a>executable(&#39;tfe&#39;, sourcefiles, resources, dependencies: gtkdep)</span></code></pre></div>
<p>In this file, just the source file names are modified from the prior version.</p>
<h2 id="source-files">source files</h2>
<p>The <a href="../src/tfe5">source files</a> of the text editor <code>tfe</code> will be shown in the next section.</p>
<p>The source files of the text editor <code>tfe</code> will be shown in the next section.</p>
<p>You can also download the files from the <a href="https://github.com/ToshioCP/Gtk4-tutorial">repository</a>. There are two options.</p>
<ul>
<li>Use git and clone.</li>
@ -325,7 +325,7 @@ $</code></pre>
</ul>
<p>If you use git, run the terminal and type the following.</p>
<pre><code>$ git clone https://github.com/ToshioCP/Gtk4-tutorial.git</code></pre>
<p>The source files are under <a href="tfe5"><code>/src/tfe5</code></a> directory.</p>
<p>The source files are under /src/tfe5 directory.</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>

View file

@ -116,7 +116,7 @@
<h2 id="menu">Menu</h2>
<p>Users often use menus to tell a command to the computer. It is like this:</p>
<figure>
<img src="../image/menu.png" alt="" /><figcaption>Menu</figcaption>
<img src="image/menu.png" alt="" /><figcaption>Menu</figcaption>
</figure>
<p>Now lets analyze the menu above. There are two types of object.</p>
<ul>
@ -124,7 +124,7 @@
<li>Menubar, submenu referenced by “Edit” item and two sections. They are called “menu”. Menu is an ordered list of items. They are similar to arrays.</li>
</ul>
<figure>
<img src="../image/menu_structure.png" alt="" /><figcaption>Menu structure</figcaption>
<img src="image/menu_structure.png" alt="" /><figcaption>Menu structure</figcaption>
</figure>
<ul>
<li>Menubar is a menu which has three items, which are “File”, “Edit” and “View”.</li>
@ -245,10 +245,10 @@ g_object_unref (menu_item_quit);</code></pre>
<li>32: Shows the window.</li>
</ul>
<figure>
<img src="../image/menu1.png" alt="" /><figcaption>menu and action</figcaption>
<img src="image/menu1.png" alt="" /><figcaption>menu and action</figcaption>
</figure>
<figure>
<img src="../image/menu1_screenshot.png" alt="" /><figcaption>Screenshot of menu1</figcaption>
<img src="image/menu1_screenshot.png" alt="" /><figcaption>Screenshot of menu1</figcaption>
</figure>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

View file

@ -218,7 +218,7 @@
<h2 id="example-code">Example code</h2>
<p>The following code includes stateful actions above. This program has menus like this:</p>
<figure>
<img src="../image/menu2.png" alt="" /><figcaption>menu2</figcaption>
<img src="image/menu2.png" alt="" /><figcaption>menu2</figcaption>
</figure>
<ul>
<li>Fullscreen menu toggles the size of the window between maximum and non-maximum. If the window is maximum size, which is called full screen, then a check mark is put before “fullscreen” label.</li>

View file

@ -142,7 +142,7 @@
<p><code>link</code> tag expresses the link to submenu. And at the same time it also expresses the submenu itself. This file illustrates the relationship between the menus and items better than the prior ui file. But <code>submenu</code> tag is simple and easy to understand. So, we usually prefer the former ui file style.</p>
<p>The following is a screenshot of the sample program in this section. Its name is <code>menu3</code>.</p>
<figure>
<img src="../image/menu3.png" alt="" /><figcaption>menu3</figcaption>
<img src="image/menu3.png" alt="" /><figcaption>menu3</figcaption>
</figure>
<p>The following is the ui file of the menu in <code>menu3</code>.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode numberSource xml numberLines"><code class="sourceCode xml"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">&lt;?xml</span> version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;<span class="kw">?&gt;</span></span>

View file

@ -402,7 +402,7 @@
<pre><code>$ gtk4-icon-browser</code></pre>
<p>The icon named “dialog-warning” is something like this.</p>
<figure>
<img src="../image/dialog_warning.png" alt="" /><figcaption>dialog-warning icon is like …</figcaption>
<img src="image/dialog_warning.png" alt="" /><figcaption>dialog-warning icon is like …</figcaption>
</figure>
<p>These are made by my hand. The real image on the alert dialog is nicer.</p>
<p>The GtkLabel <code>lb_alert</code> has no text yet. An alert message will be inserted by the program later.</p>
@ -821,11 +821,11 @@ org.gnome.calculator show-zeroes false</code></pre>
<p>This schema is used by Gnome Calculator. Run the calculator and change the mode, then check the schema again.</p>
<pre><code>$ gnome-calculator</code></pre>
<figure>
<img src="../image/gnome_calculator_basic.png" alt="" /><figcaption>gnome-calculator basic mode</figcaption>
<img src="image/gnome_calculator_basic.png" alt="" /><figcaption>gnome-calculator basic mode</figcaption>
</figure>
<p>Then, change the mode to advanced and quit.</p>
<figure>
<img src="../image/gnome_calculator_advanced.png" alt="" /><figcaption>gnome-calculator advanced mode</figcaption>
<img src="image/gnome_calculator_advanced.png" alt="" /><figcaption>gnome-calculator advanced mode</figcaption>
</figure>
<p>Run gsettings and check whether the value of <code>button-mode</code> changes.</p>
<pre><code>$ gsettings list-recursively org.gnome.calculator
@ -939,7 +939,7 @@ install_data(&#39;com.github.ToshioCP.tfe.gschema.xml&#39;, install_dir: schema_
<span id="cb40-13"><a href="#cb40-13"></a>schema_dir = get_option(&#39;prefix&#39;) / get_option(&#39;datadir&#39;) / &#39;glib-2.0/schemas/&#39;</span>
<span id="cb40-14"><a href="#cb40-14"></a>install_data(&#39;com.github.ToshioCP.tfe.gschema.xml&#39;, install_dir: schema_dir)</span>
<span id="cb40-15"><a href="#cb40-15"></a>meson.add_install_script(&#39;glib-compile-schemas&#39;, schema_dir)</span></code></pre></div>
<p>Source files of <code>tfe</code> is under <a href="../src/tfe6">src/tfe6</a> directory. Copy them to your temporary directory and try to compile and install.</p>
<p>Source files of <code>tfe</code> is under src/tfe6 directory. Copy them to your temporary directory and try to compile and install.</p>
<pre><code>$ meson --prefix=$HOME/local _build
$ ninja -C _build
$ GSETTINGS_SCHEMA_DIR=_build:$GSETTINGS_SCHEMA_DIR _build/tfe
@ -956,7 +956,7 @@ gschemas.compiled
... ...</code></pre>
<p>The screenshot is as follows.</p>
<figure>
<img src="../image/tfe6.png" alt="" /><figcaption>tfe6</figcaption>
<img src="image/tfe6.png" alt="" /><figcaption>tfe6</figcaption>
</figure>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

View file

@ -789,7 +789,7 @@ $ ninja -C _build install</code></pre>
<pre><code>$ meson _build
$ ninja -C _build
$ ninja -C _build install # or &#39;sudo ninja -C _build install&#39;</code></pre>
<p>Source files are in <a href="../src/tfe7">src/tfe7</a> directory.</p>
<p>Source files are in src/tfe7 directory.</p>
<p>We made a very small text editor. You can add features to this editor. When you add a new feature, care about the structure of the program. Maybe you need to divide a file into several files like this section. It isnt good to put many things into one file. And it is important to think about the relationship between source files and widget structures. It is appropriate that they correspond to each other in many cases.</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

View file

@ -131,7 +131,7 @@
<li>A transformation can be applied before the transfer completes. The transformation which is applied is called affine, which is a mathematical term meaning transofrmations that preserve straight lines. Scaling, rotating, reflecting, shearing and translating are all examples of affine transformations. They are mathematically represented by matrix multiplication and vector addition. In this section we dont use it, instead we will only use the identity transformation. This means that the coordinates in the source and mask are the same as the coordinates in destination.</li>
</ul>
<figure>
<img src="../image/cairo.png" alt="" /><figcaption>Stroke a rectangle</figcaption>
<img src="image/cairo.png" alt="" /><figcaption>Stroke a rectangle</figcaption>
</figure>
<p>The instruction is as follows:</p>
<ol type="1">
@ -199,7 +199,7 @@
<p>To compile this, type the following.</p>
<pre><code>$ gcc `pkg-config --cflags cairo` cairo.c `pkg-config --libs cairo`</code></pre>
<figure>
<img src="../image/rectangle.png" alt="" /><figcaption>rectangle.png</figcaption>
<img src="image/rectangle.png" alt="" /><figcaption>rectangle.png</figcaption>
</figure>
<p>See the <a href="https://www.cairographics.org/">Cairos website</a> for more details.</p>
<h2 id="gtkdrawingarea">GtkDrawingArea</h2>
@ -266,7 +266,7 @@
</ul>
<p>Compile and run it, then a window with a black rectangle (square) appears. Try resizing the window. The square always appears at the center of the window because the drawing function is invoked each time the window is resized.</p>
<figure>
<img src="../image/da1.png" alt="" /><figcaption>Square in the window</figcaption>
<img src="image/da1.png" alt="" /><figcaption>Square in the window</figcaption>
</figure>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

View file

@ -115,7 +115,7 @@
<h1 id="combine-gtkdrawingarea-and-tfetextview">Combine GtkDrawingArea and TfeTextView</h1>
<p>Now, we will make a new application which has GtkDrawingArea and TfeTextView in it. Its name is “color”. If you write a name of a color in TfeTextView and click on the <code>run</code> button, then the color of GtkDrawingArea changes to the color given by you.</p>
<figure>
<img src="../image/color.png" alt="" /><figcaption>color</figcaption>
<img src="image/color.png" alt="" /><figcaption>color</figcaption>
</figure>
<p>The following colors are available.</p>
<ul>

View file

@ -115,11 +115,11 @@
<h1 id="tiny-turtle-graphics-interpreter">Tiny turtle graphics interpreter</h1>
<p>A program <code>turtle</code> is an example with the combination of TfeTextView and GtkDrawingArea objects. It is a very small interpreter but it provides a tool to draw fractal curves. The following diagram is a Koch curve, which is a famous example of fractal curves.</p>
<figure>
<img src="../src/turtle/image/turtle_koch.png" alt="" /><figcaption>Koch curve</figcaption>
<img src="image/turtle_koch.png" alt="" /><figcaption>Koch curve</figcaption>
</figure>
<p>This program uses flex and bison. Flex is a lexical analyzer. Bison is a parser generator. These two programs are similar to lex and yacc which are proprietary software developed in Bell Laboratory. However, flex and bison are open source software. I will write about how to use those software, but they are not topics about gtk. So, readers can skip that part of this sections.</p>
<h2 id="how-to-use-turtle">How to use turtle</h2>
<p>The documentation of turtle is <a href="../html/turtle_doc.html">here</a>. Ill show you a simple example.</p>
<p>The documentation of turtle is here. Ill show you a simple example.</p>
<pre><code>fc (1,0,0) # Foreground color is red, rgb = (1,0,0).
pd # Pen down.
fd 100 # Go forward by 100 pixels.
@ -135,7 +135,7 @@ tr 90</code></pre>
<li>Type the program above in the editor (left part of the window).</li>
<li>Click on the <code>Run</code> button, then a red square appears on the right part of the window. The side of the square is 100 pixels long.</li>
</ol>
<p>In the same way, you can draw other curves. The documentation above shows some fractal curves such as tree, snow and square-koch. The source code in turtle language is located at <a href="../src/turtle/example">src/turtle/example</a> directory. You can read these files into <code>turtle</code> editor by clicking on the <code>Open</code> button.</p>
<p>In the same way, you can draw other curves. The documentation above shows some fractal curves such as tree, snow and square-koch. The source code in turtle language is located at src/turtle/example directory. You can read these files into <code>turtle</code> editor by clicking on the <code>Open</code> button.</p>
<h2 id="combination-of-tfetextview-and-gtkdrawingarea-objects">Combination of TfeTextView and GtkDrawingArea objects</h2>
<p>Turtle uses TfeTextView and GtkDrawingArea. It is similar to <code>color</code> program in the previous section.</p>
<ol type="1">
@ -146,7 +146,7 @@ tr 90</code></pre>
<li>The widget is added to the queue. It will be redrawn with the drawing function. The function just copies the surface, which is drawn by the interpreter, into the surface of the GtkDrawingArea.</li>
</ol>
<figure>
<img src="../image/turtle.png" alt="" /><figcaption>Parser, interpreter and drawing function</figcaption>
<img src="image/turtle.png" alt="" /><figcaption>Parser, interpreter and drawing function</figcaption>
</figure>
<p>The body of the interpreter is written with flex and bison. The codes are not thread safe. So the handler of “clicked” signal of the <code>Run</code> button prevents from reentering.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1"></a><span class="dt">void</span></span>
@ -198,7 +198,7 @@ tr 90</code></pre>
<li>27: The interpreter program has finished so <code>busy</code> is now changed to FALSE.</li>
<li>29-34: A handler of “resized” signal. If <code>surface</code> isnt NULL, it destroys the old surface. Then it creates a new surface. Its size is the same as the surface of the GtkDrawingArea instance.</li>
</ul>
<p>Other part of <code>turtleapplication.c</code> is almost same as the codes of <code>colorapplication.c</code> in the previous section. The codes of <code>turtleapplication.c</code> is in the <a href="../src/turtle">turtle directory</a>.</p>
<p>Other part of <code>turtleapplication.c</code> is almost same as the codes of <code>colorapplication.c</code> in the previous section. The codes of <code>turtleapplication.c</code> is in the turtle directory.</p>
<h2 id="what-does-the-interpreter-do">What does the interpreter do?</h2>
<p>Suppose that the turtle runs with the following program.</p>
<pre><code>distance = 100
@ -267,7 +267,7 @@ fd distance*2</code></pre>
<li><code>turtle</code> makes a tree structured data. This part of <code>turtle</code> is called parser.</li>
</ul>
<figure>
<img src="../image/turtle_parser_tree.png" alt="" /><figcaption>turtle parser tree</figcaption>
<img src="image/turtle_parser_tree.png" alt="" /><figcaption>turtle parser tree</figcaption>
</figure>
<ul>
<li><code>turtle</code> analyzes the tree and executes it. This part of <code>turtle</code> is called runtime routine or interpreter. The tree consists of rectangles and line segments between the rectangles. The rectangles are called nodes. For example, N_PROGRAM, N_ASSIGN, N_FD and N_MUL are nodes.
@ -306,7 +306,7 @@ fd distance*2</code></pre>
<li>gcc compiles <code>application.c</code>, <code>resources.c</code>, <code>turtle_parser.c</code> and <code>turtle_lex.c</code> with <code>turtle.h</code>, <code>turtle_lex.h</code>, <code>resources.h</code> and <code>turtle_parser.h</code>. It generates an executable file <code>turtle</code>.</li>
</ol>
<figure>
<img src="../image/turtle_compile_process.png" alt="" /><figcaption>compile process</figcaption>
<img src="image/turtle_compile_process.png" alt="" /><figcaption>compile process</figcaption>
</figure>
<p>Meson controls the process and the instruction is described in <code>meson.build</code>.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode numberSource numberLines"><code class="sourceCode"><span id="cb4-1"><a href="#cb4-1"></a>project(&#39;turtle&#39;, &#39;c&#39;)</span>
@ -1283,7 +1283,7 @@ expression:
<li>Finally <code>node_top</code> points the node <code>N_FD</code> and the node <code>N_FD</code> points the node <code>N_NUM</code>.</li>
</ol>
<figure>
<img src="../image/tree.png" alt="" /><figcaption>tree</figcaption>
<img src="image/tree.png" alt="" /><figcaption>tree</figcaption>
</figure>
<p>The following is the grammar rule extracted from <code>turtle.y</code>. The rules there are based on the same idea above. I dont want to explain the whole rules below. Please look into each line carefully so that you will understand all the rules and actions.</p>
<pre class="bison"><code>program:
@ -1546,7 +1546,7 @@ drawline (90, 100)</code></pre>
<p>The following diagram shows the structure of the stack. First, <code>procedure 1</code> is called. The procedure has two parameters. In the <code>procedure 1</code>, another procedure <code>procedure 2</code>, which has one parameter, is called. And in the <code>procedure 2</code>, <code>procedure 3</code>, which has three parameters, is called.</p>
<p>Programs push data to a stack from a low address memory to a high address memory. In the following diagram, the lowest address is at the top and the highest address is at the bottom. That is the order of the address. However, “the top of the stack” is the last pushed data and “the bottom of the stack” is the first pushed data. Therefore, “the top of the stack” is the bottom of the rectangle in the diagram and “the bottom of the stack” is the top of the rectangle.</p>
<figure>
<img src="../image/stack.png" alt="" /><figcaption>Stack</figcaption>
<img src="image/stack.png" alt="" /><figcaption>Stack</figcaption>
</figure>
<p>There are four functions to access the stack.</p>
<ul>
@ -1628,7 +1628,7 @@ drawline (90, 100)</code></pre>
<p>Turtle has its own coordinate. The origin is at the center of the surface, and positive direction of x and y axes are right and up respectively. But surfaces have its own coordinate. Its origin is at the top-left corner of the surface and positive direction of x and y are right and down respectively. A plane with the turtles coordinate is called user space, which is the same as cairos user space. A plane with the surfaces coordinate is called device space.</p>
<p>Cairo provides a transformation which is an affine transformation. It transforms a user-space coordinate (x, y) into a device-space coordinate (z, w).</p>
<figure>
<img src="../image/transformation.png" alt="" /><figcaption>transformation</figcaption>
<img src="image/transformation.png" alt="" /><figcaption>transformation</figcaption>
</figure>
<p><code>init_cairo</code> gets the width and height of the <code>surface</code> (See the program below).</p>
<ul>
@ -1913,15 +1913,15 @@ drawline (90, 100)</code></pre>
<p>This example draws a square.</p>
<p>When The parser reads the lines from one to four, it creates nodes like this:</p>
<figure>
<img src="../image/tree2.png" alt="" /><figcaption>Nodes of drawline</figcaption>
<img src="image/tree2.png" alt="" /><figcaption>Nodes of drawline</figcaption>
</figure>
<p>Runtime routine just stores the procedure to the symbol table with its name and node.</p>
<figure>
<img src="../image/table.png" alt="" /><figcaption>Symbol table</figcaption>
<img src="image/table.png" alt="" /><figcaption>Symbol table</figcaption>
</figure>
<p>When the parser reads the fifth line in the example, it creates nodes like this:</p>
<figure>
<img src="../image/proc_call.png" alt="" /><figcaption>Nodes of procedure call</figcaption>
<img src="image/proc_call.png" alt="" /><figcaption>Nodes of procedure call</figcaption>
</figure>
<p>When the runtime routine meets <code>N_procedure_call</code> node, it behaves like this:</p>
<ol type="1">

View file

@ -120,7 +120,7 @@
<p>A list is a sequential data structure. For example, an ordered string sequence “one”, “two”, “three”, “four” is a list. Each element of the list is called item. A list is like an array, but in many cases it is implemented with pointers which point to the next item of the list. And it has a start point. So, each item can be referred by the index of the item (first item, second item, …, nth item, …). There are two cases. One is the index starts from one (one-based) and the other is it starts from zero (zero-based).</p>
<p>Gio provides GListModel interface. It is a zero-based list of the same type of GObject objects, or objects that implement the same interface. An object implements GListModel is usually not a widget. So, the list is not displayed on the screen directly. Theres another object GtkListView which is a widget to display the list. The items in the list need to be connected to the items in GtkListView. GtkListItemFactory object maps items in the list to GListView.</p>
<figure>
<img src="../image/list.png" alt="" /><figcaption>List</figcaption>
<img src="image/list.png" alt="" /><figcaption>List</figcaption>
</figure>
<p>The instruction to build the whole list related objects is:</p>
<ol type="1">
@ -150,7 +150,7 @@
<h2 id="gtklistview-1">GtkListView</h2>
<p>GtkListView is a widget to show GListModel items. GtkListItem is used by GtkListView to represent items of a list model. But, GtkListItem itself is not a widget, so a user needs to set a widget, for example GtkLabel, as a child of GtkListItem to display an item of the list model. “item” property of GtkListItem points an object that belongs to the list model.</p>
<figure>
<img src="../image/gtklistitem.png" alt="" /><figcaption>GtkListItem</figcaption>
<img src="image/gtklistitem.png" alt="" /><figcaption>GtkListItem</figcaption>
</figure>
<p>In case the number of items is very big, for example more than a thousand, GtkListItem is recycled and connected to another item which is newly displayed. This recycle makes the number of GtkListItem objects fairly small, less than 200. This is very effective to restrain the growth of memory consumption so that GListModel can contain lots of items, for example, more than a million items.</p>
<h2 id="gtklistitemfactory">GtkListItemFactory</h2>
@ -242,7 +242,7 @@
<span id="cb2-76"><a href="#cb2-76"></a> g_object_unref (app);</span>
<span id="cb2-77"><a href="#cb2-77"></a> <span class="cf">return</span> stat;</span>
<span id="cb2-78"><a href="#cb2-78"></a>}</span></code></pre></div>
<p>The file <code>list1.c</code> is located under the directory <a href="../src/misc">src/misc</a>. Make a shell script below and save it to your bin directory. (If youve installed Gtk4 from the source to $HOME/local, then your bin directory is $Home/local/bin. Otherwise, $Home/bin is your private bin directory.)</p>
<p>The file <code>list1.c</code> is located under the directory src/misc. Make a shell script below and save it to your bin directory. (If youve installed Gtk4 from the source to $HOME/local, then your bin directory is $Home/local/bin. Otherwise, $Home/bin is your private bin directory.)</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="fu">gcc</span> <span class="kw">`</span><span class="ex">pkg-config</span> --cflags gtk4<span class="kw">`</span> <span class="va">$1</span>.c <span class="kw">`</span><span class="ex">pkg-config</span> --libs gtk4<span class="kw">`</span></span></code></pre></div>
<p>Change the current directory to the directory includes <code>list1.c</code> and type as follows.</p>
<pre><code>$ chmod 755 $HOME/local/bin/comp # or chmod 755 $Home/bin/comp
@ -250,7 +250,7 @@ $ comp list1
$ ./a.out</code></pre>
<p>Then, <code>list1.c</code> has been compiled and executed.</p>
<figure>
<img src="../image/list1.png" alt="" /><figcaption>list1</figcaption>
<img src="image/list1.png" alt="" /><figcaption>list1</figcaption>
</figure>
<p>I think the program is not so difficult. If you feel some difficulty, read this section again, especially GtkSignalListItemFactory subsubsection.</p>
<h3 id="gtkbuilderlistitemfactory">GtkBuilderListItemFactory</h3>
@ -276,7 +276,7 @@ $ ./a.out</code></pre>
<p>Remember that the classname (GtkListItem) in a ui template is used as the “this” pointer referring to the object that is being instantiated.</p>
</blockquote>
<p>Therefore, GtkListItem instance is used as the <code>this</code> object of the lookup tag when it is evaluated. <code>this</code> object will be explained in <a href="sec28.html">section 28</a>.</p>
<p>The C source code is as follows. Its name is <code>list2.c</code> and located under <a href="../src/misc">src/misc</a> directory.</p>
<p>The C source code is as follows. Its name is <code>list2.c</code> and located under src/misc directory.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="co">/* ----- activate, open, startup handlers ----- */</span></span>
@ -412,7 +412,7 @@ $ ./a.out</code></pre>
<li>closure tag has type attribute and function attribute. Function attribute specifies the function name and type attribute specifies the type of the return value of the function. The contents of closure tag (it is between &lt;closure…&gt; and&lt;/closure&gt;) is parameters of the function. <code>&lt;lookup name="item"&gt;GtkListItem&lt;/lookup&gt;</code> gives the value of the item property of the GtkListItem. This will be the second argument of the function. The first parameter is always the GListItem instance.</li>
<li><code>gtk_file_name</code> function first check the <code>info</code> parameter. Because it can be NULL when GListItem <code>item</code> is unbound. If its GFileInfo, then return the filename (copy of the filename).</li>
</ul>
<p>The whole program (<code>list3.c</code>) is as follows. The program is located in <a href="../src/misc">src/misc</a> directory.</p>
<p>The whole program (<code>list3.c</code>) is as follows. The program is located in src/misc directory.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb11-1"><a href="#cb11-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2"></a></span>
<span id="cb11-3"><a href="#cb11-3"></a><span class="dt">char</span> *</span>
@ -499,7 +499,7 @@ $ chmod +x $HOME/bin/comp</code></pre>
<pre><code>$ comp list3
$ ./a.out</code></pre>
<figure>
<img src="../image/list3.png" alt="" /><figcaption>screenshot list3</figcaption>
<img src="image/list3.png" alt="" /><figcaption>screenshot list3</figcaption>
</figure>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

View file

@ -115,7 +115,7 @@
<h1 id="gtkgridview-and-activate-signal">GtkGridView and activate signal</h1>
<p>GtkGridView is similar to GtkListView. It displays a GListModel as a grid, which is like a square tessellation.</p>
<figure>
<img src="../image/list4.png" alt="" /><figcaption>Grid</figcaption>
<img src="image/list4.png" alt="" /><figcaption>Grid</figcaption>
</figure>
<p>This is often seen when you use a file browser like nautilus.</p>
<p>In this section, lets make a very simple file browser <code>list4</code>. It just shows the files in the current directory. And a user can choose list or grid by clicking on buttons in the tool bar. Each item in the list or grid has an icon and a filename. In addition, <code>list4</code> provides the way to open the <code>tfe</code> text editor to show a text file. A user can do that by double clicking on an item or pressing enter key when an item is selected.</p>
@ -125,7 +125,7 @@
<pre><code>GtkListView (model property) =&gt; GtkSingleSelection (model property) =&gt; GtkDirectoryList
GtkGridView (model property) =&gt; GtkSingleSelection (model property) =&gt; GtkDirectoryList</code></pre>
<figure>
<img src="../image/directorylist.png" alt="" /><figcaption>DirectoryList</figcaption>
<img src="image/directorylist.png" alt="" /><figcaption>DirectoryList</figcaption>
</figure>
<p>The following is the part of the ui file <code>list4.ui</code>. It defines GtkListView, GtkSingleSelection and GtkDirectoryList. It also defines GtkGridView and GtkSingleSelection.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode xml"><code class="sourceCode xml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true"></a><span class="kw">&lt;object</span><span class="ot"> class=</span><span class="st">&quot;GtkListView&quot;</span><span class="ot"> id=</span><span class="st">&quot;list&quot;</span><span class="kw">&gt;</span></span>
@ -449,14 +449,14 @@ GtkGridView (model property) =&gt; GtkSingleSelection (model property) =&gt; Gtk
</ul>
<p>If your distribution supports Gtk4, using <code>g_app_info_launch_default_for_uri</code> is convenient. The function automatically determines the default application from the file and launches it. For example, if the file is text, then it launches gedit with the file. Such functionality comes from desktop.</p>
<h2 id="compilation-and-execution">Compilation and execution</h2>
<p>The source files are located in <a href="../src/list4">src/list4</a> directory. To compile and execute list4, type as follows.</p>
<p>The source files are located in src/list4 directory. To compile and execute list4, type as follows.</p>
<pre><code>$ cd list4 # or cd src/list4. It depends your current directory.
$ meson _build
$ ninja -C _build
$ _build/list4</code></pre>
<p>Then a file list appears as a list style. Click on a button on the tool bar so that you can change the style to grid or back to list. Double click “list4.c” item, then <code>tfe</code> text editor runs with the argument “list4.c”. The following is the screenshot.</p>
<figure>
<img src="../image/screenshot_list4.png" alt="" /><figcaption>Screenshot</figcaption>
<img src="image/screenshot_list4.png" alt="" /><figcaption>Screenshot</figcaption>
</figure>
<h2 id="gbytes-property-of-gtkbuilderlistitemfactory">“gbytes” property of GtkBuilderListItemFactory</h2>
<p>GtkBuilderListItemFactory has “gbytes” property. The property contains a byte sequence of ui data. If you use this property, you can put the contents of <code>factory_list.ui</code> and <code>factory_grid.ui</code>into <code>list4.ui</code>. The following shows a part of the new ui file (<code>list5.ui</code>).</p>
@ -510,7 +510,7 @@ $ _build/list4</code></pre>
<span id="cb13-48"><a href="#cb13-48" aria-hidden="true"></a> <span class="kw">&lt;/object&gt;</span></span></code></pre></div>
<p>CDATA section begins with “&lt;[CDATA[" and ends with "]]&gt;”. The contents of CDATA section is recognized as a string. Any character, even if it is a key syntax marker such as &lt; or &gt;, is recognized literally. Therefore, the text between “&lt;[CDATA[" and "]]&gt;” is inserted to “bytes” property as it is.</p>
<p>This method decreases the number of ui files. But, the new ui file is a bit complicated especially for the beginners. If you feel some difficulty, it is better for you to separate the ui file.</p>
<p>A directory <a href="../src/list5">src/list5</a> includes the ui file above.</p>
<p>A directory src/list5 includes the ui file above.</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>

View file

@ -118,7 +118,7 @@
<pre><code>1 + 2 = 3</code></pre>
<p><code>1+2</code> is an expression. It shows the way how to calculate. <code>3</code> is the value comes from the expression. Evaluation is to calculate the expression and get the value.</p>
<p>GtkExpression is a way to get a value. Evaluation is like a calculation. A value is got by evaluating the expression.</p>
<p>First, I want to show you the C file of the example for GtkExpression. Its name is <code>exp.c</code> and located under <a href="../src/expression">src/expression</a> directory. You dont need to understand the details now, just look at it. It will be explained in the next subsection.</p>
<p>First, I want to show you the C file of the example for GtkExpression. Its name is <code>exp.c</code> and located under src/expression directory. You dont need to understand the details now, just look at it. It will be explained in the next subsection.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
<span id="cb2-2"><a href="#cb2-2"></a></span>
<span id="cb2-3"><a href="#cb2-3"></a>GtkWidget *win1;</span>
@ -527,13 +527,13 @@
<p>Youve probably been noticed that ui file is easier and clearer than the corresponding C program. One of the most useful case of GtkExpression is building GtkListItem instance with GtkBuilderListItemFatory. Such case has already been described in the prior two sections.</p>
<p>It will be used in the next section to build GtkListItem in GtkColumnView, which is the most useful view object for GListModel.</p>
<h2 id="compilation-and-execution">Compilation and execution</h2>
<p>All the sources are in <a href="../src/expression">src/expression</a> directory. Change your current directory to the directory and run meson and ninja. Then, execute the application.</p>
<p>All the sources are in src/expression directory. Change your current directory to the directory and run meson and ninja. Then, execute the application.</p>
<pre><code>$ meson _build
$ ninja -C _build
$ build/exp</code></pre>
<p>Then, two windows appear.</p>
<figure>
<img src="../image/expression.png" alt="" /><figcaption>Expression</figcaption>
<img src="image/expression.png" alt="" /><figcaption>Expression</figcaption>
</figure>
<p>If you put some text in the field of the entry, then the same text appears in the second GtkLabel. Because the “label” property of the second GtkLabel instance is bound to the text in the GtkEntryBuffer.</p>
<p>If you resize the window, then the size appears in the title bar because the “title” property is bound to “default-width” and “default-height” properties.</p>

View file

@ -113,7 +113,7 @@
<h2 id="gtkcolumnview-1">GtkColumnView</h2>
<p>GtkColumnView is like GtkListView, but it has multiple columns. Each column is GtkColumnViewColumn.</p>
<figure>
<img src="../image/column_view.png" alt="" /><figcaption>Column View</figcaption>
<img src="image/column_view.png" alt="" /><figcaption>Column View</figcaption>
</figure>
<ul>
<li>GtkColumnView has “model” property. The property points a GtkSelectionModel object.</li>
@ -122,7 +122,7 @@
</ul>
<p>The following diagram shows the image how it works.</p>
<figure>
<img src="../image/column.png" alt="" /><figcaption>ColumnView</figcaption>
<img src="image/column.png" alt="" /><figcaption>ColumnView</figcaption>
</figure>
<p>The example in this section is a window that displays information of files in a current directory. The information is the name, size and last modified datetime of files. So, there are three columns.</p>
<p>In addition, the example uses GtkSortListModel and GtkSorter to sort the information.</p>
@ -498,13 +498,13 @@
</ul>
<p><code>exp.c</code> is simple and short thanks to <code>exp.ui</code>.</p>
<h2 id="compilation-and-execution.">Compilation and execution.</h2>
<p>All the source files are in <a href="../src/column">src/column</a> directory. Change your current directory to the directory and type the following.</p>
<p>All the source files are in src/column directory. Change your current directory to the directory and type the following.</p>
<pre><code>$ meson _build
$ ninja -C _build
$ _build/column</code></pre>
<p>Then, a window appears.</p>
<figure>
<img src="../image/column_view.png" alt="" /><figcaption>Column View</figcaption>
<img src="image/column_view.png" alt="" /><figcaption>Column View</figcaption>
</figure>
<p>If you click the header of a column, then the whole lists are sorted by the column. If you click the header of another column, then the whole lists are sorted by the newly selected column.</p>
<p>GtkColumnView is very useful and it can manage very big GListModel. It is possible to use it for file list, application list, database frontend and so on.</p>

View file

@ -234,7 +234,7 @@ $</code></pre>
GtkWidget -- GtkWindow</code></pre>
<p>GtkWindow includes GtkWidget at the top of its object.</p>
<figure>
<img src="../image/window_widget.png" alt="" /><figcaption>GtkWindow and GtkWidget</figcaption>
<img src="image/window_widget.png" alt="" /><figcaption>GtkWindow and GtkWidget</figcaption>
</figure>
<p>The function <code>gtk_window_new</code> is defined as follows.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a>GtkWidget *</span>
@ -258,7 +258,7 @@ GtkWidget -- GtkWindow</code></pre>
$ ./a.out</code></pre>
<p>A small window appears.</p>
<figure>
<img src="../image/screenshot_pr3.png" alt="" /><figcaption>Screenshot of the window</figcaption>
<img src="image/screenshot_pr3.png" alt="" /><figcaption>Screenshot of the window</figcaption>
</figure>
<p>Click on the close button then the window disappears and the program finishes.</p>
<h3 id="gtkapplicationwindow">GtkApplicationWindow</h3>
@ -276,7 +276,7 @@ $ ./a.out</code></pre>
<p>When you create GtkApplicationWindow, you need to give GtkApplication instance as an argument. Then it automatically connect these two instances. So you dont need to call <code>gtk_window_set_application</code> any more.</p>
<p>The program sets the title and the default size of the window. Compile it and run <code>a.out</code>, then you will see a bigger window with its title “pr4”.</p>
<figure>
<img src="../image/screenshot_pr4.png" alt="" /><figcaption>Screenshot of the window</figcaption>
<img src="image/screenshot_pr4.png" alt="" /><figcaption>Screenshot of the window</figcaption>
</figure>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>

View file

@ -149,7 +149,7 @@
$ ./a.out</code></pre>
<p>A window with a message “Hello.” appears.</p>
<figure>
<img src="../image/screenshot_lb1.png" alt="" /><figcaption>Screenshot of the label</figcaption>
<img src="image/screenshot_lb1.png" alt="" /><figcaption>Screenshot of the label</figcaption>
</figure>
<p>Theres only a little change between <code>pr4.c</code> and <code>lb1.c</code>. A program <code>diff</code> is good to know the difference between two files.</p>
<pre><code>$ cd misc; diff pr4.c lb1.c
@ -215,7 +215,7 @@ $ ./a.out</code></pre>
<p>Look at the line 17 to 19. First, it creates a GtkButton instance <code>btn</code> with a label “Click me”. Then, adds the button to the window <code>win</code> as a child. Finally, connects a “clicked” signal of the button to a handler (function) <code>click_cb</code>. So, if <code>btn</code> is clicked, the function <code>click_cb</code> is invoked. The suffix “cb” means “call back”.</p>
<p>Name the program <code>lb2.c</code> and save it. Now compile and run it.</p>
<figure>
<img src="../image/screenshot_lb2.png" alt="" /><figcaption>Screenshot of the label</figcaption>
<img src="image/screenshot_lb2.png" alt="" /><figcaption>Screenshot of the label</figcaption>
</figure>
<p>A window with the button appears. Click the button (it is a large button, you can click everywhere in the window), then a string “Clicked.” appears on the terminal. It shows the handler was invoked by clicking the button.</p>
<p>Its good that we make sure that the clicked signal was caught and the handler was invoked by using <code>g_print</code>. However, using g_print is out of harmony with Gtk which is a GUI library. So, we will change the handler. The following code is <code>lb3.c</code>.</p>
@ -282,7 +282,7 @@ $ ./a.out</code></pre>
</ul>
<p>After this, the Widgets are connected as the following diagram.</p>
<figure>
<img src="../image/box.png" alt="" /><figcaption>Parent-child relationship</figcaption>
<img src="image/box.png" alt="" /><figcaption>Parent-child relationship</figcaption>
</figure>
<p>The program <code>lb4.c</code> includes these widgets. It is as follows.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1"></a><span class="pp">#include </span><span class="im">&lt;gtk/gtk.h&gt;</span></span>
@ -349,7 +349,7 @@ gtk_box_set_homogeneous (GTK_BOX (box), TRUE);</code></pre>
<p>The first argument arranges the children of the box vertically. The second argument is the size between the children. The next function fills the box with the children, giving them the same space.</p>
<p>After that, two buttons <code>btn1</code> and <code>btn2</code> are created and the signal handlers are set. Then, these two buttons are appended to the box.</p>
<figure>
<img src="../image/screenshot_lb4.png" alt="" /><figcaption>Screenshot of the box</figcaption>
<img src="image/screenshot_lb4.png" alt="" /><figcaption>Screenshot of the box</figcaption>
</figure>
<p>The handler corresponds to <code>btn1</code> toggles its label. The handler corresponds to <code>btn2</code> destroys the top-level window and the application quits.</p>
</div>

View file

@ -166,7 +166,7 @@
<p>In line 30, <code>tv</code> is added to <code>win</code> as a child.</p>
<p>Now compile and run it.</p>
<figure>
<img src="../image/screenshot_tfv1.png" alt="" /><figcaption>GtkTextView</figcaption>
<img src="image/screenshot_tfv1.png" alt="" /><figcaption>GtkTextView</figcaption>
</figure>
<p>Theres an I-beam pointer in the window. You can add or delete any characters on the GtkTextview, and your changes are kept in the GtkTextBuffer. If you add more characters beyond the limit of the window, the height increases and the window extends. If the height gets bigger than the height of the display screen, you wont be able to control the size of the window, and change it back to the original size. This is a problem and shows that there is a bug in our program. This can solve it by adding a GtkScrolledWindow between the GtkApplicationWindow and GtkTextView.</p>
<h3 id="gtkscrolledwindow">GtkScrolledWindow</h3>

View file

@ -227,7 +227,7 @@ G_APPLICATION_HANDLES_OPEN This application handles opening files (in the prima
<pre><code>$ comp tfv3
$ ./a.out tfv3.c</code></pre>
<figure>
<img src="../image/screenshot_tfv3.png" alt="" /><figcaption>File viewer</figcaption>
<img src="image/screenshot_tfv3.png" alt="" /><figcaption>File viewer</figcaption>
</figure>
<p>Lets explain how the program <code>tfv3.c</code> works. First, the function <code>main</code> has only two changes from the previous version.</p>
<ul>
@ -264,7 +264,7 @@ $ ./a.out tfv3.c</code></pre>
<h2 id="gtknotebook">GtkNotebook</h2>
<p>GtkNotebook is a container widget that uses tabs and contains multiple children. The child that is displayed depends on which tab has been selected.</p>
<figure>
<img src="../image/screenshot_gtk_notebook.png" alt="" /><figcaption>GtkNotebook</figcaption>
<img src="image/screenshot_gtk_notebook.png" alt="" /><figcaption>GtkNotebook</figcaption>
</figure>
<p>Looking at the screenshots above, the left one is the window at the startup. It shows the file <code>pr1.c</code> and the filename is in the left tab. After clicking on the right tab, the contents of the file <code>tfv1.c</code> are shown instead. This is shown in the right screenshot.</p>
<p>The GtkNotebook widget is inserted as a child of GtkApplicationWindow and contains a GtkScrolledWindow for each file that is being displayed. The code to do this is given in <code>tfv4.c</code> and is:</p>

View file

@ -130,7 +130,7 @@
<p>The variable <code>f[i]</code> corresponds to the file associated to the i-th GtkNotebookPage. There are however two problems with this. The first concerns the size of the array. If a user gives too many arguments (more than 20 in the example above), it is impossible to store the additional pointers to the GFile instances. The second is the increasing difficulty for maintenance of the program. We have a small program so far, but however, if you continue developing it, the size of the program will grow. Generally speaking, the bigger the program size, the more difficult it is to keep track of and maintain global variables. Global variables can be used and changed anywhere throughout the entire program.</p>
<p>Making a child object is a good idea in terms of maintenance. One thing you need to be careful of is the difference between “child object” and “child widget”. Here we are describing a “child object”. A child object includes, and expands on its parent object, as a child object derives everything from the parent object.</p>
<figure>
<img src="../image/child.png" alt="" /><figcaption>Child object of GtkTextView</figcaption>
<img src="image/child.png" alt="" /><figcaption>Child object of GtkTextView</figcaption>
</figure>
<p>We will define TfeTextView as a child object of GtkTextView. It has everything that GtkTextView has. Specifically, TfeTextView has a GtkTextbuffer which corresponds to the GtkTextView inside TfeTextView. The additional important thing is that TfeTextView can also keep an additional pointer to GFile.</p>
<p>In general, this is how GObjects work. Understanding the general theory about Gobjects is difficult, particularly for beginners. So, I will just show you the way how to write the code and avoid the theoretical side. If you want to know about GObject system, refer to the separate tutorial](https://github.com/ToshioCP/Gobject-tutorial).</p>

View file

@ -116,7 +116,7 @@
<h2 id="new-open-and-save-button">New, Open and Save button</h2>
<p>In the last section we made the almost simplest editor possible. It reads files in the <code>app_open</code> function at start-up and writes them out when closing the window. It works but is not very good. It would be better if we had “New”, “Open”, “Save” and “Close” buttons. This section describes how to put those buttons into the window. Signals and handlers will be explained later.</p>
<figure>
<img src="../image/screenshot_tfe2.png" alt="" /><figcaption>Screenshot of the file editor</figcaption>
<img src="image/screenshot_tfe2.png" alt="" /><figcaption>Screenshot of the file editor</figcaption>
</figure>
<p>The screenshot above shows the layout. The function <code>app_open</code> in the source code <code>tfe2.c</code> is as follows.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode numberSource C numberLines"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1"></a><span class="dt">static</span> <span class="dt">void</span></span>
@ -408,7 +408,7 @@
<span id="cb5-46"><a href="#cb5-46"></a> } <span class="cf">else</span></span>
<span id="cb5-47"><a href="#cb5-47"></a> gtk_window_destroy (GTK_WINDOW (win));</span>
<span id="cb5-48"><a href="#cb5-48"></a>}</span></code></pre></div>
<p>The whole source code of <code>tfe3.c</code> is stored in <a href="../src/tfe">src/tfe</a> directory. If you want to see it, click the link above.</p>
<p>The whole source code of <code>tfe3.c</code> is stored in src/tfe directory. If you want to see it, click the link above.</p>
<h3 id="using-ui-string">Using ui string</h3>
<p>GtkBuilder can build widgets using string. Use the function <code>gtk_builder_new_from_string</code> instead of <code>gtk_builder_new_from_file</code>.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="dt">char</span> *uistring;</span>

View file

@ -110,23 +110,23 @@
<p>TfeTextView Child object of GtkTextView. It holds GFile which the contents of GtkTextBuffer correponds to.</p>
<h2 id="functions">Functions</h2>
<ul>
<li>GFile *<a href="../src/tfetextview/#tfe_text_view_get_file">tfe_text_view_get_file ()</a></li>
<li>void <a href="../src/tfetextview/#tfe_text_view_open">tfe_text_view_open ()</a></li>
<li>void <a href="../src/tfetextview/#tfe_text_view_save">tfe_text_view_save ()</a></li>
<li>void <a href="../src/tfetextview/#tfe_text_view_saveas">tfe_text_view_saveas ()</a></li>
<li>GtkWidget *<a href="../src/tfetextview/#tfe_text_view_new_with_file">tfe_text_view_new_with_file ()</a></li>
<li>GtkWidget *<a href="../src/tfetextview/#tfe_text_view_new">tfe_text_view_new ()</a></li>
<li>GFile *tfe_text_view_get_file ()</li>
<li>void tfe_text_view_open ()</li>
<li>void tfe_text_view_save ()</li>
<li>void tfe_text_view_saveas ()</li>
<li>GtkWidget *tfe_text_view_new_with_file ()</li>
<li>GtkWidget *tfe_text_view_new ()</li>
</ul>
<h2 id="signals">Signals</h2>
<ul>
<li>void <a href="../src/tfetextview/#change-file">change-file</a></li>
<li>void <a href="../src/tfetextview/#open-response">open-response</a></li>
<li>void change-file</li>
<li>void open-response</li>
</ul>
<h2 id="types-and-values">Types and Values</h2>
<ul>
<li><a href="../src/tfetextview/#tfetextview-1">TfeTextView</a></li>
<li><a href="../src/tfetextview/#tfetextviewclass">TfeTextViewClass</a></li>
<li><a href="../src/tfetextview/#enum-tfetextviewopenresponsetype">TfeTextViewOpenResponseType</a></li>
<li>TfeTextView</li>
<li>TfeTextViewClass</li>
<li>TfeTextViewOpenResponseType</li>
</ul>
<h2 id="object-hierarchy">Object Hierarchy</h2>
<pre><code>GObject

View file

@ -122,12 +122,12 @@ $ ninja -C _build install</code></pre>
<p>Type the following command then turtle shows the following window.</p>
<pre><code>$ turtle</code></pre>
<figure>
<img src="../src/turtle/image/turtle1.png" alt="" /><figcaption>Screenshot just after its executed</figcaption>
<img src="image/turtle1.png" alt="" /><figcaption>Screenshot just after its executed</figcaption>
</figure>
<p>The left half is a text editor and the right half is a surface. Surface is like a canvas to draw shapes.</p>
<p>Write turtle language in the text editor and click on <code>run</code> button, then the program will be executed and it draws shapes on the surface.</p>
<figure>
<img src="../src/turtle/image/turtle_tree.png" alt="" /><figcaption>Tree</figcaption>
<img src="image/turtle_tree.png" alt="" /><figcaption>Tree</figcaption>
</figure>
<p>If you add the following line in <code>turtle.h</code>, then codes to inform the status will also be compiled. However, the speed will be quite slow because of the output messages.</p>
<pre><code># define debug 1</code></pre>
@ -151,7 +151,7 @@ tr 90
fd 100</code></pre>
<p>The command <code>tr</code> is “Turn Right”. The argument is angle with degrees. Therefore, <code>tr 90</code> means “Turn right by 90 degrees”. If you click on the <code>run</code>button, then two line segments appears. One is vertical and the other is horizontal.</p>
<figure>
<img src="../src/turtle/image/turtle2.png" alt="" /><figcaption>Two line segments on the surface</figcaption>
<img src="image/turtle2.png" alt="" /><figcaption>Two line segments on the surface</figcaption>
</figure>
<h2 id="background-and-foreground-color">Background and foreground color</h2>
<p>Colors are specified with RGB. A vector (r, g, b) denotes RGB color. Each of the elements is a real number between 0 and 1.</p>
@ -169,7 +169,7 @@ fd 100</code></pre>
<li>fc: Foreground Color. <code>fc (0,1,0)</code> changes the foreground color to green. This command changes the pen color. The prior shapes on the surface arent affected. After this command, the turtle draws lines with the new color.</li>
</ul>
<figure>
<img src="../src/turtle/image/turtle3.png" alt="" /><figcaption>Change the foreground color</figcaption>
<img src="image/turtle3.png" alt="" /><figcaption>Change the foreground color</figcaption>
</figure>
<h2 id="other-simple-commands">Other simple commands</h2>
<ul>
@ -269,15 +269,15 @@ repeat (4)</code></pre>
<h2 id="fractal-curves">Fractal curves</h2>
<p>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.</p>
<figure>
<img src="../src/turtle/image/turtle_tree.png" alt="" /><figcaption>Tree</figcaption>
<img src="image/turtle_tree.png" alt="" /><figcaption>Tree</figcaption>
</figure>
<p>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 it several times.</p>
<p>This repeating is programmed by recursive call. Two more examples are shown here. They are Koch curve and Square Koch curve.</p>
<figure>
<img src="../src/turtle/image/turtle_koch.png" alt="" /><figcaption>Koch curve</figcaption>
<img src="image/turtle_koch.png" alt="" /><figcaption>Koch curve</figcaption>
</figure>
<figure>
<img src="../src/turtle/image/turtle_square_koch.png" alt="" /><figcaption>Square Koch curve</figcaption>
<img src="image/turtle_square_koch.png" alt="" /><figcaption>Square Koch curve</figcaption>
</figure>
<h2 id="tokens-and-punctuations">Tokens and punctuations</h2>
<p>The following is the list of tokens.</p>

View file

@ -319,6 +319,6 @@ If you use git, run the terminal and type the following.
$ git clone https://github.com/ToshioCP/Gtk4-tutorial.git
The source files are under [`/src/tfe5`](tfe5) directory.
The source files are under [/src/tfe5](../src/tfe5) directory.
Up: [Readme.md](../Readme.md), Prev: [Section 14](sec14.md), Next: [Section 16](sec16.md)

19
lib/lib_cp_images.rb Normal file
View file

@ -0,0 +1,19 @@
require 'fileutils'
include FileUtils
def cp_images srcmdfiles, dst_dir
mkdir_p(dst_dir) unless Dir.exist?(dst_dir)
images = srcmdfiles.map do |file|
d = File.dirname(file)
f = File.read(file)
f = f.gsub(/^ .*\n/,'')
f = f.gsub(/^~~~.*?^~~~\n/m,'')
imgs = f.scan(/!\[.*?\]\((.*?)\)/).flatten.uniq
imgs.map{|img| File.absolute_path("#{d}/#{img}")}
end
images = images.flatten.sort.uniq
images.each do |src|
dst = "#{dst_dir}/#{File.basename(src)}"
cp(src, dst)
end
end

View file

@ -325,26 +325,25 @@ def change_link src, old_dir, type, new_dir=nil
when "latex"
name.match(/!?\[(.*?)\]/)[1]
end
elsif m[2] =~ /^(http|\/)/
elsif target =~ /^(http|\/)/
c
elsif size != nil
p_target = Pathname.new "#{old_dir}/#{target}"
target = p_target.relative_path_from(p_new_dir).to_s
elsif name =~ /^!/ # link to an image file
n_target = Pathname.new("#{old_dir}/#{target}").relative_path_from(p_new_dir).to_s
b_target = File.basename(target)
case type
when "gfm"
"#{name}(#{target})"
"#{name}(#{n_target})"
when "html"
"#{name}(#{target})"
"#{name}(image/#{b_target})"
when "latex"
"#{name}(#{target})#{size}"
size ? "#{name}(#{n_target})#{size}" : "#{name}(#{target})"
end
else
p_target = Pathname.new "#{old_dir}/#{target}"
target = p_target.relative_path_from(p_new_dir).to_s
if type == "latex" && name[0] != '!'
name.match(/!?\[(.*?)\]/)[1]
else
"#{name}(#{target})"
n_target = Pathname.new("#{old_dir}/#{target}").relative_path_from(p_new_dir).to_s
if type == "gfm"
"#{name}(#{n_target})"
else # remove link
name.match(/\[(.*?)\]/)[1]
end
end
end

View file

@ -269,4 +269,4 @@ If you use git, run the terminal and type the following.
$ git clone https://github.com/ToshioCP/Gtk4-tutorial.git
The source files are under [`/src/tfe5`](tfe5) directory.
The source files are under [/src/tfe5](tfe5) directory.

View file

@ -342,10 +342,10 @@ module Prepare_test
html
[Relative link](../temp/sample.c) will be converted when the target type is gfm or html.
Relative link will be converted when the target type is gfm or html.
Otherwise (latex) the link will be removed.
Another [relative link](../../Rakefile).
Another relative link.
[Absolute link](https://github.com/ToshioCP) is kept as it is.
@ -353,7 +353,7 @@ module Prepare_test
If the target type is gfm or html, the size will be removed.
Otherwise (latex) it remains.
![Screenshot of the box](../../image/screenshot_lb4.png)
![Screenshot of the box](image/screenshot_lb4.png)
EOS
sample_md_latex = <<~EOS
@ -826,7 +826,7 @@ class Test_lib_src_file < Minitest::Test
dst_src = <<~'EOS'
[Section 1](sec1.html)
[document](document.html)
![image](../image/image.png)
![image](image/image.png)
[Github](https://github.com/ToshioCP)
EOS
assert_equal dst_src, change_link(src_src, "src", "html", "html")
@ -892,7 +892,7 @@ class Test_lib_src_file < Minitest::Test
end
remove_entry_secure(temp)
assert_equal "![image](../src/image/image.png)\n", dst_md["gfm"]
assert_equal "![image](../src/image/image.png)\n", dst_md["html"]
assert_equal "![image](image/image.png)\n", dst_md["html"]
assert_equal "![image](../src/image/image.png){width=8cm hight=6cm}\n", dst_md["latex"]
end