postmarkdown 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/Rakefile +24 -0
- data/app/controllers/application_controller.rb +2 -0
- data/app/controllers/posts_controller.rb +31 -0
- data/app/models/post.rb +149 -0
- data/app/views/layouts/postmarkdown.html.haml +16 -0
- data/app/views/posts/_feed_link.html.haml +2 -0
- data/app/views/posts/_post.html.haml +15 -0
- data/app/views/posts/feed.xml.builder +29 -0
- data/app/views/posts/index.html.haml +8 -0
- data/app/views/posts/show.html.haml +3 -0
- data/lib/generators/postmarkdown/install_generator.rb +19 -0
- data/lib/generators/postmarkdown/override_generator.rb +44 -0
- data/lib/generators/postmarkdown/post_generator.rb +33 -0
- data/lib/generators/postmarkdown/templates/example-post.markdown +67 -0
- data/lib/generators/postmarkdown/usage/install.txt +10 -0
- data/lib/generators/postmarkdown/usage/override.txt +9 -0
- data/lib/generators/postmarkdown/usage/post.txt +14 -0
- data/lib/postmarkdown.rb +5 -0
- data/lib/postmarkdown/config.rb +22 -0
- data/lib/postmarkdown/engine.rb +12 -0
- data/lib/postmarkdown/railtie.rb +18 -0
- data/lib/postmarkdown/routes.rb +29 -0
- data/lib/postmarkdown/util.rb +12 -0
- data/lib/postmarkdown/version.rb +3 -0
- data/postmarkdown.gemspec +35 -0
- data/public/stylesheets/postmarkdown/postmarkdown.css +67 -0
- data/readme.md +143 -0
- data/spec/acceptance/posts_spec.rb +167 -0
- data/spec/models/posts_spec.rb +72 -0
- data/spec/routing/posts_routing_spec.rb +80 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/data/posts/2011-04-01-first-post.markdown +3 -0
- data/spec/support/data/posts/2011-04-28-image.markdown +3 -0
- data/spec/support/data/posts/2011-04-28-summary.markdown +8 -0
- data/spec/support/data/posts/2011-05-01-full-metadata.markdown +10 -0
- data/spec/support/data/posts/2011-05-02-md-file-extension.md +1 -0
- data/spec/support/data/posts/2011-05-02-mdown-file-extension.mdown +1 -0
- data/spec/support/data/posts/2011-05-02-mkd-file-extension.mkd +1 -0
- data/spec/support/data/posts/2015-02-13-custom-title.markdown +5 -0
- data/spec/support/data/posts/missing-date-from-filename.markdown +1 -0
- data/spec/support/rails_app/.gitignore +4 -0
- data/spec/support/rails_app/README +256 -0
- data/spec/support/rails_app/Rakefile +7 -0
- data/spec/support/rails_app/app/controllers/application_controller.rb +3 -0
- data/spec/support/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/support/rails_app/app/posts/2011-04-01-first-post.markdown +3 -0
- data/spec/support/rails_app/app/posts/2011-04-28-image.markdown +3 -0
- data/spec/support/rails_app/app/posts/2011-04-28-summary.markdown +8 -0
- data/spec/support/rails_app/app/posts/2011-05-01-full-metadata.markdown +13 -0
- data/spec/support/rails_app/app/posts/2015-02-13-custom-title.markdown +5 -0
- data/spec/support/rails_app/app/views/layouts/application.html.erb +14 -0
- data/spec/support/rails_app/config.ru +4 -0
- data/spec/support/rails_app/config/application.rb +42 -0
- data/spec/support/rails_app/config/boot.rb +10 -0
- data/spec/support/rails_app/config/database.yml +22 -0
- data/spec/support/rails_app/config/environment.rb +5 -0
- data/spec/support/rails_app/config/environments/development.rb +26 -0
- data/spec/support/rails_app/config/environments/production.rb +49 -0
- data/spec/support/rails_app/config/environments/test.rb +35 -0
- data/spec/support/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/support/rails_app/config/initializers/inflections.rb +10 -0
- data/spec/support/rails_app/config/initializers/mime_types.rb +5 -0
- data/spec/support/rails_app/config/initializers/secret_token.rb +7 -0
- data/spec/support/rails_app/config/initializers/session_store.rb +8 -0
- data/spec/support/rails_app/config/locales/en.yml +5 -0
- data/spec/support/rails_app/config/routes.rb +3 -0
- data/spec/support/rails_app/db/seeds.rb +7 -0
- data/spec/support/rails_app/doc/README_FOR_APP +2 -0
- data/spec/support/rails_app/lib/tasks/.gitkeep +0 -0
- data/spec/support/rails_app/public/404.html +26 -0
- data/spec/support/rails_app/public/422.html +26 -0
- data/spec/support/rails_app/public/500.html +26 -0
- data/spec/support/rails_app/public/favicon.ico +0 -0
- data/spec/support/rails_app/public/images/rails.png +0 -0
- data/spec/support/rails_app/public/index.html +239 -0
- data/spec/support/rails_app/public/javascripts/application.js +2 -0
- data/spec/support/rails_app/public/javascripts/controls.js +965 -0
- data/spec/support/rails_app/public/javascripts/dragdrop.js +974 -0
- data/spec/support/rails_app/public/javascripts/effects.js +1123 -0
- data/spec/support/rails_app/public/javascripts/prototype.js +6001 -0
- data/spec/support/rails_app/public/javascripts/rails.js +191 -0
- data/spec/support/rails_app/public/robots.txt +5 -0
- data/spec/support/rails_app/public/stylesheets/.gitkeep +0 -0
- data/spec/support/rails_app/script/rails +6 -0
- data/spec/support/rails_app/test/performance/browsing_test.rb +9 -0
- data/spec/support/rails_app/test/test_helper.rb +13 -0
- data/spec/support/rails_app/vendor/plugins/.gitkeep +0 -0
- data/todo.txt +25 -0
- metadata +315 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create ruby-1.9.2-p180@postmarkdown
|
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
|
8
|
+
require 'rake'
|
9
|
+
require 'rake/rdoctask'
|
10
|
+
|
11
|
+
require 'rspec/core'
|
12
|
+
require 'rspec/core/rake_task'
|
13
|
+
|
14
|
+
RSpec::Core::RakeTask.new(:spec)
|
15
|
+
|
16
|
+
task :default => :spec
|
17
|
+
|
18
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
19
|
+
rdoc.rdoc_dir = 'rdoc'
|
20
|
+
rdoc.title = 'ContactForm'
|
21
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
22
|
+
rdoc.rdoc_files.include('README.rdoc')
|
23
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class PostsController < ApplicationController
|
2
|
+
layout lambda { |controller| Postmarkdown::Config.options[:use_theme] ? 'postmarkdown' : 'application' }
|
3
|
+
|
4
|
+
def show
|
5
|
+
resource
|
6
|
+
end
|
7
|
+
|
8
|
+
def feed
|
9
|
+
max_age = 4.hours
|
10
|
+
response.headers['Cache-Control'] = 'public, max-age=' + max_age.to_i.to_s
|
11
|
+
response.headers['Expires'] = max_age.from_now.httpdate
|
12
|
+
response.content_type = 'application/atom+xml'
|
13
|
+
fresh_when :last_modified => Post.feed_last_modified
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def resource
|
19
|
+
@resource ||= Post.find(params[:id])
|
20
|
+
end
|
21
|
+
helper_method :resource
|
22
|
+
|
23
|
+
def collection
|
24
|
+
@collection ||= begin
|
25
|
+
posts = Post.where(params.slice(:year, :month, :day))
|
26
|
+
posts = Kaminari.paginate_array(posts).page(params[:page]).per(10)
|
27
|
+
posts
|
28
|
+
end
|
29
|
+
end
|
30
|
+
helper_method :collection
|
31
|
+
end
|
data/app/models/post.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
class Post
|
2
|
+
extend ActiveModel::Naming
|
3
|
+
|
4
|
+
include Gravtastic
|
5
|
+
is_gravtastic
|
6
|
+
|
7
|
+
attr_reader :slug
|
8
|
+
|
9
|
+
FILENAME_FORMAT = /^(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@path = path
|
13
|
+
@date_str, @slug = File.basename(path).match(FILENAME_FORMAT).captures
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_param
|
17
|
+
case permalink_format
|
18
|
+
when :day then "%04d/%02d/%02d/%s" % [year, month, day, slug]
|
19
|
+
when :month then "%04d/%02d/%s" % [year, month, slug]
|
20
|
+
when :year then "%04d/%s" % [year, slug]
|
21
|
+
when :slug then slug
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def permalink_format
|
26
|
+
Postmarkdown::Config.options[:permalink_format]
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_key
|
30
|
+
[slug]
|
31
|
+
end
|
32
|
+
|
33
|
+
def metadata
|
34
|
+
load_content
|
35
|
+
@metadata
|
36
|
+
end
|
37
|
+
|
38
|
+
def content
|
39
|
+
load_content
|
40
|
+
@content
|
41
|
+
end
|
42
|
+
|
43
|
+
def title
|
44
|
+
metadata[:title] || slug.titleize
|
45
|
+
end
|
46
|
+
|
47
|
+
def author
|
48
|
+
metadata[:author]
|
49
|
+
end
|
50
|
+
|
51
|
+
def email
|
52
|
+
metadata[:email]
|
53
|
+
end
|
54
|
+
|
55
|
+
def date
|
56
|
+
@date ||= Time.zone.parse(metadata[:date] || @date_str).to_date
|
57
|
+
end
|
58
|
+
|
59
|
+
delegate :year, :month, :day, :to => :date
|
60
|
+
|
61
|
+
def timestamp
|
62
|
+
date.to_time_in_current_zone
|
63
|
+
end
|
64
|
+
alias_method :last_modified, :timestamp
|
65
|
+
|
66
|
+
def visible?
|
67
|
+
timestamp <= Time.zone.now
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_s
|
71
|
+
"#{title.inspect} (#{slug})"
|
72
|
+
end
|
73
|
+
|
74
|
+
def content_html
|
75
|
+
RDiscount.new(content).to_html.html_safe
|
76
|
+
end
|
77
|
+
|
78
|
+
class Sanitizer < HTML::WhiteListSanitizer
|
79
|
+
self.allowed_tags -= %w(img a)
|
80
|
+
end
|
81
|
+
|
82
|
+
TagHelper = Class.new.extend ActionView::Helpers::TagHelper
|
83
|
+
|
84
|
+
def summary_html
|
85
|
+
if metadata[:summary].present?
|
86
|
+
TagHelper.content_tag :p, metadata[:summary]
|
87
|
+
else
|
88
|
+
html = Sanitizer.new.sanitize(content_html)
|
89
|
+
doc = Nokogiri::HTML.fragment(html)
|
90
|
+
para = doc.search('p').detect { |p| p.text.present? }
|
91
|
+
para.try(:to_html).try(:html_safe)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def all
|
97
|
+
file_extensions = Postmarkdown::Config.options[:markdown_file_extensions].join(',')
|
98
|
+
@@posts ||= Dir.glob(Rails.root + "app/posts/*.{#{file_extensions}}").map do |filename|
|
99
|
+
Post.new filename
|
100
|
+
end.select(&:visible?).sort_by(&:date).reverse
|
101
|
+
end
|
102
|
+
|
103
|
+
def where(conditions = {})
|
104
|
+
conditions = conditions.symbolize_keys
|
105
|
+
conditions.assert_valid_keys :year, :month, :day, :slug, :to_param
|
106
|
+
[:year, :month, :day].each do |key|
|
107
|
+
conditions[key] = conditions[key].to_i if conditions[key].present?
|
108
|
+
end
|
109
|
+
all.select do |post|
|
110
|
+
conditions.all? { |key, value| post.send(key) == value }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def find(id)
|
115
|
+
where(:to_param => id).first or raise ActiveRecord::RecordNotFound, "Could not find post with ID #{id.inspect}"
|
116
|
+
end
|
117
|
+
|
118
|
+
def first
|
119
|
+
all.first
|
120
|
+
end
|
121
|
+
|
122
|
+
def last
|
123
|
+
all.last
|
124
|
+
end
|
125
|
+
|
126
|
+
def feed
|
127
|
+
all.first(10)
|
128
|
+
end
|
129
|
+
|
130
|
+
def feed_last_modified
|
131
|
+
feed.first.try(:last_modified) || Time.now.utc
|
132
|
+
end
|
133
|
+
|
134
|
+
def reset!
|
135
|
+
@@posts = nil
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
protected
|
140
|
+
|
141
|
+
def load_content
|
142
|
+
@content = File.read(@path)
|
143
|
+
if @content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
144
|
+
@content = @content[($1.size + $2.size)..-1]
|
145
|
+
@metadata = YAML.load($1)
|
146
|
+
end
|
147
|
+
@metadata = (@metadata || {}).with_indifferent_access
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
!!! 5
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%title= Postmarkdown::Util.app_name
|
5
|
+
= stylesheet_link_tag 'postmarkdown/postmarkdown'
|
6
|
+
= yield :head
|
7
|
+
%body
|
8
|
+
%header#header
|
9
|
+
%h1= link_to Postmarkdown::Util.app_name, '/'
|
10
|
+
%p
|
11
|
+
A #{link_to 'postmarkdown', 'https://github.com/getencode/postmarkdown'} blog
|
12
|
+
- if Post.last.try(:author)
|
13
|
+
= "by #{Post.last.author}"
|
14
|
+
%section#content= yield
|
15
|
+
%footer
|
16
|
+
%small= "Copyright © #{Date.today.year}".html_safe
|
@@ -0,0 +1,15 @@
|
|
1
|
+
= content_tag_for :article, post do
|
2
|
+
%header
|
3
|
+
%h1= link_to post.title, post
|
4
|
+
= image_tag post.gravatar_url(:size => 32, :default => 'identicon'), :height => 32, :width => 32
|
5
|
+
.meta
|
6
|
+
%time{:pubdate => 'true', :datetime => post.timestamp.iso8601}
|
7
|
+
Posted on #{post.date.strftime '%e %B %Y'}
|
8
|
+
%span
|
9
|
+
by
|
10
|
+
= post.author
|
11
|
+
- if summary
|
12
|
+
= post.summary_html
|
13
|
+
%p.more= link_to 'Read more…'.html_safe, post
|
14
|
+
- else
|
15
|
+
~ post.content_html
|
@@ -0,0 +1,29 @@
|
|
1
|
+
xml.instruct!
|
2
|
+
xml.feed :xmlns => 'http://www.w3.org/2005/Atom' do
|
3
|
+
xml.title Postmarkdown::Config.options[:feed_title]
|
4
|
+
xml.link :href => posts_feed_url, :rel => :self, :type => 'application/atom+xml'
|
5
|
+
xml.link :href => posts_url, :rel => :alternate, :type => 'text/html'
|
6
|
+
xml.id posts_url
|
7
|
+
xml.updated Post.feed_last_modified.xmlschema
|
8
|
+
|
9
|
+
Post.feed.each do |post|
|
10
|
+
xml.entry do
|
11
|
+
xml.title post.title, :type => :text
|
12
|
+
xml.link :href => post_url(post), :rel => :alternate, :type => 'text/html'
|
13
|
+
xml.published post.timestamp.xmlschema
|
14
|
+
xml.updated post.last_modified.xmlschema
|
15
|
+
|
16
|
+
if post.author.present?
|
17
|
+
xml.author do
|
18
|
+
xml.name post.author
|
19
|
+
xml.email post.email if post.email.present?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
xml.id post_url(post)
|
24
|
+
xml.content :type => :html, 'xml:base' => post_url(post) do
|
25
|
+
xml.cdata! post.content_html
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Postmarkdown
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
3
|
+
desc File.read(File.expand_path('../usage/install.txt', __FILE__)).gsub('{{CURRENT_DATE}}', Time.zone.now.strftime('%Y-%m-%d'))
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
class_option :skip_example, :type => :boolean, :group => :runtime, :desc => 'Skip generating an example post'
|
6
|
+
|
7
|
+
def create_directory
|
8
|
+
empty_directory 'app/posts'
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_example_post
|
12
|
+
generate 'postmarkdown:post', 'example-post' unless options.skip_example?
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_routes
|
16
|
+
insert_into_file 'config/routes.rb', " postmarkdown :as => :posts\n\n", :after => "::Application.routes.draw do\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Postmarkdown
|
2
|
+
class OverrideGenerator < Rails::Generators::Base
|
3
|
+
desc File.read(File.expand_path('../usage/override.txt', __FILE__))
|
4
|
+
source_root File.expand_path('../../../../app', __FILE__)
|
5
|
+
|
6
|
+
class_option :all, :type => :boolean, :group => :override, :desc => 'Override all of the things'
|
7
|
+
class_option :views, :type => :boolean, :group => :override, :desc => 'Override the Post views'
|
8
|
+
class_option :model, :type => :boolean, :group => :override, :desc => 'Override the Post model'
|
9
|
+
class_option :controller, :type => :boolean, :group => :override, :desc => 'Override the Posts controller'
|
10
|
+
class_option :theme, :type => :boolean, :group => :override, :desc => 'Override the layout and stylesheet'
|
11
|
+
|
12
|
+
def check_class_options
|
13
|
+
if options.blank?
|
14
|
+
exec 'rails g postmarkdown:override --help'
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def override_views
|
20
|
+
if options.views || options.all
|
21
|
+
directory 'views/posts', 'app/views/posts'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def override_model
|
26
|
+
if options.model || options.all
|
27
|
+
copy_file 'models/post.rb', 'app/models/post.rb'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def override_controller
|
32
|
+
if options.controller || options.all
|
33
|
+
copy_file 'controllers/posts_controller.rb', 'app/controllers/posts_controller.rb'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def override_theme
|
38
|
+
if options.theme || options.all
|
39
|
+
directory 'views/layouts', 'views/layouts'
|
40
|
+
directory '../public/stylesheets', 'public/stylesheets'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Postmarkdown
|
2
|
+
class PostGenerator < Rails::Generators::Base
|
3
|
+
desc File.read(File.expand_path('../usage/post.txt', __FILE__)).gsub('{{CURRENT_DATE}}', Time.zone.now.strftime('%Y-%m-%d'))
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
5
|
+
argument :slug, :type => :string, :required => true
|
6
|
+
class_option :date, :type => :string, :group => :runtime, :desc => 'Publish date for the post'
|
7
|
+
|
8
|
+
def check_slug
|
9
|
+
unless slug =~ /^[A-Za-z0-9\-]+$/
|
10
|
+
puts 'Invalid slug - valid characters include letters, digits and dashes.'
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def check_date
|
16
|
+
if options.date && options.date !~ /^\d{4}-\d{2}-\d{2}$/
|
17
|
+
puts 'Invalid date - please use the following format: YYYY-MM-DD, eg. 2011-01-01.'
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate_post
|
23
|
+
template 'example-post.markdown', "app/posts/#{publish_date}-#{slug.downcase}.markdown"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def publish_date
|
29
|
+
date = options.date.present? ? Time.zone.parse(options.date) : Time.zone.now
|
30
|
+
date.strftime('%Y-%m-%d')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
title: <%= slug.underscore.humanize %>
|
3
|
+
<%- if author = Postmarkdown::Util.git_config('user.name') -%>
|
4
|
+
author: <%= author %>
|
5
|
+
<%- end -%>
|
6
|
+
<%- if email = Postmarkdown::Util.git_config('user.email') -%>
|
7
|
+
email: <%= email %>
|
8
|
+
<%- end -%>
|
9
|
+
---
|
10
|
+
|
11
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
12
|
+
|
13
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
14
|
+
|
15
|
+
# Markdown Formatting
|
16
|
+
|
17
|
+
[Reference](http://daringfireball.net/projects/markdown/syntax)
|
18
|
+
|
19
|
+
---
|
20
|
+
|
21
|
+
# Headers
|
22
|
+
|
23
|
+
## Header 2
|
24
|
+
|
25
|
+
### Header 3
|
26
|
+
|
27
|
+
---
|
28
|
+
|
29
|
+
# Emphasis
|
30
|
+
|
31
|
+
*italic* **bold**
|
32
|
+
_italic_ __bold__
|
33
|
+
|
34
|
+
---
|
35
|
+
|
36
|
+
# Links and Images
|
37
|
+
|
38
|
+
An [example](http://url.com/ "Title") Reference-style labels (titles are optional):
|
39
|
+
|
40
|
+
![Placeholder Kitten](http://placekitten.com/200/300)
|
41
|
+
|
42
|
+
---
|
43
|
+
|
44
|
+
# Lists
|
45
|
+
|
46
|
+
1. Foo
|
47
|
+
2. Bar
|
48
|
+
|
49
|
+
Unordered, with nesting:
|
50
|
+
|
51
|
+
* Abacus
|
52
|
+
* answer
|
53
|
+
* Bubbles
|
54
|
+
1. bunk
|
55
|
+
2. bupkis
|
56
|
+
* BELITTLER
|
57
|
+
3. burper
|
58
|
+
* Cunning
|
59
|
+
|
60
|
+
---
|
61
|
+
|
62
|
+
# Preformatted Code Blocks
|
63
|
+
|
64
|
+
Indent every line of a code block by at least 4 spaces or 1 tab.
|
65
|
+
|
66
|
+
This is a preformatted
|
67
|
+
code block.
|