frenchpress 0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 733b1dd11e9a3d619d074e3a4852ed1ddb97aec6
4
+ data.tar.gz: fe3db9f717e99d5d0bbbfeb985988257da2f9227
5
+ SHA512:
6
+ metadata.gz: 1b3821caa532752576333993b9ca64e17c25241081f3034496aa40d5c7a30e63476b31e13cb91d955c114f6eabfc4268f2b4d63a85c9c9b3e9d4053a8112c1a6
7
+ data.tar.gz: 2b5c6720160bf48a4f658a4e30028d46fc80fbb3fabfcefb4f09e8c4bef2ac0fb99cfef1089ef70faf61332ce75b9c3cf05829a5348582e50b7a7d5a7246beda
@@ -0,0 +1,35 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
@@ -0,0 +1 @@
1
+ 0.2
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Kyle Fahringer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,82 @@
1
+ <img src="https://cdn.rawgit.com/vulpino/frenchpress/master/logo.svg" width="200" />
2
+ # FrenchPress
3
+ ## A blogging engine that positively must be shared!
4
+
5
+ ![Frenchpress Version](https://img.shields.io/gem/v/frenchpress.svg)
6
+
7
+ Frenchpress is for blogging using github pages. It's pretty easy to use.
8
+
9
+ ## How?
10
+
11
+ `gem install frenchpress`
12
+ `cd my_github_site`
13
+ `frenchpress init`
14
+ `frenchpress default`
15
+
16
+ Now you have a frenchpress blog.
17
+
18
+ ### Posting
19
+
20
+ Write a post wherever. It doesn't matter. Then,
21
+
22
+ `frenchpress post cool_post.md`
23
+
24
+ or,
25
+
26
+ `frenchpress post cool_code.rb "This code is really cool!"`
27
+
28
+ or,
29
+
30
+ `frenchpress post cool_picture.jpg cool_story.md`
31
+
32
+ or,
33
+
34
+ `frenchpress post "Hey, does anyone have directions to the cool cafe?"`
35
+
36
+ or,
37
+
38
+ `frenchpress post cool_long_post_1.md cool_long_post_2.md cool_long_post_3.md`
39
+
40
+ ### Replying
41
+
42
+ Frenchpress posts can be replied to.
43
+
44
+ `frenchpress reply coolblog.name/2015/12/25/dkpgqggvpa.html "It's down by the cool river, intersection of cool street and amazing road. You can't miss it."`
45
+
46
+ or,
47
+
48
+ `frenchpress reply coolblog.name/2015/12/25/dkpgqggvpa.html cool_map.jpg cool_detailed_directions.md`
49
+
50
+ etc.
51
+
52
+ Frenchpress helpfully supplies a copy/paste solution on each page, so you've only got to append your response.
53
+
54
+ ### What else?
55
+
56
+ Planned for the future are methods to detect and respond to incoming replies, and to follow blogs of interest, without leaving the terminal. Also planned is themes support.
57
+
58
+ ## FAQ
59
+
60
+ ### But Octopress already exists?
61
+
62
+ Don't like it, so I made my own. Don't need the bells and whistles.
63
+
64
+ ### This is really ugly.
65
+
66
+ I plan to support themes in a future version. And also to make the default theme not awful.
67
+
68
+ You can edit the theme yourself by modifying the following files to your taste, if you've got the know-how:
69
+
70
+ `_layouts/index.html`
71
+ `_layouts/post.html`
72
+ `css/main.css`
73
+
74
+ ### I'm having an issue! / I have a feature request!
75
+
76
+ The issue tracker is open! I'd love to hear your feedback.
77
+
78
+ ### This code is bad!
79
+
80
+ Please improve on it in a PR, or otherwise inform me why the code is bad in a Github issue, nicely and without shouting. I am an entirely self-taught programmer, and while I try to stick to the ruby style guide and I'm constantly running checks on my code, I understand it still may not be "well programmed" for some definition of well programmed. Any constructive feedback you give will improve my future code, so please do give feedback if you see something done in a less than ideal manner. Thank you!
81
+
82
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'frenchpress'
4
+ require 'frenchpress/cmd'
5
+ FrenchPress::CMD.start(ARGV)
@@ -0,0 +1,25 @@
1
+ require 'date'
2
+ version = StringIO.new
3
+ File.open('FRENCHPRESS_VERSION', 'r') do |f|
4
+ version.write f.read
5
+ end
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'frenchpress'
9
+ s.version = version.string
10
+ s.date = Date.today.strftime('%Y-%m-%d')
11
+ s.summary = 'Frenchpress is just for blogging.'
12
+ s.description = 'Frenchpress is a blogging engine to host your blog on ' \
13
+ 'github pages and Just Blog (TM) without the fuss of octopress.'
14
+ s.authors = ['Kyle Fahringer']
15
+ s.files = `git ls-files`.split("\n")
16
+ s.require_paths = ['lib']
17
+ s.executables << 'frenchpress'
18
+ s.license = 'MIT'
19
+ s.homepage = 'https://github.com/vulpino/frenchpress'
20
+ s.email = 'hispanic@hush.ai'
21
+ s.add_runtime_dependency 'thor', '~> 0.19'
22
+ s.add_runtime_dependency 'ruby-progressbar', '~> 1.7'
23
+ s.add_runtime_dependency 'redcarpet', '~> 3.3'
24
+ s.add_runtime_dependency 'rouge', '~> 1.10'
25
+ end
@@ -0,0 +1,23 @@
1
+ <html>
2
+ <head>
3
+ <title>{{ site.title }}</title>
4
+ <link rel="stylesheet" href="/css/main.css" />
5
+ <link rel="stylesheet" href="/css/monokai.css" />
6
+ <link href='https://fonts.googleapis.com/css?family=Poiret+One|Droid+Serif:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
7
+ </head>
8
+ <body>
9
+ <h1><a href="/">{{ site.title }}Title</a></h1>
10
+ <div id="posts">
11
+ {% for post in site.posts %}
12
+ <div class="post">
13
+ {% if post.real_title %}
14
+ <h1 class="post-title"><a href="{{ post.url }}">{{ post.real_title }}</a></h1>
15
+ {% endif %}
16
+ <p class="post-date"><a href="{{ post.url }}">{{ post.date | date: "%b %d %y" }}</a></p>
17
+ <div class="post-content">{{ post.content }}</div>
18
+ <p class="post-reply">To reply: "frenchpress reply {{ site.url }}/{{ post.url }}"</p>
19
+ </div>
20
+ {% endfor %}
21
+ </div>
22
+ </body>
23
+ </html>
@@ -0,0 +1,16 @@
1
+ ---
2
+ ---
3
+ <head>
4
+ <link rel="stylesheet" href="/css/main.css" />
5
+ <link rel="stylesheet" href="/css/monokai.css" />
6
+ <link href='https://fonts.googleapis.com/css?family=Poiret+One|Droid+Serif:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
7
+ <title>{{ site.title }}</title>
8
+ </head>
9
+ <body>
10
+ <h1><a href="/">{{ site.title }}Title</a></h1>
11
+ <div id="posts">
12
+ <div class="post">
13
+ {{ content }}
14
+ </div>
15
+ </div>
16
+ </body>
@@ -0,0 +1,70 @@
1
+ body {
2
+ width: 100%;
3
+ text-align: center;
4
+ overflow-x: hidden;
5
+ }
6
+
7
+ #posts {
8
+ width: 700px;
9
+ display: inline-block;
10
+ text-align: left;
11
+ }
12
+
13
+ .post {
14
+ padding: 25px;
15
+ border: 1px solid black;
16
+ }
17
+
18
+ a {
19
+ text-decoration: none;
20
+ color: grey;
21
+ }
22
+
23
+ a:hover {
24
+ color: black;
25
+ }
26
+
27
+ h1 {
28
+ font-family: 'Poiret One', cursive;
29
+ }
30
+
31
+ h2, h3, h4, p {
32
+ font-family: 'Droid Serif', serif;
33
+ }
34
+
35
+ p {
36
+ margin-top: 4px;
37
+ margin-bottom: 4px;
38
+ }
39
+
40
+ blockquote {
41
+ background: rgba(0, 0, 0, 0.05);
42
+ border-left: 7px solid #ccc;
43
+ margin: 1em 10px;
44
+ padding: 0.5em 10px;
45
+ }
46
+
47
+ .post-date {
48
+ font-size: 8px;
49
+ }
50
+
51
+ .quote-attr {
52
+ font-size: 10px;
53
+ margin-left: 8px;
54
+ }
55
+
56
+ .post-reply {
57
+ font-size: 10px;
58
+ color: grey;
59
+ margin-top: 8px;
60
+ }
61
+
62
+ .code {
63
+ background: #272822;
64
+ padding: 1em;
65
+ overflow-x: scroll;
66
+ }
67
+
68
+ .img-post {
69
+ width: 650px;
70
+ }
@@ -0,0 +1,64 @@
1
+ .hll { background-color: #49483e }
2
+ .c { color: #75715e } /* Comment */
3
+ .err { color: #960050; background-color: #1e0010 } /* Error */
4
+ .k { color: #66d9ef } /* Keyword */
5
+ .l { color: #ae81ff } /* Literal */
6
+ .n { color: #f8f8f2 } /* Name */
7
+ .o { color: #f92672 } /* Operator */
8
+ .p { color: #f8f8f2 } /* Punctuation */
9
+ .cm { color: #75715e } /* Comment.Multiline */
10
+ .cp { color: #75715e } /* Comment.Preproc */
11
+ .c1 { color: #75715e } /* Comment.Single */
12
+ .cs { color: #75715e } /* Comment.Special */
13
+ .ge { font-style: italic } /* Generic.Emph */
14
+ .gs { font-weight: bold } /* Generic.Strong */
15
+ .kc { color: #66d9ef } /* Keyword.Constant */
16
+ .kd { color: #66d9ef } /* Keyword.Declaration */
17
+ .kn { color: #f92672 } /* Keyword.Namespace */
18
+ .kp { color: #66d9ef } /* Keyword.Pseudo */
19
+ .kr { color: #66d9ef } /* Keyword.Reserved */
20
+ .kt { color: #66d9ef } /* Keyword.Type */
21
+ .ld { color: #e6db74 } /* Literal.Date */
22
+ .m { color: #ae81ff } /* Literal.Number */
23
+ .s { color: #e6db74 } /* Literal.String */
24
+ .na { color: #a6e22e } /* Name.Attribute */
25
+ .nb { color: #f8f8f2 } /* Name.Builtin */
26
+ .nc { color: #a6e22e } /* Name.Class */
27
+ .no { color: #66d9ef } /* Name.Constant */
28
+ .nd { color: #a6e22e } /* Name.Decorator */
29
+ .ni { color: #f8f8f2 } /* Name.Entity */
30
+ .ne { color: #a6e22e } /* Name.Exception */
31
+ .nf { color: #a6e22e } /* Name.Function */
32
+ .nl { color: #f8f8f2 } /* Name.Label */
33
+ .nn { color: #f8f8f2 } /* Name.Namespace */
34
+ .nx { color: #a6e22e } /* Name.Other */
35
+ .py { color: #f8f8f2 } /* Name.Property */
36
+ .nt { color: #f92672 } /* Name.Tag */
37
+ .nv { color: #f8f8f2 } /* Name.Variable */
38
+ .ow { color: #f92672 } /* Operator.Word */
39
+ .w { color: #f8f8f2 } /* Text.Whitespace */
40
+ .mf { color: #ae81ff } /* Literal.Number.Float */
41
+ .mh { color: #ae81ff } /* Literal.Number.Hex */
42
+ .mi { color: #ae81ff } /* Literal.Number.Integer */
43
+ .mo { color: #ae81ff } /* Literal.Number.Oct */
44
+ .sb { color: #e6db74 } /* Literal.String.Backtick */
45
+ .sc { color: #e6db74 } /* Literal.String.Char */
46
+ .sd { color: #e6db74 } /* Literal.String.Doc */
47
+ .s2 { color: #e6db74 } /* Literal.String.Double */
48
+ .se { color: #ae81ff } /* Literal.String.Escape */
49
+ .sh { color: #e6db74 } /* Literal.String.Heredoc */
50
+ .si { color: #e6db74 } /* Literal.String.Interpol */
51
+ .sx { color: #e6db74 } /* Literal.String.Other */
52
+ .sr { color: #e6db74 } /* Literal.String.Regex */
53
+ .s1 { color: #e6db74 } /* Literal.String.Single */
54
+ .ss { color: #e6db74 } /* Literal.String.Symbol */
55
+ .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
56
+ .vc { color: #f8f8f2 } /* Name.Variable.Class */
57
+ .vg { color: #f8f8f2 } /* Name.Variable.Global */
58
+ .vi { color: #f8f8f2 } /* Name.Variable.Instance */
59
+ .il { color: #ae81ff } /* Literal.Number.Integer.Long */
60
+
61
+ .gh { } /* Generic Heading & Diff Header */
62
+ .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
63
+ .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
64
+ .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
@@ -0,0 +1,3 @@
1
+ ---
2
+ layout: index
3
+ ---
@@ -0,0 +1,39 @@
1
+ require_relative 'frenchpress/blog'
2
+
3
+ # The FrenchPress class houses some conveience methods for accessing a Blog
4
+ # object, as well as misc properties (such as self.version) and settings
5
+ # manipulation (such as self.default=)
6
+ class FrenchPress
7
+
8
+ @working = nil
9
+
10
+ def self.open(dir)
11
+ default_file = File.join Dir.home, '.frenchpress_dir'
12
+ dir ||= File.open(default_file).read.to_s if File.exist?(default_file)
13
+ dir ||= Dir.getwd
14
+ dir = File.expand_path(dir)
15
+ FrenchPress.working = FrenchPress::Blog.new dir # sets a class inst var
16
+ FrenchPress.working
17
+ end
18
+
19
+ def self.version
20
+ '0.1.0'
21
+ end
22
+
23
+ def self.default=(default_dir)
24
+ Dir.chdir(Dir.home) do
25
+ File.open('.frenchpress_dir', 'w+') do |f|
26
+ f.truncate 0
27
+ f.write default_dir
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.working
33
+ @working
34
+ end
35
+
36
+ def self.working=(blag)
37
+ @working = blag
38
+ end
39
+ end
@@ -0,0 +1,80 @@
1
+ require 'uri'
2
+ require 'ruby-progressbar'
3
+ require 'fileutils'
4
+ require 'open-uri'
5
+
6
+ require_relative 'post'
7
+
8
+ class FrenchPress
9
+ # This represents a blog object in FrenchPress.
10
+ # Usually it is created from the FrenchPress object (through FrenchPress.open
11
+ # for convenience) and manipulated by .post(f) or .new_blog.
12
+ class Blog
13
+ attr_reader :dir
14
+
15
+ def initialize(dir = Dir.getwd)
16
+ @dir = dir
17
+ end
18
+
19
+ def new_blog
20
+ dir = File.expand_path File.join(File.dirname(__FILE__), '..', '..')
21
+ copy_install_files dir
22
+ end
23
+
24
+ def copy_install_files(dir, update = false)
25
+ dir = File.join dir, 'install'
26
+ wd = File.expand_path Dir.getwd
27
+ unless update
28
+ Dir.mkdir '_posts' unless File.directory? '_posts'
29
+ Dir.mkdir 'raw' unless File.directory? 'raw'
30
+ end
31
+ Dir.chdir(dir) do
32
+ files = Dir.glob('**/*')
33
+ pb = ProgressBar.create(total: files.length)
34
+ Dir.glob('**/*/').each do |d|
35
+ begin
36
+ d = File.expand_path d
37
+ Dir.mkdir(d.gsub(dir, wd))
38
+ rescue
39
+ puts "Error creating #{d.gsub(dir, wd)}"
40
+ end
41
+ end
42
+ files.each do |f|
43
+ next if f == 'frenchpress'
44
+ next if File.directory? f
45
+ f = File.expand_path f
46
+ FileUtils.cp f, f.gsub(dir, wd)
47
+ pb.increment
48
+ end
49
+ end
50
+ end
51
+
52
+ def post(*args)
53
+ commit FrenchPress::Post.new_post_from_multiple(*args)
54
+ end
55
+
56
+ def reply(url, *args)
57
+ commit FrenchPress::Post.generate_reply(url, *args)
58
+ end
59
+
60
+ def commit(post)
61
+ puts "Committing #{post}"
62
+ file_path = File.join(@dir, '_posts', "#{post.file_name}.html")
63
+ raw_file_path = File.join(
64
+ @dir, 'raw', "#{post.file_name.split('-').pop}.html")
65
+ File.open(file_path, 'a+') { |f| f.puts post.render_with_tags }
66
+ File.open(raw_file_path, 'a+') { |f| f.puts post.render }
67
+ # TODO: Git commit
68
+ end
69
+
70
+ def update
71
+ Dir.chdir(@dir) do
72
+ FileUtils.rm_rf '_layouts'
73
+ FileUtils.rm_rf 'css'
74
+ FileUtils.rm_rf 'index.html'
75
+ end
76
+ dir = File.expand_path File.join(File.dirname(__FILE__), '..', '..')
77
+ copy_install_files dir, true
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,36 @@
1
+ require 'thor'
2
+
3
+ class FrenchPress
4
+ # This is the command line interface for FrenchPress.
5
+ class CMD < Thor
6
+ class_option :dir
7
+
8
+ desc 'init', 'Initialize a new frenchpress blog.'
9
+ def init
10
+ FrenchPress.open(options[:dir]).new_blog
11
+ end
12
+
13
+ desc 'post', 'Create a new post from given file or URL.'
14
+ def post(*items)
15
+ FrenchPress.open(options[:dir]).post(*items)
16
+ end
17
+
18
+ desc 'default', 'Set the current working directory to your default ' \
19
+ 'frenchpress directory.'
20
+ def default
21
+ dir = options[:dir]
22
+ dir ||= Dir.getwd
23
+ FrenchPress.default = File.expand_path dir
24
+ end
25
+
26
+ desc 'reply', 'Reply to a frenchpress post with new content.'
27
+ def reply(orig, *resp)
28
+ FrenchPress.open(options[:dir]).reply(orig, *resp)
29
+ end
30
+
31
+ desc 'update', "Update your frenchpress theme if it's outdated."
32
+ def update
33
+ FrenchPress.open(options[:dir]).update
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,120 @@
1
+ require 'pathname'
2
+ require_relative 'post/generic'
3
+ require_relative 'post/code'
4
+ require_relative 'post/image'
5
+ require_relative 'post/link'
6
+ require_relative 'post/markdown'
7
+ require_relative 'post/spotify'
8
+ require_relative 'post/youtube'
9
+
10
+ class FrenchPress
11
+ # This represents a post in a FrenchPress blog
12
+ class Post
13
+ def self.new_post(item)
14
+ type = parse_type item
15
+ file = nil
16
+ if type =~ /^file-[^-]+$/
17
+ item, file = parse_file item
18
+ type = type.gsub 'file-', ''
19
+ end
20
+ case type
21
+ when 'text'
22
+ FrenchPress::Post::Generic.new(item)
23
+ when 'code'
24
+ FrenchPress::Post::Code.new(item, file)
25
+ when 'markdown'
26
+ FrenchPress::Post::Markdown.new(item)
27
+ when 'image'
28
+ FrenchPress::Post::Image.new(item, type.split('-')[1])
29
+ when 'link'
30
+ FrenchPress::Post::Link.new(item)
31
+ when 'spotify'
32
+ FrenchPress::Post::Spotify.new(item)
33
+ when 'youtube'
34
+ FrenchPress::Post::Youtube.new(item)
35
+ end
36
+ end
37
+
38
+ def self.new_post_from_multiple(*args)
39
+ # Check we really have multiple arguments
40
+ return new_post(args[0]) if args.length == 1
41
+
42
+ args.map!(&method(:new_post)) # Run new_post on each item in args
43
+ args.map!(&:render) # Render each item in args (which are now posts)
44
+
45
+ # Then join them with newlines, and pass them to a new, combined post
46
+ FrenchPress::Post::Generic.new args.join("\n\n")
47
+ end
48
+
49
+ def self.generate_reply(original_url, *args)
50
+ original = get_post_from_url original_url
51
+ reply = new_post_from_multiple(*args) # Form a reply from all other args
52
+ new_post_from_multiple original.render_as_quote, reply.render
53
+ end
54
+
55
+ def self.parse_type(item)
56
+ if item =~ /\A#{URI.regexp(%w(http https))}\z/
57
+ if item.include?('open.spotify.com')
58
+ return 'spotify'
59
+ elsif item.include?('youtube.com')
60
+ return 'youtube'
61
+ else
62
+ return 'link'
63
+ end
64
+ elsif File.exist?(item)
65
+ filetype = item.split('.').pop
66
+ # it's a file that's being posted
67
+ # is it a text or markdown file?
68
+ # or possibly a code snippet
69
+ if %w(md markdown).include?(filetype)
70
+ return 'file-markdown'
71
+ elsif %w(rb py c go cpp rs swift js yml).include?(filetype)
72
+ return 'file-code'
73
+ elsif %w(png jpg).include?(filetype)
74
+ return "file-image-#{filetype}"
75
+ else
76
+ return 'file-text'
77
+ end
78
+ else
79
+ return 'text'
80
+ end
81
+ end
82
+
83
+ def self.get_post_from_url(url_string)
84
+ # Ensure we have http:// prefix
85
+ url_string = url_string.gsub('http://', '').gsub('https://', '')
86
+ url_string = url_string.prepend('https://') # i'm an optimist
87
+ post_uri = URI.parse(url_string)
88
+ # Update path to point to raw file
89
+ post_uri.path = post_uri.path.split('/').pop.prepend('/raw/')
90
+ dl = nil
91
+ begin
92
+ dl = post_uri.open.read.dup # Dup to remove frozen state
93
+ rescue
94
+ begin
95
+ url_string = url_string.gsub 'https://', 'http://'
96
+ post_uri = URI.parse url_string
97
+ post_uri.path = post_uri.path.split('/').pop.prepend('/raw/')
98
+ dl = post_uri.open.read.dup
99
+ rescue StandardError => e
100
+ puts "Woah! I can't grab the original post. Check your internet."
101
+ puts e
102
+ exit 1
103
+ end
104
+ end
105
+ post = FrenchPress::Post.new_post dl
106
+ post.parent_blog = {
107
+ url: url_string,
108
+ host: post_uri.host
109
+ }
110
+ post
111
+ end
112
+
113
+ def self.parse_file(f)
114
+ file = File.open f
115
+ r = file.read
116
+ file.close
117
+ [r, f.split('.').pop]
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,61 @@
1
+ require 'rouge'
2
+
3
+ class FrenchPress
4
+ class Post
5
+ class Code < Generic
6
+ def lang
7
+ case @file_type
8
+ when 'rb'
9
+ 'ruby'
10
+ when 'c'
11
+ 'c'
12
+ when 'css'
13
+ 'css'
14
+ when 'py'
15
+ 'python'
16
+ when 'yml'
17
+ 'yaml'
18
+ when 'swift'
19
+ 'swift'
20
+ when 'rs'
21
+ 'rust'
22
+ when 'go'
23
+ 'go'
24
+ when 'cpp'
25
+ 'cpp'
26
+ else
27
+ ''
28
+ end
29
+ end
30
+
31
+ def lexer
32
+ case lang
33
+ when 'ruby'
34
+ Rouge::Lexers::Ruby.new
35
+ when 'c'
36
+ Rouge::Lexers::C.new
37
+ when 'css'
38
+ Rouge::Lexers::Css.new
39
+ when 'python'
40
+ Rouge::Lexers::Python.new
41
+ when 'yaml'
42
+ Rouge::Lexers::Yaml.new
43
+ when 'swift'
44
+ Rouge::Lexers::Swift.new
45
+ when 'rust'
46
+ Rouge::Lexers::Rust.new
47
+ when 'go'
48
+ Rouge::Lexers::Go.new
49
+ when 'cpp'
50
+ Rouge::Lexers::Cpp.new
51
+ end
52
+ end
53
+
54
+ def render
55
+ return "<code class=\"code\">#{@content}</code>" unless lexer
56
+ renderer = Rouge::Formatters::HTML.new(css_class: 'highlight')
57
+ "<div class=\"code\">#{renderer.format(lexer.lex(@content))}</div>"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,56 @@
1
+ require 'time'
2
+
3
+ class FrenchPress
4
+ class Post
5
+ # Represents a generic post (i.e. a text post)
6
+ class Generic
7
+ attr_reader :file_name
8
+ attr_writer :parent_blog
9
+
10
+ def initialize(content, file_type = nil)
11
+ title = (rand(36**9) + rand(36**10)).to_s(36) # Random title
12
+ assign_variables(:@content => content,
13
+ :@blog => FrenchPress.working,
14
+ :@date => Time.now,
15
+ :@title => title,
16
+ :@file_type => file_type)
17
+ derive_variables
18
+ end
19
+
20
+ def assign_variables(args)
21
+ args.each(&method(:instance_variable_set)) # Thanks, SO
22
+ end
23
+
24
+ def derive_variables
25
+ @file_name = @date.strftime '%Y-%m-%d' + '-' + @title
26
+ @file_suffix = 'jpeg' if @file_suffix == 'jpg'
27
+ @file_suffix ||= 'html'
28
+ end
29
+
30
+ def tags
31
+ [
32
+ '---',
33
+ "type: #{@type}",
34
+ "date: #{@date.strftime '%Y-%m-%d %H:%M:%S'}",
35
+ 'layout: post',
36
+ "title: #{@title}",
37
+ '---'
38
+ ]
39
+ end
40
+
41
+ def render
42
+ @content
43
+ end
44
+
45
+ def render_as_quote
46
+ "<a href=\"#{@parent_blog[:url]}\" class=\"quote-attr\">" \
47
+ "#{@parent_blog[:host]}</a>\n" \
48
+ "<blockquote>#{render}</blockquote>"
49
+ end
50
+
51
+ def render_with_tags
52
+ (tags << render).join("\n")
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,13 @@
1
+ require 'base64'
2
+
3
+ class FrenchPress
4
+ class Post
5
+ # Represents an image post.
6
+ class Image < Generic
7
+ def render
8
+ "<img src=\"data:image/#{@file_type}, #{Base64.encode64(@content)}\" " \
9
+ "class=\"img-post\" />"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ class FrenchPress
2
+ class Post
3
+ # Represents a link post
4
+ class Link < Generic
5
+ def render
6
+ "<h2><a href=\"#{@content}\">" \
7
+ "#{@content.delete('http://').delete('https://')}</a></h2>"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'redcarpet'
2
+
3
+ class FrenchPress
4
+ class Post
5
+ # Represents a Markdown post.
6
+ class Markdown < Generic
7
+ def render
8
+ Redcarpet::Markdown.new(Redcarpet::Render::HTML).render @content
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ class FrenchPress
2
+ class Post
3
+ class Spotify
4
+ def render
5
+ "<iframe src=\"https://embed.spotify.com/?uri=#{@content}\" " \
6
+ "width=\"300\" height=\"380\" frameborder=\"0\" " \
7
+ "allowtransparency=\"true\"></iframe>"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ class FrenchPress
2
+ class Post
3
+ # Represents a youtube object.
4
+ class Youtube
5
+ def render
6
+ "<iframe width=\"480\" height=\"390\" " \
7
+ "src=\"https://www.youtube.com/embed/#{@content}\" " \
8
+ "frameborder=\"0\" allowfullscreen></iframe>"
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,124 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
5
+ <g>
6
+ <path fill="#FFFFFF" d="M42.3,0.2c19.3,0,38.6,0,57.9,0c0,33.3,0,66.7,0,100c-15.1,0-30.1,0-45.2,0c0.4-0.1,0.9-0.2,1.3-0.2
7
+ c1.4-0.2,1.7-0.5,1.8-1.9c0-0.4-0.2-0.8-0.3-1.2c-0.1-0.5-0.1-1.1-0.2-1.6c-0.1-0.5-0.2-1-0.2-1.6c0.7-0.6,1.4-1.5,1.5-2.7
8
+ c0.1-2,0.2-4,0.3-6c0-0.6,0.2-0.9,0.8-1c0.7-0.1,1.5-0.4,2.2-0.5c0.7-0.1,1-0.6,1.1-1.2c0-0.6,0.1-1.3,0.1-1.9c0,0,0.1,0,0.1,0
9
+ c0,0.8,0,1.6,0,2.3c0.2,0.1,0.2,0.1,0.3,0.1c1,0,2,0,3-0.1c7.3-0.8,12.6-4.5,15.4-11.3c1.9-4.6,2.4-9.5,2.2-14.4
10
+ c-0.2-5.4-1.5-10.5-3.6-15.5c-2.4-5.6-7.7-9.1-13.7-9.1c-2.1,0-4.1,0-6.2,0c0,0,0,0,0,0c-0.1-0.3-0.2-0.8-0.4-0.9
11
+ c-0.8-0.3-0.9-0.9-0.8-1.5c0.2-2.1,0.4-4.1,0.6-6.2c0.1-0.5,0.3-0.9,0.9-0.9c0.6,0,0.8-0.4,0.8-1c0-0.4,0-0.8-0.1-1.2
12
+ c-0.1-0.3-0.4-0.6-0.6-0.7c-0.8-0.1-0.9-0.6-1-1.2c-0.2-1-0.3-2-0.7-2.9c-0.9-2.2-2.8-3.3-4.8-4.1c-3.2-1.4-6.6-1.7-10.1-1.8
13
+ c-0.9,0-1.5-0.2-1.6-1.3c0.1-0.1,0.3-0.3,0.5-0.4c1.3-0.8,1.6-2.3,2.2-3.6c0.2-0.3-0.3-1-0.5-1.5C45,1.7,43.8,0.8,42.3,0.2z"/>
14
+ <path d="M42.3,0.2c1.5,0.6,2.7,1.5,3.1,3.1c0.1,0.5,0.6,1.2,0.5,1.5c-0.6,1.3-0.9,2.8-2.2,3.6c-0.2,0.1-0.4,0.3-0.5,0.4
15
+ c0.1,1,0.7,1.2,1.6,1.3c3.4,0.1,6.8,0.4,10.1,1.8c2,0.9,3.9,2,4.8,4.1c0.4,0.9,0.5,1.9,0.7,2.9c0.1,0.6,0.3,1.1,1,1.2
16
+ c0.2,0,0.5,0.4,0.6,0.7c0.1,0.4,0,0.8,0.1,1.2c0,0.6-0.2,0.9-0.8,1c-0.6,0-0.8,0.5-0.9,0.9c-0.2,2.1-0.4,4.1-0.6,6.2
17
+ c-0.1,0.7,0,1.3,0.8,1.5c0.2,0.1,0.2,0.6,0.4,0.9c0.1,0.1,0.3,0.4,0.4,0.4c1.2,0,2.3,0,3.5,0c-1-0.1-2.1-0.1-3.1-0.1
18
+ c-0.3,0-0.6-0.2-0.8-0.3c2.1,0,4.1,0,6.2,0c6.1,0,11.3,3.5,13.7,9.1c2.1,4.9,3.4,10.1,3.6,15.5c0.2,5-0.3,9.8-2.2,14.4
19
+ c-2.8,6.8-8.1,10.5-15.4,11.3c-1,0.1-2,0.1-3,0.1c-0.1,0-0.1-0.1-0.3-0.1c0-0.8,0-1.6,0-2.3c0,0-0.1,0-0.1,0c0,0.6,0,1.3-0.1,1.9
20
+ c0,0.7-0.4,1.1-1.1,1.2c-0.7,0.2-1.5,0.4-2.2,0.5c-0.6,0.1-0.8,0.4-0.8,1c-0.1,2-0.2,4-0.3,6c-0.1,1.2-0.7,2.1-1.5,2.7
21
+ c0.1,0.6,0.2,1.1,0.2,1.6c0.1,0.5,0.1,1.1,0.2,1.6c0.1,0.4,0.3,0.8,0.3,1.2c-0.1,1.4-0.4,1.7-1.8,1.9c-0.4,0.1-0.9,0.2-1.3,0.2
22
+ c-0.6,0-1.1,0-1.7,0c-0.2-0.2-0.5-0.4-0.7-0.6c-2.3-2.2-5-3.4-8.3-3.2c-1.2,0.1-2.4,0-3.7,0c0-0.1,0-0.2,0-0.3c2.2,0,4.4,0,6.6,0
23
+ c0,0,0-0.1,0-0.1c-4.4,0-8.9,0-13.4,0c0.3,0.1,0.5,0.1,0.7,0.2c-0.9,0.2-1.7,0.3-2.5,0.5c-1.7,0.4-3.3,1.2-4.5,2.6
24
+ c-0.7,0.8-1.5,1-2.5,0.9c-0.5-0.1-1-0.2-1.6-0.2c-1.8-0.3-2.3-1.2-1.6-2.9c0.3-0.9,0.7-1.7,1-2.6c0.1-0.2,0-0.7-0.2-0.9
25
+ c-1.3-1.2-1.8-2.6-1.7-4.3c0-4.9,0.1-9.9,0.1-14.8c0-2.8,0-5.7,0-8.5c0-3.3,0-6.6,0-9.9c0-5.3,0.1-10.6,0.2-15.9c0-0.6,0-1-0.7-1.2
26
+ c-0.2,0-0.5-0.5-0.5-0.8c-0.1-2,0-4-0.1-6c0-0.6,0.2-0.9,0.7-1c0.2-0.1,0.5-0.3,0.6-0.6c0.2-1.3-0.2-2.1-1.3-2.7
27
+ c0-0.7,0.4-0.8,0.9-0.6c0.9,0.3,1.2,0,1.3-0.9c0-0.6,0-1.1,0-1.7c0.1,0,0.2,0,0.3,0c0.1,1,0.1,2,0.2,3c0.1,0,0.1,0,0.2,0
28
+ c0-0.7,0-1.5,0-2.2c0.1-1.2-0.4-1.6-1.6-1.1c-1.1,0.5-2.1,1.3-3.1,2.1c-0.5,0.4-0.3,0.8,0.3,1c0.3,0.1,0.6,0.2,0.9,0.3
29
+ c-0.6,0-1.2,0.1-1.8,0.1c-0.2,0-0.3-0.1-0.5-0.2c-0.7-0.5-0.8-1-0.1-1.6c0.5-0.4,0.8-1,1.3-1.4c0.9-0.7,1.9-1.3,2.8-1.8
30
+ c-1.4-0.5-1.4-0.5-1.3-2.2c0-0.5,0.2-0.9,0.8-0.9c0.6-0.1,0.9-0.4,0.9-1c0.2-3.4,2.1-5.5,5.2-6.8c3.3-1.4,6.8-1.7,10.3-1.7
31
+ c1.8,0,1.3,0.2,2-1.4c-1.3-0.8-2.1-1.9-2.4-3.5c0-0.3-0.3-0.6-0.2-0.8c0.6-1.9,1.5-3.6,3.6-4.2C40.7,0.2,41.5,0.2,42.3,0.2z
32
+ M37.4,77.9c0.1,0.3,0.1,0.4,0.2,0.6c0.1,0.2,0.2,0.3,0.3,0.5c0.1-0.2,0.3-0.3,0.4-0.5c0.1-0.5,0.1-1,0.1-1.5
33
+ c0.1-0.3,0.1-0.7,0.4-0.9c0.5-0.3,0.6-0.7,0.6-1.3c0-5.3,0.1-10.5,0.2-15.8c0.1-6.1,0.1-12.2,0.2-18.3c0-0.6,0-1,0.8-1.1
34
+ c1,0,1.1,0.1,1.1,1.1c-0.1,6.1-0.2,12.1-0.3,18.2c-0.1,5,0,10,0,15c0,0.9-0.5,1.9,0.7,2.4c0.1,0,0.1,0.2,0.1,0.2
35
+ c-0.1,1,0.3,1.6,1.1,2.2c0.2-0.4,0.5-0.8,1.1-0.3c0,0,0.2,0,0.2,0c0.6-0.1,1.2-0.2,1.8-0.2c1.4,0,2.9,0.1,4.3,0.3
36
+ c0.9,0.1,1-0.2,1-0.9c-0.1-4.9-0.1-9.7-0.1-14.6c0-5.9,0.1-11.8,0.1-17.7c0-1.8-0.1-3.6,0.5-5.3c0-0.1,0-0.2,0-0.4
37
+ c-0.4,0-0.7-0.1-1-0.1c-7.3-0.1-14.6-0.1-22-0.2c-0.7,0-0.8,0.3-0.7,0.9c0.2,0.6,0.4,1.3,0.4,2c0.1,3.5,0.1,7.1,0.2,10.6
38
+ c0.2,6.3,0.3,12.6,0.5,18.9c0.1,1.9,0.1,3.8,0.2,5.7c0,0.7,0.2,0.9,1,0.8c0.5-0.1,1.1,0,1.6,0c0.2,0,0.6-0.2,0.7-0.1
39
+ c0.2,0.2,0.3,0.6,0.4,0.7c0.1-0.3,0.3-0.6,0.5-0.9c0.2,0.3,0.5,0.6,0.7,0.9c0.1-0.3,0.2-0.7,0.4-1c0.1,0,0.2,0,0.2,0
40
+ c0.1,0.4,0.3,0.8,0.4,1.2c0.1,0,0.2,0,0.2,0c0.1-0.4,0.2-0.8,0.4-1.3c0.3,0.5,0.5,0.8,0.7,1.1C37,78.7,37.2,78.3,37.4,77.9z
41
+ M61.1,37.8c-0.3,0.5-0.6,1-0.9,1.2c-0.5,0.3-0.6,0.6-0.6,1.1c0,2.9,0,5.8,0,8.7c0,4.6,0,9.1,0,13.7c0,3.5-0.1,7-0.1,10.5
42
+ c0,2.7,0,2.7,2.7,2.8c0.4,0,0.9,0.1,1.1,0.3c0.5,0.9,1.3,0.7,2.1,0.7c0.6,0,1.2-0.1,1.7-0.2c4.7-0.6,9.2-4.4,10.4-9
43
+ c2.1-8.1,1.5-16.1-2-23.8c-1.5-3.2-3.9-5.3-7.5-5.6c-1.8-0.2-3.6,0-5.3,0c-0.4,0-0.7,0-1.1-0.1c0-0.1,0-0.2,0-0.2
44
+ c1.4,0,2.7,0,4.1,0c0,0,0-0.1,0-0.1C64.1,37.8,62.5,37.8,61.1,37.8z M56.7,16.2c-0.1-1.4-0.9-2.1-1.9-2.5c-1.5-0.6-3.1-1.2-4.8-1.5
45
+ c-2-0.4-4.1-0.5-6.2-0.6c-1.6-0.1-3.2,0.3-4.7,0c-2.5-0.4-4.8-0.2-7.2,0.3c-1.8,0.4-3.6,1.1-5.4,1.7c-0.4,0.1-0.7,0.4-0.5,1
46
+ c0.3,0.7,0.2,1.4,0.3,2.1c6.5,2.1,24.7,2.1,29.9,0.1C55.9,16.4,56.2,16.2,56.7,16.2z M52.5,92.3c0-0.4,0-0.7-0.1-1
47
+ c-0.6-1.5-0.9-3-0.9-4.6c0-0.2-0.4-0.4-0.7-0.4c-3.3,0.1-6.7,0.2-10,0.2c-3.4,0-6.8-0.3-10.3-0.4c-1.1-0.1-1.1,0-1.2,1
48
+ c-0.3,1.8-0.1,3.8-2,5.1c0.3,0.1,0.5,0.1,0.6,0.1c2.3,0,4.6,0,6.9,0.1c1.1,0,2.2,0.1,3.2,0.1c1.2,0.1,2.5,0.2,3.7,0.1
49
+ c1.9,0,3.8-0.2,5.7-0.3C49.1,92.3,50.7,92.3,52.5,92.3z M50.9,20.4c0-0.1,0-0.1,0-0.2c0.7,0,1.4,0,2.1,0c0.7,0,1.4,0,2.2,0
50
+ c0.6,0,1.3-0.1,1.9-0.1c0,0,0-0.1,0-0.1c-10.8-0.1-21.7-0.2-32.5-0.4c0,0.1,0,0.2,0,0.3c2.4,0.1,4.7,0.2,7.1,0.3c0,0,0,0,0,0
51
+ c-2.7,0-5.4,0-8.1,0c11.5,0.8,23,0.9,34.5,0.4c0-0.1,0-0.1,0-0.2C55.7,20.4,53.3,20.4,50.9,20.4z M54.6,98.1
52
+ c0.1-0.8,0.7-0.6,1.2-0.7c0.6-0.1,1.1-0.2,1.8-0.3c-0.3-0.7-0.5-1.3-0.7-1.8c-0.2-0.5-0.5-0.7-1.1-0.6c-0.9,0.1-1.7-0.1-2.6-0.1
53
+ C53.7,95.6,54.2,96.8,54.6,98.1z M46.9,95.3c0-0.1,0-0.2,0-0.3c-4.6,0-9.2-0.7-13.8-0.1c0,0.1,0,0.2,0,0.4
54
+ C37.7,95.3,42.3,95.3,46.9,95.3z M55.5,39.7c0.4,1.7,0.7,3.3,1.1,4.9c0.2-1,0.2-2,0.2-3c0-0.8-0.2-1.7,0.8-2.1
55
+ C56.8,39.5,56.2,39.6,55.5,39.7z M56.1,75C56.1,75,56.1,75,56.1,75c0.1-3.9,0.2-7.9,0.3-11.8c-0.1,0-0.2,0-0.3,0
56
+ C56.1,67.2,56.1,71.1,56.1,75z M37.7,32.3C37.7,32.3,37.7,32.4,37.7,32.3c4,0.1,7.9,0.1,11.9,0.1c0,0,0,0,0-0.1
57
+ C45.6,32.3,41.7,32.3,37.7,32.3z M25.4,96.8c0.1,0,0.2,0.1,0.2,0.1c0.8-0.4,1.7-0.8,2.5-1.1c-0.7-0.3-1.6,0.7-2.3-0.4
58
+ C25.7,95.9,25.5,96.3,25.4,96.8z M20.5,23.4c-1.7,0.6-2.8,1.8-4,3.5C18,25.6,19.3,24.5,20.5,23.4z M56.3,56.6
59
+ C56.3,56.6,56.4,56.6,56.3,56.6c0.1-2.8,0.1-5.5,0.1-8.3c0,0-0.1,0-0.1,0C56.3,51.1,56.3,53.9,56.3,56.6z M64.7,34.5
60
+ c-0.8-0.9-1.6-0.9-2.3,0C63.1,34.5,63.9,34.5,64.7,34.5z M31.4,93c0-0.1,0-0.2,0-0.4c-1.2-0.1-2.3-0.2-3.5-0.2c0,0.1,0,0.2,0,0.2
61
+ C29.1,92.8,30.3,92.9,31.4,93z M52.6,85.9C52.6,85.9,52.6,85.9,52.6,85.9c0.1-2.1,0.1-4.3,0.1-6.4c0,0-0.1,0-0.1,0
62
+ C52.6,81.6,52.6,83.8,52.6,85.9z M51.8,96c0.7,0.3,1.3,0.5,1.9,0.8C53.5,95.8,52.8,95.5,51.8,96z M63.4,77c-0.1,0-0.2,0-0.3,0
63
+ c0.1,0.8,0.2,1.5,0.3,2.2C63.4,78.6,63.4,77.8,63.4,77z"/>
64
+ <path fill="#FFFFFF" d="M40,0.2c-2.2,0.6-3,2.3-3.6,4.2c-0.1,0.2,0.2,0.6,0.2,0.8c0.3,1.5,1,2.7,2.4,3.5c-0.7,1.5-0.3,1.4-2,1.4
65
+ c-3.5,0-7,0.3-10.3,1.7c-3,1.3-5,3.4-5.2,6.8c0,0.6-0.3,0.9-0.9,1c-0.6,0.1-0.7,0.4-0.8,0.9c-0.1,1.7-0.1,1.7,1.3,2.2
66
+ c-0.9,0.6-1.9,1.2-2.8,1.8c-0.5,0.4-0.9,0.9-1.3,1.4c-0.6,0.6-0.5,1.1,0.1,1.6c0.1,0.1,0.3,0.2,0.5,0.2c0.6,0,1.2-0.1,1.8-0.1
67
+ c0.2,0.1,0.4,0.1,0.6,0.2c1.1,0.6,1.5,1.5,1.3,2.7c0,0.2-0.3,0.5-0.6,0.6c-0.6,0.1-0.8,0.4-0.7,1c0,2,0,4,0.1,6
68
+ c0,0.3,0.3,0.8,0.5,0.8c0.7,0.1,0.7,0.6,0.7,1.2c-0.1,5.3-0.1,10.6-0.2,15.9c0,3.3,0,6.6,0,9.9c0,2.8,0,5.7,0,8.5
69
+ c0,4.9-0.1,9.9-0.1,14.8c0,1.6,0.5,3.1,1.7,4.3c0.2,0.2,0.3,0.6,0.2,0.9c-0.3,0.9-0.7,1.7-1,2.6c-0.7,1.7-0.1,2.6,1.6,2.9
70
+ c0.5,0.1,1,0.2,1.6,0.2c1,0.1,1.8-0.1,2.5-0.9c1.2-1.4,2.7-2.1,4.5-2.6c0.8-0.2,1.7-0.3,2.5-0.5c-0.2,0-0.4-0.1-0.7-0.2
71
+ c4.5,0,9,0,13.4,0c0,0,0,0.1,0,0.1c-2.2,0-4.4,0-6.6,0c0,0.1,0,0.2,0,0.3c1.2,0,2.4,0.1,3.7,0c3.3-0.2,6,1,8.3,3.2
72
+ c0.2,0.2,0.5,0.4,0.7,0.6c-17.7,0-35.5,0-53.2,0c0-33.3,0-66.7,0-100C13.4,0.2,26.7,0.2,40,0.2z"/>
73
+ <path fill="#FFFFFF" d="M37.4,77.9c-0.2,0.4-0.4,0.8-0.6,1.1c-0.2-0.3-0.4-0.6-0.7-1.1c-0.1,0.5-0.2,0.9-0.4,1.3
74
+ c-0.1,0-0.2,0-0.2,0c-0.1-0.4-0.3-0.8-0.4-1.2c-0.1,0-0.2,0-0.2,0c-0.1,0.3-0.2,0.7-0.4,1c-0.2-0.3-0.5-0.6-0.7-0.9
75
+ c-0.2,0.3-0.3,0.6-0.5,0.9c-0.1-0.2-0.1-0.5-0.4-0.7c-0.1-0.1-0.5,0.1-0.7,0.1c-0.5,0-1.1-0.2-1.6,0c-0.7,0.1-0.9-0.1-1-0.8
76
+ c0-1.9-0.1-3.8-0.2-5.7c-0.2-6.3-0.4-12.6-0.5-18.9c-0.1-3.5-0.1-7.1-0.2-10.6c0-0.7-0.2-1.3-0.4-2c-0.2-0.6,0-0.9,0.7-0.9
77
+ c7.3,0.1,14.6,0.1,22,0.2c0.3,0,0.6,0,1,0.1c0,0.2,0,0.3,0,0.4c-0.7,1.7-0.5,3.5-0.5,5.3c0,5.9-0.1,11.8-0.1,17.7
78
+ c0,4.9,0.1,9.7,0.1,14.6c0,0.7-0.1,1-1,0.9c-1.4-0.2-2.9-0.2-4.3-0.3c-0.6,0-1.2,0.1-1.8,0.2c-0.1,0-0.2,0-0.2,0
79
+ c-0.5-0.5-0.8-0.2-1.1,0.3c-0.7-0.6-1.2-1.2-1.1-2.2c0-0.1,0-0.2-0.1-0.2c-1.1-0.5-0.7-1.5-0.7-2.4c0-5,0-10,0-15
80
+ c0.1-6.1,0.2-12.1,0.3-18.2c0-1-0.1-1.1-1.1-1.1c-0.8,0-0.8,0.5-0.8,1.1c-0.1,6.1-0.1,12.2-0.2,18.3c-0.1,5.3-0.1,10.5-0.2,15.8
81
+ c0,0.5-0.1,0.9-0.6,1.3c-0.2,0.1-0.3,0.6-0.4,0.9c-0.1,0.5-0.1,1-0.1,1.5c0,0.2-0.2,0.3-0.4,0.5c-0.1-0.2-0.2-0.3-0.3-0.5
82
+ C37.5,78.4,37.5,78.2,37.4,77.9z"/>
83
+ <path fill="#FFFFFF" d="M61.1,37.8c1.5,0,3,0,4.6,0c0,0,0,0.1,0,0.1c-1.4,0-2.7,0-4.1,0c0,0.1,0,0.2,0,0.2c0.4,0,0.7,0.1,1.1,0.1
84
+ c1.8,0,3.6-0.2,5.3,0c3.6,0.3,6.1,2.4,7.5,5.6c3.4,7.7,4.1,15.6,2,23.8c-1.2,4.6-5.6,8.4-10.4,9c-0.6,0.1-1.2,0.1-1.7,0.2
85
+ c-0.8,0-1.6,0.3-2.1-0.7c-0.1-0.2-0.7-0.3-1.1-0.3c-2.7-0.1-2.7-0.1-2.7-2.8c0-3.5,0.1-7,0.1-10.5c0-4.6,0-9.1,0-13.7
86
+ c0-2.9,0-5.8,0-8.7c0-0.5,0.1-0.8,0.6-1.1C60.5,38.8,60.7,38.3,61.1,37.8z"/>
87
+ <path fill="#FFFFFF" d="M56.7,16.2c-0.5,0-0.8,0.2-0.4,0.7c-5.3,2.1-23.5,2-29.9-0.1c-0.1-0.7-0.1-1.5-0.3-2.1
88
+ c-0.3-0.6,0.1-0.9,0.5-1c1.8-0.6,3.5-1.4,5.4-1.7c2.4-0.5,4.8-0.7,7.2-0.3c1.5,0.2,3.2-0.1,4.7,0c2.1,0.1,4.2,0.2,6.2,0.6
89
+ c1.6,0.3,3.2,0.9,4.8,1.5C55.9,14.1,56.7,14.8,56.7,16.2z"/>
90
+ <path fill="#FFFFFF" d="M52.5,92.3c-1.8,0-3.4,0-5,0c-1.9,0.1-3.8,0.2-5.7,0.3c-1.2,0-2.5-0.1-3.7-0.1c-1.1,0-2.2-0.1-3.2-0.1
91
+ c-2.3,0-4.6,0-6.9-0.1c-0.1,0-0.3-0.1-0.6-0.1c1.9-1.3,1.7-3.3,2-5.1c0.2-1,0.2-1.1,1.2-1c3.4,0.2,6.8,0.4,10.3,0.4
92
+ c3.3,0,6.7-0.2,10-0.2c0.2,0,0.7,0.3,0.7,0.4c0,1.6,0.3,3.1,0.9,4.6C52.4,91.6,52.4,91.9,52.5,92.3z"/>
93
+ <path fill="#FFFFFF" d="M50.9,20.4c2.4,0,4.8,0,7.2,0c0,0.1,0,0.1,0,0.2c-11.5,0.5-23,0.4-34.5-0.4c2.7,0,5.4,0,8.1,0c0,0,0,0,0,0
94
+ c-2.4-0.1-4.7-0.2-7.1-0.3c0-0.1,0-0.2,0-0.3c10.8,0.1,21.7,0.2,32.5,0.4c0,0,0,0.1,0,0.1c-0.6,0.1-1.3,0.1-1.9,0.1
95
+ c-0.7,0-1.4,0-2.2,0c-0.7,0-1.4,0-2.1,0C50.9,20.3,50.9,20.4,50.9,20.4z"/>
96
+ <path fill="#FFFFFF" d="M19.9,27.8c-0.2-0.1-0.4-0.1-0.6-0.2c-0.3-0.1-0.6-0.2-0.9-0.3c-0.6-0.2-0.8-0.7-0.3-1c1-0.8,2-1.6,3.1-2.1
97
+ c1.2-0.5,1.7-0.1,1.6,1.1c-0.1,0.7,0,1.5,0,2.2c-0.1,0-0.1,0-0.2,0c-0.1-1-0.1-2-0.2-3c-0.1,0-0.2,0-0.3,0c0,0.6,0,1.1,0,1.7
98
+ c0,0.9-0.4,1.2-1.3,0.9C20.3,27,19.9,27.1,19.9,27.8z"/>
99
+ <path fill="#FFFFFF" d="M54.6,98.1c-0.5-1.2-1-2.5-1.4-3.6c0.9,0,1.7,0.2,2.6,0.1c0.6,0,0.9,0.1,1.1,0.6c0.2,0.6,0.4,1.1,0.7,1.8
100
+ c-0.6,0.1-1.2,0.2-1.8,0.3C55.4,97.5,54.7,97.3,54.6,98.1z M55.1,94.9c0,0.1,0,0.2,0,0.3c0.4,0,0.8-0.1,1.2-0.1c0-0.1,0-0.2,0-0.3
101
+ C55.9,94.9,55.5,94.9,55.1,94.9z"/>
102
+ <path fill="#FFFFFF" d="M46.9,95.3c-4.6,0-9.2,0-13.8,0c0-0.1,0-0.2,0-0.4C37.8,94.3,42.4,95,47,95C47,95.1,46.9,95.2,46.9,95.3z"
103
+ />
104
+ <path fill="#FFFFFF" d="M55.5,39.7c0.7-0.1,1.4-0.2,2-0.2c-1,0.5-0.8,1.3-0.8,2.1c0,1,0,2-0.2,3C56.2,43,55.8,41.4,55.5,39.7z"/>
105
+ <path fill="#FFFFFF" d="M56.1,75c0-3.9,0-7.9,0-11.8c0.1,0,0.2,0,0.3,0C56.3,67.2,56.2,71.1,56.1,75C56.1,75,56.1,75,56.1,75z"/>
106
+ <path fill="#FFFFFF" d="M37.7,32.3c4,0,7.9,0,11.9,0c0,0,0,0,0,0.1C45.6,32.4,41.7,32.4,37.7,32.3C37.7,32.4,37.7,32.3,37.7,32.3z"
107
+ />
108
+ <path fill="#FFFFFF" d="M25.4,96.8c0.1-0.5,0.3-0.9,0.4-1.4c0.7,1.1,1.6,0.1,2.3,0.4c-0.8,0.4-1.7,0.8-2.5,1.1
109
+ C25.6,96.9,25.5,96.8,25.4,96.8z"/>
110
+ <path fill="#FFFFFF" d="M20.5,23.4c-1.3,1.1-2.6,2.2-4,3.5C17.7,25.2,18.9,23.9,20.5,23.4z"/>
111
+ <path fill="#FFFFFF" d="M56.3,56.6c0-2.8,0-5.6,0-8.3c0,0,0.1,0,0.1,0C56.4,51.1,56.4,53.9,56.3,56.6
112
+ C56.4,56.6,56.3,56.6,56.3,56.6z"/>
113
+ <path fill="#FFFFFF" d="M64.7,34.5c-0.8,0-1.6,0-2.3,0C63.1,33.6,63.9,33.6,64.7,34.5z"/>
114
+ <path fill="#FFFFFF" d="M31.4,93c-1.2-0.1-2.3-0.2-3.5-0.4c0-0.1,0-0.2,0-0.2c1.2,0.1,2.3,0.2,3.5,0.2C31.5,92.8,31.4,92.9,31.4,93
115
+ z"/>
116
+ <path fill="#FFFFFF" d="M52.6,85.9c0-2.1,0-4.3,0-6.4c0,0,0.1,0,0.1,0C52.6,81.6,52.6,83.8,52.6,85.9
117
+ C52.6,85.9,52.6,85.9,52.6,85.9z"/>
118
+ <path fill="#FFFFFF" d="M51.8,96c1-0.4,1.7-0.1,1.9,0.8C53.1,96.5,52.5,96.3,51.8,96z"/>
119
+ <path fill="#FFFFFF" d="M63.4,77c0,0.8,0,1.6,0,2.3c-0.1-0.7-0.2-1.5-0.3-2.2C63.2,77,63.3,77,63.4,77z"/>
120
+ <path fill="#FFFFFF" d="M60.9,32.4c0.3,0.1,0.6,0.3,0.8,0.3c1,0,2,0,3.1,0.1c-1.2,0-2.3,0-3.5,0C61.2,32.9,61,32.6,60.9,32.4
121
+ C60.9,32.4,60.9,32.4,60.9,32.4z"/>
122
+ <path d="M55.1,94.9c0.4,0,0.8,0,1.2,0c0,0.1,0,0.2,0,0.3c-0.4,0-0.8,0.1-1.2,0.1C55.1,95.1,55.1,95,55.1,94.9z"/>
123
+ </g>
124
+ </svg>
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frenchpress
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
+ platform: ruby
6
+ authors:
7
+ - Kyle Fahringer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.19'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ruby-progressbar
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redcarpet
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rouge
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.10'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.10'
69
+ description: Frenchpress is a blogging engine to host your blog on github pages and
70
+ Just Blog (TM) without the fuss of octopress.
71
+ email: hispanic@hush.ai
72
+ executables:
73
+ - frenchpress
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - FRENCHPRESS_VERSION
79
+ - LICENSE
80
+ - README.md
81
+ - bin/frenchpress
82
+ - frenchpress.gemspec
83
+ - install/_layouts/index.html
84
+ - install/_layouts/post.html
85
+ - install/css/main.css
86
+ - install/css/monokai.css
87
+ - install/index.html
88
+ - lib/frenchpress.rb
89
+ - lib/frenchpress/blog.rb
90
+ - lib/frenchpress/cmd.rb
91
+ - lib/frenchpress/post.rb
92
+ - lib/frenchpress/post/code.rb
93
+ - lib/frenchpress/post/generic.rb
94
+ - lib/frenchpress/post/image.rb
95
+ - lib/frenchpress/post/link.rb
96
+ - lib/frenchpress/post/markdown.rb
97
+ - lib/frenchpress/post/spotify.rb
98
+ - lib/frenchpress/post/youtube.rb
99
+ - logo.svg
100
+ homepage: https://github.com/vulpino/frenchpress
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.4.5.1
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: Frenchpress is just for blogging.
124
+ test_files: []
125
+ has_rdoc: