schizm 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,398 @@
1
+ require_relative 'chunk'
2
+ require_relative 'match'
3
+ require_relative 'markup'
4
+ require_relative 'string'
5
+ require 'strscan'
6
+ require 'uri'
7
+
8
+ module Schizm
9
+
10
+ module Parse
11
+
12
+ CPP_HIGHLIGHT = [
13
+ ["hi-comment", /\/\/.*$/u],
14
+ ["hi-comment", /\/\*.*?\*\//um],
15
+ ["hi-preproc", /\#(?:ifn?def|endif|if|else|elif|define|pragma|include)\b.*?(?<=[^\\])(?:\n|\z)/um],
16
+ ["hi-type", /(?:auto|bool|char|short|long|int|(?:un)?signed|float|double|void)\b/u],
17
+ ["hi-type", /(?:size|ptrdiff|char(?:16|32)|wchar|u?int(?:_least|_fast)?(?:8|16|32|64))_t\b/u],
18
+ ["hi-type-spec", /(?:constexpr|const|volatile|static|mutable|thread_local|register|extern|inline|noexcept)\b/u],
19
+ ["hi-flow", /(?:new|delete|do|while|for|if|else|try|throw|catch|switch|case|default|break|continue|goto|return)\b/u],
20
+ ["hi-op", /(?:(?:and|or|xor|not)(?:_eq)?|bitand|bitor|compl|(?:(?:const|dynamic|static|reinterpret)_cast))\b/u],
21
+ ["hi-value", /(?:true|false|this|nullptr|NULL)\b/u],
22
+ ["hi-value", /'[^'\\]*(?:\\.[^'\\]*)*'/u], # Single quote
23
+ ["hi-value", /"[^"\\]*(?:\\.[^"\\]*)*"/u], # Double quote
24
+ ["hi-other", /(?:alignas|alignof|sizeof|decltype|template|typename|typedef|using|concept|requires|operator)\b/u],
25
+ ["hi-other", /(?:namespace|class|struct|enum|public|protected|private|friend|final|virtual|override)\b/u],
26
+ ["hi-ident", /\p{Word}+/u],
27
+ [nil, /[^\p{Word}\p{Space}]+/um]
28
+ ]
29
+
30
+ # Markup hash.
31
+ @@hash =
32
+ Hash.new do |hash, where|
33
+ hash[where] = Markup.new
34
+ end
35
+
36
+ # Markup hash accessor.
37
+ def self.hash
38
+ return @@hash
39
+ end
40
+
41
+ # Link hash.
42
+ @@links =
43
+ Hash.new do |hash, where|
44
+ hash[where] =
45
+ Hash.new do |hash, entry|
46
+ hash[entry] = Hash.new
47
+ end
48
+ end
49
+
50
+ # Link hash accessor.
51
+ def self.links
52
+ return @@links
53
+ end
54
+
55
+ # Hash attribute reference.
56
+ class HashAttr
57
+ def initialize hash, attr
58
+ @hash = hash
59
+ @attr = attr
60
+ end
61
+ def to_s
62
+ return @hash[@attr].to_s
63
+ end
64
+ end
65
+
66
+ class ChunkRef
67
+ def initialize where, label
68
+ @where = where
69
+ @label = label
70
+ end
71
+ def to_s
72
+ Chunk.each do |chunk|
73
+ if chunk.label == @label and
74
+ (chunk.where == @where or chunk.share?)
75
+ return Env.path_href(@where) + '#' + chunk.id(1)
76
+ end
77
+ end
78
+ return ""
79
+ end
80
+ end
81
+
82
+ class BlockRef
83
+ def initialize chunk, index
84
+ @chunk = chunk
85
+ @index = index
86
+ end
87
+ def to_s
88
+ return "" if @index < 1
89
+ return "" if @index > @chunk.blocks.size
90
+ Env.path_href(@chunk.where) + '#' + @chunk.id(@index)
91
+ end
92
+ end
93
+
94
+ def self.line_elems where, input
95
+ elems = Markup.new
96
+ sscan = StringScanner.new input.strip
97
+ until sscan.eos?
98
+ elems.add_elems(
99
+ case
100
+ when (sscan.skip SPACE) then " "
101
+ when (sscan.skip HTML_ENTITY) then sscan[0]
102
+ when (sscan.skip HTML_ESCAPE) then sscan[0].codepoints[0]
103
+ when (sscan.skip CHAR_ESCAPE) then sscan[0].codepoints[0]
104
+ when (sscan.skip LINK_REF)
105
+ shown = String.new(sscan[1]).unescape(']')
106
+ param = String.new(sscan[2]).unescape(')')
107
+ param = LINK_PARAMS.match(param)
108
+ if (param[2] =~ URI::regexp)
109
+ attrs = {"href" => param[2],
110
+ "title" => param[1]}
111
+ else
112
+ entry = param[2]
113
+ attrs = {"href" => HashAttr.new(@@links[where][entry], "href"),
114
+ "title" => HashAttr.new(@@links[where][entry], "title")}
115
+ end
116
+ attrs["target"] = "_blank"
117
+ Markup.new("a")
118
+ .add_attrs(attrs)
119
+ .add_elems(line_elems(where, shown))
120
+ when (sscan.skip CENTER_MATH)
121
+ Markup.new("script")
122
+ .add_attrs(CENTER_MATH_ATTRS)
123
+ .add_elems(String.new(sscan[1]).slim)
124
+ when (sscan.skip INLINE_MATH)
125
+ Markup.new("script")
126
+ .add_attrs(INLINE_MATH_ATTRS)
127
+ .add_elems(String.new(sscan[1]).slim)
128
+ when (sscan.skip INLINE_EMPH)
129
+ depth = sscan[1].size
130
+ inner = line_elems(where, sscan[2])
131
+ case
132
+ when depth <= 1
133
+ Markup.new("em").add_elems(inner)
134
+ when depth == 2
135
+ Markup.new("strong").add_elems(inner)
136
+ when depth >= 3
137
+ Markup.new("strong").add_elems(Markup.new("em").add_elems(inner))
138
+ end
139
+ when sscan.skip(INLINE_CODE)
140
+ Markup.new("code")
141
+ .add_elems(String.new(sscan[1]).unescape("`").html)
142
+ when sscan.skip(INLINE_SUP)
143
+ Markup.new("sup").add_elems(line_elems(where, sscan[1]))
144
+ when sscan.skip(INLINE_SUB)
145
+ Markup.new("sub").add_elems(line_elems(where, sscan[1]))
146
+ when (sscan.skip INLINE_INS)
147
+ Markup.new("ins").add_elems(line_elems(where, sscan[1]))
148
+ when (sscan.skip INLINE_DEL)
149
+ Markup.new("del").add_elems(line_elems(where, sscan[1]))
150
+ when sscan.skip(/\w+|\S/)
151
+ sscan[0]
152
+ end)
153
+ end
154
+ return elems
155
+ end
156
+
157
+ def self.page_elems where, input
158
+ elems = Markup.new
159
+ sscan = StringScanner.new(
160
+ String.new(input)
161
+ .expand_tab(4).trim_blank
162
+ .concat("\n"))
163
+ until sscan.eos?
164
+ elems.add_elems(
165
+ case
166
+ when (sscan.skip EMPTY_LINE) then nil
167
+ when (sscan.skip EOB_MARKER) then nil
168
+ when (sscan.skip HRULE)
169
+ Markup.new "hr"
170
+ when (sscan.skip HEADING_ATX)
171
+ type = String.new sscan[1]
172
+ text = String.new sscan[2]
173
+ slug = text.slugify
174
+ Markup.new(
175
+ case type.size
176
+ when 1 then "h1"
177
+ when 2 then "h2"
178
+ when 3 then "h3"
179
+ when 4 then "h4"
180
+ when 5 then "h5"
181
+ when 6 then "h6"
182
+ end).add_attrs("id" => slug)
183
+ .add_elems(line_elems(where, text))
184
+ when (sscan.skip HEADING_SETEXT)
185
+ type = String.new sscan[2]
186
+ text = String.new sscan[1]
187
+ slug = text.slugify
188
+ Markup.new(
189
+ case type[0]
190
+ when "=" then "h1"
191
+ when "-" then "h2"
192
+ end).add_attrs("id" => slug)
193
+ .add_attrs("class" => "title")
194
+ .add_elems(line_elems(where, text))
195
+ when (sscan.skip LINK_DEF)
196
+ entry = String.new(sscan[1]).unescape(")")
197
+ param = String.new(sscan[2])#.unescape("]")
198
+ match = LINK_PARAMS.match param
199
+ @@links[where][entry]["href"] = match[2]
200
+ @@links[where][entry]["title"] = match[1]
201
+ nil
202
+ when (sscan.skip /^#{CHUNK_LABEL}/u)
203
+ div = nil
204
+ chunk = Chunk.hash[where][String.new(sscan[1]).unescape("]")]
205
+ case
206
+ when (sscan.skip /[ ]*->[ ]*(.*?)\n/u)
207
+ chunk.target = sscan[1].strip
208
+ when (sscan.skip /[ ]*::[ ]*(.*?)\n/u)
209
+ case sscan[1].strip
210
+ when "Share" then chunk.share = true
211
+ when "Local" then chunk.share = false
212
+ else raise "Unknown attribute."
213
+ end
214
+ when (sscan.skip /[ ]*\#=[ ]*(.*?)\n/u)
215
+ sscan[1].split(' ').each_with_index do |param, index|
216
+ chunk.params[param][:index] = index
217
+ end
218
+ when (sscan.skip /[ ]*\+=[ ]*(?:#{CHUNK_BLOCK})?\n/u)
219
+ label = sscan[1]
220
+ block = sscan.scan_until(END_INDENT)
221
+ block = String.new(block).erase(INDENT).trim
222
+ label = String.new(label).unescape(")") if label
223
+ chunk.push block, label
224
+ div =
225
+ Markup.new("div")
226
+ .add_attrs("id" => chunk.id)
227
+ .add_attrs("class" => "panel")
228
+ .add_elems([
229
+ Markup.new("div")
230
+ .add_attrs("class" => "panel-head")
231
+ .add_elems([
232
+ Markup.new("div")
233
+ .add_attrs("style" => "float: left; width: 75%;")
234
+ .add_elems([
235
+ Markup.new("div")
236
+ .add_attrs("class" => "the-chunk")
237
+ .add_elems(line_elems(where, chunk.label)),
238
+ case
239
+ when label
240
+ Markup.new("div")
241
+ .add_attrs("class" => "the-block")
242
+ .add_elems(line_elems(where, label))
243
+ else nil
244
+ end
245
+ ]),
246
+ Markup.new("div")
247
+ .add_attrs("style" => "float: right;")
248
+ .add_elems([
249
+ Markup.new("a").add_attrs("class" => "panel-link", "href" => BlockRef.new(chunk, chunk.blocks.size - 1)).add_elems(Markup.new("span").add_attrs("class" => "genericons-neue genericons-neue-previous")),
250
+ Markup.new("a").add_attrs("class" => "panel-link", "href" => BlockRef.new(chunk, chunk.blocks.size + 1)).add_elems(Markup.new("span").add_attrs("class" => "genericons-neue genericons-neue-next")),
251
+ ]),
252
+ Markup.new("div").add_attrs("style" => "clear: both;")
253
+ ]),
254
+ Markup.new("div")
255
+ .add_attrs("class" => "panel-body")
256
+ .add_elems(Markup.new("pre").add_elems(highlight(where, block, CPP_HIGHLIGHT)))
257
+ ])
258
+ end
259
+ div
260
+ when (sscan.skip ENTER_ASIDE)
261
+ text = sscan.scan_until END_INDENT
262
+ text = String.new(text).erase INDENT
263
+ Markup.new("div")
264
+ .add_attrs("class" => "aside")
265
+ .add_elems([
266
+ Markup.new("div")
267
+ .add_attrs("class" => "icon-holder")
268
+ .add_elems(
269
+ Markup.new("span")
270
+ .add_attrs("class" => "genericons-neue genericons-neue-info")),
271
+ page_elems(where, text)
272
+ ])
273
+ when (sscan.skip ENTER_ALERT)
274
+ text = sscan.scan_until END_INDENT
275
+ text = String.new(text).erase INDENT
276
+ Markup.new("div")
277
+ .add_attrs("class" => "alert")
278
+ .add_elems([
279
+ Markup.new("div")
280
+ .add_attrs("class" => "icon-holder")
281
+ .add_elems(
282
+ Markup.new("span")
283
+ .add_attrs("class" => "genericons-neue genericons-neue-notice")),
284
+ page_elems(where, text)
285
+ ])
286
+ when (sscan.skip ENTER_BUG)
287
+ text = sscan.scan_until END_INDENT
288
+ text = String.new(text).erase INDENT
289
+ Markup.new("div")
290
+ .add_attrs("class" => "alert")
291
+ .add_elems([
292
+ Markup.new("div")
293
+ .add_attrs("class" => "icon-holder")
294
+ .add_elems(
295
+ Markup.new("span")
296
+ .add_attrs("class" => "genericons-neue genericons-neue-bug")),
297
+ page_elems(where, text)
298
+ ])
299
+ when (sscan.skip ENTER_QUOTE)
300
+ text = sscan.scan_until END_INDENT
301
+ text = String.new(text).erase INDENT
302
+ Markup.new("blockquote")
303
+ .add_elems(page_elems(where, text))
304
+ when (sscan.match? ENTER_OLIST)
305
+ list = Markup.new "ol"
306
+ while sscan.skip ENTER_OLIST
307
+ text = sscan.scan_until END_INDENT
308
+ text = String.new(text).erase INDENT
309
+ item = Markup.new "li"
310
+ item.add_elems page_elems(where, text)
311
+ list.add_elems item
312
+ sscan.skip EMPTY_LINES
313
+ end
314
+ list
315
+ when (sscan.match? ENTER_ULIST)
316
+ list = Markup.new "ul"
317
+ while sscan.skip ENTER_ULIST
318
+ text = sscan.scan_until END_INDENT
319
+ text = String.new(text).erase INDENT
320
+ item = Markup.new "li"
321
+ item.add_elems page_elems(where, text)
322
+ list.add_elems item
323
+ sscan.skip EMPTY_LINES
324
+ end
325
+ list
326
+ when (sscan.match? ENTER_TLIST)
327
+ list = Markup.new "ul"
328
+ list.add_attrs("class" => "tl")
329
+ while sscan.skip ENTER_TLIST
330
+ type = sscan[1]
331
+ text = sscan.scan_until END_INDENT
332
+ text = String.new(text).erase INDENT
333
+ item = Markup.new "li"
334
+ item.add_attrs("class" =>
335
+ case
336
+ when (type[0] == " ") then "li-todo"
337
+ when (type[0] != " ") then "li-done"
338
+ end)
339
+ item.add_elems page_elems(where, text)
340
+ list.add_elems item
341
+ sscan.skip EMPTY_LINES
342
+ end
343
+ list
344
+ when sscan.match?(ENTER_CODE)
345
+ text = sscan.scan_until END_INDENT
346
+ text = String.new(text).erase INDENT
347
+ Markup.new("pre")
348
+ .add_elems(
349
+ Markup.new("code")
350
+ .add_elems(String.new(text).trim.html))
351
+ when sscan.match?(ENTER_TEXT)
352
+ text = sscan.scan_until END_SIMPLE
353
+ text = String.new(text).erase EOB_MARKER
354
+ Markup.new("p").add_elems(line_elems(where, text))
355
+ end)
356
+ end
357
+ return elems
358
+ end
359
+
360
+ def self.highlight where, input, table
361
+ elems = Markup.new
362
+ sscan = StringScanner.new input
363
+ until sscan.eos?
364
+ if sscan.skip /\p{Space}+/um
365
+ elems.add_elems(String.new(sscan[0]).html)
366
+ next
367
+ end
368
+ if sscan.skip CHUNK_LABEL
369
+ label = String.new(sscan[1]).unescape("]")
370
+ elems.add_elems(
371
+ Markup.new("a")
372
+ .add_attrs("class" => "chunk")
373
+ .add_attrs("href" => ChunkRef.new(where, label))
374
+ .add_elems(line_elems(where, label)))
375
+ next
376
+ end
377
+ table.each do |entry|
378
+ if sscan.skip entry[1]
379
+ if entry[0] == nil
380
+ elems.add_elems(String.new(sscan[0]).html)
381
+ else
382
+ elems.add_elems(
383
+ Markup.new("span")
384
+ .add_attrs("class" => entry[0])
385
+ .add_elems(String.new(sscan[0]).html))
386
+ end
387
+ break
388
+ end
389
+ end
390
+ end
391
+ return elems
392
+ end
393
+
394
+ end # module Parse
395
+
396
+ end # module Schizm
397
+
398
+ # puts Schizm::Parse.page_elems('File.zrc', $stdin.read).to_s
@@ -0,0 +1,161 @@
1
+ module Schizm
2
+
3
+ # Extend the default +String+ class.
4
+ class String < ::String
5
+
6
+ # Erase occurances of +Regexp.union(*args)+.
7
+ def erase! *args
8
+ gsub! Regexp.union(*args), ""
9
+ end
10
+
11
+ # Erase occurances of +Regexp.union(*args)+.
12
+ def erase *args
13
+ gsub Regexp.union(*args), ""
14
+ end
15
+
16
+ # Replace sequences of +\p{^Word}+ by an underscore.
17
+ def wordify!
18
+ gsub! /\p{^Word}+/u, '_'
19
+ end
20
+
21
+ # Replace sequences of +\p{^Word}+ by an underscore.
22
+ def wordify
23
+ gsub /\p{^Word}+/u, '_'
24
+ end
25
+
26
+ # Make suitable string for slug.
27
+ def slugify
28
+ gsub(/^\p{^Word}+/u, "")
29
+ .gsub(/\p{^Word}+$/u, "")
30
+ .gsub(/\p{^Word}+/u, '-').downcase
31
+ end
32
+
33
+ # Make suitable string for include guard.
34
+ def guardify
35
+ strip.wordify.upcase
36
+ end
37
+
38
+ # Encode non-ASCII characters and '&', '<', and '>' as HTML entities.
39
+ def html!
40
+ gsub! /[&<>\p{^ASCII}]/u do |char|
41
+ '&#' + char.codepoints[0].to_s + ';'
42
+ end
43
+ end
44
+
45
+ # Encode non-ASCII characters and '&', '<', and '>' as HTML entities.
46
+ def html
47
+ gsub /[&<>\p{^ASCII}]/u do |char|
48
+ '&#' + char.codepoints[0].to_s + ';'
49
+ end
50
+ end
51
+
52
+ # Remove blanks preceding newlines.
53
+ def trim_blank!
54
+ gsub! /\p{Blank}+\n/u, "\n"
55
+ end
56
+
57
+ # Remove blanks preceding newlines.
58
+ def trim_blank
59
+ gsub /\p{Blank}+\n/u, "\n"
60
+ end
61
+
62
+ # Remove blanks preceding newlines, remove trailing
63
+ # spaces, remove newlines succeeding empty lines, and
64
+ # remove leading newlines.
65
+ def trim!
66
+ gsub! /\p{Blank}+\n/u, "\n"
67
+ gsub! /\p{Space}+\z/u, ""
68
+ gsub! /\n\n+/u, "\n\n"
69
+ while start_with? "\n"
70
+ slice! 0
71
+ end
72
+ end
73
+
74
+ # Remove blanks preceding newlines, remove trailing
75
+ # spaces, remove newlines succeeding empty lines, and
76
+ # remove leading newlines.
77
+ def trim
78
+ copy = String.new self
79
+ copy.trim!
80
+ copy
81
+ end
82
+
83
+ # Replace space sequences by a single ASCII space.
84
+ def slim!
85
+ gsub! /\p{Space}+/u, " "
86
+ end
87
+
88
+ # Replace space sequences by a single ASCII space.
89
+ def slim
90
+ gsub /\p{Space}+/u, " "
91
+ end
92
+
93
+ # Expand tabs, subject to tabstop +stop+.
94
+ def expand_tab! stop
95
+ gsub! /([^\t\n]*)\t/u do
96
+ $1 + " " * (stop - $1.size % stop)
97
+ end
98
+ end
99
+
100
+ # Expand tabs, subject to tabstop +stop+.
101
+ def expand_tab stop
102
+ gsub /([^\t\n]*)\t/u do
103
+ $1 + " " * (stop - $1.size % stop)
104
+ end
105
+ end
106
+
107
+ # Distance from last newline to +length+.
108
+ # If there's no last newline, just +length+.
109
+ def find_indent
110
+ if (offset = rindex /\n/u)
111
+ length - offset - 1
112
+ else
113
+ length
114
+ end
115
+ end
116
+
117
+ # Format as a C-style comment.
118
+ def comment
119
+ s = "/*"
120
+ each_line do |line|
121
+ s.concat " "
122
+ s.concat line
123
+ s.concat " *"
124
+ end
125
+ s.concat "/"
126
+ end
127
+
128
+ # Remove backslashes which escape characters +chars+.
129
+ def unescape *chars
130
+ s = String.new
131
+ prev_char_bslash = false
132
+ each_char do |char|
133
+ if prev_char_bslash
134
+ prev_char_bslash = false
135
+ unless chars.include? char
136
+ s.concat '\\'
137
+ end
138
+ else
139
+ if char == '\\'
140
+ prev_char_bslash = true
141
+ next
142
+ end
143
+ end
144
+ s.concat char
145
+ end
146
+ s
147
+ end
148
+
149
+ def truncate n
150
+ if size <= n
151
+ return String.new self
152
+ else
153
+ return String.new(self[0..n])
154
+ .gsub(/\p{Space}+/u, " ")
155
+ .gsub(/\p{Space}+\p{Graph}+\z/u, "...")
156
+ end
157
+ end
158
+
159
+ end # class String
160
+
161
+ end # module Schizm
Binary file
@@ -0,0 +1,102 @@
1
+ Copyright (c) 2014, Nikita Prokopov http://tonsky.me
2
+ with Reserved Font Name Fira Code.
3
+
4
+ Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
5
+ with Reserved Font Name Fira Sans.
6
+
7
+ Copyright (c) 2014, Mozilla Foundation https://mozilla.org/
8
+ with Reserved Font Name Fira Mono.
9
+
10
+ Copyright (c) 2014, Telefonica S.A.
11
+
12
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
13
+ This license is copied below, and is also available with a FAQ at:
14
+ http://scripts.sil.org/OFL
15
+
16
+
17
+ -----------------------------------------------------------
18
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
19
+ -----------------------------------------------------------
20
+
21
+ PREAMBLE
22
+ The goals of the Open Font License (OFL) are to stimulate worldwide
23
+ development of collaborative font projects, to support the font creation
24
+ efforts of academic and linguistic communities, and to provide a free and
25
+ open framework in which fonts may be shared and improved in partnership
26
+ with others.
27
+
28
+ The OFL allows the licensed fonts to be used, studied, modified and
29
+ redistributed freely as long as they are not sold by themselves. The
30
+ fonts, including any derivative works, can be bundled, embedded,
31
+ redistributed and/or sold with any software provided that any reserved
32
+ names are not used by derivative works. The fonts and derivatives,
33
+ however, cannot be released under any other type of license. The
34
+ requirement for fonts to remain under this license does not apply
35
+ to any document created using the fonts or their derivatives.
36
+
37
+ DEFINITIONS
38
+ "Font Software" refers to the set of files released by the Copyright
39
+ Holder(s) under this license and clearly marked as such. This may
40
+ include source files, build scripts and documentation.
41
+
42
+ "Reserved Font Name" refers to any names specified as such after the
43
+ copyright statement(s).
44
+
45
+ "Original Version" refers to the collection of Font Software components as
46
+ distributed by the Copyright Holder(s).
47
+
48
+ "Modified Version" refers to any derivative made by adding to, deleting,
49
+ or substituting -- in part or in whole -- any of the components of the
50
+ Original Version, by changing formats or by porting the Font Software to a
51
+ new environment.
52
+
53
+ "Author" refers to any designer, engineer, programmer, technical
54
+ writer or other person who contributed to the Font Software.
55
+
56
+ PERMISSION & CONDITIONS
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
59
+ redistribute, and sell modified and unmodified copies of the Font
60
+ Software, subject to the following conditions:
61
+
62
+ 1) Neither the Font Software nor any of its individual components,
63
+ in Original or Modified Versions, may be sold by itself.
64
+
65
+ 2) Original or Modified Versions of the Font Software may be bundled,
66
+ redistributed and/or sold with any software, provided that each copy
67
+ contains the above copyright notice and this license. These can be
68
+ included either as stand-alone text files, human-readable headers or
69
+ in the appropriate machine-readable metadata fields within text or
70
+ binary files as long as those fields can be easily viewed by the user.
71
+
72
+ 3) No Modified Version of the Font Software may use the Reserved Font
73
+ Name(s) unless explicit written permission is granted by the corresponding
74
+ Copyright Holder. This restriction only applies to the primary font name as
75
+ presented to the users.
76
+
77
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
78
+ Software shall not be used to promote, endorse or advertise any
79
+ Modified Version, except to acknowledge the contribution(s) of the
80
+ Copyright Holder(s) and the Author(s) or with their explicit written
81
+ permission.
82
+
83
+ 5) The Font Software, modified or unmodified, in part or in whole,
84
+ must be distributed entirely under this license, and must not be
85
+ distributed under any other license. The requirement for fonts to
86
+ remain under this license does not apply to any document created
87
+ using the Font Software.
88
+
89
+ TERMINATION
90
+ This license becomes null and void if any of the above conditions are
91
+ not met.
92
+
93
+ DISCLAIMER
94
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
95
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
96
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
97
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
98
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
99
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
100
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
101
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
102
+ OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file
Binary file
Binary file
@@ -0,0 +1,20 @@
1
+ @font-face {
2
+ font-family: Fira-Code;
3
+ font-weight: 300;
4
+ src: url(/assets/fonts/fira-code-light.otf);
5
+ }
6
+ @font-face {
7
+ font-family: Fira-Code;
8
+ font-weight: 400;
9
+ src: url(/assets/fonts/fira-code-regular.otf);
10
+ }
11
+ @font-face {
12
+ font-family: Fira-Code;
13
+ font-weight: 500;
14
+ src: url(/assets/fonts/fira-code-medium.otf);
15
+ }
16
+ @font-face {
17
+ font-family: Fira-Code;
18
+ font-weight: 700;
19
+ src: url(/assets/fonts/fira-code-bold.otf);
20
+ }