nanoc-conref-fs 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,23 +1,87 @@
1
1
  require 'liquid'
2
2
 
3
- module Conrefifier
3
+ module NanocConrefFS
4
+ module Conrefifier
5
+ SINGLE_SUB = /(\{\{[^\}]+\}\})/m
6
+ BLOCK_SUB = /\{% (?:if|unless).+? %\}.*?\{% end(?:if|unless) %\}/m
7
+ PATH_TO_VARS = {}
4
8
 
5
- SINGLE_SUB = /(\{\{[^\}]+\}\})/m
6
- BLOCK_SUB = /\{% (?:if|unless).+? %\}.*?\{% end(?:if|unless) %\}/m
9
+ def self.file_variables(variables, path, rep)
10
+ return {} if variables.nil?
7
11
 
8
- def self.file_variables(variables, path)
9
- return {} if variables.nil?
12
+ data_vars = {}
10
13
 
11
- data_vars = {}
12
- scopes = variables.select { |v| v[:scope][:path].empty? || Regexp.new(v[:scope][:path]) =~ path }
13
- scopes.each do |scope|
14
- data_vars = data_vars.merge(scope[:values])
14
+ # this saves a bunch of time because we don't need to
15
+ # recalculate the paths (looping over scopes, etc)
16
+ if PATH_TO_VARS[rep] && PATH_TO_VARS[rep][path]
17
+ data_vars = PATH_TO_VARS[rep][path]
18
+ else
19
+ scopes = variables.select do |v|
20
+ scope_block = v[:scope]
21
+ scoped_path = scope_block[:path].empty? || Regexp.new(scope_block[:path]) =~ path
22
+ scoped_rep = scope_block[:reps].nil? || scope_block[:reps].include?(rep)
23
+ scoped_path && scoped_rep
24
+ end
25
+ # I benchmarked that assignment is much faster than
26
+ # merging an empty hash
27
+ if scopes.length == 1
28
+ data_vars = scopes.first[:values]
29
+ else
30
+ scopes.each do |scope|
31
+ data_vars = data_vars.merge(scope[:values])
32
+ end
33
+ end
34
+ # stash for later use
35
+ PATH_TO_VARS[rep] = {}
36
+ PATH_TO_VARS[rep][path] = data_vars
37
+ end
38
+
39
+ data_vars
15
40
  end
16
- data_vars
17
- end
18
41
 
