diff options
89 files changed, 1754 insertions, 1827 deletions
| @@ -1,11 +1,12 @@  .PHONY: check clean serve -gendeps   = ${filter-out %/index.html,${wildcard ${1}/*}} +gendeps   = ${filter-out %/index.gsp,${wildcard ${1}/*}}  includes := ${wildcard include/*}  srcdirs  := ${shell find src -type d}  outdirs  := ${srcdirs:src%=out%} -sources  := ${shell find src -type f -regextype egrep -regex '.*/(index\.html|.*\.(css|svg|png|dot))'} +sources  := ${shell find src -type f -regextype egrep -regex '.*/(index\.gsp|.*\.(css|svg|png|dot))'}  outputs  := ${sources:src/%=out/%} +outputs  := ${outputs:%.gsp=%.html}  outputs  := ${outputs:%.dot=%.svg}  all: ${outdirs} ${outputs} fonts @@ -24,21 +25,22 @@ out/%.svg: src/%.dot  	@dot -Tsvg $< >$@  	@printf 'DOT\t%s\n' "$@" -out/%.html: src/%.html ${includes} src/style.css -	@PATH="$$PATH:./include" m4 -P ${foreach dir,${^D},-I${dir}} include/lib.m4 $< >$@ -	@printf 'M4\t%s\n' "$@" +out/%.html: src/%.gsp ${includes} src/style.css +	@PATH="$$PATH:./include" \ +	m4 -P ${foreach dir,${^D},-I${dir}} include/lib.m4 $< | gsp >$@ +	@printf 'GSP\t%s\n' "$@" -src/srp/fw-ec/index.html: ${call gendeps,src/srp/fw-ec} +src/srp/fw-ec/index.gsp: ${call gendeps,src/srp/fw-ec}  	@touch $@ -src/prj/mmv/index.html: ${call gendeps,src/prj/mmv} +src/prj/mmv/index.gsp: ${call gendeps,src/prj/mmv}  	@touch $@ -src/prj/mkpass/index.html: ${call gendeps,src/prj/mkpass} +src/prj/mkpass/index.gsp: ${call gendeps,src/prj/mkpass}  	@touch $@ -src/prj/totp/index.html: ${call gendeps,src/prj/totp} +src/prj/totp/index.gsp: ${call gendeps,src/prj/totp}  	@touch $@  check: -	LANG=en_US.UTF-8 find src -name 'index.html' -exec \ +	LANG=en_US.UTF-8 find src -name 'index.gsp' -exec \  		aspell --home-dir=./ --ignore-case check {} \;  clean: diff --git a/include/fmt-code b/include/fmt-code index 9da3828..c02a389 100755 --- a/include/fmt-code +++ b/include/fmt-code @@ -1,3 +1,3 @@  #!/bin/sh -sed 's|.*|<code>&</code>|' "${2%/*}/$1" +sed 's|.*|>code{-&}|; $s/>//' "${2%/*}/$1" diff --git a/include/footer.html b/include/footer.gsp index 6b45a2c..f613fcf 100644 --- a/include/footer.html +++ b/include/footer.gsp @@ -1,14 +1,14 @@  m4_define(m4___id__, m4_esyscmd(git rev-list -1 HEAD m4___caller__)) -<small> +small {-  	Page last edited: -	<a +	@a  		href="https://git.thomasvoss.com/www.thomasvoss.com/commit?id=m4___id__"  		target="_blank" -	> +	{-  		m4_esyscmd(  			git log -1 --pretty='format:%cI' m4___caller__ \  				| ifne xargs date +'%A %d %B %Y — %T %Z' -d \  				| ifne -n echo 'No commit yet…'  		) -	</a> -</small> +	} +} diff --git a/include/head.gsp b/include/head.gsp new file mode 100644 index 0000000..407589a --- /dev/null +++ b/include/head.gsp @@ -0,0 +1,5 @@ +meta charset="UTF-8" {} +meta name="viewport" content="width=device-width, initial-scale=1.0" {} +link href="/favicon.svg" rel="shortcut icon" type="image/svg" {} +link href="/style.css" rel="stylesheet" {} +title {-The Mango Tree} diff --git a/include/head.html b/include/head.html deleted file mode 100644 index 97aa283..0000000 --- a/include/head.html +++ /dev/null @@ -1,5 +0,0 @@ -<meta charset="UTF-8"> -<meta name="viewport" content="width=device-width, initial-scale=1.0"> -<link href="/favicon.svg" rel="shortcut icon" type="image/svg"> -<link href="/style.css" rel="stylesheet"> -<title>The Mango Tree</title> diff --git a/include/lib.m4 b/include/lib.m4 index 34cf2c3..3d0e50f 100644 --- a/include/lib.m4 +++ b/include/lib.m4 @@ -2,12 +2,27 @@ m4_dnl To avoid annoying conflicts with quote characters, use  m4_dnl U+2068 FIRST STRONG ISOLATE and U+2069 POP DIRECTIONAL ISOLATE  m4_changequote(,) +m4_dnl We also need to avoid the comment character ever doing absolutely +m4_dnl anything.  I don’t think I’ll ever use ASCII character 1 (SOH) lol. +m4_changecom() + +m4_dnl Macro to create a page footer  m4_define(  	m4_footer, -	m4_define(m4___caller__, m4___file__)m4_include(footer.html) +	m4_define(m4___caller__, m4___file__)m4_include(footer.gsp)  ) +m4_dnl Macro to properly format code blocks  m4_define(  	m4_fmt_code,  	m4_esyscmd(fmt-code "$1" m4___file__)m4_dnl  ) + +m4_dnl Macro to escape characters in gsp(5) text-nodes +m4_define( +	m4_gsp_quote, +	m4_patsubst($1, [@}\\], \\\&) +) + +m4_dnl Macro for generating abbrevations +m4_define(m4_abbr, @abbr .m4_translit($1, A-Z2, a-zt) {-$1}) diff --git a/include/nav.gsp b/include/nav.gsp new file mode 100644 index 0000000..93a7ae5 --- /dev/null +++ b/include/nav.gsp @@ -0,0 +1,4 @@ +menu { +  li {a href="/"  {-Home}} +	li {a href=".." {-Back}} +} diff --git a/include/nav.html b/include/nav.html deleted file mode 100644 index 9f8f2c2..0000000 --- a/include/nav.html +++ /dev/null @@ -1,4 +0,0 @@ -<menu> -	<li><a href="/">Home</a></li> -	<li><a href="..">Back</a></li> -</menu> diff --git a/src/ame/index.gsp b/src/ame/index.gsp new file mode 100644 index 0000000..e0ed55b --- /dev/null +++ b/src/ame/index.gsp @@ -0,0 +1,92 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-About Me} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						One obvious advantage [of lisp syntax] is that there hardly *is* any +						syntax.  You can learn enough Lisp syntax to write useful programs +						in about ten minutes. +					} +				} +				figcaption {-Mark J. Dominus} +			} +		} + +		main { +			p {- +				If you are a prospective employer, you can view my m4_abbr(CV) +				@a href="https://cv.thomasvoss.com" target="_blank" {-here}. +			} + +			h2 {-Who Am I} + +			p {- +				I’m Thomas.  A self-taught software developer from Brazil and the +				Netherlands who grew up in the Middle East.  I started to code at the +				age of 9, writing batch scripts @x-ref {-1} on my schools Windows 7 +				machines to toggle folder visibility with a password.  That became +				necessary because the genius m4_abbr(IT) guys at our school decided we +				should all save our work onto a shared m4_abbr(NAS) where everyone has +				read+write access to everyone elses work.  @em {-How could that ever go +				wrong.} +			} + +			aside { +				p data-ref="1" {- +					Shoutouts to +					@a +						href="https://www.instructables.com/member/Prof.%20Pickle/" +						target="_blank" +					{- +						Prof. Pickle on Instructables +					} +					by the way.  Most of his stuff seems to have been deleted all these +					years later, but he was the guy I learnt to code from. +				} +			} + +			p {- +				These days my interests lie mostly in m4_abbr(CLI) development.  I take +				a great joy in writing simple yet highly effective tools to solve +				problems not only in the easiest way, but also in the most extensible +				way possible.  I think my batch file-renaming utility @em {-mmv} +				@a href="/prj/mmv" {-does a great job at that}. +			} + +			p {- +				That being said, I also have a great interest in operating systems, +				shells, and really anything that could be considered remotely low-level. +				I’m not totally afraid of front-end development, although I @em {-did} +				write this site in plain m4_abbr(HTML) and m4_abbr(CSS) because modern +				m4_abbr(HTML) frameworks are the worst excuses for software I have ever +				seen. +			} + +			p {- +				As for my religious- and political beliefs, let’s make those +				clear: +				@ul { +					li {-Spaces should never be used for indentation} +					li {-Tabs should never be used for alignment} +					li {-Emacs is better than Vim} +					li {-The dominance of VSCode is an embarrassment to our industry} +					li {- +						Object-oriented programming, Java, JavaScript, and m4_abbr(XML) were +						all massive mistakes +					} +					li {-C is far superior to C++} +					li {-Rust is not gods chosen language (even if it’s pretty cool)} +				} +			} +		} + +		footer { m4_footer } +	} +} diff --git a/src/ame/index.html b/src/ame/index.html deleted file mode 100644 index 20ebacd..0000000 --- a/src/ame/index.html +++ /dev/null @@ -1,105 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -    <head> -		m4_include(head.html) -    </head> -    <body> -		<header> -			<div> -				<h1>About Me</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>One obvious advantage [of lisp syntax] is that there -						hardly *is* any syntax.  You can learn enough Lisp -						syntax to write useful programs in about ten minutes.</p> -				</blockquote> -				<figcaption> -					Mark J. Dominus -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				If you are a prospective employer, you can view -				my <abbr class="cv">CV</abbr> -				<a href="https://cv.thomasvoss.com" target="_blank">here</a>. -			</p> - -			<h2>Who Am I</h2> -			 -			<p> -				I’m Thomas.  A self-taught software developer from Brazil and -				the Netherlands who grew up in the Middle East.  I started to -				code at the age of 9, writing batch scripts <x-ref>1</x-ref> on -				my schools Windows 7 machines to toggle folder visibility with a -				password.  That became necessary because the -				genius <abbr class="it">IT</abbr> guys at our school decided we -				should all save our work onto a -				shared <abbr class="nas">NAS</abbr> where everyone has -				read+write access to everyone elses work.  <em>How could that -				ever go wrong.</em> -			</p> - -			<aside> -				<p data-ref="1"> -					Shoutouts -					to <a href="https://www.instructables.com/member/Prof.%20Pickle/" -					target="_blank">Prof. Pickle on Instructables</a> by the -					way.  Most of his stuff seems to have been deleted all these -					years later, but he was the guy I learnt to code from. -				</p> -			</aside> - -			<p> -				These days my interests lie mostly -				in <abbr class="cli">CLI</abbr> development.  I take a great joy -				in writing simple yet highly effective tools to solve problems -				not only in the easiest way, but also in the most extensible way -				possible.  I think my batch file-renaming -				utility <em>mmv</em> <a href="/prj/mmv">does a great job at -				that</a>. -			</p> - -			<p> -				That being said, I also have a great interest in operating -				systems, shells, and really anything that could be considered -				remotely low-level.  I’m not totally afraid of front-end -				development, although I <em>did</em> write this site in plain -				<abbr class="html">HTML</abbr> and <abbr class="css">CSS</abbr> -				because modern <abbr class="html">HTML</abbr> frameworks are the -				worst excuses for software I have ever seen. -			</p> - -			<p> -				As for my religious- and political beliefs, let’s make those -				clear: -				<ul> -					<li>Spaces should never be used for indentation</li> -					<li>Tabs should never be used for alignment</li> -					<li>Emacs is better than Vim</li> -					<li> -						The dominance of VSCode is an embarrassment to our -						industry -					</li> -					<li> -						Object-oriented programming, Java, JavaScript, -						and <abbr class="xml">XML</abbr> were all massive -						mistakes -					</li> -					<li>C is far superior to C++</li> -					<li>Rust is not gods chosen language (even if it’s pretty cool)</li> -				</ul> -			</p> -		</main> -		 -		<hr> - -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/index.gsp b/src/index.gsp new file mode 100644 index 0000000..9f2808c --- /dev/null +++ b/src/index.gsp @@ -0,0 +1,55 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			h1 {-Root Page} + +			figure .quote { +				blockquote { +					p {= +						If Java had true garbage collection, most programs would delete +						themselves upon execution. +					} +				} +				figcaption {-Robert Sewell} +			} +		} + +		main { +			p {- +				Welcome to my plot of the internet.  This site is mostly oriented +				towards topics related to software development, but you might eventually +				find some things that are completely unrelated as well.  The “source +				code” for the site (if you can call m4_abbr(HTML) @x-ref{-1} and a basic +				build system source code) +				@a +					href="https://git.thomasvoss.com/www.thomasvoss.com" +					target="_blank" +				{-are available through git}. +			} + +			aside { +				p data-ref="1" {- +					The site is actually written in my own m4_abbr(GSP) language, but it +					transpiles into m4_abbr(HTML).  Also, this site doesn’t even have any +					JavaScript.  There truly is no code. +				} +			} + +			p {- +				Now go branch off to a subsection of the site: +			} + +			ul { +				li {a href="prj" {-My Projects}} +				li {a href="srp" {-Software-Related Posts}} +				li {a href="www" {-Other Websites}} +				li {a href="ame" {-About Me}} +			} + +			hr{} + +			footer { m4_footer } +		} +	} +} diff --git a/src/index.html b/src/index.html deleted file mode 100644 index 19747dc..0000000 --- a/src/index.html +++ /dev/null @@ -1,59 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -	<head> -		m4_include(head.html) -	</head> -	<body> -		<header> -			<h1>Root Page</h1> - -			<figure class="quote"> -				<blockquote> -					<p>If Java had true garbage collection, most programs would -						delete themselves upon execution.</p> -				</blockquote> -				<figcaption> -					Robert Sewell -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				Welcome to my plot of the internet.  This site is mostly oriented -				towards topics related to software development, but you might -				eventually find some things that are completely unrelated as -				well.  The “source code” for the site (if you can call -				<abbr class="html">HTML</abbr> <x-ref>1</x-ref> and a basic build -				system source code) -				<a href="https://git.thomasvoss.com/www.thomasvoss.com" -				   target="_blank"> -					are available through git</a>. -			</p> - -			<aside> -				<p data-ref="1"> -					This site doesn’t even have any JavaScript.  There truly is -					no code. -				</p> -			</aside> - -			<p> -				Now go branch off to a subsection of the site: -			</p> - -			<ul> -				<li><a href="prj">My Projects</a></li> -				<li><a href="srp">Software-Related Posts</a></li> -				<li><a href="www">Other Websites</a></li> -				<li><a href="ame">About Me</a></li> -			</ul> -		</main> - -		<hr> -		 -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/prj/index.gsp b/src/prj/index.gsp new file mode 100644 index 0000000..a5da5ca --- /dev/null +++ b/src/prj/index.gsp @@ -0,0 +1,40 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-My Projects} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						Computers make it easier to do a lot of things, but most of the +						things they make it easier to do don’t need to be done. +					} +				} +				figcaption {-Andy Rooney} +			} +		} + +		main { +			p {- +				In this section of the website I cover some of my projects.  Some are +				completed, some are ongoing; really I’ll just add a post here if I ever +				have something I feel is interesting enough to share. +			} + +			p {-Posts:} +			ul { +				li {a href="totp"   {-totp — generate TOTP codes}} +				li {a href="mkpass" {-mkpass — make a password}} +				li {a href="mmv"    {-mmv, mpc — mapped file moves and -copies}} +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/prj/index.html b/src/prj/index.html deleted file mode 100644 index b8c8bc9..0000000 --- a/src/prj/index.html +++ /dev/null @@ -1,45 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -	<head> -		m4_include(head.html) -	</head> -	<body> -		<header> -			<div> -				<h1>My Projects</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>Computers make it easier to do a lot of things, but most of the -						things they make it easier to do don’t need to be done.</p> -				</blockquote> -				<figcaption> -					Andy Rooney -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				In this section of the website I cover some of my projects.  Some are -				completed, some are ongoing; really I’ll just add a post here if I ever -				have something I feel is interesting enough to share. -			</p> - -			<p>Posts:</p> -			<ul> -				<li><a href="totp">totp — generate TOTP codes</a></li> -				<li><a href="mkpass">mkpass — make a password</a></li> -				<li><a href="mmv">mmv, mpc — mapped file moves and -copies</a></li> -			</ul> -		</main> - -		<hr> -		 -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/prj/mkpass/basic-usage.sh.gsp b/src/prj/mkpass/basic-usage.sh.gsp new file mode 100644 index 0000000..bd8ddf7 --- /dev/null +++ b/src/prj/mkpass/basic-usage.sh.gsp @@ -0,0 +1,6 @@ +$ @span .sh-fn {-mkpass} +m4_gsp_quote(;%_)1S%wYO-unC6%D2pz9'bx^YFI>"VX;T[jzOUsiUr}r/R#T0Qs*XMT*fUef|2L)m4_dnl +$ @span .sh-fn {-mkpass} a-zA-Z0-9 +qTneHVHfwH3b1nCanKKW24lIcsRO2TUAgp7AGbZInfsV8ZjdsR35ZikHIzyUu06x +$ @span .sh-fn {-mkpass} [:alpha:][:digit:] +JlGe9kLOT1ik3CRvOb8VxHqHzluG6oLJ9VI8BVGFTn2lODu3pvTv5ZqeXy3XfT1R diff --git a/src/prj/mkpass/basic-usage.sh.html b/src/prj/mkpass/basic-usage.sh.html deleted file mode 100644 index ab1aca8..0000000 --- a/src/prj/mkpass/basic-usage.sh.html +++ /dev/null @@ -1,6 +0,0 @@ -$ <span class="sh-fn">mkpass</span> -;%_)1S%wYO-unC6%D2pz9'bx^YFI>"VX;T[jzOUsiUr}r/R#T0Qs*XMT*fUef|2L -$ <span class="sh-fn">mkpass</span> a-zA-Z0-9 -qTneHVHfwH3b1nCanKKW24lIcsRO2TUAgp7AGbZInfsV8ZjdsR35ZikHIzyUu06x -$ <span class="sh-fn">mkpass</span> [:alpha:][:digit:] -JlGe9kLOT1ik3CRvOb8VxHqHzluG6oLJ9VI8BVGFTn2lODu3pvTv5ZqeXy3XfT1R diff --git a/src/prj/mkpass/index.gsp b/src/prj/mkpass/index.gsp new file mode 100644 index 0000000..a7ff910 --- /dev/null +++ b/src/prj/mkpass/index.gsp @@ -0,0 +1,106 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-Easy Password Generation} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						Why does JavaScript suck?  The answer is simple: history. +						JavaScript was created by a really smart guy called Brendan Eich +						over a period of a week or so.  He did it because Microsoft was +						largely perceived as evil, and his aim was to create a programming +						platform in the Netscape navigator.  That way, the browser would run +						everywhere, and the OS wouldn't matter as much.  HAHA! Down with +						Microsoft.  You can see how well that worked out. +					} +				} +				figcaption {-Sahil Malik} +			} +		} + +		main { +			p { +				em {- +					You can find the @code{-mkpass} git repository over at +					@a +						href="https://git.sr.ht/~mango/mkpass" +						target="_blank" +					{-sourcehut} +					or +					@a +						href="https://github.com/Mango0x45/mkpass" +						target="_blank" +					{-GitHub}. +				} +			} + +			h2 {-Table of Contents} +			ul { +				li {a href="#prologue" {-Prologue}} +				li {a href="#usage" {-Basic Usage}} +			} + +			h2 #prologue {-Prologue} +			p {- +				Password generators are incredibly useful for those who don’t use the +				same password everywhere.  The issue is that everyone uses the same +				password everywhere.  Hopefully when people see how easy password +				generation can be, that’ll change; there really is no excuse to not use +				different passwords these days.  @code{-mkpass} aims to be the absolute +				simplest password generator possible while still providing the +				functionality you need.ls +			} + +			p {- +				Two factor authentication is also something you should be using — and +				something that is very easy to manage — and something that I will be +				posting about shortly™. +			} + +			h2 #usage {-Basic Usage} +			p {- +				The most basic usage of @code{-mkpass} is to just call @code{-mkpass}. +				By default this will generate a 64-character password made up of random +				printable characters.  If you need to use specific characters (for +				example, maybe you can only use alphanumeric characters) then you can +				simply specify a +				@code { +					a +						href="https://www.man7.org/linux/man-pages/man1/tr.1.html" +						target="_blank" +					{-tr(1)} +				} +				style range: +			} + +			figure { +				pre { m4_fmt_code(basic-usage.sh.gsp) } +			} + +			p {- +				You can also specify the length of the password using +				the @code{--l} flag: +			} + +			figure { +				pre { m4_fmt_code(length-flag.sh.gsp) } +			} + +			p {- +				And that ladies and gentlemen, is the entire program.  A nice minimal +				tool that does one thing and one thing only, while integrating nicely +				with the UNIX environment.  This is (in my opinion), an example of +				well-designed software. +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/prj/mkpass/index.html b/src/prj/mkpass/index.html deleted file mode 100644 index 8180358..0000000 --- a/src/prj/mkpass/index.html +++ /dev/null @@ -1,102 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -  <head> -		m4_include(head.html) -  </head> -  <body> -		<header> -			<div> -				<h1>Easy Password Generation</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>Why does JavaScript suck? The answer is simple: history. JavaScript -					was created by a really smart guy called Brendan Eich over a period of -					a week or so. He did it because Microsoft was largely perceived as -					evil, and his aim was to create a programming platform in the Netscape -					navigator. That way, the browser would run everywhere, and the OS -					wouldn't matter as much. HAHA! Down with Microsoft. You can see how -					well that worked out.</p> -				</blockquote> -				<figcaption> -					Sahil Malik -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				<em> -					You can find the <code>mkpass</code> git repository over at -					<a href="https://git.sr.ht/~mango/mkpass" -						 target="_blank">sourcehut</a> -						 or <a href="https://github.com/Mango0x45/mkpass" -						 target="_blank">GitHub</a>. -				</em> -			</p> - -			<h2>Table of Contents</h2> - -			<ul> -        <li><a href="#prologue">Prologue</a></li> -        <li><a href="#usage">Basic Usage</a></li> -			</ul> - -			<h2 id="prologue">Prologue</h2> -			<p> -				Password generators are incredibly useful for those who don’t use the -				same password everywhere.  The issue is that everyone uses the same -				password everywhere.  Hopefully when people see how easy password -				generation can be, that’ll change; there really is no excuse to not use -				different passwords these days.  <code>mkpass</code> aims to be the -				absolute simplest password generator possible while still providing the -				functionality you need.ls -			</p> - -			<p> -				Two factor authentication is also something you should be using — and -				something that is very easy to manage — and something that I will be -				posting about shortly™. -			</p> - -			<h2 id="usage">Basic Usage</h2> -			<p> -				The most basic usage of <code>mkpass</code> is to just -				call <code>mkpass</code>.  By default this will generate a 64-character -				password made up of random printable characters.  If you need to use -				specific characters (for example, maybe you can only use alphanumeric -				characters) then you can simply specify a -				<code><a href="https://www.man7.org/linux/man-pages/man1/tr.1.html" -								 target="_blank">tr(1)</a></code> style range: -			</p> - -			<figure> -				<pre>m4_fmt_code(basic-usage.sh.html)</pre> -			</figure> - -			<p> -				You can also specify the length of the password using -				the <code>-l</code> flag: -			</p> - -			<figure> -				<pre>m4_fmt_code(length-flag.sh.html)</pre> -			</figure> - -			<p> -				And that ladies and gentlemen, is the entire program.  A nice minimal -				tool that does one thing and one thing only, while integrating nicely -				with the UNIX environment.  This is (in my opinion), an example of -				well-designed software. -			</p> -		</main> - -		<hr> - -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/prj/mkpass/length-flag.sh.gsp b/src/prj/mkpass/length-flag.sh.gsp new file mode 100644 index 0000000..24ed26e --- /dev/null +++ b/src/prj/mkpass/length-flag.sh.gsp @@ -0,0 +1,4 @@ +$ @span .sh-fn {-mkpass} a-z +hxjgusvfxzfasluhlkxvsdszxbzoffkyruauiggigjmhptivctnudnkiararlwcn +$ @span .sh-fn {-mkpass} -l 12 a-z +wymyggnmwkwz diff --git a/src/prj/mkpass/length-flag.sh.html b/src/prj/mkpass/length-flag.sh.html deleted file mode 100644 index f9405a1..0000000 --- a/src/prj/mkpass/length-flag.sh.html +++ /dev/null @@ -1,4 +0,0 @@ -$ <span class="sh-fn">mkpass</span> a-z -hxjgusvfxzfasluhlkxvsdszxbzoffkyruauiggigjmhptivctnudnkiararlwcn -$ <span class="sh-fn">mkpass</span> -l 12 a-z -wymyggnmwkwz diff --git a/src/prj/mmv/camel-to-snake-naïve.sh.gsp b/src/prj/mmv/camel-to-snake-naïve.sh.gsp new file mode 100644 index 0000000..cd0d156 --- /dev/null +++ b/src/prj/mmv/camel-to-snake-naïve.sh.gsp @@ -0,0 +1,2 @@ +@span .sh-cmt {-# If you aren’t a shell-guru, take a moment to figure out how this works!} +$ @span .sh-fn {-ls} *.[ch] | @span .sh-fn {-sed} @span .sh-str {-'p; s/[A-Z]/\\L_&/g'} | @span .sh-fn {-xargs} -L2 mv diff --git a/src/prj/mmv/camel-to-snake-naïve.sh.html b/src/prj/mmv/camel-to-snake-naïve.sh.html deleted file mode 100644 index 573da41..0000000 --- a/src/prj/mmv/camel-to-snake-naïve.sh.html +++ /dev/null @@ -1,2 +0,0 @@ -<span class="sh-cmt"># If you aren’t a shell-guru, take a moment to figure out how this works!</span> -$ <span class="sh-fn">ls</span> *.[ch] | <span class="sh-fn">sed</span> <span class="sh-str">'p; s/[A-Z]/\L_&/g'</span> | <span class="sh-fn">xargs</span> -L2 mv diff --git a/src/prj/mmv/camel-to-snake-smart.sh.gsp b/src/prj/mmv/camel-to-snake-smart.sh.gsp new file mode 100644 index 0000000..9ce6123 --- /dev/null +++ b/src/prj/mmv/camel-to-snake-smart.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} *.[ch] | @span .sh-fn {-mmv} sed @span .sh-str {-'s/[A-Z]/\\L_&/g'} diff --git a/src/prj/mmv/camel-to-snake-smart.sh.html b/src/prj/mmv/camel-to-snake-smart.sh.html deleted file mode 100644 index 191e87f..0000000 --- a/src/prj/mmv/camel-to-snake-smart.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> *.[ch] | <span class="sh-fn">mmv</span> sed <span class="sh-str">'s/[A-Z]/\L_&/g'</span> diff --git a/src/prj/mmv/examples/camel-to-snake.sh.gsp b/src/prj/mmv/examples/camel-to-snake.sh.gsp new file mode 100644 index 0000000..7948861 --- /dev/null +++ b/src/prj/mmv/examples/camel-to-snake.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-git} ls-files @span .sh-str {-'*.[ch]'} | @span .sh-fn {-mmv} sed @span .sh-str {-'s/[A-Z]/\\L_&/g'} diff --git a/src/prj/mmv/examples/camel-to-snake.sh.html b/src/prj/mmv/examples/camel-to-snake.sh.html deleted file mode 100644 index bd67492..0000000 --- a/src/prj/mmv/examples/camel-to-snake.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">git</span> ls-files <span class="sh-str">'*.[ch]'</span> | <span class="sh-fn">mmv</span> sed <span class="sh-str">'s/[A-Z]/\L_&/g'</span> diff --git a/src/prj/mmv/examples/hyphens.sh.gsp b/src/prj/mmv/examples/hyphens.sh.gsp new file mode 100644 index 0000000..8f9cc76 --- /dev/null +++ b/src/prj/mmv/examples/hyphens.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} | @span .sh-fn {-mmv} tr ' ' '-' diff --git a/src/prj/mmv/examples/hyphens.sh.html b/src/prj/mmv/examples/hyphens.sh.html deleted file mode 100644 index ca49946..0000000 --- a/src/prj/mmv/examples/hyphens.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> | <span class="sh-fn">mmv</span> tr ' ' '-' diff --git a/src/prj/mmv/examples/i-flag.sh.gsp b/src/prj/mmv/examples/i-flag.sh.gsp new file mode 100644 index 0000000..6977635 --- /dev/null +++ b/src/prj/mmv/examples/i-flag.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} --zero | @span .sh-fn {-mmv} -0i cmd diff --git a/src/prj/mmv/examples/i-flag.sh.html b/src/prj/mmv/examples/i-flag.sh.html deleted file mode 100644 index c22c7c9..0000000 --- a/src/prj/mmv/examples/i-flag.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> --zero | <span class="sh-fn">mmv</span> -0i cmd diff --git a/src/prj/mmv/examples/lowercase.sh.gsp b/src/prj/mmv/examples/lowercase.sh.gsp new file mode 100644 index 0000000..72a8e4c --- /dev/null +++ b/src/prj/mmv/examples/lowercase.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-find} . -print0 | @span .sh-fn {-mmv} -0 tr A-Z a-z diff --git a/src/prj/mmv/examples/lowercase.sh.html b/src/prj/mmv/examples/lowercase.sh.html deleted file mode 100644 index 84abb92..0000000 --- a/src/prj/mmv/examples/lowercase.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">find</span> . -print0 | <span class="sh-fn">mmv</span> -0 tr A-Z a-z diff --git a/src/prj/mmv/examples/number.sh.gsp b/src/prj/mmv/examples/number.sh.gsp new file mode 100644 index 0000000..ce82f24 --- /dev/null +++ b/src/prj/mmv/examples/number.sh.gsp @@ -0,0 +1,2 @@ +$ @span .sh-fn {-ls} @span .sh-str {-'The Fellowship of the Ring.mp4'} … @span .sh-str {-'The Two Towers.mp4'} | \\ +	@span .sh-fn {-mmv} awk @span .sh-str {-'{ gsub(" ", "-"); printf "%02d-%s", NR, tolower($0) \}'} diff --git a/src/prj/mmv/examples/number.sh.html b/src/prj/mmv/examples/number.sh.html deleted file mode 100644 index 5e8e74a..0000000 --- a/src/prj/mmv/examples/number.sh.html +++ /dev/null @@ -1,2 +0,0 @@ -$ <span class="sh-fn">ls</span> <span class="sh-str">'The Fellowship of the Ring.mp4'</span> … <span class="sh-str">'The Two Towers.mp4'</span> | \ -	<span class="sh-fn">mmv</span> awk <span class="sh-str">'{ gsub(" ", "-"); printf "%02d-%s", NR, tolower($0) }'</span> diff --git a/src/prj/mmv/examples/swap.sh.gsp b/src/prj/mmv/examples/swap.sh.gsp new file mode 100644 index 0000000..0249751 --- /dev/null +++ b/src/prj/mmv/examples/swap.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} foo bar | @span .sh-fn {-mmv} tac diff --git a/src/prj/mmv/examples/swap.sh.html b/src/prj/mmv/examples/swap.sh.html deleted file mode 100644 index 02c9c28..0000000 --- a/src/prj/mmv/examples/swap.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> foo bar | <span class="sh-fn">mmv</span> tac diff --git a/src/prj/mmv/examples/vipe.sh.gsp b/src/prj/mmv/examples/vipe.sh.gsp new file mode 100644 index 0000000..b738ae1 --- /dev/null +++ b/src/prj/mmv/examples/vipe.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} | @span .sh-fn {-mmv} -0e vipe diff --git a/src/prj/mmv/examples/vipe.sh.html b/src/prj/mmv/examples/vipe.sh.html deleted file mode 100644 index 933039a..0000000 --- a/src/prj/mmv/examples/vipe.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> | <span class="sh-fn">mmv</span> -0e vipe diff --git a/src/prj/mmv/index.gsp b/src/prj/mmv/index.gsp new file mode 100644 index 0000000..3c2fd97 --- /dev/null +++ b/src/prj/mmv/index.gsp @@ -0,0 +1,645 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-Moving Files the Right Way} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						I think the OpenBSD crowd is a bunch of masturbating monkeys, in +						that they make such a big deal about concentrating on security to +						the point where they pretty much admit that nothing else matters to +						them. +					} +				} +				figcaption {-Linus Torvalds} +			} +		} + +		main { +			p { +				em {- +					You can find the @code{-mmv} git repository over at +					@a +						href="https://git.sr.ht/~mango/mmv" +						target="_blank" +					{-sourcehut} +					or +					@a +						href="https://github.com/Mango0x45/mmv" +					  target="_blank" +					{-GitHub}. +				} +			} + +			p {- +				NOTE: As of the +				@a href="https://git.sr.ht/~mango/mmv/refs/v1.2.0" {-v1.2.0} +				release there is now also the @code{-mcp} utility.  It behaves the same +				as the @code{-mmv} utility but it copies files instead of moving them. +				It also doesn’t support the ‘@code{--n}’ flag as it doesn’t need to deal +				with backups. +			} + +			h2 {-Table of Contents} + +			ul { +				li {a href="#prologue" {-Prologue}} +				li {a href="#moving" {-Advanced Moving and Pitfalls}} +				li {a href="#mapping" {-Name Mapping with @code{-mmv}}} +				li {a href="#newlines" {-Filenames with Embedded Newlines}} +				ul { +					li {a href="0-flag" {-The Simple Case}} +					li {a href="#e-flag" {-Encoding Newlines}} +				} +				li {a href="#i-flag" {-Individual Execution}} +				li {a href="#safety" {-Safety}} +				li {a href="#examples" {-Examples}} +			} +			 +			h2 #prologue {-Prologue} +			p {- +				File moving and renaming is one of the most common tasks we undertake on +				the command-line.  We basically always do this with the @code{-mv} +				utility, and it gets the job done most of the time.  Want to rename one +				file?  Use @code{-mv}!  Want to move a bunch of files into a directory? +				Use @code{-mv}! How could mv ever go wrong?  Well I’m glad you asked! +			} + +			h2 #moving {-Advanced Moving and Pitfalls} +			p {- +				Let’s start off nice and simple.  You just inherited a C project that +				uses the sacrilegious +				@a +					href="https://en.wikipedia.org/wiki/Camel_case" +					target="_blank" +				{-camelCase} +				naming convention for its files: +			} + +			figure { +				pre { m4_fmt_code(ls-files.sh.gsp) } +			} + +			p {- +				This deeply upsets you, as it upsets me.  So you decide you want to +				switch all these files to use +				@a +					href="https://en.wikipedia.org/wiki/Snake_case" +					target="_blank" +				{-snake_case}, +				like a normal person.  Well how would you do this?  You use @code{-mv}! +				This is what you might end up doing: +			} + +			figure { +				pre { m4_fmt_code(manual-mv.sh.gsp) } +			} + +			p {- +				Well… it works I guess, but it’s a pretty shitty way of renaming these +				files.  Luckily we only had 5, but what if this was a much larger +				project with many more files to rename?  Things would get tedious.  So +				instead we can use a pipeline for this: +			} + +			figure { +				pre { m4_fmt_code(camel-to-snake-naïve.sh.gsp) } +			} + +			aside { +				p {- +					The given example assumes your @code{-sed} implementation supports +					‘@code{-\\L}’ which is a non-standard m4_abbr(GNU) extension. +				} +			} + +			p {- +				That works and it gets the job done, but it’s not really ideal is +				it?  There are a couple of issues with this. +			} + +			ol { +				li { +					p {- +						You’re writing more complicated code.  This has the obvious drawback +						of potentially being more error-prone, but also risks taking more +						time to write than you’d like as you might have forgotten if +						@code{-xargs} actually has an ‘@code{--L}’ option or not (which +						would require reading the +						@a +							href="https://www.man7.org/linux/man-pages/man1/xargs.1.html" +							target="_blank" +						{ +							code {-xargs(1)} +						} +						manual). +					} +				} +				li { +					p {- +						If you try to rename the file @em{-foo} to @em{-bar} but @em{-bar} +						already exists, you end up deleting a file you may not have wanted +						to. +					} +				} +				li { +					p {- +						In a similar vein to the previous point, you need to be very careful +						about schemes like renaming the file @em{-a} to @em{-b} and @em{-b} +						to @em{-c}.  You run the risk of turning @em{-a} into @em{-c} and +						losing the file @em{-b} entirely. +					} +				} +				li { +					p {- +						Moving symbolic links is its own whole can of worms.  If a symlink +						points to a relative location then you need to make sure you keep +						pointing to the right place.  If the symlink is absolute however +						then you can leave it untouched.  But what if the symlink points to +						a file that you’re moving as part of your batch move operation? Now +						you need to handle that too. +					} +				} +			} + +			h2 #mapping {-Name Mapping with @code{-mmv}} + +			p {- +				What is @code{-mmv}?  It’s the solution to all your problems, that’s +				what it is!  @code{-mmv} takes as its argument(s) a utility and that +				utilities arguments and uses that to create a mapping between old and +				new filenames — similar to the @code{-map()} function found in many +				programming languages.  I think to best convey how the tool functions, I +				should provide an example.  Let’s try to do the same thing we did +				previously where we tried to turn camelCase files to snake_case, but +				using @code{-mmv}: +			} + +			figure { +				pre { m4_fmt_code(camel-to-snake-smart.sh.gsp) } +			} + +			p {-Let me break down how this works.} + +			p {- +				@code{-mmv} starts by reading a series of filenames separated by +				newlines from the standard input.  Yes, sometimes filenames have +				newlines in them and yes there is a way to handle them but I shall get +				to that later.  The filenames that @code{-mmv} reads from the standard +				input will be referred to as the @em{-input files}.  Once all the input +				files have been read, the utility specified by the arguments is spawned; +				in this case that would be @code{-sed} with the argument +				@code{-'s/[A-Z]/\\L_&/g'}. The input files are then piped into +				@code{-sed} the exact same way that they would have been if we ran the +				above commands without @code{-mmv}, and the output of @code{-sed} then +				forms what will be referred to as the @em{-output files}.  Once a +				complete list of output files is accumulated, each input file gets +				renamed to its corresponding output file. +			} + +			p {- +				Let’s look at a simpler example.  Say we want to rename 2 files in the +				current directory to use lowercase letters, we could use the following +				command: +			} +			 +			figure { +				pre { m4_fmt_code(mmv-tr.sh.gsp) } +			} + +			p {- +				In the above example @code{-mmv} reads 2 lines from standard input, +				those being @em{-LICENSE} and @em{-README}.  Those are our 2 input files +				now. The @code{-tr} utility is then spawned and the input files are +				piped into it.  We can simulate this in the shell: +			} + +			figure { +				pre { m4_fmt_code(tr.sh.gsp) } +			} + +			p {- +				As you can see above, @code{-tr} has produced 2 lines of output; these +				are our 2 output files.  Since we now have our 2 input files and 2 +				output files, @code{-mmv} can go ahead and rename the files.  In this +				case it will rename @em{-LICENSE} to @em{-license} and @em{-README} to +				@em{-readme}.  For some examples, check the @a href="#examples" +				{-examples} section of this page down below. +			} + +			h2 #newlines {-Filenames with Embedded Newlines} + +			p {- +				People are retarded, and as a result we have filenames with newlines in +				them.  All it would have taken to solve this issue for everyone was for +				literally @strong{-anybody} during the early UNIX days to go “@em{-hey, +				this is a bad idea!}”, but alas, we must deal with this.  Newlines are +				of course not the only special characters filenames can contain, but +				they are the single most infuriating to deal with; the UNIX utilities +				all being line-oriented really doesn’t work well with these files. +			} + +			p {- +				So how does @code{-mmv} deal with special characters, and newlines in +				particular?  Well it does so by providing the user with the @code{--0} +				and @code{--e} flags: +			} + +			dl { +				dt { code{--0} } +				dd { +					p {- +						Tell @code{-mmv} to expect its input to not be separated by newlines +						(‘@code{-\\n}’), but by NUL bytes (‘@code{-\\0}’).  NUL bytes are +						the only characters not allowed in filenames besides forward +						slashes, so they are an obvious choice for an alternative separator. +					} +				} +				dt { code{--e} } +				dd { +					p {- +						Encode newlines in filenames before passing them to the provided +						utility.  Newline characters are replaced by the literal string +						‘@code{-\\n}’ and backslashes by the literal string ‘@code{-\\\\}’. +						After processing, the resulting output is decoded again. +					} +					p {- +						If combined with the @code{--0} flag, then while input will be read +						assuming a NUL-byte input-seperator, the encoded input files will be +						written to the spawned process newline-seperated. +					} +				} +			} + +			h3 id="0-flag" {-The Simple Case} + +			p {- +				In order to better understand these flags and how they work let’s go +				though another example.  We have 2 files — one with and one without an +				embedded newline — and our goal is to simply reverse these filenames. +				In this example I am going to be displaying newlines in filenames with +				the “@code{-$'\\n'}” syntax as this is how my shell displays embedded +				newlines. +			} + +			p {- +				We can start by just trying to naïvely pass these 2 files to @code{-mmv} +				and use @code{-rev} to reverse the names, but this doesn’t work: +			} + +			figure { +				pre { m4_fmt_code(mmv-rev.sh.gsp) } +			} + +			p {- +				The reason this doesn’t work is because due to the line-oriented nature +				of @code{-ls} and @code{-rev}, we are actually trying to rename the +				files @em{-foo}, @em{-bar}, and @em{-baz} to the new filenames +				@em{-zab}, @em{-rab}, and @em{-oof}.  As can be seen in the following +				diagram, the embedded newline is causing our input to be ambiguous and +				@code{-mmv} can’t reliably proceed anymore @x-ref{-1}: +			} + +			figure { +				object data="conflict.svg" type="image/svg+xml" {-} +			} + +			aside { +				p data-ref="1" {- +					The reason you get a cryptic “file not found” error message is because +					@code{-mmv} tries to assert that all the input files actually exist +					before doing anything.  Since “foo” isn’t a real file, we error out. +				} +			} +			 +			p {- +				The first thing we need to do in order to proceed is to pass the +				@code{--0} flag to @code{-mmv}.  This will tell @code{-mmv} that we want +				to use the NUL-byte as our input separator and not the newline.  We also +				need @code{-ls} to actually provide us with the filenames delimited by +				NUL-bytes. Luckily m4_abbr(GNU) @code{-ls} gives us the @code{---zero} +				flag to do just that: +			} + +			figure { +			  pre { m4_fmt_code(mmv-rev-zero.sh.gsp) } +			} + +			p {- +				So we’re getting places, but we aren’t quite there yet.  The issue we’re +				getting now is that @code{-mmv} recieved 2 input files from the standard +				input, but @code{-rev} produced 3 output files.  Why is that?  Well +				let’s try our hand at a little bit of command-line debugging with +				@code{-sed}: +			} + +			figure { +				pre { m4_fmt_code(sed-debugging.sh.gsp) } +			} + +			p {- +				If you aren’t quite sure what the above is doing, here’s a quick +				summary: +			} + +			ul { +				li {- +					The @code{--U} flag given to @code{-ls} tells it not to sort our +					output.  This is purely just to keep this example clear to the reader. +				} +				li {- +					The @code{--n} flag given to @code{-sed} tells it not to print the +					input line automatically at the end of the provided script. +				} +				li {- +					The @code{-l} command in @code{-sed} prints the current input in a +					“visually unambiguous form”. +				} +			} + +			p {- +				In the @code{-sed} output, we can see that @samp{-$} represents the end +				of a line, and @samp{-\\000} represents the NUL-byte.  All looks good +				here, we have two inputs seperated by NUL-bytes.  Now let’s try to throw +				in @code{-rev}: +			} + +			figure { +				pre { m4_fmt_code(sed-debugging-rev.sh.gsp) } +			} + +			p {- +				Well wouldn’t you know it?  Since @code{-rev} @em{-also} works with +				newline-seperated input, it reversed out NUL-byte seperators and now +				gives us 3 outputs.  Luckily the folks over at @em{-util-linux} provided +				us with the @code{--0} flag here too, so that we can properly handle +				NUL-delimited input. Combining all of this together we get a final +				working product: +			} + +			figure { +				pre { m4_fmt_code(reverse-embedded-newline.sh.gsp) } +			} + +			h3 #e-flag {-Encoding Newlines} + +			p {- +				Sometimes we want to rename a bunch of files, but the command we want to +				use doesn’t support NUL-bytes as nicely as we would like.  In these +				cases, you may want to consider encoding your newline characters into +				the literal string ‘@code{-\\n}’ and then passing your input +				newline-seperated to your given command with the @code{--e} flag. +			} + +			p {- +				For a real-world example, perhaps you want to edit some filenames in +				vim, or whatever other editor you use.  Well we can do this incredibly +				easily with the @code{-vipe} utility from the +				@a href="https://joeyh.name/code/moreutils/" {-moreutils} +				collection.  The @code{-vipe} command simply reads input from the +				standard input, opens it up in your editor, and then prints the +				resulting output to the standard output; perfect for @code{-mmv}!  We do +				not really want to deal with NUL-bytes in our text-editor though, so +				let’s just encode our newlines: +			} + +			figure { +				pre { m4_fmt_code(vipe.sh.gsp) } +			} + +			aside { +				p {- +					Notice how you still need to pass the @code{--0} flag to @code{-mmv} +					know that our inputfiles may have embedded newlines. +				} +			} + +			p {- +				When running the above code example, you will see the following in your +				editor: +			} + +			figure { +				pre { m4_fmt_code(vim.gsp) } +			} + +			p {- +				After you exit your editor, @code{-mmv} will decode all occurances of +				‘@code{-\\n}’ back into a newline, and all occurances of ‘@code{-\\\\}’ +				back into a backslash: +			} + +			figure { +				object data="e-flag.svg" type="image/svg+xml" {-} +			} + +			h2 #i-flag {-Individual Execution} +			p {- +				The previous examples are great and all, but what do you do if your +				mapping command doesn’t have the concept of an input seperator at all? +				This is where the @code{--i} flag comes into play.  With the @code{--i} +				flag we can get @code{-mmv} to execute our mapping command for every +				input filename.  This means that as long as we can work with a complete +				buffer, we don’t need to worry about seperators. +			} + +			p {- +				To be honest, I cannot really think of any situation where you might +				actually need to do this.  If you can think of one, please @a +				href="mailto:mail@thomasvoss.com" {-email me} and I’ll update the +				example on this page.  Regardless, let’s imagine that we wanted to +				rename some files so that their filenames are replaced with their +				filename +				@a +					href="https://en.wikipedia.org/wiki/SHA-1" +					target="_blank" +				{-m4_abbr(SHA)-1 hash}. +				On Linux we have the @code{-sha1sum} program which reads input from the +				standard input and outputs the m4_abbr(SHA)-1 hash.  This is how we +				would use it with @code{-mmv}: +			} + +			figure { +				pre { m4_fmt_code(sha1sum-long-example.sh.gsp) } +			} + +			p {- +				Another approach is to invoke @code{-mmv} twice: +			} + +			figure { +				pre { m4_fmt_code(sha1sum-short-example.sh.gsp) } +			} + +			p {- +				If you are confused about why we need to make a call to @code{-awk}, +				it’s because the @code{-sha1sum} program outputs 2 columns of data.  The +				first column is our hash and the second column is the filename where the +				to-be-hashed data was read from.  We don’t want the second column. +			} + +			p {- +				Unlike in previous examples where one process was spawned to map all our +				filenames, with the @code{--i} flag we are spawning a new instance for +				each filename.  If you struggle to visualize this, perhaps the following +				diagrams help: +			} + +			figure { +				figcaption {-Invoking @code{-mmv} without @code{--i}} +				object data="without-i-flag.svg" type="image/svg+xml" {-} +			} + +			figure { +				figcaption {-Invoking @code{-mmv} with @code{--i}} +				object data="with-i-flag.svg" type="image/svg+xml" {-} +			} + +			h2 #safety {-Safety} +			p {- +				When compared to the standard @code{-for f in *; do mv $f …; done} or +				@code{-ls | … | xargs -L2 mv} constructs, @code{-mmv} is significantly +				more safe to use. These are some of the safety features that are built +				into the tool: +			} + +			ol { +				li {- +					If the number of input- and output files differs, execution is aborted +					before making any changes. +				} +				li {- +					If an input file is renamed to the name of another input file, the +					second input file is not lost (i.e. you can rename @em{-a} to @em{-b} +					and @em{-b} to @em{-a} with no problem). +				} +				li {- +					All input files must be unique and all output files must be unique. +					Otherwise execution is aborted before making any changes. +				} +				li {- +					In the case that something goes wrong during execution (perhaps you +					tried to move a file to a non-existant directory, or a syscall +					failed), a backup of your input files is saved automatically by +					@code{-mmv} for recovery. +				} +			} + +			p {- +				Due to the way @code{-mmv} handles #2, when things do go wrong you may +				find that all of your input files have disappeared.  Don’t worry though, +				@code{-mmv} takes a backup of your code before doing anything.  If you +				run @code{-mmv} with the @code{--v} option for verbose output, you’ll +				notice it backing up your stuff in the @code{-$XDG_CACHE_DIR} directory: +			} + +			figure { +				pre { m4_fmt_code(mmv-verbose.sh.gsp) } +			} + +			p {- +				Upon successful execution the @code{-$XDG_CACHE_DIR/mmv/TIMESTAMP} +				directory will be automatically removed, but it remains when things go +				wrong so that you can recover any missing data.  The names of the +				backup-subdirectories in the @code{-$XDG_CACHE_DIR/mmv} directory are +				timestamps of when the directories were created. This should make it +				easier for you to figure out which directory you need to recover if you +				happen to have multiple of these. +			} +			 +			h2 #examples {-Examples} + +			aside { +				p {- +					All of these examples are ripped straight from the @code{-mmv(1)} +					manual page. If you installed @code{-mmv} through a package manager or +					via @code{-make install} then you should have the manual installed on +					your system. +				} +			} + +			p {-Swap the files @em{-foo} and @em{-bar}:} +			figure { +				pre { m4_fmt_code(examples/swap.sh.gsp) } +			} + +			p {- +				Rename all files in the current directory to use hyphens (‘-’) instead +				of spaces: +			} +			figure { +				pre { m4_fmt_code(examples/hyphens.sh.gsp) } +			} + +			p {- +				Rename a given list of movies to use lowercase letters and hyphens +				instead of uppercase letters and spaces, and number them so that they’re +				properly ordered in globs (e.g. rename @em{-The Return of the King.mp4} +				to @em{-02-the-return-of-the-king.mp4}): +			} +			figure { +				pre { m4_fmt_code(examples/number.sh.gsp) } +			} + +			p {- +				Rename files interactively in your editor while encoding newline into +				the literal string ‘@code{-\\n}’, making use of +				@code { +					a +						href="https://linux.die.net/man/1/vipe" +						target="_blank" +					{-vipe(1)} +				} +				from @em{-moreutils}: +			} +			figure { +				pre { m4_fmt_code(examples/vipe.sh.gsp) } +			} + +			p {- +				Rename all C source code- and header files in a git repository +				to use snake_case instead of camelCase using +				the m4_abbr(GNU) +				@code { +					a +						href="https://www.man7.org/linux/man-pages/man1/sed.1.html" +						target="_blank" +					{-sed(1)} +				} +				‘@code{-\\n}’ extension: +			} +			figure { +				pre { m4_fmt_code(examples/camel-to-snake.sh.gsp) } +			} + +			p {- +				Lowercase all filenames within a directory hierarchy which may contain +				newline characters: +			} +			figure { +				pre { m4_fmt_code(examples/lowercase.sh.gsp) } +			} + +			p {- +				Map filenames which may contain newlines in the current directory with +				the command ‘@code{-cmd}’, which itself does not support nul-byte +				separated entries.  This only works assuming your mapping doesn’t +				require any context outside of the given input filename (for example, +				you would not be able to number your files as this requires knowledge of +				the input files position in the input list): +			} +			figure { +				pre { m4_fmt_code(examples/i-flag.sh.gsp) } +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/prj/mmv/index.html b/src/prj/mmv/index.html deleted file mode 100644 index 09aadb1..0000000 --- a/src/prj/mmv/index.html +++ /dev/null @@ -1,667 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -	<head> -		m4_include(head.html) -	</head> -	<body> -		<header> -			<div> -				<h1>Moving Files the Right Way</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>I think the OpenBSD crowd is a bunch of masturbating -					monkeys, in that they make such a big deal about -					concentrating on security to the point where they pretty much -					admit that nothing else matters to them.</p> -				</blockquote> -				<figcaption> -					Linux Torvalds -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				<em> -					You can find the <code>mmv</code> git repository over at -					<a href="https://git.sr.ht/~mango/mmv" target="_blank">sourcehut</a> -					   or <a href="https://github.com/Mango0x45/mmv" -					   target="_blank">GitHub</a>. -				</em> -			</p> - -			<p> -				NOTE: As of the -				<a href="https://git.sr.ht/~mango/mmv/refs/v1.2.0">v1.2.0</a> release -				there is now also the <code>mcp</code> utility.  It behaves the same as -				the <code>mmv</code> utility but it copies files instead of moving them. -				It also doesn’t support the ‘<code>-n</code>’ flag as it doesn’t need to -				deal with backups. -			</p> - -			<h2>Table of Contents</h2> - -			<ul> -				<li><a href="#prologue">Prologue</a></li> -				<li><a href="#moving">Advanced Moving and Pitfalls</a></li> -				<li><a href="#mapping">Name Mapping with <code>mmv</code></a></li> -				<li><a href="#newlines">Filenames with Embedded Newlines</a></li> -				<ul> -					<li><a href="#0-flag">The Simple Case</a></li> -					<li><a href="#e-flag">Encoding Newlines</a></li> -				</ul> -				<li><a href="#i-flag">Individual Execution</a></li> -				<li><a href="#safety">Safety</a></li> -				<li><a href="#examples">Examples</a></li> -			</ul> -			 -			<h2 id="prologue">Prologue</h2> -			<p> -				File moving and renaming is one of the most common tasks we -				undertake on the command-line.  We basically always do this with -				the <code>mv</code> utility, and it gets the job done most of the -				time.  Want to rename one file?  Use <code>mv</code>!  Want to -				move a bunch of files into a directory?  Use <code>mv</code>! -				How could mv ever go wrong?  Well I’m glad you asked! -			</p> - -			<h2 id="moving">Advanced Moving and Pitfalls</h2> -			<p> -				Let’s start off nice and simple.  You just inherited a C project -				that uses the sacrilegious -				<a -					href="https://en.wikipedia.org/wiki/Camel_case" -					target="_blank" -				>camelCase</a> -				naming convention for its files: -			</p> - -			<figure> -				<pre>m4_fmt_code(ls-files.sh.html)</pre> -			</figure> - -			<p> -				This deeply upsets you, as it upsets me.  So you decide you want -				to switch all these files to use -				<a -					href="https://en.wikipedia.org/wiki/Snake_case" -					target="_blank" -				>snake_case</a>, -				like a normal person.  Well how would you do this?  You use -				<code>mv</code>!  This is what you might end up doing: -			</p> - -			<figure> -				<pre>m4_fmt_code(manual-mv.sh.html)</pre> -			</figure> - -			<p> -				Well… it works I guess, but it’s a pretty shitty way of renaming -				these files.  Luckily we only had 5, but what if this was a much -				larger project with many more files to rename?  Things would get -				tedious.  So instead we can use a pipeline for -				this: -			</p> - -			<figure> -				<pre>m4_fmt_code(camel-to-snake-naïve.sh.html)</pre> -			</figure> - -			<aside> -				<p> -					The given example assumes your <code>sed</code> -					implementation supports ‘<code>\L</code>’ which is a -					non-standard <abbr class="gnu">GNU</abbr> extension. -				</p> -			</aside> - -			<p> -				That works and it gets the job done, but it’s not really ideal is -				it?  There are a couple of issues with this. -			</p> - -			<ol> -				<li> -					<p> -						You’re writing more complicated code.  This has the -						obvious drawback of potentially being more error-prone, -						but also risks taking more time to write than you’d like -						as you might have forgotten if <code>xargs</code> -						actually has an ‘<code>-L</code>’ option or not (which -						would require reading the -						<a href="https://www.man7.org/linux/man-pages/man1/xargs.1.html" -							target="_blank" ><code>xargs(1)</code></a> manual). -					</p> -				</li> -				<li> -					<p> -						If you try to rename the file <em>foo</em> -						to <em>bar</em> but <em>bar</em> already exists, you end -						up deleting a file you may not have wanted to. -					</p> -				</li> -				<li> -					<p> -						In a similar vein to the previous point, you need to be -						very careful about schemes like renaming the -						file <em>a</em> to <em>b</em> and <em>b</em> -						to <em>c</em>.  You run the risk of turning <em>a</em> -						into <em>c</em> and losing the file <em>b</em> entirely. -					</p> -				</li> -				<li> -					<p> -						Moving symbolic links is its own whole can of worms.  If -						a symlink points to a relative location then you need to -						make sure you keep pointing to the right place.  If the -						symlink is absolute however then you can leave it -						untouched.  But what if the symlink points to a file -						that you’re moving as part of your batch move operation? -						Now you need to handle that too. -					</p> -				</li> -			</ol> - -			<h2 id="mapping">Name Mapping with <code>mmv</code></h2> - -			<p> -				What is <code>mmv</code>?  It’s the solution to all your -				problems, that’s what it is!  <code>mmv</code> takes as its -				argument(s) a utility and that utilities arguments and uses that -				to create a mapping between old and new filenames — similar to -				the <code>map()</code> function found in many programming -				languages.  I think to best convey how the tool functions, I -				should provide an example.  Let’s try to do the same thing we did -				previously where we tried to turn camelCase files to snake_case, -				but using <code>mmv</code>: -			</p> - -			<figure> -				<pre>m4_fmt_code(camel-to-snake-smart.sh.html)</pre> -			</figure> - -			<p>Let me break down how this works.</p> - -			<p> -				<code>mmv</code> starts by reading a series of filenames -				separated by newlines from the standard input.  Yes, sometimes -				filenames have newlines in them and yes there is a way to handle -				them but I shall get to that later.  The filenames that -				<code>mmv</code> reads from the standard input will be referred -				to as the <em>input files</em>.  Once all the input files have -				been read, the utility specified by the arguments is spawned; in -				this case that would be <code>sed</code> with the argument -				<code>'s/[A-Z]/\L_&/g'</code>. The input files are then piped -				into <code>sed</code> the exact same way that they would have -				been if we ran the above commands without <code>mmv</code>, and -				the output of <code>sed</code> then forms what will be referred -				to as the <em>output files</em>.  Once a complete list of output -				files is accumulated, each input file gets renamed to its -				corresponding output file. -			</p> - -			<p> -				Let’s look at a simpler example.  Say we want to rename 2 files -				in the current directory to use lowercase letters, we could use -				the following command: -			</p> -			 -			<figure> -				<pre>m4_fmt_code(mmv-tr.sh.html)</pre> -			</figure> - -			<p> -				In the above example <code>mmv</code> reads 2 lines from -				standard input, those being <em>LICENSE</em> -				and <em>README</em>.  Those are our 2 input files now. -				The <code>tr</code> utility is then spawned and the input files -				are piped into it.  We can simulate this in the shell: -			</p> - -			<figure> -				<pre>m4_fmt_code(tr.sh.html)</pre> -			</figure> - -			<p> -				As you can see above, <code>tr</code> has produced 2 lines of -				output; these are our 2 output files.  Since we now have our 2 -				input files and 2 output files, <code>mmv</code> can go ahead -				and rename the files.  In this case it will rename -				<em>LICENSE</em> to <em>license</em> and -				<em>README</em> to <em>readme</em>.  For some examples, check -				the <a href="#examples">examples</a> section of this page down -				below. -			</p> - -			<h2 id="newlines">Filenames with Embedded Newlines</h2> - -			<p> -				People are retarded, and as a result we have filenames with -				newlines in them.  All it would have taken to solve this issue -				for everyone was for literally <strong>anybody</strong> during -				the early UNIX days to go “<em>hey, this is a bad idea!</em>”, -				but alas, we must deal with this.  Newlines are of course not -				the only special characters filenames can contain, but they are -				the single most infuriating to deal with; the UNIX utilities all -				being line-oriented really doesn’t work well with these files. -			</p> - -			<p> -				So how does <code>mmv</code> deal with special characters, and -				newlines in particular?  Well it does so by providing the user -				with the <code>-0</code> and <code>-e</code> flags: -			</p> - -			<dl> -				<dt><code>-0</code></dt> -				<dd> -					<p> -						Tell <code>mmv</code> to expect its input to not be -						separated by newlines (‘<code>\n</code>’), but by NUL -						bytes (‘<code>\0</code>’).  NUL bytes are the only -						characters not allowed in filenames besides forward -						slashes, so they are an obvious choice for an -						alternative separator. -					</p> -				</dd> -				<dt><code>-e</code></dt> -				<dd> -					<p> -						Encode newlines in filenames before passing them to the -						provided utility.  Newline characters are replaced by the -						literal string ‘<code>\n</code>’ and backslashes by the -						literal string ‘<code>\\</code>’.  After processing, the -						resulting output is decoded again. -					</p> -					<p> -						If combined with the <code>-0</code> flag, then while -						input will be read assuming a NUL-byte input-seperator, -						the encoded input files will be written to the spawned -						process newline-seperated. -					</p> -				</dd> -			</dl> - -			<h3 id="0-flag">The Simple Case</h3> - -			<p> -				In order to better understand these flags and how they work -				let’s go though another example.  We have 2 files — one with and -				one without an embedded newline — and our goal is to simply -				reverse these filenames.  In this example I am going to be -				displaying newlines in filenames with the “<code>$'\n'</code>” -				syntax as this is how my shell displays embedded newlines. -			</p> - -			<p> -				We can start by just trying to naïvely pass these 2 files -				to <code>mmv</code> and use <code>rev</code> to reverse the -				names, but this doesn’t work: -			</p> - -			<figure> -				<pre>m4_fmt_code(mmv-rev.sh.html)</pre> -			</figure> - -			<p> -			  The reason this doesn’t work is because due to the line-oriented -			  nature of <code>ls</code> and <code>rev</code>, we are actually -			  trying to rename the files <em>foo</em>, <em>bar</em>, and -			  <em>baz</em> to the new filenames <em>zab</em>, -			  <em>rab</em>, and <em>oof</em>.  As can be seen in the following -			  diagram, the embedded newline is causing our input to be ambiguous -			  and <code>mmv</code> can’t reliably proceed -			  anymore <x-ref>1</x-ref>: -			</p> - -			<figure> -				<object data="conflict.svg" type="image/svg+xml"></object> -			</figure> - -			<aside> -				<p data-ref="1"> -					The reason you get a cryptic “file not found” error message -					is because <code>mmv</code> tries to assert that all the -					input files actually exist before doing anything.  Since -					“foo” isn’t a real file, we error out. -				</p> -			</aside> -			 -			<p> -			  The first thing we need to do in order to proceed is to pass -			  the <code>-0</code> flag to <code>mmv</code>.  This will -			  tell <code>mmv</code> that we want to use the NUL-byte as our -			  input separator and not the newline.  We also need <code>ls</code> -			  to actually provide us with the filenames delimited by NUL-bytes. -			  Luckily <abbr class="gnu">GNU</abbr> <code>ls</code> gives us the -			  <code>--zero</code> flag to do just that: -			</p> - -			<figure> -			  <pre>m4_fmt_code(mmv-rev-zero.sh.html)</pre> -			</figure> - -			<p> -				So we’re getting places, but we aren’t quite there yet.  The -				issue we’re getting now is that <code>mmv</code> recieved 2 -				input files from the standard input, but <code>rev</code> -				produced 3 output files.  Why is that?  Well let’s try our hand -				at a little bit of command-line debugging with <code>sed</code>: -			</p> - -			<figure> -				<pre>m4_fmt_code(sed-debugging.sh.html)</pre> -			</figure> - -			<p> -				If you aren’t quite sure what the above is doing, here’s a quick -				summary: -			</p> - -			<ul> -				<li> -					The <code>-U</code> flag given to <code>ls</code> tells it -					not to sort our output.  This is purely just to keep this -					example clear to the reader. -				</li> -				<li> -					The <code>-n</code> flag given to <code>sed</code> tells it -					not to print the input line automatically at the end of the -					provided script. -				</li> -				<li> -					The <code>l</code> command in <code>sed</code> prints the -					current input in a “visually unambiguous form”. -				</li> -			</ul> - -			<p> -				In the <code>sed</code> output, we can see that <samp>$</samp> -				represents the end of a line, and <samp>\000</samp> represents -				the NUL-byte.  All looks good here, we have two inputs seperated -				by NUL-bytes.  Now let’s try to throw in <code>rev</code>: -			</p> - -			<figure> -				<pre>m4_fmt_code(sed-debugging-rev.sh.html)</pre> -			</figure> - -			<p> -				Well wouldn’t you know it?  Since <code>rev</code> <em>also</em> -				works with newline-seperated input, it reversed out NUL-byte -				seperators and now gives us 3 outputs.  Luckily the folks over -				at <em>util-linux</em> provided us with the <code>-0</code> flag -				here too, so that we can properly handle NUL-delimited input. -				Combining all of this together we get a final working product: -			</p> - -			<figure> -				<pre>m4_fmt_code(reverse-embedded-newline.sh.html)</pre> -			</figure> - -			<h3 id="e-flag">Encoding Newlines</h3> - -			<p> -				Sometimes we want to rename a bunch of files, but the command we -				want to use doesn’t support NUL-bytes as nicely as we would -				like.  In these cases, you may want to consider encoding your -				newline characters into the literal string ‘<code>\n</code>’ and -				then passing your input newline-seperated to your given command -				with the <code>-e</code> flag. -			</p> - -			<p> -				For a real-world example, perhaps you want to edit some -				filenames in vim, or whatever other editor you use.  Well we can -				do this incredibly easily with the <code>vipe</code> utility -				from -				the <a href="https://joeyh.name/code/moreutils/">moreutils</a> -				collection.  The <code>vipe</code> command simply reads input -				from the standard input, opens it up in your editor, and then -				prints the resulting output to the standard output; perfect -				for <code>mmv</code>!  We do not really want to deal with -				NUL-bytes in our text-editor though, so let’s just encode our -				newlines: -			</p> - -			<figure> -				<pre>m4_fmt_code(vipe.sh.html)</pre> -			</figure> - -			<aside> -				<p> -					Notice how you still need to pass the <code>-0</code> flag -					to <code>mmv</code> know that our inputfiles may have -					embedded newlines. -				</p> -			</aside> - -			<p> -				When running the above code example, you will see the following -				in your editor: -			</p> - -			<figure> -				<pre>m4_fmt_code(vim.html)</pre> -			</figure> - -			<p> -				After you exit your editor, <code>mmv</code> will decode all -				occurances of ‘<code>\n</code>’ back into a newline, and all -				occurances of ‘<code>\\</code>’ back into a backslash: -			</p> - -			<figure> -				<object data="e-flag.svg" type="image/svg+xml"></object> -			</figure> - -			<h2 id="i-flag">Individual Execution</h2> -			<p> -				The previous examples are great and all, but what do you do if -				your mapping command doesn’t have the concept of an input -				seperator at all?  This is where the <code>-i</code> flag comes -				into play.  With the <code>-i</code> flag we can -				get <code>mmv</code> to execute our mapping command for every -				input filename.  This means that as long as we can work with a -				complete buffer, we don’t need to worry about seperators. -			</p> - -			<p> -				To be honest, I cannot really think of any situation where you -				might actually need to do this.  If you can think of one, -				please <a href="mailto:mail@thomasvoss.com">email me</a> and -				I’ll update the example on this page.  Regardless, let’s imagine -				that we wanted to rename some files so that their filenames are -				replaced with their filename -				<a href="https://en.wikipedia.org/wiki/SHA-1" target="_blank"> -					SHA-1 hash</a>. -				On Linux we have the <code>sha1sum</code> program which reads -				input from the standard input and outputs the SHA-1 hash.  This -				is how we would use it with <code>mmv</code>: -			</p> - -			<figure> -				<pre>m4_fmt_code(sha1sum-long-example.sh.html)</pre> -			</figure> - -			<p> -				Another approach is to invoke <code>mmv</code> twice: -			</p> - -			<figure> -				<pre>m4_fmt_code(sha1sum-short-example.sh.html)</pre> -			</figure> - -			<p> -				If you are confused about why we need to make a call -				to <code>awk</code>, it’s because the <code>sha1sum</code> -				program outputs 2 columns of data.  The first column is our hash -				and the second column is the filename where the to-be-hashed -				data was read from.  We don’t want the second column. -			</p> - -			<p> -				Unlike in previous examples where one process was spawned to map -				all our filenames, with the <code>-i</code> flag we are spawning -				a new instance for each filename.  If you struggle to visualize -				this, perhaps the following diagrams help: -			</p> - -			<figure> -				<figcaption>Invoking <code>mmv</code> without <code>-i</code></figcaption> -				<object data="without-i-flag.svg" type="image/svg+xml"></object> -			</figure> - -			<figure> -				<figcaption>Invoking <code>mmv</code> with <code>-i</code></figcaption> -				<object data="with-i-flag.svg" type="image/svg+xml"></object> -			</figure> - -			<h2 id="safety">Safety</h2> -			<p> -				When compared to the standard <code>for f in *; do mv $f …; -				done</code> or <code>ls | … | xargs -L2 mv</code> -				constructs, <code>mmv</code> is significantly more safe to use. -				These are some of the safety features that are built into the -				tool: -			</p> - -			<ol> -				<li> -					If the number of input- and output files differs, execution -					is aborted before making any changes. -				</li> -				<li> -					If an input file is renamed to the name of another input -					file, the second input file is not lost (i.e. you can rename -					<em>a</em> to <em>b</em> and <em>b</em> to <em>a</em> with -					no problem). -				</li> -				<li> -					All input files must be unique and all output files must be -					unique. Otherwise execution is aborted before making any -					changes. -				</li> -				<li> -					In the case that something goes wrong during execution -					(perhaps you tried to move a file to a non-existant -					directory, or a syscall failed), a backup of your input -					files is saved automatically by <code>mmv</code> for -					recovery. -				</li> -			</ol> - -			<p> -				Due to the way <code>mmv</code> handles #2, when things do go -				wrong you may find that all of your input files have -				disappeared.  Don’t worry though, <code>mmv</code> takes a -				backup of your code before doing anything.  If you -				run <code>mmv</code> with the <code>-v</code> option for verbose -				output, you’ll notice it backing up your stuff in -				the <code>$XDG_CACHE_DIR</code> directory: -			</p> - -			<figure> -				<pre>m4_fmt_code(mmv-verbose.sh.html)</pre> -			</figure> - -			<p> -				Upon successful execution -				the <code>$XDG_CACHE_DIR/mmv/TIMESTAMP</code> directory will be -				automatically removed, but it remains when things go wrong so -				that you can recover any missing data.  The names of the -				backup-subdirectories in the <code>$XDG_CACHE_DIR/mmv</code> -				directory are timestamps of when the directories were created. -				This should make it easier for you to figure out which directory -				you need to recover if you happen to have multiple of these. -			</p> -			 -			<h2 id="examples">Examples</h2> - -			<aside> -				<p> -					All of these examples are ripped straight from -					the <code>mmv(1)</code> manual page. If you -					installed <code>mmv</code> through a package manager or -					via <code>make install</code> then you should have the -					manual installed on your system. -				</p> -			</aside> - -			<p>Swap the files <em>foo</em> and <em>bar</em>:</p> -			<figure> -				<pre>m4_fmt_code(examples/swap.sh.html)</pre> -			</figure> - -			<p> -				Rename all files in the current directory to use hyphens (‘-’) -				instead of spaces: -			</p> -			<figure> -				<pre>m4_fmt_code(examples/hyphens.sh.html)</pre> -			</figure> - -			<p> -				Rename a given list of movies to use lowercase letters and -				hyphens instead of uppercase letters and spaces, and number them -				so that they’re properly ordered in globs (e.g. rename <em>The -				Return of the King.mp4</em> to -				<em>02-the-return-of-the-king.mp4</em>): -			</p> -			<figure> -				<pre>m4_fmt_code(examples/number.sh.html)</pre> -			</figure> - -			<p> -				Rename files interactively in your editor while encoding newline -				into the literal string ‘<code>\n</code>’, making use -				of <code><a href="https://linux.die.net/man/1/vipe" -				target="_blank">vipe(1)</a></code> from <em>moreutils</em>: -			</p> -			<figure> -				<pre>m4_fmt_code(examples/vipe.sh.html)</pre> -			</figure> - -			<p> -				Rename all C source code- and header files in a git repository -				to use snake_case instead of camelCase using -				the <abbr class="gnu">GNU</abbr> -				<code><a href="https://www.man7.org/linux/man-pages/man1/sed.1.html" -				target="_blank">sed(1)</a></code> ‘<code>\n</code>’ extension: -			</p> -			<figure> -				<pre>m4_fmt_code(examples/camel-to-snake.sh.html)</pre> -			</figure> - -			<p> -				Lowercase all filenames within a directory hierarchy which may -				contain newline characters: -			</p> -			<figure> -				<pre>m4_fmt_code(examples/lowercase.sh.html)</pre> -			</figure> - -			<p> -				Map filenames which may contain newlines in the current -				directory with the command ‘<code>cmd</code>’, which itself does -				not support nul-byte separated entries.  This only works -				assuming your mapping doesn’t require any context outside of the -				given input filename (for example, you would not be able to -				number your files as this requires knowledge of the input files -				position in the input list): -			</p> -			<figure> -				<pre>m4_fmt_code(examples/i-flag.sh.html)</pre> -			</figure> -		</main> - -		<hr> -			 -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/prj/mmv/ls-files.sh.html b/src/prj/mmv/ls-files.sh.gsp index d24b5af..95e6af3 100644 --- a/src/prj/mmv/ls-files.sh.html +++ b/src/prj/mmv/ls-files.sh.gsp @@ -1,2 +1,2 @@ -$ <span class="sh-fn">ls</span> +$ @span .sh-fn {-ls}  bytecodeVm.c  fastLexer.c  fastLexer.h  slowParser.c  slowParser.h diff --git a/src/prj/mmv/manual-mv.sh.gsp b/src/prj/mmv/manual-mv.sh.gsp new file mode 100644 index 0000000..0dbc3e5 --- /dev/null +++ b/src/prj/mmv/manual-mv.sh.gsp @@ -0,0 +1,5 @@ +$ @span .sh-fn {-mv} bytecodeVm.c bytecode_vm.c +$ @span .sh-fn {-mv} fastLexer.c fast_lexer.c +$ @span .sh-fn {-mv} fastLexer.h fast_lexer.h +$ @span .sh-fn {-mv} slowParser.c slow_parser.c +$ @span .sh-fn {-mv} slowParser.h slow_parser.h diff --git a/src/prj/mmv/manual-mv.sh.html b/src/prj/mmv/manual-mv.sh.html deleted file mode 100644 index 2484d9f..0000000 --- a/src/prj/mmv/manual-mv.sh.html +++ /dev/null @@ -1,5 +0,0 @@ -$ <span class="sh-fn">mv</span> bytecodeVm.c bytecode_vm.c -$ <span class="sh-fn">mv</span> fastLexer.c fast_lexer.c -$ <span class="sh-fn">mv</span> fastLexer.h fast_lexer.h -$ <span class="sh-fn">mv</span> slowParser.c slow_parser.c -$ <span class="sh-fn">mv</span> slowParser.h slow_parser.h diff --git a/src/prj/mmv/mmv-rev-zero.sh.gsp b/src/prj/mmv/mmv-rev-zero.sh.gsp new file mode 100644 index 0000000..ef8d158 --- /dev/null +++ b/src/prj/mmv/mmv-rev-zero.sh.gsp @@ -0,0 +1,2 @@ +$ @span .sh-fn {-ls} --zero foo$'\\n'bar baz | @span .sh-fn {-mmv} -0 rev +mmv: Files have been added or removed during editing diff --git a/src/prj/mmv/mmv-rev-zero.sh.html b/src/prj/mmv/mmv-rev-zero.sh.html deleted file mode 100644 index 4be992e..0000000 --- a/src/prj/mmv/mmv-rev-zero.sh.html +++ /dev/null @@ -1,2 +0,0 @@ -$ <span class="sh-fn">ls</span> --zero foo$'\n'bar baz | <span class="sh-fn">mmv</span> -0 rev -mmv: Files have been added or removed during editing diff --git a/src/prj/mmv/mmv-rev.sh.gsp b/src/prj/mmv/mmv-rev.sh.gsp new file mode 100644 index 0000000..e2e6a1c --- /dev/null +++ b/src/prj/mmv/mmv-rev.sh.gsp @@ -0,0 +1,2 @@ +$ @span .sh-fn {-ls} foo$'\\n'bar baz | @span .sh-fn {-mmv} rev +mmv: No such file or directory (os error 2) diff --git a/src/prj/mmv/mmv-rev.sh.html b/src/prj/mmv/mmv-rev.sh.html deleted file mode 100644 index 3d2e683..0000000 --- a/src/prj/mmv/mmv-rev.sh.html +++ /dev/null @@ -1,2 +0,0 @@ -$ <span class="sh-fn">ls</span> foo$'\n'bar baz | <span class="sh-fn">mmv</span> rev -mmv: No such file or directory (os error 2) diff --git a/src/prj/mmv/mmv-tr.sh.gsp b/src/prj/mmv/mmv-tr.sh.gsp new file mode 100644 index 0000000..83a728b --- /dev/null +++ b/src/prj/mmv/mmv-tr.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} LICENSE README | @span .sh-fn {-mmv} tr A-Z a-z diff --git a/src/prj/mmv/mmv-tr.sh.html b/src/prj/mmv/mmv-tr.sh.html deleted file mode 100644 index 4d8773a..0000000 --- a/src/prj/mmv/mmv-tr.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> LICENSE README | <span class="sh-fn">mmv</span> tr A-Z a-z diff --git a/src/prj/mmv/mmv-verbose.sh.html b/src/prj/mmv/mmv-verbose.sh.gsp index 3767416..dc4dfa0 100644 --- a/src/prj/mmv/mmv-verbose.sh.html +++ b/src/prj/mmv/mmv-verbose.sh.gsp @@ -1,4 +1,4 @@ -$ <span class="sh-fn">ls</span> foo bar | <span class="sh-fn">mmv</span> -v awk <span class="sh-str">'{ printf "%d-%s\n", NR, $0 }'</span> +$ @span .sh-fn {-ls} foo bar | @span .sh-fn {-mmv} -v awk @span .sh-str {-'{ printf "%d-%s\\n", NR, $0 \}'}  …  created directory ‘/home/thomas/.cache/mmv/1692102229’  created directory ‘/home/thomas/.cache/mmv/1692102229/home/thomas/code/repo/Mango0x45/mmv’ diff --git a/src/prj/mmv/reverse-embedded-newline.sh.gsp b/src/prj/mmv/reverse-embedded-newline.sh.gsp new file mode 100644 index 0000000..3a91d08 --- /dev/null +++ b/src/prj/mmv/reverse-embedded-newline.sh.gsp @@ -0,0 +1,3 @@ +$ @span .sh-fn {-ls} --zero foo$'\\n'bar baz | @span .sh-fn {-mmv} -0 rev -0 +$ @span .sh-fn {-ls} +'rab'$'\\n''oof'   zab diff --git a/src/prj/mmv/reverse-embedded-newline.sh.html b/src/prj/mmv/reverse-embedded-newline.sh.html deleted file mode 100644 index ff84d5c..0000000 --- a/src/prj/mmv/reverse-embedded-newline.sh.html +++ /dev/null @@ -1,3 +0,0 @@ -$ <span class="sh-fn">ls</span> --zero foo$'\n'bar baz | <span class="sh-fn">mmv</span> -0 rev -0 -$ <span class="sh-fn">ls</span> -'rab'$'\n''oof'   zab diff --git a/src/prj/mmv/sed-debugging-rev.sh.gsp b/src/prj/mmv/sed-debugging-rev.sh.gsp new file mode 100644 index 0000000..39b7c5a --- /dev/null +++ b/src/prj/mmv/sed-debugging-rev.sh.gsp @@ -0,0 +1,3 @@ +$ @span .sh-fn {-ls} -U --zero foo$'\\n'bar baz | @span .sh-fn {-rev} | @span .sh-fn {-sed} -n l +oof$ +\\000zab\\000rab$ diff --git a/src/prj/mmv/sed-debugging-rev.sh.html b/src/prj/mmv/sed-debugging-rev.sh.html deleted file mode 100644 index f1fddb1..0000000 --- a/src/prj/mmv/sed-debugging-rev.sh.html +++ /dev/null @@ -1,3 +0,0 @@ -$ <span class="sh-fn">ls</span> -U --zero foo$'\n'bar baz | <span class="sh-fn">rev</span> | <span class="sh-fn">sed</span> -n l -oof$ -\000zab\000rab$ diff --git a/src/prj/mmv/sed-debugging.sh.gsp b/src/prj/mmv/sed-debugging.sh.gsp new file mode 100644 index 0000000..3db277f --- /dev/null +++ b/src/prj/mmv/sed-debugging.sh.gsp @@ -0,0 +1,3 @@ +$ @span .sh-fn {-ls} -U --zero foo$'\\n'bar baz | @span .sh-fn {-sed} -n l +foo$ +bar\\000baz\\000$ diff --git a/src/prj/mmv/sed-debugging.sh.html b/src/prj/mmv/sed-debugging.sh.html deleted file mode 100644 index e61cde4..0000000 --- a/src/prj/mmv/sed-debugging.sh.html +++ /dev/null @@ -1,3 +0,0 @@ -$ <span class="sh-fn">ls</span> -U --zero foo$'\n'bar baz | <span class="sh-fn">sed</span> -n l -foo$ -bar\000baz\000$ diff --git a/src/prj/mmv/sha1sum-long-example.sh.gsp b/src/prj/mmv/sha1sum-long-example.sh.gsp new file mode 100644 index 0000000..f997509 --- /dev/null +++ b/src/prj/mmv/sha1sum-long-example.sh.gsp @@ -0,0 +1,11 @@ +$ @span .sh-fn {-touch} foo bar +$ @span .sh-fn {-cat} <<@span .sh-hd {-EOF} >hash-filename +@span .sh-hd {-#!/bin/sh} + +@span .sh-hd {-sha1sum | awk '{ print \\$1 \}'} +@span .sh-hd {-EOF} +$ @span .sh-fn {-chmod} +x hash-filename +$ @span .sh-fn {-ls} foo bar | @span .sh-fn {-mmv} -i ./hash-filename +$ @span .sh-fn {-ls} +e242ed3bffccdf271b7fbaf34ed72d089537b42f  hash-filename +f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 diff --git a/src/prj/mmv/sha1sum-long-example.sh.html b/src/prj/mmv/sha1sum-long-example.sh.html deleted file mode 100644 index ddbda86..0000000 --- a/src/prj/mmv/sha1sum-long-example.sh.html +++ /dev/null @@ -1,11 +0,0 @@ -$ <span class="sh-fn">touch</span> foo bar -$ <span class="sh-fn">cat</span> <<<span class="sh-hd">EOF</span> >hash-filename -<span class="sh-hd">#!/bin/sh</span> - -<span class="sh-hd">sha1sum | awk '{ print \$1 }'</span> -<span class="sh-hd">EOF</span> -$ <span class="sh-fn">chmod</span> +x hash-filename -$ <span class="sh-fn">ls</span> foo bar | <span class="sh-fn">mmv</span> -i ./hash-filename -$ <span class="sh-fn">ls</span> -e242ed3bffccdf271b7fbaf34ed72d089537b42f  hash-filename -f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 diff --git a/src/prj/mmv/sha1sum-short-example.sh.gsp b/src/prj/mmv/sha1sum-short-example.sh.gsp new file mode 100644 index 0000000..0811dde --- /dev/null +++ b/src/prj/mmv/sha1sum-short-example.sh.gsp @@ -0,0 +1,6 @@ +$ @span .sh-fn {-touch} foo bar +$ @span .sh-fn {-ls} | @span .sh-fn {-mmv} -i sha1sum +$ @span .sh-fn {-ls} | @span .sh-fn {-mmv} awk @span .sh-str {-'{ print $1 \}'} +$ @span .sh-fn {-ls} +e242ed3bffccdf271b7fbaf34ed72d089537b42f +f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 diff --git a/src/prj/mmv/sha1sum-short-example.sh.html b/src/prj/mmv/sha1sum-short-example.sh.html deleted file mode 100644 index 99e781c..0000000 --- a/src/prj/mmv/sha1sum-short-example.sh.html +++ /dev/null @@ -1,6 +0,0 @@ -$ <span class="sh-fn">touch</span> foo bar -$ <span class="sh-fn">ls</span> | <span class="sh-fn">mmv</span> -i sha1sum -$ <span class="sh-fn">ls</span> | <span class="sh-fn">mmv</span> awk <span class="sh-str">'{ print $1 }'</span> -$ <span class="sh-fn">ls</span> -e242ed3bffccdf271b7fbaf34ed72d089537b42f -f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 diff --git a/src/prj/mmv/tr.sh.gsp b/src/prj/mmv/tr.sh.gsp new file mode 100644 index 0000000..e357de8 --- /dev/null +++ b/src/prj/mmv/tr.sh.gsp @@ -0,0 +1,3 @@ +$ @span .sh-fn {-ls} LICENSE README | @span .sh-fn {-tr} A-Z a-z +license +readme diff --git a/src/prj/mmv/tr.sh.html b/src/prj/mmv/tr.sh.html deleted file mode 100644 index db08c38..0000000 --- a/src/prj/mmv/tr.sh.html +++ /dev/null @@ -1,3 +0,0 @@ -$ <span class="sh-fn">ls</span> LICENSE README | <span class="sh-fn">tr</span> A-Z a-z -license -readme diff --git a/src/prj/mmv/vim.gsp b/src/prj/mmv/vim.gsp new file mode 100644 index 0000000..1c20dca --- /dev/null +++ b/src/prj/mmv/vim.gsp @@ -0,0 +1,2 @@ +foo\\nbar +baz diff --git a/src/prj/mmv/vim.html b/src/prj/mmv/vim.html deleted file mode 100644 index cd89cd8..0000000 --- a/src/prj/mmv/vim.html +++ /dev/null @@ -1,2 +0,0 @@ -foo\nbar -baz diff --git a/src/prj/mmv/vipe.sh.gsp b/src/prj/mmv/vipe.sh.gsp new file mode 100644 index 0000000..690db73 --- /dev/null +++ b/src/prj/mmv/vipe.sh.gsp @@ -0,0 +1 @@ +$ @span .sh-fn {-ls} --zero foo$'\\n'bar baz | @span .sh-fn {-mmv} -0e vipe diff --git a/src/prj/mmv/vipe.sh.html b/src/prj/mmv/vipe.sh.html deleted file mode 100644 index c56ff08..0000000 --- a/src/prj/mmv/vipe.sh.html +++ /dev/null @@ -1 +0,0 @@ -$ <span class="sh-fn">ls</span> --zero foo$'\n'bar baz | <span class="sh-fn">mmv</span> -0e vipe diff --git a/src/prj/totp/basic-usage.sh.gsp b/src/prj/totp/basic-usage.sh.gsp new file mode 100644 index 0000000..f1afa3f --- /dev/null +++ b/src/prj/totp/basic-usage.sh.gsp @@ -0,0 +1,7 @@ +$ @span .sh-var {-code}=@span .sh-ex {-`mkpass A-Z0-7`} +$ @span .sh-fn {-totp} $@span .sh-var {-code} +475867 +$ @span .sh-fn {-echo} $@span .sh-var {-code} | @span .sh-fn {-totp} +475867 +$ @span .sh-fn {-totp} -d 10 $@span .sh-var {-code} +0718732338 diff --git a/src/prj/totp/basic-usage.sh.html b/src/prj/totp/basic-usage.sh.html deleted file mode 100644 index 9023218..0000000 --- a/src/prj/totp/basic-usage.sh.html +++ /dev/null @@ -1,7 +0,0 @@ -$ <span class="sh-var">code</span>=<span class="sh-ex">`mkpass A-Z0-7`</span> -$ <span class="sh-fn">totp</span> $<span class="sh-var">code</span> -475867 -$ <span class="sh-fn">echo</span> $<span class="sh-var">code</span> | <span class="sh-fn">totp</span> -475867 -$ <span class="sh-fn">totp</span> -d 10 $<span class="sh-var">code</span> -0718732338 diff --git a/src/prj/totp/index.gsp b/src/prj/totp/index.gsp new file mode 100644 index 0000000..ea5637a --- /dev/null +++ b/src/prj/totp/index.gsp @@ -0,0 +1,134 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-Easy Password Generation} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						The C preprocessor is worse than m4, and I would kill myself before I +						had to use m4. +					} +				} +				figcaption {-Arav K.} +			} +		} + +		main { +			p { +				em {- +					You can find the @code{-totp} git repository over at +					@a href="https://git.sr.ht/~mango/totp" target="_blank" {-sourcehut} +					or +					@a href="https://github.com/Mango0x45/totp" target="_blank" {-GitHub}. +				} +			} + +			h2 {-Table of Contents} +			ul { +				li {a href="#prologue" {-Prologue}} +				li {a href="#terms" {-Terminology}} +				li {a href="#usage" {-Basic Usage}} +				li {a href="#qr" {-Working with QR Codes}} +			} + +			h2 #prologue {-Prologue} +			p {- +				m4_abbr(TOTP) codes are pretty cool, and really easay to do.  They’re +				also the backbone of modern two-factor authentication.  With +				@code{-totp} I hope to handling m4_abbr(TOTP) codes as easy and +				extensible as possible +			} + +			h2 #terms {-Terminology} +			p {- +				There are a few terms that I will be using throughout this post, so it’s +				good to make sure that we’re all on the same page about what I’m +				referring to. +			} + +			dl { +				dt {-Secret} +				dd { +					p {- +						Your @em{-secret} is a +						@a +							href="https://en.wikipedia.org/wiki/Base32" +							target="_blank" +						{-base32} +						encoded secret key that you should under no circumstances share with +						anyone else.  It is from this secret key that we can generate valid +						m4_abbr(TOTP) codes. +					} +				} + +				dt {-Digits} +				dd { +					p {- +						Your @em {-digits} is the length of the generated m4_abbr(TOTP) in +						digits.  If @em{-digits} is 8, then your generated key could be +						‘01234567’.  When dealing with m4_abbr(2FA) this is typically 6. +					} +				} + +				dt {-Period} +				dd { +					p {- +						Your @em{-period} it the duration for which the generated key is +						valid in seconds.  When working with m4_abbr(2FA) this is typically +						30. +					} +				} +			} + +			h2 #usage {-Basic Usage} + +			p {- +				@code{-totp} takes secret keys as command-line arguments, but also reads +				them from the standard input if none are provided.  It assumes that +				@em{-digits} is 6 and @em{-period} is 30.  These defaults can be changed +				with the @code{--d} and @code{--p} flags. +			} + +			figure { +				pre { m4_fmt_code(basic-usage.sh.gsp) } +			} + +			aside { +				p {- +					I’m using @code{-mkpass} to generate a random secret.  You can +					see my post about @code{-mkpass} @a href="/prj/mkpass" {-here}. +				} +			} + +			h2 #qr {-Working with m4_abbr(QR) Codes} +			p {- +				Often times when enabling m4_abbr(2FA) on your account on some website +				or platform, you will be shown a m4_abbr(QR) code you can scan with your +				m4_abbr(2FA) mobile application.  These m4_abbr(QR) codes contain +				@em{-otpauth} m4_abbr(URI)s.  We can extract these from downloaded +				images using utilities such as @code{-zbarimg} and use them in +				@code{-totp} using the @code{--u} flag to enable ‘m4_abbr(URI) mode’ +			} + +			figure { +				pre { m4_fmt_code(zbarimg.sh.gsp) } +			} + +			p {- +				…and that’s all!  There’s nothing else you need.  You can use secret +				keys and otpauth m4_abbr(URI)s, and you can configure the @em{-digits} +				and @em{-period} of the generated codes.  You can generate multiple keys +				at once, and all outputs are printed to the standard output. +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/prj/totp/index.html b/src/prj/totp/index.html deleted file mode 100644 index aa040d4..0000000 --- a/src/prj/totp/index.html +++ /dev/null @@ -1,140 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -  <head> -		m4_include(head.html) -  </head> -  <body> -		<header> -			<div> -				<h1>Easy Password Generation</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>The C preprocessor is worse than m4, and I would kill myself -					before I had to use m4.</p> -				</blockquote> -				<figcaption> -					Arav K. -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				<em> -					You can find the <code>totp</code> git repository over at -					<a href="https://git.sr.ht/~mango/totp" target="_blank">sourcehut</a> -					or <a href="https://github.com/Mango0x45/totp" -					target="_blank">GitHub</a>. -				</em> -			</p> - -			<h2>Table of Contents</h2> - -			<ul> -        <li><a href="#prologue">Prologue</a></li> -        <li><a href="#terms">Terminology</a></li> -        <li><a href="#usage">Basic Usage</a></li> -        <li><a href="#qr">Working with QR Codes</a></li> -			</ul> - -			<h2 id="prologue">Prologue</h2> -			<p> -				<abbr class="totp">TOTP</abbr> codes are pretty cool, and really easy to -				do.  They’re also the backbone of modern two-factor authentication. -				With <code>totp</code> I hope to make -				handling <abbr class="totp">TOTP</abbr> codes as easy and extensible as -				possible. -			</p> - -			<h2 id="terms">Terminology</h2> -			<p> -				There are a few terms that I will be using throughout this post, so it’s -				good to make sure that we’re all on the same page about what I’m -				referring to. -			</p> - -			<dl> -				<dt>Secret</dt> -				<dd> -					<p> -						Your <em>secret</em> is -						a <a href="https://en.wikipedia.org/wiki/Base32" -						target="_blank">base32</a> encoded secret key that you should under -						no circumstances share with anyone else.  It is from this secret key -						that we can generate valid <abbr class="totp">TOTP</abbr> codes. -					</p> -				</dd> - -				<dt>Digits</dt> -				<dd> -					<p> -						Your <em>digits</em> is the length of the generated -						<abbr class="totp">TOTP</abbr> in digits.  If <em>digits</em> is 8, -						then your generated key could be ‘01234567’.  When dealing -						with <abbr class="tfa">2FA</abbr> this is typically 6. -					</p> -				</dd> - -				<dt>Period</dt> -				<dd> -					<p> -						Your <em>period</em> it the duration for which the generated key is -						valid in seconds.  When working with <abbr class="tfa">2FA</abbr> -						this is typically 30. -					</p> -				</dd> -			</dl> - -			<h2 id="usage">Basic Usage</h2> -			<p> -				<code>totp</code> takes secret keys as command-line arguments, but also -				reads them from the standard input if none are provided.  It assumes -				that <em>digits</em> is 6 and <em>period</em> is 30.  These defaults can -				be changed with the <code>-d</code> and <code>-p</code> flags. -			</p> - -			<figure> -				<pre>m4_fmt_code(basic-usage.sh.html)</pre> -			</figure> - -			<aside> -				<p> -					I’m using <code>mkpass</code> to generate a random secret.  You can -					see my post about <code>mkpass</code> <a href="/prj/mkpass">here</a>. -				</p> -			</aside> - -			<h2 id="qr">Working with <abbr class="qr">QR</abbr> Codes</h2> -			<p> -				Often times when enabling <abbr class="tfa">2FA</abbr> on your account -				on some website or platform, you will be shown -				a <abbr class="qr">QR</abbr> code you can scan with -				your <abbr class="tfa">2FA</abbr> mobile application. -				These <abbr class="qr">QR</abbr> codes -				contain <em>otpauth</em> <abbr class="uri">URI</abbr>s.  We can extract -				these from downloaded images using utilities such -				as <code>zbarimg</code> and use them in <code>totp</code> using -				the <code>-u</code> flag to enable ‘<abbr class="uri">URI</abbr> mode’ -			</p> - -			<figure> -				<pre>m4_fmt_code(zbarimg.sh.html)</pre> -			</figure> - -			…and that’s all!  There’s nothing else you need.  You can use secret keys -			and otpauth <abbr class="uri">URI</abbr>s, and you can configure -			the <em>digits</em> and <em>period</em> of the generated codes.  You can -			generate multiple keys at once, and all outputs are printed to the -			standard output. -		</main> - -		<hr> - -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/prj/totp/zbarimg.sh.gsp b/src/prj/totp/zbarimg.sh.gsp new file mode 100644 index 0000000..cd0669b --- /dev/null +++ b/src/prj/totp/zbarimg.sh.gsp @@ -0,0 +1,4 @@ +$ @span .sh-fn {-zbarimg} -q my-qr-code.svg  @span .sh-cmt {-# Also works with jpg, png, etc.} +QR-Code:otpauth://totp/GitHub:Mango0x45?secret=O1AIWMONKWVRJY4H&issuer=GitHub +$ @span .sh-fn {-zbarimg} -q my-qr-code.svg | @span .sh-fn {-sed} s/QR-Code:// | @span .sh-fn {-totp} -u +554210 diff --git a/src/prj/totp/zbarimg.sh.html b/src/prj/totp/zbarimg.sh.html deleted file mode 100644 index 862eb78..0000000 --- a/src/prj/totp/zbarimg.sh.html +++ /dev/null @@ -1,4 +0,0 @@ -$ <span class="sh-fn">zbarimg</span> -q my-qr-code.svg  <span class="sh-cmt"># Also works with jpg, png, etc.</span> -QR-Code:otpauth://totp/GitHub:Mango0x45?secret=O1AIWMONKWVRJY4H&issuer=GitHub -$ <span class="sh-fn">zbarimg</span> -q my-qr-code.svg | <span class="sh-fn">sed</span> s/QR-Code:// | <span class="sh-fn">totp</span> -u -554210 diff --git a/src/srp/fw-ec/fn-lock-1.diff.gsp b/src/srp/fw-ec/fn-lock-1.diff.gsp new file mode 100644 index 0000000..f847e41 --- /dev/null +++ b/src/srp/fw-ec/fn-lock-1.diff.gsp @@ -0,0 +1,12 @@ +@span .diff-meta {-diff --git a/board/hx20/board.h b/board/hx20/board.h} +@span .diff-meta {-index 7b4ea288a..cfc6a61a2 100644} +@span .diff-meta {---- a/board/hx20/board.h} +@span .diff-meta {-+++ b/board/hx20/board.h} +@span .diff-loc {-\@\@ -218,7 +218,6 \@\@} + #define CONFIG_CMD_LEDTEST + #define CONFIG_LED_PWM_COUNT 3 + #define CONFIG_LED_PWM_TASK_DISABLED +@span .diff-del {--#define CONFIG_CAPSLED_SUPPORT} + + #ifdef CONFIG_ACCEL_KX022 + #define CONFIG_LID_ANGLE diff --git a/src/srp/fw-ec/fn-lock-1.diff.html b/src/srp/fw-ec/fn-lock-1.diff.html deleted file mode 100644 index 9222d4b..0000000 --- a/src/srp/fw-ec/fn-lock-1.diff.html +++ /dev/null @@ -1,12 +0,0 @@ -<span class="diff-meta">diff --git a/board/hx20/board.h b/board/hx20/board.h</span> -<span class="diff-meta">index 7b4ea288a..cfc6a61a2 100644</span> -<span class="diff-meta">--- a/board/hx20/board.h</span> -<span class="diff-meta">+++ b/board/hx20/board.h</span> -<span class="diff-loc">@@ -218,7 +218,6 @@</span> - #define CONFIG_CMD_LEDTEST - #define CONFIG_LED_PWM_COUNT 3 - #define CONFIG_LED_PWM_TASK_DISABLED -<span class="diff-del">-#define CONFIG_CAPSLED_SUPPORT</span> - - #ifdef CONFIG_ACCEL_KX022 - #define CONFIG_LID_ANGLE diff --git a/src/srp/fw-ec/fn-lock-2.diff.gsp b/src/srp/fw-ec/fn-lock-2.diff.gsp new file mode 100644 index 0000000..7f9e702 --- /dev/null +++ b/src/srp/fw-ec/fn-lock-2.diff.gsp @@ -0,0 +1,36 @@ +@span .diff-meta {-diff --git a/board/hx20/keyboard_customization.c b/board/hx20/keyboard_customization.c} +@span .diff-meta {-index 2b91f2e0c..9a5050a0f 100644} +@span .diff-meta {---- a/board/hx20/keyboard_customization.c} +@span .diff-meta {-+++ b/board/hx20/keyboard_customization.c} +@span .diff-loc {-\@\@ -249,6 +249,23 \@\@ int fn_table_set(int8_t pressed, uint32_t fn_bit)} + 	return false; + \} + +@span .diff-ins {-+static void hx20_update_fnkey_led(void) {} +@span .diff-ins {-+	/* Turn the capslock light into a fn-lock light */} +@span .diff-ins {-+	gpio_set_level(GPIO_CAP_LED_L, (Fn_key & FN_LOCKED) ? 1 : 0);} +@span .diff-ins {-+\}} +@span .diff-ins {-+} +@span .diff-ins {-+/* Set the fn-lock light to the correct setting when the system resumes */} +@span .diff-ins {-+void hx20_fnkey_resume(void) {} +@span .diff-ins {-+	hx20_update_fnkey_led();} +@span .diff-ins {-+\}} +@span .diff-ins {-+DECLARE_HOOK(HOOK_CHIPSET_RESUME, hx20_fnkey_resume, HOOK_PRIO_DEFAULT);} +@span .diff-ins {-+} +@span .diff-ins {-+/* Disable the fn-lock light on suspend */} +@span .diff-ins {-+void hx20_fnkey_suspend(void) {} +@span .diff-ins {-+	gpio_set_level(GPIO_CAP_LED_L, 0);} +@span .diff-ins {-+\}} +@span .diff-ins {-+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, hx20_fnkey_suspend, HOOK_PRIO_DEFAULT);} +@span .diff-ins {-+} + void fnkey_shutdown(void) { + 	uint8_t current_kb = 0; + +@span .diff-loc {-\@\@ -420,6 +437,7 \@\@ int functional_hotkey(uint16_t *key_code, int8_t pressed)} + 					Fn_key &= ~FN_LOCKED; + 				else + 					Fn_key |= FN_LOCKED; +@span .diff-ins {-+				hx20_update_fnkey_led();} + 			\} + 			return EC_ERROR_UNIMPLEMENTED; + 		\} diff --git a/src/srp/fw-ec/fn-lock-2.diff.html b/src/srp/fw-ec/fn-lock-2.diff.html deleted file mode 100644 index f1a7a39..0000000 --- a/src/srp/fw-ec/fn-lock-2.diff.html +++ /dev/null @@ -1,36 +0,0 @@ -<span class="diff-meta">diff --git a/board/hx20/keyboard_customization.c b/board/hx20/keyboard_customization.c</span> -<span class="diff-meta">index 2b91f2e0c..9a5050a0f 100644</span> -<span class="diff-meta">--- a/board/hx20/keyboard_customization.c</span> -<span class="diff-meta">+++ b/board/hx20/keyboard_customization.c</span> -<span class="diff-loc">@@ -249,6 +249,23 @@ int fn_table_set(int8_t pressed, uint32_t fn_bit)</span> - 	return false; - } - -<span class="diff-ins">+static void hx20_update_fnkey_led(void) {</span> -<span class="diff-ins">+	/* Turn the capslock light into a fn-lock light */</span> -<span class="diff-ins">+	gpio_set_level(GPIO_CAP_LED_L, (Fn_key & FN_LOCKED) ? 1 : 0);</span> -<span class="diff-ins">+}</span> -<span class="diff-ins">+</span> -<span class="diff-ins">+/* Set the fn-lock light to the correct setting when the system resumes */</span> -<span class="diff-ins">+void hx20_fnkey_resume(void) {</span> -<span class="diff-ins">+	hx20_update_fnkey_led();</span> -<span class="diff-ins">+}</span> -<span class="diff-ins">+DECLARE_HOOK(HOOK_CHIPSET_RESUME, hx20_fnkey_resume, HOOK_PRIO_DEFAULT);</span> -<span class="diff-ins">+</span> -<span class="diff-ins">+/* Disable the fn-lock light on suspend */</span> -<span class="diff-ins">+void hx20_fnkey_suspend(void) {</span> -<span class="diff-ins">+	gpio_set_level(GPIO_CAP_LED_L, 0);</span> -<span class="diff-ins">+}</span> -<span class="diff-ins">+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, hx20_fnkey_suspend, HOOK_PRIO_DEFAULT);</span> -<span class="diff-ins">+</span> - void fnkey_shutdown(void) { - 	uint8_t current_kb = 0; - -<span class="diff-loc">@@ -420,6 +437,7 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)</span> - 					Fn_key &= ~FN_LOCKED; - 				else - 					Fn_key |= FN_LOCKED; -<span class="diff-ins">+				hx20_update_fnkey_led();</span> - 			} - 			return EC_ERROR_UNIMPLEMENTED; - 		} diff --git a/src/srp/fw-ec/hybrid.diff.gsp b/src/srp/fw-ec/hybrid.diff.gsp new file mode 100644 index 0000000..dfd4518 --- /dev/null +++ b/src/srp/fw-ec/hybrid.diff.gsp @@ -0,0 +1,88 @@ +@span .diff-meta {-diff --git a/board/hx20/keyboard_customization.c b/board/hx20/keyboard_customization.c} +@span .diff-meta {-index 9a5050a0f..2756f17ce 100644} +@span .diff-meta {---- a/board/hx20/keyboard_customization.c} +@span .diff-meta {-+++ b/board/hx20/keyboard_customization.c} +@span .diff-loc {-\@\@ -22,12 +22,15 \@\@} + #define CPRINTS(format, args...) cprints(CC_KEYBOARD, format, ## args) + #define CPRINTF(format, args...) cprintf(CC_KEYBOARD, format, ## args) + +@span .diff-ins {-+/* The scancode for the caps-lock key, which is now a hybrid key */} +@span .diff-ins {-+#define SCANCODE_CTRL_ESC 0x0101} +@span .diff-ins {-+} + uint16_t scancode_set2[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = { + 		{0x0021, 0x007B, 0x0079, 0x0072, 0x007A, 0x0071, 0x0069, 0xe04A\}, + 		{0xe071, 0xe070, 0x007D, 0xe01f, 0x006c, 0xe06c, 0xe07d, 0x0077\}, + 		{0x0015, 0x0070, 0x00ff, 0x000D, 0x000E, 0x0016, 0x0067, 0x001c\}, + 		{0xe011, 0x0011, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000\}, +@span .diff-del {--		{0xe05a, 0x0029, 0x0024, 0x000c, 0x0058, 0x0026, 0x0004, 0xe07a\},} +@span .diff-ins {-+		{0xe05a, 0x0029, 0x0024, 0x000c, 0x0101, 0x0026, 0x0004, 0xe07a\},} + 		{0x0022, 0x001a, 0x0006, 0x0005, 0x001b, 0x001e, 0x001d, 0x0076\}, + 		{0x002A, 0x0032, 0x0034, 0x002c, 0x002e, 0x0025, 0x002d, 0x002b\}, + 		{0x003a, 0x0031, 0x0033, 0x0035, 0x0036, 0x003d, 0x003c, 0x003b\}, +@span .diff-loc {-\@\@ -497,6 +500,55 \@\@ int functional_hotkey(uint16_t *key_code, int8_t pressed)} + 	return EC_SUCCESS; + \} + +@span .diff-ins {-+int try_ctrl_esc(uint16_t *key_code, int8_t pressed) {} +@span .diff-ins {-+	static enum {} +@span .diff-ins {-+		NONE,} +@span .diff-ins {-+		HELD,} +@span .diff-ins {-+		CTRL} +@span .diff-ins {-+	\} ctrl_esc_state;} +@span .diff-ins {-+} +@span .diff-ins {-+	if (*key_code == SCANCODE_CTRL_ESC) {} +@span .diff-ins {-+		/* If we pressed the caps key, enter the HELD state.  Otherwise,} +@span .diff-ins {-+		 * we are either releasing from the HELD state or the CTRL} +@span .diff-ins {-+		 * state.  In both cases we should reset the state to NONE, but} +@span .diff-ins {-+		 * when releasing from the HELD state we want to send an ESC and} +@span .diff-ins {-+		 * when releasing from the CTRL state we want to end the CTRL.} +@span .diff-ins {-+		 *} +@span .diff-ins {-+		 * Also important to note is that even before we know if we’re} +@span .diff-ins {-+		 * going to be acting as ESC or CTRL, we need to send a press-} +@span .diff-ins {-+		 * event of the CTRL key because you can chord CTRL with mouse-} +@span .diff-ins {-+		 * clicks too, not just other keys.} +@span .diff-ins {-+		 */} +@span .diff-ins {-+		if (pressed) {} +@span .diff-ins {-+			ctrl_esc_state = HELD;} +@span .diff-ins {-+			simulate_keyboard(SCANCODE_LEFT_CTRL, 1);} +@span .diff-ins {-+		\} else if (ctrl_esc_state == HELD) {} +@span .diff-ins {-+			ctrl_esc_state = NONE;} +@span .diff-ins {-+			simulate_keyboard(SCANCODE_LEFT_CTRL, 0);} +@span .diff-ins {-+			simulate_keyboard(SCANCODE_ESC, 1);} +@span .diff-ins {-+			simulate_keyboard(SCANCODE_ESC, 0);} +@span .diff-ins {-+		\} else if (ctrl_esc_state == CTRL) {} +@span .diff-ins {-+			ctrl_esc_state = NONE;} +@span .diff-ins {-+			simulate_keyboard(SCANCODE_LEFT_CTRL, 0);} +@span .diff-ins {-+		\}} +@span .diff-ins {-+} +@span .diff-ins {-+		return EC_ERROR_UNIMPLEMENTED;} +@span .diff-ins {-+	\}} +@span .diff-ins {-+} +@span .diff-ins {-+	/* If we get here then we are dealing with a key that isn’t the caps} +@span .diff-ins {-+	 * key.  In that case we need to handle all 3 states.  If the state is} +@span .diff-ins {-+	 * NONE then we can just exit from this function.  If it’s HELD and we} +@span .diff-ins {-+	 * are pressing a key, then that’s a key-chord and we need to start a} +@span .diff-ins {-+	 * CTRL.  Finally, if we are in the CTRL state, there is nothing to do.} +@span .diff-ins {-+	 */} +@span .diff-ins {-+	if (ctrl_esc_state == HELD && pressed) {} +@span .diff-ins {-+		ctrl_esc_state = CTRL;} +@span .diff-ins {-+		simulate_keyboard(SCANCODE_LEFT_CTRL, 1);} +@span .diff-ins {-+	\}} +@span .diff-ins {-+} +@span .diff-ins {-+	return EC_SUCCESS;} +@span .diff-ins {-+\}} +@span .diff-ins {-+} + enum ec_error_list keyboard_scancode_callback(uint16_t *make_code, + 					      int8_t pressed) + { +@span .diff-loc {-\@\@ -521,6 +573,10 \@\@ enum ec_error_list keyboard_scancode_callback(uint16_t *make_code,} + 	if (!pos_get_state()) + 		return EC_SUCCESS; + +@span .diff-ins {-+	r = try_ctrl_esc(make_code, pressed);} +@span .diff-ins {-+	if (r != EC_SUCCESS)} +@span .diff-ins {-+		return r;} +@span .diff-ins {-+} + 	r = hotkey_F1_F12(make_code, Fn_key, pressed); + 	if (r != EC_SUCCESS) + 		return r; diff --git a/src/srp/fw-ec/hybrid.diff.html b/src/srp/fw-ec/hybrid.diff.html deleted file mode 100644 index 0ad9717..0000000 --- a/src/srp/fw-ec/hybrid.diff.html +++ /dev/null @@ -1,88 +0,0 @@ -<span class="diff-meta">diff --git a/board/hx20/keyboard_customization.c b/board/hx20/keyboard_customization.c</span> -<span class="diff-meta">index 9a5050a0f..2756f17ce 100644</span> -<span class="diff-meta">--- a/board/hx20/keyboard_customization.c</span> -<span class="diff-meta">+++ b/board/hx20/keyboard_customization.c</span> -<span class="diff-loc">@@ -22,12 +22,15 @@</span> - #define CPRINTS(format, args...) cprints(CC_KEYBOARD, format, ## args) - #define CPRINTF(format, args...) cprintf(CC_KEYBOARD, format, ## args) - -<span class="diff-ins">+/* The scancode for the caps-lock key, which is now a hybrid key */</span> -<span class="diff-ins">+#define SCANCODE_CTRL_ESC 0x0101</span> -<span class="diff-ins">+</span> - uint16_t scancode_set2[KEYBOARD_COLS_MAX][KEYBOARD_ROWS] = { - 		{0x0021, 0x007B, 0x0079, 0x0072, 0x007A, 0x0071, 0x0069, 0xe04A}, - 		{0xe071, 0xe070, 0x007D, 0xe01f, 0x006c, 0xe06c, 0xe07d, 0x0077}, - 		{0x0015, 0x0070, 0x00ff, 0x000D, 0x000E, 0x0016, 0x0067, 0x001c}, - 		{0xe011, 0x0011, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, -<span class="diff-del">-		{0xe05a, 0x0029, 0x0024, 0x000c, 0x0058, 0x0026, 0x0004, 0xe07a},</span> -<span class="diff-ins">+		{0xe05a, 0x0029, 0x0024, 0x000c, 0x0101, 0x0026, 0x0004, 0xe07a},</span> - 		{0x0022, 0x001a, 0x0006, 0x0005, 0x001b, 0x001e, 0x001d, 0x0076}, - 		{0x002A, 0x0032, 0x0034, 0x002c, 0x002e, 0x0025, 0x002d, 0x002b}, - 		{0x003a, 0x0031, 0x0033, 0x0035, 0x0036, 0x003d, 0x003c, 0x003b}, -<span class="diff-loc">@@ -497,6 +500,55 @@ int functional_hotkey(uint16_t *key_code, int8_t pressed)</span> - 	return EC_SUCCESS; - } - -<span class="diff-ins">+int try_ctrl_esc(uint16_t *key_code, int8_t pressed) {</span> -<span class="diff-ins">+	static enum {</span> -<span class="diff-ins">+		NONE,</span> -<span class="diff-ins">+		HELD,</span> -<span class="diff-ins">+		CTRL</span> -<span class="diff-ins">+	} ctrl_esc_state;</span> -<span class="diff-ins">+</span> -<span class="diff-ins">+	if (*key_code == SCANCODE_CTRL_ESC) {</span> -<span class="diff-ins">+		/* If we pressed the caps key, enter the HELD state.  Otherwise,</span> -<span class="diff-ins">+		 * we are either releasing from the HELD state or the CTRL</span> -<span class="diff-ins">+		 * state.  In both cases we should reset the state to NONE, but</span> -<span class="diff-ins">+		 * when releasing from the HELD state we want to send an ESC and</span> -<span class="diff-ins">+		 * when releasing from the CTRL state we want to end the CTRL.</span> -<span class="diff-ins">+		 *</span> -<span class="diff-ins">+		 * Also important to note is that even before we know if we’re</span> -<span class="diff-ins">+		 * going to be acting as ESC or CTRL, we need to send a press-</span> -<span class="diff-ins">+		 * event of the CTRL key because you can chord CTRL with mouse-</span> -<span class="diff-ins">+		 * clicks too, not just other keys.</span> -<span class="diff-ins">+		 */</span> -<span class="diff-ins">+		if (pressed) {</span> -<span class="diff-ins">+			ctrl_esc_state = HELD;</span> -<span class="diff-ins">+			simulate_keyboard(SCANCODE_LEFT_CTRL, 1);</span> -<span class="diff-ins">+		} else if (ctrl_esc_state == HELD) {</span> -<span class="diff-ins">+			ctrl_esc_state = NONE;</span> -<span class="diff-ins">+			simulate_keyboard(SCANCODE_LEFT_CTRL, 0);</span> -<span class="diff-ins">+			simulate_keyboard(SCANCODE_ESC, 1);</span> -<span class="diff-ins">+			simulate_keyboard(SCANCODE_ESC, 0);</span> -<span class="diff-ins">+		} else if (ctrl_esc_state == CTRL) {</span> -<span class="diff-ins">+			ctrl_esc_state = NONE;</span> -<span class="diff-ins">+			simulate_keyboard(SCANCODE_LEFT_CTRL, 0);</span> -<span class="diff-ins">+		}</span> -<span class="diff-ins">+</span> -<span class="diff-ins">+		return EC_ERROR_UNIMPLEMENTED;</span> -<span class="diff-ins">+	}</span> -<span class="diff-ins">+</span> -<span class="diff-ins">+	/* If we get here then we are dealing with a key that isn’t the caps</span> -<span class="diff-ins">+	 * key.  In that case we need to handle all 3 states.  If the state is</span> -<span class="diff-ins">+	 * NONE then we can just exit from this function.  If it’s HELD and we</span> -<span class="diff-ins">+	 * are pressing a key, then that’s a key-chord and we need to start a</span> -<span class="diff-ins">+	 * CTRL.  Finally, if we are in the CTRL state, there is nothing to do.</span> -<span class="diff-ins">+	 */</span> -<span class="diff-ins">+	if (ctrl_esc_state == HELD && pressed) {</span> -<span class="diff-ins">+		ctrl_esc_state = CTRL;</span> -<span class="diff-ins">+		simulate_keyboard(SCANCODE_LEFT_CTRL, 1);</span> -<span class="diff-ins">+	}</span> -<span class="diff-ins">+</span> -<span class="diff-ins">+	return EC_SUCCESS;</span> -<span class="diff-ins">+}</span> -<span class="diff-ins">+</span> - enum ec_error_list keyboard_scancode_callback(uint16_t *make_code, - 					      int8_t pressed) - { -<span class="diff-loc">@@ -521,6 +573,10 @@ enum ec_error_list keyboard_scancode_callback(uint16_t *make_code,</span> - 	if (!pos_get_state()) - 		return EC_SUCCESS; - -<span class="diff-ins">+	r = try_ctrl_esc(make_code, pressed);</span> -<span class="diff-ins">+	if (r != EC_SUCCESS)</span> -<span class="diff-ins">+		return r;</span> -<span class="diff-ins">+</span> - 	r = hotkey_F1_F12(make_code, Fn_key, pressed); - 	if (r != EC_SUCCESS) - 		return r; diff --git a/src/srp/fw-ec/index.gsp b/src/srp/fw-ec/index.gsp new file mode 100644 index 0000000..254becc --- /dev/null +++ b/src/srp/fw-ec/index.gsp @@ -0,0 +1,229 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-Framework is Awesome} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						UNIX was not designed to stop its users from doing stupid things, as +						that would also stop them from doing clever things. +					} +				} +				figcaption {-Doug Gywn} +			} +		} + +		main { +			h2 {-Table of Contents} + +			ul { +				li {a href="#framework" {-Framework and the EC}} +				li {a href="#led" {-LED Fun!}} +				li {a href="#more" {-There’s More Than One LED‽}} +				li {a href="#hybrid" {-The Hybrid Key}} +				li {a href="#next" {-What’s Next?}} +			} + +			h2 #framework {-Framework and the m4_abbr(EC)} +			p {- +				@a href="https://frame.work" target="_blank" {-Framework} +				— for those unaware — is the coolest laptop manufacturer ever.  Their +				whole @em{-shtick} is producing laptops that give the user the ability +				to easily and effortlessly disassemble, repair, and modify their +				hardware.  I highly suggest checking them out if you’re interested in +				computer hardware at all.  The laptops even have hotswappable I/O! +			} + +			p {- +				Anyways getting back on topic, Framework has also been giving power to +				the user on the software-side of things too!  A good while ago they +				open-sourced the +				@a +					href="https://github.com/FrameworkComputer/EmbeddedController" +					target="_blank" +				{-code for the embedded controller} +				of their laptops, which offers all sorts of possibilities for +				customization of the keyboard, m4_abbr(LED) lights, and more. +			} + +			h2 #led {-m4_abbr(LED) Fun!} +			p {- +				This is an area of the m4_abbr(EC) which I have not really looked at or +				touched much.  I do want to play around with this a lot more in the +				coming future though!  So far just for shits-and-giggles, I’ve patched +				the m4_abbr(EC) to make the power-button m4_abbr(LED) green instead of +				the normal boring white: +			} + +			aside { +				p {- +					Just a tip: if you want to try any of these patches out, +					simply copy the diffs and paste them +					into @code {-git apply}. +				} +			} + +			figure { +				figcaption { +					code {-~/board/hx20/led.c} +				} +				pre { m4_fmt_code(led.diff.gsp) } +			} + +			p {- +				As you can see, it’s all fairly simple.  I just had to change our +				@code{-EC_LED_COLOR_WHITE} for @code{-EC_LED_COLOR_GREEN}.  The codebase +				defines a few colors, but they’re defined as m4_abbr(RGB) tuples which +				is awesome, because it opens the door to custom m4_abbr(RGB) effects in +				the future! +			} + +			h2 #more {-There’s More Than One m4_abbr(LED)‽} +			p {- +				That’s right!  The Framework laptop I own (13″; the 16″ releases soon +				though!) has 3 more m4_abbr(LED) lights.  One on the left of the +				chassis, one on right of the chassis, and one on the capslock key.  The +				capslock m4_abbr(LED) acts as an indicator of whether or not you’ve got +				capslock enabled.  This is useless to me though, because my custom +				keyboard layout doesn’t even support capslock (see the next section) — +				so I patched it to be a function-lock indicator instead! +			} + +			p {- +				Here’s the diff — but do take care if you want to apply similar patches +				to your laptop!  The files I’m editing are under @code{-board/hx20} +				since I’m on an 11th Gen Intel m4_abbr(CPU).  If you have a different +				m4_abbr(CPU), you will probably need to fuck with different code: +			} + +			figure { +				figcaption { +					code {-~/board/hx20/board.h} +				} +				pre { m4_fmt_code(fn-lock-1.diff.gsp) } +			} + +			figure { +				figcaption { +					code {-~/board/hx20/keyboard-customization.c} +				} +				pre { m4_fmt_code(fn-lock-2.diff.gsp) } +			} + +			p {- +				As you can see, toggling the capslock m4_abbr(LED) is as simple as +				invoking @code{-gpio_set_level()}.  Not only that, but disabling its +				functionality with the capslock key is as easy as undefining the +				@code{-CONFIG_CAPSLOCK_SUPPORT} macro.  Figuring out if the function key +				is locked is also really easy.  The @code{-Fn_key} global variable is a +				bit-field containing information pertaining to the function key, and we +				also conveniently already have the @code{-FN_LOCKED} constant defined +				that we can bitwise-AND with @code{-Fn_key} to check the locked state! +			} + +			p {- +				We also setup some hooks with the @code{-DECLARE_HOOK()} macro.  These +				just ensure that we are behaving properly on system resume and -suspend. +			} + +			h2 #hybrid {-The Hybrid Key} +			p {- +				Wouldn’t it be cool if a physical key could represent two keys at the +				same time?  I thought so too.  Like all Emacs users, I suffer from a +				distinct lack of easily-accessible modifier keys.  I need escape because +				I use Vim bindings; I need left-control because all the Emacs bindings +				use it; I need super for my window-managers’ bindings; I need left-alt +				so I can type characters that don’t come on a standard American keyboard +				(such as @em{-ß}, @em{-€}, and @em{-é}), and now I have a problem.  All +				my modifiers are taken, but Emacs still needs a meta key to work! +			} + +			figure { +				figcaption {- +					@cite{-Workflow} by Randall Munroe +				} +				img alt="XKCD Comic 1172" src="1172.png" {} +			} + +			p {- +				What will I ever do‽  Well thanks to Framework making the m4_abbr(EC) +				open-source, and conveniently giving me a file called +				@code{-keyboard_customization.c}, I’m going to take two keys and stick +				them in one!  The basic premise is this: the capslock key is arguably +				the easiest modifier key to hit, and it’s currently bound to the escape +				key on my system.  This is inefficient though, because nobody makes +				key-bindings that chord the escape-key with another key; +				chords @x-ref{-1} are always done with a modifier like control, and +				Emacs is no different.  So my plan was to make it so that the capslock +				key when used on its own mimics an escape-key, while instead mimicking +				the left-control-key when used in a chord with another key. +			} + +			p {- +				It took me a little longer this time to figure out how to implement what +				I wanted since the code isn’t as clear, but it was still a surprisingly +				easy feature to patch into the m4_abbr(EC)!  I basically just updated +				the scancode table, swapping out the capslock scancode for my own random +				one that I called @code{-SCANCODE_CTRL_ESC}.  I then created a new +				function called @code{-try_ctrl_esc()} which is called in the on-keyup +				and -down callback function.  The @code{-try_ctrl_esc()} function +				handles all of the logic as you can see in the following diff; it’s +				basically just a state machine: +			} + +			aside { +				p data-ref="1" {- +					If you’re confused by what I mean by a “key-chord”, I am simply +					referring to pressing multiple keys in conjunction, such as when you +					press “@kbd{-Ctrl + C}” to copy text. +				} +			} + +			figure { +				figcaption { +					code {-~/board/hx20/keyboard_customization.c} +				} +				pre { m4_fmt_code(hybrid.diff.gsp) } +			} + +			p {- +				One thing that’s good to take note of is what I return from +				@code{-try_ctrl_esc()}.  The general pattern for handling a keyup or +				-down event is to stick the following code into +				@code{-keyboard_scancode_callback()}: +			} + +			figure { +				figcaption {- +					@code{-keyboard_scancode_callback()} in +					@code{-~/board/hx20/keyboard_customization.c} +				} +				pre { m4_fmt_code(kbd-sc-cb.c.gsp) } +			} + +			p {- +				In @code{-my_handler_function()} (or whatever you decide to name it), +				you attempt to handle the event.  If you don’t want to handle a +				particular event and instead want to pass it on to the next handler, you +				need to return @code{-EC_SUCCESS}.  If you managed to successfully +				handle the event though, then you need to return an error such as +				@code{-EC_ERROR_UNIMPLEMENTED}.  It’s pretty stupid and makes very +				little sense from a naming perspective, but oh well… +			} + +			h2 #next {-What’s Next?} +			p {- +				m4_abbr(RGB) m4_abbr(LED)s maybe. +			} +		} + +		hr{} +		 +		footer { m4_footer } +	} +} diff --git a/src/srp/fw-ec/index.html b/src/srp/fw-ec/index.html deleted file mode 100644 index 1a2d2ec..0000000 --- a/src/srp/fw-ec/index.html +++ /dev/null @@ -1,263 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -	<head> -		m4_include(head.html) -	</head> -	<body> -		<header> -			<div> -				<h1>Framework is Awesome</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>UNIX was not designed to stop its users from doing stupid -					things, as that would also stop them from doing clever -					things.</p> -				</blockquote> -				<figcaption> -					Doug Gywn -				</figcaption> -			</figure> -		</header> - -		<main> -			<h2>Table of Contents</h2> - -			<ul> -				<li><a href="#framework">Framework and the EC</a></li> -				<li><a href="#led">LED Fun!</a></li> -				<li><a href="#more">There’s More Than One LED‽</a></li> -				<li><a href="#hybrid">The Hybrid Key</a></li> -				<li><a href="#next">What’s Next?</a></li> -			</ul> - -			<h2 id="framework">Framework and the <abbr class="ec">EC</abbr></h2> - -			<p> -				<a href="https://frame.work" target="_blank"> -					Framework -				</a> -				— for those unaware — is the coolest laptop manufacturer ever. -				Their whole <em>shtick</em> is producing laptops that give the -				user the ability to easily and effortlessly disassemble, repair, -				and modify their hardware.  I highly suggest checking them out if -				you’re interested in computer hardware at all.  The laptops even -				have hotswappable I/O! -			</p> - -			<p> -				Anyways getting back on topic, Framework has also been giving -				power to the user on the software-side of things too!  A good -				while ago they open-sourced the -				<a href="https://github.com/FrameworkComputer/EmbeddedController"> -					code for the embedded controller -				</a> -				of their laptops, which offers all sorts of possibilities for -				customization of the keyboard, -				<abbr class="led">LED</abbr> -				lights, and more. -			</p> - -			<h2 id="led"><abbr class="led">LED</abbr> Fun!</h2> - -			<p> -				This is an area of the -				<abbr class="ec">EC</abbr> -				which I have not really looked at or touched much.  I do want to -				play around with this a lot more in the coming future though!  So -				far just for shits-and-giggles, I’ve patched the -				<abbr class="ec">EC</abbr> -				to make the power-button -				<abbr class="ec">LED</abbr> -				green instead of the normal boring white: -			</p> - -			<aside> -				<p> -					Just a tip: if you want to try any of these patches out, -					simply copy the diffs and paste them -					into <code>git apply</code>. -				</p> -			</aside> - -			<figure> -				<figcaption> -					<code>~/board/hx20/led.c</code> -				</figcaption> -				<pre>m4_fmt_code(led.diff.html)</pre> -			</figure> - -			<p> -				As you can see, it’s all fairly simple.  I just had to change our -				<code>EC_LED_COLOR_WHITE</code> for -				<code>EC_LED_COLOR_GREEN</code>.  The codebase defines a few -				colors, but they’re defined as <abbr class="rgb">RGB</abbr> -				tuples which is awesome, because it opens the door to -				custom <abbr class="rgb">RGB</abbr> effects in the future! -			</p> - -			<h2 id="more">There’s More Than One <abbr class="led">LED</abbr>‽</h2> - -			<p> -				That’s right!  The Framework laptop I own (13″; the 16″ releases -				soon though!) has 3 more <abbr class="led">LED</abbr> lights. -				One on the left of the chassis, one on right of the chassis, and -				one on the capslock key.  The capslock -				<abbr class="led">LED</abbr> acts as an indicator of whether or -				not you’ve got capslock enabled.  This is useless to me though, -				because my custom keyboard layout doesn’t even support capslock -				(see the next section) — so I patched it to be a function-lock -				indicator instead! -			</p> - -			<p> -				Here’s the diff — but do take care if you want to apply similar -				patches to your laptop!  The files I’m editing are under -				<code>board/hx20</code> since I’m on an 11th Gen Intel -				<abbr class="cpu">CPU</abbr>.  If you have a different -				<abbr class="cpu">CPU</abbr>, you will probably need to fuck with -				different code: -			</p> - -			<figure> -				<figcaption> -					<code>~/board/hx20/board.h</code> -				</figcaption> -				<pre>m4_fmt_code(fn-lock-1.diff.html)</pre> -			</figure> - -			<figure> -				<figcaption> -					<code>~/board/hx20/keyboard-customization.c</code> -				</figcaption> -				<pre>m4_fmt_code(fn-lock-2.diff.html)</pre> -			</figure> - -			<p> -				As you can see, toggling the capslock -				<abbr class="led">LED</abbr> is as simple as -				invoking <code>gpio_set_level()</code>.  Not only that, but -				disabling its functionality with the capslock key is as easy as -				undefining the <code>CONFIG_CAPSLOCK_SUPPORT</code> macro. -				Figuring out if the function key is locked is also really easy. -				The <code>Fn_key</code> global variable is a bit-field containing -				information pertaining to the function key, and we also -				conveniently already have the <code>FN_LOCKED</code> constant -				defined that we can bitwise-AND with <code>Fn_key</code> to check -				the locked state! -			</p> - -			<p> -				We also setup some hooks with the <code>DECLARE_HOOK()</code> -				macro.  These just ensure that we are behaving properly on system -				resume and -suspend. -			</p> - -			<h2 id="hybrid">The Hybrid Key</h2> - -			<p> -				Wouldn’t it be cool if a physical key could represent two keys at -				the same time?  I thought so too.  Like all Emacs users, I suffer -				from a distinct lack of easily-accessible modifier keys.  I need -				escape because I use Vim bindings; I need left-control because -				all the Emacs bindings use it; I need super for my -				window-managers’ bindings; I need left-alt so I can type -				characters that don’t come on a standard American keyboard (such -				as <em>ß</em>, <em>€</em>, and <em>é</em>), and now I have a -				problem.  All my modifiers are taken, but Emacs still needs a -				meta key to work! -			</p> -			<figure> -				<figcaption> -					<cite>Workflow</cite> by Randall Munroe -				</figcaption> -				<img alt="XKCD Comic 1172" src="1172.png"> -			</figure> - -			<p> -				What will I ever do‽  Well thanks to Framework making -				the <abbr class="ec">EC</abbr> open-source, and conveniently -				giving me a file called <code>keyboard_customization.c</code>, -				I’m going to take two keys and stick them in one!  The basic -				premise is this: the capslock key is arguably the easiest -				modifier key to hit, and it’s currently bound to the escape key -				on my system.  This is inefficient though, because nobody makes -				key-bindings that chord the escape-key with another key; -				chords <x-ref>1</x-ref> are always done with a modifier like -				control, and Emacs is no different.  So my plan was to make it -				so that the capslock key when used on its own mimics an -				escape-key, while instead mimicking the left-control-key when -				used in a chord with another key. -			</p> - -			<p> -				It took me a little longer this time to figure out how to -				implement what I wanted since the code isn’t as clear, but it was -				still a surprisingly easy feature to patch into the -				<abbr class="ec">EC</abbr>!  I basically just updated the -				scancode table, swapping out the capslock scancode for my own -				random one that I called <code>SCANCODE_CTRL_ESC</code>.  I then -				created a new function called <code>try_ctrl_esc()</code> which -				is called in the on-keyup and -down callback function.  The -				<code>try_ctrl_esc()</code> function handles all of the logic as -				you can see in the following diff; it’s basically just a state -				machine: -			</p> - -			<aside> -				<p data-ref="1"> -					If you’re confused by what I mean by a “key-chord”, I am -					simply referring to pressing multiple keys in conjunction, -					such as when you press “<kbd>Ctrl + C</kbd>” to copy text. -				</p> -			</aside> - -			<figure> -				<figcaption><code>~/board/hx20/keyboard_customization.c</code></figcaption> -				<pre>m4_fmt_code(hybrid.diff.html)</pre> -			</figure> - -			<p> -				One thing that’s good to take note of is what I return from -				<code>try_ctrl_esc()</code>.  The general pattern for handling a -				keyup or -down event is to stick the following code into -				<code>keyboard_scancode_callback()</code>: -			</p> - -			<figure> -				<figcaption> -					<code>keyboard_scancode_callback()</code> in -					<code>~/board/hx20/keyboard_customization.c</code> -				</figcaption> -				<pre>m4_fmt_code(kbd-sc-cb.c.html)</pre> -			</figure> - -			<p> -				In <code>my_handler_function()</code> (or whatever you decide to -				name it), you attempt to handle the event.  If you don’t want to -				handle a particular event and instead want to pass it on to the -				next handler, you need to return <code>EC_SUCCESS</code>.  If you -				managed to successfully handle the event though, then you need to -				return an error such as <code>EC_ERROR_UNIMPLEMENTED</code>. -				It’s pretty stupid and makes very little sense from a naming -				perspective, but oh well… -			</p> - -			<h2 id="next">What’s Next?</h2> - -			<p> -				<abbr class="rgb">RGB</abbr> -				<abbr class="led">LED</abbr>s -				maybe. -			</p> -		</main> - -		<hr> -		 -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/srp/fw-ec/kbd-sc-cb.c.gsp b/src/srp/fw-ec/kbd-sc-cb.c.gsp new file mode 100644 index 0000000..fa03466 --- /dev/null +++ b/src/srp/fw-ec/kbd-sc-cb.c.gsp @@ -0,0 +1,6 @@ +@span .c-cmt {-/* “make_code” is the scancode.  “pressed” is a boolean that is true if this is a} +   @span .c-cmt {-keydown event, and false if it’s a keyup. */} + +r = @span .c-fn {-my_handler_function}(make_code, pressed); +@span .c-kw {-if} (r != @span .c-pp {-EC_SUCCESS}) +	@span .c-kw {-return} r; diff --git a/src/srp/fw-ec/kbd-sc-cb.c.html b/src/srp/fw-ec/kbd-sc-cb.c.html deleted file mode 100644 index 34b7f8d..0000000 --- a/src/srp/fw-ec/kbd-sc-cb.c.html +++ /dev/null @@ -1,6 +0,0 @@ -<span class="c-cmt">/* “make_code” is the scancode.  “pressed” is a boolean that is true if this is a</span> -<span class="c-cmt">   keydown event, and false if it’s a keyup. */</span> - -r = <span class="c-fn">my_handler_function</span>(make_code, pressed); -<span class="c-kw">if</span> (r != <span class="c-pp">EC_SUCCESS</span>) -	<span class="c-kw">return</span> r; diff --git a/src/srp/fw-ec/led.diff.gsp b/src/srp/fw-ec/led.diff.gsp new file mode 100644 index 0000000..36e2ab3 --- /dev/null +++ b/src/srp/fw-ec/led.diff.gsp @@ -0,0 +1,32 @@ +@span .diff-meta {-diff --git a/board/hx20/led.c b/board/hx20/led.c} +@span .diff-meta {-index a4dc4564e..dacf73fda 100644} +@span .diff-meta {---- a/board/hx20/led.c} +@span .diff-meta {-+++ b/board/hx20/led.c} +@span .diff-loc {-\@\@ -283,22 +283,22 \@\@ static void led_set_power(void)} + 	/* don't light up when at lid close */ + 	if (!lid_is_open()) { + 		set_pwr_led_color(PWM_LED2, -1); +@span .diff-del {--		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_WHITE, breath_led_length, 0);} +@span .diff-ins {-+		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_GREEN, breath_led_length, 0);} + 		return; + 	\} + + 	if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) +@span .diff-del {--		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_WHITE, breath_led_length, 1);} +@span .diff-ins {-+		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_GREEN, breath_led_length, 1);} + 	else +@span .diff-del {--		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_WHITE, breath_led_length, 0);} +@span .diff-ins {-+		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_GREEN, breath_led_length, 0);} + + 	if (chipset_in_state(CHIPSET_STATE_ON) | power_button_enable) { + 		if (charge_prevent_power_on(0)) + 			set_pwr_led_color(PWM_LED2, (power_tick % + 				LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? +@span .diff-del {--				EC_LED_COLOR_WHITE : -1);} +@span .diff-ins {-+				EC_LED_COLOR_GREEN : -1);} + 		else +@span .diff-del {--			set_pwr_led_color(PWM_LED2, EC_LED_COLOR_WHITE);} +@span .diff-ins {-+			set_pwr_led_color(PWM_LED2, EC_LED_COLOR_GREEN);} + 	\} else + 		set_pwr_led_color(PWM_LED2, -1); + \} diff --git a/src/srp/fw-ec/led.diff.html b/src/srp/fw-ec/led.diff.html deleted file mode 100644 index 9959b0d..0000000 --- a/src/srp/fw-ec/led.diff.html +++ /dev/null @@ -1,32 +0,0 @@ -<span class="diff-meta">diff --git a/board/hx20/led.c b/board/hx20/led.c</span> -<span class="diff-meta">index a4dc4564e..dacf73fda 100644</span> -<span class="diff-meta">--- a/board/hx20/led.c</span> -<span class="diff-meta">+++ b/board/hx20/led.c</span> -<span class="diff-loc">@@ -283,22 +283,22 @@ static void led_set_power(void)</span> - 	/* don't light up when at lid close */ - 	if (!lid_is_open()) { - 		set_pwr_led_color(PWM_LED2, -1); -<span class="diff-del">-		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_WHITE, breath_led_length, 0)</span>; -<span class="diff-ins">+		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_GREEN, breath_led_length, 0)</span>; - 		return; - 	} - - 	if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) -<span class="diff-del">-		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_WHITE, breath_led_length, 1)</span>; -<span class="diff-ins">+		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_GREEN, breath_led_length, 1)</span>; - 	else -<span class="diff-del">-		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_WHITE, breath_led_length, 0)</span>; -<span class="diff-ins">+		enable_pwr_breath(PWM_LED2, EC_LED_COLOR_GREEN, breath_led_length, 0)</span>; - - 	if (chipset_in_state(CHIPSET_STATE_ON) | power_button_enable) { - 		if (charge_prevent_power_on(0)) - 			set_pwr_led_color(PWM_LED2, (power_tick % - 				LED_TICKS_PER_CYCLE < LED_ON_TICKS) ? -<span class="diff-del">-				EC_LED_COLOR_WHITE : -1);</span> -<span class="diff-ins">+				EC_LED_COLOR_GREEN : -1);</span> - 		else -<span class="diff-del">-			set_pwr_led_color(PWM_LED2, EC_LED_COLOR_WHITE);</span> -<span class="diff-ins">+			set_pwr_led_color(PWM_LED2, EC_LED_COLOR_GREEN);</span> - 	} else - 		set_pwr_led_color(PWM_LED2, -1); - } diff --git a/src/srp/index.gsp b/src/srp/index.gsp new file mode 100644 index 0000000..8b2ddad --- /dev/null +++ b/src/srp/index.gsp @@ -0,0 +1,40 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-Sortware-Related Posts} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						Object-oriented programming is an exceptionally bad idea which could +						only have originated in California. +					} +				} +				figcaption {-Edsgar W. Dijkstra} +			} +		} + +		main { +			p {- +				In this section of the website I cover random software-related stuff +				that isn’t related to actual projects of mine.  Posts here could be +				about anything from a cool program I found, to a patch I wrote, to me +				complaining about bad software design. +			} + +			p {-Posts:} + +			ul { +				li {a href="fw-ec" {-Patching My Laptop’s Embedded Controller}} +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/srp/index.html b/src/srp/index.html deleted file mode 100644 index f66d4ae..0000000 --- a/src/srp/index.html +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -	<head> -		m4_include(head.html) -	</head> -	<body> -		<header> -			<div> -				<h1>Software-Related Posts</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>Object-oriented programming is an exceptionally bad idea -					which could only have originated in California.</p> -				</blockquote> -				<figcaption> -					Edsgar W. Dijkstra -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				In this section of the website I cover random software-related -				stuff that isn’t related to actual projects of mine.  Posts here -				could be about anything from a cool program I found, to a patch I -				wrote, to me complaining about bad software design. -			</p> - -			<p> -				Posts: -			</p> - -			<ul> -				<li><a href="fw-ec">Patching My Laptop’s Embedded Controller</a></li> -			</ul> -		</main> - -		<hr> -		 -		<footer> -			m4_footer -		</footer> -	</body> -</html> diff --git a/src/style.css b/src/style.css index 78e8ef2..713e4bb 100644 --- a/src/style.css +++ b/src/style.css @@ -228,12 +228,14 @@ dl {  	abbr.cv::before   { content: 'Curriculum Vitæ';              }  	abbr.ec::before   { content: 'Embedded Controller';          }  	abbr.gnu::before  { content: 'GNU’s Not UNIX';               } +	abbr.gsp::before  { content: 'German Shorthaired Pointer';   }  	abbr.html::before { content: 'Hypertext Markup Language';    }  	abbr.it::before   { content: 'Information Technology';       }  	abbr.led::before  { content: 'Light-Emitting Diode';         }  	abbr.nas::before  { content: 'Network Attached Storage';     }  	abbr.qr::before   { content: 'Quick Response';               }  	abbr.rgb::before  { content: 'Red Green Blue';               } +	abbr.sha::before  { content: 'Secure Hash Algorithm';        }  	abbr.tfa::before  { content: 'Two-Factor Authentication';    }  	abbr.totp::before { content: 'Time-Based One-Time Password'; }  	abbr.uri::before  { content: 'Uniform Resource Identifier';  } diff --git a/src/www/index.gsp b/src/www/index.gsp new file mode 100644 index 0000000..c46c5bc --- /dev/null +++ b/src/www/index.gsp @@ -0,0 +1,118 @@ +html lang="en" { +	head { m4_include(head.gsp) } +	body { +		header { +			div { +				h1 {-Other Websites} +				m4_include(nav.gsp) +			} + +			figure .quote { +				blockquote { +					p {= +						The essence of m4_abbr(XML) is this: the problem it solves it not +						hard, and it does not solve the problem well. +					} +				} +				figcaption {-Phil Wadler} +			} +		} + +		main { +			p {- +				On this section of the website you can find links to all sorts of other +				websites I think are somewhat interesting.  Some of these are my own +				sites, and some of them aren’t.  Feel free to explore. +			} + +			h3 {-My Websites} +			ul { +				li { +					a target="_blank" href="https://archive.thomasvoss.com" {- +						@cite{-archive} — Mario Kart Wii time trials archive +					} +				} +				li { +					a target="_blank" href="https://cv.thomasvoss.com" {- +						@cite{-cv} — my résumé/curriculum vitæ +					} +				} +				li { +					a target="_blank" href="https://euro.thomasvoss.com" {- +						@cite{-euro} — my euro coin and -banknote collection +					} +				} +				li { +					a target="_blank" href="https://git.thomasvoss.com" {- +						@cite{-git} — my git server +					} +				} +				li { +					a target="_blank" href="https://paste.thomasvoss.com" {- +						@cite{-paste} — my paste server +					} +				} +				li { +					a target="_blank" href="https://retime.mcbe.wtf" {- +						@cite{-retime} — a webtool for retiming speedruns +					} +				} +			} + +			h3 {-Not My Websites} +			ul { +				li { +					a target="_blank" href="https://classicshorts.com" {- +						@cite{-classicshorts} — a collection of short stories +					} +				} +				li { +					a target="_blank" href="https://iannis.io" {- +						@cite{-iannis.io} — blog posts on programming topics +					} +				} +				li { +					a target="_blank" href="https://redblobgames.com" {- +						@cite{-redblobgames} — algorithms in the context of video games +					} +				} +				li { +					a target="_blank" href="https://tdmm.eu" {- +						@cite{-tdmm} — blog posts on low-level development +					} +				} +				li { +					a target="_blank" href="https://blog.bal-e.org/" {- +						@cite{-bal-e} — it’s like tdmm.eu I guess +					} +				} +				li { +					a target="_blank" href="http://textfiles.com" {- +						@cite{-textfiles} — a collection of thousands of plain-text files +					} +				} +				li { +					a target="_blank" href="https://cat-v.org" {- +						@cite{-cat-v} — @q{-The Internet is not for sissies.} +					} +				} +			} + +			h3 {-Assorted Links} +			ul { +				li { +					a +						target="_blank" +						href="https://web.archive.org/web/20230619115633/http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html" +					{ +						cite {-Why Lisp Macros are Cool} +					} +				} +			} +		} + +		hr{} + +		footer { m4_footer } +	} +} diff --git a/src/www/index.html b/src/www/index.html deleted file mode 100644 index 82ac06c..0000000 --- a/src/www/index.html +++ /dev/null @@ -1,123 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> -	<head> -		m4_include(head.html) -	</head> -	<body> -		<header> -			<div> -				<h1>Other Websites</h1> -				m4_include(nav.html) -			</div> - -			<figure class="quote"> -				<blockquote> -					<p>The essence of XML is this: the problem it solves is not -					hard, and it does not solve the problem well.</p> -				</blockquote> -				<figcaption> -					Phil Wadler -				</figcaption> -			</figure> -		</header> - -		<main> -			<p> -				On this section of the website you can find links to all sorts of -				other websites I think are somewhat interesting.  Some of these -				are my own sites, and some of them aren’t.  Feel free to explore. -			</p> - -			<p>My websites:</p> -			<ul> -				<li> -					<a target="_blank" href="https://archive.thomasvoss.com"> -						<cite>archive</cite> — Mario Kart Wii time trials archive -					</a> -				</li> -				<li> -					<a target="_blank" href="https://cv.thomasvoss.com"> -						<cite>cv</cite> — my résumé/curriculum vitæ -					</a> -				</li> -				<li> -					<a target="_blank" href="https://euro.thomasvoss.com"> -						<cite>euro</cite> — my euro coin and -banknote collection -					</a> -				</li> -				<li> -					<a target="_blank" href="https://git.thomasvoss.com"> -						<cite>git</cite> — my git server -					</a> -				</li> -				<li> -					<a target="_blank" href="https://paste.thomasvoss.com"> -						<cite>paste</cite> — my paste server -					</a> -				</li> -				<li> -					<a target="_blank" href="https://retime.mcbe.wtf"> -						<cite>retime</cite> — a webtool for retiming speedruns -					</a> -				</li> -			</ul> - -			<p>Not my websites:</p> -			<ul> -				<li> -					<a target="_blank" href="https://classicshorts.com"> -						<cite>classicshorts</cite> — a collection of short stories -					</a> -				</li> -				<li> -					<a target="_blank" href="https://iannis.io"> -						<cite>iannis.io</cite> — blog posts on programming topics -					</a> -				</li> -				<li> -					<a target="_blank" href="https://redblobgames.com"> -						<cite>redblobgames</cite> — algorithms in the context of video games -					</a> -				</li> -				<li> -					<a target="_blank" href="https://tdmm.eu"> -						<cite>tdmm</cite> — blog posts on low-level development -					</a> -				</li> -				<li> -					<a target="_blank" href="https://blog.bal-e.org/"> -						<cite>bal-e</cite> — it’s like tdmm.eu I guess -					</a> -				</li> -				<li> -					<a target="_blank" href="http://textfiles.com"> -						<cite>textfiles</cite> — a collection of thousands of plain-text files -					</a> -				</li> -				<li> -					<a target="_blank" href="https://cat-v.org"> -						<cite>cat-v</cite> — <q>The Internet is not for sissies.</q> -					</a> -				</li> -			</ul> - -			<p>Assorted Links</p> -			<ul> -				<li> -					<a -						target="_blank" -						href="https://web.archive.org/web/20230619115633/http://lists.warhead.org.uk/pipermail/iwe/2005-July/000130.html" -					> -						<cite>Why Lisp Macros are Cool</cite> -					</a> -				</li> -			</ul> -		</main> - -		<hr> -		 -		<footer> -			m4_footer -		</footer> -	</body> -</html> |