aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorGravatar Étienne Deparis 2020-10-10 14:31:55 +0200
committerGravatar Étienne Deparis 2020-10-10 14:31:55 +0200
commit8574acc5f2038e2ce4918e3e752a2173eea80277 (patch)
treef915c3df268f4ec3cfd01b62b743a7891cd61126
parenta17d52aeb7b2c87cfc09f7d271f51c53818b906c (diff)
parentf7b7fedc5e7563b83ba292a6df3f454b840c7336 (diff)
downloadfronde-0.2.0.tar.gz
fronde-0.2.0.tar.xz
fronde-0.2.0.zip
chore: Merge branch 'v0.2.0-dev' into masterv0.2.0
-rw-r--r--.rspec1
-rw-r--r--.rubocop.yml4
-rw-r--r--CONFIG.org75
-rw-r--r--README.org17
-rw-r--r--Rakefile14
-rwxr-xr-xbin/pablo29
-rw-r--r--lib/neruda/config.rb71
-rw-r--r--lib/neruda/config/lisp_config.rb204
-rw-r--r--lib/neruda/config/org-config.el9
-rw-r--r--lib/neruda/config/ox-neruda.el30
-rw-r--r--lib/neruda/emacs.rb44
-rw-r--r--lib/neruda/index.rb79
-rw-r--r--lib/neruda/index/atom_generator.rb30
-rw-r--r--lib/neruda/index/org_generator.rb105
-rw-r--r--lib/neruda/org_file.rb59
-rw-r--r--lib/neruda/org_file/class_methods.rb55
-rw-r--r--lib/neruda/org_file/extracter.rb13
-rw-r--r--lib/neruda/org_file/htmlizer.rb35
-rw-r--r--lib/neruda/preview.rb12
-rw-r--r--lib/neruda/templater.rb5
-rw-r--r--lib/neruda/utils.rb48
-rw-r--r--lib/neruda/version.rb3
-rw-r--r--lib/tasks/org.rake45
-rw-r--r--lib/tasks/site.rake34
-rw-r--r--lib/tasks/tags.rake8
-rw-r--r--locales/en.yml5
-rw-r--r--locales/fr.yml5
-rw-r--r--neruda.gemspec13
-rw-r--r--spec/config_spec.rb286
-rw-r--r--spec/data/content.org1
-rw-r--r--spec/data/index_proof.html28
-rw-r--r--spec/data/org-config-blog-proof.el37
-rw-r--r--spec/data/org-config-proof.el37
-rw-r--r--spec/data/test2.org1
-rw-r--r--spec/index_spec.rb629
-rw-r--r--spec/org_file_spec.rb180
-rw-r--r--spec/rake_org_spec.rb27
-rw-r--r--spec/rake_site_spec.rb223
-rw-r--r--spec/requirements.rb51
-rw-r--r--spec/templater_spec.rb100
-rw-r--r--spec/utils_spec.rb70
-rw-r--r--themes/default/css/style.css293
-rw-r--r--themes/default/fonts/Yanone_Kaffeesatz_400.woffbin22256 -> 0 bytes
-rw-r--r--themes/default/fonts/Yanone_Kaffeesatz_400.woff2bin18320 -> 0 bytes
-rw-r--r--themes/default/img/Firma_Pablo_Neruda.svg (renamed from themes/default/assets/Firma_Pablo_Neruda.svg)0
-rw-r--r--themes/default/img/bottom.pngbin0 -> 243 bytes
-rw-r--r--themes/default/img/content.pngbin0 -> 279 bytes
-rw-r--r--themes/default/img/tic.pngbin0 -> 310 bytes
-rw-r--r--themes/default/img/top.pngbin0 -> 300 bytes
49 files changed, 2133 insertions, 882 deletions
diff --git a/.rspec b/.rspec
index 734ab84..73d7afd 100644
--- a/.rspec
+++ b/.rspec
@@ -1 +1,2 @@
+-I ./lib
-r ./spec/requirements.rb
diff --git a/.rubocop.yml b/.rubocop.yml
index 016e832..c603583 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,5 +1,6 @@
---
AllCops:
+ NewCops: enable
TargetRubyVersion: 2.6
Layout:
@@ -31,6 +32,9 @@ Metrics/MethodLength:
Metrics/ModuleLength:
Max: 120
+ Exclude:
+ - lib/neruda/config/lisp_config.rb
+ - lib/neruda/utils.rb
Metrics/PerceivedComplexity:
Max: 10
diff --git a/CONFIG.org b/CONFIG.org
index 72d1c47..32f37cb 100644
--- a/CONFIG.org
+++ b/CONFIG.org
@@ -2,6 +2,7 @@
#+author: Étienne Deparis
#+lang: en
#+description: Glossary of all possible configuration options for Neruda
+#+options: ^:{}
This file explain all possible configuration options for Neruda, which
may be put in file named ~config.yml~ at the root of your static website
@@ -12,41 +13,12 @@ be put in any order in the ~config.yml~ file.
The ~author~ option stores the default author name of your org
files. This value is used when you create a new file. *It is not used by
-the regular org mode publishing process*. You must be sure that your org
+the regular Org mode publishing process*. You must be sure that your org
files contains an ~#+author:~ metadata field before publishing them.
This value is used in the generation of the blog index page and the main
atom feed.
-* ~blog_path~
-:PROPERTIES:
-:CUSTOM_ID: sec-blog_path
-:END:
-
-The ~blog_path~ options store the folder name *inside* the ~src~ folder,
-which will contains org document to be specifically indexed to produce a
-blog-like website.
-
-Neruda will introspect the org documents inside this folder in order to
-find keywords (declared with the ~#+keywords:~ header) and produce as
-many new time-sorted indexes for these keywords, plus a specific index
-page at the root of this folder.
-
-The default value is ~blog~.
-
-* ~blog_pattern~
-:PROPERTIES:
-:CUSTOM_ID: sec-blog_pattern
-:END:
-
-The ~blog_pattern~ option stores a [[https://en.wikipedia.org/wiki/Glob_(programming)][glob pattern]] to help Neruda to find
-the documents you want to index under the [[#sec-blog_path][~blog_path~]] folder. It may be
-handy to only selecte precisely some files. The default value is
-~**/*.org~, which means absolutely all org documents (under the
-~blog_path~).
-
-See also the [[#sec-exclude_pattern][~exclude_pattern~ section]].
-
* ~domain~
The domain name pointing to where your static website is expected to be
@@ -65,23 +37,6 @@ value. Thus, ~https://example.com/example~ or
~https://example.com/example/~ or ~https://example.com/complex/example/~
are not.
-* ~exclude_pattern~
-:PROPERTIES:
-:CUSTOM_ID: sec-exclude_pattern
-:END:
-
-The ~exclude_pattern~ option stores a [[https://en.wikipedia.org/wiki/Regular_expression][regular expression]] to help Neruda
-to find precisely which files you want to index under the [[#sec-blog_path][~blog_path~]]
-folder. It may be handy to remove some unrelated data files, for example
-with a value like ~comments\.org$~. This filter is executed *after*
-files have been selected by the [[#sec-blog_pattern][~blog_pattern~]] and *matching* files are
-excluded.
-
-There is no default value (thus nothing match and thus all org files
-matched by the ~blog_pattern~ option are indexed).
-
-See also the [[#sec-blog_pattern][~blog_pattern~ section]].
-
* ~lang~
The main locale your website will be written in. Its value must comply
@@ -108,3 +63,29 @@ an ~#+title:~ metadata field before publishing them.
This value is used in the generation of the blog index page and the main
atom feed.
+
+* ~sources~
+
+The ~sources~ option stores an array of all source folders, where your
+org files to be published are. This allow you to gather various
+different places (even at some absolute path in your computer) in your
+website.
+
+Each source listed in that array is an object, which must use the
+following keys:
+
+- path :: [string] path to the folder containing the file to exports
+- name :: [string, optional] key used to generate the Org project name.
+ Defaults to the last dirname of the path value.
+- recursive :: [boolean, optional] wether the path should be exported
+ recursively. Defaults to True
+- exclude :: [string, optional] Regexp of files to not export for this
+ projects. Default to nothing (no files to exclude).
+- target :: [string, optional] Path where to put the exported files,
+ relative to the ~public_folder~ folder. Default to the project name at
+ the root of the ~public_folder~ folder.
+- is_blog :: [boolean, optional] Whether this project should be
+ considered as a blog and thus, serves as source to generate blog
+ index, tags indexes and atom feeds.
+- theme :: [string, optional] Theme name to use for this
+ project. Defaults to “default”.
diff --git a/README.org b/README.org
index d264eed..b556824 100644
--- a/README.org
+++ b/README.org
@@ -3,24 +3,27 @@
#+lang: en
#+keywords: static website generator, ruby, gem, org mode, emacs
#+description: Neruda is a ruby gem, which helps you to manage your
-#+description: static website generated with org mode
+#+description: static website generated with Org mode
* What's for?
#+attr_html: :style width:150px;float:right;margin-top:-4.5em;margin-left:2em;
-[[file:themes/default/assets/Firma_Pablo_Neruda.svg]]
+[[file:themes/default/img/Firma_Pablo_Neruda.svg]]
-Neruda is a static website generator made for [[https://orgmode.org][org files]]. It improves the
-default org mode HTML exporting/publishing routine.
+Neruda is a static website generator made for [[https://orgmode.org][Org files]]. It improves the
+default Org HTML exporting/publishing routine.
* Features
-- Inherits all [[https://orgmode.org][org mode features]] (tables, syntax highlighting,
+- Inherits all [[https://orgmode.org][Org mode features]] (tables, syntax highlighting,
code blocks evaluation, multiple languages support…)
- Does not require any emacs lisp knowledge
-- Does not require any server-side code, nor databases
+- Does not require any server-side code, nor databases, only a simple
+ http server like apache, nginx, lighttpd, hiawatha…
- Allows fine customization of generated html files
-- Allows easy switch between various themes
+- Allows multiple sources for your Org file and let you organize them as
+ you wish in the destination folder
+- Can use different theme for different sources
- Supports tags and [[https://en.wikipedia.org/wiki/Atom_(Web_standard)][ATOM feeds]]
* How to install it
diff --git a/Rakefile b/Rakefile
index f60fc47..c9ff820 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,10 +1,14 @@
# frozen_string_literal: true
-require 'yard'
+begin
+ require 'yard'
+ require 'rspec/core/rake_task'
-$LOAD_PATH.unshift('./lib')
-import './lib/tasks/org.rake'
+ RSpec::Core::RakeTask.new(:spec)
-YARD::Rake::YardocTask.new do |t|
- t.options = ['-m', 'org', '--no-progress']
+ YARD::Rake::YardocTask.new do |t|
+ t.options = ['-m', 'org', '--no-progress']
+ end
+rescue LoadError
+ warn 'You are not using the development bundle.'
end
diff --git a/bin/pablo b/bin/pablo
index 1a48d15..e6d915e 100755
--- a/bin/pablo
+++ b/bin/pablo
@@ -7,8 +7,8 @@ require 'r18n-core'
require 'neruda/utils'
require 'neruda/version'
-R18n.set(Neruda::Config.settings['lang'],
- File.expand_path('../locales', __dir__))
+R18n.default_places = File.expand_path('../locales', __dir__)
+R18n.set Neruda::Config.settings['lang']
# Pablo commands
module PabloCommands
@@ -20,8 +20,8 @@ module PabloCommands
Neruda::Config.save(Neruda::Config.settings.merge(cnf))
@rake.options.build_all = true
@rake.invoke_task('org:install')
- o = Neruda::OrgFile.new('src/index.org', @options)
- o.write unless File.exist? 'src/index.org'
+ return if File.exist? 'src/index.org'
+ Neruda::OrgFile.new('src/index.org', @options).write
end
alias_method :pablo_config, :pablo_init
@@ -37,12 +37,13 @@ module PabloCommands
def pablo_preview
Thread.new do
sleep 1
- port = Neruda::Config.settings['server_port'] || 5000
+ port = Neruda::Config.settings.dig('preview', 'server_port') || 5000
uri = "http://127.0.0.1:#{port}/"
current_os = Neruda::Utils.current_os
- if current_os == 'windows'
+ case current_os
+ when 'windows'
system 'start', uri
- elsif current_os == 'apple'
+ when 'apple'
system 'open', uri
else
system 'gio', 'open', uri
@@ -66,14 +67,14 @@ module PabloCommands
@rake.invoke_task('sync:push')
end
- def pablo_help(command = 'basic', error = false)
+ def pablo_help(command = 'basic', error: false)
warn R18n.t.pablo.error.no_command if error
cmd = Neruda::Utils.resolve_possible_alias(command)
cmd_opt = Neruda::Utils::PABLO_COMMANDS[cmd]
label = cmd_opt[:label] || command
- warn R18n.t.pablo.usage(label) + "\n\n"
+ warn format("%<label>s\n\n", label: R18n.t.pablo.usage(label))
if R18n.t.pablo.commands[cmd].translated?
- warn R18n.t.pablo.commands[cmd] + "\n\n"
+ warn format("%<label>s\n\n", label: R18n.t.pablo.commands[cmd])
end
warn help_command_body(cmd).join("\n")
exit 1 if error
@@ -130,8 +131,8 @@ class Pablo
require 'r18n-core'
neruda_spec = Gem::Specification.find_by_name 'neruda'
- R18n.set(Neruda::Config.settings['lang'] || 'en',
- "\#{neruda_spec.gem_dir}/locales")
+ R18n.default_places = "\#{neruda_spec.gem_dir}/locales"
+ R18n.set(Neruda::Config.settings['lang'] || 'en')
R18n::Filters.on(:named_variables)
Dir.glob("\#{neruda_spec.gem_dir}/lib/tasks/*.rake").each { |r| import r }
@@ -166,10 +167,10 @@ command = "pablo_#{ARGV[0]}".to_sym
cmd_err = !pablo.respond_to?(command)
if params[:help] || cmd_err
cmd_err = false if params[:help] && !ARGV[0]
- pablo.pablo_help(ARGV[0], cmd_err)
+ pablo.pablo_help(ARGV[0], error: cmd_err)
end
ARGV.shift
-init_cmds = ['pablo_init', 'pablo_config']
+init_cmds = [:pablo_init, :pablo_config]
pablo.pablo_init unless File.exist?('config.yml') || init_cmds.include?(command)
pablo.send command
diff --git a/lib/neruda/config.rb b/lib/neruda/config.rb
index a43a067..28f77bd 100644
--- a/lib/neruda/config.rb
+++ b/lib/neruda/config.rb
@@ -53,8 +53,17 @@ module Neruda
# @param new_config [Hash] the settings to save
# @return [Hash] the new settings after save
def save(new_config)
+ # Do not save obvious default config values. We'll always try to
+ # save author and lang as they default on system variables,
+ # which may be different from a system to another. Thus it may
+ # be confusing if one use neruda on two different computer and
+ # these params always change.
+ new_config.delete_if do |k, v|
+ ['domain', 'public_folder', 'templates', 'theme'].include?(k) \
+ && v == default_settings[k]
+ end
IO.write 'config.yml', new_config.to_yaml
- @config = new_config.freeze
+ load_settings # Reload config, taking default settings into account
end
# Load the given settings as if they comes from the ~config.yml~ file.
@@ -66,32 +75,62 @@ module Neruda
# @param config [Hash] the settings to artificially load
# @return [Hash] the new settings
def load_test(config)
- @config = config
- add_default_settings
+ @sources = nil # Reset sources
+ @config = default_settings.merge config
+ end
+
+ # Return the qualified projects sources list.
+ #
+ # @return [Array] the fully qualified projects sources list
+ def sources
+ return @sources if @sources
+ default_sources = [{ 'path' => 'src', 'target' => '.' }]
+ @sources = (settings['sources'] || default_sources).map do |s|
+ build_source(s)
+ end.compact
end
private
def load_settings
- @config = {}
- conf = 'config.yml'
- @config = YAML.load_file(conf) if File.exist? conf
- add_default_settings
- @config.freeze
+ @sources = nil
+ conf_file = 'config.yml'
+ if File.exist? conf_file
+ @config = default_settings.merge(YAML.load_file(conf_file)).freeze
+ else
+ @config = default_settings
+ end
end
def extract_lang_from_env(default)
(ENV['LANG'] || default).split('_', 2).first
end
- def add_default_settings
- @config['lang'] ||= extract_lang_from_env 'en'
- @config['author'] ||= (ENV['USER'] || '')
- @config['domain'] ||= ''
- @config['public_folder'] ||= 'public_html'
- @config['templates'] ||= []
- return if @config['blog_path'].nil?
- @config['blog_pattern'] ||= '**/*.org'
+ def default_settings
+ return @default_settings if @default_settings
+ @default_settings = {
+ 'author' => (ENV['USER'] || ''),
+ 'domain' => '',
+ 'lang' => extract_lang_from_env('en'),
+ 'public_folder' => 'public_html',
+ 'templates' => [],
+ 'theme' => 'default'
+ }.freeze
+ end
+
+ def build_source(seed)
+ opts = { 'recursive' => true, 'is_blog' => false }
+ case seed
+ when String
+ opts['path'] = seed
+ when Hash
+ opts.merge! seed
+ end
+ return nil unless opts.has_key?('path')
+ opts['path'] = File.expand_path(opts['path'])
+ opts['name'] ||= File.basename(opts['path']).sub(/^\./, '')
+ opts['target'] ||= opts['name']
+ opts
end
end
end
diff --git a/lib/neruda/config/lisp_config.rb b/lib/neruda/config/lisp_config.rb
index f35c5f8..3863173 100644
--- a/lib/neruda/config/lisp_config.rb
+++ b/lib/neruda/config/lisp_config.rb
@@ -1,28 +1,35 @@
# frozen_string_literal: true
require 'open-uri'
+require 'neruda/version'
module Neruda
# This module contains utilitary methods to ease ~org-config.el~
# file generation
module LispConfig
- # Fetch and return the last published version of org mode.
+ # Fetch and return the last published version of Org.
#
- # @return [String] the new x.x.x version string of org mode
+ # @return [String] the new x.x.x version string of Org
def org_last_version
return @org_version if @org_version
- index = open('https://orgmode.org/index.html', 'r').read
+ if File.exist?('tmp/__last_org_version__')
+ @org_version = IO.read('tmp/__last_org_version__')
+ return @org_version
+ end
+ index = URI('https://orgmode.org/index.html').open.read
last_ver = index.match(/https:\/\/orgmode\.org\/org-([0-9.]+)\.tar\.gz/)
# :nocov:
if last_ver.nil?
warn 'Org last version not found'
return nil
end
+ FileUtils.mkdir_p 'tmp'
+ IO.write('tmp/__last_org_version__', last_ver[1])
# :nocov:
@org_version = last_ver[1]
end
- # Generate emacs lisp configuration file for org mode and write it.
+ # Generate emacs lisp configuration file for Org and write it.
#
# This method saves the generated configuration in the file
# ~org-config.el~ at the root of your project, overwriting it if it
@@ -30,15 +37,16 @@ module Neruda
#
# @return [Integer] the length written (as returned by the
# underlying ~IO.write~ method call)
- def write_org_lisp_config
- projects = org_generate_projects
+ def write_org_lisp_config(with_tags: false)
+ projects = org_generate_projects(with_tags: with_tags)
workdir = Dir.pwd
content = IO.read(File.expand_path('./org-config.el', __dir__))
+ .gsub('__VERSION__', Neruda::VERSION)
.gsub('__WORK_DIR__', workdir)
.gsub('__NERUDA_DIR__', __dir__)
.gsub('__ORG_VER__', org_last_version)
- .gsub('__ALL_PROJECTS__', all_projects(projects).strip)
- .gsub('__THEME_CONFIG__', org_theme_config.strip)
+ .gsub('__ALL_PROJECTS__', all_projects(projects))
+ .gsub('__THEME_CONFIG__', org_default_theme_config)
.gsub('__ALL_PROJECTS_NAMES__', project_names(projects))
.gsub('__LONG_DATE_FMT__', r18n_full_datetime_format)
.gsub('__AUTHOR_EMAIL__', settings['author_email'] || '')
@@ -49,8 +57,8 @@ module Neruda
# Generate emacs directory variables file.
#
# This method generate the file ~.dir-locals.el~, which is
- # responsible to load neruda org mode settings when visiting an
- # org file of this neruda instance.
+ # responsible to load neruda Org settings when visiting an Org file
+ # of this neruda instance.
#
# @return [Integer] the length written (as returned by the
# underlying ~IO.write~ method call)
@@ -76,67 +84,120 @@ module Neruda
)
end
+ def ruby_to_lisp_boolean(value)
+ return 't' if value == true
+ 'nil'
+ end
+
def project_names(projects)
- projects.keys.map { |p| ["\"#{p}\"", "\"#{p}-assets\""] }
- .flatten.join(' ')
+ names = projects.keys.map do |p|
+ ["\"#{p}\"", "\"#{p}-assets\""]
+ end.flatten
+ names << "\"theme-#{settings['theme']}\""
+ sources.each do |s|
+ next unless s['theme'] && s['theme'] != settings['theme']
+ theme = "\"theme-#{s['theme']}\""
+ next if names.include? theme
+ names << theme
+ end
+ names.join(' ')
end
def all_projects(projects)
projects.values.join("\n").strip
- .gsub(/\n\n/, "\n")
+ .gsub(/\n\s*\n/, "\n")
.gsub(/\n/, "\n ")
end
- def org_project(project_name, opts)
- orgtpl = opts['org_headers']
- base_directory = File.expand_path(opts['path'])
+ # Return the full path to the publication path of a given project
+ # configuration.
+ #
+ # @param project [Hash] a project configuration (as extracted from
+ # the ~sources~ key)
+ # @return [String] the full path to the target dir of this project
+ def publication_path(project)
publish_in = [Dir.pwd, settings['public_folder']]
- publish_in << project_name unless project_name == 'neruda'
- publish_in = publish_in.join('/')
- recline = [opts['recursive'] || 't']
- default_ex_ptrn = settings['exclude_pattern']
+ publish_in << project['target'] unless project['target'] == '.'
+ publish_in.join('/')
+ end
+
+ def org_project(project_name, opts)
+ publish_in = publication_path(opts)
+ other_lines = [
+ format(':recursive %<value>s',
+ value: ruby_to_lisp_boolean(opts['recursive']))
+ ]
if opts['exclude']
- recline << ":exclude \"#{opts['exclude']}\""
- elsif project_name == 'neruda' && default_ex_ptrn
- recline << ":exclude \"#{default_ex_ptrn}\""
+ other_lines << format(':exclude "%<value>s"',
+ value: opts['exclude'])
end
+ themeconf = org_theme_config(opts['theme']) || ''
<<~ORGPROJECT
("#{project_name}"
- :base-directory "#{base_directory}"
+ :base-directory "#{opts['path']}"
:base-extension "org"
- :recursive #{recline.join("\n ")}
+ #{other_lines.join("\n ")}
:publishing-directory "#{publish_in}"
:publishing-function org-html-publish-to-html
:section-numbers nil
:with-toc nil
- #{orgtpl})
+ #{opts['org_headers']})
("#{project_name}-assets"
- :base-directory "#{base_directory}"
+ :base-directory "#{opts['path']}"
:base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|svg\\\\\\|pdf"
- :recursive #{recline[0]}
+ #{other_lines[0]}
:publishing-directory "#{publish_in}"
:publishing-function org-publish-attachment)
+ #{themeconf}
ORGPROJECT
end
- def org_default_theme_options
- postamble = <<~POSTAMBLE
+ def org_default_postamble
+ <<~POSTAMBLE
<p><span class="author">#{R18n.t.neruda.org.postamble.written_by}</span>
#{R18n.t.neruda.org.postamble.with_emacs}</p>
<p class="date">#{R18n.t.neruda.org.postamble.last_modification}</p>
<p class="validation">%v</p>
POSTAMBLE
- { 'html-head' => build_html_head.strip,
- 'html-postamble' => postamble.strip,
+ end
+
+ def org_default_html_head
+ <<~HTMLHEAD
+ <link rel="stylesheet" type="text/css" media="screen"
+ href="__DOMAIN__/assets/__THEME__/css/style.css">
+ <link rel="stylesheet" type="text/css" media="screen"
+ href="__DOMAIN__/assets/__THEME__/css/htmlize.css">
+ __ATOM_FEED__
+ HTMLHEAD
+ end
+
+ def org_default_html_options
+ { 'html-head' => org_default_html_head,
+ 'html-postamble' => org_default_postamble,
'html-head-include-default-style' => 't',
'html-head-include-scripts' => 'nil' }
end
- def org_templates
- orgtplopts = org_default_theme_options.merge
- orgtplopts.merge!(settings['org-html'] || {})
+ def expand_vars_in_html_head(head, project)
+ curtheme = project['theme'] || settings['theme']
+ # Head may be frozen when coming from settings
+ head = head.gsub('__THEME__', curtheme)
+ .gsub('__DOMAIN__', settings['domain'])
+ return head.gsub('__ATOM_FEED__', '') unless project['is_blog']
+ atomfeed = <<~ATOMFEED
+ <link rel="alternate" type="application/atom+xml" title="Atom 1.0"
+ href="#{settings['domain']}/feeds/index.xml" />
+ ATOMFEED
+ head.gsub('__ATOM_FEED__', atomfeed)
+ end
+
+ def build_project_org_headers(project)
+ orgtplopts = org_default_html_options.merge(
+ settings['org-html'] || {}, project['org-html'] || {}
+ )
orgtpl = []
orgtplopts.each do |k, v|
+ v = expand_vars_in_html_head(v, project) if k == 'html-head'
val = v.strip.gsub(/"/, '\"')
if ['t', 'nil', '1'].include? val
orgtpl << ":#{k} #{val}"
@@ -147,62 +208,47 @@ module Neruda
orgtpl.join("\n ")
end
- def org_external_projects_opts(seed, orgtpl)
- opts = { 'org_headers' => orgtpl }
- if seed.is_a? String
- opts['path'] = seed
- elsif seed.is_a? Hash
- opts.merge! seed
+ def org_generate_projects(with_tags: false)
+ projects = {}
+ projects_sources = sources
+ if with_tags
+ tags_conf = build_source('tags')
+ tags_conf['recursive'] = false
+ projects_sources << tags_conf
end
- opts
- end
-
- def org_generate_projects
- orgtpl = org_templates
- default_project = org_project(
- 'neruda', 'org_headers' => orgtpl, 'path' => './src'
- )
- projects = { 'neruda' => default_project }
- settings['external_sources']&.each do |s|
- opts = org_external_projects_opts(s, orgtpl)
- next unless opts.has_key?('path')
- pname = File.basename(opts['path']).sub(/^\./, '')
- projects[pname] = org_project(pname, opts)
+ projects_sources.each do |opts|
+ opts['org_headers'] = build_project_org_headers(opts)
+ projects[opts['name']] = org_project(opts['name'], opts)
end
projects
end
- def org_theme_config
- curtheme = settings['theme'] || 'default'
+ def org_default_theme_config
+ org_theme_config(settings['theme']).split("\n").map do |line|
+ if line[0] == '('
+ line
+ else
+ " #{line}"
+ end
+ end.join("\n")
+ end
+
+ def org_theme_config(theme)
+ return nil if theme.nil?
workdir = Dir.pwd
- if curtheme == 'default'
+ if theme == 'default'
sourcedir = File.expand_path('../../../', __dir__)
else
sourcedir = workdir
end
<<~THEMECONFIG
- ("theme"
- :base-directory "#{sourcedir}/themes/#{curtheme}"
- :base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|js\\\\\\|css\\\\\\|otf\\\\\\|ttf\\\\\\|woff2?"
- :recursive t
- :publishing-directory "#{workdir}/#{settings['public_folder']}/assets"
- :publishing-function org-publish-attachment)
+ ("theme-#{theme}"
+ :base-directory "#{sourcedir}/themes/#{theme}"
+ :base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|js\\\\\\|css\\\\\\|otf\\\\\\|ttf\\\\\\|woff2?"
+ :recursive t
+ :publishing-directory "#{workdir}/#{settings['public_folder']}/assets/#{theme}"
+ :publishing-function org-publish-attachment)
THEMECONFIG
end
-
- def build_html_head
- stylesheet = <<~CSS
- <link rel="stylesheet" type="text/css" media="screen"
- href="#{settings['domain']}/assets/css/style.css">
- <link rel="stylesheet" type="text/css" media="screen"
- href="#{settings['domain']}/assets/css/htmlize.css">
- CSS
- return stylesheet if settings['blog_path'].nil?
- <<~ATOM
- #{stylesheet.strip}
- <link rel="alternate" type="application/atom+xml" title="Atom 1.0"
- href="#{settings['domain']}/feeds/index.xml" />
- ATOM
- end
end
end
diff --git a/lib/neruda/config/org-config.el b/lib/neruda/config/org-config.el
index 1ecbd15..740ded9 100644
--- a/lib/neruda/config/org-config.el
+++ b/lib/neruda/config/org-config.el
@@ -1,17 +1,18 @@
-;; Add custom org mode to load path
+;; Add org-mode to load path
(add-to-list 'load-path (expand-file-name "org-__ORG_VER__/lisp" "__WORK_DIR__"))
-;; Load modern version of htmlize.el
+;; Load last version of htmlize.el
(load-file (expand-file-name "htmlize.el" "__WORK_DIR__"))
;; Current project options
-(setq neruda/current-work-dir "__WORK_DIR__"
+(setq neruda/version "__VERSION__"
+ neruda/current-work-dir "__WORK_DIR__"
user-mail-address "__AUTHOR_EMAIL__"
user-full-name "__AUTHOR_NAME__"
org-html-metadata-timestamp-format "__LONG_DATE_FMT__"
org-publish-project-alist
`(__ALL_PROJECTS__
__THEME_CONFIG__
- ("website" :components (__ALL_PROJECTS_NAMES__ "theme"))))
+ ("website" :components (__ALL_PROJECTS_NAMES__))))
;; Load neruda lib
(load-file (expand-file-name "ox-neruda.el" "__NERUDA_DIR__"))
diff --git a/lib/neruda/config/ox-neruda.el b/lib/neruda/config/ox-neruda.el
index 488f867..0a5e938 100644
--- a/lib/neruda/config/ox-neruda.el
+++ b/lib/neruda/config/ox-neruda.el
@@ -33,13 +33,38 @@
;;; Function Declarations
+(defvar neruda/version ""
+ "Version of the current neruda installation")
+
(defvar neruda/current-work-dir nil
"Location of the current neruda website base directory.")
(defvar neruda/org-temp-dir nil
- "Location of the local org-mode temporary directory (where to place
+ "Location of the local Org temporary directory (where to place
org timestamps and id locations).")
+(defun neruda/org-html-format-spec (upstream info)
+ "Return format specification for preamble and postamble.
+INFO is a plist used as a communication channel."
+ (let ((output (funcall upstream info)))
+ (push `(?A . ,(format "<span class=\"author\">%s</span>"
+ (org-export-data (plist-get info :author) info)))
+ output)
+ (push `(?k . ,(org-export-data (plist-get info :keywords) info)) output)
+ (push `(?K . ,(format "<ul class=\"keywords-list\">%s</ul>"
+ (mapconcat
+ (lambda (k) (format "<li class=\"keyword\">%s</li>" k))
+ (split-string (or (plist-get info :keywords) "") ",+ *")
+ "\n")))
+ output)
+ (push `(?l . ,(org-export-data (plist-get info :language) info)) output)
+ (push `(?n . ,(format "Neruda %s" neruda/version)) output)
+ (push `(?N . ,(format "<a href=\"https://git.umaneti.net/neruda/about/\">Neruda</a> %s" neruda/version)) output)
+ (push `(?x . ,(org-export-data (plist-get info :description) info)) output)
+ (push `(?X . ,(format "<p>%s</p>"
+ (org-export-data (plist-get info :description) info)))
+ output)))
+
(defun neruda/org-i18n-export (link description format)
"Export a i18n link"
(let* ((splitted-link (split-string link "|"))
@@ -72,6 +97,7 @@ org timestamps and id locations).")
make-backup-files nil
enable-local-variables :all
org-confirm-babel-evaluate nil
+ org-export-with-broken-links t
org-html-doctype "html5"
org-html-html5-fancy t
org-html-htmlize-output-type 'css
@@ -81,7 +107,7 @@ org timestamps and id locations).")
(strike-through . "<del>%s</del>")
(underline . "<span class=\"underline\">%s</span>")
(verbatim . "<code>%s</code>")))
-
+(advice-add 'org-html-format-spec :around #'neruda/org-html-format-spec)
(provide 'ox-neruda)
diff --git a/lib/neruda/emacs.rb b/lib/neruda/emacs.rb
new file mode 100644
index 0000000..fe6c34f
--- /dev/null
+++ b/lib/neruda/emacs.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'neruda/config'
+
+module Neruda
+ # Wraps Gnu/Emacs calls
+ class Emacs
+ def initialize(file_path: nil, verbose: false)
+ @file = file_path
+ @verbose = verbose
+ end
+
+ def publish
+ if @file.nil?
+ emacs_args = ['--eval \'(org-publish "website")\'']
+ else
+ emacs_args = ['-f org-publish-current-file']
+ end
+ call_emacs emacs_args
+ end
+
+ private
+
+ def emacs_command(arguments = [])
+ default_emacs = Neruda::Config.settings['emacs']
+ emacs_cmd = [default_emacs || 'emacs -Q --batch -nw']
+ emacs_cmd << '--eval \'(setq enable-dir-local-variables nil)\''
+ emacs_cmd << '--eval \'(setq inhibit-message t)\'' unless @verbose
+ emacs_cmd << '-l ./org-config.el'
+ emacs_cmd << "--eval '(find-file \"#{@file}\")'" unless @file.nil?
+ emacs_cmd.concat(arguments)
+ emacs_cmd.join(' ')
+ end
+
+ def call_emacs(arguments = [])
+ command = emacs_command arguments
+ if @verbose
+ warn command
+ return system(command, exception: true)
+ end
+ system command, out: '/dev/null', err: '/dev/null', exception: true
+ end
+ end
+end
diff --git a/lib/neruda/index.rb b/lib/neruda/index.rb
index 1821073..84809cb 100644
--- a/lib/neruda/index.rb
+++ b/lib/neruda/index.rb
@@ -16,35 +16,32 @@ module Neruda
include Neruda::IndexAtomGenerator
include Neruda::IndexOrgGenerator
- def initialize(file_list = nil)
- @blog_path = Neruda::Config.settings['blog_path']
+ def initialize
@pubdir = Neruda::Config.settings['public_folder']
@index = { 'index' => [] }
+ @projects = {}
@tags_names = {}
@date = DateTime.now
- if @blog_path.nil?
- @sources = []
- else
- @sources = sources_list(file_list)
- filter_and_prefix_sources!
- @sources.each { |f| add_to_indexes(Neruda::OrgFile.new(f)) }
- sort!
- end
+ feed
+ sort!
end
def entries
- @index.keys
+ @index.keys.reject { |k| k == 'index' }
+ end
+
+ def empty?
+ @index['index'].empty?
end
- def write_all(verbose = true)
- @index.keys.each do |k|
+ def write_all(verbose: true)
+ @index.each_key do |k|
write_org(k)
warn "Generated index file for #{k}" if verbose
write_atom(k)
warn "Generated atom feed for #{k}" if verbose
end
- write_org_lists
- warn 'Generated all tags index' if verbose
+ write_all_blog_home(verbose)
end
def sort_by(kind)
@@ -61,35 +58,36 @@ module Neruda
private
- def sources_list(file_list)
- return file_list unless file_list.nil?
- Dir.glob(Neruda::Config.settings['blog_pattern'],
- base: "src/#{@blog_path}")
- end
-
- def filter_and_prefix_sources!
- exclude = Neruda::Config.settings['exclude_pattern']
- sources = []
- @sources.each do |f|
- next if f == 'index.org'
- if File.exist?(f)
- file_path = f
+ def feed
+ Neruda::Config.sources.each do |project|
+ next unless project['is_blog']
+ if project['recursive']
+ file_pattern = '**/*.org'
else
- file_path = "src/#{@blog_path}/#{f}"
- next unless File.exist?(file_path)
+ file_pattern = '*.org'
+ end
+ Dir.glob(file_pattern, base: project['path']).map do |s|
+ org_file = File.join(project['path'], s)
+ add_to_indexes(
+ Neruda::OrgFile.new(org_file, project: project)
+ )
end
- next if exclude && file_path.match(exclude)
- sources << file_path
end
- @sources = sources
+ end
+
+ def add_to_project_index(article)
+ project = article.project
+ @projects[project['name']] ||= []
+ @projects[project['name']] << article
end
def add_to_indexes(article)
@index['index'] << article
+ add_to_project_index article
article.keywords.each do |k|
slug = Neruda::OrgFile.slug k
@tags_names[slug] = k # Overwrite is permitted
- @index[slug] = [] unless @index.has_key?(slug)
+ @index[slug] ||= []
@index[slug] << article
end
end
@@ -98,16 +96,27 @@ module Neruda
@index.each do |k, i|
@index[k] = i.sort { |a, b| b.timekey <=> a.timekey }
end
+ @projects.each do |k, i|
+ @projects[k] = i.sort { |a, b| b.timekey <=> a.timekey }
+ end
end
def sort_tags_by_name_and_weight
tags_sorted = {}
- all_keys = @index.keys.reject { |k| k == 'index' }
+ all_keys = entries
tags_sorted[:by_name] = all_keys.sort
tags_sorted[:by_weight] = all_keys.sort do |a, b|
@index[b].length <=> @index[a].length
end
tags_sorted
end
+
+ def save?
+ return true unless empty?
+ Neruda::Config.sources.each do |project|
+ return true if project['is_blog'] && Dir.exist?(project['path'])
+ end
+ false
+ end
end
end
diff --git a/lib/neruda/index/atom_generator.rb b/lib/neruda/index/atom_generator.rb
index 5e7787d..ad12462 100644
--- a/lib/neruda/index/atom_generator.rb
+++ b/lib/neruda/index/atom_generator.rb
@@ -11,11 +11,11 @@ module Neruda
@index[index_name][0...10].each do |article|
content << atom_entry(article)
end
- content.join("\n") + '</feed>'
+ format '%<content>s</feed>', content: content.join("\n")
end
def write_atom(index_name)
- return 0 if @blog_path.nil?
+ return unless save?
slug = Neruda::OrgFile.slug index_name
FileUtils.mkdir_p "#{@pubdir}/feeds"
atomdest = "#{@pubdir}/feeds/#{slug}.xml"
@@ -31,17 +31,17 @@ module Neruda
def atom_header(title)
domain = Neruda::Config.settings['domain']
upddate = @date.rfc3339
- slug = Neruda::OrgFile.slug(title)
- tagurl = "#{domain}/tags/#{slug}.html"
if title == 'index'
- if Neruda::Config.settings['title']
- title = Neruda::Config.settings['title']
- end
- tagurl = "#{domain}/#{@blog_path}"
- elsif @tags_names.has_key?(title)
+ slug = 'index'
+ tagurl = domain
+ title = Neruda::Config.settings['title'] || \
+ R18n.t.neruda.index.all_tags
+ else
+ slug = Neruda::OrgFile.slug(title)
+ tagurl = "#{domain}/tags/#{slug}.html"
title = @tags_names[title]
end
- title_esc = CGI.escapeHTML(title)
+ title = CGI.escapeHTML(title)
<<~ENDATOM
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
@@ -49,9 +49,9 @@ module Neruda
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xml:lang="#{Neruda::Config.settings['lang']}">
- <title>#{title_esc}</title>
+ <title>#{title}</title>
<link href="#{domain}/feeds/#{slug}.xml" rel="self" type="application/atom+xml"/>
- <link href="#{tagurl}" rel="alternate" type="text/html" title="#{title_esc}"/>
+ <link href="#{tagurl}" rel="alternate" type="text/html" title="#{title}"/>
<updated>#{upddate}</updated>
<author><name>#{Neruda::Config.settings['author'] || ''}</name></author>
<id>urn:md5:#{Digest::MD5.hexdigest(domain)}</id>
@@ -69,12 +69,12 @@ module Neruda
"<dc:subject>#{CGI.escapeHTML(k)}</dc:subject>"
end.join
keywords += "\n " if keywords != ''
- title_esc = CGI.escapeHTML(article.title)
+ title = CGI.escapeHTML(article.title)
<<~ENDENTRY
<entry>
- <title>#{title_esc}</title>
+ <title>#{title}</title>
<link href="#{article.url}" rel="alternate" type="text/html"
- title="#{title_esc}"/>
+ title="#{title}"/>
<id>urn:md5:#{Digest::MD5.hexdigest(article.timekey)}</id>
<published>#{article.datestring(:rfc3339)}</published>
<author><name>#{CGI.escapeHTML(article.author)}</name></author>
diff --git a/lib/neruda/index/org_generator.rb b/lib/neruda/index/org_generator.rb
index 63a51a1..cd9704b 100644
--- a/lib/neruda/index/org_generator.rb
+++ b/lib/neruda/index/org_generator.rb
@@ -4,73 +4,96 @@ module Neruda
# Embeds methods responsible for generating an org file for a given
# index.
module IndexOrgGenerator
- def to_org(index_name = 'index')
- content = [org_header(index_name).strip]
- last_year = nil
- @index[index_name].each do |article|
- year = article.timekey.slice(0, 4)
- if year != last_year
- content << ''
- content << org_title(year)
- last_year = year
- end
- content << org_entry(article)
- end
- content.join("\n")
+ def to_org(index_name = 'index', is_project: false)
+ return project_home_page(index_name) if is_project
+ return all_tags_index if index_name == 'index'
+ [org_header(index_name),
+ org_articles(@index[index_name])].join("\n")
end
alias_method :to_s, :to_org
def write_org(index_name)
- return 0 if @blog_path.nil?
- FileUtils.mkdir_p 'src/tags' unless index_name == 'index'
- src = index_source_path(index_name)
- IO.write(src, to_org(index_name))
+ return unless save?
+ slug = Neruda::OrgFile.slug index_name
+ FileUtils.mkdir 'tags' unless Dir.exist? 'tags'
+ content = to_org index_name
+ orgdest = "tags/#{slug}.org"
+ IO.write(orgdest, content)
end
- def write_org_lists
- return 0 if @blog_path.nil?
- domain = Neruda::Config.settings['domain']
- content = [org_header(R18n.t.neruda.index.all_tags)]
+ private
+
+ def project_home_page(project_name)
+ content = [org_header(project_name, is_tag: false)]
+ if @projects[project_name]&.any?
+ content += org_articles(@projects[project_name])
+ end
+ content.join("\n")
+ end
+
+ def write_all_blog_home(verbose)
+ Neruda::Config.sources.each do |project|
+ next unless project['is_blog']
+ next unless Dir.exist?(project['path'])
+ warn "Generated blog home for #{project['name']}" if verbose
+ orgdest = format('%<root>s/index.org', root: project['path'])
+ IO.write(orgdest, to_org(project['name'], is_project: true))
+ end
+ end
+
+ def all_tags_index
+ content = [
+ org_header(R18n.t.neruda.index.all_tags, is_tag: false)
+ ]
sort_tags_by_name_and_weight.each do |t, tags|
content << ''
content << org_title(R18n.t.neruda.index.send(t), 'index-tags')
+ next if tags.empty?
tags.each do |k|
- title = @tags_names[k] || k
- link = "[[#{domain}/tags/#{k}.html][#{title}]]"
- content << "- #{link} (#{@index[k].length})"
+ content << "- #{tag_published_url(k)} (#{@index[k].length})"
end
end
- FileUtils.mkdir_p 'src/tags'
- src = 'src/tags/index.org'
- IO.write(src, content.join("\n"))
+ content.join("\n")
end
- private
-
- def index_source_path(index_name)
- slug = Neruda::OrgFile.slug index_name
- src = ['src', 'tags', "#{slug}.org"]
- src[1] = @blog_path if slug == 'index'
- src.join('/')
+ def tag_published_url(tag_name)
+ domain = Neruda::Config.settings['domain']
+ title = @tags_names[tag_name]
+ tag_link = "#{domain}/tags/#{tag_name}.html"
+ "[[#{tag_link}][#{title}]]"
end
- def org_header(title = nil)
- if title.nil? || title == 'index'
- title = Neruda::Config.settings['title']
- elsif @tags_names.has_key?(title)
+ def org_header(title = nil, is_tag: true)
+ if is_tag
title = @tags_names[title]
+ elsif title.nil? || title == 'index'
+ title = Neruda::Config.settings['title']
end
- <<~HEADER
+ head = <<~HEADER
#+title: #{title}
#+author: #{Neruda::Config.settings['author']}
#+language: #{Neruda::Config.settings['lang']}
HEADER
+ head.strip
+ end
+
+ def org_articles(articles_list)
+ last_year = nil
+ articles_list.map do |article|
+ year_title = ''
+ year = article.timekey.slice(0, 4)
+ if year != last_year
+ year_title = format("\n%<title>s\n", title: org_title(year))
+ last_year = year
+ end
+ year_title + org_entry(article)
+ end
end
def org_entry(article)
- line = "- *[[..#{article.html_file}][#{article.title}]]*"
+ line = "- *[[#{article.url}][#{article.title}]]*"
if article.date
- art_date = article.datestring(:full, false)
+ art_date = article.datestring(:full, year: false)
published = R18n.t.neruda.index.published_on art_date
line += " / #{published}"
end
diff --git a/lib/neruda/org_file.rb b/lib/neruda/org_file.rb
index 9149f67..e6dd000 100644
--- a/lib/neruda/org_file.rb
+++ b/lib/neruda/org_file.rb
@@ -7,6 +7,7 @@ require 'neruda/org_file/htmlizer'
require 'neruda/org_file/extracter'
require 'neruda/org_file/class_methods'
require 'neruda/index'
+require 'neruda/version'
module Neruda
# Handles org files.
@@ -19,6 +20,10 @@ module Neruda
# the ~#+title:~ header.
attr_reader :title
+ # @return [String] the subtitle of the current org document, taken
+ # from the ~#+subtitle:~ header.
+ attr_reader :subtitle
+
# @return [DateTime] the date and time of the current org document,
# taken from the ~#+date:~ header.
attr_reader :date
@@ -40,6 +45,10 @@ module Neruda
# taken from the ~#+keywords:~ header.
attr_reader :keywords
+ # @return [String] the description of this org document, taken from
+ # the ~#+description:~ header.
+ attr_reader :excerpt
+
# The locale of the current org document, taken from the
# ~#+language:~ header.
#
@@ -61,9 +70,8 @@ module Neruda
# settings and the above {#html_file @html_file} attribute.
attr_reader :url
- # @return [String] the description of this org document, taken from
- # the ~#+description:~ header.
- attr_reader :excerpt
+ # @return [String] the project owning this document.
+ attr_reader :project
extend Neruda::OrgFileClassMethods
@@ -96,21 +104,25 @@ module Neruda
# o.title
# => "New file"
#
- # @param file_name [String] path to the corresponding org mode file
- # @param opts [Hash] optional data to initialize new org file
- # @option opts [String] title ('') the title of the new org file
+ # @param file_name [String] path to the corresponding Org file
+ # @param opts [Hash] optional data to initialize new Org file
+ # @option opts [String] title ('') the title of the new Org file
# @option opts [String] author (system user or '') the author of the
# document
# @option opts [Boolean] verbose (false) if the
# {Neruda::OrgFileHtmlizer#publish publish} method should output
# emacs process messages
+ # @option opts [String] project the project owning this file
+ # must be stored
# @return [Neruda::OrgFile] the new instance of Neruda::OrgFile
def initialize(file_name, opts = {})
file_name = nil if file_name == ''
@file = file_name
- @html_file = Neruda::OrgFile.html_file @file
- @url = Neruda::OrgFile.html_file_with_domain @file
+ @html_file = nil
+ @url = nil
+ @project = opts.delete :project
@options = opts
+ build_html_file_and_url
if @file && File.exist?(@file)
extract_data
else
@@ -166,7 +178,7 @@ module Neruda
# @param year [Boolean] wether or not the ~:full~ format must
# contain the year
# @return [String] the document DateTime string representation
- def datestring(dateformat = :full, year = true)
+ def datestring(dateformat = :full, year: true)
return '' if @date.nil?
return R18n.l @date.to_date if dateformat == :short
return @date.rfc3339 if dateformat == :rfc3339
@@ -202,6 +214,10 @@ module Neruda
# - %l :: the lang of the document
# - %L :: the license information, taken from the
# {Neruda::Config#settings}
+ # - %n :: the Neruda name and version
+ # - %N :: the Neruda name and version with a link to the project
+ # home on the name
+ # - %s :: the subtitle of the document
# - %t :: the title of the document
# - %u :: the web path to the related published HTML document
# - %x :: the raw description (eXcerpt)
@@ -213,8 +229,9 @@ module Neruda
# => "Article written by Alice Smith the Wednesday 3rd July"
#
# @return [String] the given ~string~ after replacement occurs
+ # rubocop:disable Metrics/MethodLength
+ # rubocop:disable Layout/LineLength
def format(string)
- license = Neruda::Config.settings['license'] || ''
string.gsub('%a', @author)
.gsub('%A', author_to_html)
.gsub('%d', date_to_html(:short))
@@ -224,12 +241,17 @@ module Neruda
.gsub('%k', @keywords.join(', '))
.gsub('%K', keywords_to_html)
.gsub('%l', @lang)
- .gsub('%L', license.gsub(/\s+/, ' ').strip)
+ .gsub('%L', (Neruda::Config.settings['license'] || '').gsub(/\s+/, ' ').strip)
+ .gsub('%n', "Neruda #{Neruda::VERSION}")
+ .gsub('%N', "<a href=\"https://git.umaneti.net/neruda/about/\">Neruda</a> #{Neruda::VERSION}")
+ .gsub('%s', @subtitle)
.gsub('%t', @title)
- .gsub('%u', @html_file)
+ .gsub('%u', @html_file || '')
.gsub('%x', @excerpt)
.gsub('%X', "<p>#{@excerpt}</p>")
end
+ # rubocop:enable Layout/LineLength
+ # rubocop:enable Metrics/MethodLength
# Writes the current OrgFile content to the underlying file.
#
@@ -246,20 +268,31 @@ module Neruda
private
+ def build_html_file_and_url
+ return if @file.nil?
+ @html_file = Neruda::OrgFile.target_for_source(
+ @file, @project, with_public_folder: false
+ )
+ @url = "#{Neruda::Config.settings['domain']}/#{@html_file}"
+ end
+
def init_empty_file
@title = @options[:title] || ''
+ @subtitle = ''
@date = DateTime.now
@notime = false
@author = @options[:author] || Neruda::Config.settings['author']
@keywords = []
@lang = @options[:lang] || Neruda::Config.settings['lang']
@excerpt = ''
- @content = @options[:content] || <<~ORG
+ body = @options[:content] || ''
+ @content = @options[:raw_content] || <<~ORG
#+title: #{@title}
#+date: <#{@date.strftime('%Y-%m-%d %a. %H:%M:%S')}>
#+author: #{@author}
#+language: #{@lang}
+ #{body}
ORG
end
end
diff --git a/lib/neruda/org_file/class_methods.rb b/lib/neruda/org_file/class_methods.rb
index 90ab617..2a150ca 100644
--- a/lib/neruda/org_file/class_methods.rb
+++ b/lib/neruda/org_file/class_methods.rb
@@ -3,33 +3,50 @@
module Neruda
# This module holds class methods for the {Neruda::OrgFile} class.
module OrgFileClassMethods
- def html_file(file_name)
- return nil if file_name.nil?
- path = Neruda::OrgFile.target_for_source(file_name)
- pubfolder = Neruda::Config.settings['public_folder']
- path.sub(/^#{pubfolder}\//, '/')
- end
-
- def html_file_with_domain(file_name)
- return nil if file_name.nil?
- Neruda::Config.settings['domain'] + html_file(file_name)
- end
-
def source_for_target(file_name)
# file_name may be frozen...
src = file_name.sub(/\.html$/, '.org')
pubfolder = Neruda::Config.settings['public_folder']
- src.sub(/^#{pubfolder}\//, 'src/')
+ src.sub!(/^#{pubfolder}\//, '')
+ # Look for match in each possible sources. The first found wins.
+ Neruda::Config.sources.each do |project|
+ if project['target'] == '.'
+ origin = File.join(project['path'], src)
+ else
+ origin = File.join(
+ project['path'], src.sub(/^#{project['target']}\//, '')
+ )
+ end
+ return origin if File.exist?(origin)
+ end
+ nil
end
- def target_for_source(file_name)
+ def target_for_source(file_name, project, with_public_folder: true)
+ return nil if file_name.nil?
# file_name may be frozen...
- target = file_name.sub(/\.org$/, '.html')
+ target = file_name.sub(/\.org$/, '.html').sub(/^#{Dir.pwd}\//, '')
+ if project.nil?
+ subfolder = File.basename(File.dirname(target))
+ target = File.basename(target)
+ target = "#{subfolder}/#{target}" if subfolder != '.'
+ else
+ project_relative_path = project['path'].sub(/^#{Dir.pwd}\//, '')
+ target.sub!(/^#{project_relative_path}\//, '')
+ target = "#{project['target']}/#{target}" if project['target'] != '.'
+ end
+ return target unless with_public_folder
pubfolder = Neruda::Config.settings['public_folder']
- return target.sub(/^src\//, "#{pubfolder}/") if /^src\//.match?(target)
- subfolder = File.basename(File.dirname(target))
- leaf = File.basename(target)
- "#{pubfolder}/#{subfolder}/#{leaf}"
+ "#{pubfolder}/#{target}"
+ end
+
+ def project_for_source(file_name)
+ # Look for match in each possible sources. The first found wins.
+ Neruda::Config.sources.each do |project|
+ project_relative_path = project['path'].sub(/^#{Dir.pwd}\//, '')
+ return project if file_name =~ /^#{project_relative_path}\//
+ end
+ nil
end
def slug(title)
diff --git a/lib/neruda/org_file/extracter.rb b/lib/neruda/org_file/extracter.rb
index 4f718d6..ac5b783 100644
--- a/lib/neruda/org_file/extracter.rb
+++ b/lib/neruda/org_file/extracter.rb
@@ -10,6 +10,7 @@ module Neruda
def extract_data
@content = IO.read @file
@title = extract_title
+ @subtitle = extract_subtitle
@date = extract_date
@author = extract_author
@keywords = extract_keywords
@@ -32,7 +33,17 @@ module Neruda
def extract_title
m = /^#\+title:(.+)$/i.match(@content)
- return @file if m.nil?
+ if m.nil?
+ # Avoid to leak absolute path
+ project_relative_path = @file.sub(/^#{Dir.pwd}\//, '')
+ return project_relative_path
+ end
+ m[1].strip
+ end
+
+ def extract_subtitle
+ m = /^#\+subtitle:(.+)$/i.match(@content)
+ return '' if m.nil?
m[1].strip
end
diff --git a/lib/neruda/org_file/htmlizer.rb b/lib/neruda/org_file/htmlizer.rb
index 7af1c60..9130e25 100644
--- a/lib/neruda/org_file/htmlizer.rb
+++ b/lib/neruda/org_file/htmlizer.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require 'neruda/config'
+require 'neruda/emacs'
module Neruda
# This module holds HTML formatter methods for the {Neruda::OrgFile}
@@ -11,12 +12,9 @@ module Neruda
#
# @return [Boolean, nil] the underlying ~system~ method return value
def publish
- if @file.nil?
- emacs_args = ['--eval \'(org-publish "website")\'']
- else
- emacs_args = ['-f org-publish-current-file']
- end
- call_emacs emacs_args
+ Neruda::Emacs.new(
+ file_path: @file, verbose: @options[:verbose]
+ ).publish
end
private
@@ -40,7 +38,7 @@ module Neruda
#
# @return [String] the HTML `time` tag
def date_to_html(dateformat = :full)
- return '' if @date.nil?
+ return '<time></time>' if @date.nil?
"<time datetime=\"#{@date.rfc3339}\">#{datestring(dateformat)}</time>"
end
@@ -49,30 +47,7 @@ module Neruda
#
# @return [String] the author HTML `span`
def author_to_html
- return '' if @author == ''
"<span class=\"author\">#{@author}</span>"
end
-
- def emacs_command(arguments = [])
- default_emacs = Neruda::Config.settings['emacs']
- emacs_cmd = [default_emacs || 'emacs -Q --batch -nw']
- emacs_cmd << '--eval \'(setq enable-dir-local-variables nil)\''
- unless @options[:verbose]
- emacs_cmd << '--eval \'(setq inhibit-message t)\''
- end
- emacs_cmd << '-l ./org-config.el'
- emacs_cmd << "--eval '(find-file \"#{@file}\")'" unless @file.nil?
- emacs_cmd.concat(arguments)
- emacs_cmd.join(' ')
- end
-
- def call_emacs(arguments = [])
- command = emacs_command arguments
- if @options[:verbose]
- warn command
- return system(command, exception: true)
- end
- system command, out: '/dev/null', err: '/dev/null', exception: true
- end
end
end
diff --git a/lib/neruda/preview.rb b/lib/neruda/preview.rb
index e9f5b7b..55e4e7d 100644
--- a/lib/neruda/preview.rb
+++ b/lib/neruda/preview.rb
@@ -19,11 +19,13 @@ module Neruda # rubocop:disable Style/Documentation
private
def local_path(requested_path)
- routes = Neruda::Config.settings['routes'] || {}
+ routes = Neruda::Config.settings.dig('preview', 'routes') || {}
return routes[requested_path] if routes.keys.include? requested_path
local_path = Neruda::Config.settings['public_folder'] + requested_path
if File.directory? local_path
- local_path = local_path.delete_suffix('/') + '/index.html'
+ local_path = format(
+ '%<path>s/index.html', path: local_path.delete_suffix('/')
+ )
end
return local_path if File.exist? local_path
raise WEBrick::HTTPStatus::NotFound, 'Not found.'
@@ -34,8 +36,8 @@ module Neruda # rubocop:disable Style/Documentation
return body unless local_path.match?(/\.(?:ht|x)ml$/)
domain = Neruda::Config.settings['domain']
return body if domain == ''
- body.gsub(/"file:\/\//, '"' + local_host)
- .gsub(/"#{domain}/, '"' + local_host)
+ body.gsub(/"file:\/\//, format('"%<host>s', host: local_host))
+ .gsub(/"#{domain}/, format('"%<host>s', host: local_host))
end
end
@@ -43,7 +45,7 @@ module Neruda # rubocop:disable Style/Documentation
def start_preview
# Inspired by ruby un.rb library, which allows normally to start a
# webrick server in one line: ruby -run -e httpd public_html -p 5000
- port = Neruda::Config.settings['server_port'] || 5000
+ port = Neruda::Config.settings.dig('preview', 'server_port') || 5000
s = WEBrick::HTTPServer.new(Port: port)
s.mount '/', Neruda::PreviewServlet
['TERM', 'QUIT', 'INT'].each { |sig| trap(sig, proc { s.shutdown }) }
diff --git a/lib/neruda/templater.rb b/lib/neruda/templater.rb
index c8bfce5..3226e42 100644
--- a/lib/neruda/templater.rb
+++ b/lib/neruda/templater.rb
@@ -99,9 +99,10 @@ module Neruda
end
def insert_new_node_at(elem, content)
- if @position == 'before'
+ case @position
+ when 'before'
elem.add_previous_sibling content
- elsif @position == 'replace'
+ when 'replace'
elem.replace content
else
elem.add_next_sibling content
diff --git a/lib/neruda/utils.rb b/lib/neruda/utils.rb
index cfa15c3..8b3edc6 100644
--- a/lib/neruda/utils.rb
+++ b/lib/neruda/utils.rb
@@ -1,6 +1,8 @@
# frozen_string_literal: true
+require 'uri'
require 'rainbow'
+require 'net/http'
require 'r18n-core'
require 'neruda/config'
@@ -67,10 +69,7 @@ module Neruda
begin
run_and_decorate_thread thread, message, frames
rescue RuntimeError => e
- done = Rainbow('An error occured.').bold.red + "\n"
- done += Rainbow('To see it, run again your command with more ' \
- 'verbosity, i.e. pablo build -v').bold
- warn "#{message} #{done}"
+ throbber_error message
raise e
else
done = Rainbow('done'.ljust(frames[0].length)).green
@@ -95,7 +94,7 @@ module Neruda
long = "--#{opt[:long]}"
return [short, long] if opt[:boolean]
key = opt[:keyword] || opt[:long].upcase
- [short + key, long + ' ' + key]
+ [short + key, format('%<long>s %<key>s', long: long, key: key)]
end
# Returns the ~pablo~ help summary for a given command.
@@ -107,7 +106,8 @@ module Neruda
Neruda::Utils::PABLO_COMMANDS[command][:opts].map do |k|
short, long = Neruda::Utils.decorate_option(k)
opt = Neruda::Utils::PABLO_OPTIONS[k]
- line = [(' ' + [short, long].join(', ')).ljust(30)]
+ label = [short, long].join(', ')
+ line = [format(' %<opt>s', opt: label).ljust(30)]
if R18n.t.pablo.options[opt[:long]].translated?
line << R18n.t.pablo.options[opt[:long]]
end
@@ -125,7 +125,7 @@ module Neruda
line = [' ', cmd.ljust(10)]
if opt.has_key? :alias
line << R18n.t.pablo.commands.alias(opt[:alias])
- elsif R18n.t.pablo.commands[cmd].translated?
+ else
line << R18n.t.pablo.commands[cmd]
end
lines << line.join(' ')
@@ -148,6 +148,7 @@ module Neruda
# Try to discover the current host operating system.
#
# @return [String] either apple, windows or linux (default)
+ # :nocov:
def current_os
if ENV['OS'] == 'Windows_NT' || RUBY_PLATFORM =~ /cygwin/
return 'windows'
@@ -155,9 +156,42 @@ module Neruda
return 'apple' if RUBY_PLATFORM =~ /darwin/
'linux'
end
+ # :nocov:
+
+ # Download latest org-mode tarball.
+ #
+ # @return [String] the downloaded org-mode version
+ def download_org
+ # :nocov:
+ return if Neruda::Config.org_last_version.nil?
+ # :nocov:
+ tarball = "org-#{Neruda::Config.org_last_version}.tar.gz"
+ dest_file = "tmp/#{tarball}"
+ return if File.exist?(dest_file)
+ uri = URI("https://orgmode.org/#{tarball}")
+ # Will crash on purpose if anything goes wrong
+ Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
+ http.request(Net::HTTP::Get.new(uri)) do |response|
+ File.open(dest_file, 'w') do |io|
+ response.read_body { |chunk| io.write chunk }
+ end
+ end
+ end
+ end
private
+ def throbber_error(message)
+ warn(
+ format(
+ "%<message>s %<label>s\n%<explanation>s",
+ message: message,
+ label: Rainbow(R18n.t.neruda.error.label).bold.red,
+ explanation: Rainbow(R18n.t.neruda.error.explanation).bold
+ )
+ )
+ end
+
def select_throbber_frames
model = Neruda::Config.settings['throbber'] || 'default'
model = 'default' unless Neruda::Utils::THROBBER_FRAMES.has_key?(model)
diff --git a/lib/neruda/version.rb b/lib/neruda/version.rb
index 18e2c62..0bbab5b 100644
--- a/lib/neruda/version.rb
+++ b/lib/neruda/version.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
module Neruda
- VERSION = '0.1.4'
+ # @return [String] the version number of the current Neruda release.
+ VERSION = '0.2.0'
end
diff --git a/lib/tasks/org.rake b/lib/tasks/org.rake
index bfce5fa..c9cea70 100644
--- a/lib/tasks/org.rake
+++ b/lib/tasks/org.rake
@@ -1,26 +1,38 @@
# frozen_string_literal: true
+require 'open-uri'
+
# Neruda::Config is required by Neruda::Utils
require 'neruda/utils'
namespace :org do
- desc 'Download last version of org-mode'
+ desc 'Download last version of Org'
task :download do
verbose = Rake::FileUtilsExt.verbose_flag
+ download = Thread.new do
+ Thread.current[:org_version] = Neruda::Config.org_last_version
+ Neruda::Utils.download_org
+ end
+ if verbose
+ download.join
+ warn "Org version #{download[:org_version]} has been downloaded"
+ else
+ Neruda::Utils.throbber(download, 'Downloading Org:')
+ end
+ end
+
+ desc 'Compile Org'
+ task compile: ['org:download'] do
+ verbose = Rake::FileUtilsExt.verbose_flag
org_version = "org-#{Neruda::Config.org_last_version}"
- next if Neruda::Config.org_last_version.nil?
next if Dir.exist?("#{org_version}/lisp")
- tarball = "#{org_version}.tar.gz"
- curl = ['curl', '--progress-bar', '-O',
- "https://orgmode.org/#{tarball}"]
make = ['make', '-C', org_version]
unless verbose
- curl[1] = '-s'
make << '-s'
make << 'EMACSQ="emacs -Q --eval \'(setq inhibit-message t)\'"'
end
build = Thread.new do
- sh curl.join(' ')
+ tarball = "tmp/#{org_version}.tar.gz"
sh "tar xzf #{tarball}"
File.unlink tarball
sh((make + ['compile']).join(' '))
@@ -34,16 +46,18 @@ namespace :org do
build.join
warn "#{org_version} has been locally installed"
else
- Neruda::Utils.throbber(build, 'Installing org mode:')
+ Neruda::Utils.throbber(build, 'Installing Org:')
end
end
file 'htmlize.el' do
verbose = Rake::FileUtilsExt.verbose_flag
- curl = ['curl', '--progress-bar', '-O',
- 'https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el']
- curl[1] = '-s' unless verbose
- build = Thread.new { sh curl.join(' ') }
+ build = Thread.new do
+ htmlize = URI(
+ 'https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el'
+ ).open.read
+ IO.write 'htmlize.el', htmlize
+ end
if verbose
build.join
warn 'htmlize.el has been locally installed'
@@ -53,7 +67,6 @@ namespace :org do
end
file 'org-config.el' => 'htmlize.el' do
- next if Neruda::Config.org_last_version.nil?
Neruda::Config.write_org_lisp_config
end
@@ -62,8 +75,10 @@ namespace :org do
end
desc 'Install org'
- task install: ['org:download', 'org-config.el', '.dir-locals.el'] do
+ task install: ['org:compile', 'org-config.el', '.dir-locals.el'] do
mkdir_p "#{Neruda::Config.settings['public_folder']}/assets"
- mkdir_p 'src'
+ Neruda::Config.sources.each do |s|
+ mkdir_p s['path'] unless Dir.exist? s['path']
+ end
end
end
diff --git a/lib/tasks/site.rake b/lib/tasks/site.rake
index ae60393..3fdec35 100644
--- a/lib/tasks/site.rake
+++ b/lib/tasks/site.rake
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+require 'neruda/emacs'
require 'neruda/index'
require 'neruda/utils'
require 'neruda/org_file'
@@ -8,9 +9,6 @@ require 'neruda/templater'
namespace :site do
desc 'Generates all index files'
task :index do
- blog_path = Neruda::Config.settings['blog_path']
- next if blog_path.nil?
- next unless Dir.exist?("src/#{blog_path}")
index = Neruda::Index.new
verbose = Rake::FileUtilsExt.verbose_flag
if verbose
@@ -18,22 +16,27 @@ namespace :site do
next
end
build = Thread.new do
- index.write_all(false)
+ index.write_all(verbose: false)
end
Neruda::Utils.throbber(build, 'Generating indexes:')
+ next if index.empty?
+ Neruda::Config.write_org_lisp_config(with_tags: true)
end
desc 'Convert all org files'
task build: :index do
build_html = Thread.new do
- Neruda::OrgFile.new(nil, verbose: Rake::FileUtilsExt.verbose_flag).publish
+ Neruda::Emacs.new(verbose: Rake::FileUtilsExt.verbose_flag).publish
+ # TODO: Find a way to publish the virtual tag project
end
begin
Neruda::Utils.throbber(build_html, 'Building:')
+ # :nocov:
rescue RuntimeError
warn 'Aborting'
next
end
+ # :nocov:
customize_html = Thread.new do
pubfolder = Neruda::Config.settings['public_folder']
Dir["#{pubfolder}/**/*.html"].each do |f|
@@ -51,26 +54,33 @@ namespace :site do
next
end
verbose = Rake::FileUtilsExt.verbose_flag
- o = Thread.new do
- Neruda::OrgFile.new(args[:source], verbose: verbose).publish
+ project = Neruda::OrgFile.project_for_source(args[:source])
+ if project.nil?
+ warn "No project found for #{args['source']}"
+ next
+ end
+ build_html = Thread.new do
+ o = Neruda::OrgFile.new(
+ args[:source], project: project, verbose: verbose
+ )
+ Thread.current[:org_file] = o
+ o.publish
end
begin
- Neruda::Utils.throbber(o, 'Building:')
+ Neruda::Utils.throbber(build_html, 'Building:')
rescue RuntimeError
warn 'Aborting'
next
end
- target = Neruda::OrgFile.target_for_source(args[:source])
+ target = Neruda::OrgFile.target_for_source(args[:source], project)
warn "Customizing file #{target}" if verbose
- Neruda::Templater.customize_output(target, o)
+ Neruda::Templater.customize_output(target, build_html[:org_file])
end
end
- # :nocov:
desc 'Start a test server'
task :preview do
require 'neruda/preview'
Neruda.start_preview
end
- # :nocov:
end
diff --git a/lib/tasks/tags.rake b/lib/tasks/tags.rake
index 02982e1..2522275 100644
--- a/lib/tasks/tags.rake
+++ b/lib/tasks/tags.rake
@@ -5,19 +5,15 @@ require 'neruda/index'
namespace :tags do
desc 'List all tags by name'
task :name do
- blog_path = Neruda::Config.settings['blog_path']
- next if blog_path.nil?
- next unless Dir.exist?("src/#{blog_path}")
index = Neruda::Index.new
+ next if index.empty?
puts index.sort_by(:name).join("\n")
end
desc 'List all tags by weight'
task :weight do
- blog_path = Neruda::Config.settings['blog_path']
- next if blog_path.nil?
- next unless Dir.exist?("src/#{blog_path}")
index = Neruda::Index.new
+ next if index.empty?
puts index.sort_by(:weight).join("\n")
end
end
diff --git a/locales/en.yml b/locales/en.yml
index 6279550..6ad7732 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -19,6 +19,9 @@ pablo:
help: Display help for a command and exit.
version: Display Neruda version and exit.
neruda:
+ error:
+ label: An error occured.
+ explanation: To see it, run again your command with more verbosity, i.e. pablo build -v
index:
unsorted: Unsorted
published_on: Published on %1
@@ -30,5 +33,5 @@ neruda:
org:
postamble:
written_by: Written by %a
- with_emacs: 'with %c, and published with <a href="https://git.umaneti.net/neruda/about/">Neruda</a>'
+ with_emacs: 'with %c, and published with %N'
last_modification: Last modification on %C
diff --git a/locales/fr.yml b/locales/fr.yml
index 55b7858..823482f 100644
--- a/locales/fr.yml
+++ b/locales/fr.yml
@@ -19,6 +19,9 @@ pablo:
help: Affiche l'aide pour une commande et quitte.
version: Affiche la version de Neruda et quitte.
neruda:
+ error:
+ label: Une erreur est survenue
+ explanation: Pour voir le détail, lancez de nouveau la commande avec plus de verbosité, par exemple pablo build -v
index:
unsorted: Non triés
published_on: Publié le %1
@@ -30,5 +33,5 @@ neruda:
org:
postamble:
written_by: Écrit par %a
- with_emacs: 'avec %c et publié avec <a href="https://git.umaneti.net/neruda/about/">Neruda</a>'
+ with_emacs: 'avec %c et publié avec %N'
last_modification: dernière modification le %C
diff --git a/neruda.gemspec b/neruda.gemspec
index 0d481dc..0390b73 100644
--- a/neruda.gemspec
+++ b/neruda.gemspec
@@ -5,10 +5,10 @@ require './lib/neruda/version'
Gem::Specification.new do |s|
s.name = 'neruda'
s.version = Neruda::VERSION
- s.summary = 'A simplistic way to create an org-mode static website.'
+ s.summary = 'A simplistic way to create an Org static website.'
s.description = <<~DESC
- An opinionated org-mode static website generator.
- Write your org files, we take care of the rest.
+ An opinionated Org static website generator.
+ Write your org-mode files, we take care of the rest.
DESC
s.authors = ['Étienne Deparis']
s.email = 'etienne@depar.is'
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
'lib/neruda/config/lisp_config.rb',
'lib/neruda/config/org-config.el',
'lib/neruda/config/ox-neruda.el',
+ 'lib/neruda/emacs.rb',
'lib/neruda/index.rb',
'lib/neruda/index/atom_generator.rb',
'lib/neruda/index/org_generator.rb',
@@ -36,9 +37,11 @@ Gem::Specification.new do |s|
'locales/en.yml',
'locales/fr.yml',
# Default theme
+ 'themes/default/css/htmlize.css',
'themes/default/css/style.css',
- 'themes/default/fonts/Yanone_Kaffeesatz_400.woff',
- 'themes/default/fonts/Yanone_Kaffeesatz_400.woff2',
+ 'themes/default/img/bottom.png',
+ 'themes/default/img/tic.png',
+ 'themes/default/img/top.png',
# Others
'LICENSE']
s.executables = ['pablo']
diff --git a/spec/config_spec.rb b/spec/config_spec.rb
index 46591ea..d9ef58f 100644
--- a/spec/config_spec.rb
+++ b/spec/config_spec.rb
@@ -15,48 +15,46 @@ CONF2
describe 'With a config file' do
before(:all) do
- FileUtils.mkdir_p 'spec/data/config'
- IO.write('spec/data/config/config.yml', SAMPLE_CONFIG)
- Dir.chdir 'spec/data/config'
+ FileUtils.mkdir_p 'tmp/config'
+ IO.write('tmp/config/config.yml', SAMPLE_CONFIG)
+ Dir.chdir 'tmp/config'
+ end
+
+ before(:each) do
# When run with all other specs, config may have been already loaded
Neruda::Config.send(:load_settings)
end
+ after(:each) do
+ Neruda::Config.load_test({})
+ end
+
after(:all) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/config'
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/config'
end
it 'should parse it successfully' do
+ # Be sure to unset @config to force parsing
+ Neruda::Config.class_eval '@config = nil', __FILE__, __LINE__
conf = Neruda::Config.settings
expect(conf['author']).to eq('Tata')
expect(conf['title']).to eq('This is a website about test')
- end
-
- it 'should expose correct head header' do
- head = <<~HEAD
- <link rel="stylesheet" type="text/css" media="screen"
- href="/assets/css/style.css">
- <link rel="stylesheet" type="text/css" media="screen"
- href="/assets/css/htmlize.css">
- HEAD
- expect(Neruda::Config.send(:build_html_head)).to eq(head)
+ expect(conf['lang']).to eq('en')
+ expect(conf['theme']).to eq('default')
+ expect(conf['domain']).to eq('')
end
it 'should save it successfully' do
Neruda::Config.save('author' => 'Titi', 'title' => 'Nevermind',
'domain' => 'https://tutu.com')
expect(IO.read('config.yml')).to eq(SAMPLE_CONFIG_2)
- end
-
- it 'should expose correct head header' do
- head = <<~HEAD
- <link rel="stylesheet" type="text/css" media="screen"
- href="https://tutu.com/assets/css/style.css">
- <link rel="stylesheet" type="text/css" media="screen"
- href="https://tutu.com/assets/css/htmlize.css">
- HEAD
- expect(Neruda::Config.send(:build_html_head)).to eq(head)
+ conf = Neruda::Config.settings
+ expect(conf['author']).to eq('Titi')
+ expect(conf['title']).to eq('Nevermind')
+ expect(conf['lang']).to eq('en')
+ expect(conf['theme']).to eq('default')
+ expect(conf['domain']).to eq('https://tutu.com')
end
end
@@ -64,53 +62,251 @@ SAMPLE_CONFIG_3 = <<~CONF
---
author: Tata
title: This is a website with a blog
- blog_path: news
+ sources:
+ - src
+ - path: src/news
+ is_blog: true
+ - wrong: source
CONF
SAMPLE_CONFIG_4 = <<~CONF
---
author: Tata
title: This is a website with a blog
- blog_path: news
domain: https://test.com
+ sources:
+ - src
+ - path: news
+ is_blog: true
+ theme: my-theme
+ - path: other
+ theme: my-theme
CONF
describe 'With a blog config file' do
before(:all) do
- FileUtils.mkdir_p 'spec/data/config'
- Dir.chdir 'spec/data/config'
+ FileUtils.mkdir_p 'tmp/config'
+ Dir.chdir 'tmp/config'
+ end
+
+ after(:each) do
+ Neruda::Config.load_test({})
end
after(:all) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/config'
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/config'
+ end
+
+ it 'should list sources' do
+ IO.write('config.yml', SAMPLE_CONFIG_3)
+ Neruda::Config.send(:load_settings)
+ expect(Neruda::Config.sources.length).to eq(2)
+ expect(Neruda::Config.sources[0]['name']).to eq('src')
+ expect(Neruda::Config.sources[0]['path']).to(
+ eq(File.expand_path('src'))
+ )
+ expect(Neruda::Config.sources[0]['target']).to eq('src')
+ expect(Neruda::Config.sources[0]['is_blog']).to be(false)
+ expect(Neruda::Config.sources[0]['recursive']).to be(true)
+ expect(Neruda::Config.sources[1]['name']).to eq('news')
+ expect(Neruda::Config.sources[1]['path']).to(
+ eq(File.expand_path('src/news'))
+ )
+ expect(Neruda::Config.sources[1]['target']).to eq('news')
+ expect(Neruda::Config.sources[1]['is_blog']).to be(true)
+ expect(Neruda::Config.sources[1]['recursive']).to be(true)
+ end
+
+ it 'should generate projects hash' do
+ IO.write('config.yml', SAMPLE_CONFIG_3)
+ Neruda::Config.send(:load_settings)
+ projects = Neruda::Config.send(:org_generate_projects)
+ expect(projects).to have_key('news')
end
it 'should expose correct head header' do
IO.write('config.yml', SAMPLE_CONFIG_3)
Neruda::Config.send(:load_settings)
+ projects = Neruda::Config.sources
+ headers = Neruda::Config.send(:build_project_org_headers, projects[0])
head = <<~HEAD
- <link rel="stylesheet" type="text/css" media="screen"
- href="/assets/css/style.css">
- <link rel="stylesheet" type="text/css" media="screen"
- href="/assets/css/htmlize.css">
- <link rel="alternate" type="application/atom+xml" title="Atom 1.0"
- href="/feeds/index.xml" />
+ :html-head "<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"/assets/default/css/style.css\\\">
+ <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"/assets/default/css/htmlize.css\\\">"
+ :html-postamble "<p><span class=\\\"author\\\">Written by %a</span>
+ with %c, and published with %N</p>
+ <p class=\\\"date\\\">Last modification on %C</p>
+ <p class=\\\"validation\\\">%v</p>"
+ :html-head-include-default-style t
+ :html-head-include-scripts nil
HEAD
- expect(Neruda::Config.send(:build_html_head)).to eq(head)
+ expect(headers).to eq(head.strip)
end
it 'should expose correct head header with custom domain' do
IO.write('config.yml', SAMPLE_CONFIG_4)
Neruda::Config.send(:load_settings)
+ projects = Neruda::Config.sources
+ headers = Neruda::Config.send(:build_project_org_headers, projects[0])
+ head = <<~HEAD
+ :html-head "<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/default/css/style.css\\\">
+ <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/default/css/htmlize.css\\\">"
+ :html-postamble "<p><span class=\\\"author\\\">Written by %a</span>
+ with %c, and published with %N</p>
+ <p class=\\\"date\\\">Last modification on %C</p>
+ <p class=\\\"validation\\\">%v</p>"
+ :html-head-include-default-style t
+ :html-head-include-scripts nil
+ HEAD
+ expect(headers).to eq(head.strip)
+ headers = Neruda::Config.send(:build_project_org_headers, projects[1])
head = <<~HEAD
- <link rel="stylesheet" type="text/css" media="screen"
- href="https://test.com/assets/css/style.css">
- <link rel="stylesheet" type="text/css" media="screen"
- href="https://test.com/assets/css/htmlize.css">
- <link rel="alternate" type="application/atom+xml" title="Atom 1.0"
- href="https://test.com/feeds/index.xml" />
+ :html-head "<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/my-theme/css/style.css\\\">
+ <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/my-theme/css/htmlize.css\\\">
+ <link rel=\\\"alternate\\\" type=\\\"application/atom+xml\\\" title=\\\"Atom 1.0\\\"
+ href=\\\"https://test.com/feeds/index.xml\\\" />"
+ :html-postamble "<p><span class=\\\"author\\\">Written by %a</span>
+ with %c, and published with %N</p>
+ <p class=\\\"date\\\">Last modification on %C</p>
+ <p class=\\\"validation\\\">%v</p>"
+ :html-head-include-default-style t
+ :html-head-include-scripts nil
HEAD
- expect(Neruda::Config.send(:build_html_head)).to eq(head)
+ expect(headers).to eq(head.strip)
+ end
+
+ it 'should generate projects' do
+ IO.write('config.yml', SAMPLE_CONFIG_4)
+ Neruda::Config.send(:load_settings)
+ projects = Neruda::Config.send(:org_generate_projects)
+ srcconf = <<~SRCCONF
+ ("src"
+ :base-directory "#{Dir.pwd}/src"
+ :base-extension "org"
+ :recursive t
+ :publishing-directory "#{Dir.pwd}/public_html/src"
+ :publishing-function org-html-publish-to-html
+ :section-numbers nil
+ :with-toc nil
+ :html-head "<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/default/css/style.css\\\">
+ <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/default/css/htmlize.css\\\">"
+ :html-postamble "<p><span class=\\\"author\\\">Written by %a</span>
+ with %c, and published with %N</p>
+ <p class=\\\"date\\\">Last modification on %C</p>
+ <p class=\\\"validation\\\">%v</p>"
+ :html-head-include-default-style t
+ :html-head-include-scripts nil)
+ ("src-assets"
+ :base-directory "#{Dir.pwd}/src"
+ :base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|svg\\\\\\|pdf"
+ :recursive t
+ :publishing-directory "#{Dir.pwd}/public_html/src"
+ :publishing-function org-publish-attachment)
+
+ SRCCONF
+ blogconf = <<~BLOGCONF
+ ("news"
+ :base-directory "#{Dir.pwd}/news"
+ :base-extension "org"
+ :recursive t
+ :publishing-directory "#{Dir.pwd}/public_html/news"
+ :publishing-function org-html-publish-to-html
+ :section-numbers nil
+ :with-toc nil
+ :html-head "<link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/my-theme/css/style.css\\\">
+ <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" media=\\\"screen\\\"
+ href=\\\"https://test.com/assets/my-theme/css/htmlize.css\\\">
+ <link rel=\\\"alternate\\\" type=\\\"application/atom+xml\\\" title=\\\"Atom 1.0\\\"
+ href=\\\"https://test.com/feeds/index.xml\\\" />"
+ :html-postamble "<p><span class=\\\"author\\\">Written by %a</span>
+ with %c, and published with %N</p>
+ <p class=\\\"date\\\">Last modification on %C</p>
+ <p class=\\\"validation\\\">%v</p>"
+ :html-head-include-default-style t
+ :html-head-include-scripts nil)
+ ("news-assets"
+ :base-directory "#{Dir.pwd}/news"
+ :base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|svg\\\\\\|pdf"
+ :recursive t
+ :publishing-directory "#{Dir.pwd}/public_html/news"
+ :publishing-function org-publish-attachment)
+ ("theme-my-theme"
+ :base-directory "#{Dir.pwd}/themes/my-theme"
+ :base-extension "jpg\\\\\\|gif\\\\\\|png\\\\\\|js\\\\\\|css\\\\\\|otf\\\\\\|ttf\\\\\\|woff2?"
+ :recursive t
+ :publishing-directory "#{Dir.pwd}/public_html/assets/my-theme"
+ :publishing-function org-publish-attachment)
+
+ BLOGCONF
+ expect(projects).to have_key('src')
+ expect(projects).to have_key('news')
+ expect(projects['src']).to eq(srcconf)
+ expect(projects['news']).to eq(blogconf)
+ end
+
+ it 'should generate projects names list' do
+ IO.write('config.yml', SAMPLE_CONFIG_4)
+ Neruda::Config.send(:load_settings)
+ projects = Neruda::Config.send(:org_generate_projects)
+ expect(Neruda::Config.send(:project_names, projects)).to(
+ eq('"src" "src-assets" "news" "news-assets" "other" "other-assets" "theme-default" "theme-my-theme"')
+ )
+ end
+end
+
+describe 'Without a config file' do
+ before(:all) do
+ FileUtils.mkdir_p 'tmp/config2'
+ Dir.chdir 'tmp/config2'
+ end
+
+ before(:each) do
+ # When run with all other specs, config may have been already loaded
+ Neruda::Config.send(:load_settings)
+ end
+
+ after(:each) do
+ Neruda::Config.load_test({})
+ end
+
+ after(:all) do
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/config2'
+ end
+
+ it 'should use default config' do
+ conf = Neruda::Config.settings
+ author = ENV['USER'] || ''
+ expect(conf['author']).to eq(author)
+ expect(conf['lang']).to eq('en') # Defined in ENV in requirements.rb
+ expect(conf['public_folder']).to eq('public_html')
+ expect(conf['domain']).to eq('')
+ end
+
+ it 'should handle weird case' do
+ expect(Neruda::Config.send(:build_source, 'name' => 'wrong')).to be(nil)
+ expect(Neruda::Config.send(:build_source, :test)).to be(nil)
+ end
+end
+
+describe 'With config utils method' do
+ after(:each) do
+ FileUtils.rm 'tmp/__last_org_version__', force: true
+ Neruda::Config.class_eval '@org_version = nil', __FILE__, __LINE__
+ end
+
+ it 'should give current org version' do
+ Neruda::Config.class_eval '@org_version = nil', __FILE__, __LINE__
+ IO.write('tmp/__last_org_version__', 'test')
+ expect(Neruda::Config.org_last_version).to eq('test')
end
end
diff --git a/spec/data/content.org b/spec/data/content.org
index 63877e8..03ba67e 100644
--- a/spec/data/content.org
+++ b/spec/data/content.org
@@ -1,4 +1,5 @@
#+title: My first blog post?
+#+subtitle: What to do with that
#+date: <2019-06-13 jeu.>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet
diff --git a/spec/data/index_proof.html b/spec/data/index_proof.html
new file mode 100644
index 0000000..6277c58
--- /dev/null
+++ b/spec/data/index_proof.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<!-- Neruda Template: 5e83e25f9df9ce28b246d28f08f99cf4 -->
+
+<!-- __PUB_DATE__ -->
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<meta property="neruda-test" content="test">
+<title>My website</title>
+<meta name="generator" content="Org mode">
+<meta name="author" content="Tata">
+<link rel="stylesheet" type="text/css" media="screen" href="style.css">
+</head>
+<body>
+<div id="content">
+<header>
+<h1 class="title">My website</h1>
+</header><p>
+Nice content.
+</p>
+</div>
+<div id="postamble" class="status">
+<footer>Published by Neruda.</footer>
+</div>
+</body>
+</html>
diff --git a/spec/data/org-config-blog-proof.el b/spec/data/org-config-blog-proof.el
index 1e83696..cd95990 100644
--- a/spec/data/org-config-blog-proof.el
+++ b/spec/data/org-config-blog-proof.el
@@ -1,18 +1,19 @@
-;; Add custom org mode to load path
+;; Add org-mode to load path
(add-to-list 'load-path (expand-file-name "org-__ORG_VERSION__/lisp" "__TEST_DIR__"))
-;; Load modern version of htmlize.el
+;; Load last version of htmlize.el
(load-file (expand-file-name "htmlize.el" "__TEST_DIR__"))
;; Current project options
-(setq neruda/current-work-dir "__TEST_DIR__"
+(setq neruda/version "__VERSION__"
+ neruda/current-work-dir "__TEST_DIR__"
user-mail-address ""
user-full-name "Tata"
- org-html-metadata-timestamp-format "%A %-d of %B, %Y at %H:%M"
+ org-html-metadata-timestamp-format "%A %-d of %B, %Y at %R"
org-publish-project-alist
`(("org"
:base-directory "__TEST_DIR__/src"
:base-extension "org"
- :recursive t
+ :recursive nil
:exclude "tata\.org"
:publishing-directory "__TEST_DIR__/public_html"
:publishing-function org-html-publish-to-html
@@ -25,9 +26,27 @@
("org-assets"
:base-directory "__TEST_DIR__/src"
:base-extension "jpg\\|gif\\|png\\|svg\\|pdf"
- :recursive t
+ :recursive nil
:publishing-directory "__TEST_DIR__/public_html"
:publishing-function org-publish-attachment)
+ ("news"
+ :base-directory "__TEST_DIR__/src/news"
+ :base-extension "org"
+ :recursive t
+ :publishing-directory "__TEST_DIR__/public_html/news"
+ :publishing-function org-html-publish-to-html
+ :section-numbers nil
+ :with-toc nil
+ :html-head "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"style.css\"/>"
+ :html-postamble "<footer>Published by Neruda.</footer>"
+ :html-head-include-default-style nil
+ :html-head-include-scripts nil)
+ ("news-assets"
+ :base-directory "__TEST_DIR__/src/news"
+ :base-extension "jpg\\|gif\\|png\\|svg\\|pdf"
+ :recursive t
+ :publishing-directory "__TEST_DIR__/public_html/news"
+ :publishing-function org-publish-attachment)
("test"
:base-directory "__TEST_DIR__/titi/test"
:base-extension "org"
@@ -65,13 +84,13 @@
:recursive t
:publishing-directory "__TEST_DIR__/public_html/tata"
:publishing-function org-publish-attachment)
- ("theme"
+ ("theme-toto"
:base-directory "__TEST_DIR__/themes/toto"
:base-extension "jpg\\|gif\\|png\\|js\\|css\\|otf\\|ttf\\|woff2?"
:recursive t
- :publishing-directory "__TEST_DIR__/public_html/assets"
+ :publishing-directory "__TEST_DIR__/public_html/assets/toto"
:publishing-function org-publish-attachment)
- ("website" :components ("org" "org-assets" "test" "test-assets" "tata" "tata-assets" "theme"))))
+ ("website" :components ("org" "org-assets" "news" "news-assets" "test" "test-assets" "tata" "tata-assets" "theme-toto"))))
;; Load neruda lib
(load-file (expand-file-name "ox-neruda.el" "__BASE_DIR__/lib/neruda/config"))
diff --git a/spec/data/org-config-proof.el b/spec/data/org-config-proof.el
index 155bdcd..1639ae4 100644
--- a/spec/data/org-config-proof.el
+++ b/spec/data/org-config-proof.el
@@ -1,18 +1,19 @@
-;; Add custom org mode to load path
+;; Add org-mode to load path
(add-to-list 'load-path (expand-file-name "org-__ORG_VERSION__/lisp" "__TEST_DIR__"))
-;; Load modern version of htmlize.el
+;; Load last version of htmlize.el
(load-file (expand-file-name "htmlize.el" "__TEST_DIR__"))
;; Current project options
-(setq neruda/current-work-dir "__TEST_DIR__"
+(setq neruda/version "__VERSION__"
+ neruda/current-work-dir "__TEST_DIR__"
user-mail-address ""
user-full-name "Tata"
- org-html-metadata-timestamp-format "%A %-d of %B, %Y at %H:%M"
+ org-html-metadata-timestamp-format "%A %-d of %B, %Y at %R"
org-publish-project-alist
`(("org"
:base-directory "__TEST_DIR__/src"
:base-extension "org"
- :recursive t
+ :recursive nil
:exclude "tata\.org"
:publishing-directory "__TEST_DIR__/public_html"
:publishing-function org-html-publish-to-html
@@ -25,9 +26,27 @@
("org-assets"
:base-directory "__TEST_DIR__/src"
:base-extension "jpg\\|gif\\|png\\|svg\\|pdf"
- :recursive t
+ :recursive nil
:publishing-directory "__TEST_DIR__/public_html"
:publishing-function org-publish-attachment)
+ ("news"
+ :base-directory "__TEST_DIR__/src/news"
+ :base-extension "org"
+ :recursive t
+ :publishing-directory "__TEST_DIR__/public_html/news"
+ :publishing-function org-html-publish-to-html
+ :section-numbers nil
+ :with-toc nil
+ :html-head "<link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"style.css\"/>"
+ :html-postamble "<footer>Published by Neruda.</footer>"
+ :html-head-include-default-style nil
+ :html-head-include-scripts nil)
+ ("news-assets"
+ :base-directory "__TEST_DIR__/src/news"
+ :base-extension "jpg\\|gif\\|png\\|svg\\|pdf"
+ :recursive t
+ :publishing-directory "__TEST_DIR__/public_html/news"
+ :publishing-function org-publish-attachment)
("test"
:base-directory "__TEST_DIR__/titi/test"
:base-extension "org"
@@ -65,13 +84,13 @@
:recursive t
:publishing-directory "__TEST_DIR__/public_html/tata"
:publishing-function org-publish-attachment)
- ("theme"
+ ("theme-default"
:base-directory "__BASE_DIR__/themes/default"
:base-extension "jpg\\|gif\\|png\\|js\\|css\\|otf\\|ttf\\|woff2?"
:recursive t
- :publishing-directory "__TEST_DIR__/public_html/assets"
+ :publishing-directory "__TEST_DIR__/public_html/assets/default"
:publishing-function org-publish-attachment)
- ("website" :components ("org" "org-assets" "test" "test-assets" "tata" "tata-assets" "theme"))))
+ ("website" :components ("org" "org-assets" "news" "news-assets" "test" "test-assets" "tata" "tata-assets" "theme-default"))))
;; Load neruda lib
(load-file (expand-file-name "ox-neruda.el" "__BASE_DIR__/lib/neruda/config"))
diff --git a/spec/data/test2.org b/spec/data/test2.org
index c094c1a..b4dbb08 100644
--- a/spec/data/test2.org
+++ b/spec/data/test2.org
@@ -2,6 +2,7 @@
#+date: <2019-06-11 mar.>
#+author: Titi
#+language: es
+#+description: Lorem ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec aliquet
sed lectus id convallis. Sed pharetra mauris mauris, vitae fringilla
diff --git a/spec/index_spec.rb b/spec/index_spec.rb
index c3a9dcc..809bde8 100644
--- a/spec/index_spec.rb
+++ b/spec/index_spec.rb
@@ -1,7 +1,31 @@
# frozen_string_literal: true
-SAMPLE_INDEX = <<~IDX1
- #+title: Blog
+SAMPLE_ALL_INDEX = <<~INDEX
+ #+title: All tags
+ #+author: Test
+ #+language: en
+
+ * By alphabetical order
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+ - [[http://perdu.com/tags/toto.html][toto]] (1)
+ - [[http://perdu.com/tags/tutu.html][tutu]] (2)
+
+ * By publication number
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+ - [[http://perdu.com/tags/tutu.html][tutu]] (2)
+ - [[http://perdu.com/tags/toto.html][toto]] (1)
+INDEX
+
+SAMPLE_PROJECT_INDEX = <<~BLOG_IDX
+ #+title: writings
#+author: Test
#+language: en
@@ -11,8 +35,9 @@ SAMPLE_INDEX = <<~IDX1
:UNNUMBERED: notoc
:END:
- - *[[../data/test3.html][My third article]]* / Published on Tuesday 11th of June at 23:42
- - *[[../data/test2.html][My second article]]* / Published on Tuesday 11th of June
+ - *[[http://perdu.com/other/test3.html][My third article]]* / Published on Tuesday 11th of June at 23:42
+ - *[[http://perdu.com/test2.html][My second article]]* / Published on Tuesday 11th of June \\\\
+ Lorem ipsum
* Unsorted
:PROPERTIES:
@@ -20,8 +45,53 @@ SAMPLE_INDEX = <<~IDX1
:UNNUMBERED: notoc
:END:
- - *[[../data/test1.html][My sweet article]]*
-IDX1
+ - *[[http://perdu.com/test1.html][My sweet article]]*
+BLOG_IDX
+
+SAMPLE_NO_REC_INDEX = <<~INDEX
+ #+title: All tags
+ #+author: Test
+ #+language: en
+
+ * By alphabetical order
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+ - [[http://perdu.com/tags/tutu.html][tutu]] (1)
+
+ * By publication number
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+ - [[http://perdu.com/tags/tutu.html][tutu]] (1)
+INDEX
+
+SAMPLE_PROJECT_NO_REC_INDEX = <<~BLOG_IDX
+ #+title: writings
+ #+author: Test
+ #+language: en
+
+ * 2019
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-year
+ :UNNUMBERED: notoc
+ :END:
+
+ - *[[http://perdu.com/test2.html][My second article]]* / Published on Tuesday 11th of June \\\\
+ Lorem ipsum
+
+ * Unsorted
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-year
+ :UNNUMBERED: notoc
+ :END:
+
+ - *[[http://perdu.com/test1.html][My sweet article]]*
+BLOG_IDX
SAMPLE_ATOM = <<~ATOM
<?xml version="1.0" encoding="utf-8"?>
@@ -32,15 +102,15 @@ SAMPLE_ATOM = <<~ATOM
<title>Blog</title>
<link href="http://perdu.com/feeds/index.xml" rel="self" type="application/atom+xml"/>
- <link href="http://perdu.com/blog" rel="alternate" type="text/html" title="Blog"/>
- <updated>%s</updated>
+ <link href="http://perdu.com" rel="alternate" type="text/html" title="Blog"/>
+ <updated>%<date>s</updated>
<author><name>Test</name></author>
<id>urn:md5:75d53866bcb20465b3287cf237234464</id>
<generator uri="https://git.umaneti.net/neruda/about/">Neruda</generator>
<entry>
<title>My third article</title>
- <link href="http://perdu.com/data/test3.html" rel="alternate" type="text/html"
+ <link href="http://perdu.com/other/test3.html" rel="alternate" type="text/html"
title="My third article"/>
<id>urn:md5:8865383febd94ddf9df318267af5ae85</id>
<published>2019-06-11T23:42:10+00:00</published>
@@ -51,17 +121,17 @@ SAMPLE_ATOM = <<~ATOM
<entry>
<title>My second article</title>
- <link href="http://perdu.com/data/test2.html" rel="alternate" type="text/html"
+ <link href="http://perdu.com/test2.html" rel="alternate" type="text/html"
title="My second article"/>
<id>urn:md5:123104bd8bb4c61e02a1e2a136e2fd6b</id>
<published>2019-06-11T00:00:00+00:00</published>
<author><name>Titi</name></author>
- <content type="html"></content>
+ <content type="html">Lorem ipsum</content>
</entry>
<entry>
<title>My sweet article</title>
- <link href="http://perdu.com/data/test1.html" rel="alternate" type="text/html"
+ <link href="http://perdu.com/test1.html" rel="alternate" type="text/html"
title="My sweet article"/>
<id>urn:md5:c47532bbb1e2883c902071591ae1ec9b</id>
<published></published>
@@ -73,70 +143,78 @@ SAMPLE_ATOM = <<~ATOM
ATOM
describe 'With blog settings' do
- before(:all) do
- ENV['LANG'] = 'en'
- end
-
describe 'with working org files' do
before(:each) do
- Neruda::Config.load_test('title' => 'Blog',
- 'author' => 'Test',
- 'public_path' => 'spec/data/indexes',
- 'blog_path' => 'blog',
- 'domain' => 'http://perdu.com')
+ FileUtils.mkdir_p 'tmp/blog/writings/other'
+ FileUtils.mkdir_p 'tmp/blog/output'
+ FileUtils.cp(
+ ['spec/data/test1.org',
+ 'spec/data/test2.org'],
+ 'tmp/blog/writings'
+ )
+ FileUtils.cp 'spec/data/test3.org', 'tmp/blog/writings/other'
+ Dir.chdir 'tmp/blog'
@now = DateTime.now
- @index = Neruda::Index.new(['spec/data/test1.org',
- 'spec/data/test2.org',
- 'spec/data/test3.org'])
- end
-
- it 'should have generated three indexes', core: true do
- expect(@index.entries.length).to eq(3)
end
- it 'should generate a main index', core: true do
- expect(@index.to_s).to eq(SAMPLE_INDEX.strip)
- end
-
- it 'should generate an atom feed', core: true do
- index_date_str = @index.date.strftime('%Y-%m-%d %H:%M')
- expect(index_date_str).to eq(@now.strftime('%Y-%m-%d %H:%M'))
- expect(@index.to_atom).to eq(SAMPLE_ATOM.strip % @index.date.rfc3339)
+ after(:each) do
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/blog', force: true
+ Neruda::Config.load_test({})
end
- describe 'when trying to save them' do
+ describe 'with recursive config' do
before(:each) do
- FileUtils.mkdir_p 'spec/data/indexes/src/blog'
- Dir.chdir 'spec/data/indexes'
+ Neruda::Config.load_test(
+ 'title' => 'Blog',
+ 'author' => 'Test',
+ 'public_folder' => 'output',
+ 'domain' => 'http://perdu.com',
+ 'sources' => [
+ { 'path' => 'writings',
+ 'target' => '.',
+ 'is_blog' => true }
+ ]
+ )
+ @index = Neruda::Index.new
end
- after(:each) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/indexes', force: true
+ it 'should have generated two indexes', core: true do
+ expect(@index.entries.length).to eq(2)
+ expect(@index.empty?).to be(false)
end
- it 'should correctly save one index', core: true do
- @index.write_org('index')
- expect(File.exist?('src/blog/index.org')).to be(true)
- expect(IO.read('src/blog/index.org')).to \
- eq(SAMPLE_INDEX.strip)
+ it 'should generate a main index', core: true do
+ expect(@index.to_s).to eq(SAMPLE_ALL_INDEX.strip)
+ expect(@index.to_s('writings', is_project: true)).to(
+ eq(SAMPLE_PROJECT_INDEX.strip)
+ )
end
- it 'should correctly save one atom feed', core: true do
- @index.write_atom('index')
- expect(File.exist?('public_html/feeds/index.xml')).to be(true)
- expect(IO.read('public_html/feeds/index.xml')).to \
- eq(SAMPLE_ATOM.strip % @index.date.rfc3339)
+ it 'should generate an atom feed', core: true do
+ index_date_str = @index.date.strftime('%Y-%m-%d %H:%M')
+ expect(index_date_str).to eq(@now.strftime('%Y-%m-%d %H:%M'))
+ expect(@index.to_atom).to(
+ eq(format(SAMPLE_ATOM.strip, date: @index.date.rfc3339))
+ )
end
- it 'should write it all', core: true do
- @index.write_all
- expect(File.exist?('src/blog/index.org')).to be(true)
- expect(File.exist?('src/tags/toto.org')).to be(true)
- expect(File.exist?('src/tags/tutu.org')).to be(true)
- expect(File.exist?('public_html/feeds/index.xml')).to be(true)
- expect(File.exist?('public_html/feeds/toto.xml')).to be(true)
- expect(File.exist?('public_html/feeds/tutu.xml')).to be(true)
+ it 'should generate the right org-header' do
+ header = ['#+title: ', '#+author: Test', '#+language: en'].join("\n").strip
+ expect(@index.send(:org_header)).to eq(header)
+ expect(@index.send(:org_header, 'index')).to eq(header)
+ expect(@index.send(:org_header, 'Test', is_tag: true)).to eq(header)
+
+ header = ['#+title: Blog', '#+author: Test', '#+language: en'].join("\n").strip
+ expect(@index.send(:org_header, is_tag: false)).to eq(header)
+ expect(@index.send(:org_header, 'index', is_tag: false)).to eq(header)
+
+ header = ['#+title: Test', '#+author: Test', '#+language: en'].join("\n")
+ expect(@index.send(:org_header, 'Test', is_tag: false)).to eq(header.strip)
+
+ header = ['#+title: tutu', '#+author: Test', '#+language: en'].join("\n").strip
+ expect(@index.send(:org_header, 'tutu')).to eq(header)
+ expect(@index.send(:org_header, 'tutu', is_tag: true)).to eq(header)
end
it 'should list tags by name', core: true do
@@ -152,88 +230,419 @@ describe 'With blog settings' do
it 'should raise an error if sort_by is called with bad argument', core: true do
expect { @index.sort_by(:test) }.to raise_error(ArgumentError)
end
+
+ describe 'when trying to save them' do
+ it 'should correctly save one index', core: true do
+ @index.write_org('index')
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(IO.read('tags/index.org')).to eq(SAMPLE_ALL_INDEX.strip)
+ end
+
+ it 'should correctly saved one blog index', core: true do
+ @index.send(:write_all_blog_home, false)
+ expect(File.exist?('writings/index.org')).to be(true)
+ expect(IO.read('writings/index.org')).to eq(SAMPLE_PROJECT_INDEX.strip)
+ end
+
+ it 'should correctly saved one blog index, even verbosely', core: true do
+ @index.send(:write_all_blog_home, true)
+ expect(File.exist?('writings/index.org')).to be(true)
+ expect(IO.read('writings/index.org')).to eq(SAMPLE_PROJECT_INDEX.strip)
+ end
+
+ it 'should correctly save one atom feed', core: true do
+ @index.write_atom('index')
+ expect(File.exist?('output/feeds/index.xml')).to be(true)
+ expect(IO.read('output/feeds/index.xml')).to(
+ eq(format(SAMPLE_ATOM.strip, date: @index.date.rfc3339))
+ )
+ end
+
+ it 'should write it all', core: true do
+ @index.write_all
+ expect(File.exist?('writings/index.org')).to be(true)
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(File.exist?('tags/toto.org')).to be(true)
+ expect(File.exist?('tags/tutu.org')).to be(true)
+ expect(File.exist?('output/feeds/index.xml')).to be(true)
+ expect(File.exist?('output/feeds/toto.xml')).to be(true)
+ expect(File.exist?('output/feeds/tutu.xml')).to be(true)
+ end
+ end
+ end
+
+ describe 'without recursive config' do
+ before(:each) do
+ Neruda::Config.load_test(
+ 'title' => 'Blog',
+ 'author' => 'Test',
+ 'public_folder' => 'output',
+ 'domain' => 'http://perdu.com',
+ 'sources' => [
+ { 'path' => 'writings',
+ 'target' => '.',
+ 'recursive' => false,
+ 'is_blog' => true }
+ ]
+ )
+ @index = Neruda::Index.new
+ end
+
+ it 'should have generated one index', core: true do
+ expect(@index.entries.length).to eq(1)
+ expect(@index.empty?).to be(false)
+ end
+
+ it 'should generate a main index', core: true do
+ expect(@index.to_s).to eq(SAMPLE_NO_REC_INDEX.strip)
+ expect(@index.to_s('writings', is_project: true)).to(
+ eq(SAMPLE_PROJECT_NO_REC_INDEX.strip)
+ )
+ end
+
+ it 'should write it all', core: true do
+ @index.write_all
+ expect(File.exist?('writings/index.org')).to be(true)
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(File.exist?('tags/toto.org')).to be(false)
+ expect(File.exist?('tags/tutu.org')).to be(true)
+ expect(File.exist?('output/feeds/index.xml')).to be(true)
+ expect(File.exist?('output/feeds/toto.xml')).to be(false)
+ expect(File.exist?('output/feeds/tutu.xml')).to be(true)
+ end
end
end
-end
-describe 'Without blog settings' do
- describe 'with working org files' do
+ describe 'without org files' do
before(:each) do
- Neruda::Config.load_test('title' => 'My site',
- 'author' => 'Test',
- 'public_path' => 'spec/data/indexes',
- 'domain' => 'http://perdu.com')
+ FileUtils.mkdir_p 'tmp/blog/writings'
+ FileUtils.mkdir_p 'tmp/blog/output'
+ Dir.chdir 'tmp/blog'
+ Neruda::Config.load_test(
+ 'title' => 'Blog',
+ 'author' => 'Test',
+ 'public_folder' => 'output',
+ 'domain' => 'http://perdu.com',
+ 'sources' => [
+ { 'path' => 'writings',
+ 'target' => '.',
+ 'is_blog' => true }
+ ]
+ )
@now = DateTime.now
- @index = Neruda::Index.new(['spec/data/test1.org',
- 'spec/data/test2.org',
- 'spec/data/test3.org'])
+ @index = Neruda::Index.new
end
- it 'should not have generated three indexes', core: true do
- expect(@index.entries.length).to eq(1) # default index one
+ after(:each) do
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/blog', force: true
+ Neruda::Config.load_test({})
end
- it 'should generate an empty main index', core: true do
- empty_index = <<~EMPTY_INDEX
- #+title: My site
+ it 'should have generated no index', core: true do
+ expect(@index.entries.length).to eq(0)
+ expect(@index.empty?).to be(true)
+ end
+
+ it 'should generate a main index', core: true do
+ empty_index = <<~INDEX
+ #+title: All tags
+ #+author: Test
+ #+language: en
+
+ * By alphabetical order
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+
+ * By publication number
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+ INDEX
+ expect(@index.to_s).to eq(empty_index)
+ empty_project_index = <<~INDEX
+ #+title: writings
#+author: Test
#+language: en
- EMPTY_INDEX
- expect(@index.to_s).to eq(empty_index.strip)
+ INDEX
+ expect(@index.to_s('writings', is_project: true)).to(
+ eq(empty_project_index.strip)
+ )
end
- it 'should generate an empty atom feed', core: true do
+ it 'should generate an atom feed', core: true do
index_date_str = @index.date.strftime('%Y-%m-%d %H:%M')
expect(index_date_str).to eq(@now.strftime('%Y-%m-%d %H:%M'))
- empty_atom = <<~EMPTY_ATOM
+ empty_atom = <<~ATOM
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xml:lang="en">
- <title>My site</title>
+ <title>Blog</title>
<link href="http://perdu.com/feeds/index.xml" rel="self" type="application/atom+xml"/>
- <link href="http://perdu.com/" rel="alternate" type="text/html" title="My site"/>
- <updated>%s</updated>
+ <link href="http://perdu.com" rel="alternate" type="text/html" title="Blog"/>
+ <updated>%<date>s</updated>
<author><name>Test</name></author>
<id>urn:md5:75d53866bcb20465b3287cf237234464</id>
<generator uri="https://git.umaneti.net/neruda/about/">Neruda</generator>
</feed>
- EMPTY_ATOM
- expect(@index.to_atom).to eq(empty_atom.strip % @index.date.rfc3339)
+ ATOM
+ expect(@index.to_atom).to(
+ eq(format(empty_atom.strip, date: @index.date.rfc3339))
+ )
end
- describe 'when trying to save them' do
- before(:each) do
- FileUtils.mkdir_p 'spec/data/indexes/src/blog'
- Dir.chdir 'spec/data/indexes'
- end
+ it 'should correctly save one index', core: true do
+ @index.write_org('index')
+ expect(File.exist?('tags/index.org')).to be(true)
+ empty_index = <<~INDEX
+ #+title: All tags
+ #+author: Test
+ #+language: en
- after(:each) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/indexes', force: true
- end
+ * By alphabetical order
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
- it 'should not save one index', core: true do
- @index.write_org('index')
- expect(File.exist?('src/blog/index.org')).to be(false)
- end
- it 'should not save one atom feed', core: true do
- @index.write_atom('index')
- expect(File.exist?('public_html/feeds/index.xml')).to be(false)
- end
+ * By publication number
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+ INDEX
+ expect(IO.read('tags/index.org')).to eq(empty_index)
+ end
- it 'should not write it all', core: true do
- @index.write_all
- expect(File.exist?('src/blog/index.org')).to be(false)
- expect(File.exist?('src/tags/toto.org')).to be(false)
- expect(File.exist?('src/tags/tutu.org')).to be(false)
- expect(File.exist?('public_html/feeds/index.xml')).to be(false)
- expect(File.exist?('public_html/feeds/toto.xml')).to be(false)
- expect(File.exist?('public_html/feeds/tutu.xml')).to be(false)
- end
+ it 'should correctly saved one blog index', core: true do
+ @index.send(:write_all_blog_home, false)
+ expect(File.exist?('writings/index.org')).to be(true)
+ empty_project_index = <<~INDEX
+ #+title: writings
+ #+author: Test
+ #+language: en
+ INDEX
+ expect(IO.read('writings/index.org')).to eq(empty_project_index.strip)
+ end
+
+ it 'should correctly save one atom feed', core: true do
+ @index.write_atom('index')
+ expect(File.exist?('output/feeds/index.xml')).to be(true)
+ empty_atom = <<~ATOM
+ <?xml version="1.0" encoding="utf-8"?>
+ <feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+ xml:lang="en">
+
+ <title>Blog</title>
+ <link href="http://perdu.com/feeds/index.xml" rel="self" type="application/atom+xml"/>
+ <link href="http://perdu.com" rel="alternate" type="text/html" title="Blog"/>
+ <updated>%<date>s</updated>
+ <author><name>Test</name></author>
+ <id>urn:md5:75d53866bcb20465b3287cf237234464</id>
+ <generator uri="https://git.umaneti.net/neruda/about/">Neruda</generator>
+ </feed>
+ ATOM
+ expect(IO.read('output/feeds/index.xml')).to(
+ eq(format(empty_atom.strip, date: @index.date.rfc3339))
+ )
end
+
+ it 'should write it all', core: true do
+ @index.write_all
+ expect(File.exist?('writings/index.org')).to be(true)
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(File.exist?('output/feeds/index.xml')).to be(true)
+ end
+ end
+end
+
+describe 'Without blog settings' do
+ before(:each) do
+ FileUtils.mkdir_p 'tmp/txt/writings'
+ FileUtils.mkdir_p 'tmp/txt/output'
+ FileUtils.cp(
+ ['spec/data/test1.org',
+ 'spec/data/test2.org',
+ 'spec/data/test3.org'],
+ 'tmp/txt/writings'
+ )
+ Dir.chdir 'tmp/txt'
+ Neruda::Config.load_test(
+ 'title' => 'My site',
+ 'author' => 'Test',
+ 'public_folder' => 'output',
+ 'domain' => 'http://perdu.com',
+ 'sources' => [{ 'path' => 'writings', 'target' => '.' }]
+ )
+ @now = DateTime.now
+ @index = Neruda::Index.new
+ end
+
+ after(:each) do
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/txt', force: true
+ Neruda::Config.load_test({})
+ end
+
+ it 'should not have generated any indexes', core: true do
+ expect(@index.entries.length).to eq(0)
+ expect(@index.empty?).to be(true)
+ end
+
+ it 'should generate an empty main index', core: true do
+ empty_index = <<~EMPTY_INDEX
+ #+title: All tags
+ #+author: Test
+ #+language: en
+
+ * By alphabetical order
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+
+ * By publication number
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+ EMPTY_INDEX
+ expect(@index.to_s).to eq(empty_index)
+ end
+
+ it 'should generate an empty atom feed', core: true do
+ index_date_str = @index.date.strftime('%Y-%m-%d %H:%M')
+ expect(index_date_str).to eq(@now.strftime('%Y-%m-%d %H:%M'))
+ empty_atom = <<~EMPTY_ATOM
+ <?xml version="1.0" encoding="utf-8"?>
+ <feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+ xml:lang="en">
+
+ <title>My site</title>
+ <link href="http://perdu.com/feeds/index.xml" rel="self" type="application/atom+xml"/>
+ <link href="http://perdu.com" rel="alternate" type="text/html" title="My site"/>
+ <updated>%<date>s</updated>
+ <author><name>Test</name></author>
+ <id>urn:md5:75d53866bcb20465b3287cf237234464</id>
+ <generator uri="https://git.umaneti.net/neruda/about/">Neruda</generator>
+ </feed>
+ EMPTY_ATOM
+ expect(@index.to_atom).to(
+ eq(format(empty_atom.strip, date: @index.date.rfc3339))
+ )
+ end
+
+ it 'should not save one index', core: true do
+ @index.write_org('index')
+ expect(File.exist?('tags/index.org')).to be(false)
+ end
+
+ it 'should not save one atom feed', core: true do
+ @index.write_atom('index')
+ expect(File.exist?('output/feeds/index.xml')).to be(false)
+ end
+
+ it 'should not write it all', core: true do
+ @index.write_all
+ expect(File.exist?('writings/index.org')).to be(false)
+ expect(File.exist?('tags/index.org')).to be(false)
+ expect(File.exist?('tags/toto.org')).to be(false)
+ expect(File.exist?('tags/tutu.org')).to be(false)
+ expect(File.exist?('output/feeds/index.xml')).to be(false)
+ expect(File.exist?('output/feeds/toto.xml')).to be(false)
+ expect(File.exist?('output/feeds/tutu.xml')).to be(false)
+ end
+end
+
+describe 'Without neither blog settings nor site title' do
+ before(:each) do
+ FileUtils.mkdir_p 'tmp/txt/writings'
+ FileUtils.mkdir_p 'tmp/txt/output'
+ FileUtils.cp 'spec/data/test1.org', 'tmp/txt/writings'
+ Dir.chdir 'tmp/txt'
+ Neruda::Config.load_test(
+ 'public_folder' => 'output',
+ 'domain' => 'http://perdu.com',
+ 'sources' => [{ 'path' => 'writings', 'target' => '.' }]
+ )
+ @now = DateTime.now
+ @index = Neruda::Index.new
+ end
+
+ after(:each) do
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/txt', force: true
+ Neruda::Config.load_test({})
+ end
+
+ it 'should not have generated any indexes', core: true do
+ expect(@index.entries.length).to eq(0)
+ expect(@index.empty?).to be(true)
+ end
+
+ it 'should generate an empty main index', core: true do
+ empty_index = <<~EMPTY_INDEX
+ #+title: All tags
+ #+author: alice
+ #+language: en
+
+ * By alphabetical order
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+
+
+ * By publication number
+ :PROPERTIES:
+ :HTML_CONTAINER_CLASS: index-tags
+ :UNNUMBERED: notoc
+ :END:
+ EMPTY_INDEX
+ expect(@index.to_s).to eq(empty_index)
+ end
+
+ it 'should generate an empty atom feed', core: true do
+ index_date_str = @index.date.strftime('%Y-%m-%d %H:%M')
+ expect(index_date_str).to eq(@now.strftime('%Y-%m-%d %H:%M'))
+ empty_atom = <<~EMPTY_ATOM
+ <?xml version="1.0" encoding="utf-8"?>
+ <feed xmlns="http://www.w3.org/2005/Atom"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+ xml:lang="en">
+
+ <title>All tags</title>
+ <link href="http://perdu.com/feeds/index.xml" rel="self" type="application/atom+xml"/>
+ <link href="http://perdu.com" rel="alternate" type="text/html" title="All tags"/>
+ <updated>%<date>s</updated>
+ <author><name>alice</name></author>
+ <id>urn:md5:75d53866bcb20465b3287cf237234464</id>
+ <generator uri="https://git.umaneti.net/neruda/about/">Neruda</generator>
+ </feed>
+ EMPTY_ATOM
+ expect(@index.to_atom).to(
+ eq(format(empty_atom.strip, date: @index.date.rfc3339))
+ )
+ end
+
+ it 'should not save any index', core: true do
+ @index.write_org('index')
+ expect(File.exist?('tags/index.org')).to be(false)
+ @index.write_atom('index')
+ expect(File.exist?('output/feeds/index.xml')).to be(false)
end
end
diff --git a/spec/org_file_spec.rb b/spec/org_file_spec.rb
index efae3d8..e3b56fb 100644
--- a/spec/org_file_spec.rb
+++ b/spec/org_file_spec.rb
@@ -20,6 +20,15 @@ describe 'With working org files' do
expect(o.lang).to eq('es')
end
+ it 'should parse with a complete date', core: true do
+ o = Neruda::OrgFile.new('spec/data/test3.org')
+ expect(o.title).to eq('My third article')
+ expect(o.date).to eq(DateTime.strptime('2019-06-11 23:42:10', '%Y-%m-%d %H:%M:%S'))
+ expect(o.timekey).to eq('20190611234210')
+ expect(o.datestring(:short)).to eq('2019-06-11')
+ expect(o.format('%i - (%t)')).to eq('2019-06-11 - (My third article)')
+ end
+
it 'should parse with a complete date, but partial time', core: true do
o = Neruda::OrgFile.new('spec/data/test4.org')
expect(o.title).to eq('Fourth test')
@@ -29,13 +38,10 @@ describe 'With working org files' do
expect(o.format('%i - (%t)')).to eq('2019-07-25 - (Fourth test)')
end
- it 'should parse with a complete date', core: true do
- o = Neruda::OrgFile.new('spec/data/test3.org')
- expect(o.title).to eq('My third article')
- expect(o.date).to eq(DateTime.strptime('2019-06-11 23:42:10', '%Y-%m-%d %H:%M:%S'))
- expect(o.timekey).to eq('20190611234210')
- expect(o.datestring(:short)).to eq('2019-06-11')
- expect(o.format('%i - (%t)')).to eq('2019-06-11 - (My third article)')
+ it 'should find a subtitle', core: true do
+ o = Neruda::OrgFile.new('spec/data/content.org')
+ expect(o.title).to eq('My first blog post?')
+ expect(o.subtitle).to eq('What to do with that')
end
end
# rubocop:enable Style/FormatStringToken
@@ -46,13 +52,19 @@ describe 'With various titles' do
expect(Neruda::OrgFile.slug('TotO')).to eq('toto')
expect(Neruda::OrgFile.slug('Tôto')).to eq('toto')
expect(Neruda::OrgFile.slug('Tôto tata')).to eq('toto-tata')
- expect(Neruda::OrgFile.slug('ÀùïỸç/+*= trulu°`')).to eq('auiyc-trulu')
+ expect(Neruda::OrgFile.slug('ÀùéïỸç/+*= truñlu°`')).to eq('aueiyc-trunlu')
end
end
describe 'Without a working file' do
+ before(:each) do
+ FileUtils.mkdir_p 'tmp/org_test'
+ Dir.chdir 'tmp/org_test'
+ end
+
after(:each) do
- FileUtils.rm 'spec/data/__test__.org', force: true
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/org_test', force: true
end
it 'should raise if file_name is nil and try to write', core: true do
@@ -62,7 +74,7 @@ describe 'Without a working file' do
it 'should return a new org file structure', core: true do
now = DateTime.now
- o = Neruda::OrgFile.new('spec/data/__test__.org', title: 'test')
+ o = Neruda::OrgFile.new('__test__.org', title: 'test')
expect(o.title).to eq('test')
o_date_str = o.date.strftime('%Y-%m-%d %H:%M')
expect(o_date_str).to eq(now.strftime('%Y-%m-%d %H:%M'))
@@ -76,9 +88,10 @@ describe 'Without a working file' do
#+author: #{o.author}
#+language: en
+
CONTENT
- expect(File.exist?('spec/data/__test__.org')).to be(true)
- expect(IO.read('spec/data/__test__.org')).to eq(empty_content)
+ expect(File.exist?('__test__.org')).to be(true)
+ expect(IO.read('__test__.org')).to eq(empty_content)
end
end
@@ -100,19 +113,23 @@ describe 'With configuration' do
it 'should compute the right html_file path for existing sources', core: true do
o = Neruda::OrgFile.new('spec/data/test1.org')
- expect(o.html_file).to eq('/data/test1.html')
+ expect(o.html_file).to eq('data/test1.html')
Neruda::Config.load_test('domain' => 'http://perdu.com')
o = Neruda::OrgFile.new('spec/data/test1.org')
- expect(o.html_file).to eq('/data/test1.html')
+ expect(o.html_file).to eq('data/test1.html')
o = Neruda::OrgFile.new('spec/data/content.org')
- expect(o.html_file).to eq('/data/content.html')
+ expect(o.html_file).to eq('data/content.html')
# The following are weird tests. We begin to test theoric stuff here
- Neruda::Config.load_test('domain' => 'http://perdu.com',
- 'blog_path' => 'data')
+ Neruda::Config.load_test(
+ 'domain' => 'http://perdu.com',
+ 'sources' => [
+ { 'path' => 'data' }
+ ]
+ )
o = Neruda::OrgFile.new('spec/data/test1.org')
- expect(o.html_file).to eq('/data/test1.html')
+ expect(o.html_file).to eq('data/test1.html')
o = Neruda::OrgFile.new('spec/data/content.org')
- expect(o.html_file).to eq('/data/content.html')
+ expect(o.html_file).to eq('data/content.html')
end
it 'should compute the right url for existing sources', core: true do
@@ -124,8 +141,12 @@ describe 'With configuration' do
o = Neruda::OrgFile.new('spec/data/content.org')
expect(o.url).to eq('http://perdu.com/data/content.html')
# The following are weird tests. We begin to test theoric stuff here
- Neruda::Config.load_test('domain' => 'http://perdu.com',
- 'blog_path' => 'data')
+ Neruda::Config.load_test(
+ 'domain' => 'http://perdu.com',
+ 'sources' => [
+ { 'path' => 'data' }
+ ]
+ )
o = Neruda::OrgFile.new('spec/data/test1.org')
expect(o.url).to eq('http://perdu.com/data/test1.html')
o = Neruda::OrgFile.new('spec/data/content.org')
@@ -133,30 +154,97 @@ describe 'With configuration' do
end
it 'should compute the right html_file path for theoritical sources', core: true do
- expect(Neruda::OrgFile.target_for_source('src/test.org')).to \
- eq('public_html/test.html')
- expect(Neruda::OrgFile.target_for_source('src/blog/test.org')).to \
- eq('public_html/blog/test.html')
- expect(Neruda::OrgFile.target_for_source('src/blog/toto/tata.org')).to \
- eq('public_html/blog/toto/tata.html')
- expect(Neruda::OrgFile.target_for_source('src/blog/toto/content.org')).to \
- eq('public_html/blog/toto/content.html')
- expect(Neruda::OrgFile.target_for_source('~/tata/tutu/content.org')).to \
- eq('public_html/tutu/content.html')
- expect(Neruda::OrgFile.target_for_source('~/tata/blog/content.org')).to \
- eq('public_html/blog/content.html')
- end
-
- it 'should compute the right source path for theoritical targets', core: true do
- expect(Neruda::OrgFile.source_for_target('public_html/test.html')).to \
- eq('src/test.org')
- expect(Neruda::OrgFile.source_for_target('public_html/blog/test.html')).to \
- eq('src/blog/test.org')
- lp = 'public_html/blog/toto/tata.html'
- expect(Neruda::OrgFile.source_for_target(lp)).to \
- eq('src/blog/toto/tata.org')
- lp = 'public_html/blog/toto/content.html'
- expect(Neruda::OrgFile.source_for_target(lp)).to \
- eq('src/blog/toto/content.org')
+ expect(Neruda::OrgFile.target_for_source(nil, nil)).to be(nil)
+ target = Neruda::OrgFile.target_for_source('src/test.org', nil)
+ expect(target).to eq('public_html/src/test.html')
+ target = Neruda::OrgFile.target_for_source('not/known/at/all.org', nil)
+ expect(target).to eq('public_html/at/all.html')
+ target = Neruda::OrgFile.target_for_source(
+ 'not/known/at/all.org', nil, with_public_folder: false
+ )
+ expect(target).to eq('at/all.html')
+ project = { 'path' => 'src', 'target' => '.' }
+ target = Neruda::OrgFile.target_for_source('src/test.org', project)
+ expect(target).to eq('public_html/test.html')
+ target = Neruda::OrgFile.target_for_source(
+ 'src/test.org', project, with_public_folder: false
+ )
+ expect(target).to eq('test.html')
+ target = Neruda::OrgFile.target_for_source(
+ 'src/blog/test.org', project
+ )
+ expect(target).to eq('public_html/blog/test.html')
+ target = Neruda::OrgFile.target_for_source(
+ 'src/blog/toto/tata.org', project
+ )
+ expect(target).to eq('public_html/blog/toto/tata.html')
+ target = Neruda::OrgFile.target_for_source(
+ 'src/blog/toto/content.org', project
+ )
+ expect(target).to eq('public_html/blog/toto/content.html')
+ project = { 'path' => '~/tata', 'target' => '.' }
+ target = Neruda::OrgFile.target_for_source(
+ '~/tata/tutu/content.org', project
+ )
+ expect(target).to eq('public_html/tutu/content.html')
+ target = Neruda::OrgFile.target_for_source(
+ '~/tata/blog/content.org', project
+ )
+ expect(target).to eq('public_html/blog/content.html')
+ end
+end
+
+describe 'With a fake sources structure' do
+ before(:each) do
+ FileUtils.mkdir_p 'tmp/test_target/src/blog/toto'
+ FileUtils.mkdir_p 'tmp/test_target/writings'
+ Dir.chdir 'tmp/test_target'
+ IO.write 'src/test.org', 'Lorem ipsum.'
+ FileUtils.touch(
+ ['src/blog/test.org', 'src/blog/toto/tata.org',
+ 'src/blog/toto/content.org', 'writings/notes.org']
+ )
+ Neruda::Config.load_test(
+ 'sources' => [{ 'path' => 'src', 'target' => '.' }, 'writings']
+ )
+ end
+
+ after(:each) do
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/test_target', force: true
+ end
+
+ it 'should use file name as title when title is empty' do
+ o = Neruda::OrgFile.new('src/test.org')
+ expect(o.title).to eq('src/test.org')
+ end
+
+ it 'should compute the right source path', core: true do
+ lp = Neruda::OrgFile.source_for_target('public_html/test.html')
+ expect(lp).to eq(File.expand_path('src/test.org'))
+ lp = Neruda::OrgFile.source_for_target('public_html/blog/test.html')
+ expect(lp).to eq(File.expand_path('src/blog/test.org'))
+ lp = Neruda::OrgFile.source_for_target('public_html/blog/toto/tata.html')
+ expect(lp).to eq(File.expand_path('src/blog/toto/tata.org'))
+ lp = Neruda::OrgFile.source_for_target(
+ 'public_html/blog/toto/content.html'
+ )
+ expect(lp).to eq(File.expand_path('src/blog/toto/content.org'))
+ end
+
+ it 'should identify a project for a given file path' do
+ ps = Neruda::OrgFile.project_for_source('src/test.org')
+ expect(ps).to eq(Neruda::Config.sources[0])
+ ps = Neruda::OrgFile.project_for_source('not/known.org')
+ expect(ps).to be(nil)
+ end
+
+ it 'should identify a source for a given published file' do
+ s = Neruda::OrgFile.source_for_target('public_html/writings/notes.html')
+ expect(s).to eq(File.expand_path('writings/notes.org'))
+ s = Neruda::OrgFile.source_for_target('public_html/test.html')
+ expect(s).to eq(File.expand_path('src/test.org'))
+ s = Neruda::OrgFile.source_for_target('public_html/not/known.html')
+ expect(s).to be(nil)
end
end
diff --git a/spec/rake_org_spec.rb b/spec/rake_org_spec.rb
index b3f22c3..4f8b390 100644
--- a/spec/rake_org_spec.rb
+++ b/spec/rake_org_spec.rb
@@ -1,14 +1,11 @@
# frozen_string_literal: true
require 'rake'
-require 'open-uri'
describe 'With working org files' do
before(:all) do
init_testing_website
@org_dir = "org-#{Neruda::Config.org_last_version}"
- # When run with all other specs, config may have been already loaded
- Neruda::Config.send(:load_settings)
@rake = Rake.application
@rake.raw_load_rakefile
Rake.verbose(false)
@@ -17,15 +14,18 @@ describe 'With working org files' do
before(:each) do
@rake.options.build_all = true
@rake.tasks.each(&:reenable)
+ Neruda::Config.send(:load_settings)
end
after(:each) do
+ Dir.glob('org-[0-9.]*').each { |ov| FileUtils.rm_r(ov, force: true) }
FileUtils.rm ['.dir-locals.el', 'org-config.el'], force: true
+ Neruda::Config.load_test({})
end
after(:all) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/website_testing', force: true
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/website_testing', force: true
end
it 'should compile org-config.el', rake: true do
@@ -36,6 +36,7 @@ describe 'With working org files' do
proof_content = IO.read(proof)
.gsub(/__TEST_DIR__/, Dir.pwd)
.gsub(/__BASE_DIR__/, base_dir)
+ .gsub(/__VERSION__/, Neruda::VERSION)
.gsub(/__ORG_VERSION__/, Neruda::Config.org_last_version)
expect(IO.read('org-config.el')).to eq(proof_content)
end
@@ -51,9 +52,9 @@ describe 'With working org files' do
proof_content = IO.read(proof)
.gsub(/__TEST_DIR__/, Dir.pwd)
.gsub(/__BASE_DIR__/, base_dir)
+ .gsub(/__VERSION__/, Neruda::VERSION)
.gsub(/__ORG_VERSION__/, Neruda::Config.org_last_version)
expect(IO.read('org-config.el')).to eq(proof_content)
- Neruda::Config.send(:load_settings)
end
it 'should create .dir-locals.el', rake: true do
@@ -65,21 +66,27 @@ describe 'With working org files' do
)
end
- it 'Should install org-mode', rake: true do
- FileUtils.mkdir 'org-2.3'
- expect(Dir.exist?('org-2.3')).to be(true)
+ it 'Should install Org', rake: true do
@rake.invoke_task('org:install')
expect(File.exist?('org-config.el')).to be(true)
expect(File.exist?('.dir-locals.el')).to be(true)
expect(File.exist?("#{@org_dir}/lisp/org-loaddefs.el")).to be(true)
+ end
+
+ it 'Should remove old Org version while installing', rake: true do
+ FileUtils.mkdir 'org-2.3'
+ expect(Dir.exist?('org-2.3')).to be(true)
+ @rake.invoke_task('org:install')
expect(Dir.exist?('org-2.3')).to be(false)
end
- it 'Should install org-mode in verbose mode', rake: true do
+ it 'Should install Org in verbose mode', rake: true do
# This one is mainly for coverage
FileUtils.rm_r @org_dir, force: true
Rake.verbose(true)
@rake.invoke_task('org:install')
+ @rake.tasks.each(&:reenable)
+ @rake.invoke_task('org:install') # To also check coverage
expect(File.exist?('org-config.el')).to be(true)
expect(File.exist?('.dir-locals.el')).to be(true)
expect(File.exist?("#{@org_dir}/lisp/org-loaddefs.el")).to be(true)
diff --git a/spec/rake_site_spec.rb b/spec/rake_site_spec.rb
index 867cfcd..51a61ca 100644
--- a/spec/rake_site_spec.rb
+++ b/spec/rake_site_spec.rb
@@ -1,15 +1,34 @@
# frozen_string_literal: true
require 'rake'
+require 'open-uri'
+
+def init_rake_and_install_org
+ # When run with all other specs, config may have been already loaded
+ Neruda::Config.send(:load_settings)
+ rake = Rake.application
+ rake.raw_load_rakefile
+ Rake.verbose(false)
+ rake.options.build_all = true
+ rake.tasks.each(&:reenable)
+ tarball = File.expand_path(
+ "../tmp/org-#{Neruda::Config.org_last_version}.tar.gz",
+ __dir__
+ )
+ FileUtils.mkdir_p 'tmp'
+ FileUtils.cp tarball, 'tmp'
+ rake.invoke_task('org:install')
+ rake
+end
def write_base_files
+ FileUtils.mkdir_p 'src/news'
org_content = <<~ORG
#+title: Index file
My website
ORG
IO.write('src/index.org', org_content)
- FileUtils.mkdir_p ['src/news/test1', 'src/news/test2']
file1 = <<~ORG
#+title: Index file
#+keywords: toto, titi
@@ -33,8 +52,8 @@ describe 'With a testing website' do
end
after(:all) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/website_testing', force: true
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/website_testing', force: true
end
describe 'building org files' do
@@ -49,7 +68,7 @@ describe 'With a testing website' do
end
after(:each) do
- FileUtils.rm 'public_html/index.html', force: true
+ FileUtils.rm_r ['tmp', 'src', 'public_html', 'tags'], force: true
end
it 'should build something', rake: true do
@@ -71,64 +90,172 @@ describe 'With a testing website' do
expect(File.exist?('public_html/tutu.html')).to be(true)
end
+ it 'should fail gracefully with wrong project', rake: true do
+ expect { @rake.invoke_task('site:build:one[very/wrong.org]') }.to(
+ output("No project found for very/wrong.org\n").to_stderr
+ )
+ end
+
+ it 'should fail gracefully with wrong file in project', rake: true do
+ expect { @rake.invoke_task('site:build:one[src/wrong.org]') }.to(
+ output(/Aborting/).to_stderr
+ )
+ end
+
+ it 'should build one specific file even in verbose mode', rake: true do
+ o = Neruda::OrgFile.new('src/tutu.org', title: 'Tutu test')
+ o.write
+ Rake.verbose(true)
+ @rake.invoke_task('site:build:one[src/tutu.org]')
+ expect(File.exist?('public_html/index.html')).to be(false)
+ expect(File.exist?('public_html/tutu.html')).to be(true)
+ end
+
it 'should return an error if no file is given in build:one', rake: true do
expect { @rake.invoke_task('site:build:one') }.to \
output("No source file given\n").to_stderr
end
- end
- describe 'generate indexes process' do
- before(:all) do
- write_base_files
+ describe 'trying preview mode' do
+ before(:each) do
+ @now_str = DateTime.now.strftime('%A %-d of %B, %Y at %R')
+ @rake.invoke_task('site:build')
+ @webrick_app = Thread.new do
+ @rake.invoke_task('site:preview')
+ end
+ sleep 1 # Necessary to let webrick start
+ end
+
+ after(:each) do
+ @webrick_app.exit # Be sure to kill test server
+ @webrick_app.join # Be patient before quitting example
+ end
+
+ it 'should be viewable with preview', rake: true do
+ home_page = URI('http://localhost:5000/index.html').open.read
+ proof = File.expand_path('data/index_proof.html', __dir__)
+ proof_content = IO.read(proof).gsub(/__PUB_DATE__/, @now_str)
+ expect(home_page).to eq(proof_content)
+ style = URI('http://localhost:5000/assets/default/css/style.css').open.read
+ proof = File.expand_path('../themes/default/css/style.css', __dir__)
+ expect(style.force_encoding('utf-8')).to eq(IO.read(proof))
+ end
+
+ it 'should serve index', rake: true do
+ home_page = URI('http://localhost:5000/').open.read
+ proof = File.expand_path('data/index_proof.html', __dir__)
+ proof_content = IO.read(proof).gsub(/__PUB_DATE__/, @now_str)
+ expect(home_page).to eq(proof_content)
+ end
+
+ it 'should be viewable with routes testing', rake: true do
+ home_page = URI('http://localhost:5000/test').open.read
+ proof = File.expand_path('data/index_proof.html', __dir__)
+ proof_content = IO.read(proof).gsub(/__PUB_DATE__/, @now_str)
+ expect(home_page).to eq(proof_content)
+ end
+
+ it 'should send an error if a page is not found', rake: true do
+ expect { URI('http://localhost:5000/not_found.html').open.read }.to(
+ raise_error(/404 Not Found/)
+ )
+ end
end
+ end
+ describe 'generate indexes process' do
before(:each) do
+ write_base_files
@rake.options.build_all = true
@rake.tasks.each(&:reenable)
+ Neruda::Config.send(:load_settings)
end
after(:each) do
- FileUtils.rm_r ['tmp', 'src/tags', 'public_html'], force: true
+ FileUtils.rm_r ['tmp', 'src', 'public_html', 'tags'], force: true
end
- after(:all) do
- FileUtils.rm_r ['src/index.org', 'src/news']
- end
+ describe 'without blog setting', rake: true do
+ before(:each) do
+ old_conf = Neruda::Config.settings.dup
+ old_conf['sources'][1]['is_blog'] = false
+ Neruda::Config.load_test(old_conf)
+ end
+
+ it 'should not generate index', rake: true do
+ @rake.invoke_task('site:index')
+ expect(File.exist?('src/news/index.org')).to be(false)
+ expect(File.exist?('tags/index.org')).to be(false)
+ expect(File.exist?('tags/toto.org')).to be(false)
+ expect(File.exist?('tags/titi.org')).to be(false)
+ expect(File.exist?('public_html/feeds/index.xml')).to be(false)
+ expect(File.exist?('public_html/feeds/toto.xml')).to be(false)
+ expect(File.exist?('public_html/feeds/titi.xml')).to be(false)
+ end
+
+ it 'should not generate index when calling build', rake: true do
+ @rake.invoke_task('site:build')
+ expect(File.exist?('src/news/index.org')).to be(false)
+ expect(File.exist?('tags/index.org')).to be(false)
+ expect(File.exist?('tags/toto.org')).to be(false)
+ expect(File.exist?('tags/titi.org')).to be(false)
+ expect(File.exist?('public_html/news/index.html')).to be(false)
+ expect(File.exist?('public_html/tags/index.html')).to be(false)
+ expect(File.exist?('public_html/tags/index.html')).to be(false)
+ expect(File.exist?('public_html/tags/toto.html')).to be(false)
+ expect(File.exist?('public_html/tags/titi.html')).to be(false)
+ expect(File.exist?('public_html/feeds/index.xml')).to be(false)
+ expect(File.exist?('public_html/feeds/toto.xml')).to be(false)
+ expect(File.exist?('public_html/feeds/titi.xml')).to be(false)
+ end
- it 'should not generate index without blog folder', rake: true do
- @rake.invoke_task('site:index')
- expect(File.exist?('src/news/index.org')).to be(false)
- expect(File.exist?('src/tags/toto.org')).to be(false)
- expect(File.exist?('src/tags/titi.org')).to be(false)
- expect(File.exist?('public_html/feeds/index.xml')).to be(false)
- expect(File.exist?('public_html/feeds/toto.xml')).to be(false)
- expect(File.exist?('public_html/feeds/titi.xml')).to be(false)
+ it 'should not list tags', rake: true do
+ expect { @rake.invoke_task('tags:name') }.to output('').to_stdout
+ expect { @rake.invoke_task('tags:weight') }.to output('').to_stdout
+ end
end
- it 'should not generate index without blog folder when calling build', rake: true do
- @rake.invoke_task('site:build')
- expect(File.exist?('src/news/index.org')).to be(false)
- expect(File.exist?('src/tags/toto.org')).to be(false)
- expect(File.exist?('src/tags/titi.org')).to be(false)
- expect(File.exist?('public_html/news/index.html')).to be(false)
- expect(File.exist?('public_html/tags/toto.html')).to be(false)
- expect(File.exist?('public_html/tags/titi.html')).to be(false)
- expect(File.exist?('public_html/feeds/index.xml')).to be(false)
- expect(File.exist?('public_html/feeds/toto.xml')).to be(false)
- expect(File.exist?('public_html/feeds/titi.xml')).to be(false)
+ describe 'with wrong blog settings', rake: true do
+ before(:each) do
+ old_conf = Neruda::Config.settings.dup
+ old_conf['sources'][1]['path'] = 'src/test'
+ Neruda::Config.load_test(old_conf)
+ end
+
+ it 'should not generate index', rake: true do
+ @rake.invoke_task('site:index')
+ expect(File.exist?('src/test/index.org')).to be(false)
+ expect(File.exist?('public_html/feeds/index.xml')).to be(false)
+ end
+
+ it 'should not generate index when calling build', rake: true do
+ @rake.invoke_task('site:build')
+ expect(File.exist?('src/test/index.org')).to be(false)
+ expect(File.exist?('tags/index.org')).to be(false)
+ expect(File.exist?('tags/toto.org')).to be(false)
+ expect(File.exist?('tags/titi.org')).to be(false)
+ expect(File.exist?('public_html/test/index.html')).to be(false)
+ expect(File.exist?('public_html/tags/index.html')).to be(false)
+ expect(File.exist?('public_html/feeds/index.xml')).to be(false)
+ end
+
+ it 'should not list tags', rake: true do
+ expect { @rake.invoke_task('tags:name') }.to output('').to_stdout
+ expect { @rake.invoke_task('tags:weight') }.to output('').to_stdout
+ end
end
describe 'with a correct blog path' do
before(:each) do
Rake.verbose(false)
- Neruda::Config.load_test('blog_path' => 'news')
end
it 'should generate indexes', rake: true do
@rake.invoke_task('site:index')
expect(File.exist?('src/news/index.org')).to be(true)
- expect(File.exist?('src/tags/toto.org')).to be(true)
- expect(File.exist?('src/tags/titi.org')).to be(true)
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(File.exist?('tags/toto.org')).to be(true)
+ expect(File.exist?('tags/titi.org')).to be(true)
expect(File.exist?('public_html/feeds/index.xml')).to be(true)
expect(File.exist?('public_html/feeds/toto.xml')).to be(true)
expect(File.exist?('public_html/feeds/titi.xml')).to be(true)
@@ -138,8 +265,9 @@ describe 'With a testing website' do
Rake.verbose(true)
@rake.invoke_task('site:index')
expect(File.exist?('src/news/index.org')).to be(true)
- expect(File.exist?('src/tags/toto.org')).to be(true)
- expect(File.exist?('src/tags/titi.org')).to be(true)
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(File.exist?('tags/toto.org')).to be(true)
+ expect(File.exist?('tags/titi.org')).to be(true)
expect(File.exist?('public_html/feeds/index.xml')).to be(true)
expect(File.exist?('public_html/feeds/toto.xml')).to be(true)
expect(File.exist?('public_html/feeds/titi.xml')).to be(true)
@@ -148,9 +276,12 @@ describe 'With a testing website' do
it 'should generate indexes, even with build', rake: true do
@rake.invoke_task('site:build')
expect(File.exist?('src/news/index.org')).to be(true)
- expect(File.exist?('src/tags/toto.org')).to be(true)
- expect(File.exist?('src/tags/titi.org')).to be(true)
+ expect(File.exist?('tags/index.org')).to be(true)
+ expect(File.exist?('tags/toto.org')).to be(true)
+ expect(File.exist?('tags/titi.org')).to be(true)
expect(File.exist?('public_html/news/index.html')).to be(true)
+ expect(File.exist?('public_html/tags/index.html')).to be(true)
+ expect(File.exist?('public_html/tags/index.html')).to be(true)
expect(File.exist?('public_html/tags/toto.html')).to be(true)
expect(File.exist?('public_html/tags/titi.html')).to be(true)
expect(File.exist?('public_html/feeds/index.xml')).to be(true)
@@ -159,20 +290,16 @@ describe 'With a testing website' do
end
it 'should list all tags by name', rake: true do
- expect { @rake.invoke_task('tags:name') }.to output("toto (2)\ntiti (1)\n").to_stdout
+ expect { @rake.invoke_task('tags:name') }.to(
+ output("toto (2)\ntiti (1)\n").to_stdout
+ )
end
it 'should list all tags by weight', rake: true do
- expect { @rake.invoke_task('tags:weight') }.to output("titi (1)\ntoto (2)\n").to_stdout
+ expect { @rake.invoke_task('tags:weight') }.to(
+ output("titi (1)\ntoto (2)\n").to_stdout
+ )
end
end
-
- it 'should use website title for blog index', rake: true do
- Neruda::Config.load_test('blog_path' => 'news', 'title' => 'Big title')
- Rake.verbose(true) # Check this too
- @rake.invoke_task('site:index')
- expect(File.exist?('src/news/index.org')).to be(true)
- expect(File.exist?('src/tags/toto.org')).to be(true)
- end
end
end
diff --git a/spec/requirements.rb b/spec/requirements.rb
index faab8d0..473e951 100644
--- a/spec/requirements.rb
+++ b/spec/requirements.rb
@@ -4,11 +4,10 @@ require 'fileutils'
require 'simplecov'
require 'r18n-core'
-R18n.set('en', File.expand_path('../locales', __dir__))
+R18n.default_places = File.expand_path('../locales', __dir__)
+R18n.set 'en'
R18n::Filters.on(:named_variables)
-$LOAD_PATH.unshift('./lib')
-
SimpleCov.start do
# Activate new covering precision
enable_coverage :branch
@@ -23,21 +22,26 @@ end
# The following requires other components automatically
require 'neruda/org_file'
+require 'neruda/utils'
+
+ENV['LANG'] = 'en'
+ENV['USER'] = 'alice'
# rubocop:disable Metrics/MethodLength
def init_testing_website
- FileUtils.mkdir_p 'spec/data/website_testing'
- Dir.chdir 'spec/data/website_testing'
+ FileUtils.mkdir_p 'tmp/website_testing'
+ Dir.chdir 'tmp/website_testing'
rakefile = <<~RAKE
# frozen_string_literal: true
require 'r18n-core'
- R18n.set('en', '../../../locales')
+ R18n.default_places = '../../locales'
+ R18n.set 'en'
R18n::Filters.on(:named_variables)
- $LOAD_PATH.unshift('../../../lib')
+ $LOAD_PATH.unshift('../../lib')
- Dir.glob('../../../lib/tasks/*.rake').each { |r| import r }
+ Dir.glob('../../lib/tasks/*.rake').each { |r| import r }
task default: 'site:build'
RAKE
@@ -46,13 +50,19 @@ def init_testing_website
---
author: Tata
title: This is a website about test
- exclude_pattern: tata\\.org
org-html:
html-head-include-default-style: nil
html-head: |
<link rel="stylesheet" type="text/css" media="screen" href="style.css"/>
html-postamble: '<footer>Published by Neruda.</footer>'
- external_sources:
+ sources:
+ - name: org
+ path: src
+ target: .
+ recursive: false
+ exclude: tata\\.org
+ - path: src/news
+ is_blog: true
- path: 'titi/test'
recursive: nil
exclude: ugly\\.org
@@ -62,19 +72,20 @@ def init_testing_website
selector: title
content: |
<meta property="neruda-test" content="test"/>
+ preview:
+ routes:
+ /test: public_html/index.html
CONF
IO.write('config.yml', config)
end
# rubocop:enable Metrics/MethodLength
-def init_rake_and_install_org
- # When run with all other specs, config may have been already loaded
- Neruda::Config.send(:load_settings)
- rake = Rake.application
- rake.raw_load_rakefile
- Rake.verbose(false)
- rake.options.build_all = true
- rake.tasks.each(&:reenable)
- rake.invoke_task('org:install')
- rake
+RSpec.configure do |config|
+ config.before(:suite) do
+ Neruda::Utils.download_org
+ end
+
+ config.after(:suite) do
+ FileUtils.rm_r 'tmp', force: true
+ end
end
diff --git a/spec/templater_spec.rb b/spec/templater_spec.rb
index 003dba2..d534040 100644
--- a/spec/templater_spec.rb
+++ b/spec/templater_spec.rb
@@ -5,18 +5,18 @@ require 'neruda/templater'
describe 'With a testing website' do
before(:all) do
init_testing_website
- FileUtils.mkdir 'public_html'
@metatag = '<meta property="test" content="TEST">'
@metatag_digest = Digest::MD5.hexdigest(@metatag)
end
after(:all) do
- Dir.chdir File.expand_path('../', __dir__)
- FileUtils.rm_r 'spec/data/website_testing', force: true
+ Dir.chdir File.expand_path('..', __dir__)
+ FileUtils.rm_r 'tmp/website_testing', force: true
end
describe 'Simple customize process' do
before(:each) do
+ FileUtils.mkdir 'public_html'
html_base = <<~HTML
<!DOCTYPE html>
<html>
@@ -32,7 +32,8 @@ describe 'With a testing website' do
end
after(:each) do
- FileUtils.rm 'public_html/customize_test.html'
+ FileUtils.rm_r ['public_html', 'src'], force: true
+ Neruda::Config.load_test({})
end
it 'should customize a given html file with simple template' do
@@ -60,6 +61,39 @@ describe 'With a testing website' do
expect(IO.read('public_html/customize_test.html')).to eq(result)
end
+ it 'should customize a given html file with a given org object' do
+ Neruda::Config.load_test(
+ 'templates' => [
+ { 'selector' => 'title',
+ 'content' => @metatag }
+ ]
+ )
+ org_content = <<~ORG
+ #+title: Index file
+
+ My website
+ ORG
+ FileUtils.mkdir 'src'
+ IO.write('src/index.org', org_content)
+ o = Neruda::OrgFile.new('src/index.org')
+ Neruda::Templater.customize_output('public_html/customize_test.html', o)
+ result = <<~RESULT
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <!-- Neruda Template: #{@metatag_digest} -->
+
+ <title>My website</title>
+ <meta property="test" content="TEST">
+ </head>
+ <body>
+ <h1>My website</h1>
+ </body>
+ </html>
+ RESULT
+ expect(IO.read('public_html/customize_test.html')).to eq(result)
+ end
+
it 'should customize a given html file with before' do
Neruda::Config.load_test(
'templates' => [
@@ -137,6 +171,45 @@ describe 'With a testing website' do
expect(IO.read('public_html/customize_test.html')).to eq(result)
end
+ it 'should customize a given html file with previous comments in head' do
+ Neruda::Config.load_test(
+ 'templates' => [
+ { 'selector' => 'body>h1',
+ 'type' => 'replace',
+ 'content' => '<p>Toto tata</p>' }
+ ]
+ )
+ html_base = <<~HTML
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <!-- This is a test comment -->
+ <title>My website</title>
+ </head>
+ <body>
+ <h1>My website</h1>
+ </body>
+ </html>
+ HTML
+ IO.write('public_html/customize_test2.html', html_base)
+ Neruda::Templater.customize_output('public_html/customize_test2.html')
+ result = <<~RESULT
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <!-- Neruda Template: #{Digest::MD5.hexdigest('<p>Toto tata</p>')} -->
+
+ <!-- This is a test comment -->
+ <title>My website</title>
+ </head>
+ <body>
+ <p>Toto tata</p>
+ </body>
+ </html>
+ RESULT
+ expect(IO.read('public_html/customize_test2.html')).to eq(result)
+ end
+
it 'should not customize a given html file with wrong templates' do
result = IO.read('public_html/customize_test.html')
Neruda::Config.load_test(
@@ -150,10 +223,18 @@ describe 'With a testing website' do
Neruda::Templater.customize_output('public_html/customize_test.html')
expect(IO.read('public_html/customize_test.html')).to eq(result)
end
+
+ it 'should not customize a given html file with no templates' do
+ result = IO.read('public_html/customize_test.html')
+ Neruda::Config.load_test({})
+ Neruda::Templater.customize_output('public_html/customize_test.html')
+ expect(IO.read('public_html/customize_test.html')).to eq(result)
+ end
end
describe 'Multiple customize call' do
before(:each) do
+ FileUtils.mkdir_p 'public_html/customize'
html_base = <<~HTML
<!DOCTYPE html>
<html>
@@ -166,7 +247,6 @@ describe 'With a testing website' do
</html>
HTML
IO.write('public_html/customize_test.html', html_base)
- FileUtils.mkdir_p 'public_html/customize'
@html_base = <<~HTML
<!DOCTYPE html>
<html>
@@ -204,8 +284,8 @@ describe 'With a testing website' do
end
after(:each) do
- FileUtils.rm_r 'public_html/customize', force: true
- FileUtils.rm 'public_html/customize_test.html'
+ FileUtils.rm_r 'public_html', force: true
+ Neruda::Config.load_test({})
end
it 'should customize a file on a specific path' do
@@ -225,6 +305,7 @@ describe 'With a testing website' do
describe 'Multiple path to customize' do
before(:each) do
+ FileUtils.mkdir_p ['public_html/customize', 'public_html/other']
html_base = <<~HTML
<!DOCTYPE html>
<html>
@@ -237,7 +318,6 @@ describe 'With a testing website' do
</html>
HTML
IO.write('public_html/customize_test.html', html_base)
- FileUtils.mkdir_p ['public_html/customize', 'public_html/other']
@html_base = <<~HTML
<!DOCTYPE html>
<html>
@@ -278,8 +358,8 @@ describe 'With a testing website' do
end
after(:each) do
- FileUtils.rm_r ['public_html/customize', 'public_html/other'], force: true
- FileUtils.rm 'public_html/customize_test.html'
+ FileUtils.rm_r 'public_html', force: true
+ Neruda::Config.load_test({})
end
it 'should customize a file on a specific path' do
diff --git a/spec/utils_spec.rb b/spec/utils_spec.rb
index b15c7b2..84eed32 100644
--- a/spec/utils_spec.rb
+++ b/spec/utils_spec.rb
@@ -5,30 +5,30 @@ require 'neruda/utils'
describe 'With theoritical pablo arguments' do
it 'should return decorated options' do
expect(Neruda::Utils.decorate_option('-a')).to \
- eq(['-a AUTHOR', '--author AUTHOR'])
+ eq(['-aAUTHOR', '--author AUTHOR'])
expect(Neruda::Utils.decorate_option('-l')).to \
- eq(['-l LOCALE', '--lang LOCALE'])
+ eq(['-lLOCALE', '--lang LOCALE'])
expect(Neruda::Utils.decorate_option('-d')).to \
eq(['-d', '--directory'])
end
it 'should summarize basic commands' do
basic_cmd = [
- " -h, --help Display help for a command and exit\n",
- " -V, --version Display Neruda version and exit\n"
+ " -h, --help Display help for a command and exit.\n",
+ ' -V, --version Display Neruda version and exit.'
].join
expect(Neruda::Utils.summarize_command('basic')).to eq(basic_cmd)
end
it 'should summarize open commands' do
basic_cmd = [
- " -a AUTHOR, --author AUTHOR\n",
- " -l LOCALE, --lang LOCALE\n",
- " -t TITLE, --title TITLE\n",
- " -d, --directory Wrap the new org file in a named folder\n",
- " -p PATH, --path PATH Path to the new file\n",
- " -v, --verbose\n",
- " -h, --help Display help for a command and exit\n"
+ " -aAUTHOR, --author AUTHOR \n",
+ " -lLOCALE, --lang LOCALE \n",
+ " -tTITLE, --title TITLE \n",
+ " -d, --directory Wrap the new org file in this named folder.\n",
+ " -pPATH, --path PATH Path to the new file.\n",
+ " -v, --verbose \n",
+ ' -h, --help Display help for a command and exit.'
].join
expect(Neruda::Utils.summarize_command('open')).to eq(basic_cmd)
end
@@ -36,10 +36,52 @@ describe 'With theoritical pablo arguments' do
it 'should list possible commands' do
basic_cmd = [
" init Initialize your Neruda instance (you just need to do it once).\n",
- " preview Start a test webserver to preview your website on http://127.0.0.1:5000\n",
- " open Open or create an org file for edition.\n",
- " help Alias for the -h switch.\n"
+ " config Alias for init.\n",
+ " preview Start a test web server to preview your website on http://127.0.0.1:5000\n",
+ " open Open or create an org file.\n",
+ " edit Alias for open.\n",
+ " build Compile your org files to HTML.\n",
+ " publish Push local changes to your public web server.\n",
+ ' help Alias for the -h switch.'
].join
expect(Neruda::Utils.list_commands).to eq(basic_cmd)
end
+
+ it 'should resolve alias' do
+ expect(Neruda::Utils.resolve_possible_alias('init')).to eq('init')
+ expect(Neruda::Utils.resolve_possible_alias('config')).to eq('init')
+ expect(Neruda::Utils.resolve_possible_alias('build')).to eq('build')
+ expect(Neruda::Utils.resolve_possible_alias('edit')).to eq('open')
+ expect(Neruda::Utils.resolve_possible_alias('wrong')).to eq('basic')
+ end
+
+ describe 'with config' do
+ after(:each) do
+ Neruda::Config.load_test({})
+ end
+
+ it 'should select the right throbber' do
+ Neruda::Config.load_test({})
+ frames = Neruda::Utils.send(:select_throbber_frames)
+ expect(frames).to(
+ eq(['⠁ ⠂ ⠄ ⡀ ⠄ ⠂ ⠁', '⠂ ⠁ ⠂ ⠄ ⡀ ⠄ ⠂', '⠄ ⠂ ⠁ ⠂ ⠄ ⡀ ⠄',
+ '⡀ ⠄ ⠂ ⠁ ⠂ ⠄ ⡀', '⠄ ⡀ ⠄ ⠂ ⠁ ⠂ ⠄', '⠂ ⠄ ⡀ ⠄ ⠂ ⠁ ⠂'])
+ )
+ Neruda::Config.load_test('throbber' => 'default')
+ frames = Neruda::Utils.send(:select_throbber_frames)
+ expect(frames).to(
+ eq(['⠁ ⠂ ⠄ ⡀ ⠄ ⠂ ⠁', '⠂ ⠁ ⠂ ⠄ ⡀ ⠄ ⠂', '⠄ ⠂ ⠁ ⠂ ⠄ ⡀ ⠄',
+ '⡀ ⠄ ⠂ ⠁ ⠂ ⠄ ⡀', '⠄ ⡀ ⠄ ⠂ ⠁ ⠂ ⠄', '⠂ ⠄ ⡀ ⠄ ⠂ ⠁ ⠂'])
+ )
+ Neruda::Config.load_test('throbber' => 'wrong')
+ frames = Neruda::Utils.send(:select_throbber_frames)
+ expect(frames).to(
+ eq(['⠁ ⠂ ⠄ ⡀ ⠄ ⠂ ⠁', '⠂ ⠁ ⠂ ⠄ ⡀ ⠄ ⠂', '⠄ ⠂ ⠁ ⠂ ⠄ ⡀ ⠄',
+ '⡀ ⠄ ⠂ ⠁ ⠂ ⠄ ⡀', '⠄ ⡀ ⠄ ⠂ ⠁ ⠂ ⠄', '⠂ ⠄ ⡀ ⠄ ⠂ ⠁ ⠂'])
+ )
+ Neruda::Config.load_test('throbber' => 'basic')
+ frames = Neruda::Utils.send(:select_throbber_frames)
+ expect(frames).to eq('-\|/')
+ end
+ end
end
diff --git a/themes/default/css/style.css b/themes/default/css/style.css
index 72d369e..ec8364c 100644
--- a/themes/default/css/style.css
+++ b/themes/default/css/style.css
@@ -1,216 +1,153 @@
-/**
- * This theme is a copy of the one of Pelican https://getpelican.com/
- * Bellow is the original notice from pelican website, about the theme
- * inspired by https://www.smashingmagazine.com/2009/08/designing-a-html-5-layout-from-scratch/
- * As the original is under a MIT license, the following is also
- * distributed under the same license.
- */
-
/*
- Name: Smashing HTML5
- Date: July 2009
- Description: Sample layout for HTML5 and CSS3 goodness.
- Version: 1.0
- License: MIT <http://opensource.org/licenses/MIT>
- Licensed by: Smashing Media GmbH <http://www.smashingmagazine.com/>
- Original author: Enrique Ramírez <http://enrique-ramirez.com/>
-*/
+Version 2
+Dernière modification: Milouse
-@font-face {
- font-family: 'Yanone Kaffeesatz';
- font-style: normal;
- font-weight: 400;
- src:
- local('Yanone Kaffeesatz Regular'),
- local('YanoneKaffeesatz-Regular'),
- /* from https://fonts.gstatic.com/s/yanonekaffeesatz/v8/YDAoLskQQ5MOAgvHUQCcLRTHiN2BPBirwIkMLKUspj4.woff */
- url('../fonts/Yanone_Kaffeesatz_400.woff') format('woff'),
- /* from https://fonts.gstatic.com/s/yanonekaffeesatz/v8/YDAoLskQQ5MOAgvHUQCcLfGwxTS8d1Q9KiDNCMKLFUM.woff2 */
- url('../fonts/Yanone_Kaffeesatz_400.woff2') format('woff2');
-}
-/***** Global *****/
-/* Body */
-body {
- background: #F5F4EF;
- color: #000305;
- font-size: 87.5%; /* Base font size: 14px */
- font-family: 'Trebuchet MS', Trebuchet, 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
- line-height: 1.429;
- margin: 0;
- padding: 0;
- text-align: left;
-}
+Umaneti.net Legacy
+==================
-/* Headings */
-h1 {font-size: 2em }
-h2 {font-size: 1.571em} /* 22px */
-h3 {font-size: 1.429em} /* 20px */
-h4 {font-size: 1.286em} /* 18px */
-h5 {font-size: 1.143em} /* 16px */
-h6 {font-size: 1em} /* 14px */
+-> pour une largeur d'écran de 800 pixels
+-> cette feuille est libre de droits
-h1, h2, h3, h4, h5, h6 {
- font-weight: 400;
- line-height: 1.1;
- margin-bottom: .8em;
- font-family: 'Yanone Kaffeesatz', arial, serif;
-}
+*/
-h3, h4, h5, h6 { margin-top: .8em; }
+body {
+ font-size: 12pt;
+ color: #000000;
+ background: url('/assets/default/img/top.png') top repeat-x;
+ font-family: sans-serif;
+ margin-bottom: 0;
+}
-hr { border: 2px solid #EEEEEE; }
+h1 {color: #ffba53;}
-/* Anchors */
-a {outline: 0;}
-a img {border: 0px; text-decoration: none;}
-a:link, a:visited {
- color: #C74350;
- padding: 0 1px;
- text-decoration: underline;
+h2 {
+ color: #68a5c3;
+ margin-left: 1em;
+ margin-top: 1.5em;
}
-a:hover, a:active {
- background-color: #C74350;
- color: #fff;
- text-decoration: none;
- text-shadow: 1px 1px 1px #333;
+h2 code {
+ color: #68a5c3;
}
-h1 a:hover {
- background-color: inherit
+h3 {color:#ffba53;}
+
+a[hreflang]:after {
+ content: "\00a0[" attr(hreflang) "]";
+ color: #cccccc;
+ background: transparent;
}
-/* Paragraphs */
-p { margin-top: 1em;
- margin-bottom: 1em;}
+a, a:visited {color: #666666;}
+a:hover {text-decoration: none;}
-strong, b {font-weight: bold;}
-em, i {font-style: italic;}
+img {border: 0;}
-/* Lists */
-ul {
- list-style: outside disc;
- margin: 0em 0 0 1.5em;
+blockquote {
+ font-style: italic;
+ border-left: 4px solid #666666;
+ padding-left: 1em;
}
-ol {
- list-style: outside decimal;
- margin: 0em 0 0 1.5em;
+acronym {
+ border-bottom:dotted 1px #666666;
+ cursor:help;
}
-li { margin-top: 0.5em;
- margin-bottom: 1em; }
-
-.post-info {
- float:right;
- margin:10px;
- padding:5px;
+code {
+ font-family: monospace;
+ color: #c74350;
+}
+.org-src-container pre {
+ overflow: auto;
+}
+.org-src-container label.org-src-name {
+ display: block;
+ text-align: center;
+ font-size: .9em;
+ color: #666666;
}
-.post-info p{
- margin-top: 1px;
- margin-bottom: 1px;
+ul {
+ list-style: url('/assets/default/img/tic.png');
+ padding-left: 2em;
}
-dl {margin: 0 0 1.5em 0;}
-dt {font-weight: bold;}
-dd {margin-left: 1.5em;}
+ol {padding-left: 2em;}
-pre{padding: 10px; margin: 10px; overflow: auto;}
+p, li {
+ text-align: justify;
+ line-height: 1.75em;
+}
-/* Quotes */
-blockquote {
- margin: 20px;
- font-style: italic;
+dt {
+ font-weight: bold;
}
-/* Tables */
-table {margin: .5em auto 1.5em auto; width: 98%;}
+.underline {
+ text-decoration: underline;
+}
-/* Thead */
-thead th {padding: .5em .4em; text-align: left;}
+.org-center {
+ text-align: center;
+}
-/* Tbody */
-tbody td {padding: .5em .4em;}
+fieldset {border: 0;}
-/* HTML5 tags */
-header, section, footer,
-aside, nav, article, figure {
- display: block;
+input, textarea {
+ border: 1px solid #cccccc;
+ margin: 3px 0px;
+ background: #ffffff;
}
-
-/*
- Header
-*****************/
-header {
- margin: 0 auto;
- padding: 0 0 2.5em 0;
-}
-
-/* Banner */
-header h1 {font-size: 3.571em;}
-
-/* Main Nav */
-header nav {
- background: #000305;
- font-size: 1.143em;
- height: 40px;
- line-height: 30px;
- margin: 0 auto 2em auto;
- padding: 0;
- text-align: center;
- width: 800px;
- border-radius: 5px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
-}
-
-header nav ul {list-style: none; margin: 0 auto; width: 800px;}
-header nav li {float: left; display: inline; margin: 0;}
-
-header nav a:link, header nav a:visited {
- color: #fff;
- display: inline-block;
- height: 30px;
- padding: 5px 1.5em;
- text-decoration: none;
-}
-header nav a:hover, header nav a:active,
-header nav .active a:link, header nav .active a:visited {
- background: #C74451;
- color: #fff;
- text-shadow: none !important;
-}
-
-header nav li:first-child a {
- border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- -webkit-border-top-left-radius: 5px;
- border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
- -webkit-border-bottom-left-radius: 5px;
+input:hover,
+input:focus,
+textarea:hover,
+textarea:focus {
+ border: 1px solid #ffba53;
+ background: #ffffff;
}
-/*
- Body
-*****************/
-#content, #postamble {
+/* ID #TOUT pour faire que la page soit centrée de 800 de large. --------------------- */
+#preamble, #content, #postamble {
width: 800px;
- margin: 0 auto;
-}
-.outline-2 {
- background: #fff;
- margin-bottom: 2em;
- overflow: hidden;
- padding: 20px 20px;
- width: 760px;
- border-radius: 10px;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
+ margin: 1em auto;
+ padding: 1em;
}
-.org-src-container label.org-src-name {
- display: block;
+
+/* Header */
+
+#content header h1 {
+ text-align: right;
+ margin-bottom: 1.5em;
+}
+
+#preamble nav ul {
+ list-style: none;
+ padding-left: 0;
+}
+#preamble li {
+ display: inline;
+ line-height: 1em;
+}
+#preamble li::before {
+ content: " · ";
+}
+#preamble li:first-child::before {
+ content: "";
+}
+
+/* Footer */
+
+#postamble {
+ background: url('/assets/default/img/bottom.png') top repeat-x;
+ border-top: 1px solid #cccccc;
+ font-size: .8em;
text-align: center;
- font-size: smaller;
+ margin-bottom: 0;
+}
+
+.post-meta {
+ font-size: .9em;
+ font-style: italic;
}
diff --git a/themes/default/fonts/Yanone_Kaffeesatz_400.woff b/themes/default/fonts/Yanone_Kaffeesatz_400.woff
deleted file mode 100644
index ddccf76..0000000
--- a/themes/default/fonts/Yanone_Kaffeesatz_400.woff
+++ /dev/null
Binary files differ
diff --git a/themes/default/fonts/Yanone_Kaffeesatz_400.woff2 b/themes/default/fonts/Yanone_Kaffeesatz_400.woff2
deleted file mode 100644
index 7b18f7e..0000000
--- a/themes/default/fonts/Yanone_Kaffeesatz_400.woff2
+++ /dev/null
Binary files differ
diff --git a/themes/default/assets/Firma_Pablo_Neruda.svg b/themes/default/img/Firma_Pablo_Neruda.svg
index a3c4df2..a3c4df2 100644
--- a/themes/default/assets/Firma_Pablo_Neruda.svg
+++ b/themes/default/img/Firma_Pablo_Neruda.svg
diff --git a/themes/default/img/bottom.png b/themes/default/img/bottom.png
new file mode 100644
index 0000000..787331d
--- /dev/null
+++ b/themes/default/img/bottom.png
Binary files differ
diff --git a/themes/default/img/content.png b/themes/default/img/content.png
new file mode 100644
index 0000000..a7bee2a
--- /dev/null
+++ b/themes/default/img/content.png
Binary files differ
diff --git a/themes/default/img/tic.png b/themes/default/img/tic.png
new file mode 100644
index 0000000..ea6b9c0
--- /dev/null
+++ b/themes/default/img/tic.png
Binary files differ
diff --git a/themes/default/img/top.png b/themes/default/img/top.png
new file mode 100644
index 0000000..bc05caa
--- /dev/null
+++ b/themes/default/img/top.png
Binary files differ