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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eaba18036cbe879e4f88d5b74513ad4a5d36abb843234c83c35e688aaaf36e03
4
- data.tar.gz: ea272b95fef2f02ec9513539dee9f4f5126b4e65c3c6a97b0603d94fa7cd37e2
3
+ metadata.gz: 50e6ea6a1e81ab7f17173c1251395a6fbeb1a4b4c236d1c9c6fd1731f3118ca8
4
+ data.tar.gz: 31235eb66b35d5c39ebd1f124e938dfcc9b3f305a020ddf05dc610b7e8832707
5
5
  SHA512:
6
- metadata.gz: 603817fcb75e8b474a4f6bc7d58408c4d8fcc55f7cbd50d1cd6a48f8d21a8b2672f2b221697b9948412e2bf4825dd9925ae10f9a4be6a6360e7c5e54c94c9471
7
- data.tar.gz: 4237a7b045723de06320999301e0c388d879d6f5016b12c7170702b7b24981e302848eb76aad46513cde1a0d37792811165710c865a9cb597064dca17a54eed5
6
+ metadata.gz: 39e2d6062ef4adf87ce11d05c2d18e4d305de91e8212d1c204bc7bd0b8c8086f3c662e59deeaa284779f326bebdbd3c06af6ec993c4bc3ad4ad0dea0a468ee80
7
+ data.tar.gz: 9db4d837a11aea7413de4362bc418cb56fb2f987dc926ab722bd1b8be06850a2a2e51110e78dd75caebec5b2b7280e0b14592910f00478879b127e8724d0b070
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ *.gem
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 ARGV[0] == "-e" || ARGV[0] == "-r"
62
+ if options.replace || options.end
11
63
  require 'open3'
12
64
 
13
65
  status = 1
14
- flag = ARGV.shift
15
66
 
16
- stdout_str, stderr_str, s = Open3.capture3("lsof -ti :#{KDWATCH_PORT} -s TCP:LISTEN")
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 flag == "-r"
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 flag == "-e"
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 "** Usage: #$0 [-r] [draft-foo.md]"
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["KD_WATCH_SRC"] = ARGV[0]
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 #{KDWATCH_PORT} .config.ru")
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.4'
36
+ spec.add_dependency "kramdown-rfc2629", '~> 1.5'
36
37
  spec.add_dependency "net-http-persistent", '~> 4.0'
37
38
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kdwatch
4
- VERSION = "0.1.1"
4
+ VERSION = "0.4.1"
5
5
  end
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["KD_WATCH_SRC"]
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
- system("time kdrfc -3h --no-txt #{sfn}")
28
- warn "...done"
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
- File.read(dfn)
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 'livereload' do
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
- url = "http://127.0.0.1:7991"
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.1.1
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: 2021-07-04 00:00:00.000000000 Z
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.4'
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.4'
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.15
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.'