kdwatch 0.1.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +142 -0
- data/bin/kdwatch +73 -10
- data/kdwatch.gemspec +2 -1
- data/lib/kdwatch/version.rb +1 -1
- data/lib/kdwatch-app.rb +33 -6
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50e6ea6a1e81ab7f17173c1251395a6fbeb1a4b4c236d1c9c6fd1731f3118ca8
|
4
|
+
data.tar.gz: 31235eb66b35d5c39ebd1f124e938dfcc9b3f305a020ddf05dc610b7e8832707
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39e2d6062ef4adf87ce11d05c2d18e4d305de91e8212d1c204bc7bd0b8c8086f3c662e59deeaa284779f326bebdbd3c06af6ec993c4bc3ad4ad0dea0a468ee80
|
7
|
+
data.tar.gz: 9db4d837a11aea7413de4362bc418cb56fb2f987dc926ab722bd1b8be06850a2a2e51110e78dd75caebec5b2b7280e0b14592910f00478879b127e8724d0b070
|
data/.gitignore
CHANGED
data/README.md
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
# Kdwatch
|
2
|
+
|
3
|
+
Auto-formatting, auto-reloading display of formatted [kramdown-rfc][] document in browser
|
4
|
+
|
5
|
+
[kramdown-rfc]: http://rfc.space
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
```
|
10
|
+
$ pip3 install --upgrade xml2rfc
|
11
|
+
$ gem update
|
12
|
+
$ gem install kdwatch
|
13
|
+
```
|
14
|
+
|
15
|
+
* For some reason, the initial `gem install` takes a couple of minutes,
|
16
|
+
during the first few of which it may seem nothing happens.
|
17
|
+
* If the above `pip3` (or `pip`) doesn't work, no problem: in a pinch,
|
18
|
+
kdrfc will use the IETF web service for xml2rfc processing (but that
|
19
|
+
may be a bit slower).
|
20
|
+
* Depending on system configuration, add `sudo` on the pip/gem
|
21
|
+
commands (but don't if it isn't actually needed).
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
* Open a separate terminal window/screen.
|
26
|
+
* Go to a directory that has a single draft-*.md (or select one by
|
27
|
+
specifying the markdown file name on the command line) and run:
|
28
|
+
|
29
|
+
```
|
30
|
+
$ kdwatch
|
31
|
+
```
|
32
|
+
|
33
|
+
* After about 10 seconds, a browser will open (or an error message will
|
34
|
+
pop up with the URL to use, which depends on the options given, but
|
35
|
+
defaults to <http://127.0.0.1:7991/>).
|
36
|
+
|
37
|
+
Now, whenever you do an editor save of the kramdown-rfc markdown file,
|
38
|
+
kdwatch auto-formats and, after a couple of seconds(*), you see an
|
39
|
+
updated HTML in the browser without pressing buttons or switching windows.
|
40
|
+
|
41
|
+
You will need to keep the `kdwatch` terminal/screen open to see
|
42
|
+
potential error messages, e.g., if you break the markdown in some way.
|
43
|
+
(The author uses an Emacs "Async Shell Command" buffer for that.)
|
44
|
+
|
45
|
+
(*) The latency depends on your computer and a bit on the size of the
|
46
|
+
file, say, around 1.6 s for my Intel Mac, 0.8 s for my M1 Mac.
|
47
|
+
|
48
|
+
### There can only be one (per host/port)
|
49
|
+
|
50
|
+
There can only be one kdwatch active on each host and port. You will
|
51
|
+
need to specify a different port (or host!) to run more than one
|
52
|
+
kdwatch at the same time.
|
53
|
+
|
54
|
+
* `-p port` to select a port number (default: 7991)
|
55
|
+
* `-1` to `6` as a shortcut for `-p 7991` (default) to `-p 7996` (must be last
|
56
|
+
option because of an idiosyncrasy of the optionparser library)
|
57
|
+
|
58
|
+
kdwatch has two flags to simplify handling servers that might be
|
59
|
+
accumulating on one host/port:
|
60
|
+
|
61
|
+
* `-e` to kill (SIGINT) any current holder of the port given and exit
|
62
|
+
* `-r` to do this, and to start a new instance as well
|
63
|
+
|
64
|
+
So the most likely use is going to be:
|
65
|
+
|
66
|
+
```
|
67
|
+
kdwatch -r
|
68
|
+
```
|
69
|
+
|
70
|
+
or maybe
|
71
|
+
|
72
|
+
```
|
73
|
+
kdwatch -r2
|
74
|
+
```
|
75
|
+
|
76
|
+
for the second draft you are editing at the same time,
|
77
|
+
|
78
|
+
or, if your drafts are weirdly named or you need to select one out of
|
79
|
+
many
|
80
|
+
|
81
|
+
```
|
82
|
+
kdwatch -r5 weird-draft.md
|
83
|
+
```
|
84
|
+
|
85
|
+
(Glitches are to be expected if you *start* more than one server out of
|
86
|
+
the same directory at the same instant; TODO; for now, wait 10 seconds
|
87
|
+
before starting another from the same directory.)
|
88
|
+
|
89
|
+
### 7991, haven't I heard that number before?
|
90
|
+
|
91
|
+
The default port number was chosen after [RFC 7991], the initial (no
|
92
|
+
longer really authoritative) version of the v3 RFCXML specification,
|
93
|
+
and the port shortcuts 1 to 6 point to this and further RFCs from this
|
94
|
+
series.
|
95
|
+
(7997 is a particularly lame RFC, so it cannot be chosen by a
|
96
|
+
shortcut [actually: this port is already registered for something else].)
|
97
|
+
|
98
|
+
[RFC 7991]: https://rfc-editor.org/rfc/rfc7991.html
|
99
|
+
|
100
|
+
### kdwatch is a web server
|
101
|
+
|
102
|
+
kdwatch essentially is a web server and can listen on any host
|
103
|
+
interface you might have:
|
104
|
+
|
105
|
+
* `-o host` to select an interface address on the serving host (default: 127.0.0.1)
|
106
|
+
* `-i` as a shortcut for `-o :: ` (`i` stands for "on the Internet")
|
107
|
+
|
108
|
+
Unless used on 127.0.0.1 (or ::1), kdwatch is accessible to anyone who
|
109
|
+
can access your laptop over IP. That may be a security problem -- do
|
110
|
+
not specify a non-local interface unless you know you are not “on the
|
111
|
+
Internet” (or trust the way I cobble together software). If you are,
|
112
|
+
maybe `kdwatch -e` before going there!
|
113
|
+
|
114
|
+
The fun thing with the `-i` option is that you can replace the local
|
115
|
+
URL by filling in the hostname of the laptop and use the resulting URL
|
116
|
+
on a different browser (e.g., `http://mylaptop.local:7991` on your iPad or
|
117
|
+
another laptop), and save some screen real-estate on your laptop.
|
118
|
+
With a globally routable address, kdwatch even can be used for joint
|
119
|
+
viewing in a team.
|
120
|
+
|
121
|
+
## Feedback, please
|
122
|
+
|
123
|
+
This has only been tested on macOS and briefly on Linux. No idea about WSL.
|
124
|
+
There is very little error handling yet, so restarts of the tool may
|
125
|
+
be required, or sometimes reloading in the browser (CMD-R/F5) is all
|
126
|
+
that is needed.
|
127
|
+
|
128
|
+
If you try it, please send feedback (and, in case of an error, *all*
|
129
|
+
output on the kdwatch terminal window, please).
|
130
|
+
|
131
|
+
Bug reports, pull requests, or simple suggestions are welcome on GitHub at
|
132
|
+
<https://github.com/cabo/kdwatch>, e.g., simply [submit an
|
133
|
+
issue][issues] or send me [mail][].
|
134
|
+
|
135
|
+
[issues]: https://github.com/cabo/kdwatch/issues
|
136
|
+
[mail]: mailto:cabo@tzi.org?Subject=kdwatch
|
137
|
+
|
138
|
+
## License
|
139
|
+
|
140
|
+
The gem is available as open source under the terms of the [MIT License][].
|
141
|
+
|
142
|
+
[MIT License]: https://opensource.org/licenses/MIT
|
data/bin/kdwatch
CHANGED
@@ -3,17 +3,77 @@ ENV["LANG"]="en_US.utf-8"
|
|
3
3
|
ENV["LC_CTYPE"]="en_US.utf-8"
|
4
4
|
ENV["KRAMDOWN_PERSISTENT"]="yes"
|
5
5
|
|
6
|
+
|
7
|
+
require 'optparse'
|
8
|
+
require 'ostruct'
|
9
|
+
|
10
|
+
require_relative "../lib/kdwatch/version"
|
11
|
+
|
6
12
|
KDWATCH_PORT = 7991 # currently unregistered...
|
7
13
|
|
14
|
+
options = OpenStruct.new
|
15
|
+
|
16
|
+
op = OptionParser.new do |opts|
|
17
|
+
opts.banner = <<BANNER
|
18
|
+
Usage: kdwatch [options] draft-foo.md|.mkd|.xml
|
19
|
+
Version: #{Kdwatch::VERSION}
|
20
|
+
BANNER
|
21
|
+
opts.on("-V", "--version", "Show version and exit") do |v|
|
22
|
+
puts "kdwatch #{Kdwatch::Version}"
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
opts.on("-H", "--help", "Show option summary and exit") do |v|
|
26
|
+
puts opts
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
opts.on("-e", "--[no-]end", "End existing server and exit")
|
30
|
+
opts.on("-r", "--[no-]replace", "Replace existing server")
|
31
|
+
opts.on("-oNAME", "--host=NAME", String, "Server host (127.0.0.1)")
|
32
|
+
opts.on("-i", "--internet", 'Abbr. "on the Internet" (host = "::")')
|
33
|
+
opts.on("-pNUM", "--port=NUM", Integer, "Port number (#{KDWATCH_PORT})")
|
34
|
+
opts.on("-[1-6]", "--[1-6]", Integer, "Abbr. port number (#{KDWATCH_PORT/10}x), must be last")
|
35
|
+
end
|
36
|
+
begin
|
37
|
+
op.parse!(into: options)
|
38
|
+
rescue OptionParser::InvalidOption => e
|
39
|
+
warn "** #{e}"
|
40
|
+
warn op
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
if options.internet
|
45
|
+
warn "** overriding host #{options.host} with ::" if options.host
|
46
|
+
options.host = "::"
|
47
|
+
else
|
48
|
+
options.host ||= "127.0.0.1"
|
49
|
+
end
|
50
|
+
if short_port = options[""]
|
51
|
+
port = short_port + KDWATCH_PORT/10*10
|
52
|
+
warn "** overriding port #{options.port} with #{port}" if options.port
|
53
|
+
options.port = port
|
54
|
+
else
|
55
|
+
options.port ||= KDWATCH_PORT
|
56
|
+
end
|
57
|
+
|
58
|
+
# p options
|
59
|
+
|
8
60
|
## -r: Kill any previous kdwatch and continue ("restart")
|
9
61
|
## -e: Kill any previous kdwatch and exit
|
10
|
-
if
|
62
|
+
if options.replace || options.end
|
11
63
|
require 'open3'
|
12
64
|
|
13
65
|
status = 1
|
14
|
-
flag = ARGV.shift
|
15
66
|
|
16
|
-
|
67
|
+
lsof_host = case options.host
|
68
|
+
when "::", "0.0.0.0"
|
69
|
+
"" # can't do more specific with lsof; hope for the best
|
70
|
+
when /:/
|
71
|
+
"@'[#{options.host}]'"
|
72
|
+
else
|
73
|
+
"@'#{options.host}'"
|
74
|
+
end
|
75
|
+
|
76
|
+
stdout_str, stderr_str, s = Open3.capture3("lsof -ti #{lsof_host}:#{options.port} -s TCP:LISTEN")
|
17
77
|
pids = if s.success? && stdout_str =~ /\A[0-9\s]*\z/ && stderr_str
|
18
78
|
stdout_str.split
|
19
79
|
else
|
@@ -22,7 +82,7 @@ if ARGV[0] == "-e" || ARGV[0] == "-r"
|
|
22
82
|
[]
|
23
83
|
end
|
24
84
|
if pids == []
|
25
|
-
warn "** Nothing listening on kdwatch port" unless
|
85
|
+
warn "** Nothing listening on kdwatch port" unless options.replace
|
26
86
|
elsif pids.size != 1
|
27
87
|
warn "** More than one process listening on kdwatch port, nothing done"
|
28
88
|
else
|
@@ -32,7 +92,7 @@ if ARGV[0] == "-e" || ARGV[0] == "-r"
|
|
32
92
|
warn "** #{pids[0]}: #{e.inspect}"
|
33
93
|
end
|
34
94
|
end
|
35
|
-
exit(status) if
|
95
|
+
exit(status) if options.end
|
36
96
|
end
|
37
97
|
|
38
98
|
## Find an .mkd or a draft-*.md (excluding README.md and such)
|
@@ -42,8 +102,7 @@ if ARGV == []
|
|
42
102
|
end
|
43
103
|
|
44
104
|
if ARGV.size != 1
|
45
|
-
warn
|
46
|
-
warn "** #$0 -e"
|
105
|
+
warn op
|
47
106
|
if warn_replace
|
48
107
|
if ARGV.size > 1
|
49
108
|
warn "** More than one draft file found #{ARGV.inspect}"
|
@@ -55,13 +114,17 @@ if ARGV.size != 1
|
|
55
114
|
exit 1
|
56
115
|
end
|
57
116
|
|
58
|
-
ENV["
|
117
|
+
ENV["KDWATCH_SRC"] = ARGV[0]
|
118
|
+
ENV["KDWATCH_HOST"] = options.host
|
119
|
+
ENV["KDWATCH_PORT"] = options.port.to_s
|
120
|
+
live_reload_port = options.port + 51234 # move up into ephemeral space
|
121
|
+
ENV["KDWATCH_LRPORT"] = live_reload_port.to_s
|
59
122
|
|
60
123
|
File.write(".config.ru", <<HERE)
|
61
124
|
require 'rack-livereload'
|
62
|
-
use Rack::LiveReload, min_delay: 500, source: :vendored, no_swf: true
|
125
|
+
use Rack::LiveReload, min_delay: 500, source: :vendored, no_swf: true, port: #{live_reload_port}, live_reload_port: #{live_reload_port}
|
63
126
|
require 'kdwatch-app.rb'
|
64
127
|
run Sinatra::Application
|
65
128
|
HERE
|
66
129
|
|
67
|
-
exec("rackup -E production -s thin -p #{
|
130
|
+
exec("rackup -E production -s thin -o #{options.host} -p #{options.port} .config.ru")
|
data/kdwatch.gemspec
CHANGED
@@ -28,10 +28,11 @@ Gem::Specification.new do |spec|
|
|
28
28
|
|
29
29
|
spec.add_dependency "bundler", '~> 2.2'
|
30
30
|
spec.add_dependency "thin", '~> 1.8'
|
31
|
+
# spec.add_dependency "cabo-guard-livereload", '~> 2.5' #, require: false
|
31
32
|
spec.add_dependency "guard-livereload", '~> 2.5' #, require: false
|
32
33
|
spec.add_dependency "rack-livereload", '~> 0.3'
|
33
34
|
spec.add_dependency "guard", '~> 2.17'
|
34
35
|
spec.add_dependency "sinatra", '~> 2.1'
|
35
|
-
spec.add_dependency "kramdown-rfc2629", '~> 1.
|
36
|
+
spec.add_dependency "kramdown-rfc2629", '~> 1.5'
|
36
37
|
spec.add_dependency "net-http-persistent", '~> 4.0'
|
37
38
|
end
|
data/lib/kdwatch/version.rb
CHANGED
data/lib/kdwatch-app.rb
CHANGED
@@ -9,25 +9,49 @@ require "rack-livereload"
|
|
9
9
|
require "guard"
|
10
10
|
require "sinatra"
|
11
11
|
require "kramdown-rfc2629"
|
12
|
+
ENV["KDRFC_PREPEND"] = "time" if system("time", "true", err: "/dev/null")
|
13
|
+
require "kramdown-rfc/kdrfc-processor"
|
12
14
|
require "net/http/persistent"
|
13
15
|
|
16
|
+
host = ENV["KDWATCH_HOST"]
|
17
|
+
port = ENV["KDWATCH_PORT"]
|
14
18
|
|
15
|
-
sfn = ENV["
|
19
|
+
sfn = ENV["KDWATCH_SRC"]
|
16
20
|
fail "No source given" unless sfn
|
17
21
|
|
18
22
|
dfn = File.join(File.dirname(sfn), "#{File.basename(sfn, ".*")}.html")
|
19
23
|
|
20
24
|
puts dfn
|
21
25
|
|
26
|
+
kdrfc = KramdownRFC::KDRFC.new
|
27
|
+
kdrfc.options.v3 = true
|
28
|
+
kdrfc.options.html = true
|
29
|
+
|
22
30
|
get "/" do
|
23
31
|
sfc = File.stat(sfn).ctime
|
24
32
|
dfc = File.stat(dfn).ctime rescue Time.at(0)
|
25
33
|
if sfc > dfc
|
26
34
|
warn "Rebuilding..."
|
27
|
-
|
28
|
-
|
35
|
+
begin
|
36
|
+
kdrfc.process sfn
|
37
|
+
rescue StandardError => e
|
38
|
+
warn e.to_s
|
39
|
+
else
|
40
|
+
warn "...done"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
dfc = File.stat(dfn).ctime rescue Time.at(0)
|
44
|
+
ret = File.read(dfn)
|
45
|
+
if sfc > dfc # somehow the above went wrong
|
46
|
+
ret.gsub!(<<CSS, <<RED)
|
47
|
+
/* general and mobile first */
|
48
|
+
html {
|
49
|
+
CSS
|
50
|
+
/* general and mobile first */
|
51
|
+
html { border: 5px solid red;
|
52
|
+
RED
|
29
53
|
end
|
30
|
-
|
54
|
+
ret
|
31
55
|
end
|
32
56
|
|
33
57
|
get "/metadata.min.js" do
|
@@ -39,7 +63,7 @@ get "/rfc-local.css" do
|
|
39
63
|
end
|
40
64
|
|
41
65
|
File.write(".Guardfile", <<GF)
|
42
|
-
guard
|
66
|
+
guard :livereload, :port => #{ENV["KDWATCH_LRPORT"]} do
|
43
67
|
watch("#{sfn}")
|
44
68
|
end
|
45
69
|
GF
|
@@ -49,7 +73,10 @@ spawn("guard -G .Guardfile", in: rd, close_others: true)
|
|
49
73
|
|
50
74
|
# wrong: puts settings.port
|
51
75
|
|
52
|
-
|
76
|
+
host = "localhost" if host == "::" # work around macOS peculiarity
|
77
|
+
host = "[#{host}]" if host =~ /:/
|
78
|
+
|
79
|
+
url = "http://#{host}:#{port}"
|
53
80
|
|
54
81
|
spawn("sleep 5; open #{url} || xdg-open #{url} || echo @@@ Please open #{url}")
|
55
82
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kdwatch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carsten Bormann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -100,14 +100,14 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '1.
|
103
|
+
version: '1.5'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '1.
|
110
|
+
version: '1.5'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: net-http-persistent
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- ".gitignore"
|
134
134
|
- Gemfile
|
135
135
|
- LICENSE.txt
|
136
|
+
- README.md
|
136
137
|
- bin/kdwatch
|
137
138
|
- kdwatch.gemspec
|
138
139
|
- lib/kdwatch-app.rb
|
@@ -156,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
157
|
- !ruby/object:Gem::Version
|
157
158
|
version: '0'
|
158
159
|
requirements: []
|
159
|
-
rubygems_version: 3.2.
|
160
|
+
rubygems_version: 3.2.32
|
160
161
|
signing_key:
|
161
162
|
specification_version: 4
|
162
163
|
summary: 'kdwatch: open auto-reloaded HTML for kramdown-rfc in a browser.'
|