utopia-project 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +13 -0
- data/.github/workflows/development.yml +62 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.yarnrc +1 -0
- data/README.md +41 -0
- data/bake/utopia/project.rb +32 -0
- data/gems.rb +4 -0
- data/guides/documentation-formatting/README.md +55 -0
- data/guides/github-pages-integration/README.md +17 -0
- data/lib/utopia/project/base.rb +167 -0
- data/lib/utopia/project/guide.rb +131 -0
- data/lib/utopia/project/version.rb +27 -0
- data/lib/utopia/project.rb +98 -0
- data/package.json +6 -0
- data/pages/_heading.xnode +3 -0
- data/pages/_navigation.xnode +23 -0
- data/pages/_page.xnode +32 -0
- data/pages/_thumbnail.xnode +8 -0
- data/pages/_usage.xnode +21 -0
- data/pages/controller.rb +29 -0
- data/pages/errors/exception.xnode +5 -0
- data/pages/errors/file-not-found.xnode +5 -0
- data/pages/guides/controller.rb +18 -0
- data/pages/guides/index.xnode +17 -0
- data/pages/guides/show.xnode +24 -0
- data/pages/index.xnode +9 -0
- data/pages/links.yaml +4 -0
- data/pages/source/controller.rb +18 -0
- data/pages/source/index.xnode +34 -0
- data/pages/source/show.xnode +63 -0
- data/public/.nojekyll +0 -0
- data/public/_components/jquery/jquery.js +10872 -0
- data/public/_components/jquery/jquery.min.js +2 -0
- data/public/_components/jquery/jquery.min.map +1 -0
- data/public/_components/jquery/jquery.slim.js +8777 -0
- data/public/_components/jquery/jquery.slim.min.js +2 -0
- data/public/_components/jquery/jquery.slim.min.map +1 -0
- data/public/_components/jquery-litebox/jquery.litebox.css +23 -0
- data/public/_components/jquery-litebox/jquery.litebox.gallery.css +48 -0
- data/public/_components/jquery-litebox/jquery.litebox.js +30 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.apache.css +12 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.applescript.css +5 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.assembly.css +8 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash-script.css +6 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.bash.css +4 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.clang.css +6 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.css.css +14 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.diff.css +16 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.html.css +5 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.ocaml.css +3 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.protobuf.css +2 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.python.css +6 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.ruby.css +2 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.brush.xml.css +18 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.core.css +58 -0
- data/public/_components/jquery-syntax/base/jquery.syntax.editor.css +6 -0
- data/public/_components/jquery-syntax/base/theme.js +1 -0
- data/public/_components/jquery-syntax/bright/jquery.syntax.core.css +27 -0
- data/public/_components/jquery-syntax/bright/theme.js +1 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.apache.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.applescript.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.assembly.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.bash-script.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.bash.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.basic.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.clang.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.csharp.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.css.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.diff.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.go.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.haskell.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.html.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.io.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.java.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.javascript.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.kai.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.lisp.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.lua.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.nginx.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.ocaml.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.ooc.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.pascal.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.perl5.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.php-script.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.php.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.plain.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.protobuf.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.python.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.ruby.js +5 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.scala.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.smalltalk.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.sql.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.super-collider.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.swift.js +3 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.trenni.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.xml.js +4 -0
- data/public/_components/jquery-syntax/jquery.syntax.brush.yaml.js +2 -0
- data/public/_components/jquery-syntax/jquery.syntax.cache.js +7 -0
- data/public/_components/jquery-syntax/jquery.syntax.core.js +34 -0
- data/public/_components/jquery-syntax/jquery.syntax.editor.js +11 -0
- data/public/_components/jquery-syntax/jquery.syntax.js +8 -0
- data/public/_components/jquery-syntax/jquery.syntax.min.js +13 -0
- data/public/_components/jquery-syntax/paper/jquery.syntax.core.css +31 -0
- data/public/_components/jquery-syntax/paper/theme.js +1 -0
- data/public/_static/icon.png +0 -0
- data/public/_static/site.css +197 -0
- data/template/Gemfile +6 -0
- data/template/config.ru +6 -0
- data/template/preload.rb +2 -0
- data/utopia-project.gemspec +38 -0
- data/yarn.lock +22 -0
- metadata +351 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6aa72e7117031702241752a366174d7bc8fa7a44ca0bbf52de399ef9c89173e4
|
4
|
+
data.tar.gz: b32f8ef78c132cfcb4cd414416aa0c7dd547e9253a989565f3446027003b55ef
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 582d3f3051f7f0a304b4bf1c286eb22fc45bc9b8a87ef3cb5f51740553608cbef88a4d1d0db5cb442acc1d101884f4eb020e34e47c4fc466b47ca4bb312b7b9a
|
7
|
+
data.tar.gz: 264853fea075ef9d3f1b1787a3b9bd3c6f42364bb29378efbbbb6f9e501eb366655f4df26fbf740b74c02ff58e96560d21ae444909afb3e52eeb186929ba3879
|
data/.editorconfig
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
name: Development
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: ${{matrix.os}}-latest
|
8
|
+
continue-on-error: ${{matrix.experimental}}
|
9
|
+
|
10
|
+
strategy:
|
11
|
+
matrix:
|
12
|
+
os:
|
13
|
+
- ubuntu
|
14
|
+
- macos
|
15
|
+
|
16
|
+
ruby:
|
17
|
+
- 2.5
|
18
|
+
- 2.6
|
19
|
+
- 2.7
|
20
|
+
|
21
|
+
experimental: [false]
|
22
|
+
env: [""]
|
23
|
+
|
24
|
+
include:
|
25
|
+
- os: ubuntu
|
26
|
+
ruby: truffleruby
|
27
|
+
experimental: true
|
28
|
+
env: JRUBY_OPTS="--debug -X+O"
|
29
|
+
- os: ubuntu
|
30
|
+
ruby: jruby
|
31
|
+
experimental: true
|
32
|
+
- os: ubuntu
|
33
|
+
ruby: head
|
34
|
+
experimental: true
|
35
|
+
- os: ubuntu
|
36
|
+
ruby: 2.6
|
37
|
+
experimental: false
|
38
|
+
env: COVERAGE=PartialSummary,Coveralls
|
39
|
+
|
40
|
+
steps:
|
41
|
+
- uses: actions/checkout@v1
|
42
|
+
- uses: ruby/setup-ruby@v1
|
43
|
+
with:
|
44
|
+
ruby-version: ${{matrix.ruby}}
|
45
|
+
|
46
|
+
- name: Installing packages (ubuntu)
|
47
|
+
if: matrix.os == 'ubuntu'
|
48
|
+
run: sudo apt-get install wget pkg-config
|
49
|
+
|
50
|
+
- name: Installing packages (macos)
|
51
|
+
if: matrix.os == 'macos'
|
52
|
+
run: brew install wget pkg-config
|
53
|
+
|
54
|
+
- name: Install dependencies
|
55
|
+
run: ${{matrix.env}} bundle install
|
56
|
+
|
57
|
+
- name: Run tests
|
58
|
+
timeout-minutes: 5
|
59
|
+
run: |
|
60
|
+
git config --global user.email "samuel@oriontransfer.net"
|
61
|
+
git config --global user.name "Samuel Williams"
|
62
|
+
${{matrix.env}} bundle exec rspec
|
data/.gitignore
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Development specific:
|
2
|
+
/.rspec_status
|
3
|
+
/.bundle
|
4
|
+
/pkg
|
5
|
+
/gems.locked
|
6
|
+
|
7
|
+
# Temporary data should not be added to the repository:
|
8
|
+
/tmp
|
9
|
+
|
10
|
+
# Node modules are 3rd party dependencies which can be fetched easily:
|
11
|
+
/node_modules
|
12
|
+
|
13
|
+
# This file should only ever exist on production, and may contain sensitive information:
|
14
|
+
/config/environment.yaml
|
15
|
+
|
16
|
+
# Ignore resized gallery photos:
|
17
|
+
/public/_gallery
|
data/.rspec
ADDED
data/.yarnrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--modules-folder lib/components
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Utopia::Project
|
2
|
+
|
3
|
+
A simple Ruby project documentation website.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
Please see the <a href="https://socketry.github.io/utopia-project/">project documentation</a> or run it locally using `bake utopia:project:serve`.
|
8
|
+
|
9
|
+
## Contributing
|
10
|
+
|
11
|
+
We welcome contributions to this project.
|
12
|
+
|
13
|
+
1. Fork it
|
14
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
15
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
16
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
17
|
+
5. Create new Pull Request
|
18
|
+
|
19
|
+
## License
|
20
|
+
|
21
|
+
Released under the MIT license.
|
22
|
+
|
23
|
+
Copyright, 2020, by [Samuel G. D. Williams](http://www.codeotaku.com).
|
24
|
+
|
25
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
26
|
+
of this software and associated documentation files (the "Software"), to deal
|
27
|
+
in the Software without restriction, including without limitation the rights
|
28
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
29
|
+
copies of the Software, and to permit persons to whom the Software is
|
30
|
+
furnished to do so, subject to the following conditions:
|
31
|
+
|
32
|
+
The above copyright notice and this permission notice shall be included in
|
33
|
+
all copies or substantial portions of the Software.
|
34
|
+
|
35
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
36
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
37
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
38
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
39
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
40
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
41
|
+
THE SOFTWARE.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
|
2
|
+
# Create an empty project in the current directory.
|
3
|
+
def create
|
4
|
+
template_path = File.expand_path("../../template/*", __dir__)
|
5
|
+
|
6
|
+
Dir.glob(template_path) do |path|
|
7
|
+
FileUtils::Verbose.cp_r path, Dir.pwd
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Serve the project locally.
|
12
|
+
def serve
|
13
|
+
config_path = File.expand_path("../../template/config.ru", __dir__)
|
14
|
+
preload_path = File.expand_path("../../template/preload.rb", __dir__)
|
15
|
+
|
16
|
+
system("falcon", "serve", "--config", config_path, "--preload", preload_path)
|
17
|
+
end
|
18
|
+
|
19
|
+
def static(output_path: "docs")
|
20
|
+
require 'rackula/command'
|
21
|
+
|
22
|
+
config_path = File.expand_path("../../template/config.ru", __dir__)
|
23
|
+
public_path = File.expand_path("../../public", __dir__)
|
24
|
+
|
25
|
+
Rackula::Command::Top["generate", "--force",
|
26
|
+
"--config", config_path,
|
27
|
+
"--public", public_path,
|
28
|
+
"--output-path", output_path
|
29
|
+
].call
|
30
|
+
|
31
|
+
FileUtils.touch File.expand_path(".nojekyll", output_path)
|
32
|
+
end
|
data/gems.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Documentation Formatting
|
2
|
+
|
3
|
+
This guide explains the conventions used by `utopia-project` when generating documentation for your project.
|
4
|
+
|
5
|
+
## Source Code Documentation
|
6
|
+
|
7
|
+
Source code documentation is expected to be in markdown format. This is different from the canonical `RDoc` format used by Ruby. However, using markdown is a good format for standardised documentation across a range of different languages.
|
8
|
+
|
9
|
+
### Tags
|
10
|
+
|
11
|
+
#### `@param`
|
12
|
+
|
13
|
+
The `@param` tag is used to describe the parameters of a method:
|
14
|
+
|
15
|
+
~~~ ruby
|
16
|
+
# @param x [Integer] The x co-ordinate.
|
17
|
+
# @param y [Integer] The y co-ordinate.
|
18
|
+
def move(x, y)
|
19
|
+
# ...
|
20
|
+
end
|
21
|
+
~~~
|
22
|
+
|
23
|
+
#### `@return`
|
24
|
+
|
25
|
+
The `@return` tag is used to describe the return type of the definition:
|
26
|
+
|
27
|
+
~~~ ruby
|
28
|
+
# @return [Integer] The result of the computation.
|
29
|
+
def fib(n)
|
30
|
+
# ...
|
31
|
+
end
|
32
|
+
~~~
|
33
|
+
|
34
|
+
### References
|
35
|
+
|
36
|
+
It is possible to insert references in your documentation using curly brackets. In the following example `{Input}` will be expanded relative to the usage, to some symbol named `Input`.
|
37
|
+
|
38
|
+
~~~ ruby
|
39
|
+
# Frobulates the input, see {Input} for more details.
|
40
|
+
def frobulate(input)
|
41
|
+
# ... left to the imagination ...
|
42
|
+
end
|
43
|
+
~~~
|
44
|
+
|
45
|
+
## Examples & Guides
|
46
|
+
|
47
|
+
Examples provide structured information to help users understand your project and are located in the `examples/` directory. One sub-directory per example.
|
48
|
+
|
49
|
+
### `README.md`
|
50
|
+
|
51
|
+
If an example has a `README.md` file, it is used as the main source of documentation.
|
52
|
+
|
53
|
+
### Source Files
|
54
|
+
|
55
|
+
All other source files are listed on the example page. Top level comments with trailing code (segments) are used to help guide the user through the example.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# GitHub Pages Integration
|
2
|
+
|
3
|
+
This guide shows you how to use `utopia-project` with GitHub Pages.
|
4
|
+
|
5
|
+
## Static Site Generation
|
6
|
+
|
7
|
+
Once you are happy with your project's documentation, simply generate a static site:
|
8
|
+
|
9
|
+
~~~ bash
|
10
|
+
$ bake utopia:project:static
|
11
|
+
~~~
|
12
|
+
|
13
|
+
This will generate a static copy of your documentation into `docs/` which is what is required by GitHub Pages.
|
14
|
+
|
15
|
+
## Enable GitHub Pages
|
16
|
+
|
17
|
+
In your GitHub project settings, you will need to [enable GitHub Pages served from `docs/`](https://help.github.com/en/github/working-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source).
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
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
|
13
|
+
# all 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
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'utopia/path'
|
24
|
+
require 'trenni/reference'
|
25
|
+
require 'decode'
|
26
|
+
|
27
|
+
require 'thread/local'
|
28
|
+
|
29
|
+
require 'kramdown'
|
30
|
+
|
31
|
+
require_relative 'guide'
|
32
|
+
|
33
|
+
module Utopia
|
34
|
+
module Project
|
35
|
+
# The base symbol table and project index.
|
36
|
+
class Base
|
37
|
+
extend Thread::Local
|
38
|
+
|
39
|
+
def self.local
|
40
|
+
instance = self.new
|
41
|
+
|
42
|
+
source_files = Dir.glob(
|
43
|
+
File.expand_path("lib/**/*.rb", instance.root)
|
44
|
+
)
|
45
|
+
|
46
|
+
instance.update(source_files)
|
47
|
+
|
48
|
+
return instance
|
49
|
+
end
|
50
|
+
|
51
|
+
# Initialize the project with the given root path.
|
52
|
+
# @param root [String] The file-system path to the root of the project.
|
53
|
+
def initialize(root = Dir.pwd)
|
54
|
+
@root = root
|
55
|
+
|
56
|
+
@source_path = Utopia::Path["/source"]
|
57
|
+
|
58
|
+
@index = Decode::Index.new
|
59
|
+
end
|
60
|
+
|
61
|
+
# The file-system path to the root of the project.
|
62
|
+
attr :root
|
63
|
+
|
64
|
+
# The source code index which is used for generating pages.
|
65
|
+
attr :index
|
66
|
+
|
67
|
+
# Return the absolute path for the given file name, if it exists in the project.
|
68
|
+
# @param file_name [String] The relative path to the project file, e.g. `README.md`.
|
69
|
+
def path_for(file_name)
|
70
|
+
full_path = File.expand_path(file_name, @root)
|
71
|
+
if File.exist?(full_path)
|
72
|
+
return full_path
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Update the index with the specified paths.
|
77
|
+
# @param paths [Array(String)] The paths to load and parse.
|
78
|
+
def update(paths)
|
79
|
+
@index.update(paths)
|
80
|
+
end
|
81
|
+
|
82
|
+
def best(symbols)
|
83
|
+
symbols.each do |symbol|
|
84
|
+
if symbol.documentation
|
85
|
+
return symbol
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
return symbols.first
|
90
|
+
end
|
91
|
+
|
92
|
+
def lookup(path)
|
93
|
+
if node = @index.trie.lookup(path.map(&:to_sym))
|
94
|
+
return node, best(node.values)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def format(text, symbol = nil, language: symbol&.language)
|
99
|
+
if text.is_a?(Enumerable)
|
100
|
+
text = text.to_a.join("\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
if language
|
104
|
+
text = text&.gsub(/{(.*?)}/) do |match|
|
105
|
+
linkify($1, symbol, language: language)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
return Trenni::MarkupString.raw(
|
110
|
+
Kramdown::Document.new(text, syntax_highlighter: nil).to_html
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
def linkify(text, symbol = nil, language: symbol&.language)
|
115
|
+
reference = language.reference(text)
|
116
|
+
|
117
|
+
Trenni::Builder.fragment do |builder|
|
118
|
+
if definition = @index.lookup(reference, relative_to: symbol)&.first
|
119
|
+
builder.inline('a', href: link_for(definition)) do
|
120
|
+
builder.inline('code', class: "language-#{definition.language.name}") do
|
121
|
+
builder.text definition.short_form
|
122
|
+
end
|
123
|
+
end
|
124
|
+
else
|
125
|
+
builder.inline('code', class: "language-#{symbol.language.name}") do
|
126
|
+
builder.text text
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Compute a unique string which can be used as `id` attribute in the HTML output.
|
133
|
+
def id_for(symbol)
|
134
|
+
symbol.qualified_name
|
135
|
+
end
|
136
|
+
|
137
|
+
# Compute a link href to the given symbol for use within the HTML output.
|
138
|
+
def link_for(symbol)
|
139
|
+
path = symbol.lexical_path.map{|entry| entry.to_s}
|
140
|
+
|
141
|
+
if symbol.container?
|
142
|
+
return Trenni::Reference.new(@source_path + path + "index")
|
143
|
+
else
|
144
|
+
name = path.pop
|
145
|
+
return Trenni::Reference.new(@source_path + path + "index", fragment: id_for(symbol))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def guides
|
150
|
+
guides_root = File.expand_path("guides", @root)
|
151
|
+
|
152
|
+
# There are no guides if there is no directory:
|
153
|
+
return unless File.directory?(guides_root)
|
154
|
+
|
155
|
+
return to_enum(:guides) unless block_given?
|
156
|
+
|
157
|
+
Dir.each_child(guides_root) do |entry|
|
158
|
+
guide_path = File.join(guides_root, entry)
|
159
|
+
|
160
|
+
next unless File.directory?(guide_path)
|
161
|
+
|
162
|
+
yield Guide.new(self, guide_path)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
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
|
13
|
+
# all 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
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require 'utopia/path'
|
24
|
+
require 'trenni/reference'
|
25
|
+
require 'decode'
|
26
|
+
require 'kramdown'
|
27
|
+
|
28
|
+
module Utopia
|
29
|
+
module Project
|
30
|
+
class Guide
|
31
|
+
# Initialize the example with the given root path.
|
32
|
+
# @param base [Base] The base instance for the project.
|
33
|
+
# @param root [String] The file-system path to the root of the example.
|
34
|
+
def initialize(base, root)
|
35
|
+
@base = base
|
36
|
+
@root = root
|
37
|
+
|
38
|
+
@documentation = nil
|
39
|
+
|
40
|
+
@document = nil
|
41
|
+
@title = nil
|
42
|
+
@description = nil
|
43
|
+
|
44
|
+
self.document
|
45
|
+
end
|
46
|
+
|
47
|
+
# The description from the first paragraph in the README.
|
48
|
+
# @attr [String | Nil]
|
49
|
+
attr :description
|
50
|
+
|
51
|
+
README = "README.md"
|
52
|
+
|
53
|
+
def readme_path
|
54
|
+
File.expand_path(README, @root)
|
55
|
+
end
|
56
|
+
|
57
|
+
def readme?
|
58
|
+
File.exist?(readme_path)
|
59
|
+
end
|
60
|
+
|
61
|
+
def document
|
62
|
+
if self.readme?
|
63
|
+
@document ||= Kramdown::Document.new(File.read(self.readme_path), syntax_highlighter: nil).tap do |document|
|
64
|
+
root = document.root
|
65
|
+
if element = root.children.first
|
66
|
+
if element.type == :header
|
67
|
+
@title = element.children.first.value
|
68
|
+
|
69
|
+
# Remove the title:
|
70
|
+
root.children.shift
|
71
|
+
|
72
|
+
# Remove any blank lines:
|
73
|
+
root.children.shift while root.children.first&.type == :blank
|
74
|
+
|
75
|
+
# Read the description:
|
76
|
+
root.children.first.options[:encoding] = root.options[:encoding]
|
77
|
+
@description = Kramdown::Converter::Kramdown.convert(root.children.first).first
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# The base instance of the project this example is loaded from.
|
85
|
+
attr :base
|
86
|
+
|
87
|
+
# The file-system path to the root of the project.
|
88
|
+
attr :root
|
89
|
+
|
90
|
+
def name
|
91
|
+
File.basename(@root)
|
92
|
+
end
|
93
|
+
|
94
|
+
def title
|
95
|
+
@title || Trenni::Strings.to_title(self.name)
|
96
|
+
end
|
97
|
+
|
98
|
+
def href
|
99
|
+
"/guides/#{self.name}/index"
|
100
|
+
end
|
101
|
+
|
102
|
+
def documentation
|
103
|
+
@documentation ||= self.best_documentation
|
104
|
+
end
|
105
|
+
|
106
|
+
def files
|
107
|
+
Dir.glob(File.expand_path("*", @root))
|
108
|
+
end
|
109
|
+
|
110
|
+
def sources
|
111
|
+
return to_enum(:sources) unless block_given?
|
112
|
+
|
113
|
+
files.each do |path|
|
114
|
+
if source = Decode::Source.for?(path)
|
115
|
+
yield source
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def best_documentation
|
123
|
+
if source = sources.first
|
124
|
+
if segment = source.segments.first
|
125
|
+
return segment.documentation
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
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
|
13
|
+
# all 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
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
module Utopia
|
24
|
+
module Project
|
25
|
+
VERSION = "0.1.0"
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
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
|
13
|
+
# all 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
|
21
|
+
# THE SOFTWARE.
|
22
|
+
|
23
|
+
require "utopia/project/version"
|
24
|
+
|
25
|
+
require 'variant'
|
26
|
+
|
27
|
+
require 'utopia/localization'
|
28
|
+
require 'utopia/gallery'
|
29
|
+
|
30
|
+
require_relative 'project/base'
|
31
|
+
|
32
|
+
module Utopia
|
33
|
+
module Project
|
34
|
+
# The root directory of the web application files.
|
35
|
+
SITE_ROOT = File.expand_path("../..", __dir__)
|
36
|
+
|
37
|
+
# The root directory for the utopia middleware.
|
38
|
+
PAGES_ROOT = File.expand_path("pages", SITE_ROOT)
|
39
|
+
|
40
|
+
# The root directory for static assets.
|
41
|
+
PUBLIC_ROOT = File.expand_path("public", SITE_ROOT)
|
42
|
+
|
43
|
+
# Appends a project application to the rack builder.
|
44
|
+
#
|
45
|
+
# ~~~ ruby
|
46
|
+
# # In your `config.ru` file:
|
47
|
+
#
|
48
|
+
# require 'utopia/setup'
|
49
|
+
# UTOPIA ||= Utopia.setup
|
50
|
+
#
|
51
|
+
# require 'utopia/project'
|
52
|
+
# Utopia::Project.call(self)
|
53
|
+
# ~~~
|
54
|
+
#
|
55
|
+
# @param locales [Array(String)] an array of locales to support, e.g. `['en', 'ja']`.
|
56
|
+
def self.call(builder, root = Dir.pwd, locales: nil)
|
57
|
+
if UTOPIA.production?
|
58
|
+
# Handle exceptions in production with a error page and send an email notification:
|
59
|
+
builder.use Utopia::Exceptions::Handler
|
60
|
+
builder.use Utopia::Exceptions::Mailer
|
61
|
+
else
|
62
|
+
# We want to propate exceptions up when running tests:
|
63
|
+
builder.use Rack::ShowExceptions unless UTOPIA.testing?
|
64
|
+
end
|
65
|
+
|
66
|
+
public_root = File.expand_path("public", root)
|
67
|
+
builder.use Utopia::Static, root: public_root
|
68
|
+
|
69
|
+
builder.use Utopia::Static, root: PUBLIC_ROOT
|
70
|
+
|
71
|
+
builder.use Utopia::Redirection::Rewrite, {
|
72
|
+
'/' => '/index'
|
73
|
+
}
|
74
|
+
|
75
|
+
builder.use Utopia::Redirection::DirectoryIndex
|
76
|
+
|
77
|
+
builder.use Utopia::Redirection::Errors, {
|
78
|
+
404 => '/errors/file-not-found'
|
79
|
+
}
|
80
|
+
|
81
|
+
if locales
|
82
|
+
builder.use Utopia::Localization,
|
83
|
+
default_locale: locales.first,
|
84
|
+
locales: locales
|
85
|
+
end
|
86
|
+
|
87
|
+
builder.use Utopia::Controller, root: PAGES_ROOT
|
88
|
+
|
89
|
+
cache_root = File.expand_path("_gallery", root)
|
90
|
+
|
91
|
+
builder.use Utopia::Content, root: PAGES_ROOT, namespaces: {
|
92
|
+
'gallery' => Utopia::Gallery::Tags.new
|
93
|
+
}
|
94
|
+
|
95
|
+
builder.run lambda { |env| [404, {}, []] }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|