overpass-doc 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +1 -0
- data/Rakefile +27 -0
- data/bin/overpass-doc +12 -0
- data/lib/overpass-doc.rb +9 -0
- data/lib/overpass-doc/assets/bootstrap.min.css +7 -0
- data/lib/overpass-doc/assets/bootstrap.min.js +7 -0
- data/lib/overpass-doc/assets/codemirror.css +176 -0
- data/lib/overpass-doc/assets/codemirror.js +3190 -0
- data/lib/overpass-doc/assets/jquery.js +2 -0
- data/lib/overpass-doc/assets/mode/clike/clike.js +303 -0
- data/lib/overpass-doc/assets/mode/clike/index.html +102 -0
- data/lib/overpass-doc/assets/mode/clike/scala.html +766 -0
- data/lib/overpass-doc/assets/mode/clike/test.js +165 -0
- data/lib/overpass-doc/assets/util/closetag.js +165 -0
- data/lib/overpass-doc/assets/util/continuecomment.js +36 -0
- data/lib/overpass-doc/assets/util/continuelist.js +29 -0
- data/lib/overpass-doc/assets/util/dialog.css +32 -0
- data/lib/overpass-doc/assets/util/dialog.js +76 -0
- data/lib/overpass-doc/assets/util/foldcode.js +196 -0
- data/lib/overpass-doc/assets/util/formatting.js +108 -0
- data/lib/overpass-doc/assets/util/javascript-hint.js +138 -0
- data/lib/overpass-doc/assets/util/loadmode.js +51 -0
- data/lib/overpass-doc/assets/util/match-highlighter.js +44 -0
- data/lib/overpass-doc/assets/util/multiplex.js +95 -0
- data/lib/overpass-doc/assets/util/overlay.js +59 -0
- data/lib/overpass-doc/assets/util/pig-hint.js +123 -0
- data/lib/overpass-doc/assets/util/runmode-standalone.js +90 -0
- data/lib/overpass-doc/assets/util/runmode.js +53 -0
- data/lib/overpass-doc/assets/util/search.js +118 -0
- data/lib/overpass-doc/assets/util/searchcursor.js +119 -0
- data/lib/overpass-doc/assets/util/simple-hint.css +16 -0
- data/lib/overpass-doc/assets/util/simple-hint.js +102 -0
- data/lib/overpass-doc/assets/util/xml-hint.js +131 -0
- data/lib/overpass-doc/generator.rb +122 -0
- data/lib/overpass-doc/query.rb +119 -0
- data/lib/overpass-doc/views/extra.erb +4 -0
- data/lib/overpass-doc/views/index.erb +37 -0
- data/lib/overpass-doc/views/layout.erb +80 -0
- data/lib/overpass-doc/views/query.erb +115 -0
- metadata +144 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
module OverpassDoc
|
2
|
+
|
3
|
+
class Generator
|
4
|
+
|
5
|
+
attr_reader :dir, :queries, :package
|
6
|
+
|
7
|
+
def initialize(dir, output_dir, view_dir=nil, asset_dir=nil)
|
8
|
+
@dir = dir
|
9
|
+
@output_dir = output_dir
|
10
|
+
@asset_dir = asset_dir || File.join( File.dirname( __FILE__ ) , "assets")
|
11
|
+
@view_dir = view_dir || File.join( File.dirname( __FILE__ ) , "views")
|
12
|
+
@package = parse_package()
|
13
|
+
@queries = parse_queries()
|
14
|
+
end
|
15
|
+
|
16
|
+
def read_template(name)
|
17
|
+
File.read(File.join(@view_dir, "#{name}.erb"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_package()
|
21
|
+
package = File.join(@dir, "package.json")
|
22
|
+
if File.exists?(package)
|
23
|
+
return JSON.load( File.open(package) )
|
24
|
+
end
|
25
|
+
Hash.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_queries()
|
29
|
+
queries = []
|
30
|
+
Dir.glob("#{@dir}/*.op") do |file|
|
31
|
+
content = File.read(file)
|
32
|
+
path = file.gsub("#{@dir}/", "")
|
33
|
+
queries << OverpassDoc::Query.new(path, content, @package)
|
34
|
+
end
|
35
|
+
queries.sort! {|x,y| x.title <=> y.title }
|
36
|
+
queries
|
37
|
+
end
|
38
|
+
|
39
|
+
def run()
|
40
|
+
copy_assets()
|
41
|
+
generate_index()
|
42
|
+
generate_query_pages()
|
43
|
+
copy_extra_files()
|
44
|
+
end
|
45
|
+
|
46
|
+
def copy_assets(asset_dir=@asset_dir)
|
47
|
+
$stderr.puts("Copying assets");
|
48
|
+
if !File.exists?(@output_dir)
|
49
|
+
FileUtils.mkdir_p(@output_dir)
|
50
|
+
end
|
51
|
+
FileUtils.cp_r( "#{@asset_dir}/.", @output_dir )
|
52
|
+
end
|
53
|
+
|
54
|
+
def copy_extra_files()
|
55
|
+
@package["extra-files"].each do |file|
|
56
|
+
markup = File.read( File.join(@dir, file) )
|
57
|
+
renderer = Redcarpet::Render::HTML.new({})
|
58
|
+
markdown = Redcarpet::Markdown.new(renderer, {})
|
59
|
+
template = ERB.new( read_template(:extra) )
|
60
|
+
_content = markdown.render(markup)
|
61
|
+
html = layout do
|
62
|
+
b = binding
|
63
|
+
template.result(b)
|
64
|
+
end
|
65
|
+
file = File.join(@output_dir, file.gsub(".md", ".html"))
|
66
|
+
File.open(file, "w") do |f|
|
67
|
+
f.puts html
|
68
|
+
end
|
69
|
+
end if @package["extra-files"]
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_overview()
|
73
|
+
overview = File.join(@dir, "overview.md")
|
74
|
+
if File.exists?( overview )
|
75
|
+
markup = File.read( overview )
|
76
|
+
renderer = Redcarpet::Render::HTML.new({})
|
77
|
+
markdown = Redcarpet::Markdown.new(renderer, {})
|
78
|
+
return markdown.render(markup)
|
79
|
+
end
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
def generate_index()
|
84
|
+
$stderr.puts("Generating index.html");
|
85
|
+
_title = @package["title"] || "Overpass Query Documentation"
|
86
|
+
_overview = get_overview()
|
87
|
+
_description = @package["description"] || ""
|
88
|
+
template = ERB.new( read_template(:index) )
|
89
|
+
html = layout do
|
90
|
+
b = binding
|
91
|
+
template.result(b)
|
92
|
+
end
|
93
|
+
File.open(File.join(@output_dir, "index.html"), "w") do |f|
|
94
|
+
f.puts(html)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def layout
|
99
|
+
b = binding
|
100
|
+
_title = @package["title"] || "Overpass Query Documentation"
|
101
|
+
_overview = get_overview()
|
102
|
+
ERB.new( read_template(:layout) ).result(b)
|
103
|
+
end
|
104
|
+
|
105
|
+
def generate_query_pages()
|
106
|
+
template = ERB.new( read_template(:query) )
|
107
|
+
@queries.each do |query|
|
108
|
+
$stderr.puts("Generating docs for #{query.path}")
|
109
|
+
File.open( File.join(@output_dir, query.output_filename), "w" ) do |f|
|
110
|
+
b = binding
|
111
|
+
_title = @package["title"] || "Overpass Query Documentation"
|
112
|
+
_overview = get_overview()
|
113
|
+
html = layout do
|
114
|
+
template.result(b)
|
115
|
+
end
|
116
|
+
f.puts( html )
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module OverpassDoc
|
2
|
+
|
3
|
+
class Query
|
4
|
+
|
5
|
+
attr_reader :path, :query, :raw_query, :package
|
6
|
+
|
7
|
+
PATTERN = %r{(?<multi>/\*(?<multi_content>(.|\n)*?)?\*/)|(?<error>/\*(.*)?)}
|
8
|
+
|
9
|
+
ANNOTATIONS = {
|
10
|
+
:author => {
|
11
|
+
:multi => true
|
12
|
+
},
|
13
|
+
:see => {
|
14
|
+
:multi => true
|
15
|
+
},
|
16
|
+
:tags => {
|
17
|
+
:multi => true
|
18
|
+
},
|
19
|
+
:title => {
|
20
|
+
:multi => false
|
21
|
+
},
|
22
|
+
}
|
23
|
+
|
24
|
+
ANNOTATIONS.each do |var, config|
|
25
|
+
attr_reader(var)
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(path, query, package={})
|
29
|
+
ANNOTATIONS.each do |var, config|
|
30
|
+
if config[:multi]
|
31
|
+
instance_variable_set( "@#{var}", [] )
|
32
|
+
else
|
33
|
+
instance_variable_set( "@#{var}", "" )
|
34
|
+
end
|
35
|
+
end
|
36
|
+
@path = path
|
37
|
+
@query = query
|
38
|
+
@raw_query = query
|
39
|
+
@title = @path
|
40
|
+
@description = ""
|
41
|
+
|
42
|
+
["author", "tag"].each do |annotation|
|
43
|
+
if package[annotation]
|
44
|
+
instance_variable_set( "@#{annotation}", package[annotation])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
parseQuery()
|
48
|
+
end
|
49
|
+
|
50
|
+
def output_filename
|
51
|
+
return "#{path.gsub(".op", "")}.html"
|
52
|
+
end
|
53
|
+
|
54
|
+
def description(html=false)
|
55
|
+
if html
|
56
|
+
renderer = Redcarpet::Render::HTML.new({})
|
57
|
+
markdown = Redcarpet::Markdown.new(renderer, {})
|
58
|
+
return markdown.render(@description)
|
59
|
+
end
|
60
|
+
@description
|
61
|
+
end
|
62
|
+
|
63
|
+
def query_string
|
64
|
+
CGI::escape( @query )
|
65
|
+
end
|
66
|
+
|
67
|
+
def extract_annotation(line)
|
68
|
+
matches = line.lstrip.match(/^@([a-zA-Z]+) *(.+)$/i)
|
69
|
+
return nil unless matches
|
70
|
+
return matches[1], matches[2]
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def parseQuery
|
76
|
+
match = @raw_query.match(PATTERN)
|
77
|
+
return if match.nil?
|
78
|
+
if match[:error]
|
79
|
+
raise "Invalid query"
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
query_lines = []
|
84
|
+
header = true
|
85
|
+
description = false
|
86
|
+
description_lines = []
|
87
|
+
|
88
|
+
match[:multi_content].split("\n").each do |line|
|
89
|
+
if ( header )
|
90
|
+
annotation, value = extract_annotation(line)
|
91
|
+
if ( annotation )
|
92
|
+
config = ANNOTATIONS[ annotation.intern ]
|
93
|
+
if config
|
94
|
+
if config[:multi]
|
95
|
+
val = instance_variable_get("@#{annotation}")
|
96
|
+
val << value.strip
|
97
|
+
else
|
98
|
+
instance_variable_set("@#{annotation}", value.strip)
|
99
|
+
end
|
100
|
+
description = true
|
101
|
+
else
|
102
|
+
$stderr.puts("Ignoring unknown annotation: @#{annotation}")
|
103
|
+
end
|
104
|
+
else
|
105
|
+
if (description == false)
|
106
|
+
description_lines << line.lstrip
|
107
|
+
end
|
108
|
+
end
|
109
|
+
else
|
110
|
+
header = false
|
111
|
+
query_lines << line
|
112
|
+
end
|
113
|
+
end
|
114
|
+
@description = description_lines.join("\n") unless description_lines.empty?
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<div class="container">
|
2
|
+
<div class="bg-light p-5 rounded">
|
3
|
+
<h1><%= _title %></h1>
|
4
|
+
<p class="lead"><%= _description %></p>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<% if _overview %>
|
8
|
+
<div class="row">
|
9
|
+
<div class="col">
|
10
|
+
<h3 id="overview">Overview</h3>
|
11
|
+
<%= _overview %>
|
12
|
+
</div>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
|
16
|
+
<div class="row">
|
17
|
+
<div class="col">
|
18
|
+
<h3>Queries</h3>
|
19
|
+
<p>This set of documentation covers <strong><%= @queries.size %></strong> queries</p>
|
20
|
+
<table class="table table-hover">
|
21
|
+
<thead>
|
22
|
+
<tr>
|
23
|
+
<th>Title</th><th>Source Path</th>
|
24
|
+
</tr>
|
25
|
+
</thead>
|
26
|
+
<tbody>
|
27
|
+
<% @queries.each do |query| %>
|
28
|
+
<tr>
|
29
|
+
<td><a href="<%= query.output_filename %>"><%= query.title %></a></td><td><code><%= query.path %></code></td>
|
30
|
+
</tr>
|
31
|
+
<% end %>
|
32
|
+
</tbody>
|
33
|
+
</table>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
</div>
|
@@ -0,0 +1,80 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html class="h-100">
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
5
|
+
<title><%= _title %></title>
|
6
|
+
|
7
|
+
<script src="jquery.js" type="text/javascript"></script>
|
8
|
+
<script src="bootstrap.min.js" type="text/javascript"></script>
|
9
|
+
<script src="codemirror.js" type="text/javascript"></script>
|
10
|
+
<script src="mode/clike/clike.js" type="text/javascript"></script>
|
11
|
+
<script src="util/multiplex.js" type="text/javascript"></script>
|
12
|
+
|
13
|
+
<link rel="stylesheet" href="codemirror.css">
|
14
|
+
<link href="bootstrap.min.css" rel="stylesheet" />
|
15
|
+
<link href="codemirror.css" rel="stylesheet" />
|
16
|
+
|
17
|
+
<style type="text/css">
|
18
|
+
.bd-placeholder-img {
|
19
|
+
font-size: 1.125rem;
|
20
|
+
text-anchor: middle;
|
21
|
+
-webkit-user-select: none;
|
22
|
+
-moz-user-select: none;
|
23
|
+
user-select: none;
|
24
|
+
}
|
25
|
+
|
26
|
+
@media (min-width: 768px) {
|
27
|
+
.bd-placeholder-img-lg {
|
28
|
+
font-size: 3.5rem;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
main > .container {
|
32
|
+
padding: 60px 15px 0;
|
33
|
+
}
|
34
|
+
</style>
|
35
|
+
|
36
|
+
</head>
|
37
|
+
|
38
|
+
|
39
|
+
<body class="d-flex flex-column h-100">
|
40
|
+
|
41
|
+
<header>
|
42
|
+
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
43
|
+
<div class="container-fluid">
|
44
|
+
<a class="navbar-brand" href="index.html"><%= _title %></a>
|
45
|
+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
46
|
+
<span class="navbar-toggler-icon"></span>
|
47
|
+
</button>
|
48
|
+
<div class="collapse navbar-collapse" id="navbarCollapse">
|
49
|
+
<ul class="navbar-nav me-auto mb-2 mb-md-0">
|
50
|
+
<% if _overview %>
|
51
|
+
<li class="nav-item">
|
52
|
+
<a class="nav-link active" aria-current="page" href="index.html#overview">Overview</a>
|
53
|
+
</li>
|
54
|
+
<% end %>
|
55
|
+
<% if @package["extra-files"] %>
|
56
|
+
<% @package["extra-files"].each do |file| %>
|
57
|
+
<li class="nav-item">
|
58
|
+
<a class="nav-link" href="<%= file.gsub(".md", ".html") %>"><%= file.gsub(".md", "").capitalize %></a>
|
59
|
+
</li>
|
60
|
+
<% end %>
|
61
|
+
<% end %>
|
62
|
+
</ul>
|
63
|
+
</div>
|
64
|
+
</div>
|
65
|
+
</nav>
|
66
|
+
</header>
|
67
|
+
|
68
|
+
<main class="flex-shrink-0">
|
69
|
+
<%= yield %>
|
70
|
+
</main>
|
71
|
+
|
72
|
+
<footer class="footer mt-auto py-3 bg-light">
|
73
|
+
<div class="container">
|
74
|
+
<span class="text-muted">Generated with <a href="http://github.com/ldodds/overpass-doc">overpass-doc</a>.</span>
|
75
|
+
</div>
|
76
|
+
</footer>
|
77
|
+
|
78
|
+
|
79
|
+
</body>
|
80
|
+
</html>
|
@@ -0,0 +1,115 @@
|
|
1
|
+
<div class="container">
|
2
|
+
<div class="row">
|
3
|
+
<div class="col">
|
4
|
+
<div class="row">
|
5
|
+
<div id="query-viewer">
|
6
|
+
<h2 property="title"><%= query.title %></h2>
|
7
|
+
<% if query.description %>
|
8
|
+
<p property="description"><%= query.description(true) %></p>
|
9
|
+
<% end %>
|
10
|
+
<dl>
|
11
|
+
<dt>Source File</dt>
|
12
|
+
<dd><code><%= query.path %></code></dd>
|
13
|
+
<% query.author.each do |author| %>
|
14
|
+
<dt>Author</dt>
|
15
|
+
<dd><span property="creator"><%= author %></span></dd>
|
16
|
+
<% end %>
|
17
|
+
<% query.see.each do |see| %>
|
18
|
+
<dt>Link</dt>
|
19
|
+
<dd><a href="<%= see %>"><%= see %></a></dd>
|
20
|
+
<% end %>
|
21
|
+
<% if query.tags.length > 0 %>
|
22
|
+
<dt>Tag</dt>
|
23
|
+
<dd>
|
24
|
+
<%= query.tags.map{|x| "<span property=\"subject\">#{x}</span>" }.join(", ") %>
|
25
|
+
</dd>
|
26
|
+
<% end %>
|
27
|
+
</dl>
|
28
|
+
<textarea id="overpass" cols="120" rows="50"><%= query.query %></textarea>
|
29
|
+
<script>
|
30
|
+
CodeMirror.defineMIME("text/x-overpassQL", {
|
31
|
+
name: "clike",
|
32
|
+
keywords: (function (str) {
|
33
|
+
var r = {};
|
34
|
+
var a = str.split(" ");
|
35
|
+
for (var i = 0; i < a.length; i++) r[a[i]] = true;
|
36
|
+
return r;
|
37
|
+
})(
|
38
|
+
"out json xml custom popup timeout maxsize bbox" + // initial declarations
|
39
|
+
" date diff adiff" + //attic declarations
|
40
|
+
" foreach" + // block statements
|
41
|
+
" relation rel way node is_in area around user uid newer changed poly pivot nwr derived" + // queries
|
42
|
+
" out meta body skel tags ids count qt asc" + // actions
|
43
|
+
" center bb geom" // geometry types
|
44
|
+
//+"r w n br bw" // recursors
|
45
|
+
)
|
46
|
+
});
|
47
|
+
CodeMirror.defineMIME("text/x-overpassXML", "xml");
|
48
|
+
CodeMirror.defineMode("xml+mustache", function (config) {
|
49
|
+
return CodeMirror.multiplexingMode(
|
50
|
+
CodeMirror.multiplexingMode(CodeMirror.getMode(config, "xml"), {
|
51
|
+
open: "{{",
|
52
|
+
close: "}}",
|
53
|
+
mode: CodeMirror.getMode(config, "text/plain"),
|
54
|
+
delimStyle: "mustache"
|
55
|
+
}),
|
56
|
+
{
|
57
|
+
open: "{{style:",
|
58
|
+
close: "}}",
|
59
|
+
mode: CodeMirror.getMode(config, "text/css"),
|
60
|
+
delimStyle: "mustache"
|
61
|
+
}
|
62
|
+
);
|
63
|
+
});
|
64
|
+
CodeMirror.defineMode("ql+mustache", function (config) {
|
65
|
+
return CodeMirror.multiplexingMode(
|
66
|
+
CodeMirror.multiplexingMode(
|
67
|
+
CodeMirror.getMode(config, "text/x-overpassQL"),
|
68
|
+
{
|
69
|
+
open: "{{",
|
70
|
+
close: "}}",
|
71
|
+
mode: CodeMirror.getMode(config, "text/plain"),
|
72
|
+
delimStyle: "mustache"
|
73
|
+
}
|
74
|
+
),
|
75
|
+
{
|
76
|
+
open: "{{style:",
|
77
|
+
close: "}}",
|
78
|
+
mode: CodeMirror.getMode(config, "text/css"),
|
79
|
+
delimStyle: "mustache"
|
80
|
+
}
|
81
|
+
);
|
82
|
+
});
|
83
|
+
var editor = CodeMirror.fromTextArea(document.getElementById("overpass"), {
|
84
|
+
height: "250px",
|
85
|
+
width: "250px",
|
86
|
+
autofocus: false,
|
87
|
+
readOnly: true,
|
88
|
+
mode: "ql+mustache",
|
89
|
+
lineNumbers: true,
|
90
|
+
lineWrapping: true,
|
91
|
+
matchBrackets: true,
|
92
|
+
closeTagEnabled: true,
|
93
|
+
closeTagIndent: [
|
94
|
+
"osm-script",
|
95
|
+
"query",
|
96
|
+
"union",
|
97
|
+
"foreach",
|
98
|
+
"difference"
|
99
|
+
]
|
100
|
+
});
|
101
|
+
</script>
|
102
|
+
<h3>Test This Query</h3>
|
103
|
+
<p>Try this query in Overpass Turbo:</p>
|
104
|
+
<ul>
|
105
|
+
<li>
|
106
|
+
<a href="https://overpass-turbo.eu/?Q=<%= query.query_string %>&R" target="_blank">https://overpass-turbo.eu/</a>
|
107
|
+
</li>
|
108
|
+
</ul>
|
109
|
+
|
110
|
+
</div>
|
111
|
+
</div><!--/row-->
|
112
|
+
</div><!--/span-->
|
113
|
+
</div><!--/row-->
|
114
|
+
|
115
|
+
</div>
|