Index: /trunk/CHANGELOG.md
===================================================================
--- /trunk/CHANGELOG.md	(revision 148)
+++ /trunk/CHANGELOG.md	(revision 149)
@@ -1,5 +1,13 @@
+# v0.2.3 - 2024.03.21
+* Document the configuration file format, which is INI-style (which is compatible to the old format in the codebase, though it's now called as `config.Config.<key>`)
+* Manual page has been rewritten (using `mdoc(7)`)
+* 'YukariSukima' is an incorrect transliteration, use 'Yukari no Sukima' to indicate possession/ownership
+* Remove the 'proxified and sanitized view' text as it should already be obvious
+* The font family used earlier is horrible, changed it to `sans-serif`
+* Bump required Go toolchain version to 1.16 in order to use `//go:embed`
+* Rename some all-uppercase constants/variables to camelCase (I think?), also rename CLIENT to Gap (lol)
+
 # v0.2.1 - 2023.08.26
-Applied some suggestions from the issue tracker, and
-rebrand this fork.
+Applied some suggestions from the [issue tracker](https://github.com/asciimoo/morty/issues), and rebrand this fork.
 
 # v0.2.0 - 2018.05.28
Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 148)
+++ /trunk/Makefile	(revision 149)
@@ -23,5 +23,5 @@
 clean:
 	$(RM) -f yukari
-install:
+install: all
 	$(MKDIR) -p $(DESTDIR)$(PREFIX)/$(BINDIR)
 	$(MKDIR) -p $(DESTDIR)$(PREFIX)/$(MANDIR)/man1
Index: /trunk/README.md
===================================================================
--- /trunk/README.md	(revision 148)
+++ /trunk/README.md	(revision 149)
@@ -20,39 +20,13 @@
 
 ## Installation and setup
-Requirement: Go version 1.16 or higher.
+Requirement: Go version 1.16 or higher (thus making it incompatible with MortyProxy's own requirement, but also to use `go embed`)
 
 ```
-$ go install marisa.chaotic.ninja/yukari@latest
+$ go install marisa.chaotic.ninja/yukari/cmd/yukari@latest
 $ "$GOPATH/bin/yukari" --help
 ```
 
 ### Usage
-
-```
-  -debug
-        Debug mode (default true)
-  -followredirect
-        Follow HTTP GET redirect
-  -hashparam string
-        User-defined requesting string HASH parameter name (ie: '/?hash=...' or '/?h=...') (default "yukarihash")
-  -ipv6
-        Allow IPv6 HTTP requests (default true)
-  -key string
-        HMAC url validation key (base64 encoded) - leave blank to disable validation
-  -listen string
-        Listen address (default "127.0.0.1:3000")
-  -proxy string
-        Use the specified HTTP proxy (ie: '[user:pass@]hostname:port'). Overrides -socks5, -ipv6.
-  -proxyenv
-        Use a HTTP proxy as set in the environment (HTTP_PROXY, HTTPS_PROXY and NO_PROXY). Overrides -proxy, -socks5, -ipv6.
-  -socks5 string
-        Use a SOCKS5 proxy (ie: 'hostname:port'). Overrides -ipv6.
-  -timeout uint
-        Request timeout (default 5)
-  -urlparam string
-        User-defined requesting string URL parameter name (ie: '/?url=...' or '/?u=...') (default "yukariurl")
-  -version
-        Show version
-```
+See `yukari(1)`
 
 ### Environment variables
@@ -82,3 +56,3 @@
 
 ## Bugs
-Bugs or suggestions? Visit the [issue tracker](https://git.chaotic.ninja/yakumo.izuru/yukari/issues).
+Bugs or suggestions? Mail [yukari-dev@chaotic.ninja](mailto:yukari-dev@chaotic.ninja)
Index: /trunk/cmd/yukari/main.go
===================================================================
--- /trunk/cmd/yukari/main.go	(revision 148)
+++ /trunk/cmd/yukari/main.go	(revision 149)
@@ -40,12 +40,12 @@
 )
 
-const MAX_REDIRECT_COUNT = 5
-
-var CLIENT *fasthttp.Client = &fasthttp.Client{
+const MaxRedirectCount = 5
+
+var Gap *fasthttp.Client = &fasthttp.Client{
 	MaxResponseBodySize: 10 * 1024 * 1024, // 10M
 	ReadBufferSize:      16 * 1024,        // 16K
 }
 
-var CSS_URL_REGEXP *regexp.Regexp = regexp.MustCompile("url\\((['\"]?)[ \\t\\f]*([\u0009\u0021\u0023-\u0026\u0028\u002a-\u007E]+)(['\"]?)\\)?")
+var cssURLRegex *regexp.Regexp = regexp.MustCompile("url\\((['\"]?)[ \\t\\f]*([\u0009\u0021\u0023-\u0026\u0028\u002a-\u007E]+)(['\"]?)\\)?")
 
 type Proxy struct {
@@ -77,34 +77,31 @@
 }
 
-var FAVICON_BYTES []byte
-var HTML_FORM_EXTENSION *template.Template
-var HTML_BODY_EXTENSION *template.Template
-var HTML_MAIN_PAGE_FORM *template.Template
+var faviconBytes []byte
+var htmlFormExtension *template.Template
+var htmlBodyExtension *template.Template
+var htmlMainPageForm *template.Template
 
 //go:embed templates/yukari_content_type.html
-var HTML_HEAD_CONTENT_TYPE string
+var htmlHeadContentType string
 //go:embed templates/yukari_start.html
-var YUKARI_HTML_PAGE_START string
+var htmlPageStart string
 //go:embed templates/yukari_stop.html
-var YUKARI_HTML_PAGE_END string
+var htmlPageStop string
 
 func init() {
 	FaviconBase64 := "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAAF0lEQVRIx2NgGAWjYBSMglEwCkbBSAcACBAAAeaR9cIAAAAASUVORK5CYII"
 
-	FAVICON_BYTES, _ = base64.StdEncoding.DecodeString(FaviconBase64)
+	faviconBytes, _ = base64.StdEncoding.DecodeString(FaviconBase64)
 	var err error
-	HTML_FORM_EXTENSION, err = template.New("html_form_extension").Parse(
+	htmlFormExtension, err = template.New("html_form_extension").Parse(
 		`<input type="hidden" name="yukariurl" value="{{.BaseURL}}" />{{if .YukariHash}}<input type="hidden" name="yukarihash" value="{{.YukariHash}}" />{{end}}`)
 	if err != nil {
 		panic(err)
 	}
-	HTML_BODY_EXTENSION, err = template.New("html_body_extension").Parse(`
-<input type="checkbox" id="yukaritoggle" autocomplete="off" />
+	htmlBodyExtension, err = template.New("html_body_extension").Parse(`
 <div id="yukariheader">
   <form method="get">
-    <label for="yukaritoggle">hide</label>
     <span><a href="/">Yukari's Gap</a></span>
     <input type="url" value="{{.BaseURL}}" name="{{.URLParamName}}" {{if .HasYukariKey }}readonly="true"{{end}} />
-    This is a proxified and sanitized view of the page, visit <a href="{{.BaseURL}}" rel="noreferrer">original site.
   </form>
 </div>
@@ -117,6 +114,4 @@
 #yukariheader label { text-align: right; cursor: pointer; position: fixed; right: 4px; top: 4px; display: block; color: #444; }
 #yukariheader > form > span { font-size: 24px; font-weight: bold; margin-right: 20px; margin-left: 20px; }
-input[type=checkbox]#yukaritoggle { display: none; }
-input[type=checkbox]#yukaritoggle:checked ~ div { display: none; visibility: hidden; }
 #yukariheader input[type=url] { width: 50%; padding: 4px; font-size: 16px; }
 </style>
@@ -125,5 +120,5 @@
 		panic(err)
 	}
-	HTML_MAIN_PAGE_FORM, err = template.New("html_main_page_form").Parse(`
+	htmlMainPageForm, err = template.New("html_main_page_form").Parse(`
 	<form action="post">
 	Visit url: <input placeholder="https://url.." name="{{.URLParamName}}" autofocus />
@@ -215,5 +210,5 @@
 	}
 
-	err = CLIENT.DoTimeout(req, resp, p.RequestTimeout)
+	err = Gap.DoTimeout(req, resp, p.RequestTimeout)
 
 	if err != nil {
@@ -235,5 +230,5 @@
 				if p.FollowRedirect && ctx.IsGet() {
 					// GET method: Yukari follows the redirect
-					if redirectCount < MAX_REDIRECT_COUNT {
+					if redirectCount < MaxRedirectCount {
 						if config.Config.Debug {
 							log.Println("follow redirect to", string(loc))
@@ -345,5 +340,5 @@
 				p.HasYukariKey = true
 			}
-			err := HTML_BODY_EXTENSION.Execute(ctx, p)
+			err := htmlBodyExtension.Execute(ctx, p)
 			if err != nil {
 				if config.Config.Debug {
@@ -394,5 +389,5 @@
 	if bytes.Equal(ctx.Path(), []byte("/favicon.ico")) {
 		ctx.SetContentType("image/png")
-		ctx.Write(FAVICON_BYTES)
+		ctx.Write(faviconBytes)
 		return true
 	}
@@ -416,5 +411,5 @@
 	// TODO
 
-	urlSlices := CSS_URL_REGEXP.FindAllSubmatchIndex(css, -1)
+	urlSlices := cssURLRegex.FindAllSubmatchIndex(css, -1)
 
 	if urlSlices == nil {
@@ -532,5 +527,5 @@
 
 				if bytes.Equal(tag, []byte("head")) {
-					fmt.Fprintf(out, HTML_HEAD_CONTENT_TYPE)
+					fmt.Fprintf(out, htmlHeadContentType)
 				}
 
@@ -552,5 +547,5 @@
 						key = hash(urlStr, rc.Key)
 					}
-					err := HTML_FORM_EXTENSION.Execute(out, HTMLFormExtParam{urlStr, key, config.Config.UrlParameter, config.Config.HashParameter})
+					err := htmlFormExtension.Execute(out, HTMLFormExtParam{urlStr, key, config.Config.UrlParameter, config.Config.HashParameter})
 					if err != nil {
 						if config.Config.Debug {
@@ -569,5 +564,5 @@
 						p.HasYukariKey = true
 					}
-					err := HTML_BODY_EXTENSION.Execute(out, p)
+					err := htmlBodyExtension.Execute(out, p)
 					if err != nil {
 						if config.Config.Debug {
@@ -873,5 +868,5 @@
 	ctx.SetContentType("text/html")
 	ctx.SetStatusCode(403)
-	ctx.Write([]byte(YUKARI_HTML_PAGE_START))
+	ctx.Write([]byte(htmlPageStart))
 	ctx.Write([]byte("<h2>You are about to exit Yukari no Sukima</h2>"))
 	ctx.Write([]byte("<p>Following</p><p><a href=\""))
@@ -880,5 +875,5 @@
 	ctx.Write([]byte(html.EscapeString(uri.String())))
 	ctx.Write([]byte("</a></p><p>the content of this URL will be <b>NOT</b> sanitized.</p>"))
-	ctx.Write([]byte(YUKARI_HTML_PAGE_END))
+	ctx.Write([]byte(htmlPageStop))
 }
 
@@ -886,5 +881,5 @@
 	ctx.SetContentType("text/html; charset=UTF-8")
 	ctx.SetStatusCode(statusCode)
-	ctx.Write([]byte(YUKARI_HTML_PAGE_START))
+	ctx.Write([]byte(htmlPageStart))
 	if err != nil {
 		if config.Config.Debug {
@@ -897,5 +892,5 @@
 	if p.Key == nil {
 		p := HTMLMainPageFormParam{config.Config.UrlParameter}
-		err := HTML_MAIN_PAGE_FORM.Execute(ctx, p)
+		err := htmlMainPageForm.Execute(ctx, p)
 		if err != nil {
 			if config.Config.Debug {
@@ -906,5 +901,5 @@
 		ctx.Write([]byte(`<h3>Warning! This instance does not support direct URL opening.</h3>`))
 	}
-	ctx.Write([]byte(YUKARI_HTML_PAGE_END))
+	ctx.Write([]byte(htmlPageStop))
 }
 
@@ -912,10 +907,8 @@
 	var configFile string
 	var proxy string
-	var proxyEnv bool
 	var socks5 string
 	var version bool
 
 	flag.StringVar(&configFile, "f", "", "Configuration file")
-	flag.BoolVar(&proxyEnv, "proxyenv", false, "Use a HTTP proxy as set in the environment (HTTP_PROXY, HTTPS_PROXY and NO_PROXY). Overrides: -proxy, -socks5, IPv6")
 	flag.StringVar(&proxy, "proxy", "", "Use the specified HTTP proxy (ie: '[user:pass@]hostname:port'). Overrides: -socks5, IPv6")
 	flag.StringVar(&socks5, "socks5", "", "Use a SOCKS5 proxy (ie: 'hostname:port'). Overrides: IPv6.")
@@ -931,5 +924,6 @@
 	config.Config.UrlParameter = "yukariurl"
 	config.Config.HashParameter = "yukarihash"
-	config.Config.MaxConnsPerHost = 4
+	config.Config.MaxConnsPerHost = 5
+	config.Config.ProxyEnv = false
 
 	if version {
@@ -938,23 +932,26 @@
 	}
 
-	if proxyEnv && os.Getenv("HTTP_PROXY") == "" && os.Getenv("HTTPS_PROXY") == "" {
+	if config.Config.ProxyEnv && os.Getenv("HTTP_PROXY") == "" && os.Getenv("HTTPS_PROXY") == "" {
 		log.Fatal("Error -proxyenv is used but no environment variables named 'HTTP_PROXY' and/or 'HTTPS_PROXY' could be found.")
 		os.Exit(1)
 	}
 
-	if proxyEnv {
-		CLIENT.Dial = fasthttpproxy.FasthttpProxyHTTPDialer()
+	if config.Config.ProxyEnv {
+		config.Config.IPV6 = false
+		Gap.Dial = fasthttpproxy.FasthttpProxyHTTPDialer()
 		log.Println("Using environment defined proxy(ies).")
 	} else if proxy != "" {
-		CLIENT.Dial = fasthttpproxy.FasthttpHTTPDialer(proxy)
+		config.Config.IPV6 = false
+		Gap.Dial = fasthttpproxy.FasthttpHTTPDialer(proxy)
 		log.Println("Using custom HTTP proxy.")
 	} else if socks5 != "" {
-		CLIENT.Dial = fasthttpproxy.FasthttpSocksDialer(socks5)
+		config.Config.IPV6 = false
+		Gap.Dial = fasthttpproxy.FasthttpSocksDialer(socks5)
 		log.Println("Using Socks5 proxy.")
 	} else if config.Config.IPV6 {
-		CLIENT.Dial = fasthttp.DialDualStack
+		Gap.Dial = fasthttp.DialDualStack
 		log.Println("Using dual stack (IPv4/IPv6) direct connections.")
 	} else {
-		CLIENT.Dial = fasthttp.Dial
+		Gap.Dial = fasthttp.Dial
 		log.Println("Using IPv4 only direct connections.")
 	}
Index: /trunk/config/config.go
===================================================================
--- /trunk/config/config.go	(revision 148)
+++ /trunk/config/config.go	(revision 149)
@@ -15,4 +15,5 @@
 	UrlParameter string
 	HashParameter string
+	ProxyEnv bool
 }
 
@@ -31,5 +32,5 @@
 	Config.UrlParameter = cfg.Section("yukari").Key("urlparam").String()
 	Config.HashParameter = cfg.Section("yukari").Key("hashparam").String()
-
+	Config.ProxyEnv, _ = cfg.Section("yukari").Key("proxyenv").Bool()
 	return nil
 }
Index: /trunk/yukari.ini.5
===================================================================
--- /trunk/yukari.ini.5	(revision 149)
+++ /trunk/yukari.ini.5	(revision 149)
@@ -0,0 +1,40 @@
+.Dd $Mdocdate$
+.Dt YUKARI.INI 5
+.Os
+.Sh NAME
+.Nm yukari.ini
+.Nd INI-style configuration file for
+.Xr yukari 1
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It debug (bool)
+Enable/disable proxy and redirection logs (default true)
+.It listen (string)
+Listen address (default "127.0.0.1:3000")
+.It key (string)
+HMAC url validation key (base64 encoded) - leave blank to disable validation
+.It ipv6 (bool)
+Enable IPv6 support for queries
+(can be overrided by the proxy options, default true)
+.It timeout (uint)
+Request timeout (default 5)
+.It followredirect (bool)
+Follow HTTP GET redirect (default false)
+.It max_conns_per_host (uint)
+How much connections are allowed per Host/IP (default 4)
+.It urlparam (string)
+User-defined requesting string URL parameter name
+(ie: '/?url=...' or '/?u=...') (default "yukariurl")
+.It hashparam (string)
+User-defined requesting string HASH parameter name
+(ie: '/?hash=...' or '/?h=...') (default "yukarihash")
+.It proxyenv (string)
+Use a HTTP proxy as set in the environment
+(
+.Ev HTTP_PROXY ,
+.Ev HTTPS_PROXY ,
+.Ev NO_PROXY
+) (overrides ipv6, default false)
+.El
+.Sh AUTHORS
+.An Izuru Yakumo Aq Mt yakumo.izuru@chaotic.ninja