19
- def self.apply_liquid(content, data_vars)
20
- data_vars['page'] = data_vars[:page].stringify_keys
21
- Liquid::Template.parse(content, :error_mode => :warn).render(data_vars)
42
+ def self.liquify(config, path:, content:, rep:)
43
+ page_vars = NanocConrefFS::Conrefifier.file_variables(config[:page_variables], path, rep)
44
+ page_vars = { :page => page_vars }.merge(NanocConrefFS::Variables.variables[rep])
45
+
46
+ # we must obfuscate essential ExtendedMarkdownFilter content
47
+ content = content.gsub(/\{\{\s*#(\S+)\s*\}\}/, '[[#\1]]')
48
+ content = content.gsub(/\{\{\s*\/(\S+)\s*\}\}/, '[[/\1]]')
49
+ content = content.gsub(/\{\{\s*(octicon-\S+\s*[^\}]+)\s*\}\}/, '[[\1]]')
50
+
51
+ begin
52
+ result = content
53
+
54
+ # This pass replaces any matched conditionals
55
+ if result =~ NanocConrefFS::Conrefifier::BLOCK_SUB || result =~ NanocConrefFS::Conrefifier::SINGLE_SUB
56
+ result = NanocConrefFS::Conrefifier.apply_liquid(result, page_vars)
57
+ end
58
+ rescue Liquid::SyntaxError => e
59
+ # unrecognized Liquid, so just return the content
60
+ STDERR.puts "Could not convert #{filename}: #{e.message}"
61
+ rescue => e
62
+ raise "#{e.message}: #{e.inspect}"
63
+ end
64
+
65
+ result = result.gsub(/\[\[\s*#(\S+)\s*\]\]/, '{{#\1}}')
66
+ result = result.gsub(/\[\[\s*\/(\S+)\s*\]\]/, '{{/\1}}')
67
+ result = result.gsub(/\[\[\s*(octicon-\S+\s*[^\]]+)\s*\]\]/, '{{\1}}')
68
+
69
+ result
70
+ end
71
+
72
+ def self.apply_liquid(content, data_vars)
73
+ data_vars['page'] = data_vars[:page].stringify_keys
74
+ result = Liquid::Template.parse(content, :error_mode => :warn).render(data_vars)
75
+ # This second pass renders any previously inserted
76
+ # data conditionals within the body. If a Liquid parse
77
+ # returns a blank string, we'll return the original
78
+ if result =~ NanocConrefFS::Conrefifier::SINGLE_SUB
79
+ result = result.gsub(NanocConrefFS::Conrefifier::SINGLE_SUB) do |match|
80
+ liquified = NanocConrefFS::Conrefifier.apply_liquid(match, data_vars)
81
+ liquified.empty? ? match : liquified
82
+ end
83
+ end
84
+ result
85
+ end
22
86
  end
23
87
  end
@@ -3,50 +3,67 @@ require 'active_support/core_ext/hash'
3
3
 
4
4
  require_relative 'conrefifier'
5
5
 
6
- module Datafiles
6
+ module NanocConrefFS
7
+ module Datafiles
8
+ def self.apply_conditionals(config, path:, content:, rep:)
9
+ vars = Conrefifier.file_variables(config[:data_variables], path, rep)
10
+ data_vars = { :page => vars, :site => { :config => config } }
7
11
 
8
- def self.apply_conditionals(config, path, content)
9
- data_vars = Conrefifier.file_variables(config[:data_variables], path)
10
- data_vars = { :page => data_vars, :site => { :config => config } }
12
+ content = obfuscate_liquid(content, data_vars)
13
+ begin
14
+ doc = YAML.load(content)
15
+ rescue Psych::SyntaxError => e
16
+ STDERR.puts "Could not convert \n#{content}"
17
+ raise "#{e.message}: #{e.inspect}"
18
+ end
19
+
20
+ path = path.dup
21
+ path.slice!('data/')
22
+ path.sub!(/\.[yaml]{3,4}\z/, '')
23
+ data_keys = path.split('/')
11
24
 
12
- content = content.gsub(Conrefifier::BLOCK_SUB) do |match|
13
- # We must obfuscate Liquid variables while replacing conditionals
14
- match = match.gsub(/{{/, '~~#~~')
15
- match = Conrefifier.apply_liquid(match, data_vars)
16
- match.gsub('~~#~~', '{{')
25
+ # we don't need to create a nested hash for root-level data files
26
+ if data_keys.length == 1
27
+ { data_keys.first => doc }
28
+ else
29
+ create_nested_hash(data_keys, doc)
30
+ end
17
31
  end
18
32
 
19
- doc = YAML.load(content)
20
- data_keys = "#{path}".gsub(%r{^data/}, '').gsub(%r{/}, '.').gsub(/\.yml/, '').split('.')
21
- # we don't need to create a nested hash for root-level data files
22
- if data_keys.length == 1
23
- { data_keys.first => doc }
24
- else
25
- create_nested_hash(data_keys, doc)
33
+ def self.create_nested_hash(keys, final)
34
+ keys.reverse.inject do |mem, var|
35
+ if mem == keys.last
36
+ { var => { mem => final } }
37
+ else
38
+ { var => mem }
39
+ end
40
+ end
26
41
  end
27
- end
28
42
 
29
- def self.create_nested_hash(keys, final)
30
- keys.reverse.inject do |mem, var|
31
- if mem == keys.last
32
- { var => { mem => final } }
33
- else
34
- { var => mem }
43
+ def self.collect_data(dir)
44
+ data_files = {}
45
+ Dir["#{dir}/**/*.{yaml,yml}"].each do |filename|
46
+ data_files[filename] = File.read(filename)
35
47
  end
48
+ data_files
36
49
  end
37
- end
38
50
 
39
- def self.collect_data(dir)
40
- Dir["#{dir}/**/*.{yaml,yml}"]
41
- end
51
+ def self.process(data_files, config, rep)
52
+ data = {}
53
+ data_files.each_pair do |filename, content|
54
+ conditionals = apply_conditionals(config, path: filename, content: content, rep: rep)
55
+ data = data.deep_merge(conditionals)
56
+ end
57
+ data
58
+ end
42
59
 
43
- def self.process(config)
44
- data = {}
45
- files = collect_data('data')
46
- files.each do |file|
47
- content = File.read(file)
48
- data = data.deep_merge apply_conditionals(config, file, content)
60
+ def self.obfuscate_liquid(content, data_vars)
61
+ content.gsub(Conrefifier::BLOCK_SUB) do |match|
62
+ # We must obfuscate Liquid variables while replacing conditionals
63
+ match = match.gsub(/{{/, '~~#~~')
64
+ match = Conrefifier.apply_liquid(match, data_vars)
65
+ match.gsub('~~#~~', '{{')
66
+ end
49
67
  end
50
- data
51
68
  end
52
69
  end
@@ -0,0 +1,30 @@
1
+ module NanocConrefFS
2
+ # Unsure why attr_accessor does not work here
3
+ module Variables
4
+ def self.variables
5
+ @variables
6
+ end
7
+
8
+ def self.variables=(variables)
9
+ @variables = variables
10
+ end
11
+
12
+ def self.data_files
13
+ @data_files
14
+ end
15
+
16
+ def self.data_files=(data_files)
17
+ @data_files = data_files
18
+ end
19
+
20
+ def self.fetch_data_file(association, rep)
21
+ return nil unless association
22
+ reference = association.split('.')
23
+ data = @variables[rep]['site']['data']
24
+ while key = reference.shift
25
+ data = data[key]
26
+ end
27
+ data
28
+ end
29
+ end
30
+ end
@@ -1,3 +1,11 @@
1
- require 'nanoc-conref-fs/conref-fs'
1
+ begin
2
+ require 'awesome_print'
3
+ rescue LoadError
4
+ end
5
+
6
+ require 'nanoc-conref-fs/ancestry'
2
7
  require 'nanoc-conref-fs/conrefifier'
3
8
  require 'nanoc-conref-fs/datafiles'
9
+ require 'nanoc-conref-fs/variables'
10
+ require 'nanoc-conref-fs/conref-fs'
11
+ require 'nanoc-conref-fs/conref-filter'
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = 'nanoc-conref-fs'
6
- spec.version = '0.5.0'
6
+ spec.version = '0.6.0'
7
7
  spec.authors = ['Garen Torikian']
8
8
  spec.email = ['gjtorikian@gmail.com']
9
9
  spec.summary = 'A Nanoc filesystem to permit using conrefs/reusables in your content.'
@@ -0,0 +1,79 @@
1
+ require 'test_helper'
2
+
3
+ class AncestryTest < MiniTest::Test
4
+ def test_it_renders_single_parents
5
+ with_site(name: FIXTURES_DIR) do |site|
6
+
7
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
8
+ site.compile
9
+
10
+ output_file = read_output_file('parents', 'single_parent')
11
+ test_file = read_test_file('parents', 'single_parent')
12
+ assert_equal output_file, test_file
13
+ end
14
+ end
15
+
16
+ def test_it_renders_two_parents
17
+ with_site(name: FIXTURES_DIR) do |site|
18
+
19
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
20
+ site.compile
21
+
22
+ output_file = read_output_file('parents', 'two_parents')
23
+ test_file = read_test_file('parents', 'two_parents')
24
+ assert_equal output_file, test_file
25
+ end
26
+ end
27
+
28
+ def test_it_renders_array_parents
29
+ with_site(name: FIXTURES_DIR) do |site|
30
+
31
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
32
+ site.compile
33
+
34
+ output_file = read_output_file('parents', 'array_parents')
35
+ test_file = read_test_file('parents', 'array_parents')
36
+ assert_equal output_file, test_file
37
+ end
38
+ end
39
+
40
+ def test_missing_category_title_does_not_blow_up_parents
41
+ with_site(name: FIXTURES_DIR) do |site|
42
+
43
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
44
+ site.compile
45
+
46
+ output_file = read_output_file('parents', 'missing_title')
47
+ test_file = read_test_file('parents', 'missing_title')
48
+ assert_equal output_file, test_file
49
+ end
50
+ end
51
+
52
+ def test_it_renders_hash_children
53
+ with_site(name: FIXTURES_DIR) do |site|
54
+
55
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
56
+ site.compile
57
+
58
+ output_file = read_output_file('children', 'hash_children')
59
+ test_file = read_test_file('children', 'hash_children')
60
+ assert_equal output_file, test_file
61
+
62
+ output_file = read_output_file('children', 'later_hash_children')
63
+ test_file = read_test_file('children', 'later_hash_children')
64
+ assert_equal output_file, test_file
65
+ end
66
+ end
67
+
68
+ def test_it_renders_array_children
69
+ with_site(name: FIXTURES_DIR) do |site|
70
+
71
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
72
+ site.compile
73
+
74
+ output_file = read_output_file('children', 'array_children')
75
+ test_file = read_test_file('children', 'array_children')
76
+ assert_equal output_file, test_file
77
+ end
78
+ end
79
+ end
@@ -62,54 +62,6 @@ class DatafilesTest < MiniTest::Test
62
62
  end
63
63
  end
64
64
 
65
- def test_it_renders_single_parents
66
- with_site(name: FIXTURES_DIR) do |site|
67
-
68
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
69
- site.compile
70
-
71
- output_file = read_output_file('parents', 'single_parent')
72
- test_file = read_test_file('parents', 'single_parent')
73
- assert_equal output_file, test_file
74
- end
75
- end
76
-
77
- def test_it_renders_two_parents
78
- with_site(name: FIXTURES_DIR) do |site|
79
-
80
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
81
- site.compile
82
-
83
- output_file = read_output_file('parents', 'two_parents')
84
- test_file = read_test_file('parents', 'two_parents')
85
- assert_equal output_file, test_file
86
- end
87
- end
88
-
89
- def test_it_renders_array_parents
90
- with_site(name: FIXTURES_DIR) do |site|
91
-
92
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
93
- site.compile
94
-
95
- output_file = read_output_file('parents', 'array_parents')
96
- test_file = read_test_file('parents', 'array_parents')
97
- assert_equal output_file, test_file
98
- end
99
- end
100
-
101
- def test_missing_category_title_does_not_blow_up_parents
102
- with_site(name: FIXTURES_DIR) do |site|
103
-
104
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
105
- site.compile
106
-
107
- output_file = read_output_file('parents', 'missing_title')
108
- test_file = read_test_file('parents', 'missing_title')
109
- assert_equal output_file, test_file
110
- end
111
- end
112
-
113
65
  def test_it_applies_any_attribute
114
66
  with_site(name: FIXTURES_DIR) do |site|
115
67
 
@@ -122,7 +74,7 @@ class DatafilesTest < MiniTest::Test
122
74
  end
123
75
  end
124
76
 
125
- def test_it_obfuscates_content
77
+ def test_it_does_not_obfuscate_content
126
78
  with_site(name: FIXTURES_DIR) do |site|
127
79
 
128
80
  site = Nanoc::Int::SiteLoader.new.new_from_cwd
@@ -149,34 +101,6 @@ class DatafilesTest < MiniTest::Test
149
101
  end
150
102
  end
151
103
 
152
- def test_it_renders_hash_children
153
- with_site(name: FIXTURES_DIR) do |site|
154
-
155
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
156
- site.compile
157
-
158
- output_file = read_output_file('children', 'hash_children')
159
- test_file = read_test_file('children', 'hash_children')
160
- assert_equal output_file, test_file
161
-
162
- output_file = read_output_file('children', 'later_hash_children')
163
- test_file = read_test_file('children', 'later_hash_children')
164
- assert_equal output_file, test_file
165
- end
166
- end
167
-
168
- def test_it_renders_array_children
169
- with_site(name: FIXTURES_DIR) do |site|
170
-
171
- site = Nanoc::Int::SiteLoader.new.new_from_cwd
172
- site.compile
173
-
174
- output_file = read_output_file('children', 'array_children')
175
- test_file = read_test_file('children', 'array_children')
176
- assert_equal output_file, test_file
177
- end
178
- end
179
-
180
104
  def test_it_ignores_unknown_tags
181
105
  with_site(name: FIXTURES_DIR) do |site|
182
106
 
@@ -238,4 +162,18 @@ class DatafilesTest < MiniTest::Test
238
162
  assert_equal output_file, test_file
239
163
  end
240
164
  end
165
+
166
+ def test_multiple_outputs
167
+ with_site(name: FIXTURES_DIR) do |site|
168
+
169
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
170
+ site.compile
171
+
172
+ single_var_github = read_output_file('multiple', 'single_var')
173
+ assert_match(/Welcome to GitHub/, single_var_github)
174
+
175
+ single_var_x = read_output_file('multiple', 'single_var_x')
176
+ assert_match(/Welcome to GitHub X/, single_var_x)
177
+ end
178
+ end
241
179
  end
@@ -1,12 +1,8 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class DatafilesTest < MiniTest::Test
4
- def setup
5
- @config = YAML.load_file(File.join(FIXTURES_DIR, 'nanoc.yaml')).deep_symbolize_keys
6
- end
7
-
8
4
  def test_it_collects_the_files
9
- files = Datafiles.collect_data(File.join(FIXTURES_DIR, 'data')).sort
5
+ files = NanocConrefFS::Datafiles.collect_data(File.join(FIXTURES_DIR, 'data')).keys.sort
10
6
  names = %w(categories/category categories/simple reusables/intro reusables/names variables/asterisks variables/empty variables/product)
11
7
  names.map! { |name| File.join(FIXTURES_DIR, 'data', "#{name}.yml") }
12
8
  assert_equal files, names
@@ -15,7 +11,7 @@ class DatafilesTest < MiniTest::Test
15
11
  def test_it_creates_nested_hash
16
12
  string = %w(this is deep)
17
13
  value = 42
18
- hash = Datafiles.create_nested_hash(string, value)
14
+ hash = NanocConrefFS::Datafiles.create_nested_hash(string, value)
19
15
  value = { 'this' => { 'is' => { 'deep' => 42 } } }
20
16
  assert_equal value, hash
21
17
  end
@@ -23,18 +19,18 @@ class DatafilesTest < MiniTest::Test
23
19
  def test_it_applies_conref_conditionals
24
20
  file = File.join(FIXTURES_DIR, 'data', 'variables', 'product.yml')
25
21
  content = File.read(file)
26
- result = Datafiles.apply_conditionals(@config, file, content)
22
+ result = NanocConrefFS::Datafiles.apply_conditionals(CONFIG, path: file, content: content, rep: :default)
27
23
  assert_includes result.to_s, 'No caveats!'
28
24
 
29
- @config[:data_variables][0][:values][:version] = 'foof'
30
- result = Datafiles.apply_conditionals(@config, file, content)
25
+ CONFIG[:data_variables][0][:values][:version] = 'foof'
26
+ result = NanocConrefFS::Datafiles.apply_conditionals(CONFIG, path: file, content: content, rep: :default)
31
27
  assert_includes result.to_s, 'Well.....there is one.'
32
28
  end
33
29
 
34
30
  def test_it_leaves_liquid_substitutions_alone
35
31
  file = File.join(FIXTURES_DIR, 'data', 'reusables', 'intro.yml')
36
32
  content = File.read(file)
37
- result = Datafiles.apply_conditionals(@config, file, content)
33
+ result = NanocConrefFS::Datafiles.apply_conditionals(CONFIG, path: file, content: content, rep: :default)
38
34
  assert_includes result.to_s, 'We use {{ site.data.reusables.names.new_name }}'
39
35
  assert_includes result.to_s, '{{ site.data.variables.product.product_name }} is great'
40
36
  end
data/test/fixtures/Rules CHANGED
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- compile '/**/*.html' do
4
- layout '/default.*'
3
+ preprocess do
5
4
  end
6
5
 
6
+ ignore '/**/*.html'
7
+
7
8
  compile '/**/*.md' do
9
+ filter :'conref-fs-filter'
8
10
  if item[:filename] =~ /retrieve/
9
11
  layout '/retrieve.*'
10
12
  elsif item[:filename] =~ /_children/
@@ -16,10 +18,20 @@ compile '/**/*.md' do
16
18
  end
17
19
  end
18
20
 
21
+ compile '/multiple/single_var.md', :rep => :X do
22
+ filter :'conref-fs-filter'
23
+ filter :erb
24
+ layout '/default.*'
25
+ end
26
+
19
27
  route '/**/*.md' do
20
28
  item.identifier.without_ext + '/index.html'
21
29
  end
22
30
 
31
+ route '/multiple/single_var.md', :rep => :X do
32
+ item.identifier.without_ext + '_x/index.html'
33
+ end
34
+
23
35
  route '/**/*' do
24
36
  item.identifier.to_s
25
37
  end
@@ -7,7 +7,7 @@
7
7
  </head>
8
8
 
9
9
  <body>
10
- <strong>Two-factor authentication</strong>, or 2FA, is a way of logging into websites that requires more than just a password. Using a password to log into a website is susceptible to security threats, because it represents a _single_ piece of information a malicious person needs to acquire. The added security that 2FA provides is requiring _additional information_ to sign in.
10
+ **Two-factor authentication**, or 2FA, is a way of logging into websites that requires more than just a password. Using a password to log into a website is susceptible to security threats, because it represents a _single_ piece of information a malicious person needs to acquire. The added security that 2FA provides is requiring _additional information_ to sign in.
11
11
 
12
12
  *Ta-da!*
13
13
 
@@ -7,7 +7,7 @@
7
7
  </head>
8
8
 
9
9
  <body>
10
- <em>Two-factor authentication</em>, or 2FA, is a way of logging into websites that requires more than just a password. Using a password to log into a website is susceptible to security threats, because it represents a _single_ piece of information a malicious person needs to acquire. The added security that 2FA provides is requiring _additional information_ to sign in.
10
+ *Two-factor authentication*, or 2FA, is a way of logging into websites that requires more than just a password. Using a password to log into a website is susceptible to security threats, because it represents a _single_ piece of information a malicious person needs to acquire. The added security that 2FA provides is requiring _additional information_ to sign in.
11
11
 
12
12
  *Ta-da!*
13
13
 
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>
5
+ Single var
6
+ </title>
7
+ </head>
8
+
9
+ <body>
10
+
11
+ Welcome to GitHub.
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Single var
3
+ ---
4
+
5
+ Welcome to {{ site.data.variables.product.multi_name }}.
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>
5
+ Single var
6
+ </title>
7
+ </head>
8
+
9
+ <body>
10
+
11
+ Welcome to GitHub X.
12
+
13
+ </body>
14
+ </html>
@@ -8,33 +8,33 @@
8
8
 
9
9
  <body>
10
10
 
11
- [[#tip]]
11
+ {{#tip}}
12
12
 
13
13
  Here's a hot tip: **line one**
14
14
  Here's a hot tip: line two
15
15
 
16
- [[/tip]]
16
+ {{/tip}}
17
17
 
18
- [[#note]]
18
+ {{#note}}
19
19
 
20
20
  This is something you should know! line one
21
21
  This is something you should know! line two
22
22
 
23
- [[/note]]
23
+ {{/note}}
24
24
 
25
- [[#warning]]
25
+ {{#warning}}
26
26
 
27
27
  Yo, check this out: line one
28
28
  Yo, check this out: line two
29
29
 
30
- [[/warning]]
30
+ {{/warning}}
31
31
 
32
- [[#danger]]
32
+ {{#danger}}
33
33
 
34
34
  Sheeeeit, this is a problem: ~~line one~~
35
35
  Sheeeeit, this is a problem: line two
36
36
 
37
- [[/danger]]
37
+ {{/danger}}
38
38
 
39
39
  </body>
40
40
  </html>
@@ -8,9 +8,9 @@
8
8
 
9
9
  <body>
10
10
 
11
- [[octicon-cat This is a cat]]
11
+ {{octicon-cat This is a cat}}
12
12
 
13
- [Click [[octicon-gear Settings ]]](http://alink.com)
13
+ [Click {{octicon-gear Settings }}](http://alink.com)
14
14
 
15
15
  </body>
16
16
  </html>
@@ -2,6 +2,15 @@ product_name:
2
2
  dotcom: 'GitHub'
3
3
  '2.0': 'GitHub Enterprise'
4
4
 
5
+ multi_name:
6
+ {% if page.version == 'dotcom' %}
7
+ 'GitHub'
8
+ {% elsif page.version == 'X' %}
9
+ 'GitHub X'
10
+ {% else %}
11
+ 'GitHub Enterprise'
12
+ {% endif %}
13
+
5
14
  caveat: |
6
15
  {% if page.version == 'dotcom' %}
7
16