summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordweller <dweller@cabin.digital>2024-02-26 11:47:32 +0200
committerdweller <dweller@cabin.digital>2024-02-26 11:47:32 +0200
commitf0181813ecf9867f13a206d87fc46b15d295acbc (patch)
treeb1b6f94e6a2318010cb322bbd119356b46076dd4
parenta87359aaacac66655af6baa80ced112ac842f651 (diff)
wire up frontend with PHP, badly
-rw-r--r--common.php8
-rw-r--r--index.php (renamed from index.html)36
-rw-r--r--js/copy.js32
-rw-r--r--js/lmmtfy.js32
-rw-r--r--main.php0
-rw-r--r--search.html94
-rw-r--r--search.php124
-rw-r--r--style/main.css29
-rw-r--r--style/man.css2
-rw-r--r--style/search.css16
10 files changed, 250 insertions, 123 deletions
diff --git a/common.php b/common.php
new file mode 100644
index 0000000..b7b588d
--- /dev/null
+++ b/common.php
@@ -0,0 +1,8 @@
+<?php
+ $root = (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
+ $manpath = "/usr/share/man";
+
+ $action = trim(urldecode($_GET['action'] ?? null));
+ $query = trim(urldecode($_GET['query'] ?? null));
+ $section = trim(urldecode($_GET['section'] ?? null));
+?>
diff --git a/index.html b/index.php
index 561746a..23e9ccb 100644
--- a/index.html
+++ b/index.php
@@ -1,3 +1,6 @@
+<?php
+ require 'common.php';
+?>
<!DOCTYPE html>
<html lang="en">
<head>
@@ -26,28 +29,37 @@
</header>
<section id="logo">
<h1>
- <span id="gc-let">Let</span>
- <span id="gc-me">me</span>
- <code id="gc-man">man</code>
- <span id="gc-that">that</span>
- <span id="gc-for">For</span>
- <span id="gc-you">you</span>
+ <span id="logo-let">Let</span>
+ <span id="logo-me">me</span>
+ <code id="logo-man">man</code>
+ <span id="logo-that">that</span>
+ <span id="logo-for">For</span>
+ <span id="logo-you">you</span>
</h1>
- <div id="version_wrap">
- <span id="version">BETA!</span>
+ <div id="logo-ver_wrap">
+ <span id="logo-ver">BETA!</span>
</div>
</section>
<nav id="search_pane">
- <form>
+ <form action="/search.php">
<div id="query_wrap">
<div id="query_icon"></div>
- <input id="query" type='search' value='' name='query' required autofocus/>
+ <input id="query" type='search' value='<?php if($action === 'lmmtfy') echo $query;?>' name='query' required autofocus/>
+ <button id="def" type='submit' value='man' name='action' class="btn-def" aria-hidden="true" tabindex="-1"></button>
+ <?php
+ if($action === 'lmmtfy')
+ echo '<input id="sect" type="hidden" value="' . $section . '" name= "section"/>';
+ ?>
</div>
<div>
<button id="mank" type='submit' value='apropos' name='action' title="apropos(1)">man -k</button>
<button id="man" type='submit' value='man' name='action' title="Feeling lucky, punk?">man</button>
</div>
</form>
+ <?php
+ if($action === 'lmmtfy')
+ echo '<noscript class="center"><p>No JavaScript means you have to manually press the <code>man</code> button.</p></noscript>';
+ ?>
<p class="hint center">Write "man" if you have no idea what to do...</p>
</nav>
@@ -72,4 +84,8 @@
</nav>
</div>
</body>
+
+<?php
+ if($action === 'lmmtfy') echo '<script src="js/lmmtfy.js"></script>';
+?>
</html>
diff --git a/js/copy.js b/js/copy.js
new file mode 100644
index 0000000..3bc7707
--- /dev/null
+++ b/js/copy.js
@@ -0,0 +1,32 @@
+const dom_lmmtfy = document.getElementById("lmmtfy_url");
+const dom_copy = document.getElementById("lmmtfy_copy");
+
+dom_copy.onclick = lmmtfy_copy;
+
+function lmmtfy_copy()
+{
+ dom_lmmtfy.focus();
+ dom_lmmtfy.select();
+
+ try
+ {
+ // TODO: deprecated -- https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand
+ if(document.execCommand('copy'))
+ dom_copy.innerHTML = "Copied!"
+
+ setTimeout(() =>
+ {
+ dom_copy.innerHTML = "Copy"
+ }, 3000);
+
+ }
+ catch(err)
+ {
+ dom_copy.innerHTML = "Error :(";
+ console.log('Oops, unable to copy');
+ }
+
+ // This unfocuses the element, but W3C decided to be funny with
+ // the naming.
+ document.activeElement.blur();
+}
diff --git a/js/lmmtfy.js b/js/lmmtfy.js
new file mode 100644
index 0000000..d0410ab
--- /dev/null
+++ b/js/lmmtfy.js
@@ -0,0 +1,32 @@
+const dom_query = document.getElementById("query");
+const dom_sect = document.getElementById("sect");
+const dom_man = document.getElementById("man");
+
+const query = dom_query.value;
+dom_query.value = "";
+
+let i = 0, j = 0;
+let elapsed = 0;
+let actions =
+[
+ [250, () => { dom_query.focus(); }, 1],
+ [150, () => { dom_query.value += query[j++]; }, query.length],
+ [250, () => { dom_man.focus(); }, 1],
+ [250, () => { dom_man.click(); }, 1],
+];
+
+function do_stuff()
+{
+ elapsed += 50;
+
+ if((elapsed % actions[i][0]) == 0)
+ {
+ actions[i][1]();
+ actions[i][2]--;
+ if(actions[i][2] <= 0) i++;
+ }
+
+ setTimeout(do_stuff, 50);
+}
+
+do_stuff();
diff --git a/main.php b/main.php
deleted file mode 100644
index e69de29..0000000
--- a/main.php
+++ /dev/null
diff --git a/search.html b/search.html
deleted file mode 100644
index 37031f3..0000000
--- a/search.html
+++ /dev/null
@@ -1,94 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-
- <title>Manup &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; Lonely MAN near You</title>
-
- <link rel="icon" type="image/png" sizes="128x128" href="imgs/logo-goog.png"/>
- <link rel="icon" type="image/png" sizes="32x32" href="imgs/logo-goog32.png"/>
- <link rel="icon" type="image/png" sizes="16x16" href="imgs/logo-goog16.png"/>
- <!--<link rel="icon" type="image/x-icon" sizes="16x16" href="imgs/logo-goog16.ico"/>-->
-
- <link rel="stylesheet" href="style/normalize.css"/>
- <link rel="stylesheet" href="style/main.css"/>
- <link rel="stylesheet" href="style/search.css"/>
- </head>
- <body>
- <div id="main">
- <header>
- <a id="logo" href="/">
- <h1>
- <span id="gc-let">L</span>
- <span id="gc-me">m</span>
- <code id="gc-man">m</code>
- <span id="gc-that">t</span>
- <span id="gc-for">F</span>
- <span id="gc-you">y</span>
- </h1>
- <div id="version_wrap">
- <span id="version">BETA!</span>
- </div>
- </a>
- <nav id="search_pane">
- <form>
- <div id="query_wrap">
- <input id="query" type='searcg' value='man' name='query' required/>
- <button id="mank" type='submit' value='apropos' name='action' title="apropos(1)">-k</button>
- <button id="man" type='submit' value='man' name='action' title="Feeling lucky, punk?" class="btn-acc">
- <div id="query_icon"></div>
- </button>
- </div>
- </form>
- </nav>
- <nav id="topnav">
- <a href="https://cabin.digital">Cabin</a>
- <a href="#"><span id="topnav_icon"></span></a>
- <button class="btn-acc">Man up</button>
- </nav>
- </header>
- <section id="results">
- <p class="hint"> Found 14 results</p>
- <dl>
- <dt><a href="/page.html">man (1)</dt></a>
- <dd>an interface to the system reference manuals</dd>
- <dt><a href="#2">manconv (1)</dt></a>
- <dd>convert manual page from one encoding to another</dd>
- <dt><a href="#3">mandb (8)</dt></a>
- <dd>create or update the manual page index caches</dd>
- <dt><a href="#4">mandoc (1)</dt></a>
- <dd>format manual pages</dd>
- <dt><a href="#5">mandoc.db (5)</dt></a>
- <dd>manual page database</dd>
- <dt><a href="#6">mandoc_char (7)</dt></a>
- <dd>mandoc special characters</dd>
- <dt><a href="#7">mandoc_eqn (7)</dt></a>
- <dd>eqn language reference for mandoc</dd>
- <dt><a href="#8">mandoc_man (7)</dt></a>
- <dd>legacy formatting language for manual pages</dd>
- <dt><a href="#9">mandoc_mdoc (7)</dt></a>
- <dd>semantic markup language for formatting manual pages</dd>
- <dt><a href="#10">mandoc_roff (7)</dt></a>
- <dd>roff language reference for mandoc</dd>
- <dt><a href="#11">mandoc_tbl (7)</dt></a>
- <dd>tbl language reference for mandoc</dd>
- <dt><a href="#12">mandocd (8)</dt></a>
- <dd>server process to format manual pages in batch mode</dd>
- <dt><a href="#13">manpath (1)</dt></a>
- <dd>determine search path for manual pages</dd>
- <dt><a href="#14">manpath (5)</dt></a>
- <dd>format of the /etc/manpath.config file</dd>
- </dl>
- </section>
- <footer>
- <p class="center">
- Copyleft <span class="copyleft">&copy;</span> 2024
- <a href="mailto:manup@cabin.digital">dweller</a> from
- <a href="https://cabin.digital">cabin.digital</a>.
- All Wrongs Reserved.
- </p>
- </footer>
- </div>
- </body>
-</html>
diff --git a/search.php b/search.php
new file mode 100644
index 0000000..a66fc41
--- /dev/null
+++ b/search.php
@@ -0,0 +1,124 @@
+<?php
+ require 'common.php';
+?>
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+
+ <title>Manup &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; &emsp; Lonely MAN near You</title>
+
+ <link rel="icon" type="image/png" sizes="128x128" href="imgs/logo-goog.png"/>
+ <link rel="icon" type="image/png" sizes="32x32" href="imgs/logo-goog32.png"/>
+ <link rel="icon" type="image/png" sizes="16x16" href="imgs/logo-goog16.png"/>
+ <!--<link rel="icon" type="image/x-icon" sizes="16x16" href="imgs/logo-goog16.ico"/>-->
+
+ <link rel="stylesheet" href="style/normalize.css"/>
+ <link rel="stylesheet" href="style/main.css"/>
+ <link rel="stylesheet" href="style/search.css"/>
+ <link rel="stylesheet" href="style/man.css"/>
+ </head>
+ <body>
+ <div id="main">
+ <header>
+ <a id="logo" href="/">
+ <h1>
+ <span id="logo-let">L</span>
+ <span id="logo-me">m</span>
+ <code id="logo-man">m</code>
+ <span id="logo-that">t</span>
+ <span id="logo-for">F</span>
+ <span id="logo-you">y</span>
+ </h1>
+ <div id="logo-ver_wrap">
+ <span id="logo-ver">BETA!</span>
+ </div>
+ </a>
+ <nav id="search_pane">
+ <form>
+ <div id="query_wrap">
+ <input id="query" type='searcg' value='<?=$query;?>' name='query' required/>
+ <button id="def" type='submit' value='man' name='action' class="btn-def" aria-hidden="true" tabindex="-1"></button>
+ <button id="mank" type='submit' value='apropos' name='action' title="apropos(1)">-k</button>
+ <button id="man" type='submit' value='man' name='action' title="Feeling lucky, punk?" class="btn-acc">
+ <div id="query_icon"></div>
+ </button>
+ </div>
+ </form>
+ </nav>
+ <nav id="topnav">
+ <a href="https://cabin.digital">Cabin</a>
+ <a href="#"><span id="topnav_icon"></span></a>
+ <button class="btn-acc">Man up</button>
+ </nav>
+ </header>
+ <section id="results">
+<?php
+ $found_man = false;
+ if($action === "man")
+ {
+ $arg_section = "";
+ if(!empty($section))
+ $arg_section = "-s ". escapeshellarg($section);
+
+ $res = exec("man -M $manpath -T html -O fragment $arg_section "
+ . escapeshellarg($query), $lines, $ret);
+ if($ret === 0)
+ {
+ $url = "$root/?query=". urlencode($query) ."&ampsection=1&action=lmmtfy";
+
+ echo "<nav id='lmmtfy'><div><div>";
+ echo " <label for='lmmtfy_url'>LmmtFy URL</label></div>";
+ echo " <textarea id='lmmtfy_url' wrap='off' rows='1' readonly>".$url."</textarea>";
+ echo " <button id='lmmtfy_copy' class='jsonly'>Copy</button></div><nav>";
+ echo "<article class='manpage'>". implode(PHP_EOL, $lines) ."</article>";
+ echo "<script src='/js/copy.js'></script>";
+
+ $found_man = true;
+ }
+ }
+
+ if(($action === "apropos") || !$found_man)
+ {
+ $res = exec("man -M $manpath -k " . escapeshellarg($query), $lines, $ret);
+ if($ret === 0)
+ {
+ $n = count($lines);
+ $s = $n > 1 ? "s" : "";
+ echo "<p class='hint'> Found $n result$s</p>";
+
+ foreach($lines as $line)
+ {
+ $split = explode(") - ", $line);
+ $full = $split[0];
+ $desc = $split[1];
+
+ $split = explode("(", $full);
+ $name = explode(",", $split[0])[0];
+ $sect = strtolower(explode(",", $split[1])[0]);
+
+ $url = "$root/search.php?query=". urlencode($name) ."&section=". urlencode($sect)
+ ."&action=man";
+
+ echo '<dl>';
+ echo " <dt><a href='".$url."'>$full)</a></dt>";
+ echo " <dd>$desc</dd>";
+ echo '</dl>';
+ }
+ }
+ else echo "<p class='hint'> No results.</p>";
+ }
+?>
+ </section>
+ <footer>
+ <p class="center">
+ Copyleft <span class="copyleft">&copy;</span> 2024
+ <a href="mailto:manup@cabin.digital">dweller</a> from
+ <a href="https://cabin.digital">cabin.digital</a>.
+ All Wrongs Reserved.
+ </p>
+ </footer>
+ </div>
+ </body>
+</html>
diff --git a/style/main.css b/style/main.css
index f373e37..0f76c33 100644
--- a/style/main.css
+++ b/style/main.css
@@ -190,14 +190,14 @@ a:hover { text-decoration: underline; }
font-size: 32pt;
}
-#gc-let { color: var(--logo-a); font-size: 46pt; }
-#gc-me { color: var(--logo-b); }
-#gc-man { color: var(--logo-c); font-family: fn-code-logo, monospace; font-size: 30pt; }
-#gc-that { color: var(--logo-a); }
-#gc-for { color: var(--logo-d); font-size: 38pt; }
-#gc-you { color: var(--logo-b); display: inline-block; transform: rotate(-2.5deg); }
+#logo-let { color: var(--logo-a); font-size: 46pt; }
+#logo-me { color: var(--logo-b); }
+#logo-man { color: var(--logo-c); font-family: fn-code-logo, monospace; font-size: 30pt; }
+#logo-that { color: var(--logo-a); }
+#logo-for { color: var(--logo-d); font-size: 38pt; }
+#logo-you { color: var(--logo-b); display: inline-block; transform: rotate(-2.5deg); }
-@keyframes verscale
+@keyframes logo-ver_scale
{
0%, 100%
{
@@ -211,13 +211,13 @@ a:hover { text-decoration: underline; }
}
}
-#version_wrap
+#log-ver_wrap
{
display: block;
min-height: 30pt;
}
-#version
+#logo-ver
{
display: block;
float: right;
@@ -227,7 +227,7 @@ a:hover { text-decoration: underline; }
color: var(--fg);
- animation: verscale 3.5s ease infinite;
+ animation: logo-ver_scale 3.5s ease infinite;
}
#search_pane
@@ -344,6 +344,15 @@ button:focus, input[type=submit]:focus
border: 1px solid var(--abtn-brdf);
}
+.btn-def
+{
+ width: 0 !important;
+ height: 0 !important;
+ padding: 0 !important;
+ border: 0 !important;
+ margin: 0 !important;
+}
+
.hint { color: var(--fg-light); }
.center { text-align: center; }
diff --git a/style/man.css b/style/man.css
index b804d45..ee0cfa9 100644
--- a/style/man.css
+++ b/style/man.css
@@ -10,7 +10,7 @@
margin-top: 3em;
margin-bottom: 1em;
- width: min(100% - 3rem, 10in);
+ width: min(100% - 5rem, 10in);
}
#lmmtfy
diff --git a/style/search.css b/style/search.css
index 8412b76..73ed99c 100644
--- a/style/search.css
+++ b/style/search.css
@@ -14,12 +14,12 @@
#logo { font-size: 1rem; }
#logo > h1 { font-size: 1.5rem; }
-#gc-let { font-size: 1.25em; }
-#gc-me { font-size: 1em; }
-#gc-man { font-size: 0.9em; }
-#gc-that { font-size: 1em; }
-#gc-for { font-size: 1.15em; }
-#gc-you { font-size: 1em; }
+#logo-let { font-size: 1.25em; }
+#logo-me { font-size: 1em; }
+#logo-man { font-size: 0.9em; }
+#logo-that { font-size: 1em; }
+#logo-for { font-size: 1.15em; }
+#logo-you { font-size: 1em; }
#main
{
@@ -97,7 +97,7 @@
margin: 3pt 0 0 0;
}
-@keyframes verscale
+@keyframes logo-ver_scale
{
0%, 100% { transform: rotate(-10deg); }
50% { transform: rotate( 10deg); }
@@ -162,5 +162,5 @@
}
#query_wrap { width: min(42rem, 95dvw); }
- #version_wrap { min-height: 15pt; }
+ #logo-ver_wrap { min-height: 15pt; }
}