overpass-doc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +1 -0
  3. data/Rakefile +27 -0
  4. data/bin/overpass-doc +12 -0
  5. data/lib/overpass-doc.rb +9 -0
  6. data/lib/overpass-doc/assets/bootstrap.min.css +7 -0
  7. data/lib/overpass-doc/assets/bootstrap.min.js +7 -0
  8. data/lib/overpass-doc/assets/codemirror.css +176 -0
  9. data/lib/overpass-doc/assets/codemirror.js +3190 -0
  10. data/lib/overpass-doc/assets/jquery.js +2 -0
  11. data/lib/overpass-doc/assets/mode/clike/clike.js +303 -0
  12. data/lib/overpass-doc/assets/mode/clike/index.html +102 -0
  13. data/lib/overpass-doc/assets/mode/clike/scala.html +766 -0
  14. data/lib/overpass-doc/assets/mode/clike/test.js +165 -0
  15. data/lib/overpass-doc/assets/util/closetag.js +165 -0
  16. data/lib/overpass-doc/assets/util/continuecomment.js +36 -0
  17. data/lib/overpass-doc/assets/util/continuelist.js +29 -0
  18. data/lib/overpass-doc/assets/util/dialog.css +32 -0
  19. data/lib/overpass-doc/assets/util/dialog.js +76 -0
  20. data/lib/overpass-doc/assets/util/foldcode.js +196 -0
  21. data/lib/overpass-doc/assets/util/formatting.js +108 -0
  22. data/lib/overpass-doc/assets/util/javascript-hint.js +138 -0
  23. data/lib/overpass-doc/assets/util/loadmode.js +51 -0
  24. data/lib/overpass-doc/assets/util/match-highlighter.js +44 -0
  25. data/lib/overpass-doc/assets/util/multiplex.js +95 -0
  26. data/lib/overpass-doc/assets/util/overlay.js +59 -0
  27. data/lib/overpass-doc/assets/util/pig-hint.js +123 -0
  28. data/lib/overpass-doc/assets/util/runmode-standalone.js +90 -0
  29. data/lib/overpass-doc/assets/util/runmode.js +53 -0
  30. data/lib/overpass-doc/assets/util/search.js +118 -0
  31. data/lib/overpass-doc/assets/util/searchcursor.js +119 -0
  32. data/lib/overpass-doc/assets/util/simple-hint.css +16 -0
  33. data/lib/overpass-doc/assets/util/simple-hint.js +102 -0
  34. data/lib/overpass-doc/assets/util/xml-hint.js +131 -0
  35. data/lib/overpass-doc/generator.rb +122 -0
  36. data/lib/overpass-doc/query.rb +119 -0
  37. data/lib/overpass-doc/views/extra.erb +4 -0
  38. data/lib/overpass-doc/views/index.erb +37 -0
  39. data/lib/overpass-doc/views/layout.erb +80 -0
  40. data/lib/overpass-doc/views/query.erb +115 -0
  41. 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,4 @@
1
+ <div class="container">
2
+ <%= _content %>
3
+
4
+ </div>
@@ -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>