aboutsummaryrefslogtreecommitdiff
path: root/doc/user/syntax.skb
blob: 2de7cbdeee827cd4a321e212310f77482d1aeb0f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
;;; syntax.skb  --  The Skribilo syntaxes.
;;; -*- coding: iso-8859-1 -*-
;;;
;;; Copyright 2008, 2009  Ludovic Court�s <ludo@gnu.org>
;;; Copyright 2001, 2002, 2003, 2004  Manuel Serrano
;;;
;;;
;;; This file is part of Skribilo.
;;;
;;; Skribilo is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; Skribilo is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Skribilo.  If not, see <http://www.gnu.org/licenses/>.

;*---------------------------------------------------------------------*/
;*    The Skribilo syntaxes                                            */
;*---------------------------------------------------------------------*/
(chapter :title "Syntax"
         :ident "syntax"
   
   (p [This chapter describes the syntax or Skribilo documents---or
rather, the available syntaxes Skribilo documents can use.  Skribilo
actually supports several input syntaxes, each of which is implemented
by a ,(emph [reader]).  The input syntax (and reader) can be selected at
document compilation time using the ,(tt [--reader]) option of the
compiler (see ,(numref :text [Chapter] :ident "compiler")).
Nevertheless, it has a ``preferred'' syntax (the default syntax), which
is that of the ,(ref :url *skribe-url* :text [Skribe document
preparation system]).  Thus, the Skribe syntax is first described, and
then alternate syntaxes are presented.])


   (section :title [The Skribe Syntax]
            :ident "skribe-syntax"

      (p [By default or when the ,(tt [--reader=skribe]) option is
passed to the compiler, a Skribilo document is composed of ,(emph
[Skribe expressions]), which resemble expressions in the Scheme
programming language, with a few extensions to make them more convenient
to use within documents.  A Skribe expression can be:

,(itemize (item [An atomic expression, such as a string of characters, a number.])
	  (item [A list.])
	  (item [A text.]))

Here are several examples of correct Skribe expressions:

,(center (frame :margin 5 :border 0 :width *prgm-width*
		(color :margin 5 :bg *disp-color* :width 100.
(itemize (item [,(color :fg "#009900" (tt "\"foo\"")), a string of characters composed of the
characters `,(color :fg "#009900" "f")', `,(color :fg "#009900" "o")'
and `,(color :fg "#009900" "o")'.])
	 (item [,(color :fg "#009900" (tt "123") " " (tt "3.14")), two numbers.])
	 (item [,(color :fg "#009900" (tt "#t") " " (tt "#f")), the ,(emph "true") and ,(emph "false")
Skribe value.])
	 (item [,(color :fg "#009900" (tt "(bold \"foo bar\")")), a list.])
	 (item [,(color :fg "#009900" (tt (char 91)"A text sample"(char 93))), a simple text containing
three words and no escape sequence.])
	 (item [,(color :fg "#009900" (tt (char 91)"Another text sample (that is still) simple"(char 93))),
another simple text.])
	 (item [,(color :fg "#009900" (tt (char 91)"Another ,(bold \"text\") sample"(char 93))),
a more complex text that contains two words (,(color :fg "#009900" (tt "Another")) and ,(color :fg "#009900" (tt "sample")))
and an expression ,(color :fg "#009900" (tt "(bold \"text\")")). The escape sequence is introduced
with the `,(color :fg "#009900" (tt ",("))' characters.])))))

,(p [
Expressions are evaluated, thus ,(color :fg "#009900" (tt "(bold \"foo\")"))
has the effect of typesetting the word ,(color :fg "#009900" (tt "foo")) in
bold face to produce ,(color :fg "#009999" (bold "foo")). Escape sequences
enable evaluation of expressions inside the text. Thus the text
,(color :fg "#009900" (tt (char 91)"Another ,(bold \"text\") sample"(char 93)))
produces `,(color :fg "#009999" (tt [Another ,(bold "text") sample]))'.
On the other hand
,(color :fg "#009900" (tt (char 91)"Another (bold \"text\") sample"(char 93)))
produces
`,(color :fg "#009999" (tt [Another (bold "text") sample]))' because it does not contain
the escape sequence `,(color :fg "#009900" (char #\,)(char #\())'.])
])

;*---------------------------------------------------------------------*/
;*    Formal syntax                                                    */
;*---------------------------------------------------------------------*/
(subsection :title [Formal Syntax]

(disp :verb #t :bg *prgm-skribe-color* [
<expr>    --> <atom>
            | <text>
            | <list>
<list>    --> (<expr>+)
<text>    --> ,(bold (color :fg "red" (char 91))),(it "any sequence but `,(' or a `,")<list>,(it "'"),(bold (color :fg "red" (char 93)))
<atom>    --> <boolean>
            | <integer>
            | <float>
            | <string>
            | <color>
<integer> --> ,(tt (char 91))0-9,(tt (char 93))+
<float>   --> ,(tt (char 91))0-9,(tt (char 93))+.,(tt (char 91))0-9,(tt (char 93))*
            | ,(tt (char 91))0-9,(tt (char 93))*.,(tt (char 91))0-9,(tt (char 93))+
<string>  --> ,(tt #\")...,(tt #\")
<color>   --> <string>
            | ,(tt #\")#,(tt (char 91))0-9a-f,(tt (char 93)),(tt (char 91))0-9a-f,(tt (char 93)),(tt (char 91))0-9a-f,(tt (char 93)),(tt (char 91))0-9a-f,(tt (char 93)),(tt (char 91))0-9a-f,(tt (char 93)),(tt (char 91))0-9a-f,(tt (char 93)),(tt #\")]))

;*---------------------------------------------------------------------*/
;*    Values                                                           */
;*---------------------------------------------------------------------*/
(subsection :title "Values" :file #f :toc #t

;*--- width -----------------------------------------------------------*/
(subsubsection :title "Width" (p [
,(mark "width")
A Skribe ,(emph "width") refers to the horizontal size a construction
occupies on an output document. There are three different ways for
specifying a width:])

(description (item :key "An absolute pixel size" 
		  [This is represented by an ,(emph "exact") integer value
                  (such as ,(code "350")).])
	    (item :key "A relative size" 
		  [This is represented by an ,(emph "inexact") integer value
                  (such as ,(code "50.0")) which ranges in the interval 
                  ,(char 91)-100.0 .. 100.0,(char 93)])
	    (item :key "An engine dependent representation" 
		  [This is represented by a string that is directly emitted
                  in the output document (such as HTML column ,(code "\"0*\"")
                  specification). Note that this way of specifying width
                  is strictly unportable.])))))
   

   (section :title [The Outline Syntax]
            :ident "outline-syntax"
      
      (p [Alternatively, Skribilo allows documents to be written in a
plain text format, with almost no markup.  Instead, conventions borrowed
from ,(ref :text [Emacs' Outline Mode] :url
"http://www.gnu.org/software/emacs/manual/html_node/emacs/Outline-Mode.html")
to denote the text structure as well as other common conventions are
used to express various formatting ideas.  This syntax is implemented by
the ,(tt [outline]) reader; thus, it is made available by passing the
,(tt [--reader=outline]) option to the ,(ref :ident "compiler" :text
[compiler]).  The major elements of this syntax are the following:])
      
      (description
	 (item :key [Document title and author]
	    [The document title is introduced by adding a line starting
with ,(code [Title:]) at the beginning of the text file, and followed by
the title.  Likewise, the author can be specified with a line starting
with ,(code [Author:]).])
	 (item :key [Sectioning]
	    [Chapters are introduced using a heading preceding by a
single ,(tt [*]) (star) character.  For instance, ,(tt [* The First
Part]) on a line on its own, followed by an empty line, introduces a new
chapter entitled ``The First Part''.  Likewise, two stars introduce a
section, three stars introduce a subsection, etc.])
	 (item :key [Emphasis, italics, bold]
	    [Words or phrases surrounded by the ,(tt [_]) (underscore)
character are emphasized; those surrounded by ,(tt [/]) (slash)
characters are italicized; finally, those surrounded by ,(tt [*]) (star)
characters are typeset in boldface (see Section ,(ref :section
"Ornaments")).])
	 (item :key [Quotes]
	    [Words enclosed in double quotes (i.e., two back-quote
characters, then two single-quote characters) are interpreted as quoted
text, as per ,(tt "q").])
	 (item :key [Code]
	    [Words enclosed in single quotes (i.e., one back-quote
character, then one single-quote) are interpreted as code and are
typeset using a fixed-width font, as per ,(markup-ref "tt").])
	 (item :key [Hyperlinks]
	    [URLs are automatically recognized and converted into a
,(code [(ref :url ...)]) form (see ,(markup-ref "ref")).  In addition,
,(tt [outline]) has limited support for Org-Mode-style hyperlinks; for
instance, ,(code "[[http://gnu.org/][The GNU Project]]") yields ,(ref
:url "http://gnu.org/" :text [The GNU Project]).]))
      
      (p [Here is an example showing how the ,(tt [outline]) syntax maps
to the native ,(tt [skribe]) syntax:])
      
      (let ((src (string-append %top-srcdir "/doc/user/src/outline.txt")))
	(example-produce
	 (example :legend [The ,(tt [outline]) syntax]
	   (tt
	      (flush :side 'left
		(pre (with-input-from-file src
			(lambda ()
			  (set-correct-file-encoding!)
			  (let loop ((line   (read-line))
				     (result '()))
			    (if (eof-object? line)
				(string-join (reverse result)
					     (string #\newline))
				(loop (read-line)
				      (cons line result))))))))))
	 (prgm 
	   (with-output-to-string
	     (lambda ()
	       (let* ((read  (make-reader 'outline))
		      (input (open-input-file src)))
		 (set-correct-file-encoding! input)
		 (pretty-print (read input) :width 65)))))))
      
      (p [The ,(tt [outline]) mode makes it possible to quickly create
documents that can be output in variety of formats (see ,(numref :text
[Chapter] :ident "engines")).  The downside is that, being a very simple
markup-less document format, there are many things that cannot be done
using it, most notably tables, bibliographies, and cross-references.]))

   (section :title [The Gemtext Syntax] :ident "gemtext-syntax"
     (p [,(ref
:url "https://gemini.circumlunar.space/docs/gemtext.gmi"
:text "Gemtext"), the lightweight markup language used by the ,(ref
:url "https://gemini.circumlunar.space" :text "Gemini protocol"), is
supported as an input syntax. To use it, just pass ,(tt
[--reader=gemtext]) to the compiler. When used programmatically, the
Gemtext reader can be customized using the following options.])

     (doc-markup 'make-gemtext-reader
                 '((:join-lines? [If ,(code "#t"), lines which are not
separated by a blank line are joined into a single paragraph. This is
a relaxation of the Gemtext standard, and is not done by default.])
                   (:section-numbers? [If ,(code "#t"), sections are
numbered. Else, they are not.]))
                 :common-args '()
                 :source "skribilo/reader/gemtext.scm"
	         :idx *function-index*))

   (section :title [The RSS 2.0 Syntax]
            :ident "rss2-syntax"
      
      (p [RSS 2.0 (aka. ,(ref :url "http://en.wikipedia.org/wiki/RSS" :text
(emph [Really Simple Syndication]))) is supported as an input syntax.
To use it, just pass ,(tt [--reader=rss-2]) to the compiler.  This
makes it possible to generate Skribilo documents from RSS 2.0 feeds,
which can be useful or at least funny.  Consider the following example:]

   (disp :verb #t [
$ wget http://planet.gnu.org/rss20.xml
$ skribilo -R rss-2 -t lout -c column-number=2 < rss20.xml \\
  | lout | ps2pdf - > gnu-planet.pdf
])

[It produces a two-column PDF file with the contents of the RSS feed of
GNU Planet, where each item of the feed is mapped to a Skribilo
``chapter''.]))
   
   (section :title [Documents in Scheme Programs]
            :ident "scheme-syntax"
      
      (p [It is also possible to create and output Skribilo documents
from a Guile Scheme program.  In that case, you get to use the Scheme
syntax, which is close to the ,(ref :ident "skribe-syntax" :text [Skribe
syntax]) described above, modulo the ,(code "[...]") constructs.  A
typical Scheme program that would produce and output a document, pretty
much like what the ,(ref :ident "compiler" :text [,(tt [skribilo])
compiler does]), would look like this:]
	 
	 (example :legend [Programming Skribilo documents in Scheme.]
	  (prgm :language scheme :file "src/scheme.scm"))
	 
        [This should give you an idea of the wonderful, life-changing
things that can be achieved with a bit of ,(emph [document
programming]).]))
   
   (section :title [Writing New Readers]
            :ident "custom-syntax"
      
      (p [Skribilo is extensible and makes it easy to add ,(emph [custom
readers]), allowing the use of virtually any input syntax.  A reader is
essentially a procedure like R5RS' ,(tt [read]), i.e., a one-argument
procedure that takes a port and returns an S-expression.  The returned
S-expression should be a valid ``document program'' as shown in ,(ref
:ident "scheme-syntax").])
      
      (p [The are a few additional details, though.  Implementations of
readers are required to use the ,(tt [(skribilo reader)]) modules and
the ,(tt [define-reader]) macro.  In addition, the reader must live in
its own module, under the ,(tt [(skribilo reader)]) module hierarchy, so
that the reader lookup mechanism (used by the ,(tt [--reader]) option of
the compiler) can find it.  This mechanism is the same as that used for
engines (see ,(numref :text [Section] :ident "custom-engine")).  A
skeleton for a reader would be like this:]
    
	(example :legend [Writing a new reader.]
	 (prgm :language scheme [
(define-module (skribilo reader my-reader)
  #:use-module (skribilo reader)
  #:export (reader-specification))

(define (make-my-reader)
  (lambda (port)
    ...))

(define-reader my-reader  ;; the reader name
  "0.1"                   ;; a version number
  make-my-reader)         ;; the procedure that returns
                          ;; a reader procedure
]))
	
      	[Users and encouraged to look at examples in the Skribilo
source for additional details.])))


;;; Local Variables:
;;; ispell-local-dictionary: "american"
;;; End: