neruda 0.0.10 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/pablo +105 -246
- data/lib/neruda/config.rb +94 -0
- data/lib/neruda/config/lisp_config.rb +201 -0
- data/lib/neruda/config/org-config.el +17 -0
- data/lib/neruda/config/ox-neruda.el +88 -0
- data/lib/neruda/index.rb +108 -0
- data/lib/neruda/index/atom_generator.rb +86 -0
- data/lib/neruda/index/org_generator.rb +92 -0
- data/lib/neruda/org_file.rb +266 -0
- data/lib/neruda/org_file/class_methods.rb +55 -0
- data/lib/neruda/org_file/extracter.rb +61 -0
- data/lib/neruda/org_file/htmlizer.rb +78 -0
- data/lib/neruda/preview.rb +53 -0
- data/lib/neruda/templater.rb +111 -0
- data/lib/neruda/utils.rb +130 -0
- data/lib/neruda/version.rb +5 -0
- data/lib/tasks/org.rake +69 -0
- data/lib/tasks/site.rake +84 -0
- data/lib/tasks/sync.rake +30 -0
- data/locales/en.yml +18 -0
- data/locales/fr.yml +18 -0
- data/themes/default/css/style.css +216 -0
- data/themes/default/fonts/Yanone_Kaffeesatz_400.woff +0 -0
- data/themes/default/fonts/Yanone_Kaffeesatz_400.woff2 +0 -0
- metadata +145 -39
- data/README.md +0 -98
- data/docs/Rakefile.example +0 -4
- data/docs/config.yml.example +0 -17
- data/lib/assets/chapter.slim +0 -14
- data/lib/assets/index.slim +0 -13
- data/lib/assets/layout.slim +0 -17
- data/lib/assets/style.css +0 -199
- data/lib/neruda.rb +0 -112
- data/lib/neruda/chapter.rb +0 -26
- data/lib/neruda/url.rb +0 -14
- data/lib/tasks/book.rake +0 -60
- data/lib/tasks/capistrano/chapters.rake +0 -60
- data/lib/tasks/capistrano/sinatra.rake +0 -18
- data/lib/tasks/chapters.rake +0 -132
- data/lib/tasks/sinatra.rake +0 -36
@@ -0,0 +1,201 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
module Neruda
|
6
|
+
# This module contains utilitary methods to ease ~org-config.el~
|
7
|
+
# file generation
|
8
|
+
module LispConfig
|
9
|
+
# Fetch and return the last published version of org mode.
|
10
|
+
#
|
11
|
+
# @return [String] the new x.x.x version string of org mode
|
12
|
+
def org_last_version
|
13
|
+
return @org_version if @org_version
|
14
|
+
index = open('https://orgmode.org/index.html', 'r').read
|
15
|
+
last_ver = index.match(/https:\/\/orgmode\.org\/org-([0-9.]+)\.tar\.gz/)
|
16
|
+
# :nocov:
|
17
|
+
if last_ver.nil?
|
18
|
+
warn 'Org last version not found'
|
19
|
+
return nil
|
20
|
+
end
|
21
|
+
# :nocov:
|
22
|
+
@org_version = last_ver[1]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Generate emacs lisp configuration file for org mode and write it.
|
26
|
+
#
|
27
|
+
# This method saves the generated configuration in the file
|
28
|
+
# ~org-config.el~ at the root of your project, overwriting it if it
|
29
|
+
# existed already.
|
30
|
+
#
|
31
|
+
# @return [Integer] the length written (as returned by the
|
32
|
+
# underlying ~IO.write~ method call)
|
33
|
+
def write_org_lisp_config
|
34
|
+
projects = org_generate_projects
|
35
|
+
workdir = Dir.pwd
|
36
|
+
content = IO.read(File.expand_path('./org-config.el', __dir__))
|
37
|
+
.gsub('__WORK_DIR__', workdir)
|
38
|
+
.gsub('__NERUDA_DIR__', __dir__)
|
39
|
+
.gsub('__ORG_VER__', org_last_version)
|
40
|
+
.gsub('__ALL_PROJECTS__', all_projects(projects).strip)
|
41
|
+
.gsub('__THEME_CONFIG__', org_theme_config.strip)
|
42
|
+
.gsub('__ALL_PROJECTS_NAMES__', project_names(projects))
|
43
|
+
.gsub('__LONG_DATE_FMT__', r18n_full_datetime_format)
|
44
|
+
.gsub('__AUTHOR_EMAIL__', settings['author_email'] || '')
|
45
|
+
.gsub('__AUTHOR_NAME__', settings['author'])
|
46
|
+
IO.write("#{workdir}/org-config.el", content)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Generate emacs directory variables file.
|
50
|
+
#
|
51
|
+
# This method generate the file ~.dir-locals.el~, which is
|
52
|
+
# responsible to load neruda org mode settings when visiting an
|
53
|
+
# org file of this neruda instance.
|
54
|
+
#
|
55
|
+
# @return [Integer] the length written (as returned by the
|
56
|
+
# underlying ~IO.write~ method call)
|
57
|
+
def write_dir_locals
|
58
|
+
workdir = Dir.pwd
|
59
|
+
IO.write(
|
60
|
+
"#{workdir}/.dir-locals.el",
|
61
|
+
"((org-mode . ((eval . (load-file \"#{workdir}/org-config.el\")))))"
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def r18n_full_datetime_format
|
68
|
+
locale = R18n.get.locale
|
69
|
+
date_fmt = R18n.t.neruda.index.full_date_format(
|
70
|
+
date: locale.full_format
|
71
|
+
)
|
72
|
+
date_fmt = locale.year_format.sub('_', date_fmt)
|
73
|
+
time_fmt = locale.time_format.delete('_').strip
|
74
|
+
R18n.t.neruda.index.full_date_with_time_format(
|
75
|
+
date: date_fmt, time: time_fmt
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def project_names(projects)
|
80
|
+
projects.keys.map { |p| ["\"#{p}\"", "\"#{p}-assets\""] }
|
81
|
+
.flatten.join(' ')
|
82
|
+
end
|
83
|
+
|
84
|
+
def all_projects(projects)
|
85
|
+
projects.values.join("\n").strip
|
86
|
+
.gsub(/\n\n/, "\n")
|
87
|
+
.gsub(/\n/, "\n ")
|
88
|
+
end
|
89
|
+
|
90
|
+
def org_project(project_name, opts)
|
91
|
+
orgtpl = opts['org_headers']
|
92
|
+
base_directory = File.expand_path(opts['path'])
|
93
|
+
publish_in = [Dir.pwd, settings['public_folder']]
|
94
|
+
publish_in << project_name unless project_name == 'org'
|
95
|
+
publish_in = publish_in.join('/')
|
96
|
+
recline = [opts['recursive'] || 't']
|
97
|
+
default_ex_ptrn = settings['exclude_pattern']
|
98
|
+
if opts['exclude']
|
99
|
+
recline << ":exclude \"#{opts['exclude']}\""
|
100
|
+
elsif project_name == 'org' && default_ex_ptrn
|
101
|
+
recline << ":exclude \"#{default_ex_ptrn}\""
|
102
|
+
end
|
103
|
+
<<~ORGPROJECT
|
104
|
+
("#{project_name}"
|
105
|
+
:base-directory "#{base_directory}"
|
106
|
+
:base-extension "org"
|
107
|
+
:recursive #{recline.join("\n ")}
|
108
|
+
:publishing-directory "#{publish_in}"
|
109
|
+
:publishing-function org-html-publish-to-html
|
110
|
+
:section-numbers nil
|
111
|
+
:with-toc nil
|
112
|
+
#{orgtpl})
|
113
|
+
("#{project_name}-assets"
|
114
|
+
:base-directory "#{base_directory}"
|
115
|
+
:base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|svg\\\\\\|pdf"
|
116
|
+
:recursive #{recline[0]}
|
117
|
+
:publishing-directory "#{publish_in}"
|
118
|
+
:publishing-function org-publish-attachment)
|
119
|
+
ORGPROJECT
|
120
|
+
end
|
121
|
+
|
122
|
+
def org_default_theme_options
|
123
|
+
postamble = <<~POSTAMBLE
|
124
|
+
<p><span class="author">#{R18n.t.neruda.org.postamble.written_by}</span>
|
125
|
+
#{R18n.t.neruda.org.postamble.with_emacs}</p>
|
126
|
+
<p class="date">#{R18n.t.neruda.org.postamble.last_modification}</p>
|
127
|
+
<p class="validation">%v</p>
|
128
|
+
POSTAMBLE
|
129
|
+
{ 'html-head' => build_html_head.strip,
|
130
|
+
'html-postamble' => postamble.strip,
|
131
|
+
'html-head-include-default-style' => 't',
|
132
|
+
'html-head-include-scripts' => 'nil' }
|
133
|
+
end
|
134
|
+
|
135
|
+
def org_templates
|
136
|
+
orgtplopts = org_default_theme_options.merge
|
137
|
+
orgtplopts.merge!(settings['org-html'] || {})
|
138
|
+
orgtpl = []
|
139
|
+
orgtplopts.each do |k, v|
|
140
|
+
val = v.strip.gsub(/"/, '\"')
|
141
|
+
if ['t', 'nil', '1'].include? val
|
142
|
+
orgtpl << ":#{k} #{val}"
|
143
|
+
else
|
144
|
+
orgtpl << ":#{k} \"#{val}\""
|
145
|
+
end
|
146
|
+
end
|
147
|
+
orgtpl.join("\n ")
|
148
|
+
end
|
149
|
+
|
150
|
+
def org_generate_projects
|
151
|
+
orgtpl = org_templates
|
152
|
+
projects = { 'org' => org_project('org', 'org_headers' => orgtpl,
|
153
|
+
'path' => './src') }
|
154
|
+
settings['external_sources']&.each do |s|
|
155
|
+
opts = { 'org_headers' => orgtpl }
|
156
|
+
if s.is_a? String
|
157
|
+
opts['path'] = s
|
158
|
+
elsif s.is_a? Hash
|
159
|
+
opts.merge! s
|
160
|
+
end
|
161
|
+
next unless opts.has_key?('path')
|
162
|
+
pname = File.basename(opts['path']).sub(/^\./, '')
|
163
|
+
projects[pname] = org_project(pname, opts)
|
164
|
+
end
|
165
|
+
projects
|
166
|
+
end
|
167
|
+
|
168
|
+
def org_theme_config
|
169
|
+
curtheme = settings['theme'] || 'default'
|
170
|
+
workdir = Dir.pwd
|
171
|
+
if curtheme == 'default'
|
172
|
+
sourcedir = File.expand_path('../../../', __dir__)
|
173
|
+
else
|
174
|
+
sourcedir = workdir
|
175
|
+
end
|
176
|
+
<<~THEMECONFIG
|
177
|
+
("theme"
|
178
|
+
:base-directory "#{sourcedir}/themes/#{curtheme}"
|
179
|
+
:base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|js\\\\\\|css\\\\\\|otf\\\\\\|ttf\\\\\\|woff2?"
|
180
|
+
:recursive t
|
181
|
+
:publishing-directory "#{workdir}/#{settings['public_folder']}/assets"
|
182
|
+
:publishing-function org-publish-attachment)
|
183
|
+
THEMECONFIG
|
184
|
+
end
|
185
|
+
|
186
|
+
def build_html_head
|
187
|
+
stylesheet = <<~CSS
|
188
|
+
<link rel="stylesheet" type="text/css" media="screen"
|
189
|
+
href="#{settings['domain']}/assets/css/style.css">
|
190
|
+
<link rel="stylesheet" type="text/css" media="screen"
|
191
|
+
href="#{settings['domain']}/assets/css/htmlize.css">
|
192
|
+
CSS
|
193
|
+
return stylesheet if settings['blog_path'].nil?
|
194
|
+
<<~ATOM
|
195
|
+
#{stylesheet.strip}
|
196
|
+
<link rel="alternate" type="application/atom+xml" title="Atom 1.0"
|
197
|
+
href="#{settings['domain']}/feeds/index.xml" />
|
198
|
+
ATOM
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
;; Add custom org mode to load path
|
2
|
+
(add-to-list 'load-path (expand-file-name "org-__ORG_VER__/lisp" "__WORK_DIR__"))
|
3
|
+
;; Load modern version of htmlize.el
|
4
|
+
(load-file (expand-file-name "htmlize.el" "__WORK_DIR__"))
|
5
|
+
|
6
|
+
;; Current project options
|
7
|
+
(setq neruda/current-work-dir "__WORK_DIR__"
|
8
|
+
user-mail-address "__AUTHOR_EMAIL__"
|
9
|
+
user-full-name "__AUTHOR_NAME__"
|
10
|
+
org-html-metadata-timestamp-format "__LONG_DATE_FMT__"
|
11
|
+
org-publish-project-alist
|
12
|
+
`(__ALL_PROJECTS__
|
13
|
+
__THEME_CONFIG__
|
14
|
+
("website" :components (__ALL_PROJECTS_NAMES__ "theme"))))
|
15
|
+
|
16
|
+
;; Load neruda lib
|
17
|
+
(load-file (expand-file-name "ox-neruda.el" "__NERUDA_DIR__"))
|
@@ -0,0 +1,88 @@
|
|
1
|
+
;;; ox-neruda.el --- Neruda Gem specific helpers for Org Export Engine -*- lexical-binding: t; -*-
|
2
|
+
|
3
|
+
;; Copyright (C) 2011-2019 Free Software Foundation, Inc.
|
4
|
+
|
5
|
+
;; Author: Étienne Deparis <etienne at depar dot is>
|
6
|
+
;; Keywords: org, export
|
7
|
+
|
8
|
+
;; This file is not part of GNU Emacs.
|
9
|
+
|
10
|
+
;; GNU Emacs is free software: you can redistribute it and/or modify
|
11
|
+
;; it under the terms of the GNU General Public License as published by
|
12
|
+
;; the Free Software Foundation, either version 3 of the License, or
|
13
|
+
;; (at your option) any later version.
|
14
|
+
|
15
|
+
;; GNU Emacs is distributed in the hope that it will be useful,
|
16
|
+
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
;; GNU General Public License for more details.
|
19
|
+
|
20
|
+
;; You should have received a copy of the GNU General Public License
|
21
|
+
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
22
|
+
|
23
|
+
;;; Commentary:
|
24
|
+
|
25
|
+
;; This library implements specific helpers function, needed by the Ruby
|
26
|
+
;; Gem Neruda, which offers an easy way to publish a static website
|
27
|
+
;; using Org files as sources.
|
28
|
+
|
29
|
+
;;; Code:
|
30
|
+
|
31
|
+
(require 'org)
|
32
|
+
(require 'ox-html)
|
33
|
+
|
34
|
+
;;; Function Declarations
|
35
|
+
|
36
|
+
(defvar neruda/current-work-dir nil
|
37
|
+
"Location of the current neruda website base directory.")
|
38
|
+
|
39
|
+
(defvar neruda/org-temp-dir nil
|
40
|
+
"Location of the local org-mode temporary directory (where to place
|
41
|
+
org timestamps and id locations).")
|
42
|
+
|
43
|
+
(defun neruda/org-i18n-export (link description format)
|
44
|
+
"Export a i18n link"
|
45
|
+
(let* ((splitted-link (split-string link "|"))
|
46
|
+
(path (car splitted-link))
|
47
|
+
(desc (or description path))
|
48
|
+
(lang (cadr splitted-link)))
|
49
|
+
(pcase format
|
50
|
+
(`html (if lang
|
51
|
+
(format "<a href=\"%s\" hreflang=\"%s\">%s</a>"
|
52
|
+
path lang desc)
|
53
|
+
(format "<a href=\"%s\">%s</a>" path desc)))
|
54
|
+
(`latex (format "\\href{%s}{%s}" path desc))
|
55
|
+
(`ascii (format "%s (%s)" desc path))
|
56
|
+
(_ path))))
|
57
|
+
|
58
|
+
(defun neruda/org-i18n-follow (link)
|
59
|
+
"Visit a i18n link"
|
60
|
+
(browse-url (car (split-string link "|"))))
|
61
|
+
|
62
|
+
(org-link-set-parameters "i18n"
|
63
|
+
:export #'neruda/org-i18n-export
|
64
|
+
:follow #'neruda/org-i18n-follow)
|
65
|
+
|
66
|
+
|
67
|
+
;;; Set configuration options
|
68
|
+
|
69
|
+
(setq neruda/org-temp-dir (expand-file-name "tmp" neruda/current-work-dir)
|
70
|
+
org-publish-timestamp-directory (expand-file-name "timestamps/" neruda/org-temp-dir)
|
71
|
+
org-id-locations-file (expand-file-name "id-locations.el" neruda/org-temp-dir)
|
72
|
+
make-backup-files nil
|
73
|
+
enable-local-variables :all
|
74
|
+
org-confirm-babel-evaluate nil
|
75
|
+
org-html-doctype "html5"
|
76
|
+
org-html-html5-fancy t
|
77
|
+
org-html-htmlize-output-type 'css
|
78
|
+
org-html-text-markup-alist '((bold . "<strong>%s</strong>")
|
79
|
+
(code . "<code>%s</code>")
|
80
|
+
(italic . "<em>%s</em>")
|
81
|
+
(strike-through . "<del>%s</del>")
|
82
|
+
(underline . "<span class=\"underline\">%s</span>")
|
83
|
+
(verbatim . "<code>%s</code>")))
|
84
|
+
|
85
|
+
|
86
|
+
(provide 'ox-neruda)
|
87
|
+
|
88
|
+
;;; ox-neruda.el ends here
|
data/lib/neruda/index.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'neruda/config'
|
6
|
+
require 'neruda/org_file'
|
7
|
+
require 'neruda/index/atom_generator'
|
8
|
+
require 'neruda/index/org_generator'
|
9
|
+
|
10
|
+
module Neruda
|
11
|
+
# Generates website indexes and atom feeds for all the org documents
|
12
|
+
# keywords.
|
13
|
+
class Index
|
14
|
+
attr_reader :date
|
15
|
+
|
16
|
+
include Neruda::IndexAtomGenerator
|
17
|
+
include Neruda::IndexOrgGenerator
|
18
|
+
|
19
|
+
def initialize(file_list = nil)
|
20
|
+
@blog_path = Neruda::Config.settings['blog_path']
|
21
|
+
@pubdir = Neruda::Config.settings['public_folder']
|
22
|
+
@index = { 'index' => [] }
|
23
|
+
@tags_names = {}
|
24
|
+
@date = DateTime.now
|
25
|
+
if @blog_path.nil?
|
26
|
+
@sources = []
|
27
|
+
else
|
28
|
+
@sources = sources_list(file_list)
|
29
|
+
filter_and_prefix_sources!
|
30
|
+
@sources.each { |f| add_to_indexes(Neruda::OrgFile.new(f)) }
|
31
|
+
sort!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def entries
|
36
|
+
@index.keys
|
37
|
+
end
|
38
|
+
|
39
|
+
def write_all(verbose = true)
|
40
|
+
@index.keys.each do |k|
|
41
|
+
write_org(k)
|
42
|
+
warn "Generated index file for #{k}" if verbose
|
43
|
+
write_atom(k)
|
44
|
+
warn "Generated atom feed for #{k}" if verbose
|
45
|
+
end
|
46
|
+
write_org_lists
|
47
|
+
warn 'Generated all tags index' if verbose
|
48
|
+
end
|
49
|
+
|
50
|
+
def sort_by(kind)
|
51
|
+
if [:name, :weight].include?(kind)
|
52
|
+
return sort_tags_by_name_and_weight["by_#{kind}".to_sym]
|
53
|
+
end
|
54
|
+
raise ArgumentError, "#{kind} not in [:name, :weight]"
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def sources_list(file_list)
|
60
|
+
return file_list unless file_list.nil?
|
61
|
+
Dir.glob(Neruda::Config.settings['blog_pattern'],
|
62
|
+
base: "src/#{@blog_path}")
|
63
|
+
end
|
64
|
+
|
65
|
+
def filter_and_prefix_sources!
|
66
|
+
exclude = Neruda::Config.settings['exclude_pattern']
|
67
|
+
sources = []
|
68
|
+
@sources.each do |f|
|
69
|
+
next if f == 'index.org'
|
70
|
+
if File.exist?(f)
|
71
|
+
file_path = f
|
72
|
+
else
|
73
|
+
file_path = "src/#{@blog_path}/#{f}"
|
74
|
+
next unless File.exist?(file_path)
|
75
|
+
end
|
76
|
+
next if exclude && file_path.match(exclude)
|
77
|
+
sources << file_path
|
78
|
+
end
|
79
|
+
@sources = sources
|
80
|
+
end
|
81
|
+
|
82
|
+
def add_to_indexes(article)
|
83
|
+
@index['index'] << article
|
84
|
+
article.keywords.each do |k|
|
85
|
+
slug = Neruda::OrgFile.slug k
|
86
|
+
@tags_names[slug] = k # Overwrite is permitted
|
87
|
+
@index[slug] = [] unless @index.has_key?(slug)
|
88
|
+
@index[slug] << article
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def sort!
|
93
|
+
@index.each do |k, i|
|
94
|
+
@index[k] = i.sort { |a, b| b.timekey <=> a.timekey }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def sort_tags_by_name_and_weight
|
99
|
+
tags_sorted = {}
|
100
|
+
all_keys = @index.keys.reject { |k| k == 'index' }
|
101
|
+
tags_sorted[:by_name] = all_keys.sort
|
102
|
+
tags_sorted[:by_weight] = all_keys.sort do |a, b|
|
103
|
+
@index[b].length <=> @index[a].length
|
104
|
+
end
|
105
|
+
tags_sorted
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
require 'neruda/config'
|
5
|
+
|
6
|
+
module Neruda
|
7
|
+
# Embeds Atom feeds sepecific methods
|
8
|
+
module IndexAtomGenerator
|
9
|
+
def to_atom(index_name = 'index')
|
10
|
+
content = [atom_header(index_name)]
|
11
|
+
@index[index_name][0...10].each do |article|
|
12
|
+
content << atom_entry(article)
|
13
|
+
end
|
14
|
+
content.join("\n") + '</feed>'
|
15
|
+
end
|
16
|
+
|
17
|
+
def write_atom(index_name)
|
18
|
+
return 0 if @blog_path.nil?
|
19
|
+
slug = Neruda::OrgFile.slug index_name
|
20
|
+
FileUtils.mkdir_p "#{@pubdir}/feeds"
|
21
|
+
atomdest = "#{@pubdir}/feeds/#{slug}.xml"
|
22
|
+
IO.write(atomdest, to_atom(index_name))
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Render the Atom feed header.
|
28
|
+
#
|
29
|
+
# @param title [String] the title of the current atom feed
|
30
|
+
# @return [String] the Atom header as a String
|
31
|
+
def atom_header(title)
|
32
|
+
domain = Neruda::Config.settings['domain']
|
33
|
+
upddate = @date.rfc3339
|
34
|
+
slug = Neruda::OrgFile.slug(title)
|
35
|
+
tagurl = "#{domain}/tags/#{slug}.html"
|
36
|
+
if title == 'index'
|
37
|
+
if Neruda::Config.settings['title']
|
38
|
+
title = Neruda::Config.settings['title']
|
39
|
+
end
|
40
|
+
tagurl = "#{domain}/#{@blog_path}"
|
41
|
+
elsif @tags_names.has_key?(title)
|
42
|
+
title = @tags_names[title]
|
43
|
+
end
|
44
|
+
title_esc = CGI.escapeHTML(title)
|
45
|
+
<<~ENDATOM
|
46
|
+
<?xml version="1.0" encoding="utf-8"?>
|
47
|
+
<feed xmlns="http://www.w3.org/2005/Atom"
|
48
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
49
|
+
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
|
50
|
+
xml:lang="#{Neruda::Config.settings['lang']}">
|
51
|
+
|
52
|
+
<title>#{title_esc}</title>
|
53
|
+
<link href="#{domain}/feeds/#{slug}.xml" rel="self" type="application/atom+xml"/>
|
54
|
+
<link href="#{tagurl}" rel="alternate" type="text/html" title="#{title_esc}"/>
|
55
|
+
<updated>#{upddate}</updated>
|
56
|
+
<author><name>#{Neruda::Config.settings['author'] || ''}</name></author>
|
57
|
+
<id>urn:md5:#{Digest::MD5.hexdigest(domain)}</id>
|
58
|
+
<generator uri="https://fossil.deparis.io/neruda">Neruda</generator>
|
59
|
+
ENDATOM
|
60
|
+
end
|
61
|
+
|
62
|
+
# Render an Atom feed entry.
|
63
|
+
#
|
64
|
+
# @param article [Neruda::OrgFile] the related org document for this
|
65
|
+
# entry
|
66
|
+
# @return [String] the Atom entry as a String
|
67
|
+
def atom_entry(article)
|
68
|
+
keywords = article.keywords.map do |k|
|
69
|
+
"<dc:subject>#{CGI.escapeHTML(k)}</dc:subject>"
|
70
|
+
end.join
|
71
|
+
keywords += "\n " if keywords != ''
|
72
|
+
title_esc = CGI.escapeHTML(article.title)
|
73
|
+
<<~ENDENTRY
|
74
|
+
<entry>
|
75
|
+
<title>#{title_esc}</title>
|
76
|
+
<link href="#{article.url}" rel="alternate" type="text/html"
|
77
|
+
title="#{title_esc}"/>
|
78
|
+
<id>urn:md5:#{Digest::MD5.hexdigest(article.timekey)}</id>
|
79
|
+
<published>#{article.datestring(:rfc3339)}</published>
|
80
|
+
<author><name>#{CGI.escapeHTML(article.author)}</name></author>
|
81
|
+
#{keywords}<content type="html">#{CGI.escapeHTML(article.excerpt)}</content>
|
82
|
+
</entry>
|
83
|
+
ENDENTRY
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|