aboutsummaryrefslogtreecommitdiff
path: root/build/blog/2015-05-22-using-a-command-table-as-wallpaper.html
diff options
context:
space:
mode:
Diffstat (limited to 'build/blog/2015-05-22-using-a-command-table-as-wallpaper.html')
-rw-r--r--build/blog/2015-05-22-using-a-command-table-as-wallpaper.html194
1 files changed, 0 insertions, 194 deletions
diff --git a/build/blog/2015-05-22-using-a-command-table-as-wallpaper.html b/build/blog/2015-05-22-using-a-command-table-as-wallpaper.html
deleted file mode 100644
index 64821bb9..00000000
--- a/build/blog/2015-05-22-using-a-command-table-as-wallpaper.html
+++ /dev/null
@@ -1,194 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8"/>
-<meta content="pandoc" name="generator"/>
-<meta content="Zhiming Wang" name="author"/>
-<meta content="2015-05-22T00:48:19-07:00" name="date"/>
-<title>Using a command table as wallpaper</title>
-<link href="/img/apple-touch-icon-152.png" rel="apple-touch-icon-precomposed"/>
-<meta content="#FFFFFF" name="msapplication-TileColor"/>
-<meta content="/img/favicon-144.png" name="msapplication-TileImage"/>
-<meta content="width=device-width, initial-scale=1" name="viewport"/>
-<link href="/css/normalize.min.css" media="all" rel="stylesheet" type="text/css"/>
-<link href="/css/theme.css" media="all" rel="stylesheet" type="text/css"/>
-<link href="/css/highlight.css" media="all" rel="stylesheet" type="text/css"/>
-</head>
-<body>
-<div id="archival-notice">This blog has been archived.<br/>Visit my home page at <a href="https://zhimingwang.org">zhimingwang.org</a>.</div>
-<nav class="nav">
-<a class="nav-icon" href="/" title="Home"><!--blog icon--></a>
-<a class="nav-title" href="/"><!--blog title--></a>
-<a class="nav-author" href="https://github.com/zmwangx" target="_blank"><!--blog author--></a>
-</nav>
-<article class="content">
-<header class="article-header">
-<h1 class="article-title">Using a command table as wallpaper</h1>
-<div class="article-metadata">
-<time class="article-timestamp" datetime="2015-05-22T00:48:19-07:00">May 22, 2015</time>
-</div>
-</header>
-<p>Recently I cleaned up my source code directory, removed a lot of rarely-used, dated scripts, and grouped the remaining standalone scripts into a central place (<code>~/dev/scripts</code>)<a class="footnoteRef" href="#fn1" id="fnref1"><sup>1</sup></a>. One thing I learned in this process is that I tend to write a reusable script but rarely actually reuse it (even if it sits on <code>PATH</code>), sometimes implementing the same functionality twice or typing a long command line over and over again.</p>
-<p>To remind myself of which scripts are at my fingertip, I decided to use a command table as wallpaper on my secondary display. So I wrote a shitty Python script<a class="footnoteRef" href="#fn2" id="fnref2"><sup>2</sup></a> (depending on XeLaTeX and ImageMagick) to automate the generation of such a wallpaper. It's pretty customizable, and anyone may grab it and do whatever they want to with it (also <a href="https://gist.github.com/zmwangx/b06aa923abf061b33fc9">available as a gist</a>):</p>
-<div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python"><span class="co">#!/usr/bin/env python3</span>
-
-<span class="co">"""Generate command table."""</span>
-
-<span class="im">import</span> argparse
-<span class="im">import</span> os
-<span class="im">import</span> shlex
-<span class="im">import</span> subprocess
-<span class="im">import</span> sys
-<span class="im">import</span> tempfile
-
-<span class="co"># pylint: disable=wildcard-import,unused-wildcard-import</span>
-
-<span class="im">from</span> zmwangx.colorout <span class="im">import</span> <span class="op">*</span>
-
-DEFAULT_COLUMN_WIDTH <span class="op">=</span> <span class="dv">120</span>
-DEFAULT_FOREGROUND_COLOR <span class="op">=</span> <span class="st">"white"</span>
-DEFAULT_BACKGROUND_COLOR <span class="op">=</span> <span class="st">"black"</span>
-DEFAULT_FONT <span class="op">=</span> <span class="st">"Consolas"</span>
-DEFAULT_BORDER <span class="op">=</span> <span class="dv">20</span>
-DEFAULT_DENSITY <span class="op">=</span> <span class="dv">300</span>
-DEFAULT_SIZE <span class="op">=</span> <span class="st">"1280x800"</span>
-
-HERE <span class="op">=</span> os.path.dirname(os.path.realpath(sys.argv[<span class="dv">0</span>]))
-XELATEX_PROGRAM <span class="op">=</span> (<span class="vs">r"""</span>
-<span class="vs">\documentclass[varwidth=\maxdimen,border=</span><span class="sc">{border}</span><span class="vs">pt]</span><span class="sc">{{</span><span class="vs">standalone</span><span class="sc">}}</span>
-<span class="vs">\usepackage</span><span class="sc">{{</span><span class="vs">color</span><span class="sc">}}</span>
-<span class="vs">\pagecolor</span><span class="sc">{{{background}}}</span>
-<span class="vs">\color</span><span class="sc">{{{foreground}}}</span>
-<span class="vs">\usepackage</span><span class="sc">{{</span><span class="vs">fontspec</span><span class="sc">}}</span>
-<span class="vs">\setmonofont</span><span class="sc">{{{font}}}</span>
-
-<span class="vs">\begin</span><span class="sc">{{</span><span class="vs">document</span><span class="sc">}}</span>
-<span class="vs">\begin</span><span class="sc">{{</span><span class="vs">verbatim</span><span class="sc">}}</span>
-<span class="sc">{table}</span>
-<span class="vs">\end</span><span class="sc">{{</span><span class="vs">verbatim</span><span class="sc">}}</span>
-<span class="vs">\end</span><span class="sc">{{</span><span class="vs">document</span><span class="sc">}}</span>
-<span class="vs">"""</span>)
-
-<span class="kw">def</span> text_table(<span class="op">**</span>kwargs):
- <span class="co">"""Generate the text version of the table."""</span>
- width <span class="op">=</span> kwargs[<span class="st">"width"</span>] <span class="cf">if</span> <span class="st">"width"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_COLUMN_WIDTH
- directory <span class="op">=</span> kwargs[<span class="st">"directory"</span>] <span class="cf">if</span> <span class="st">"directory"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> HERE
- command_line <span class="op">=</span> (<span class="vs">r"find </span><span class="sc">{directory}</span><span class="vs"> -maxdepth 1 -type f -perm -u=x -exec basename </span><span class="sc">{{}}</span><span class="vs"> \; "</span>
- <span class="st">"| column -c </span><span class="sc">{width}</span><span class="st"> | expand"</span>.<span class="bu">format</span>(
- directory<span class="op">=</span>shlex.quote(directory), width<span class="op">=</span>width))
- ccommand(command_line)
- <span class="cf">return</span> subprocess.check_output(command_line, shell<span class="op">=</span><span class="va">True</span>).decode(<span class="st">"utf-8"</span>)
-
-<span class="kw">def</span> pdf_table(<span class="op">**</span>kwargs):
- <span class="co">"""Generate the PDF version of the table.</span>
-
-<span class="co"> Returns 0 on success or 1 on failure. Generated PDF is "table.pdf"</span>
-<span class="co"> in the current working directory.</span>
-
-<span class="co"> """</span>
- border <span class="op">=</span> kwargs[<span class="st">"border"</span>] <span class="cf">if</span> <span class="st">"border"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_BORDER
- foreground <span class="op">=</span> kwargs[<span class="st">"foreground"</span>] <span class="cf">if</span> <span class="st">"foreground"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_FOREGROUND_COLOR
- background <span class="op">=</span> kwargs[<span class="st">"background"</span>] <span class="cf">if</span> <span class="st">"background"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_BACKGROUND_COLOR
- font <span class="op">=</span> kwargs[<span class="st">"font"</span>] <span class="cf">if</span> <span class="st">"font"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_FONT
- program <span class="op">=</span> XELATEX_PROGRAM.<span class="bu">format</span>(table<span class="op">=</span>text_table(<span class="op">**</span>kwargs).strip(),
- font<span class="op">=</span>font, border<span class="op">=</span>border,
- foreground<span class="op">=</span>foreground, background<span class="op">=</span>background)
- <span class="cf">with</span> <span class="bu">open</span>(<span class="st">"table.tex"</span>, <span class="st">"w"</span>) <span class="im">as</span> texfileobj:
- texfileobj.write(program)
- <span class="cf">try</span>:
- ccommand(<span class="st">"xelatex table.tex"</span>)
- subprocess.check_call([<span class="st">"xelatex"</span>, <span class="st">"table.tex"</span>],
- stdout<span class="op">=</span>subprocess.DEVNULL, stderr<span class="op">=</span>subprocess.DEVNULL)
- <span class="cf">return</span> <span class="dv">0</span>
- <span class="cf">except</span> subprocess.CalledProcessError:
- cerror(<span class="st">"xelatex failed on the following program:"</span>)
- cerrnewline()
- cerrwrite(<span class="st">"default"</span>, program)
- <span class="cf">return</span> <span class="dv">1</span>
-
-<span class="kw">def</span> png_table(<span class="op">**</span>kwargs):
- <span class="co">"""Generate the PNG version of the table.</span>
-
-<span class="co"> Returns 0 on success or 1 on failure. Generated PNG is "table.png"</span>
-<span class="co"> in the current working directory.</span>
-
-<span class="co"> """</span>
- <span class="cf">if</span> pdf_table(<span class="op">**</span>kwargs) <span class="op">==</span> <span class="dv">1</span>:
- <span class="cf">return</span> <span class="dv">1</span>
- density <span class="op">=</span> kwargs[<span class="st">"density"</span>] <span class="cf">if</span> <span class="st">"density"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_DENSITY
- size <span class="op">=</span> kwargs[<span class="st">"size"</span>] <span class="cf">if</span> <span class="st">"size"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_SIZE
- background <span class="op">=</span> kwargs[<span class="st">"background"</span>] <span class="cf">if</span> <span class="st">"background"</span> <span class="kw">in</span> kwargs <span class="cf">else</span> DEFAULT_BACKGROUND_COLOR
- command_line <span class="op">=</span> (<span class="st">"convert -density </span><span class="sc">{density}</span><span class="st"> table.pdf -resize </span><span class="sc">{size}</span><span class="st"> -size </span><span class="sc">{size}</span><span class="st"> "</span>
- <span class="st">"xc:</span><span class="sc">{background}</span><span class="st"> +swap -gravity center -composite table.png"</span>.<span class="bu">format</span>(
- density<span class="op">=</span>density, size<span class="op">=</span>size, background<span class="op">=</span>background))
- <span class="cf">try</span>:
- ccommand(command_line)
- subprocess.check_call(shlex.split(command_line))
- <span class="cf">return</span> <span class="dv">0</span>
- <span class="cf">except</span> subprocess.CalledProcessError:
- cerror(<span class="st">"the following ImageMagick command failed:"</span>)
- cerrprint(<span class="st">"default"</span>, command_line)
- <span class="cf">return</span> <span class="dv">1</span>
-
-<span class="kw">def</span> main():
- <span class="co">"""CLI."""</span>
- description <span class="op">=</span> <span class="st">"Generate a PNG table of all executable commands in a directory."</span>
- parser <span class="op">=</span> argparse.ArgumentParser(description<span class="op">=</span>description)
- parser.add_argument(<span class="st">"--width"</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">int</span>, default<span class="op">=</span>DEFAULT_COLUMN_WIDTH,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""line width, default is 120"""</span>)
- parser.add_argument(<span class="st">"--directory"</span>,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""directory containing executables, default is</span>
-<span class="st"> the directory containing this command"""</span>)
- parser.add_argument(<span class="st">"--border"</span>, <span class="bu">type</span><span class="op">=</span><span class="bu">int</span>, default<span class="op">=</span>DEFAULT_BORDER,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""default is 20pt"""</span>)
- parser.add_argument(<span class="st">"--foreground"</span>, default<span class="op">=</span>DEFAULT_FOREGROUND_COLOR,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""foreground color, default is white"""</span>)
- parser.add_argument(<span class="st">"--background"</span>, default<span class="op">=</span>DEFAULT_BACKGROUND_COLOR,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""background color, default is black"""</span>)
- parser.add_argument(<span class="st">"--font"</span>, default<span class="op">=</span>DEFAULT_FONT,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""default is Consolas"""</span>)
- parser.add_argument(<span class="st">"--density"</span>, default<span class="op">=</span>DEFAULT_DENSITY,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""used for the -density argument of convert,</span>
-<span class="st"> default is 300"""</span>)
- parser.add_argument(<span class="st">"--size"</span>, default<span class="op">=</span>DEFAULT_SIZE,
- <span class="bu">help</span><span class="op">=</span><span class="st">"""size of image, default is 1280x800"""</span>)
- args <span class="op">=</span> parser.parse_args()
- kwargs <span class="op">=</span> {k: v <span class="cf">for</span> (k, v) <span class="kw">in</span> args.__dict__.items() <span class="cf">if</span> v <span class="kw">is</span> <span class="kw">not</span> <span class="va">None</span>}
-
- fd, tmpfilepath <span class="op">=</span> tempfile.mkstemp(suffix<span class="op">=</span><span class="st">".png"</span>, prefix<span class="op">=</span><span class="st">"table-"</span>)
- os.close(fd)
- <span class="cf">with</span> tempfile.TemporaryDirectory(prefix<span class="op">=</span><span class="st">"table-"</span>) <span class="im">as</span> working_directory:
- os.chdir(working_directory)
- <span class="cf">if</span> png_table(<span class="op">**</span>kwargs) <span class="op">==</span> <span class="dv">1</span>:
- cerror(<span class="st">"execution failed"</span>)
- os.remove(tmpfilepath)
- <span class="cf">else</span>:
- os.rename(<span class="st">"table.png"</span>, tmpfilepath)
- cprogress(<span class="st">"saved to:"</span>)
- <span class="bu">print</span>(tmpfilepath)
-
-<span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">"__main__"</span>:
- main()</code></pre></div>
-<p>By the way, the <code>zmwangx.colorout</code> module is <a href="https://github.com/zmwangx/pyzmwangx/blob/41b0bffaad9439888d68097a85c7aed594240283/zmwangx/colorout.py">here</a>, just to ease the printing of progress and errors to tty. You may safely remove all the <code>ccommand</code>, <code>cerr*</code> and <code>cprogress</code> calls.</p>
-<p>Here is an example wallpaper reflecting my current <code>~/dev/scripts</code>:</p>
-<div class="figure">
-<a href="https://i.imgur.com/mccQu1e.png" target="_blank"><img alt="Command table wallpaper for my secondary display (MBP 13'' builtin display)." src="https://i.imgur.com/mccQu1e.png"/></a>
-<p class="caption">Command table wallpaper for my secondary display (MBP 13'' builtin display).</p>
-</div>
-<div class="footnotes">
-<hr/>
-<ol>
-<li id="fn1"><p>The <code>~/dev</code> directory stands for development, and contains all my source code and almost all local builds. The point is by having a <code>~/dev</code> directory, I no longer need to have <code>bin</code>, <code>include</code>, <code>lib</code>, and <code>share</code> in my <code>HOME</code>, thus saving a few slots. Backing up and restoring is also slightly easier.<a class="footnotes-backlink" href="#fnref1">↩︎</a></p></li>
-<li id="fn2"><p>Yeah, I know it's a shitty script, so don't nitpick on style problems.<a class="footnotes-backlink" href="#fnref2">↩︎</a></p></li>
-</ol>
-</div>
-</article>
-<hr class="content-separator"/>
-<footer class="footer">
-<span class="rfooter">
-<a class="rss-icon" href="/rss.xml" target="_blank" title="RSS feed"><!--RSS feed icon--></a><a class="atom-icon" href="/atom.xml" target="_blank" title="Atom feed"><!--Atom feed icon--></a><a class="cc-icon" href="https://creativecommons.org/licenses/by/4.0/" target="_blank" title="Released under the Creative Commons Attribution 4.0 International license."><!--CC icon--></a>
-<a href="https://github.com/zmwangx" target="_blank">Zhiming Wang</a>
-</span>
-</footer>
-</body>
-</html>