summaryrefslogtreecommitdiff
path: root/www/www.org
blob: e4432af96103072c314c6474e4b593cf33ce55cd (about) (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
#+STARTUP: showall

* [[https://orgmode.org/manual/Publishing.html][Publishing]]

Org includes a publishing management system that allows you to configure
automatic HTML conversion of /projects/ composed of interlinked Org files. You
can also configure Org to automatically upload your exported HTML pages and
related attachments, such as images and source code files, to a web server.

You can also use Org to convert files into PDF, or even combine HTML and PDF
conversion so that files are available in both formats on the server.

Publishing has been contributed to Org by David O’Toole.

** [[https://orgmode.org/manual/Configuration.html][Configuration]]

Publishing needs significant configuration to specify files, destination and
many other properties of a project.

#+NAME: www-test-data
#+BEGIN_SRC elisp :tangle www-test-data.el
  ;; -*- lexical-binding: t; -*-

  ( load "~/src/channel/www/build-site" )

  ( print "publish-test-1" )

  ( let ( ( publication-instance ( publication-object ) ) )
    ( publish publication-instance ( list "test.pl" "example.org" ) ) )

  ( print "publish-test-2" )

  ( let ( ( publication-instance ( publication-object ) ) )
    ( publish publication-instance
      ( list "test.pl"

        :property1
        "value1"

        :property2
        "value2" ) ) )

  ( print "publish-test-3" )

  ( let ( ( publication-instance ( publication-object ) ) )
    ( publish publication-instance
      ( list "test.pl"

        :components
        ( list "example.pl" "example.org" )) ) )
#+END_SRC

*** [[https://orgmode.org/manual/Project-alist.html][The variable =org-publish-project-alist=]]

Publishing is configured almost entirely through setting the value of one
variable, called =org-publish-project-alist=. Each element of the list
configures one project, and may be in one of the two following forms:

#+BEGIN_EXAMPLE
  ( "project-name" :property value :property value ... )
#+END_EXAMPLE

i.e., a well-formed property list with alternating keys and values, or:

#+BEGIN_EXAMPLE
  ( "project-name" :components ( "project-name" "project-name" ... ) )
#+END_EXAMPLE

In both cases, projects are configured by specifying property values. A project
defines the set of files that are to be published, as well as the publishing
configuration to use when publishing those files. When a project takes the
second form listed above, the individual members of the =:components= property
are taken to be sub-projects, which group together files requiring different
publishing options. When you publish such a “meta-project”, all the components
are also published, in the sequence given.

#+NAME: build-site
#+BEGIN_SRC elisp :tangle build-site.el
  ;; -*- lexical-binding: t; -*-

  ;;; The Object Prototype

  ( defun publication-object ( )
    ( let ( ( object-projects ( list ) )
            ( org-publish-project-alist ( list ) )
            ( success-report "Build complete!" ) )
      ( list

        :object-compose
        ( lambda ( )
          ( setq org-publish-project-alist ( list object-projects ) ) )

        :object-get-projects
        ( lambda ( project-data )
          ( setq object-projects ( append project-data object-projects ) ) )

        :object-report
        ( lambda ( )
          ( print org-publish-project-alist )
          ( print success-report ) ) ) ) )

  ;;; The Object Interface

  ( defun object-compose ( publication-instance )
    ( funcall ( plist-get publication-instance :object-compose ) ) )

  ( defun object-get-projects ( publication-instance project-data )
    ( funcall
      ( plist-get publication-instance :object-get-projects ) project-data ) )

  ( defun object-report ( publication-instance )
    ( funcall ( plist-get publication-instance :object-report ) ) )

  ;;; The User Logic

  ( defun atypical-header-p ( project-data )
    ( let ( ( element-1 ( pop project-data ) )
            ( element-2 ( pop project-data ) )
            ( error-1 "First element is not a string: " )
            ( error-2 "Second element is not a keyword: " ) )
      ( condition-case error
          ( cond
            ( ( not ( stringp element-1 ) )
              ( signal 'scan-error ( concat error-1 element-1 ) ) )
            ( ( not ( keywordp element-2 ) )
              ( signal 'scan-error ( concat error-2 element-2 ) ) ) )
        ( scan-error ( print ( cdr error ) ) ) ) ) )

  ( defun export-project-alist ( publication-instance )
    ( object-compose publication-instance )
    ( object-report publication-instance ) )

  ( defun get-component ( project-data )
    ( let ( ( component ( nth 2 project-data ) ) )
      ( print component )
      component ) )

  ( defun has-component-p ( project-data )
    ( let ( ( component-keyword ':components )
            ( second ( nth 1 project-data ) ) )
      ( eq component-keyword second ) ) )

  ( defun import-data ( publication-instance project-data )
    ( object-get-projects publication-instance project-data ) )

  ( defun too-short-p ( project-data )
    ( let ( ( minimal-length 2 ) )
      ( < ( length project-data ) minimal-length ) ) )

  ;;; The User Interface

  ( defun publish ( publication-instance &rest project-data-wrapped )
    ( let ( ( project-data ( car project-data-wrapped ) ) )
        ( pcase project-data
          ( ( guard ( too-short-p project-data ) ) nil )
          ( ( guard ( atypical-header-p project-data ) nil ) )
          ( ( pred has-component-p project-data )
            ( let ( ( component ( get-component project-data ) )
                    ( head ( nth 0 project-data ) )
                    ( tail ( nthcdr 3  project-data ) ) )
              ( list
                head
                ( publish publication-instance component )
                ( publish publication-instance tail ) ) ) )
          ( _
            ( progn
              ( import-data publication-instance project-data )
              ( export-project-alist publication-instance ) ) ) ) ) )
#+END_SRC

* EOF