mirror of
https://github.com/home-assistant/home-assistant.io.git
synced 2025-07-16 05:46:52 +00:00
Merge branch 'jekyll-3'
Conflicts: .gitignore Gemfile.lock source/_components/media_player.plex.markdown source/_includes/site/head.html
This commit is contained in:
commit
a08459ec8f
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,3 +10,4 @@ source/_stash
|
||||
source/stylesheets/screen.css
|
||||
vendor
|
||||
node_modules
|
||||
source/.jekyll-metadata
|
||||
|
17
Gemfile
17
Gemfile
@ -2,10 +2,8 @@ source "https://rubygems.org"
|
||||
|
||||
group :development do
|
||||
gem 'rake', '~> 10.0'
|
||||
gem 'jekyll', '~> 2.0'
|
||||
gem 'octopress-hooks', '~> 2.2'
|
||||
gem 'octopress-date-format', '~> 2.0'
|
||||
gem 'jekyll-sitemap'
|
||||
gem 'jekyll', '~> 3.0'
|
||||
gem 'pygments.rb', '~> 0.6.3'
|
||||
gem 'rdiscount', '~> 2.0'
|
||||
gem 'RedCloth', '~> 4.2.9'
|
||||
gem 'haml', '~> 4.0'
|
||||
@ -14,9 +12,18 @@ group :development do
|
||||
gem 'rubypants', '~> 0.2.0'
|
||||
gem 'rb-fsevent', '~> 0.9'
|
||||
gem 'stringex', '~> 1.4.0'
|
||||
gem 'jekyll-time-to-read'
|
||||
gem 'execjs'
|
||||
gem 'therubyracer', :platforms => :ruby
|
||||
gem 'coderay'
|
||||
end
|
||||
|
||||
group :jekyll_plugins do
|
||||
gem 'jekyll-paginate'
|
||||
gem 'jekyll-sitemap'
|
||||
gem 'jekyll-time-to-read'
|
||||
gem 'octopress', '~> 3.0'
|
||||
gem 'octopress-filters'
|
||||
gem 'octopress-include-tag'
|
||||
end
|
||||
|
||||
gem 'sinatra', '~> 1.4.2'
|
||||
|
68
Gemfile.lock
68
Gemfile.lock
@ -2,43 +2,27 @@ GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
RedCloth (4.2.9)
|
||||
blankslate (2.1.2.4)
|
||||
chunky_png (1.3.4)
|
||||
classifier-reborn (2.0.3)
|
||||
fast-stemmer (~> 1.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.9.1.1)
|
||||
chunky_png (1.3.5)
|
||||
coderay (1.1.0)
|
||||
colorator (0.1)
|
||||
compass (0.12.7)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.2.19)
|
||||
execjs (2.6.0)
|
||||
fast-stemmer (1.0.2)
|
||||
ffi (1.9.10)
|
||||
fssm (0.2.10)
|
||||
haml (4.0.7)
|
||||
tilt
|
||||
jekyll (2.5.3)
|
||||
classifier-reborn (~> 2.0)
|
||||
jekyll (3.0.0)
|
||||
colorator (~> 0.1)
|
||||
jekyll-coffeescript (~> 1.0)
|
||||
jekyll-gist (~> 1.0)
|
||||
jekyll-paginate (~> 1.0)
|
||||
jekyll-sass-converter (~> 1.0)
|
||||
jekyll-watch (~> 1.1)
|
||||
kramdown (~> 1.3)
|
||||
liquid (~> 2.6.1)
|
||||
liquid (~> 3.0)
|
||||
mercenary (~> 0.3.3)
|
||||
pygments.rb (~> 0.6.0)
|
||||
redcarpet (~> 3.1)
|
||||
rouge (~> 1.7)
|
||||
safe_yaml (~> 1.0)
|
||||
toml (~> 0.1.0)
|
||||
jekyll-coffeescript (1.0.1)
|
||||
coffee-script (~> 2.2)
|
||||
jekyll-gist (1.3.5)
|
||||
jekyll-paginate (1.1.0)
|
||||
jekyll-sass-converter (1.3.0)
|
||||
sass (~> 3.2)
|
||||
@ -49,18 +33,35 @@ GEM
|
||||
listen (~> 3.0)
|
||||
kramdown (1.9.0)
|
||||
libv8 (3.16.14.13)
|
||||
liquid (2.6.3)
|
||||
liquid (3.0.6)
|
||||
listen (3.0.3)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
mercenary (0.3.5)
|
||||
octopress-date-format (2.0.2)
|
||||
jekyll (~> 2.0)
|
||||
octopress (3.0.11)
|
||||
jekyll (>= 2.0)
|
||||
mercenary (~> 0.3.2)
|
||||
octopress-deploy
|
||||
octopress-escape-code (~> 2.0)
|
||||
octopress-hooks (~> 2.0)
|
||||
redcarpet (~> 3.0)
|
||||
titlecase
|
||||
octopress-deploy (1.3.0)
|
||||
colorator
|
||||
octopress-escape-code (2.0.6)
|
||||
octopress-hooks (~> 2.0)
|
||||
octopress-filters (1.4.0)
|
||||
jekyll
|
||||
octopress-hooks (~> 2.0)
|
||||
rubypants-unicode
|
||||
titlecase
|
||||
octopress-hooks (2.6.1)
|
||||
jekyll (>= 2.0)
|
||||
parslet (1.5.0)
|
||||
blankslate (~> 2.0)
|
||||
octopress-include-tag (1.1.3)
|
||||
jekyll (>= 2.0)
|
||||
octopress-tag-helpers (~> 1.0)
|
||||
octopress-tag-helpers (1.0.8)
|
||||
jekyll (>= 2.0)
|
||||
posix-spawn (0.3.11)
|
||||
pygments.rb (0.6.3)
|
||||
posix-spawn (~> 0.3.6)
|
||||
@ -75,7 +76,9 @@ GEM
|
||||
rdiscount (2.1.8)
|
||||
redcarpet (3.3.3)
|
||||
ref (2.0.0)
|
||||
rouge (1.10.1)
|
||||
rubypants (0.2.0)
|
||||
rubypants-unicode (0.2.5)
|
||||
safe_yaml (1.0.4)
|
||||
sass (3.2.19)
|
||||
sass-globbing (1.0.0)
|
||||
@ -89,8 +92,7 @@ GEM
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
tilt (2.0.1)
|
||||
toml (0.1.2)
|
||||
parslet (~> 1.5.0)
|
||||
titlecase (0.1.1)
|
||||
yajl-ruby (1.2.1)
|
||||
|
||||
PLATFORMS
|
||||
@ -98,14 +100,18 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
RedCloth (~> 4.2.9)
|
||||
coderay
|
||||
compass (~> 0.12.2)
|
||||
execjs
|
||||
haml (~> 4.0)
|
||||
jekyll (~> 2.0)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-paginate
|
||||
jekyll-sitemap
|
||||
jekyll-time-to-read
|
||||
octopress-date-format (~> 2.0)
|
||||
octopress-hooks (~> 2.2)
|
||||
octopress (~> 3.0)
|
||||
octopress-filters
|
||||
octopress-include-tag
|
||||
pygments.rb (~> 0.6.3)
|
||||
rake (~> 10.0)
|
||||
rb-fsevent (~> 0.9)
|
||||
rdiscount (~> 2.0)
|
||||
|
6
Rakefile
6
Rakefile
@ -65,7 +65,7 @@ task :watch do
|
||||
raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir)
|
||||
puts "Starting to watch source with Jekyll and Compass."
|
||||
system "compass compile --css-dir #{source_dir}/stylesheets" unless File.exist?("#{source_dir}/stylesheets/screen.css")
|
||||
jekyllPid = Process.spawn({"OCTOPRESS_ENV"=>"preview"}, "jekyll build --watch")
|
||||
jekyllPid = Process.spawn({"OCTOPRESS_ENV"=>"preview"}, "jekyll build --watch --incremental")
|
||||
compassPid = Process.spawn("compass watch")
|
||||
|
||||
trap("INT") {
|
||||
@ -81,7 +81,7 @@ task :preview do
|
||||
raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir)
|
||||
puts "Starting to watch source with Jekyll and Compass. Starting Rack on port #{server_port}"
|
||||
system "compass compile --css-dir #{source_dir}/stylesheets" unless File.exist?("#{source_dir}/stylesheets/screen.css")
|
||||
jekyllPid = Process.spawn({"OCTOPRESS_ENV"=>"preview"}, "jekyll build --watch")
|
||||
jekyllPid = Process.spawn({"OCTOPRESS_ENV"=>"preview"}, "jekyll build --watch --incremental")
|
||||
compassPid = Process.spawn("compass watch")
|
||||
rackupPid = Process.spawn("rackup --port #{server_port}")
|
||||
|
||||
@ -252,7 +252,7 @@ desc "deploy public directory to github pages"
|
||||
multitask :push do
|
||||
puts "## Deploying branch to Github Pages "
|
||||
puts "## Pulling any updates from Github Pages "
|
||||
cd "#{deploy_dir}" do
|
||||
cd "#{deploy_dir}" do
|
||||
Bundler.with_clean_env { system "git pull" }
|
||||
end
|
||||
(Dir["#{deploy_dir}/*"]).each { |f| rm_rf(f) }
|
||||
|
34
_config.yml
34
_config.yml
@ -26,24 +26,38 @@ email:
|
||||
# Jekyll & Plugins #
|
||||
# ----------------------- #
|
||||
|
||||
# If publishing to a subdirectory as in http://site.com/project set 'root: /project'
|
||||
root: /
|
||||
permalink: /blog/:year/:month/:day/:title/
|
||||
source: source
|
||||
destination: public/
|
||||
plugins: plugins
|
||||
plugins_dir: plugins
|
||||
code_dir: downloads/code
|
||||
category_dir: blog/categories
|
||||
markdown: rdiscount
|
||||
rdiscount:
|
||||
extensions:
|
||||
- autolink
|
||||
- footnotes
|
||||
- smart
|
||||
highlighter: pygments # default python pygments have been replaced by pygments.rb
|
||||
markdown: kramdown
|
||||
|
||||
kramdown:
|
||||
input: GFM
|
||||
auto_ids: false
|
||||
footnote_nr: 1
|
||||
entity_output: as_char
|
||||
toc_levels: 1..6
|
||||
smart_quotes: lsquo,rsquo,ldquo,rdquo
|
||||
parse_block_html: true
|
||||
enable_coderay: true
|
||||
|
||||
coderay:
|
||||
coderay_wrap: div
|
||||
coderay_line_numbers: nil
|
||||
coderay_line_number_start: 1
|
||||
coderay_tab_width: 4
|
||||
coderay_bold_every: 10
|
||||
coderay_css: class
|
||||
|
||||
highlighter: rouge
|
||||
|
||||
gems:
|
||||
- jekyll-time-to-read
|
||||
- octopress-filters
|
||||
- octopress-include-tag
|
||||
|
||||
paginate: 10 # Posts per page on the blog index
|
||||
paginate_path: "blog/posts/:num" # Directory base for pagination URLs eg. /posts/2/
|
||||
|
@ -16,7 +16,7 @@ class SinatraStaticServer < Sinatra::Base
|
||||
|
||||
def send_sinatra_file(path, &missing_file_block)
|
||||
file_path = File.join(File.dirname(__FILE__), 'public', path)
|
||||
file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
|
||||
file_path = File.join(file_path, 'index.html') if File.directory?(file_path)
|
||||
File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
|
||||
end
|
||||
|
||||
|
163
generate-redirect.py
Normal file
163
generate-redirect.py
Normal file
@ -0,0 +1,163 @@
|
||||
import os
|
||||
|
||||
dirs = ['components', 'getting-started', 'developers']
|
||||
|
||||
template = "<script>document.location = '/{}/{}/';</script>"
|
||||
|
||||
for check_dir in dirs:
|
||||
for path in os.listdir(os.path.join('public', check_dir)):
|
||||
check_path = os.path.join('public', check_dir, path)
|
||||
|
||||
if os.path.isdir(check_path):
|
||||
new_path = os.path.join('source', check_dir, "{}.html".format(path))
|
||||
# print(template.format(check_dir, path))
|
||||
# print(new_path)
|
||||
with open(new_path, 'w') as outp:
|
||||
outp.write(template.format(check_dir, path))
|
||||
|
||||
# Generated
|
||||
# source/components/alarm_control_panel.html
|
||||
# source/components/alarm_control_panel.manual.html
|
||||
# source/components/alarm_control_panel.mqtt.html
|
||||
# source/components/arduino.html
|
||||
# source/components/automation.html
|
||||
# source/components/browser.html
|
||||
# source/components/camera.foscam.html
|
||||
# source/components/camera.generic.html
|
||||
# source/components/configurator.html
|
||||
# source/components/conversation.html
|
||||
# source/components/device_sun_light_trigger.html
|
||||
# source/components/device_tracker.html
|
||||
# source/components/device_tracker.actiontec.html
|
||||
# source/components/device_tracker.aruba.html
|
||||
# source/components/device_tracker.asuswrt.html
|
||||
# source/components/device_tracker.ddwrt.html
|
||||
# source/components/device_tracker.geofancy.html
|
||||
# source/components/device_tracker.luci.html
|
||||
# source/components/device_tracker.mqtt.html
|
||||
# source/components/device_tracker.netgear.html
|
||||
# source/components/device_tracker.nmap_scanner.html
|
||||
# source/components/device_tracker.owntracks.html
|
||||
# source/components/device_tracker.snmp.html
|
||||
# source/components/device_tracker.thomson.html
|
||||
# source/components/device_tracker.tomato.html
|
||||
# source/components/device_tracker.tplink.html
|
||||
# source/components/device_tracker.ubus.html
|
||||
# source/components/discovery.html
|
||||
# source/components/downloader.html
|
||||
# source/components/group.html
|
||||
# source/components/history.html
|
||||
# source/components/ifttt.html
|
||||
# source/components/ifttt.manything.html
|
||||
# source/components/introduction.html
|
||||
# source/components/isy994.html
|
||||
# source/components/keyboard.html
|
||||
# source/components/light.html
|
||||
# source/components/light.blinksticklight.html
|
||||
# source/components/light.hue.html
|
||||
# source/components/light.hyperion.html
|
||||
# source/components/light.limitlessled.html
|
||||
# source/components/light.rfxtrx.html
|
||||
# source/components/light.tellstick.html
|
||||
# source/components/light.vera.html
|
||||
# source/components/light.wink.html
|
||||
# source/components/logbook.html
|
||||
# source/components/media_player.html
|
||||
# source/components/media_player.cast.html
|
||||
# source/components/media_player.denon.html
|
||||
# source/components/media_player.firetv.html
|
||||
# source/components/media_player.itunes.html
|
||||
# source/components/media_player.kodi.html
|
||||
# source/components/media_player.mpd.html
|
||||
# source/components/media_player.plex.html
|
||||
# source/components/media_player.sonos.html
|
||||
# source/components/media_player.squeezebox.html
|
||||
# source/components/modbus.html
|
||||
# source/components/mqtt.html
|
||||
# source/components/notify.html
|
||||
# source/components/notify.file.html
|
||||
# source/components/notify.instapush.html
|
||||
# source/components/notify.nma.html
|
||||
# source/components/notify.pushbullet.html
|
||||
# source/components/notify.pushover.html
|
||||
# source/components/notify.slack.html
|
||||
# source/components/notify.smtp.html
|
||||
# source/components/notify.syslog.html
|
||||
# source/components/notify.telegram.html
|
||||
# source/components/notify.xmpp.html
|
||||
# source/components/rfxtrx.html
|
||||
# source/components/scene.html
|
||||
# source/components/script.html
|
||||
# source/components/sensor.html
|
||||
# source/components/sensor.arduino.html
|
||||
# source/components/sensor.arest.html
|
||||
# source/components/sensor.bitcoin.html
|
||||
# source/components/sensor.command_sensor.html
|
||||
# source/components/sensor.cpuspeed.html
|
||||
# source/components/sensor.dht.html
|
||||
# source/components/sensor.efergy.html
|
||||
# source/components/sensor.forecast.html
|
||||
# source/components/sensor.glances.html
|
||||
# source/components/sensor.modbus.html
|
||||
# source/components/sensor.mqtt.html
|
||||
# source/components/sensor.mysensors.html
|
||||
# source/components/sensor.openweathermap.html
|
||||
# source/components/sensor.rest.html
|
||||
# source/components/sensor.rfxtrx.html
|
||||
# source/components/sensor.rpi_gpio.html
|
||||
# source/components/sensor.sabnzbd.html
|
||||
# source/components/sensor.swiss_public_transport.html
|
||||
# source/components/sensor.systemmonitor.html
|
||||
# source/components/sensor.tellstick.html
|
||||
# source/components/sensor.temper.html
|
||||
# source/components/sensor.time_date.html
|
||||
# source/components/sensor.transmission.html
|
||||
# source/components/sensor.vera.html
|
||||
# source/components/sensor.wink.html
|
||||
# source/components/sensor.worldclock.html
|
||||
# source/components/shell_command.html
|
||||
# source/components/simple_alarm.html
|
||||
# source/components/sun.html
|
||||
# source/components/switch.html
|
||||
# source/components/switch.arduino.html
|
||||
# source/components/switch.arest.html
|
||||
# source/components/switch.command_switch.html
|
||||
# source/components/switch.edimax.html
|
||||
# source/components/switch.hikvision.html
|
||||
# source/components/switch.modbus.html
|
||||
# source/components/switch.mqtt.html
|
||||
# source/components/switch.rest.html
|
||||
# source/components/switch.rfxtrx.html
|
||||
# source/components/switch.rpi_gpio.html
|
||||
# source/components/switch.tellstick.html
|
||||
# source/components/switch.transmission.html
|
||||
# source/components/switch.vera.html
|
||||
# source/components/switch.wemo.html
|
||||
# source/components/switch.wink.html
|
||||
# source/components/tellstick.html
|
||||
# source/components/thermostat.html
|
||||
# source/components/thermostat.heat_control.html
|
||||
# source/components/thermostat.nest.html
|
||||
# source/components/thermostat.radiotherm.html
|
||||
# source/components/vera.html
|
||||
# source/components/verisure.html
|
||||
# source/components/wink.html
|
||||
# source/components/zone.html
|
||||
# source/components/zwave.html
|
||||
# source/getting-started/android.html
|
||||
# source/getting-started/automation.html
|
||||
# source/getting-started/autostart.html
|
||||
# source/getting-started/configuration.html
|
||||
# source/getting-started/devices.html
|
||||
# source/getting-started/presence-detection.html
|
||||
# source/getting-started/troubleshooting.html
|
||||
# source/getting-started/troubleshooting-configuration.html
|
||||
# source/developers/add_new_platform.html
|
||||
# source/developers/api.html
|
||||
# source/developers/architecture.html
|
||||
# source/developers/creating_components.html
|
||||
# source/developers/credits.html
|
||||
# source/developers/frontend.html
|
||||
# source/developers/python_api.html
|
||||
# source/developers/rest_api.html
|
||||
# source/developers/website.html
|
@ -1,42 +0,0 @@
|
||||
require './plugins/pygments_code'
|
||||
|
||||
module BacktickCodeBlock
|
||||
AllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/i
|
||||
LangCaption = /([^\s]+)\s*(.+)?/i
|
||||
def self.render_code_block(input)
|
||||
@options = nil
|
||||
@caption = nil
|
||||
@lang = nil
|
||||
@url = nil
|
||||
@title = nil
|
||||
input.gsub(/^`{3} *([^\n]+)?\n(.+?)\n`{3}/m) do
|
||||
@options = $1 || ''
|
||||
str = $2
|
||||
|
||||
if @options =~ AllOptions
|
||||
@lang = $1
|
||||
@caption = "<figcaption><span>#{$2}</span><a href='#{$3}'>#{$4 || 'link'}</a></figcaption>"
|
||||
elsif @options =~ LangCaption
|
||||
@lang = $1
|
||||
@caption = "<figcaption><span>#{$2}</span></figcaption>"
|
||||
end
|
||||
|
||||
if str.match(/\A( {4}|\t)/)
|
||||
str = str.gsub(/^( {4}|\t)/, '')
|
||||
end
|
||||
if @lang.nil? || @lang == 'plain'
|
||||
code = HighlightCode::tableize_code(str.gsub('<','<').gsub('>','>'))
|
||||
"<figure class='code'>#{@caption}#{code}</figure>"
|
||||
else
|
||||
if @lang.include? "-raw"
|
||||
raw = "``` #{@options.sub('-raw', '')}\n"
|
||||
raw += str
|
||||
raw += "\n```\n"
|
||||
else
|
||||
code = HighlightCode::highlight(str, @lang)
|
||||
"<figure class='code'>#{@caption}#{code}</figure>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,82 +0,0 @@
|
||||
#
|
||||
# Author: Brandon Mathis
|
||||
# A full rewrite based on the work of: Josediaz Gonzalez - https://github.com/josegonzalez/josediazgonzalez.com/blob/master/_plugins/blockquote.rb
|
||||
#
|
||||
# Outputs a string with a given attribution as a quote
|
||||
#
|
||||
# {% blockquote Bobby Willis http://google.com/search?q=pants the search for bobby's pants %}
|
||||
# Wheeee!
|
||||
# {% endblockquote %}
|
||||
# ...
|
||||
# <blockquote>
|
||||
# <p>Wheeee!</p>
|
||||
# <footer>
|
||||
# <strong>Bobby Willis</strong><cite><a href="http://google.com/search?q=pants">The Search For Bobby's Pants</a>
|
||||
# </blockquote>
|
||||
#
|
||||
require './plugins/titlecase.rb'
|
||||
|
||||
module Jekyll
|
||||
|
||||
class Blockquote < Liquid::Block
|
||||
FullCiteWithTitle = /(\S.*)\s+(https?:\/\/)(\S+)\s+(.+)/i
|
||||
FullCite = /(\S.*)\s+(https?:\/\/)(\S+)/i
|
||||
AuthorTitle = /([^,]+),([^,]+)/
|
||||
Author = /(.+)/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@by = nil
|
||||
@source = nil
|
||||
@title = nil
|
||||
if markup =~ FullCiteWithTitle
|
||||
@by = $1
|
||||
@source = $2 + $3
|
||||
@title = $4.titlecase.strip
|
||||
elsif markup =~ FullCite
|
||||
@by = $1
|
||||
@source = $2 + $3
|
||||
elsif markup =~ AuthorTitle
|
||||
@by = $1
|
||||
@title = $2.titlecase.strip
|
||||
elsif markup =~ Author
|
||||
@by = $1
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
quote = paragraphize(super)
|
||||
author = "<strong>#{@by.strip}</strong>" if @by
|
||||
if @source
|
||||
url = @source.match(/https?:\/\/(.+)/)[1].split('/')
|
||||
parts = []
|
||||
url.each do |part|
|
||||
if (parts + [part]).join('/').length < 32
|
||||
parts << part
|
||||
end
|
||||
end
|
||||
source = parts.join('/')
|
||||
source << '/…' unless source == @source
|
||||
end
|
||||
if !@source.nil?
|
||||
cite = " <cite><a href='#{@source}'>#{(@title || source)}</a></cite>"
|
||||
elsif !@title.nil?
|
||||
cite = " <cite>#{@title}</cite>"
|
||||
end
|
||||
blockquote = if @by.nil?
|
||||
quote
|
||||
elsif cite
|
||||
"#{quote}<footer>#{author + cite}</footer>"
|
||||
else
|
||||
"#{quote}<footer>#{author}</footer>"
|
||||
end
|
||||
"<blockquote>#{blockquote}</blockquote>"
|
||||
end
|
||||
|
||||
def paragraphize(input)
|
||||
"<p>#{input.lstrip.rstrip.gsub(/\n\n/, '</p><p>').gsub(/\n/, '<br/>')}</p>"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('blockquote', Jekyll::Blockquote)
|
@ -1,92 +0,0 @@
|
||||
# Title: Simple Code Blocks for Jekyll
|
||||
# Author: Brandon Mathis http://brandonmathis.com
|
||||
# Description: Write codeblocks with semantic HTML5 <figure> and <figcaption> elements and optional syntax highlighting — all with a simple, intuitive interface.
|
||||
#
|
||||
# Syntax:
|
||||
# {% codeblock [title] [url] [link text] %}
|
||||
# code snippet
|
||||
# {% endcodeblock %}
|
||||
#
|
||||
# For syntax highlighting, put a file extension somewhere in the title. examples:
|
||||
# {% codeblock file.sh %}
|
||||
# code snippet
|
||||
# {% endcodeblock %}
|
||||
#
|
||||
# {% codeblock Time to be Awesome! (awesome.rb) %}
|
||||
# code snippet
|
||||
# {% endcodeblock %}
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# {% codeblock Got pain? painreleif.sh http://site.com/painreleief.sh Download it! %}
|
||||
# $ rm -rf ~/PAIN
|
||||
# {% endcodeblock %}
|
||||
#
|
||||
# Output:
|
||||
#
|
||||
# <figure class='code'>
|
||||
# <figcaption><span>Got pain? painrelief.sh</span> <a href="http://site.com/painrelief.sh">Download it!</a>
|
||||
# <div class="highlight"><pre><code class="sh">
|
||||
# -- nicely escaped highlighted code --
|
||||
# </code></pre></div>
|
||||
# </figure>
|
||||
#
|
||||
# Example 2 (no syntax highlighting):
|
||||
#
|
||||
# {% codeblock %}
|
||||
# <sarcasm>Ooooh, sarcasm... How original!</sarcasm>
|
||||
# {% endcodeblock %}
|
||||
#
|
||||
# <figure class='code'>
|
||||
# <pre><code><sarcasm> Ooooh, sarcasm... How original!</sarcasm></code></pre>
|
||||
# </figure>
|
||||
#
|
||||
require './plugins/pygments_code'
|
||||
require './plugins/raw'
|
||||
|
||||
module Jekyll
|
||||
|
||||
class CodeBlock < Liquid::Block
|
||||
CaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/i
|
||||
Caption = /(\S[\S\s]*)/
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@title = nil
|
||||
@caption = nil
|
||||
@filetype = nil
|
||||
@highlight = true
|
||||
if markup =~ /\s*lang:(\S+)/i
|
||||
@filetype = $1
|
||||
markup = markup.sub(/\s*lang:(\S+)/i,'')
|
||||
end
|
||||
if markup =~ CaptionUrlTitle
|
||||
@file = $1
|
||||
@caption = "<figcaption><span>#{$1}</span><a href='#{$2}'>#{$3 || 'link'}</a></figcaption>"
|
||||
elsif markup =~ Caption
|
||||
@file = $1
|
||||
@caption = "<figcaption><span>#{$1}</span></figcaption>\n"
|
||||
end
|
||||
if @file =~ /\S[\S\s]*\w+\.(\w+)/ && @filetype.nil?
|
||||
@filetype = $1
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
output = super
|
||||
code = super
|
||||
source = "<figure class='code'>"
|
||||
source += @caption if @caption
|
||||
if @filetype
|
||||
source += "#{HighlightCode::highlight(code, @filetype)}</figure>"
|
||||
else
|
||||
source += "#{HighlightCode::tableize_code(code.lstrip.rstrip.gsub(/</,'<'))}</figure>"
|
||||
end
|
||||
source = TemplateWrapper::safe_wrap(source)
|
||||
source = context['pygments_prefix'] + source if context['pygments_prefix']
|
||||
source = source + context['pygments_suffix'] if context['pygments_suffix']
|
||||
source
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('codeblock', Jekyll::CodeBlock)
|
@ -1,44 +0,0 @@
|
||||
require 'json'
|
||||
|
||||
class ConfigTag < Liquid::Tag
|
||||
def initialize(tag_name, options, tokens)
|
||||
super
|
||||
options = options.split(' ').map {|i| i.strip }
|
||||
@key = options.slice!(0)
|
||||
@tag = nil
|
||||
@classname = nil
|
||||
options.each do |option|
|
||||
@tag = $1 if option =~ /tag:(\S+)/
|
||||
@classname = $1 if option =~ /classname:(\S+)/
|
||||
end
|
||||
end
|
||||
|
||||
def render(context)
|
||||
config_tag(context.registers[:site].config, @key, @tag, @classname)
|
||||
end
|
||||
end
|
||||
|
||||
def config_tag(config, key, tag=nil, classname=nil)
|
||||
options = key.split('.').map { |k| config[k] }.last #reference objects with dot notation
|
||||
tag ||= 'div'
|
||||
classname ||= key.sub(/_/, '-').sub(/\./, '-')
|
||||
output = "<#{tag} class='#{classname}'"
|
||||
|
||||
if options.respond_to? 'keys'
|
||||
options.each do |k,v|
|
||||
unless v.nil?
|
||||
v = v.join ',' if v.respond_to? 'join'
|
||||
v = v.to_json if v.respond_to? 'keys'
|
||||
output += " data-#{k.sub'_','-'}='#{v}'"
|
||||
end
|
||||
end
|
||||
elsif options.respond_to? 'join'
|
||||
output += " data-value='#{config[key].join(',')}'"
|
||||
else
|
||||
output += " data-value='#{config[key]}'"
|
||||
end
|
||||
output += "></#{tag}>"
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('config_tag', ConfigTag)
|
||||
|
@ -1,113 +0,0 @@
|
||||
# Title: Dynamic directories for Jekyll
|
||||
# Author: Tommy Sullivan http://superawesometommy.com, Robert Park http://exolucere.ca
|
||||
# Description: The directory tag lets you iterate over files at a particular path. If files conform to the standard Jekyll format, YYYY-MM-DD-file-title, then those attributes will be populated on the yielded file object. The `forloop` object maintains [its usual context](http://wiki.shopify.com/UsingLiquid#For_loops).
|
||||
#
|
||||
# Syntax:
|
||||
#
|
||||
# {% directory path: path/from/source [reverse] [exclude] %}
|
||||
# {{ file.url }}
|
||||
# {{ file.name }}
|
||||
# {{ file.date }}
|
||||
# {{ file.slug }}
|
||||
# {{ file.title }}
|
||||
# {% enddirectory %}
|
||||
#
|
||||
# Options:
|
||||
#
|
||||
# - `reverse` - Defaults to 'false', ordering files the same way `ls` does: 0-9A-Za-z.
|
||||
# - `exclude` - Defaults to '.html$', a Regexp of files to skip.
|
||||
#
|
||||
# File Attributes:
|
||||
#
|
||||
# - `url` - The absolute path to the published file
|
||||
# - `name` - The basename
|
||||
# - `date` - The date extracted from the filename, otherwise the file's creation time
|
||||
# - `slug` - The basename with date and extension removed
|
||||
# - `title` - The titlecase'd slug
|
||||
#
|
||||
|
||||
module Jekyll
|
||||
|
||||
class DirectoryTag < Liquid::Block
|
||||
include Convertible
|
||||
|
||||
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
||||
|
||||
attr_accessor :content, :data
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
attributes = {}
|
||||
|
||||
# Parse parameters
|
||||
markup.scan(Liquid::TagAttributes) do |key, value|
|
||||
attributes[key] = value
|
||||
end
|
||||
|
||||
@path = attributes['path'] || '.'
|
||||
@exclude = Regexp.new(attributes['exclude'] || '.html$', Regexp::EXTENDED | Regexp::IGNORECASE)
|
||||
@rev = attributes['reverse'].nil?
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
context.registers[:directory] ||= Hash.new(0)
|
||||
|
||||
source_dir = context.registers[:site].source
|
||||
directory_files = File.join(source_dir, @path, "*")
|
||||
|
||||
files = Dir.glob(directory_files).reject{|f| f =~ @exclude }
|
||||
files.sort! {|x,y| @rev ? x <=> y : y <=> x }
|
||||
|
||||
length = files.length
|
||||
result = []
|
||||
|
||||
context.stack do
|
||||
files.each_with_index do |filename, index|
|
||||
basename = File.basename(filename)
|
||||
|
||||
filepath = [@path, basename] - ['.']
|
||||
path = filepath.join '/'
|
||||
url = '/' + filepath.join('/')
|
||||
|
||||
m, cats, date, slug, ext = *basename.match(MATCHER)
|
||||
|
||||
if m
|
||||
date = Time.parse(date)
|
||||
ext = ext
|
||||
slug = slug
|
||||
else
|
||||
date = File.ctime(filename)
|
||||
ext = basename[/\.[a-z]+$/, 0]
|
||||
slug = basename.sub(ext, '')
|
||||
end
|
||||
|
||||
context['file'] = {
|
||||
'date' => date,
|
||||
'name' => basename,
|
||||
'slug' => slug,
|
||||
'url' => url
|
||||
}
|
||||
|
||||
context['forloop'] = {
|
||||
'name' => 'directory',
|
||||
'length' => length,
|
||||
'index' => index + 1,
|
||||
'index0' => index,
|
||||
'rindex' => length - index,
|
||||
'rindex0' => length - index - 1,
|
||||
'first' => (index == 0),
|
||||
'last' => (index == length - 1)
|
||||
}
|
||||
|
||||
result << render_all(@nodelist, context)
|
||||
end
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('directory', Jekyll::DirectoryTag)
|
@ -1,130 +0,0 @@
|
||||
# A Liquid tag for Jekyll sites that allows embedding Gists and showing code for non-JavaScript enabled browsers and readers.
|
||||
# by: Brandon Tilly
|
||||
# Source URL: https://gist.github.com/1027674
|
||||
# Post http://brandontilley.com/2011/01/31/gist-tag-for-jekyll.html
|
||||
#
|
||||
# Example usage: {% gist 1027674 gist_tag.rb %} //embeds a gist for this plugin
|
||||
|
||||
require 'cgi'
|
||||
require 'digest/md5'
|
||||
require 'net/https'
|
||||
require 'uri'
|
||||
|
||||
module Jekyll
|
||||
class GistTag < Liquid::Tag
|
||||
def initialize(tag_name, text, token)
|
||||
super
|
||||
@text = text
|
||||
@cache_disabled = false
|
||||
@cache_folder = File.expand_path "../.gist-cache", File.dirname(__FILE__)
|
||||
FileUtils.mkdir_p @cache_folder
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if parts = @text.match(/([a-zA-Z\d]*) (.*)/)
|
||||
gist, file = parts[1].strip, parts[2].strip
|
||||
else
|
||||
gist, file = @text.strip, ""
|
||||
end
|
||||
if gist.empty?
|
||||
""
|
||||
else
|
||||
script_url = script_url_for gist, file
|
||||
code = get_cached_gist(gist, file) || get_gist_from_web(gist, file)
|
||||
html_output_for script_url, code
|
||||
end
|
||||
end
|
||||
|
||||
def html_output_for(script_url, code)
|
||||
code = CGI.escapeHTML code
|
||||
<<-HTML
|
||||
<div><script src='#{script_url}'></script>
|
||||
<noscript><pre><code>#{code}</code></pre></noscript></div>
|
||||
HTML
|
||||
end
|
||||
|
||||
def script_url_for(gist_id, filename)
|
||||
url = "https://gist.github.com/#{gist_id}.js"
|
||||
url = "#{url}?file=#{filename}" unless filename.nil? or filename.empty?
|
||||
url
|
||||
end
|
||||
|
||||
def get_gist_url_for(gist, file)
|
||||
"https://gist.githubusercontent.com/raw/#{gist}/#{file}"
|
||||
end
|
||||
|
||||
def cache(gist, file, data)
|
||||
cache_file = get_cache_file_for gist, file
|
||||
File.open(cache_file, "w") do |io|
|
||||
io.write data
|
||||
end
|
||||
end
|
||||
|
||||
def get_cached_gist(gist, file)
|
||||
return nil if @cache_disabled
|
||||
cache_file = get_cache_file_for gist, file
|
||||
File.read cache_file if File.exist? cache_file
|
||||
end
|
||||
|
||||
def get_cache_file_for(gist, file)
|
||||
bad_chars = /[^a-zA-Z0-9\-_.]/
|
||||
gist = gist.gsub bad_chars, ''
|
||||
file = file.gsub bad_chars, ''
|
||||
md5 = Digest::MD5.hexdigest "#{gist}-#{file}"
|
||||
File.join @cache_folder, "#{gist}-#{file}-#{md5}.cache"
|
||||
end
|
||||
|
||||
def get_gist_from_web(gist, file)
|
||||
gist_url = get_gist_url_for(gist, file)
|
||||
data = get_web_content(gist_url)
|
||||
|
||||
locations = Array.new
|
||||
while (data.code.to_i == 301 || data.code.to_i == 302)
|
||||
data = handle_gist_redirecting(data)
|
||||
break if locations.include? data.header['Location']
|
||||
locations << data.header['Location']
|
||||
end
|
||||
|
||||
if data.code.to_i != 200
|
||||
raise RuntimeError, "Gist replied with #{data.code} for #{gist_url}"
|
||||
end
|
||||
|
||||
cache(gist, file, data.body) unless @cache_disabled
|
||||
data.body
|
||||
end
|
||||
|
||||
def handle_gist_redirecting(data)
|
||||
redirected_url = data.header['Location']
|
||||
if redirected_url.nil? || redirected_url.empty?
|
||||
raise ArgumentError, "GitHub replied with a 302 but didn't provide a location in the response headers."
|
||||
end
|
||||
|
||||
get_web_content(redirected_url)
|
||||
end
|
||||
|
||||
def get_web_content(url)
|
||||
raw_uri = URI.parse url
|
||||
proxy = ENV['http_proxy']
|
||||
if proxy
|
||||
proxy_uri = URI.parse(proxy)
|
||||
https = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new raw_uri.host, raw_uri.port
|
||||
else
|
||||
https = Net::HTTP.new raw_uri.host, raw_uri.port
|
||||
end
|
||||
https.use_ssl = true
|
||||
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
request = Net::HTTP::Get.new raw_uri.request_uri
|
||||
data = https.request request
|
||||
end
|
||||
end
|
||||
|
||||
class GistTagNoCache < GistTag
|
||||
def initialize(tag_name, text, token)
|
||||
super
|
||||
@cache_disabled = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('gist', Jekyll::GistTag)
|
||||
Liquid::Template.register_tag('gistnocache', Jekyll::GistTagNoCache)
|
@ -1,24 +0,0 @@
|
||||
module Jekyll
|
||||
require 'haml'
|
||||
class HamlConverter < Converter
|
||||
safe true
|
||||
priority :low
|
||||
|
||||
def matches(ext)
|
||||
ext =~ /haml/i
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
begin
|
||||
engine = Haml::Engine.new(content)
|
||||
engine.render
|
||||
rescue StandardError => e
|
||||
puts "!!! HAML Error: " + e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,50 +0,0 @@
|
||||
# Title: Simple Image tag for Jekyll
|
||||
# Authors: Brandon Mathis http://brandonmathis.com
|
||||
# Felix Schäfer, Frederic Hemberger
|
||||
# Description: Easily output images with optional class names, width, height, title and alt attributes
|
||||
#
|
||||
# Syntax {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | "title text" ["alt text"]] %}
|
||||
#
|
||||
# Examples:
|
||||
# {% img /images/ninja.png Ninja Attack! %}
|
||||
# {% img left half http://site.com/images/ninja.png Ninja Attack! %}
|
||||
# {% img left half http://site.com/images/ninja.png 150 150 "Ninja Attack!" "Ninja in attack posture" %}
|
||||
#
|
||||
# Output:
|
||||
# <img src="/images/ninja.png">
|
||||
# <img class="left half" src="http://site.com/images/ninja.png" title="Ninja Attack!" alt="Ninja Attack!">
|
||||
# <img class="left half" src="http://site.com/images/ninja.png" width="150" height="150" title="Ninja Attack!" alt="Ninja in attack posture">
|
||||
#
|
||||
|
||||
module Jekyll
|
||||
|
||||
class ImageTag < Liquid::Tag
|
||||
@img = nil
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
attributes = ['class', 'src', 'width', 'height', 'title']
|
||||
|
||||
if markup =~ /(?<class>\S.*\s+)?(?<src>(?:https?:\/\/|\/|\S+\/)\S+)(?:\s+(?<width>\d+))?(?:\s+(?<height>\d+))?(?<title>\s+.+)?/i
|
||||
@img = attributes.reduce({}) { |img, attr| img[attr] = $~[attr].strip if $~[attr]; img }
|
||||
if /(?:"|')(?<title>[^"']+)?(?:"|')\s+(?:"|')(?<alt>[^"']+)?(?:"|')/ =~ @img['title']
|
||||
@img['title'] = title
|
||||
@img['alt'] = alt
|
||||
else
|
||||
@img['alt'] = @img['title'].gsub!(/"/, '"') if @img['title']
|
||||
end
|
||||
@img['class'].gsub!(/"/, '') if @img['class']
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if @img
|
||||
"<img #{@img.collect {|k,v| "#{k}=\"#{v}\"" if v}.join(" ")}>"
|
||||
else
|
||||
"Error processing input, expected syntax: {% img [class name(s)] [http[s]:/]/path/to/image [width [height]] [title text | \"title text\" [\"alt text\"]] %}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('img', Jekyll::ImageTag)
|
@ -1,71 +0,0 @@
|
||||
# Title: Include Code Tag for Jekyll
|
||||
# Author: Brandon Mathis http://brandonmathis.com
|
||||
# Description: Import files on your filesystem into any blog post as embedded code snippets with syntax highlighting and a download link.
|
||||
# Configuration: You can set default import path in _config.yml (defaults to code_dir: downloads/code)
|
||||
#
|
||||
# Syntax {% include_code path/to/file %}
|
||||
#
|
||||
# Example 1:
|
||||
# {% include_code javascripts/test.js %}
|
||||
#
|
||||
# This will import test.js from source/downloads/code/javascripts/test.js
|
||||
# and output the contents in a syntax highlighted code block inside a figure,
|
||||
# with a figcaption listing the file name and download link
|
||||
#
|
||||
# Example 2:
|
||||
# You can also include an optional title for the <figcaption>
|
||||
#
|
||||
# {% include_code Example 2 javascripts/test.js %}
|
||||
#
|
||||
# will output a figcaption with the title: Example 2 (test.js)
|
||||
#
|
||||
|
||||
require './plugins/pygments_code'
|
||||
require './plugins/raw'
|
||||
require 'pathname'
|
||||
|
||||
module Jekyll
|
||||
|
||||
class IncludeCodeTag < Liquid::Tag
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@title = nil
|
||||
@file = nil
|
||||
if markup.strip =~ /\s*lang:(\S+)/i
|
||||
@filetype = $1
|
||||
markup = markup.strip.sub(/lang:\S+/i,'')
|
||||
end
|
||||
if markup.strip =~ /(.*)?(\s+|^)(\/*\S+)/i
|
||||
@title = $1 || nil
|
||||
@file = $3
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
code_dir = (context.registers[:site].config['code_dir'].sub(/^\//,'') || 'downloads/code')
|
||||
code_path = (Pathname.new(context.registers[:site].source) + code_dir).expand_path
|
||||
file = code_path + @file
|
||||
|
||||
if File.symlink?(code_path)
|
||||
return "Code directory '#{code_path}' cannot be a symlink"
|
||||
end
|
||||
|
||||
unless file.file?
|
||||
return "File #{file} could not be found"
|
||||
end
|
||||
|
||||
Dir.chdir(code_path) do
|
||||
code = file.read
|
||||
@filetype = file.extname.sub('.','') if @filetype.nil?
|
||||
title = @title ? "#{@title} (#{file.basename})" : file.basename
|
||||
url = "/#{code_dir}/#{@file}"
|
||||
source = "<figure class='code'><figcaption><span>#{title}</span> <a href='#{url}'>download</a></figcaption>\n"
|
||||
source += "#{HighlightCode::highlight(code, @filetype)}</figure>"
|
||||
TemplateWrapper::safe_wrap(source)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('include_code', Jekyll::IncludeCodeTag)
|
@ -1,40 +0,0 @@
|
||||
# Title: jsFiddle tag for Jekyll
|
||||
# Author: Brian Arnold (@brianarn)
|
||||
# Description:
|
||||
# Given a jsFiddle shortcode, outputs the jsFiddle iframe code.
|
||||
# Using 'default' will preserve defaults as specified by jsFiddle.
|
||||
#
|
||||
# Syntax: {% jsfiddle shorttag [tabs] [skin] [height] [width] %}
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# Input: {% jsfiddle ccWP7 %}
|
||||
# Output: <iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/ccWP7/embedded/js,resources,html,css,result/light/"></iframe>
|
||||
#
|
||||
# Input: {% jsfiddle ccWP7 js,html,result %}
|
||||
# Output: <iframe style="width: 100%; height: 300px" src="http://jsfiddle.net/ccWP7/embedded/js,html,result/light/"></iframe>
|
||||
#
|
||||
|
||||
module Jekyll
|
||||
class JsFiddle < Liquid::Tag
|
||||
def initialize(tag_name, markup, tokens)
|
||||
if /(?<fiddle>\w+\/?\d?)(?:\s+(?<sequence>[\w,]+))?(?:\s+(?<skin>\w+))?(?:\s+(?<height>\w+))?(?:\s+(?<width>\w+))?/ =~ markup
|
||||
@fiddle = fiddle
|
||||
@sequence = (sequence unless sequence == 'default') || 'js,resources,html,css,result'
|
||||
@skin = (skin unless skin == 'default') || 'light'
|
||||
@width = width || '100%'
|
||||
@height = height || '300px'
|
||||
end
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if @fiddle
|
||||
"<iframe style=\"width: #{@width}; height: #{@height}\" frameborder=\"0\" seamless=\"seamless\" src=\"http://jsfiddle.net/#{@fiddle}/embedded/#{@sequence}/#{@skin}/\"></iframe>"
|
||||
else
|
||||
"Error processing input, expected syntax: {% jsfiddle shorttag [tabs] [skin] [height] [width] %}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('jsfiddle', Jekyll::JsFiddle)
|
@ -1,142 +0,0 @@
|
||||
#custom filters for Octopress
|
||||
require './plugins/backtick_code_block'
|
||||
require 'octopress-hooks'
|
||||
require 'jekyll-sitemap'
|
||||
require 'octopress-date-format'
|
||||
require './plugins/raw'
|
||||
require 'rubypants'
|
||||
|
||||
module OctopressFilters
|
||||
def self.pre_filter(page)
|
||||
if page.ext.match('html|textile|markdown|md|haml|slim|xml')
|
||||
input = BacktickCodeBlock::render_code_block(page.content)
|
||||
page.content = input.gsub /(<figure.+?>.+?<\/figure>)/m do
|
||||
TemplateWrapper::safe_wrap($1)
|
||||
end
|
||||
end
|
||||
end
|
||||
def self.post_filter(page)
|
||||
if page.ext.match('html|textile|markdown|md|haml|slim|xml')
|
||||
page.output = TemplateWrapper::unwrap(page.output)
|
||||
end
|
||||
|
||||
page.output = RubyPants.new(page.output).to_html
|
||||
end
|
||||
|
||||
class PageFilters < Octopress::Hooks::Page
|
||||
def pre_render(page)
|
||||
OctopressFilters::pre_filter(page)
|
||||
end
|
||||
|
||||
def post_render(page)
|
||||
OctopressFilters::post_filter(page)
|
||||
end
|
||||
end
|
||||
|
||||
class PostFilters < Octopress::Hooks::Post
|
||||
def pre_render(post)
|
||||
OctopressFilters::pre_filter(post)
|
||||
end
|
||||
|
||||
def post_render(post)
|
||||
OctopressFilters::post_filter(post)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module OctopressLiquidFilters
|
||||
|
||||
# Used on the blog index to split posts on the <!--more--> marker
|
||||
def excerpt(input)
|
||||
if input.index(/<!--\s*more\s*-->/i)
|
||||
input.split(/<!--\s*more\s*-->/i)[0]
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Checks for excerpts (helpful for template conditionals)
|
||||
def has_excerpt(input)
|
||||
input =~ /<!--\s*more\s*-->/i ? true : false
|
||||
end
|
||||
|
||||
# Summary is used on the Archive pages to return the first block of content from a post.
|
||||
def summary(input)
|
||||
if input.index(/\n\n/)
|
||||
input.split(/\n\n/)[0]
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Extracts raw content DIV from template, used for page description as {{ content }}
|
||||
# contains complete sub-template code on main page level
|
||||
def raw_content(input)
|
||||
/<div class="entry-content">(?<content>[\s\S]*?)<\/div>\s*<(footer|\/article)>/ =~ input
|
||||
return (content.nil?) ? input : content
|
||||
end
|
||||
|
||||
# Escapes CDATA sections in post content
|
||||
def cdata_escape(input)
|
||||
input.gsub(/<!\[CDATA\[/, '<![CDATA[').gsub(/\]\]>/, ']]>')
|
||||
end
|
||||
|
||||
# Replaces relative urls with full urls
|
||||
def expand_urls(input, url='')
|
||||
url ||= '/'
|
||||
input.gsub /(\s+(href|src)\s*=\s*["|']{1})(\/[^\/>]{1}[^\"'>]*)/ do
|
||||
$1+url+$3
|
||||
end
|
||||
end
|
||||
|
||||
# Improved version of Liquid's truncate:
|
||||
# - Doesn't cut in the middle of a word.
|
||||
# - Uses typographically correct ellipsis (…) insted of '...'
|
||||
def truncate(input, length)
|
||||
if input.length > length && input[0..(length-1)] =~ /(.+)\b.+$/im
|
||||
$1.strip + ' …'
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Improved version of Liquid's truncatewords:
|
||||
# - Uses typographically correct ellipsis (…) insted of '...'
|
||||
def truncatewords(input, length)
|
||||
truncate = input.split(' ')
|
||||
if truncate.length > length
|
||||
truncate[0..length-1].join(' ').strip + ' …'
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Condenses multiple spaces and tabs into a single space
|
||||
def condense_spaces(input)
|
||||
input.gsub(/\s{2,}/, ' ')
|
||||
end
|
||||
|
||||
# Removes trailing forward slash from a string for easily appending url segments
|
||||
def strip_slash(input)
|
||||
if input =~ /(.+)\/$|^\/$/
|
||||
input = $1
|
||||
end
|
||||
input
|
||||
end
|
||||
|
||||
# Returns a url without the protocol (http://)
|
||||
def shorthand_url(input)
|
||||
input.gsub /(https?:\/\/)(\S+)/ do
|
||||
$2
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a title cased string based on John Gruber's title case http://daringfireball.net/2008/08/title_case_update
|
||||
def titlecase(input)
|
||||
input.titlecase
|
||||
end
|
||||
|
||||
end
|
||||
Liquid::Template.register_filter OctopressLiquidFilters
|
||||
|
@ -1,45 +0,0 @@
|
||||
#
|
||||
# Author: Brandon Mathis
|
||||
# Based on the semantic pullquote technique by Maykel Loomans at http://miekd.com/articles/pull-quotes-with-html5-and-css/
|
||||
#
|
||||
# Outputs a span with a data-pullquote attribute set from the marked pullquote. Example:
|
||||
#
|
||||
# {% pullquote %}
|
||||
# When writing longform posts, I find it helpful to include pullquotes, which help those scanning a post discern whether or not a post is helpful.
|
||||
# It is important to note, {" pullquotes are merely visual in presentation and should not appear twice in the text. "} That is why it is prefered
|
||||
# to use a CSS only technique for styling pullquotes.
|
||||
# {% endpullquote %}
|
||||
# ...will output...
|
||||
# <p>
|
||||
# <span data-pullquote="pullquotes are merely visual in presentation and should not appear twice in the text.">
|
||||
# When writing longform posts, I find it helpful to include pullquotes, which help those scanning a post discern whether or not a post is helpful.
|
||||
# It is important to note, pullquotes are merely visual in presentation and should not appear twice in the text. This is why a CSS only approach
|
||||
# for styling pullquotes is prefered.
|
||||
# </span>
|
||||
# </p>
|
||||
#
|
||||
# {% pullquote left %} will create a left-aligned pullquote instead.
|
||||
#
|
||||
# Note: this plugin now creates pullquotes with the class of pullquote-right by default
|
||||
|
||||
module Jekyll
|
||||
|
||||
class PullquoteTag < Liquid::Block
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@align = (markup =~ /left/i) ? "left" : "right"
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
output = super
|
||||
if output =~ /\{"\s*(.+?)\s*"\}/m
|
||||
@quote = RubyPants.new($1).to_html
|
||||
"<span class='pullquote-#{@align}' data-pullquote='#{@quote}'>#{output.gsub(/\{"\s*|\s*"\}/, '')}</span>"
|
||||
else
|
||||
return "Surround your pullquote like this {\" text to be quoted \"}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('pullquote', Jekyll::PullquoteTag)
|
@ -1,45 +0,0 @@
|
||||
require 'pygments'
|
||||
require 'fileutils'
|
||||
require 'digest/md5'
|
||||
|
||||
PYGMENTS_CACHE_DIR = File.expand_path('../../.pygments-cache', __FILE__)
|
||||
FileUtils.mkdir_p(PYGMENTS_CACHE_DIR)
|
||||
|
||||
module HighlightCode
|
||||
def self.highlight(str, lang)
|
||||
lang = 'ruby' if lang == 'ru'
|
||||
lang = 'objc' if lang == 'm'
|
||||
lang = 'perl' if lang == 'pl'
|
||||
lang = 'yaml' if lang == 'yml'
|
||||
str = pygments(str, lang).match(/<pre>(.+)<\/pre>/m)[1].to_s.gsub(/ *$/, '') #strip out divs <div class="highlight">
|
||||
tableize_code(str, lang)
|
||||
end
|
||||
|
||||
def self.pygments(code, lang)
|
||||
if defined?(PYGMENTS_CACHE_DIR)
|
||||
path = File.join(PYGMENTS_CACHE_DIR, "#{lang}-#{Digest::MD5.hexdigest(code)}.html")
|
||||
if File.exist?(path)
|
||||
highlighted_code = File.read(path)
|
||||
else
|
||||
begin
|
||||
highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html', :options => {:encoding => 'utf-8', :startinline => true})
|
||||
rescue MentosError
|
||||
raise "Pygments can't parse unknown language: #{lang}."
|
||||
end
|
||||
File.open(path, 'w') {|f| f.print(highlighted_code) }
|
||||
end
|
||||
else
|
||||
highlighted_code = Pygments.highlight(code, :lexer => lang, :formatter => 'html', :options => {:encoding => 'utf-8', :startinline => true})
|
||||
end
|
||||
highlighted_code
|
||||
end
|
||||
def self.tableize_code (str, lang = '')
|
||||
table = '<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers">'
|
||||
code = ''
|
||||
str.lines.each_with_index do |line,index|
|
||||
table += "<span class='line-number'>#{index+1}</span>\n"
|
||||
code += "<span class='line'>#{line}</span>"
|
||||
end
|
||||
table += "</pre></td><td class='code'><pre><code class='#{lang}'>#{code}</code></pre></td></tr></table></div>"
|
||||
end
|
||||
end
|
@ -1,40 +0,0 @@
|
||||
# Author: Brandon Mathis
|
||||
# Description: Provides plugins with a method for wrapping and unwrapping input to prevent Markdown and Textile from parsing it.
|
||||
# Purpose: This is useful for preventing Markdown and Textile from being too aggressive and incorrectly parsing in-line HTML.
|
||||
module TemplateWrapper
|
||||
# Wrap input with a <div>
|
||||
def self.safe_wrap(input)
|
||||
"<div class='bogus-wrapper'><notextile>#{input}</notextile></div>"
|
||||
end
|
||||
# This must be applied after the
|
||||
def self.unwrap(input)
|
||||
input.gsub /<div class='bogus-wrapper'><notextile>(.+?)<\/notextile><\/div>/m do
|
||||
$1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Author: phaer, https://github.com/phaer
|
||||
# Source: https://gist.github.com/1020852
|
||||
# Description: Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %} and {% endraw %}
|
||||
|
||||
module Jekyll
|
||||
class RawTag < Liquid::Block
|
||||
def parse(tokens)
|
||||
@nodelist ||= []
|
||||
@nodelist.clear
|
||||
|
||||
while token = tokens.shift
|
||||
if token =~ FullToken
|
||||
if block_delimiter == $1
|
||||
end_tag
|
||||
return
|
||||
end
|
||||
end
|
||||
@nodelist << token if not token.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('raw', Jekyll::RawTag)
|
@ -1,69 +0,0 @@
|
||||
# Title: Render Partial Tag for Jekyll
|
||||
# Author: Brandon Mathis http://brandonmathis.com
|
||||
# Description: Import files on your filesystem into any blog post and render them inline.
|
||||
# Note: Paths are relative to the source directory, if you import a file with yaml front matter, the yaml will be stripped out.
|
||||
#
|
||||
# Syntax {% render_partial path/to/file %}
|
||||
#
|
||||
# Example 1:
|
||||
# {% render_partial about/_bio.markdown %}
|
||||
#
|
||||
# This will import source/about/_bio.markdown and render it inline.
|
||||
# In this example I used an underscore at the beginning of the filename to prevent Jekyll
|
||||
# from generating an about/bio.html (Jekyll doesn't convert files beginning with underscores)
|
||||
#
|
||||
# Example 2:
|
||||
# {% render_partial ../README.markdown %}
|
||||
#
|
||||
# You can use relative pathnames, to include files outside of the source directory.
|
||||
# This might be useful if you want to have a page for a project's README without having
|
||||
# to duplicated the contents
|
||||
#
|
||||
#
|
||||
|
||||
require 'pathname'
|
||||
require './plugins/octopress_filters'
|
||||
|
||||
module Jekyll
|
||||
|
||||
class RenderPartialTag < Liquid::Tag
|
||||
include OctopressFilters
|
||||
def initialize(tag_name, markup, tokens)
|
||||
@file = nil
|
||||
@raw = false
|
||||
if markup =~ /^(\S+)\s?(\w+)?/
|
||||
@file = $1.strip
|
||||
@raw = $2 == 'raw'
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
file_dir = (context.registers[:site].source || 'source')
|
||||
file_path = Pathname.new(file_dir).expand_path
|
||||
file = file_path + @file
|
||||
|
||||
unless file.file?
|
||||
return "File #{file} could not be found"
|
||||
end
|
||||
|
||||
Dir.chdir(file_path) do
|
||||
contents = file.read
|
||||
if contents =~ /\A-{3}.+[^\A]-{3}\n(.+)/m
|
||||
contents = $1.lstrip
|
||||
end
|
||||
contents = pre_filter(contents)
|
||||
if @raw
|
||||
contents
|
||||
else
|
||||
partial = Liquid::Template.parse(contents)
|
||||
context.stack do
|
||||
partial.render(context)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('render_partial', Jekyll::RenderPartialTag)
|
@ -1,489 +0,0 @@
|
||||
#
|
||||
# = RubyPants -- SmartyPants ported to Ruby
|
||||
#
|
||||
# Ported by Christian Neukirchen <mailto:chneukirchen@gmail.com>
|
||||
# Copyright (C) 2004 Christian Neukirchen
|
||||
#
|
||||
# Incooporates ideas, comments and documentation by Chad Miller
|
||||
# Copyright (C) 2004 Chad Miller
|
||||
#
|
||||
# Original SmartyPants by John Gruber
|
||||
# Copyright (C) 2003 John Gruber
|
||||
#
|
||||
|
||||
#
|
||||
# = RubyPants -- SmartyPants ported to Ruby
|
||||
#
|
||||
# == Synopsis
|
||||
#
|
||||
# RubyPants is a Ruby port of the smart-quotes library SmartyPants.
|
||||
#
|
||||
# The original "SmartyPants" is a free web publishing plug-in for
|
||||
# Movable Type, Blosxom, and BBEdit that easily translates plain ASCII
|
||||
# punctuation characters into "smart" typographic punctuation HTML
|
||||
# entities.
|
||||
#
|
||||
#
|
||||
# == Description
|
||||
#
|
||||
# RubyPants can perform the following transformations:
|
||||
#
|
||||
# * Straight quotes (<tt>"</tt> and <tt>'</tt>) into "curly" quote
|
||||
# HTML entities
|
||||
# * Backticks-style quotes (<tt>``like this''</tt>) into "curly" quote
|
||||
# HTML entities
|
||||
# * Dashes (<tt>--</tt> and <tt>---</tt>) into en- and em-dash
|
||||
# entities
|
||||
# * Three consecutive dots (<tt>...</tt> or <tt>. . .</tt>) into an
|
||||
# ellipsis entity
|
||||
#
|
||||
# This means you can write, edit, and save your posts using plain old
|
||||
# ASCII straight quotes, plain dashes, and plain dots, but your
|
||||
# published posts (and final HTML output) will appear with smart
|
||||
# quotes, em-dashes, and proper ellipses.
|
||||
#
|
||||
# RubyPants does not modify characters within <tt><pre></tt>,
|
||||
# <tt><code></tt>, <tt><kbd></tt>, <tt><math></tt> or
|
||||
# <tt><script></tt> tag blocks. Typically, these tags are used to
|
||||
# display text where smart quotes and other "smart punctuation" would
|
||||
# not be appropriate, such as source code or example markup.
|
||||
#
|
||||
#
|
||||
# == Backslash Escapes
|
||||
#
|
||||
# If you need to use literal straight quotes (or plain hyphens and
|
||||
# periods), RubyPants accepts the following backslash escape sequences
|
||||
# to force non-smart punctuation. It does so by transforming the
|
||||
# escape sequence into a decimal-encoded HTML entity:
|
||||
#
|
||||
# \\ \" \' \. \- \`
|
||||
#
|
||||
# This is useful, for example, when you want to use straight quotes as
|
||||
# foot and inch marks: 6'2" tall; a 17" iMac. (Use <tt>6\'2\"</tt>
|
||||
# resp. <tt>17\"</tt>.)
|
||||
#
|
||||
#
|
||||
# == Algorithmic Shortcomings
|
||||
#
|
||||
# One situation in which quotes will get curled the wrong way is when
|
||||
# apostrophes are used at the start of leading contractions. For
|
||||
# example:
|
||||
#
|
||||
# 'Twas the night before Christmas.
|
||||
#
|
||||
# In the case above, RubyPants will turn the apostrophe into an
|
||||
# opening single-quote, when in fact it should be a closing one. I
|
||||
# don't think this problem can be solved in the general case--every
|
||||
# word processor I've tried gets this wrong as well. In such cases,
|
||||
# it's best to use the proper HTML entity for closing single-quotes
|
||||
# ("<tt>’</tt>") by hand.
|
||||
#
|
||||
#
|
||||
# == Bugs
|
||||
#
|
||||
# To file bug reports or feature requests (except see above) please
|
||||
# send email to: mailto:chneukirchen@gmail.com
|
||||
#
|
||||
# If the bug involves quotes being curled the wrong way, please send
|
||||
# example text to illustrate.
|
||||
#
|
||||
#
|
||||
# == Authors
|
||||
#
|
||||
# John Gruber did all of the hard work of writing this software in
|
||||
# Perl for Movable Type and almost all of this useful documentation.
|
||||
# Chad Miller ported it to Python to use with Pyblosxom.
|
||||
#
|
||||
# Christian Neukirchen provided the Ruby port, as a general-purpose
|
||||
# library that follows the *Cloth API.
|
||||
#
|
||||
#
|
||||
# == Copyright and License
|
||||
#
|
||||
# === SmartyPants license:
|
||||
#
|
||||
# Copyright (c) 2003 John Gruber
|
||||
# (http://daringfireball.net)
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# * Neither the name "SmartyPants" nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this
|
||||
# software without specific prior written permission.
|
||||
#
|
||||
# This software is provided by the copyright holders and contributors
|
||||
# "as is" and any express or implied warranties, including, but not
|
||||
# limited to, the implied warranties of merchantability and fitness
|
||||
# for a particular purpose are disclaimed. In no event shall the
|
||||
# copyright owner or contributors be liable for any direct, indirect,
|
||||
# incidental, special, exemplary, or consequential damages (including,
|
||||
# but not limited to, procurement of substitute goods or services;
|
||||
# loss of use, data, or profits; or business interruption) however
|
||||
# caused and on any theory of liability, whether in contract, strict
|
||||
# liability, or tort (including negligence or otherwise) arising in
|
||||
# any way out of the use of this software, even if advised of the
|
||||
# possibility of such damage.
|
||||
#
|
||||
# === RubyPants license
|
||||
#
|
||||
# RubyPants is a derivative work of SmartyPants and smartypants.py.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# This software is provided by the copyright holders and contributors
|
||||
# "as is" and any express or implied warranties, including, but not
|
||||
# limited to, the implied warranties of merchantability and fitness
|
||||
# for a particular purpose are disclaimed. In no event shall the
|
||||
# copyright owner or contributors be liable for any direct, indirect,
|
||||
# incidental, special, exemplary, or consequential damages (including,
|
||||
# but not limited to, procurement of substitute goods or services;
|
||||
# loss of use, data, or profits; or business interruption) however
|
||||
# caused and on any theory of liability, whether in contract, strict
|
||||
# liability, or tort (including negligence or otherwise) arising in
|
||||
# any way out of the use of this software, even if advised of the
|
||||
# possibility of such damage.
|
||||
#
|
||||
#
|
||||
# == Links
|
||||
#
|
||||
# John Gruber:: http://daringfireball.net
|
||||
# SmartyPants:: http://daringfireball.net/projects/smartypants
|
||||
#
|
||||
# Chad Miller:: http://web.chad.org
|
||||
#
|
||||
# Christian Neukirchen:: http://kronavita.de/chris
|
||||
#
|
||||
|
||||
|
||||
class RubyPants < String
|
||||
|
||||
# Create a new RubyPants instance with the text in +string+.
|
||||
#
|
||||
# Allowed elements in the options array:
|
||||
#
|
||||
# 0 :: do nothing
|
||||
# 1 :: enable all, using only em-dash shortcuts
|
||||
# 2 :: enable all, using old school en- and em-dash shortcuts (*default*)
|
||||
# 3 :: enable all, using inverted old school en and em-dash shortcuts
|
||||
# -1 :: stupefy (translate HTML entities to their ASCII-counterparts)
|
||||
#
|
||||
# If you don't like any of these defaults, you can pass symbols to change
|
||||
# RubyPants' behavior:
|
||||
#
|
||||
# <tt>:quotes</tt> :: quotes
|
||||
# <tt>:backticks</tt> :: backtick quotes (``double'' only)
|
||||
# <tt>:allbackticks</tt> :: backtick quotes (``double'' and `single')
|
||||
# <tt>:dashes</tt> :: dashes
|
||||
# <tt>:oldschool</tt> :: old school dashes
|
||||
# <tt>:inverted</tt> :: inverted old school dashes
|
||||
# <tt>:ellipses</tt> :: ellipses
|
||||
# <tt>:convertquotes</tt> :: convert <tt>"</tt> entities to
|
||||
# <tt>"</tt> for Dreamweaver users
|
||||
# <tt>:stupefy</tt> :: translate RubyPants HTML entities
|
||||
# to their ASCII counterparts.
|
||||
#
|
||||
def initialize(string, options=[2])
|
||||
super string
|
||||
@options = [*options]
|
||||
end
|
||||
|
||||
# Apply SmartyPants transformations.
|
||||
def to_html
|
||||
do_quotes = do_backticks = do_dashes = do_ellipses = do_stupify = nil
|
||||
convert_quotes = false
|
||||
|
||||
if @options.include? 0
|
||||
# Do nothing.
|
||||
return self
|
||||
elsif @options.include? 1
|
||||
# Do everything, turn all options on.
|
||||
do_quotes = do_backticks = do_ellipses = true
|
||||
do_dashes = :normal
|
||||
elsif @options.include? 2
|
||||
# Do everything, turn all options on, use old school dash shorthand.
|
||||
do_quotes = do_backticks = do_ellipses = true
|
||||
do_dashes = :oldschool
|
||||
elsif @options.include? 3
|
||||
# Do everything, turn all options on, use inverted old school
|
||||
# dash shorthand.
|
||||
do_quotes = do_backticks = do_ellipses = true
|
||||
do_dashes = :inverted
|
||||
elsif @options.include?(-1)
|
||||
do_stupefy = true
|
||||
else
|
||||
do_quotes = @options.include? :quotes
|
||||
do_backticks = @options.include? :backticks
|
||||
do_backticks = :both if @options.include? :allbackticks
|
||||
do_dashes = :normal if @options.include? :dashes
|
||||
do_dashes = :oldschool if @options.include? :oldschool
|
||||
do_dashes = :inverted if @options.include? :inverted
|
||||
do_ellipses = @options.include? :ellipses
|
||||
convert_quotes = @options.include? :convertquotes
|
||||
do_stupefy = @options.include? :stupefy
|
||||
end
|
||||
|
||||
# Parse the HTML
|
||||
tokens = tokenize
|
||||
|
||||
# Keep track of when we're inside <pre> or <code> tags.
|
||||
in_pre = false
|
||||
|
||||
# Here is the result stored in.
|
||||
result = ""
|
||||
|
||||
# This is a cheat, used to get some context for one-character
|
||||
# tokens that consist of just a quote char. What we do is remember
|
||||
# the last character of the previous text token, to use as context
|
||||
# to curl single- character quote tokens correctly.
|
||||
prev_token_last_char = nil
|
||||
|
||||
tokens.each { |token|
|
||||
if token.first == :tag
|
||||
result << token[1]
|
||||
if token[1] =~ %r!<(/?)(?:pre|code|kbd|script|math)[\s>]!
|
||||
in_pre = ($1 != "/") # Opening or closing tag?
|
||||
end
|
||||
else
|
||||
t = token[1]
|
||||
|
||||
# Remember last char of this token before processing.
|
||||
last_char = t[-1].chr
|
||||
|
||||
unless in_pre
|
||||
t = process_escapes t
|
||||
|
||||
t.gsub!(/"/, '"') if convert_quotes
|
||||
|
||||
if do_dashes
|
||||
t = educate_dashes t if do_dashes == :normal
|
||||
t = educate_dashes_oldschool t if do_dashes == :oldschool
|
||||
t = educate_dashes_inverted t if do_dashes == :inverted
|
||||
end
|
||||
|
||||
t = educate_ellipses t if do_ellipses
|
||||
|
||||
# Note: backticks need to be processed before quotes.
|
||||
if do_backticks
|
||||
t = educate_backticks t
|
||||
t = educate_single_backticks t if do_backticks == :both
|
||||
end
|
||||
|
||||
if do_quotes
|
||||
if t == "'"
|
||||
# Special case: single-character ' token
|
||||
if prev_token_last_char =~ /\S/
|
||||
t = "’"
|
||||
else
|
||||
t = "‘"
|
||||
end
|
||||
elsif t == '"'
|
||||
# Special case: single-character " token
|
||||
if prev_token_last_char =~ /\S/
|
||||
t = "”"
|
||||
else
|
||||
t = "“"
|
||||
end
|
||||
else
|
||||
# Normal case:
|
||||
t = educate_quotes t
|
||||
end
|
||||
end
|
||||
|
||||
t = stupefy_entities t if do_stupefy
|
||||
end
|
||||
|
||||
prev_token_last_char = last_char
|
||||
result << t
|
||||
end
|
||||
}
|
||||
|
||||
# Done
|
||||
result
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Return the string, with after processing the following backslash
|
||||
# escape sequences. This is useful if you want to force a "dumb" quote
|
||||
# or other character to appear.
|
||||
#
|
||||
# Escaped are:
|
||||
# \\ \" \' \. \- \`
|
||||
#
|
||||
def process_escapes(str)
|
||||
str.gsub('\\\\', '\').
|
||||
gsub('\"', '"').
|
||||
gsub("\\\'", ''').
|
||||
gsub('\.', '.').
|
||||
gsub('\-', '-').
|
||||
gsub('\`', '`')
|
||||
end
|
||||
|
||||
# The string, with each instance of "<tt>--</tt>" translated to an
|
||||
# em-dash HTML entity.
|
||||
#
|
||||
def educate_dashes(str)
|
||||
str.gsub(/--/, '—')
|
||||
end
|
||||
|
||||
# The string, with each instance of "<tt>--</tt>" translated to an
|
||||
# en-dash HTML entity, and each "<tt>---</tt>" translated to an
|
||||
# em-dash HTML entity.
|
||||
#
|
||||
def educate_dashes_oldschool(str)
|
||||
str.gsub(/---/, '—').gsub(/--/, '–')
|
||||
end
|
||||
|
||||
# Return the string, with each instance of "<tt>--</tt>" translated
|
||||
# to an em-dash HTML entity, and each "<tt>---</tt>" translated to
|
||||
# an en-dash HTML entity. Two reasons why: First, unlike the en- and
|
||||
# em-dash syntax supported by +educate_dashes_oldschool+, it's
|
||||
# compatible with existing entries written before SmartyPants 1.1,
|
||||
# back when "<tt>--</tt>" was only used for em-dashes. Second,
|
||||
# em-dashes are more common than en-dashes, and so it sort of makes
|
||||
# sense that the shortcut should be shorter to type. (Thanks to
|
||||
# Aaron Swartz for the idea.)
|
||||
#
|
||||
def educate_dashes_inverted(str)
|
||||
str.gsub(/---/, '–').gsub(/--/, '—')
|
||||
end
|
||||
|
||||
# Return the string, with each instance of "<tt>...</tt>" translated
|
||||
# to an ellipsis HTML entity. Also converts the case where there are
|
||||
# spaces between the dots.
|
||||
#
|
||||
def educate_ellipses(str)
|
||||
str.gsub('...', '…').gsub('. . .', '…')
|
||||
end
|
||||
|
||||
# Return the string, with "<tt>``backticks''</tt>"-style single quotes
|
||||
# translated into HTML curly quote entities.
|
||||
#
|
||||
def educate_backticks(str)
|
||||
str.gsub("``", '“').gsub("''", '”')
|
||||
end
|
||||
|
||||
# Return the string, with "<tt>`backticks'</tt>"-style single quotes
|
||||
# translated into HTML curly quote entities.
|
||||
#
|
||||
def educate_single_backticks(str)
|
||||
str.gsub("`", '‘').gsub("'", '’')
|
||||
end
|
||||
|
||||
# Return the string, with "educated" curly quote HTML entities.
|
||||
#
|
||||
def educate_quotes(str)
|
||||
punct_class = '[!"#\$\%\'()*+,\-.\/:;<=>?\@\[\\\\\]\^_`{|}~]'
|
||||
|
||||
str = str.dup
|
||||
|
||||
# Special case if the very first character is a quote followed by
|
||||
# punctuation at a non-word-break. Close the quotes by brute
|
||||
# force:
|
||||
str.gsub!(/^'(?=#{punct_class}\B)/, '’')
|
||||
str.gsub!(/^"(?=#{punct_class}\B)/, '”')
|
||||
|
||||
# Special case for double sets of quotes, e.g.:
|
||||
# <p>He said, "'Quoted' words in a larger quote."</p>
|
||||
str.gsub!(/"'(?=\w)/, '“‘')
|
||||
str.gsub!(/'"(?=\w)/, '‘“')
|
||||
|
||||
# Special case for decade abbreviations (the '80s):
|
||||
str.gsub!(/'(?=\d\ds)/, '’')
|
||||
|
||||
close_class = %![^\ \t\r\n\\[\{\(\-]!
|
||||
dec_dashes = '–|—'
|
||||
|
||||
# Get most opening single quotes:
|
||||
str.gsub!(/(\s| |--|&[mn]dash;|#{dec_dashes}|ȁ[34];)'(?=\w)/,
|
||||
'\1‘')
|
||||
# Single closing quotes:
|
||||
str.gsub!(/(#{close_class})'/, '\1’')
|
||||
str.gsub!(/'(\s|s\b|$)/, '’\1')
|
||||
# Any remaining single quotes should be opening ones:
|
||||
str.gsub!(/'/, '‘')
|
||||
|
||||
# Get most opening double quotes:
|
||||
str.gsub!(/(\s| |--|&[mn]dash;|#{dec_dashes}|ȁ[34];)"(?=\w)/,
|
||||
'\1“')
|
||||
# Double closing quotes:
|
||||
str.gsub!(/(#{close_class})"/, '\1”')
|
||||
str.gsub!(/"(\s|s\b|$)/, '”\1')
|
||||
# Any remaining quotes should be opening ones:
|
||||
str.gsub!(/"/, '“')
|
||||
|
||||
str
|
||||
end
|
||||
|
||||
# Return the string, with each RubyPants HTML entity translated to
|
||||
# its ASCII counterpart.
|
||||
#
|
||||
# Note: This is not reversible (but exactly the same as in SmartyPants)
|
||||
#
|
||||
def stupefy_entities(str)
|
||||
str.
|
||||
gsub(/–/, '-'). # en-dash
|
||||
gsub(/—/, '--'). # em-dash
|
||||
|
||||
gsub(/‘/, "'"). # open single quote
|
||||
gsub(/’/, "'"). # close single quote
|
||||
|
||||
gsub(/“/, '"'). # open double quote
|
||||
gsub(/”/, '"'). # close double quote
|
||||
|
||||
gsub(/…/, '...') # ellipsis
|
||||
end
|
||||
|
||||
# Return an array of the tokens comprising the string. Each token is
|
||||
# either a tag (possibly with nested, tags contained therein, such
|
||||
# as <tt><a href="<MTFoo>"></tt>, or a run of text between
|
||||
# tags. Each element of the array is a two-element array; the first
|
||||
# is either :tag or :text; the second is the actual value.
|
||||
#
|
||||
# Based on the <tt>_tokenize()</tt> subroutine from Brad Choate's
|
||||
# MTRegex plugin. <http://www.bradchoate.com/past/mtregex.php>
|
||||
#
|
||||
# This is actually the easier variant using tag_soup, as used by
|
||||
# Chad Miller in the Python port of SmartyPants.
|
||||
#
|
||||
def tokenize
|
||||
tag_soup = /([^<]*)(<[^>]*>)/
|
||||
|
||||
tokens = []
|
||||
|
||||
prev_end = 0
|
||||
scan(tag_soup) {
|
||||
tokens << [:text, $1] if $1 != ""
|
||||
tokens << [:tag, $2]
|
||||
|
||||
prev_end = $~.end(0)
|
||||
}
|
||||
|
||||
if prev_end < size
|
||||
tokens << [:text, self[prev_end..-1]]
|
||||
end
|
||||
|
||||
tokens
|
||||
end
|
||||
end
|
@ -1,56 +0,0 @@
|
||||
# Title: Simple Video tag for Jekyll
|
||||
# Author: Brandon Mathis http://brandonmathis.com
|
||||
# Description: Easily output MPEG4 HTML5 video with a flash backup.
|
||||
#
|
||||
# Syntax {% video url/to/video [width height] [url/to/poster] %}
|
||||
#
|
||||
# Example:
|
||||
# {% video http://site.com/video.mp4 720 480 http://site.com/poster-frame.jpg %}
|
||||
#
|
||||
# Output:
|
||||
# <video width='720' height='480' preload='none' controls poster='http://site.com/poster-frame.jpg'>
|
||||
# <source src='http://site.com/video.mp4' type='video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'/>
|
||||
# </video>
|
||||
#
|
||||
|
||||
module Jekyll
|
||||
|
||||
class VideoTag < Liquid::Tag
|
||||
@video = nil
|
||||
@poster = ''
|
||||
@height = ''
|
||||
@width = ''
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
if markup =~ /(https?:\S+)(\s+(https?:\S+))?(\s+(https?:\S+))?(\s+(\d+)\s(\d+))?(\s+(https?:\S+))?/i
|
||||
@video = [$1, $3, $5].compact
|
||||
@width = $7
|
||||
@height = $8
|
||||
@poster = $10
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def render(context)
|
||||
output = super
|
||||
type = {
|
||||
'mp4' => "type='video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"'",
|
||||
'ogv' => "type='video/ogg; codecs=theora, vorbis'",
|
||||
'webm' => "type='video/webm; codecs=vp8, vorbis'"
|
||||
}
|
||||
if @video.size > 0
|
||||
video = "<video width='#{@width}' height='#{@height}' preload='none' controls poster='#{@poster}'>"
|
||||
@video.each do |v|
|
||||
t = v.match(/([^\.]+)$/)[1]
|
||||
video += "<source src='#{v}' #{type[t]}>"
|
||||
end
|
||||
video += "</video>"
|
||||
else
|
||||
"Error processing input, expected syntax: {% video url/to/video [url/to/video] [url/to/video] [width height] [url/to/poster] %}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('video', Jekyll::VideoTag)
|
||||
|
@ -2,7 +2,7 @@
|
||||
@import "partials/navigation";
|
||||
@import "partials/blog";
|
||||
@import "partials/sharing";
|
||||
@import "partials/syntax";
|
||||
// @import "partials/syntax";
|
||||
@import "partials/archive";
|
||||
@import "partials/sidebar";
|
||||
@import "partials/footer";
|
||||
|
144
sass/custom/_coderay.scss
Normal file
144
sass/custom/_coderay.scss
Normal file
@ -0,0 +1,144 @@
|
||||
code {
|
||||
background: #fff;
|
||||
font-size: .8em;
|
||||
line-height: 1.5em;
|
||||
color: #555;
|
||||
border: 1px solid #ddd;
|
||||
@include border-radius(.4em);
|
||||
padding: 0 .3em;
|
||||
}
|
||||
|
||||
.CodeRay {
|
||||
background-color: #FFF;
|
||||
border: 1px solid #CCC;
|
||||
font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
|
||||
color: #000;
|
||||
padding: 1em 0px 1em 1em;
|
||||
font-size: 12px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.CodeRay pre {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
div.CodeRay { }
|
||||
span.CodeRay { white-space: pre; border: 0px; padding: 2px }
|
||||
|
||||
table.CodeRay { border-collapse: collapse; width: 100%; padding: 2px }
|
||||
table.CodeRay td {
|
||||
padding: 1em 0.5em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.CodeRay .line-numbers, .CodeRay .no {
|
||||
background-color: #ECECEC;
|
||||
color: #AAA;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.CodeRay .line-numbers a {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
.CodeRay .line-numbers tt { font-weight: bold }
|
||||
.CodeRay .line-numbers .highlighted { color: red }
|
||||
.CodeRay .line { display: block; float: left; width: 100%; }
|
||||
.CodeRay span.line-numbers { padding: 0px 4px }
|
||||
.CodeRay .code { width: 100% }
|
||||
|
||||
ol.CodeRay { font-size: 10pt }
|
||||
ol.CodeRay li { white-space: pre }
|
||||
|
||||
.CodeRay .code pre { overflow: auto }
|
||||
.CodeRay .debug { color:white ! important; background:blue ! important; }
|
||||
|
||||
.CodeRay .annotation { color:#007 }
|
||||
.CodeRay .attribute-name { color:#f08 }
|
||||
.CodeRay .attribute-value { color:#700 }
|
||||
.CodeRay .binary { color:#509; font-weight:bold }
|
||||
.CodeRay .comment { color:#998; font-style: italic;}
|
||||
.CodeRay .char { color:#04D }
|
||||
.CodeRay .char .content { color:#04D }
|
||||
.CodeRay .char .delimiter { color:#039 }
|
||||
.CodeRay .class { color:#458; font-weight:bold }
|
||||
.CodeRay .complex { color:#A08; font-weight:bold }
|
||||
.CodeRay .constant { color:teal; }
|
||||
.CodeRay .color { color:#0A0 }
|
||||
.CodeRay .class-variable { color:#369 }
|
||||
.CodeRay .decorator { color:#B0B; }
|
||||
.CodeRay .definition { color:#099; font-weight:bold }
|
||||
.CodeRay .directive { color:#088; font-weight:bold }
|
||||
.CodeRay .delimiter { color:black }
|
||||
.CodeRay .doc { color:#970 }
|
||||
.CodeRay .doctype { color:#34b }
|
||||
.CodeRay .doc-string { color:#D42; font-weight:bold }
|
||||
.CodeRay .escape { color:#666; font-weight:bold }
|
||||
.CodeRay .entity { color:#800; font-weight:bold }
|
||||
.CodeRay .error { color:#F00; background-color:#FAA }
|
||||
.CodeRay .exception { color:#C00; font-weight:bold }
|
||||
.CodeRay .filename { color:#099; }
|
||||
.CodeRay .function { color:#900; font-weight:bold }
|
||||
.CodeRay .global-variable { color:teal; font-weight:bold }
|
||||
.CodeRay .hex { color:#058; font-weight:bold }
|
||||
.CodeRay .integer { color:#099; }
|
||||
.CodeRay .include { color:#B44; font-weight:bold }
|
||||
.CodeRay .inline { color: black }
|
||||
.CodeRay .inline .inline { background: #ccc }
|
||||
.CodeRay .inline .inline .inline { background: #bbb }
|
||||
.CodeRay .inline .inline-delimiter { color: #D14; }
|
||||
.CodeRay .inline-delimiter { color: #D14; }
|
||||
.CodeRay .important { color:#f00; }
|
||||
.CodeRay .interpreted { color:#B2B; font-weight:bold }
|
||||
.CodeRay .instance-variable { color:teal }
|
||||
.CodeRay .label { color:#970; font-weight:bold }
|
||||
.CodeRay .local-variable { color:#963 }
|
||||
.CodeRay .octal { color:#40E; font-weight:bold }
|
||||
.CodeRay .operator { }
|
||||
.CodeRay .predefined-constant { font-weight:bold }
|
||||
.CodeRay .predefined { color:#369; font-weight:bold }
|
||||
.CodeRay .preprocessor { color:#579; }
|
||||
.CodeRay .pseudo-class { color:#00C; font-weight:bold }
|
||||
.CodeRay .predefined-type { color:#074; font-weight:bold }
|
||||
.CodeRay .reserved, .keyword { color:#000; font-weight:bold }
|
||||
|
||||
.CodeRay .key { color: #808; }
|
||||
.CodeRay .key .delimiter { color: #606; }
|
||||
.CodeRay .key .char { color: #80f; }
|
||||
.CodeRay .value { color: #088; }
|
||||
|
||||
.CodeRay .regexp { background-color:#fff0ff }
|
||||
.CodeRay .regexp .content { color:#808 }
|
||||
.CodeRay .regexp .delimiter { color:#404 }
|
||||
.CodeRay .regexp .modifier { color:#C2C }
|
||||
.CodeRay .regexp .function { color:#404; font-weight: bold }
|
||||
|
||||
.CodeRay .string { color: #D20; }
|
||||
.CodeRay .string .string { }
|
||||
.CodeRay .string .string .string { background-color:#ffd0d0 }
|
||||
.CodeRay .string .content { color: #D14; }
|
||||
.CodeRay .string .char { color: #D14; }
|
||||
.CodeRay .string .delimiter { color: #D14; }
|
||||
|
||||
.CodeRay .shell { color:#D14 }
|
||||
.CodeRay .shell .content { }
|
||||
.CodeRay .shell .delimiter { color:#D14 }
|
||||
|
||||
.CodeRay .symbol { color:#990073 }
|
||||
.CodeRay .symbol .content { color:#A60 }
|
||||
.CodeRay .symbol .delimiter { color:#630 }
|
||||
|
||||
.CodeRay .tag { color:#070 }
|
||||
.CodeRay .tag-special { color:#D70; font-weight:bold }
|
||||
.CodeRay .type { color:#339; font-weight:bold }
|
||||
.CodeRay .variable { color:#036 }
|
||||
|
||||
.CodeRay .insert { background: #afa; }
|
||||
.CodeRay .delete { background: #faa; }
|
||||
.CodeRay .change { color: #aaf; background: #007; }
|
||||
.CodeRay .head { color: #f8f; background: #505 }
|
||||
|
||||
.CodeRay .insert .insert { color: #080; font-weight:bold }
|
||||
.CodeRay .delete .delete { color: #800; font-weight:bold }
|
||||
.CodeRay .change .change { color: #66f; }
|
||||
.CodeRay .head .head { color: #f4f; }
|
@ -16,14 +16,18 @@
|
||||
}
|
||||
|
||||
.front-install {
|
||||
border: none;
|
||||
font-size: 1em;
|
||||
background-color: #333;
|
||||
margin-bottom: 16px;
|
||||
display: inline-block;
|
||||
padding: 8px;
|
||||
color: #DDD;
|
||||
|
||||
.sh {
|
||||
div:before {
|
||||
content: '$';
|
||||
color: #c82829;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -360,4 +364,4 @@ p.note {
|
||||
max-height: 97px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,333 +1,333 @@
|
||||
// This file is just a butchered version fo the one included in the default Octopress theme.
|
||||
// It could most definitely do with some cleaning up in the future.
|
||||
// // This file is just a butchered version fo the one included in the default Octopress theme.
|
||||
// // It could most definitely do with some cleaning up in the future.
|
||||
|
||||
@mixin selection($bg, $color: inherit, $text-shadow: none){
|
||||
* {
|
||||
&::-moz-selection { background: $bg; color: $color; text-shadow: $text-shadow; }
|
||||
&::-webkit-selection { background: $bg; color: $color; text-shadow: $text-shadow; }
|
||||
&::selection { background: $bg; color: $color; text-shadow: $text-shadow; }
|
||||
}
|
||||
}
|
||||
// @mixin selection($bg, $color: inherit, $text-shadow: none){
|
||||
// * {
|
||||
// &::-moz-selection { background: $bg; color: $color; text-shadow: $text-shadow; }
|
||||
// &::-webkit-selection { background: $bg; color: $color; text-shadow: $text-shadow; }
|
||||
// &::selection { background: $bg; color: $color; text-shadow: $text-shadow; }
|
||||
// }
|
||||
// }
|
||||
|
||||
$base03: #002b36 !default; //darkest blue
|
||||
$base02: #073642 !default; //dark blue
|
||||
$base01: #586e75 !default; //darkest gray
|
||||
$base00: #657b83 !default; //dark gray
|
||||
$base0: #839496 !default; //medium gray
|
||||
$base1: #93a1a1 !default; //medium light gray
|
||||
$base2: #eee8d5 !default; //cream
|
||||
$base3: #fdf6e3 !default; //white
|
||||
$solar-yellow: #b58900 !default;
|
||||
$solar-orange: #cb4b16 !default;
|
||||
$solar-red: #dc322f !default;
|
||||
$solar-magenta: #d33682 !default;
|
||||
$solar-violet: #6c71c4 !default;
|
||||
$solar-blue: #268bd2 !default;
|
||||
$solar-cyan: #2aa198 !default;
|
||||
$solar-green: #859900 !default;
|
||||
// $base03: #002b36 !default; //darkest blue
|
||||
// $base02: #073642 !default; //dark blue
|
||||
// $base01: #586e75 !default; //darkest gray
|
||||
// $base00: #657b83 !default; //dark gray
|
||||
// $base0: #839496 !default; //medium gray
|
||||
// $base1: #93a1a1 !default; //medium light gray
|
||||
// $base2: #eee8d5 !default; //cream
|
||||
// $base3: #fdf6e3 !default; //white
|
||||
// $solar-yellow: #b58900 !default;
|
||||
// $solar-orange: #cb4b16 !default;
|
||||
// $solar-red: #dc322f !default;
|
||||
// $solar-magenta: #d33682 !default;
|
||||
// $solar-violet: #6c71c4 !default;
|
||||
// $solar-blue: #268bd2 !default;
|
||||
// $solar-cyan: #2aa198 !default;
|
||||
// $solar-green: #859900 !default;
|
||||
|
||||
$solarized: dark !default;
|
||||
// $solarized: dark !default;
|
||||
|
||||
@if $solarized == light {
|
||||
// @if $solarized == light {
|
||||
|
||||
$_base03: $base03;
|
||||
$_base02: $base02;
|
||||
$_base01: $base01;
|
||||
$_base00: $base00;
|
||||
$_base0: $base0;
|
||||
$_base1: $base1;
|
||||
$_base2: $base2;
|
||||
$_base3: $base3;
|
||||
// $_base03: $base03;
|
||||
// $_base02: $base02;
|
||||
// $_base01: $base01;
|
||||
// $_base00: $base00;
|
||||
// $_base0: $base0;
|
||||
// $_base1: $base1;
|
||||
// $_base2: $base2;
|
||||
// $_base3: $base3;
|
||||
|
||||
$base03: $_base3;
|
||||
$base02: $_base2;
|
||||
$base01: $_base1;
|
||||
$base00: $_base0;
|
||||
$base0: $_base00;
|
||||
$base1: $_base01;
|
||||
$base2: $_base02;
|
||||
$base3: $_base03;
|
||||
}
|
||||
// $base03: $_base3;
|
||||
// $base02: $_base2;
|
||||
// $base01: $_base1;
|
||||
// $base00: $_base0;
|
||||
// $base0: $_base00;
|
||||
// $base1: $_base01;
|
||||
// $base2: $_base02;
|
||||
// $base3: $_base03;
|
||||
// }
|
||||
|
||||
/* non highlighted code colors */
|
||||
$pre-bg: $base03 !default;
|
||||
$pre-border: darken($base02, 5) !default;
|
||||
$pre-color: $base1 !default;
|
||||
// /* non highlighted code colors */
|
||||
// $pre-bg: $base03 !default;
|
||||
// $pre-border: darken($base02, 5) !default;
|
||||
// $pre-color: $base1 !default;
|
||||
|
||||
$noise-bg: image-url('noise.png') top left !default;
|
||||
$sans: "Helvetica Neue", Arial, sans-serif !default;
|
||||
$mono: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace !default;
|
||||
.sans { font-family: $sans; }
|
||||
.mono { font-family: $mono; }
|
||||
// $noise-bg: image-url('noise.png') top left !default;
|
||||
// $sans: "Helvetica Neue", Arial, sans-serif !default;
|
||||
// $mono: Menlo, Monaco, "Andale Mono", "lucida console", "Courier New", monospace !default;
|
||||
// .sans { font-family: $sans; }
|
||||
// .mono { font-family: $mono; }
|
||||
|
||||
.highlight {
|
||||
table {margin-bottom: 0;}
|
||||
.gutter, .code {
|
||||
padding: 0;
|
||||
}
|
||||
.gutter {
|
||||
.line-number {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
// .highlight {
|
||||
// table {margin-bottom: 0;}
|
||||
// .gutter, .code {
|
||||
// padding: 0;
|
||||
// }
|
||||
// .gutter {
|
||||
// .line-number {
|
||||
// display: block;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.highlight, html .gist .gist-file .gist-syntax .gist-highlight {
|
||||
table td.code { width: 100%; }
|
||||
border: 1px solid $pre-border !important;
|
||||
}
|
||||
.highlight .line-numbers, html .gist .gist-file .gist-syntax .highlight .line_numbers {
|
||||
text-align: right;
|
||||
font-size: 13px;
|
||||
line-height: 1.45em;
|
||||
@if $solarized == light {
|
||||
background: lighten($base03, 1) $noise-bg !important;
|
||||
border-right: 1px solid darken($base02, 2) !important;
|
||||
@include box-shadow(lighten($base03, 2) -1px 0 inset);
|
||||
text-shadow: lighten($base02, 2) 0 -1px;
|
||||
} @else {
|
||||
background: $base02 $noise-bg !important;
|
||||
border-right: 1px solid darken($base03, 2) !important;
|
||||
@include box-shadow(lighten($base02, 2) -1px 0 inset);
|
||||
text-shadow: darken($base02, 10) 0 -1px;
|
||||
}
|
||||
span { color: $base01 !important; }
|
||||
padding: .8em !important;
|
||||
@include border-radius(0);
|
||||
}
|
||||
// .highlight, html .gist .gist-file .gist-syntax .gist-highlight {
|
||||
// table td.code { width: 100%; }
|
||||
// border: 1px solid $pre-border !important;
|
||||
// }
|
||||
// .highlight .line-numbers, html .gist .gist-file .gist-syntax .highlight .line_numbers {
|
||||
// text-align: right;
|
||||
// font-size: 13px;
|
||||
// line-height: 1.45em;
|
||||
// @if $solarized == light {
|
||||
// background: lighten($base03, 1) $noise-bg !important;
|
||||
// border-right: 1px solid darken($base02, 2) !important;
|
||||
// @include box-shadow(lighten($base03, 2) -1px 0 inset);
|
||||
// text-shadow: lighten($base02, 2) 0 -1px;
|
||||
// } @else {
|
||||
// background: $base02 $noise-bg !important;
|
||||
// border-right: 1px solid darken($base03, 2) !important;
|
||||
// @include box-shadow(lighten($base02, 2) -1px 0 inset);
|
||||
// text-shadow: darken($base02, 10) 0 -1px;
|
||||
// }
|
||||
// span { color: $base01 !important; }
|
||||
// padding: .8em !important;
|
||||
// @include border-radius(0);
|
||||
// }
|
||||
|
||||
figure.code, .gist-file, pre {
|
||||
@include box-shadow(rgba(#000, .06) 0 0 10px);
|
||||
.highlight pre { @include box-shadow(none); }
|
||||
}
|
||||
// figure.code, .gist-file, pre {
|
||||
// @include box-shadow(rgba(#000, .06) 0 0 10px);
|
||||
// .highlight pre { @include box-shadow(none); }
|
||||
// }
|
||||
|
||||
.gist .highlight, figure.code .highlight {
|
||||
@include selection(adjust-color($base03, $lightness: 23%, $saturation: -65%), $text-shadow: $base03 0 1px);
|
||||
}
|
||||
html .gist .gist-file {
|
||||
margin-bottom: 1.8em;
|
||||
position: relative;
|
||||
border: none;
|
||||
padding-top: image-height("code_bg.png") !important;
|
||||
.highlight {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.gist-syntax {
|
||||
border-bottom: 0 !important;
|
||||
background: none !important;
|
||||
.gist-highlight {
|
||||
background: $base03 !important;
|
||||
}
|
||||
.highlight pre {
|
||||
@extend .pre-code;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
.gist-meta {
|
||||
padding: .6em 0.8em;
|
||||
border: 1px solid lighten($base02, 2) !important;
|
||||
color: $base01;
|
||||
font-size: .7em !important;
|
||||
@if $solarized == light {
|
||||
background: lighten($base03, 2) $noise-bg;
|
||||
border: 1px solid $pre-border !important;
|
||||
border-top: 1px solid lighten($base03, 2) !important;
|
||||
} @else {
|
||||
background: $base02 $noise-bg;
|
||||
}
|
||||
@extend .sans;
|
||||
line-height: 1.5em;
|
||||
a {
|
||||
color: mix($base1, $base01) !important;
|
||||
&:hover { color: $base1 !important; }
|
||||
}
|
||||
a[href*='#file'] {
|
||||
position: absolute; top: 0; left:0; right:-10px;
|
||||
color: #474747 !important;
|
||||
@extend .code-title;
|
||||
&:hover { color: $link-color !important; }
|
||||
}
|
||||
a[href*=raw]{
|
||||
@extend .download-source;
|
||||
top: .4em;
|
||||
}
|
||||
}
|
||||
}
|
||||
pre {
|
||||
background: $pre-bg $noise-bg;
|
||||
@include border-radius(.4em);
|
||||
@extend .mono;
|
||||
border: 1px solid $pre-border;
|
||||
line-height: 1.45em;
|
||||
font-size: 13px;
|
||||
margin-bottom: 2.1em;
|
||||
padding: .8em 1em;
|
||||
color: $pre-color;
|
||||
overflow: auto;
|
||||
}
|
||||
h3.filename {
|
||||
@extend .code-title;
|
||||
+ pre { @include border-radius(0px); }
|
||||
}
|
||||
// .gist .highlight, figure.code .highlight {
|
||||
// @include selection(adjust-color($base03, $lightness: 23%, $saturation: -65%), $text-shadow: $base03 0 1px);
|
||||
// }
|
||||
// html .gist .gist-file {
|
||||
// margin-bottom: 1.8em;
|
||||
// position: relative;
|
||||
// border: none;
|
||||
// padding-top: image-height("code_bg.png") !important;
|
||||
// .highlight {
|
||||
// margin-bottom: 0;
|
||||
// }
|
||||
// .gist-syntax {
|
||||
// border-bottom: 0 !important;
|
||||
// background: none !important;
|
||||
// .gist-highlight {
|
||||
// background: $base03 !important;
|
||||
// }
|
||||
// .highlight pre {
|
||||
// @extend .pre-code;
|
||||
// padding: 0;
|
||||
// }
|
||||
// }
|
||||
// .gist-meta {
|
||||
// padding: .6em 0.8em;
|
||||
// border: 1px solid lighten($base02, 2) !important;
|
||||
// color: $base01;
|
||||
// font-size: .7em !important;
|
||||
// @if $solarized == light {
|
||||
// background: lighten($base03, 2) $noise-bg;
|
||||
// border: 1px solid $pre-border !important;
|
||||
// border-top: 1px solid lighten($base03, 2) !important;
|
||||
// } @else {
|
||||
// background: $base02 $noise-bg;
|
||||
// }
|
||||
// @extend .sans;
|
||||
// line-height: 1.5em;
|
||||
// a {
|
||||
// color: mix($base1, $base01) !important;
|
||||
// &:hover { color: $base1 !important; }
|
||||
// }
|
||||
// a[href*='#file'] {
|
||||
// position: absolute; top: 0; left:0; right:-10px;
|
||||
// color: #474747 !important;
|
||||
// @extend .code-title;
|
||||
// &:hover { color: $link-color !important; }
|
||||
// }
|
||||
// a[href*=raw]{
|
||||
// @extend .download-source;
|
||||
// top: .4em;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// pre {
|
||||
// background: $pre-bg $noise-bg;
|
||||
// @include border-radius(.4em);
|
||||
// @extend .mono;
|
||||
// border: 1px solid $pre-border;
|
||||
// line-height: 1.45em;
|
||||
// font-size: 13px;
|
||||
// margin-bottom: 2.1em;
|
||||
// padding: .8em 1em;
|
||||
// color: $pre-color;
|
||||
// overflow: auto;
|
||||
// }
|
||||
// h3.filename {
|
||||
// @extend .code-title;
|
||||
// + pre { @include border-radius(0px); }
|
||||
// }
|
||||
|
||||
p, li {
|
||||
code {
|
||||
@extend .mono;
|
||||
display: inline-block;
|
||||
white-space: no-wrap;
|
||||
background: #fff;
|
||||
font-size: .8em;
|
||||
line-height: 1.5em;
|
||||
color: #555;
|
||||
border: 1px solid #ddd;
|
||||
@include border-radius(.4em);
|
||||
padding: 0 .3em;
|
||||
margin: -1px 0;
|
||||
}
|
||||
pre code { font-size: 1em !important; background: none; border: none; }
|
||||
}
|
||||
// p, li {
|
||||
// code {
|
||||
// @extend .mono;
|
||||
// display: inline-block;
|
||||
// white-space: no-wrap;
|
||||
// background: #fff;
|
||||
// font-size: .8em;
|
||||
// line-height: 1.5em;
|
||||
// color: #555;
|
||||
// border: 1px solid #ddd;
|
||||
// @include border-radius(.4em);
|
||||
// padding: 0 .3em;
|
||||
// margin: -1px 0;
|
||||
// }
|
||||
// pre code { font-size: 1em !important; background: none; border: none; }
|
||||
// }
|
||||
|
||||
.pre-code {
|
||||
font-family: $mono !important;
|
||||
overflow: scroll;
|
||||
overflow-y: hidden;
|
||||
display: block;
|
||||
padding: .8em;
|
||||
overflow-x: auto;
|
||||
line-height: 1.45em;
|
||||
background: $base03 $noise-bg !important;
|
||||
color: $base1 !important;
|
||||
span { color: $base1 !important; }
|
||||
span { font-style: normal !important; font-weight: normal !important; }
|
||||
// .pre-code {
|
||||
// font-family: $mono !important;
|
||||
// overflow: scroll;
|
||||
// overflow-y: hidden;
|
||||
// display: block;
|
||||
// padding: .8em;
|
||||
// overflow-x: auto;
|
||||
// line-height: 1.45em;
|
||||
// background: $base03 $noise-bg !important;
|
||||
// color: $base1 !important;
|
||||
// span { color: $base1 !important; }
|
||||
// span { font-style: normal !important; font-weight: normal !important; }
|
||||
|
||||
.c { color: $base01 !important; font-style: italic !important; } /* Comment */
|
||||
.cm { color: $base01 !important; font-style: italic !important; } /* Comment.Multiline */
|
||||
.cp { color: $base01 !important; font-style: italic !important; } /* Comment.Preproc */
|
||||
.c1 { color: $base01 !important; font-style: italic !important; } /* Comment.Single */
|
||||
.cs { color: $base01 !important; font-weight: bold !important; font-style: italic !important; } /* Comment.Special */
|
||||
.err { color: $solar-red !important; background: none !important; } /* Error */
|
||||
.k { color: $solar-orange !important; } /* Keyword */
|
||||
.o { color: $base1 !important; font-weight: bold !important; } /* Operator */
|
||||
.p { color: $base1 !important; } /* Operator */
|
||||
.ow { color: $solar-cyan !important; font-weight: bold !important; } /* Operator.Word */
|
||||
.gd { color: $base1 !important; background-color: mix($solar-red, $base03, 25%) !important; display: inline-block; } /* Generic.Deleted */
|
||||
.gd .x { color: $base1 !important; background-color: mix($solar-red, $base03, 35%) !important; display: inline-block; } /* Generic.Deleted.Specific */
|
||||
.ge { color: $base1 !important; font-style: italic !important; } /* Generic.Emph */
|
||||
//.gr { color: #aa0000 } /* Generic.Error */
|
||||
.gh { color: $base01 !important; } /* Generic.Heading */
|
||||
.gi { color: $base1 !important; background-color: mix($solar-green, $base03, 20%) !important; display: inline-block; } /* Generic.Inserted */
|
||||
.gi .x { color: $base1 !important; background-color: mix($solar-green, $base03, 40%) !important; display: inline-block; } /* Generic.Inserted.Specific */
|
||||
//.go { color: #888888 } /* Generic.Output */
|
||||
//.gp { color: #555555 } /* Generic.Prompt */
|
||||
.gs { color: $base1 !important; font-weight: bold !important; } /* Generic.Strong */
|
||||
.gu { color: $solar-violet !important; } /* Generic.Subheading */
|
||||
//.gt { color: #aa0000 } /* Generic.Traceback */
|
||||
.kc { color: $solar-green !important; font-weight: bold !important; } /* Keyword.Constant */
|
||||
.kd { color: $solar-blue !important; } /* Keyword.Declaration */
|
||||
.kp { color: $solar-orange !important; font-weight: bold !important; } /* Keyword.Pseudo */
|
||||
.kr { color: $solar-magenta !important; font-weight: bold !important; } /* Keyword.Reserved */
|
||||
.kt { color: $solar-cyan !important; } /* Keyword.Type */
|
||||
.n { color: $solar-blue !important; }
|
||||
.na { color: $solar-blue !important; } /* Name.Attribute */
|
||||
.nb { color: $solar-green !important; } /* Name.Builtin */
|
||||
.nc { color: $solar-magenta !important;} /* Name.Class */
|
||||
.no { color: $solar-yellow !important; } /* Name.Constant */
|
||||
//.ni { color: #800080 } /* Name.Entity */
|
||||
.nl { color: $solar-green !important; }
|
||||
.ne { color: $solar-blue !important; font-weight: bold !important; } /* Name.Exception */
|
||||
.nf { color: $solar-blue !important; font-weight: bold !important; } /* Name.Function */
|
||||
.nn { color: $solar-yellow !important; } /* Name.Namespace */
|
||||
.nt { color: $solar-blue !important; font-weight: bold !important; } /* Name.Tag */
|
||||
.nx { color: $solar-yellow !Important; }
|
||||
//.bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
//.vc { color: #008080 } /* Name.Variable.Class */
|
||||
.vg { color: $solar-blue !important; } /* Name.Variable.Global */
|
||||
.vi { color: $solar-blue !important; } /* Name.Variable.Instance */
|
||||
.nv { color: $solar-blue !important; } /* Name.Variable */
|
||||
//.w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.mf { color: $solar-cyan !important; } /* Literal.Number.Float */
|
||||
.m { color: $solar-cyan !important; } /* Literal.Number */
|
||||
.mh { color: $solar-cyan !important; } /* Literal.Number.Hex */
|
||||
.mi { color: $solar-cyan !important; } /* Literal.Number.Integer */
|
||||
//.mo { color: #009999 } /* Literal.Number.Oct */
|
||||
.s { color: $solar-cyan !important; } /* Literal.String */
|
||||
//.sb { color: #d14 } /* Literal.String.Backtick */
|
||||
//.sc { color: #d14 } /* Literal.String.Char */
|
||||
.sd { color: $solar-cyan !important; } /* Literal.String.Doc */
|
||||
.s2 { color: $solar-cyan !important; } /* Literal.String.Double */
|
||||
.se { color: $solar-red !important; } /* Literal.String.Escape */
|
||||
//.sh { color: #d14 } /* Literal.String.Heredoc */
|
||||
.si { color: $solar-blue !important; } /* Literal.String.Interpol */
|
||||
//.sx { color: #d14 } /* Literal.String.Other */
|
||||
.sr { color: $solar-cyan !important; } /* Literal.String.Regex */
|
||||
.s1 { color: $solar-cyan !important; } /* Literal.String.Single */
|
||||
//.ss { color: #990073 } /* Literal.String.Symbol */
|
||||
//.il { color: #009999 } /* Literal.Number.Integer.Long */
|
||||
div { .gd, .gd .x, .gi, .gi .x { display: inline-block; width: 100%; }}
|
||||
}
|
||||
// .c { color: $base01 !important; font-style: italic !important; } /* Comment */
|
||||
// .cm { color: $base01 !important; font-style: italic !important; } /* Comment.Multiline */
|
||||
// .cp { color: $base01 !important; font-style: italic !important; } /* Comment.Preproc */
|
||||
// .c1 { color: $base01 !important; font-style: italic !important; } /* Comment.Single */
|
||||
// .cs { color: $base01 !important; font-weight: bold !important; font-style: italic !important; } /* Comment.Special */
|
||||
// .err { color: $solar-red !important; background: none !important; } /* Error */
|
||||
// .k { color: $solar-orange !important; } /* Keyword */
|
||||
// .o { color: $base1 !important; font-weight: bold !important; } /* Operator */
|
||||
// .p { color: $base1 !important; } /* Operator */
|
||||
// .ow { color: $solar-cyan !important; font-weight: bold !important; } /* Operator.Word */
|
||||
// .gd { color: $base1 !important; background-color: mix($solar-red, $base03, 25%) !important; display: inline-block; } /* Generic.Deleted */
|
||||
// .gd .x { color: $base1 !important; background-color: mix($solar-red, $base03, 35%) !important; display: inline-block; } /* Generic.Deleted.Specific */
|
||||
// .ge { color: $base1 !important; font-style: italic !important; } /* Generic.Emph */
|
||||
// //.gr { color: #aa0000 } /* Generic.Error */
|
||||
// .gh { color: $base01 !important; } /* Generic.Heading */
|
||||
// .gi { color: $base1 !important; background-color: mix($solar-green, $base03, 20%) !important; display: inline-block; } /* Generic.Inserted */
|
||||
// .gi .x { color: $base1 !important; background-color: mix($solar-green, $base03, 40%) !important; display: inline-block; } /* Generic.Inserted.Specific */
|
||||
// //.go { color: #888888 } /* Generic.Output */
|
||||
// //.gp { color: #555555 } /* Generic.Prompt */
|
||||
// .gs { color: $base1 !important; font-weight: bold !important; } /* Generic.Strong */
|
||||
// .gu { color: $solar-violet !important; } /* Generic.Subheading */
|
||||
// //.gt { color: #aa0000 } /* Generic.Traceback */
|
||||
// .kc { color: $solar-green !important; font-weight: bold !important; } /* Keyword.Constant */
|
||||
// .kd { color: $solar-blue !important; } /* Keyword.Declaration */
|
||||
// .kp { color: $solar-orange !important; font-weight: bold !important; } /* Keyword.Pseudo */
|
||||
// .kr { color: $solar-magenta !important; font-weight: bold !important; } /* Keyword.Reserved */
|
||||
// .kt { color: $solar-cyan !important; } /* Keyword.Type */
|
||||
// .n { color: $solar-blue !important; }
|
||||
// .na { color: $solar-blue !important; } /* Name.Attribute */
|
||||
// .nb { color: $solar-green !important; } /* Name.Builtin */
|
||||
// .nc { color: $solar-magenta !important;} /* Name.Class */
|
||||
// .no { color: $solar-yellow !important; } /* Name.Constant */
|
||||
// //.ni { color: #800080 } /* Name.Entity */
|
||||
// .nl { color: $solar-green !important; }
|
||||
// .ne { color: $solar-blue !important; font-weight: bold !important; } /* Name.Exception */
|
||||
// .nf { color: $solar-blue !important; font-weight: bold !important; } /* Name.Function */
|
||||
// .nn { color: $solar-yellow !important; } /* Name.Namespace */
|
||||
// .nt { color: $solar-blue !important; font-weight: bold !important; } /* Name.Tag */
|
||||
// .nx { color: $solar-yellow !Important; }
|
||||
// //.bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
// //.vc { color: #008080 } /* Name.Variable.Class */
|
||||
// .vg { color: $solar-blue !important; } /* Name.Variable.Global */
|
||||
// .vi { color: $solar-blue !important; } /* Name.Variable.Instance */
|
||||
// .nv { color: $solar-blue !important; } /* Name.Variable */
|
||||
// //.w { color: #bbbbbb } /* Text.Whitespace */
|
||||
// .mf { color: $solar-cyan !important; } /* Literal.Number.Float */
|
||||
// .m { color: $solar-cyan !important; } /* Literal.Number */
|
||||
// .mh { color: $solar-cyan !important; } /* Literal.Number.Hex */
|
||||
// .mi { color: $solar-cyan !important; } /* Literal.Number.Integer */
|
||||
// //.mo { color: #009999 } /* Literal.Number.Oct */
|
||||
// .s { color: $solar-cyan !important; } /* Literal.String */
|
||||
// //.sb { color: #d14 } /* Literal.String.Backtick */
|
||||
// //.sc { color: #d14 } /* Literal.String.Char */
|
||||
// .sd { color: $solar-cyan !important; } /* Literal.String.Doc */
|
||||
// .s2 { color: $solar-cyan !important; } /* Literal.String.Double */
|
||||
// .se { color: $solar-red !important; } /* Literal.String.Escape */
|
||||
// //.sh { color: #d14 } /* Literal.String.Heredoc */
|
||||
// .si { color: $solar-blue !important; } /* Literal.String.Interpol */
|
||||
// //.sx { color: #d14 } /* Literal.String.Other */
|
||||
// .sr { color: $solar-cyan !important; } /* Literal.String.Regex */
|
||||
// .s1 { color: $solar-cyan !important; } /* Literal.String.Single */
|
||||
// //.ss { color: #990073 } /* Literal.String.Symbol */
|
||||
// //.il { color: #009999 } /* Literal.Number.Integer.Long */
|
||||
// div { .gd, .gd .x, .gi, .gi .x { display: inline-block; width: 100%; }}
|
||||
// }
|
||||
|
||||
.highlight, .gist-highlight {
|
||||
pre { background: none; @include border-radius(0px); border: none; padding: 0; margin-bottom: 0; }
|
||||
margin-bottom: 1.8em;
|
||||
background: $base03;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
}
|
||||
// .highlight, .gist-highlight {
|
||||
// pre { background: none; @include border-radius(0px); border: none; padding: 0; margin-bottom: 0; }
|
||||
// margin-bottom: 1.8em;
|
||||
// background: $base03;
|
||||
// overflow-y: hidden;
|
||||
// overflow-x: auto;
|
||||
// }
|
||||
|
||||
$solar-scroll-bg: rgba(#fff, .15);
|
||||
$solar-scroll-thumb: rgba(#fff, .2);
|
||||
@if $solarized == light {
|
||||
$solar-scroll-bg: rgba(#000, .15);
|
||||
$solar-scroll-thumb: rgba(#000, .15);
|
||||
}
|
||||
// $solar-scroll-bg: rgba(#fff, .15);
|
||||
// $solar-scroll-thumb: rgba(#fff, .2);
|
||||
// @if $solarized == light {
|
||||
// $solar-scroll-bg: rgba(#000, .15);
|
||||
// $solar-scroll-thumb: rgba(#000, .15);
|
||||
// }
|
||||
|
||||
pre, .highlight, .gist-highlight {
|
||||
&::-webkit-scrollbar { height: .5em; background: $solar-scroll-bg; }
|
||||
&::-webkit-scrollbar-thumb:horizontal { background: $solar-scroll-thumb; -webkit-border-radius: 4px; border-radius: 4px }
|
||||
}
|
||||
// pre, .highlight, .gist-highlight {
|
||||
// &::-webkit-scrollbar { height: .5em; background: $solar-scroll-bg; }
|
||||
// &::-webkit-scrollbar-thumb:horizontal { background: $solar-scroll-thumb; -webkit-border-radius: 4px; border-radius: 4px }
|
||||
// }
|
||||
|
||||
.highlight code {
|
||||
@extend .pre-code; background: #000;
|
||||
}
|
||||
figure.code {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin-bottom: 1.5em;
|
||||
pre { margin-bottom: 0; }
|
||||
figcaption {
|
||||
position: relative;
|
||||
@extend .code-title;
|
||||
a { @extend .download-source; }
|
||||
}
|
||||
.highlight {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
// .highlight code {
|
||||
// @extend .pre-code; background: #000;
|
||||
// }
|
||||
// figure.code {
|
||||
// background: none;
|
||||
// padding: 0;
|
||||
// border: 0;
|
||||
// margin-bottom: 1.5em;
|
||||
// pre { margin-bottom: 0; }
|
||||
// figcaption {
|
||||
// position: relative;
|
||||
// @extend .code-title;
|
||||
// a { @extend .download-source; }
|
||||
// }
|
||||
// .highlight {
|
||||
// margin-bottom: 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
.code-title {
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
line-height: 2em;
|
||||
text-shadow: #cbcccc 0 1px 0;
|
||||
color: #474747;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0;
|
||||
@include border-radius(5px 5px 0 0);
|
||||
font-family: "Helvetica Neue", Arial, "Lucida Grande", "Lucida Sans Unicode", Lucida, sans-serif;
|
||||
background: #aaaaaa image-url("code_bg.png") top repeat-x;
|
||||
border: 1px solid #565656;
|
||||
border-top-color: #cbcbcb;
|
||||
border-left-color: #a5a5a5;
|
||||
border-right-color: #a5a5a5;
|
||||
border-bottom: 0;
|
||||
}
|
||||
// .code-title {
|
||||
// text-align: center;
|
||||
// font-size: 13px;
|
||||
// line-height: 2em;
|
||||
// text-shadow: #cbcccc 0 1px 0;
|
||||
// color: #474747;
|
||||
// font-weight: normal;
|
||||
// margin-bottom: 0;
|
||||
// @include border-radius(5px 5px 0 0);
|
||||
// font-family: "Helvetica Neue", Arial, "Lucida Grande", "Lucida Sans Unicode", Lucida, sans-serif;
|
||||
// background: #aaaaaa image-url("code_bg.png") top repeat-x;
|
||||
// border: 1px solid #565656;
|
||||
// border-top-color: #cbcbcb;
|
||||
// border-left-color: #a5a5a5;
|
||||
// border-right-color: #a5a5a5;
|
||||
// border-bottom: 0;
|
||||
// }
|
||||
|
||||
.download-source {
|
||||
position: absolute; right: .8em;
|
||||
color: #666 !important;
|
||||
z-index: 1;
|
||||
font-size: 13px;
|
||||
text-shadow: #cbcccc 0 1px 0;
|
||||
padding-left: 3em;
|
||||
}
|
||||
// .download-source {
|
||||
// position: absolute; right: .8em;
|
||||
// color: #666 !important;
|
||||
// z-index: 1;
|
||||
// font-size: 13px;
|
||||
// text-shadow: #cbcccc 0 1px 0;
|
||||
// padding-left: 3em;
|
||||
// }
|
||||
|
@ -1,2 +1,3 @@
|
||||
@import 'oscailte/oscailte';
|
||||
@import 'custom/paulus';
|
||||
@import 'custom/coderay';
|
||||
|
@ -12,7 +12,7 @@ footer: true
|
||||
|
||||
Home Assistant can give you an interface with is similar to a classic alarm system. There are several panels supported:
|
||||
|
||||
- [Manual](/components/alarm_control_panel.manual.html)
|
||||
- [MQTT](/components/alarm_control_panel.mqtt.html)
|
||||
- [Verisure](/components/verisure.html)
|
||||
- [Manual](/components/alarm_control_panel.manual/)
|
||||
- [MQTT](/components/alarm_control_panel.mqtt/)
|
||||
- [Verisure](/components/verisure/)
|
||||
|
||||
|
@ -12,10 +12,7 @@ ha_category: Alarm
|
||||
---
|
||||
|
||||
|
||||
This platform enables the possibility to control an MQTT alarm. The alarm will only change state after
|
||||
receiving the a new state from `state_topic`. If these messages are published with RETAIN flag, the MQTT
|
||||
alarm will receive an instant state update after subscription and will start with correct state. Otherwise,
|
||||
the initial state will be `unknown`.
|
||||
This platform enables the possibility to control an MQTT alarm. The alarm will only change state after receiving the a new state from `state_topic`. If these messages are published with RETAIN flag, the MQTT alarm will receive an instant state update after subscription and will start with correct state. Otherwise, the initial state will be `unknown`.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
|
@ -35,7 +35,7 @@ Configuration variables:
|
||||
- **port** (*Required*): The port where your board is connected to your Home Assistant host. If you are using an original Arduino the port will be named `ttyACM*`. The exact number can be determined with `ls /dev/ttyACM*`.
|
||||
|
||||
```bash
|
||||
ls /dev/ttyACM*
|
||||
$ ls /dev/ttyACM*
|
||||
```
|
||||
|
||||
If that is not working, check your `dmesg` or `journalctl -f` output. Keep in mind that Arduino clones are often using a different name for the port (e.g. `/dev/ttyUSB*`).
|
||||
@ -46,6 +46,6 @@ A word of caution: The Arduino boards are not storing states. This means that wi
|
||||
|
||||
## Building on top of the Arduino component
|
||||
|
||||
- [Arduino Sensor](/components/sensor.arduino.html)
|
||||
- [Arduino Switch](/components/switch.arduino.html)
|
||||
- [Arduino Sensor](/components/sensor.arduino/)
|
||||
- [Arduino Switch](/components/switch.arduino/)
|
||||
|
||||
|
@ -10,12 +10,9 @@ footer: true
|
||||
ha_category: Automation
|
||||
---
|
||||
|
||||
This page will go into more detail about the various options the `automation` component offers. If
|
||||
you haven't yet, read the [getting started page on automation](/getting-started/automation.html).
|
||||
This page will go into more detail about the various options the `automation` component offers. If you haven't yet, read the [getting started page on automation](/getting-started/automation/).
|
||||
|
||||
A configuration section of an automation requires a `trigger` and an `action` section. `condition` and
|
||||
`condition_type` are optional. To keep this page compact, all following sections will not show the
|
||||
full configuration but only the relevant part.
|
||||
A configuration section of an automation requires a `trigger` and an `action` section. `condition` and `condition_type` are optional. To keep this page compact, all following sections will not show the full configuration but only the relevant part.
|
||||
|
||||
```yaml
|
||||
# Example of entry in configuration.yaml
|
||||
@ -77,13 +74,10 @@ automation:
|
||||
|
||||
## {% linkable_title Triggers %}
|
||||
|
||||
Triggers are what starts the processing of an automation rule. It is possible to specify multiple
|
||||
triggers for the same rule. Once a trigger starts, Home Assistant will validate the conditions, if any,
|
||||
and call the action.
|
||||
Triggers are what starts the processing of an automation rule. It is possible to specify multiple triggers for the same rule. Once a trigger starts, Home Assistant will validate the conditions, if any, and call the action.
|
||||
|
||||
#### {% linkable_title Event trigger %}
|
||||
Triggers when an event is being processed. Events are the raw building blocks of Home Assistant.
|
||||
You can match events on just the event name or also require specific event data to be present.
|
||||
Triggers when an event is being processed. Events are the raw building blocks of Home Assistant. You can match events on just the event name or also require specific event data to be present.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -96,8 +90,7 @@ automation:
|
||||
```
|
||||
|
||||
#### {% linkable_title MQTT trigger %}
|
||||
Triggers when a specific message is received on given topic. Optionally can match on the payload
|
||||
being sent over the topic.
|
||||
Triggers when a specific message is received on given topic. Optionally can match on the payload being sent over the topic.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -109,8 +102,7 @@ automation:
|
||||
```
|
||||
|
||||
#### {% linkable_title Numeric state trigger %}
|
||||
On state change of a specified entity, attempts to parse the state as a number and triggers if value
|
||||
is above and/or below a threshold.
|
||||
On state change of a specified entity, attempts to parse the state as a number and triggers if value is above and/or below a threshold.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -123,6 +115,7 @@ automation:
|
||||
```
|
||||
|
||||
#### {% linkable_title State trigger %}
|
||||
|
||||
Triggers when the state of an entity changes. If only entity_id given will match all state changes.
|
||||
|
||||
```yaml
|
||||
@ -136,13 +129,11 @@ automation:
|
||||
```
|
||||
|
||||
<p class='note warning'>
|
||||
Use quotes around your values for <code>from</code> and <code>to</code> to avoid the YAML parser
|
||||
interpreting some values as booleans.
|
||||
Use quotes around your values for `from` and `to` to avoid the YAML parser interpreting values as booleans.
|
||||
</p>
|
||||
|
||||
#### {% linkable_title Sun trigger %}
|
||||
Trigger when the sun is setting or rising. An optional time offset can be given to have it trigger for
|
||||
example 45 minutes before sunset, when dusk is setting in.
|
||||
Trigger when the sun is setting or rising. An optional time offset can be given to have it trigger for example 45 minutes before sunset, when dusk is setting in.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -155,10 +146,8 @@ automation:
|
||||
```
|
||||
|
||||
#### {% linkable_title Time trigger %}
|
||||
Time can be triggered in many ways. The most common is to specify `after` and trigger at a specific
|
||||
point in time each day. Alternatively, you can also match if the hour, minute or second of the current
|
||||
time has a specific value. For example, by only setting minutes in the config to 5 it will trigger every
|
||||
hour when it is 5 minutes past whole. You cannot use `after` together with hour, minute or second.
|
||||
|
||||
Time can be triggered in many ways. The most common is to specify `after` and trigger at a specific point in time each day. Alternatively, you can also match if the hour, minute or second of the current time has a specific value. For example, by only setting minutes in the config to 5 it will trigger every hour when it is 5 minutes past whole. You cannot use `after` together with hour, minute or second.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -176,16 +165,13 @@ automation:
|
||||
- sun
|
||||
```
|
||||
|
||||
You can use `weekday` to limit the trigger times to speific days as well (also available in conditions).
|
||||
Valid values for `weekday` are (`sun`, `mon`, `tue`, `wed`, `thu`, `fri` & `sat`)
|
||||
You can use `weekday` to limit the trigger times to speific days as well (also available in conditions). Valid values for `weekday` are (`sun`, `mon`, `tue`, `wed`, `thu`, `fri` & `sat`)
|
||||
|
||||
The above example will trigger on Saturday and Sunday every hour on the 5 (2:05, 3:05, 4:05, etc).
|
||||
|
||||
|
||||
#### {% linkable_title Zone trigger %}
|
||||
Zone triggers can trigger when an entity is entering or leaving the zone. For zone automation to work,
|
||||
you need to have setup a device tracker platform that supports reporting GPS coordinates. Currently
|
||||
this is limited to the [OwnTracks platform](/components/device_tracker.owntracks.html).
|
||||
|
||||
Zone triggers can trigger when an entity is entering or leaving the zone. For zone automation to work, you need to have setup a device tracker platform that supports reporting GPS coordinates. Currently this is limited to the [OwnTracks platform](/components/device_tracker.owntracks/).
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -199,15 +185,9 @@ automation:
|
||||
|
||||
## {% linkable_title Conditions %}
|
||||
|
||||
Conditions are an optional part of an automation rule and be used to prevent an action from happening
|
||||
when triggered. Conditions look very familiar to triggers but are very different. A trigger will look
|
||||
at events happening at the system while a condition only looks at how the system looks right now.
|
||||
A trigger can observe that a switch is being turned on. A condition can only see if a switch is on
|
||||
or off.
|
||||
Conditions are an optional part of an automation rule and be used to prevent an action from happening when triggered. Conditions look very familiar to triggers but are very different. A trigger will look at events happening at the system while a condition only looks at how the system looks right now. A trigger can observe that a switch is being turned on. A condition can only see if a switch is on or off.
|
||||
|
||||
An automation rule can have mulitiple triggers. By default the action will only fire if all conditions
|
||||
pass. An optional key `condition_type: 'or'` can be set on the automation rule to fire action if any
|
||||
condition matches. In the example below, the automation would trigger if the time is before 05:00 _OR_ after 20:00.
|
||||
An automation rule can have mulitiple triggers. By default the action will only fire if all conditions pass. An optional key `condition_type: 'or'` can be set on the automation rule to fire action if any condition matches. In the example below, the automation would trigger if the time is before 05:00 _OR_ after 20:00.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -219,16 +199,16 @@ automation:
|
||||
after: '20:00'
|
||||
```
|
||||
|
||||
If your triggers and conditions are exactly the same, you can use a shortcut to specify conditions.
|
||||
In this case, triggers that are not valid conditions will be ignored.
|
||||
If your triggers and conditions are exactly the same, you can use a shortcut to specify conditions. In this case, triggers that are not valid conditions will be ignored.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
condition: use_trigger_values
|
||||
```
|
||||
|
||||
#### {% linkable_title Numeric state condition %}
|
||||
Attempts to parse the state of specified entity as a number and triggers if value is above and/or
|
||||
below a threshold.
|
||||
|
||||
Attempts to parse the state of specified entity as a number and triggers if value is above and/or below a threshold.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -241,6 +221,7 @@ automation:
|
||||
```
|
||||
|
||||
#### {% linkable_title State condition %}
|
||||
|
||||
Tests if an entity is a specified state.
|
||||
|
||||
```yaml
|
||||
@ -252,8 +233,8 @@ automation:
|
||||
```
|
||||
|
||||
#### {% linkable_title Time condition %}
|
||||
The time condition can test if it is after a specified time, before a specified time or if it is a
|
||||
certain day of the week
|
||||
|
||||
The time condition can test if it is after a specified time, before a specified time or if it is a certain day of the week
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -268,12 +249,11 @@ automation:
|
||||
- fri
|
||||
```
|
||||
|
||||
Valid values for `weekday` are (sun, mon, tue, wed, thu, fri & sat)
|
||||
Valid values for `weekday` are (`sun`, `mon`, `tue`, `wed`, `thu`, `fri` & `sat`)
|
||||
|
||||
#### {% linkable_title Zone condition %}
|
||||
Zone conditions test if an entity is in a certain zone. For zone automation to work,
|
||||
you need to have setup a device tracker platform that supports reporting GPS coordinates. Currently
|
||||
this is limited to the [OwnTracks platform](/components/device_tracker.owntracks.html).
|
||||
|
||||
Zone conditions test if an entity is in a certain zone. For zone automation to work, you need to have setup a device tracker platform that supports reporting GPS coordinates. Currently this is limited to the [OwnTracks platform](/components/device_tracker.owntracks/).
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -285,8 +265,7 @@ automation:
|
||||
|
||||
## {% linkable_title Actions %}
|
||||
|
||||
When an automation rule fires, it calls a service. For this service you can specify an entity id it
|
||||
should apply to and optional service parameters (to specify for example the brightness).
|
||||
When an automation rule fires, it calls a service. For this service you can specify an entity id it should apply to and optional service parameters (to specify for example the brightness).
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
@ -310,23 +289,19 @@ automation:
|
||||
message: Something just happened, better take a look!
|
||||
```
|
||||
|
||||
If you want to specify multiple services to be called or include a delay, have a look at the
|
||||
[script component](/components/script.html). If you want to describe how certain entities should look,
|
||||
check out the [scene component](/components/scene.html).
|
||||
If you want to specify multiple services to be called or include a delay, have a look at the [script component](/components/script/). If you want to describe how certain entities should look, check out the [scene component](/components/scene/).
|
||||
|
||||
## {% linkable_title Troubleshooting %}
|
||||
|
||||
You can verify that your automation rules are being initialized correctly by watching both the realtime
|
||||
logs and also the logbook. The realtime logs will show the rules being initialized (once for each trigger):
|
||||
You can verify that your automation rules are being initialized correctly by watching both the realtime logs and also the logbook. The realtime logs will show the rules being initialized (once for each trigger):
|
||||
|
||||
```bash
|
||||
```plain
|
||||
INFO [homeassistant.components.automation] Initialized rule Rainy Day
|
||||
INFO [homeassistant.components.automation] Initialized rule Rainy Day
|
||||
INFO [homeassistant.components.automation] Initialized rule Rainy Day
|
||||
INFO [homeassistant.components.automation] Initialized rule Rain is over
|
||||
```
|
||||
|
||||
The Logbook component will show a line entry when an automation is triggered. You can look at the
|
||||
previous entry to determine which trigger in the rule triggered the event.
|
||||
The Logbook component will show a line entry when an automation is triggered. You can look at the previous entry to determine which trigger in the rule triggered the event.
|
||||
|
||||

|
||||
|
@ -15,7 +15,8 @@ The browser component provides a service to open urls in the default browser on
|
||||
|
||||
To load this component, add the following lines to your `configuration.yaml`:
|
||||
|
||||
```
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
browser:
|
||||
```
|
||||
|
||||
|
@ -16,6 +16,7 @@ This component allows you to integrate any IP camera into Home Assistant. It sup
|
||||
Home Assistant will serve the images via its server, making it possible to view your IP camera's while outside of your network.
|
||||
|
||||
As part of the basic support the following features will be provided:
|
||||
|
||||
- MJPEG video streaming
|
||||
- Saving a snapshot
|
||||
- Recording(JPEG frame capture)
|
||||
|
@ -20,6 +20,6 @@ The configurator component allows components to request information from the use
|
||||
- Input fields can be defined with a description, and optional type
|
||||
- It will trigger a callback when the button is pressed
|
||||
|
||||
The Hue component in [the demo](/demo) and Plex are implemented using the configurator. See [the source of the demo component](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/demo.py#L72) for a simple example.
|
||||
The Hue component in [the demo](/demo) and Plex are implemented using the configurator. See [the source of the demo component](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/demo.py#L132) for a simple example.
|
||||
|
||||
See [the source](https://github.com/balloob/home-assistant/blob/master/homeassistant/components/configurator.py#L39) for more details on how to use the configurator component.
|
||||
|
@ -15,7 +15,8 @@ The conversation component can process sentences into commands for Home Assistan
|
||||
|
||||
To enable the conversion option in your installation, add the following to your `configuration.yaml` file:
|
||||
|
||||
```
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
conversation:
|
||||
```
|
||||
|
||||
|
@ -16,7 +16,7 @@ Home Assistant has a built-in component called `device_sun_light_trigger` to hel
|
||||
* Turn on the lights when people get home after the sun has set
|
||||
* Turn off the lights when all people leave the house
|
||||
|
||||
This component requires the components [sun](/components/sun.html), [device_tracker](/components/device_tracker.html) and [light](/components/light.html) to be enabled.
|
||||
This component requires the components [sun](/components/sun/), [device_tracker](/components/device_tracker/) and [light](/components/light/) to be enabled.
|
||||
|
||||
To enable this component, add the following lines to your `configuration.yaml` file:
|
||||
|
||||
|
@ -39,5 +39,5 @@ Configuration variables:
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
- **home_interval** (*Optional*): If the home_interval is set then the component will not let a device be AWAY if it has been HOME in the last home_interval minutes. This is in addition to the 3 minute wait built into the device_tracker component.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
||||
|
@ -37,5 +37,5 @@ Configuration variables:
|
||||
- **username** *Required*: The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** *Required*: The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
||||
|
@ -35,4 +35,4 @@ Configuration variables:
|
||||
- **username** (*Required*: The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -31,4 +31,4 @@ Configuration variables:
|
||||
- **username** (*Required*: The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -11,7 +11,7 @@ logo: openwrt.png
|
||||
ha_category: Presence Detection
|
||||
---
|
||||
|
||||
_This is one of the two ways we support OpenWRT. If you encounter problems, try [ubus](/components/device_tracker.ubus.html)._
|
||||
_This is one of the two ways we support OpenWRT. If you encounter problems, try [ubus](/components/device_tracker.ubus/)._
|
||||
|
||||
This is a presence detection scanner for OpenWRT using [luci](http://wiki.openwrt.org/doc/techref/luci).
|
||||
|
||||
@ -36,4 +36,4 @@ Configuration variables:
|
||||
- **username** (*Required*): The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -11,7 +11,7 @@ footer: true
|
||||
|
||||
Home Assistant can get information from your wireless router to track which devices are connected. Please check the sidebar for a list of brands of supported wireless routers.
|
||||
|
||||
There are also trackers available which uses different technologies like [MQTT](/components/mqtt.html) or [nmap](/components/device_tracker.nmap_scanner.html) to scan the network for devices
|
||||
There are also trackers available which uses different technologies like [MQTT](/components/mqtt/) or [nmap](/components/device_tracker.nmap_scanner/) to scan the network for devices
|
||||
|
||||
To get started add the following lines to your `configuration.yaml` (example for Netgear):
|
||||
|
||||
|
@ -12,8 +12,7 @@ ha_category: Presence Detection
|
||||
---
|
||||
|
||||
|
||||
This platform allows you to detect presence by monitoring an MQTT topic for new locations. To use this
|
||||
platform, you specify a unique topic for each device.
|
||||
This platform allows you to detect presence by monitoring an MQTT topic for new locations. To use this platform, you specify a unique topic for each device.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
|
@ -29,4 +29,4 @@ Configuration variables:
|
||||
- **username** (*Required*: The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -12,12 +12,9 @@ featured: true
|
||||
---
|
||||
|
||||
|
||||
As an alternative to the router-based device tracking, it is possible to directly scan the network
|
||||
for devices by using Nmap. The IP addresses to scan can be specified in any format that Nmap understands,
|
||||
including the network-prefix notation (`192.168.1.1/24`) and the range notation (`192.168.1.1-255`).
|
||||
As an alternative to the router-based device tracking, it is possible to directly scan the network for devices by using Nmap. The IP addresses to scan can be specified in any format that Nmap understands, including the network-prefix notation (`192.168.1.1/24`) and the range notation (`192.168.1.1-255`).
|
||||
|
||||
If you're on Debian or Ubuntu, you might have to install the packages for arp and nmap. Do so by
|
||||
running `apt-get install net-tools nmap`.
|
||||
If you're on Debian or Ubuntu, you might have to install the packages for arp and nmap. Do so by running `apt-get install net-tools nmap`.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
@ -27,8 +24,6 @@ device_tracker:
|
||||
home_interval: 10
|
||||
```
|
||||
|
||||
`home_interval` is an optional value set in minutes. This will be the number of minutes nmap will not
|
||||
scan this device, assuming it is home, in order to preserve the device battery.
|
||||
`home_interval` is an optional value set in minutes. This will be the number of minutes nmap will not scan this device, assuming it is home, in order to preserve the device battery.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to
|
||||
configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -13,12 +13,9 @@ featured: true
|
||||
---
|
||||
|
||||
|
||||
This platform allows you to detect presence using [Owntracks](http://owntracks.org/). OwnTracks allows
|
||||
users to track their location on Android and iOS phones and publish it to an MQTT broker. This platform
|
||||
will connect to the broker and monitor for new locations.
|
||||
This platform allows you to detect presence using [Owntracks](http://owntracks.org/). OwnTracks allows users to track their location on Android and iOS phones and publish it to an MQTT broker. This platform will connect to the broker and monitor for new locations.
|
||||
|
||||
This component requires [the MQTT component](/components/mqtt.html) to be set up and works very well
|
||||
together with [the zone component](/components/zone.html).
|
||||
This component requires [the MQTT component](/components/mqtt/) to be set up and works very well together with [the zone component](/components/zone/).
|
||||
|
||||
To integrate Owntracks in Home Assistant, add the following section to your `configuration.yaml` file:
|
||||
|
||||
|
@ -39,4 +39,4 @@ Configuration variables:
|
||||
|
||||
- **baseoid** (*Required*): The OID prefix where wireless client registrations can be found, usually vendor specific. It's advised to use the numerical notation. To find this base OID, check vendor documentation or check the MIB file for your device.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -31,4 +31,4 @@ Configuration variables:
|
||||
- **username** (*Required*: The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -30,4 +30,4 @@ Configuration variables:
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
- **http_id** (*Required*): The value can be obtained by logging in to the Tomato admin interface and search for `http_id` in the page source code.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -38,4 +38,4 @@ For Archer C9 models running firmware version 150811 or later please use the enc
|
||||
5. Type ```document.getElementById("login-password").value;```.
|
||||
6. Copy the returned value to your Home Assistant configuration as password.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -11,7 +11,7 @@ logo: openwrt.png
|
||||
ha_category: Presence Detection
|
||||
---
|
||||
|
||||
_This is one of the two ways we support OpenWRT. If you encounter problems, try [luci](/components/device_tracker.luci.html)._
|
||||
_This is one of the two ways we support OpenWRT. If you encounter problems, try [luci](/components/device_tracker.luci/)._
|
||||
|
||||
This is a presence detection scanner for OpenWRT using [ubus](http://wiki.openwrt.org/doc/techref/ubus).
|
||||
|
||||
@ -55,4 +55,4 @@ Configuration variables:
|
||||
- **username** (*Required*): The username of an user with administrative privileges, usually *admin*.
|
||||
- **password** (*Required*): The password for your given admin account.
|
||||
|
||||
See the [device tracker component page](/components/device_tracker.html) for instructions how to configure the people to be tracked.
|
||||
See the [device tracker component page](/components/device_tracker/) for instructions how to configure the people to be tracked.
|
||||
|
@ -28,7 +28,7 @@ To load this component, add the following lines to your `configuration.yaml`:
|
||||
discovery:
|
||||
```
|
||||
|
||||
If you are developing a new platform, please read [how to make your platform discoverable]({{site_root}}/developers/add_new_platform.html#discovery).
|
||||
If you are developing a new platform, please read [how to make your platform discoverable]({{site_root}}/developers/add_new_platform/#discovery).
|
||||
|
||||
<p class='note warning'>
|
||||
There is currently a <a href='https://bitbucket.org/al45tair/netifaces/issues/17/dll-fails-to-load-windows-81-64bit'>known issue</a> with running this playform on a 64-bit version of Python.
|
||||
|
@ -11,11 +11,9 @@ logo: manything.png
|
||||
ha_category: Camera
|
||||
---
|
||||
|
||||
[Manything](https://manything.com) is a smart app that turns your iPhone, iPod, or iPad into a wifi
|
||||
camera for monitoring your home, your pets, anything! Comes with live streaming, motion activated alerts, cloud video recording, and more.
|
||||
[Manything](https://manything.com) is a smart app that turns your iPhone, iPod, or iPad into a wifi camera for monitoring your home, your pets, anything! Comes with live streaming, motion activated alerts, cloud video recording, and more.
|
||||
|
||||
To get manything support, HA will use IFTTT's [Maker Channel](https://ifttt.com/maker) and the [ManyThing Channel](https://ifttt.com/manything).
|
||||
Use the [IFTTT Setup instructions](/components/ifttt.html) to activate the IFTTT Platform.
|
||||
To get manything support, HA will use IFTTT's [Maker Channel](https://ifttt.com/maker) and the [ManyThing Channel](https://ifttt.com/manything). Use the [IFTTT Setup instructions](/components/ifttt/) to activate the IFTTT Platform.
|
||||
|
||||
After setting up IFTTT, Maker Channel and ManyThing Channel, you can use the following examples to configure Home Assistant.
|
||||
|
||||
@ -62,7 +60,7 @@ automation:
|
||||
<p class='img'>
|
||||
<img src='/images/components/ifttt/IFTTT_manything_trigger.png' />
|
||||
You need to setup a unique trigger for each event you sent to IFTTT.
|
||||
For ManyThing support, you need to set up an <code>on</code> and <code>off</code> event.
|
||||
For ManyThing support, you need to set up an `on` and `off` event.
|
||||
</p>
|
||||
|
||||
### {% linkable_title Testing your trigger %}
|
||||
|
@ -12,10 +12,7 @@ ha_category: Automation
|
||||
featured: true
|
||||
---
|
||||
|
||||
[IFTTT](https://ifttt.com) is a web service that allows users to create chains of simple conditional
|
||||
statements, so called "recipes". With the ifttt component you can trigger recipes through the "maker"
|
||||
channel. See the [announcement blog post](/blog/2015/09/13/home-assistant-meets-ifttt/) for examples
|
||||
how to use it.
|
||||
[IFTTT](https://ifttt.com) is a web service that allows users to create chains of simple conditional statements, so called "recipes". With the IFTTT component you can trigger recipes through the "maker" channel. See the [announcement blog post](/blog/2015/09/13/home-assistant-meets-ifttt/) for examples how to use it.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
@ -60,10 +57,7 @@ You need to setup a unique trigger for each event you sent to IFTTT.
|
||||
|
||||
### {% linkable_title Sending events from IFTTT to Home Assistant %}
|
||||
|
||||
To be able to receive events from IFTTT, your Home Assistant instance needs to be accessible from
|
||||
the web. This can be achieved by forwarding port 8123 from your router to the device running Home
|
||||
Assistant. If your ISP is giving you a new IP address from time to time, consider using
|
||||
[DuckDNS][duck-dns].
|
||||
To be able to receive events from IFTTT, your Home Assistant instance needs to be accessible from the web. This can be achieved by forwarding port 8123 from your router to the device running Home Assistant. If your ISP is giving you a new IP address from time to time, consider using [DuckDNS][duck-dns].
|
||||
|
||||
[duck-dns]: https://duckdns.org
|
||||
|
||||
@ -72,8 +66,9 @@ Assistant. If your ISP is giving you a new IP address from time to time, conside
|
||||
</p>
|
||||
|
||||
### {% linkable_title Additional Channel Examples %}
|
||||
|
||||
Additional examples of using IFTTT channels can be found below.
|
||||
|
||||
Channel | Description
|
||||
----- | -----
|
||||
[Manything](/components/ifttt.manything.html) | Automates turning recording ON and OFF based on Home Assistant AWAY and HOME values.
|
||||
[Manything](/components/ifttt.manything/) | Automates turning recording ON and OFF based on Home Assistant AWAY and HOME values.
|
||||
|
@ -22,7 +22,7 @@ The `keyboard` component simulates key presses on the host machine. It currently
|
||||
|
||||
To load this component, add the following lines to your `configuration.yaml`:
|
||||
|
||||
```
|
||||
```yaml
|
||||
keyboard:
|
||||
```
|
||||
|
||||
@ -30,8 +30,8 @@ keyboard:
|
||||
|
||||
You may need to install platform-specific [dependencies for PyUserInput](https://github.com/SavinaRoja/PyUserInput#dependencies) in order to use the keyboard component. In most cases this can be done by running:
|
||||
|
||||
```
|
||||
pip3 install [package name]
|
||||
```bash
|
||||
$ pip3 install [package name]
|
||||
```
|
||||
|
||||
#### {% linkable_title Windows %}
|
||||
|
@ -14,7 +14,7 @@ featured: true
|
||||
|
||||
|
||||
|
||||
Philips Hue support is integrated into Home Assistant as a light platform. The preferred way to setup the Philips Hue platform is by enabling the [the discovery component]({{site_root}}/components/discovery.html).
|
||||
Philips Hue support is integrated into Home Assistant as a light platform. The preferred way to setup the Philips Hue platform is by enabling the [the discovery component]({{site_root}}/components/discovery/).
|
||||
|
||||
If you want to enable the light component directly, add the following lines to your `configuration.yaml`:
|
||||
|
||||
|
@ -18,7 +18,7 @@ It supports the following platforms:
|
||||
* `hue` for Philips Hue
|
||||
* `wink` for Wink
|
||||
|
||||
Preferred way to setup the Philips Hue platform is through the [the discovery component]({{site_root}}/components/discovery.html). For the Wink light platform enable [the wink component]({{site_root}}/components/wink.html).
|
||||
Preferred way to setup the Philips Hue platform is through the [the discovery component]({{site_root}}/components/discovery/). For the Wink light platform enable [the wink component]({{site_root}}/components/wink/).
|
||||
|
||||
If you want to enable the light component directly, add the following lines to your `configuration.yaml`:
|
||||
|
||||
@ -33,7 +33,7 @@ The light component supports multiple entries in <code>configuration.yaml</code>
|
||||
|
||||
### Service `light.turn_on`
|
||||
|
||||
Turns one light on or multiple lights on using [groups]({{site_root}}/components/group.html).
|
||||
Turns one light on or multiple lights on using [groups]({{site_root}}/components/group/).
|
||||
|
||||
| Service data attribute | Optional | Description |
|
||||
| ---------------------- | -------- | ----------- |
|
||||
|
@ -14,4 +14,4 @@ ha_category: Light
|
||||
|
||||
The wink sensor platform allows you to use your [Wink](http://www.wink.com/) lights.
|
||||
|
||||
The requirement is that you have setup your [Wink hub](/components/light.wink.html).
|
||||
The requirement is that you have setup your [Wink hub](/components/light.wink/).
|
||||
|
@ -10,10 +10,7 @@ footer: true
|
||||
ha_category: "History"
|
||||
---
|
||||
|
||||
<img src='/images/screenshots/logbook.png' style='margin-left:10px; float: right;' height="100" />
|
||||
The logbook component provides a different perspective on the history of your house by showing all
|
||||
the changes that happened to your house in reverse chronological order.
|
||||
[See the demo for a live example](/demo/).
|
||||
<img src='/images/screenshots/logbook.png' style='margin-left:10px; float: right;' height="100" /> The logbook component provides a different perspective on the history of your house by showing all the changes that happened to your house in reverse chronological order. [See the demo for a live example](/demo/).
|
||||
|
||||
To enable the logbook in your installation, add the following to your `configuration.yaml` file:
|
||||
|
||||
|
@ -13,7 +13,7 @@ featured: true
|
||||
---
|
||||
|
||||
|
||||
Google Cast devices will be automatically discovered if you enable [the discovery component]({{site_root}}/components/discovery.html). There is a issue where Chromecasts can only be discovered if your device is connected to the same subnet as your Chromecast.
|
||||
Google Cast devices will be automatically discovered if you enable [the discovery component]({{site_root}}/components/discovery/). There is a issue where Chromecasts can only be discovered if your device is connected to the same subnet as your Chromecast.
|
||||
|
||||
Chromecast platform can also be forced to load by adding the following lines to your `configuration.yaml`:
|
||||
|
||||
|
@ -13,11 +13,9 @@ featured: true
|
||||
---
|
||||
|
||||
|
||||
The Plex platform allows you to connect a [Plex Media Server](https://plex.tv) to Home Assistant. It will allow you to control media playback and see the current playing item.
|
||||
The preferred way to setup the Plex platform is by enabling the the [the discovery component]({{site_root}}/components/discovery.html) and requires GDM to be enabled.
|
||||
|
||||
If local authentication is enabled or multiple users are defined, HASS requires an authentication token to be entered in the webinterface. See <A TARGET="_new" HREF=https://support.plex.tv/hc/en-us/articles/204059436>Finding your account token / X-Plex-Token</A>.
|
||||
The Plex platform allows you to connect a [Plex Media Server](https://plex.tv) to Home Assistant. It will allow you to control media playback and see the current playing item. The preferred way to setup the Plex platform is by enabling the the [the discovery component](/components/discovery/) and requires GDM to be enabled.
|
||||
|
||||
If local authentication is enabled or multiple users are defined, HASS requires an authentication token to be entered in the webinterface. See [Finding your account token / X-Plex-Token](https://support.plex.tv/hc/en-us/articles/204059436).
|
||||
|
||||
If you want to enable the plex platform directly, add the following lines to your `configuration.yaml`:
|
||||
|
||||
@ -27,14 +25,14 @@ media_player:
|
||||
- platform: plex
|
||||
```
|
||||
|
||||
You may also need to create the file `plex.conf`.
|
||||
You may also need to create the file `plex.conf`.
|
||||
|
||||
```
|
||||
{'IP_ADDRESS:PORT': {'token': 'TOKEN'}}
|
||||
```json
|
||||
{"<IP_ADDRESS>:<PORT>": {"token": "<TOKEN>"}}
|
||||
```
|
||||
|
||||
- **IP_ADDRESS** *Required*: IP address of the Plex Media Server
|
||||
- **PORT** *required*: Default is 32400
|
||||
- **TOKEN** *Optional*: Only is authentication is required. Set to `None` (without quotes) otherwise.
|
||||
- `<IP_ADDRESS>` *Required*: IP address of the Plex Media Server
|
||||
- `<PORT>` *required*: Default is 32400
|
||||
- `<TOKEN>` *Optional*: Only if authentication is required. Set to `None` (without quotes) otherwise.
|
||||
|
||||
At this moment, the Plex platform only supports one Plex Media Server.
|
||||
|
@ -18,6 +18,7 @@ To add modbus to your installation, add the following to your `configuration.yam
|
||||
|
||||
For a network connection:
|
||||
|
||||
```yaml
|
||||
#Modbus TCP
|
||||
modbus:
|
||||
type: tcp
|
||||
@ -57,6 +58,6 @@ Configuration variables:
|
||||
|
||||
## {% linkable_title Building on top of Modbus %}
|
||||
|
||||
- [Modbus Sensor](/components/sensor.modbus.html)
|
||||
- [Modbus Switch](/components/switch.modbus.html)
|
||||
- [Modbus Sensor](/components/sensor.modbus/)
|
||||
- [Modbus Switch](/components/switch.modbus/)
|
||||
|
||||
|
@ -40,14 +40,11 @@ Configuration variables:
|
||||
|
||||
## {% linkable_title Picking a broker %}
|
||||
|
||||
The MQTT component needs you to run an MQTT broker for Home Assistant to connect to.
|
||||
|
||||
There are three options, each with various degrees of ease of setup and privacy.
|
||||
The MQTT component needs you to run an MQTT broker for Home Assistant to connect to. There are three options, each with various degrees of ease of setup and privacy.
|
||||
|
||||
#### {% linkable_title Run your own %}
|
||||
|
||||
Most private option but requires a bit more work. There are two free and open-source brokers to pick
|
||||
from: [Mosquitto](http://mosquitto.org/) and [Mosca](http://www.mosca.io/).
|
||||
Most private option but requires a bit more work. There are two free and open-source brokers to pick from: [Mosquitto](http://mosquitto.org/) and [Mosca](http://www.mosca.io/).
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
@ -62,9 +59,7 @@ mqtt:
|
||||
|
||||
#### {% linkable_title Public MQTT %}
|
||||
|
||||
The Mosquitto project runs a [public broker](http://test.mosquitto.org). Easiest to setup but there
|
||||
is 0 privacy as all messages are public. Use this only for testing purposes and not for real tracking
|
||||
of your devices.
|
||||
The Mosquitto project runs a [public broker](http://test.mosquitto.org). Easiest to setup but there is 0 privacy as all messages are public. Use this only for testing purposes and not for real tracking of your devices.
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
@ -80,9 +75,7 @@ mqtt:
|
||||
|
||||
#### {% linkable_title CloudMQTT %}
|
||||
|
||||
[CloudMQTT](https://www.cloudmqtt.com) is a hosted private MQTT instance that is free up to 10
|
||||
connected devices. This is enough to get started with for example
|
||||
[OwnTracks](/components/device_tracker.owntracks.html) and give you a taste of what is possible.
|
||||
[CloudMQTT](https://www.cloudmqtt.com) is a hosted private MQTT instance that is free up to 10 connected devices. This is enough to get started with for example [OwnTracks](/components/device_tracker.owntracks/) and give you a taste of what is possible.
|
||||
|
||||
<p class='note'>
|
||||
Home Assistant is not affiliated with CloudMQTT nor will receive any kickbacks.
|
||||
@ -97,35 +90,35 @@ Home Assistant is not affiliated with CloudMQTT nor will receive any kickbacks.
|
||||
a. Under manage users, fill in username, password and click add
|
||||
b. Under ACLs, select user, topic `#`, check 'read access' and 'write access'
|
||||
5. Copy the instance info to your configuration.yaml:
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
broker: <Server>
|
||||
port: <SSL Port>
|
||||
username: <User>
|
||||
password: <Password>
|
||||
mqtt:
|
||||
broker: <Server>
|
||||
port: <SSL Port>
|
||||
username: <User>
|
||||
password: <Password>
|
||||
```
|
||||
|
||||
<p class='note'>
|
||||
Home Assistant will automatically load the correct certificate if you connect to an encrypted channel
|
||||
of CloudMQTT (port range 20 000 - 30 000).
|
||||
Home Assistant will automatically load the correct certificate if you connect to an encrypted channel of CloudMQTT (port range 20 000 - 30 000).
|
||||
</p>
|
||||
|
||||
## {% linkable_title Building on top of MQTT %}
|
||||
|
||||
- [MQTT Sensor](/components/sensor.mqtt.html)
|
||||
- [MQTT Switch](/components/switch.mqtt.html)
|
||||
- [MQTT Device Tracker](/components/device_tracker.mqtt.html)
|
||||
- [OwnTracks Device Tracker](/components/device_tracker.owntracks.html)
|
||||
- [MQTT automation rule](/components/automation.html#mqtt-based-automation)
|
||||
- [MQTT alarm](/components/alarm_control_panel.mqtt.html)
|
||||
- Integrating it into a component. See the [MQTT example component](https://github.com/balloob/home-assistant/blob/dev/config/custom_components/mqtt_example.py) how to do this.
|
||||
- [MQTT Sensor](/components/sensor.mqtt/)
|
||||
- [MQTT Switch](/components/switch.mqtt/)
|
||||
- [MQTT Device Tracker](/components/device_tracker.mqtt/)
|
||||
- [OwnTracks Device Tracker](/components/device_tracker.owntracks/)
|
||||
- [MQTT automation rule](/components/automation/#mqtt-based-automation)
|
||||
- [MQTT alarm](/components/alarm_control_panel.mqtt/)
|
||||
- Integrating it into own component. See the [MQTT example component](https://github.com/balloob/home-assistant/blob/dev/config/custom_components/mqtt_example.py) how to do this.
|
||||
|
||||
## {% linkable_title Testing your setup %}
|
||||
|
||||
For debugging purposes `mosquitto` is shipping commandline tools to send and recieve MQTT messages. For sending test messages to a broker running on localhost:
|
||||
|
||||
```bash
|
||||
mosquitto_pub -h 127.0.0.1 -t home-assistant/switch/1/on -m "Switch is ON"
|
||||
$ mosquitto_pub -h 127.0.0.1 -t home-assistant/switch/1/on -m "Switch is ON"
|
||||
```
|
||||
|
||||
Another way to send MQTT messages by hand is to use the "Developer Tools" in the Frontend. Choose "Call Service" and then `mqtt/mqtt_send` under "Available Services". Enter something similar to the example below into the "Service Data" field.
|
||||
@ -146,5 +139,5 @@ The message should appear on the bus:
|
||||
For reading all messages sent on the topic `home-assistant` to a broker running on localhost:
|
||||
|
||||
```bash
|
||||
mosquitto_sub -h 127.0.0.1 -v -t "home-assistant/#"
|
||||
$ mosquitto_sub -h 127.0.0.1 -v -t "home-assistant/#"
|
||||
```
|
||||
|
@ -30,4 +30,4 @@ Configuration variables:
|
||||
- **filename** (*Required*): Name of the file to use. The file will be created if it doesn't exist and saved in your `config/` folder.
|
||||
- **timestamp** (*Optional*): Setting `timestamp` to 1 adds a timestamp to every entry.
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -49,4 +49,4 @@ curl -X POST \
|
||||
```
|
||||
For further details, please check the [API](https://instapush.im/developer/rest).
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -40,4 +40,4 @@ automation:
|
||||
service_data: {"message":"YAY"}
|
||||
```
|
||||
|
||||
For more automation examples, see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
For more automation examples, see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -31,4 +31,4 @@ Configuration variables:
|
||||
|
||||
Details for the API : https://www.notifymyandroid.com/api.jsp
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -30,4 +30,4 @@ Configuration variables:
|
||||
- **name** (*Optional*): Setting the optional parameter `name` allows multiple notifiers to be created. The default value is `notify`. The notifier will bind to the service `notify.NOTIFIER_NAME`.
|
||||
- **api_key** (*Required*): Enter the API key for PushBullet. Go to https://www.pushbullet.com/ to retrieve your API key.
|
||||
|
||||
For more automation examples, see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
For more automation examples, see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -32,9 +32,9 @@ Configuration variables:
|
||||
- **user_key** (*Required*): To retrieve this value log into your account at https://pushover.net
|
||||
|
||||
This is a quote from the pushover website regarding free/open source apps:
|
||||
> "If you are creating a client-side library, application, or open source project that will be redistributed and installed by end-users, you may want to require each of your users to register their own application rather than including your own API token with the software."
|
||||
|
||||
<blockquote>
|
||||
If you are creating a client-side library, application, or open source project that will be redistributed and installed by end-users, you may want to require each of your users to register their own application rather than including your own API token with the software.
|
||||
</blockquote>
|
||||
|
||||
When setting up the application you can use this [icon](https://home-assistant.io/images/favicon-192x192.png).
|
||||
|
||||
For more automation examples, see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
|
||||
|
@ -33,5 +33,5 @@ Configuration variables:
|
||||
- **api_key** (*Required*): The slack API token to use for sending slack messages. You can get your slack API token here https://api.slack.com/web?sudo=1
|
||||
- **default_channel** (*Required*): The default channel to post to if no channel is explicitly specified when sending the notification message.
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
||||
|
@ -51,4 +51,4 @@ Keep in mind that if the password contains a colon, it needs to be wrapped in ap
|
||||
For Google Mail (smtp.gmail.com) an additional step in the setup process is needed. Google has some extra layers of protection
|
||||
which need special attention. By default, the usage by external applications, especially scripts, is limited. Visit the [Less secure apps](https://www.google.com/settings/security/lesssecureapps) page and enable it.
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -57,4 +57,4 @@ The table contains values to use in your `configuration.yaml` file.
|
||||
|
||||
For details about facility, option, and priority please consult the [wikpedia article](http://en.wikipedia.org/wiki/Syslog) and [RFC 3164](http://tools.ietf.org/html/rfc3164).
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -48,4 +48,4 @@ The default value is `notify`. The notifier will bind to the service
|
||||
- **api_key** (*Required*): The API token of your bot.
|
||||
- **chat_id** (*Required*: The chat ID of your user.
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -34,4 +34,4 @@ Configuration variables:
|
||||
All Jabber IDs (JID) must include the domain. Make sure that the password matches the account provided as sender.
|
||||
|
||||
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation.html).
|
||||
To use notifications, please see the [getting started with automation page]({{site_root}}/components/automation/).
|
||||
|
@ -10,25 +10,14 @@ footer: true
|
||||
ha_category: Organization
|
||||
---
|
||||
|
||||
A user can create scenes that capture the states you want certain entities to be. For example a scene
|
||||
can contain that light A should be turned on and light B should be bright red.
|
||||
A user can create scenes that capture the states you want certain entities to be. For example a scene can contain that light A should be turned on and light B should be bright red.
|
||||
|
||||
A scene is active if all states of the scene match the actual states. An optional `fuzzy_match` option
|
||||
can be given to allow entities to match if attributes are not exact but are in range of the preferred
|
||||
state.
|
||||
|
||||
If a scene is manually activated it will store the previous state of the entities. These will be
|
||||
restored when the state is deactivated manually. If one of the enties that are being tracked change
|
||||
state on its own, the old state will not be restored when it is being deactivated.
|
||||
|
||||
Scenes can be activated using the service `scene.turn_on` and deactivated using the service `scene.turn_off`.
|
||||
Scenes can be activated using the service `scene.turn_on`.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
scene:
|
||||
- name: Romantic
|
||||
# Optional, allow fuzzy matching number atttributes to check if scene is on
|
||||
fuzzy_match: 0.2
|
||||
entities:
|
||||
light.tv_back_light: on
|
||||
light.ceiling:
|
||||
|
@ -10,8 +10,7 @@ footer: true
|
||||
ha_category: Automation
|
||||
---
|
||||
|
||||
The script component allows users to create a sequence of service calls and delays. Scripts can be
|
||||
started using the service `script/turn_on` and interrupted using the service `script/turn_off`.
|
||||
The script component allows users to create a sequence of service calls and delays. Scripts can be started using the service `script/turn_on` and interrupted using the service `script/turn_off`.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
|
@ -43,7 +43,7 @@ In this section you find some real life examples of how to use this sensor.
|
||||
There are several ways to get the temperature of your hard drive. A simple solution is to use [hddtemp](https://savannah.nongnu.org/projects/hddtemp/).
|
||||
|
||||
```bash
|
||||
hddtemp -n /dev/sda
|
||||
$ hddtemp -n /dev/sda
|
||||
```
|
||||
|
||||
To use those information, the entry for a sensor in the `configuration.yaml` file will look like this.
|
||||
@ -59,8 +59,7 @@ sensor:
|
||||
|
||||
### {% linkable_title CPU temperature %}
|
||||
|
||||
Thanks to the [`proc`](https://en.wikipedia.org/wiki/Procfs) file system, various details about a system can be retrieved. Here the CPU temperature
|
||||
is of interest. Add something similar to your `configuration.yaml` file:
|
||||
Thanks to the [`proc`](https://en.wikipedia.org/wiki/Procfs) file system, various details about a system can be retrieved. Here the CPU temperature is of interest. Add something similar to your `configuration.yaml` file:
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
@ -75,19 +74,18 @@ The `correction_factor` will make sure that the value is shown in a useful forma
|
||||
|
||||
### {% linkable_title Use an external script %}
|
||||
|
||||
The example is doing the same as the [aREST sensor](/components/sensor.arest.html) but with an external Python script. It should give you an idea about interacting with devices which are exposing a RESTful API.
|
||||
The example is doing the same as the [aREST sensor](/components/sensor.arest/) but with an external Python script. It should give you an idea about interacting with devices which are exposing a RESTful API.
|
||||
|
||||
The one-line script to retrieve a value is shown below. Of course would it be possible to use this directly in the `configuration.yaml` file but need extra care about the quotation marks.
|
||||
|
||||
```python
|
||||
python3 -c "import requests; print(requests.get('http://10.0.0.48/analog/2').json()['return_value'])"
|
||||
```bash
|
||||
$ python3 -c "import requests; print(requests.get('http://10.0.0.48/analog/2').json()['return_value'])"
|
||||
```
|
||||
|
||||
The script (saved as `arest-value.py`) that is used looks like the example below.
|
||||
|
||||
```python
|
||||
#!/usr/bin/python3
|
||||
#
|
||||
from requests import get
|
||||
response = get('http://10.0.0.48/analog/2')
|
||||
print(response.json()['return_value'])
|
||||
|
@ -14,7 +14,7 @@ featured: true
|
||||
|
||||
The forecast platform uses the [Forecast.io](https://forecast.io/) web service as a source for meteorological data for your location. The location is based on the Longitude and Latitude cooridinates configured in `configuration.yaml`. The cooridinates are auto detected but to take advantage of the hyper-local weather reported by forecast.io, you can refine them down to your exact home address. GPS cooridinates can be found by using Google Maps and clicking on your home.
|
||||
|
||||
You need an API key which is free but requires a [registration](https://developer.forecast.io/register). You can make 1000 requests per day. This means that you could create approximately every 1.4 minute one.
|
||||
You need an API key which is free but requires a [registration](https://developer.forecast.io/register). You can make 1000 requests per day. This means that you could create one approximately every 1.4 minutes.
|
||||
|
||||
To add Forecast.io to your installation, add the following to your `configuration.yaml` file:
|
||||
|
||||
@ -45,7 +45,7 @@ sensor:
|
||||
|
||||
Configuration variables:
|
||||
|
||||
- **api_key** (*Required*): Your API key for http://forecast.io/.
|
||||
- **api_key** (*Required*): Your API key for http://forecast.io/.
|
||||
- **monitored_conditions** array (*Required*): Conditions to display in the frontend.
|
||||
- **summary**: A human-readable text summary.
|
||||
- **precip_type**: The type of precipitation occurring.
|
||||
@ -59,7 +59,7 @@ Configuration variables:
|
||||
- **pressure**: The sea-level air pressure in millibars.
|
||||
- **visibility**: The average visibility.
|
||||
- **ozone**: The columnar density of total atmospheric ozone in Dobson.
|
||||
- **units** (*Optional*): Specify the unit system. Default to `si` or `us` based on the temperature preference in Home Assistant. Other options are auto, us, si, ca, and uk2.
|
||||
- **units** (*Optional*): Specify the unit system. Default to `si` or `us` based on the temperature preference in Home Assistant. Other options are `auto`, `us`, `si`, `ca`, and `uk2`.
|
||||
`auto` will let forecast.io decide the unit system based on location.
|
||||
|
||||
Details about the API are available in the [Forecast.io documentation](https://developer.forecast.io/docs/v2).
|
||||
|
@ -35,6 +35,6 @@ Configuration variables:
|
||||
If you are using an original Arduino the port will be named `ttyACM*`. The exact number can be determined with the command shown below.
|
||||
|
||||
```bash
|
||||
ls /dev/ttyACM*
|
||||
$ ls /dev/ttyACM*
|
||||
```
|
||||
|
||||
|
@ -86,7 +86,7 @@ To display the IP address, the entry for a sensor in the `configuration.yaml` fi
|
||||
|
||||
### {% linkable_title Single value from a local Glances instance %}
|
||||
|
||||
The [glances](/components/sensor.glances.html) sensor is doing the exact same thing for all exposed values.
|
||||
The [glances](/components/sensor.glances/) sensor is doing the exact same thing for all exposed values.
|
||||
|
||||
Add something similar to the entry below to your `configuration.yaml` file:
|
||||
|
||||
|
@ -14,5 +14,5 @@ ha_category: Sensor
|
||||
|
||||
The wink sensor platform allows you to get data from your [Wink](http://www.wink.com/) sensors.
|
||||
|
||||
The requirement is that you have setup your [Wink hub](/components/light.wink.html).
|
||||
The requirement is that you have setup your [Wink hub](/components/light.wink/).
|
||||
|
||||
|
@ -10,9 +10,7 @@ footer: true
|
||||
ha_category: Automation
|
||||
---
|
||||
|
||||
|
||||
This component can expose regular shell commands as services. Services can be called from a script
|
||||
or in automation.
|
||||
This component can expose regular shell commands as services. Services can be called from a script or in automation.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
|
@ -11,9 +11,9 @@ ha_category: Alarm
|
||||
---
|
||||
|
||||
|
||||
The component `simple_alarm` is capable of detecting intruders. It does so by checking if lights are being turned on while there is no one at home. When this happens it will turn the lights red, flash them for 30 seconds and send a message via [the notifiy component]({{site_root}}/components/notify.html). It will also flash a specific light when a known person comes home.
|
||||
The component `simple_alarm` is capable of detecting intruders. It does so by checking if lights are being turned on while there is no one at home. When this happens it will turn the lights red, flash them for 30 seconds and send a message via [the notifiy component]({{site_root}}/components/notify/). It will also flash a specific light when a known person comes home.
|
||||
|
||||
This component depends on the components [device_tracker]({{site_root}}/components/device_tracker.html) and [light]({{site_root}}/components/light.html) being setup.
|
||||
This component depends on the components [device_tracker]({{site_root}}/components/device_tracker/) and [light]({{site_root}}/components/light/) being setup.
|
||||
|
||||
To set it up, add the following lines to your `configuration.yaml` file:
|
||||
|
||||
|
@ -10,11 +10,9 @@ footer: true
|
||||
ha_category: Weather
|
||||
---
|
||||
|
||||
The sun component will use your current location to track if the sun is above or below the horizon.The sun can be used within automation as [a trigger with an optional offset to simulate dawn/dusk][automation-trigger].
|
||||
|
||||
The `sun` component will use your current location to track if the sun is above or below the horizon.
|
||||
The sun can be used within automation as [a trigger with an optional offset to simulate dawn/dusk][automation-trigger].
|
||||
|
||||
[automation-trigger]: /components/automation.html#sun-trigger
|
||||
[automation-trigger]: /components/automation/#sun-trigger
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
|
@ -38,7 +38,7 @@ In this section you find some real life examples of how to use this switch.
|
||||
|
||||
### {% linkable_title aREST device %}
|
||||
|
||||
The example below is doing the same as the [aREST switch](/components/switch.arest.html). The commandline tool `[curl](http://curl.haxx.se/)` is used to toogle a pin which is controllable through REST.
|
||||
The example below is doing the same as the [aREST switch](/components/switch.arest/). The commandline tool [`curl`](http://curl.haxx.se/) is used to toogle a pin which is controllable through REST.
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
|
@ -12,11 +12,9 @@ ha_category: Switch
|
||||
---
|
||||
|
||||
|
||||
In an ideal scenario, the MQTT device will have a state topic to publish state changes. If these messages are published with RETAIN flag, the MQTT switch will receive an instant state update after subscription and will
|
||||
start with correct state. Otherwise, the initial state of the switch will be false/off.
|
||||
In an ideal scenario, the MQTT device will have a state topic to publish state changes. If these messages are published with RETAIN flag, the MQTT switch will receive an instant state update after subscription and will start with correct state. Otherwise, the initial state of the switch will be false/off.
|
||||
|
||||
When a state topic is not available, the switch will work in optimistic mode. In this mode, the switch will immediately change state after every command. Otherwise, the switch will wait for state confirmation from device
|
||||
(message from `state_topic`).
|
||||
When a state topic is not available, the switch will work in optimistic mode. In this mode, the switch will immediately change state after every command. Otherwise, the switch will wait for state confirmation from device (message from `state_topic`).
|
||||
|
||||
Optimistic mode can be forced, even if state topic is available. Try to enable it, if experiencing incorrect switch operation.
|
||||
|
||||
@ -44,5 +42,5 @@ Configuration variables:
|
||||
- **optimistic** (*Optional*): Flag that defines if switch works in optimistic mode. Default is true if no state topic defined, else false.
|
||||
|
||||
<p class='note warning'>
|
||||
Make sure that your topics match exact. <code>some-topic/</code> and <code>some-topic</code> are different topics.
|
||||
Make sure that your topics match exact. `some-topic/` and `some-topic` are different topics.
|
||||
</p>
|
||||
|
@ -14,5 +14,5 @@ ha_category: Switch
|
||||
|
||||
The wink switch platform allows you to control your [Wink](http://www.wink.com/) switches.
|
||||
|
||||
The requirement is that you have setup your [Wink hub](/components/light.wink.html).
|
||||
The requirement is that you have setup your [Wink hub](/components/light.wink/).
|
||||
|
||||
|
@ -12,8 +12,7 @@ ha_category: Hub
|
||||
---
|
||||
|
||||
|
||||
The tellstick component integrates [TellStick](http://www.telldus.se/products/tellstick) devices into Home Assistant. This integration allows users to add switches, lights, and sensors which are communicating with 433 Mhz. There are couple of vendors (Capidi
|
||||
Elro, Intertechno, Nexa, Proove, Sartano, and Viking) how are selling products which works with TellStick. For more details, please check the TellStick [compatibility list](http://telldus.se/products/compability).
|
||||
The tellstick component integrates [TellStick](http://www.telldus.se/products/tellstick) devices into Home Assistant. This integration allows users to add switches, lights, and sensors which are communicating with 433 Mhz. There are couple of vendors (Capidi Elro, Intertechno, Nexa, Proove, Sartano, and Viking) how are selling products which works with TellStick. For more details, please check the TellStick [compatibility list](http://telldus.se/products/compability).
|
||||
|
||||
To get started, add the devices to your `configuration.yaml` file.
|
||||
|
||||
@ -28,6 +27,5 @@ sensor:
|
||||
# All dimmers will be picked up as lights.
|
||||
light:
|
||||
platform: tellstick
|
||||
|
||||
```
|
||||
|
||||
|
@ -16,6 +16,6 @@ The [Vera](http://getvera.com) ecosystem is using Z-Wave for communication betwe
|
||||
|
||||
## {% linkable_title Building on top of Vera %}
|
||||
|
||||
- [Vera Sensor](/components/sensor.vera.html)
|
||||
- [Vera Switch](/components/switch.vera.html)
|
||||
- [Vera Light](/components/light.vera.html)
|
||||
- [Vera Sensor](/components/sensor.vera/)
|
||||
- [Vera Switch](/components/switch.vera/)
|
||||
- [Vera Light](/components/light.vera/)
|
||||
|
@ -12,14 +12,15 @@ ha_category: Hub
|
||||
featured: true
|
||||
---
|
||||
|
||||
|
||||
[Wink](http://www.wink.com/) is a home automation hub that can control a whole wide range of devices on the market. Or, as they say in their own words:
|
||||
|
||||
<blockquote>Wink offers one, quick and simple way to connect people with the products they rely on every day in their home.</blockquote>
|
||||
<blockquote>
|
||||
Wink offers one, quick and simple way to connect people with the products they rely on every day in their home.
|
||||
</blockquote>
|
||||
|
||||
Home Assistant integrates the Wink hub and allows you to get the status and control connected switches, lights and sensors.
|
||||
|
||||
To get started with the Wink API, you will first need to get yourself an API access token. Because it is very difficult right now to get access to their API, John McLaughlin has created the form below to get you one.
|
||||
To get started with the Wink API, you will first need to get yourself an API access token. Because it is very difficult right now to get access to their API, John McLaughlin has created the form below to get you one.
|
||||
|
||||
<iframe src="https://winkbearertoken.appspot.com"
|
||||
style='width: 100%; height: 200px; border: 0; margin: 0 auto 15px; border-left: 2px solid #049cdb; padding-left: 15px;'></iframe>
|
||||
@ -38,5 +39,5 @@ Configuration variables:
|
||||
This will connect to the Wink hub and automatically set up any lights, switches and sensors that it finds.
|
||||
|
||||
<p class='note'>
|
||||
The Wink hub can only be accessed via the cloud. This means it requires an active internet connection and you will experience delays when controlling devices (~3s) and getting an updated device state (~15s).
|
||||
The Wink hub can only be accessed via the cloud. This means it requires an active internet connection and you will experience delays when controlling devices (~3s) and getting an updated device state (~15s).
|
||||
</p>
|
||||
|
@ -10,10 +10,7 @@ footer: true
|
||||
ha_category: Organization
|
||||
---
|
||||
|
||||
Zones allow you to specify certain regions on earth (for now). When a device tracker sees a device
|
||||
to be within a zone, the state will take the name from the zone. Zones can also be used as a
|
||||
[trigger](/components/automation.html#zone-trigger) or [condition](/components/automation.html#zone-condition)
|
||||
inside automation setups.
|
||||
Zones allow you to specify certain regions on earth (for now). When a device tracker sees a device to be within a zone, the state will take the name from the zone. Zones can also be used as a [trigger](/components/automation/#zone-trigger) or [condition](/components/automation/#zone-condition) inside automation setups.
|
||||
|
||||
Zones support the usual method to specify multiple zones, use keys `zone:`, `zone 2:` etc.
|
||||
|
||||
@ -44,18 +41,12 @@ zone 3:
|
||||
|
||||
#### {% linkable_title Home zone %}
|
||||
|
||||
If no configuration is given, the zone component will create a zone for home. This zone will use
|
||||
location given in the `configuration.yaml` file and have a radius of 100 meters. To override this,
|
||||
create a zone configuration and name it 'Home'.
|
||||
If no configuration is given, the zone component will create a zone for home. This zone will use location given in the `configuration.yaml` file and have a radius of 100 meters. To override this, create a zone configuration and name it 'Home'.
|
||||
|
||||
#### {% linkable_title Icons %}
|
||||
|
||||
It is preferred to pick an icon to use for your zone. By default, Home Assistant includes most of the
|
||||
[material icons](https://www.google.com/design/icons/). See [the source][icon-source] for a specific list which
|
||||
categories are included.
|
||||
It is preferred to pick an icon to use for your zone. By default, Home Assistant includes most of the [material icons](https://www.google.com/design/icons/). See [the source][icon-source] for a specific list which categories are included.
|
||||
|
||||
For all but the action category you will need to prefix the icon name with its category. For example
|
||||
`social:people` or `av:radio`. For the action category, you will not need to do this, examples are
|
||||
`home`, `work,`, `group-work` and `shopping-cart`.
|
||||
For all but the action category you will need to prefix the icon name with its category. For example `social:people` or `av:radio`. For the action category, you will not need to do this, examples are `home`, `work,`, `group-work` and `shopping-cart`.
|
||||
|
||||
[icon-source]: https://github.com/balloob/home-assistant-polymer/blob/master/src/resources/home-assistant-icons.html#L3
|
||||
|
@ -19,9 +19,9 @@ To allow Home Assistant to talk to your Z-Wave USB stick you will have to compil
|
||||
|
||||
Please make sure you have the correct dependencies installed:
|
||||
|
||||
```
|
||||
apt-get install cython3 libudev-dev python-sphinx python3-setuptools
|
||||
pip3 install "cython<0.23"
|
||||
```bash
|
||||
$ apt-get install cython3 libudev-dev python-sphinx python3-setuptools
|
||||
$ pip3 install "cython<0.23"
|
||||
```
|
||||
|
||||
As an alternative, the Home Assistant docker image has support for Z-Wave built-in.
|
||||
@ -36,6 +36,8 @@ Configuration variables:
|
||||
|
||||
- **usb_path** (*Required*): The port where your device is connected to your Home Assistant host.
|
||||
|
||||
To find the path of your Z-Wave stick, run:
|
||||
|
||||
```bash
|
||||
ls /dev/ttyUSB*
|
||||
$ ls /dev/ttyUSB*
|
||||
```
|
||||
|
@ -11,7 +11,7 @@ footer: true
|
||||
|
||||
### Rainy Day Light ###
|
||||
|
||||
This requires a [forecast.io](components/sensor.forecast.html) sensor with the condition `weather_precip` that tells if it's raining or not.
|
||||
This requires a [forecast.io](components/sensor.forecast/) sensor with the condition `weather_precip` that tells if it's raining or not.
|
||||
|
||||
Turn on a light in the living room when it starts raining, someone is home, and it's afternoon or later.
|
||||
|
||||
@ -40,6 +40,7 @@ automation:
|
||||
And then of course turn off the lamp when it stops raining but only if it's within an hour before sunset.
|
||||
|
||||
```yaml
|
||||
automation 2:
|
||||
alias: 'Rain is over'
|
||||
trigger:
|
||||
- platform: state
|
||||
|
@ -27,7 +27,9 @@ automation:
|
||||
```
|
||||
|
||||
#### Natural wake up light
|
||||
|
||||
_Note, Philips Hue is currently the only light platform that support transitions._
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
trigger:
|
||||
|
@ -17,9 +17,15 @@
|
||||
</header>
|
||||
{% endunless %}
|
||||
{% if index %}
|
||||
<div class="entry-content">{{ content | excerpt }}</div>
|
||||
{% capture excerpted %}{{ content | has_excerpt }}{% endcapture %}
|
||||
{% if excerpted == 'true' %}
|
||||
<div class="entry-content">
|
||||
{% if post.excerpted %}
|
||||
{{ post.excerpt }}
|
||||
<a href="{{ post.url }}"Continue reading →</a>
|
||||
{% else %}
|
||||
{{ post.content }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if post.excerpted %}
|
||||
<footer>
|
||||
<a rel="full-article" href="{{ root_url }}{{ post.url }}">{{ site.excerpt_link }}</a>
|
||||
</footer>
|
||||
|
@ -7,11 +7,12 @@
|
||||
</div>
|
||||
|
||||
{% assign file_parts = page.url | split: '/' | last | split: '.' %}
|
||||
{% if file_parts.size == 3 %}
|
||||
|
||||
{% if file_parts.size == 2 %}
|
||||
{% assign is_platform = true %}
|
||||
{% assign imp_name = file_parts[1] %}
|
||||
{% assign parent_name = file_parts[0] %}
|
||||
{% assign parent_url = parent_name | prepend: '/components/' | append: '.html' %}
|
||||
{% assign parent_url = parent_name | prepend: '/components/' | append: '/' %}
|
||||
{% assign parent_component = components | where: 'url', parent_url | first %}
|
||||
{% else %}
|
||||
{% assign is_platform = false %}
|
||||
@ -54,8 +55,8 @@
|
||||
{% for component in components %}
|
||||
{% if component.url != page.url %}
|
||||
{% assign comp_file_parts = component.url | split: '/' | last | split: '.' %}
|
||||
{% if comp_file_parts.size == 3 %}
|
||||
{% assign comp_imp_name = comp_file_parts[1] %}
|
||||
{% if comp_file_parts.size == 2 %}
|
||||
{% assign comp_imp_name = comp_file_parts | last %}
|
||||
{% else %}
|
||||
{% assign comp_imp_name = comp_file_parts | first %}
|
||||
{% endif %}
|
||||
|
@ -22,13 +22,13 @@
|
||||
{% endunless %}
|
||||
</header>
|
||||
|
||||
{% capture excerpted %}{{ content | has_excerpt }}{% endcapture %}
|
||||
|
||||
{% if excerpted == 'true' and index %}
|
||||
<div class="entry-content clearfix">
|
||||
{{ content | excerpt }}
|
||||
<a class="btn pull-right" href="{{ root_url }}{{ post.url }}#read-more">{{ site.excerpt_link }}</a>
|
||||
</div>
|
||||
{% if index %}
|
||||
<div class="entry-content clearfix">
|
||||
{{ post.excerpt }}
|
||||
{% if post.content contains site.excerpt_separator %}
|
||||
<a class="btn pull-right" href="{{ post.url }}#read-more">{{ site.excerpt_link }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ content | replace: site.excerpt_separator, '<a name="read-more"></a>' }}
|
||||
{% endif %}
|
||||
{{ post.content | replace: site.excerpt_separator, '<a name="read-more"></a>' }}
|
||||
{% endif %}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% capture date %}{{ page.date }}{{ post.date }}{% endcapture %}
|
||||
{% capture date_formatted %}{{ page.date_formatted }}{{ post.date_formatted }}{% endcapture %}
|
||||
{% capture date_formatted %}{{ post.date_formatted }}{% endcapture %}
|
||||
{% capture has_date %}{{ date | size }}{% endcapture %}
|
||||
|
||||
{% capture updated %}{{ page.updated }}{{ post.updated }}{% endcapture %}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user