_drafts https://evanwill.github.io/_drafts/ Leaflet and Image Annotation Template <p>Someone asked me if there was a tool to add hotspot annotations to an image for a presentation where she wanted to label some features. I could swear I knew some methods to do this, like <a href="https://h5p.org/image-hotspots">H5P Image Hotspots</a>, <a href="https://storymap.knightlab.com/advanced/">StoryMapJS gigapixel option</a>, or some IIIF thing… but I couldn’t find something simple.</p> <p>A long time ago I played around with <a href="https://leafletjs.com/examples/crs-simple/crs-simple.html">Leaflet CRS</a> to create <a href="https://evanwill.github.io/antirubbersheet-test/">something similar</a>, but the antirubbersheeter “geocoding” app I used to get the coordinates has gone away. So I decided to quickly build a replacement!</p> <p>This lead to two new template projects:</p> <ul> <li> <p><a href="https://github.com/evanwill/image-annotate-template" class="buttons">image-annotate-template</a> - image annotation with <a href="https://annotorious.dev/">Annotorious</a>. Add custom sized rectangle markers and display a modal or popover on click.</p> </li> <li> <p><a href="https://github.com/evanwill/leaflet-annotate-template" class="buttons">leaflet-annotate-template</a> - image and map annotation with <a href="https://leafletjs.com/">Leaflet</a>. Uses Leaflet CRS to display an image with markers + popups or a conventional map.</p> </li> </ul> <p>The concept is that the websites contains a page for interactively creating annotations which can then be exported as JSON, which in turn is put back into the project to publish/host annotated images embedded in content pages.</p> <p>Each is designed as a template project –&gt; you make a copy for yourself to create a fully self-contained static website project that can be easily hosted on github pages or similar. The repositories contain all the assets with no external dependencies. This means you can create a copy, do your thing, and then just leave it–and it won’t break.</p> <h2 id="developing-with-claude">Developing with Claude</h2> <p>I am targeted in how I use LLMs in my work so I wanted to outline how I used Claude in this case to very quickly develop these mini projects:</p> <ul> <li>I started from the base of <a href="https://github.com/thecdil/bootstrap5-template">bootstrap5-template</a> which provides a sort of boiler plate Jekyll project with all the self contained assets. I like to start with a limited environment that I understand.</li> <li>Next I add in the libraries I want to use, again not using a CDN or npm, just actual copies of the files to ensure it stays self contained. I don’t let the LLM decide which libraries to use or install random stuff, I find they are pretty maximalist throwing in all sorts of extra junk.</li> <li>Then I set up the placeholder files in the template, this way I control the organization and ensure it makes sense for future users of the template.</li> <li>I start drafting in the placeholder files, adding the asset links and script tags.</li> <li>Inside the script tags I start writing comments detailing what I want. I add variables containing the data and options that I want available. I know better than the LLM where the data is in the template. In this context, I am using Liquid to pull in data from other files or Jekyll.</li> <li>In the comments I add links to the library documentation, and sometimes to specific features of the libraries I want it to use.</li> <li>I create some same JSON files demonstrating the output I want, in the location in the template where they will be.</li> <li>Then I open the VS Code Copilot Chat. I provide all the related files as context and ask the LLM to finish writing one specific script. With this much structure and context the results are usually pretty good right away.</li> </ul> <p>I have access to GitHub Copilot via a free educator account–I have no idea about subscriptions or tokens etc. I turn off all the auto suggestions and distractions in the editor, so that I can just use it by clicking the Copilot Chat or asking for inline chat. In this case I used Claude Sonnet 4.6 in “Agent” mode (check the <a href="https://docs.github.com/en/copilot/reference/ai-models/model-comparison">Copilot model comparison</a> for reference).</p> <hr /> <h2 id="bootstrap5-template">bootstrap5-template</h2> <p><a href="https://github.com/thecdil/bootstrap-template">bootstrap5-template</a> is a basic template repository to create a <a href="https://getbootstrap.com/">Bootstrap 5</a> site using Jekyll on GitHub Pages (or where every you want to host it). The layout is based on the <a href="https://getbootstrap.com/docs/5.3/examples/">Bootstrap starter template example</a> with a navbar, search box (using lunr.js), and footer. It is intended as a quick starting point for creating new web projects.</p> <p><a href="https://thecdil.github.io/bootstrap5-template/">Demo</a></p> <hr /> <h2 id="image-annotate-template">Image Annotate Template</h2> <p><a href="https://github.com/evanwill/image-annotate-template">image-annotate-template</a> is a simple website template for creating a presentation with annotated images. It uses <a href="https://jekyllrb.com/">Jekyll</a> static site generation, <a href="https://getbootstrap.com/">Bootstrap 5</a>, and <a href="https://annotorious.dev/">Annotorious</a>. This makes it easy to host on GitHub Pages or anywhere else.</p> <p><a href="https://evanwill.github.io/image-annotate-template/">Demo</a></p> <hr /> <h2 id="leaflet-annotate-template">Leaflet Annotate Template</h2> <p><a href="https://github.com/evanwill/leaflet-annotate-template">leaflet-annotate-template</a> is a simple website template for creating a presentation with annotated images and maps. It uses Jekyll static site generation, Bootstrap 5, and <a href="https://leafletjs.com/">Leaflet.js</a>. This makes it easy to host on GitHub Pages or anywhere else.</p> <p><a href="https://evanwill.github.io/leaflet-annotate-template/">Demo</a></p> Thu, 05 Mar 2026 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/annotation.html https://evanwill.github.io/_drafts/notes/annotation.html Workshop Templates <p>My most re-used projects are a series of three workshop templates which have been adopted by hundreds of people to make workshop outlines, conference websites, lab websites, documentation, and other projects.</p> <p>The idea is to provide a template repository with a basic Jekyll project set up with everything you need to start a simple website, designed for easy hosting on GitHub Pages (or anywhere).</p> <p>Each repository is a template project –&gt; to get started, make a copy and replace the demo with your own content and customizations. The content pages serve as documentation, models to follow, and examples to copy from. The user just needs to understand a bit about GitHub and how to edit Markdown–which you can learn while doing it!</p> <p>Here are the three projects, in order of development:</p> <ul> <li> <p><a href="https://github.com/evanwill/workshop-template" class="buttons">workshop-template</a> (2017) - the original, built on the old Jekyll Minima theme, provides conventions to create nav and footer so that you can step through the workshop content.</p> </li> <li> <p><a href="https://github.com/evanwill/workshop-template-b" class="buttons">workshop-template-b</a> (2018) - features a basic custom Bootstrap theme, includes to simplify adding Bootstrap components, and conventions to add features using front matter on each page (such as video, summaries, and topics).</p> </li> <li> <p><a href="https://github.com/learn-static/lesson-template" class="buttons">Learn-Static lesson-template</a> (2021) - features a sidebar navigation with nested sections, providing clear structure for step by step content. It has an advanced search for quickly finding content. It is great for documentation.</p> </li> </ul> <p>I regularly use workshop-template-b and lesson-template for my teaching and documentation projects, so they are often updated with new versions of Bootstrap and other features. The assets are all self contained and complete, so once you make a copy, it requires no ongoing maintenance or dependencies.</p> <p>All content is written using basic Markdown, making it simple to write, edit, and reuse lesson materials. The templates provides Liquid includes to simplify adding features to your pages.</p> <p>Writing content in this simple, reuseable format makes for a better Open Educational Resource since anyone can make a copy and adapt–importantly, I find this means myself, I can easily re-use and adapt all the content I write for new purposes. I find this much easier than making slides!</p> Mon, 05 Jan 2026 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/workshop-templates.html https://evanwill.github.io/_drafts/notes/workshop-templates.html Character Corruption Issues in CSVs <p>CSVs are <a href="https://en.wikipedia.org/wiki/Plain_text">plain text files</a>, which means all the bytes in the file are a series of character codes, each representing some text character (<code class="language-plaintext highlighter-rouge">a</code>, <code class="language-plaintext highlighter-rouge">1</code>, <code class="language-plaintext highlighter-rouge">&lt;</code>, etc) or control characters (like tabs and line breaks). The characters in a plain text file are encoded at the byte level following various standards, such as <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> (which is the standard encoding on the web). The computer reads the bytes then uses the encoding standard to select which visual character to display.</p> <p>Unfortunately, character encoding is complicated!</p> <p>For example, a text file containing one encoding can get a character from a different standard saved into it. A text file written in one encoding can be opened with the wrong encoding. These cases can end up with the characters in the file being incorrectly displayed or fully corrupted (saved incorrectly into the file).</p> <p>When that happens, usually what is displayed is the <a href="https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character">replacement characters</a>:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>��� � </code></pre></div></div> <p>Or nonsense like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Singapore’s </code></pre></div></div> <p>(This nonsense is called <a href="https://en.wikipedia.org/wiki/Mojibake">Mojibake</a>. A slightly different issue is when a specific font does not have the character to display, which is called <a href="https://fonts.google.com/knowledge/glossary/tofu">“tofu”</a>–an issue with the font, not necessarily encoding.)</p> <p>Avoiding character corruption issues requires careful handling and attention to CSVs.</p> <p>The main forms of corrupt characters are from two sources:</p> <ol> <li>Opening UTF-8 CSV in Excel (or opening it in wrong character encoding in another program) <ul> <li>This situation can be avoided by NEVER opening or saving a CSV with Excel! Only open and save XLSX files with Excel.</li> <li>If you accidentally double click on a CSV and it opens in Excel, the characters are potentially corrupted (via the replacement character issue).</li> </ul> </li> <li>Ambiguous characters saved in UTF-8 later opened by a spreadsheet program (ambiguous characters converted into replacement characters) <ul> <li>This situation usually comes from pasting text from MS Word or other document editor into a textfile, CSV, or Sheet. At first it will appear correct, but when re-imported into Sheets all ambiguous character will be corrupted into replacement characters.</li> </ul> </li> </ol> <h2 id="ambiguous-characters">Ambiguous characters</h2> <p>Ambiguous characters are generally special fancy looking punctuation marks that are supported by specific editing programs, but not necessarily UTF-8 itself. The main examples are smart quotes, smart apostrophes, emdashes, and ellipsis:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>” “ – — ’ … </code></pre></div></div> <p>For example, when writing in MS Word or other editors, typing a pair of quotes <code class="language-plaintext highlighter-rouge">"</code> are automatically replaced with smart quotes, <code class="language-plaintext highlighter-rouge">“example”</code>. These have specific meaning in Word, but not in UTF-8.</p> <p>The source of these characters in our metadata is most likely from pasting text from another program, such as MS Word.</p> <p>These ambiguous characters normally display fine in VS Code (they are usually highlighted with a gold box indicating an ambiguous character), and can be built into the website without any issues. They can go through OpenRefine without issues.</p> <p>However, when importing into Google Sheets, they will become corrupted (i.e. the ambiguous character byte sequence will be replaced with the replacement character code in UTF-8). Once corrupted they will display as tofu <code class="language-plaintext highlighter-rouge">���</code>, and since the byte code has been replaced, it is impossible to translate back to the original.</p> <p>It is often very difficult to notice this corruption as it might only impact a few random values in a large spreadsheet.</p> <p>If a CSV has ambiguous characters, it is best to try to clean them up. Work in VS Code or OpenRefine, do not import into Sheets to do this work!</p> <ul> <li>Use the regular expression <code class="language-plaintext highlighter-rouge">[^\x00-\x7f]</code> to find problem characters.</li> <li>Use find &amp; replace to replace the ambiguous character with a correct UTF-8 version</li> <li>In OpenRefine, use All column &gt; Edit all columns &gt; Replace smart quotes with ASCII…</li> </ul> <h2 id="special-characters">Special characters</h2> <p>Metadata often contains accented characters or diacritics, such as:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>à, á, â, ä, å, æ, ç, è, é, ê, ë, ì, í, î, ï, ñ, ò, ó, ô, ö, ø, ù, ú, û, ü, ý </code></pre></div></div> <p>These can commonly become corrupted by incorrectly handling UTF-8 or pasting from non-UTF-8 sources. Diacritics are the most commonly corrupted character type when opening a CSV in Excel.</p> <p>Pay close attention to diacritics in metadata to ensure they do not become corrupted–once corrupted it is difficult to recover the correct content.</p> <h2 id="numbers-converted-to-decimals">Numbers converted to decimals</h2> <p>Another form of corruption can happen when importing CSVs into spreadsheet programs if the option to “Convert text to numbers, dates, and formulas” is NOT UNCHECKED. In columns that have numbers, sometimes spreadsheet program will interpret the column as a number rather than text. In that case it can add a decimal (e.g. <code class="language-plaintext highlighter-rouge">1</code> to <code class="language-plaintext highlighter-rouge">1.0</code>) or round off as if it was a decimal (e.g. id <code class="language-plaintext highlighter-rouge">1.10</code> to <code class="language-plaintext highlighter-rouge">1.1</code>).</p> <p>This often comes up in identifier columns that use chapter or folder numbers like <code class="language-plaintext highlighter-rouge">1.1</code>, <code class="language-plaintext highlighter-rouge">1.2</code>. You will end up with several <code class="language-plaintext highlighter-rouge">1.1</code> values as <code class="language-plaintext highlighter-rouge">1.1</code>, <code class="language-plaintext highlighter-rouge">1.10</code>, <code class="language-plaintext highlighter-rouge">1.100</code> will all be converted to the same number.</p> <h2 id="escaped-unicode">Escaped unicode</h2> <p>In some applications, uncommon characters (anything unicode outside of basic ASCII) can be replaced with “escaped unicode”. This is more common in JSON. To handle correctly, the software will need to unescape the unicode converting it into a normal UTF-8 character (which is not typically done with spreadsheet CSVs).</p> <p>For example, Montréal Canada:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"value": "Montr\u00e9al Canada" </code></pre></div></div> <p>In this case the UTF-8 character <code class="language-plaintext highlighter-rouge">é</code> has been replaced by the unicode <code class="language-plaintext highlighter-rouge">\u00e9</code> (with the escape <code class="language-plaintext highlighter-rouge">\</code> character in front).</p> <p>Escaped unicode can be corrupt as well. For example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>`Singapore\u00e2\u0080\u0099s` </code></pre></div></div> <p>In this case, the original unicode for apostrophe has been corrupted into a nonsense three character sequence.</p> Sat, 30 Aug 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/character-corruption.html https://evanwill.github.io/_drafts/notes/character-corruption.html ScanTailor Book Scan Image Processing <p>ScanTailor is a unique piece of software that does its niche job very well–so I wanted to gather some notes about it.</p> <p>There was a ton of enthusiasm in 2000 - 2010s for DIY book scanning, where you set up your own library lab style book scanning rig and join Internet Archive in digitizing the worlds print heritage. A lot of this is embodied in the <a href="https://diybookscanner.org">DIY Bookscanner community</a> which contains a lot of information, plans, and documentation.</p> <p>Once you capture images of a book’s pages (either with a rig or flatbed scanner), you need to process them into something useable. There is two competing aims of the post-processing:</p> <ul> <li>Create super clean images for OCR to extract the text for a fully digital edition (the images won’t be used for human reading)</li> <li>Normalize and clean images for creating a PDF facsimile edition (make something that looks like the original book pages, which limits how much you will process the images. Images become the PDF pages.)</li> </ul> <p>Some commercial scanning rigs have their own proprietary software, and others use Acrobat, Abby Finereader, or Omnipage (which aren’t really designed for this task). The DIY community created a few pieces of software specially suited to the post-processing challenges–resulting in the original <a href="https://github.com/scantailor/scantailor">ScanTailor</a> (probably don’t install this version!). But in the last decade, community energy has fizzled (even at its height was very tiny and niche)–leaving a everything unmaintained.</p> <p>Since then ScanTailor has been forked and re-forked dozens of times by a bunch of random people trying to enhance and keep it functioning, leaving a maze of versions that is hard to navigate.</p> <p>The current most solid option seems to be <a href="https://github.com/ScanTailor-Advanced/scantailor-advanced">ScanTailor-Advanced</a>. A couple that seem active, but I haven’t personally used are <a href="https://github.com/ImageProcessing-ElectronicPublications/scantailor-experimental">scantailor-experimental</a> and <a href="https://github.com/trufanov-nok/scantailor-universal">scantailor-universal</a>).</p> <p>What ScanTailor does well is providing a mix of automated batch processing with individual review / manual tweaks on each page. Through each step of processing it gives you a preview of the results–then when you want to finalize, it runs all steps in one operation to maximize image quality.</p> <p>It can:</p> <ul> <li>Split, rotate, and crop pages.</li> <li>Deskew.</li> <li>Detect page content, so you can select text blocks and illustrations. The text and illustrations will be processed differently (which is pretty hard to do using other tools), and everything else cropped away.</li> <li>For text areas, sharpens text and removes the background.</li> <li>With everything selected, create a standardized page size and margin so the output images are all exactly the same.</li> </ul> Fri, 29 Aug 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/book-scan.html https://evanwill.github.io/_drafts/notes/book-scan.html Pasty Awareness Week <p><a href="https://evanwill.github.io/pastyAware/">Pasty Awareness Week</a> was one of my first personal static web projects on GitHub. I started from an old version of the default Jekyll <code class="language-plaintext highlighter-rouge">minima</code> theme and added some content that is near &amp; dear to my heart.</p> <p>Creating this pretty random project was a great way to learn more about Jekyll and GitHub Pages when I was first starting out. The platforms and my development has evolved a lot since then, but the content is definitely still really good and important.</p> <p>If you don’t know, pasties are a delicious food commonly found in the Upper Peninsula of Michigan and the Iron Range of Minnesota (and a few other US mining areas like Butte, Montana). In the UK they think Cornish folks invented them or something, but the things in the UP are uniquely their own and much better.</p> <p>Be sure to celebrate National Pasty Awareness Week every year and share <a href="https://evanwill.github.io/pastyAware/">#PastyAware</a>!</p> Wed, 30 Jul 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pasties.html https://evanwill.github.io/_drafts/notes/pasties.html Correct Math Answers <p>Encountering the every increasing absolute crap AI web content ecosystem and thinking about LLM lack of ability to do math randomly inspired me to make this useful and absolutely essential project:</p> <p><a href="https://evanwill.github.io/correct-math-answers/">Correct Math Answers</a></p> <p>I hope to add static generated pages to better allow AI bots to crawl and capture all the information to help train their models, but I enjoyed getting this rapidly set up, starting from <a href="https://github.com/thecdil/bootstrap5-template">bootstrap5-template</a> and using GitHub Copilot to quickly write everything.</p> <p>Like my other random projects, this was essentially a learning opportunity to figure out how to better use Copilot efficiently. I think having the LLM inside a well-known, self-contained environment is helpful to get better results than starting from scratch or letting it add batches of random dependencies.</p> <p>From the site:</p> <p>“Do you need to know 2 + 2, 6 - 4, 10 * -5, or 99 / 678493? We’ve got you covered! And you don’t need a calculator. If you need correct answers to math questions this site will provide exactly what you need.”</p> <p>Be sure to read the <a href="https://evanwill.github.io/correct-math-answers/about.html">About page</a>.</p> Wed, 30 Jul 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/math.html https://evanwill.github.io/_drafts/notes/math.html Water of the Wondrous Isles <p>I’ve always enjoyed the writing of <a href="https://en.wikipedia.org/wiki/William_Morris">William Morris</a>, a true “renaissance man” who dabbled well in an amazing array of artistic, academic, and social pursuits. Building on my <a href="https://evanwill.github.io/_drafts/notes/aladore.html">Aladore projects</a>, I was interested in creating some projects with Morris texts to further explore creating useable web editions with added data features using static web generation.</p> <p>In 2020 I created <a href="https://evanwill.github.io/morris-wondrous-isles-book/">morris-wondrous-isles-book project</a> building an edition of <em>The Water of the Wondrous Isles</em> (1897). The intent was to create a fully self-contained, minimal static web-based “artisanal” digital edition. With the text parsed into semi-structured markdown files, there is new opportunities to generate data and search.</p> <p>Water of the Wondrous Isles is a fascinating book, a female protagonist, powerful women, strange magic, in a fairy tale like setting. Give it a read at <a href="https://evanwill.github.io/morris-wondrous-isles-book/">morris-wondrous-isles-book</a>!</p> Tue, 29 Jul 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/morris.html https://evanwill.github.io/_drafts/notes/morris.html Beowulf-s <p>In 2021, I created the <a href="https://evanwill.github.io/beowulf-s/">Beowulf-s project</a> essentially by using OpenRefine to parse the text of Chauncey B. Tinker’s <em>The Translations of Beowulf: A Critical Bibliography</em> (1903) into structured data. Tinker <em>as data</em> provides a handy curated list of (now) public domain texts, so I enriched the data with links to digitized copies of each record on the web. I could then use the structured data (a CSV) to generate a website (<a href="https://collectionbuilder.github.io/">using CollectionBuilder</a>) to explore the historic bibliography of Beowulf translations.</p> <p>The whole project was inspired by Maria Dahvana Headley’s introduction to <em>Beowulf: a New Translation</em> (2020), which I would recommend giving a read! I describe it all a bit more on the <a href="https://evanwill.github.io/beowulf-s/about.html">About page</a>.</p> Tue, 29 Jul 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/beowulfs.html https://evanwill.github.io/_drafts/notes/beowulfs.html Digital Aladore and aladore-book <p>I started the <a href="https://digitalaladore.wordpress.com/">Digital Aladore project</a> in 2014 as a grad student project blog with the idea to take an obscure digitized public domain text and make it more usable. In 2018, I used the text to develop the <a href="https://evanwill.github.io/aladore-book/">aladore-book project</a>, exploring ideas of using static web generation to create ebooks with added data features.</p> <p>Here is an introduction adapted from my presentation <a href="https://osf.io/bvhnd">“Digital Aladore: Reflecting on Five Years of a DH Learning Project”</a> at DHSI Colloquium 2020:</p> <h2 id="abstract">Abstract</h2> <p>Digital Aladore started in 2014 as a project blog with the idea to take an obscure digitized public domain text and make it more usable. Grappling with the crummy digital legacy of the Million Book Project/Universal Library digitization initiatives of 2000’s, it was conceptually an opportunity to apply a background in Classical Studies to investigating the twisted details of digital witnesses and textual transmission. However, encountering the limitations of digitization that failed to take advantage of the affordances of digital mediums, it led down a path to learning the software and approaches for transforming images, text, and data. Importantly, publicly articulating the learning process of encountering challenges and discovering solutions resulted in a lasting resource of accessible explanations about using technical tools–attracting significant use from outside of academic sources. After more than five years of maintaining Digital Aladore as a venue for thinking through ideas and tinkering with DH tools, it has moved far beyond its origins as a course assignment in library school. The experience guided my development into the realm of open software, content, and communication, while providing a playground of data for tooling up DH projects. This talk reflects on the unexpected value, outcomes, and sustainability of a simple side project for learning DH hands-on.</p> <h2 id="presentation">Presentation</h2> <p>Rather than introducing my official scholarship–this presentation reflects on more than five years of a Digital Humanities side project–a little personal gem that has sat simmering on the side of my desk since grad school–and the unexpected value that comes of having this space for thinking through ideas and tinkering with DH tools. This little project acts as a medium for exploration and learning, a theme DH thinkers have commonly returned to, “messing about” and play, which is especially appropriate in the DHSI context where traditionally we come together for a week of exploring, learning, and concocting new ideas in lovely Victoria–which I am missing very much this year.</p> <p>Digital Aladore was a project I started with the idea to take an obscure digitized public domain text and make it more useable. It has it’s roots in a weird mix of academic ideas, personal whimsy, and, of course, a class assignment.</p> <p>In 2014 I was taking a course at UBC nicknamed “OK MOOC”. It was a collaboration of six international universities offering in person, for credit classes, embedded inside a free online course with over 12,000 other learners– it was basically very intense, overwhelming, but truly fascinating.</p> <p>Digital Aladore came out of that mix, thinking about open culture, working with public domain text and open source software–as well as an aim for transparency and clear communication.</p> <p>My background was in Classical Studies, meanwhile I was working in a digitization lab, I was fascinated with how the scholarship of textual transmission might apply in the digital archives. Particularly, in the legacy of terrible metadata and horrific OCR from mass digitization projects of the late 2000’s, such as the Million Book Project/Universal Library.</p> <p>You could find these digitized texts online, but due to the poor quality they are barely useable for reading or analysis. On the other hand there are academic projects such as the William Morris archive that provide critical edition quality text, but are often locked in outdated web sites (the Adobe Flash Edition). I mention William Morris here because Aladore is basically an imitation his romances–but Morris is popular enough to have good human-edited reading editions available in places such as Project Gutenberg. For more obscure texts, we are stuck with trying to read auto-generated bad OCR ebooks or a lousy PDF.</p> <p>I really just wanted to read a nice clean copy of Aladore, so I set out to make my own, learning everything that went into it along the way.</p> <p>In retrospect, this is a classic digital librarian idea–untangle metadata, create more useable access, and reporting out about everything.</p> <p>So the blog was just that–step-by-step notes about open source tools and processes to work with digitized texts, publicly articulating my learning process and recording solutions.</p> <p>I processed the two print editions of Aladore that were available, and then I collated them to help in the textual editing process.</p> <p>I wanted to engage people with thought about textual transmission and concepts of openness. However my most popular posts ended up being the practical steps to use OCR. And they seem to get used–for example, I ran across this forum post of an IT person trying to optimize some batch script based on a Digital Aladore post.</p> <p>Think about that, some publishing company is using a random code copied from a DH student learning blog…</p> <p>Documenting learning is powerful.</p> <p>That approach of open communication has stuck with me, contributing to organizations such as Software Carpentry or Programming Historian, and my own workshop resources.</p> <p>The text of Digital Aladore lives on.</p> <p>For me, it acts as a well known text data set for use in testing out ideas or any new tools that comes across my plate, a playground of data for tooling up for other, more important, DH projects. And a lot of the use cases end up built into my current edition, <a href="https://evanwill.github.io/aladore-book/">aladore-book project</a>, where I play off the “collections as data” concept to make a variety of handy text derivatives readily available for use on the web.</p> <p>And, true to the original project, it is also reader friendly, so if you you are looking for a obscure summer read, check it out.</p> Tue, 29 Jul 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/aladore.html https://evanwill.github.io/_drafts/notes/aladore.html University Wifi on Linux <p>Sometimes connecting to secure wifi at institutions like universities is not so obvious and easy on Linux, it doesn’t just connect but asks you for a bunch of configuration options.</p> <p>Go to your full Settings &gt; Wi-Fi, click on the network name, which will get you to a security settings form with a lot of options. In my experience, if you are trying to connect to most university wifi or eduroam, this is usually the correct configuration:</p> <ul> <li>Security: WPA &amp; WPA2 Enterprise</li> <li>Authentication: Protected EAP (PEAP)</li> <li>Anonymous identity: [leave blank]</li> <li>Domain: [leave blank]</li> <li>CA certification: None</li> <li>check off “No CA certificate is required”</li> <li>PEAP version: Automatic</li> <li>Inner authentication: MSCHAPv2</li> <li>Username: [your individual username or email, for eduroam this is your full home institution email]</li> <li>Password: [your individual password]</li> </ul> <p>Since your password is saved, don’t share this with other users on your system.</p> Mon, 02 Jun 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/linux-wifi.html https://evanwill.github.io/_drafts/notes/linux-wifi.html Ubuntu 24.04 <p>When I started writing this blog, I had new computers, and liked to install every new release of Ubuntu and Fedora to see how much better my laptops got. I still use those same computers which are now old. I only install long term releases (LTS, five+ years of support) and keep using it for a long time.</p> <p>Well, <a href="https://ubuntu.com/download/desktop">Ubuntu 24.04</a> has been out for a while now, and I haven’t written an updated “getting started with Ubuntu” post for five years–so I thought I better get back to it!</p> <p>This is (like other posts) notes to myself, since I installed Ubuntu 24.04 on a bunch of Dell XPS 13 laptops. The Dell laptops are well supported, since they used to sell them with Ubuntu as an option. They have only 8 GB ram and were running horribly slow on end of life Windows 10–but work great in Ubuntu 24.04!</p> <h2 id="unencrypt-bitlocker">Unencrypt Bitlocker</h2> <p>If you are installing over an old Windows machine which used Bitlocker encryption, first you may want to disable/unencrypt the drive. This step shouldn’t be necessary, however, the Ubuntu installer would NOT let me overwrite the encrypted Windows drive.</p> <ul> <li>Open Start Menu and search for “manage bitlocker” (or go to Control Panel &gt; System and Security &gt; Bitlocker Drive Encryption)</li> <li>Next to each drive it will have a “Turn off Bitlocker” option. Click it.</li> <li>Wait. Unencrypting the drive takes a very long time.</li> <li>Once complete, fully shutdown Windows.</li> </ul> <h2 id="create-install-usb">Create Install USB</h2> <ol> <li>download <a href="https://ubuntu.com/download/desktop">Ubuntu 24.04 LTS</a></li> <li><a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn ISO to a USB stick</a></li> <li>Plug in your live USB into computer (while turned off)</li> </ol> <h2 id="set-up-bios">Set up BIOS</h2> <p>This part varies a lot on different computers and isn’t always necessary…</p> <ol> <li>Click the power button of you computer</li> <li>Hit the boot interrupt key to enter BIOS menu. This is usually F2, F12, Delete, or Esc, sometimes the key is flashed on the screen as the computer boots along with the manufacturer logo. For Dell XPS hit F2.</li> <li>Enter BIOS: Look for something about “SATA Operation” and select “AHCI” (you need to turn “RAID” mode off because it is not supported by Linux).</li> <li>Save and exit BIOS</li> </ol> <h2 id="boot-usb">Boot USB</h2> <ol> <li>Reboot and hit the boot interrupt or boot option menu key. For Dell XPS hit F12. This will get you to a temporary boot menu (alternatively, these options are available in the main BIOS menu of most computers).</li> <li>Choose the first USB boot option</li> <li>After some thought, you may see an Ubuntu boot option menu, select “try and install” to continue. Or it will boot into the Ubuntu live image, where you can choose to test or install.</li> </ol> <h2 id="install-ubuntu">Install Ubuntu</h2> <p>Use the installer to follow through the steps (official <a href="https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview">Ubuntu tutorial</a>). Suggestions:</p> <ul> <li>Connect to wifi to greatly speed getting everything set up.</li> <li>Use “Default selection” for apps, rather then the full install, <em>unless</em> you want LibreOffice all set up and ready.</li> <li>Check the “recommend proprietary software” to simplify set up.</li> <li>On “How do you want to install Ubuntu?” use the “Erase disk” option. Click “Advanced feature” and select “LVM and encryption” option. If you use encryption, you will set a encryption password (separate from your user password) that you will need to use each time your reboot the computer.</li> </ul> <h2 id="get-set-up-in-ubuntu">Get Set Up in Ubuntu</h2> <ul> <li>Update everything with the “Updates” app or in the terminal <code class="language-plaintext highlighter-rouge">sudo apt update</code> then <code class="language-plaintext highlighter-rouge">sudo apt upgrade</code>.</li> <li>Open Settings: <ul> <li>Settings &gt; Appearance - set your background and new option to set an accent color.</li> <li>Settings &gt; Ubuntu Desktop - Customize the Desktop icons and Dock. Option to turn off Enhanced Tiling (I’m not used to it, so sort of drives me crazy).</li> <li>Settings &gt; System &gt; Date &amp; Time - use “Time Format” option to change 24hr or AM/PM.</li> </ul> </li> <li>Install some essentials to customize the desktop: <code class="language-plaintext highlighter-rouge">sudo apt install gnome-tweaks gnome-shell-extension-prefs gnome-shell-extension-manager</code> <ul> <li>gnome-tweaks lets you customize all details of the desktop, for example moving the window buttons from right to left corner.</li> <li>gnome-shell-extension-prefs provides a visual tool to customize the options of gnome extensions.</li> <li>gnome-shell-extension-manager provides a visual tool to install gnome extensions.</li> </ul> </li> <li>Open “Extension Manager”, click Browse, search for “Caffeine”, and click install. <a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine extension</a> allows you to disable screen lock manually, and shows up in the menu from upper right corner of the menu bar.</li> <li>Enable firewall: <code class="language-plaintext highlighter-rouge">sudo ufw enable</code></li> <li>Development essentials: <code class="language-plaintext highlighter-rouge">sudo apt install build-essential git curl</code></li> <li>Chromium (browser): <code class="language-plaintext highlighter-rouge">sudo snap install chromium</code></li> <li>VS Code (editor): <code class="language-plaintext highlighter-rouge">sudo snap install code --classic</code></li> <li>KeePassXC (password manager): <code class="language-plaintext highlighter-rouge">sudo snap install keepassxc</code></li> <li>Ruby: <a href="https://evanwill.github.io/_drafts/notes/ruby-rbenv.html">rbenv</a></li> <li><a href="https://documentation.ubuntu.com/ubuntu-for-developers/howto/python-setup/">python</a>, <a href="https://documentation.ubuntu.com/ubuntu-for-developers/tutorials/python-use/">venv</a> or <a href="https://github.com/astral-sh/uv">uv</a></li> </ul> <p>Note: I don’t think tlp / advanced laptop power management is necessary any more.</p> Mon, 20 Jan 2025 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu24.html https://evanwill.github.io/_drafts/notes/ubuntu24.html Git Credential Manager <p>Git for Windows comes bundled with Git Credential Manager (gcm) which makes using git on command-line much easier, automatically opening up authentication in a GUI window or web browser and storing the results. On linux things are not quite so simple–however, you can <em>now</em> install <a href="https://github.com/git-ecosystem/git-credential-manager">Git Credential Manager</a> manually.</p> <p>(alternatively, you can use <a href="https://evanwill.github.io/_drafts/notes/git-credential.html">Git Credential Helper</a> if you have authentication tokens set up already)</p> <h2 id="install-git-credential-manager">Install git-credential-manager</h2> <p>Follow the instructions for your OS <a href="https://github.com/git-ecosystem/git-credential-manager/blob/release/docs/install.md">documented at the gcm github repository</a>. Here a the summary for Ubuntu:</p> <ul> <li>download latest “.deb” package <a href="https://github.com/git-ecosystem/git-credential-manager/releases">release</a></li> <li>install the deb <code class="language-plaintext highlighter-rouge">sudo dpkg -i &lt;path-to-package&gt;</code></li> <li>run <code class="language-plaintext highlighter-rouge">git-credential-manager configure</code></li> <li><a href="https://github.com/git-ecosystem/git-credential-manager/blob/release/docs/credstores.md">configure a credential store</a>. I use the secretservice option which is built in to Ubuntu: <code class="language-plaintext highlighter-rouge">git config --global credential.credentialStore secretservice</code></li> <li>Restart your system! (otherwise you will get weird errors)</li> </ul> <p>Next time you clone or pull from a private repository (or push), gcm will pop open a little window to handle authentication for the platform. The credentials will be stored for future re-use.</p> <p>If you need to <strong>update</strong> your credentials, the easiest method is to use “Passwords and Keys” / Seahorse app: Look in Passwords &gt; Login category. You should find an entry such as “git:https://github.com/” that corresponds with the credential. I usually just delete the old one, then provide the updated version on my next git operation.</p> Mon, 30 Dec 2024 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-cred-manager.html https://evanwill.github.io/_drafts/notes/git-cred-manager.html Ruby rbenv on Ubuntu <p>For a long time I used <a href="https://rvm.io/">RVM</a> as version manager to install <a href="https://www.ruby-lang.org/en/">Ruby</a> on Linux (<a href="https://evanwill.github.io/_drafts/notes/ruby-notes.html">note</a>). However, while teaching workshops Mac users seem to run into endless issues trying to install RVM. For Mac, using <a href="https://brew.sh/">brew</a> to install <a href="https://github.com/rbenv/rbenv">rbenv</a> seems a better alternative. Also, some folks don’t like how RVM handles it’s Ruby version switching magic (e.g. basically it is too heavy and hacks the <code class="language-plaintext highlighter-rouge">cd</code> command, see <a href="https://dev.to/krtb/why-and-how-i-replaced-rvm-with-rbenv-23ad">summary</a>). So eventually I switched to rbenv on Linux as well.</p> <p><em>Unfortunately, rbenv documentation is poor and seems focused on Mac users–thus this note to remember what I did on Ubuntu…</em></p> <p>There are a few things to keep in mind:</p> <ul> <li>If you have RVM currently installed, you will have to fully remove it which isn’t very easy (I switched to rbenv only when I did a fresh install).</li> <li>Unlike RVM, rbenv only switches Ruby versions, it doesn’t install/build them. This is not obvious for Mac users since installing rbenv via brew automatically installs <a href="https://github.com/rbenv/ruby-build">ruby-build</a> at the same time (without mentioning it…). So you will want to install ruby-build as well.</li> <li>Using rbenv has changed a bit since earlier versions (easier now), so looking at old suggestions / instructions is probably a wild goose chase.</li> <li>You will have to keep rbenv and ruby-build up-to-date manually, which is a bit of a pain, but sort of refreshingly simple…</li> <li>You can automate install using <a href="https://github.com/rbenv/rbenv-installer">rbenv-installer</a>, which is basically a script just like brew recipes (I did not try this).</li> </ul> <p><strong>Note:</strong> there is an Ubuntu package to install, so you can use <code class="language-plaintext highlighter-rouge">sudo apt install rbenv ruby-build</code>. Unfortunately the <code class="language-plaintext highlighter-rouge">ruby-build</code> package is <em>super</em> out of date, so it will only list very out-of-date versions of Ruby to install. This is not a good install method!</p> <h2 id="install-rbenv-and-ruby-build">Install rbenv and ruby-build</h2> <p><strong>First</strong>, install build dependencies. Honestly, I am not sure about these, but this is the <a href="https://github.com/rbenv/ruby-build/wiki#suggested-build-environment">suggested build environment</a> from ruby-build, which I updated a bit for recent Ubuntu since some of the listed packages are out-of-date:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev </code></pre></div></div> <p>Finish the install, close your terminal and open a new one.</p> <p><strong>Second</strong>, clone rbenv into your home directory:</p> <p><code class="language-plaintext highlighter-rouge">git clone https://github.com/rbenv/rbenv.git ~/.rbenv</code></p> <p><strong>Third</strong>, run the init function to set it up:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>~/.rbenv/bin/rbenv init </code></pre></div></div> <p>Close terminal and open a new one.</p> <p><strong>Fourth</strong>, clone ruby-build into the rbenv plugins directory:</p> <p><code class="language-plaintext highlighter-rouge">git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build</code></p> <h2 id="install-a-ruby">Install a Ruby</h2> <p>Check the <a href="https://www.ruby-lang.org/en/downloads/">Ruby download page</a> to find the latest stable version or your project requirements to find your desired Ruby version number. Check <code class="language-plaintext highlighter-rouge">rbenv install -l</code> to get a list of available versions.</p> <p>Use <code class="language-plaintext highlighter-rouge">rbenv install</code> + version number, e.g.:</p> <p><code class="language-plaintext highlighter-rouge">rbenv install 3.4.1</code></p> <p>This can take awhile since ruby-build will download and build from source.</p> <p>Once complete, set the version you want to use:</p> <p><code class="language-plaintext highlighter-rouge">rbenv global 3.4.1</code></p> <p>Now, <code class="language-plaintext highlighter-rouge">ruby -v</code> should report what you just set. If you need a different version for a specific project, run <code class="language-plaintext highlighter-rouge">rbenv local &lt;version number&gt;</code> in the directory (which creates a file called <code class="language-plaintext highlighter-rouge">.ruby-version</code> to keep track).</p> <p><em>Note:</em> Gems you install will be specific to the currently used version (global or local). When you install a new gem that includes commands (e.g. Jekyll) rbenv shims have to be rebuilt. This is done automatically (assuming you followed the <code class="language-plaintext highlighter-rouge">rbenv init</code> instructions), or can be manually triggered with command <code class="language-plaintext highlighter-rouge">rbenv rehash</code>.</p> <h2 id="switching-rubies">Switching Rubies</h2> <p><code class="language-plaintext highlighter-rouge">rbenv versions</code> lists installed versions with <code class="language-plaintext highlighter-rouge">*</code> next to current global version</p> <p><code class="language-plaintext highlighter-rouge">rbenv global &lt;version number&gt;</code> will switch global version. Once you switch, just remember that your installed gems are specific to a version, so you won’t have the same set of gems available!</p> <h2 id="update-rbenv-and-ruby-build">Update rbenv and ruby-build</h2> <p>Since you installed the tools using git, to update rbenv and ruby-build you simply <code class="language-plaintext highlighter-rouge">git pull</code> the most recent master branch code.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~/.rbenv &amp;&amp; git pull cd "$(rbenv root)"/plugins/ruby-build &amp;&amp; git pull </code></pre></div></div> <p><strong>Note:</strong> the list of available Ruby versions (<code class="language-plaintext highlighter-rouge">rbenv install -l</code>) is <strong>NOT automatically updated</strong>. So you should periodically update ruby-build following the git pull method above (i.e. <code class="language-plaintext highlighter-rouge">cd ~/.rbenv/plugins/ruby-build &amp;&amp; git pull</code>).</p> Thu, 05 Dec 2024 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ruby-rbenv.html https://evanwill.github.io/_drafts/notes/ruby-rbenv.html Ubuntu 20th Anniversary <p>I was surprized to read that it is <a href="https://ubuntu.com/20years">Ubuntu’s 20th anniversary</a>–honestly, that’s pretty cool.</p> <p>There are not a lot of <a href="https://www.omgubuntu.co.uk/2024/09/ubuntu-24-10-new-features">new features for version 24.10</a> marking the milestone, but seems like improvements to the installer–which is fitting, because I think what was so great about Ubuntu in the early days was having a relatively easy to use install process, enabling people to actually get started on linux easier.</p> <p>I’ve used Ubuntu since almost the beginning! I was a poor college student. I could pick up discarded old laptops on campus for free. The batteries were bad. Windows was bad and making them unusably slow and cumbersome. But I could plug in a usb drive, install Ubuntu, and have a great running computer. Something that just worked, had no sketchy bloatware, and fit my budget of zero.</p> <p>People still complain that Linux is too weird and hard or tech elitist–I never quite understand. I was a Classical Studies student. I didn’t have any technical training or interest in computers. I worked construction and as a studio artist, so I guess I was willing to be hands on to figure something out.</p> <p>This allowed me to actually have a functional computer. Once installed, it was just a perfectly normal computer, easy to use.</p> <p>My partner has been an Ubuntu user now for 15 years, and she seriously has no idea what Linux or Ubuntu is. It’s never come up. If you said “operating system” she would have no clue what you mean. It’s just a computer that works great.</p> <p>Honestly, that’s pretty amazing. So, thank you Ubuntu and happy anniversary.</p> <p>If you want to learn more, <a href="https://evanwill.github.io/try-linux/">Try Linux</a>!</p> Thu, 10 Oct 2024 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu20yrs.html https://evanwill.github.io/_drafts/notes/ubuntu20yrs.html Chromebooks Disable Touchscreen <p>I have several nice higher end Chromebooks that we got via pandemic money for remote schooling. The problem is that in most of the devices (2 out of 3) the touch screen goes wacky, causing all sorts of ghost clicking that makes it totally unusable. Which is too bad, since the devices are fine otherwise…</p> <p>I wish Chromebook manufacturers wouldn’t do such a terrible job on this hardware–these aren’t cheapo ones, so it is really disappointing. Also, not sure why disabling touch screen isn’t a built in short cut <em>or</em> why there isn’t a permanent method to do so (and that is on ChromeOS)…</p> <p>But, if you have them, and the screen starts going crazy, there is still a couple of ways to use it.</p> <h2 id="connect-to-monitortv">Connect to Monitor/TV</h2> <p>First, to escape wild behavior if the touch screen is making it impossible to even log in, connect the Chromebook to a monitor or TV. Hopefully your device has some port that will allow that (mine all have HDMI output).</p> <p>Leave the Chromebook closed, connect the monitor, a keyboard, and mouse. Then push the power button to start the device up without opening the screen.</p> <p>This will allow you to get into the settings to fix things.</p> <p>(Or just keep using it as a desktop computer…)</p> <h2 id="use-chrome-flags">Use Chrome Flags</h2> <ol> <li>Open Chrome browser on the Chromebook.</li> <li>Put <code class="language-plaintext highlighter-rouge">chrome://flags/</code> in the address bar.</li> <li>Search for ash-debug-shortcuts</li> <li>Switch ash-debug-shortcuts option to “Enabled”</li> <li>Click Restart (which will restart the device)</li> </ol> <p>Now you will have a new keyboard shortcut <code class="language-plaintext highlighter-rouge">Shift + Search + T</code> that toggles the touch screen on and off.</p> <p>Unfortunately, it will toggle back on each time you restart (for example when installing updates). This is okay if you can get the shortcut applied fast enough when logging in before the ghost action gets too wild.</p> <p>However, if your touch screen is really out of wack, this can still be super frustrating. One of my devices is super erratic, sometimes fine I can toggle off the touch screen and log in and be happy–other times the ghosting starts zooming in and out and randomly clicking all over resulting in all kinds of wild activity. To recover, you can always go back to connecting to a monitor–but if this is the case you might want to go more drastic.</p> <h2 id="developer-mode">Developer Mode</h2> <p>If you want to go further, you have to switch on Developer Mode. This will erase all the local data and set up.</p> <p>Unfortunately, Chromebook is a maze of proprietary weird exceptions, so pretty much nothing you find online with <em>exactly</em> match up with your actual device. It goes out of date fast and each vendor has a bunch of odd custom stuff.</p> <ul> <li><a href="https://techysnoop.com/enable-disable-chrome-os-developer-mode-chromebook/">enable developer mode</a></li> <li><a href="https://techysnoop.com/disable-touchscreen-on-chromebook/">permanently disable touchscreen via shell</a> - however, this does NOT work for me (xinput not found) and I have been unable to debug or find any other suggestion.</li> <li>Install something else, <a href="https://docs.chrultrabook.com/">chrultrabook</a> and <a href="https://docs.mrchromebox.tech/docs/getting-started.html">mrchromebox</a>.</li> </ul> <p>Some handy key shortcuts:</p> <ul> <li>Open crosh shell: <code class="language-plaintext highlighter-rouge">Ctrl + Alt + T</code></li> <li>Switch to VT-2 shell with sudo commands: <code class="language-plaintext highlighter-rouge">Ctrl + Alt + -&gt;/F2</code> (log in as “chronos”)</li> <li>Switch back to crosh: <code class="language-plaintext highlighter-rouge">Ctrl + Alt + &lt;-/F1</code></li> </ul> Sat, 05 Oct 2024 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/chromebooks.html https://evanwill.github.io/_drafts/notes/chromebooks.html Firefox Tips <p>Tips about Firefox:</p> <ul> <li>Settings &gt; Privacy &amp; Security &gt; check “Use a primary password” and set. This ensures your saved passwords are encrypted on your device.</li> <li>Settings &gt; Privacy &amp; Security &gt; Website Advertising Preferences, uncheck “Allow” option!</li> <li>Add Firefox <a href="https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/?src=search">Multi-Account Containers</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/facebook-container/">Facebook Container</a></li> <li>Add adblocker such as <a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/?src=search">uBlock Origin</a></li> </ul> <h2 id="disable-gestures">Disable Gestures</h2> <p>I have issues accedentally going back via the default “guestures” for “swipe” somehow causing Back at random on my touch pad. Turn off the option to avoid this issue:</p> <ul> <li>in address bar, type <code class="language-plaintext highlighter-rouge">about:config</code></li> <li>accept the risk warning</li> <li>search for <code class="language-plaintext highlighter-rouge">browser.gesture</code></li> <li>in the <code class="language-plaintext highlighter-rouge">.swipe.left</code> and <code class="language-plaintext highlighter-rouge">.swipe.right</code> options, click the edit icon, delete the value, and click the check icon to save.</li> </ul> <h2 id="issues-with-cisco-vpn">Issues with Cisco VPN</h2> <p>For some weird reason, Cisco AnyConnect / Secure Client has issues with Ubuntu + Firefox for authentication. To avoid issues, first go to Ubuntu Settings &gt; Connectivity and uncheck the option. Second, use Chromium for authentication…</p> Fri, 05 Jul 2024 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/firefox.html https://evanwill.github.io/_drafts/notes/firefox.html Hoppy Alternative Drinks <p>I love IPA beers mainly just for the incredible hop aroma. But one downside (sometimes) to IPAs is that they tend to be high in alcohol. Sometimes you just want some delicious hops!</p> <p>This table relates my experiences exploring non-alcoholic hoppy drinks. I purchase the beverages (no sponsors!), pour them into a pint glass (to get the max aroma), and drink them (to probe their tastiness). Drinks are rated 1 - 5 on these highly scientific qualities:</p> <ul> <li><strong>hoppyness</strong> - overall hop quality and quantity.</li> <li><strong>aroma</strong> - does it smell wonderfully hoppy?</li> <li><strong>body</strong> - does the beverage have mouth-feel and body?</li> <li><strong>beeriness</strong> - does it taste like or stand in for a beer? This isn’t necessary for deliciousness, but sometimes you want a beer-like substance.</li> <li><strong>deliciousness</strong> - just how delicious is it overall <em>as a hoppy alternative beverage</em>?</li> </ul> <h2 id="hoppy-drink-list">Hoppy Drink List</h2> <style> .stats { margin-left: 1.5rem; } .bordered { border: solid 1px #212529; padding: 0 .45rem; } .b-green { border-color: green; } .b-red { border-color: red; } .b-gold { border-color: orange; } .b-blue { border-color: blue; } </style> <div id="archiveList" class="archive-list"> <div class="browse"> <input class="search" placeholder=" Search" type="text" aria-label="Search beverages" /> <button class="buttons sort" data-sort="title">Name</button> <button class="buttons sort" data-sort="brewer">Brewer</button> <br /> <strong>Sort by Rating:</strong> <button class="buttons sort b-green" data-sort="hop">Hoppyness</button> <button class="buttons sort b-red" data-sort="aroma">Aroma</button> <button class="buttons sort b-gold" data-sort="beer">Beeriness</button> <button class="buttons sort b-blue" data-sort="delic">Deliciousness</button> </div> <div class="listjs"> <div class="archive-list-link"> <span class="title archive-list-link-title">Calm One HopTea,</span> <span class="brewer">Hoplark</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">2</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">This is probably the most delicious HopTea, the sweet smoothness of chamomile suits the flavors very well. Citra hops.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Really Hoppy One HopTea,</span> <span class="brewer">Hoplark</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">2</span> <br /> <div class="descr">The flavors of this aren't very balanced, I find it overly hoppy but not delicious.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Green Tea One HopTea,</span> <span class="brewer">Hoplark</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Pretty good balance of very light beverage and good hop aroma. Mosaic hops.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Mile-High-Biscus One HopTea,</span> <span class="brewer">Hoplark</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Surprisingly delicious, I didn't expect to like the hibiscus, but it adds nicely to the aroma.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Hop Water,</span> <span class="brewer">Sockeye</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">2</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">Very simple hoppy sparkling water, light aroma, good taste, refreshing. Grapefruit-y? Idaho grown hops.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Hop Splash,</span> <span class="brewer">Sierra Nevada</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">2</span> <br /> <div class="descr">A tasty sparkling water, less citrus-y or sweetness, crisp and refreshing. The aroma is light, and the favor isn't totally balanced. Citra and Amarillo hops.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Trail Pass IPA,</span> <span class="brewer">Sierra Nevada</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">2</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Very good flavor, but light aroma and light lager-like taste. This is the first NA IPA I have come across in 12 packs!</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Hazy IPA,</span> <span class="brewer">Sierra Nevada</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">2</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Distinctive hazy favor. I think I prefer the regular Trail Pass, but this is quite good.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Brewveza,</span> <span class="brewer">Sierra Nevada</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">2</span> <br /> <div class="descr">Reasonable light lager-like drink.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Hoppy Refresher,</span> <span class="brewer">Lagunitas</span> <br /> <div class="stats"> <span class="hop bordered b-green">1</span> <span class="aroma bordered b-red">0</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">2</span> <br /> <div class="descr">Very citrus-y more than hoppy, definitely refreshing and tasty as a sparkling water--but not really hop forward.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">IPNA,</span> <span class="brewer">Lagunitas</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">2</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Light, crisp, has good bitterness but weak on the aroma which brings down the feeling of hoppyness--however, much more tasty than an average non-alcoholic beer.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Juicy IPA,</span> <span class="brewer">Grüvi</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Marketed as non-alcoholic craft brew, this goes for beeriness and does a good job. Interestingly, the taste and aroma in the first few minutes is GREAT, but then it seems to gradually get sweeter and less delicious as it warms.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Stout,</span> <span class="brewer">Grüvi</span> <br /> <div class="stats"> <span class="hop bordered b-green">1</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">4</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">Really tasty rich stout.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Non-Alcoholic IPA,</span> <span class="brewer">Fremont</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">2</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">2</span> <br /> <div class="descr">Pretty solid as a basic very light IPA substitute. Tasty, but almost more like a lager in favor.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Run Wild IPA,</span> <span class="brewer">Athletic Brewing Co.</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">This is pretty delicious as an light IPA.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Free Wave Hazy IPA,</span> <span class="brewer">Athletic Brewing Co.</span> <br /> <div class="stats"> <span class="hop bordered b-green">3</span> <span class="aroma bordered b-red">3</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">Refreshing, tasty light beer-like light IPA. Crushable.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Lime,</span> <span class="brewer">HOP WTR</span> <br /> <div class="stats"> <span class="hop bordered b-green">1</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">1</span> <br /> <div class="descr">Billed as sparkling hop water with adaptogens and nootropics, this is the most expensive drink I have tried. I found it not good. Tasted exactly like a cheap lime bubble water, but slightly nasty.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Classic,</span> <span class="brewer">HOP WTR</span> <br /> <div class="stats"> <span class="hop bordered b-green">0</span> <span class="aroma bordered b-red">0</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">0</span> <br /> <div class="descr">Like the Lime version, I got this on 50% off sale (otherwise far too expensive) and found it nasty. It is very acidic and mineral-water-like, with very faint if any hop related favor. The main ingredient is ascorbic acid (120% of your vitamin C, rather than hops...), which I guess must contribute significantly. I didn't even finish drinking a single can--however, I must admit that for some reason my partner loved it--so maybe its just me?</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Hop Water,</span> <span class="brewer">Trail Magic</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">3</span> <span class="beer bordered b-gold">2</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">This is a delicious beverage, with 3mg THC (in Minnesota). It has a nice aroma and some body, not trying to be an beer exactly, but something delicious with hops in it.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Organic Session IPA,</span> <span class="brewer">Sober Carpenter</span> <br /> <div class="stats"> <span class="hop bordered b-green">4</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">4</span> <span class="delic bordered b-blue">4</span> <br /> <div class="descr">A very tasty IPA substitute, basically just like a session IPA. Available in Canada.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">0.0% Premium Pils,</span> <span class="brewer">Bitburger</span> <br /> <div class="stats"> <span class="hop bordered b-green">1</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">1</span> <br /> <div class="descr">One of classic popular german beers as an NA. Pretty traditional sort of NA, meaning pretty terrible--but I guess better than really old school ones from the 2000s.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Original NA,</span> <span class="brewer">Clausthaler</span> <br /> <div class="stats"> <span class="hop bordered b-green">1</span> <span class="aroma bordered b-red">1</span> <span class="beer bordered b-gold">2</span> <span class="delic bordered b-blue">1</span> <br /> <div class="descr">Really not a tasty beverage from my point of view. Something pretty bad about these old school NA beers.</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Fresh Squeezed Non-Alcoholic IPA,</span> <span class="brewer">Deschutes</span> <br /> <div class="stats"> <span class="hop bordered b-green">4</span> <span class="aroma bordered b-red">4</span> <span class="beer bordered b-gold">3</span> <span class="delic bordered b-blue">5</span> <br /> <div class="descr">Very hoppy, yet balanced good flavor. To me it seems not quite as beer-like as the Athletic Brewing offerings, but in a good way, as a slightly different genre of deliciously hoppy drink (that is similar, but not quite like beer).</div> </div> </div> <div class="archive-list-link"> <span class="title archive-list-link-title">Sparkle Hops,</span> <span class="brewer">Pelican Brewing</span> <br /> <div class="stats"> <span class="hop bordered b-green">2</span> <span class="aroma bordered b-red">2</span> <span class="beer bordered b-gold">0</span> <span class="delic bordered b-blue">3</span> <br /> <div class="descr">Very good, more mineral-water-y taste.</div> </div> </div> </div> </div> <!-- add list.js http://www.listjs.com/ @javve --> <script src="/_drafts/js/list.min.js"></script> <script> // init list var options = { valueNames: [ 'title', 'brewer', 'hop', 'aroma', 'beer', 'delic' ], listClass: 'listjs' }; var userList = new List('archiveList', options); </script> Sat, 08 Apr 2023 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/hoppy.html https://evanwill.github.io/_drafts/notes/hoppy.html Crazy Cake Recipe <blockquote> <p>My favorite cake (“minimal cake infrastructure”), regularly cooked after school when a teenager. Very delicious and very simple to make. Since this recipe always comes out well it is also great for experimenting by adding random other ingredients.</p> </blockquote> <p>Heat oven 350 degrees.</p> <p>Combine all dry ingredients directly in an ungreased 9 x 13in pan:</p> <ul> <li>3 cups flour</li> <li>2 cups sugar</li> <li>1/2 cup baking cocoa (you can play with this amount depending on how strong you like your chocolate, approximately from 1/3 cp to 2/3 cup, or even 0)</li> <li>2 teaspoons baking soda</li> <li>1 teaspoon salt</li> </ul> <p>After mixing the dry stuff in the pan, make three depressions and add each liquid ingredient into is own spot:</p> <ul> <li>2 teaspoon vanilla extract</li> <li>3/4 cup vegetable oil</li> <li>2 tablespoons vinegar</li> </ul> <p>Next pour:</p> <ul> <li>2 cups cold water</li> </ul> <p>over everything in the pan. Mixing everything up with a fork (blend it up, but don’t beat or over mix).</p> <p>Put pan in the oven and bake for approximately 34 - 40 minutes until pick comes out clean.</p> <p>I generally like to serve it up right away just plain with some milk. But you can treat it just like any other cake (e.g. cool and frost it, etc).</p> Wed, 25 Jan 2023 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/crazy-cake.html https://evanwill.github.io/_drafts/notes/crazy-cake.html Deploy a Jekyll Site with GitHub Actions using Starter Workflow (v3) <p>GitHub Pages’ default build process runs an older version of Jekyll and does not support plugins (see <a href="https://pages.github.com/versions/">dependency versions</a> for details). However, you <em>can</em> set up an alternative build using <a href="https://docs.github.com/en/actions">GitHub Actions</a>. GitHub has recently made setting up Actions to deploy your site to Pages easier, so this is a great option. (note, an older more <a href="/_drafts/notes/github-actions2.html">manual method to set up Actions also works</a> if you want customize more)</p> <h2 id="prep-project-repository">Prep Project Repository</h2> <p>First, check your “_config.yml” to ensure the <code class="language-plaintext highlighter-rouge">url</code> and <code class="language-plaintext highlighter-rouge">baseurl</code> values are set correctly for hosting on GitHub Pages following the pattern <code class="language-plaintext highlighter-rouge">url: https://username.github.io</code> and <code class="language-plaintext highlighter-rouge">baseurl: /repository-name</code>. If you don’t have these set, the Liquid filter <code class="language-plaintext highlighter-rouge">absolute_url</code> won’t work correctly.</p> <p>Second, make sure your project has a “Gemfile” committed. A Gemfile with just this will work:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source 'https://rubygems.org' gem 'jekyll' </code></pre></div></div> <p><em>Optional:</em> Commit your “Gemfile.lock” to ensure the build uses the same setup as you have been using to develop the project. I usually .gitignore the “Gemfile.lock”, but if you want to keep the dependencies locked, you can commit it.</p> <p><em>Note:</em> some accounts may have GitHub Actions disabled by default. If you do not see the “Actions” tab in your repository’s navigation (in between “Discussions” and “Projects”), it will need to be turned on first. Visit the repository’s “Settings”, click on “Actions” in the left side nav menu, select “Allow all actions”, and click “Save”.</p> <h2 id="setup-action-yaml-using-pages">Setup Action YAML using Pages</h2> <p>To add a GitHub Action, you will be adding a YAML file describing the build steps to your project repository–you can do this automatically using GitHub’s suggested starter workflows from the Pages settings.</p> <ol> <li>On your project repository’s home page, click the “Settings” button (appears on the right along the tabs above the code area).</li> <li>On “Settings” page: click “Pages” in the left side menu.</li> <li>On the “Pages” page: under “Source”, click the dropdown and select “GitHub Actions”.</li> <li>Below the “Source” dropdown, a box will appear under “Use a suggested workflow” titled “Jekyll”. Click the “Configure” button.</li> <li>This will open an editor page creating a new file named “.github/workflows/jekyll.yml” populated with GitHub’s <a href="https://github.com/actions/starter-workflows/blob/main/pages/jekyll.yml">starter Jekyll workflow</a>. You can ignore the file and other options displayed on the right side, and just click the green “Start commit” button.</li> <li>Fill in the commit message as usual and click the green “Commit new file” button.</li> </ol> <p>Committing the action file to your repository will start the build process. It may take a few minutes for the action to complete. You can monitor the progress by looking at the status icon displayed next to your most recent commit message or by checking the “Actions” tab of your repository.</p> <p>Once the action successfully completes a green checkmark will appear and your site will be live. To find the URL you can visit “Settings” &gt; “Pages”.</p> <p>Going forward, each time you push or directly commit to the repository, the action will rebuild the site.</p> <p>The green checkmark will appear next to the most recent commit that triggered a successful build. If a red “X” appears next to your commit, the build failed and your updates will not be deployed–the last working version of the site will still be live. Visit the Actions tab to see detailed information about the error to help debug the issue.</p> Tue, 10 Jan 2023 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/github-actions3.html https://evanwill.github.io/_drafts/notes/github-actions3.html Marshmallow Wreaths Recipe <p>My favorite Yuletime treat is marshmallow wreaths–crisp cereal embedded in sumptuous green marshmallow goo, lovingly formed into circles and adorned with red candies. Somehow, they are richer (and of course much more festive) than regular rice crispy treats.</p> <h2 id="ingredients">Ingredients</h2> <ul> <li>1/2 c. (115g) butter</li> <li>4 c. (200g) marshmallows</li> <li>1/2 tsp (3ml) vanilla</li> <li>4 c. (190g) cereal (corn flakes, rice crispy, or whatever)</li> <li>1 tsp (5ml) green food coloring</li> <li>Cinnamon Imperials / red hots (little red candies for decoration)</li> </ul> <h2 id="preparation">Preparation</h2> <ol> <li>Add butter and marshmallows to a large glass bowl.</li> <li>Microwave in 30 second increments until fully melted, stirring occasionally.</li> <li>Add vanilla and food coloring, and mix well (should be <em>extremely</em> green for maximum festiveness).</li> <li>Add cereal and mix furiously (as your mixture is probably getting very sticky).</li> <li>Painstakingly form into circular wreath shapes on wax paper or greased pan.</li> <li>While still sticky, decorate each with three red hots to make pretty.</li> </ol> <h2 id="notes">Notes</h2> <p>I first tried to reproduce these on my own while living in Scotland. I translated the american style measurements (cups, tea spoons, etc) into UK style metric, and found some delicious artisan marshmallows made with natural pork gelatin. I soon discovered it was rather hard and far too tedious to reproduce the wreath shapes. However, my research confirms that they are equally delicious no matter what they look like… (for example, in 2009 my efforts resulted in a large red blob, which I served to Scottish people claiming it was a famous american delicacy and received positive reviews.)</p> <p>I have converted the ingredients back to american style measurements–metric is provided in parenthesis in case you bring this heirloom recipe with you in your world travels.</p> Tue, 06 Dec 2022 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/wreaths.html https://evanwill.github.io/_drafts/notes/wreaths.html RAWGraphs and browser-based apps <blockquote> <p>Data Hub Tool Talk: RAWGraphs is a browser-based app for quick data visualization. With extensive help built in, this is a great tool for teaching, learning, and experimenting with charts. This session will introduce the tool, along with tips for working with data on the web and other browser-based apps. <a href="https://youtu.be/A1iQb00FjUU">talk recording</a></p> </blockquote> <h2 id="rawgraphs-intro">RAWGraphs intro</h2> <p><a href="https://www.rawgraphs.io/">https://www.rawgraphs.io/</a></p> <p>RAWGraphs is a free, <a href="https://github.com/rawgraphs/rawgraphs-app">open source</a>, browser-based data visualization app.</p> <p>There are a lot of <em>free-ish</em> web-based data viz tools, e.g.</p> <ul> <li><a href="https://developers.google.com/chart">Google Charts</a> (integrated with Sheets)</li> <li><a href="https://flourish.studio/">Florish</a> (data storytelling)</li> <li><a href="https://www.datawrapper.de/">Datawrapper</a> (embeddable visualizations)</li> <li><a href="https://public.tableau.com/app/discover">Tableau Public</a> (free hosted version of famous business analytics software)</li> </ul> <p>However, each of these tools are proprietary and server-based services. You need to send your data to their servers where the processing is done and your visualizations are hosted.</p> <p>RAWGraphs is different –&gt; it is a client-side JavaScript app, meaning that all the processing is done on your computer, in your browser. It works on any computer without installing anything. You don’t send any data to their server. They also don’t host your data or visualizations.</p> <p>Instead RAWGraphs focuses in on being a pragmatic visual tool to efficiently move from a spreadsheet to a vector graphic visualization. Most often you would do some data wrangling (with Sheets, Excel, LibreOffice, <a href="https://openrefine.org/">OpenRefine</a>) before using RAWGraphs, and maybe some vector editing after exporting your visualization (with <a href="https://inkscape.org/">Inkscape</a>).</p> <p>Early versions built on the svg visualization library <a href="https://d3js.org/">D3.js</a>. Part of what was cool about D3 was there was a gallery of examples with the code directly available to edit, copy, and repurpose with your own data (now closely integrated with <a href="https://observablehq.com/">Observable</a>, JS browser-based code notebooks; for example of older style, see <a href="https://nvd3.org/livecode/index.html">NVD3 live code</a>). These examples make a clear connection of learning by experimenting and re-using templates. However, D3 has a steep learning curve, and you can’t just smoothly explore your data via a variety of visualizations.</p> <p>As a code free alternative, RAWGraphs uses the power of JS to provide a simple-ish visual interface to create and configure data visualizations in the browser. The goal is to get you to a solid SVG export that can then be tweaked for publication and sharing.</p> <p>It is a great tool for prototyping, quick exploration, and teaching/learning. For example, provide your students a link to RAWGraphs plus a link to a CSV, and have them learn about steps to a visualization–without installing anything or leaving the browser. Each chart type has a description and related tutorial, so there is a ton of learning built directly into the interface.</p> <p>Walkthrough <a href="https://app.rawgraphs.io/">RAWGraphs app</a>:</p> <ol> <li>“Try our data samples” &gt; Iris flowers. Check parsing options and <a href="https://www.rawgraphs.io/learning/how-to-stack-your-unstacked-data-or-meet-the-unpivoter">stacking transformation utility</a>.</li> <li>select “Convex hull” (check description and tutorial)</li> <li>map length to X, width to Y, Species to Groups</li> <li>customize</li> <li>Export as SVG</li> </ol> <h2 id="data-on-the-web">Data on the web</h2> <p>When trying to load data from the web you may encounter <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS">CORS</a> errors. Browsers will not directly load files from a different domain than the page’s home domain for security reasons. However, servers can implement a CORS-enabled policy that allows cross-domain sharing–so you will have to put your data somewhere that is configured for sharing!</p> <p>Here is some good options:</p> <ul> <li>Publish a Google Sheet as CSV –&gt; On the Sheet, go to File &gt; Publish to the Web. On the popup modal, use the dropdowns in “Link” tab to select the sheet name of your metadata (usually “Sheet 1”) and “Comma-separated values (.csv)” options, then click “Publish” button. Copy the link that is provided.</li> <li>Publish on GitHub –&gt; put your data in a repository, then use the “raw” link provided. It follows the pattern: “https://raw.githubusercontent.com/username/repositoryname/branchname/filename”</li> <li>Publish on GitHub Gist –&gt; create a new Gist, paste or drag your data in, make sure you provide a correct filename. Use the “raw” link. It follows the pattern: “https://gist.githubusercontent.com/username/hash/raw/hash/filename”</li> <li>Handy note: GitHub will preview render geojson on a map!</li> </ul> <h2 id="other-client-side-apps">Other client-side apps</h2> <ul> <li><a href="https://kepler.gl/">Kepler.gl</a> (geospatial tool that can export a static web app)</li> <li><a href="https://mapshaper.org/">mapshaper</a> (utility for manipulating geospatial data, helpful for transforming geojason. <a href="https://github.com/mbloch/mapshaper">mapshaper source code</a>)</li> <li><a href="https://lite.datasette.io/">Datasette-lite</a> (data exploration tool <a href="https://datasette.io/">Datasette</a> running in locally in your browser using webassembly)</li> <li><a href="https://www.koia.io/intro/index.html">Koia</a> (more complicated viz tool)</li> <li><a href="https://vega.github.io/">Vega</a> language ecosystem with online tools <a href="https://idl.cs.washington.edu/projects/lyra/app/">Lyra</a> and <a href="https://vega.github.io/voyager">Voyager</a> (steeper learning curve)</li> <li><a href="https://starboard.gg/">Starboard</a> (beta in-browser static/server-less notebook. Can also run Python Jupyter notebooks using <a href="https://github.com/pyodide/pyodide">Pyodide</a>, demo <a href="https://pyodide.org/en/stable/console.html">python REPL</a>)</li> <li><a href="https://flowchart.fun/">flowchart creator</a></li> <li><a href="https://jsonvisio.com/">jsonvisio</a> (visual json editor)</li> <li><a href="https://dillinger.io/">Dillinger</a> (markdown editor)</li> <li><a href="https://squoosh.app/">Squoosh</a> (image optimizer utility)</li> <li><a href="https://www.photopea.com/">Photopea</a> (full image editor, plus basic vector editing)</li> <li>Weird text utilities: <a href="https://plaintextformat.com/">Plain Text Format</a>, <a href="https://gchq.github.io/CyberChef/">CyberChef</a>, <a href="https://jhy.io/tools/convert-word-to-plain-text">Word-cleaning</a></li> </ul> <h2 id="data-viz-resources">Data viz resources</h2> <ul> <li><a href="https://www.data-to-viz.com/">From Data to Viz</a></li> <li><a href="https://r-graph-gallery.com/index.html">R Graph Gallery</a></li> <li><a href="https://www.python-graph-gallery.com/">Python Graph Gallery</a></li> <li><a href="https://datavizcatalogue.com/">Data Viz Catalogue</a></li> <li><a href="https://github.com/Quartz/bad-data-guide">bad data guide</a></li> <li><a href="http://projects.susielu.com/viz-palette">viz palette</a> (<a href="https://medium.com/@Elijah_Meeks/viz-palette-for-data-visualization-color-8e678d996077">article</a>)</li> </ul> Tue, 29 Nov 2022 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/rawgraphs.html https://evanwill.github.io/_drafts/notes/rawgraphs.html Issues Switching NVIDIA mode on Ubuntu <p>Ubuntu supports NVIDIA graphics cards out of the box with a proprietary driver that allows you to switch between different modes on your laptop for battery life, called “PRIME profiles”:</p> <ul> <li>nvidia (nvidia gpu always on high performance mode)</li> <li>on-demand (turn on nvidia for select tasks only)</li> <li>intel (use only builtin gpu for power saving)</li> </ul> <p>Any change in profile requires a restart.</p> <p><a href="https://pop.system76.com/">Pop!_OS</a> does a good job of integrating switching modes directly in the tool bar, but Ubuntu doesn’t offer that option out of the box. In general, switching profiles is possible using the “NVIDIA X Server Settings” application, which also gives you lots of details about your graphics card when in NVIDIA modes. However, I find that the NVIDIA settings app can switch from intel into nvidia modes, but <em>not back to intel mode</em>…</p> <p>So as an alternative that always works, you can use the command line tool <code class="language-plaintext highlighter-rouge">prime-select</code> to switch profiles. Use <code class="language-plaintext highlighter-rouge">prime-select -h</code> to list the options:</p> <ul> <li>To check the profile currently in use, <code class="language-plaintext highlighter-rouge">prime-select query</code>.</li> <li>To switch to a different profile, use <code class="language-plaintext highlighter-rouge">sudo prime-select intel</code> (with either <code class="language-plaintext highlighter-rouge">nvidia</code>, <code class="language-plaintext highlighter-rouge">intel</code>, or <code class="language-plaintext highlighter-rouge">on-demand</code> option). Then restart your system!</li> </ul> Tue, 22 Nov 2022 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu-prime.html https://evanwill.github.io/_drafts/notes/ubuntu-prime.html Baritone Ukulele stings <p>Finding strings you like on your ukulele is surprisingly complicated. It is a very personal choice, depending on your ukulele, the sound and feel you like, and your playing style. And it’s hard to find advice (its all conflicting forum-post rant style garbage).</p> <p>I enjoyed reading this ongoing strings journal <a href="https://baritoneukes.com/choosing-strings-for-baritone-ukuleles/">“Best Strings for Baritone Uke: A Three-Year Experiment”</a>. So thought I would do something similar for myself. As most of this blog, this is mainly notes to my future self!</p> <blockquote> <p>p.s. I find this <a href="https://content.westmusic.com/blog-how-to-replace-ukulele-strings/">west music how to replace strings</a> helpful for knot diagrams.</p> </blockquote> <h2 id="baritone-ukulele-context">Baritone Ukulele Context</h2> <p>I’m a intermediate beginner, not particularly good. I pick and strum, but really just like to strum out campfire jams. I play DGBE, low D. I have two cheaper end baritones:</p> <ul> <li>Kala Satin Mahogany Baritone <a href="https://kalabrand.com/products/ka-b">KA-B</a> (<a href="https://web.archive.org/web/20220519070825/https://kalabrand.com/products/ka-b">archived</a>) - traditional, standard cheap baritone with a nice rich tone.</li> <li>Ohana Solid Spruce &amp; Round Composite Back Baritone <a href="https://ohana-music.com/products/ohana-ukuleles-ck-70rb-solid-spruce-round-composite-back-concert?variant=31535720136804">BK-70RB</a> (<a href="https://web.archive.org/web/20220411072715/https://ohana-music.com/products/ohana-ukuleles-ck-70rb-solid-spruce-round-composite-back-concert?variant=31535720136804">archived</a>) - slightly larger, slightly more guitar-y sound, crisp distinct tones. low action set up. I really like this weird, unique sounding uke!</li> </ul> <p>I have purchased most strings from <a href="https://www.stringsbymail.com/ukulele-strings-684/baritone-ukulele-strings-3214/">Strings by Mail</a>, except <a href="https://www.etsy.com/shop/UkeLogic">Uke Logic on Etsy</a>.</p> <h2 id="strings-i-have-tried">Strings I Have Tried</h2> <p>When I get ready to change strings, I record a video sound check of myself with a few chords and picking greensleeves on the old strings. Once the new strings are fully settled in, I record the same thing. This gives me a chance to listen to the differences. All the strings have been <em>very</em> different, and also distinct on each ukulele. It is hard to characterize without an extensive music vocabulary, but these are my impressions.</p> <p>Organized from favorite to least favorite.</p> <h3 id="uke-logic-baritone-soft-tension">Uke Logic Baritone “Soft Tension”</h3> <p>These are my current favorite strings! They sound wonderful and seem extra playable.</p> <p>I choose the “pink” version, which is just cosmetic, a very light pink tint to the clear fluorocarbon strings–but looks nice, interesting at least. For low D you have a choice of fluorocarbon or gold smooth wound–so far I have only used the fluorocarbon with this set (I did use the gold wound in the “Hard Tension” version, and it is a beautiful string!). The fluorocarbon D is a reasonable thickness and the feel seems reasonably balanced with the other strings. All strings easily fit standard nut.</p> <p>On BK-70RB:</p> <p>Crisp and clear, ring out beautifully with a rich sound. Pleasant medium tension, similar to PhD (no buzz on low action), but seem easier to play.</p> <p>After playing on the “hard” version, these seem light and airy–buttery smooth and easy to play, the sound just seems to jump out. Compared to the “hard” they seem to have more sustain. The “hard” have a bit more unique sound, but I love the playability of these strings, and they sound great.</p> <p>On K-B:</p> <p>Immediately after restringing, the sound was a revelation! They sound really good, feel really good. Seemed to settle in quickly.</p> <table> <tbody> <tr> <td>String</td> <td>Material</td> <td>Diameter (mm)</td> </tr> <tr> <td>E</td> <td>Pink Fluorocarbon</td> <td>0.508</td> </tr> <tr> <td>B</td> <td>Pink Fluorocarbon</td> <td>0.635</td> </tr> <tr> <td>G</td> <td>Pink Fluorocarbon</td> <td>0.813</td> </tr> <tr> <td>D</td> <td>Pink Fluorocarbon</td> <td>0.914</td> </tr> </tbody> </table> <h3 id="uke-logic-baritone-hard-tension">Uke Logic Baritone “Hard Tension”</h3> <p>On BK-70RB:</p> <p>Seemed to settle in quickly. Good volume and sustain. Full, rich tone, mellower than other bright flourocarbon, but still has that crispness.</p> <p>The gold wound string is smooth, seems very stiff and heavy when installing, but feels good and balanced with other strings when playing. It seems to have a real strong, driving sound giving body to chords without overpowering. This wound string has <em>very</em> good durability–it was still sounding and looking good when I switched out the fluorocarbon strings for being a bit worn out.</p> <p>The tension <em>is</em> noticeably “hard” compared to other strings. You can really play them hard, dig into the strumming–but I didn’t realize until switching back to “soft” strings that it is more work to actually play these.</p> <p>I really like the sound and feel of these strings. They seem unique.</p> <table> <tbody> <tr> <td>String</td> <td>Material</td> <td>Diameter (mm)</td> </tr> <tr> <td>E</td> <td>Pink Fluorocarbon</td> <td>0.584</td> </tr> <tr> <td>B</td> <td>Pink Fluorocarbon</td> <td>0.711</td> </tr> <tr> <td>G</td> <td>Pink Fluorocarbon</td> <td>0.914</td> </tr> <tr> <td>D</td> <td>Gold smooth wound</td> <td>0.762</td> </tr> </tbody> </table> <p>There is an option for D Flourocarbon at 1.06mm. This seemed too big for my nut, so I didn’t try it.</p> <h3 id="phd-strings---premium-high-density">PhD Strings - Premium High Density</h3> <p>On KA-B:</p> <p>After using the stretchy Worth Browns, these felt a much nicer balanced tension. They seem to have a full bright tone, with strong sustain and volume. They feel good on fingers, smooth.</p> <p>PhD doesn’t publish diameters anywhere I could find. The G string seems thicker than other sets, enough to stick in the nut, requiring some extra attention to tune.</p> <p>Material is “PVDF”, some sort of fluorocarbon.</p> <h3 id="worth-brown">Worth Brown</h3> <p>On KA-B:</p> <p>Nice rich, mild sound. Seemed to make the KA-B’s tone crisper and louder than Aquilas.</p> <p>They have an oddly low tension, or sort of stretchiness, that I didn’t really like. They took forever to settle in and stay in tune.</p> <table> <tbody> <tr> <td>String</td> <td>Material</td> <td>Diameter (mm)</td> </tr> <tr> <td>E</td> <td>Brown Fluorocarbon</td> <td>0.620</td> </tr> <tr> <td>B</td> <td>Brown Fluorocarbon</td> <td>0.739</td> </tr> <tr> <td>G</td> <td>Brown Fluorocarbon</td> <td>0.810</td> </tr> <tr> <td>D</td> <td>Brown Fluorocarbon</td> <td>0.909</td> </tr> </tbody> </table> <p>Lots of people repeat that Worth brown and clear are the same–that doesn’t seem true, Worth intends them to have different sound qualities, not just looks.</p> <h3 id="aquila-nylgut">Aquila Nylgut</h3> <p>Came as stock on both my Baritones (which is very common).</p> <p>On KA-B:</p> <p>They sounded okay, nothing particularly noteworthy–flourocarbon strings sound much crisper in comparison. However, I wore out the wound strings very rapidly, leaving cuts at each fret, so I had to change them out soon. Much prefer the durability of fluorocarbon.</p> <p>On BK-70RB:</p> <p>They sounded very crisp, <em>very</em> loud, powerful, a bit jangley like a guitar–I liked the sound a lot. There seemed to be wider dynamics possible compared to other strings. The nylgut strings feel uniquely crispy and responsive. They occasionally had a buzz on the wound strings–not enough tension on low action. However, I hated the feel on the BK-70RB–the wound strings feel very different from the nylgut, and the tensions are so inconsistent. It bothered me enough to change them before wearing them out.</p> <table> <tbody> <tr> <td>String</td> <td>Material</td> <td>Diameter (mm)</td> </tr> <tr> <td>E</td> <td>nylgut</td> <td>0.67</td> </tr> <tr> <td>B</td> <td>nylgut</td> <td>0.84</td> </tr> <tr> <td>G</td> <td>wound</td> <td>0.60</td> </tr> <tr> <td>D</td> <td>wound</td> <td>0.70</td> </tr> </tbody> </table> <p>I am intrigued by other unique Aquila strings (Sugar and Red), but since they all come with the same two wound lower strings there doesn’t seem like much point to trying them out–not enough durability.</p> <h3 id="oasis-fluorocarbon-uke-baritone-uke-8200b">Oasis Fluorocarbon Uke Baritone UKE-8200B</h3> <p>Strings come as double length size, so each pack is really two sets, meaning these are actually the cheapest strings I have tried.</p> <p>On BK-70RB:</p> <p>First impression was the tone sounds nice, clear, and distinct. However, I noticed a serious loss of volume and sustain. The surface has an odd grippiness, which feels fine–but when I play creates terrible squichy sounds from my fingers–it drove me crazy. I also had a buzz on the G string, I guess due to lower tension on low action.</p> <p>After playing these for two weeks I hated them. They felt sort of dead. Bad.</p> <table> <tbody> <tr> <td>String</td> <td>Material</td> <td>Diameter (mm)</td> </tr> <tr> <td>E</td> <td>Fluorocarbon</td> <td>0.620</td> </tr> <tr> <td>B</td> <td>Fluorocarbon</td> <td>0.739</td> </tr> <tr> <td>G</td> <td>Fluorocarbon</td> <td>0.800</td> </tr> <tr> <td>D</td> <td>Fluorocarbon</td> <td>0.909</td> </tr> </tbody> </table> <h2 id="string-diameter-table">String Diameter table</h2> <div id="archiveList" class="archive-list"> <div class="browse"> <input class="search" placeholder=" Search" type="text" aria-label="Search strings" /> </div> <table> <thead> <tr> <th><button class="buttons sort" data-sort="brand">Brand</button></th> <th><button class="buttons sort" data-sort="string">String</button></th> <th><button class="buttons sort" data-sort="material">Material</button></th> <th><button class="buttons sort" data-sort="diameter">Diameter</button></th> </tr> </thead> <tbody class="listjs"> <tr> <td class="brand">Uke Logic Baritone Hard</td> <td class="string">E</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.584</td> </tr><tr> <td class="brand">Uke Logic Baritone Hard</td> <td class="string">B</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.711</td> </tr><tr> <td class="brand">Uke Logic Baritone Hard</td> <td class="string">G</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.914</td> </tr><tr> <td class="brand">Uke Logic Baritone Hard</td> <td class="string">D</td> <td class="material">Gold smooth wound</td> <td class="diameter">0.762</td> </tr><tr> <td class="brand">Uke Logic Baritone Soft</td> <td class="string">E</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.508</td> </tr><tr> <td class="brand">Uke Logic Baritone Soft</td> <td class="string">B</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.635</td> </tr><tr> <td class="brand">Uke Logic Baritone Soft</td> <td class="string">G</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.813</td> </tr><tr> <td class="brand">Uke Logic Baritone Soft</td> <td class="string">D</td> <td class="material">Pink Fluorocarbon</td> <td class="diameter">0.914</td> </tr><tr> <td class="brand">PhD Strings</td> <td class="string">*</td> <td class="material">PVDF fluorocarbon</td> <td class="diameter">none given </td> </tr><tr> <td class="brand">Worth Brown</td> <td class="string">E</td> <td class="material">Brown Fluorocarbon</td> <td class="diameter">0.620</td> </tr><tr> <td class="brand">Worth Brown</td> <td class="string">B</td> <td class="material">Brown Fluorocarbon</td> <td class="diameter">0.739</td> </tr><tr> <td class="brand">Worth Brown</td> <td class="string">G</td> <td class="material">Brown Fluorocarbon</td> <td class="diameter">0.810</td> </tr><tr> <td class="brand">Worth Brown</td> <td class="string">D</td> <td class="material">Brown Fluorocarbon</td> <td class="diameter">0.909</td> </tr><tr> <td class="brand">Aquila Nylgut</td> <td class="string">E</td> <td class="material">nylgut</td> <td class="diameter">0.67</td> </tr><tr> <td class="brand">Aquila Nylgut</td> <td class="string">B</td> <td class="material">nylgut</td> <td class="diameter">0.84</td> </tr><tr> <td class="brand">Aquila Nylgut</td> <td class="string">G</td> <td class="material">wound</td> <td class="diameter">0.60</td> </tr><tr> <td class="brand">Aquila Nylgut</td> <td class="string">D</td> <td class="material">wound</td> <td class="diameter">0.70</td> </tr><tr> <td class="brand">Oasis Fluorocarbon UKE-8200B</td> <td class="string">E</td> <td class="material">Fluorocarbon</td> <td class="diameter">0.620</td> </tr><tr> <td class="brand">Oasis Fluorocarbon UKE-8200B</td> <td class="string">B</td> <td class="material">Fluorocarbon</td> <td class="diameter">0.739</td> </tr><tr> <td class="brand">Oasis Fluorocarbon UKE-8200B</td> <td class="string">G</td> <td class="material">Fluorocarbon</td> <td class="diameter">0.800</td> </tr><tr> <td class="brand">Oasis Fluorocarbon UKE-8200B</td> <td class="string">D</td> <td class="material">Fluorocarbon</td> <td class="diameter">0.909</td> </tr> </tbody> </table> </div> <!-- add list.js http://www.listjs.com/ @javve --> <script src="/_drafts/js/list.min.js"></script> <script> var options = { valueNames: [ 'brand', 'string', 'material', 'diameter' ], listClass: 'listjs' }; var userList = new List('archiveList', options); </script> Fri, 01 Apr 2022 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ukulele-strings.html https://evanwill.github.io/_drafts/notes/ukulele-strings.html Paged.js for HTML to PDF <p><a href="https://pagedjs.org/">Paged.js</a> is a javascript library to create high quality print layouts from your HTML content. It is designed to be part of a new content to print workflow that cuts out all the messing around with clunky word processors, layout design, and desktop publishing software. There are some <a href="https://pagedjs.org/made-with-paged.js.html">amazing examples</a> of print books created using it. Also check out this demo using <a href="https://s3.amazonaws.com/pagedmedia/pagedjs/examples/polyfill.html">Aurorae</a> (text from Project Gutenberg).</p> <p>I think this has a lot of potential for creating open educational resources in static web workflows.</p> <p>OER tools often want to use Markdown content to output both a website and PDF version. Currently, that generally involves using <a href="https://evanwill.github.io/_drafts/notes/pandoc.html">Pandoc plus LaTeX to create PDFs</a> at some point. This is limiting because controlling the layout of HTML processed through Pandoc is difficult, as well as adding extra software for users to install.</p> <p>To use paged.js integrated into a static web workflow we don’t need to install anything else. We simply gather all the content on one HTML page, add the library and some custom print CSS, and then view the output in the browser. You can use dev tools to tweak the CSS to get instant feedback on your changes. Then print using the browser’s native print functionality.</p> <blockquote> <p><em>Note:</em> the fully features only seem supported in Chrome browser, and Chrome’s builtin PDF printing seems a bit better. Paged.js calls the library a “polyfill” because it is implementing the CSS “Paged Media” standards that aren’t currently supported by browsers.</p> </blockquote> <h2 id="aladore-test">Aladore Test</h2> <p>To play around with the possibilities, I created a print version of Aladore on my <code class="language-plaintext highlighter-rouge">aladore-book</code> project. <code class="language-plaintext highlighter-rouge">aladore-book</code> is an edited version of a public domain novel, with each chapter contained in a Markdown stub, that is generated into a website using Jekyll. Using Liquid in Jekyll, I also set up a variety of data derivatives and text outputs made available on the <a href="https://evanwill.github.io/aladore-book/data/">Aladore Data page</a>.</p> <p>Starting from the <a href="https://evanwill.github.io/aladore-book/data/newbolt_aladore_1914.html">minimal HTML full text version</a>, I added the full CSS used by the main website version, the <a href="https://gitlab.coko.foundation/pagedjs/pagedjs/-/blob/main/examples/assets/styles/preview.css">“preview” CSS provided by pagedjs</a>, plus a handful of custom print styles:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;link rel="stylesheet" href="/aladore-book/assets/css/main.css"&gt; &lt;link rel="stylesheet" href="/aladore-book/assets/pagedjs/preview.css"&gt; &lt;style&gt; /* page basics */ @page { size: letter; margin: 1.5in 1.5in; } /* chapter page set up */ @page chapter { /* add page number at bottom */ @bottom-center { content: counter(page); } /* add title header */ @top-center { content: "Aladore"; } } /* start page numbers from first chapter */ #chapter01 { counter-reset: page 1; } /* set up page breaks */ .frontmatter-pages { break-before: right; } .chapter-pages { page: chapter; break-before: page; margin-top: 8em; } /* keep figures on page alone */ figure { max-width: 100%; max-height: 100%; break-before: page; break-after: page; } &lt;/style&gt; </code></pre></div></div> <blockquote> <p><em>Note:</em> using inline comments <code class="language-plaintext highlighter-rouge">//</code> seemed to mess up Paged.js parsing.</p> </blockquote> <p>At the bottom of the page, we add the <a href="https://unpkg.com/pagedjs/dist/paged.polyfill.js">paged.js “polyfill”</a>:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;script src="/aladore-book/assets/pagedjs/paged.polyfill.js"&gt;&lt;/script&gt; </code></pre></div></div> <p>This gets us to the <a href="https://evanwill.github.io/aladore-book/data/newbolt_aladore_1914_print.html">Aladore full text for print version</a>. Open the page in Chrome browser, use the browser “print” option, and “save as PDF”.</p> Sat, 05 Feb 2022 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pagedjs.html https://evanwill.github.io/_drafts/notes/pagedjs.html Getting Started with Raspberry Pi <blockquote> <p>Curious about Raspberry Pi and other single board computers? This session will introduce everything you need to know to get started, from burning an SD card to Linux basics. Single board computers can be used to power research projects, host a local media server, or just play video games–so join us to learn about all the interesting things you can do with a Pi!</p> </blockquote> <h2 id="what-is-raspberry-pi">What is Raspberry Pi?</h2> <p>Raspberry Pi is a <em>very</em> popular family of single board computers (SBCs) designed to be simple, flexible, affordable, and educational. Basically, it is just a minimal computer with everything contained on a small circuit board.</p> <p>It isn’t much different than the insides of your laptop:</p> <ul> <li>Single board computer: 64-bit CPU, 512MB - 4GB RAM, graphics card</li> <li>Connect: USB, Ethernet, Wifi, Bluetooth</li> <li>Output: Video (HDMI), audio (HDMI, 3.5mm jack), <a href="https://www.raspberrypi.com/documentation/computers/os.html#gpio-and-the-40-pin-header">GPIO pins</a></li> </ul> <p>However, this minimal form factor, and modular input and output options (such as GPIO pins) invite us to interact with it very differently from a standard laptop. Raspberry Pi is ready to act like a typical computer, or to power anything you can dream up! It is commonly used in education, prototyping new hardware, controlling unique science experiments, and powering hobbyist computing projects.</p> <p>There are other SBCs on the market, but Raspberry Pi has remained the most popular. Here are some reasons why:</p> <ul> <li>High <strong>quality build</strong> with stable form factor and specs. Wide adoption and stability improves the sustainability and interoperability of your projects.</li> <li>Large <strong>ecosystem</strong> of compatible “hats”, “bonnets”, and add ons. There are tons of vendors out there making things that work with Pi, which makes it easier to build your project!</li> <li>Well supported and maintained <strong>software</strong> and Linux operating system. Many SBCs rely on community builds for software, which can be frustrating and unsustainable. An official Raspberry Pi OS is maintained by the foundation, and many Linux projects distribute official builds as well, providing a solid and reliable base for your project.</li> <li>Excellent <strong>documentation</strong>, both official and community projects. If something goes wrong or you need to figure out how to do something, there is usually help readily available.</li> <li>Extensive <strong>learning materials</strong> available, including many tutorials, courses, and teacher guides. Pi started as an educational initiative and retains that spirit. There is curriculum around learning the hardware, as well as learning more generalized concepts about computing, coding, linux, inventing, making, and more.</li> </ul> <blockquote> <p><a href="https://www.raspberrypi.com/">Raspberry Pi .com</a> is where you can shop for hardware, download software, find <a href="https://forums.raspberrypi.com/">forums</a> and read <a href="https://www.raspberrypi.com/documentation/">documentation</a>. The educational foundation maintains a separate site at <a href="https://www.raspberrypi.org/">Raspberry Pi .org</a> where you can find teaching and learning resources (not all Pi based), and research.</p> </blockquote> <h2 id="raspberry-pi-vs-arduino">Raspberry Pi vs. Arduino</h2> <p>Raspberry Pi is the most popular <strong>SBC</strong>, Arduino is the most popular <strong>microcontroller</strong>. Both are very flexible, with great documentation and community. Which one you need depends on your project!</p> <p>Arduino:</p> <ul> <li>Microcontroller board, 8-bit processor, tiny memory.</li> <li>Very simple, solid, reliable.</li> <li>Very low power consumption.</li> <li>Doesn’t have an operating system, it just runs your code, i.e. it does one thing really well!</li> <li>Generally programmed in C/C++ (not the easiest to learn), and require code to be compiled for flashing to the board.</li> </ul> <p>Raspberry Pi:</p> <ul> <li>Single board computer with full operating system.</li> <li>Having an operating system means you can do lots more stuff, like outputting to a monitor, running software, and using high-level programming languages (mainly Python).</li> <li>Relatively simple and reliable, but OS requires updates, might need restarting, etc.</li> <li>Consumes much more power than a microcontroller and requires steady power supply to avoid issues.</li> </ul> <blockquote> <p>A new ecosystem of microcontroller boards powered by <a href="https://micropython.org/">MicroPython</a> / <a href="https://circuitpython.org/">CircuitPython</a> is emerging which removes some of the barriers of the traditional Arduino programming. These are worth checking out if you want to use Python, or need a board slightly more powerful than Arduino but don’t need a full computer!</p> </blockquote> <h2 id="what-can-you-do-with-raspberry-pi">What Can You Do with Raspberry Pi?</h2> <ul> <li>Use it as a <a href="https://www.raspberrypi.com/products/raspberry-pi-400/">personal computer</a> running Linux.</li> <li>Set up a <a href="https://libreelec.tv/">media center</a> connected to your TV.</li> <li>Build a high end <a href="https://volumio.com/en/get-started/">audio player</a> controllable by your phone.</li> <li>Play games on dedicated <a href="https://retropie.org.uk/">emulator system</a>, <a href="https://www.adafruit.com/product/4334">cabinet</a>, or <a href="https://www.adafruit.com/product/3160">handheld</a>.</li> <li><a href="https://github.com/evanwill/poemBot">Print poems</a>?</li> </ul> <p>To get an idea of the range of projects out there, browse <a href="https://learn.adafruit.com/category/raspberry-pi">adafruit tutorials</a>, <a href="https://projects.raspberrypi.org/en/projects?hardware%5B%5D=raspberry-pi">Raspberry Pi Projects</a>, or <a href="https://hackaday.io/list/3424-raspberry-pi-projects">Hackaday</a>.</p> <hr /> <h1 id="getting-started">Getting Started</h1> <h2 id="hardware-raspberry-pi-starter-kit">Hardware: Raspberry Pi Starter Kit</h2> <p>What you need:</p> <ul> <li><a href="https://www.raspberrypi.com/products/"><strong>Pi SBC</strong></a> (see <a href="https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications">spec chart</a>). Most common models: <ul> <li>Raspberry Pi 3 Model B+ - the standard for projects for awhile.</li> <li>Raspberry Pi Zero 2 W - basically a Pi 3 in tiny form factor (and cheap price)! This is great if you need to fit your project into a small space. For general prototyping, Pi 3 might be easier to work with.</li> <li>Raspberry Pi 4 Model B - newest, most advanced and powerful option, but also uses more power, creates more heat, and costs more! You can get it with up to 8GB ram, making it very viable as a desktop computer.</li> <li>Although the specs vary, the models are mostly interchangeable, so the best choice may simply be the one that you have readily available.</li> </ul> </li> <li><strong>Power supply.</strong> Most Pi run off a micro USB charger, but you need a decent one! A rainbow icon shows up on screen if power goes low.</li> <li><strong>Micro SD card.</strong> This will be your Pi’s hard drive. Try to get decent quality, high read/write speed, “SDHC, Class 10 / UHS 3”, min 8GB. Low quality SDs are a common source of issues.</li> </ul> <p>You might want:</p> <ul> <li>HDMI cable to attach to monitor or TV.</li> <li>USB <a href="https://www.logitech.com/en-us/products/keyboards/k400-plus-touchpad-keyboard.920-007119.html">Keyboard</a>, mouse, or other input devices. Bluetooth also works once you get everything set up.</li> <li><a href="https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable/overview">Console cable</a> can be used for headless setup and prototyping.</li> <li><a href="https://www.adafruit.com/product/1988">Ribbon cable</a> + breadboard for circuit prototyping.</li> </ul> <h2 id="software-getting-an-operating-system">Software: Getting an Operating System</h2> <p>Many people take operating systems for granted since they come pre-installed on Windows and Apple computers–you don’t get any choices with these proprietary systems! Raspberry Pi does not come with an operating system or even a “hard drive” for it to load from. If you just plug it in, it can’t do anything–first you have to choose and install an operating system.</p> <p>Pi’s are designed for Linux, a family of open source operating systems used to run all kinds of computers, from servers to super computers. Check the <a href="https://evanwill.github.io/try-linux/">Try Linux workshop</a> for a general introduction and resources.</p> <p>Linux OS are usually provided as a downloadable disk image (sometimes called ISO), that can be burned onto a SD card. The basic steps for Pi:</p> <ul> <li>Choose and download an OS image.</li> <li>Burn the image onto a SD card. (Keep in mind this is <strong>not</strong> the same as copying the files over!)</li> <li>Insert SD into Pi.</li> <li>Plug in the Pi to boot up! (Pi’s don’t have power buttons…)</li> </ul> <p>The easiest way to complete these steps is using the “Raspberry Pi Imager” app. Imager will download select OS images, burn SDs, and provide other helpful utilities (such as reformating SDs). Visit the <a href="https://www.raspberrypi.com/software/">Raspberry Pi Software page</a>, download Imager for your computer, and install.</p> <p>For detailed instructions see <a href="https://www.raspberrypi.com/documentation/computers/getting-started.html">Pi Getting Started</a>, for the <a href="https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up">official step-by-step guide</a> for a visual walk through.</p> <blockquote> <p>Just keep in mind, once you burn an image, Windows won’t be able to read or use the SD. You can use Pi Imager to “Erase” the SD to restore it to normal.</p> <p>You don’t have to use Imager! The <a href="https://www.raspberrypi.com/software/operating-systems/">official images</a> or other ISOs can be downloaded manually, then burnt the SD using any disk imaging software, such as <a href="https://www.balena.io/etcher/">Etcher</a>. Check <a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">burn ISO note</a> for details.</p> </blockquote> <h3 id="choosing-an-os">Choosing an OS</h3> <p>Which operating system you choose depends on your use case. For the officially supported Pi OS you have two main choices:</p> <ul> <li>“Raspberry Pi OS with desktop” - is the generally recommended version. It is compatible with all Pi versions. The “desktop” is the visual interface you are familiar with on Windows or Mac. This is the default choice on Imager.</li> <li>“Raspberry Pi OS Lite” - does not come with a desktop. This is a good option for <em>headless</em> projects or servers where you don’t need to use a visual interface.</li> </ul> <p>Each version also comes in 32-bit or 64-bit editions. The 32-bit versions are compatible with all Pi models and are the default. On Pi 4, the 64-bit version may provide better performance and compatibility with newer software.</p> <p>In addition to the official Pi OS, many other Linux distributions provide images built for Raspberry Pi. Some of these are specialty OS, such as media servers or game consoles. Others are general purpose OS or servers from popular distros. Popular options include:</p> <ul> <li><a href="https://ubuntu.com/download/raspberry-pi">Ubuntu</a>, one of the most popular Linux distributions for desktop and servers, so may simplify some projects or be familiar. Desktop version only runs on Pi 4.</li> <li><a href="https://libreelec.tv/">LibreElec</a>, a minimal OS designed to run as a media center on your TV.</li> <li><a href="https://retropie.org.uk/">RetroPie</a>, a minimal OS designed to run game emulators on your TV.</li> </ul> <blockquote> <p>The confusingly named “Raspberry Pi Desktop for PC and Mac” is simply an image of the OS built for normal laptop architecture. This gives you the option to run “Raspberry Pi OS” on a non-Pi computer–but you might want to check out other <a href="https://evanwill.github.io/try-linux/content/5-resources.html#major-distro-families">distros</a>! Raspberry Pi OS is based on <a href="https://www.debian.org/">Debian Linux</a>.</p> </blockquote> <h2 id="boot-up">Boot Up!</h2> <p>Once you SD is burnt:</p> <ul> <li>Insert SD into your Pi.</li> <li>Plug in any peripherals, such as HDMI to a monitor/tv and a USB keyboard.</li> <li>Plug in your Pi power supply.</li> <li>Wait for it to boot!</li> </ul> <p>You will see a bunch of text flash past on the screen–that is okay and normal. Eventually you will get to the desktop and you can start using your new Linux computer!</p> <p>Check the <a href="https://www.raspberrypi.com/documentation/computers/os.html">official OS docs</a> for lots of details.</p> <p>Even for headless projects, it is often easiest to start with your Pi plugged into a monitor for initial set up. If your OS does not come with a desktop, you will see the text terminal interface. Alternatively, you can use a <a href="https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable/overview">console cable</a> or SSH into your Pi for <a href="https://www.raspberrypi.com/documentation/computers/remote-access.html#introduction-to-remote-access">remote access</a>.</p> Thu, 03 Feb 2022 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/rpi-intro2.html https://evanwill.github.io/_drafts/notes/rpi-intro2.html Git Command-line Tokens <p>Most git repository hosts have changed authentications methods in the last few years to increase account security. Rather than using your account password to authenticate for push/pull on the command line, you will need a special token or app password set up.</p> <h2 id="github-tokens">GitHub Tokens</h2> <p>GitHub requires using a <a href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token">“personal access token”</a> rather than your account password for command-line git commands <a href="https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/">since around Aug 2021</a>.</p> <p>On GitHub click your profile image in upper right, click Settings &gt; Developer settings &gt; Personal access tokens. Generate a new token, check off the “repo” level of access. Copy the token to secure password manager (treat it just like a password).</p> <p>When you authenticate on command-line, use username as normal, but paste in the token rather than your password.</p> <h2 id="bitbucket-app-passwords">Bitbucket App Passwords</h2> <p>Bitbucket requires using an <a href="https://support.atlassian.com/bitbucket-cloud/docs/app-passwords/">“app password”</a> rather than your account password for command-line git commands (see <a href="https://bitbucket.org/blog/deprecating-atlassian-account-password-for-bitbucket-api-and-git-activity">notice</a>).</p> <p>On Bitbucket click your profile image in lower left, click “Personal settings”, then “App passwords”. Create a new app password with the “Repository” level permissions checked (doesn’t need any of the other types of permission). Copy the password it provides (treat it just like any other password).</p> <p>When you authenticate on command-line, use username as normal, but paste in the app password rather than your account password.</p> <h2 id="update-credential-manager">Update Credential Manager</h2> <p>Git for Windows comes with git credential manager installed and configured, so your password/token is probably automatically stored (i.e. you don’t have to type your password in for every git operation). On Linux you can also <a href="/_drafts/notes/git-credential.html">set up a Git Credential Helper</a>.</p> <p>If you need to <strong>update</strong> your credentials to a new token/password, you will need to delete or update the values stored in your credential manager.</p> <p>On Windows look in Control Panel &gt; User Accounts &gt; Credential Manager &gt; Windows Credentials. Then under “Generic Credentials” &gt; Edit, look for the corresponding entry like “git:https://bitbucket.org”.</p> <p>On Linux the easiest method is to use GNOME “Passwords and Keys” (i.e. Seahorse), the GUI to use libsecret. Open “Passwords and Keys”, then look in Passwords &gt; Login category. You should find entries that correspond with the repo platforms (github.com or bitbucket.org etc). Double click the listing to open the properties. Either delete the old one (then provide updated version on next git operation on commandline)–or click in the password box, paste in the new token/password, then close the box (this will ask if you want to save).</p> Wed, 01 Dec 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-tokens.html https://evanwill.github.io/_drafts/notes/git-tokens.html Intro to HTML, SEO, and Analytics <blockquote> <p>workshop outline for writing for the web</p> </blockquote> <h2 id="html">HTML</h2> <p>Despite the slick interfaces and amazing websites out there today, everything that is displayed in your browser is made up of HTML, CSS, and JS.</p> <p>(i.e. the same components that made up the web since the beginning: <a href="https://web.archive.org/web/19970218140532/https://www.lib.uidaho.edu/">U of I Library website, Feb 1, 1997</a>)</p> <p>Yet, if you use a modern <a href="https://en.wikipedia.org/wiki/Content_management_system">Content Management System</a> such as WordPress, Drupal, SquareSpace, WIX, or Google Sites, you may have created entire sites without ever seeing HTML.</p> <p>CMS are “dynamic web” applications that provide a web-based administration interface to create and manage a website. Under the hood CMS consist of software that runs on a server (server-side processing) and a database to store information. When a user visits a web page (i.e. by clicking a link), their browser sends a request to the site server –&gt; the CMS interprets the request, retrieves the correct data and templates, and sends the user a response (i.e. HTML).</p> <p>So to better understand how the web works and what your CMS is doing, it is helpful to dive into the fundamentals of HTML.</p> <p>Lessons:</p> <ul> <li><a href="https://github.com/learn-static/foundations-1-html/blob/main/0-web.md">Intro to Web and URLs</a></li> <li><a href="https://github.com/learn-static/foundations-1-html/blob/main/1-html.md">Intro to HTML concepts</a></li> <li><a href="https://github.com/learn-static/foundations-1-html/blob/main/1-html.md">HTML Example</a></li> </ul> <h2 id="seo">SEO</h2> <p><a href="https://en.wikipedia.org/wiki/Search_engine_optimization">Search engine optimization</a> is a sort of mad science of how to get your site ranked higher in search indexes… In early 2000’s it was essentially spammy attempts to boost apparent relevance of pages by jamming them full of keywords. Search engines are some what smarter than that now, but keep the exact details of indexing workflows and algorithms secret to avoid sites trying to game the system.</p> <p>The basic idea is that search companies use “crawlers” to surf the web following links (since there isn’t some central directory of everything!) to collect content to index. These bots aren’t quite like human users and pay a lot more attention to the code than the visual elements we see.</p> <p><em>There is no magic SEO.</em> You can only follow the best practices to present your site in the best possible way, so that crawlers can find and correctly understand the content.</p> <p>The best way to do this is to have a well organized site with well structured pages–which will also benefit your human users! While many of the technical details should be handled by your CMS, as a web designer and web writer you will still make many choices that impact your SEO. To learn more details check the <a href="https://developers.google.com/search/docs/beginner/seo-starter-guide">Google SEO Starter Guide</a> and <a href="https://developers.google.com/search/docs/advanced/guidelines/webmaster-guidelines">Google Webmaster guidelines</a>.</p> <p>Things Google cares about when crawling and indexing:</p> <ul> <li>Mobile friendliness –&gt; use <a href="https://search.google.com/test/mobile-friendly">Mobile-Friendly Test</a> to ensure Google considers your pages mobile friendly.</li> <li>Page speed –&gt; use <a href="https://developers.google.com/speed/pagespeed/insights/">PageSpeed Insights</a> to see what Google crawlers think about your site performance.</li> <li>Well formed HTML with descriptive title and headings –&gt; remember those HTML fundamentals and view-source!</li> <li>Sensible link structures and good navigation links. Also sitemap XML can help.</li> <li>Structured markup such as <a href="https://schema.org/">Schema.org</a>. Example, view source of pages and items in <a href="https://www.lib.uidaho.edu/digital/barstock/">Barnard-Stockbridge digital collection</a>.</li> <li>Other sites link to your content.</li> <li>People click on your pages in search results –&gt; use <a href="https://search.google.com/search-console/about">Google Search Console</a> to see how your site content looks to Google and understand what searchers are pointing people to your site.</li> </ul> <h2 id="analytics">Analytics</h2> <p>Once you have a site, you often want to know if anyone is visiting it –&gt; or maybe who is using it and how they are using it! If you make changes to the navigation, features, or content, it can be helpful to have data to understand the impact of your updates. This is the value of site analytics.</p> <p>There is a few main types of use data available:</p> <ul> <li><strong>Server logs</strong> –&gt; your server records basic information based on requests sent to it. This data can be analysed to provide statistics about usage. The numbers are usually pretty accurate (it is impossible to block, but requests can fake the information). Example: logs in Reclaim host</li> <li><strong>CMS statics</strong> –&gt; most CMS platforms will have some analytics built into the system. This is often analyzing data similar to server logs, but can be more meaningful since the CMS can connect the requests with content. These are much easier to use and interpret since they are built into the CMS admin interface. Example: WordPress stats</li> <li><strong>JS analytics</strong> –&gt; to understand what a user actually does when they visit a page, it is necessary to use JavaScript loaded in their browser. The most widely used platform to do this is <a href="https://analytics.google.com/analytics/web">Google Analytics</a>, which track detailed information about visitors and interactions, providing enriched data about user groups. This type of analytics can be centralized across many related sites, doesn’t require access to a server, and can be used to track links from marketing campaigns. The disadvantage is that JS analytics libraries can be blocked by users, so may be becoming less accurate (see <a href="https://plausible.io/blog/google-analytics-adblockers-missing-data">Plausible post</a>), and they present privacy trade-offs to your users (i.e. handing over user data to Google). Example: Google Analytics</li> </ul> <p>It is important to understand that analytics numbers are <em>squishy</em> –&gt; they should be used to understand trends, make comparisons, and evaluate changes, not be taken as exact statistics.</p> <p>Notes:</p> <ul> <li><a href="https://support.google.com/analytics/answer/1008015?hl=en">Get started with Analytics</a> – current version is called “GA4”. Sign in using your Google account and set up a “property” for your website.</li> <li>Some hosted CMS platforms don’t allow you to add your own Analytics code when using a “free” tier account. E.g. <a href="https://wordpress.com/support/google-analytics/">WordPress.com requires paid account</a>.</li> <li>There are alternatives to Google Analytics! <a href="https://matomo.org/">Matomo</a> is largest open source full analytics platform that can be self hosted (free but need to maintain yourself) or paid hosting. However, there are many more alternatives popping up, with many focused on user privacy and simplicity (vs. the very complicated and heavy Google Analytics). Consider if you need all that user data at all–for many, stats built into CMS platforms is enough.</li> </ul> <h2 id="resources">Resources</h2> <p>Learning and reference:</p> <ul> <li><a href="https://www.w3schools.com/">w3schools</a></li> <li><a href="https://developer.mozilla.org/en-US/">MDN web docs</a></li> <li><a href="https://web.dev/learn">web.dev</a></li> </ul> <p>Accessibility:</p> <ul> <li><a href="https://www.usability.gov/what-and-why/accessibility.html">Usability.gov</a></li> <li><a href="https://www.accessibility-developer-guide.com/">Accessibility Developer Guide</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Common accessibility problems</a></li> </ul> <p>Freely licensed images:</p> <ul> <li><a href="https://unsplash.com/">Unsplash</a></li> <li><a href="https://www.flickr.com/commons">Flickr Commons</a></li> <li><a href="https://www.pexels.com/">PEXELS</a></li> <li>Optimize your images: <a href="https://squoosh.app/">Squoosh web app</a></li> </ul> <p>Design tips:</p> <ul> <li><a href="https://www.nngroup.com/articles/ten-usability-heuristics/">10 Usability Heuristics for User Interface Design</a> - famous Nielsen Norman Group article about UX.</li> <li><a href="https://www.nngroup.com/articles/writing-links/">Writing Hyperlinks: Salient, Descriptive, Start with Keyword</a></li> <li><a href="https://www.smashingmagazine.com/2012/06/links-should-never-say-click-here/">Why Your Links Should Never Say “Click Here”</a></li> <li><a href="https://gcs.civilservice.gov.uk/blog/link-shorteners-the-long-and-short-of-why-you-shouldnt-use-them/">don’t use link shorteners</a></li> <li><a href="https://lawsofux.com/">Laws of UX</a></li> <li><a href="https://webfieldmanual.com/">Web Field Manual</a></li> <li><a href="https://practicaltypography.com/">Butterick’s Practical Typography</a></li> <li><a href="https://color.adobe.com/">Adobe color wheel</a> – play with color schemes and check accessibility.</li> <li><a href="https://coolors.co">Coolors</a></li> </ul> Wed, 03 Nov 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/html-intro.html https://evanwill.github.io/_drafts/notes/html-intro.html Git Credential Helper <p>Git for Windows comes with git credential manager installed and configured, which makes using git on command-line much easier (i.e. not having to type your password every time). (<em>note:</em> <a href="https://evanwill.github.io/_drafts/notes/git-cred-manager.html">git credential manager is now useable on Linux too</a>)</p> <p>On Linux you can set up libsecret as a similar secure credential manager.</p> <p>Configure Git as usual:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --global user.name "Evan Will" git config --global user.email "[email protected]" git config --global core.editor "nano -w" </code></pre></div></div> <p>Install dependencies:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install libsecret-1-0 libsecret-1-dev</code></p> <p>Build the helper (included with git):</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /usr/share/doc/git/contrib/credential/libsecret sudo make </code></pre></div></div> <p>Configure git to use the helper:</p> <p><code class="language-plaintext highlighter-rouge">git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret</code></p> <p>The next time you need a credential (e.g. pushing), it will prompt for username and <a href="/_drafts/notes/git-tokens.html">password/token</a> as normal, but it will be stored by libsecret and can be used for any future authentication to that site (e.g. github, bitbucket, etc).</p> <h2 id="update-credentials">Update Credentials</h2> <p>If you need to <strong>update</strong> your credentials, the easiest method is to use GNOME “Passwords and Keys” (i.e. Seahorse), the GUI to use libsecret. Open Seahorse, then look in Passwords &gt; Login category. You should find an entry such as https://[email protected]/ that corresponds with the credential. I usually just delete the old one, then provide the updated version on my next git operation.</p> <hr /> <h2 id="older-version-gnome-keyring">Older version: gnome-keyring</h2> <p>Older versions of Linux might use gnome-keyring rather than libsecret. Here is the old version:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install libgnome-keyring-dev cd /usr/share/doc/git/contrib/credential/gnome-keyring sudo make git config --global credential.helper /usr/share/doc/git/contrib/credential </code></pre></div></div> Tue, 01 Jun 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-credential.html https://evanwill.github.io/_drafts/notes/git-credential.html Copy a Git Repo (Don't Fork) <p>“Fork” is a cool concept on GitHub, but a bit misunderstood–if you want to start your own repository (not contribute back to the project), it is <strong>not</strong> the best way to make a copy of the code.</p> <h2 id="forks">Forks</h2> <p>“Fork” is a GitHub feature (not part of Git), designed for a workflow similar to using git branches to collaborate with people who do not have direct access to a repository (<a href="https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/working-with-forks">fork docs</a>).</p> <p>Clicking the fork button on a repo creates your own “fork”–a full copy of the repository code and history with a link configured back to the original, with the same name as the original. It is intended to be used to contribute changes back to the original via Pull Requests, thus the “fork” repository will <strong>not</strong> have the full features of normal repositories.</p> <p>If you want a copy of a repository to do your own thing or to start a new project, forks are not the best solution.</p> <h2 id="copy-a-repository">Copy a Repository</h2> <p>If you want to make an exact copy of another project you can:</p> <ul> <li><strong>GitHub Import:</strong> On GitHub click the plus icon in upper right, select “import repository”, then paste in the clone link from the repo you want to copy. The new repo will have the full code and full history of the old one–but will not be configured as a fork and will have no link to the original. It will be a fully featured repository.</li> <li><strong>Copy files:</strong> Always keep in mind a GitHub repository is just a folder of files… Create a new empty repository in your account. Add all the files from the other repository. The new repo will have the full code, but not the history of the old one. Add contents via: <ul> <li>on old repository, click “Code” button and select “download zip”. Extract the zip and copy the files to your new repo (note: the download zip will <strong>not</strong> have files such as .gitignore or other workflow files that you might want!).</li> <li>clone old repository, make sure you have “view hidden files” enabled, then copy all the files except​ “.git” from the old repo folder and paste into the new one.</li> </ul> </li> <li><strong>GitHub Template:</strong> if a repository is configured as a “template”, you can simply click the green “Use this template” button near the “Code” button. This will start a create a new repository with the full code of the main branch, without the full history. The new repo will display a “generated from…” link on its homepage, but there is no direct link configured between the repositories.This is the best way to copy a repository if it is configured. <ul> <li>if you own a repository you want to repeatedly use a model/template for others or yourself, look in the “Settings” tab towards the top for the check box “Template repository”. Check the box.</li> </ul> </li> </ul> Thu, 20 May 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-copy-fork.html https://evanwill.github.io/_drafts/notes/git-copy-fork.html Convert Videos with FFmpeg <p>FFmpeg is a powerful command line tool to work with video files. Video formats are complex–they involve combinations of video encoding, audio encoding, and containers–it all gets really confusing fast… But FFmpeg will help you deal with conversions pretty quickly.</p> <h2 id="install-ffmpeg">Install FFmpeg</h2> <ul> <li>Windows install with downloaded installer: <a href="https://www.ffmpeg.org/">https://www.ffmpeg.org/</a></li> <li>Mac install using Homebrew: <code class="language-plaintext highlighter-rouge">brew install ffmpeg</code></li> <li>Ubuntu install from repository: <code class="language-plaintext highlighter-rouge">sudo apt install ffmpeg</code></li> </ul> <p>FFmpeg is a command line application, so to use it:</p> <ul> <li>open your terminal and navigate to the directory containing your videos (or open the terminal in that folder!)</li> <li>type your FFmpeg commands, starting with <code class="language-plaintext highlighter-rouge">ffmpeg</code></li> </ul> <p>For full information check <a href="https://www.ffmpeg.org/ffmpeg.html">FFmpeg docs</a>.</p> <h2 id="convert-avi-to-mp4">Convert AVI to MP4</h2> <p>To losslessly copy your AVI video into the MP4 container (i.e. <em>without</em> re-encoding the video stream), use the command:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ffmpeg -i input-video.avi -c:v copy -c:a copy -y output-video.mp4 </code></pre></div></div> <p>This command uses the options <code class="language-plaintext highlighter-rouge">-c:v copy</code> and <code class="language-plaintext highlighter-rouge">-c:a copy</code> to copy the video and audio streams without changing the encoding into the new MP4 container.</p> <p>If you want to do a whole folder of AVI videos, you can use a Bash loop, like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for f in *.avi; do ffmpeg -i "$f" -c:v copy -c:a copy -y "${f%.avi}".mp4; done </code></pre></div></div> <p>This loop goes through all AVI files in the current folder (<code class="language-plaintext highlighter-rouge">*.avi</code>), copies each one to a new MP4 file, and names it using the same base filename swapping out the extension (<code class="language-plaintext highlighter-rouge">"${f%.avi}".mp4</code> removes “.avi” and adds “.mp4” to the filename).</p> <p>If you get an error using the <code class="language-plaintext highlighter-rouge">copy</code> method, it probably means your AVI contains encodings that are not compatible with MP4. To just get it to work with the default options, just remove the <code class="language-plaintext highlighter-rouge">-c</code> flags, using just:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ffmpeg -i input-video.avi -y output-video.mp4 </code></pre></div></div> <p>or</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for f in *.avi; do ffmpeg -i "$f" -y "${f%.avi}".mp4; done </code></pre></div></div> <p>This might not be the optimal conversion, but it should work!</p> <p>If you want to take more care, use <code class="language-plaintext highlighter-rouge">ffprobe -i input-video.avi</code> to learn more about the video and audio encodings embedded in your AVI. Then use specific encodings in the <code class="language-plaintext highlighter-rouge">-c</code> flags to control your output file.</p> Sat, 01 May 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ffmpeg.html https://evanwill.github.io/_drafts/notes/ffmpeg.html Compare Matomo to Google Analytics <blockquote> <p>this is a draft page to peek at the data. I hope to add more data and better viz.</p> </blockquote> <p>Adding Google Analytics tracking code to your site has been standard practice for years to gather data about visitors. However, many people are more critically considering this practice–Analytics is “free” because you are giving your user’s data/privacy away to Google in return. And with growing numbers of users blocking analytics, your data might not even be very accurate (see <a href="https://plausible.io/blog/google-analytics-adblockers-missing-data">Marko Saric 1</a> and <a href="https://markosaric.com/google-analytics-blocking/">Marko Saric 2</a>).</p> <p>Luckily, there are a growing number of alternative options out there.</p> <p>One fairly easy to adopt option is <a href="https://matomo.org/">Matomo</a>, an open source analytics platform. It is available as a one-click install on many hosts.</p> <p>From Dec 2020 until Mar 2021 I had both Google Analytics and Matomo on some of my sites. This note compares the data from the two services.</p> <h2 id="set-up">Set Up</h2> <p>At bottom of head section:</p> <ul> <li>Matomo code came first loaded from a personal .org domain, self hosted on Reclaim.</li> <li>Google Analytics loaded via analytics.js version.</li> </ul> <p>I collected the data for a set of top pages that have both analytics.</p> <h2 id="pageviews">Pageviews</h2> <table> <thead> <tr> <th>Page</th> <th>Month</th> <th>GA views</th> <th>MA views</th> <th>Difference</th> </tr> </thead> <tbody> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2020-12</td> <td>678</td> <td>618</td> <td>8%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2020-12</td> <td>325</td> <td>291</td> <td>10%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2020-12</td> <td>111</td> <td>85</td> <td>23%</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2020-12</td> <td>189</td> <td>140</td> <td>25%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2021-01</td> <td>680</td> <td>623</td> <td>8%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2021-01</td> <td>429</td> <td>344</td> <td>19%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2021-01</td> <td>137</td> <td>120</td> <td>12%</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2021-01</td> <td>190</td> <td>187</td> <td>1%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2021-02</td> <td>693</td> <td>608</td> <td>12%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2021-02</td> <td>297</td> <td>266</td> <td>10%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2021-02</td> <td>177</td> <td>152</td> <td>14%</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2021-02</td> <td>107</td> <td>93</td> <td>13%</td> </tr> </tbody> </table> <p>GA seems to consistently record more pageviews.</p> <p>In 2021-01 Google Analytics on sites across the world were hit by a spam spike from <code class="language-plaintext highlighter-rouge">bot-traffic.icu</code> (in my case, 5040 views in a day). Matomo did not record this traffic. Does Matomo do better at filtering out junk traffic?</p> <h2 id="unique-pageviews">Unique Pageviews</h2> <table> <thead> <tr> <th>Page</th> <th>Month</th> <th>GA uniq views</th> <th>MA uniq views</th> <th>Difference</th> </tr> </thead> <tbody> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2020-12</td> <td>558</td> <td>502</td> <td>10%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2020-12</td> <td>300</td> <td>269</td> <td>10%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2020-12</td> <td>106</td> <td>83</td> <td>21%</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2020-12</td> <td>105</td> <td>88</td> <td>16%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2021-01</td> <td>570</td> <td>527</td> <td>7%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2021-01</td> <td>392</td> <td>313</td> <td>20%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2021-01</td> <td>129</td> <td>114</td> <td>11%</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2021-01</td> <td>125</td> <td>122</td> <td>2%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2021-02</td> <td>571</td> <td>501</td> <td>12%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2021-02</td> <td>266</td> <td>238</td> <td>10%</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2021-02</td> <td>160</td> <td>139</td> <td>13%</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2021-02</td> <td>78</td> <td>67</td> <td>14%</td> </tr> </tbody> </table> <p>GA seems to consistently record more unique pageviews.</p> <h2 id="average-load-time">Average Load Time</h2> <table> <thead> <tr> <th>Page</th> <th>Month</th> <th>GA average</th> <th>MA average</th> <th>Difference</th> </tr> </thead> <tbody> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2020-12</td> <td>2.63</td> <td>1.75</td> <td>0.88</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2020-12</td> <td>0</td> <td>0.81</td> <td>-0.81</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2020-12</td> <td>2.35</td> <td>2.07</td> <td>0.28</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2020-12</td> <td>0</td> <td>1.81</td> <td>-1.81</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2021-01</td> <td>0.76</td> <td>1.81</td> <td>-1.05</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2021-01</td> <td>2.04</td> <td>0.7</td> <td>1.34</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2021-01</td> <td>0</td> <td>1.81</td> <td>-1.81</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2021-01</td> <td>1.15</td> <td>1.88</td> <td>-0.73</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Setup Jupyter with Py 2, 3, and R</a></td> <td>2021-02</td> <td>2.25</td> <td>1.78</td> <td>0.47</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">Transfer iPhone to Linux</a></td> <td>2021-02</td> <td>2.13</td> <td>0.98</td> <td>1.15</td> </tr> <tr> <td><a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Add more to Git Bash on Windows</a></td> <td>2021-02</td> <td>1.9</td> <td>0.7</td> <td>1.2</td> </tr> <tr> <td><a href="https://evanwill.github.io/go-go-ghpages-b/">Go-Go GH-Pages home</a></td> <td>2021-02</td> <td>1.63</td> <td>1.34</td> <td>0.29</td> </tr> </tbody> </table> <p>GA load times seem more random. Not sure why they would report “0” and then rather long load times.</p> <h2 id="browser">Browser</h2> <table> <thead> <tr> <th>Browser</th> <th>GA User %</th> <th>MA User %</th> <th>Difference</th> </tr> </thead> <tbody> <tr> <td>Chrome</td> <td>71.88</td> <td>64.5</td> <td>7.38</td> </tr> <tr> <td>Firefox</td> <td>12.51</td> <td>18.6</td> <td>-6.09</td> </tr> <tr> <td>Safari</td> <td>7.68</td> <td>10.8</td> <td>-3.12</td> </tr> <tr> <td>Edge</td> <td>3.58</td> <td>3.5</td> <td>0.08</td> </tr> </tbody> </table> <p>Not including <em>other</em> browsers (so it doesn’t add up to 100%). MA provides stats for desktop vs mobile browsers separately, so I added them together.</p> <h2 id="os">OS</h2> <table> <thead> <tr> <th>OS</th> <th>GA User %</th> <th>MA User %</th> <th>Difference</th> </tr> </thead> <tbody> <tr> <td>Windows</td> <td>45.88</td> <td>45.4</td> <td>0.48</td> </tr> <tr> <td>GNU/Linux</td> <td>17.27</td> <td>24.4</td> <td>-7.13</td> </tr> <tr> <td>Mac</td> <td>15.4</td> <td>18.4</td> <td>-3.0</td> </tr> <tr> <td>iOS</td> <td>4</td> <td>6.4</td> <td>-2.4</td> </tr> <tr> <td>Android</td> <td>15.4</td> <td>5</td> <td>10.4</td> </tr> <tr> <td>Chrome OS</td> <td>1.42</td> <td>0.3</td> <td>1.12</td> </tr> </tbody> </table> <p>The large differences here are interesting. Has MA classified some Android as Linux? Do Linux users block GA but not MA?</p> <h2 id="other-notes">Other notes</h2> <p>Overall, MA’s interface is very nice and less confusing than GA. It is definitely a viable alternative.</p> Mon, 01 Mar 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/analytics.html https://evanwill.github.io/_drafts/notes/analytics.html Software Snapshot <p>I want to capture an annual snapshot of software I am using on my computer. This info is sort of embedded in other notes where I talk about setting up Ubuntu, but I thought it would be interesting to regularly record a snapshot to compare over time. I have noticed a significant decrease in software I actually use, moving more to either browser or text editor.</p> <h2 id="jan-2021">Jan 2021</h2> <ul> <li>Distro: Ubuntu 20.04 LTS - I used to really enjoy installing the latest releases and completely wiping my laptop every 6 months, but lately LTS seems less work…</li> <li>Desktop: <ul> <li>GNOME 3.36.8</li> <li>Extensions: <a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine</a></li> <li>GNOME Tweaks</li> </ul> </li> <li>Browsers: <ul> <li>Firefox 85 - I use firefox for every thing. Interesting to have work access to office365, Word is just as terrible in browser as on desktop. <ul> <li>uBlock Origin</li> <li>Multi-Account Containers</li> <li>Facebook Container</li> </ul> </li> <li>Chromium 88 (snap) - I use chromium just for testing web development. I prefer the dev tools to Firefox’s.</li> </ul> </li> <li>Text editors: <ul> <li>VS Code - used constantly, but getting more annoyed by each update. It seems like it is getting constantly more features, with debugging and information popping up everywhere. I don’t need or appreciate that stuff. I spend a lot of time trying to turn it off, but seems harder…</li> <li>TextEditor / Gedit - used as extra scratch pad constantly.</li> <li>Atom - installed, but not used. I want to like it (it seems like it <em>should</em> be slightly better than VS Code), but just seems slow and not quite right. Not having a good integrated terminal is a big draw back for me.</li> </ul> </li> <li>Other GUI software: <ul> <li>GIMP</li> <li>OBS Studio</li> <li>VidCutter</li> <li>KeePassXC</li> <li>Etcher</li> <li>OpenRefine</li> <li>LibreOffice Calc</li> </ul> </li> <li>Pandemic work from home has introduced some new every day tools: <ul> <li>Zoom - not great on Linux, has less features, freezes up on screen share.</li> <li>Cisco VPN</li> <li>Remmina</li> </ul> </li> <li>Command line tools: <ul> <li>git</li> <li>ImageMagick</li> <li>ExifTool (via <code class="language-plaintext highlighter-rouge">libimage-exiftool-perl</code>)</li> <li>ffmpeg</li> <li>Pandoc</li> <li>LaTeX (via <code class="language-plaintext highlighter-rouge">texlive texlive texlive-fonts-extra texlive-xetex texlive-extra-utils</code>) - mainly just for use with Pandoc.</li> <li>Ruby (via rbenv) - used to do more with Python, but recently just using commandline, OpenRefine, or Ruby + Rake for anything.</li> <li>Jekyll (via Ruby)</li> <li>Java (via <code class="language-plaintext highlighter-rouge">default-jre</code>) - just for use with OpenRefine.</li> <li>tlp tlp-rdw - laptop battery utilities.</li> </ul> </li> </ul> Fri, 05 Feb 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/software-2021.html https://evanwill.github.io/_drafts/notes/software-2021.html Deploy a Jekyll Site with GitHub Actions (v2) <blockquote> <p>This page describes manually creating an Action and was updated in 2023 to fix issues that broke with updates at GitHub. Recent updates allow you to easily use a default starter template–check <a href="/_drafts/notes/github-actions3.html">Deploy a Jekyll Site with GitHub Actions using Starter Workflow</a> for details!</p> </blockquote> <p><a href="https://github.com/features/actions">GitHub Actions</a> are a newish feature of the platform that allows you to create / run workflow automation scripts in repositories. It functions similar to 3rd party continuous integration tools like <a href="https://travis-ci.org/">Travis CI</a>, but built directly into GitHub. Explore the <a href="https://docs.github.com/en/actions">documentation</a> and <a href="https://github.com/marketplace?type=actions">marketplace</a> to get the idea of what you can do.</p> <p>In my use case, I just want to <strong>build a Jekyll site and deploy on GitHub Pages</strong>. However, the default Pages build uses an old version of Jekyll and does not allow plugins (see <a href="https://pages.github.com/versions/">dependency versions</a> for details). Actions allows us to set up our own build instead.</p> <p>Jekyll docs provide a <a href="https://jekyllrb.com/docs/continuous-integration/github-actions/">GitHub Actions tutorial</a> that is a bit out of date. I assume you already have a Jekyll project set up and are ready to deploy it on GitHub Pages.</p> <p>Here are the steps to set up a new Jekyll build Action:</p> <h2 id="url-and-baseurl">url and baseurl</h2> <p>If you use the Liquid filter <code class="language-plaintext highlighter-rouge">absolute_url</code> ensure your “_config.yml” has the <code class="language-plaintext highlighter-rouge">url</code> and <code class="language-plaintext highlighter-rouge">baseurl</code> values set correctly for hosting on GitHub Pages following the pattern <code class="language-plaintext highlighter-rouge">url: https://username.github.io</code> and <code class="language-plaintext highlighter-rouge">baseurl: /repository-name</code>.</p> <h2 id="gemfile-and-gemfilelock">Gemfile and Gemfile.lock</h2> <p>Your Jekyll project repository needs a “Gemfile” committed. I often .gitignore these since my projects aren’t complex, and they tend to confuse others trying to re-use my repos. You don’t need anything fancy. A Gemfile with just this will work:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source 'https://rubygems.org' gem 'jekyll' </code></pre></div></div> <p><em>Optionally</em>, you can also commit your “Gemfile.lock” to reproduce the environment exactly as you use it on your local computer (<em>in theory</em>).</p> <h2 id="add-action-yaml">Add Action YAML</h2> <p>Next, you need to create the YAML Action file in the directory “.github/workflows/”. You can name it what ever you want, but I call mine, “.github/workflows/jekyll.yml”.</p> <p>Adding this file will automatically set up a <code class="language-plaintext highlighter-rouge">GITHUB_TOKEN</code> secret, which is nice so you don’t need to mess around with personal access tokens. However, <strong>you do need permission to create a “workflow” level token when committing the file</strong>. So depending on how your local GitHub authentication is set up, you might not be able to push this file or if you are editing an existing one your action might end up with permissions errors!</p> <p>To avoid issues, I create and edit the file <em>only</em> using the web interface. On the repository home page, click “Add file” &gt; “Create new file”. In the filename field start typing <code class="language-plaintext highlighter-rouge">.github/workflows/jekyll.yml</code>. This will create a folder “.github” (with a period in front!), with “workflows” folder inside, with a file “jekyll.yml” inside.</p> <p>Add this text to your yml action:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>name: build site with jekyll and deploy on github pages # runs when you push or merge PR to main branch on: push: branches: - main pull_request: branches: - main # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: contents: write pages: write id-token: write jobs: jekyll: runs-on: ubuntu-latest steps: # checkout code - uses: actions/checkout@v3 # Use ruby/setup-ruby to shorten build times # https://github.com/ruby/setup-ruby - uses: ruby/setup-ruby@v1 with: ruby-version: 3.1 # Not needed with a .ruby-version file bundler-cache: true # runs 'bundle install' and caches installed gems automatically # use jekyll-action-ts to build # https://github.com/limjh16/jekyll-action-ts - uses: limjh16/jekyll-action-ts@v2 with: enable_cache: true # use actions-gh-pages to deploy # https://github.com/peaceiris/actions-gh-pages - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: # GITHUB_TOKEN secret is set up automatically github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./_site </code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">on</code> key says to build on any push or PR to the main branch (you could switch it to what ever branch works for you, just don’t try to use gh-pages branch).</p> <p>The <code class="language-plaintext highlighter-rouge">permissions</code> key sets the access for the GITHUB_TOKEN necessary to add changes to your repository.</p> <p>The <code class="language-plaintext highlighter-rouge">jobs</code> key gives the list of things to do.</p> <p>Each <code class="language-plaintext highlighter-rouge">uses</code> value is a repository on GitHub, so you can go look at the code to see what it is doing, or set up your own version. In this workflow:</p> <ul> <li><a href="https://github.com/actions/checkout">actions/checkout@v3</a> checks out the code from the main branch (from GitHub).</li> <li><a href="https://github.com/ruby/setup-ruby">ruby/setup-ruby@v1</a> uses a pre-built Ruby and cached gems to speed up built time (when using Ruby, this is apparently preferable to using “actions/cache”).</li> <li><a href="https://github.com/limjh16/jekyll-action-ts">limjh16/jekyll-action-ts@v2</a> runs the <code class="language-plaintext highlighter-rouge">jekyll build</code> (supposedly faster than “helaili/jekyll-action”).</li> <li><a href="https://github.com/peaceiris/actions-gh-pages">peaceiris/actions-gh-pages@v3</a> takes the output and commits it to the <code class="language-plaintext highlighter-rouge">gh-pages</code> branch.</li> </ul> <p>Once committed, the action will run each time you push a new commit or merge a pull request.</p> <p>However, the first time you have to manually activate GitHub Pages. Go to the repository Settings, click “Pages” in the side nav. In the “Source” dropdown select “Deploy from a branch”, and in “Branch” dropdown select “gh-pages”, and save. After Pages is activated, you may need to create another new commit to finally get the web site live.</p> <p><em>Note</em>, in the “Pages” settings do <em>NOT</em> use the “GitHub Actions” option under “Source”. This older style Action commits the output of your build to the gh-pages branch, rather than delivering it directly to Pages. So although you are using an Action, Pages is still “Deploy from a branch”!</p> <p>The Actions tab of the repository provides detailed progress (and error messages) for your workflow, so if something goes wrong it is easier to debug than default GitHub Pages.</p> Fri, 05 Feb 2021 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/github-actions2.html https://evanwill.github.io/_drafts/notes/github-actions2.html OBS: Creating Screencast Videos <p><a href="https://obsproject.com/">Open Broadcast Studio (OBS)</a> is an open source, cross platform tool for recording and live streaming video. It is focused on performance for video game streaming, but works well for creating instructional videos where you would like to share a screen cast of using software.</p> <p>To install, grab the package from the main website. On Linux, first make sure you have ffmpeg installed, <code class="language-plaintext highlighter-rouge">sudo apt install ffmpeg</code>, then <a href="https://obsproject.com/wiki/install-instructions#linux">add the PPA</a>.</p> <h2 id="tips">Tips</h2> <ul> <li>By default all audio sources are active which might result in crummy sound–so you might want to mute/disable desktop audio, and the mic on your webcam if you have a separate headset mic.</li> <li>If you want to use a webcam in multiple scenes: first make a scene that is just the webcam full screen, then add that scene to other scenes (adding it as a source to multiple scenes doesn’t work).</li> </ul> <h2 id="handy-utilities">Handy Utilities</h2> <ul> <li><a href="https://github.com/ozmartian/vidcutter">vidcutter</a> is a handy visual utility for cutting and combining videos. Installing via Flathub seems to work well–don’t use old distro repository versions, since they probably won’t work.</li> <li>Use ffmpeg to convert formats: <code class="language-plaintext highlighter-rouge">ffmpeg -i input.mp4 output.webm</code> (see <a href="https://opensource.com/article/17/6/ffmpeg-convert-media-file-formats">tips</a>)</li> <li><a href="https://trac.ffmpeg.org/wiki/Concatenate">combine videos with ffmpeg</a></li> </ul> Fri, 04 Dec 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/video-creating.html https://evanwill.github.io/_drafts/notes/video-creating.html File naming for web and Git collaboration <p>Be <em>extra careful</em> of file naming case sensitivity when working with people across Linux, Mac, and Windows.</p> <p>In Linux file systems, filenames are case sensitive. So files like “README.md”, “readme.md”, and “ReadMe.md” are three totally different files.</p> <p>However, Windows and Mac file systems are by default case insensitive. On Window and Mac files like “README.md”, “readme.md”, and “ReadMe.md” can not exist at the same time, and all would refer to a single file.</p> <p>Adding to confusion, Windows and Mac are still <em>case preserving</em>, i.e. the filesystem stores the original case information (“README.md” vs. “readme.md”) even though they treat filename as case insensitive. Windows Explorer lets you edit the filename case including extension. However, Mac doesn’t seem to really let you change case in the filesystem and records extensions as upper case by default. This can lead to a lot of confusion trying to fix case sensitivity in filenames and extensions.</p> <p><em>Importantly</em>, even if you do not have a desktop Linux user in your team, case sensitivity still matters since Git platforms, testing, continuous integration, and web servers are most likely Linux systems.</p> <p>So to avoid issues:</p> <ul> <li>Set up a project filename convention (probably all lowercase if a web project)</li> <li>When working on Linux or web platforms don’t create files that would conflict if insensitive</li> <li>When working on Windows and Mac, use actual filenames and don’t rely on case insensitivity when creating links or scripts.</li> <li><em>Tell everyone that file naming is super important!</em></li> </ul> <h2 id="issues-on-web">Issues On Web</h2> <p>For example, when Windows and Mac users run a local dev server (such as using Jekyll), the localhost urls and filesystem will be case insensitive. You may have a file like “assets/ExampleImg.PNG”, and the urls “localhost:4000//assets/ExampleImg.PNG”, “localhost:4000//assets/ExampleImg.png”, and “localhost:4000//assets/exampleimg.png” will work. They test using the site and everything seems to be working fine.</p> <p>However, once deployed on most Linux servers, only the case sensitive filename “/assets/ExampleImg.PNG” will work. So they end up with mysterious errors in production.</p> <h2 id="issues-on-git">Issues on Git</h2> <p>Git is developed and designed for Linux, thus treat files and their history as case sensitive. This can lead to nasty Git errors on Windows and Mac if a Linux user commits files that would be the same if case insensitive.</p> <p>E.g. Linux user commits “README.md” in a directory that already contains “readme.md”, this is valid on Linux and GitHub. However, if Windows and Mac users pull that update they will end up with fatal errors and a lot of confusion. It can’t be gracefully fixed on Windows or Mac, so it is best to clean it up on GitHub or Linux, then do a fresh clone (see <a href="https://xkcd.com/1597/">xkcd git</a>).</p> Tue, 01 Dec 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/filenaming.html https://evanwill.github.io/_drafts/notes/filenaming.html Getting iPhone HEIC Images on Linux <p>Apple seems to spend a lot of effort <em>trying</em> to make their ecosystem incompatible with others. Which is frustrating, selfish, greedy, stupid, etc.</p> <p>But sometimes you need to get images off an iphone. Support to just plug it in seems to go in and out on mainstream Linux (see <a href="https://evanwill.github.io/_drafts/notes/iphone-transfer.html">my earlier notes</a>), but right now it sort of works. I can plug in an iphone, tell the phone to “trust” the computer, and automatically mount the iphone’s “photos” and “documents” without too much trouble. If it doesn’t work after you “trust”, unplug and plug it in again.</p> <h2 id="keep-originals">Keep Originals</h2> <p>Once connected you will still get endless errors trying to transfer more than a few photos. It seems like the iphone in its wisdom is trying to convert the HEIC format images in its storage on the fly to JPG for you–and this kind gesture seems to cause it to timeout constantly. To fix this, you need to go into Settings &gt; Photos &gt; “Transfer to mac or pc” and switch from “Automatic” to “Keep Originals”. (Notice the “mac or pc” snub? Apple seems to really hate linux…)</p> <p>If you are making large transfers, you still may need to unplug and plug in again a few times if you start getting errors.</p> <h2 id="convert-heic">Convert HEIC?</h2> <p>Now you have a folder of <code class="language-plaintext highlighter-rouge">.HEIC</code> images (<a href="https://en.wikipedia.org/wiki/High_Efficiency_Image_File_Format">HEIF format</a>).</p> <p>To decode HEIC files you need <code class="language-plaintext highlighter-rouge">libheif</code>, which is already installed on Ubuntu (package <code class="language-plaintext highlighter-rouge">libheif1</code>). However, most programs (other than GIMP) need some additional packages installed to actually start using HEIF. To use ImageViewer you need <code class="language-plaintext highlighter-rouge">heif-gdk-pixbuf</code>, to get thumbnails in Files you need <code class="language-plaintext highlighter-rouge">heif-thumbnailer</code>, and to do conversions you need extra utilities provided in <code class="language-plaintext highlighter-rouge">libheif-examples</code> (unless you want to manually recompile imagemagick). So:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt install libheif1 heif-gdk-pixbuf heif-thumbnailer libheif-examples</code></p> <p>should get everything you need. Right click on a <code class="language-plaintext highlighter-rouge">.heic</code> image, select open with ImageViewer, and from then on they will be viewable just like any other image.</p> <p>However, there isn’t a ton of support for <code class="language-plaintext highlighter-rouge">.heic</code>. If you are uploading images to a website or working with many apps you may need to convert them all to <code class="language-plaintext highlighter-rouge">.jpg</code>. GIMP can do an individual image effectively, however for batch conversion <code class="language-plaintext highlighter-rouge">libheif-examples</code> provides the commandline tool <code class="language-plaintext highlighter-rouge">heif-convert</code>. Use a bash loop in the folder of <code class="language-plaintext highlighter-rouge">.heic</code> images:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.HEIC; do heif-convert "$f" "${f%.HEIC}.jpg"; done</code></p> <p>By default <code class="language-plaintext highlighter-rouge">heif-convert</code> seems to use “90” quality. You can set your own quality (0-100) by adding <code class="language-plaintext highlighter-rouge">-q</code> flag, e.g. <code class="language-plaintext highlighter-rouge">heif-convert -q 98 input.heic output.jpg</code></p> <p>Have fun!</p> Thu, 05 Nov 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/heic.html https://evanwill.github.io/_drafts/notes/heic.html Library Research and Citation Tools <blockquote> <p>Notes for graduate student meeting introducing library research and citation tools.</p> </blockquote> <h2 id="library-reminders">Library Reminders</h2> <p>Get help:</p> <ul> <li><a href="https://www.lib.uidaho.edu/help/" target="_blank" rel="noopener">Reference Desk</a> (Ask a reference librarian: chat, txt, email, don’t be shy! <a href="https://www.lib.uidaho.edu/about/hours.html#reference" target="_blank" rel="noopener">Hours</a>)</li> <li><a href="https://www.lib.uidaho.edu/" target="_blank" rel="noopener">Library website!</a> (there is a ton of information and resources here)</li> <li>Research Refresher <a href="https://youtu.be/2jZK25a1wZQ" target="_blank" rel="noopener">video</a> , <a href="https://www.lib.uidaho.edu/media/workshops/Library_Flyer_GradStudents.pdf" target="_blank" rel="noopener">handout</a> (be sure to check out the full <a href="https://www.youtube.com/playlist?list=PL3MdArvT5LVfhw9XxOkKUvB3f77oipDXx" target="_blank" rel="noopener">Graduate Essentials Series</a>)</li> </ul> <p>Resources:</p> <ul> <li>Summit (network of 37 NW academic libraries in <a href="https://www.orbiscascade.org/member/" target="_blank" rel="noopener">Orbis Cascade Alliance</a>) and <a href="https://www.lib.uidaho.edu/services/ill/" target="_blank" rel="noopener">ILL</a> (worldwide network for library sharing)</li> <li><a href="https://www.lib.uidaho.edu/services/ill/docdelivery.html">Document Delivery / digitization requests</a>, <a href="https://www.lib.uidaho.edu/covid19/impact.html#curbside-delivery">Curbside Delivery</a> (new no contact access methods)</li> <li><a href="https://www.lib.uidaho.edu/services/reserve/" target="_blank" rel="noopener">Reserves</a> (save your students money!)</li> <li><a href="https://www.lib.uidaho.edu/find/request.html" target="_blank" rel="noopener">Book purchase requests</a> (we have endowed funds to buy stuff, use the form or email me)</li> <li><a href="https://vivo.nkn.uidaho.edu/vivo" target="_blank" rel="noopener">VIVO U of I Research Network</a> (explore research on campus)</li> </ul> <hr /> <h2 id="research-tools">Research Tools</h2> <p>Important research concepts for scholarly literature:</p> <ul> <li><a href="http://libguides.uidaho.edu/citing" target="_blank" rel="noopener">Citation guide</a>, <a href="https://owl.excelsior.edu/citation-and-documentation/">Excelsior Online Writing Lab Citation &amp; Documentation</a></li> <li><a href="https://www.lib.ncsu.edu/tutorials/peerreview/" target="_blank" rel="noopener">Peer Review</a></li> <li><a href="http://guides.library.cornell.edu/graylit" target="_blank" rel="noopener">Grey Lit</a></li> <li>Preprint archives, e.g. <a href="https://arxiv.org/" target="_blank" rel="noopener">arXiv</a> or <a href="https://engrxiv.org/" target="_blank" rel="noopener">engrXiv</a></li> </ul> <p>General search strategies:</p> <ul> <li>Booleans (AND, OR, NOT - learn how to expand, narrow, and refine your search terms)</li> <li>Keywords and concept mapping (from your known topics explore broader, narrower, related, synonyms / thesaurus. <a href="https://youtu.be/v_8rNiW4A9A" target="_blank" rel="noopener">concept mapping intro video</a>)</li> <li>Citation chaining (look at what an important paper in your area cites and who cites it)</li> </ul> <h3 id="library-catalog-primo">Library Catalog (Primo)</h3> <p><a href="https://alliance-primo.hosted.exlibrisgroup.com/primo-explore/search?tab=everything&amp;search_scope=everything&amp;vid=UID" target="_blank" rel="noopener">Primo Discovery Service</a></p> <ul> <li>Content: everything that the library has access to (books, journals, gov docs, articles, physical and digital)</li> <li>Less focused and powerful than databases</li> <li>Use notes: <ul> <li>sign in (access resources off campus)</li> <li>account (check loan status, saved items/searches/history, requests)</li> <li>scopes (UI Library, Summit, E-Resources)</li> <li>filters (date, resource type, etc)</li> <li>“personalize” (weights search results in your discipline)</li> <li>item features (citation, permalink, email, summit libraries, virtual browse)</li> </ul> </li> </ul> <h3 id="library-databases">Library “Databases”</h3> <p><a href="https://libguides.uidaho.edu/az.php" target="_blank" rel="noopener">Database A-Z List</a> (all databases that the Library subscribes to)</p> <ul> <li>Content: each database has a specialized set of materials with enhanced metadata to aid in discovery.</li> <li>Use notes: <ul> <li>databases may <em>not</em> include full text access</li> <li>each may have different limitations and restrictions</li> <li>use proxy to access from off campus</li> </ul> </li> </ul> <p>Important ENGR databases:</p> <ul> <li><a href="https://uidaho.idm.oclc.org/login?url=http://ieeexplore.ieee.org/" target="_blank" rel="noopener">IEEE Xplore</a> (standards, personalized account)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://www.engineeringvillage.com/" target="_blank" rel="noopener">Engineering Village / Compendex</a></li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://search.proquest.com/materialscienceengineering?accountid=14551" target="_blank" rel="noopener">Materials Science &amp; Engineering Collection</a></li> <li><a href="https://uidaho.idm.oclc.org/login?url=http://dl.acm.org/dl.cfm" target="_blank" rel="noopener">ACM Digital Library</a> (conference proceedings)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://search.proquest.com/pqdtft/advanced?accountid=14551" target="_blank" rel="noopener">Dissertations &amp; Theses PQDT</a> (ETD database for most universities)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://www.safaribooksonline.com/library/view/temporary-access/" target="_blank" rel="noopener">Safari: O’Reilly Learning Platform</a> (handy tech learning resources)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://scifinder.cas.org/" target="_blank" rel="noopener">SciFinder</a> (patents, chemical abstracts)</li> </ul> <h3 id="external-indexes">External Indexes</h3> <ul> <li><a href="https://uidaho.idm.oclc.org/login?url=http://webofknowledge.com/UA" target="_blank" rel="noopener">Web of Science</a> <ul> <li>Content: wide coverage of science scholarly/peer-reviewed articles from the most important journals and conference proceedings. Index only (metadata, not full text), contains items that the Library might not have access to.</li> <li>Excellent citation tracking, enables in depth citation chaining</li> <li>Filter by highly cited, “hot in the field”, etc., to explore subject area</li> <li>Export data, citation lists</li> <li><a href="https://youtu.be/xwhy0JBHlMw" target="_blank" rel="noopener">WoS Search intro video</a>, <a href="http://clarivate.libguides.com/ld.php?content_id=35888196" target="_blank" rel="noopener">quick ref</a></li> </ul> </li> <li><a href="https://scholar.google.com" target="_blank" rel="noopener">Google Scholar</a> <ul> <li>Content: good content coverage of academic literature, but not all peer-reviewed and sources are not always clearly labeled. Index only (metadata, not full text), contains items that the Library might not have access to.</li> <li>Familiar / easy to search</li> <li>Good citation tracking</li> <li>Connect to UI Library: <ul> <li>If you connect U of I Library to your Scholar account, search results will show a link “Univ of Idaho - Get it” to access full text items in our subscriptions.</li> <li><a href="https://www.lib.uidaho.edu/find/accesstools.html#connect-google-scholar-to-u-of-i-library" target="_blank" rel="noopener">How to connect to UI Library</a></li> </ul> </li> </ul> </li> <li><a href="https://www.lib.uidaho.edu/find/accesstools.html" target="_blank" rel="noopener">Article Access and Discovery Tools</a> <ul> <li>Variety of plugins and tools to help find access to articles that the library doesn’t have access to, or to discover more research.</li> </ul> </li> </ul> <hr /> <h2 id="citation-management">Citation Management</h2> <p><a href="http://libguides.uidaho.edu/citation-management" target="_blank" rel="noopener">Citation management software</a> are tools to store citations and automatically generate bibliographies. They can help you keep track of your research, discover new items, collaborate on writing, and share resource lists for teaching/research. <em>Start using one now, it will make your future life so much easier, saving you time and effort!</em></p> <p>Common features:</p> <ul> <li>Store references, generate any style citation (you don’t need to learn the citation styles, or convert between them!)</li> <li>Organize your research (keep all your references and notes in one place)</li> <li>Create groups for sharing and collaborating on research (easiest if your collaborators use the same platform…)</li> <li>Auto extract citations from web pages and PDFs</li> <li>Store / manage article PDFs</li> <li>Integrate with word processors (MS Word, Libre Office, Google Docs)</li> <li>Standalone app + web version + browser plugins</li> </ul> <p>Summary of the biggest platforms:</p> <table> <thead> <tr> <th> </th> <th><a href="https://www.zotero.org/">Zotero</a></th> <th><a href="https://www.endnote.com/">EndNote</a></th> <th><a href="https://www.mendeley.com/">Mendeley</a></th> </tr> </thead> <tbody> <tr> <td>Cost</td> <td>Free, open source, $ storage upgrades</td> <td>$$$</td> <td>Freemium, $ storage upgrades</td> </tr> <tr> <td>Developer</td> <td>Center for History and New Media/George Mason University</td> <td>Clarivate Analytics</td> <td>Elsevier</td> </tr> <tr> <td>Pros</td> <td>ease of use, availability</td> <td>integration with Web of Science</td> <td>integration with Elsevier</td> </tr> </tbody> </table> <hr /> <h2 id="zotero">Zotero</h2> <p>Zotero is free, open source, cross platform, and probably the easiest citation manager to get started with. The web interface makes it easy to collaborate on and share reference lists. It has many options to <a href="https://www.zotero.org/support/moving_to_zotero">import</a> / export other citation management lists and formats. Developed by an academic non-profit, Zotero is independent and does not sell your data.</p> <h3 id="get-started">Get started</h3> <ul> <li><a href="https://www.zotero.org/user/login/">Zotero web account</a> - first set up an account to use web version. This is important for syncing your local data, working on multiple computers, and collaborating with others.</li> <li><a href="https://www.zotero.org/download/">Zotero Desktop</a> - optionally download and install the “personal research assistant” / “stand alone” app. The installation will likely prompt you to install plugins for LibreOffice / MS Word, the “Zotero Connector”, and set up an online account. <ul> <li>If you already set up your online account, add it in Preferences &gt; Sync. Once set up, the green refresh arrow appears in upper right of the app window.</li> </ul> </li> <li>“Zotero Connector” browser plugin (Addon/Extension) - install the plugin for your web browser. This will allow you to save references / pdfs directly from web pages. <ul> <li>Access Connector preferences by right clicking the icon. Check for defaults about saving PDFs and website snapshots. You may also need to “Authorize” to save items directly to the web version if your desktop app isn not open.</li> <li>Will automatically detect Proxy links (i.e. logging in via U of I Library) and offer to save that setting to facilitate access.</li> <li>Provides Google Doc integration.</li> </ul> </li> </ul> <h3 id="create-citation-records">Create citation records</h3> <ul> <li><a href="https://www.zotero.org/support/adding_items_to_zotero">Create a new record</a> - use one of the methods to add references to your library: <ul> <li>“Magic wand button” - paste in a URL, DOI, ISBN. Zotero will auto extract the information to create a new record. It will automatically attempt to download related PDF or create a website snapshot.</li> <li>“Plus button” - manually fill in the information.</li> <li>Click the browser plugin in your address bar - information will be auto extracted to create new record.</li> </ul> </li> <li>Edit &amp; Annotate record - check the record “tabs” for options. Use these fields to organize and enrich your collections: <ul> <li>“Info” - manually edit the citation details if necessary.</li> <li>“Notes” - your annotations about the record. You can add multiple writing in rich text. Write summaries, key points you want to use, facts, sentences to quote?</li> <li>“Tags” - add tags to group your articles around topics (see the tag visualization in lower left).</li> <li>“Attachments” - add files or links, or view current. “Snapshots” are locally saved version of a web page.</li> </ul> </li> <li>Create folders to keep organized.</li> <li>Create group libraries to collaborate - setting up groups is done in the web account only (but will sync to desktop). <ul> <li>share PDFs, which can be a huge time saver and simplify access.</li> <li>can be public or private. Great way to publicly share reading lists.</li> </ul> </li> </ul> <h3 id="generate-bibliography">Generate bibliography</h3> <ul> <li>“Create citation/bibliography” - select some references, click the button / right click, and copy the bibliography into your document.</li> <li><a href="https://www.zotero.org/support/word_processor_integration">Word Processor Plugins</a> - Integrate directly with LibreOffice, Word, or Google Docs. Use the tool to insert citations from your manager directly into the paper. This will add the correct inline/footnote citation and populate the bibliography/works cited section. (note: these are automatically installed by the desktop app)</li> <li><a href="https://www.zotero.org/support/rtf_scan">RTF scan</a> - alternative to using the word processor plugins when writing in .RTF format. Add name+date to text, Zotero scans it and matches to your records to auto generate citation and bibliography.</li> <li>“Export” options include BibTeX if integrating with LaTeX writing workflows.</li> <li>“Generate report” option on desktop outputs publication info plus your notes, a nice way to create an annotated bibliography to share.</li> </ul> <h3 id="usage-tips">Usage tips</h3> <ul> <li><a href="https://zbib.org/">ZoteroBib</a> - handy tool to create a bibliography, <em>after you skipped using a citation manager</em>.</li> <li><a href="https://www.zotero.org/support/storage_faq">Zotero Storage</a> - 300 MB for free, 2GB for $20/yr, 6GB for $60/yr, Unlimited for $120/yr. Groups storage counts against the owner’s account, so be strategic if you plan on using it extensively (i.e. have lab leader buy it so you can share all PDFs!).</li> <li><a href="https://www.zotero.org/settings/cv">Create CV</a></li> </ul> <p>Resources:</p> <ul> <li><a href="https://www.zotero.org/support/">Zotero Docs</a> - detailed and helpful documentation.</li> <li><a href="https://youtu.be/Fowy_bVtbr4">U of I Zotero workshop video</a> - 30 minute intro to Zotero.</li> </ul> Sun, 25 Oct 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/library-research.html https://evanwill.github.io/_drafts/notes/library-research.html DIY air filter for fire season <style> .figures img { margin: 12px auto; } </style> <p>Record fire conditions in California, Oregon, and Washington in Sep 2020 plunged all of the Northwest in choking, hazardous levels of smokey haze. For air quality details see <a href="https://www.airnow.gov/">AirNow</a> and the <a href="https://fire.airnow.gov/">Fire and Smoke Map</a>. There isn’t much you can do to escape. <a href="https://www.epa.gov/indoor-air-quality-iaq/wildfires-and-indoor-air-quality-iaq">Official advice</a> is basically just stay inside, turn your air conditioner on recirculate, and run your air purifier full time.</p> <p>What if you don’t have a HVAC system, recirculate option, or air purifier?</p> <p>Basically its miserable… but here is a viable DIY option to clean your indoor air made with a box fan, furnace filter, and duct tape.</p> <blockquote> <p>p.s. more recently it has been discovered that running this type of filtration also helps protect from Covid in enclosed spaces! If you have four air filters available, build a more advanced <a href="https://engineering.ucdavis.edu/news/science-action-how-build-corsi-rosenthal-box">Corsi-Rosenthal box</a> (or <a href="https://cleanaircrew.org/box-fan-filters/">collection of DIY resources from Clean Air Crew</a>). UC Davis has published some <a href="https://energy.ucdavis.edu/wp-content/uploads/Case-Study_DIY-Portable-Air-Cleaners-083121.pdf">research confirming the effectiveness of these DIY filters</a>.</p> </blockquote> <h2 id="step-1-get-fan">Step 1: Get Fan</h2> <p>Do you have a box fan? Great. Measure it, usually they are about 20” x 20” square.</p> <h2 id="step-2-get-filter">Step 2: Get Filter</h2> <p>Wild fire smoke produces fine particle pollution (2.5 micrometers and smaller), so you need a high quality furnace filter, something like <a href="https://www.filtrete.com/3M/en_US/filtrete/products/~/Filtrete-Healthy-Living-Air-Filters/?N=4315+3292675507+3294529207&amp;preselect=7568680+3293786499&amp;rt=rud">Filtrete Healthy Living</a> that uses electrostatic charge to capture particles. Look for a MERV rating of at least 11, MERV 12 or higher is better.</p> <p>If you are in a pinch and not using your furnace, you can just grab it out of your system.</p> <p>If you go to the store, look for a size that will cover your box fan. Ideally, it would be 20”x20”x4” size fitting perfectly over your fan. Deeper filters provide better flow and last longer, but the standard 1” will be fine too.</p> <p>However, that ideal size is rare and if you are in a smokey area filters sell out fast–so just find anything that covers the fan with the highest MERV rating. I find that odd sizes are usually cheaper than common ones, so I used 20x30x1 because it was $5 cheaper than 20x20 for the same quality!</p> <h2 id="step-3-duck-tape">Step 3: Duck Tape!</h2> <p>The filter will have an arrow showing which way the air should flow through. Lay the filter onto the back of your box fan with the arrow pointing into the fan. Use a few pieces of duct tape to secure it directly to the fan.</p> <div class="figures"> <img src="/_drafts/assets/filter1.jpg" alt="DIY filter on box fan" /> <img src="/_drafts/assets/filter2.jpg" alt="DIY filter on box fan" /> </div> <h2 id="step-4-use-it">Step 4: Use It</h2> <p>Obviously. The picture below shows a fresh filter next to one used for 24hr during horrible smokey conditions.</p> <p><strong>Another tip:</strong> get a spray bottle with clean water and spritz the air around your house every so often. Moisture particles help pull smoke pollution out of the air.</p> <div class="figures"> <img src="/_drafts/assets/filter3.jpg" alt="Clean filter vs. after 24hr of use" /> <img src="/_drafts/assets/spray.jpg" alt="Water spray bottle" /> </div> Mon, 14 Sep 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/filter.html https://evanwill.github.io/_drafts/notes/filter.html Estimating Ideal Text Body Width <p>Typographers have a variety of stylistic and idealistic reasons for finding an ideal line length for printed text (for example see Bringhurst <a href="https://en.wikipedia.org/wiki/The_Elements_of_Typographic_Style"><em>The Elements of Typographic Style</em></a>. On the web, line length is also important for useability–too often web pages present really long lines of text across your screen, making it hard to read.</p> <p>Setting ideal line lengths can be complicated to translate to the web because of all the variables of text layout. It seems like you should just be able to say <code class="language-plaintext highlighter-rouge">max-width: 66rem;</code>, but that doesn’t translate correctly and would be much wider than 66 characters.</p> <p>Butterick <a href="https://practicaltypography.com/line-length.html"><em>Practical Typography</em></a> says to use “average line length of 45 – 90 characters, including spaces”, or “to fit between two and three alphabets on a line”. Butterick’s site uses 2.31 alphabets, which in his font + spacing = 652px width for his text block layout. The idea of alphabets on a line seems like the most practical method to estimate line lengths on a website.</p> <p>Two alphabets:</p> <p><code class="language-plaintext highlighter-rouge">abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz</code></p> <p>2.31 alphabets:</p> <p><code class="language-plaintext highlighter-rouge">abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh</code></p> <p>Three alphabets:</p> <p><code class="language-plaintext highlighter-rouge">abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz</code></p> <h2 id="find-your-ideal-line-length">Find Your Ideal Line Length</h2> <ol> <li>put two or three alphabets in a paragraph your main body text.</li> <li>viewing the page, right click the paragraph and inspect element.</li> <li>using your dev tools inspector, set the paragraph to <code class="language-plaintext highlighter-rouge">display: inline-block;</code> (this allows you to get the size of just the text, not the full p element)</li> <li>check dev tools Layout Box Model / Computed to find the calculated width in pixels.</li> <li>Adjust your text block width to your ideal width (some where between the pixel length of two or three alphabets).</li> <li>Enjoy your <em>perfect</em> typography.</li> </ol> <hr /> <p>This site’s text block is currently wider than three alphabets…</p> <p>abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz</p> <p>I like to think that is because it is mostly about sharing code blocks, which are annoying to look at if too narrow. My web book editions, like <a href="https://evanwill.github.io/aladore-book/">aladore-book</a>, use a more ideal width.</p> Tue, 18 Aug 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/text-body.html https://evanwill.github.io/_drafts/notes/text-body.html Deploy a Jekyll Site with GitHub Actions <p><strong>Note:</strong> GitHub Actions has become much easier than when this post was written, please <a href="/_drafts/notes/github-actions2.html">see my most recent version Actions using Starter Workflow</a>! I would strongly suggest using it instead!</p> <hr /> <p><a href="https://github.com/features/actions">GitHub Actions</a> are a fairly new feature of the platform that allows you to create / run workflow automation scripts in repositories. It functions similar to 3rd party continuous integration tools like <a href="https://travis-ci.org/">Travis CI</a>, but built directly into GitHub. It is currently being pushed pretty heavily, with the new “Actions” tab added to every repository interface. Explore the <a href="https://docs.github.com/en/actions">documentation</a> and <a href="https://github.com/marketplace?type=actions">marketplace</a> to get the idea of what you can do.</p> <p>In my use case, I just want to <strong>build a Jekyll site and deploy on GitHub Pages</strong>. However, the default Pages build uses an old version of Jekyll and does not allow plugins. Actions allows us to set up our own build instead.</p> <p>Jekyll docs provide a <a href="https://jekyllrb.com/docs/continuous-integration/github-actions/">GitHub Actions tutorial</a>. However, I assume you already have a Jekyll project set up, and I made a few tweaks to their set up.</p> <p>Here are the steps to set up a new Jekyll build Action:</p> <h2 id="1-gemfile-and-gemfilelock">1. Gemfile and Gemfile.lock</h2> <p>First, your Jekyll project repository needs a <code class="language-plaintext highlighter-rouge">Gemfile</code> and <code class="language-plaintext highlighter-rouge">Gemfile.lock</code> committed. I often .gitignore these since my projects aren’t complex, and they tend to confuse others trying to re-use my repos. However, you need the Gemfile.lock to tell the build process exactly what Gems to use–this way, if it works on your computer, it will work on the virtual machine. (Keep in mind, the VM is Ubuntu, so not sure if that is true if you use Windows…)</p> <p>You don’t need anything fancy. A Gemfile with just this will work:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source 'https://rubygems.org' gem 'jekyll' </code></pre></div></div> <p>Create the Gemfile, then run <code class="language-plaintext highlighter-rouge">jekyll s</code> to generate the Gemfile.lock, and commit them both.</p> <h2 id="2-action-yml">2. Action YML</h2> <p>Next, you need to create the YAML Action file in the directory <code class="language-plaintext highlighter-rouge">.github/workflows/</code>. You can name it what ever you want, but I call mine, <code class="language-plaintext highlighter-rouge">.github/workflows/jekyll.yml</code>, and added this text:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>name: build with jekyll and deploy on github pages on: push: branches: - main pull_request: branches: - main jobs: jekyll: runs-on: ubuntu-latest steps: # checkout code - uses: actions/checkout@v2 # Use GitHub Actions' cache to shorten build times and decrease load on servers - uses: actions/cache@v1 with: path: vendor/bundle key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} restore-keys: | ${{ runner.os }}-gems- # use jekyll action from jekyll docs example - uses: helaili/[email protected] env: JEKYLL_PAT: ${{ secrets.JEKYLL_PAT }} </code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">on</code> key says to build on any push or PR to the main branch (you could switch it to what ever branch works for you, just don’t try to use gh-pages branch).</p> <p>The <code class="language-plaintext highlighter-rouge">jobs</code> key gives the list of things to do. Each <code class="language-plaintext highlighter-rouge">uses</code> value is a repository on GitHub, so you can go look at the code to see what it is doing, or set up your own version. In this workflow:</p> <ul> <li><code class="language-plaintext highlighter-rouge">actions/checkout@v2</code> checks out the code from the main branch (from GitHub).</li> <li><code class="language-plaintext highlighter-rouge">actions/cache@v1</code> checks to see if the gems listed in your Gemfile.lock are already cached (from GitHub).</li> <li><code class="language-plaintext highlighter-rouge">helaili/[email protected]</code> basically runs <code class="language-plaintext highlighter-rouge">bundle exec jekyll build</code>, then commits the output into the <code class="language-plaintext highlighter-rouge">gh-pages</code> branch, using the secret called “JEKYLL_PAT”.</li> </ul> <p>Commit your Action in your project repository.</p> <h2 id="3-access-token-and-secret">3. Access Token and Secret</h2> <p>To allow the Action to do stuff to your repository, you need to set up a personal access token and secret for it to use.</p> <p>First, create a new personal access token: <a href="https://github.com/settings/tokens">https://github.com/settings/tokens</a></p> <p>I make mine specific to the project so I can easily revoke them when messing around. If you are using a public repo, you only have to give it access to <code class="language-plaintext highlighter-rouge">public_repo</code>, and probably don’t want to give any more. Copy the key, since you can only see it once.</p> <p>Next, go to your project repository &gt; Settings &gt; Secrets. Click “New secret”, name it exactly <code class="language-plaintext highlighter-rouge">JEKYLL_PAT</code>, and paste in your key. (note: “JEKYLL_PAT” is set in the <code class="language-plaintext highlighter-rouge">jekyll.yml</code> workflow, so if you really wanted you could name it something else if you edit it there).</p> <h2 id="4-commit--pr">4. Commit / PR</h2> <p>With everything set up, the Acton should run on your next commit or PR to main. You do not need to activate GitHub Pages in settings, it will happen automatically.</p> <p>The Actions tab provides detailed progress for your workflow, so if something goes wrong it is a bit easier to debug than default GitHub Pages.</p> <p>Just enjoy your newly built website!</p> Wed, 05 Aug 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/github-actions.html https://evanwill.github.io/_drafts/notes/github-actions.html Markdown in a Minute <style> #markdown-frame { border: solid #868e96 1px; padding: 5px; margin-bottom: 25px; } #source { display: block; } #rendered { display: none; }</style> <p>You can start writing <a href="https://daringfireball.net/projects/markdown/">Markdown</a> in one minute!</p> <p>Markdown is a simple syntax for writing content for the web. The plain text code below demonstrates all the basics–click the button to view how it will look rendered into HTML. Check the resources at the bottom to learn more!</p> <p>Toggle this Markdown: <button id="toggle" class="buttons">Markdown / Rendered</button></p> <div id="markdown-frame"> <div id="source"> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Heading One ## Heading Two ### Heading Three, etc. Any text with no empty lines between will become a paragraph. Leave an empty line between headings and paragraphs. Font can be *Italic* or **Bold**. Code can be highlighted with `backticks`. Hyperlinks look like [GitHub Help](https://help.github.com/). Images look similar: ![alt text here](https://upload.wikimedia.org/wikipedia/commons/4/4b/Focus_ubt.jpeg) A bullet list is created using `*`, `+`, or `-`, like: - dog - cat - muffin A numbered list is created using a number + `.`, like: 1. one 2. two 6. three 2. four &gt; Block quote. &gt; Continuing the quote. Horizontal rule: ------- </code></pre></div> </div> </div> <div id="rendered"> <h1 id="heading-one">Heading One</h1> <h2 id="heading-two">Heading Two</h2> <h3 id="heading-three-etc">Heading Three, etc.</h3> <p>Any text with no empty lines between will become a paragraph. Leave an empty line between headings and paragraphs.</p> <p>Font can be <em>Italic</em> or <strong>Bold</strong>. Code can be highlighted with <code class="language-plaintext highlighter-rouge">backticks</code>. Hyperlinks look like <a href="https://help.github.com/">GitHub Help</a>.</p> <p>Images look similar:</p> <p><img src="https://upload.wikimedia.org/wikipedia/commons/4/4b/Focus_ubt.jpeg" alt="alt text here" /></p> <p>A bullet list is created using <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge">+</code>, or <code class="language-plaintext highlighter-rouge">-</code>, like:</p> <ul> <li>dog</li> <li>cat</li> <li>muffin</li> </ul> <p>A numbered list is created using a number + <code class="language-plaintext highlighter-rouge">.</code>, like:</p> <ol> <li>one</li> <li>two</li> <li>three</li> <li>four</li> </ol> <blockquote> <p>Block quote. Continuing the quote.</p> </blockquote> <p>Horizontal rule:</p> <hr /> </div> </div> <p>Reference:</p> <ul> <li>GitHub <a href="https://guides.github.com/features/mastering-markdown/">Mastering Markdown Guide</a></li> <li><a href="http://www.markdowntutorial.com/">Markdown Tutorial</a></li> <li><a href="https://evanwill.github.io/write-md/">Markdown and Pandoc for Academic Writing</a></li> <li>More <a href="https://evanwill.github.io/_drafts/tags/index.html#md">_drafts notes</a></li> </ul> <p>Online editors:</p> <ul> <li><a href="http://dillinger.io/">Dillinger</a></li> <li><a href="https://stackedit.io/">StackEdit</a></li> <li><a href="https://hackmd.io/">HackMD</a> (real time collaboration)</li> </ul> <script> function markdownToggle() { document.getElementById("source").style.display = (document.getElementById("source").style.display === "none") ? "block" : "none"; document.getElementById("rendered").style.display = (document.getElementById("rendered").style.display === "block") ? "none" : "block"; } document.getElementById("toggle").onclick = function () { markdownToggle(); }; </script> Sat, 01 Aug 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/markdown-minute.html https://evanwill.github.io/_drafts/notes/markdown-minute.html Process Document with XML + XSL <p>People who work a lot with XML tend to use <a href="https://www.oxygenxml.com/">Oxygen XML Editor</a>. Unfortunately, the XML ecosystem seems fairly stagnant outside of Oxygen. XSLT has version 1, 2, and 3 (draft)–but only <a href="http://www.saxonica.com/welcome/welcome.xml">Saxon</a> has fully implemented versions 2 and 3.</p> <p>I don’t work with XML a lot, so I don’t want to pay for Oxygen nor learn how to use it, but occasionally I have to process some XML using XSLT. So here are some options… (p.s. my favorite is to avoid the XSLT by parsing the XML with Ruby, then just outputting using Ruby instead)</p> <h2 id="xsltproc">xsltproc</h2> <p>For a quick and easy utility, install:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt install xsltproc</code></p> <p>Then use the v.1 processor like:</p> <p><code class="language-plaintext highlighter-rouge">xsltproc --output out.html stylesheet.xsl example.xml</code></p> <h2 id="saxon">Saxon</h2> <p>Saxon provides an open source and commercial version of their v.2 processor implemented in Java. If you install from a Linux repository, you will get a relatively old version–which in this case is actually good. Apparently more recent “open” versions from Saxonica have limited advanced features.</p> <p>Be sure you have Java installed (<code class="language-plaintext highlighter-rouge">default-jre</code>), then install:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt install libsaxonb-java</code></p> <p>Use is via a Java command like:</p> <p><code class="language-plaintext highlighter-rouge">java net.sf.saxon.Transform -o:output.html -s:example.xml -xsl:test.xslt</code></p> <p>Or via the commandline wrapper (<a href="http://manpages.ubuntu.com/manpages/trusty/man1/saxonb-xslt.1.html">man page</a>):</p> <p><code class="language-plaintext highlighter-rouge">saxonb-xslt -s:example.xml -xsl:stylesheet.xsl -o:output.html</code></p> <p>If you run with a v1 stylesheet you may get a warning, but it still works fine. You will also get a warning for “unsafe extensions” for commands such as <code class="language-plaintext highlighter-rouge">xsl:result-document</code>. To ignore the warning, add <code class="language-plaintext highlighter-rouge">-ext:on</code>, like:</p> <p><code class="language-plaintext highlighter-rouge">saxonb-xslt -s:example.xml -xsl:test.xsl -ext:on</code></p> <h2 id="ruby-nokogiri">Ruby Nokogiri</h2> <p><a href="https://nokogiri.org/">Nokogiri</a> is a popular Ruby Gem for parsing HTML and XML documents. It implements v.1 features. It is fairly easy to set up a <code class="language-plaintext highlighter-rouge">.rb</code> file or Rake task to process batches of XML.</p> <p>First, ensure you have a complete, up-to-date version of Ruby installed on your system. Then <code class="language-plaintext highlighter-rouge">gem install nokogiri</code>.</p> <p>Using it looks something like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'nokogiri' document = Nokogiri::XML(File.read('example.xml')) template = Nokogiri::XSLT(File.read('test.xsl')) transformed_document = template.transform(document) File.write('output.html', transformed_document) </code></pre></div></div> <p>i.e. open the XML; open the XSL; apply the XSLT; write the output to a file. See <a href="https://nokogiri.org/rdoc/Nokogiri/XSLT/Stylesheet.html">Nokogiri stylesheet docs</a>.</p> <p>Alternatively, rather than writing/applying an XSL, I have found it easier to just parse values out of the XML using selectors, then write the new document using Ruby instead.</p> <p>In fact, I think I will do my best to avoid XML if possible…</p> Mon, 06 Jul 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/xml-xslt.html https://evanwill.github.io/_drafts/notes/xml-xslt.html pdfjam is Handy <p><a href="https://github.com/DavidFirth/pdfjam">pdfjam</a> is a handy package for using the pdf utilities in LaTeX. I use it to quickly combine a batch of image files into a standard PDF. It can be installed as part of the TeX Live LaTeX distribution on Ubuntu:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt install texlive-extra-utils</code></p> <p>(if you don’t have TeX Live installed, add <code class="language-plaintext highlighter-rouge">texlive texlive-fonts-extra</code> as well)</p> <p>Once installed, you can check the full options: <code class="language-plaintext highlighter-rouge">pdfjam --help</code></p> <p>Now you can easily combine separate PDFs or images into a single PDF. The basic command is put together like <code class="language-plaintext highlighter-rouge">pdfjam --options filenames page-selections</code>.</p> <p>For example, if I have a folder of JPG images I want to combine into a standard PDF:</p> <p><code class="language-plaintext highlighter-rouge">pdfjam --letterpaper *.jpg</code></p> <p>Let’s say I have three PDFs where I want to combine only some of the pages:</p> <p><code class="language-plaintext highlighter-rouge">pdfjam --letterpaper example1.pdf 1-3 example2.pdf - example3.pdf 4-5</code></p> <p>This will output a single PDF including pages 1 - 3 of example1, all pages of example2, and pages 4 - 5 of example3.</p> <p>You can use any of these standard LaTeX paper sizes:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>a0paper, a1paper, a2paper, a3paper, a4paper, a5paper, a6paper, b0paper, b1paper, b2paper, b3paper, b4paper, b5paper, b6paper, c0paper, c1paper, c2paper, c3paper, c4paper, c5paper, c6paper, b0j, b1j, b2j, b3j, b4j, b5j, b6j, ansiapaper, ansibpaper, ansicpaper, ansidpaper, ansiepaper, letterpaper, executivepaper, legalpaper </code></pre></div></div> <p>Or create a custom size using the option <code class="language-plaintext highlighter-rouge">--papersize '{WIDTH,HEIGHT}'</code>.</p> <p>You can also add embedded metadata using options like <code class="language-plaintext highlighter-rouge">--pdftitle STRING</code> and <code class="language-plaintext highlighter-rouge">--pdfauthor STRING</code>.</p> <p>Handy!</p> <p><em>Note:</em> in theory you can install it on Windows if you use MiKTeX via the MiKTeX console by searching the in the packages. However, it might be easier to get it to work using <a href="https://evanwill.github.io/_drafts/notes/wsl.html">Ubuntu WSL</a> instead.</p> Sun, 05 Jul 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pdfjam.html https://evanwill.github.io/_drafts/notes/pdfjam.html Atom Editor Notes <blockquote> <p><strong>Atom Editor project is no longer active</strong>, and was <a href="https://techcrunch.com/2022/06/08/github-sunsets-atom-the-software-dev-environment-it-launched-in-2011/">sunsetted by GitHub Dec 2022</a>.</p> <p>Some community led projects have forked the code, including <a href="https://pulsar-edit.dev/">Pulsar edit</a>.</p> </blockquote> <p><a href="https://atom.io/">Atom</a> is an open source code editor built by GitHub in the <a href="https://electronjs.org/">Electron</a> framework. In the past, I used it for quite awhile before switching to <a href="https://evanwill.github.io/_drafts/notes/vs-code.html">VS Code</a>, because I felt like Atom was too slow and clunky. However, in classic Microsoft style, VS Code is moving toward too much unnecessary/undesired functionality that gets in the way of the clean, quick, simple interface that attracted users to it in the first place. Now MS purchased GitHub, so the development status of Atom seems a bit unclear–does MS really want to develop both the leading Electron based text editors separately? Seeing the many unmaintained Packages makes me feel like Atom community is losing steam… In any case, I recently tried it again to see if I would like to switch back.</p> <p>Install is easy and good on all OS. Click Edit &gt; Preferences to start customizing.</p> <p>Click on the Editor tab. I like to check “Show Indent Guide”, “Soft Wrap”, and “Soft Wrap Hanging Indent” 1. Spellcheck is built in which is handy.</p> <h3 id="git--github-builtin">Git / GitHub (builtin)</h3> <p>Atom comes bundled with GUI Git / GitHub tools which look similar to GitHub Desktop. Click the icons in the lower right or <code class="language-plaintext highlighter-rouge">Ctrl+Shift+9</code> toggles the Git panel. Click on a file to view it’s diff.</p> <p>Like GitHub Desktop an icon offers Fetch, but then changes to Push once you make some Commits, or Pull when there are remote updates. Right click the icon to access more options.</p> <p>This seems like a real plus for people who might use GitHub Desktop instead. However, I prefer the efficiency of VS Code’s approach which adds version control to a tab in the Project browsing panel.</p> <h3 id="markdown-builtin">Markdown (builtin)</h3> <p>Atom has a Markdown preview builtin: just click <code class="language-plaintext highlighter-rouge">Ctrl+Shift+M</code> and a side-by-side live preview will appear. However, I like to tweak the settings to use GitHub’s standard Markdown styling. Go to Preferences &gt; Packages, search for Markdown, click on <code class="language-plaintext highlighter-rouge">markdown-preview</code>, and check off “Use GitHub.com style”.</p> <h3 id="terminal">Terminal</h3> <p>Atom is missing a built in terminal, so you need to install one from the Community Packages. This seems like a major barrier to adoption since it frustrates many users. There is a confusingly large array of options, yet very few actively developed.</p> <p>Open Edit &gt; Preferences &gt; +Install, and search for terminal to find options. In the past I used <a href="https://github.com/platformio/platformio-atom-ide-terminal">platformio-ide-terminal</a>. However recently (as of Nov 2020) it no longer works for me on Ubuntu, nor do the many related terminals. <code class="language-plaintext highlighter-rouge">platformio-ide-terminal</code> adds an icon to the lower left and the key binding <code class="language-plaintext highlighter-rouge">Ctrl+`</code> to open the terminal.</p> <p>The only terminal package that actually works for me anymore is <a href="https://github.com/bus-stop/x-terminal">x-terminal</a>. <code class="language-plaintext highlighter-rouge">x-terminal</code> treats the terminal as a pane just like any other open editor–interesting approach, but I don’t think I like it. It uses the keybinding <code class="language-plaintext highlighter-rouge">Ctrl+`</code> to open a terminal, but doesn’t seem to add an icon anywhere.</p> <h3 id="fira-code">Fira Code</h3> <p>I like to use <a href="https://github.com/tonsky/FiraCode">Fira Code</a> font in my editor. However, I do not like Fira Code’s fancy font ligatures–they just confuse me. Ligatures are enabled by default on Atom, so to turn them off you need to edit the config.</p> <p>First, open Edit &gt; Preferences &gt; Editor, and add <code class="language-plaintext highlighter-rouge">Fira Code</code> to the front of the Font Family list. Then open Edit &gt; Stylesheet, which will open a file <code class="language-plaintext highlighter-rouge">styles.less</code> in your config folder where you can add customizations. Inside the <code class="language-plaintext highlighter-rouge">atom-text-editor</code> selector, add the rule <code class="language-plaintext highlighter-rouge">-webkit-font-feature-settings: "liga" off, "calt" off;</code>. It will look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>atom-text-editor { -webkit-font-feature-settings: "liga" off, "calt" off; } </code></pre></div></div> <p>You should have Fira Code with no ligatures.</p> <h2 id="handy-keys">Handy keys</h2> <ul> <li>Use Ctrl + mouse wheel to zoom font size.</li> </ul> Wed, 27 May 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/atom-editor.html https://evanwill.github.io/_drafts/notes/atom-editor.html Windows Subsystem for Linux <p><strong>Probably out of date? I haven’t used this for a long time!</strong></p> <p>On Windows I use Git Bash (from <a href="https://git-scm.com/">Git for Windows</a>) for everyday commandline tasks. Occasionally I need something a bit more complete and have used <a href="https://evanwill.github.io/_drafts/notes/cygwin.html">Cygwin</a> in the past. However, <a href="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</a> (WSL) is now offering a great alternative that is easy to install.</p> <blockquote> <p><em>P.S.</em> <a href="https://docs.microsoft.com/en-us/windows/wsl/wsl2-about">WSL 2</a> sounds even better, but I don’t have an up-to-date enough Windows built to try it. <em>P.S.S.</em> If you are using Bash commandline a lot, why not just <a href="https://evanwill.github.io/_drafts/notes/linux-workshop.html">try to linux</a> fulltime or dual boot!</p> </blockquote> <h2 id="install-wsl">Install WSL</h2> <p>Check the <a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">official install docs</a> for details, but recent improvements has made installing WSL relatively easy.</p> <ol> <li>Enable WSL by opening PowerShell as admin and running <code class="language-plaintext highlighter-rouge">Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux</code>. You will probably have to restart.</li> <li>Open “Microsoft Store” app and search for your preferred distro (check the author to ensure it is official). I suggest the latest LTS Ubuntu from “Canonical Group Limited”, currently 20.04 LTS.</li> <li>On the app listing, click “Get” button then “Install”.</li> <li>Once installed, click “Launch” on the app listing, or find and click in your Start Menu. This will open up a terminal window that says something about initializing. This first time startup will take awhile, a few minutes at least.</li> <li>Once initialization finishes, a prompt will appear in the terminal to create a username and password. This will be your sudo admin user (and is not related to your Windows accounts).</li> <li>Once your user is set, a normal terminal prompt will appear. Update your system since this is not done automatically (Ubuntu: <code class="language-plaintext highlighter-rouge">sudo apt update</code>, then <code class="language-plaintext highlighter-rouge">sudo apt upgrade</code>).</li> <li>All ready! Now you can find it in your Start Menu, or from the context menu when holding Shift.</li> </ol> <h2 id="wsl-tips">WSL Tips</h2> <ul> <li>From WSL terminal, your Windows files are at <code class="language-plaintext highlighter-rouge">/mnt/c/</code>.</li> <li>The easiest way to get to a Windows file location is to hold <code class="language-plaintext highlighter-rouge">Shift</code> then right click in a folder in Explorer–the context menu will have the option “Open linux shell here”.</li> <li>On the Windows side, your WSL files are somewhere in <code class="language-plaintext highlighter-rouge">C:\Users\&lt;username&gt;\AppData\Local\Packages</code>, but Windows says don’t mess with that. Up-to-date Window’s builds allow you to access WSL directly in Explorer at <code class="language-plaintext highlighter-rouge">\\wsl$\</code>. If you are in WSL terminal, type <code class="language-plaintext highlighter-rouge">explore.exe .</code> to open Explorer in that location.</li> <li>Updates are not automatic, so update manually when you use it.</li> <li>Uninstall is easy via Microsoft Store app.</li> <li>If you forget your user password it is possible to <a href="https://docs.microsoft.com/en-us/windows/wsl/user-support#reset-your-linux-password">reset via Powershell</a>.</li> </ul> Tue, 28 Apr 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/wsl.html https://evanwill.github.io/_drafts/notes/wsl.html Ubuntu 20.04 <p>New long term release <a href="https://ubuntu.com/download/desktop">Ubuntu 20.04</a> is out!</p> <p>Long term releases get guaranteed five years of support, so are great if you like to install a solid system once and leave it. On the other hand, I like do a fresh install at every release, but either way, this note gathers up tips for getting everything set up after you install. I have a Dell XPS 15, Lenovo Flex, and HP Envy, and so far everything seems to work well–and the desktop seems noticeably faster than 18.04.</p> <h2 id="install-from-usb">Install from USB</h2> <ol> <li>download <a href="https://ubuntu.com/download/desktop">Ubuntu 20.04</a></li> <li><a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn ISO to a USB stick</a></li> <li>Plug in your live USB into computer (while turned off)</li> <li>Press power button and hit boot interrupt button (usually F12, Delete, Esc, or F2)</li> <li>Look for boot options menu, then select your USB to boot from</li> <li>After some thought, it should boot into the Ubuntu installer where you can choose to test or install. I usually test first, so you can play around with the live system to make sure it seems to be working, then click the installer from the live system.</li> <li>During install, when it asks about hard drive, select the “Advanced options” to find LVM and encryption.</li> </ol> <h2 id="settings">Settings</h2> <p>Open Settings:</p> <ul> <li>Settings &gt; Background to get your wallpaper set.</li> <li>Settings &gt; Appearance &gt; checkout new “Dark” mode option and set Dock icon size.</li> <li>Settings &gt; File History &amp; Trash &gt; checkout new options for automatically deleting history, trash, and temp files.</li> <li>Settings &gt; Display &gt; click the “Night Light” option at the top to configure a red shift in the evening.</li> <li>Settings &gt; Date &amp; Time &gt; use “Time Format” option to change 24hr or AM/PM.</li> </ul> <h2 id="tweaks">Tweaks</h2> <p>Install Gnome Tweaks (GUI tool to customize desktop) and Gnome Extensions integration (enables using extensions via browser interface) right away, <code class="language-plaintext highlighter-rouge">sudo apt install gnome-tweaks chrome-gnome-shell</code>. (Note: <code class="language-plaintext highlighter-rouge">gnome-tweaks</code> used to be named <code class="language-plaintext highlighter-rouge">gnome-tweak-tool</code>)</p> <p>Open Tweaks:</p> <ul> <li>General &gt; turn Animations off for faster performance.</li> <li>Appearance &gt; change themes.</li> <li>Extensions &gt; turn off Desktop icons.</li> </ul> <p>Open Firefox browser:</p> <ul> <li>Preferences &gt; Privacy &amp; Security &gt; check “Use a primary password” and set. This ensures your saved passwords are encrypted on your device.</li> <li>Add Firefox <a href="https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/?src=search">Multi-Account Containers</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/facebook-container/">Facebook Container</a></li> <li>Add adblocker such as <a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/?src=search">uBlock Origin</a></li> </ul> <p>Next you want some GNOME extensions. Earlier installations use <a href="https://extensions.gnome.org/">GNOME extensions</a> plugin and <a href="https://addons.mozilla.org/en/firefox/addon/gnome-shell-integration/">gnome-shell-integration</a> on Firefox to install and manage extensions. However, in newer installations using the Firefox snap this option no longer works! Install <code class="language-plaintext highlighter-rouge">gnome-shell-extension-manager</code> instead which gives you an app to find, install, and manage extensions. Try <a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine</a> (disable screen lock to watch movies or just not have your laptop locking all the time) or check some <a href="https://evanwill.github.io/_drafts/notes/ubuntu-gnome.html#get-extensions">other suggestions</a>.</p> <p>Enable firewall: <code class="language-plaintext highlighter-rouge">sudo ufw enable</code></p> <p>Next I like to have Gedit (“Text Editor”) customized so its ready as a quick editor. Open the app, then click the name in the top bar to open the app menu &gt; Preferences. See <a href="https://evanwill.github.io/_drafts/notes/gedit-editor.html">customization suggestions notes</a>.</p> <h2 id="install-essentials">Install Essentials</h2> <p>Check <a href="https://packages.ubuntu.com/">Ubuntu packages</a> and install <code class="language-plaintext highlighter-rouge">sudo apt install</code>:</p> <ul> <li><code class="language-plaintext highlighter-rouge">tlp tlp-rdw</code> (<a href="https://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html">advanced laptop power management</a>)</li> <li>development necessities: <code class="language-plaintext highlighter-rouge">build-essential git curl</code></li> </ul> <p>Note that some packages are transitioning to snaps instead traditional debs. Check <a href="https://snapcraft.io/store">snapcraft store</a> for snap details or find them in Ubuntu Software. I like to look for the official “Canonical” + checkmark as developer, since you have to pay attention to who packaged the snaps. From snap install:</p> <ul> <li>Chromium (browser)</li> <li>Visual Studio Code or Atom (editor)</li> <li>KeePassXC (password manager)</li> </ul> <h2 id="install-languages">Install Languages</h2> <p><em>Note</em>, 20.04 has some different system languages installed. It ships with Ruby 2.7 (new) and Python 3.8 (no more Python 2). In the terminal, Python is <code class="language-plaintext highlighter-rouge">python3</code>, so <code class="language-plaintext highlighter-rouge">which python</code> will come up with nothing.</p> <ul> <li>Ruby: <a href="https://evanwill.github.io/_drafts/notes/ruby-rbenv.html">rbenv</a> or <a href="https://evanwill.github.io/_drafts/notes/ruby-notes.html">RVM set up</a></li> <li>Python: <a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Anaconda set up</a></li> <li>Java: <code class="language-plaintext highlighter-rouge">sudo apt install default-jre</code> or <code class="language-plaintext highlighter-rouge">default-jdk</code> (this will be OpenJDK 11+, fine for apps like OpenRefine, if you need more specific versions search <a href="https://packages.ubuntu.com/search?keywords=jdk&amp;searchon=names&amp;suite=bionic&amp;section=all">packages</a>)</li> <li>Node: use <a href="https://github.com/creationix/nvm">nvm</a> (this seems to be the best method; install nvm, then <code class="language-plaintext highlighter-rouge">nvm install --lts</code>), or official <a href="https://github.com/nodesource/distributions/blob/master/README.md">NodeSource ppa</a>, or repository version <code class="language-plaintext highlighter-rouge">nodejs</code> (which is out of date)</li> </ul> Mon, 27 Apr 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu20.html https://evanwill.github.io/_drafts/notes/ubuntu20.html CONTENTdm metadata export tips <p>Many libraries use <a href="https://www.oclc.org/en/contentdm.html">CONTENTdm</a> (CDM) to create and host their digital collections. Because many workflows include creating and updating metadata in project client, your CDM repository may contain metadata that is not reflected in other sources. Additionally, you may want to get CDM numbers out of the system for your objects so that you can use the <a href="https://www.oclc.org/support/services/contentdm/help/customizing-website-help/other-customizations/contentdm-api-reference.en.html">CDM API</a> to access them–or to create “skins” like <a href="https://github.com/CollectionBuilder/collectionbuilder-contentdm">CollectionBuilder-CONTENTdm</a>.</p> <p>The most efficient way to get this metadata is to export it from the CDM admin interface. These tips assume you have access to a CDM instance’s admin interface–if you do not have access, check <a href="/_drafts/notes/contentdm-tips.html">CDM api tips</a> for other ways to harvest metadata.</p> <h2 id="export-collection-metadata">Export collection metadata</h2> <ol> <li>Log into your CDM admin (at a url something like “https://server12345.contentdm.oclc.org/cgi-bin/admin/start.exe” using your associated OCLC account).</li> <li>Click on “Collections” tab.</li> <li>Select desired collection from the drop down menu on left, then click “Change” to switch to that collection.</li> <li>Click on “export” in the nav under the “Collections” tab.</li> <li>On Export metadata page, choose “Tab-delimited”, check “Return field names in first record” option, and then click “next”.</li> <li>This will lead to an “Export successful” page. Right click on the “export.txt” and select “Save link as” from your context menu. This should open a file save dialog box on your computer–I usually rename the file from “export.txt” to something meaningful including the collection name and export date (“example_2020-12.txt”).</li> </ol> <p>At this point I also like to record some collection information for reference:</p> <ul> <li>Click “reports”, then “Item Types” to see total number of items and file types.You will want this information to check the accuracy of your metadata once you start processing the export.</li> <li>Click “profile” to find the “Collection alias” (e.g. <code class="language-plaintext highlighter-rouge">/example</code>). This will be necessary to construct API calls.</li> <li>Click “fields” to review the metadata template for the collection so you know what should be in the export.</li> </ul> <h2 id="reformat-exporttxt">Reformat “export.txt”</h2> <p>“Tab-delimited” text (also commonly called “tab-separated values” or TSV) is a plain text tabular data format, using tabs as the delimiter between columns. Like “Comma-separated values” (CSV), it is a convenient format for data exchange often used to store spreadsheet data, but is often implemented without a formal spec.</p> <p>The tab-delimited “export.txt” from CDM uses UTF-8 encoding and LF line endings, which are the standard on the web and Linux, but not well supported in default Windows applications. If you open the file directly with Excel, it has a good chance of being corrupted (messing up special characters or line breaks). Collections that include a full text field (e.g. extracted from PDFs) are particularly challenging to get parsed correctly. These errors are often hard to detect, so it is important to take care in initial handling the “export.txt” and reformat to a more useable file type.</p> <p>Here is some suggestion workflows:</p> <p><a href="https://openrefine.org/">OpenRefine</a> (free and open):</p> <ul> <li>Start OpenRefine.</li> <li>Select your “export.txt” and click “Next”.</li> <li>On the “Configure Parsing Options”, the preview will likely be all wrong. Choose <em>all</em> these options to parse correctly: <ul> <li>In “Parse data as” select “CSV / TSV / separator-based files”.</li> <li>In “Character encoding” click the box and select “UTF-8” (<em>this is essential to avoid losing special characters on Windows</em>).</li> <li>In “Columns are separated by” select “tabs (TSV)”.</li> <li>Uncheck the option ‘Use character “ to enclose cells containing column separators’ (<em>this is essential to avoid scrambled or losing records!</em>)</li> <li>Click “Create Project” to finish parsing / importing the data</li> </ul> </li> <li>Once set up, use Refine’s “Export” button to cleanly reformat. If you would like to work with Excel, use “.xlsx” option. For preservation and interchange, “Comma-separated value” is best option.</li> </ul> <p><a href="https://www.libreoffice.org/">LibreOffice Calc</a> (free and open):</p> <ul> <li>Open LibreOffice Calc, then File &gt; Open and choose your “export.txt”</li> <li>This will open the “Text Import” parsing options, choose these options: <ul> <li>“Character set” select “Unicode (UTF-8)”</li> <li>“Separator Options” choose “Separated by” and check <em>only</em> “Tab”.</li> <li>“Fields” use the box to select all the columns, then select “Column type” “text” (this will prevent it from reformatting dates and numbers).</li> <li>Click “Okay” to finish parsing.</li> </ul> </li> <li>Calc will allow you to safely save as CSV, ODS, or XLSX.</li> </ul> <p>Google Sheets:</p> <ul> <li>Open a new blank Sheet.</li> <li>Click “File” &gt; “Import” &gt; “Upload”, and choose your “export.txt”.</li> <li>This will open the “Import file”, choose these options: <ul> <li>“Import location” select “Replace current sheet”.</li> <li>“Separator type” select “Tab”.</li> <li>“Convert text to numbers, dates, and formulas” select “No” (to avoid reformatting dates and numbers and running into issues with full text field).</li> </ul> </li> </ul> <p>Excel (different versions have the menu options labeled differently, so these steps are just a vague approximation. As far as I can tell online Excel 365 can’t import data and can’t really be used for this process at all.):</p> <ul> <li>Open a new blank spreadsheet in Excel (<em>do not double click “export.txt” or open with Excel directly</em>)</li> <li>Click “Data” &gt; “From Text/CSV” (in “Get data” area left side of ribbon)</li> <li>This should pop open an “Import” options menu similar to the one described above for LibreOffice Calc–choose similar options. In “File origin” be sure to choose “Unicode (UTF-8)” or the parsing will have errors. (Excel 365 flashes some notices like “connecting” and “loading” data, as if you are setting up a live database connection–you can ignore this mysticism, its just importing data like normal).</li> </ul> <h2 id="metadata-notes">Metadata notes</h2> <p><strong>Admin fields:</strong> Exports contain a set of administrative metadata fields added by CDM. These are the last columns of the export, including: “Filename,OCLC number,Date created,Date modified,Reference URL,CONTENTdm number,CONTENTdm file name,CONTENTdm file path”. “CONTENTdm number” is the most useful, since this provides the “pointer” used along with the collection “alias” in API calls. The “Full Text” field is also usually auto generated by extracting text from uploaded items.</p> <p><strong>Compound objects:</strong> If your collection contains Compound objects (image or pdf), there will be a row for the object description, as well as each page of the compound object. The main object descriptions can be identified by checking “CONTENTdm file name” column for the extension <code class="language-plaintext highlighter-rouge">.cpd</code>. Page level item rows follow the main item, but can be difficult to disambiguate from normal items. Usually page level items do not have the full metadata filled out, so use a column always filled in object descriptions but blank in page level to isolate them. If you have extensive page level metadata this can be complex.</p> <h2 id="cdm-terms">CDM Terms</h2> <p>CDM uses some terminology for the components of their API:</p> <ul> <li>CDM server number: each hosted CDM has a number which is used in two different URLs in the “contentdm.oclc.org” subdomain, which are used for different types of API calls. <ul> <li>“CDM server URL” - this is where your CDM admin is hosted, named “server” + server number, e.g. <code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/</code>. In general collection level API calls have to go to this URL.</li> <li>“CDM website URL” - this is where your public CDM instance is exposed, named “cdm” + server number, e.g. <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/</code>. Many organizations have a custom domain in front of this subdomain which should work for most API calls. In general item level API calls have to go to this URL.</li> </ul> </li> <li>“Alias” - the identifier name for an individual collection, used in URLs. If set by CDM they look like <code class="language-plaintext highlighter-rouge">p17254coll3</code>, or can be manually created looking like <code class="language-plaintext highlighter-rouge">argonaut</code>.</li> <li>“pointer” / “CONTENTdm number” - the identifier number of an individual item or object assigned by the CDM database, e.g. <code class="language-plaintext highlighter-rouge">14</code>. If harvesting metadata, this value is usually called “pointer” in XML. However, it is found in metadata export as “CONTENTdm number”.</li> </ul> <p>If you look at the URL for at a CDM item page you can find the information. For example, in:</p> <p><code class="language-plaintext highlighter-rouge">https://cdm17254.contentdm.oclc.org/digital/collection/p17254coll3/id/155/rec/1</code></p> <p>The “CDM website URL” is <code class="language-plaintext highlighter-rouge">https://cdm17254.contentdm.oclc.org</code>, collection “Alias” is <code class="language-plaintext highlighter-rouge">p17254coll3</code>, and “pointer” is <code class="language-plaintext highlighter-rouge">155</code>.</p> <p>Check <a href="/_drafts/notes/contentdm-tips.html">CDM API tips</a> for API recipes to use / harvest digital objects.</p> Sat, 04 Apr 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/contentdm-meta.html https://evanwill.github.io/_drafts/notes/contentdm-meta.html Tea Data <p>This study seeks to find the best flavor black tea at the best value price point for bulk drinking at work in the library.</p> <h2 id="methodology">Methodology</h2> <p>Two library employees with extensive experience in tea drinking (i.e. drink at least one pot of tea per day) took part in a tasting session featuring seven widely available varieties of black tea. Each tea was prepared according to the manufacturer instructions printed on the box. A standard measure of milk was added to each prepared tea after the brew time was complete.</p> <p>Each tester sampled the tea taking several moments to savor the flavors. Testers general impressions were discussed and recorded, as well as an overall rating out of five possible points. The highest rating awarded by individual testers was four (Red Rose and Taylors Yorkshire), and the lowest was one (Tazo Awake).</p> <p>Prices of tea brands vary significantly at each grocery chain. To find a standardized price for comparisons, we chose to use the price at Walmart which carried all brands tested.</p> <h2 id="best-value">Best Value</h2> <p>In attempt to evaluate the best overall value, we used the equation:</p> <p><code class="language-plaintext highlighter-rouge">Mean Rating / Price per Tea Bag</code></p> <h3 id="base-value-ratings">Base Value Ratings</h3> <table> <thead> <tr> <th>Tea</th> <th>Value Rating</th> </tr> </thead> <tbody> <tr> <td>Red Rose</td> <td>1.077586207</td> </tr> <tr> <td>Taylors Yorkshire Red Tea</td> <td>0.7155635063</td> </tr> <tr> <td>Tetley British Blend</td> <td>0.6711409396</td> </tr> <tr> <td>PG Xtra Strong</td> <td>0.6276150628</td> </tr> <tr> <td>Twinnings Irish Breakfast</td> <td>0.5573248408</td> </tr> <tr> <td>Twinnings English Breakfast</td> <td>0.398089172</td> </tr> <tr> <td>Tazo Awake English Breakfast Tea</td> <td>0.2090301003</td> </tr> </tbody> </table> <p>This surfaced two surprising results:</p> <ul> <li>Best value was the rather unassuming <em>Red Rose Tea</em>, which tastes pretty good yet is available very cheap.</li> <li>Worst value was the popular <em>Tazo Awake</em>, very often served at conferences and hotels, which tastes terrible yet is very expensive.</li> </ul> <!-- (tast weight * rating)/(price weight * price)--> <h2 id="complete-tea-data">Complete Tea Data</h2> <link href="https://cdn.jsdelivr.net/npm/simple-datatables@latest/dist/style.css" rel="stylesheet" type="text/css" /> <table id="teaTable"> </table> <script src="https://cdn.jsdelivr.net/npm/simple-datatables@latest" type="text/javascript"></script> <script> const data = { headings: [ 'Tea', '$ Price / Bag', 'Mean Rating', 'Comments' ], data: [ [ 'Red Rose', 0.035, 3.75, 'Distinctive, different, easy drinking. Light flavor, but not weak.' ], [ 'Taylors Yorkshire Red Tea', 0.07, 4, 'Smooth, mild but favored. Pleasant.' ], [ 'Tetley British Blend', 0.037, 2, 'Ok. Not Great. Bland.' ], [ 'Twinnings Irish Breakfast', 0.126, 3.5, 'Richer and earthier than average.' ], [ 'Twinnings English Breakfast', 0.126, 2.5, 'Less Full Body than Irish Breakfast. Similar to Tetley, but better.' ], [ 'PG Xtra Strong', 0.12, 3, 'Not smooth, almost smokey. Not strong enough at recommended 2 min.' ], [ 'Tazo Awake English Breakfast Tea', 0.125, 1.25, 'Not flavorful. "Cheap tea" taste.' ] ] }; const teaTable = document.querySelector("#teaTable"); const config = { data, columns: [{ select: 2, sort: 'desc' }] }; const dt = new simpleDatatables.DataTable(teaTable, config); </script> <p><small>table powered by <a href="https://github.com/fiduswriter/Simple-DataTables">simple-datatables</a></small></p> Mon, 09 Mar 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/tea-data.html https://evanwill.github.io/_drafts/notes/tea-data.html Detect Website Platform <p>In January 2020 I completed a quick scan of university library websites to include in a paper I was writing. The data and method are shared as a repository, <a href="https://github.com/evanwill/library_websites_scan">library_websites_scan</a>, or on Zenodo <a href="https://doi.org/10.5281/zenodo.3653184">doi:10.5281/zenodo.3653184</a>.</p> <p>I wanted to share part of the method here, since it is basically just tips on how to inspect a web page and determine the platform used to build it.</p> <h2 id="platform-signatures">Platform signatures</h2> <p>To determine the platform, use “View Page Source” and “Inspect” developer tools to look at the base HTML code. Check the HTML for platform signatures. Occasionally, the main index page has more customization and added features than other content pages, thus is harder to determine the platform–in that case, visit a less busy page to view the code.</p> <p><strong>Drupal</strong> based sites:</p> <ul> <li>usually include the generator meta tag with the major version number, <ul> <li><code class="language-plaintext highlighter-rouge">&lt;meta name="Generator" content="Drupal 8 (https://www.drupal.org)" /&gt;</code></li> <li><code class="language-plaintext highlighter-rouge">&lt;meta name="generator" content="Drupal 7 (https://www.drupal.org)" /&gt;</code></li> </ul> </li> <li>older sites usually load CSS as a huge series of import statements, with the file paths including “/modules/”, e.g. <code class="language-plaintext highlighter-rouge">@import url("https://example.edu/modules/system/system.base.css?q4zjuk");</code></li> <li>newer sites usually load CSS as a smaller series of CSS files, with the file paths including “/files/”, and filenames with a bunch of random characters, e.g. ` <link rel="stylesheet" media="all" href="/files/css/css_m7u_1cZUfQut08KzfMvXKdCtsaNcW8FRd5XXUI_Z_cU.css?q55bom" />`</li> <li>usually have a JS file, JS object, and element attributes that include “drupal”, e.g. <code class="language-plaintext highlighter-rouge">data-drupal-selector="drupal-settings-json"</code></li> <li>often use links/src that contain “/node/”</li> </ul> <p><strong>WordPress</strong> based sites:</p> <ul> <li>usually include the generator meta tag with version number, <ul> <li><code class="language-plaintext highlighter-rouge">&lt;meta name="generator" content="WordPress 4.9.10" /&gt;</code></li> <li><code class="language-plaintext highlighter-rouge">&lt;meta name="generator" content="WordPress 5.3.2" /&gt;</code></li> </ul> </li> <li>usually contain the short link “s.w.org” (which resolves to wordpress.org), e.g. <code class="language-plaintext highlighter-rouge">&lt;link rel='dns-prefetch' href='//s.w.org' /&gt;</code></li> <li>usually use asset paths that contain “wp-“, e.g. <code class="language-plaintext highlighter-rouge">href='//example.edu/wp-content/themes/eu-2014/style.css?ver=3.6'</code></li> </ul> <p><strong>ASP.NET</strong> based sites:</p> <ul> <li>usually include classes that include <code class="language-plaintext highlighter-rouge">aspNet</code>, e.g. <code class="language-plaintext highlighter-rouge">class="aspNetHidden"</code>.</li> <li>usually contain “viewstate” variables such as <code class="language-plaintext highlighter-rouge">&lt;input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="0DhWp/KtK1Wf-some-crazy-string" /&gt;</code> and other ids with “__” in front of the name.</li> <li>usually contain links/src ending in <code class="language-plaintext highlighter-rouge">.aspx</code> or <code class="language-plaintext highlighter-rouge">.axd</code></li> <li>may contain a generator meta tag giving a specific CMS platform, e.g. <code class="language-plaintext highlighter-rouge">&lt;meta name="Generator" content="Sitefinity 11.2.6900.0 PE" /&gt;</code></li> <li>may use asset paths that include a specific CMS name, e.g. <code class="language-plaintext highlighter-rouge">src="https://example.azureedge.net/sitefinity-production/images/example-icon.png?sfvrsn=11106867"</code></li> </ul> <p><strong>PHP</strong> based sites:</p> <ul> <li>contain links/src ending in <code class="language-plaintext highlighter-rouge">.php</code></li> </ul> Mon, 03 Feb 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/website_scan.html https://evanwill.github.io/_drafts/notes/website_scan.html Quick Local Static Servers <p>Three quick local static web server for dev or what ever.</p> <h2 id="python">Python</h2> <p>Use <a href="https://docs.python.org/3/library/http.server.html">http.server</a> from the standard library:</p> <p><code class="language-plaintext highlighter-rouge">python -m http.server 8000</code> then surf to <code class="language-plaintext highlighter-rouge">localhost:8000</code></p> <p>(in python 2: <code class="language-plaintext highlighter-rouge">python -m SimpleHTTPServer</code>)</p> <h2 id="ruby">Ruby</h2> <p>Use Ruby WEBrick server with handy command from standard <a href="https://ruby-doc.org/stdlib-2.7.1/libdoc/un/rdoc/un_rb.html">“un”</a> library:</p> <p><code class="language-plaintext highlighter-rouge">ruby -run -e httpd . -p 8080</code> then surf to <code class="language-plaintext highlighter-rouge">localhost:8080</code></p> <p>(see <a href="https://idiosyncratic-ruby.com/6-run-ruby-run.html">Run, Ruby, Run</a> for details of this idiosyncratic command)</p> <h2 id="node">Node</h2> <p>Use <a href="https://www.npmjs.com/package/http-server">http-server</a> package. Install <code class="language-plaintext highlighter-rouge">npm install -g http-server</code>. Then:</p> <p><code class="language-plaintext highlighter-rouge">http-server</code> in the directory to serve</p> Wed, 29 Jan 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/web-server.html https://evanwill.github.io/_drafts/notes/web-server.html Ruby RVM Notes <p><a href="https://www.ruby-lang.org/en/">Ruby</a> is an interesting language, but can be a bit frustrating with the many versions and incompatibilities. My main use is for working with <a href="https://jekyllrb.com/">Jekyll</a> or <a href="http://rubyonrails.org/">Ruby on Rails</a>.</p> <p>On Windows I always use <a href="https://rubyinstaller.org/">RubyInstaller</a>, which seems to work well.</p> <p>On Linux, I have tried the version in the distro repositories (Ubuntu: <code class="language-plaintext highlighter-rouge">ruby-full</code>), but this is usually fairly out-of-date and can cause some headaches (such as requiring <code class="language-plaintext highlighter-rouge">sudo</code> to install gems, unless you edit your bash profile, see Jekyll <a href="https://jekyllrb.com/docs/installation/ubuntu/" target="_blank" rel="noopener">Ubuntu install docs</a>). On Ubuntu 19.10 <code class="language-plaintext highlighter-rouge">ruby-full</code> will be version 2.5.1, and updates are rare.</p> <p>A better, easy alternative is to use the official <a href="https://snapcraft.io/ruby">Ruby snap package</a> maintained by the Ruby core team which stays up-to-date. Install using <code class="language-plaintext highlighter-rouge">sudo snap install ruby –classic</code> (<em>note:</em> the <code class="language-plaintext highlighter-rouge">-classic</code> flag means the snap will not be “confined”, since Ruby will need full access to your system to function. Snaps requiring <code class="language-plaintext highlighter-rouge">-classic</code> are audited by the repository). The snap will keep itself up-to-date, so may change versions on you. You may need to install additional build tools as well (at least ` build-essential zlib1g-dev`).</p> <p>However, you might want to use a Ruby version manager to keep your dependencies in order and separate from your system Ruby. I have used <a href="https://rvm.io/">RVM</a> described below–however, more recently switched to using rbenv (see <a href="https://evanwill.github.io/_drafts/notes/ruby-rbenv.html">rbenv notes</a>).</p> <p>When installing RVM on Ubuntu there can be some barriers because the way RVM functions isn’t compatible with the default set up of Gnome terminal–either you can reconfigure, or do a little workaround by setting up a second terminal.</p> <h2 id="set-up-rvm-on-ubuntu">Set up RVM on Ubuntu</h2> <p>Install curl and build-essential if you don’t have them (<code class="language-plaintext highlighter-rouge">sudo apt install curl build-essential</code>).</p> <p>Set up Tilix:</p> <ul> <li>Install Tilix terminal emulator (<code class="language-plaintext highlighter-rouge">sudo apt install tilix</code>)</li> <li>Open Tilix</li> <li>Click on the user name above the terminal window, select Profiles &gt; Edit Profile.</li> <li>Click on Command tab, check “Run command as a login shell”</li> <li>Close Tilix</li> </ul> <p>Open Tilix and install RVM using the <a href="https://rvm.io/rvm/install">official instructions</a> (note: there is a <a href="https://github.com/rvm/ubuntu_rvm">PPA for Ubuntu</a> that can take care of everything).</p> <p>Install a Ruby version, probably the most recent stable (listed on <a href="https://www.ruby-lang.org/en/downloads/">Ruby downloads</a>), for example: <code class="language-plaintext highlighter-rouge">rvm install 2.7.0</code>. This will download all the dependencies and build the Ruby version, which might take awhile…</p> <p>When it completes, check your Ruby, <code class="language-plaintext highlighter-rouge">ruby -v</code>. If this is your first version, it will become the default, or you can select one, <code class="language-plaintext highlighter-rouge">rvm use 2.7.0</code>. If you want to generate the documentation, run <code class="language-plaintext highlighter-rouge">rvm docs generate-ri</code>.</p> <p>Now you can install Jekyll: <code class="language-plaintext highlighter-rouge">gem install bundler jekyll</code></p> <p>Once you restart your system, Gnome terminal will recognize your current Ruby version. Use RVM from Tilix.</p> <p>Intros:</p> <ul> <li><a href="https://ruby.github.io/TryRuby/">TryRuby (in browser)</a></li> <li><a href="https://www.ruby-lang.org/en/documentation/quickstart/">Ruby in Twenty Minutes</a></li> <li><a href="http://railsforzombies.org/">Rails for Zombies</a></li> </ul> Sat, 04 Jan 2020 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ruby-notes.html https://evanwill.github.io/_drafts/notes/ruby-notes.html Introduction to CDIL <blockquote> <p>Notes and links for Honors visit to CDIL. The Center for Digital Inquiry and Learning (CDIL) is a collaboration between the College of Letters, Arts and Social Sciences (CLASS) and the University of Idaho Library. Its purpose is to advance digital scholarship opportunities at the University of Idaho.</p> </blockquote> <h2 id="introductions">Introductions</h2> <ul> <li>Introductions</li> <li>Digital Humanities and Digital Scholarship???</li> <li><a href="https://whatisdigitalhumanities.com/">What is DH</a></li> <li><a href="https://cdil.lib.uidaho.edu/">Center for Digital Inquiry and Learning (CDIL)</a></li> </ul> <h2 id="cdil-projects">CDIL Projects</h2> <p>Learning, outreach, events:</p> <ul> <li><a href="https://palousedh.github.io/symposium/">Palouse Digital Scholarship Symposium</a></li> <li><a href="https://poetry.lib.uidaho.edu/">Vandal Poem of the Day</a></li> </ul> <p>Research, publishing, digital collections:</p> <ul> <li><a href="https://www.lib.uidaho.edu/digital/hjccc/">Historical Japanese Ceramic Comparative Collection</a> (Graduate fellow Renae Campbell, Historical Archaeology)</li> <li><a href="https://uidaho.maps.arcgis.com/apps/Cascade/index.html?appid=a459d05f5e2c4b5c9cd9e535e0c4afaa">Closure of Syringa</a> (Undergraduate fellow Denessy Rodriguez, Sociology &amp; Anthropology)</li> <li><a href="https://ctrl-shift.org">CTRL+SHIFT</a> (Devin Becker, graduate fellows Corey Oglesby and Lauren Westerfield, MFA)</li> <li><a href="https://www.lib.uidaho.edu/digital/cccidaho/">CCC in Idaho</a> (Patricia Hart, JAMM)</li> </ul> <p>Software:</p> <ul> <li><a href="https://github.com/uidaholib/syringa-project">researchlab-template (syringa project)</a></li> <li><a href="https://collectionbuilder.github.io/">CollectionBuilder</a></li> <li><a href="https://github.com/evanwill/poemBot">poemBot</a></li> </ul> <h2 id="virtual-reality">Virtual Reality</h2> <ul> <li>Oculus Rift</li> <li>HTC Vive</li> <li>Sony PlayStation VR</li> </ul> Mon, 11 Nov 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/cdil-intro.html https://evanwill.github.io/_drafts/notes/cdil-intro.html Intro to Raspberry Pi <blockquote> <p>Please see <a href="https://evanwill.github.io/_drafts/notes/rpi-intro2.html">newer version of this outline</a>. Some content below is out of date.</p> </blockquote> <h2 id="arduino-vs-raspberry-pi">Arduino vs. Raspberry Pi</h2> <p>Both are very flexible, with great documentation and community.</p> <p>Arduino:</p> <ul> <li>microcontroller, 8-bit, tiny memory</li> <li>very simple, solid, reliable</li> <li>very low power consumption</li> <li>do one thing really well</li> </ul> <p>Raspberry Pi:</p> <ul> <li>Single board computer, 32/64-bit CPU, 512MB - 4GB RAM</li> <li>Connect: USB, Ethernet, Wifi, Bluetooth</li> <li>Output: Video (HDMI), audio (HDMI, 3.5mm jack), GPIO pins</li> <li>Full operating system</li> <li>Use high-level programming languages (mainly Python)</li> <li>can do MUCH more than Arduino, but… <ul> <li>consumes much more power and requires steady power supply</li> <li>OS requires updates</li> <li>less reliable overall</li> </ul> </li> </ul> <p>e.g. <a href="https://github.com/evanwill/poemBot">poemBot</a></p> <h3 id="raspberry-pi-starter-kit">Raspberry Pi starter kit</h3> <ul> <li><a href="https://www.raspberrypi.org/products/">Boards</a> (A, B, Zero, Compute, <a href="https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications">spec chart</a>)</li> <li>Power supply (you need a good one! A rainbow icon shows up on screen if power goes low)</li> <li>SD card (try to get decent quality, high read/write speed, “SDHC, Class 10 / UHS 3”, min 8GB)</li> <li><a href="https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable/overview">Console cable</a></li> <li><a href="https://www.logitech.com/en-us/product/wireless-touch-keyboard-k400r?crid=27">Keyboard</a>, mouse, HDMI cord</li> <li>add ons / HATs</li> <li><a href="https://www.adafruit.com/product/1988">ribbon cable</a> + breadboard</li> </ul> <h1 id="get-started">Get Started</h1> <p>First step is to choose an OS for your Pi and burn it to your SD card. See <a href="https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up">official step-by-step</a> for a visual walk through. Most likely you will want to start with NOOBS (does not require burning image) or an image of Raspbian:</p> <p><strong>NOOBS</strong></p> <ul> <li><a href="https://www.raspberrypi.org/downloads/noobs/">NOOBS</a> is an automatic Pi OS installer designed to be super simple</li> <li>Download NOOBS, unzip, copy to SD card (you do NOT burn an image, just copy)</li> <li>Plugin SD, connect video, keyboard, and power to Pi</li> <li>Follow instructions!</li> </ul> <p><strong>Burn image to SD</strong></p> <ul> <li>See <a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn ISO note</a></li> <li>Download <a href="https://www.raspberrypi.org/downloads/raspbian/">Raspbian</a> (headless or desktop) (Linux distro for Pi, based on <a href="https://www.debian.org/">Debian</a>, see <a href="https://evanwill.github.io/_drafts/notes/linux-intro.html">Intro to Linux note</a>)</li> <li><a href="https://www.sdcard.org/downloads/formatter/index.html">SD Formatter</a></li> <li><a href="https://www.balena.io/etcher/">Etcher</a></li> <li>Plug SD into Pi, boot up!</li> <li>see <a href="https://www.raspberrypi.org/documentation/raspbian/">Raspbian docs</a></li> </ul> <h2 id="use-pi">Use Pi</h2> <ul> <li>GUI (i.e. plugin HDMI, this is often easiest way to get started, even if you are planning to go headless)</li> <li><a href="https://learn.adafruit.com/adafruits-raspberry-pi-lesson-5-using-a-console-cable/overview">console cable</a> (can be handy for developing headless projects, can provide power to the board)</li> <li>SSH (not possible on university wifi) <code class="language-plaintext highlighter-rouge">ssh [email protected]</code> <ul> <li>enable on Pi</li> <li><a href="https://www.raspberrypi.org/documentation/remote-access/ip-address.md">find IP address</a></li> <li><a href="https://www.raspberrypi.org/documentation/remote-access/ssh/README.md">use SSH</a></li> <li>copy files to Pi: <code class="language-plaintext highlighter-rouge">scp filename [email protected]:~/destination/foldername/</code></li> <li>copy files from Pi: <code class="language-plaintext highlighter-rouge">scp [email protected]:~/source/file /destination/directory/</code></li> </ul> </li> <li><a href="https://www.raspberrypi.org/documentation/remote-access/vnc/README.md">VNC (virtual desktop)</a> <ul> <li>enable/install on Pi</li> <li>install client, use cloud service</li> </ul> </li> <li>Tip: plug SD into computer to directly edit file system!</li> <li><code class="language-plaintext highlighter-rouge">/etc/rc.local</code> file runs at boot, so you can add command line calls to start your program</li> </ul> <h2 id="resources">Resources</h2> <ul> <li>Offical Raspberry Pi <a href="https://www.raspberrypi.org/documentation/">Documentation</a>, <a href="https://www.raspberrypi.org/help/">Help</a>, and <a href="https://www.raspberrypi.org/forums/">Forum</a></li> <li><a href="https://learn.adafruit.com/">Adafruit Learn</a>, <a href="https://learn.adafruit.com/category/learn-raspberry-pi">pi category</a></li> <li>Play around to learn more: <a href="https://volumio.org/">Volumio</a> music center, <a href="https://retropie.org.uk/">RetroPi</a></li> </ul> Mon, 07 Oct 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/rpi-intro.html https://evanwill.github.io/_drafts/notes/rpi-intro.html Visual Studio Code Notes <p><a href="https://code.visualstudio.com">Code</a> is an open source text editor from microsoft (<a href="https://code.visualstudio.com/Docs">docs</a>). It is (<em>was??</em>) light weight compared to most traditional IDE, yet fully featured and efficient. I find it perfect for working on web projects (i.e. <em>Open Folder</em> not a file), such as using Jekyll, with Git nicely integrated.</p> <blockquote> <p>The <a href="https://vscodium.com/">VSCodium</a> project provides an alternative all open source + no tracking version of VS Code. VS Code is open source, however, the installers you download from MS include additional non-open-source components and extra MS tracking features.</p> <p><em>Update:</em> unfortunately MS seems to be continuously adding more and more features (i.e. junk) all the time–taking it from a nice minimalist editor, to yet another bloated piece of software. I am still using it, but starting to get frustrated by more and more features that I don’t want and actually get in the way of working. Almost every update I have to figure out how to turn off another feature. Typical MS…</p> </blockquote> <p>To configure the editor click the cog icon in the lower left and choose <em>Settings</em> (or go to <em>File</em> &gt; <em>Preferences</em> &gt; <em>Settings</em>, or <code class="language-plaintext highlighter-rouge">Ctrl + ,</code>). This will bring up the visual settings editor which can be searched to find options. By clicking the file icon in the upper right of the Settings pane will switch to the <code class="language-plaintext highlighter-rouge">settings.json</code> view. This allows you to view the key + value pairs representing your settings, or allow you to paste in new ones that will override the default settings. This is <em>very</em> handy for sharing your set up–just copy the values and save in a text file, then paste the values on a different computer (see my version pasted at the bottom). The Settings are cross-platform, so they will work on any computer, with a few that are specific to each OS.</p> <p>Here are my notes-to-self about stuff:</p> <h2 id="config-preferences">Config preferences</h2> <p>A few highlights:</p> <ul> <li>Enable word wrap: <code class="language-plaintext highlighter-rouge">"editor.wordWrap": "on"</code></li> <li>Get rid of excessive stuff in file explorer: <code class="language-plaintext highlighter-rouge">"problems.decorations.enabled": false</code></li> <li>Hide minimap, sometimes I find the map annoyingly in the way: <code class="language-plaintext highlighter-rouge">"editor.minimap.enabled": false</code></li> <li>Disable clearing clipboard if you accidentally <code class="language-plaintext highlighter-rouge">Ctrl+C</code> on blank line: <code class="language-plaintext highlighter-rouge">"editor.emptySelectionClipboard": false</code></li> <li>Disable annoying drag and drop selection moving: <code class="language-plaintext highlighter-rouge">"editor.dragAndDrop": false</code></li> <li>Disable annoyingly unhelpful html tag closing: <code class="language-plaintext highlighter-rouge">"html.autoClosingTags": false</code></li> <li>Disable annoying persistent terminal sessions which cause endless errors: <code class="language-plaintext highlighter-rouge">"terminal.integrated.enablePersistentSessions": false</code></li> <li>Disable weird git visualization that is super distracting in source control panel: <code class="language-plaintext highlighter-rouge">"scm.showHistoryGraph": false</code></li> </ul> <p>There is an ever increasing number of “helpful” “smart” auto select and delete things (seemingly modelled after the utterly infuriating and worthless features of MS Word) regularly added, so I end up spending a lot of time trying to turn things off. But, once you have everything set up nicely, copy your <code class="language-plaintext highlighter-rouge">settings.json</code> file to a git repo and reuse it on all your computers! (example at the bottom of this note)</p> <h2 id="integrated-terminal">Integrated terminal</h2> <p>Access a terminal without leaving the editor by typing Ctrl + `   (control + backtick). This is extremely handy when developing Jekyll projects, since you can <code class="language-plaintext highlighter-rouge">jekyll s</code> and have the output easily visible while you are editing. I also use it for any non-routine Git activity, since the built in GUI client is only good for basic <code class="language-plaintext highlighter-rouge">git add/commit/push</code> equivalents.</p> <p>The terminal is very straight forward (automatic) on Linux or Mac, but on Windows the default terminal is horrible old cmd. The first time you open the terminal on Windows, it should prompt you to with options to change to other terminals you have installed (i.e. Git Bash, WSL Bash, or PowerShell). If you don’t get the prompt, click the drop down on the left side of the terminal window that says “Command Prompt” and select “Select Default Shell”. This should open a list of option in the “command pallet” at the top of the window. Or override the setting <code class="language-plaintext highlighter-rouge">"terminal.integrated.shell.windows": "C:\\Windows\\system32\\cmd.exe"</code> with the path to the terminal you want to use.</p> <h2 id="extensions">Extensions</h2> <p>Code has a growing ecosystem of extensions. Click the Extensions icon on the left side and search in the box to find new ones.</p> <ul> <li>Spell check: I use <a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker">“Code Spell Checker”</a>, and it seems really good and avoids a lot of code-related false positives.</li> <li>CSV highlighter: <a href="https://marketplace.visualstudio.com/items?itemName=mechatroner.rainbow-csv">“Rainbow CSV”</a>, this is incredibly helpful for looking at CSVs.</li> <li>Data viz: <a href="https://marketplace.visualstudio.com/items?itemName=msrvida.vscode-sanddance">SandDance for VSCode</a> (handy for looking at CSV contents)</li> <li>Arduino: If you have Arduino IDE installed on your system, you can add similar functionality to Code. Search for “Arduino” from Microsoft. Now when you open a <code class="language-plaintext highlighter-rouge">.ino</code> sketch, you will have options at the bottom of the window to select your board and port. More info <a href="https://github.com/Microsoft/vscode-arduino">vscode-arduino</a>.</li> <li>XML: “XML Language Support”</li> </ul> <h2 id="multi-cursor">Multi-cursor</h2> <p>To add more cursors to work on multiple lines at once, <code class="language-plaintext highlighter-rouge">Alt</code> and left-click (or toggle to <code class="language-plaintext highlighter-rouge">Ctrl</code> + left-click in Selection menu).</p> <h2 id="html">HTML</h2> <p>Auto format html, highlight area and type <code class="language-plaintext highlighter-rouge">Ctrl+K</code> followed by <code class="language-plaintext highlighter-rouge">Ctrl+F</code> (or maybe <code class="language-plaintext highlighter-rouge">Ctrl+Shift+I</code>). Setting for auto format are in Settings, add <code class="language-plaintext highlighter-rouge">"html.format.wrapLineLength": 0,</code> to prevent auto link breaks.</p> <p>Emmet snippet expansion: write the abbreviation and press <code class="language-plaintext highlighter-rouge">tab</code> (<a href="http://docs.emmet.io/cheat-sheet/">Emmet Cheatsheet</a>).</p> <h2 id="markdown-preview">Markdown preview</h2> <p>Click <code class="language-plaintext highlighter-rouge">Ctrl+Shift+V</code> to preview rendered file.</p> <h2 id="change-themes">Change themes</h2> <p>Type <code class="language-plaintext highlighter-rouge">Ctrl+K</code> then <code class="language-plaintext highlighter-rouge">Ctrl+T</code>, then choose a theme from the list. Get more themes from the Extensions shop.</p> <h2 id="settings">Settings</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{ "editor.fontFamily": "'Fira Code', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'", "editor.wordWrap": "on", "breadcrumbs.enabled": false, "editor.autoClosingBrackets": "never", "editor.autoClosingQuotes": "never", "editor.autoSurround": "never", "editor.codeLens": false, "editor.colorDecorators": false, "editor.copyWithSyntaxHighlighting": false, "editor.dragAndDrop": false, "editor.emptySelectionClipboard": false, "editor.links": false, "editor.acceptSuggestionOnCommitCharacter": false, "editor.acceptSuggestionOnEnter": "off", "editor.quickSuggestionsDelay": 100, "workbench.enableExperiments": false, "workbench.startupEditor": "none", "workbench.statusBar.feedback.visible": false, "explorer.enableDragAndDrop": false, "outline.problems.badges": false, "outline.problems.enabled": false, "outline.problems.colors": false, "extensions.ignoreRecommendations": true, "problems.autoReveal": false, "html.autoClosingTags": false, "html.format.maxPreserveNewLines": 2, "terminal.integrated.cursorBlinking": true, "terminal.integrated.rightClickBehavior": "default", "html.format.wrapLineLength": 0, "git.terminalAuthentication": false, "cSpell.enabledLanguageIds": [ "asciidoc", "c", "cpp", "csharp", "css", "git-commit", "go", "handlebars", "haskell", "html", "jade", "java", "javascript", "javascriptreact", "json", "jsonc", "latex", "less", "markdown", "php", "plaintext", "python", "pug", "restructuredtext", "rust", "scala", "scss", "text", "typescript", "typescriptreact", "yaml", "yml", "xml" ], //"terminal.integrated.sendKeybindingsToShell": true, "problems.decorations.enabled": false, "rainbow_csv.enable_tooltip": false, "rainbow_csv.enable_tooltip_warnings": false, "rainbow_csv.enable_tooltip_column_names": false, "terminal.integrated.enableFileLinks": false, "terminal.integrated.experimentalLinkProvider": false, "terminal.integrated.altClickMovesCursor": false, "terminal.integrated.gpuAcceleration": "off", "workbench.settings.enableNaturalLanguageSearch": false, "telemetry.telemetryLevel": "off", "cSpell.enableFiletypes": [ "csv" ], "html.autoCreateQuotes": false, "editor.autoClosingDelete": "never", "editor.autoClosingOvertype": "never", "workbench.editor.enablePreview": false, "terminal.integrated.enablePersistentSessions": false, "terminal.integrated.persistentSessionReviveProcess": "never", "editor.smartSelect.selectLeadingAndTrailingWhitespace": false, "editor.smartSelect.selectSubwords": false, "editor.minimap.enabled": false, "editor.unicodeHighlight.ambiguousCharacters": false, "editor.pasteAs.showPasteSelector": "never", "markdown.editor.filePaste.enabled": "never", "markdown.editor.pasteUrlAsFormattedLink.enabled": "never", "scm.showHistoryGraph": false } </code></pre></div></div> <h2 id="old-notes">Old Notes</h2> <p>A few things are easier now–below are some older notes about configuring things the hard way.</p> <p>To use Git Bash as Windows terminal, look in Git’s <code class="language-plaintext highlighter-rouge">bin</code> directory in the program files (on Win 10 this should be <code class="language-plaintext highlighter-rouge">C:\Program Files\Git\bin</code> or something more complicated on Win 7 like <code class="language-plaintext highlighter-rouge">C:\Users\username\AppData\Local\Programs\Git\bin</code>). In your settings replace the cmd path with the full path to <code class="language-plaintext highlighter-rouge">bash.exe</code>, and escape the back slashes, e.g. <code class="language-plaintext highlighter-rouge">"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe"</code>.</p> <p>(note: shortcuts to Git Bash terminal on your desktop and start menu will point to <code class="language-plaintext highlighter-rouge">C:\Program Files\Git\git-bash.exe</code>, the MinTTY terminal. If you use that app, Code will open a new external terminal. To use Git Bash on the built in terminal make sure you are pointing to the <code class="language-plaintext highlighter-rouge">bin\bash.exe</code>).</p> Tue, 01 Oct 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/vs-code.html https://evanwill.github.io/_drafts/notes/vs-code.html Library Intro Notes <blockquote> <p>Notes for graduate student meeting introducing library resources.</p> </blockquote> <h2 id="library-services">Library Services</h2> <p>Get help:</p> <ul> <li><a href="https://www.lib.uidaho.edu/help/" target="_blank" rel="noopener">Reference Desk</a> (Ask a reference librarian: walk up, chat, email, phone, don’t be shy! <a href="https://www.lib.uidaho.edu/about/hours.html#reference" target="_blank" rel="noopener">Hours</a>)</li> <li><a href="https://www.lib.uidaho.edu/" target="_blank" rel="noopener">Library website!</a> (there is a ton of information and resources here)</li> </ul> <p>Resources:</p> <ul> <li>Summit (network of 37 NW academic libraries in <a href="https://www.orbiscascade.org/member/" target="_blank" rel="noopener">Orbis Cascade Alliance</a>) and <a href="https://www.lib.uidaho.edu/services/ill/" target="_blank" rel="noopener">ILL</a> (worldwide network for library sharing)</li> <li><a href="https://www.lib.uidaho.edu/services/reserve/" target="_blank" rel="noopener">Reserves</a> (save your students money!)</li> <li><a href="https://www.lib.uidaho.edu/find/request.html" target="_blank" rel="noopener">Book purchase requests</a></li> </ul> <p>More stuff:</p> <ul> <li><a href="https://www.lib.uidaho.edu/services/workshops/" target="_blank" rel="noopener">Workshops</a></li> <li><a href="https://vivo.nkn.uidaho.edu/vivo" target="_blank" rel="noopener">VIVO UI Research</a></li> <li><a href="https://www.lib.uidaho.edu/services/oapf/" target="_blank" rel="noopener">OA Fund</a></li> <li><a href="https://www.lib.uidaho.edu/mill/" target="_blank" rel="noopener">The MILL</a> and <a href="https://www.lib.uidaho.edu/studio/" target="_blank" rel="noopener">The Studio</a></li> </ul> <h2 id="library-catalog">Library Catalog</h2> <p><a href="https://alliance-primo.hosted.exlibrisgroup.com/primo-explore/search?tab=everything&amp;search_scope=everything&amp;vid=UID" target="_blank" rel="noopener">Primo</a> Discovery</p> <ul> <li>Content: everything that the library has access to (books, journals, gov docs, articles, physical and digital)</li> <li>Less focused and powerful than databases</li> <li>Use notes: <ul> <li>sign in (access resources off campus)</li> <li>account (check loan status, saved items/searches/history)</li> <li>scopes (UI Library, Summit, Articles, Reserves)</li> <li>filters (date, resource type, etc)</li> <li>“personalize” (weights search results in your discipline)</li> <li>item features (citation, permalink, email, summit libraries, virtual browse)</li> <li>advanced search, personalize, facets</li> </ul> </li> </ul> <h2 id="databases">Databases</h2> <p><a href="https://libguides.uidaho.edu/az.php" target="_blank" rel="noopener">Database A-Z List</a> (all databases that the Library subscribes to)</p> <ul> <li>Content: each database has a specialized set of materials with enhanced metadata to aid in discovery.</li> <li>Use notes: <ul> <li>databases may <em>not</em> include full text access</li> <li>each may have different limitations and restrictions</li> <li>use proxy to access from off campus</li> </ul> </li> </ul> <p>Important ENGR databases:</p> <ul> <li><a href="https://uidaho.idm.oclc.org/login?url=http://ieeexplore.ieee.org/" target="_blank" rel="noopener">IEEE Xplore</a> (standards, personalized account)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://www.engineeringvillage.com/" target="_blank" rel="noopener">Engineering Village / Compendex</a></li> <li><a href="https://uidaho.idm.oclc.org/login?url=http://dl.acm.org/dl.cfm" target="_blank" rel="noopener">ACM Digital Library</a> (conference proceedings)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://search.proquest.com/pqdtft/advanced?accountid=14551" target="_blank" rel="noopener">Dissertations &amp; Theses PQDT</a> (ETD database for most universities)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://www.safaribooksonline.com/library/view/temporary-access/" target="_blank" rel="noopener">Safari: O’Reilly Learning Platform</a> (handy tech learning resources)</li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://scifinder.cas.org/" target="_blank" rel="noopener">SciFinder</a> (patents, chemical abstracts)</li> </ul> <h2 id="research-concepts">Research Concepts</h2> <p>Scholarly literature:</p> <ul> <li><a href="https://www.lib.ncsu.edu/tutorials/peerreview/" target="_blank" rel="noopener">Peer Review</a></li> <li><a href="http://guides.library.cornell.edu/graylit" target="_blank" rel="noopener">Grey Lit</a></li> <li>Preprint archives, e.g. <a href="https://arxiv.org/" target="_blank" rel="noopener">arXiv</a> or <a href="https://engrxiv.org/" target="_blank" rel="noopener">engrXiv</a></li> </ul> <p>Citation:</p> <ul> <li><a href="http://libguides.uidaho.edu/citing" target="_blank" rel="noopener">Citation guide</a></li> <li><a href="http://libguides.uidaho.edu/citation-management" target="_blank" rel="noopener">Citation management software</a> (tools to store citations and create bibliographies. Start using one now, it will make your life so much easier!)</li> </ul> <p>General search strategies:</p> <ul> <li>Booleans (AND, OR, NOT)</li> <li>Keywords and concept mapping (broader, narrower, related, synonyms / thesaurus. <a href="https://youtu.be/v_8rNiW4A9A" target="_blank" rel="noopener">intro video</a>)</li> <li>Citation chaining (look at what an important paper in your area cites and who cites it)</li> </ul> <h2 id="web-of-science"><a href="https://uidaho.idm.oclc.org/login?url=http://webofknowledge.com/UA" target="_blank" rel="noopener">Web of Science</a></h2> <ul> <li>Content: wide coverage of science scholarly/peer-reviewed articles from the most important journals and conference proceedings <ul> <li>Index only (metadata, not full text), contains items that the Library might not have access to.</li> </ul> </li> <li>Excellent citation tracking, enables in depth citation chaining</li> <li>Filter by highly cited, “hot in the field”, etc., to explore subject area</li> <li>Export data, citation lists</li> <li><a href="https://youtu.be/xwhy0JBHlMw" target="_blank" rel="noopener">WoS Search intro video</a>, <a href="http://clarivate.libguides.com/ld.php?content_id=35888196" target="_blank" rel="noopener">quick ref</a></li> </ul> <h2 id="google-scholar"><a href="https://scholar.google.com" target="_blank" rel="noopener">Google Scholar</a></h2> <ul> <li>Content: good content coverage of academic literature, but not all peer-reviewed and sources are not always clearly labeled <ul> <li>Index only (metadata, not full text), contains items that the Library might not have access to.</li> </ul> </li> <li>Familiar / easy to search</li> <li>Good citation tracking</li> <li>Connect to UI Library: <ul> <li>Adding UI Library to your Scholar account will provide a link to full text content in search results via our subscriptions.</li> <li>Log in to Google Scholar with your Gmail account; From menu in upper left, go to settings &gt; Library links; Search for University of Idaho, and click the check box; Click “Save”.</li> </ul> </li> </ul> Wed, 11 Sep 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/reference.html https://evanwill.github.io/_drafts/notes/reference.html Handy web dev tools <p>Key shortcuts:</p> <ul> <li>Paste plain text (get rid of weird formatting): <code class="language-plaintext highlighter-rouge">Ctrl + Shift + V</code></li> <li>Override a page’s custom context menu (so you can access your normal one): <code class="language-plaintext highlighter-rouge">Shift + right click</code></li> </ul> <p>Browser support:</p> <ul> <li><a href="http://caniuse.com/">Can I Use</a></li> <li><a href="http://www.cssfontstack.com/">CSS font stack</a></li> </ul> <p>Tests:</p> <ul> <li><a href="https://web.dev/vitals/">Web Vitals</a></li> <li><a href="https://web.dev/measure">Lighthouse tests</a></li> <li><a href="https://developers.google.com/speed/pagespeed/insights/">Page Speed</a></li> <li><a href="https://search.google.com/test/mobile-friendly">mobile-friendly</a></li> <li><a href="https://search.google.com/test/rich-results">Rich Results Test</a> (replaces discontinued <a href="https://search.google.com/structured-data/testing-tool">Structured Data Testing Tool</a>)</li> <li><a href="https://developers.facebook.com/tools/debug/sharing/">Facebook Sharing Debugger</a></li> <li><a href="http://webpagetest.org/">webpagetest</a> (test on actual devices and connections)</li> </ul> <p>Web Master utilities:</p> <ul> <li><a href="https://www.sitemaps.org/protocol.html">sitemaps</a></li> <li><a href="https://cse.google.com/cse/">Google Custom Search</a></li> <li><a href="https://www.google.com/webmasters/tools/home">Google Search Console</a></li> <li><a href="ttps://patorjk.com/software/taag/">ascii font generator</a></li> </ul> <p>Colors:</p> <ul> <li><a href="https://material.io/tools/color/#!/?view.left=0&amp;view.right=0">Material Design Color Tool</a></li> <li><a href="https://color.adobe.com/">Adobe color wheel</a></li> <li><a href="https://coolors.co">Coolors</a></li> <li><a href="https://picular.co/">Picular</a></li> </ul> <p>Accessibility:</p> <ul> <li><a href="https://www.whocanuse.com/">Who Can Use (color checker)</a></li> <li><a href="https://www.accessibility-developer-guide.com/">Accessibility Developer Guide</a></li> <li><a href="http://accessibility.arl.org/standards-best-practices/">ARL web accessibility toolkit</a></li> <li><a href="http://www.usability.gov/what-and-why/accessibility.html">Usability.gov</a></li> <li>Chrome <a href="https://chrome.google.com/webstore/detail/accessibility-developer-t/fpkknkljclfencbdbgkenhalefipecmb">Accessibility Developer Tools</a></li> <li><a href="http://wave.webaim.org/">WAVE tool</a></li> <li>W3C <a href="https://www.w3.org/WAI/eval/preliminary">Easy Checks</a> documentation</li> <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility">Accessibility testing and tools (MDN web docs)</a></li> <li><a href="https://www.washington.edu/accessibility/videos/free-captioning/">captioning videos for free</a></li> </ul> <p>Stop using “click here”:</p> <ul> <li><a href="https://www.nngroup.com/articles/writing-links/">Writing Hyperlinks: Salient, Descriptive, Start with Keyword</a></li> <li><a href="https://www.smashingmagazine.com/2012/06/links-should-never-say-click-here/">Why Your Links Should Never Say “Click Here”</a></li> </ul> <p>Also, <a href="https://gcs.civilservice.gov.uk/blog/link-shorteners-the-long-and-short-of-why-you-shouldnt-use-them/">don’t use link shorteners</a></p> <p>Free images:</p> <ul> <li><a href="https://unsplash.com/">Unsplash</a></li> <li><a href="https://www.flickr.com/commons">Flickr Commons</a></li> <li><a href="https://www.pexels.com/">PEXELS</a></li> <li><a href="https://www.oldbookillustrations.com/">Old Book Illustrations</a></li> <li><a href="https://coverr.co/">Coverr (free stock video)</a></li> <li><a href="https://storyset.com/">Storyset (free illustrations)</a></li> </ul> <p>Image optimize:</p> <ul> <li>For one off, <a href="https://pagespeed.web.dev/">Page Speed</a> has a little link at the bottom of the analysis to download optimized images, css, and js (see <a href="https://developers.google.com/speed/docs/insights/OptimizeImages">Optimize Image</a>)</li> <li><a href="https://images.guide/">Essential Image Optimization</a> by Addy Osmani</li> <li><a href="https://squoosh.app/">Squoosh web app</a></li> <li><a href="https://imagemagick.org/">Image Magick</a> (<a href="https://evanwill.github.io/_drafts/notes/imagemagick.html">notes</a>)</li> </ul> <p>Reference:</p> <ul> <li><a href="https://developer.mozilla.org/en-US/">MDN web docs</a></li> <li><a href="https://www.w3schools.com/">w3schools</a></li> <li><a href="https://web.dev/learn">web.dev</a></li> </ul> <p>JQuery?</p> <ul> <li><a href="http://youmightnotneedjquery.com/">You Might Not Need JQuery</a></li> <li><a href="https://plainjs.com/">plainjs</a></li> </ul> <p>Design:</p> <ul> <li><a href="https://lookup.design/">design examples</a></li> <li><a href="https://component.gallery/components/">Components Gallery</a></li> <li><a href="https://lawsofux.com/">Laws of UX</a></li> <li><a href="https://webfieldmanual.com/">Web Field Manual</a></li> <li><a href="http://www.perf-tooling.today/">Performance Tooling Today</a></li> <li><a href="https://practicaltypography.com/">Butterick’s Practical Typography</a></li> <li><a href="https://www.planetfriendlyweb.org/">Planet Friendly Web Guide</a></li> <li><a href="https://opensource.guide/">Open Source Guide</a></li> <li><a href="http://library.ac4d.com/">ac4d Design Library</a></li> </ul> <p>Quick local server:</p> <ul> <li>Python 3: <code class="language-plaintext highlighter-rouge">python -m http.server 8000</code> then surf to <code class="language-plaintext highlighter-rouge">localhost:8000</code> (part of python standard library)</li> <li>Ruby: <code class="language-plaintext highlighter-rouge">ruby -run -e httpd . -p 8080</code> then surf to <code class="language-plaintext highlighter-rouge">localhost:8080</code> (<em>note</em> in ruby 3.0+ webrick is removed from the standard library, so you will have to install <code class="language-plaintext highlighter-rouge">webrick</code> gem)</li> <li>Node: install <code class="language-plaintext highlighter-rouge">npm install -g http-server</code>, run <code class="language-plaintext highlighter-rouge">http-server</code></li> </ul> <p>Ultra minimal computing notebook:</p> <ul> <li><a href="https://github.com/jjjjjjjjjjjjjjjjjjjj/new-note/">new-note</a> (see <a href="https://boingboing.net/2018/05/08/the-simplest-online-note-takin.html">article</a>)</li> <li>or paste into address bar <code class="language-plaintext highlighter-rouge">data:text/html, &lt;html contenteditable style='padding:10%;'&gt;</code>, type, then save with <code class="language-plaintext highlighter-rouge">Ctrl+S</code>.</li> </ul> <p>Minimal hosting:</p> <ul> <li><a href="https://sdnotes.com/faq">sdnotes</a></li> </ul> <p>Find good font for your editor:</p> <ul> <li><a href="https://app.programmingfonts.org/">Programming Fonts</a>, test out mono fonts in web based editor</li> </ul> <p>Check content of certificate file:</p> <ul> <li><code class="language-plaintext highlighter-rouge">openssl x509 -in libcal_uidaho_edu_cert.cer -noout -text</code></li> </ul> Mon, 29 Jul 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/web-dev.html https://evanwill.github.io/_drafts/notes/web-dev.html Git Intro <blockquote> <p>Introduce using Git and GitHub for collaborating (workshop outline)</p> </blockquote> <ol> <li>Finish <a href="https://evanwill.github.io/get-git/0-prep.html" target="_blank" rel="noopener">Prep</a> (git + github account)</li> <li>Take <a href="https://docs.google.com/forms/d/e/1FAIpQLSeC0XH3vHOAOU9gSMmkdTGrND8PN0AAIo6f5PL5WOAXRWMjNg/viewform?usp=sf_link" target="_blank" rel="noopener">Survey</a></li> </ol> <h2 id="why-use-git-and-github">Why use Git and GitHub?</h2> <p><a href="https://git-scm.com/" target="_blank" rel="noopener">Git</a> is a <a href="https://www.gnu.org/philosophy/free-sw.en.html" target="_blank" rel="noopener">free</a>, <a href="https://en.wikipedia.org/wiki/Distributed_version_control" target="_blank" rel="noopener">distributed</a> version control system originally developed for coordinating huge software development projects (i.e. the <a href="https://www.kernel.org/" target="_blank" rel="noopener">Linux Kernel</a> led by <a href="https://www.linuxfoundation.org/about" target="_blank" rel="noopener">Linux Foundation</a>).</p> <p>However, Git paired with GitHub is also great for academic and personal uses, such as collaborating over code for your research project, drafting articles, or creating lab websites.</p> <p><strong>Intro to version control:</strong></p> <ul> <li><a href="http://www.phdcomics.com/comics/archive.php?comicid=1531" target="_blank" rel="noopener">notFinal.doc</a></li> <li><a href="http://phdcomics.com/comics/archive.php?comicid=1323" target="_blank" rel="noopener">A story told in file names</a></li> <li><a href="https://xkcd.com/1597/" target="_blank" rel="noopener">xkcd: Git</a></li> <li>Get Git, <a href="https://uidaholib.github.io/get-git/1why.html" target="_blank" rel="noopener">Why</a></li> </ul> <p><strong>Git for science:</strong></p> <ul> <li>Reproducibility: records all steps and participants, ability to share complete history.</li> <li>Backup: it is very difficult to delete history–if you commit it, Git stores it with integrity.</li> <li>Collaborate: manage complicated work in parallel with multiple people/computers.</li> <li>Experiment: branching makes you feel brave and free to explore!</li> </ul> <p><strong>GitHub:</strong></p> <ul> <li>Project management features</li> <li><a href="https://evanwill.github.io/_drafts/notes/github-org.html">Organizations</a></li> <li>Community (find code, connect)</li> <li>Sharing (DOIs for citable code / data)</li> </ul> <h2 id="basic-workflow">Basic Workflow</h2> <p>Git is best learned hands-on. Intro is via command line to give a clear step-by-step overview of how it works–in the future you may use a GUI tool or functions built into your IDE.</p> <ul> <li><a href="https://evanwill.github.io/get-git/2-setup.html" target="_blank" rel="noopener">Setup Git</a></li> <li><a href="https://evanwill.github.io/get-git/3-workflow.html" target="_blank" rel="noopener">Basic Git Workflow</a></li> <li><a href="https://evanwill.github.io/get-git/4-history.html" target="_blank" rel="noopener">History</a></li> <li><a href="https://evanwill.github.io/get-git/cheatsheet.html" target="_blank" rel="noopener">Cheatsheet</a></li> </ul> <p>Keep in your heart that Git keeps track of Everything! Have peace of mind that you can’t loose your history once committed to a Git repo, unless you try really hard.</p> <p>Be sure to <code class="language-plaintext highlighter-rouge">.gitignore</code> cache files and temporary outputs–just commit the source code, data, and notes.</p> <h2 id="basic-github-collaborating-workflows">Basic GitHub Collaborating Workflows</h2> <p>There is two basic workflows to collaborate on a GitHub repository:</p> <ol> <li>Add collaborators to repo (simple, typical of smaller projects) <ul> <li>On GitHub, click the “Settings” tab of your repository.</li> <li>On the left menu, click “Collaborators”.</li> <li>Add collaborators via email or GitHub name.</li> <li>Collaborator will need to accept the invite.</li> <li>Clone the repo to your local machine.</li> <li>Now you all have equal control over the repo content: <code class="language-plaintext highlighter-rouge">push</code>, <code class="language-plaintext highlighter-rouge">pull</code>, <code class="language-plaintext highlighter-rouge">merge</code>, etc.</li> <li>Using feature <a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell" target="_blank" rel="noopener">branches</a> may be helpful to organize your work–create a branch, do some work, push the new branch to GitHub, then create a Pull Request to discuss with your team.</li> </ul> </li> <li>Fork and Pull Request (more complex, centralized control, typical of bigger projects) <ul> <li>Navigate to your partner’s repo on GitHub.</li> <li>Click “Fork” in upper right.</li> <li>Make changes in your personal fork of the repo.</li> <li>On your personal fork, click “New pull request” button.</li> <li>Check the changes, click “Create pull request” button.</li> <li>Create a message saying exactly what changes you made and why.</li> <li>The original repo will now have a PR that collaborators can view and comment on. Only the owner can accept the request and merge it.</li> </ul> </li> </ol> <p>See GitHub Help <a href="https://help.github.com/articles/fork-a-repo/" target="_blank" rel="noopener">Fork a Repo</a>, <a href="https://help.github.com/articles/about-pull-requests/" target="_blank" rel="noopener">About Pull requests</a>, and <a href="https://guides.github.com/introduction/flow/" target="_blank" rel="noopener">Understanding the GitHub Flow</a> for more info. Also, check out Atlassian’s <a href="https://www.atlassian.com/git/tutorials/comparing-workflows" target="_blank" rel="noopener">Comparing Workflows</a> or GitHub <a href="https://help.github.com/en/articles/about-collaborative-development-models" target="_blank" rel="noopener">About collaborative development models</a> for more options.</p> <h2 id="collaborating-practice">Collaborating Practice</h2> <p>Add collaborators:</p> <ul> <li>create a new repository with README</li> <li>clone to your local machine</li> <li>add partner as collaborator</li> <li>accept partner’s invite (check <a href="https://github.com/notifications" target="_blank" rel="noopener">notifications</a>)</li> <li>clone partner’s repo</li> <li>make change locally to partner’s repo README and push</li> </ul> <p>Auto merge:</p> <ul> <li>make change locally in your repo, creating a new file <code class="language-plaintext highlighter-rouge">test.txt</code></li> <li>try to push</li> <li>pull (auto merge message)</li> <li>push</li> </ul> <p>Conflicts:</p> <ul> <li>pull your partner’s repo</li> <li>make a change to <code class="language-plaintext highlighter-rouge">test.txt</code> locally in your partner’s repo</li> <li>push</li> <li>make a change to <code class="language-plaintext highlighter-rouge">test.txt</code> locally in your repo</li> <li>try to push</li> <li>pull, enter merging state</li> <li>fix conflicts</li> <li>commit</li> <li>push</li> </ul> <p><em>Art of the commit:</em> it is best to create small, targeted commits when collaborating. Each commit should do one specific thing making it easier for others to understand your work and navigate the history if necessary.</p> <h2 id="rstudio-integration">RStudio Integration</h2> <p>RStudio has builtin integration with Git, allowing you do complete the basic commands with the interface. Basically, an RStudio “Project” will equal a Git repo. You can directly <code class="language-plaintext highlighter-rouge">clone</code> a repo from GitHub using <em>File &gt; New Project &gt; Version Control &gt; Git</em>. When you open a Project that is a git repo, you should see the “Git” menu on the interface giving access to the git commands.</p> <ul> <li>RStudio support, <a href="https://support.rstudio.com/hc/en-us/articles/200532077-Version-Control-with-Git-and-SVN" target="_blank" rel="noopener">Version Control with Git and SVN</a></li> <li>SWC, <a href="https://swcarpentry.github.io/git-novice/14-supplemental-rstudio/index.html" target="_blank" rel="noopener">Using Git from RStudio</a></li> <li><a href="https://happygitwithr.com/" target="_blank" rel="noopener">Happy Git and GitHub for the useR</a></li> </ul> <h2 id="project-management-features">Project management features</h2> <p>GitHub adds many handy web-based features to manage your projects / Git repositories:</p> <ul> <li>Issues. Create an issue to discuss and track ideas, bugs, projects, requests, etc. Can be assigned to people, tagged, and more. Also allows people outside of the project report problems with your code. Be sure to create checklists in the first comment box (<code class="language-plaintext highlighter-rouge">- [ ] step</code>)–they become click-able and show progress in the Issue view.</li> <li>Projects. Create Trello board like lists to organize work.</li> <li>Wiki. Simple wiki-style documentation that can be edited by your collaborators (note: written in Markdown not wikitext).</li> </ul> <p>To make the most of these features, you will want to learn <a href="https://help.github.com/articles/basic-writing-and-formatting-syntax/" target="_blank" rel="noopener">Markdown</a> because it’s a <a href="https://evanwill.github.io/_drafts/notes/writing-markdown.html" target="_blank" rel="noopener">great way to write</a> and is used everywhere on GitHub. Issues, PR, and commits can be mentioned in any GitHub comment and will be replaced by <a href="https://help.github.com/articles/autolinked-references-and-urls/" target="_blank" rel="noopener">reference shortlinks</a>. GitHub users can be mentioned using <code class="language-plaintext highlighter-rouge">@</code> and will be notified of your comment.</p> <h2 id="gh-pages">gh-pages</h2> <p>GitHub also offers free web hosting for your project, organization, or personal profile. Check workshop <a href="https://evanwill.github.io/go-go-ghpages/" target="_blank" rel="noopener">Go-go gh-pages!</a></p> <p>Also, use <a href="https://gist.github.com/" target="_blank" rel="noopener">GitHub Gist</a> to instantly share simple notes, outlines, snippets, etc.</p> <h2 id="citable-code">Citable Code</h2> <p>GitHub repos can be integrated with Zenodo to issue a DOI. DOI are a persistent identifier used in academic writing to cite articles and other works. Having a DOI for your code makes it easier to track citations and impact. Learn how at <a href="https://guides.github.com/activities/citable-code/" target="_blank" rel="noopener">Making Your Code Citable</a>.</p> <h2 id="license">License</h2> <p>Choosing a license is important if you want share data, code, and content. It ensures users have legal rights to reuse, and reserves your rights as the creator. The <a href="https://www.go-fair.org/fair-principles/r1-1-metadata-released-clear-accessible-data-usage-license/">FAIR Principles</a> point out that having a clear license is a requirement for <em>legal interoperability</em> of data.</p> <p>It is convention to add a file as <code class="language-plaintext highlighter-rouge">LICENSE</code> or <code class="language-plaintext highlighter-rouge">LICENSE.md</code> to a repository so that people can easily find the license. GitHub can automatically generate some open source licenses for you, see <a href="https://help.github.com/en/articles/adding-a-license-to-a-repository">Adding a license to a repository</a>.</p> <ul> <li><a href="https://choosealicense.com/">Choose an open source license</a> (for software)</li> <li>Creative Commons <a href="https://creativecommons.org/choose/">Choose a License</a> (more common for text and data)</li> </ul> <h2 id="resources">Resources</h2> <ul> <li>Software Carpentry, <a href="https://swcarpentry.github.io/git-novice/" target="_blank" rel="noopener">Version Control with Git</a></li> <li><a href="https://www.datacarpentry.org/lessons/" target="_blank" rel="noopener">Data Carpentry</a> for discipline specific data lessons</li> <li><a href="https://git-scm.com/book" target="_blank" rel="noopener">Git Book</a></li> <li><a href="http://gitforteams.com/" target="_blank" rel="noopener">Git for Teams</a></li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://www.oreilly.com/library/view/temporary-access/" target="_blank" rel="noopener">Safari Books Online</a></li> </ul> Thu, 27 Jun 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-intro.html https://evanwill.github.io/_drafts/notes/git-intro.html Random Interesting Fonts <ul> <li><a href="https://app.programmingfonts.org/">Programming Fonts</a>, test out mono fonts in web based editor</li> <li><a href="https://public-sans.digital.gov/">Public Sans</a>, open font created by US government, on available on GitHub, “A strong, neutral typeface for interfaces, text, and headings.”</li> <li><a href="https://rsms.me/inter/">Inter</a>, open font “specially designed for user interfaces with focus on high legibility of small-to-medium sized text on computer screens.”</li> <li><a href="http://www.margoburns.com/fonts/DanaLibraryHand/">Dana Library Hand</a>, font created by Margo Burns inspired by a writing style recommended for card catalogues by 1899 <a href="https://archive.org/details/primerlibrary00danarich/page/n8">“A library primer”</a>.</li> <li><a href="https://github.com/cmiscm/leonsans">Leon Sans</a>, javascript based font allowing interesting transformations and effects (awesome <a href="https://leon-kim.com/examples/">leonsans demos</a>).</li> <li><a href="http://fontello.com/">Fontello</a>, icon font generator.</li> <li><a href="https://fonts.google.com/specimen/Press+Start+2P">Press Start 2P</a> or <a href="https://www.dafont.com/kongtext.font">Kongtext</a> (retro game fonts)</li> <li><a href="https://boingboing.net/2019/10/17/how-dare-you-2.html">Greta Grotesk</a> (based on Greta’s hand lettered signs)</li> <li><a href="https://hellveticafont.com/">Hell vetica</a> (helvetica twisted by messed up kernings)</li> <li><a href="http://vollkorn-typeface.com/">Vollkorn</a> (includes ligatures that can make your text as unreadable as early typeface…)</li> <li><a href="https://ctrlcctrlv.github.io/TT2020/">TT2020</a> (typewriter font with realistic irregularities built in)</li> <li><a href="https://vole.wtf/raybees-font/">Raybees</a> (cutout-style font, with gyphs like a skull in place of brackets)</li> <li><a href="https://bennettfeely.com/ztext/">ztext.js</a> (3D typography that works with any font)</li> <li><a href="https://github.com/alias-rahil/handwritten.js">Handwritten.JS</a> (converts text into realistic handwritten image)</li> </ul> Wed, 29 May 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/fonts.html https://evanwill.github.io/_drafts/notes/fonts.html Random Interesting CSS <ul> <li><a href="https://nostalgic-css.github.io/NES.css/">NES.css</a> (retro game styling)</li> <li><a href="https://github.com/kristopolous/BOOTSTRA.386">Bootstrap/386</a> (retro computer style)</li> <li><a href="https://edwardtufte.github.io/tufte-css/">Tufte CSS</a> (Edward Tufte inspired layout with lots of asides)</li> <li><a href="https://1linelayouts.glitch.me/">1linelayouts</a></li> </ul> Wed, 29 May 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/css.html https://evanwill.github.io/_drafts/notes/css.html Machine Learning <blockquote> <p>Intro workshop for digital humanities group.</p> </blockquote> <p>Machine Learning (ML) is the application of algorithms and statistical modeling to allow computers to “learn” from data to do a task (often overlapping or used interchangeably with Artificial Intelligence / AI).</p> <p>ML tasks are broadly separated into <em>supervised</em> or <em>unsupervised</em> learning. Supervised learning tasks typically involve feeding the algorithm a labeled training data set which is used to build a model that can then classify unknown items, making inferences based on what it knows. Unsupervised learning tasks involve feeding unlabeled data to an algorithm that can identify patterns and clustering in the grouping.</p> <p>The ability to learn from data is changing the approach to many computational tasks, such as OCR or NLP, putting the focus on curating training data sets rather than developing new software (see Andrej Karpathy, <a href="https://medium.com/@karpathy/software-2-0-a64152b37c35">Software 2.0</a>, 2017). However, computational techniques can also challenge our expertise in DH, stretching even stats experts ability to evaluate the validity of complex models (for fun, <a href="http://www.tylervigen.com/spurious-correlations" target="blank">spurious correlations</a>).</p> <h2 id="natural-language-processing-nlp">Natural Language Processing (NLP)</h2> <p>NLP is a family of techniques to analyze unstructured language data found in everyday speech and writing.</p> <p>Historically, it wasn’t based in ML, but relied on manually identifying rules and patterns in human speech that could be parsed by code. For example, take a minute to play with <a href="https://www.masswerk.at/elizabot/eliza.html">ELIZA</a> (1966), an electronic psychologist based in early NLP pattern matching.</p> <p>The web has provided an explosion of unstructured text, making NLP a huge business as enterprise seeks to extract information from social media or create chat-bots to minimize labor costs. Typical tasks involve chunking/stemming, part-of-speech tagging, named entity recognition (NER), classification, and sentiment analysis. Speech recognition, OCR , and text-to-speech are also considered NLP tasks.</p> <p>Demos:</p> <ul> <li>IBM Watson <a href="https://www.ibm.com/watson/services/natural-language-understanding/">Natural Language Understanding</a> (API trained on web content) <ul> <li><a href="https://uidaholib.github.io/poemchoice/index.html">VPOD sentiment analysis</a> (poetry sent to IBM NLU API for sentiment analysis)</li> </ul> </li> <li>Text-processing <a href="http://text-processing.com/demo/">NLTK demos</a> (free API, based on <a href="https://www.nltk.org/">Python NLTK</a>)</li> <li><a href="https://observablehq.com/@bmschmidt/book-visualizations-sandbox?htid=pst.000061166424">Book Visualizations Sandbox</a> (Text and sentiment analysis with Hathi books. Shared on the Observable platform, a web-based code notebook for javascript)</li> </ul> <h2 id="fun-with-text-generators">Fun with Text Generators</h2> <p>Unsupervised deep learning neural network models? Can you collaborate with a machine algorithm?</p> <ul> <li><a href="https://youtu.be/LY7x2Ihqjmc">Sunspring</a> (Oscar Sharp, Ross Goodwin, Thomas Middleditch, 2016)</li> <li>Janelle Shane, <a href="https://twitter.com/JanelleCShane/status/1125963320823934976">Darth Vader’s recipe</a> (<a href="https://aiweirdness.com/">aiweirdness blog</a>)</li> <li><a href="https://colab.research.google.com/drive/1VLG8e7YSEwypxU-noRNhsv5dW4NfTGce">Train a GPT-2 Text-Generating Model w/ GPU For Free</a>, google colab</li> <li><a href="https://github.com/openai/gpt-2">GPT-2 code</a>, recent press <a href="https://openai.com/blog/better-language-models/">1</a> <a href="https://towardsdatascience.com/openais-gpt-2-the-model-the-hype-and-the-controversy-1109f4bfd5e8">2</a>, <a href="https://www.vox.com/2019/5/15/18623134/openai-language-ai-gpt2-poetry-try-it">3</a>, etc…</li> <li><a href="https://talktotransformer.com/">Talk to Transformer</a> (ask it a question, like <code class="language-plaintext highlighter-rouge">Q: What is Digital Humanities?</code>)</li> </ul> Wed, 15 May 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ml_dh.html https://evanwill.github.io/_drafts/notes/ml_dh.html YouTube API tips <p>YouTube is pretty handy for hosting video and audio to embed in your sites. Here are some tips to use the embeds and image API effectively.</p> <h2 id="video-embed-options">Video Embed Options</h2> <p>When grabbing the embed iframe code from YouTube share button, I usually modify a few options. Some of these are documented in <a href="https://developers.google.com/youtube/iframe_api_reference">YouTube Player iframe reference</a>, but not all or very well…</p> <ul> <li>Privacy-enhanced mode: does not send data to YouTube unless users click play, is enabled by using domain <code class="language-plaintext highlighter-rouge">www.youtube-nocookie.com</code> rather than <code class="language-plaintext highlighter-rouge">www.youtube.com</code> in the iframe src.</li> <li>Related videos: the option <code class="language-plaintext highlighter-rouge">rel=0</code> asks YouTube to not show related videos. However, YouTube changed this option in 2018 and may still show related videos from the same channel (which is better than totally random stuff at least).</li> <li>Modest branding: the option <code class="language-plaintext highlighter-rouge">modestbranding=1</code> removes some YouTube branding from the iframe player.</li> </ul> <p>This will look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/oacUgWXrqwc?rel=0&amp;modestbranding=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt; </code></pre></div></div> <h2 id="image-api">Image API</h2> <p>YouTube image API is used by a ton of sites, yet doesn’t seem to be documented anywhere by Google. Basically, you can get four sizes of the default thumbnail, or four smaller thumbnails from different points in the video using a YouTube ID. Find the YouTube ID by look at the <code class="language-plaintext highlighter-rouge">v</code> key parameter at the end of the video’s url or the last part of the “Share” url. For example, in</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://www.youtube.com/watch?v=oacUgWXrqwc or https://youtu.be/oacUgWXrqwc </code></pre></div></div> <p>the youtube id is <code class="language-plaintext highlighter-rouge">oacUgWXrqwc</code>. Use that string to replace <code class="language-plaintext highlighter-rouge">&lt; youtube id&gt;</code> in the api recipes below.</p> <p>Default images:</p> <ul> <li>thumb 120x90, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/default.jpg</code></li> <li>medium quality 320x180, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/mqdefault.jpg</code></li> <li>high quality 480x360, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/hqdefault.jpg</code></li> <li>SD 640x480 (not available for all videos), <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/sddefault.jpg</code></li> <li>max quality 1280×720 (or 1920x1080?, not available for all videos), <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/maxresdefault.jpg</code></li> </ul> <p>Auto thumbs:</p> <ul> <li>default image 480x360, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/0.jpg </code></li> <li>alternate thumb 120x90, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/1.jpg</code></li> <li>alternate thumb 120x90, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/2.jpg</code></li> <li>alternate thumb 120x90, <code class="language-plaintext highlighter-rouge">https://img.youtube.com/vi/&lt; youtube id &gt;/3.jpg</code></li> </ul> <p>Note: you can use the domain <code class="language-plaintext highlighter-rouge">img.youtube.com</code> or <code class="language-plaintext highlighter-rouge">i3.ytimg.com</code>.</p> <p>For more control, you can use <a href="https://developers.google.com/youtube/v3/">YouTube Data API</a>, but it requires a key to access.</p> Mon, 06 May 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/youtube.html https://evanwill.github.io/_drafts/notes/youtube.html Handy Jekyll Tips <blockquote> <p>random notes about Jekyll quirks</p> </blockquote> <h2 id="add-attributes-to-elements">Add attributes to elements</h2> <p><a href="https://kramdown.gettalong.org/">Kramdown</a> allows you to add additional attributes to elements with a basic syntax called <a href="https://kramdown.gettalong.org/syntax.html#attribute-list-definitions">Attribute Lists</a>. Directly proceeding or following the block or inline element (as written in Markdown), add a <code class="language-plaintext highlighter-rouge">{:</code> the attributes, and close <code class="language-plaintext highlighter-rouge">}</code>. Multiple attributes can be added inside the brackets.</p> <p>For example, to create <code class="language-plaintext highlighter-rouge">&lt;p id="example" class="red"&gt;Stuff&lt;/p&gt;</code>, use:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Stuff {: #example .red } </code></pre></div></div> <p>To create <code class="language-plaintext highlighter-rouge">&lt;a href="https://example.com" target="_blank" rel="noopener"&gt;example&lt;/a&gt;</code>, use:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[example](https://example.com){:target="_blank" rel="noopener"} </code></pre></div></div> <h2 id="mix-html-with-markdown">Mix HTML with Markdown</h2> <p>In a Markdown file, all HTML is valid Markdown. However, Markdown inside HTML tags will be ignored.</p> <p>For example, <code class="language-plaintext highlighter-rouge">&lt;div&gt; # Header One&lt;/div&gt;</code> won’t render as an <code class="language-plaintext highlighter-rouge">&lt;h1&gt;</code>. However, with Jekyll’s kramdown, you can add the attribute <code class="language-plaintext highlighter-rouge">markdown="1"</code> to an HTML element to tell the converter to render the Markdown inside. Thus, <code class="language-plaintext highlighter-rouge">&lt;div markdown="1"&gt; # Header One&lt;/div&gt;</code> will render as <code class="language-plaintext highlighter-rouge">&lt;div&gt;&lt;h1&gt;Header One&lt;/h1&gt;&lt;/div&gt;</code>.</p> <h2 id="use-variables-to-write-liquid-expressions">Use variables to write Liquid expressions</h2> <p>Jekyll’s version of Liquid tweaks some of the functions to provide additional features. Sometimes it is handy to use a variable to actually write/modify a Liquid expression. For example, a page or site variable can be used to set up an include, basically Liquid <em>inside</em> a Liquid expression:</p> <p><code class="language-plaintext highlighter-rouge">{% include {{ page.variable }} %}</code></p> <h2 id="add-yml-front-matter">Add YML front matter</h2> <p>Jekyll processes any file that has YML front matter on top. Any file that does not have front matter is just copied directly to <code class="language-plaintext highlighter-rouge">_site</code> as a static asset, thus you can not use any Liquid, etc. Sometimes you want to copy over HTML or assets from an old project and need to add YML header to each file. Use <code class="language-plaintext highlighter-rouge">sed</code>, like <code class="language-plaintext highlighter-rouge">sed -i '1i---\n# \n---' file.html</code>. For a batch:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.html; do sed -i '1i---\n# \n---' "$f"; done</code></p> <h2 id="grab-key--value-when-iterating-over-hash">Grab key / value when iterating over hash</h2> <p>If you have a YML hash like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>example: key1: value1 key2: value2 key3: value3 </code></pre></div></div> <p>You can iterate over the hash, in the loop access the key with <code class="language-plaintext highlighter-rouge">[0]</code> and value at <code class="language-plaintext highlighter-rouge">[1]</code>, like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{% for e in site.data.file.example %} key: {{ e[0] }} value: {{ e[1] }} {% endfor %} </code></pre></div></div> <p>(see old <a href="https://github.com/Shopify/liquid/wiki/Liquid-for-Designers#allowed-collection-types">Liquid wiki docs</a>)</p> Fri, 19 Apr 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/jekyll-ref.html https://evanwill.github.io/_drafts/notes/jekyll-ref.html Python JupyterLab and Kernels <blockquote> <p>Mini workshop.</p> </blockquote> <ol> <li>Intro</li> <li>Survey, <a href="https://docs.google.com/forms/d/e/1FAIpQLSdcjgn14HTf2PR4Iifu_yCGJTvjFp1anoccBtKlmagjYirsPQ/viewform?usp=sf_link">click here!</a></li> <li>Discuss</li> <li>Environments and Kernels</li> <li>Notebooks</li> </ol> <h2 id="conda">Conda</h2> <p>Package + environment management for Python (but can be used for other languages), <a href="https://conda.io/en/latest/">conda docs</a>.</p> <p>Version and updates:</p> <ul> <li><code class="language-plaintext highlighter-rouge">conda --version</code> / <code class="language-plaintext highlighter-rouge">conda info</code></li> <li><code class="language-plaintext highlighter-rouge">conda update conda</code></li> <li><code class="language-plaintext highlighter-rouge">conda update --all</code> / <code class="language-plaintext highlighter-rouge">conda update anaconda</code></li> </ul> <p>Packages:</p> <ul> <li><code class="language-plaintext highlighter-rouge">conda install [package]</code></li> <li><code class="language-plaintext highlighter-rouge">conda remove [package]</code></li> <li><code class="language-plaintext highlighter-rouge">conda list</code> (all current packages + versions)</li> </ul> <p>Keep in mind if you install something without using <code class="language-plaintext highlighter-rouge">conda</code> (i.e. pip), conda can’t update it.</p> <h2 id="environments">Environments</h2> <p><img src="https://imgs.xkcd.com/comics/python_environment.png" alt="XKCD python environment" /></p> <ul> <li><code class="language-plaintext highlighter-rouge">conda create -n testenv</code></li> <li><code class="language-plaintext highlighter-rouge">conda env list</code></li> <li><code class="language-plaintext highlighter-rouge">conda activate testenv</code></li> <li><code class="language-plaintext highlighter-rouge">conda deactivate</code></li> <li><code class="language-plaintext highlighter-rouge">conda env remove -n testenv</code></li> </ul> <p>Share:</p> <ul> <li><code class="language-plaintext highlighter-rouge">conda env export --name myenv &gt; myenv.yml</code></li> <li><code class="language-plaintext highlighter-rouge">conda env create --file myenv.yml</code></li> </ul> <h2 id="installing-kernels">Installing kernels</h2> <p>Python 2:</p> <ul> <li><code class="language-plaintext highlighter-rouge">conda create -n py27 python=2.7</code></li> <li><code class="language-plaintext highlighter-rouge">conda activate py27</code></li> <li><code class="language-plaintext highlighter-rouge">conda install ipykernel</code></li> <li><code class="language-plaintext highlighter-rouge">source deactivate</code></li> </ul> <p>R:</p> <ul> <li><code class="language-plaintext highlighter-rouge">conda create -n mro_env r-essentials mro-base</code></li> </ul> <p>Julia:</p> <ul> <li><a href="http://julialang.org/downloads/">Download Julia</a> and install</li> <li><code class="language-plaintext highlighter-rouge">which jupyter</code></li> <li><code class="language-plaintext highlighter-rouge">JUPYTER=$(which jupyter) julia</code></li> <li><code class="language-plaintext highlighter-rouge">using Pkg</code></li> <li><code class="language-plaintext highlighter-rouge">Pkg.add("IJulia")</code></li> </ul> <p><a href="https://github.com/jupyter/jupyter/wiki/Jupyter-kernels">Kernels list</a></p> <h2 id="navigator">Navigator</h2> <p>Anaconda Navigator is a GUI app to manage conda and install stuff…</p> <ul> <li><a href="https://docs.anaconda.com/anaconda/navigator/">Navigator docs</a></li> <li>start on Linux: <code class="language-plaintext highlighter-rouge">anaconda-navigator</code></li> <li>create / manage / switch environments</li> <li>manage packages, check versions</li> <li>links to learning resources</li> <li>launch apps in the correct environment</li> </ul> <h2 id="jupyterlab">JupyterLab</h2> <ul> <li>It’s the future and it’s ready (<a href="https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906">news</a>, <a href="https://towardsdatascience.com/jupyter-lab-evolution-of-the-jupyter-notebook-5297cacde6b">blog</a>). Notebook was designed around 2011–since then Python has been relatively stable, but web technology has changed rapidly… Jupyter Lab is an update using modern web technology,</li> <li>If you have an up-to-date Anaconda install, it’s already installed</li> <li><a href="https://jupyterlab.readthedocs.io/en/stable/index.html">JupyterLab docs</a></li> <li>fully backwards compatible (“Classic” Notebooks runs from the same server)</li> <li>updated framework (built on JS)</li> <li>more extensible</li> <li>more IDE like (tabs and panes)</li> <li>updated notebook features (drag &amp; drop cells, collapse, context menu, more live preview formats and syntax highlighting)</li> <li>code console (with notebook, text file, or codeblock in markdown &gt; right-click to start console, shift+enter to run line or block)</li> <li>Output view (right-click &gt; “Create new view for output”)</li> <li><code class="language-plaintext highlighter-rouge">conda install nb_conda</code></li> <li><code class="language-plaintext highlighter-rouge">jupyter lab</code></li> </ul> <h2 id="sharing-notebooks">Sharing notebooks</h2> <ul> <li><a href="https://nbviewer.jupyter.org/">nbviewer</a> (easy way to share a static rendered version of a notebook from GitHub)</li> <li><a href="https://mybinder.org/">binder</a> (open a GitHub repo of notebooks in a temporary executable environment, <a href="https://mybinder.readthedocs.io/en/latest/">docs</a>)</li> </ul> <h2 id="library-resources">Library resources</h2> <ul> <li><a href="https://matplotlib.org/gallery/showcase/xkcd.html">matplotlib XKCD</a></li> <li><a href="https://uidaho.idm.oclc.org/login?url=https://www.safaribooksonline.com/library/view/temporary-access/">Safari: O’Reilly Books</a></li> <li><a href="https://www.lib.uidaho.edu/services/workshops/">workshops</a></li> </ul> Thu, 18 Apr 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/py-club.html https://evanwill.github.io/_drafts/notes/py-club.html R Resources <p>The R community seems like it is really taking off as a supportive, inclusive coding group in academics with less of the exclusion and barriers associated with traditional CS. I rarely use R, but want to expand my knowledge to provide better support on campus.</p> <p>So here is random R links that I need somewhere to put before I forget…</p> <p>Tutorials / learning:</p> <ul> <li><a href="https://www.rfordatasci.com/">R4DS Online Learning Community</a></li> <li><a href="https://rfortherestofus.com/courses/getting-started/">Getting Started with R</a>, R for the rest of us</li> <li><a href="https://rstudio.cloud/learn/primers">RStudio Primers</a></li> <li><a href="https://preludeinr.com/">Prelude in R</a></li> <li>Software Carpentry <a href="http://swcarpentry.github.io/r-novice-inflammation/">Programming with R</a> or <a href="http://swcarpentry.github.io/r-novice-gapminder/">R for Reproducible Scientific Analysis</a>.</li> </ul> <p>Reference:</p> <ul> <li><a href="https://r-graphics.org/">R Graphics Cookbook</a>, 2nd ed., Winston Chang.</li> <li><a href="http://r4ds.had.co.nz/">R for Data Science</a>, Grolemund and Wickham, 2017.</li> <li><a href="https://www.tidytextmining.com/">Text Mining with R: A Tidy Approach</a>, Silge and Robinson. 2019.</li> <li><a href="http://adv-r.had.co.nz/">Advanced R</a>, Wickham, 2014.</li> <li><a href="http://dh-r.lincolnmullen.com/">Computational Historical Thinking: With Applications in R</a>, Lincoln A. Mullen (work in progress).</li> <li><a href="https://learningstatisticswithr.com/">Learning Statistics with R</a>, Danielle Navarro (open course text/outline).</li> </ul> <p>Articles:</p> <ul> <li><a href="https://doi.org/10.7287/peerj.preprints.3159v2">Excuse me, do you have a moment to talk about version control?</a></li> <li><a href="https://matthewlincoln.net/2018/03/26/best-practices-for-using-google-sheets-in-your-data-project.html">Best Practices for Using Google Sheets in Your Data Project</a></li> </ul> Sun, 03 Mar 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/r-stuff.html https://evanwill.github.io/_drafts/notes/r-stuff.html Setup XPS 15 with Pop_OS <p>I recently got a <a href="https://www.dell.com/en-us/shop/dell-laptops/xps-15/spd/xps-15-9570-laptop">Dell XPS 15 9570</a> (16gb ram, i7-8750H CPU) for work expecting it to have good support in Linux, considering other XPS laptops ship with Ubuntu. However, the massive (for a laptop) NVIDIA GeForce GTX 1050Ti with 4GB GDDR5 ensures installing Linux is not so smooth…</p> <p><em>Update: <a href="https://evanwill.github.io/_drafts/notes/ubuntu20.html">Ubuntu 20.04 installs/works great</a> on XPS 15. I have moved to Ubuntu 20.04, but most of this post is still relevant. The most recent versions of Pop!_OS have some unique gnome extensions, including an auto-tiling desktop option.</em></p> <p>Any distro will boot into the live usb pretty well with the basic Intel graphics–however, you will eventually end up with a few issues trying to get NVIDIA to work. To simplify, I decided to use <a href="https://system76.com/pop">Pop!_OS</a>, an Ubuntu-based distro from computer manufacturer <a href="https://system76.com">System76</a>. There is a few <a href="https://support.system76.com/articles/difference-between-pop-ubuntu/">differences from Ubuntu</a>, but most importantly Pop!_OS provides a special image specifically for NVIDIA machines so it is easy to get things working.</p> <p><em>Note: I did not install as a dual boot, so I am not sure how smoothly that would go, but check the <a href="https://pop.system76.com/docs/dual-booting-windows/">official docs</a>.</em></p> <h2 id="set-up-and-install-pop_os">Set up and install Pop!_OS</h2> <ol> <li><a href="https://pop.system76.com/">download Pop!_OS</a> choosing the NVIDIA option.</li> <li><a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn to a USB stick</a></li> <li>Plug in your Pop!_OS USB</li> <li>Boot XPS 15 and hit F2 as it boots to enter the BIOS menu</li> <li>Enter BIOS: <ul> <li>turn off Secure Boot (this is necessary for the NVIDIA drivers, and eventually if you want to use virtual machines)</li> <li>Settings &gt; General &gt; Advanced Boot Option, select “enable legacy option ROMS”</li> <li>SATA Operation, select “AHCI” (you need to turn “RAID” mode off because it is not supported by Linux, because its not worth while… If you are dual booting, check the steps on the windows side before doing this)</li> </ul> </li> <li>Save and exit BIOS</li> <li>Reboot and hit F12 as it boots to enter boot option menu</li> <li>Choose the first USB boot option</li> <li>After a minute, it should boot into a live desktop with the Pop installer running. You can test out the live system if desired.</li> <li>Follow the installer steps. It is a bit different than other distros because setting up a user takes place after install, during your first boot. Check the <a href="https://pop.system76.com/docs/install-pop-os/">official docs</a>. I chose to do a full disk encrypt (work computer), but keep in mind it will ask you for the encryption password (different than your user password) at every restart.</li> <li>After installation is complete, reboot, and type in your encrypt password a few times</li> <li>Follow the steps to set up a user account</li> <li>Checkout your new system! See the <a href="https://support.system76.com/articles/pop-basics/">intro docs</a> and <a href="https://pop.system76.com/docs/keyboard-shortcuts/">keyboard shortcuts</a> for more info.</li> </ol> <h2 id="updates">Updates</h2> <p>If you have used GNOME before, everything should be pretty familiar although it starts out more vanilla than an Ubuntu install. Click on Activities or hit Super (windows key) to bring up your menu.</p> <p>You should run updates, which brings up the first noticeable difference from Ubuntu. The “update manager” is gone, instead updates are applied from the “Pop!_Shop” software center. Open Pop!_Shop, click on Installed, and if updates are available a button will appear to install them.</p> <h2 id="graphics-switch">Graphics switch</h2> <p>Another unique Pop! feature: click the upper right for the power menu, then click the battery icon / status meter. This opens options to set power profile (performance / balanced / long life), or to switch between graphics cards (NVIDIA / Intel). Switching between graphics cards takes a minute and a restart–its not instantaneous…</p> <h2 id="set-up-and-customize-desktop">Set up and customize desktop</h2> <p>Open Settings:</p> <ul> <li>Settings &gt; Background to get your wallpaper set.</li> <li>Settings &gt; Devices &gt; Display to set up your monitor and turn on Night Light if you want a red shift in the evening.</li> <li>Settings &gt; Bluetooth, turn bluetooth off if you don’t use it, since it is a security risk.</li> </ul> <p>Pop uses <a href="https://packages.ubuntu.com/">Ubuntu packages</a>. Open a terminal and install these right away, <code class="language-plaintext highlighter-rouge">sudo apt install</code>:</p> <ul> <li><code class="language-plaintext highlighter-rouge">gnome-tweak-tool</code> (lets you customize the desktop)</li> <li><code class="language-plaintext highlighter-rouge">chrome-gnome-shell</code> (might be installed already, but enables gnome extensions, connecting the manager with Firefox or Chromium)</li> <li><code class="language-plaintext highlighter-rouge">tlp tlp-rdw</code> (<a href="https://linrunner.de/en/tlp/docs/tlp-linux-advanced-power-management.html">advanced laptop power management</a>, also see <a href="https://support.system76.com/articles/battery/">system76 battery</a>)</li> </ul> <p>Pop! comes with a lot of development essentials already installed (build-essentials, git, curl, gpg2, ufw). But you do have to enable firewall: <code class="language-plaintext highlighter-rouge">sudo ufw enable</code>.</p> <p>Next, set up Firefox browser:</p> <ul> <li>Preferences &gt; Privacy &amp; Security &gt; check “Use a master password” and set.</li> <li>Add <a href="https://extensions.gnome.org/">GNOME extensions</a> plugin, <a href="https://addons.mozilla.org/en/firefox/addon/gnome-shell-integration/">gnome-shell-integration</a></li> <li>Add Firefox <a href="https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/?src=search">Multi-Account Containers</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/facebook-container/">Facebook Container</a></li> <li>Add adblocker such as <a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/?src=search">uBlock Origin</a></li> </ul> <p>Now you can add <a href="https://extensions.gnome.org/">GNOME extensions</a>, click the GNOME icon in the browser’s upper right side. Pop! comes with a few pre-installed, but here are a few more to add:</p> <ul> <li><a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine</a>, disable screen lock to watch movies or just not have your laptop locking all the time.</li> <li><a href="https://extensions.gnome.org/extension/307/dash-to-dock/">Dash to Dock</a>, adds a highly customizable dock to your desktop. For an Ubuntu-like look, go to installed extensions page: click settings, turn off intelligent autohide, select panel mode, and make icon size smaller.</li> <li>More suggestions, see <a href="https://evanwill.github.io/_drafts/notes/ubuntu-gnome.html">GNOME on Ubuntu notes</a></li> </ul> <p>Next I like to have Gedit (“Text Editor”) customized so its ready as a quick editor. Open the app, then click the name in the top bar to open the app menu &gt; Preferences. See <a href="https://evanwill.github.io/_drafts/notes/gedit-editor.html">customization suggestions notes</a>.</p> <h2 id="simplify-git-credentials">Simplify git credentials</h2> <p>You can permanently store your Git credentials with your user account. Configure Git as normal:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --global user.name "Evan Will" git config --global user.email "[email protected]" git config --global core.editor "nano -w" </code></pre></div></div> <p>Install dependencies:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt install libgnome-keyring-dev</code></p> <p>Build the helper:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /usr/share/doc/git/contrib/credential/gnome-keyring sudo make </code></pre></div></div> <p>Configure git helper:</p> <p><code class="language-plaintext highlighter-rouge">git config --global credential.helper /usr/share/doc/git/contrib/credential</code></p> <p>Then the next time you need a Git credential, it will prompt for username and password as normal, but it will be stored going forward.</p> <p><strong>Note: newer versions of Git require a different manager, if libgnome-keyring-dev gives a permission error, use libsecret instead. I found this is necessary on Ubuntu 19.04.</strong></p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install libsecret-1-0 libsecret-1-dev cd /usr/share/doc/git/contrib/credential/libsecret sudo make git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret </code></pre></div></div> <h2 id="issue-with-sleep">Issue with sleep</h2> <p>With Intel graphics activated, closing the lid for sleep or using the sleep icon from the power menu works correctly. However, XPS 15 does not seem to sleep correctly with NVIDIA activated, either it won’t go to sleep or it won’t wake up the screen…</p> <p>Supposedly there is a way to fix this with boot options passed to the Linux kernel. If you were on Ubuntu, editing the GRUB options <em>in theory</em> should work. However, Pop! no longer uses GRUB, instead uses systemd-boot and <a href="https://github.com/pop-os/kernelstub">kernelstub</a>.</p> <p>Ubuntu would look something like:</p> <blockquote> <p>Open GRUB options, <code class="language-plaintext highlighter-rouge">sudo nano /etc/default/grub</code>, and edit the value of the <code class="language-plaintext highlighter-rouge">GRUB_CMDLINE_LINUX_DEFAULT</code> line, so it looks like:</p> <p><code class="language-plaintext highlighter-rouge">GRUB_CMDLINE_LINUX_DEFAULT="quiet acpi_rev_override=1 acpi_osi=Linux nouveau.modeset=0 pcie_aspm=force drm.vblankoffdelay=1 scsi_mod.use_blk_mq=1 nouveau.runpm=0 mem_sleep_default=deep"</code></p> <p>Then update GRUB: <code class="language-plaintext highlighter-rouge">sudo update-grub</code></p> <p>See <a href="https://github.com/JackHack96/dell-xps-9570-ubuntu-respin">dell-xps-9570-ubuntu-respin</a> “xps-tweaks.sh” for scripts which inspired these settings.</p> </blockquote> <p>You can do this on Pop (since all the Ubuntu stuff is still there), but it won’t have any effect, since it isn’t actually booting via GRUB!</p> <p>Check your current set up with <code class="language-plaintext highlighter-rouge">sudo kernelstub -p</code> (mine says the kernel options are “quiet loglevel=0 systemd.show_status=false splash”). You could then add on the same kernel options as the GRUB config above, like:</p> <p><code class="language-plaintext highlighter-rouge">sudo kernelstub -a "acpi_rev_override=1 acpi_osi=Linux nouveau.modeset=0 pcie_aspm=force drm.vblankoffdelay=1 scsi_mod.use_blk_mq=1 nouveau.runpm=0 mem_sleep_default=deep"</code></p> <p>Honestly, I haven’t tried it… Since sleep works fine on Intel graphics, which I generally use for better battery life anyway, I will wait for some other brave soul to figure out the best boot options. Let me know if you do!</p> <h2 id="add-some-apps">Add some apps</h2> <p>Languages:</p> <ul> <li>Ruby: <a href="https://evanwill.github.io/_drafts/notes/ruby-notes.html">RVM set up</a></li> <li>Python: <a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">Anaconda set up</a></li> <li>Java: <code class="language-plaintext highlighter-rouge">sudo apt install default-jre</code> or <code class="language-plaintext highlighter-rouge">default-jdk</code> (this will be OpenJDK 11+, fine for apps like OpenRefine, if you need more specific versions search <a href="https://packages.ubuntu.com/search?keywords=jdk&amp;searchon=names&amp;suite=bionic&amp;section=all">packages</a>)</li> <li>Node: use <a href="https://github.com/creationix/nvm">nvm</a> (this seems to be the best method; install nvm, then <code class="language-plaintext highlighter-rouge">nvm install --lts</code>), or official <a href="https://github.com/nodesource/distributions/blob/master/README.md">NodeSource ppa</a>, or repository version <code class="language-plaintext highlighter-rouge">nodejs</code> (which is out of date)</li> </ul> <p>Search <a href="https://packages.ubuntu.com/">Ubuntu Packages</a> or Pop!_Shop for software. App essentials:</p> <ul> <li>A few extra fonts: <code class="language-plaintext highlighter-rouge">fonts-firacode</code>, <code class="language-plaintext highlighter-rouge">fonts-noto</code></li> <li>Chromium Browser, <code class="language-plaintext highlighter-rouge">chromium-browser</code></li> <li>Tilix terminal, <code class="language-plaintext highlighter-rouge">tilix</code></li> <li>KeePassXC</li> <li>GIMP image editing, <code class="language-plaintext highlighter-rouge">gimp</code></li> </ul> Fri, 25 Jan 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/xps15.html https://evanwill.github.io/_drafts/notes/xps15.html File types notes <blockquote> <p>notes clarifying plain text which is often mentioned in other notes…</p> </blockquote> <h1 id="bits-and-bytes">Bits and Bytes</h1> <p><em>Bit</em> = binary digit, i.e. <code class="language-plaintext highlighter-rouge">0</code> or <code class="language-plaintext highlighter-rouge">1</code>. <em>Byte</em> = a grouping of 8 bits (normally) that are used together, which was historically just the right amount of data to encode text characters.</p> <p><em>Hex</em> = a convenient way to represent bytes as two <a href="https://en.wikipedia.org/wiki/Hexadecimal">hexadecimal</a> digits, i.e. if you have groups of 4 bits, there is 16 possible combos from <code class="language-plaintext highlighter-rouge">0000</code> to <code class="language-plaintext highlighter-rouge">1111</code>, represented in hexadecimal from <code class="language-plaintext highlighter-rouge">0</code> to <code class="language-plaintext highlighter-rouge">F</code>. Files can be opened in a “hex editor” to view the raw bytes represented as pairs of hexadecimal digits. For example, in <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> <code class="language-plaintext highlighter-rouge">A</code> is <code class="language-plaintext highlighter-rouge">41</code> in hex, <code class="language-plaintext highlighter-rouge">B</code> is <code class="language-plaintext highlighter-rouge">42</code>, <code class="language-plaintext highlighter-rouge">Z</code> is <code class="language-plaintext highlighter-rouge">5A</code>, etc.</p> <h2 id="text-vs-binary">Text vs. Binary</h2> <p>Generally, there is a distinction between two broad types of computer files: text or binary.</p> <p><strong>Text files</strong> contain a series of bytes intended to represent text characters organized in lines (e.g. <code class="language-plaintext highlighter-rouge">a</code>, <code class="language-plaintext highlighter-rouge">B</code>, space, tab, line breaks, etc.). It can be opened with a text editor to see the characters.</p> <p><strong>Binary files</strong> contain bytes that are NOT character codes, data that is meant to be interpreted as something other than characters. It will require software (other than a text editor) that can correctly interpret the bytes. For example, a JPG image, MP3 sound file, or a ZIP compressed folder. A binary file can be represented in a text file by <a href="https://en.wikipedia.org/wiki/Binary-to-text_encoding">binary-to-text encoding</a> standards, such as Base64, where the bytes are represented by text characters. The text will be gibberish of course, but can be converted back into the binary format to retrieve the original data.</p> <p>Usually, when talking about text files, we mean <strong>plain text</strong>. It is defined by <a href="https://www.unicode.org/">Unicode standard</a> as:</p> <blockquote> <p>“Plain text is a pure sequence of character codes; plain Unicode-encoded text is therefore a sequence of Unicode character codes.”</p> </blockquote> <p>Plain text files are text files, i.e. contain only characters like <code class="language-plaintext highlighter-rouge">a</code>, <code class="language-plaintext highlighter-rouge">1</code>, <code class="language-plaintext highlighter-rouge">&lt;</code>, <code class="language-plaintext highlighter-rouge">!</code>, etc. Some characters might be “hidden” control characters, such as tabs and line breaks.</p> <p>In some contexts you will hear a distinction between plain text and rich text, i.e. just the characters/words vs. text with information about the style/presentation (fonts, colors, sizing, etc). However, “rich text” is often written in plain text, e.g. HTML, LaTeX, Markdown, or XML. So in this distinction, <code class="language-plaintext highlighter-rouge">hello world</code> is plain text, but <code class="language-plaintext highlighter-rouge">&lt;h1&gt;hello world&lt;/h1&gt;</code> is rich text written in plain text. On this blog I call text files “plain text”, and don’t use the distinction with “rich text” in this way.</p> <h2 id="raster-vs-vector">Raster vs. Vector</h2> <p>There is a broad distinction between two types of image file types:</p> <p><strong>Raster image</strong> files contain data that describes the individual pixels that make up the image. This are often captured by a digital camera or scanner. Common formats include JPEG, PNG, TIFF, etc.</p> <p><strong>Vector image</strong> files contain data that describes the geometry/geometric features that makes up the image. Since digital screens are made up of pixels, vector images are rendered into a raster image when viewing–however, because the vector image is made of points, lines, curves, etc. it can be scaled to any size without loss of quality. Common formats include <a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG</a>, which is written in XML.</p> <h2 id="demos">Demos</h2> <p>Open these all with a text editor:</p> <ul> <li>text file (text)</li> <li>html file (text. with markup)</li> <li>docx file (binary. A zipped folder of XML components)</li> <li>unzipped docx (use <code class="language-plaintext highlighter-rouge">unzip</code> or right-click to extract contents which are plain text files)</li> </ul> <p>Open this “dogtest” image in various formats with a viewer and text editor:</p> <ul> <li><a href="/_drafts/assets/testimage/dogtest.png">png</a> (raster, binary, lossless compression)</li> <li><a href="/_drafts/assets/testimage/dogtest.jpg">jpg</a> (raster, binary, lossy compression)</li> <li><a href="/_drafts/assets/testimage/dogtest.svg">svg</a> (vector, text. Open with a text editor to view the XML, edit the numbers to change the image)</li> <li><a href="/_drafts/assets/testimage/dogtest.pbm">pbm</a> (raster, text. Open with a text editor to see black and white pixels represented as <code class="language-plaintext highlighter-rouge">1</code> and <code class="language-plaintext highlighter-rouge">0</code>, edit to change the image)</li> </ul> Sun, 06 Jan 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/file-types.html https://evanwill.github.io/_drafts/notes/file-types.html Setup Jupyter with Py 2, 3, and R <p><strong>Note: this is out of date and due to new licensing terms, I no longer suggest using Anaconda.</strong></p> <p><a href="http://jupyter.org/">Jupyter</a> / Jupyter Notebook is a great tool for teaching code and exploratory, iterative coding.</p> <p>You can quickly demo it online at <a href="https://jupyter.org/try">Try Jupyter</a>!</p> <p>Jupyter was originally developed for <a href="https://www.python.org">Python</a>, but it now supports <a href="https://github.com/jupyter/jupyter/wiki/Jupyter-kernels">kernels for many languages</a>. With multiple kernels installed, you will be given a choice to launch notebooks using any of those languages. Thus, Notebook becomes even more useful with both Python 2 and 3 installed (keep in mind <a href="https://wiki.python.org/moin/Python2orPython3">Python 3 is current, 2 is legacy</a>). And you may as well add <a href="https://www.r-project.org/">R</a> while you’re at it!</p> <h2 id="1-install-jupyter-via-anaconda">1. Install Jupyter via Anaconda</h2> <p>First, <a href="http://jupyter.org/install.html">Jupyter project</a> and I suggest you install Python 3 via the <a href="https://www.anaconda.com/download/">Anaconda</a> distribution. Anaconda gives you a <a href="https://docs.anaconda.com/anaconda/packages/pkg-docs/">huge package</a> of scientific Python libraries pre-installed, plus <code class="language-plaintext highlighter-rouge">conda</code>, a very handy management and virtual environment tool (also comes with <a href="https://docs.anaconda.com/anaconda/navigator/">Anaconda Navigator</a> GUI, which is kind of annoying, and <a href="https://www.spyder-ide.org/">Spyder IDE</a>). Once you install Anaconda Python 3, you automagically have Jupyter with the IPython3 kernel ready to go.</p> <ul> <li>Download latest version of <a href="https://www.anaconda.com/download/">Anaconda Python 3</a></li> <li>Run <a href="http://docs.anaconda.com/anaconda/install/">installer</a>, but be sure to say yes to “add Anaconda to my PATH”.</li> </ul> <p>If you already have Anaconda installed, be sure to update before adding the additional kernels. Anaconda can be completely upgraded using <code class="language-plaintext highlighter-rouge">conda update conda</code>, then <code class="language-plaintext highlighter-rouge">conda update anaconda</code>.</p> <h2 id="2-add-python-2-kernel-to-jupyter">2. Add Python 2 kernel to Jupyter</h2> <p>Second, add the Python 2 kernel using a <a href="https://docs.conda.io/projects/conda/en/latest/user-guide/getting-started.html#managing-envs">virtual environment</a>:</p> <ol> <li>open a terminal and create a new Python 2 environment: <code class="language-plaintext highlighter-rouge">conda create -n py27 python=2.7</code>. This will take a minute to install the Python 2 dependency.</li> <li>activate the environment: linux <code class="language-plaintext highlighter-rouge">source activate py27</code> or windows <code class="language-plaintext highlighter-rouge">activate py27</code></li> <li>install the kernel in the env: <code class="language-plaintext highlighter-rouge">conda install ipykernel</code></li> <li>close the env: <code class="language-plaintext highlighter-rouge">source deactivate</code></li> </ol> <h2 id="3-add-r-kernel-to-jupyter">3. Add R kernel to Jupyter</h2> <p>Third, add <a href="https://docs.anaconda.com/anaconda/user-guide/tasks/use-r-language/">R via Conda</a>. Conda <a href="https://docs.anaconda.com/anaconda/packages/r-language-pkg-docs/">R-essentials</a> package includes a bunch of popular R packages, including the Notebook IRKernel.</p> <blockquote> <p>Note: Anaconda gives you the choice of using <a href="https://mran.microsoft.com/open">MRO</a> or normal <a href="https://www.r-project.org/">R</a>. Use conda packages <code class="language-plaintext highlighter-rouge">mro-base</code> or <code class="language-plaintext highlighter-rouge">r</code> respectively.</p> </blockquote> <p>If you want R to be generally available, simply open a terminal and install R, R-essentials, and RStudio (optional, <a href="https://evanwill.github.io/_drafts/notes/r-linux.html">more notes</a>): <code class="language-plaintext highlighter-rouge">conda install -c r r-essentials rstudio</code></p> <p>If you would rather keep R in a environment, open a terminal and create a new R env: <code class="language-plaintext highlighter-rouge">conda create -n mro_env r-essentials mro-base</code>. The R installed in this env will be available to Jupyter Notebook.</p> <h2 id="start-notebook">Start Notebook</h2> <p>Open a terminal and type: <code class="language-plaintext highlighter-rouge">jupyter notebook</code></p> <p>The Notebook interface will open in your browser (ignore the server back end running in the terminal). On the right side of the Notebook, click the “New” button. You should have the options for Python [default] (i.e. conda py 3), Python 2, and R. Pretty handy for teaching and learning!</p> <p>To shut down Jupyter, close the browser window, then <code class="language-plaintext highlighter-rouge">Ctrl + C</code> in the terminal host.</p> <h2 id="extensions">Extensions</h2> <p>Conda has a few other addons available for Jupyter. Check the <a href="https://docs.anaconda.com/anaconda/user-guide/tasks/use-jupyter-notebook-extensions/">extension documentation</a> to learn more.</p> <ul> <li><a href="http://beakerx.com/">BeakerX</a> (newish project recently converted into an extension of Jupyter allowing multiple languages in a single notebook and other enhancements. Can be installed via <code class="language-plaintext highlighter-rouge">conda</code>)</li> </ul> <h2 id="sharing-on-the-web">Sharing on the web</h2> <ul> <li><a href="https://nbviewer.jupyter.org/">nbviewer</a> (easy way to share a static rendered version of a notebook from GitHub)</li> <li><a href="https://mybinder.org/">binder</a> (open a GitHub repo of notebooks in a temporary executable environment, <a href="https://mybinder.readthedocs.io/en/latest/">docs</a>)</li> </ul> <h2 id="jupyterlab">JupyterLab</h2> <p><a href="https://jupyterlab.readthedocs.io/en/stable/index.html">JupyterLab</a> is the next generation of Notebook that has been rolling out since about Feb 2018 (<a href="https://blog.jupyter.org/jupyterlab-is-ready-for-users-5a6f039b8906">news</a>). Designed as a more complete IDE-like environment, Lab still fully supports notebooks, but provides more advanced features. If you installed Anaconda, you already have Lab ready to go, and all your environments will be available.</p> <p>Open a terminal and type <code class="language-plaintext highlighter-rouge">jupyter lab</code> to start it up.</p> <blockquote> <p>JupyterLab is actually available when you run <code class="language-plaintext highlighter-rouge">jupyter notebook</code> too, from the base url, something like <code class="language-plaintext highlighter-rouge">http://localhost:8888/tree</code>, replace the directory with <code class="language-plaintext highlighter-rouge">/lab</code>.</p> </blockquote> <h2 id="other-notebooks">Other Notebooks</h2> <p>Notebooks are gaining attention for integrating code and publication, opening possibilities for interactive sharing and visualization.</p> <ul> <li><a href="http://www.sagemath.org/">SageMath</a> (math focused notebook platform, an “open source alternative to Magma, Maple, Mathematica, and MATLAB”. A solid project that has been around fsince 2005, but hasn’t gained much popularity.)</li> <li><a href="https://zeppelin.apache.org/">Apache Zepplin</a> (Java based notebook particularly useful for dashboards and Spark cluster integration, i.e. big data)</li> <li><a href="https://nteract.io/">nteract</a> (desktop app or <a href="https://atom.io/packages/hydrogen">Atom package</a> built on top of Jupyter kernels to improve/simplify notebook experience)</li> </ul> <p>Others are running in the cloud to lower barriers to getting started and promote reproducibility:</p> <ul> <li><a href="https://colab.research.google.com/">Colaboratory</a> (Jupyter environment hosted by Google designed to run TensorFlow without installing anything, with your notebooks stored in Google Drive)</li> <li><a href="https://observablehq.com/">Observable</a> (JavaScript based data visualization for the web)</li> <li><a href="https://codeocean.com/">Code Ocean</a> (a variety of notebooks and IDE available)</li> <li><a href="https://cocalc.com/">COCALC</a> (was SageMath Cloud, now has Jupyter Notebook with lots of kernels, a LaTeX editor, and more)</li> <li><a href="https://github.com/iodide-project/iodide">Iodide</a> and <a href="https://github.com/iodide-project/pyodide/">Pyodide</a> (web focused notebooks implemented in browser, in alpha development)</li> <li><a href="https://stenci.la/">Stencila</a> (word processor + spreadsheet + code)</li> <li><a href="https://notebooks.azure.com/">Azure Notebooks</a></li> </ul> <h2 id="issues-on-linux">Issues on Linux</h2> <p>When installing on Fedora I have run into issues where some applications no longer work because they are trying to use Anaconda rather than the default system Python (I haven’t had this happen on Ubuntu). The installer adds a line to your <code class="language-plaintext highlighter-rouge">.bashrc</code> in order to make Anaconda available on your path. Open <code class="language-plaintext highlighter-rouge">sudo nano ~/.bashrc</code>, and look for a line like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># added by Anaconda3 installer export PATH="/home/username/anaconda3/bin:$PATH" </code></pre></div></div> <p>One quick fix is to flip PATH and Anaconda, so your system Python will be found first by default. Change the <code class="language-plaintext highlighter-rouge">.bashrc</code> line above to <code class="language-plaintext highlighter-rouge">export PATH="$PATH:/home/edog/anaconda3/bin"</code>, then reboot. Your applications will correctly find the system Python, but you can still easily access Anaconda’s <code class="language-plaintext highlighter-rouge">conda</code>, <code class="language-plaintext highlighter-rouge">ipython</code>, and <code class="language-plaintext highlighter-rouge">jupyter</code>. Keep in mind, if you type <code class="language-plaintext highlighter-rouge">python</code> in the terminal, it will be the system Python, not Anaconda.</p> Sun, 06 Jan 2019 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/dual-python-notebook.html https://evanwill.github.io/_drafts/notes/dual-python-notebook.html Update GitHub Fork <p><a href="https://help.github.com/articles/fork-a-repo/">Forking</a> a repository is a feature unique to GitHub (i.e. it is <em>not</em> a Git function). A fork is a complete copy of a repository that retains a link to the original. They are used in a similar way to Git <a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell">Branches</a>, allowing you to experiment and make changes independent of the main/master version which can then be merged back into the source. This supports a workflow where anyone can offer contributions to open projects via <a href="https://help.github.com/articles/creating-a-pull-request-from-a-fork/">pull requests</a>.</p> <p>However, it is often a bit mystifying how to keep your fork up-to-date with the original. A simple solution is to delete your stale fork and then fork a new one–but there is (of course) a way to update safely.</p> <p><em>Instructions below use <code class="language-plaintext highlighter-rouge">main</code> as default branch, if you have an older repository the default may be <code class="language-plaintext highlighter-rouge">master</code> instead</em></p> <h2 id="sync-fork-on-commandline">Sync fork on commandline</h2> <p>To sync your fork from the original repository is two steps:</p> <ol> <li><a href="https://help.github.com/articles/configuring-a-remote-for-a-fork/">Setup the upstream remote</a> (only have to do this one time) <ul> <li>check current config: <code class="language-plaintext highlighter-rouge">git remote -v</code></li> <li>add upstream remote (use the clone link from the original repo): <code class="language-plaintext highlighter-rouge">git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git</code></li> </ul> </li> <li><a href="https://help.github.com/articles/syncing-a-fork/">Sync fork</a> <ul> <li><code class="language-plaintext highlighter-rouge">git fetch upstream</code></li> <li><code class="language-plaintext highlighter-rouge">git checkout main</code></li> <li><code class="language-plaintext highlighter-rouge">git merge upstream/main</code></li> <li>You’re up-to-date locally, then update your fork on github, <code class="language-plaintext highlighter-rouge">git push</code></li> </ul> </li> </ol> <h2 id="sync-fork-on-github-desktop">Sync fork on GitHub Desktop</h2> <ol> <li>Click current branch button in top menu (this should bring up a branch panel)</li> <li>At bottom of the branch panel click “choose branch to merge with main” (this should open a dialog box)</li> <li>Click “upstream/main” (this should be the original repo that you forked)</li> <li>Click “Merge upstream/main” (this will fetch the updates in the original repo and attempt to merge them into your current branch)</li> </ol> <h2 id="sync-fork-on-github-web-interface">Sync fork on GitHub web interface</h2> <p>There is also a weird work around to do it via the GitHub web interface:</p> <ol> <li>Go to the original repository (not your fork).</li> <li>Click on “New pull request”</li> <li>On “compare changes” page, click the little text that says “compare across forks”.</li> <li>Select your fork from the “base fork” drop down (this means you are pulling code from the original and sending it to your fork), if all is good it will say “Able to merge”</li> <li>Add a PR message and click green “Create pull request” button.</li> <li>Your fork now has a PR, click “Merge pull request” to complete.</li> </ol> Tue, 04 Dec 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-update-fork.html https://evanwill.github.io/_drafts/notes/git-update-fork.html ExifTool Notes <p>To read, write, and manipulate metadata embedded in image files you need <a href="https://exiftool.org/">ExifTool</a> (p.s. can also read/write metadata on many other file formats such as PDF, videos, music, and documents). Truthfully, nothing else works reliably.</p> <h2 id="install">Install</h2> <p>ExifTool is a <a href="https://www.perl.org/">Perl</a> library and commandline tool. Check the <a href="https://exiftool.org/install.html">install docs</a> for full information, but basically on Windows use the “stand-alone executable”, Mac use the “MacOS package”, and on Linux use your distro repository.</p> <p><strong>Windows:</strong></p> <ul> <li>Download the “stand-alone Windows Executable” from the <a href="https://exiftool.org/">ExifTool</a> page (this will be a <code class="language-plaintext highlighter-rouge">.zip</code> file e.g. “exiftool-11.99.zip”).</li> <li>Unzip the downloaded file.</li> <li>Inside you will find a file named <code class="language-plaintext highlighter-rouge">exiftool(-k).exe</code>. Rename it to <code class="language-plaintext highlighter-rouge">exiftool.exe</code>.</li> <li>Add it to your PATH: <ul> <li>If you use Git Bash, find your Git Bash root directory by typing <code class="language-plaintext highlighter-rouge">cd /</code> then <code class="language-plaintext highlighter-rouge">pwd -W</code>. In your Git Bash root, copy <code class="language-plaintext highlighter-rouge">exiftool.exe</code> into the <code class="language-plaintext highlighter-rouge">bin</code> folder (see <a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">my note on adding stuff to Git Bash</a> for more detail). ExifTool will only be available on Git Bash, but this install method does not require admin access and I would suggest only using Git Bash with it anyway.</li> <li>Alternatively, you can copy <code class="language-plaintext highlighter-rouge">exiftool.exe</code> into a directory on the Window’s PATH, i.e. <code class="language-plaintext highlighter-rouge">C:\Windows</code>. ExifTool will be available on CMD and GitBash.</li> </ul> </li> </ul> <p><strong>Linux:</strong></p> <ul> <li>install ExifTool as the Perl library, e.g. <code class="language-plaintext highlighter-rouge">sudo apt install libimage-exiftool-perl</code>.</li> </ul> <h2 id="use">Use</h2> <p>To use ExifTool, start with the command <code class="language-plaintext highlighter-rouge">exiftool</code>, add some options, and the file name of an image. Type <code class="language-plaintext highlighter-rouge">exiftool</code> to printout the <a href="https://exiftool.org/exiftool_pod.html">full manual page</a>.</p> <h3 id="read-metadata">Read Metadata</h3> <p>The most basic command is to read all metadata for an image:</p> <p><code class="language-plaintext highlighter-rouge">exiftool test.jpg</code></p> <p>However, Exiftool has batch options built in, so you could replace the filename with a selector such as <code class="language-plaintext highlighter-rouge">*.jpg</code> to read multiple images.</p> <p>From there add <em>Options</em> and/or <em>Tags</em> to the command.</p> <p><strong>Options</strong> typically change the tool’s output. Option examples:</p> <ul> <li><code class="language-plaintext highlighter-rouge">-v</code>, the <a href="https://exiftool.org/verbose.html">Verbose Option</a> adds more technical detail to the output: <code class="language-plaintext highlighter-rouge">exiftool -v test.jpg</code></li> <li><code class="language-plaintext highlighter-rouge">-T</code> outputs the data as a tab delimited table: <code class="language-plaintext highlighter-rouge">exiftool -T test.jpg &gt; table.txt</code></li> <li><code class="language-plaintext highlighter-rouge">-csv</code> outputs as csv and automatically adds a “SourceFile” column with the file name: <code class="language-plaintext highlighter-rouge">exiftool -csv *.jpg &gt; metadata.csv</code></li> <li><code class="language-plaintext highlighter-rouge">-X</code> outputs RDF/XML format: <code class="language-plaintext highlighter-rouge">exiftool -X test.jpg &gt; metadata.xml</code></li> <li><code class="language-plaintext highlighter-rouge">-ee</code> reads metadata for embedded files in addition to the main file, e.g. images combined into a PDF: <code class="language-plaintext highlighter-rouge">exiftool -ee test.pdf</code></li> <li><code class="language-plaintext highlighter-rouge">-a</code> (allow duplicates) and <code class="language-plaintext highlighter-rouge">-u</code> (allow unknown tags) extract metadata that might otherwise be hidden: <code class="language-plaintext highlighter-rouge">exiftool -a -u test.jpg</code></li> </ul> <p><strong>Tags</strong> correspond to embedded metadata elements and are used to read or write specific values. Metadata elements are given a “Tag Name” (and machine readable “Tag ID”) that ExifTool can take as a commandline argument by adding <code class="language-plaintext highlighter-rouge">-</code> in front. To find the notation explore the <a href="https://exiftool.org/TagNames/index.html">Tag Names</a> index.</p> <p>To <strong>read</strong> a specific tag, include it as an argument. For example, <code class="language-plaintext highlighter-rouge">exiftool -Make test.jpg</code> will output the EXIF metadata for camera/scanner make.</p> <p>A batch of GPS tags can be extracted using:</p> <p><code class="language-plaintext highlighter-rouge">exiftool -gpslatitude -gpslongitude -csv *.jpg &gt; locations.csv</code></p> <p><em>Note</em>, some tags are part of a larger “group”, such as IPTC or XMP, and may have a “namespace”. The tag names are prefixed with the group name, for example, <code class="language-plaintext highlighter-rouge">-XMP:Description</code> or <code class="language-plaintext highlighter-rouge">-IPTC:Source</code>. Namespaces are added to the group name, for example, <code class="language-plaintext highlighter-rouge">-XMP-dc:Source</code>.</p> <h3 id="write-metadata">Write Metadata</h3> <p>Writing metadata follows the same pattern as reading, but adds a value to the Tag. To <strong>write</strong> a specific tag, include the tag argument followed by a <code class="language-plaintext highlighter-rouge">=</code> and value.</p> <p>For example, to build up the command flag we want to add XMP metadata (<code class="language-plaintext highlighter-rouge">-XMP</code>), from Dublin Core namespace (<code class="language-plaintext highlighter-rouge">-dc</code>), in the tag Source (<code class="language-plaintext highlighter-rouge">:ProjectionType</code>), with the value of “Example source” (<code class="language-plaintext highlighter-rouge">="Example source"</code>). Thus to add/change that one metadata value, the full command would be: <code class="language-plaintext highlighter-rouge">exiftool -XMP-dc:Source="Example source" test.jpg</code>.</p> <p>Writing examples:</p> <ul> <li><code class="language-plaintext highlighter-rouge">exiftool -Title="New title value" test.jpg</code> will delete the current EXIF title and replace it with “New title value”.</li> <li><code class="language-plaintext highlighter-rouge">exiftool -Title= test.jpg</code> will delete the current EXIF title, i.e. replacing the value with nothing.</li> <li><code class="language-plaintext highlighter-rouge">exiftool -all= test.jpg</code> will delete all current metadata except the most basic technical EXIF.</li> <li><code class="language-plaintext highlighter-rouge">exiftool -XMP-dc:Source="Uni, Uni Archives, Wonderful Collection" test.jpg</code> will add XMP Dublin Core metadata.</li> <li>Multiple tags can be written simply by adding more flags, <code class="language-plaintext highlighter-rouge">exiftool -Title="New title" -XMP-dc:Source="Uni, Uni Archives, Wonderful Collection" test.jpg</code></li> </ul> <p><em>Note</em>, although there are lots of possible ways to embed metadata, not many are actually readable to commonly used applications. If you want the metadata to be visible in Window’s file properties stick to common tags such as Title, Authors, and Copyright. Full XMP DC elements are not commonly read. IPTC metadata has a ~30 character limit.</p> <h3 id="use-for-batches">Use for Batches</h3> <p>If you want to add the same metadata to a large batch of files, it is most efficient to use ExifTool’s built in batch processing. For example, adding a wildcard <code class="language-plaintext highlighter-rouge">*</code> and file extension <code class="language-plaintext highlighter-rouge">.tif</code> will add the metadata tags to all TIF files in a folder:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>exiftool -Title="Example Collection" -Copyright="Photo courtesy of the Example Collection, University of X." -XMP-dc:Source="Example Collection, SPEC, University of X." *.tif </code></pre></div></div> <p>If each file requires individualized metadata, it is possible to use a Bash loop, although this is much slower. For example, this loop uses the file name (assumed to be based on an identifier) to add an identifier to the metadata:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for f in *.tif; do exiftool -Title="Example Collection, ${f%.tif}" -Copyright="Photo courtesy of the Example Collection, catalog nos. ${f%.tif}, SPEC, University of X" -XMP-dc:Source="Example Collection, catalog nos. ${f%.tif}, SPEC, University of X" "$f"; done </code></pre></div></div> <h2 id="guidelines-for-digitized-materials">Guidelines for Digitized materials</h2> <ul> <li>FADGI, <a href="http://www.digitizationguidelines.gov/guidelines/digitize-core_embedded_metadata.html">Minimal Descriptive Embedded Metadata in Digital Still Images</a> (<a href="http://www.digitizationguidelines.gov/guidelines/GuidelinesEmbeddedMetadata.pdf">PDF</a>)</li> <li>FADGI, <a href="http://www.digitizationguidelines.gov/guidelines/digitize-tiff.html">Embedded Metadata in TIFF Images</a></li> </ul> Tue, 27 Nov 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/exiftool.html https://evanwill.github.io/_drafts/notes/exiftool.html OpenRefine for Metadata <p>Outline:</p> <ul> <li>Import metadata: <ul> <li>character encoding (UTF-8!)</li> <li>import options (separator, batches)</li> <li>CONTENTdm TSV parsing issues: uncheck the option <code class="language-plaintext highlighter-rouge">Use character " to enclose cells containing column separators</code></li> </ul> </li> <li>Explore metadata: <ul> <li>facets (from column menu)</li> <li>text filter (from column menu)</li> </ul> </li> <li>Clean up metadata: <ul> <li>editing facets / cells (hover on value)</li> <li>trim whitespace (from column menu)</li> <li>Star / Flag, and facet (all column menu)</li> <li>remove rows (all column menu)</li> <li>reorder columns (all column menu)</li> <li>split into multiple columns (from column menu)</li> </ul> </li> <li>Clean up multi-valued cells (e.g. Subjects): <ul> <li>split multi-valued cells (from column menu)</li> <li>trim (from column menu)</li> <li>cluster (from column menu)</li> <li>join multi-valued cells (from column menu)</li> </ul> </li> <li>Transform using GREL: <ul> <li>add text, <code class="language-plaintext highlighter-rouge">value + " something new"</code></li> <li>find &amp; replace, <code class="language-plaintext highlighter-rouge">value.replace("old","new")</code></li> <li>get values from other cells, <code class="language-plaintext highlighter-rouge">cells['column_name'].value</code></li> <li>dates: <a href="https://github.com/OpenRefine/OpenRefine/wiki/GREL-Date-Functions">GREL dates</a>, <code class="language-plaintext highlighter-rouge">value.toDate().toString('yyyy-MM-dd')</code></li> </ul> </li> <li>Export metadata: <ul> <li>CSV export</li> <li>templating</li> </ul> </li> </ul> <p>Reference:</p> <ul> <li><a href="https://github.com/OpenRefine/OpenRefine/wiki/General-Refine-Expression-Language">GREL</a></li> <li><a href="https://evanwill.github.io/clean-your-data/">Clean Your Data</a> workshop</li> <li><a href="https://programminghistorian.org/en/lessons/fetch-and-parse-data-with-openrefine">Fetching and Parsing Data from the Web with OpenRefine</a> tutorial</li> <li><a href="https://evanwill.github.io/_drafts/notes/open-refine-tips.html">Handy OpenRefine Functions to Remember</a></li> </ul> Mon, 26 Nov 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/open-refine-metadata.html https://evanwill.github.io/_drafts/notes/open-refine-metadata.html Get started with Linux! <blockquote> <p>Please check out <a href="https://evanwill.github.io/try-linux/">Try Linux</a>, an updated version of this workshop.</p> <p>MILL workshop:</p> <p>Want to get started with Raspberry Pi or Linux on your laptop? This workshop will introduce the most popular operating system in the world! Although most people are more familiar with Windows or Mac, Linux OS runs the vast majority of web servers, super computers, smartphones (Android), TVs, and other electronic devices. You can also use desktop versions for free on your laptop or home computer! Come get an introduction to free and open source operating systems, and see desktop versions of Linux in action on Raspberry Pi and laptops. We will get oriented to the basics of the desktop and learn how to install it on a computer.</p> </blockquote> <p>The following notes provide a TON of information about getting started with Linux. But first, <em>take a deep breath</em>… don’t get overwhelmed by all this information!</p> <p>The barrier to getting started with desktop Linux on your own computer is much lower than you expect. Choose a Linux distribution (I suggest Ubuntu to start), create a live USB, plug it in to your computer, and voilà–you can try out Linux without having to install anything!</p> <p>Learn all the details from these notes:</p> <ol> <li><a href="https://evanwill.github.io/_drafts/notes/linux-intro.html">Intro to Linux</a>, learn about how to choose a Distro.</li> <li><a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn USB</a>, learn how to create a Live USB install media.</li> <li><a href="https://evanwill.github.io/_drafts/notes/linux-boot-usb.html">Boot USB</a>, the tips and tricks to boot a Live USB.</li> <li>Demo time (explore the “live session” from the USB. connect to the wifi, try the apps, just don’t click install!)</li> <li><a href="https://evanwill.github.io/_drafts/notes/commandline.html">Command Line demo</a> (optional)</li> </ol> Thu, 08 Nov 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/linux-workshop.html https://evanwill.github.io/_drafts/notes/linux-workshop.html Introduction to Linux! <blockquote> <p>Mini workshop:</p> <p>Want to get started with Raspberry Pi or Linux on your laptop? This workshop will introduce the most popular operating system in the world! Although most people are more familiar with Windows or Mac, Linux OS runs the vast majority of web servers, super computers, smartphones, TVs, and other electronic devices. You can also use desktop versions for free on your laptop or home computer!</p> </blockquote> <h2 id="what-is-linux">What is Linux?</h2> <p>Linux (<a href="https://upload.wikimedia.org/wikipedia/commons/0/03/Linus-linux.ogg">pronunciation</a>) is a family of open source operating systems (OS). You might hear “Unix-like” or “*nix”, since Linux is part of a group of OS descended from the early research computing system <a href="https://en.wikipedia.org/wiki/Unix">UNIX</a>.</p> <p>An OS is made up of a many components, basically:</p> <ul> <li><strong>Bootloader:</strong> starts the low level processes necessary to boot an OS, most linux distributions use <a href="https://www.gnu.org/software/grub/">GRUB</a>.</li> <li><strong>Kernel:</strong> manages the hardware and low level software components, coordinating the complete OS. This is actually “<a href="https://www.kernel.org/">Linux</a>”.</li> <li><strong>Shell:</strong> text-based command line interface.</li> <li><strong>Desktop environment:</strong> graphical interface .</li> <li><strong>Applications:</strong> individual programs run from the desktop or shell.</li> </ul> <p>The core of Linux, the <a href="https://www.kernel.org/">kernel</a>, is developed by the <a href="https://www.linuxfoundation.org/about/">Linux Foundation</a> and original creator Linus Torvalds, with contributions from thousands of people and corporations around the world. Linux operating systems are usually shipped as a complete package of components called a distribution, or “distro”. There are hundreds to choose from, each with different philosophies, strengths, and use cases.</p> <h2 id="why-linux">Why Linux?</h2> <p>Linux core is <a href="https://www.gnu.org/philosophy/free-sw.en.html">Free Software</a>, meaning cost-free and freely licensed, giving you <strong>freedom</strong> (as in <a href="https://youtu.be/n9D7oeM3zd8">freeeeeedoooom</a>)! You can control, inspect, modify, copy, and share the OS. But for most users, that is not necessarily the most compelling reason to use Linux. Instead they just appreciate a solid, powerful, and user-friendly OS. Linux provides security, privacy, stability/reliability, customization, and cost benefits, in addition to access to a huge ecosystem of open-source applications and services.</p> <p>Linux runs the vast majority of web servers (95%+), super computers (all of the top 500), smart phones (80%+), Chromebooks, IoT, and single board computers. So if you want to use a VM in the cloud, do high performance computing, or tinker with a Raspberry Pi at home, it’s helpful to know Linux. But it also makes a great desktop OS for your personal computer! Thus, there are many practical <em>and</em> ideological reasons to use Free and Open software.</p> <p>For an in depth introduction, try the free edX course from the Linux Foundation, <a href="https://training.linuxfoundation.org/training/introduction-to-linux/">Introduction to Linux</a>.</p> <blockquote> <p>Bloatware, adware, viruses, oh my! Many people are sick of the shady commercial practices of Windows, Apple, and PC manufacturers that put user security and privacy at risk. Proprietary OS limit your rights and control as a user. Linux distros are viable alternatives!</p> </blockquote> <h2 id="distributions">Distributions</h2> <p>Surf <a href="https://distrowatch.com/">Distrowatch</a> to browse the latest distro news! Part of the fun of getting started with Linux is choosing a distro, but there are so many it can also be very overwhelming. Most distros are a package of technical low-level stuff, plus a desktop and selection of basic applications. Some are focused on running servers, others on desktop users.</p> <p>Here are some things to consider:</p> <ul> <li><strong>Out-of-the-box experience.</strong> Do you want it to just work or are you willing to spend time customizing? Do you want all the applications pre-installed (openSUSE) or minimalist (Arch)?</li> <li><strong>Community.</strong> Do you want to search online and find hundreds of answers to your questions (Ubuntu), be part of a values driven community (Fedora), or get involved in a smaller forum of deeply invested enthusiasts (Arch)?</li> <li><strong>Repositories.</strong> Some distros have huge repos of applications (Debian), making installing new software secure and easy. Some are more up-to-date than others (Fedora). Others are more DIY (Arch). Some distros package only free and open software that meets their community guidelines (Fedora); others include commonly used, but non-free software, such as MP3 encodings (Ubuntu).</li> <li><strong>Ecosystem.</strong> Do you use a Linux server at work or some hobby project? Choose a distro from the same family to make life easier.</li> <li><strong>Hardware support.</strong> Unlike Windows, with Linux you don’t have to install a bunch of drivers to get everything to work. However, some distros support a huge range of legacy hardware, while others have better support for the newest hardware built in. It is often difficult to run high performance graphics cards with out specific distro support. Distros have different versions of the Linux Kernel–the newest have upgraded features and performance baked in, but have less of the kinks worked out.</li> <li><strong>Updates.</strong> Do you want to install an OS that will be supported for a LONG time so that you won’t have to upgrade or do you want the latest-and-greatest? Distros typically follow either a rolling or fixed release. <em>Rolling release</em> distros have a continuous stream of updates, you always have the latest software and never have to upgrade to a new version (but may encounter some instability). <em>Fixed release</em> are more traditional and stable with incremental versions that require a large upgrade every so often. Fixed releases are often broken into latest and LTS (long term support)–if you want to install once, and use the system for years without needed to upgrade, choose an LTS. For example, Ubuntu normal releases are officially supported for nine months, LTS for five years.</li> <li><strong>Installer!</strong> In the past, Linux distros were confusing to install, a major barrier to adoption–Ubuntu really changed that, and some installers are still friendlier than others. <ul> <li><strong>Secure Boot UEFI</strong>. If you have a newer computer, it will have Secure Boot UEFI which is only supported by the bigger Linux distros (Ubuntu, Fedora, SUSE)–otherwise you will have to tweak your UEFI / BIOS to get the installer to work.</li> <li><strong>Dual booting.</strong> Do you want to keep windows? Some installers make it easy (Ubuntu).</li> </ul> </li> </ul> <p>My easy suggestion: use <a href="https://www.ubuntu.com/">Ubuntu</a> or an <a href="https://ubuntu.com/download/flavours">Ubuntu flavor</a>. The installer is easy to use (supports easy dual booting with Windows) and hardware support is great. It also has the largest beginner and intermediate user community, so help is always easily at hand via blogs, wikis, and forums–if you search for general Linux help majority of answers are about Ubuntu. If a piece of software provides Linux instructions or packages, it will include Ubuntu.</p> <p>But check out the <a href="#major-distro-families">Major Distro Families</a> below for MORE suggestions!</p> <h2 id="desktop-environment">Desktop Environment</h2> <p>Next, you will have to choose your desktop environment (DE)–the graphical interface you will be staring at all day! Unlike windows, mac, or chrome, with Linux distros you have a choice of desktops. It is separate from the core of the distro and can be installed independently.</p> <p>Generally, you will choose a package pre-bundled with a DE, most distros will give you several options, with GNOME, KDE, and Xfce being most common. Distros often tweak their versions of the desktops, so the final look, default software, and features vary a bit. Just take a look at their screenshots and decide!</p> <p>But here are a bunch more details…</p> <p>Things to consider:</p> <ul> <li>Weight. How resource intensive is it? Slicker desktops (GNOME, KDE) require modern hardware to run well. If you have an old computer or low spec hardware, go light (Xfce, LXqt)!</li> <li>Configurability. How much do you want to tweak the look and feel? Do you want it to just look good out of the box?</li> <li>Unique vs. traditional. Do you want something different (GNOME) or are you nostalgic for the old days (Cinnamon)?</li> </ul> <p>See <a href="#major-desktop-environments">Major Desktop Environments</a> below for lots more detail…</p> <h2 id="64-or-32">64 or 32</h2> <p>One last choice you might have to make is 64 or 32-bit? Many distros have started to phase out 32-bit support, but you may still encounter the choice to download “64-bit” / “x86_64” / “AMD64” versus “32-bit” / “i386” / “i586”. If your computer is still running, it is likely new enough to be 64-bit, so I would suggest ignoring 32-bit options unless you know your hardware requires it. Some distros now also support ARM processors, such as found in Raspberry Pi, so you may encounter an option like “ARMv7”.</p> <h2 id="try-and-install">Try and Install!</h2> <p>The best way to learn Linux is to try it.</p> <p>When you buy a Windows, Chromebook, or Mac computer, the operating system (OS) comes pre-installed. However, if you are interested in running Linux or other open OS, you will usually have to install it yourself.</p> <p>Most modern Linux distros are released as an ISO disk image, usually a “live cd” or “live usb”. This means you can download an ISO, burn it to a USB stick, and then boot up into the live desktop without actually installing or changing your hard drive!</p> <p>Give it a try with these instructions to <a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">burn an ISO</a> and <a href="https://evanwill.github.io/_drafts/notes/linux-boot-usb.html">boot a live USB</a>.</p> <p>Once you try it out, install it!</p> <p>The live session will have an app to permanently install the OS on your machine. Most installers are graphical and user-friendly. Here is Ubuntu’s official <a href="https://tutorials.ubuntu.com/tutorial/tutorial-install-ubuntu-desktop">install tutorial</a>.</p> <blockquote> <p>Alternatively, if you <em>really</em> don’t want to even download anything, you can visit <a href="https://distrotest.net/index.php">Distrotest</a>. Distrotest will boot up a virtual machine with your disto of choice and open a remote desktop window right in your browser. The performance is slow (depending on your connection and the VM) and not exactly like using real hardware, but can be a nice option to quickly check out a new OS.</p> <p>As another option, you can install <a href="https://www.virtualbox.org/wiki/Downloads">VirtualBox</a> on a computer to try out any distro in a disposable virtual machine. The performance will be very limited, but it is an easy way to test something out or see what the install process looks like–and grab screenshots for tutorials or debugging.</p> <p>Manufactures such as Dell and Lenovo are offering more computers with Linux pre-installed, and Linux specific companies such as <a href="https://system76.com/">System76</a> are booming. More manufactures offering devices means better hardware support is being built into the Linux kernel.</p> </blockquote> <h2 id="basics">Basics</h2> <p>If you have ever used a computer, almost everything will be familiar! No big deal. Here are a few things slightly different from Windows:</p> <ul> <li><strong>User accounts and passwords.</strong> You are always logged in as a user and require a password to make any changes to the system (Windows tends to hide this).</li> <li><strong>File system, home directory.</strong> Linux uses a file system that Windows can’t read and is presented differently. On Windows the root is the drive letter <code class="language-plaintext highlighter-rouge">C:\</code>. Linux presents all drives as a unified file system, with the root at <code class="language-plaintext highlighter-rouge">/</code> and your user directory at <code class="language-plaintext highlighter-rouge">/home/username</code> (Linux doesn’t use Windows back slashes <code class="language-plaintext highlighter-rouge">\</code>).</li> <li><strong>Updates.</strong> Updates are pushed out regularly keeping you secure and fixing bugs–updates are <em>much</em> more common than on Windows, yet usually less of a hassle. The updates cover the OS <em>and</em> all applications installed from a repository. First, the catalog of all software in the distro’s repositories is updated, then updates that apply to your installed software (and dependencies) are downloaded. There is usually an updater application, but you may need to start it manually.</li> <li><strong>Software center.</strong> Applications can be easily and securely installed from your distro’s repository. There is usually an GUI app to find and manage software curated by the distro. Recently distro independent application packaging frameworks are supplementing or replacing traditional software repositories. The main frameworks include Snap (Ubuntu, <a href="https://snapcraft.io/">Snapcraft</a>), Flatpack (<a href="https://flathub.org/">Flathub</a>), and <a href="https://appimage.org/">Appimage</a>. These formats simplify software distribution, as each package has all dependencies fully self-contained (and often sandboxed).</li> <li><strong>Terminal.</strong> Command line is really handy! See this <a href="https://evanwill.github.io/_drafts/notes/commandline.html">mini-workshop</a>.</li> </ul> <h1 id="major-desktop-environments">Major Desktop Environments</h1> <p>The major desktops can be divided by their “widget toolkit” used to create the GUI elements and default applications. This is probably the last time you will ever hear “widget toolkit”, but you might hear something like GTX theme or Qt application. The details aren’t important, but you will see some family resemblance. All desktops can support both GTX and Qt applications, but software in the native toolkit will have more closely integrated and themed.</p> <p>Major desktops:</p> <ul> <li><a href="https://en.wikipedia.org/wiki/GTK">GTX based</a> <ul> <li><a href="https://www.gnome.org/">GNOME</a>. modern, minimalist-style, unique “Activities Overview” (no start menu), <a href="https://extensions.gnome.org/">extensions</a> add functionality, and themes easily change the look.</li> <li><a href="https://www.xfce.org/">Xfce</a>. lighter weight, simple, stable, traditional linux desktop. Offered as the default of many distros, often highly customized.</li> <li>Less common: <ul> <li><a href="http://developer.linuxmint.com/projects.html">Cinnamon</a>. more traditional desktop with start menu (get newest version with <a href="https://www.linuxmint.com/">Mint</a>).</li> <li><a href="https://budgie-desktop.org/">Budgie</a>. slick, GNOME-based (get newest version with <a href="https://getsol.us/home/">Solus</a>).</li> <li>Pantheon. polished, GNOME-based (developed by <a href="https://elementary.io/">ElementaryOS</a>)</li> <li><a href="https://mate-desktop.org/">MATE</a>. traditional, lighter weight, based on an old version of GNOME.</li> <li><a href="http://lxde.org/">LXDE</a>. very light weight, basic features (development has shifted to LXQt instead, so check out LXQt instead).</li> <li>Historic note: <del>Unity</del>. Until version 17.10, Ubuntu shipped with a unique desktop. However, Ubuntu’s GNOME theme emulates the Unity look.</li> </ul> </li> </ul> </li> <li><a href="https://en.wikipedia.org/wiki/Qt_(software)">Qt based</a> <ul> <li><a href="https://www.kde.org/">KDE</a>. very configurable, complex, windows-like (get newest version with <a href="https://neon.kde.org/">Neon</a>).</li> <li><a href="http://lxqt.org/">LXQt</a>. very light weight, basic features (sibling of LXDE).</li> <li>DDE. Polished desktop of <a href="https://www.deepin.org/en/">Deepin linux</a> (Chinese focused), recently becoming available in other distros.</li> </ul> </li> <li>Other <ul> <li>Tiling window managers (the traditional desktop metaphor is replaced by automatically dividing the screen with your open application windows, controlled by key commands, for a simple and efficient desktop. There is a bit of a learning curve!) Checkout <a href="http://xmonad.org/">xmonad</a> or <a href="https://i3wm.org/">i3</a>. For any easy intro, checkout <a href="https://regolith-linux.org/">Regolith Linux</a> which combines i3-wm with Ubuntu.</li> </ul> </li> </ul> <blockquote> <p>Most desktops support themes which make it easy to change the look and feel. For example check out the themes page at <a href="http://www.omgubuntu.co.uk/category/themes-2">OMG! Ubuntu!</a>.</p> </blockquote> <h1 id="major-distro-families">Major Distro Families</h1> <p>Below is a basic introduction to the major linux families, with a focus on distros with desktop friendly versions.</p> <h3 id="debian">Debian</h3> <p>One of the oldest active linux distros, Debian has extensive stable repositories that are the base of MANY other distros. This includes Ubuntu, developed by enterprise software company <a href="https://www.canonical.com/">Canonical</a> based in the UK. Uses <code class="language-plaintext highlighter-rouge">apt</code> configuration and <code class="language-plaintext highlighter-rouge">.deb</code> packages.</p> <ul> <li><a href="https://www.debian.org/">Debian</a>, entirely free software released by the Debian Project. <a href="https://www.debian.org/distrib/packages">Debian packages</a>.</li> <li><a href="https://www.ubuntu.com/">Ubuntu</a>, the most popular desktop linux, beginner friendly. <a href="https://packages.ubuntu.com/">Ubuntu Packages</a> and <a href="https://snapcraft.io/">Snapcraft</a>. <ul> <li><a href="https://ubuntu.com/download/flavours">Ubuntu flavors</a>, Ubuntu spins featuring alternative desktops.</li> <li><a href="https://www.linuxmint.com/">Linux Mint</a>, one of the most popular and beginner friendly, featuring the Cinnamon desktop.</li> <li><a href="https://elementary.io/">Elementary OS</a>, stylish mac replacement, unique Pantheon desktop.</li> <li><a href="https://system76.com/pop">Pop!_os</a>, customized Gnome desktop with some unique addons, built by computer company <a href="https://system76.com">System76</a> focused on developers.</li> <li><a href="https://neon.kde.org/">KDE Neon</a>, cutting edge KDE on Ubuntu base.</li> <li><a href="https://zorinos.com/">Zorin OS</a>, polished windows replacement.</li> <li><a href="https://www.linuxliteos.com/">Linux Lite</a>, focused on easy to use, windows replacement, with Xfce.</li> <li><a href="https://www.bodhilinux.com/">Bodhi Linux</a>, minimalist, lightweight distro with unique Moksha desktop.</li> <li><a href="https://peppermintos.com/">Peppermint</a>, ChromeOS-like cloud focused minimal desktop.</li> <li><a href="https://galliumos.org/">GalliumOS</a>, Xubuntu based replacement for Chromebook hardware.</li> </ul> </li> <li><a href="https://www.raspberrypi.org/software/">Raspberry Pi OS</a>, official distro of Raspberry Pi, unique Pixel desktop (some other distros offer specialized spins for Pi as well)</li> <li><a href="https://endlessos.com/home/">Endless OS</a>, simplified, education focused system designed for offline use, by computer company <a href="https://endlessos.com/computers/">Endless</a>.</li> <li><a href="https://deepin.org/">deepin</a>, Chinese based distro with unique desktop and apps.</li> </ul> <h3 id="fedora--redhat">Fedora / RedHat</h3> <p>Based in the USA, <a href="https://www.redhat.com/">Red Hat</a> is one of the largest open-source enterprise software companies, providing support, development, and Linux OS to major corporations. It is a good choice to learn if you are interested in working with enterprise environments. Uses <code class="language-plaintext highlighter-rouge">yum</code> or <code class="language-plaintext highlighter-rouge">dnf</code> configuration and <code class="language-plaintext highlighter-rouge">.rpm</code> packages.</p> <ul> <li><a href="https://getfedora.org/">Fedora</a>, open project sponsored by Red Hat with a focus on free-software. Considered fairly cutting edge with two new versions each year, a testing ground for RHEL, yet stable enough for most users. <a href="https://apps.fedoraproject.org/packages/">Fedora Packages</a>. <ul> <li><a href="https://spins.fedoraproject.org/">Fedora Spins</a>, alternative desktops.</li> <li><a href="https://labs.fedoraproject.org/">Fedora Labs</a>, specialized distros from science to music.</li> <li><a href="https://spins.fedoraproject.org/en/soas/">Sugar on a Stick</a>, very unique kid focused learning platform, packaged to run on a live USB. Learn more at <a href="https://www.sugarlabs.org/">Sugar Labs</a>.</li> </ul> </li> <li><a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux">Red Hat Enterprise Linux (RHEL)</a>, an industry standard, non-free.</li> <li><del><a href="https://www.centos.org/">CentOS</a></del>, free community supported RHEL. Once very popular, was unexpectedly discontinued in 2020 during Red Hat corporate changes.</li> <li><del><a href="https://www.scientificlinux.org/">Scientific Linux</a></del>, free RHEL-based OS developed by Fermilab for high performance scientific computing environments (is now being phased out in favor of CentOS).</li> </ul> <h3 id="suse">SUSE</h3> <p>Germany based enterprise FOSS company. Uses <code class="language-plaintext highlighter-rouge">ZYpp</code> or <code class="language-plaintext highlighter-rouge">YaST</code> for configuration and <code class="language-plaintext highlighter-rouge">.rpm</code> packages.</p> <ul> <li><a href="https://www.opensuse.org/">openSUSE</a>, developer focused with a rolling release option, Tumbleweed. <em>Note: openSUSE default install ISO are not live images and can not be used to try without installing. They provide a separate live image, but it is not complete and cannot be used to install.</em> <a href="https://software.opensuse.org/find">openSUSE Packages</a>. <ul> <li><a href="https://geckolinux.github.io/">GeckoLinux</a>, openSUSE spin focused on being user friendly.</li> </ul> </li> <li><a href="https://www.suse.com/">SUSE Linux Enterprise</a>, commercial distro with focus on mature and stable server environments.</li> </ul> <h3 id="arch">Arch</h3> <p>An independent, community built family with rolling release following a <em>K.I.S.S.</em> and DIY philosophy. Not traditionally user friendly. Uses <code class="language-plaintext highlighter-rouge">pacman</code> for configuration. <a href="https://www.archlinux.org/packages/">Archlinux packages</a>.</p> <ul> <li><a href="https://www.archlinux.org/">Arch</a></li> <li><a href="https://manjaro.org/">Manjaro</a>, user friendly Arch for beginners.</li> <li><a href="https://endeavouros.com/">EndeavourOS</a>, intended to build user-friendly installer and community for Arch.</li> </ul> <h3 id="others">Others</h3> <p><strong>Independent.</strong> Some distros go it alone. For example:</p> <ul> <li><a href="https://getsol.us/home/">Solus</a>, up-and-coming independent distro developing Budgie desktop.</li> <li><a href="https://www.qubes-os.org/">Qubes OS</a>, personal security focused distro with unique architecture that isolates all software in separate VM-like containers. Major distros have also started offering fully containerized OS versions for max security and stability, such as <a href="https://ubuntu.com/core">Ubuntu Core</a> and <a href="https://silverblue.fedoraproject.org/">Fedora Silverblue</a> (see <a href="https://arstechnica.com/gadgets/2021/02/ubuntu-core-20-adds-secure-boot-with-hardware-backed-encryption/">explainer article</a>).</li> <li><a href="https://www.alpinelinux.org/">Alpine Linux</a>, minimalistic, security focused distro from Norway, commonly used as basic server image or as base for containers.</li> <li><a href="http://www.linuxfromscratch.org/">Linux From Scratch</a>, build everything yourself, step-by-step DIY!</li> </ul> <p><strong>Portable.</strong> Some linux distros are specifically designed to be portable, i.e. you always use them from a USB stick and do not install to a hard drive. This makes them simple, fast, and secure. For example:</p> <ul> <li><a href="http://puppylinux.org/">Puppy Linux</a></li> <li><a href="https://www.slax.org/en/">Slax</a></li> <li><a href="http://www.porteus.org/">Porteus</a></li> </ul> <p><strong>Android.</strong> Based on Linux, Android is the most popular smart phone OS in the world.</p> <ul> <li><a href="http://www.android-x86.org/">Android-x86</a>, port of Android that can be run on a laptop.</li> </ul> <p><strong>Entertainment.</strong> There are many specialized minimalist distros that act as entertainment centers, usually run on a Raspberry Pi or similar device.</p> <ul> <li>music player: <a href="https://volumio.org/">Volumio</a>.</li> <li>media center: <a href="https://osmc.tv/">OSMC</a> or <a href="http://openelec.tv/">OpenELEC</a>.</li> <li>gaming: <a href="https://retropie.org.uk/">RetroPie</a> or <a href="http://store.steampowered.com/steamos/">SteamOS</a>.</li> <li>NAS: <a href="http://www.freenas.org/">FreeNAS</a> or <a href="http://www.easynas.org/">EasyNAS</a>.</li> </ul> <p><strong>Utilities.</strong> Some specialized distros are basic utilities used to work on a computer where the main drive or OS maybe corrupted.</p> <ul> <li><a href="https://gparted.sourceforge.io/livecd.php">GParted Live</a>, partition and disk utility.</li> <li><a href="http://www.clonezilla.org/">Clonezilla</a>, disk imaging/cloning deployment or recovery.</li> <li><a href="https://dban.org/">DBAN</a>, disk data destroyer.</li> </ul> <h3 id="other-open-os">Other open OS</h3> <p>There are other open-source OS out there, Linux is just the most popular.</p> <ul> <li>BSD: a family of OS descended from <a href="https://en.wikipedia.org/wiki/Berkeley_Software_Distribution">Berkeley Software Distribution</a> Unix. Considered rock-solid stable and secure for servers, with desktop options <a href="https://www.freebsd.org/">FreeBSD</a> and <a href="https://www.trueos.org/">TrueOS</a>.</li> <li>OpenSolaris / illumos / SunOS: a family of Unix-like OS descended from proprietary enterprise systems, currently openly developed by the <a href="https://www.openindiana.org/">openindiana</a> community.</li> <li><a href="https://www.haiku-os.org/">Haiku</a>, based on BeOS, an early competitor to Mac.</li> <li><a href="http://kolibrios.org/en/">KolibriOS</a>, minimalist, tiny OS.</li> <li><a href="https://www.redox-os.org/">Redox OS</a>, newly developed OS written in <a href="https://www.rust-lang.org/en-US/">Rust</a> language.</li> </ul> <h1 id="resources">Resources</h1> <ul> <li>Julia Evans <a href="https://drawings.jvns.ca/">Drawings</a> and <a href="https://jvns.ca/zines/">Zines</a> are an approachable and amusing way to learn about advanced linux topics.</li> </ul> Tue, 06 Nov 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/linux-intro.html https://evanwill.github.io/_drafts/notes/linux-intro.html Commandline notes <p>Just some general notes to remember helpful things on the command line…</p> <h2 id="variable-remove-pattern">Variable remove pattern</h2> <p>In a bash loop you often want to replace a part of a filename with something else. There is two easy functions to remove filename/variable parts:</p> <ul> <li>Remove from front: <code class="language-plaintext highlighter-rouge">${var#pattern}</code></li> <li>Remove from back: <code class="language-plaintext highlighter-rouge">${var%pattern}</code></li> </ul> <p>For example, lets say you have a bunch of files with following the pattern <code class="language-plaintext highlighter-rouge">front-[id number]-back.txt</code> (front-10-back.txt, front-192-back.txt, etc.).</p> <p>To rename while removing the front: <code class="language-plaintext highlighter-rouge">for f in *.txt; do mv "$f" "${f#front-}"; done</code></p> <p>To rename while removing the back and changing the file extension: <code class="language-plaintext highlighter-rouge">for f in *.txt; do mv "$f" "${f%-back.txt}.md"; done</code></p> <p>However, you can’t use both a front and back remove at the same time. To get around that, use an extra variable. To combine the other two commands:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.txt; do NAME="${f#front-}"; mv "$f" "${NAME%-back.txt}.md"; done</code></p> <p>If you have spaces in the pattern, escape them. E.g. <code class="language-plaintext highlighter-rouge">name with space</code> use something like <code class="language-plaintext highlighter-rouge">${f#name\ with\ space}</code>.</p> <p>You can also use the syntax <code class="language-plaintext highlighter-rouge">${var/pattern/replacementstring}</code> to replace things in the filename. If the “pattern” chunk starts with an extra <code class="language-plaintext highlighter-rouge">/</code>, then it replaces all matches (not just the first). This way you could remove all spaces from filenames in a directory and replace them with underscore like: <code class="language-plaintext highlighter-rouge">for f in *\ *; do mv "$f" "${f// /_}"; done</code></p> <h2 id="change-string-case">Change String Case</h2> <p>Bash has a built in feature to convert the case of strings:</p> <ul> <li><code class="language-plaintext highlighter-rouge">^</code> convert 1st character to uppercase</li> <li><code class="language-plaintext highlighter-rouge">^^</code> convert whole string to uppercase</li> <li><code class="language-plaintext highlighter-rouge">,</code> convert 1st character to lowercase</li> <li><code class="language-plaintext highlighter-rouge">,,</code> convert whole string to lowercase</li> </ul> <p>This can be helpful for renaming all files with lowercase filenames and extensions. To do the renaming by copying to a new folder “renamed”:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.*; do cp "$f" "renamed/${f,,}"; done</code></p> <p>This could also be done using the older <code class="language-plaintext highlighter-rouge">tr</code> utility using a much more complicated command:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.*; do cp "$f" "renamed/$( tr '[:upper:]' '[:lower:]' &lt;&lt;&lt;"$f" )"; done</code></p> <h2 id="combine-csvs">Combine CSVs</h2> <p>Remove headers and combine all files into one:</p> <p><code class="language-plaintext highlighter-rouge">tail -n +1 *.csv &gt; all.csv</code></p> <p>Then, each file will be separated by <code class="language-plaintext highlighter-rouge">==&gt; filename &lt;==</code>. Open in OpenRefine, use separator <code class="language-plaintext highlighter-rouge">==&gt;</code>, then use <code class="language-plaintext highlighter-rouge">&lt;==</code> to create filename column.</p> <p>Or use a loop:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.txt; do cat $f; echo "separator"; done &gt; combo.txt</code></p> <h2 id="count-files-of-a-specific-type">Count files of a specific type</h2> <p>Sometimes you need a count of how many files of a specific type are in a folder including sub-folders. A quick method is to use find and wc to get a count. In the directory you want to count:</p> <p><code class="language-plaintext highlighter-rouge">find . -name "*.pdf" -type f | wc -l</code></p> <h2 id="extract-text-from-pdf">Extract text from PDF</h2> <p>Use <code class="language-plaintext highlighter-rouge">poppler-utils</code> package command <code class="language-plaintext highlighter-rouge">pdftotext</code> (which is probably already installed on linux, can be installed with <a href="https://www.xpdfreader.com/download.html">Xpdf tools</a> on windows):</p> <p><code class="language-plaintext highlighter-rouge">pdftotext filename outputname</code></p> <p><code class="language-plaintext highlighter-rouge">for f in *.pdf; do pdftotext "$f"; done</code></p> <h2 id="add-something-to-each-line">Add something to each line</h2> <p>Use sed:</p> <p><code class="language-plaintext highlighter-rouge">sed 's/^/stuff in front/; s/$/stuff at end/' "input.txt" &gt; output.txt</code></p> <p>In batch:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.txt; do sed 's/^/front/; s/$/back/' "$f" &gt; output/"$f"; done</code></p> <p>See <a href="https://www.grymoire.com/Unix/Sed.html">Sed: an introduction</a> for extensive tips.</p> <h2 id="get-list-of-files-meeting-criteria">Get list of files meeting criteria</h2> <p>I often have a folder of text files and need a list of which one contain some specific string. Easy using <code class="language-plaintext highlighter-rouge">grep</code> with the <code class="language-plaintext highlighter-rouge">-l</code> flag for listing filename only (not the matching lines):</p> <p><code class="language-plaintext highlighter-rouge">grep -l "string" * &gt; list.txt</code></p> <p>Or the opposite, files without the phrase, using <code class="language-plaintext highlighter-rouge">-L</code> for filenames with no match:</p> <p><code class="language-plaintext highlighter-rouge">grep -L "string" * &gt; list.txt</code></p> <h2 id="compare-two-text-files">Compare two text files</h2> <p>To compare two text files you can use <code class="language-plaintext highlighter-rouge">diff</code> or <code class="language-plaintext highlighter-rouge">comm</code>. I often use this to find the difference between two folders or lists of files (<code class="language-plaintext highlighter-rouge">ls &gt; filelist.txt</code>).</p> <p>Diff will show a report something like a git diff:</p> <p><code class="language-plaintext highlighter-rouge">diff list1.txt list2.txt</code></p> <p>Comm will output a list comparing the lines in the two files, grouping them by lines only in file 1, only in file 2, and in both. Add the options <code class="language-plaintext highlighter-rouge">-1</code>, <code class="language-plaintext highlighter-rouge">-2</code>, or <code class="language-plaintext highlighter-rouge">-3</code> to not view one of those groupings. Generally, I just want the differences, so use <code class="language-plaintext highlighter-rouge">-3</code> to NOT see the lines that are the same in both.</p> <p><code class="language-plaintext highlighter-rouge">comm -3 list1.txt list2.txt &gt; comparison.txt</code></p> <h2 id="copy-a-list-of-files">Copy a list of files</h2> <p>I often have a folder of binary files, like images, where I need to sort out a small group to upload or move somewhere else. Often the list of files that need to move comes from some other source, such as a spreadsheet. To do it as a batch, I export a list of the filenames that need to move, one filename per line (just like if you did <code class="language-plaintext highlighter-rouge">ls &gt; list.txt</code>), then use a bash loop like this:</p> <p><code class="language-plaintext highlighter-rouge">for f in $(cat list.txt); do cp $f ../upload/; done</code></p> <p>In this example, we use <code class="language-plaintext highlighter-rouge">cat list.txt</code> to print out the file contents to provide the variables for the loop to iterate over–this can be handy for a lot of pragmatic solutions!</p> <h2 id="dont-store-in-history">Don’t store in history</h2> <p>If you add a space at the beginning of the line, then the command won’t be recorded in your history. This is important if you are manually adding some passwords or secrets in the command.</p> <h2 id="use-command-output-in-another-command">Use command output in another command</h2> <p>Sometimes you can’t pipe output into a command, you need the output inside the command instead (i.e. “command substitution”). Use <code class="language-plaintext highlighter-rouge">$(command)</code> in place. E.g. <code class="language-plaintext highlighter-rouge">JUPYTER=$(which jupyter) julia</code> (gives julia-lang location of Jupyter Notebook).</p> <h2 id="handy-ref">Handy Ref</h2> <ul> <li><a href="https://devhints.io/bash">Bash scripting cheatsheet</a></li> <li><a href="https://ss64.com/bash/">SS64</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">mdn web docs Command Line Crash Course</a></li> <li><a href="https://ubuntu.com/tutorials/command-line-for-beginners#1-overview">Ubuntu commandline fore beginners</a></li> </ul> Tue, 30 Oct 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/commandline-notes.html https://evanwill.github.io/_drafts/notes/commandline-notes.html Golden Flippy Things <p><img src="/_drafts/assets/goldenflippies.jpg" alt="golden flippy things" /></p> <p>Rules for the <em>classic</em> beer game:</p> <ul> <li>each player must create their own golden flippy things (i.e. by taking bottle caps and pounding them flat and smooth with a hammer)</li> <li>each player should have a bunch</li> <li>each player should probably have an equal amount</li> <li>each round all players: <ul> <li>put one flippy into the pot</li> <li>shake out all of their golden flippy things at once</li> <li>then count up your flippies that landed with gold side up: <ul> <li>person with most gold up wins,</li> <li>unless a player has <em>all</em> non-gold side up, then they win,</li> <li>unless there is a tie, then all players have to put one extra flippy into the pot and no one wins this round.</li> </ul> </li> <li>the winner collects all flippies in the pot</li> </ul> </li> </ul> <p>Mechanics make it so that once someone starts winning, they will likely keep winning, yet it is quite hard to finish players off.</p> <blockquote> <p>these official rules date back to Pittsburgh, 2000.</p> </blockquote> Tue, 23 Oct 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/golden-flippy.html https://evanwill.github.io/_drafts/notes/golden-flippy.html Fake a photosphere with ExifTool <p>I like to incorrectly use photo features to see what interesting stuff happens. In this case, I want to upload any random image to Flickr and make it display as a photosphere.</p> <p>Photosphere’s are just regular flat JPG images, but the recorded image is a projection (probably “equirectangular”)–just like a map is a flat representation of a globe. Photosphere viewers know how to display the image to correctly unwarp the projection to make it appear like a 360 degree view. The viewer relies on some embedded metadata to tell it that the JPG could be viewed in this way. If you upload a valid photosphere to Flickr, the photo page will trigger a special in browser viewer so you can check out the 360 view.</p> <p>The upshot: if we add the correct metadata to an image, we can trick Flickr or other viewers into displaying the image in 360, with odd and fascinating results.</p> <p>As far as I can tell, Flickr requires four XMP tags in the GPano namespace (it is similar on other platforms), which in xml would look like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;GPano:FullPanoHeightPixels&gt;5000&lt;/GPano:FullPanoHeightPixels&gt; &lt;GPano:FullPanoWidthPixels&gt;10000&lt;/GPano:FullPanoWidthPixels&gt; &lt;GPano:ProjectionType&gt;equirectangular&lt;/GPano:ProjectionType&gt; &lt;GPano:UsePanoramaViewer&gt;True&lt;/GPano:UsePanoramaViewer&gt; </code></pre></div></div> <h2 id="exiftool">ExifTool</h2> <p>To manipulate image metadata you need <a href="https://sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a>. Truthfully, nothing else works reliably.</p> <blockquote> <p>On Linux install ExifTool as the Perl library, e.g. <code class="language-plaintext highlighter-rouge">sudo apt install libimage-exiftool-perl</code>. On Windows download the standalone package.</p> </blockquote> <p>To use ExifTool, we start with the command <code class="language-plaintext highlighter-rouge">exiftool</code> and the file name of an image. For example, the command <code class="language-plaintext highlighter-rouge">exiftool test.jpg</code> will print out all the current metadata embedded in test.jpg.</p> <p>From there we add flags to the command to add or change the image’s metadata. For example, the command <code class="language-plaintext highlighter-rouge">exiftool -all= test.jpg</code> will delete all embedded metadata, i.e. replacing all values with nothing.</p> <p>To figure out how to add the photosphere tags dig through the <a href="https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/XMP.html#GPano">XMP Tags docs</a> to find the correct keys. For example, to build up the command flag we want to add XMP metadata (<code class="language-plaintext highlighter-rouge">-XMP</code>), from GPano namespace (<code class="language-plaintext highlighter-rouge">-GPano</code>), in the tag ProjectionType (<code class="language-plaintext highlighter-rouge">:ProjectionType</code>), with the value of “equirectangular” (<code class="language-plaintext highlighter-rouge">="equirectangular"</code>). Thus to add/change that one metadata value, the full command would be: <code class="language-plaintext highlighter-rouge">exiftool -XMP-GPano:ProjectionType="equirectangular" test.jpg</code>. We can add multiple tags simply by adding more flags.</p> <h2 id="fake-a-photosphere">Fake a Photosphere</h2> <p>Here are the steps:</p> <ol> <li>edit image to 2:1 ratio (for reference, Pixel 2 camera shoots real photospheres around 9000px width by 4500px height).</li> <li>remove all existing image metdata: <code class="language-plaintext highlighter-rouge">exiftool -all= test.jpg</code></li> <li>add the new fake photosphere metadata (be sure to replace the pixel dimensions with the actual size of your image): <code class="language-plaintext highlighter-rouge">exiftool -XMP-GPano:FullPanoHeightPixels="4500" -XMP-GPano:FullPanoWidthPixels="9000" -XMP-GPano:ProjectionType="equirectangular" -XMP-GPano:UsePanoramaViewer="True" test.jpg</code></li> <li>upload to Flickr or other viewer</li> </ol> <h2 id="some-other-viewer">Some Other Viewer</h2> <p>Checkout my project <a href="https://evanwill.github.io/sphere-view/">sphere-view</a> that uses <a href="https://pannellum.org/">Pannellum</a> photosphere viewer, in a minimal Jekyll template on GitHub Pages. You don’t actually have to fake the metadata if you use this viewer…</p> Fri, 21 Sep 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/photosphere.html https://evanwill.github.io/_drafts/notes/photosphere.html MRIC: Adapting Technology for Teaching <blockquote> <p>Sean Butterfield and Evan Williamson, “Adapting Technology for Teaching: The Creation of an Open Educational Resource”, Malcolm M. Renfrew Interdisciplinary Colloquium, University of Idaho, 2018-09-18.</p> <p><strong>Abstract:</strong> Last year, Sean Butterfield accidentally wrote a textbook, and it was Evan Williamson’s fault. Together, they developed an Open Educational Resource (OER) for teaching the Lionel Hampton School of Music’s sophomore music theory sequence – a core class for all music majors that has a reputation for being difficult and inaccessible. This OER not only made the class accessible financially, but it also accommodated an entirely new curriculum designed around an inquiry-based learning method. The online distribution system allows the class teaching assistants to update the textbook in real time, enabling students to take an active role not only in their own learning, but in designing a permanent resource that includes their own thoughts, wording and concepts. The presenters will give an overview of the course and discuss the software and distribution platforms. They also will explain how this pedagogy has the potential to allow any course to engage instructors and students in a more meaningful, effective and memorable way.</p> </blockquote> <h1 id="intmus-links">IntMus Links</h1> <ul> <li><a href="https://intmus.github.io/inttheory18-19/" target="_blank" rel="noopener">Integrated Musicianship: Theory</a></li> <li><a href="https://github.com/intmus/inttheory18-19" target="_blank" rel="noopener">IntMus Theory source code</a> on GitHub</li> </ul> <hr /> <ul> <li><a href="https://libguides.uidaho.edu/THINKOPEN" target="_blank" rel="noopener">Think Open Fellowship</a> (University of Idaho Library)</li> <li><a href="https://opendefinition.org/" target="_blank" rel="noopener">Open Definition</a> (Open Knowledge International)</li> <li><a href="http://openmusictheory.com/" target="_blank" rel="noopener">Open Music Theory</a>, by Kris Shaffer, Bryn Hughes, and Brian Moseley, 2014+ (<a href="https://github.com/openmusictheory/openmusictheory.github.io" target="_blank" rel="noopener">OMT source on GitHub</a>)</li> </ul> <hr /> <ul> <li>Static Web tools: <ul> <li><a href="https://github.com/" target="_blank" rel="noopener">GitHub</a> (cloud based platform for version control, collaboration, project management, and code sharing)</li> <li><a href="https://pages.github.com/" target="_blank" rel="noopener">GitHub Pages</a> (free web hosting service)</li> <li><a href="https://jekyllrb.com/" target="_blank" rel="noopener">Jekyll</a> (static site generator, provides the theme / templates)</li> <li><a href="https://daringfireball.net/projects/markdown/" target="_blank" rel="noopener">Markdown</a> (simple plain text content)</li> </ul> </li> <li>Interactive features: <ul> <li><a href="https://github.com/paulrosen/abcjs" target="_blank" rel="noopener">abcjs</a> (live editable music examples in the text, e.g. <a href="https://intmus.github.io/inttheory18-19/02-int-scales-keys/b1-scales.html" target="_blank" rel="noopener">Happy Birthday in G major</a>)</li> <li><a href="https://disqus.com/" target="_blank" rel="noopener">Disqus</a> (discussion around assignments, e.g. <a href="https://intmus.github.io/inttheory18-19/assignments/Fall-semester/2018-09-17.html" target="_blank" rel="noopener">Unit 4 assignment</a>)</li> </ul> </li> </ul> Tue, 18 Sep 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/intmus-mric.html https://evanwill.github.io/_drafts/notes/intmus-mric.html Pandoc for PDFs <p><a href="http://pandoc.org/">Pandoc</a>, the “universal document converter”, is a command line utility to convert between countless file types. I use it in my writing workflow to convert from <a href="https://evanwill.github.io/_drafts/notes/writing-markdown.html">Markdown</a> to PDF.</p> <p>Check the docs for full <a href="http://pandoc.org/installing.html">installation instructions</a>, but basically you need to install Pandoc and a <a href="https://www.latex-project.org/about/">LaTeX</a> distribution. Pandoc converts your Markdown and your Tex / LaTeX distribution does the typesetting to create PDFs. Here is everything necessary on Ubuntu Linux:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install pandoc texlive texlive-fonts-extra texlive-xetex </code></pre></div></div> <p>If you install <a href="https://miktex.org/">MiKTeX</a> on Windows (your LaTeX distro) plus Pandoc, most of these commands should work–MiKTeX’s package manager will pop up asking to install what ever is necessary.</p> <p><em>Note: this was written on Linux using Pandoc 1.19.2.1, it doesn’t work quite the same on Pandoc 2+ on Windows. I will update when I get a chance…</em></p> <p>To create a basic PDF, use the <code class="language-plaintext highlighter-rouge">-o</code> output flag and a file name with <code class="language-plaintext highlighter-rouge">.pdf</code> extension. For example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pandoc -o output.pdf input.md </code></pre></div></div> <p>For writing your content Pandoc supports an extended version of <a href="http://pandoc.org/MANUAL.html#pandocs-markdown">markdown syntax</a> with many enhancements such as footnotes and tables (similar to GitHub Flavor Markdown). If you include a <a href="http://pandoc.org/MANUAL.html#extension-yaml_metadata_block">YAML metadata block</a> at the top of your file, the standard fields will be translated into LaTeX elements (title, date, author, etc).</p> <p>To tweak your PDF layout / typesetting, you can pass LaTeX variables to Pandoc using the <code class="language-plaintext highlighter-rouge">-V</code> variable flag (see docs for all <a href="http://pandoc.org/MANUAL.html#variables-for-latex">LaTeX variable options</a>). If you know LaTeX, you can get fancy right away and use existing templates. However, you can also use a few very simple options to spruce up the defaults. For example, the default margin is very large, so you might want to use:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pandoc -V geometry=margin=1.25in -o output.pdf input.md </code></pre></div></div> <p>This will use the LaTeX package <code class="language-plaintext highlighter-rouge">geometry</code> to set all the margins to 1.25 inch. You could set each margin individually with geometry options margin-left, margin-right, margin-top, or margin-bottom.</p> <p>To change the font I usually use the XeLaTeX engine, since it can use any normal font installed on your system. First, you need to figure out the correct names for installed fonts. Use this command:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>fc-list : family | cut -f1 -d"," | sort </code></pre></div></div> <p>The full name listed will be passed as a variable. Alternatively, open <a href="https://www.libreoffice.org/">LibreOffice</a> Writer and look through the font names. However, the variable is picky about the exact name used, so check against the official name as given in <code class="language-plaintext highlighter-rouge">fc-list</code>. The command looks like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pandoc --pdf-engine=xelatex -V geometry=margin=1.25in -V mainfont="Noto Sans" -o output.pdf input.md </code></pre></div></div> <blockquote> <p>Note: older versions of Pandoc use <code class="language-plaintext highlighter-rouge">--latex-engine</code> instead of <code class="language-plaintext highlighter-rouge">--pdf-engine</code>, which is likely if you installed Pandoc from a distro repository.</p> </blockquote> <p>You can also use the pdfLaTeX engine, which requires specifically prepared LaTeX fonts (usually stored with a <code class="language-plaintext highlighter-rouge">.sty</code> extension). Preparing and using the fonts requires a bit of LaTeX savvy (in theory you can use lots of cool fonts, <a href="https://www.tug.org/FontCatalogue/">FontCatalogue</a>). However, the <code class="language-plaintext highlighter-rouge">texlive-fonts-extra</code> package contains a few ready to go options. The command looks like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pandoc --latex-engine=pdflatex -V fontfamily="electrum" -V geometry=margin=1.25in -o output.pdf input.md </code></pre></div></div> <p>Font size can be controlled using <code class="language-plaintext highlighter-rouge">-V fontsize=12pt</code>, however, the default template only supports sizes 10, 11, or 12. More sizes are supported using the extsize package (8pt, 9pt, 10pt, 11pt, 12pt, 14pt, 17pt, 20pt) which can be used by adding <code class="language-plaintext highlighter-rouge">-V documentclass=extarticle</code> plus the desired fontsize (if extsize is not installed, your LaTeX distribution should automatically fetch it).</p> <p>Now we are getting a lot of commandline arguments to keep track of… You can simplify by declaring the LaTeX options as YAML metadata at the top of the document instead. You will still need to use the <code class="language-plaintext highlighter-rouge">--pdf-engine=xelatex</code> option, but won’t need to list out all the <code class="language-plaintext highlighter-rouge">-V</code> options. For example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>--- geometry: margin=1in documentclass: extarticle mainfont: Noto Sans fontsize: 14pt colorlinks: true --- </code></pre></div></div> <p>For my basic purposes, that is plenty of control, but of course you can go much further by learning more about LaTeX. Check <a href="https://github.com/danstoner/pandoc_samples">danstoner</a> for samples of PDF creation, <a href="http://practicaltypography.com/system-fonts.html">Practical Typography</a> for system font suggestions, and the <a href="http://pandoc.org/MANUAL.html">Pandoc User Guide</a> for more info.</p> Wed, 05 Sep 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pandoc.html https://evanwill.github.io/_drafts/notes/pandoc.html GNOME on Ubuntu <p>Starting with 17.10+ Ubuntu ships with <a href="https://www.gnome.org/">GNOME</a> desktop rather than Unity. Here are some notes to start customizing:</p> <h2 id="start-tweaking">Start Tweaking</h2> <p>When you first install, there are a few things to do right away to get Gnome on Ubuntu looking better. First, remove the junk from the dock, i.e. Amazon, by right clicking and selecting “remove from favorites” (to uninstall Amazon, open Ubuntu Software and look on the Installed tab). Add good stuff to the dock as you open it, by right clicking the dock icon and selecting “add to favorites”.</p> <p>Then head to Settings to get the desktop looking better.</p> <ul> <li>Settings &gt; Dock, make the icons smaller (the default seems to take up way too much space). This is the configurations for Ubuntu’s customized version of the popular extension <a href="https://extensions.gnome.org/extension/307/dash-to-dock/">Dash to Dock</a>.</li> <li>Settings &gt; Background to get your wallpaper set.</li> <li>Settings &gt; Devices &gt; Display to set up your monitor and turn on Night Light if you want a red shift in the evening.</li> <li>Settings &gt; Bluetooth, turn bluetooth off if you don’t use it, since it is a security risk.</li> </ul> <p>Next, install Tweak tool, <code class="language-plaintext highlighter-rouge">gnome-tweak-tool</code>, to give more complete customization options.</p> <p>Finally, if you don’t like Ubuntu’s dock, you can remove it to go to a more <a href="http://www.omgubuntu.co.uk/2017/10/install-vanilla-gnome-shell-ubuntu-17-10">vanilla Gnome experience</a>.</p> <h2 id="change-themes">Change Themes</h2> <p>The default style for 18.04 is the pretty ugly and dated “Ambiance”, the familiar default from Unity. Luckily, changing themes is incredibly easy with Tweak tool, a simple drop down in Appearance &gt; Themes, plus a separate drop down for your icon set. There is a whole <a href="https://www.gnome-look.org/">universe of themes</a> out there, but to get started you can install a few decent options from the main repository:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt install arc-theme numix-gtk-theme numix-blue-gtk-theme materia-gtk-theme numix-icon-theme papirus-icon-theme moka-icon-theme faba-icon-theme elementary-icon-theme pocillo-icon-theme</code></p> <p>Other themes can be installed via PPA or manually. I like <a href="https://github.com/pop-os/gtk-theme">Pop theme</a> (see instructions in the middle of the readme).</p> <p>Ubuntu 18.10+ ships with a new theme <a href="https://github.com/ubuntu/yaru">Yaru</a> (formerly known as “communitheme”). You can also try it out in 18.04 by installing it as a snap app, <code class="language-plaintext highlighter-rouge">snap install communitheme</code>, then choose it as a session when you log in (click the little cog next to the password box).</p> <h2 id="get-extensions">Get Extensions</h2> <p>The cool part of GNOME is the flexibility of using shell extensions to quickly add functionality to the desktop. These range from new themes to menus to info widgets.</p> <p>First, install the Extensions browser plugin for <a href="https://addons.mozilla.org/en/firefox/addon/gnome-shell-integration/">Firefox</a> or <a href="https://chrome.google.com/webstore/detail/gnome-shell-integration/gphhapmejobijbbhgpjhcjognlahblep">Chromium</a>. Then, install the helper <code class="language-plaintext highlighter-rouge">sudo apt install chrome-gnome-shell</code> on your system (works for all browsers). Now, you can install, manage, and configure everything from your browser by visiting the <a href="https://extensions.gnome.org/">GNOME Extensions page</a>. Configuration can also be done in Tweak tool &gt; Extensions.</p> <p>For example, add useful utilities:</p> <ul> <li><a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine</a>, disable screen lock to watch movies–I consider this an essential, and the app version used in other Ubuntu versions will not work with Gnome.</li> <li><a href="https://extensions.gnome.org/extension/750/openweather/">OpenWeather</a></li> <li><a href="https://extensions.gnome.org/extension/779/clipboard-indicator/">Clipboard Indicator</a>, saves history of clipboard.</li> <li><a href="https://extensions.gnome.org/extension/104/netspeed/">NetSpeed</a>, displays internet connection stats in top bar.</li> </ul> <p>Or completely change the desktop functionality:</p> <ul> <li><a href="https://extensions.gnome.org/extension/307/dash-to-dock/">Dash to Dock</a>, a customized version of this extension ships with Ubuntu to create the Unity-like dock on the left side of the desktop–you can uninstall the Ubuntu version and add the vanilla extension if you want.</li> <li><a href="https://extensions.gnome.org/extension/1160/dash-to-panel/">Dash to Panel</a>, puts dash into the top/bottom bar, sort of like windows 10.</li> <li><a href="https://extensions.gnome.org/extension/1228/arc-menu/">Arc Menu</a>, replaces “show applications” with a more traditional drop down menu organized into categories. Similarly, <a href="https://extensions.gnome.org/extension/608/gnomenu/">Gno-Menu</a> adds a “menu” option to the top bar with a comprehensive apps menu.</li> <li><a href="https://extensions.gnome.org/extension/28/gtile/">gTile</a>, add a button to resize windows based on a grid, something like a basic tiling window manager (that you manually adjust).</li> </ul> <h2 id="organize-apps">Organize Apps</h2> <p>The main application launcher has an icon for every installed app. To help organize this list, you can group items together using GNOME/Ubuntu Software, it’s just not very obvious how to do it (in fact people often think it is impossible)…</p> <p>Open Software, click on Installed tab, then on the check mark at the upper right corner. Now click the box next to each app you want to add to a folder. Once the group is checked off, click the “Add to Folder” button at the bottom left. In the pop up, click on the folder you want to add them too, or click the “+” to create a new folder. Finally, click “Add” to finish creating the new group.</p> <p>This process can be simplified using the <a href="https://extensions.gnome.org/extension/1217/appfolders-manager/">Appfolders Management</a> extension, which adds folder options when you right click on the application menu.</p> <h2 id="new-apps">New Apps</h2> <p>18.04 contains some new apps not available in the older version repositories. Here are a few I like:</p> <ul> <li><code class="language-plaintext highlighter-rouge">gnome-games</code> (collection of games)</li> <li><code class="language-plaintext highlighter-rouge">gnome-games-app</code> (browse and organize games)</li> <li><code class="language-plaintext highlighter-rouge">tilix</code> (tiling terminal)</li> <li><code class="language-plaintext highlighter-rouge">gnome-boxes</code> (browse virtual boxes)</li> </ul> <h2 id="keyboard-shortcuts">Keyboard shortcuts</h2> <ul> <li><code class="language-plaintext highlighter-rouge">F11</code>, toggle full screen for any app</li> <li><code class="language-plaintext highlighter-rouge">Super</code> (i.e. Windows key between Ctrl and Alt), toggle “Activities” overview / switcher (or <code class="language-plaintext highlighter-rouge">Alt+F1</code>)</li> <li><code class="language-plaintext highlighter-rouge">Super+A</code>, show application menu</li> <li><code class="language-plaintext highlighter-rouge">Ctrl+Alt</code> + Up/Down arrow, switch between workspaces (or <code class="language-plaintext highlighter-rouge">Super+Page Up/Down</code>)</li> <li><code class="language-plaintext highlighter-rouge">Alt+Tab</code>, switch between windows (or <code class="language-plaintext highlighter-rouge">Super+Tab</code>)</li> <li><code class="language-plaintext highlighter-rouge">Alt+F2</code>, command window, type <code class="language-plaintext highlighter-rouge">r</code> to restart GNOME to recover from freezes</li> <li>To sleep rather than shutdown, open the topbar menu, hold <code class="language-plaintext highlighter-rouge">Alt</code> and the shutdown power icon will turn into a pause icon.</li> <li>You can also <a href="https://help.gnome.org/users/gnome-help/stable/keyboard-shortcuts-set.html.en">customize your shortcuts</a> using Settings &gt; Keyboard &gt; Shortcuts.</li> </ul> <h2 id="issues-with-snap-apps-and-themes">Issues with snap apps and themes</h2> <p>A few of the standard applications that ship with 18.04 are now snap apps, rather than traditionally installed software. There seems to be a bug with them when you are using a non-default theme, and they either won’t open or just look unusably terrible. This is <em>really</em> frustrating. So uninstall the snaps and reinstall the traditional app.</p> <p><code class="language-plaintext highlighter-rouge">sudo snap remove gnome-system-monitor gnome-calculator</code></p> <p><code class="language-plaintext highlighter-rouge">sudo apt install gnome-system-monitor gnome-calculator</code></p> <h2 id="wayland-issues">Wayland Issues</h2> <p>While Ubuntu 17.10 shipped with next gen display server Wayland as default, 18.04 switched back to the venerable Xorg. At the login screen, you can choose which type of session to start When you start up your computer and arrive at the login screen, click on the gear icon next to the “Sign In” button. This will display two options, one saying “on Xorg” or “on Wayland”.</p> <p>Using Wayland introduces a few complications with some traditional applications, most notably with graphical apps that require sudo access (gparted, synaptic, gufw) and screen recorders. These issues are part of the reason 18.04 went back to Xorg.</p> <p>The other option is to avoid using those problematic graphical apps. For example, <code class="language-plaintext highlighter-rouge">gufw</code> is commonly used to set up a simple firewall on your personal computer, but will not run on Wayland. Just go commandline and use <code class="language-plaintext highlighter-rouge">ufw</code> with out the graphical interface (the defaults are good for most personal uses).</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install ufw sudo ufw status sudo ufw enable </code></pre></div></div> <h2 id="more-stuff">More stuff</h2> <p>Other than the complications mentioned above, most of the essentials to get set up are in my older <a href="https://evanwill.github.io/_drafts/notes/ubuntu-tips.html">Ubuntu tips</a>.</p> <p>If you want to do some more serious customization, GTK+ can be styled with CSS (<a href="https://developer.gnome.org/gtk3/stable/theming.html">docs</a>). You can start a program with a debug window to get all the information, sort of like using inspect dev tools on a web browser:</p> <p><code class="language-plaintext highlighter-rouge">GTK_DEBUG=interactive gedit</code></p> <h2 id="older-notes">Older notes</h2> <p>If you have issues with your keyboard or touch pad, there is a bug with some laptops in the kernel shipped with 17.10–see my note on <a href="https://evanwill.github.io/_drafts/notes/ubuntu-kernel.html">adding new kernels to Ubuntu</a>.</p> Sun, 02 Sep 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu-gnome.html https://evanwill.github.io/_drafts/notes/ubuntu-gnome.html Git Branch Notes <p><a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell" target="_blank" rel="noopener">Branching</a> is a Git fundamental that allows you to test out ideas in parallel to your main repository without disrupting the main/master copy. Notes about confusing things:</p> <h2 id="remote-branches">Remote branches</h2> <p>It is a bit confusing that branches are only local by default, e.g. when you <code class="language-plaintext highlighter-rouge">git checkout -b example</code> on your laptop, the new <code class="language-plaintext highlighter-rouge">example</code> branch is only on your machine and will not automatically be pushed to GitHub. Likewise, a new branch on GitHub will not automatically appear on your local machine when you use <code class="language-plaintext highlighter-rouge">git branch</code> to list branches.</p> <p>A branch that is connected to a remote repository (GitHub) is called a “tracking branch”. When you <code class="language-plaintext highlighter-rouge">git clone</code>, the <code class="language-plaintext highlighter-rouge">main</code>/<code class="language-plaintext highlighter-rouge">master</code> branch is automatically created as a “tracking branch” with the GitHub repository as the “upstream branch”. However, git knows about the other remote branches, but does not automatically create them locally. Furthermore, after you create a new branch locally, and you want to push it to GitHub, you will need to add a remote.</p> <p>To get information about all your remotes, <code class="language-plaintext highlighter-rouge">git remote show origin</code> lists everything tracked locally and how it lines up with your remotes.</p> <p>Use a remote “tracking branch” locally:</p> <ul> <li>Clone the repo, <code class="language-plaintext highlighter-rouge">git clone https://github.com/user/repository.git</code></li> <li>Checking <code class="language-plaintext highlighter-rouge">git branch</code> will display only the local branches, i.e. <code class="language-plaintext highlighter-rouge">main</code>/<code class="language-plaintext highlighter-rouge">master</code> if you just cloned it.</li> <li>Check <code class="language-plaintext highlighter-rouge">git branch -a</code> to see all branches, including remotes, i.e. git knows about the other branches, it just didn’t create a local version of it yet. The remote branches will be named like <code class="language-plaintext highlighter-rouge">remotes/origin/branch-name</code>.</li> <li>To create a local version of a remote branch, use <code class="language-plaintext highlighter-rouge">git checkout branch-name</code> (when there is no local branch with that name <em>and</em> it exactly matches a remote branch, git will automatically create a local “tracking branch”). This is the short cut to <code class="language-plaintext highlighter-rouge">git checkout -b branch-name origin/branch-name</code>. Now with the branch there locally, you can push and fetch/pull as normal.</li> </ul> <p>Create a branch locally, then add to remote:</p> <ul> <li>Create and switch to a new branch, <code class="language-plaintext highlighter-rouge">git checkout -b branch-name</code>. (reminder: this is a short cut combo of two commands, <code class="language-plaintext highlighter-rouge">git branch branch-name</code> and <code class="language-plaintext highlighter-rouge">git checkout branch-name</code>)</li> <li>To add the branch to the remote, <code class="language-plaintext highlighter-rouge">git push origin branch-name</code> will create the remote branch and set the “upstream” for the local version. (this is a shortcut to <code class="language-plaintext highlighter-rouge">git branch --set-upstream-to origin branch-name</code> plus <code class="language-plaintext highlighter-rouge">git push</code>)</li> </ul> <h2 id="update-branch-from-mainmaster">Update branch from main/master</h2> <p>In most workflows you might not actually want to do this to avoid weird histories, but…</p> <ol> <li>Update your <code class="language-plaintext highlighter-rouge">main</code>/<code class="language-plaintext highlighter-rouge">master</code> branch, with <code class="language-plaintext highlighter-rouge">git pull</code>.</li> <li>Switch to the feature branch that needs updating, <code class="language-plaintext highlighter-rouge">git checkout feature-branch</code>.</li> <li>Merge <code class="language-plaintext highlighter-rouge">main</code>/<code class="language-plaintext highlighter-rouge">master</code> into the feature: <code class="language-plaintext highlighter-rouge">git merge main</code>.</li> </ol> Fri, 01 Jun 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-branch.html https://evanwill.github.io/_drafts/notes/git-branch.html Web intro <p>Idealistic Canadian video: <a href="https://youtu.be/i5oe63pOhLI">How Does the Internet Work ?</a></p> <p>A network is two or more computers connected. URLs are stand ins for <a href="https://en.wikipedia.org/wiki/IP_address">Internet Protocol addresses (IP)</a>, which are numerical identifiers for devices connected to a network.</p> <p><em>The internet is network of networks that connects devices.</em></p> <p>Demo IP addresses:</p> <ul> <li><a href="https://support.google.com/websearch/answer/1696588">Find your IP</a></li> <li>Check another IP: <code class="language-plaintext highlighter-rouge">ping www.google.com</code> or <code class="language-plaintext highlighter-rouge">nslookup www.uidaho.edu</code></li> <li>Follow your traffic: traceroute / tracert / tracepath <code class="language-plaintext highlighter-rouge">tracepath www.google.com</code> or <code class="language-plaintext highlighter-rouge">mtr --report google.com</code></li> <li>Make a request: <code class="language-plaintext highlighter-rouge">curl www.google.com</code></li> </ul> <p>For an in-depth, but fun intro, checkout Julia Evan’s <a href="https://wizardzines.com/zines/networking/">Networking Zine</a>.</p> <h2 id="whats-in-a-url">What’s in a URL</h2> <p><code class="language-plaintext highlighter-rouge">https://example.com/about?key=value#anchor</code></p> <p>protocol <code class="language-plaintext highlighter-rouge">://</code> domain <code class="language-plaintext highlighter-rouge">.</code> top-level domain (optional port :80) <code class="language-plaintext highlighter-rouge">/</code> path and filename <code class="language-plaintext highlighter-rouge">?</code> query with parameters <code class="language-plaintext highlighter-rouge">#</code> fragment or anchor</p> <ul> <li><strong>Protocol:</strong> there is actually more than 100 defined Internet Protocols, however with URLs the most common are <a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol">Hypertext Transfer Protocol (HTTP)</a> or <a href="https://en.wikipedia.org/wiki/File_Transfer_Protocol">File Transfer Protocol (FTP)</a>.</li> <li><strong>Domain:</strong> the <a href="https://en.wikipedia.org/wiki/Domain_Name_System">Domain Name System (DNS)</a> is often described as a “phone book” that translates easy to understand web addresses into the appropriate <a href="https://en.wikipedia.org/wiki/IP_address">IP addresses</a> of servers with the desired information. A subdomain can be added in front of the main domain. For example, in <code class="language-plaintext highlighter-rouge">lib.uidaho.edu</code> &gt; <code class="language-plaintext highlighter-rouge">lib</code> is a subdomain of <code class="language-plaintext highlighter-rouge">uidaho</code>, which is a subdomain of the top-level domain <code class="language-plaintext highlighter-rouge">edu</code>. Occasionally, you may see a port number at the end of the domain which refer to specific communication endpoints that the server is listening on. For the web the standard ports are <code class="language-plaintext highlighter-rouge">:80</code> (http) and <code class="language-plaintext highlighter-rouge">:443</code> (https).</li> <li><strong>Path and filename:</strong> these can be imagined like folders and files on the server (and actually are in static web sites). For example, <code class="language-plaintext highlighter-rouge">/about/index.html</code>, is the index file in the “about” folder. If no filename is given, by default the server provides the file named <code class="language-plaintext highlighter-rouge">index</code>.</li> <li><strong>Query string:</strong> is added to the end of an URL following a <code class="language-plaintext highlighter-rouge">?</code> and is given in key value pairs. Multiple pairs can be separated by <code class="language-plaintext highlighter-rouge">&amp;</code>. The characters must be URL encoded / escaped, since some characters such as space are not allowed in URLs. The queries are processed by the server or javascript, so what exactly they do depends on the page. For example, <code class="language-plaintext highlighter-rouge">/index.php?title=Query_string&amp;action=edit</code> might return a wiki article in edit mode.</li> <li><strong>Anchor:</strong> are added to the end of a URL following a <code class="language-plaintext highlighter-rouge">#</code>. They traditionally correspond to specific <code class="language-plaintext highlighter-rouge">id</code> on an html page, but are often used by javascript to add other functionality. For example, <code class="language-plaintext highlighter-rouge">/index.html#Chapter1</code> might jump to a chapter heading in the web page.</li> </ul> Sun, 20 May 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/web-cli.html https://evanwill.github.io/_drafts/notes/web-cli.html Data Visualization Resources <blockquote> <p>Resources from “<a href="http://www.lib.uidaho.edu/services/workshops/resources/UIdaho_DataViz101_workshop.pdf">Data Viz 101: Concepts and Tools</a>” workshop 2015-10-14</p> </blockquote> <h1 id="background">Background</h1> <p><img src="https://upload.wikimedia.org/wikipedia/commons/2/29/Minard.png" alt="Charles Joseph Minard’s Map (1869)" /></p> <p>Charles Joseph Minard’s Map (1869), <a href="https://commons.wikimedia.org/wiki/File:Minard.png">from wikimedia</a>. <a href="http://www.edwardtufte.com/tufte/posters">Edward Tufte</a> says it’s “probably the best statistical graphic ever drawn”.</p> <p>Different areas:</p> <ul> <li>Data Visualization</li> <li>Information Visualization</li> <li>Visual Analytics</li> </ul> <p>Books:</p> <ul> <li>Matthew Ward, Georges G. Grinstein, and Daniel Keim. <em>Interactive data visualization : foundations, techniques, and applications</em>, Second edition (Boca Raton : CRC Press, 2015).</li> <li>Colin Ware, <em>Visual thinking for design</em> (Burlington, MA : Morgan Kaufmann, 2008).</li> <li>Colin Ware, <em>Information Visualization Perception for Design</em>, 3rd ed (Burlington : Elsevier Science, 2012).</li> </ul> <h1 id="visual-analytics">Visual Analytics</h1> <blockquote> <p>“Visualization allows people to offload cognition to the perceptual system, using carefully designed images as a form of external memory. The human visual system is a very high-bandwidth channel to the brain, with a significant amount of processing occurring in parallel and at the pre-conscious level. We can thus use external images as a substitute for keeping track of things inside our own heads.”</p> </blockquote> <p>Tamara Munzner, “Visualization,” in <em>Fundamentals of Computer Graphics</em> (3rd edition), ed. Peter Shirley, Michael Ashikhmin, and Steve Marschner (Natick, MA: A K Peters, 2009).</p> <blockquote> <p>“Visual analytics solutions provide technology that combines the strengths of human and electronic data processing. Visualization becomes the medium of a semi-automated analytical process, where humans and machines cooperate using their respective distinct capabilities for the most effective results.”</p> </blockquote> <p>Daniel Keim, Gennady Andrienko, Jean-Daniel Fekete, Carsten Görg, Jörn Kohlhammer, and Guy Melan, “Visual Analytics: Definition, Process, and Challenges”, in <em>Information Visualization - Human-Centered Issues and Perspectives</em>, LNCS, ed. Andreas Kerren, et al. (Springer, 2008), 154-175. Available at http://hal-lirmm.ccsd.cnrs.fr/lirmm-00272779/document</p> <h1 id="shneiderman">Shneiderman</h1> <p><strong>Visual Information Seeking Mantra</strong>:</p> <ul> <li>Overview first, zoom and filter, then details-on-demand.</li> </ul> <p><strong>Type by Task Taxonomy (TTT)</strong></p> <ul> <li>Seven data types: 1-, 2-, 3-dimensional data, temporal and multi-dimensional data, and tree and network data</li> <li>Seven tasks: overview, zoom, filter, details-on-demand, relate, history, extract</li> </ul> <blockquote> <p>Ben Shneiderman, “The Eyes Have It: A Task by Data Type Taxonomy for Information Visualizations”, <em>Proceedings of the 1996 IEEE Symposium on Visual Languages</em> (1996): 336. Available at http://www.interactiondesign.us/courses/2011_AD690/PDFs/Shneiderman_1996.pdf</p> </blockquote> <h1 id="preattentive-features">Preattentive Features</h1> <p>Visualizations and Viz tools need to be designed with human visual abilities in mind. For example, check out this research about “Preattentive Features and Tasks” <a href="https://youtu.be/wnvoZxe95bo">(on youtube)</a>:</p> <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/wnvoZxe95bo" frameborder="0" allowfullscreen=""></iframe> <blockquote> <p>Christopher G. Healey, “Perception in Visualization”, http://www.csc.ncsu.edu/faculty/healey/PP/</p> </blockquote> <h1 id="visualization-examples">Visualization Examples</h1> <p>The best way to get ideas of good ways to visualize data is to look at lots of examples. Try some of these catalogs:</p> <ul> <li><a href="http://www.datavizcatalogue.com/">The Data Visualisation Catalogue</a></li> <li><a href="http://www.visual-literacy.org/periodic_table/periodic_table.html">Period Table of Visualization Methods</a></li> <li><a href="http://visual.ly/graphic-continuum">Grapic Continuum</a></li> <li><a href="http://survey.timeviz.net/">TimeViz Browser</a></li> <li><a href="http://vcg.informatik.uni-rostock.de/~hs162/treeposter/poster.html">A Visual Bibliography of Tree Visualization 2.0</a></li> </ul> <p>Negative Examples:</p> <ul> <li><a href="http://viz.wtf/">WTF Visualizations</a></li> <li><a href="http://www.tylervigen.com/spurious-correlations">Spurious Correlations</a></li> </ul> <h1 id="viz-resources">Viz Resources</h1> <ul> <li><a href="http://flowingdata.com/">Flowingdata</a></li> <li><a href="http://www.infovis-wiki.net/">Infovis Wiki</a></li> <li><a href="http://www.visualisingdata.com/">visualising data</a></li> <li><a href="http://www.gapminder.org/">Gapminder</a></li> <li><a href="https://projects.susielu.com/viz-palette">Viz-Palette</a> (helps you choose accessible color palettes)</li> <li><a href="https://pudding.cool/">The Pudding</a> (visual essays)</li> </ul> <h1 id="simple-web-based-tools">Simple Web Based Tools</h1> <ul> <li><a href="https://developers.google.com/chart/">Google Charts</a></li> <li><a href="https://rawgraphs.io/">Raw Graphs</a> (based on D3.js)</li> <li><a href="https://datawrapper.de/">Data Wrapper</a></li> <li><a href="http://www.charted.co/">Charted</a></li> <li><a href="https://github.com/vega/voyager">Vega Voyager</a> (open alternative to Tableau in development)</li> <li><a href="https://cloud.highcharts.com/">Highcharts Cloud</a> (free web editor version of popular commercial js library)</li> <li><a href="https://flourish.studio/">Flourish</a> (free version with public data)</li> </ul> <h1 id="libraries">Libraries</h1> <ul> <li>HTML+JS: <a href="http://d3js.org/">D3</a> (Alternatively, checkout <a href="http://c3js.org/">C3.js</a>, <a href="http://dygraphs.com/">dygraphs</a>, <a href="https://www.taucharts.com/">TauCharts</a>, <a href="http://www.chartjs.org/">chartjs</a>, or <a href="https://vega.github.io/vega/">Vega</a>)</li> <li>Python: <a href="https://matplotlib.org/">matplotlib</a> (you will probably want to use it along with <a href="https://pandas.pydata.org/">Pandas</a> to manipulate the data. Alternatively, checkout <a href="http://bokeh.pydata.org/">Bokeh</a>, <a href="http://seaborn.pydata.org/index.html">seaborn</a>, <a href="https://plot.ly/python/">plotly</a>, or <a href="http://ggplot.yhathq.com/">ggplot</a>)</li> <li>R: <a href="http://ggplot2.org/">ggplot</a> (usually used in conjunction with other <a href="https://www.tidyverse.org/">Tidyverse</a> packages. Alternatively, checkout <a href="http://ggvis.rstudio.com/">ggvis</a>, <a href="http://ggvis.rstudio.com/">Shiny</a>)</li> </ul> <h1 id="code-notebooks">Code Notebooks</h1> <p>Code notebooks such as <a href="http://jupyter.org/">Jupyter</a> are becoming an essential tool in data science. They combine code blocks with text and visualizations into a shareable document. Many notebooks now have cloud hosted versions to lower barriers to getting started and promote reproducibility:</p> <ul> <li><a href="https://jupyter.org/try">Try Jupyter</a>, or share Jupyter notebooks with <a href="https://nbviewer.jupyter.org/">nbviewer</a> or <a href="https://mybinder.org/">binder</a></li> <li><a href="https://colab.research.google.com/">Colaboratory</a> (Jupyter environment hosted by Google designed to run TensorFlow without installing anything, with your notebooks stored in Google Drive)</li> <li><a href="https://observablehq.com/">Observable</a> (JavaScript based data visualization for the web)</li> <li><a href="https://codeocean.com/">Code Ocean</a> (a variety of notebooks and IDE available)</li> <li><a href="https://cocalc.com/">COCALC</a> (was SageMath Cloud, now has Jupyter Notebook with lots of kernels, a LaTeX editor, and more)</li> <li><a href="https://github.com/iodide-project/iodide">Iodide</a> and <a href="https://github.com/iodide-project/pyodide/">Pyodide</a> (web focused notebooks implemented in browser, in alpha development)</li> <li><a href="https://stenci.la/">Stencila</a> (word processor + spreadsheet + code)</li> <li><a href="https://notebooks.azure.com/">Azure Notebooks</a></li> </ul> <h1 id="tableau">Tableau</h1> <p>I rarely recommend non-opensource tools, but Tableau is fairly unique tool for visually exploring data in a flexible, powerful sandbox.<br /> It is commonly used in enterprise settings, however, they provide free licenses for academic learning use. If your data can be shared publicly, <a href="https://public.tableau.com/">Tableau Public</a> is a good option. Also, checkout their <a href="https://www.tableau.com/about/blog/2017/10/explore-viz-reigned-supreme-iron-viz-2017-77497">Iron Viz</a> competition for interesting examples.</p> <p><a href="http://www.tableau.com/academic">Academic program</a>:</p> <ul> <li>Free for students and teachers</li> <li>Not free for administration, see <a href="http://www.tableau.com/solutions/higher-ed">higher-ed solutions</a></li> </ul> <p><a href="https://public.tableau.com/">Tableau Public</a></p> <p>Tutorials:</p> <ul> <li><a href="https://www.tableau.com/learn/tutorials/on-demand/getting-started">training videos</a></li> <li><a href="https://www.tableau.com/learn/starter-kit">short course</a></li> <li><a href="http://www.tableau.com/learn/gallery">gallery examples</a></li> <li><a href="http://www.dataplusscience.com/TableauReferenceGuide/index.htm">reference</a></li> </ul> Sun, 06 May 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/viz-notes.html https://evanwill.github.io/_drafts/notes/viz-notes.html Fluffy Pancake Recipe <blockquote> <p>Usually I like custardy <a href="https://evanwill.github.io/_drafts/notes/pannukakku.html">pannaukakku</a>, but occasionally I have a hankering for a very fluffy pancake. Here is my most successful recipe.</p> </blockquote> <p>In a big bowl, mix up:</p> <ul> <li>2 eggs</li> <li>1 3/4 cp milk</li> <li>2 tbsp sugar</li> <li>pinch of salt</li> <li>1 tsp vanilla</li> <li>1 tsp cardamom</li> </ul> <p>Take a whisk and beat it up really well. Then add:</p> <ul> <li>1/4 cp butter, melted (gently melt in microwave, and let cool a bit so it is not hot)</li> </ul> <p>and stir up. Finally, add:</p> <ul> <li>2 cp flour</li> <li>4 tsp baking powder</li> </ul> <p>and very <em>gently</em> stir it in with the whisk–don’t mix it too much! Should be thick and lumpy.</p> <p>Then let the batter sit for awhile, like 10 minutes. It needs to rest.</p> <p>Heat up a pan with bit of cooking oil, and cook as normal pancakes (i.e. drop blob of batter on to pan, cook until gets bubbly, gently flip over and cook until golden).</p> Sun, 08 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pancake-fluffy.html https://evanwill.github.io/_drafts/notes/pancake-fluffy.html Hot Fudge Pudding Cake Recipe <blockquote> <p>Inspired by memories of cook book for kids from when I was a kid, delicious, chocolaty, and very simple.</p> </blockquote> <p>Heat oven to 350 degrees. Grease a square baking pan (or small oval casserole, or double recipe for big rectangle baking pan).</p> <p>In a mixing bowl, add:</p> <ul> <li>1 cup flour</li> <li>2/3 cup sugar</li> <li>1/4 cup baking cocoa</li> <li>2 tsp baking powder</li> <li>1/4 tsp salt</li> <li>1 ts vanilla extract</li> <li>1/4 cup vegetable oil</li> <li>1/2 cup milk</li> </ul> <p>Mix it all up into thick batter. Spread into the greased square pan. Use a spatula to scrape out the mixing bowl pretty clean and dry.</p> <p>In the fairly clean mixing bowl, add:</p> <ul> <li>1/4 cup baking cocoa</li> <li>3/4 cup brown sugar</li> </ul> <p>Mix it up. Sprinkle over the top of the batter in the pan (don’t mix in at all).</p> <p>Prep (in electric kettle or microwave or whatever):</p> <ul> <li>1 1/4 cup hot water</li> </ul> <p>Pour the hot water over the pan (don’t stir or mix or anything).</p> <p>Put into oven and bake about 40 - 45 minutes. The top will become a brownie like crust, with gooey hot fudge sauce below.</p> <p>Remove from oven, let cool a few minutes, then serve immediately in bowls.</p> <p>I like to serve with some milk or ice cream.</p> Sun, 08 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/hot-fudge.html https://evanwill.github.io/_drafts/notes/hot-fudge.html Pannukakku Recipe <p>Inspired by memories of Chocolate Moose in Ely, MN, and ancient ancestral foods, we wanted to create thick, custardy Pannukakku (a Finnish oven pancake). Partly based on a <a href="https://web.archive.org/web/20150523014123/http://scandinavianfood.about.com:80/od/pancakewafflerecipes/r/pannukakku.htm">“Scandinavian food expert” website</a>, we came up with this recipe.</p> <p>Basic concept is to create a batter following the ratio of <code class="language-plaintext highlighter-rouge">1 egg : 1/4 cup flour : 1/4 cup milk</code>, beating it very well. Add a bit of vanilla, sugar, baking powder, and lemon zest, then bake in a hot oven.</p> <p>We are not very exact about the measurements, but here is an approximate recipe for a rectangle cake pan. We like to use enough eggs to create a fairly thick pancake, which will be more custardy in the middle.</p> <p>In a big bowl, add:</p> <ul> <li>8 eggs</li> <li>2 cup flour</li> <li>2 cup milk</li> <li>2 Tbs sugar</li> <li>2 tsp vanilla extract</li> <li>1 tsp cardamom</li> <li>dash of salt</li> </ul> <p>Beat it up really well (I think you want to get some air into the batter), then let it sit for awhile. Preheat the oven to 400 degrees (or higher). After the batter has rested a bit, add:</p> <ul> <li>1 tsp baking powder</li> <li>a bit of lemon zest (or lemon juice)</li> </ul> <p>And mix up well.</p> <p>Take a pan (oven safe cast iron or glass cake pan), add a couple big dollops of butter, and put into the oven until the butter is melted and bubbling near browning. Pull out the pan, pour the batter in, and pop it back into the oven.</p> <p>Bake for around 15 minutes, until golden on top (it will puff up a lot!).</p> <p>Meanwhile, whip up some fresh whipped cream.</p> <p>Serve chucks of the pannukakku topped with whipped cream and fresh or canned berries. (Alternatively, serve with syrup or with lemon and butter)</p> Sat, 07 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pannukakku.html https://evanwill.github.io/_drafts/notes/pannukakku.html Open Image Editing Workshop <blockquote> <p>MILL workshop 2018: Learn about free and open-source applications that make advanced media editing possible without expensive software! This session will introduce the most popular open-source media editing applications and get you setup to use GIMP for photo editing.</p> </blockquote> <p>When thinking about editing images and other media, a certain super expensive, close-source ecosystem usually comes to mind (i.e. Adobe)–to the point it has even become a verb, “photoshopping”. However, there are plenty of excellent open source alternatives that can power your media editing workflows for <a href="https://www.gnu.org/philosophy/free-sw.en.html" target="_blank" rel="noopener">free</a>. These cross-platform, open source options respect your rights as a user, and you won’t be locked into a subscription service or platform.</p> <p><em>Please note:</em> we often mention open source software as an “alternative to” some proprietary / commercial option. However, none of these open source projects are designed to specifically mimic or replace a proprietary tool. They are developed and guided by their own community and goals.</p> <p>These notes are a sketch outline with links to lots of free tools. For open image editing tutorials and resources, the go to resource is <a href="https://pixls.us/" target="_blank" rel="noopener">PIXLS</a>.</p> <h2 id="gnu-image-manipulation-program-gimp">GNU Image Manipulation Program (GIMP)</h2> <p>When we talk about photo editing, we usually mean “raster images” or “pixel editing”. While “photoshopping” is a verb, <a href="https://www.gimp.org/" target="_blank" rel="noopener">GIMP</a> is a powerful and popular free and open alternative.</p> <p><a href="https://www.gimp.org/downloads/" target="_blank" rel="noopener"><button class="buttons" type="button">Download GIMP</button></a></p> <p>Once installed I suggest a quick tweak: click “Windows” &gt; “Single window mode” for a more usable experience, unless you are comfortable with the floating docks. If you have some favorite keyboard shortcuts, check in “Edit” &gt; “Preferences” &gt; “Interface” to configure them. For help, click “Help” &gt; “User Manual”.</p> <p>Download a couple free images to practice on:</p> <ul> <li><a href="https://unsplash.com/" target="_blank" rel="noopener">Unsplash</a>.</li> <li><a href="https://www.flickr.com/commons" target="_blank" rel="noopener">Flickr Commons</a>.</li> </ul> <p>The basic GIMP interface:</p> <ul> <li>Left dock: tool box and tool options.</li> <li>Center: image window.</li> <li>Right dock: layers, history, channels; brushes options.</li> </ul> <p>Demo outline:</p> <ul> <li>Load image (File &gt; Open).</li> <li>Adjust view on image window (zoom, quick move in corner, F11 for full screen).</li> <li>Image &gt; Transform &gt; rotate.</li> <li>Select tool, rectangle select, adjust selection.</li> <li>Image &gt; Crop to selection.</li> <li>Filters &gt; Enhance &gt; Unsharp mask.</li> <li>Colors &gt; Levels.</li> <li>Image &gt; Scale image.</li> <li>File &gt; Export as (add file extension to control output. <em>Note:</em> “Save as” is only <code class="language-plaintext highlighter-rouge">.xcf</code> format, similar to Photoshop’s <code class="language-plaintext highlighter-rouge">.psd</code>, which stores the full image and editing history so it can be worked on losslessly in the future. However, it can not be opened by other software and is much bigger!)</li> <li>History tab, step back.</li> <li>Try some tools: Airbrush, Smudge, Text, Color Picker.</li> <li>Select, Cut; Select, Copy, Move.</li> <li>Foreground / Background color.</li> <li>Export review!</li> <li>Load another image review!</li> </ul> <blockquote> <p><em>Note:</em> GIMP used to have a great plugin ecosystem. However, it is temporarily suspended due to security concerns.</p> </blockquote> <h2 id="raw-processing-workflow">Raw processing workflow</h2> <p>Advanced collection management and processing of raw image file types, including metadata editing, color management, batch processing, and automation (something like Adobe Lightroom).</p> <ul> <li><a href="https://www.darktable.org/" target="_blank" rel="noopener">darktable</a>, full workflow.</li> <li><a href="http://rawtherapee.com/" target="_blank" rel="noopener">RawTherapee</a>, focus on raw processing.</li> <li><a href="https://www.digikam.org/" target="_blank" rel="noopener">digiKam</a>, focus on management.</li> </ul> <h2 id="other-raster-image-tools">Other Raster image tools</h2> <ul> <li><a href="https://krita.org/" target="_blank" rel="noopener">Krita</a>, community focused on “digital painting” application.</li> <li><a href="http://qtpfsgui.sourceforge.net/" target="_blank" rel="noopener">Luminance HDR</a>, HDR utility.</li> <li><a href="http://hugin.sourceforge.net/" target="_blank" rel="noopener">Hugin</a>, Panorama stitching utility.</li> <li><a href="https://29a.ch/film-emulator/" target="_blank" rel="noopener">Film Emulator</a>, web based tool to emulate to color of old film types with your image.</li> </ul> <p><strong>Advanced:</strong></p> <ul> <li><a href="http://www.imagemagick.org/script/index.php" target="_blank" rel="noopener">ImageMagick</a>, powerful image manipulation tool, used via CLI or by many other applications (my <a href="https://evanwill.github.io/_drafts/notes/imagemagick.html">get started notes</a>).</li> <li><a href="http://gmic.eu/" target="_blank" rel="noopener">G’MIC</a>, CLI, library, and GIMP plugin for advanced image processing.</li> <li><a href="http://www.sno.phy.queensu.ca/~phil/exiftool/" target="_blank" rel="noopener">ExifTool</a>, image metadata utility, the only reliable way to read and write photo file embedded metadata. Or you can try <a href="http://www.exiv2.org/index.html">Exiv2</a>.</li> <li><a href="http://imagej.net/Welcome" target="_blank" rel="noopener">ImageJ</a>, powerful batch image processor designed for scientific analysis (or <a href="https://digitalaladore.wordpress.com/2017/06/07/visualizing-aladore-the-book/" target="_blank" rel="noopener">my notes</a> for less scientific purposes).</li> </ul> <h2 id="vector-editing">Vector editing</h2> <p>Vector editing programs (something like Adobe Illustrator) use standards such as SVG to record information about the positions, paths, and properties of the components that make up a graphic, rather than the individual pixels seen in raster images. This means the image can be scaled to any size with out loss of detail.</p> <ul> <li><a href="https://inkscape.org/" target="_blank" rel="noopener">Inkscape</a>, powerful, with more advanced features than AI under the hood, but a steep learning curve. Luckily, there are a lot of tutorials, check the <a href="https://inkscape.org/en/learn/tutorials/" target="_blank" rel="noopener">official list</a>, <a href="http://libregraphicsworld.org/blog/entry/mastering-inkscape-in-2018" target="_blank" rel="noopener">“Mastering Inkscape in 2018”</a>, or <a href="https://opensource.com/article/18/1/9-awesome-new-inkscape-features-and-how-use-them" target="_blank" rel="noopener">“Awesome new Inkscape features”</a>. The developers collaborate directly with the SVG standards committee to innovate the open specification.</li> <li>Not open source, but cost-free, easy to use: <a href="https://vectr.com/" target="_blank" rel="noopener">Vectr</a> or <a href="https://designer.io/" target="_blank" rel="noopener">Gravit Designer</a>.</li> <li>Traditional, but handy: <em>Draw</em> in <a href="https://www.libreoffice.org/" target="_blank" rel="noopener">LibreOffice</a> or <em>Karbon</em> in <a href="https://www.calligra.org/" target="_blank" rel="noopener">Calligra</a>.</li> <li>Super basic, but quick and open: <a href="https://github.com/SVG-Edit/svgedit" target="_blank" rel="noopener">SVG-edit</a>.</li> </ul> <h2 id="video">Video</h2> <p>Unfortunately, none of the open video editors are <em>great</em> just yet, and all seem a bit unstable at times. I have used <a href="https://www.openshot.org/" target="_blank" rel="noopener">OpenShot</a> successfully on many projects, fairly easy to use. Others say <a href="https://kdenlive.org/" target="_blank" rel="noopener">Kdenlive</a> is stable and professional (check out the <a href="https://opensource.com/article/18/4/new-state-video-editing-linux">“Current state of Linux video editing”</a> for some in-depth reviews).</p> <ul> <li>Decent: <a href="https://www.openshot.org/" target="_blank" rel="noopener">OpenShot</a> and <a href="https://kdenlive.org/" target="_blank" rel="noopener">kdenlive</a>.</li> <li>Less stable in my experience: <a href="https://shotcut.org/" target="_blank" rel="noopener">Shotcut</a>, <a href="http://www.pitivi.org/" target="_blank" rel="noopener">Pitivi</a>, and <a href="http://avidemux.sourceforge.net/" target="_blank" rel="noopener">avidemux</a>.</li> <li>Pro, not open, but cost-free: <a href="https://www.lwks.com/" target="_blank" rel="noopener">Lightworks</a> (full editing software used by professional studios, with export limited to 720p) or <a href="https://www.blackmagicdesign.com/uk/products/davinciresolve/" target="_blank" rel="noopener">DaVinci Resolve</a>.</li> </ul> <h2 id="others">Others</h2> <ul> <li><a href="https://www.blender.org/" target="_blank" rel="noopener">Blender</a>, super powerful 3D modeling, animation, rendering, and video. Complex, professional grade tool. The developers host movie projects that produce completely <a href="https://www.blender.org/about/projects/" target="_blank" rel="noopener">free and open short films</a>.</li> <li><a href="https://www.audacityteam.org/" target="_blank" rel="noopener">Audacity</a>, audio recording and editing.</li> <li><a href="https://www.scribus.net/" target="_blank" rel="noopener">Scribus</a>, desktop publishing.</li> <li><a href="https://github.com/ozmartian/vidcutter" target="_blank" rel="noopener">vidcutter</a>, handy utility for cutting video files.</li> </ul> Wed, 04 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/open-image.html https://evanwill.github.io/_drafts/notes/open-image.html R and RStudio on Linux <p><strong>Note: this is out of date and due to new licensing terms, I no longer suggest using Anaconda.</strong></p> <p>Installing RStudio is a surprisingly complex on Linux, or at least much more work than expected. However, there is one easy way if you use Anaconda Python distribution. This note describes both methods.</p> <h1 id="rstudio-and-r-with-conda">RStudio and R with Conda</h1> <p><a href="https://www.anaconda.com/what-is-anaconda/">Anaconda</a> is a major Python distribution that comes packaged with a huge number of scientific Python tools, including Jupyter Notebook and several difficult to install SciPy packages. Futhermore, it provides the <code class="language-plaintext highlighter-rouge">conda</code> package and environment management tool that simplifies installing, updating, and managing everything. Overall, it is very handy and powerful, simplifying the initial set up of a data science / SciPy environment.</p> <p>Conda can also install and manage R on your system, which is nice since it makes keeping everything up-to-date easier.</p> <ol> <li><a href="https://www.anaconda.com/download/#linux">Download Anaconda</a>.</li> <li>Install using the downloaded script (<a href="https://docs.anaconda.com/anaconda/install/linux">full instructions</a>), <code class="language-plaintext highlighter-rouge">bash ~/Downloads/Anaconda3-5.1.0-Linux-x86_64.sh</code>.</li> <li>Install R and RStudio: <code class="language-plaintext highlighter-rouge">conda install -c r r-essentials rstudio</code>.</li> </ol> <p>You can now start RStudio by typing <code class="language-plaintext highlighter-rouge">rstudio</code> in the terminal (it will not show up in your applications), or start an R prompt by typing <code class="language-plaintext highlighter-rouge">R</code>. As a bonus, <code class="language-plaintext highlighter-rouge">r-essentials</code> automatically installs the IRKernel is that can be used in Jupyter Notebook. When you start Jupyter (<code class="language-plaintext highlighter-rouge">jupyter notebook</code>), R is available in the options to create a new notebook.</p> <blockquote> <p>Anaconda gives you the choice of using <a href="https://mran.microsoft.com/open">MRO</a> or normal <a href="https://www.r-project.org/">R</a>. Use conda packages <code class="language-plaintext highlighter-rouge">mro-base</code> or <code class="language-plaintext highlighter-rouge">r</code> respectively.</p> </blockquote> <p><strong>Note:</strong> When installing on Fedora I have run into issues where some applications no longer work because they are trying to use Anaconda rather than the default system Python (I haven’t had this happen on Ubuntu). The installer adds a line to your <code class="language-plaintext highlighter-rouge">.bashrc</code> in order to make Anaconda available on your path. Open <code class="language-plaintext highlighter-rouge">sudo nano ~/.bashrc</code>, and look for a line like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># added by Anaconda3 installer export PATH="/home/username/anaconda3/bin:$PATH" </code></pre></div></div> <p>One quick fix is to flip PATH and Anaconda, so your system Python will be found first by default. Change the <code class="language-plaintext highlighter-rouge">.bashrc</code> line above to <code class="language-plaintext highlighter-rouge">export PATH="$PATH:/home/edog/anaconda3/bin"</code>, then reboot. Your applications will correctly find the system Python, but you can still easily access Anaconda’s <code class="language-plaintext highlighter-rouge">conda</code>, <code class="language-plaintext highlighter-rouge">ipython</code>, and <code class="language-plaintext highlighter-rouge">jupyter</code>. Keep in mind, if you type <code class="language-plaintext highlighter-rouge">python</code> in the terminal, it will be the system Python, not Anaconda.</p> <blockquote> <p>I am conflicted about Anaconda. It is undeniably useful and powerful, simplifying getting started with advanced Python and scientific computing. It is great for teaching, thus has been adopted by organizations such as Software Carpentry. However, as it grows, it is a for-profit enterprise company and building “partnerships” with huge tech companies. This has led to questionable activities, such as adding a prompt to install Microsoft Code Editor to the Anaconda installer. I am actually a Code user, but it seems like classic shady software marketing technique that makes me uncomfortable. The good part of these “partnerships” is sustainable funding and development from the biggest drivers of data science industry. However, it also reduces the community driven spirit and values of open source software.</p> </blockquote> <h1 id="traditional-install">Traditional Install</h1> <p>To get RStudio running first you need <a href="https://cran.r-project.org/">R</a>. R is available in some distro repositories, but is often out-of-date. Specific information on the best way to install can be found from CRAN in the Readme files in the <a href="https://cran.r-project.org/bin/linux/">bin/linux</a> directory (not exactly the most user-friendly way to provide information, but the readmes are comprehensive).</p> <p>On Fedora, the repository version is good, just use the metapackage: <code class="language-plaintext highlighter-rouge">sudo dnf install R</code>.</p> <p>On Ubuntu things are a bit more complicated:</p> <ol> <li>Choose your closest mirror from the <a href="https://cran.r-project.org/mirrors.html">CRAN mirror list</a>, for example <code class="language-plaintext highlighter-rouge">https://cran.cnr.berkeley.edu/</code>.</li> <li>Open your apt sources: <code class="language-plaintext highlighter-rouge">sudo nano /etc/apt/sources.list</code></li> <li>At the bottom, on a new line add the CRAN source, following the pattern <code class="language-plaintext highlighter-rouge">deb</code> + <code class="language-plaintext highlighter-rouge">&lt;mirror url&gt;</code> + <code class="language-plaintext highlighter-rouge">/bin/linux/ubuntu</code> + <code class="language-plaintext highlighter-rouge">&lt;ubuntu version name&gt;/</code>, for example: <code class="language-plaintext highlighter-rouge">deb https://cran.rstudio.com/bin/linux/ubuntu artful/</code>, then save (Ctrl+X, then Y).</li> <li>Add the secure key from CRAN, <code class="language-plaintext highlighter-rouge">sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9</code></li> <li>Update <code class="language-plaintext highlighter-rouge">sudo apt update</code></li> <li>Install R: <code class="language-plaintext highlighter-rouge">sudo apt install r-base r-base-dev r-recommended</code></li> <li>Install dependencies necessary to build R packages: <code class="language-plaintext highlighter-rouge">sudo apt install libxml2-dev libssl-dev libcurl4-openssl-dev libopenblas-dev</code></li> </ol> <p>Next, install RStudio:</p> <ol> <li>Download the package from <a href="https://www.rstudio.com/products/rstudio/download/#download">RStudio</a>.</li> <li>Double click the package to install using the Software center.</li> </ol> <h1 id="r-resources">R Resources</h1> <ul> <li><a href="http://r4ds.had.co.nz/">R for Data Science</a>, Grolemund and Wickham.</li> <li><a href="https://www.tidytextmining.com/">Text Mining with R</a>, Silge and Robinson.</li> <li>SWC <a href="http://swcarpentry.github.io/r-novice-inflammation/">Programming with R</a> or <a href="http://swcarpentry.github.io/r-novice-gapminder/">R for Reproducible Scientific Analysis</a>.</li> </ul> Tue, 03 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/r-linux.html https://evanwill.github.io/_drafts/notes/r-linux.html Setup ImageMagick <p><a href="https://imagemagick.org/">ImageMagick</a> is a powerful open source commandline utility for processing image files that is used under the hood by numerous other tools and websites. Once you get the hang of it, you can use it directly to do a lot of interesting things, from simple batch conversions to complex rendering.</p> <blockquote> <p><em>Note:</em> ImageMagick commands made a major change between version 6 and 7+. The <a href="http://www.imagemagick.org/script/command-line-processing.php">docs</a> on the main website refer to version 7+, where all commands start with <code class="language-plaintext highlighter-rouge">magick</code>. Previous versions used several different commands, such as <code class="language-plaintext highlighter-rouge">convert</code>, instead. A mirror site contains all documentation about <a href="https://legacy.imagemagick.org/script/command-line-processing.php">“legacy” ImageMagick</a>.</p> </blockquote> <h2 id="install-imagemagick">Install ImageMagick</h2> <p>Install ImageMagick and Ghostscript (which enables it to work with PDFs). Setup is easy on Linux, however, it will likely be a legacy version (see note above):</p> <ul> <li>Ubuntu: <code class="language-plaintext highlighter-rouge">sudo apt install imagemagick ghostscript</code>.</li> <li>Fedora: <code class="language-plaintext highlighter-rouge">sudo dnf install ImageMagick ghostscript</code>.</li> </ul> <p>On Windows:</p> <ol> <li>Download the <a href="http://www.imagemagick.org/script/download.php#windows">ImageMagick installer</a>.</li> <li>Run the installer with default options.</li> <li>Download the <a href="https://www.ghostscript.com/download/gsdnld.html">Ghostscript installer</a> (you probably want the AGPL Windows 64 bit version).</li> <li>Run the installer with default options.</li> </ol> <p>Also on Windows, if you want to follow the commands in this note, be sure to have a bash terminal, such as Git Bash (packaged with <a href="https://git-scm.com/">Git installer</a>) or <a href="https://evanwill.github.io/_drafts/notes/cmdr.html">Cmder</a>.</p> <h2 id="using-imagemagick">Using ImageMagick</h2> <p>The full <a href="http://www.imagemagick.org/script/command-line-processing.php">ImageMagick docs</a> do a nice job of introducing commandline processing concepts. However, here is the basics.</p> <blockquote> <p>Basic pattern: <code class="language-plaintext highlighter-rouge">&lt;command&gt; &lt;image options&gt; &lt;input filename(s)&gt; &lt;image operator(s)&gt; &lt;output filename(s)&gt;</code></p> </blockquote> <p>First, use a built in pattern to create a test image: <code class="language-plaintext highlighter-rouge">magick -size 640x480 pattern:checkerboard checkerboard.png</code></p> <p>Convert into a JPEG: <code class="language-plaintext highlighter-rouge">magick checkerboard.png output.jpg</code></p> <p>Resize: <code class="language-plaintext highlighter-rouge">magick checkerboard.png -resize 75% out2.png</code></p> <p>Crop: <code class="language-plaintext highlighter-rouge">magick checkerboard.png -crop 120x120+10+5 test-cr.png</code></p> <p>Combine all PNG in the folder into a PDF: <code class="language-plaintext highlighter-rouge">magick *.png test.pdf</code></p> <p>Combine all JPEG in the folder into a GIF: <code class="language-plaintext highlighter-rouge">magick *.jpg test.gif</code></p> <p>Create an image from first page of PDF: <code class="language-plaintext highlighter-rouge">magick test.pdf[0] new.jpg</code></p> <p>Resize all PNG in a folder, convert to JPEG, and sequentially number: <code class="language-plaintext highlighter-rouge">magick *.png -resize 200x200 thumb%d.jpg</code></p> <p>Resize all PNG in a folder, convert to JPEG, but keep original file name: <code class="language-plaintext highlighter-rouge">magick *.png -resize 300x300 -set filename:f '%t' '%[filename:f]-thumb.jpg'</code></p> <p>Check the <a href="https://www.imagemagick.org/script/command-line-options.php">commandline options</a> page for more details.</p> <h2 id="create-pdf-thumbs">Create PDF Thumbs</h2> <p>In this example, I want to create an image representing a PDF by grabbing the first page from each PDF in a directory and creating a JPEG. A few approaches:</p> <ul> <li>use Magick’s batch abilities: <code class="language-plaintext highlighter-rouge">magick *.pdf[0] -resize x500 -set filename:f '%t' '%[filename:f]-thumb.jpg'</code></li> <li>use simple Magick command in a Bash loop: <code class="language-plaintext highlighter-rouge">for f in *.pdf; do magick "$f"[0] -resize x500 -flatten "${f%.pdf}.jpg"; done</code></li> </ul> <p>For higher quality result, add <code class="language-plaintext highlighter-rouge">-density 600</code>, for example: <code class="language-plaintext highlighter-rouge">for f in *.pdf; do magick -density 600 "$f"[0] -resize x500 -flatten "${f%.pdf}.jpg"; done</code>. Before working with the PDF, Magick must render it at a specific resolution. The default <a href="https://www.imagemagick.org/script/command-line-options.php#density">density</a> is 72 dpi, so bumping it up to 300 or 600 will greatly enhance the quality of most image, but also significantly slow processing.</p> <p>If you need higher speed processing the PDFs, it <em>might</em> be faster to use Ghostscript or Xpdf directly to create the images:</p> <ul> <li>Ghostscript: <code class="language-plaintext highlighter-rouge">for f in *.pdf; do gs -q -o "${f%.pdf}.jpg" -sDEVICE=jpeg -dLastPage=1 -r300 "$f"; done</code> gets the images.</li> <li><a href="http://www.xpdfreader.com/index.html">Xpdf tools</a> provides the <code class="language-plaintext highlighter-rouge">pdftopng</code> utility that can quickly create PNG images from PDFs. For example, <code class="language-plaintext highlighter-rouge">for f in *.pdf; do pdftopng -l 1 -r 300 "$f" "${f%.pdf}"; done</code>, would grab the first page at 300 dpi.</li> </ul> <p>Then use <code class="language-plaintext highlighter-rouge">magick</code> to resize the JPEGs, something like <code class="language-plaintext highlighter-rouge">for f in *.jpg; do magick "$f" -thumbnail x800 -flatten "${f%.jpg}-sm.jpg"; done</code>.</p> <p>If ImageMagick seems too slow, you can try <a href="http://www.graphicsmagick.org/">GraphicsMagick</a> which implements all the same tools and options, but is more optimized for speed. In the example commands above, the only difference is <code class="language-plaintext highlighter-rouge">magick</code> would be replaced with <code class="language-plaintext highlighter-rouge">gm convert</code>. When working with images of very large pixel dimensions, <code class="language-plaintext highlighter-rouge">gm</code> seems more efficient than <code class="language-plaintext highlighter-rouge">magick</code>.</p> <h2 id="pdf-error-on-ubuntu">PDF Error on Ubuntu</h2> <p>If you are using the older version of ImageMagick installed from Ubuntu repository (v. 6.9.x, and thus using <code class="language-plaintext highlighter-rouge">convert</code>), you will probably get an error trying to create images from PDFs. Version 6 had a security policy against using Ghostscript functions due to an security issue in <code class="language-plaintext highlighter-rouge">gs</code>. However, the Ghostscript version in the repositories is more up to date than the ImageMagick version–so the issue probably doesn’t apply.</p> <p>Check your Ghostscript version:</p> <p><code class="language-plaintext highlighter-rouge">gs -v</code></p> <p>If you have &gt; 9.24, you can safely override ImageMagick’s policy. Open the policy file:</p> <p><code class="language-plaintext highlighter-rouge">sudo nano /etc/ImageMagick-6/policy.xml</code></p> <p>Find this section:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;!-- disable ghostscript format types --&gt; &lt;policy domain="coder" rights="none" pattern="PS" /&gt; &lt;policy domain="coder" rights="none" pattern="PS2" /&gt; &lt;policy domain="coder" rights="none" pattern="PS3" /&gt; &lt;policy domain="coder" rights="none" pattern="EPS" /&gt; &lt;policy domain="coder" rights="none" pattern="PDF" /&gt; &lt;policy domain="coder" rights="none" pattern="XPS" /&gt; </code></pre></div></div> <p>Then comment it out:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;!-- disable ghostscript format types --&gt; &lt;!-- &lt;policy domain="coder" rights="none" pattern="PS" /&gt; &lt;policy domain="coder" rights="none" pattern="PS2" /&gt; &lt;policy domain="coder" rights="none" pattern="PS3" /&gt; &lt;policy domain="coder" rights="none" pattern="EPS" /&gt; &lt;policy domain="coder" rights="none" pattern="PDF" /&gt; &lt;policy domain="coder" rights="none" pattern="XPS" /&gt; --&gt; </code></pre></div></div> <p>And save.</p> <h2 id="random-helpful-things">Random helpful things</h2> <p>Sometimes TIFF files have compression inside, which some other utilities can’t read. You can pass them through imagemagick to resave uncompressed: <code class="language-plaintext highlighter-rouge">magick compressed.tif out.tif</code></p> <p>Or as a batch:</p> <p><code class="language-plaintext highlighter-rouge">for f in *.tif; do magick "$f" -set filename:f '%t' 'magick-%[filename:f].tif'; done</code></p> Mon, 02 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/imagemagick.html https://evanwill.github.io/_drafts/notes/imagemagick.html Connect to AirVandalGold wifi on Linux <blockquote> <p>There is no automatic set up utility for University of Idaho’s AirVandalGold wifi network for Linux users. <em>2020 Update:</em> CA certificate step is no longer needed which greatly simplifies the process and <a href="https://support.uidaho.edu/TDClient/40/Portal/KB/ArticleDet?ID=1555#linux">ITS finally added instructions</a> (with screenshots from an very out of date Ubuntu desktop). However, VandalGuest’s new captive login portal does not seem to work.</p> </blockquote> <p>I got it to work using these <a href="https://support.uidaho.edu/TDClient/40/Portal/KB/ArticleDet?ID=1555#linux">ITS instructions</a> on Ubuntu and Fedora:</p> <ol> <li>Open Settings &gt; Wifi, then click on AirVandal Gold, which should pop up the full manual settings (alternatively, from the Wifi menu, choose ‘Edit Connections’, then click ‘Add’. Choose connection type ‘Wi-Fi’, click ‘Create’. Give it a connection name (this is for your own use), AirVandalGold. Under Wi-Fi tab add SSID: AirVandalGold.)</li> <li>Under Wi-Fi Security tab, select/add these options: <ul> <li>Security: “WPA &amp; WPA2 Enterprise”</li> <li>Authentication: “Protected EAP (PEAP)”</li> <li>Anonymous identity: [leave blank]</li> <li>CA Certificate: check “No CA certificate is required”</li> <li>PEAP version: “Automatic”</li> <li>Inner authentication: “MSCHAPv2”</li> <li>Username: [your vandal web id]</li> <li>Password: [your vandal web password]</li> </ul> </li> </ol> <p>You should now be able to connect!</p> <h2 id="vpn">VPN</h2> <p>You can also connect to UI VPN on Linux:</p> <ol> <li>Request VPN access by starting an ITS ticket if you aren’t already set up with permissions.</li> <li>Download the Cisco AnyConnect VPN software from <a href="https://support.uidaho.edu/TDClient/40/Portal/KB/ArticleDet?ID=231#cac-linux-64">ITS software page</a>.</li> <li>Follow <a href="https://support.uidaho.edu/TDClient/40/Portal/KB/ArticleDet?ID=38">VPN install instructions</a>. Even though it is out of date, the <code class="language-plaintext highlighter-rouge">sh</code> install script should work, taking just a few seconds.</li> <li>Open Cisco AnyConnect, in the “Connect to:” box add <code class="language-plaintext highlighter-rouge">vpn.uidaho.edu</code>, then use your UI netid and password. Your Duo two factor id will be prompted to complete the log in. The first time you connect, the client will immediately download and install an update.</li> </ol> <p>Once connected via VPN, it is like you are connected to the network on campus. You can also then connect to the shared drives (although these are being phased out for OneDrive) and remote desktop.</p> <p>To connect to shared drives, you can use the “Other locations” &gt; “connect to server” option in Files. However, this is usually very slow because Ubuntu uses an out-of-date SMB version to retrieve directory information (<a href="https://askubuntu.com/questions/1179576/ubuntu-18-04-problem-to-connect-to-windows-10-smb-share">see note</a>). It is better to manually mount the share, once you have connected via VPN.</p> <p>Remote desktop works well with the default Remmina remote client:</p> <ol> <li>The windows computer must be set up to enable remote desktop (must be admin).</li> <li>Connect via VPN.</li> <li>Open Remmina and click “create new connection profile”.</li> <li>Use the computer name given during windows setup, something like xxxx.uidaho.edu (don’t fill in other fields).</li> <li>accept security certificate.</li> <li>use UI netid and password to log in (leave Domain blank).</li> </ol> Sun, 01 Apr 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/airvandalgold-setup.html https://evanwill.github.io/_drafts/notes/airvandalgold-setup.html Boot a Live USB <p>Burning a live USB is a great way to test out Linux distros (<em>see</em> <a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn SD/USB</a> and <a href="https://evanwill.github.io/_drafts/notes/linux-intro.html">Linux Intro</a> notes). However, for it to work you need to boot from USB. For most systems this is not the default and you will have to intervene as your computer starts up.</p> <p>The boot process is controlled by the BIOS or UEFI installed by your computer manufacturer. Since each company creates a slightly different firmware, there is a lot of variation in how to exactly interrupt normal startup–but this note tries to gather some general tips together.</p> <h2 id="backup">Backup</h2> <p>If you are messing around with your computer, its a good time to take some basic precautions to give you peace of mind–these are best practices that you should follow anyway! Backup of all your files on external storage to make sure you have everything you <em>really</em> want saved in multiple stable locations.</p> <p>On Mac, review how to get to <a href="https://support.apple.com/en-us/HT201314">macOS Recovery</a>. On Windows, make a Windows Recovery Drive on a USB stick (search your system for “recovery” and the option to create a recovery drive will pop up. This ensures you can reinstall or repair Windows if necessary).</p> <h2 id="windows-10--8-prep">Windows 10 / 8 Prep</h2> <p>Windows 10 / 8 overwrite parts of the file system to enable quicker boot times, bypassing the traditional boot process. This “Fast Startup” needs to be disabled or you will not have the option to boot from USB and your linux install will not be able to properly identify the Windows boot manager.</p> <ul> <li>Open the Control Panel &gt; Power Options.</li> <li>Click “Choose what the power button does”, then “Change settings that are currently unavailable”</li> <li>Uncheck the box next to “Turn on fast startup (Recommended)”</li> <li>Completely shutdown your computer (not sleep, hibernate, or restart).</li> </ul> <h2 id="secure-boot">Secure Boot</h2> <p>Newer PCs have a <a href="https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface#Secure_boot">Secure Boot</a> feature that prevents unsigned OS from booting on the system. Major Linux distributions (Ubuntu, Fedora, SUSE) have secure signatures that allow them to run on systems with Secure Boot (you do NOT need to disable it). However, smaller distros do not, so the Secure Boot will have to be disabled. If you try the Boot USB tips below, but after selecting the USB the system skips it and boots into the normal OS–Secure Boot is probably at work and should be disabled.</p> <p>To disable Secure Boot:</p> <ul> <li>Enter your BIOS menu during bootup (see tips as below) or while in Windows: go to the shutdown menu, hold the <code class="language-plaintext highlighter-rouge">shift</code> key and click Restart, from the recovery menu select “Troubleshoot” then “Advanced Options: UEFI Firmware Settings”.</li> <li>Look for the Secure Boot settings under the Security, Boot, or Authentication tab (each manufacturer is different).</li> <li>Set Secure Boot to Disabled.</li> <li>Save changes and exit</li> </ul> <p>(See more advice from <a href="https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/disabling-secure-boot">Microsoft help</a>)</p> <h2 id="boot-usb">Boot USB</h2> <p>With your system fully shutdown, plug your Live USB into your computer.</p> <p>If your computer currently has Linux or Mac installed, it <em>might</em> be easy:</p> <ul> <li><strong>On Linux:</strong> turn on the computer, when you see the GRUB boot menu, use arrow keys to select “System Setup”. This should open the machine’s BIOS/UEFI menu, which should have a boot device option.</li> <li><strong>On Mac:</strong> turn on the computer, immediately press and hold the <code class="language-plaintext highlighter-rouge">Option</code> key. This should bring you to the “Startup Manager” allowing you to select the USB drive (more tips on <a href="https://support.apple.com/en-us/HT202796">Mac help</a>).</li> </ul> <p><em>Otherwise</em>, try the following tips:</p> <p>Press the power button–then watch closely! Each device is different, but just as the computer starts to boot you should see a screen with the manufacture’s logo and a message that tells you which key to press to “interrupt the boot process”, enter BIOS/UEFI, or “choose a boot device”. Sometimes it flashes by so fast you can’t read it!</p> <p>The key is usually F12, Esc, F11, F10, F9, F1, F2, or DEL (here are some tips from <a href="https://www.pendrivelinux.com/how-to-access-bios/">Pendrivelinux</a> or <a href="https://www.groovypost.com/howto/bios-uefi-setup-guide-boot-from-cd-dvd-usb-drive-sd-card/">gpost</a>). If your laptop has a compact keyboard, be sure to use the correct key combo (often <code class="language-plaintext highlighter-rouge">fn</code> + key). Click the key repeatedly until you get a response, if it flashes by too quick and starts booting Windows, hold the power button to shut down, then try again.</p> <p>Here are some possible outcomes:</p> <ul> <li><strong>Choose Boot Device:</strong> If you are lucky, your vender provides the “choose a boot device” option. Once you click the correct key, a small menu will appear listing the available disk drives in the system. Look for your USB’s label and size to identify the correct drive. Use the arrow keys to highlight the USB drive, then click enter to boot–Success!</li> <li><strong>BIOS Boot Order:</strong> For older systems if you get into a BIOS menu, but can’t find a “choose a boot device” option, look for a “Boot order” setting. Use the menu to change the boot order, moving USB drives to the top (traditionally, optical drives are at the top, then hard drives). Save and exit the BIOS menu and reboot–the USB should boot.</li> <li><strong>Locked down UEFI:</strong> On some Windows 10 / 8 machines, UEFI has been made a bit more complicated and there is no boot device or boot order options at start up. Allow Windows to boot up. First, make sure you have disabled “Fast Startup” as described above. Then, go to the Windows shutdown menu, hold the <code class="language-plaintext highlighter-rouge">shift</code> key and click Restart. This should bring up a blue boot options menu, select “Use a device”, then select your USB. Alternatively, try Settings &gt; Update &amp; security &gt; Recovery, then look for “Advanced startup” and click “Restart now”.</li> </ul> <p>There is a lot of variation in exactly how to access BIOS and UEFI options from different computer companies, so if none of this seems to work, try searching for help on your specific model and manufacturer.</p> Mon, 26 Mar 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/linux-boot-usb.html https://evanwill.github.io/_drafts/notes/linux-boot-usb.html Fedora Setup <p>After being a long-term Ubuntu user, while using 17.10 and looking ahead at 18.04, I suddenly lost a bit of hope for the distribution and decided to try some others for awhile (especially since I have been manually <a href="https://evanwill.github.io/_drafts/notes/ubuntu-kernel.html">installing new kernels</a> due to bugs with my laptop with 17.10).</p> <p>First, <a href="https://getfedora.org/">Fedora</a>. I choose Fedora because it is a bit more cutting edge than Ubuntu, yet still fairly stable (and running a newer kernel that works correctly with my laptop). I have found that although Debian/Ubuntu is known for gigantic repositories, Fedora plus RPM Fusion has more packages that I am interested in and they are more up-to-date. Fedora is also interesting because of its connection to the huge enterprize Linux company <a href="https://www.redhat.com/en">Red Hat</a>. There are a lot of good things about Fedora philosophically, I am liking it but I haven’t been totally sold on it yet… anyway, here are my notes about getting started:</p> <h2 id="installer">Installer</h2> <p>Fedora uses their “Anaconda” installer, which is not as immediately user friendly as Ubuntu’s. Unlike Ubuntu, it does not automatically detect existing operating systems and offer to dual-boot or other options. However, dual-booting is still possible, it is just not well documented and the UX is poor.</p> <p>To dual-boot with an existing OS, chick on the install location icon and select your hard drive. In the options below, check “Automatic” and “I would like to make additional space available”. Then click “Done” at the top. This will open a window where you can choose existing partitions to delete–i.e. select your old Linux partition you want to over write. The selected partitions will be deleted, and Fedora will automatically set up new ones in the freed up space.</p> <p>In my case, this seemed to work good. However, Grub does not detect Windows on my machine for some reason. I haven’t been able to fix this yet, because Grub uses <code class="language-plaintext highlighter-rouge">os-prober</code> and doesn’t find anything except Fedora.</p> <p>This highlights the main frustration I have run into so far with Fedora: there just isn’t as much help online. If you search for any issue you will get a thousand Ubuntu answers, and maybe one incomplete/out-of-date Fedora one.</p> <p>Try <a href="https://ask.fedoraproject.org/en/questions/">Ask Fedora</a>…</p> <h2 id="get-started">Get started</h2> <p>Once Fedora is installed, I noticed start up time is longer than expected.</p> <ol> <li>Update: do a <code class="language-plaintext highlighter-rouge">sudo dnf upgrade --refresh</code>, this will refresh the package list and update everything. This first one might be big and will require a restart to finish updating.</li> <li>Tweaks: <code class="language-plaintext highlighter-rouge">sudo dnf install gnome-tweaks</code>, to get started customizing the look and feel. I turn off animations right away.</li> <li>Enable RPM Fusion: follow the links on the <a href="https://rpmfusion.org/Configuration">Fusion Configuration page</a> to set up the extended repository for Fedora (the main repos are purely Free software only).</li> </ol> <h2 id="get-gnome-extensions">Get Gnome Extensions</h2> <p>Fedora comes with a few GNOME extensions installed, head to Tweaks &gt; Extensions to try turning them off and on. To get more, you have to add some things, because the current GNOME shell extensions browser plugin doesn’t work with up-to-date Firefox. You need Chromium and the host app to get started:</p> <p><code class="language-plaintext highlighter-rouge">sudo dnf install chromium chrome-gnome-shell</code></p> <p>Once installed, head to <a href="https://extensions.gnome.org/">GNOME Extensions</a> to try stuff out. Here are two I like:</p> <ul> <li><a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine</a>, disable screen lock to watch movies</li> <li><a href="https://extensions.gnome.org/extension/1160/dash-to-panel/">Dash to Panel</a>, puts dash into the top/bottom bar, sort of like windows 10</li> </ul> <h2 id="get-themes">Get themes</h2> <p>The default Adwaita theme isn’t that lovely. There are a bunch of themes in the Fedora repos, so install a bunch and play around:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo dnf install arc-theme numix-gtk-theme numix-icon-theme numix-icon-theme-circle bluecurve-gnome-theme bluecurve-icon-theme gnome-shell-theme-selene bluecurve-metacity-theme nodoka-theme-gnome elementary-icon-theme pop-gtk-theme pop-icon-theme moka-icon-theme evopop-gtk-theme evopop-icon-theme arc-theme adapta-gtk-theme paper-icon-theme </code></pre></div></div> <p>Then open Tweaks &gt; Appearance to switch between the Applications and Icons themes to see how they look.</p> <h2 id="get-more-apps">Get more apps</h2> <p>Use Software, or search <a href="https://apps.fedoraproject.org/packages/">Fedora Packages</a> and use <code class="language-plaintext highlighter-rouge">sudo dnf install &lt;packagename&gt;</code>.</p> <h2 id="jekyll">Jekyll</h2> <p>My next set is always to get Jekyll set up. You could use the main repositories, like <code class="language-plaintext highlighter-rouge">sudo dnf install ruby ruby-devel rubygem-jekyll</code>, but you end up with a fairly out-of-date Jekyll.</p> <p>Unfortunately, you need a bunch of stuff. This worked for me:</p> <p><code class="language-plaintext highlighter-rouge">sudo dnf groupinstall "C Development Tools and Libraries"</code></p> <p><code class="language-plaintext highlighter-rouge">sudo dnf install redhat-rpm-config</code></p> <p><code class="language-plaintext highlighter-rouge">sudo dnf install ruby ruby-devel rubygems-devel</code></p> <p><code class="language-plaintext highlighter-rouge">gem update --system</code> <em>note: vulnerabilities recently discovered in gem, update!</em></p> <p><code class="language-plaintext highlighter-rouge">gem install jekyll bundler</code></p> <h2 id="fonts">Fonts</h2> <p>You might want a few more fonts, open Software, click Add-ons &gt; Fonts. Scroll through and install a bunch. I also do: <code class="language-plaintext highlighter-rouge">sudo dnf install google-noto-mono-fonts adobe-source-code-pro-fonts</code>.</p> <p>Also, you can download <a href="https://github.com/tonsky/FiraCode">Fira Code</a>, look in the ttf folder, then double click on each of the font weights. This opens up the font install window, click the Install button to add to the system.</p> Sat, 17 Mar 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/fedora-setup.html https://evanwill.github.io/_drafts/notes/fedora-setup.html Alternative Kernels on Ubuntu <p>I encountered an amazingly annoying <a href="https://askubuntu.com/questions/995819/touchpad-gestures-and-holding-keys-does-not-work">keyboard and touchpad bug</a> in early 2018 with the linux kernel that ships with Ubuntu 17.10. This led me to switch to a newer mainline kernel where the bug is fixed. At first it sounds complicated to re-install the most basic parts of your operating system, but in fact it is pretty easy!</p> <h2 id="check-current-kernel-version">Check Current Kernel Version</h2> <p>The command <code class="language-plaintext highlighter-rouge">uname -r</code> will list your current kernel version. If you want to see a list of all kernels currently installed, try <code class="language-plaintext highlighter-rouge">dpkg --list | grep linux-image</code> (yes, you probably have more than one!).</p> <h2 id="boot-with-an-older-kernel">Boot with an Older Kernel</h2> <p>As you install regular updates, Ubuntu will add new versions of the kernel. Unless you <code class="language-plaintext highlighter-rouge">sudo apt autoremove</code>, these older versions will be available on your system in case you need to roll back. When you hit the GRUB menu during system start up, arrow down and select “Advanced options for Ubuntu”. This will give you a list of installed kernels. Simply select one of the older ones to boot up and see if the bug goes away.</p> <h2 id="add-new-kernels">Add New Kernels</h2> <p>To get Ubuntu packages for the new kernels, visit the <a href="http://kernel.ubuntu.com/~kernel-ppa/mainline/?C=M;O=D">Ubuntu kernel ppa</a>. The kernel versions are numbered like <code class="language-plaintext highlighter-rouge">v4.15.1</code> and fall into several <a href="https://www.kernel.org/category/releases.html">categories</a> (RC, Mainline, Stable, or Longterm). Mainline is the newest version line (e.g. <code class="language-plaintext highlighter-rouge">4.15</code>), and is continuously updated with new Stable subversions (e.g. <code class="language-plaintext highlighter-rouge">4.15.1</code>). The newest Mainline kernel has the most up-to-date fixes and performance improvements, but also has the most <em>unknown</em> bugs. Older Stable and Longterm kernels are regularly updated with patches from the Mainline, thus may have issues, but most are <em>known</em> bugs that have documented fixes. There is a trade off between the most up-to-date and more stable kernels (see <a href="https://www.linux.com/blog/learn/2018/2/which-linux-kernel-version-stable">“Which kernel version is stable”</a> for a good discussion), thus most distros maintain a LTS version with their releases.</p> <p>From the the <a href="http://kernel.ubuntu.com/~kernel-ppa/mainline/?C=M;O=D">Ubuntu kernel ppa</a>, click on the newer version you want to install. Scroll down to the “build” section for your computer’s architecture, most likely “amd64” and “generic” for a 64-bit laptop. You’ll need three <code class="language-plaintext highlighter-rouge">.deb</code> files from the list: headers all, headers generic, and image generic (i.e. not the “lowlatency” ones). Download the three packages for the new kernel, for example, the version number is replaced with “…” in the list below:</p> <ul> <li><code class="language-plaintext highlighter-rouge">linux-headers-... _all.deb</code></li> <li><code class="language-plaintext highlighter-rouge">linux-headers-... -generic... _amd64.deb</code></li> <li><code class="language-plaintext highlighter-rouge">linux-image-... -generic... _amd64.deb</code></li> </ul> <p>Next, to simplify install, I create a new folder and add the three downloaded <code class="language-plaintext highlighter-rouge">.deb</code> packages. In the new folder containing <em>only</em> the three kernel packages, run <code class="language-plaintext highlighter-rouge">sudo dpkg -i *.deb</code> (it is best to install all at once, since they are dependencies of each other). Once the install has finished, restart and you will be using the new kernel. If you encounter an issue with the new kernel, rollback to the older version using the GRUB menu.</p> <p>Keep in mind that the manually installed kernel will not be updated or automatically removed. Once your distro adds a newer kernel version, automatic updates will kick in again and install the newest version. Thus, if you want to keep on the regular updates, it is best not to jump a major version ahead if possible, since your distro may not ever catch up.</p> <p>To remove manually installed kernels, it is easiest to use <code class="language-plaintext highlighter-rouge">synaptic</code> package manager (note: does not run in a Wayland session). Search for “linux-image”, mark the versions “for Complete Removal”, then click Apply. Just be sure not to remove ALL your kernels, or you will have nothing to boot!</p> Thu, 01 Feb 2018 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu-kernel.html https://evanwill.github.io/_drafts/notes/ubuntu-kernel.html Ubuntu essentials <p>Ubuntu is great, but here are some essentials and tips to get started and fix some issues that I regularly encounter. This post is from Ubuntu &lt; 17.04, when Ubuntu shipped with the Unity desktop. Since 17.10+, Ubuntu ships with Gnome desktop, so some of this post is not relevant or out-of-date–check my notes about <a href="https://evanwill.github.io/_drafts/notes/ubuntu-gnome.html">Gnome on Ubuntu</a> for tips.</p> <h2 id="install-essentials">Install essentials</h2> <p>The quick and easiest method to install <a href="https://packages.ubuntu.com/">packages</a> is to use the command line, <code class="language-plaintext highlighter-rouge">sudo apt install packagename</code>. Otherwise, search the Software Center.</p> <ul> <li>Tweak Tool is handy to change the look &amp; feel of the desktop, exposing many settings that are normally buried deep in config files. On Gnome (17.10+) <code class="language-plaintext highlighter-rouge">gnome-tweak-tool</code> or Unity (&lt;17.04) <code class="language-plaintext highlighter-rouge">unity-tweak-tool</code>.</li> <li>Play MP3s: many common media codec are not free and open source, requiring complicated licensing. Thus Ubuntu does not ship with them. There is an option to add them during install, but I don’t since it complicates the process. Install manually using <code class="language-plaintext highlighter-rouge">ubuntu-restricted-extras</code> (note there is a different package name for each desktop and version, so confirm by searching on <a href="https://packages.ubuntu.com/">packages</a>).</li> <li>Play videos: VLC, get a better video player right away, <code class="language-plaintext highlighter-rouge">vlc</code>.</li> <li>Play DVDs: DVDs can’t be played until you install some non-free stuff. The codecs are not ready to go in the main repositories, so the easiest way seems to be to build it yourself: <code class="language-plaintext highlighter-rouge">sudo apt install libdvd-pkg</code> then <code class="language-plaintext highlighter-rouge">sudo dpkg-reconfigure libdvd-pkg</code>. You may also need to add these packages <code class="language-plaintext highlighter-rouge">sudo apt install libdvdnav4 libdvdread4</code></li> <li>Caffeine, turns off screen lock so that your screen doesn’t turn off while you are watching youtube! On Unity look for <code class="language-plaintext highlighter-rouge">caffeine-indicator</code> in the Software center. On Gnome, use the <a href="https://extensions.gnome.org/extension/517/caffeine/">Caffeine extension</a>.</li> <li>Text editor: tweak the settings of <a href="https://evanwill.github.io/_drafts/notes/gedit-editor.html">Gedit</a>, and add <a href="https://code.visualstudio.com/">Visual Studio Code</a> or <a href="https://atom.io/">Atom</a>.</li> <li>Git: <code class="language-plaintext highlighter-rouge">sudo apt install git</code> do it!</li> <li>Simple firewall: <code class="language-plaintext highlighter-rouge">gufw</code>. Check out some more extreme <a href="https://wiki.ubuntu.com/BasicSecurity">security suggestions</a>.</li> <li>Image editing: GIMP, <code class="language-plaintext highlighter-rouge">gimp</code> (the first time you open it, click “Windows” &gt; “Single window mode” for a more usable experience). If you use raw images, check out Darktable. To play with HDR, <code class="language-plaintext highlighter-rouge">luminance-hdr</code>.</li> <li>Ebook manager: Calibre, if you have ebooks, this helps you manage them and connect with reading devices. It also has great built in editing and conversion tools.</li> <li>KeePass2 (<code class="language-plaintext highlighter-rouge">keepass2</code>) or KeePassX for passwords.</li> <li><code class="language-plaintext highlighter-rouge">build-essential</code> adds Make and compilers necessary for building a lot of software.</li> <li><code class="language-plaintext highlighter-rouge">curl</code> is often to grab web stuff on the command line.</li> <li>A few extra fonts: <code class="language-plaintext highlighter-rouge">fonts-firacode</code> <code class="language-plaintext highlighter-rouge">fonts-noto</code></li> <li>Firefox extensions: <a href="https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/">uBlock Origin</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/facebook-container/">Facebook Container</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/multi-account-containers/">Multi-account Containers</a>, <a href="https://testpilot.firefox.com/experiments/side-view">Side-view</a>, <a href="https://testpilot.firefox.com/experiments/notes/">Notes</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/onetab/">OneTab</a></li> <li>Disk utilities: <a href="https://www.balena.io/etcher/">Etcher</a> for burning USBs, and GParted for formatting.</li> </ul> <h2 id="languages">Languages</h2> <ul> <li>Python: Ubuntu comes with a system Python version installed. If you want to work with Python, its a good idea to install a more up-to-date version for your user account. I suggest <a href="https://www.continuum.io/downloads">Anaconda</a>, a scientific Python distribution with comes packages with everything you need, including iPython and Jupyter Notebook. Then <a href="https://evanwill.github.io/_drafts/notes/dual-python-notebook.html">set up Jupyter</a> with Py 2, 3, and R.</li> <li>Java: <code class="language-plaintext highlighter-rouge">default-jre</code> or <code class="language-plaintext highlighter-rouge">default-jdk</code> (this tends to be up-to-date, some apps may require an old version, search <a href="https://packages.ubuntu.com/search?keywords=jdk&amp;searchon=names&amp;suite=bionic&amp;section=all">packages</a> for find them).</li> <li>Ruby: probably best to use <a href="https://rvm.io/">RVM</a> (see <a href="/_drafts/notes/ruby-notes.html">note</a>), although you can use the repository (<code class="language-plaintext highlighter-rouge">ruby-full</code>), but it is slightly out of date.</li> <li>Processing3: <a href="https://processing.org/download/">download</a></li> <li>Arduino: <a href="https://www.arduino.cc/en/Main/Software">download</a></li> <li>NodeJS: use <a href="https://github.com/creationix/nvm">nvm</a> (this seems to be the best method; install nvm, then <code class="language-plaintext highlighter-rouge">nvm install --lts</code>), or official <a href="https://github.com/nodesource/distributions/blob/master/README.md">NodeSource ppa</a>, or repository version <code class="language-plaintext highlighter-rouge">nodejs</code> (which maybe a bit behind)</li> </ul> <h2 id="older-suggestions-for-ubuntu--1704-with-unity">Older suggestions for Ubuntu &lt; 17.04 with Unity</h2> <h3 id="tweak-settings">Tweak settings</h3> <p>Open the Settings app:</p> <ul> <li>Appearance &gt; Behavior &gt; set options to Show the menus in the window’s title bar and Always displayed.</li> <li>Screen Display &gt; set the Scale if everything looks tiny on your High DPI screen. Start with this setting before tweaking other scaling options.</li> <li>Use Unity Tweak to customize everything else…</li> </ul> <p>If you like the night time color shift, check out Redshift.</p> <h3 id="mouse-doesnt-seem-quite-right">Mouse doesn’t seem quite right</h3> <p>If its a logitech mouse, install <code class="language-plaintext highlighter-rouge">solaar</code> with Unity/gnome extensions, <code class="language-plaintext highlighter-rouge">sudo apt-get install solaar-gnome3</code>. Then unplug the mouse and restart the system. Or try <code class="language-plaintext highlighter-rouge">lomoco</code> to manually configure.</p> <h3 id="gvfsd-smb-browse-uses-100-of-one-cpu-core">gvfsd-smb-browse uses 100% of one CPU core</h3> <p>This is an odd bug that has effected people for a long time, but hasn’t been fixed, particularly on 16.04. If you notice your machine heating up, check you system monitor and <code class="language-plaintext highlighter-rouge">stop</code> gvsd-smb-browse process, don’t kill it. There is 100 fixes available online, but all are sort of sketchy and odd. The best option: install samaba, <code class="language-plaintext highlighter-rouge">sudo apt-get install samba</code>. It seems Ubuntu doesn’t have the full package, and once you install it, the bug seems to go away.</p> Thu, 02 Nov 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/ubuntu-tips.html https://evanwill.github.io/_drafts/notes/ubuntu-tips.html Gaming on Raspberry Pi <blockquote> <p>#MakeItMondays in the <a href="https://mill.lib.uidaho.edu/">MILL</a>: Gaming on Raspberry Pi!</p> </blockquote> <p>Raspberry Pi is a wonderful little $35 linux computer–and it’s a lot of fun. Sure there is a lot of applications for physical computing or learning to code, but Pi also a handy open-source gaming machine! If you are interested in retro emulation, there are specialized distributions such as <a href="https://retropie.org.uk/">RetroPie</a> (my <a href="https://evanwill.github.io/_drafts/notes/retropie.html">RetroPie notes</a>). However, there are plenty of gaming opportunities on the standard Pi operating system, <a href="https://www.raspberrypi.org/downloads/raspbian/">Rasbian</a>. Rasbian is a <a href="https://www.gnu.org/philosophy/free-sw.en.html">free and open-source</a> OS, and most of the applications available are as well, which means no cost for you, so give these games a try!</p> <h2 id="built-in-games">Built in games</h2> <p>These can be found in the Menu, under the Games category:</p> <ul> <li><a href="https://minecraft.net/en-us/edition/pi/">Minecraft Pi</a>: RPI ships with a special edition of the popular game Minecraft with a programming console for learning Python. Check out <a href="https://www.raspberrypi.org/learning/getting-started-with-minecraft-pi/">Getting Started with Minecraft Pi</a>.</li> <li><a href="https://www.raspberrypi.org/documentation/usage/python-games/">Python Games</a>. A set of a dozen simple games writen in the Python programming language. This means you can play the games–and easily learn to edit them yourself. The source code for each is in <code class="language-plaintext highlighter-rouge">/home/pi/python_games</code>. Check out Al Sweigart’s <a href="https://inventwithpython.com/pygame/chapters/">Making Games with Python &amp; Pygame</a> to learn Python while making games!</li> </ul> <h2 id="install-packages">Install packages</h2> <p>Linux distributions have package managers designed to automatically install and update in software in a safe and secure way. Rasbian is based on <a href="https://www.debian.org/">Debian linux</a> and uses the <code class="language-plaintext highlighter-rouge">apt</code> utility on the command line. To use it, open Terminal, and type <code class="language-plaintext highlighter-rouge">sudo apt install package-name</code> (replacing package-name with the actual application name). You can search for package names using <code class="language-plaintext highlighter-rouge">sudo apt-cache search</code>. If you want more information, check Linux’s built in manual by typing <code class="language-plaintext highlighter-rouge">man apt</code>.</p> <p>Debian’s repositories have a lot of fun games (here’s a decent <a href="http://www.raspberryconnect.com/raspbian-packages-list/item/65-raspbian-games">list for Pi</a>, or a database of all <a href="https://lgdb.org/">linux games</a>). Keep in mind not all will run well on Pi given the low spec hardware, but it is all free, so why not give them a try? (p.s. remove packages using <code class="language-plaintext highlighter-rouge">sudo apt remove package-name</code>) Here are a few options:</p> <ul> <li>Classic <a href="https://games.kde.org/">KDE games</a>: <code class="language-plaintext highlighter-rouge">kblocks kbreakout kapman kmines kgoldrunner kdiamond kspaceduel kpat</code></li> <li>Arcade-like classics: <code class="language-plaintext highlighter-rouge">frozen-bubble</code>, <code class="language-plaintext highlighter-rouge">xgalaga</code>, <code class="language-plaintext highlighter-rouge">snake4</code>, <code class="language-plaintext highlighter-rouge">battleball</code>, <code class="language-plaintext highlighter-rouge">tint</code>, <code class="language-plaintext highlighter-rouge">freesweep</code>, <code class="language-plaintext highlighter-rouge">pingus</code>, <code class="language-plaintext highlighter-rouge">chromium-bsu</code></li> <li>Classic point-n-click adventures: <code class="language-plaintext highlighter-rouge">flight-of-the-amazon-queen</code>, <code class="language-plaintext highlighter-rouge">beneath-a-steel-sky</code>, <code class="language-plaintext highlighter-rouge">drascula</code>, <code class="language-plaintext highlighter-rouge">lure-of-the-temptress</code></li> <li>Tux classics: <code class="language-plaintext highlighter-rouge">supertux</code> (Mario inspired platformer), <code class="language-plaintext highlighter-rouge">supertuxkart</code> (Mario kart like races, might not work on current Rasbian), <code class="language-plaintext highlighter-rouge">extremetuxracer</code> (downhill penguin race)</li> <li>Rogue-like: <code class="language-plaintext highlighter-rouge">games-rogue</code> (group of rogue-like games, including <code class="language-plaintext highlighter-rouge">angband</code>, <code class="language-plaintext highlighter-rouge">crawl</code>, <code class="language-plaintext highlighter-rouge">moria</code>, and <code class="language-plaintext highlighter-rouge">slashem</code>), <code class="language-plaintext highlighter-rouge">crawl-tiles</code> (classic rogue-like with graphics)</li> <li>Others: <code class="language-plaintext highlighter-rouge">freeciv</code> (Civilization builder), <code class="language-plaintext highlighter-rouge">openttd</code> (Transport Tycoon), <code class="language-plaintext highlighter-rouge">lincity</code> (sim city), <code class="language-plaintext highlighter-rouge">endless-sky</code> (space exploration), <code class="language-plaintext highlighter-rouge">freeorion</code> (space conquest)</li> <li>Create levels: there are many games inspired by commercial classics that fans create open engines and free content for, such as <code class="language-plaintext highlighter-rouge">freedink</code> (zelda-like),<code class="language-plaintext highlighter-rouge">flare</code> (action rpg), or <code class="language-plaintext highlighter-rouge">freedoom</code> (free DOOM game base).</li> <li>Cat that follows your mouse: <code class="language-plaintext highlighter-rouge">oneko</code> (is this a game? well it’s amusing anyway…)</li> </ul> <h2 id="web-emulator">Web emulator</h2> <p>The <a href="https://archive.org/">Internet Archive</a> has thousands of old games preserved in their digital library. They make them available in a browser based emulator, so you can play them anywhere, but Pi is just right for many of these retro games! Yes, you can play <a href="https://archive.org/details/msdos_Oregon_Trail_The_1990">Oregon Trail</a> right now, or check out these collections:</p> <ul> <li><a href="https://archive.org/details/internetarcade">Internet Arcade</a></li> <li><a href="https://archive.org/details/softwarelibrary_msdos_games">MS DOS</a></li> <li><a href="https://archive.org/details/consolelivingroom">Console Living Room</a></li> </ul> <h2 id="commandline-fun">Commandline fun</h2> <p>The Terminal is a powerful command line interface in Linux. So why not use it for some fun?</p> <ul> <li>Classic BSD Games: install <code class="language-plaintext highlighter-rouge">bsdgames</code> to get access to dozens of classics. Type the name of the game in the terminal to start playing, for example, <code class="language-plaintext highlighter-rouge">tetris-bsd</code>. Check the <a href="http://wiki.linuxquestions.org/wiki/BSD_games">list</a> for the names.</li> <li>Text adventure: try the original <code class="language-plaintext highlighter-rouge">colossal-cave-adventure</code></li> <li>Rogue-like: enter the retro world of text-based RPGs with <code class="language-plaintext highlighter-rouge">nethack</code>, <code class="language-plaintext highlighter-rouge">slashem</code>, <code class="language-plaintext highlighter-rouge">omega-rpg</code>, <code class="language-plaintext highlighter-rouge">crawl</code>, <code class="language-plaintext highlighter-rouge">angband</code>, or <code class="language-plaintext highlighter-rouge">moria</code></li> <li>Wise cow: install <code class="language-plaintext highlighter-rouge">cowsay</code> and <code class="language-plaintext highlighter-rouge">fortune</code> to access the wisdom of the command line. Try <code class="language-plaintext highlighter-rouge">cowsay "Hello"</code> or <code class="language-plaintext highlighter-rouge">fortune</code>, then advance to <code class="language-plaintext highlighter-rouge">fortune | cowsay</code> or <code class="language-plaintext highlighter-rouge">fortune | cowsay -f dragon</code>.</li> </ul> <h2 id="opengl">OpenGL</h2> <p>On rpi2 with the newest version of Raspbian Stretch, you can enable a new hardware OpenGL driver. Run <code class="language-plaintext highlighter-rouge">sudo raspi-config</code>, look in Advanced &gt; GL Driver. Select the new driver, then select finish and reboot the pi.</p> <p>Try it out with a few OpenGL games, such as <code class="language-plaintext highlighter-rouge">neverball</code> and <code class="language-plaintext highlighter-rouge">oolite</code>.</p> Mon, 18 Sep 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pi-gaming.html https://evanwill.github.io/_drafts/notes/pi-gaming.html Dates in Excel <p>Excel will mess up your dates. Assuming you want to use your data outside of Excel, it is best to avoid allowing it to convert them to its built in format, so import as “text” and set the column type to “text” to avoid issues.</p> <p>Excel uses the 1900 date system (sometimes called numeric dates, serial dates, or 1900 system). It simply counts the number of days since 1900. Thus, 1900-01-01 = 1, 1900-01-02 = 2, and so on. This allows dates to be more easily used in calculations. However, MS has several historical bugs built into Excel which they have never fixed for compatibility reasons:</p> <ul> <li>Some versions of Excel on Mac <a href="https://support.microsoft.com/en-us/help/180162/xl-the-1900-date-system-vs--the-1904-date-system">used 1904 date system</a></li> <li>Excel <a href="https://support.microsoft.com/en-us/help/214326/excel-incorrectly-assumes-that-the-year-1900-is-a-leap-year-1900-is-a-leap-year">assumes 1900 is a leap year</a>, which is false.</li> </ul> <p>So sometimes you will see plain text data, such as a CSV, exported from Excel that has dates that look like <code class="language-plaintext highlighter-rouge">42291</code> and you need to convert that serial date back into a real one. Unfortunately, unless you know what version of Excel it was exported from, you can not be sure if the serial date number is off by one day or potentially more (1904 system). But you can do you best to convert it back using OpenRefine GREL like:</p> <p><code class="language-plaintext highlighter-rouge">"1900-01-01".toDate().inc(value.toNumber()-2,'day').toString('yyyy-MM-dd')</code></p> <p>Start at Excel’s starting point, “1900-01-01” and convert to a date. Then use <code class="language-plaintext highlighter-rouge">inc</code> function to add the number of days in Excel’s serial date, but add -1 day because our date “1900-01-01” is actually 1 (i.e. we are not starting at zero), and then -1 again for the 1900 leap year bug. I add the cell value to the express with <code class="language-plaintext highlighter-rouge">value.toNumber()</code> if the column is currently a text column, but if it was already a number column, you could just use <code class="language-plaintext highlighter-rouge">value</code>. Finally, convert the date format into a preferred text format using <code class="language-plaintext highlighter-rouge">toString()</code>.</p> <p>Ugly.</p> Tue, 05 Sep 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/excel-dates.html https://evanwill.github.io/_drafts/notes/excel-dates.html Epic Music! <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://evanwill.github.io/_drafts/css/abcmusic.css"> <script src="https://evanwill.github.io/_drafts/js/abcjs_editor_midi_3.1.2-min.js" type="text/javascript"></script> <div id="playground"> <div id="notation" class="abc-rendered"></div> <div id="play"></div> <div id="warnings" class="abc-warnings"></div> <textarea name="abc" id="abc-text" class="abc-text" rows="14"></textarea> <button type="button" class="buttons" onclick="loadAbc();">New Epic Music!</button> <button type="button" class="buttons" onclick="showEdit();">Edit</button> <!--<button type="button" onclick="printAbc();">Print</button>--> <button type="button" class="buttons" id="ref" onclick="showRef();">ABC Ref</button> <button type="button" class="buttons" id="midi-download"></button> <br> <div id="quickref"> <p><a href="https://en.wikipedia.org/wiki/ABC_notation" target="_blank" rel="noopener">ABC notation</a> is a shorthand standard for representing music, commonly used to record and share traditional folk tunes. Each tune has a header and some notes.</p> <p>Common header elements:</p> <ul> <li><code class="highlighter-rouge">X:</code> index number, required in some software [e.g. <code class="highlighter-rouge">X:1</code>]</li> <li><code class="highlighter-rouge">T:</code> title [e.g <code class="highlighter-rouge">T: Happy Birthday</code>]</li> <li><code class="highlighter-rouge">M:</code> meter, required [e.g. <code class="highlighter-rouge">M:C</code>, <code class="highlighter-rouge">M:4/4</code>, <code class="highlighter-rouge">M:3/4</code>]</li> <li><code class="highlighter-rouge">L:</code> default note length [e.g. <code class="highlighter-rouge">L:1/2</code>, <code class="highlighter-rouge">L:1/4</code>, <code class="highlighter-rouge">L:1/8</code>]</li> <li><code class="highlighter-rouge">Q:</code> tempo [e.g. <code class="highlighter-rouge">Q:120</code>, <code class="highlighter-rouge">Q:1/8=120</code>, <code class="highlighter-rouge">Q:1/4=60</code>]</li> <li><code class="highlighter-rouge">K:</code> key signature, required [e.g. <code class="highlighter-rouge">K:G</code>, <code class="highlighter-rouge">K:Gm</code>]</li> <li><code class="highlighter-rouge">V:</code> voice, can set the clef [e.g. <code class="highlighter-rouge">V:1 name=Violin</code>, <code class="highlighter-rouge">V:2 name=Cello clef=bass</code>]</li> </ul> <p>Common notation elements:</p> <ul> <li>bottom octave <code class="highlighter-rouge">CDEFGAB</code>, top octave <code class="highlighter-rouge">cdefgab</code> [e.g. <code class="highlighter-rouge">C</code> = middle C]</li> <li><code class="highlighter-rouge">z</code> rest</li> <li><code class="highlighter-rouge">,</code> down an octave, <code class="highlighter-rouge">'</code> up an octave [e.g. <code class="highlighter-rouge">C,</code> or <code class="highlighter-rouge">c'</code>]</li> <li><code class="highlighter-rouge">^</code> sharps, <code class="highlighter-rouge">_</code> flats [e.g. <code class="highlighter-rouge">^c</code> or <code class="highlighter-rouge">_c</code>]</li> <li>make note longer by multiplying number, or shorter by a <code class="highlighter-rouge">/</code> dividing number [e.g. <code class="highlighter-rouge">a2</code> or <code class="highlighter-rouge">a/2</code>]</li> <li>notes separated by spaces will not have beams, those together will [e.g. <code class="highlighter-rouge">a b c</code> versus <code class="highlighter-rouge">abc</code>]</li> <li><code class="highlighter-rouge">|</code> barline, <code class="highlighter-rouge">|]</code> double bar, <code class="highlighter-rouge">|:</code> repeats <code class="highlighter-rouge">:|</code></li> </ul> </div> </div> <p>Epic Music reads Samuel Butler's translations of the Iliad and Odyssey as if it was <a href="https://en.wikipedia.org/wiki/ABC_notation" target="_blank" rel="noopener">ABC notation</a>, a simple plain text music format. The editor is created using <a href="https://github.com/paulrosen/abcjs" >abcjs</a>, which renders the ABC in musical notation and generates MIDI sound playback (full functionality only on Chromium / Chrome browser). Click the Edit button to show the ABC notation, and try modifying the Epic Music!</p> <!--<div id="print-abc"></div>--> <script src="https://evanwill.github.io/_drafts/js/butler-epics.js"></script> <script type="text/javascript"> /* create lines array */ var lines = text.split(/[.!?]/); // abcChar = [ abcdefgz,' ]; // v 1, remove non-abc char // encounter k = key change 'K:a' next valid key // encounter m = meter change, M: next letter values // v 2, map alphabet to octaves /* set soundfonts location */ window.ABCJS.midi.soundfontUrl = "https://evanwill.github.io/_drafts/assets/soundfont/"; var reel var line; var abc = []; var notesArray = []; var leng = "L: 1/4"; var key = ["K:A", "K:Am", "K:B", "K:Bb", "K:Bm", "K:C", "K:D", "K:Dm", "K:E", "K:Em", "K:F", "K:G", "K:Gm"]; var meter = [ "M:2/2", "M:2/4", "M:3/4", "M:4/4", "M:6/8"]; /* UI functions */ function showRef() { document.getElementById("quickref").style.display = (document.getElementById("quickref").style.display === "block") ? "none" : "block"; } function showEdit() { document.getElementById("abc-text").style.display = (document.getElementById("abc-text").style.display === "block") ? "none" : "block"; } /* create abc */ function createAbc() { var i; abc = ["X: 1"]; /* shuffle data */ /* select random interval? */ var l = Math.floor(Math.random() * lines.length); line = lines[l]; /* create title */ var title = "T: Epic Music " + l.toString(); abc.push(title); /* create source */ abc.push("S: Epic Music v1, https://evanwill.github.io/_drafts/notes/epic-music.html"); /* add line, wrap to score size */ var words = "W:" + line; words = words.match(/.{1,75}(\s|$)/g).join('\nW: '); abc.push(words); /* create meter */ var m = Math.floor(Math.random() * meter.length); abc.push(meter[m]); /* create length */ abc.push(leng); /* create key */ var k = Math.floor(Math.random() * key.length); abc.push(key[k]); /* create notes */ var tune = line.match(/[ABCDEFGabcdefgz,']+/g).join(' ').replace(/(\s*,)/g,","); while (tune[0] == ",") { tune = tune.slice(1); } abc.push(tune); abc[abc.length-1] = abc[abc.length-1] + "|"; reel = abc.join("\n"); } function initEditor() { new ABCJS.Editor("abc-text", { paper_id: "notation", generate_midi: true, midi_id:"play", midi_download_id: "midi-download", generate_warnings: true, warnings_id:"warnings", midi_options: { generateDownload: true } }); } /* function printAbc() { var currentAbc = document.getElementById('abc-text').value; new ABCJS.renderAbc("print-abc", currentAbc); document.getElementById("no-print").style.display = "none"; window.print(); document.getElementById("no-print").style.display = "block"; document.getElementById("print-abc").innerHTML = ''; } */ function loadAbc() { createAbc(); document.getElementById("abc-text").value = reel; initEditor(); } /* start up */ window.addEventListener("load", loadAbc, false); </script> Sat, 02 Sep 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/epic-music.html https://evanwill.github.io/_drafts/notes/epic-music.html Brand New Reel! <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> <link rel="stylesheet" href="https://evanwill.github.io/_drafts/css/abcmusic.css"> <script src="https://evanwill.github.io/_drafts/js/abcjs_editor_midi_3.1.2-min.js" type="text/javascript"></script> <div id="playground"> <div id="notation" class="abc-rendered"></div> <div id="play"></div> <div id="warnings" class="abc-warnings"></div> <textarea name="abc" id="abc-text" class="abc-text" rows="14"></textarea> <button type="button" class="buttons" onclick="loadAbc();">Brand New Reel!</button> <button type="button" class="buttons" onclick="showEdit();">Edit</button> <!--<button type="button" onclick="printAbc();">Print</button>--> <button type="button" class="buttons" id="ref" onclick="showRef();">ABC Ref</button> <button type="button" class="buttons" id="midi-download"></button> <br> <div id="quickref"> <p><a href="https://en.wikipedia.org/wiki/ABC_notation" target="_blank" rel="noopener">ABC notation</a> is a shorthand standard for representing music, commonly used to record and share traditional folk tunes. Each tune has a header and some notes.</p> <p>Common header elements:</p> <ul> <li><code class="highlighter-rouge">X:</code> index number, required in some software [e.g. <code class="highlighter-rouge">X:1</code>]</li> <li><code class="highlighter-rouge">T:</code> title [e.g <code class="highlighter-rouge">T: Happy Birthday</code>]</li> <li><code class="highlighter-rouge">M:</code> meter, required [e.g. <code class="highlighter-rouge">M:C</code>, <code class="highlighter-rouge">M:4/4</code>, <code class="highlighter-rouge">M:3/4</code>]</li> <li><code class="highlighter-rouge">L:</code> default note length [e.g. <code class="highlighter-rouge">L:1/2</code>, <code class="highlighter-rouge">L:1/4</code>, <code class="highlighter-rouge">L:1/8</code>]</li> <li><code class="highlighter-rouge">Q:</code> tempo [e.g. <code class="highlighter-rouge">Q:120</code>, <code class="highlighter-rouge">Q:1/8=120</code>, <code class="highlighter-rouge">Q:1/4=60</code>]</li> <li><code class="highlighter-rouge">K:</code> key signature, required [e.g. <code class="highlighter-rouge">K:G</code>, <code class="highlighter-rouge">K:Gm</code>]</li> <li><code class="highlighter-rouge">V:</code> voice, can set the clef [e.g. <code class="highlighter-rouge">V:1 name=Violin</code>, <code class="highlighter-rouge">V:2 name=Cello clef=bass</code>]</li> </ul> <p>Common notation elements:</p> <ul> <li>bottom octave <code class="highlighter-rouge">CDEFGAB</code>, top octave <code class="highlighter-rouge">cdefgab</code> [e.g. <code class="highlighter-rouge">C</code> = middle C]</li> <li><code class="highlighter-rouge">z</code> rest</li> <li><code class="highlighter-rouge">,</code> down an octave, <code class="highlighter-rouge">'</code> up an octave [e.g. <code class="highlighter-rouge">C,</code> or <code class="highlighter-rouge">c'</code>]</li> <li><code class="highlighter-rouge">^</code> sharps, <code class="highlighter-rouge">_</code> flats [e.g. <code class="highlighter-rouge">^c</code> or <code class="highlighter-rouge">_c</code>]</li> <li>make note longer by multiplying number, or shorter by a <code class="highlighter-rouge">/</code> dividing number [e.g. <code class="highlighter-rouge">a2</code> or <code class="highlighter-rouge">a/2</code>]</li> <li>notes separated by spaces will not have beams, those together will [e.g. <code class="highlighter-rouge">a b c</code> versus <code class="highlighter-rouge">abc</code>]</li> <li><code class="highlighter-rouge">|</code> barline, <code class="highlighter-rouge">|]</code> double bar, <code class="highlighter-rouge">|:</code> repeats <code class="highlighter-rouge">:|</code></li> </ul> </div> </div> <p>Brand New Reel remixes the titles and tunes of about 460 traditional reels. The music data is derived from the <a href="http://abc.sourceforge.net/NMD/" target="_blank" rel="noopener">ABC version of the Nottingham Music Database</a>. Because <a href="https://en.wikipedia.org/wiki/ABC_notation" target="_blank" rel="noopener">ABC notation</a> is a simple plain text format, it is ideal for sharing music on the web--and for manipulating with code. The editor is created using <a href="https://github.com/paulrosen/abcjs" >abcjs</a>, which renders the ABC in musical notation and generates MIDI sound playback (full functionality only on Chromium / Chrome browser). Click the Edit button to show the ABC notation, and try modifying the Brand New Reel!</p> <!--<div id="print-abc"></div>--> <script src="https://evanwill.github.io/_drafts/js/reels-data.js"></script> <script type="text/javascript"> /* set soundfonts location */ window.ABCJS.midi.soundfontUrl = "https://evanwill.github.io/_drafts/assets/soundfont/"; var reel; var abc = []; var notesArray = []; var titleArray = []; /* Fisher-Yates shuffle https://bost.ocks.org/mike/shuffle/ */ function shuffle(array) { var m = array.length, t, i; while (m) { i = Math.floor(Math.random() * m--); t = array[m]; array[m] = array[i]; array[i] = t; } return array; } function mixData() { notesArray = notes.split("|"); titleArray = titles.split(" "); shuffle(notesArray); shuffle(titleArray); } function showRef() { document.getElementById("quickref").style.display = (document.getElementById("quickref").style.display === "block") ? "none" : "block"; } function showEdit() { document.getElementById("abc-text").style.display = (document.getElementById("abc-text").style.display === "block") ? "none" : "block"; } function createAbc() { var i; abc = ["X: 1"]; /* shuffle data */ if (notesArray.length == 0 || titleArray.length == 0) { mixData(); } /* create title */ var t = Math.floor(Math.random() * 5) + 1; var title = ["T:"]; for (i = 0; i < t; i++) { title.push(titleArray.pop()); } abc.push(title.join(" ")); /* create source */ abc.push("S: Brand New Reel, https://evanwill.github.io/_drafts/notes/reel.html") /* create meter */ var m = Math.floor(Math.random() * meter.length); abc.push(meter[m]); /* create length */ abc.push(leng); /* create key */ var k = Math.floor(Math.random() * key.length); abc.push(key[k]); /* create notes */ var bars = (Math.floor(Math.random() * 2) + 4); var z; for (i=0; i < 4; i++) { var tune = []; for (z = 0; z < bars; z++) { tune.push(notesArray.pop()); } tune.push(""); abc.push(tune.join("|")); } abc[abc.length-1] = abc[abc.length-1] + "|"; reel = abc.join("\n"); } function initEditor() { new ABCJS.Editor("abc-text", { paper_id: "notation", generate_midi: true, midi_id:"play", midi_download_id: "midi-download", generate_warnings: true, warnings_id:"warnings", midi_options: { generateDownload: true } }); } /* function printAbc() { var currentAbc = document.getElementById('abc-text').value; new ABCJS.renderAbc("print-abc", currentAbc); document.getElementById("no-print").style.display = "none"; window.print(); document.getElementById("no-print").style.display = "block"; document.getElementById("print-abc").innerHTML = ''; } */ function loadAbc() { createAbc(); document.getElementById("abc-text").value = reel; initEditor(); } window.addEventListener("load", loadAbc, false); </script> Thu, 24 Aug 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/reel.html https://evanwill.github.io/_drafts/notes/reel.html Open Music Theory Intro <blockquote> <p>Mini intro to working with OER “text book”</p> </blockquote> <p>Welcome to <a href="https://smbutterfield.github.io/ibmt17-18/">Inquiry-Based Music Theory</a>, OER Text Book!</p> <p>What is it?</p> <ul> <li>part of the <a href="https://open.lib.uidaho.edu/">Think Open fellowship</a></li> <li>an <a href="https://en.wikipedia.org/wiki/Open_educational_resources">OER</a></li> <li>a fork (i.e. a new adaptation) of Kris Shaffer, Bryn Hughes, and Brian Moseley, <a href="http://openmusictheory.com/"><em>Open Music Theory</em></a>, <a href="http://www.digitalpedagogylab.com/hybridped/">Hybrid Pedagogy</a> 2014+ (<a href="https://github.com/openmusictheory/openmusictheory.github.io">github repository</a>).</li> <li>a git <a href="https://github.com/smbutterfield/ibmt17-18">repository</a> hosted on <a href="https://github.com/">GitHub</a>. [more on Git and GitHub: <a href="https://uidaholib.github.io/get-git/">Get Git</a>, <a href="https://evanwill.github.io/_drafts/notes/git-collaboration.html">Git for collaboration</a>]</li> <li>a website build using <a href="http://jekyllrb.com/">Jekyll</a> static site generator, hosted by GitHub Pages. [ more on gh-pages: <a href="https://evanwill.github.io/go-go-ghpages/">go-go gh-pages</a> ]</li> <li>content written in <a href="https://daringfireball.net/projects/markdown/">Markdown</a>, a simple mark up language written in <a href="https://en.wikipedia.org/wiki/Plain_text">plain text</a>. [more on Markdown: <a href="https://evanwill.github.io/_drafts/notes/markdown-minute.html">markdown in a minute</a>]</li> </ul> <p>Activities:</p> <ul> <li>GitHub account set up</li> <li>practice repository</li> <li>practice markdown editing</li> <li>“commit”</li> <li>fork</li> </ul> <p>Workflow?</p> Tue, 15 Aug 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/openmusic.html https://evanwill.github.io/_drafts/notes/openmusic.html Epic Tweets <style> #tweet-box { border: 1px solid #e6ecf0; padding: 5px; } #profile-img { border-radius: 100%; vertical-align: middle; float: left; } #tweet { margin-left: 60px; } #name { color: #14171a; font-weight: bold; } #handle { color: #657786; } </style> <div id="tweet-box"> <img id="profile-img" src="https://evanwill.github.io/_drafts/assets/Bust_Homer_BM.jpg" alt="Homer profile image" > <div id="tweet"> <span id="name">Homer </span> <span id="handle">@realEpicAuthor</span> <div id="epic" ></div> </div> </div> <br> <p><button id="new" class="buttons">new epic tweet</button></p> <p>Epic Tweets remixes Samuel Butler's translations of the Iliad and Odyssey into 140 character outbursts.</p> <script src="https://evanwill.github.io/_drafts/js/butler-epics.js"></script> <script> var poem = document.getElementById("epic"); /* Fisher-Yates shuffle https://bost.ocks.org/mike/shuffle/ */ function shuffle(array) { var m = array.length, t, i; while (m) { i = Math.floor(Math.random() * m--); t = array[m]; array[m] = array[i]; array[i] = t; } return array; } var lines = text.split(/[.!?]/); var fronts = []; var ends = []; function typeSort(x) { var parts = x.split(/[,;]/); fronts.push(parts[0]); parts.slice(1).forEach(function(y) { ends.push(y); }); } lines.forEach(typeSort); shuffle(fronts); shuffle(ends); function makeTweet() { var i; var epicTweet = []; var next = []; while (poem.hasChildNodes()) { poem.removeChild(poem.lastChild); } epicTweet.push(fronts.pop()); for (i = 0; i < 5; i++) { var line = ends.pop(); if ( epicTweet.join(" ").length + line.length < 140) { epicTweet.push(line); } } poem.innerHTML = epicTweet.join("<br>").toUpperCase() + "!</p>"; } makeTweet(); document.getElementById("new").onclick = function () { makeTweet(); }; </script> Wed, 02 Aug 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/epic-tweet.html https://evanwill.github.io/_drafts/notes/epic-tweet.html Epic Episode <div id="epic"></div> <br> <p><button id="new" class="buttons">new episode</button></p> <p>Epic Episode remixes Samuel Butler's translations of the Iliad and Odyssey.</p> <script src="https://evanwill.github.io/_drafts/js/butler-epics.js"></script> <script> var poem = document.getElementById("epic"); /* Fisher-Yates shuffle https://bost.ocks.org/mike/shuffle/ */ function shuffle(array) { var m = array.length, t, i; while (m) { i = Math.floor(Math.random() * m--); t = array[m]; array[m] = array[i]; array[i] = t; } return array; } function randomInterval(min,max) { return Math.floor(Math.random()*(max-min+1)+min); } /* // version 1 var lines = text.split(/[.!?;]/); function makeEpic(array) { var i; var line; shuffle(array); while (poem.hasChildNodes()) { poem.removeChild(poem.lastChild); } for (i = 0; i < 5; i++) { line = array[i] + ".<br>"; poem.innerHTML += line; } } makeEpic(lines); */ /* // version 2 var lines = text.split(/[.!?;]/); function comaSort(x) { if ( x.includes(",") ) { clines.push(x); } else { nclines.push(x); } } function comaSplit(x) { var parts = x.split(","); ends.push(parts.pop()); fronts.push(parts[0]); parts.slice(1).forEach(function(y) { middles.push(y); }); } var clines = []; var nclines = []; var fronts = []; var middles = []; var ends = []; lines.forEach(comaSort); clines.forEach(comaSplit); */ /* function titleCase(string) { return string.charAt(0).toUpperCase() + string.slice(1); }function titleCase(string) { return string.charAt(0).toUpperCase() + string.slice(1); } */ /* // version 3 var lines = text.split(/[.!?;,]/); function makeEpic(array) { var i; var epicLength = randomInterval(4,10); var epicEpisode = []; shuffle(array); while (poem.hasChildNodes()) { poem.removeChild(poem.lastChild); } for (i = 0; i < epicLength; i++) { var line = []; var lineLength = randomInterval(1,5); for (l = 0; l < lineLength; l++) { line.push(array.pop()); } epicEpisode.push( line.join(", ") + "." ); } poem.innerHTML = epicEpisode.join("<br>"); } makeEpic(lines); */ var lines = text.split(/[.!?]/); var fronts = []; var ends = []; function typeSort(x) { var parts = x.split(/[,;]/); fronts.push(parts[0]); parts.slice(1).forEach(function(y) { ends.push(y); }); } lines.forEach(typeSort); shuffle(fronts); shuffle(ends); function makeEpic() { var i; var chapter = randomInterval(1,fronts.length/5); var epicLength = randomInterval(3,10); var epicEpisode = []; while (poem.hasChildNodes()) { poem.removeChild(poem.lastChild); } for (i = 0; i < epicLength; i++) { var line = []; var lineLength = randomInterval(0,5); line.push(fronts.pop()); for (l = 0; l < lineLength; l++) { line.push(ends.pop()); } epicEpisode.push( line.join(", ") + "." ); } poem.innerHTML = "<h2>Chapter " + chapter + "</h2> <p>" + epicEpisode.join("<br>") + "</p>"; } makeEpic(); document.getElementById("new").onclick = function () { makeEpic(); }; </script> Wed, 05 Jul 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/epic.html https://evanwill.github.io/_drafts/notes/epic.html Get started with RetroPie <p><a href="https://retropie.org.uk/">RetroPie</a> is a fun and handy linux distribution that turns your raspberry pi into a console game emulator. It is intended to get emulators and controllers setup with minimum configuration and hassle. Perfect for your living room, the graphical interface is is designed to be navigated with game pad controllers, so you don’t need a boring old keyboard and mouse to use it!</p> <p>Check the <a href="https://retropie.org.uk/docs/First-Installation/">official installation guide</a> for full details, but here is my quick reference summary:</p> <h2 id="hardware">Hardware</h2> <p>Suggested:</p> <ul> <li>a Raspberry Pi 3 (from <a href="http://www.mcmelectronics.com/product/83-17300">MCM</a>, official distributor in US, also available many other places)</li> <li>an micro SD card &gt; 8GB (the RetroPie image is 2GB+, but you want plenty of room to add games)</li> <li>some game pads, <a href="https://www.amazon.com/dp/B01KJS4ILY/ref=cm_sw_r_cp_ep_dp_09aIzb6JAXW5P">USB</a> or <a href="https://www.amazon.com/dp/B014QP2H1E/ref=cm_sw_r_cp_ep_dp_58aIzbS183WB8">bluetooth</a></li> </ul> <h2 id="burn-sd">Burn SD</h2> <ol> <li>Download the <a href="https://retropie.org.uk/download/">RetroPie image</a> for your RPI type (it will be an <code class="language-plaintext highlighter-rouge">img.gz</code> file, you do NOT need to extract it).</li> <li>Download and install <a href="https://www.balena.io/etcher/">Etcher</a> if you don’t have it.</li> <li>Insert your SD card into your computer and start up Etcher.</li> <li>Select the RetroPie image (e.g. <code class="language-plaintext highlighter-rouge">retropie-4.4-rpi2_rpi3.img.gz</code>), your SD card, and click “Flash!”</li> </ol> <p><em>For more about burning SD images, see <a href="https://evanwill.github.io/_drafts/notes/burn-iso.html">Burn SD or USB</a> note.</em></p> <h2 id="start-retropie">Start RetroPie</h2> <ol> <li>Put your SD into the RPI, plug the HDMI into a TV, and connect USB controllers.</li> <li>Plug in the RPI and watch it boot. It will need go through some initial set up, such as expanding the file system–so this is a slow process, but only happens this once.</li> <li>Follow on screen instructions to configure game pads. Tip: if configuration asks for more buttons than your device has, hold down one of the buttons to skip.</li> </ol> <p>After configuring the pads, you will see a menu, but no games will show up, because you haven’t added any yet…</p> <p><em>(personally I don’t bother connecting to wifi, but you could)</em></p> <h2 id="add-roms">Add ROMS</h2> <p>There are a few methods to get ROMs on your RetroPie, but the most foolproof way seems via their USB method:</p> <ol> <li>Get a USB drive with enough space to hold all your ROMs, preferably one that has a LED indicator light.</li> <li>Format the USB stick.</li> <li>Create a single folder named <code class="language-plaintext highlighter-rouge">retropie</code> on the USB stick.</li> <li>Plug the USB stick into your RetroPie, watch the busy indicator light and wait for it to stop flashing.</li> <li>Unplug the USB stick from RetroPie (no need to “eject”, just pull it out), and plug it back into your computer.</li> <li>Copy your ROMs into the correct folders in the directory structure set up by the RetroPie (i.e. inside <code class="language-plaintext highlighter-rouge">retropie/roms</code>… keep in mind the folders are named after the international model names, so don’t necessarily match USA console names.)</li> <li>Plug the USB stick back into the RetroPie, watch the indicator light and wait for it to stop flashing–this may take awhile depending on how many ROMs you are adding!</li> <li>Restart the RetroPie via the menu system (access by clicking “Select + Start” on a game pad. Do not shut down your RPI by simply unplugging if possible, this has the potential to permanently corrupt your SD. When you give the shutdown command, wait for the screen to go blank and the green light on the RPI to stop blinking.)</li> </ol> <p>However, my favorite <em>fast</em> method is to just pull out the SD and plug it into a linux computer. Then head into the <code class="language-plaintext highlighter-rouge">/retropie/home/pi/RetroPie/roms</code> directory, and copy roms into the correct folders. Unmount from your computer, and plug back into Pi.</p> <h2 id="play">Play!</h2> <p>You should be good to go!</p> <p>General menu controls:</p> <ul> <li>A = select</li> <li>B = back</li> <li>Start = menu</li> <li>Start + Select (in game) = exit back to main menu</li> <li>Select + B (in game) = reset</li> </ul> <p>To shut down: “Start” (for main menu) &gt; “Quit” &gt; “Shutdown System”</p> Mon, 26 Jun 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/retropie.html https://evanwill.github.io/_drafts/notes/retropie.html Sonnet Thing <div id="poem"></div> <br> <p> <button id="new" class="buttons">new poem</button> </p> <p> Sonnet Thing uses JS to take the text from <a href="http://www.gutenberg.org/ebooks/1105">Shakespeare's Sonnets</a>, chop each line in half, shuffle it all, and spit out a new poem. Each "sonnet" has 14 lines, reconstituted from halves. White space and blank lines are included for the sake of variety. </p> <script> var poem = document.getElementById("poem"); var text = `From fairest creatures we desire increase, That thereby beauty's rose might never die, But as the riper should by time decease, His tender heir might bear his memory: But thou contracted to thine own bright eyes, Feed'st thy light's flame with self-substantial fuel, Making a famine where abundance lies, Thy self thy foe, to thy sweet self too cruel: Thou that art now the world's fresh ornament, And only herald to the gaudy spring, Within thine own bud buriest thy content, And tender churl mak'st waste in niggarding: Pity the world, or else this glutton be, To eat the world's due, by the grave and thee. When forty winters shall besiege thy brow, And dig deep trenches in thy beauty's field, Thy youth's proud livery so gazed on now, Will be a tattered weed of small worth held: Then being asked, where all thy beauty lies, Where all the treasure of thy lusty days; To say within thine own deep sunken eyes, Were an all-eating shame, and thriftless praise. How much more praise deserved thy beauty's use, If thou couldst answer 'This fair child of mine Shall sum my count, and make my old excuse' Proving his beauty by succession thine. This were to be new made when thou art old, And see thy blood warm when thou feel'st it cold. Look in thy glass and tell the face thou viewest, Now is the time that face should form another, Whose fresh repair if now thou not renewest, Thou dost beguile the world, unbless some mother. For where is she so fair whose uneared womb Disdains the tillage of thy husbandry? Or who is he so fond will be the tomb, Of his self-love to stop posterity? Thou art thy mother's glass and she in thee Calls back the lovely April of her prime, So thou through windows of thine age shalt see, Despite of wrinkles this thy golden time. But if thou live remembered not to be, Die single and thine image dies with thee. Unthrifty loveliness why dost thou spend, Upon thy self thy beauty's legacy? Nature's bequest gives nothing but doth lend, And being frank she lends to those are free: Then beauteous niggard why dost thou abuse, The bounteous largess given thee to give? Profitless usurer why dost thou use So great a sum of sums yet canst not live? For having traffic with thy self alone, Thou of thy self thy sweet self dost deceive, Then how when nature calls thee to be gone, What acceptable audit canst thou leave? Thy unused beauty must be tombed with thee, Which used lives th' executor to be. Those hours that with gentle work did frame The lovely gaze where every eye doth dwell Will play the tyrants to the very same, And that unfair which fairly doth excel: For never-resting time leads summer on To hideous winter and confounds him there, Sap checked with frost and lusty leaves quite gone, Beauty o'er-snowed and bareness every where: Then were not summer's distillation left A liquid prisoner pent in walls of glass, Beauty's effect with beauty were bereft, Nor it nor no remembrance what it was. But flowers distilled though they with winter meet, Leese but their show, their substance still lives sweet. Then let not winter's ragged hand deface, In thee thy summer ere thou be distilled: Make sweet some vial; treasure thou some place, With beauty's treasure ere it be self-killed: That use is not forbidden usury, Which happies those that pay the willing loan; That's for thy self to breed another thee, Or ten times happier be it ten for one, Ten times thy self were happier than thou art, If ten of thine ten times refigured thee: Then what could death do if thou shouldst depart, Leaving thee living in posterity? Be not self-willed for thou art much too fair, To be death's conquest and make worms thine heir. Lo in the orient when the gracious light Lifts up his burning head, each under eye Doth homage to his new-appearing sight, Serving with looks his sacred majesty, And having climbed the steep-up heavenly hill, Resembling strong youth in his middle age, Yet mortal looks adore his beauty still, Attending on his golden pilgrimage: But when from highmost pitch with weary car, Like feeble age he reeleth from the day, The eyes (fore duteous) now converted are From his low tract and look another way: So thou, thy self out-going in thy noon: Unlooked on diest unless thou get a son. Music to hear, why hear'st thou music sadly? Sweets with sweets war not, joy delights in joy: Why lov'st thou that which thou receiv'st not gladly, Or else receiv'st with pleasure thine annoy? If the true concord of well-tuned sounds, By unions married do offend thine ear, They do but sweetly chide thee, who confounds In singleness the parts that thou shouldst bear: Mark how one string sweet husband to another, Strikes each in each by mutual ordering; Resembling sire, and child, and happy mother, Who all in one, one pleasing note do sing: Whose speechless song being many, seeming one, Sings this to thee, 'Thou single wilt prove none'. Is it for fear to wet a widow's eye, That thou consum'st thy self in single life? Ah, if thou issueless shalt hap to die, The world will wail thee like a makeless wife, The world will be thy widow and still weep, That thou no form of thee hast left behind, When every private widow well may keep, By children's eyes, her husband's shape in mind: Look what an unthrift in the world doth spend Shifts but his place, for still the world enjoys it; But beauty's waste hath in the world an end, And kept unused the user so destroys it: No love toward others in that bosom sits That on himself such murd'rous shame commits. For shame deny that thou bear'st love to any Who for thy self art so unprovident. Grant if thou wilt, thou art beloved of many, But that thou none lov'st is most evident: For thou art so possessed with murd'rous hate, That 'gainst thy self thou stick'st not to conspire, Seeking that beauteous roof to ruinate Which to repair should be thy chief desire: O change thy thought, that I may change my mind, Shall hate be fairer lodged than gentle love? Be as thy presence is gracious and kind, Or to thy self at least kind-hearted prove, Make thee another self for love of me, That beauty still may live in thine or thee. As fast as thou shalt wane so fast thou grow'st, In one of thine, from that which thou departest, And that fresh blood which youngly thou bestow'st, Thou mayst call thine, when thou from youth convertest, Herein lives wisdom, beauty, and increase, Without this folly, age, and cold decay, If all were minded so, the times should cease, And threescore year would make the world away: Let those whom nature hath not made for store, Harsh, featureless, and rude, barrenly perish: Look whom she best endowed, she gave thee more; Which bounteous gift thou shouldst in bounty cherish: She carved thee for her seal, and meant thereby, Thou shouldst print more, not let that copy die. When I do count the clock that tells the time, And see the brave day sunk in hideous night, When I behold the violet past prime, And sable curls all silvered o'er with white: When lofty trees I see barren of leaves, Which erst from heat did canopy the herd And summer's green all girded up in sheaves Borne on the bier with white and bristly beard: Then of thy beauty do I question make That thou among the wastes of time must go, Since sweets and beauties do themselves forsake, And die as fast as they see others grow, And nothing 'gainst Time's scythe can make defence Save breed to brave him, when he takes thee hence. O that you were your self, but love you are No longer yours, than you your self here live, Against this coming end you should prepare, And your sweet semblance to some other give. So should that beauty which you hold in lease Find no determination, then you were Your self again after your self's decease, When your sweet issue your sweet form should bear. Who lets so fair a house fall to decay, Which husbandry in honour might uphold, Against the stormy gusts of winter's day And barren rage of death's eternal cold? O none but unthrifts, dear my love you know, You had a father, let your son say so. Not from the stars do I my judgement pluck, And yet methinks I have astronomy, But not to tell of good, or evil luck, Of plagues, of dearths, or seasons' quality, Nor can I fortune to brief minutes tell; Pointing to each his thunder, rain and wind, Or say with princes if it shall go well By oft predict that I in heaven find. But from thine eyes my knowledge I derive, And constant stars in them I read such art As truth and beauty shall together thrive If from thy self, to store thou wouldst convert: Or else of thee this I prognosticate, Thy end is truth's and beauty's doom and date. When I consider every thing that grows Holds in perfection but a little moment. That this huge stage presenteth nought but shows Whereon the stars in secret influence comment. When I perceive that men as plants increase, Cheered and checked even by the self-same sky: Vaunt in their youthful sap, at height decrease, And wear their brave state out of memory. Then the conceit of this inconstant stay, Sets you most rich in youth before my sight, Where wasteful time debateth with decay To change your day of youth to sullied night, And all in war with Time for love of you, As he takes from you, I engraft you new. But wherefore do not you a mightier way Make war upon this bloody tyrant Time? And fortify your self in your decay With means more blessed than my barren rhyme? Now stand you on the top of happy hours, And many maiden gardens yet unset, With virtuous wish would bear you living flowers, Much liker than your painted counterfeit: So should the lines of life that life repair Which this (Time's pencil) or my pupil pen Neither in inward worth nor outward fair Can make you live your self in eyes of men. To give away your self, keeps your self still, And you must live drawn by your own sweet skill. Who will believe my verse in time to come If it were filled with your most high deserts? Though yet heaven knows it is but as a tomb Which hides your life, and shows not half your parts: If I could write the beauty of your eyes, And in fresh numbers number all your graces, The age to come would say this poet lies, Such heavenly touches ne'er touched earthly faces. So should my papers (yellowed with their age) Be scorned, like old men of less truth than tongue, And your true rights be termed a poet's rage, And stretched metre of an antique song. But were some child of yours alive that time, You should live twice in it, and in my rhyme. Shall I compare thee to a summer's day? Thou art more lovely and more temperate: Rough winds do shake the darling buds of May, And summer's lease hath all too short a date: Sometime too hot the eye of heaven shines, And often is his gold complexion dimmed, And every fair from fair sometime declines, By chance, or nature's changing course untrimmed: But thy eternal summer shall not fade, Nor lose possession of that fair thou ow'st, Nor shall death brag thou wand'rest in his shade, When in eternal lines to time thou grow'st, So long as men can breathe or eyes can see, So long lives this, and this gives life to thee. Devouring Time blunt thou the lion's paws, And make the earth devour her own sweet brood, Pluck the keen teeth from the fierce tiger's jaws, And burn the long-lived phoenix, in her blood, Make glad and sorry seasons as thou fleet'st, And do whate'er thou wilt swift-footed Time To the wide world and all her fading sweets: But I forbid thee one most heinous crime, O carve not with thy hours my love's fair brow, Nor draw no lines there with thine antique pen, Him in thy course untainted do allow, For beauty's pattern to succeeding men. Yet do thy worst old Time: despite thy wrong, My love shall in my verse ever live young. A woman's face with nature's own hand painted, Hast thou the master mistress of my passion, A woman's gentle heart but not acquainted With shifting change as is false women's fashion, An eye more bright than theirs, less false in rolling: Gilding the object whereupon it gazeth, A man in hue all hues in his controlling, Which steals men's eyes and women's souls amazeth. And for a woman wert thou first created, Till nature as she wrought thee fell a-doting, And by addition me of thee defeated, By adding one thing to my purpose nothing. But since she pricked thee out for women's pleasure, Mine be thy love and thy love's use their treasure. So is it not with me as with that muse, Stirred by a painted beauty to his verse, Who heaven it self for ornament doth use, And every fair with his fair doth rehearse, Making a couplement of proud compare With sun and moon, with earth and sea's rich gems: With April's first-born flowers and all things rare, That heaven's air in this huge rondure hems. O let me true in love but truly write, And then believe me, my love is as fair, As any mother's child, though not so bright As those gold candles fixed in heaven's air: Let them say more that like of hearsay well, I will not praise that purpose not to sell. My glass shall not persuade me I am old, So long as youth and thou are of one date, But when in thee time's furrows I behold, Then look I death my days should expiate. For all that beauty that doth cover thee, Is but the seemly raiment of my heart, Which in thy breast doth live, as thine in me, How can I then be elder than thou art? O therefore love be of thyself so wary, As I not for my self, but for thee will, Bearing thy heart which I will keep so chary As tender nurse her babe from faring ill. Presume not on thy heart when mine is slain, Thou gav'st me thine not to give back again. As an unperfect actor on the stage, Who with his fear is put beside his part, Or some fierce thing replete with too much rage, Whose strength's abundance weakens his own heart; So I for fear of trust, forget to say, The perfect ceremony of love's rite, And in mine own love's strength seem to decay, O'ercharged with burthen of mine own love's might: O let my looks be then the eloquence, And dumb presagers of my speaking breast, Who plead for love, and look for recompense, More than that tongue that more hath more expressed. O learn to read what silent love hath writ, To hear with eyes belongs to love's fine wit. Mine eye hath played the painter and hath stelled, Thy beauty's form in table of my heart, My body is the frame wherein 'tis held, And perspective it is best painter's art. For through the painter must you see his skill, To find where your true image pictured lies, Which in my bosom's shop is hanging still, That hath his windows glazed with thine eyes: Now see what good turns eyes for eyes have done, Mine eyes have drawn thy shape, and thine for me Are windows to my breast, where-through the sun Delights to peep, to gaze therein on thee; Yet eyes this cunning want to grace their art, They draw but what they see, know not the heart. Let those who are in favour with their stars, Of public honour and proud titles boast, Whilst I whom fortune of such triumph bars Unlooked for joy in that I honour most; Great princes' favourites their fair leaves spread, But as the marigold at the sun's eye, And in themselves their pride lies buried, For at a frown they in their glory die. The painful warrior famoused for fight, After a thousand victories once foiled, Is from the book of honour razed quite, And all the rest forgot for which he toiled: Then happy I that love and am beloved Where I may not remove nor be removed. Lord of my love, to whom in vassalage Thy merit hath my duty strongly knit; To thee I send this written embassage To witness duty, not to show my wit. Duty so great, which wit so poor as mine May make seem bare, in wanting words to show it; But that I hope some good conceit of thine In thy soul's thought (all naked) will bestow it: Till whatsoever star that guides my moving, Points on me graciously with fair aspect, And puts apparel on my tattered loving, To show me worthy of thy sweet respect, Then may I dare to boast how I do love thee, Till then, not show my head where thou mayst prove me. Weary with toil, I haste me to my bed, The dear respose for limbs with travel tired, But then begins a journey in my head To work my mind, when body's work's expired. For then my thoughts (from far where I abide) Intend a zealous pilgrimage to thee, And keep my drooping eyelids open wide, Looking on darkness which the blind do see. Save that my soul's imaginary sight Presents thy shadow to my sightless view, Which like a jewel (hung in ghastly night) Makes black night beauteous, and her old face new. Lo thus by day my limbs, by night my mind, For thee, and for my self, no quiet find. How can I then return in happy plight That am debarred the benefit of rest? When day's oppression is not eased by night, But day by night and night by day oppressed. And each (though enemies to either's reign) Do in consent shake hands to torture me, The one by toil, the other to complain How far I toil, still farther off from thee. I tell the day to please him thou art bright, And dost him grace when clouds do blot the heaven: So flatter I the swart-complexioned night, When sparkling stars twire not thou gild'st the even. But day doth daily draw my sorrows longer, And night doth nightly make grief's length seem stronger When in disgrace with Fortune and men's eyes, I all alone beweep my outcast state, And trouble deaf heaven with my bootless cries, And look upon my self and curse my fate, Wishing me like to one more rich in hope, Featured like him, like him with friends possessed, Desiring this man's art, and that man's scope, With what I most enjoy contented least, Yet in these thoughts my self almost despising, Haply I think on thee, and then my state, (Like to the lark at break of day arising From sullen earth) sings hymns at heaven's gate, For thy sweet love remembered such wealth brings, That then I scorn to change my state with kings. When to the sessions of sweet silent thought, I summon up remembrance of things past, I sigh the lack of many a thing I sought, And with old woes new wail my dear time's waste: Then can I drown an eye (unused to flow) For precious friends hid in death's dateless night, And weep afresh love's long since cancelled woe, And moan th' expense of many a vanished sight. Then can I grieve at grievances foregone, And heavily from woe to woe tell o'er The sad account of fore-bemoaned moan, Which I new pay as if not paid before. But if the while I think on thee (dear friend) All losses are restored, and sorrows end. Thy bosom is endeared with all hearts, Which I by lacking have supposed dead, And there reigns love and all love's loving parts, And all those friends which I thought buried. How many a holy and obsequious tear Hath dear religious love stol'n from mine eye, As interest of the dead, which now appear, But things removed that hidden in thee lie. Thou art the grave where buried love doth live, Hung with the trophies of my lovers gone, Who all their parts of me to thee did give, That due of many, now is thine alone. Their images I loved, I view in thee, And thou (all they) hast all the all of me. If thou survive my well-contented day, When that churl death my bones with dust shall cover And shalt by fortune once more re-survey These poor rude lines of thy deceased lover: Compare them with the bett'ring of the time, And though they be outstripped by every pen, Reserve them for my love, not for their rhyme, Exceeded by the height of happier men. O then vouchsafe me but this loving thought, 'Had my friend's Muse grown with this growing age, A dearer birth than this his love had brought To march in ranks of better equipage: But since he died and poets better prove, Theirs for their style I'll read, his for his love'. Full many a glorious morning have I seen, Flatter the mountain tops with sovereign eye, Kissing with golden face the meadows green; Gilding pale streams with heavenly alchemy: Anon permit the basest clouds to ride, With ugly rack on his celestial face, And from the forlorn world his visage hide Stealing unseen to west with this disgrace: Even so my sun one early morn did shine, With all triumphant splendour on my brow, But out alack, he was but one hour mine, The region cloud hath masked him from me now. Yet him for this, my love no whit disdaineth, Suns of the world may stain, when heaven's sun staineth. Why didst thou promise such a beauteous day, And make me travel forth without my cloak, To let base clouds o'ertake me in my way, Hiding thy brav'ry in their rotten smoke? 'Tis not enough that through the cloud thou break, To dry the rain on my storm-beaten face, For no man well of such a salve can speak, That heals the wound, and cures not the disgrace: Nor can thy shame give physic to my grief, Though thou repent, yet I have still the loss, Th' offender's sorrow lends but weak relief To him that bears the strong offence's cross. Ah but those tears are pearl which thy love sheds, And they are rich, and ransom all ill deeds. No more be grieved at that which thou hast done, Roses have thorns, and silver fountains mud, Clouds and eclipses stain both moon and sun, And loathsome canker lives in sweetest bud. All men make faults, and even I in this, Authorizing thy trespass with compare, My self corrupting salving thy amiss, Excusing thy sins more than thy sins are: For to thy sensual fault I bring in sense, Thy adverse party is thy advocate, And 'gainst my self a lawful plea commence: Such civil war is in my love and hate, That I an accessary needs must be, To that sweet thief which sourly robs from me. Let me confess that we two must be twain, Although our undivided loves are one: So shall those blots that do with me remain, Without thy help, by me be borne alone. In our two loves there is but one respect, Though in our lives a separable spite, Which though it alter not love's sole effect, Yet doth it steal sweet hours from love's delight. I may not evermore acknowledge thee, Lest my bewailed guilt should do thee shame, Nor thou with public kindness honour me, Unless thou take that honour from thy name: But do not so, I love thee in such sort, As thou being mine, mine is thy good report. As a decrepit father takes delight, To see his active child do deeds of youth, So I, made lame by Fortune's dearest spite Take all my comfort of thy worth and truth. For whether beauty, birth, or wealth, or wit, Or any of these all, or all, or more Entitled in thy parts, do crowned sit, I make my love engrafted to this store: So then I am not lame, poor, nor despised, Whilst that this shadow doth such substance give, That I in thy abundance am sufficed, And by a part of all thy glory live: Look what is best, that best I wish in thee, This wish I have, then ten times happy me. How can my muse want subject to invent While thou dost breathe that pour'st into my verse, Thine own sweet argument, too excellent, For every vulgar paper to rehearse? O give thy self the thanks if aught in me, Worthy perusal stand against thy sight, For who's so dumb that cannot write to thee, When thou thy self dost give invention light? Be thou the tenth Muse, ten times more in worth Than those old nine which rhymers invocate, And he that calls on thee, let him bring forth Eternal numbers to outlive long date. If my slight muse do please these curious days, The pain be mine, but thine shall be the praise. O how thy worth with manners may I sing, When thou art all the better part of me? What can mine own praise to mine own self bring: And what is't but mine own when I praise thee? Even for this, let us divided live, And our dear love lose name of single one, That by this separation I may give: That due to thee which thou deserv'st alone: O absence what a torment wouldst thou prove, Were it not thy sour leisure gave sweet leave, To entertain the time with thoughts of love, Which time and thoughts so sweetly doth deceive. And that thou teachest how to make one twain, By praising him here who doth hence remain. Take all my loves, my love, yea take them all, What hast thou then more than thou hadst before? No love, my love, that thou mayst true love call, All mine was thine, before thou hadst this more: Then if for my love, thou my love receivest, I cannot blame thee, for my love thou usest, But yet be blamed, if thou thy self deceivest By wilful taste of what thy self refusest. I do forgive thy robbery gentle thief Although thou steal thee all my poverty: And yet love knows it is a greater grief To bear love's wrong, than hate's known injury. Lascivious grace, in whom all ill well shows, Kill me with spites yet we must not be foes. Those pretty wrongs that liberty commits, When I am sometime absent from thy heart, Thy beauty, and thy years full well befits, For still temptation follows where thou art. Gentle thou art, and therefore to be won, Beauteous thou art, therefore to be assailed. And when a woman woos, what woman's son, Will sourly leave her till he have prevailed? Ay me, but yet thou mightst my seat forbear, And chide thy beauty, and thy straying youth, Who lead thee in their riot even there Where thou art forced to break a twofold truth: Hers by thy beauty tempting her to thee, Thine by thy beauty being false to me. That thou hast her it is not all my grief, And yet it may be said I loved her dearly, That she hath thee is of my wailing chief, A loss in love that touches me more nearly. Loving offenders thus I will excuse ye, Thou dost love her, because thou know'st I love her, And for my sake even so doth she abuse me, Suff'ring my friend for my sake to approve her. If I lose thee, my loss is my love's gain, And losing her, my friend hath found that loss, Both find each other, and I lose both twain, And both for my sake lay on me this cross, But here's the joy, my friend and I are one, Sweet flattery, then she loves but me alone. When most I wink then do mine eyes best see, For all the day they view things unrespected, But when I sleep, in dreams they look on thee, And darkly bright, are bright in dark directed. Then thou whose shadow shadows doth make bright How would thy shadow's form, form happy show, To the clear day with thy much clearer light, When to unseeing eyes thy shade shines so! How would (I say) mine eyes be blessed made, By looking on thee in the living day, When in dead night thy fair imperfect shade, Through heavy sleep on sightless eyes doth stay! All days are nights to see till I see thee, And nights bright days when dreams do show thee me. If the dull substance of my flesh were thought, Injurious distance should not stop my way, For then despite of space I would be brought, From limits far remote, where thou dost stay, No matter then although my foot did stand Upon the farthest earth removed from thee, For nimble thought can jump both sea and land, As soon as think the place where he would be. But ah, thought kills me that I am not thought To leap large lengths of miles when thou art gone, But that so much of earth and water wrought, I must attend, time's leisure with my moan. Receiving nought by elements so slow, But heavy tears, badges of either's woe. The other two, slight air, and purging fire, Are both with thee, wherever I abide, The first my thought, the other my desire, These present-absent with swift motion slide. For when these quicker elements are gone In tender embassy of love to thee, My life being made of four, with two alone, Sinks down to death, oppressed with melancholy. Until life's composition be recured, By those swift messengers returned from thee, Who even but now come back again assured, Of thy fair health, recounting it to me. This told, I joy, but then no longer glad, I send them back again and straight grow sad. Mine eye and heart are at a mortal war, How to divide the conquest of thy sight, Mine eye, my heart thy picture's sight would bar, My heart, mine eye the freedom of that right, My heart doth plead that thou in him dost lie, (A closet never pierced with crystal eyes) But the defendant doth that plea deny, And says in him thy fair appearance lies. To side this title is impanelled A quest of thoughts, all tenants to the heart, And by their verdict is determined The clear eye's moiety, and the dear heart's part. As thus, mine eye's due is thy outward part, And my heart's right, thy inward love of heart. Betwixt mine eye and heart a league is took, And each doth good turns now unto the other, When that mine eye is famished for a look, Or heart in love with sighs himself doth smother; With my love's picture then my eye doth feast, And to the painted banquet bids my heart: Another time mine eye is my heart's guest, And in his thoughts of love doth share a part. So either by thy picture or my love, Thy self away, art present still with me, For thou not farther than my thoughts canst move, And I am still with them, and they with thee. Or if they sleep, thy picture in my sight Awakes my heart, to heart's and eye's delight. How careful was I when I took my way, Each trifle under truest bars to thrust, That to my use it might unused stay From hands of falsehood, in sure wards of trust! But thou, to whom my jewels trifles are, Most worthy comfort, now my greatest grief, Thou best of dearest, and mine only care, Art left the prey of every vulgar thief. Thee have I not locked up in any chest, Save where thou art not, though I feel thou art, Within the gentle closure of my breast, From whence at pleasure thou mayst come and part, And even thence thou wilt be stol'n I fear, For truth proves thievish for a prize so dear. Against that time (if ever that time come) When I shall see thee frown on my defects, When as thy love hath cast his utmost sum, Called to that audit by advised respects, Against that time when thou shalt strangely pass, And scarcely greet me with that sun thine eye, When love converted from the thing it was Shall reasons find of settled gravity; Against that time do I ensconce me here Within the knowledge of mine own desert, And this my hand, against my self uprear, To guard the lawful reasons on thy part, To leave poor me, thou hast the strength of laws, Since why to love, I can allege no cause. How heavy do I journey on the way, When what I seek (my weary travel's end) Doth teach that case and that repose to say 'Thus far the miles are measured from thy friend.' The beast that bears me, tired with my woe, Plods dully on, to bear that weight in me, As if by some instinct the wretch did know His rider loved not speed being made from thee: The bloody spur cannot provoke him on, That sometimes anger thrusts into his hide, Which heavily he answers with a groan, More sharp to me than spurring to his side, For that same groan doth put this in my mind, My grief lies onward and my joy behind. Thus can my love excuse the slow offence, Of my dull bearer, when from thee I speed, From where thou art, why should I haste me thence? Till I return of posting is no need. O what excuse will my poor beast then find, When swift extremity can seem but slow? Then should I spur though mounted on the wind, In winged speed no motion shall I know, Then can no horse with my desire keep pace, Therefore desire (of perfect'st love being made) Shall neigh (no dull flesh) in his fiery race, But love, for love, thus shall excuse my jade, Since from thee going, he went wilful-slow, Towards thee I'll run, and give him leave to go. So am I as the rich whose blessed key, Can bring him to his sweet up-locked treasure, The which he will not every hour survey, For blunting the fine point of seldom pleasure. Therefore are feasts so solemn and so rare, Since seldom coming in that long year set, Like stones of worth they thinly placed are, Or captain jewels in the carcanet. So is the time that keeps you as my chest Or as the wardrobe which the robe doth hide, To make some special instant special-blest, By new unfolding his imprisoned pride. Blessed are you whose worthiness gives scope, Being had to triumph, being lacked to hope. What is your substance, whereof are you made, That millions of strange shadows on you tend? Since every one, hath every one, one shade, And you but one, can every shadow lend: Describe Adonis and the counterfeit, Is poorly imitated after you, On Helen's cheek all art of beauty set, And you in Grecian tires are painted new: Speak of the spring, and foison of the year, The one doth shadow of your beauty show, The other as your bounty doth appear, And you in every blessed shape we know. In all external grace you have some part, But you like none, none you for constant heart. O how much more doth beauty beauteous seem, By that sweet ornament which truth doth give! The rose looks fair, but fairer we it deem For that sweet odour, which doth in it live: The canker blooms have full as deep a dye, As the perfumed tincture of the roses, Hang on such thorns, and play as wantonly, When summer's breath their masked buds discloses: But for their virtue only is their show, They live unwooed, and unrespected fade, Die to themselves. Sweet roses do not so, Of their sweet deaths, are sweetest odours made: And so of you, beauteous and lovely youth, When that shall vade, by verse distills your truth. Not marble, nor the gilded monuments Of princes shall outlive this powerful rhyme, But you shall shine more bright in these contents Than unswept stone, besmeared with sluttish time. When wasteful war shall statues overturn, And broils root out the work of masonry, Nor Mars his sword, nor war's quick fire shall burn: The living record of your memory. 'Gainst death, and all-oblivious enmity Shall you pace forth, your praise shall still find room, Even in the eyes of all posterity That wear this world out to the ending doom. So till the judgment that your self arise, You live in this, and dwell in lovers' eyes. Sweet love renew thy force, be it not said Thy edge should blunter be than appetite, Which but to-day by feeding is allayed, To-morrow sharpened in his former might. So love be thou, although to-day thou fill Thy hungry eyes, even till they wink with fulness, To-morrow see again, and do not kill The spirit of love, with a perpetual dulness: Let this sad interim like the ocean be Which parts the shore, where two contracted new, Come daily to the banks, that when they see: Return of love, more blest may be the view. Or call it winter, which being full of care, Makes summer's welcome, thrice more wished, more rare. Being your slave what should I do but tend, Upon the hours, and times of your desire? I have no precious time at all to spend; Nor services to do till you require. Nor dare I chide the world-without-end hour, Whilst I (my sovereign) watch the clock for you, Nor think the bitterness of absence sour, When you have bid your servant once adieu. Nor dare I question with my jealous thought, Where you may be, or your affairs suppose, But like a sad slave stay and think of nought Save where you are, how happy you make those. So true a fool is love, that in your will, (Though you do any thing) he thinks no ill. That god forbid, that made me first your slave, I should in thought control your times of pleasure, Or at your hand th' account of hours to crave, Being your vassal bound to stay your leisure. O let me suffer (being at your beck) Th' imprisoned absence of your liberty, And patience tame to sufferance bide each check, Without accusing you of injury. Be where you list, your charter is so strong, That you your self may privilage your time To what you will, to you it doth belong, Your self to pardon of self-doing crime. I am to wait, though waiting so be hell, Not blame your pleasure be it ill or well. If there be nothing new, but that which is, Hath been before, how are our brains beguiled, Which labouring for invention bear amis The second burthen of a former child! O that record could with a backward look, Even of five hundred courses of the sun, Show me your image in some antique book, Since mind at first in character was done. That I might see what the old world could say, To this composed wonder of your frame, Whether we are mended, or whether better they, Or whether revolution be the same. O sure I am the wits of former days, To subjects worse have given admiring praise. Like as the waves make towards the pebbled shore, So do our minutes hasten to their end, Each changing place with that which goes before, In sequent toil all forwards do contend. Nativity once in the main of light, Crawls to maturity, wherewith being crowned, Crooked eclipses 'gainst his glory fight, And Time that gave, doth now his gift confound. Time doth transfix the flourish set on youth, And delves the parallels in beauty's brow, Feeds on the rarities of nature's truth, And nothing stands but for his scythe to mow. And yet to times in hope, my verse shall stand Praising thy worth, despite his cruel hand. Is it thy will, thy image should keep open My heavy eyelids to the weary night? Dost thou desire my slumbers should be broken, While shadows like to thee do mock my sight? Is it thy spirit that thou send'st from thee So far from home into my deeds to pry, To find out shames and idle hours in me, The scope and tenure of thy jealousy? O no, thy love though much, is not so great, It is my love that keeps mine eye awake, Mine own true love that doth my rest defeat, To play the watchman ever for thy sake. For thee watch I, whilst thou dost wake elsewhere, From me far off, with others all too near. Sin of self-love possesseth all mine eye, And all my soul, and all my every part; And for this sin there is no remedy, It is so grounded inward in my heart. Methinks no face so gracious is as mine, No shape so true, no truth of such account, And for my self mine own worth do define, As I all other in all worths surmount. But when my glass shows me my self indeed beated and chopt with tanned antiquity, Mine own self-love quite contrary I read: Self, so self-loving were iniquity. 'Tis thee (my self) that for my self I praise, Painting my age with beauty of thy days. Against my love shall be as I am now With Time's injurious hand crushed and o'erworn, When hours have drained his blood and filled his brow With lines and wrinkles, when his youthful morn Hath travelled on to age's steepy night, And all those beauties whereof now he's king Are vanishing, or vanished out of sight, Stealing away the treasure of his spring: For such a time do I now fortify Against confounding age's cruel knife, That he shall never cut from memory My sweet love's beauty, though my lover's life. His beauty shall in these black lines be seen, And they shall live, and he in them still green. When I have seen by Time's fell hand defaced The rich-proud cost of outworn buried age, When sometime lofty towers I see down-rased, And brass eternal slave to mortal rage. When I have seen the hungry ocean gain Advantage on the kingdom of the shore, And the firm soil win of the watery main, Increasing store with loss, and loss with store. When I have seen such interchange of State, Or state it self confounded, to decay, Ruin hath taught me thus to ruminate That Time will come and take my love away. This thought is as a death which cannot choose But weep to have, that which it fears to lose. Since brass, nor stone, nor earth, nor boundless sea, But sad mortality o'ersways their power, How with this rage shall beauty hold a plea, Whose action is no stronger than a flower? O how shall summer's honey breath hold out, Against the wrackful siege of batt'ring days, When rocks impregnable are not so stout, Nor gates of steel so strong but time decays? O fearful meditation, where alack, Shall Time's best jewel from Time's chest lie hid? Or what strong hand can hold his swift foot back, Or who his spoil of beauty can forbid? O none, unless this miracle have might, That in black ink my love may still shine bright. Tired with all these for restful death I cry, As to behold desert a beggar born, And needy nothing trimmed in jollity, And purest faith unhappily forsworn, And gilded honour shamefully misplaced, And maiden virtue rudely strumpeted, And right perfection wrongfully disgraced, And strength by limping sway disabled And art made tongue-tied by authority, And folly (doctor-like) controlling skill, And simple truth miscalled simplicity, And captive good attending captain ill. Tired with all these, from these would I be gone, Save that to die, I leave my love alone. Ah wherefore with infection should he live, And with his presence grace impiety, That sin by him advantage should achieve, And lace it self with his society? Why should false painting imitate his cheek, And steal dead seeming of his living hue? Why should poor beauty indirectly seek, Roses of shadow, since his rose is true? Why should he live, now nature bankrupt is, Beggared of blood to blush through lively veins, For she hath no exchequer now but his, And proud of many, lives upon his gains? O him she stores, to show what wealth she had, In days long since, before these last so bad. Thus is his cheek the map of days outworn, When beauty lived and died as flowers do now, Before these bastard signs of fair were born, Or durst inhabit on a living brow: Before the golden tresses of the dead, The right of sepulchres, were shorn away, To live a second life on second head, Ere beauty's dead fleece made another gay: In him those holy antique hours are seen, Without all ornament, it self and true, Making no summer of another's green, Robbing no old to dress his beauty new, And him as for a map doth Nature store, To show false Art what beauty was of yore. Those parts of thee that the world's eye doth view, Want nothing that the thought of hearts can mend: All tongues (the voice of souls) give thee that due, Uttering bare truth, even so as foes commend. Thy outward thus with outward praise is crowned, But those same tongues that give thee so thine own, In other accents do this praise confound By seeing farther than the eye hath shown. They look into the beauty of thy mind, And that in guess they measure by thy deeds, Then churls their thoughts (although their eyes were kind) To thy fair flower add the rank smell of weeds: But why thy odour matcheth not thy show, The soil is this, that thou dost common grow. That thou art blamed shall not be thy defect, For slander's mark was ever yet the fair, The ornament of beauty is suspect, A crow that flies in heaven's sweetest air. So thou be good, slander doth but approve, Thy worth the greater being wooed of time, For canker vice the sweetest buds doth love, And thou present'st a pure unstained prime. Thou hast passed by the ambush of young days, Either not assailed, or victor being charged, Yet this thy praise cannot be so thy praise, To tie up envy, evermore enlarged, If some suspect of ill masked not thy show, Then thou alone kingdoms of hearts shouldst owe. No longer mourn for me when I am dead, Than you shall hear the surly sullen bell Give warning to the world that I am fled From this vile world with vilest worms to dwell: Nay if you read this line, remember not, The hand that writ it, for I love you so, That I in your sweet thoughts would be forgot, If thinking on me then should make you woe. O if (I say) you look upon this verse, When I (perhaps) compounded am with clay, Do not so much as my poor name rehearse; But let your love even with my life decay. Lest the wise world should look into your moan, And mock you with me after I am gone. O lest the world should task you to recite, What merit lived in me that you should love After my death (dear love) forget me quite, For you in me can nothing worthy prove. Unless you would devise some virtuous lie, To do more for me than mine own desert, And hang more praise upon deceased I, Than niggard truth would willingly impart: O lest your true love may seem false in this, That you for love speak well of me untrue, My name be buried where my body is, And live no more to shame nor me, nor you. For I am shamed by that which I bring forth, And so should you, to love things nothing worth. That time of year thou mayst in me behold, When yellow leaves, or none, or few do hang Upon those boughs which shake against the cold, Bare ruined choirs, where late the sweet birds sang. In me thou seest the twilight of such day, As after sunset fadeth in the west, Which by and by black night doth take away, Death's second self that seals up all in rest. In me thou seest the glowing of such fire, That on the ashes of his youth doth lie, As the death-bed, whereon it must expire, Consumed with that which it was nourished by. This thou perceiv'st, which makes thy love more strong, To love that well, which thou must leave ere long. But be contented when that fell arrest, Without all bail shall carry me away, My life hath in this line some interest, Which for memorial still with thee shall stay. When thou reviewest this, thou dost review, The very part was consecrate to thee, The earth can have but earth, which is his due, My spirit is thine the better part of me, So then thou hast but lost the dregs of life, The prey of worms, my body being dead, The coward conquest of a wretch's knife, Too base of thee to be remembered, The worth of that, is that which it contains, And that is this, and this with thee remains. So are you to my thoughts as food to life, Or as sweet-seasoned showers are to the ground; And for the peace of you I hold such strife As 'twixt a miser and his wealth is found. Now proud as an enjoyer, and anon Doubting the filching age will steal his treasure, Now counting best to be with you alone, Then bettered that the world may see my pleasure, Sometime all full with feasting on your sight, And by and by clean starved for a look, Possessing or pursuing no delight Save what is had, or must from you be took. Thus do I pine and surfeit day by day, Or gluttoning on all, or all away. Why is my verse so barren of new pride? So far from variation or quick change? Why with the time do I not glance aside To new-found methods, and to compounds strange? Why write I still all one, ever the same, And keep invention in a noted weed, That every word doth almost tell my name, Showing their birth, and where they did proceed? O know sweet love I always write of you, And you and love are still my argument: So all my best is dressing old words new, Spending again what is already spent: For as the sun is daily new and old, So is my love still telling what is told. Thy glass will show thee how thy beauties wear, Thy dial how thy precious minutes waste, These vacant leaves thy mind's imprint will bear, And of this book, this learning mayst thou taste. The wrinkles which thy glass will truly show, Of mouthed graves will give thee memory, Thou by thy dial's shady stealth mayst know, Time's thievish progress to eternity. Look what thy memory cannot contain, Commit to these waste blanks, and thou shalt find Those children nursed, delivered from thy brain, To take a new acquaintance of thy mind. These offices, so oft as thou wilt look, Shall profit thee, and much enrich thy book. So oft have I invoked thee for my muse, And found such fair assistance in my verse, As every alien pen hath got my use, And under thee their poesy disperse. Thine eyes, that taught the dumb on high to sing, And heavy ignorance aloft to fly, Have added feathers to the learned's wing, And given grace a double majesty. Yet be most proud of that which I compile, Whose influence is thine, and born of thee, In others' works thou dost but mend the style, And arts with thy sweet graces graced be. But thou art all my art, and dost advance As high as learning, my rude ignorance. Whilst I alone did call upon thy aid, My verse alone had all thy gentle grace, But now my gracious numbers are decayed, And my sick muse doth give an other place. I grant (sweet love) thy lovely argument Deserves the travail of a worthier pen, Yet what of thee thy poet doth invent, He robs thee of, and pays it thee again, He lends thee virtue, and he stole that word, From thy behaviour, beauty doth he give And found it in thy cheek: he can afford No praise to thee, but what in thee doth live. Then thank him not for that which he doth say, Since what he owes thee, thou thy self dost pay. O how I faint when I of you do write, Knowing a better spirit doth use your name, And in the praise thereof spends all his might, To make me tongue-tied speaking of your fame. But since your worth (wide as the ocean is) The humble as the proudest sail doth bear, My saucy bark (inferior far to his) On your broad main doth wilfully appear. Your shallowest help will hold me up afloat, Whilst he upon your soundless deep doth ride, Or (being wrecked) I am a worthless boat, He of tall building, and of goodly pride. Then if he thrive and I be cast away, The worst was this, my love was my decay. Or I shall live your epitaph to make, Or you survive when I in earth am rotten, From hence your memory death cannot take, Although in me each part will be forgotten. Your name from hence immortal life shall have, Though I (once gone) to all the world must die, The earth can yield me but a common grave, When you entombed in men's eyes shall lie, Your monument shall be my gentle verse, Which eyes not yet created shall o'er-read, And tongues to be, your being shall rehearse, When all the breathers of this world are dead, You still shall live (such virtue hath my pen) Where breath most breathes, even in the mouths of men. I grant thou wert not married to my muse, And therefore mayst without attaint o'erlook The dedicated words which writers use Of their fair subject, blessing every book. Thou art as fair in knowledge as in hue, Finding thy worth a limit past my praise, And therefore art enforced to seek anew, Some fresher stamp of the time-bettering days. And do so love, yet when they have devised, What strained touches rhetoric can lend, Thou truly fair, wert truly sympathized, In true plain words, by thy true-telling friend. And their gross painting might be better used, Where cheeks need blood, in thee it is abused. I never saw that you did painting need, And therefore to your fair no painting set, I found (or thought I found) you did exceed, That barren tender of a poet's debt: And therefore have I slept in your report, That you your self being extant well might show, How far a modern quill doth come too short, Speaking of worth, what worth in you doth grow. This silence for my sin you did impute, Which shall be most my glory being dumb, For I impair not beauty being mute, When others would give life, and bring a tomb. There lives more life in one of your fair eyes, Than both your poets can in praise devise. Who is it that says most, which can say more, Than this rich praise, that you alone, are you? In whose confine immured is the store, Which should example where your equal grew. Lean penury within that pen doth dwell, That to his subject lends not some small glory, But he that writes of you, if he can tell, That you are you, so dignifies his story. Let him but copy what in you is writ, Not making worse what nature made so clear, And such a counterpart shall fame his wit, Making his style admired every where. You to your beauteous blessings add a curse, Being fond on praise, which makes your praises worse. My tongue-tied muse in manners holds her still, While comments of your praise richly compiled, Reserve their character with golden quill, And precious phrase by all the Muses filed. I think good thoughts, whilst other write good words, And like unlettered clerk still cry Amen, To every hymn that able spirit affords, In polished form of well refined pen. Hearing you praised, I say 'tis so, 'tis true, And to the most of praise add something more, But that is in my thought, whose love to you (Though words come hindmost) holds his rank before, Then others, for the breath of words respect, Me for my dumb thoughts, speaking in effect. Was it the proud full sail of his great verse, Bound for the prize of (all too precious) you, That did my ripe thoughts in my brain inhearse, Making their tomb the womb wherein they grew? Was it his spirit, by spirits taught to write, Above a mortal pitch, that struck me dead? No, neither he, nor his compeers by night Giving him aid, my verse astonished. He nor that affable familiar ghost Which nightly gulls him with intelligence, As victors of my silence cannot boast, I was not sick of any fear from thence. But when your countenance filled up his line, Then lacked I matter, that enfeebled mine. Farewell! thou art too dear for my possessing, And like enough thou know'st thy estimate, The charter of thy worth gives thee releasing: My bonds in thee are all determinate. For how do I hold thee but by thy granting, And for that riches where is my deserving? The cause of this fair gift in me is wanting, And so my patent back again is swerving. Thy self thou gav'st, thy own worth then not knowing, Or me to whom thou gav'st it, else mistaking, So thy great gift upon misprision growing, Comes home again, on better judgement making. Thus have I had thee as a dream doth flatter, In sleep a king, but waking no such matter. When thou shalt be disposed to set me light, And place my merit in the eye of scorn, Upon thy side, against my self I'll fight, And prove thee virtuous, though thou art forsworn: With mine own weakness being best acquainted, Upon thy part I can set down a story Of faults concealed, wherein I am attainted: That thou in losing me, shalt win much glory: And I by this will be a gainer too, For bending all my loving thoughts on thee, The injuries that to my self I do, Doing thee vantage, double-vantage me. Such is my love, to thee I so belong, That for thy right, my self will bear all wrong. Say that thou didst forsake me for some fault, And I will comment upon that offence, Speak of my lameness, and I straight will halt: Against thy reasons making no defence. Thou canst not (love) disgrace me half so ill, To set a form upon desired change, As I'll my self disgrace, knowing thy will, I will acquaintance strangle and look strange: Be absent from thy walks and in my tongue, Thy sweet beloved name no more shall dwell, Lest I (too much profane) should do it wrong: And haply of our old acquaintance tell. For thee, against my self I'll vow debate, For I must ne'er love him whom thou dost hate. Then hate me when thou wilt, if ever, now, Now while the world is bent my deeds to cross, join with the spite of fortune, make me bow, And do not drop in for an after-loss: Ah do not, when my heart hath 'scaped this sorrow, Come in the rearward of a conquered woe, Give not a windy night a rainy morrow, To linger out a purposed overthrow. If thou wilt leave me, do not leave me last, When other petty griefs have done their spite, But in the onset come, so shall I taste At first the very worst of fortune's might. And other strains of woe, which now seem woe, Compared with loss of thee, will not seem so. Some glory in their birth, some in their skill, Some in their wealth, some in their body's force, Some in their garments though new-fangled ill: Some in their hawks and hounds, some in their horse. And every humour hath his adjunct pleasure, Wherein it finds a joy above the rest, But these particulars are not my measure, All these I better in one general best. Thy love is better than high birth to me, Richer than wealth, prouder than garments' costs, Of more delight than hawks and horses be: And having thee, of all men's pride I boast. Wretched in this alone, that thou mayst take, All this away, and me most wretchcd make. But do thy worst to steal thy self away, For term of life thou art assured mine, And life no longer than thy love will stay, For it depends upon that love of thine. Then need I not to fear the worst of wrongs, When in the least of them my life hath end, I see, a better state to me belongs Than that, which on thy humour doth depend. Thou canst not vex me with inconstant mind, Since that my life on thy revolt doth lie, O what a happy title do I find, Happy to have thy love, happy to die! But what's so blessed-fair that fears no blot? Thou mayst be false, and yet I know it not. So shall I live, supposing thou art true, Like a deceived husband, so love's face, May still seem love to me, though altered new: Thy looks with me, thy heart in other place. For there can live no hatred in thine eye, Therefore in that I cannot know thy change, In many's looks, the false heart's history Is writ in moods and frowns and wrinkles strange. But heaven in thy creation did decree, That in thy face sweet love should ever dwell, Whate'er thy thoughts, or thy heart's workings be, Thy looks should nothing thence, but sweetness tell. How like Eve's apple doth thy beauty grow, If thy sweet virtue answer not thy show. They that have power to hurt, and will do none, That do not do the thing, they most do show, Who moving others, are themselves as stone, Unmoved, cold, and to temptation slow: They rightly do inherit heaven's graces, And husband nature's riches from expense, Tibey are the lords and owners of their faces, Others, but stewards of their excellence: The summer's flower is to the summer sweet, Though to it self, it only live and die, But if that flower with base infection meet, The basest weed outbraves his dignity: For sweetest things turn sourest by their deeds, Lilies that fester, smell far worse than weeds. How sweet and lovely dost thou make the shame, Which like a canker in the fragrant rose, Doth spot the beauty of thy budding name! O in what sweets dost thou thy sins enclose! That tongue that tells the story of thy days, (Making lascivious comments on thy sport) Cannot dispraise, but in a kind of praise, Naming thy name, blesses an ill report. O what a mansion have those vices got, Which for their habitation chose out thee, Where beauty's veil doth cover every blot, And all things turns to fair, that eyes can see! Take heed (dear heart) of this large privilege, The hardest knife ill-used doth lose his edge. Some say thy fault is youth, some wantonness, Some say thy grace is youth and gentle sport, Both grace and faults are loved of more and less: Thou mak'st faults graces, that to thee resort: As on the finger of a throned queen, The basest jewel will be well esteemed: So are those errors that in thee are seen, To truths translated, and for true things deemed. How many lambs might the stern wolf betray, If like a lamb he could his looks translate! How many gazers mightst thou lead away, if thou wouldst use the strength of all thy state! But do not so, I love thee in such sort, As thou being mine, mine is thy good report. How like a winter hath my absence been From thee, the pleasure of the fleeting year! What freezings have I felt, what dark days seen! What old December's bareness everywhere! And yet this time removed was summer's time, The teeming autumn big with rich increase, Bearing the wanton burden of the prime, Like widowed wombs after their lords' decease: Yet this abundant issue seemed to me But hope of orphans, and unfathered fruit, For summer and his pleasures wait on thee, And thou away, the very birds are mute. Or if they sing, 'tis with so dull a cheer, That leaves look pale, dreading the winter's near. From you have I been absent in the spring, When proud-pied April (dressed in all his trim) Hath put a spirit of youth in every thing: That heavy Saturn laughed and leaped with him. Yet nor the lays of birds, nor the sweet smell Of different flowers in odour and in hue, Could make me any summer's story tell: Or from their proud lap pluck them where they grew: Nor did I wonder at the lily's white, Nor praise the deep vermilion in the rose, They were but sweet, but figures of delight: Drawn after you, you pattern of all those. Yet seemed it winter still, and you away, As with your shadow I with these did play. The forward violet thus did I chide, Sweet thief, whence didst thou steal thy sweet that smells, If not from my love's breath? The purple pride Which on thy soft check for complexion dwells, In my love's veins thou hast too grossly dyed. The lily I condemned for thy hand, And buds of marjoram had stol'n thy hair, The roses fearfully on thorns did stand, One blushing shame, another white despair: A third nor red, nor white, had stol'n of both, And to his robbery had annexed thy breath, But for his theft in pride of all his growth A vengeful canker eat him up to death. More flowers I noted, yet I none could see, But sweet, or colour it had stol'n from thee. Where art thou Muse that thou forget'st so long, To speak of that which gives thee all thy might? Spend'st thou thy fury on some worthless song, Darkening thy power to lend base subjects light? Return forgetful Muse, and straight redeem, In gentle numbers time so idly spent, Sing to the ear that doth thy lays esteem, And gives thy pen both skill and argument. Rise resty Muse, my love's sweet face survey, If time have any wrinkle graven there, If any, be a satire to decay, And make time's spoils despised everywhere. Give my love fame faster than Time wastes life, So thou prevent'st his scythe, and crooked knife. O truant Muse what shall be thy amends, For thy neglect of truth in beauty dyed? Both truth and beauty on my love depends: So dost thou too, and therein dignified: Make answer Muse, wilt thou not haply say, 'Truth needs no colour with his colour fixed, Beauty no pencil, beauty's truth to lay: But best is best, if never intermixed'? Because he needs no praise, wilt thou be dumb? Excuse not silence so, for't lies in thee, To make him much outlive a gilded tomb: And to be praised of ages yet to be. Then do thy office Muse, I teach thee how, To make him seem long hence, as he shows now. My love is strengthened though more weak in seeming, I love not less, though less the show appear, That love is merchandized, whose rich esteeming, The owner's tongue doth publish every where. Our love was new, and then but in the spring, When I was wont to greet it with my lays, As Philomel in summer's front doth sing, And stops her pipe in growth of riper days: Not that the summer is less pleasant now Than when her mournful hymns did hush the night, But that wild music burthens every bough, And sweets grown common lose their dear delight. Therefore like her, I sometime hold my tongue: Because I would not dull you with my song. Alack what poverty my muse brings forth, That having such a scope to show her pride, The argument all bare is of more worth Than when it hath my added praise beside. O blame me not if I no more can write! Look in your glass and there appears a face, That over-goes my blunt invention quite, Dulling my lines, and doing me disgrace. Were it not sinful then striving to mend, To mar the subject that before was well? For to no other pass my verses tend, Than of your graces and your gifts to tell. And more, much more than in my verse can sit, Your own glass shows you, when you look in it. To me fair friend you never can be old, For as you were when first your eye I eyed, Such seems your beauty still: three winters cold, Have from the forests shook three summers' pride, Three beauteous springs to yellow autumn turned, In process of the seasons have I seen, Three April perfumes in three hot Junes burned, Since first I saw you fresh which yet are green. Ah yet doth beauty like a dial hand, Steal from his figure, and no pace perceived, So your sweet hue, which methinks still doth stand Hath motion, and mine eye may be deceived. For fear of which, hear this thou age unbred, Ere you were born was beauty's summer dead. Let not my love be called idolatry, Nor my beloved as an idol show, Since all alike my songs and praises be To one, of one, still such, and ever so. Kind is my love to-day, to-morrow kind, Still constant in a wondrous excellence, Therefore my verse to constancy confined, One thing expressing, leaves out difference. Fair, kind, and true, is all my argument, Fair, kind, and true, varying to other words, And in this change is my invention spent, Three themes in one, which wondrous scope affords. Fair, kind, and true, have often lived alone. Which three till now, never kept seat in one. When in the chronicle of wasted time, I see descriptions of the fairest wights, And beauty making beautiful old rhyme, In praise of ladies dead, and lovely knights, Then in the blazon of sweet beauty's best, Of hand, of foot, of lip, of eye, of brow, I see their antique pen would have expressed, Even such a beauty as you master now. So all their praises are but prophecies Of this our time, all you prefiguring, And for they looked but with divining eyes, They had not skill enough your worth to sing: For we which now behold these present days, Have eyes to wonder, but lack tongues to praise. Not mine own fears, nor the prophetic soul, Of the wide world, dreaming on things to come, Can yet the lease of my true love control, Supposed as forfeit to a confined doom. The mortal moon hath her eclipse endured, And the sad augurs mock their own presage, Incertainties now crown themselves assured, And peace proclaims olives of endless age. Now with the drops of this most balmy time, My love looks fresh, and death to me subscribes, Since spite of him I'll live in this poor rhyme, While he insults o'er dull and speechless tribes. And thou in this shalt find thy monument, When tyrants' crests and tombs of brass are spent. What's in the brain that ink may character, Which hath not figured to thee my true spirit, What's new to speak, what now to register, That may express my love, or thy dear merit? Nothing sweet boy, but yet like prayers divine, I must each day say o'er the very same, Counting no old thing old, thou mine, I thine, Even as when first I hallowed thy fair name. So that eternal love in love's fresh case, Weighs not the dust and injury of age, Nor gives to necessary wrinkles place, But makes antiquity for aye his page, Finding the first conceit of love there bred, Where time and outward form would show it dead. O never say that I was false of heart, Though absence seemed my flame to qualify, As easy might I from my self depart, As from my soul which in thy breast doth lie: That is my home of love, if I have ranged, Like him that travels I return again, Just to the time, not with the time exchanged, So that my self bring water for my stain, Never believe though in my nature reigned, All frailties that besiege all kinds of blood, That it could so preposterously be stained, To leave for nothing all thy sum of good: For nothing this wide universe I call, Save thou my rose, in it thou art my all. Alas 'tis true, I have gone here and there, And made my self a motley to the view, Gored mine own thoughts, sold cheap what is most dear, Made old offences of affections new. Most true it is, that I have looked on truth Askance and strangely: but by all above, These blenches gave my heart another youth, And worse essays proved thee my best of love. Now all is done, have what shall have no end, Mine appetite I never more will grind On newer proof, to try an older friend, A god in love, to whom I am confined. Then give me welcome, next my heaven the best, Even to thy pure and most most loving breast. O for my sake do you with Fortune chide, The guilty goddess of my harmful deeds, That did not better for my life provide, Than public means which public manners breeds. Thence comes it that my name receives a brand, And almost thence my nature is subdued To what it works in, like the dyer's hand: Pity me then, and wish I were renewed, Whilst like a willing patient I will drink, Potions of eisel 'gainst my strong infection, No bitterness that I will bitter think, Nor double penance to correct correction. Pity me then dear friend, and I assure ye, Even that your pity is enough to cure me. Your love and pity doth th' impression fill, Which vulgar scandal stamped upon my brow, For what care I who calls me well or ill, So you o'er-green my bad, my good allow? You are my all the world, and I must strive, To know my shames and praises from your tongue, None else to me, nor I to none alive, That my steeled sense or changes right or wrong. In so profound abysm I throw all care Of others' voices, that my adder's sense, To critic and to flatterer stopped are: Mark how with my neglect I do dispense. You are so strongly in my purpose bred, That all the world besides methinks are dead. Since I left you, mine eye is in my mind, And that which governs me to go about, Doth part his function, and is partly blind, Seems seeing, but effectually is out: For it no form delivers to the heart Of bird, of flower, or shape which it doth latch, Of his quick objects hath the mind no part, Nor his own vision holds what it doth catch: For if it see the rud'st or gentlest sight, The most sweet favour or deformed'st creature, The mountain, or the sea, the day, or night: The crow, or dove, it shapes them to your feature. Incapable of more, replete with you, My most true mind thus maketh mine untrue. Or whether doth my mind being crowned with you Drink up the monarch's plague this flattery? Or whether shall I say mine eye saith true, And that your love taught it this alchemy? To make of monsters, and things indigest, Such cherubins as your sweet self resemble, Creating every bad a perfect best As fast as objects to his beams assemble: O 'tis the first, 'tis flattery in my seeing, And my great mind most kingly drinks it up, Mine eye well knows what with his gust is 'greeing, And to his palate doth prepare the cup. If it be poisoned, 'tis the lesser sin, That mine eye loves it and doth first begin. Those lines that I before have writ do lie, Even those that said I could not love you dearer, Yet then my judgment knew no reason why, My most full flame should afterwards burn clearer, But reckoning time, whose millioned accidents Creep in 'twixt vows, and change decrees of kings, Tan sacred beauty, blunt the sharp'st intents, Divert strong minds to the course of alt'ring things: Alas why fearing of time's tyranny, Might I not then say 'Now I love you best,' When I was certain o'er incertainty, Crowning the present, doubting of the rest? Love is a babe, then might I not say so To give full growth to that which still doth grow. Let me not to the marriage of true minds Admit impediments, love is not love Which alters when it alteration finds, Or bends with the remover to remove. O no, it is an ever-fixed mark That looks on tempests and is never shaken; It is the star to every wand'ring bark, Whose worth's unknown, although his height be taken. Love's not Time's fool, though rosy lips and cheeks Within his bending sickle's compass come, Love alters not with his brief hours and weeks, But bears it out even to the edge of doom: If this be error and upon me proved, I never writ, nor no man ever loved. Accuse me thus, that I have scanted all, Wherein I should your great deserts repay, Forgot upon your dearest love to call, Whereto all bonds do tie me day by day, That I have frequent been with unknown minds, And given to time your own dear-purchased right, That I have hoisted sail to all the winds Which should transport me farthest from your sight. Book both my wilfulness and errors down, And on just proof surmise, accumulate, Bring me within the level of your frown, But shoot not at me in your wakened hate: Since my appeal says I did strive to prove The constancy and virtue of your love. Like as to make our appetite more keen With eager compounds we our palate urge, As to prevent our maladies unseen, We sicken to shun sickness when we purge. Even so being full of your ne'er-cloying sweetness, To bitter sauces did I frame my feeding; And sick of welfare found a kind of meetness, To be diseased ere that there was true needing. Thus policy in love t' anticipate The ills that were not, grew to faults assured, And brought to medicine a healthful state Which rank of goodness would by ill be cured. But thence I learn and find the lesson true, Drugs poison him that so feil sick of you. What potions have I drunk of Siren tears Distilled from limbecks foul as hell within, Applying fears to hopes, and hopes to fears, Still losing when I saw my self to win! What wretched errors hath my heart committed, Whilst it hath thought it self so blessed never! How have mine eyes out of their spheres been fitted In the distraction of this madding fever! O benefit of ill, now I find true That better is, by evil still made better. And ruined love when it is built anew Grows fairer than at first, more strong, far greater. So I return rebuked to my content, And gain by ills thrice more than I have spent. That you were once unkind befriends me now, And for that sorrow, which I then did feel, Needs must I under my transgression bow, Unless my nerves were brass or hammered steel. For if you were by my unkindness shaken As I by yours, y'have passed a hell of time, And I a tyrant have no leisure taken To weigh how once I suffered in your crime. O that our night of woe might have remembered My deepest sense, how hard true sorrow hits, And soon to you, as you to me then tendered The humble salve, which wounded bosoms fits! But that your trespass now becomes a fee, Mine ransoms yours, and yours must ransom me. 'Tis better to be vile than vile esteemed, When not to be, receives reproach of being, And the just pleasure lost, which is so deemed, Not by our feeling, but by others' seeing. For why should others' false adulterate eyes Give salutation to my sportive blood? Or on my frailties why are frailer spies, Which in their wills count bad what I think good? No, I am that I am, and they that level At my abuses, reckon up their own, I may be straight though they themselves be bevel; By their rank thoughts, my deeds must not be shown Unless this general evil they maintain, All men are bad and in their badness reign. Thy gift, thy tables, are within my brain Full charactered with lasting memory, Which shall above that idle rank remain Beyond all date even to eternity. Or at the least, so long as brain and heart Have faculty by nature to subsist, Till each to razed oblivion yield his part Of thee, thy record never can be missed: That poor retention could not so much hold, Nor need I tallies thy dear love to score, Therefore to give them from me was I bold, To trust those tables that receive thee more: To keep an adjunct to remember thee Were to import forgetfulness in me. No! Time, thou shalt not boast that I do change, Thy pyramids built up with newer might To me are nothing novel, nothing strange, They are but dressings Of a former sight: Our dates are brief, and therefore we admire, What thou dost foist upon us that is old, And rather make them born to our desire, Than think that we before have heard them told: Thy registers and thee I both defy, Not wond'ring at the present, nor the past, For thy records, and what we see doth lie, Made more or less by thy continual haste: This I do vow and this shall ever be, I will be true despite thy scythe and thee. If my dear love were but the child of state, It might for Fortune's bastard be unfathered, As subject to time's love or to time's hate, Weeds among weeds, or flowers with flowers gathered. No it was builded far from accident, It suffers not in smiling pomp, nor falls Under the blow of thralled discontent, Whereto th' inviting time our fashion calls: It fears not policy that heretic, Which works on leases of short-numbered hours, But all alone stands hugely politic, That it nor grows with heat, nor drowns with showers. To this I witness call the fools of time, Which die for goodness, who have lived for crime. Were't aught to me I bore the canopy, With my extern the outward honouring, Or laid great bases for eternity, Which proves more short than waste or ruining? Have I not seen dwellers on form and favour Lose all, and more by paying too much rent For compound sweet; forgoing simple savour, Pitiful thrivers in their gazing spent? No, let me be obsequious in thy heart, And take thou my oblation, poor but free, Which is not mixed with seconds, knows no art, But mutual render, only me for thee. Hence, thou suborned informer, a true soul When most impeached, stands least in thy control. O thou my lovely boy who in thy power, Dost hold Time's fickle glass his fickle hour: Who hast by waning grown, and therein show'st, Thy lovers withering, as thy sweet self grow'st. If Nature (sovereign mistress over wrack) As thou goest onwards still will pluck thee back, She keeps thee to this purpose, that her skill May time disgrace, and wretched minutes kill. Yet fear her O thou minion of her pleasure, She may detain, but not still keep her treasure! Her audit (though delayed) answered must be, And her quietus is to render thee. In the old age black was not counted fair, Or if it were it bore not beauty's name: But now is black beauty's successive heir, And beauty slandered with a bastard shame, For since each hand hath put on nature's power, Fairing the foul with art's false borrowed face, Sweet beauty hath no name no holy bower, But is profaned, if not lives in disgrace. Therefore my mistress' eyes are raven black, Her eyes so suited, and they mourners seem, At such who not born fair no beauty lack, Slandering creation with a false esteem, Yet so they mourn becoming of their woe, That every tongue says beauty should look so. How oft when thou, my music, music play'st, Upon that blessed wood whose motion sounds With thy sweet fingers when thou gently sway'st The wiry concord that mine ear confounds, Do I envy those jacks that nimble leap, To kiss the tender inward of thy hand, Whilst my poor lips which should that harvest reap, At the wood's boldness by thee blushing stand. To be so tickled they would change their state And situation with those dancing chips, O'er whom thy fingers walk with gentle gait, Making dead wood more blest than living lips, Since saucy jacks so happy are in this, Give them thy fingers, me thy lips to kiss. Th' expense of spirit in a waste of shame Is lust in action, and till action, lust Is perjured, murd'rous, bloody full of blame, Savage, extreme, rude, cruel, not to trust, Enjoyed no sooner but despised straight, Past reason hunted, and no sooner had Past reason hated as a swallowed bait, On purpose laid to make the taker mad. Mad in pursuit and in possession so, Had, having, and in quest, to have extreme, A bliss in proof and proved, a very woe, Before a joy proposed behind a dream. All this the world well knows yet none knows well, To shun the heaven that leads men to this hell. My mistress' eyes are nothing like the sun, Coral is far more red, than her lips red, If snow be white, why then her breasts are dun: If hairs be wires, black wires grow on her head: I have seen roses damasked, red and white, But no such roses see I in her cheeks, And in some perfumes is there more delight, Than in the breath that from my mistress reeks. I love to hear her speak, yet well I know, That music hath a far more pleasing sound: I grant I never saw a goddess go, My mistress when she walks treads on the ground. And yet by heaven I think my love as rare, As any she belied with false compare. Thou art as tyrannous, so as thou art, As those whose beauties proudly make them cruel; For well thou know'st to my dear doting heart Thou art the fairest and most precious jewel. Yet in good faith some say that thee behold, Thy face hath not the power to make love groan; To say they err, I dare not be so bold, Although I swear it to my self alone. And to be sure that is not false I swear, A thousand groans but thinking on thy face, One on another's neck do witness bear Thy black is fairest in my judgment's place. In nothing art thou black save in thy deeds, And thence this slander as I think proceeds. Thine eyes I love, and they as pitying me, Knowing thy heart torment me with disdain, Have put on black, and loving mourners be, Looking with pretty ruth upon my pain. And truly not the morning sun of heaven Better becomes the grey cheeks of the east, Nor that full star that ushers in the even Doth half that glory to the sober west As those two mourning eyes become thy face: O let it then as well beseem thy heart To mourn for me since mourning doth thee grace, And suit thy pity like in every part. Then will I swear beauty herself is black, And all they foul that thy complexion lack. Beshrew that heart that makes my heart to groan For that deep wound it gives my friend and me; Is't not enough to torture me alone, But slave to slavery my sweet'st friend must be? Me from my self thy cruel eye hath taken, And my next self thou harder hast engrossed, Of him, my self, and thee I am forsaken, A torment thrice three-fold thus to be crossed: Prison my heart in thy steel bosom's ward, But then my friend's heart let my poor heart bail, Whoe'er keeps me, let my heart be his guard, Thou canst not then use rigour in my gaol. And yet thou wilt, for I being pent in thee, Perforce am thine and all that is in me. So now I have confessed that he is thine, And I my self am mortgaged to thy will, My self I'll forfeit, so that other mine, Thou wilt restore to be my comfort still: But thou wilt not, nor he will not be free, For thou art covetous, and he is kind, He learned but surety-like to write for me, Under that bond that him as fist doth bind. The statute of thy beauty thou wilt take, Thou usurer that put'st forth all to use, And sue a friend, came debtor for my sake, So him I lose through my unkind abuse. Him have I lost, thou hast both him and me, He pays the whole, and yet am I not free. Whoever hath her wish, thou hast thy will, And 'Will' to boot, and 'Will' in over-plus, More than enough am I that vex thee still, To thy sweet will making addition thus. Wilt thou whose will is large and spacious, Not once vouchsafe to hide my will in thine? Shall will in others seem right gracious, And in my will no fair acceptance shine? The sea all water, yet receives rain still, And in abundance addeth to his store, So thou being rich in will add to thy will One will of mine to make thy large will more. Let no unkind, no fair beseechers kill, Think all but one, and me in that one 'Will.' If thy soul check thee that I come so near, Swear to thy blind soul that I was thy 'Will', And will thy soul knows is admitted there, Thus far for love, my love-suit sweet fulfil. 'Will', will fulfil the treasure of thy love, Ay, fill it full with wills, and my will one, In things of great receipt with case we prove, Among a number one is reckoned none. Then in the number let me pass untold, Though in thy store's account I one must be, For nothing hold me, so it please thee hold, That nothing me, a something sweet to thee. Make but my name thy love, and love that still, And then thou lov'st me for my name is Will. Thou blind fool Love, what dost thou to mine eyes, That they behold and see not what they see? They know what beauty is, see where it lies, Yet what the best is, take the worst to be. If eyes corrupt by over-partial looks, Be anchored in the bay where all men ride, Why of eyes' falsehood hast thou forged hooks, Whereto the judgment of my heart is tied? Why should my heart think that a several plot, Which my heart knows the wide world's common place? Or mine eyes seeing this, say this is not To put fair truth upon so foul a face? In things right true my heart and eyes have erred, And to this false plague are they now transferred. When my love swears that she is made of truth, I do believe her though I know she lies, That she might think me some untutored youth, Unlearned in the world's false subtleties. Thus vainly thinking that she thinks me young, Although she knows my days are past the best, Simply I credit her false-speaking tongue, On both sides thus is simple truth suppressed: But wherefore says she not she is unjust? And wherefore say not I that I am old? O love's best habit is in seeming trust, And age in love, loves not to have years told. Therefore I lie with her, and she with me, And in our faults by lies we flattered be. O call not me to justify the wrong, That thy unkindness lays upon my heart, Wound me not with thine eye but with thy tongue, Use power with power, and slay me not by art, Tell me thou lov'st elsewhere; but in my sight, Dear heart forbear to glance thine eye aside, What need'st thou wound with cunning when thy might Is more than my o'erpressed defence can bide? Let me excuse thee, ah my love well knows, Her pretty looks have been mine enemies, And therefore from my face she turns my foes, That they elsewhere might dart their injuries: Yet do not so, but since I am near slain, Kill me outright with looks, and rid my pain. Be wise as thou art cruel, do not press My tongue-tied patience with too much disdain: Lest sorrow lend me words and words express, The manner of my pity-wanting pain. If I might teach thee wit better it were, Though not to love, yet love to tell me so, As testy sick men when their deaths be near, No news but health from their physicians know. For if I should despair I should grow mad, And in my madness might speak ill of thee, Now this ill-wresting world is grown so bad, Mad slanderers by mad ears believed be. That I may not be so, nor thou belied, Bear thine eyes straight, though thy proud heart go wide. In faith I do not love thee with mine eyes, For they in thee a thousand errors note, But 'tis my heart that loves what they despise, Who in despite of view is pleased to dote. Nor are mine cars with thy tongue's tune delighted, Nor tender feeling to base touches prone, Nor taste, nor smell, desire to be invited To any sensual feast with thee alone: But my five wits, nor my five senses can Dissuade one foolish heart from serving thee, Who leaves unswayed the likeness of a man, Thy proud heart's slave and vassal wretch to be: Only my plague thus far I count my gain, That she that makes me sin, awards me pain. Love is my sin, and thy dear virtue hate, Hate of my sin, grounded on sinful loving, O but with mine, compare thou thine own state, And thou shalt find it merits not reproving, Or if it do, not from those lips of thine, That have profaned their scarlet ornaments, And sealed false bonds of love as oft as mine, Robbed others' beds' revenues of their rents. Be it lawful I love thee as thou lov'st those, Whom thine eyes woo as mine importune thee, Root pity in thy heart that when it grows, Thy pity may deserve to pitied be. If thou dost seek to have what thou dost hide, By self-example mayst thou be denied. Lo as a careful huswife runs to catch, One of her feathered creatures broke away, Sets down her babe and makes all swift dispatch In pursuit of the thing she would have stay: Whilst her neglected child holds her in chase, Cries to catch her whose busy care is bent, To follow that which flies before her face: Not prizing her poor infant's discontent; So run'st thou after that which flies from thee, Whilst I thy babe chase thee afar behind, But if thou catch thy hope turn back to me: And play the mother's part, kiss me, be kind. So will I pray that thou mayst have thy Will, If thou turn back and my loud crying still. Two loves I have of comfort and despair, Which like two spirits do suggest me still, The better angel is a man right fair: The worser spirit a woman coloured ill. To win me soon to hell my female evil, Tempteth my better angel from my side, And would corrupt my saint to be a devil: Wooing his purity with her foul pride. And whether that my angel be turned fiend, Suspect I may, yet not directly tell, But being both from me both to each friend, I guess one angel in another's hell. Yet this shall I ne'er know but live in doubt, Till my bad angel fire my good one out. Those lips that Love's own hand did make, Breathed forth the sound that said 'I hate', To me that languished for her sake: But when she saw my woeful state, Straight in her heart did mercy come, Chiding that tongue that ever sweet, Was used in giving gentle doom: And taught it thus anew to greet: 'I hate' she altered with an end, That followed it as gentle day, Doth follow night who like a fiend From heaven to hell is flown away. 'I hate', from hate away she threw, And saved my life saying 'not you'. Poor soul the centre of my sinful earth, My sinful earth these rebel powers array, Why dost thou pine within and suffer dearth Painting thy outward walls so costly gay? Why so large cost having so short a lease, Dost thou upon thy fading mansion spend? Shall worms inheritors of this excess Eat up thy charge? is this thy body's end? Then soul live thou upon thy servant's loss, And let that pine to aggravate thy store; Buy terms divine in selling hours of dross; Within be fed, without be rich no more, So shall thou feed on death, that feeds on men, And death once dead, there's no more dying then. My love is as a fever longing still, For that which longer nurseth the disease, Feeding on that which doth preserve the ill, Th' uncertain sickly appetite to please: My reason the physician to my love, Angry that his prescriptions are not kept Hath left me, and I desperate now approve, Desire is death, which physic did except. Past cure I am, now reason is past care, And frantic-mad with evermore unrest, My thoughts and my discourse as mad men's are, At random from the truth vainly expressed. For I have sworn thee fair, and thought thee bright, Who art as black as hell, as dark as night. O me! what eyes hath love put in my head, Which have no correspondence with true sight, Or if they have, where is my judgment fled, That censures falsely what they see aright? If that be fair whereon my false eyes dote, What means the world to say it is not so? If it be not, then love doth well denote, Love's eye is not so true as all men's: no, How can it? O how can love's eye be true, That is so vexed with watching and with tears? No marvel then though I mistake my view, The sun it self sees not, till heaven clears. O cunning love, with tears thou keep'st me blind, Lest eyes well-seeing thy foul faults should find. Canst thou O cruel, say I love thee not, When I against my self with thee partake? Do I not think on thee when I forgot Am of my self, all-tyrant, for thy sake? Who hateth thee that I do call my friend, On whom frown'st thou that I do fawn upon, Nay if thou lour'st on me do I not spend Revenge upon my self with present moan? What merit do I in my self respect, That is so proud thy service to despise, When all my best doth worship thy defect, Commanded by the motion of thine eyes? But love hate on for now I know thy mind, Those that can see thou lov'st, and I am blind. O from what power hast thou this powerful might, With insufficiency my heart to sway, To make me give the lie to my true sight, And swear that brightness doth not grace the day? Whence hast thou this becoming of things ill, That in the very refuse of thy deeds, There is such strength and warrantise of skill, That in my mind thy worst all best exceeds? Who taught thee how to make me love thee more, The more I hear and see just cause of hate? O though I love what others do abhor, With others thou shouldst not abhor my state. If thy unworthiness raised love in me, More worthy I to be beloved of thee. Love is too young to know what conscience is, Yet who knows not conscience is born of love? Then gentle cheater urge not my amiss, Lest guilty of my faults thy sweet self prove. For thou betraying me, I do betray My nobler part to my gross body's treason, My soul doth tell my body that he may, Triumph in love, flesh stays no farther reason, But rising at thy name doth point out thee, As his triumphant prize, proud of this pride, He is contented thy poor drudge to be, To stand in thy affairs, fall by thy side. No want of conscience hold it that I call, Her love, for whose dear love I rise and fall. In loving thee thou know'st I am forsworn, But thou art twice forsworn to me love swearing, In act thy bed-vow broke and new faith torn, In vowing new hate after new love bearing: But why of two oaths' breach do I accuse thee, When I break twenty? I am perjured most, For all my vows are oaths but to misuse thee: And all my honest faith in thee is lost. For I have sworn deep oaths of thy deep kindness: Oaths of thy love, thy truth, thy constancy, And to enlighten thee gave eyes to blindness, Or made them swear against the thing they see. For I have sworn thee fair: more perjured I, To swear against the truth so foul a be. Cupid laid by his brand and fell asleep, A maid of Dian's this advantage found, And his love-kindling fire did quickly steep In a cold valley-fountain of that ground: Which borrowed from this holy fire of Love, A dateless lively heat still to endure, And grew a seeting bath which yet men prove, Against strange maladies a sovereign cure: But at my mistress' eye Love's brand new-fired, The boy for trial needs would touch my breast, I sick withal the help of bath desired, And thither hied a sad distempered guest. But found no cure, the bath for my help lies, Where Cupid got new fire; my mistress' eyes. The little Love-god lying once asleep, Laid by his side his heart-inflaming brand, Whilst many nymphs that vowed chaste life to keep, Came tripping by, but in her maiden hand, The fairest votary took up that fire, Which many legions of true hearts had warmed, And so the general of hot desire, Was sleeping by a virgin hand disarmed. This brand she quenched in a cool well by, Which from Love's fire took heat perpetual, Growing a bath and healthful remedy, For men discased, but I my mistress' thrall, Came there for cure and this by that I prove, Love's fire heats water, water cools not love.`; var lines = text.split("\n"); var halves = []; lines.forEach(function(line) { var words = line.split(" "); var len = Math.round(words.length/2); var first = words.slice(0,len).join(" "); var last = words.slice(len).join(" "); halves.push(first,last); }); /* Fisher-Yates shuffle https://bost.ocks.org/mike/shuffle/ */ function shuffle(array) { var m = array.length, t, i; while (m) { i = Math.floor(Math.random() * m--); t = array[m]; array[m] = array[i]; array[i] = t; } return array; } function makepoem(array) { var i; var line; shuffle(array); while (poem.hasChildNodes()) { poem.removeChild(poem.lastChild); } for (i = 0; i < 14; i++) { line = array[i] + " " + array[i+20] + "<br>"; poem.innerHTML += line; } } makepoem(halves); document.getElementById("new").onclick = function () { makepoem(halves); }; </script> Thu, 22 Jun 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/poem.html https://evanwill.github.io/_drafts/notes/poem.html Wget and Web Archiving <blockquote> <p>Mini intro to practical Wget for archivists</p> </blockquote> <h2 id="whats-in-a-url">What’s in a URL?</h2> <p><code class="language-plaintext highlighter-rouge">https://example.com/about?key=value#anchor</code></p> <p>protocol + domain name (optional port :80) + path + query with parameters + fragment/anchor</p> <p>A subdomain can be added in front of the main domain name(s). For example, in <code class="language-plaintext highlighter-rouge">lib.uidaho.edu</code> &gt; <code class="language-plaintext highlighter-rouge">lib</code> is a subdomain of <code class="language-plaintext highlighter-rouge">uidaho</code>, which is a subdomain of the top-level domain <code class="language-plaintext highlighter-rouge">edu</code>.</p> <h2 id="dynamic-vs-static-web">Dynamic vs Static web</h2> <p>A static website is a collection of HTML, CSS, JS, images, and other files that are delivered exactly as they are on the server to users. A URL in a static site generally represents a request for an HTML document in a specific file location.</p> <p>Dynamic web uses a server-side scripting language to create pages on the fly when a user makes a request. Thus a URL represents a query, rather than an existing document on the server. Content, templates, and metadata are usually stored in a database. For example, <a href="https://wordpress.org/">WordPress</a> uses the scripting language <a href="https://secure.php.net/">PHP</a> and database <a href="https://www.mysql.com/">MySQL</a>. This enables more complex interactivity such as comments, customized views, user management, and a web-based admin interface.</p> <p>Web crawls harvest the set of pages generated by following the links within a domain. This is a static snap shot at a specific point in time, meaning the dynamic functionality of a website will NOT be captured. Depending on the site design this could lead to loss of information. For example, some information is not fetched until a button click, links are written to the page using JS, images are changed for different browsers, or data is retrieved via a web form (POST request).</p> <p>In a web archive features such as search bar, streaming media, widget embeds, and complex JS won’t work (or will introduce context anomalies). (<a href="https://web.archive.org/web/20150628225214/http://www.lib.uidaho.edu/">example</a>)</p> <p><a href="https://webrecorder.io/">Webrecorder</a> is a tool used to capture features that require user interaction, but this requires actually surfing everything you want to harvest. (example use case, <a href="http://transparent.idaho.gov/Pages/transhome.aspx">Transparent Idaho</a>)</p> <h2 id="dynamic-requests-issues">Dynamic requests issues</h2> <p>UIdaho uses the <a href="https://en.wikipedia.org/wiki/Content_management_system">CMS</a> platform <a href="http://www.sitecore.net/">sitecore</a>. This is a database driven dynamic site written using ASP.NET (?, check their <a href="http://habitat.demo.sitecore.net/">SiteCore demo site</a>).</p> <p>Look at <a href="https://www.uidaho.edu/">https://www.uidaho.edu/</a>, notice that the hyperlinks on page look like <a href="https://www.uidaho.edu/academics.aspx">https://www.uidaho.edu/academics.aspx</a>. Rather than a static HTML document, the links are a dynamic request to “active server page extended” script, which creates the page <a href="https://www.uidaho.edu/academics">https://www.uidaho.edu/academics</a> (which is not academics.html or academics/index.html).</p> <p>This causes problems for a web archive, since we harvest the resulting static HTML, not the aspx script. The file “www.uidaho.edu/academics.aspx” will not be in the web archive, but the document is captured as “www.uidaho.edu/academics”. (<a href="https://web.archive.org/web/20160302145114/http://www.uidaho.edu/">example</a>)</p> <h2 id="wget-prep">Wget Prep</h2> <p><a href="https://www.gnu.org/software/wget/">Wget</a> is a handy <a href="https://www.gnu.org/philosophy/free-sw.en.html">Free</a> command line tool to robustly retrieve documents from the web. It is a standard utility on Linux. On Windows, I suggest setting up a Bash terminal with Wget, for example Cygwin as outlined in <a href="https://evanwill.github.io/_drafts/notes/cygwin.html">Using Cygwin</a> (<em>note: I previously suggested <a href="https://evanwill.github.io/_drafts/notes/cmdr.html">Cmder</a> as a handy portable option. However, we have discovered some bugs when creating WARC files with Wget on Cmder.</em>).</p> <p>See: <a href="https://evanwill.github.io/_drafts/notes/commandline.html">Intro to the Command Line</a></p> <h2 id="basic-wget">Basic Wget</h2> <p>Open a terminal and navigate to a test directory.</p> <p>Wget commands typically take arguments and a URL. Arguments are set using a <code class="language-plaintext highlighter-rouge">--</code> flag. There is a long and short of version of most (e.g. <code class="language-plaintext highlighter-rouge">--help</code> and <code class="language-plaintext highlighter-rouge">-h</code>):</p> <p><code class="language-plaintext highlighter-rouge">wget --help</code></p> <p>To retrieve a single web page or file, just add the URL:</p> <p><code class="language-plaintext highlighter-rouge">wget https://evanwill.github.io/_drafts/notes/commandline.html</code></p> <p>To get a list of files, create a plain text list of urls you want to download, one per line. Use the <code class="language-plaintext highlighter-rouge">--input-file=</code> option to pass that list to wget.</p> <p><code class="language-plaintext highlighter-rouge">wget --input-file=download-file-list.txt</code></p> <p>Adding the <code class="language-plaintext highlighter-rouge">--recursive</code> argument allows Wget to act as a web crawler, following links a page until everything in a domain has been downloaded. All assets will be downloaded in a directory structure mirroring the site organization. A crawl can be limited to a specific file type using the <code class="language-plaintext highlighter-rouge">--accept</code> option. For example, download all PDFs:</p> <p><code class="language-plaintext highlighter-rouge">wget --recursive --accept=pdf http://site-with-pdfs.com/</code></p> <p>When using <code class="language-plaintext highlighter-rouge">--recursive</code>, add <code class="language-plaintext highlighter-rouge">--no-parent</code>, <code class="language-plaintext highlighter-rouge">--level=NUMBER</code>, or <code class="language-plaintext highlighter-rouge">--domains=LIST</code> to limit your crawl:</p> <p><code class="language-plaintext highlighter-rouge">wget -r -np -Apdf http://site-with-pdfs.com/services/workshops/resources/</code></p> <p>Correctly <strong>scoping</strong> your crawl is important, spend time exploring the hierarchy of the site to ensure you will capture what you want, but not download the entire internet…</p> <p>To get an entire web site, use the <code class="language-plaintext highlighter-rouge">--mirror</code> and <code class="language-plaintext highlighter-rouge">--page-requisites</code> arguments. This will recursively crawl the domain and collect everything needed to reproduce the site. Adding <code class="language-plaintext highlighter-rouge">--convert-links</code> will rewrite the internal links to work offline if desired. It is important to add <code class="language-plaintext highlighter-rouge">--wait=SECONDS</code> and <code class="language-plaintext highlighter-rouge">--random-wait</code> to avoid bothering servers (you are unlikely to overload them, but they are likely to block you).</p> <p><code class="language-plaintext highlighter-rouge">wget -mpk --wait=5 --random-wait https://example.com</code></p> <h2 id="archival-wget-with-warc">Archival Wget with WARC</h2> <p><code class="language-plaintext highlighter-rouge">wget --help | grep warc</code></p> <p><a href="https://www.loc.gov/preservation/digital/formats/fdd/fdd000236.shtml">WARC</a> is a web archive format that stores page content, response headers, and metadata for a group of web pages. One WARC can contain all the pages gathered during a web harvest. In addition to HTML documents, it can contain binary content such as images.</p> <p>Wget can create a WARC for any crawl simply by adding the flag <code class="language-plaintext highlighter-rouge">--warc-file="filename"</code> to the command. Wget will harvest the site assets as normal, but additionally create a WARC compressed as a <a href="https://en.wikipedia.org/wiki/Gzip">gzip</a> file (<code class="language-plaintext highlighter-rouge">.gz</code>). For larger sites it’s a good idea to add <code class="language-plaintext highlighter-rouge">--warc-max-size=1G</code> to limit the max size of each WARC so they don’t get too big.</p> <p>If the server refuses to give content to wget’s default user agent (sometimes identified as a robot), you can send a different one, like <code class="language-plaintext highlighter-rouge">--user-agent=Mozilla</code>. Occasionally it may be necessary to ignore <a href="https://en.wikipedia.org/wiki/Robots_exclusion_standard">“robots.txt”</a> for archival purposes. Add <code class="language-plaintext highlighter-rouge">--execute robots=off</code> to the command.</p> <p>Test example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget --mirror --page-requisites --wait=2 --random-wait --no-parent --trust-server-names --warc-file="test-archive" http://www.example.com/path/sometopic/ </code></pre></div></div> <p>More complete example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget -mpkE --span-hosts --domains=example.com,www.example.com,sub.example.com --warc-file="test-archive" --warc-max-size=1G --warc-cdx --user-agent=Mozilla -e robots=off --wait=2 --random-wait http://www.example.com </code></pre></div></div> <p>More examples in use:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget -mpkE -np --trust-server-names --warc-max-size=1G --warc-file="test-archive" --warc-cdx --wait=1 --random-wait https://www.example.com/path/news/newsletter </code></pre></div></div> <p>Limit using <code class="language-plaintext highlighter-rouge">--include-directories=</code> (instead of <code class="language-plaintext highlighter-rouge">--no-parent</code>), be sure to include all directories for page requisites:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget -mpkE --trust-server-names -I /~,/css,/fonts,/Images,/Scripts,/path/news/newsletters --warc-max-size=1G --warc-file="test-archive" --warc-cdx --wait=0.5 https://www.example.com/path/news/newsletters/ </code></pre></div></div> <h2 id="playback">Playback</h2> <p>Options:</p> <ul> <li><a href="https://github.com/webrecorder/webrecorderplayer-electron">Webrecorder Player</a> (actively developed desktop app created by <a href="https://webrecorder.io/">Webrecorder</a> / <a href="https://rhizome.org/">Rhizome</a>. Currently seems extremely slow and buggy on some computers when using warc not created by Webrecorder.)</li> <li><a href="https://github.com/ikreymer/webarchiveplayer">Webarchive Player</a> (not actively developed, but still works. simple desktop app)</li> <li><a href="https://github.com/ikreymer/pywb">pywb</a> (“Python WayBack” Python package. Lots of features using wb-manager commandline utility. Can serve and manages multiple warc files in a collection.)</li> </ul> <h2 id="workflow-questions">Workflow questions</h2> <ul> <li>Policy</li> <li>Harvest</li> <li>Store</li> <li>Catalogue</li> <li>Access</li> </ul> <h2 id="reference">Reference:</h2> <ul> <li>ArchiveTeam, <a href="http://www.archiveteam.org/index.php?title=Wget_with_WARC_output">“Wget with WARC output”</a>.</li> <li>IIPC <a href="https://github.com/iipc/awesome-web-archiving">Awesome Web Archiving</a>.</li> <li><a href="http://www.netpreserve.org/web-archiving/overview">IIPC overview</a>.</li> <li>Corey Davis, “Archiving the Web: A Case Study from the University of Victoria”, <em>code4lib</em> 26 (2014), <a href="http://journal.code4lib.org/articles/10015">http://journal.code4lib.org/articles/10015</a>.</li> <li>Adrian Brown, <em>Archiving websites : a practical guide for information management professionals</em> (2006). <a href="http://search.lib.uidaho.edu/UID:everything:CP71127753580001451">http://search.lib.uidaho.edu/UID:everything:CP71127753580001451</a></li> <li>Maureen Pennock, “Web-Archiving”, <em>DPC Technology Watch Report</em> 13 (2013), <a href="http://www.dpconline.org/docman/technology-watch-reports/865-dpctw13-01-pdf/file">http://www.dpconline.org/docman/technology-watch-reports/865-dpctw13-01-pdf/file</a></li> <li>Jinfang Niu, “An Overview of Web Archiving”, DLib 18, 3/4 (2012), <a href="http://www.dlib.org/dlib/march12/niu/03niu1.html">doi:10.1045/march2012-niu1</a>.</li> <li><a href="https://library.stanford.edu/projects/web-archiving/archivability">“Archivability”</a> guide, Stanford Libraries</li> <li><a href="http://archiveready.com/">ArchiveReady</a> (test sites for archivability)</li> <li><a href="http://oldweb.today/">Oldweb.today</a> (surf web archives in emulated historic web browsers)</li> </ul> <p>Collection Development Policy examples:</p> <ul> <li>Columbia University Libraries, <a href="https://library.columbia.edu/bts/web_resources_collection/policies.html">“Web Resources Collection Program”</a></li> <li>Stanford Libraries, <a href="http://library.stanford.edu/projects/web-archiving/collection-development">“Collection development”</a></li> <li>MSU Archives, <a href="http://archives.msu.edu/collections/documents/CollectionPlan_v3.pdf">“Web Site Collection Plan”</a> (<a href="http://archives.msu.edu/collections/webarchive.php">Web Archives @ MSU</a>)</li> <li>Michael Shallcross, “On the Development of the University of Michigan Web Archives: Archival Principles and Strategies” SAA Campus Case Studies 13 (2011) <a href="http://files.archivists.org/pubs/CampusCaseStudies/Case13Final.pdf">http://files.archivists.org/pubs/CampusCaseStudies/Case13Final.pdf</a>.</li> </ul> <p>Tools:</p> <ul> <li><a href="https://github.com/DIA-NZ/webcurator">Web Curator Tool</a></li> <li><a href="https://github.com/netarchivesuite/netarchivesuite">NetarchiveSuite</a> (<a href="https://sbforge.org/display/NASDOC/Quickstart+with+Vagrant">vagrant</a>, package to manage harvesting developed by The Royal Danish Library)</li> <li><a href="https://github.com/machawk1/wail">WAIL</a> (GUI interface to work with Heritrix and OpenWayback, buggy in my experience, <a href="http://machawk1.github.io/wail/">repo</a>)</li> <li><a href="http://warcreate.com/">WARCreate</a> (Chrome plugin for one off WARC creation)</li> <li><a href="https://github.com/chfoo/wpull">Wpull</a> and <a href="https://github.com/ludios/grab-site">grab-site</a> (archival focused Wget alternative in development)</li> </ul> <p>Videos:</p> <ul> <li>IIPC dramatic <a href="https://youtu.be/pU32rjTaMFE">“Why Archive the Web?”</a></li> <li>LOC <a href="https://youtu.be/T0943YkhLWU">“Web Archiving”</a></li> <li>UK WebArchive, <a href="https://youtu.be/ubDHY-ynWi0">“What is a web archive?”</a></li> </ul> Wed, 07 Jun 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/wget-archives.html https://evanwill.github.io/_drafts/notes/wget-archives.html Handy OpenRefine Functions to Remember <p>This page lists some handy functions to use for data wrangling tasks.</p> <h2 id="combining-columns">Combining columns</h2> <p>Combining columns can be tricky because merging a blank cell cell with another value results in an error. To avoid issues, first facet by blank and combine only non-empty cells with a transform like: <code class="language-plaintext highlighter-rouge">value + " " + cells["col_2"].value</code></p> <h2 id="cross-function">Cross function</h2> <p>Use <code class="language-plaintext highlighter-rouge">cross</code> to retrieve columns from other OpenRefine projects based on a common column.</p> <ol> <li>Open the two projects you want to join</li> <li>Identify the common column to be used as a key. Ensure that it is a unique identifier, or cross won’t work how you expect. You can create a new unique column on both projects by adding an index number an existing common column (on common column &gt; Add column based on this column… &gt; <code class="language-plaintext highlighter-rouge">value + "-" + row.index</code> ).</li> <li>On the project where you want to import values, go to the key column you identified, and Add column based on this column…</li> <li>In the expression window, put: <code class="language-plaintext highlighter-rouge">cell.cross("name_of_other_project", "name_of_key_column").cells["name_of_column_you_want_to_import"].value[0]</code></li> </ol> <p>You should have a new column that has the correct values from the other project.</p> <h2 id="string--array-functions">String + Array functions</h2> <p>A powerful way to interact with multi-valued text fields (values with a separator in them, e.g. <code class="language-plaintext highlighter-rouge">dogs; muffins; cats; idaho</code>) or large strings (such as the text of poems or web scrape) is to turn them into arrays, then use array functions to manipulate. You might be surprized by how useful it is to break text values into arrays!</p> <p>Create an array from any string by using the <code class="language-plaintext highlighter-rouge">split(value, expression)</code> function. The expression is the character or pattern you want to split the string up on, often a new line or a deliminator in a list.</p> <p>For example, split on semi-colon <code class="language-plaintext highlighter-rouge">value.split(";")</code> (a classic multi-valued cell list), split on spaces <code class="language-plaintext highlighter-rouge">value.split(" ")</code> (basic word array), or split on a new line <code class="language-plaintext highlighter-rouge">value.split(/\n/)</code> (lines of a text).</p> <p>Once the cell is an array, it can be rearranged and sliced in many ways with <a href="https://openrefine.org/docs/manual/grelfunctions#array-functions">array functions</a>. Finally, reconstitute the string by using <code class="language-plaintext highlighter-rouge">join()</code> on the array (usually using the same deliminator that you used to split!).</p> <p>For example, if we had a column with lists of tags like “dogs;cats;muffins” as cell values, we could put each cell in alphabetic order using:</p> <p><code class="language-plaintext highlighter-rouge">value.split(";").sort().join(";")</code></p> <p>Remove the first item in the list:</p> <p><code class="language-plaintext highlighter-rouge">value.split(";").slice(1).join(";")</code></p> <p>Remove the last item in the list:</p> <p><code class="language-plaintext highlighter-rouge">value.split(";").slice(0,-1).join(";")</code></p> <p>Remove duplicate values in the list:</p> <p><code class="language-plaintext highlighter-rouge">value.split(";").uniques().join(";")</code></p> <p>Or trim the white space for each value:</p> <p><code class="language-plaintext highlighter-rouge">forEach(value.split(";"),e,e.trim()).join(";")</code></p> <p>If you had lines of a poem or text as a cell value you could do the same types of operations. For example, remove the first line of a poem:</p> <p><code class="language-plaintext highlighter-rouge">value.split(/\n/).slice(1).join("\n")</code></p> <p>Remove the last two lines:</p> <p><code class="language-plaintext highlighter-rouge">value.split(/\n/).slice(0,-2).join("\n")</code></p> <p>Or trim the white space around each line:</p> <p><code class="language-plaintext highlighter-rouge">forEach(value.split(/\n/),e,e.trim()).join("\n")</code></p> <h2 id="de-dupe-rows">De-dupe Rows</h2> <p>Deduplicate rows using the values in a key column:</p> <ul> <li>On the key column to deduplicate, click “Sort”, and choose sort method.</li> <li>Next to the show rows selection above the table, click on the “Sort” menu (this menu only shows up once you add a Sort). Select “Reorder row permanently” (if you do not do this step, sort is just visual and did not transform the data).</li> <li>On the key column, select “Edit cells” &gt; “Blank down”.</li> <li>On the key column, facet on blank, select true (the blank values), and remove all matching rows.</li> </ul> <h2 id="compare-two-columns">Compare two columns</h2> <p>Create new “equal” column using expression: <code class="language-plaintext highlighter-rouge">if(cells["column1"].value == cells["column2"].value, "True", "False")</code></p> <h2 id="add-leading-zeros">Add leading zeros</h2> <p>If the column has numbers that should have leading zeros, add the number of zeros it should have in total digits, sliced by value length. For example, if you had “12345”, “123456”, “1234567”, and wanted them all to be 8 digits with leading zeros, transform using:</p> <p><code class="language-plaintext highlighter-rouge">"00000000"[0,8-length(value)] + value</code></p> <p>You can also create a new row identifier with leading zeros using the <code class="language-plaintext highlighter-rouge">row.index</code> variable. For example,</p> <p><code class="language-plaintext highlighter-rouge">"row_id_" + "0000"[0,4-length(row.index +1)] + (row.index +1)</code></p> <h2 id="remove-leading-or-trailing-character">Remove leading or trailing character</h2> <p>In regex <code class="language-plaintext highlighter-rouge">^</code> is start of string and <code class="language-plaintext highlighter-rouge">$</code> means end of string, which can be used in a <code class="language-plaintext highlighter-rouge">replace</code> statement.</p> <p>Remove “T” from front of string:</p> <p><code class="language-plaintext highlighter-rouge">value.replace(/^T/,"")</code></p> <p>Remove trailing period, “.” at end of string:</p> <p><code class="language-plaintext highlighter-rouge">value.replace(/\.$/,"")</code></p> <p>(note the “.” needs to be escaped with <code class="language-plaintext highlighter-rouge">\</code> since it has a meaning in regex)</p> <h2 id="facet-by-facet-count">Facet by facet count</h2> <p>Sometimes you have a column with many repeating values, that you might explore using a text facet. In the text facet pane you can sort by facet count, but you would have to manually select each if you wanted a subset based on the facet count. To select a group of rows based on the facet count of a value in a column:</p> <p>First, if you just need all the values with &gt; 1 count, you can use the built in Facet &gt; Customized facets &gt; Duplicates facet. This returns “true” for rows with &gt; 1 count, false if the value is unique.</p> <p>Second, if you need a subset based on the count, create a new column using the <code class="language-plaintext highlighter-rouge">facetCount</code> function. On the column you want a count for, Edit column &gt; Add column based on this column, and use:</p> <p><code class="language-plaintext highlighter-rouge">value.facetCount("value","name_of_the_column")</code></p> <p>The result will be a number (same as the “count” given in facet pane), which you can then filter with a numeric facet. Note in this context facetCount seems a bit non-intuitive since you have provide “value” and the name of the column again–facetCount is set up with flexibility to do some more complicated operations by adding an expression to the value or matching values in a different column (but weirdly requires quotes around the expression which isn’t typical of other functions).</p> <p>The “name_of_column” could be a different column than the one the cell is in. If you are using the current column, you can use the builtin variable <code class="language-plaintext highlighter-rouge">columnName</code> instead, like <code class="language-plaintext highlighter-rouge">value.facetCount("value",columnName)</code>.</p> <p>If you want to add transformations to the value first, apply the same to the value feeding in as the first argument.</p> <p><code class="language-plaintext highlighter-rouge">value.fingerprint().facetCount("value.fingerprint()",columnName)</code></p> <h2 id="parse-json">Parse JSON</h2> <p>It is common to get JSON data when fetching from APIs using Refine. It’s easy to grab specific dictionary values out of JSON cells using the built in JSON parse function. From the column with JSON, create a new column and transform with <code class="language-plaintext highlighter-rouge">value.parseJson().get('key')</code>, where ‘key’ is the dictionary key you want to extract.</p> <p>For example, if the cell contained <code class="language-plaintext highlighter-rouge">{ "type" : "dog", "color" : "brown", "size" : "large" }</code>, and your transform was<code class="language-plaintext highlighter-rouge">value.parseJson().get('color')</code>, you would get the value “brown” in your new column. (<em>note</em>: if your key does not have spaces, you can use the shorter version like <code class="language-plaintext highlighter-rouge">value.parseJson().color</code>)</p> <p>To get multiple values from the same key, combine with <code class="language-plaintext highlighter-rouge">forEach()</code>. For example, to extract all the keywords from a cell with the JSON <code class="language-plaintext highlighter-rouge">{'language': 'en', 'keywords': [{'text': 'dogs', 'relevance': 0.979292}, {'text': 'muffins', 'relevance': 0.977987}, {'text': 'cats', 'relevance': 0.969001}, {'text': 'idaho', 'relevance': 0.967973}] }</code>, transform with <code class="language-plaintext highlighter-rouge">forEach(value.parseJson().keywords,v,v.text).join("; ")</code>, resulting in the new cell value of <code class="language-plaintext highlighter-rouge">dogs; muffins; cats; idaho</code>.</p> <h2 id="parsing-contentdm-tsv-export">Parsing CONTENTdm TSV export</h2> <p>CONTENTdm and some other platforms export metadata in TSV format which often end up with parsing errors on import. When starting a project:</p> <ul> <li>make sure you select the correct encoding (for CONTENTdm = “UTF-8”)</li> <li>uncheck the option <code class="language-plaintext highlighter-rouge">Use character " to enclose cells containing column separators</code></li> <li>parsing issues are often not immediately apparent, so carefully check the number of records you expect and view the last rows of your data</li> </ul> <h2 id="local-server-to-input-data-from-files">Local server to input data from files</h2> <p>A goofy approach to get a bunch of text data into a spreadsheet from individual files is to serve the directory of files up on a local server then grab them using Refine’s fetch. This avoids many limitations of working with conventional spreadsheets, and lets you parse the files into data using Refine methods such as parseHtml, split columns, or split multivalued cells.</p> <p>For example, imagine I have a folder of hundreds of HTML files that I want to parse into data:</p> <ul> <li>create a list of the files on commandline with <code class="language-plaintext highlighter-rouge">ls &gt; list.txt</code></li> <li>create Refine project using <code class="language-plaintext highlighter-rouge">list.txt</code> so each row will equal one of the files</li> <li><a href="/_drafts/notes/web-server.html">start a local server</a> in the folder of files and note where it is served (e.g. <code class="language-plaintext highlighter-rouge">localhost:8080</code>)</li> <li>Add column based on the filenames with the local url, e.g. <code class="language-plaintext highlighter-rouge">"http://localhost:8080/" + value</code></li> <li>Add column by fetching urls</li> </ul> <p>Now you have a spreadsheet with a giant amount of text data!</p> <h2 id="common-html-parsing">Common HTML parsing</h2> <p>Combining “Create new column by fetching from URL” and the <code class="language-plaintext highlighter-rouge">parseHtml()</code> GREL function is a powerful and flexible method to harvest data from the web or scrape sites. Always remember to use <code class="language-plaintext highlighter-rouge">.toString()</code> or <code class="language-plaintext highlighter-rouge">.join("|")</code> at the end of your parsing statements or you will end up with empty cells even through your html parsing is correct!</p> <p>I often use these GREL statements to extract stuff out of HTML:</p> <ul> <li>get all image src out: <code class="language-plaintext highlighter-rouge">forEach(value.parseHtml().select('img'),i,i.htmlAttr('src')).join("; ")</code></li> <li>get all links out: <code class="language-plaintext highlighter-rouge">forEach(value.parseHtml().select('a'),i,i.htmlAttr('href')).join("; ")</code></li> </ul> <h2 id="info-on-using-more-memory">Info on using more memory</h2> <p><a href="https://docs.openrefine.org/manual/installing/#increasing-memory-allocation">https://docs.openrefine.org/manual/installing/#increasing-memory-allocation</a></p> <h2 id="linux-issue-with-java-version-not-found-v30">Linux issue with Java version not found (V&lt;3.0)</h2> <p>If you have an up-to-date version of Java installed on linux (<code class="language-plaintext highlighter-rouge">openjdk-11-jre</code>), starting Refine V&lt;3.0 with <code class="language-plaintext highlighter-rouge">./refine</code> will throw an error saying you don’t have Java installed or need to set <code class="language-plaintext highlighter-rouge">$JAVA_HOME</code>. The message is false (no matter how much you mess with <code class="language-plaintext highlighter-rouge">$JAVA_HOME</code> it won’t work!), there is a bug in <code class="language-plaintext highlighter-rouge">./refine</code> where it checks for older versions of Java as “up-to-date” and was not future proofed.</p> <p>To fix the bug, you can try a newer version of Refine (it is fixed in 3.0+), or just grab the updated <code class="language-plaintext highlighter-rouge">./refine</code> file and manually replace your faulty one:</p> <ul> <li>in your openrefine directory (e.g. <code class="language-plaintext highlighter-rouge">openrefine-2.8/</code>), delete <code class="language-plaintext highlighter-rouge">refine</code>.</li> <li>Go to this <a href="https://github.com/OpenRefine/OpenRefine/blob/5f9777ffae1568165da8df006e5d7465d91f4b78/refine">updated version</a>, click “Raw”, save as “refine” in the openrefine directory.</li> <li>Done!</li> </ul> Thu, 01 Jun 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/open-refine-tips.html https://evanwill.github.io/_drafts/notes/open-refine-tips.html Transfer iPhone to Linux <p>There was a brief time when you could simply plug your iPhone in to your Linux computer via USB and access the photos. For all logical people this seems like sensible functionality. So of course, Apple killed it with the latest iOS 10 updates (cause Apple hates users, linux, and openness as far as I can tell based on my experience).</p> <p>But maybe you are like me, you have an iPhone that some one gave you and you need to get the photos off. Don’t mess around with searching years and years of forum posts for solutions, because iOS changes constantly and intentionally prevents the functionality you want and expect. If you have iOS &lt;=9, Ubuntu will work with it automatically. If you have iOS &gt;=10, as of around March 2017 none of the old solutions to directly connect via USB will work. (*Note: as of 2020, it sort of works again, but <a href="https://evanwill.github.io/_drafts/notes/heic.html">see my notes about HEIC transfer issues</a>)</p> <p>The utility package <code class="language-plaintext highlighter-rouge">libimobiledevice</code> that allowed connection to iOS ships with Ubuntu now, but doesn’t seem to work alone with iOS 10+. Some have suggested downloading the most recent source code and manually building <code class="language-plaintext highlighter-rouge">libimobiledevice</code> works. However, with most i-devices, adding the simply <code class="language-plaintext highlighter-rouge">ifuse</code> package seems to bring back normal plugin functionality, but you have to manually mount the iphone’s drive.</p> <p>Install it via <code class="language-plaintext highlighter-rouge">sudo apt install ifuse</code>. Then you can use <code class="language-plaintext highlighter-rouge">ifuse</code> to mount the iPhone file system:</p> <ol> <li>make sure it is connected: <code class="language-plaintext highlighter-rouge">idevicepair validate</code></li> <li>create a mount point: <code class="language-plaintext highlighter-rouge">mkdir ~/phone</code></li> <li>mount the phone’s file system: <code class="language-plaintext highlighter-rouge">ifuse ~/phone</code></li> <li>now you can navigate to the directory and copy files off the phone (images are in “DCIM”)</li> <li>unmount the iphone: <code class="language-plaintext highlighter-rouge">fusermount -u ~/phone</code></li> </ol> <p>Now if that didn’t work, oddly enough, the easiest solution seems to be FTP:</p> <ol> <li>On the iphone, install <code class="language-plaintext highlighter-rouge">FileExplorer</code> by Skyjos.</li> <li>You can’t directly share your photo library, so using the <code class="language-plaintext highlighter-rouge">FileExplorer</code> app, create a new “local” folder and copy your photos to it.</li> <li>On the Local tab, click the wifi icon to start a FTP server.</li> <li>Using the IP address and port given by the app, connect from your computer. The url is basically <code class="language-plaintext highlighter-rouge">ftp://[ip-address]:[port]</code>. On Ubuntu the easiest method is to use the built in “connect to a server” feature of the Nautilus file explorer. Open the file browser, click on “Other Locations”, look at the bottom of the window for “Connect to Server”. Type in the url and click connect. Now you can copy &amp; paste where ever you would like!</li> </ol> Thu, 01 Jun 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/iphone-transfer.html https://evanwill.github.io/_drafts/notes/iphone-transfer.html Git notes <h2 id="quick-fix-the-last-commit">Quick fix the last commit</h2> <p>If you just made a commit, <em>and haven’t pushed it yet</em>, but suddenly realize you forgot to add something, need to change the message, or tweak a file, use <code class="language-plaintext highlighter-rouge">git commit --amend</code>.</p> <ol> <li>make the changes you need</li> <li><code class="language-plaintext highlighter-rouge">git add</code> any changes (nothing if you are just changing the commit message)</li> <li><code class="language-plaintext highlighter-rouge">git commit --amend -m "new commit message that replaces the old one"</code></li> </ol> <p>This commit will just be combined with the last one into a single new commit as if the first one never happened.</p> <h2 id="undo-one-file">Undo one file</h2> <p>Checkout the version of the file you want from the history, then commit that file. For example, go back a version from one commit back:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git checkout HEAD~1 example.txt git add example.txt git commit -m "undo example changes" </code></pre></div></div> <h2 id="undo-a-whole-commit">Undo a whole commit</h2> <p><code class="language-plaintext highlighter-rouge">git revert &lt;somehash&gt;</code> will undo a commit you list by creating a new commit reversing those changes. It doesn’t go back to that point in the history or undo other commits along the way, it just does exactly the opposite of that one commit. Get the hash for the commit from the GitHub commits page or <code class="language-plaintext highlighter-rouge">git log --oneline</code> and add it to the end of <code class="language-plaintext highlighter-rouge">git revert</code>.</p> <h2 id="undo-a-merge">Undo a merge</h2> <p>You can undo a merge commit, which will undo the whole batch of changes created by the merge–the exact opposite of the merge.</p> <p>However, when reverting merge commits, you need an extra option, because you need to tell it which side of the history you want to keep, i.e. the parent or the merging branch. Normally you would keep the parent with option <code class="language-plaintext highlighter-rouge">-m 1</code>, the command ends up looking like:</p> <p><code class="language-plaintext highlighter-rouge">git revert -m 1 &lt;somehash&gt;</code></p> <p>Your history will look wonky (and can potentially have odd effects if you try to merge the same branch again), but it is usually the best way to avoid problems collaborating on a remote.</p> <h2 id="graph">Graph</h2> <p>You can actually reproduce those pretty visualizations of history you see on GitHub in the terminal. Try: <code class="language-plaintext highlighter-rouge">git log --graph --abbrev-commit --date=relative</code></p> <h2 id="file-naming-for-collaboration">file naming for collaboration!</h2> <p>Be <em>extra careful</em> of file naming case sensitivity when working with people across Linux, Mac, and Windows.</p> <p>Git is developed and designed for Linux. In Linux file systems, filenames are case sensitive. So files like “README.md”, “readme.md”, and “ReadMe.md” are three totally different files, and can be tracked and committed by Git. GitHub and other web services run on Linux so also allow case sensitive file naming.</p> <p>However, Windows and Mac file systems are by default case insensitive. On Window and Mac files like “README.md”, “readme.md”, and “ReadMe.md” can not exist at the same time, and all refer to a single file.</p> <p>This can lead to nasty Git errors if a Linux user commits files that would be the same if case insensitive. E.g. Linux user commits “README.md” and “readme.md” in the same directory, if Windows and Mac users pull the update they end up with fatal errors and a lot of confusion. It can’t be gracefully fixed on Windows or Mac, so it is best to clean it up on GitHub or Linux, then do a fresh clone (see <a href="https://xkcd.com/1597/">xkcd git</a>).</p> <h2 id="git-merge-error-message">Git Merge Error Message</h2> <p>Recent Git installations (late 2023+) do not have a default behavior set for git pull, so the first time you encounter a conflict and merge, you will get a big error message asking which approach you want to use (merge or rebase). It looks like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>hint: You have divergent branches and need to specify how to reconcile them. hint: You can do so by running one of the following commands sometime before hint: your next pull: hint: hint: git config pull.rebase false # merge hint: git config pull.rebase true # rebase hint: git config pull.ff only # fast-forward only </code></pre></div></div> <p>To avoid this error, you can set the old default behavior in your config, which is:</p> <p><code class="language-plaintext highlighter-rouge">git config --global pull.rebase false.</code></p> <h2 id="helpful">Helpful</h2> <ul> <li><a href="https://github.com/edx/edx-platform/wiki/How-to-Rebase-a-Pull-Request">Rebase a Pull Request</a></li> <li><a href="https://help.github.com/articles/about-pull-request-merges/">About pull request merges</a></li> <li><a href="https://github.com/blog/2243-rebase-and-merge-pull-requests">Rebase and merge</a></li> <li>Amusing way to view Git Log, <a href="https://github.com/artemave/StarLogs">StarLogs</a></li> <li><a href="https://www.gitignore.io/">gitignore.io</a> (ready made ignore templates for various project types)</li> </ul> <h2 id="git-in-classroom">Git in Classroom</h2> <ul> <li><a href="https://classroom.github.com/">GitHub Classroom</a></li> <li><a href="http://www.storybench.org/use-github-lessons-classroom-newsroom/">Why you should use GitHub: Lessons for the classroom and newsroom</a></li> <li><a href="http://www.digitalpedagogylab.com/hybridped/push-pull-fork-github-for-academics/">GitHub for Academics</a></li> <li><a href="https://gist.github.com/chrisdaaz/1e894dc5af2e2c9cf0cc75d057fcf79f">git for librarians reading list</a></li> </ul> <h2 id="github">GitHub</h2> <ul> <li>use Emoji in GitHub markdown, see <a href="https://www.webpagefx.com/tools/emoji-cheat-sheet/">Emoji cheat sheet</a></li> </ul> Thu, 01 Jun 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-notes.html https://evanwill.github.io/_drafts/notes/git-notes.html Kill Unresponsive Apps using Terminal <p>Lately on Ubuntu Firefox has been going unresponsive, then makes System Monitor go unresponsive when trying to kill it. Very frustrating, and I always wish I remembered how to kill processes on the command line.</p> <p>Well, it’s not very hard, so hopefully I will really remember if I write it down here (since I can’t access my notes if Firefox is freezing everything)…</p> <p>Basically, you need to know the process ID of the application, then send a <code class="language-plaintext highlighter-rouge">kill</code> command for that PID.</p> <ol> <li>Find the PID, use one of these methods depending on what you know: <ul> <li><code class="language-plaintext highlighter-rouge">top</code>, simply type it into the terminal to get a visual display of the running processes and system resources, similar to System Monitor. The PID is the first column, and the offending unresponsive app is often at the top, using up 100% of one CPU core.</li> <li><code class="language-plaintext highlighter-rouge">ps x</code>, will give a static list of all your processes (or <code class="language-plaintext highlighter-rouge">ps aux</code> for all users). You can sort through this using grep, like <code class="language-plaintext highlighter-rouge">ps aux | grep firefox</code>.</li> <li><code class="language-plaintext highlighter-rouge">pgrep</code>, if you are in a hurry and know the offending app by name, try <code class="language-plaintext highlighter-rouge">pgrep firefox</code> to return a single PID.</li> </ul> </li> <li>Kill the process: <ul> <li>first, try <code class="language-plaintext highlighter-rouge">kill</code> plus the PID, like <code class="language-plaintext highlighter-rouge">kill 10705</code>. This sends a polite message to the process to shutdown. If the app is unresponsive, it probably won’t work.</li> <li>then, force the kill by using the SIGKILL flag (<code class="language-plaintext highlighter-rouge">-9</code> or <code class="language-plaintext highlighter-rouge">-KILL</code>), which directly tells the kernel to kill the process, rather than asking the app first. For example, <code class="language-plaintext highlighter-rouge">kill -KILL 10705</code></li> </ul> </li> </ol> <p>Don’t forget, <code class="language-plaintext highlighter-rouge">kill -KILL</code>!</p> Tue, 30 May 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/kill.html https://evanwill.github.io/_drafts/notes/kill.html Create a GitHub Organization <p>A GitHub organization is a useful tool to collaborate with a group and ensure continuity in situations with members may move on from a project or lab. GitHub organizations are NOT a separate account or profile, but are a group of users, i.e. you can’t log in as an Org. One or more persons can be the Owner with full admin control over the org including managing members.</p> <p>To start an organization, click the plus sign icon on the upper right of the GitHub menu bar and select “Create organization”. Give your org a good name, preferably with no spaces, since this will be used for your page and URLs. Select the Free account. Then add members!</p> <p>Now, when creating a new repository, all members can use the drop down option to create the repository under their own account or under the organization. Repositories owned by the Org will be accessible and managed by the Owner accounts. They stay with the Org even if the original creator leaves the Org.</p> <p>Accounts in your Org have one of two roles:</p> <ul> <li>Owner = full admin access to everything</li> <li>Member = can see all teams and members, and can create new repos</li> </ul> <p>Your Org can create Teams. Set up teams to manage groups with access to specific repositories. Teams also have their own page that hosts a discussion forum, and can be <code class="language-plaintext highlighter-rouge">@</code> mentioned to notify all members in other discussion comments.</p> <p>People who need access to a repository, but aren’t part of the Org, are added as “Outside Collaborators”.</p> <h2 id="education-discount">Education discount</h2> <p>Visit the <a href="https://education.github.com/">GitHub Education page</a> to learn about current discounts. In general, they grant free private repositories to non-profit, educational organizations for teaching purposes. Click the “Request a discount” button and fill out the request form will full information about your Org to get the discount applied.</p> Sat, 06 May 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/github-org.html https://evanwill.github.io/_drafts/notes/github-org.html Using Cmder <p><strong>Out of date! I haven’t used this for a long time!</strong></p> <p><a href="http://cmder.net/">Cmder</a> is a fully featured terminal emulator for Windows that can host a variety of shells, including Git for Windows Git Bash (which comes bundled with the full version). It is handy because it is full portable–simply unzip and start using it. Once you configure Cmder, you can even copy the directory to a USB and use/share your fully customized version. This is great for workshops.</p> <h2 id="install">“Install”</h2> <p><a href="http://cmder.net/">Download</a> the <strong>full</strong> version and unzip to a permanent location (such as <code class="language-plaintext highlighter-rouge">C:\</code>).</p> <p>In the <code class="language-plaintext highlighter-rouge">cmder</code> directory, double click <code class="language-plaintext highlighter-rouge">Cmder.exe</code> to get started. Windows might give a warning about programs downloaded from the internet that you have to Okay to run. ConEmu (the terminal emulator) might also suggest you download a newer version, click “Cancel” to ignore or the first download option to automatically install the update. Pin the icon to the taskbar to make starting it easier.</p> <p>By default Cmder opens with the standard Windows <code class="language-plaintext highlighter-rouge">cmd.exe</code> shell, but you can open other shells in a new tab by clicking the drop down next to the plus icon in the lower right. Options include Windows CMD (bad), PowerShell (bad), mintty (better, same as Git Bash), or bash (best). You can (and should) change the default shell. Click the menu button in the lower right and select “settings”. Click on “Startup”, then check the “Specified named task” option and select “{bash::bash}” from the drop down, and “Save settings”. Now when Cmder starts, Bash will be the default terminal.</p> <p>On Bash, your drive letters will be translated to UNIX-like paths. For example, Windows <code class="language-plaintext highlighter-rouge">C:\</code> will be <code class="language-plaintext highlighter-rouge">/c/</code>. Your home directory will probably be <code class="language-plaintext highlighter-rouge">/c/Users/username</code>.</p> <p>Similar to <a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">Git Bash</a>, binaries for standard utilities can be placed the <code class="language-plaintext highlighter-rouge">bin</code> directory to add functionality. Anything in the <code class="language-plaintext highlighter-rouge">bin</code> will be on the PATH, i.e. you can use it directly on the command line. Sometimes the Windows binaries have funny filenames, so you should rename the <code class="language-plaintext highlighter-rouge">.exe</code> file to the standard name.</p> <h2 id="add-nano-editor">Add Nano editor</h2> <p>Unlike Git Bash, Cmder bash supports adding Nano. Get the Nano binary from Nano <a href="https://www.nano-editor.org/dist/win32-support/">win32-support</a> page. You just need the <code class="language-plaintext highlighter-rouge">.exe</code> file, which is named <code class="language-plaintext highlighter-rouge">nano-git-0d9a7347243.exe</code> (as of this writing). Download it, rename the file to <code class="language-plaintext highlighter-rouge">nano.exe</code>, and copy to the Cmder <code class="language-plaintext highlighter-rouge">bin</code> directory.</p> <p>Now, Nano editor can be started from the Bash shell using a command such as <code class="language-plaintext highlighter-rouge">nano test.txt</code>.</p> <h2 id="add-wget">Add Wget</h2> <p>Download the Windows binary from one of the options listed at <a href="http://wget.addictivecode.org/FrequentlyAskedQuestions.html#download">Wget FAQ</a> (for example, from <a href="https://eternallybored.org/misc/wget/current/wget64.exe">eternallybored wget64.exe</a>. Rename the file to <code class="language-plaintext highlighter-rouge">wget.exe</code>, and copy to the Cmder <code class="language-plaintext highlighter-rouge">bin</code>.</p> <p><em>Note: I have noticed some bugs when using Wget on Cmder to create WARC files. For more complex use of Wget, consider <a href="https://evanwill.github.io/_drafts/notes/cygwin.html">Cygwin</a> instead.</em></p> <h2 id="add-ubuntu-bash-shell">Add Ubuntu Bash shell</h2> <p>If you have Windows 10 and <a href="https://msdn.microsoft.com/en-us/commandline/wsl/install_guide">installed “Windows Subsystem for Linux”</a>, you can add the “Bash on Ubuntu on Windows” shell to Cmder. Check solutions <a href="https://gingter.org/2016/11/16/running-windows-10-ubuntu-bash-in-cmder/">here</a> and <a href="http://conemu.github.io/en/BashOnWindows.html">here</a>.</p> Sat, 06 May 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/cmdr.html https://evanwill.github.io/_drafts/notes/cmdr.html Git for Collaboration Intro <blockquote> <p>Introduce using Git and GitHub for collaborating on code, writing, and websites.</p> </blockquote> <h2 id="why-use-git-and-github">Why use Git and GitHub?</h2> <p><a href="https://git-scm.com/">Git</a> is a <a href="https://www.gnu.org/philosophy/free-sw.en.html">free</a>, <a href="https://en.wikipedia.org/wiki/Distributed_version_control">distributed</a> version control system originally developed for coordinating huge software development projects (i.e. the <a href="https://www.kernel.org/">Linux Kernel</a> led by <a href="https://www.linuxfoundation.org/about">Linux Foundation</a>). However, Git is also great for personal uses such as organizing the code for your research project or the drafts and notes for writing an article. Pair Git with free hosting from <a href="https://github.com/">Github</a> and you have a powerful platform for managing your code and writing while collaborating and sharing with others.</p> <p>If you are working with code or collaborating, version control WILL make your life better!</p> <p>See:</p> <ul> <li>Get Git, <a href="https://uidaholib.github.io/get-git/1why.html">Why</a></li> <li>Software Carpentry, <a href="https://swcarpentry.github.io/git-novice/">Version Control with Git</a></li> <li>also check out <a href="https://www.datacarpentry.org/lessons/">Data Carpentry</a> for discipline specific data lessons</li> </ul> <h2 id="basic-workflow">Basic Workflow</h2> <p>I want to introduce collaboration aspects of GitHub, but it’s easiest to explain by using it! Git seems pretty weird until you Do it…</p> <p>Follow the first time <a href="https://uidaholib.github.io/get-git/2setup.html">Setup</a> and <a href="https://uidaholib.github.io/get-git/3workflow.html">Workflow</a> from Get Git.</p> <p>Skip the <a href="https://uidaholib.github.io/get-git/4history.html">History</a> section for now, but just keep in your heart that Git keeps track of Everything! Have peace of mind that you can’t loose your history once committed to a Git repo, unless you try really hard.</p> <h2 id="collaborating-via-github">Collaborating via GitHub</h2> <p>Putting your project on GitHub adds powerful options for user management, project management, and sharing.</p> <p>There is two basic workflows to collaborate on a GitHub repository:</p> <ol> <li>Add collaborators (simple, typical of smaller projects) <ul> <li>On GitHub, click the “Settings” tab of your repository.</li> <li>On the left menu, click “Collaborators”.</li> <li>Add collaborators via email or GitHub name.</li> <li>Collaborator will need to accept the invite.</li> <li>Clone the repo to your local machine.</li> <li>Now you all have equal control over the repo content: <code class="language-plaintext highlighter-rouge">push</code>, <code class="language-plaintext highlighter-rouge">pull</code>, <code class="language-plaintext highlighter-rouge">merge</code>, etc.</li> <li>Using feature <a href="https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell">branches</a> may be helpful to organize your work–create a branch, do some work, push the new branch to GitHub, then create a Pull Request to discuss with your team.</li> </ul> </li> <li>Fork and Pull Request (more complex, centralized control, typical of bigger projects) <ul> <li>Navigate to your partner’s repo on GitHub.</li> <li>Click “Fork” in upper right.</li> <li>Make changes in your personal fork of the repo.</li> <li>On your personal fork, click “New pull request” button.</li> <li>Check the changes, click “Create pull request” button.</li> <li>Create a message saying exactly what changes you made and why.</li> <li>The original repo will now have a PR that collaborators can view and comment on. Only the owner can accept the request and merge it.</li> </ul> </li> </ol> <p>See GitHub Help <a href="https://help.github.com/articles/fork-a-repo/">Fork a Repo</a>, <a href="https://help.github.com/articles/about-pull-requests/">About Pull requests</a>, and <a href="https://guides.github.com/introduction/flow/">Understanding the GitHub Flow</a> for more info. Also, check out Atlassian’s <a href="https://www.atlassian.com/git/tutorials/comparing-workflows">Comparing Workflows</a> or GitHub <a href="https://help.github.com/en/articles/about-collaborative-development-models">About collaborative development models</a> for more options.</p> <p><em>Note:</em> it is best to create small, targeted commits when collaborating. Each commit should do one specific thing making it easier for others to understand your work and navigate the history if necessary. PR’s should include only one change so they can be merged in as a module–don’t combine several unrelated commits since the owner may not want to merge all of them.</p> <h2 id="project-management-features">Project management features</h2> <p>GitHub adds many handy web-based features to manage your projects / Git repositories:</p> <ul> <li>Issues. Create an issue to discuss and track ideas, bugs, projects, requests, etc. Can be assigned to people, tagged, and more. Also allows people outside of the project report problems with your code. Be sure to create checklists in the first comment box (<code class="language-plaintext highlighter-rouge">- [ ] step</code>)–they become click-able and show progress in the Issue view.</li> <li>Projects. Create Trello board like lists to organize work.</li> <li>Wiki. Simple wiki-style documentation that can be edited by your collaborators (note: written in Markdown not wikitext).</li> </ul> <p>To make the most of these features, you will want to learn <a href="https://help.github.com/articles/basic-writing-and-formatting-syntax/">Markdown</a> because it’s a <a href="https://evanwill.github.io/_drafts/notes/writing-markdown.html">great way to write</a> and is used everywhere on GitHub. Issues, PR, and commits can be mentioned in any GitHub comment and will be replaced by <a href="https://help.github.com/articles/autolinked-references-and-urls/">reference shortlinks</a>. GitHub users can be mentioned using <code class="language-plaintext highlighter-rouge">@</code> and will be notified of your comment.</p> <h2 id="gh-pages">gh-pages</h2> <p>GitHub also offers free web hosting for your project, organization, or personal profile. Check workshop <a href="https://evanwill.github.io/go-go-ghpages/">Go-go gh-pages!</a></p> <p>Also, use <a href="https://gist.github.com/">GitHub Gist</a> to instantly share simple notes, outlines, snippets, etc.</p> <h2 id="resources">Resources</h2> <ul> <li><a href="https://git-scm.com/book">Git Book</a></li> <li><a href="http://gitforteams.com/">Git for Teams</a></li> <li>SWC <a href="http://swcarpentry.github.io/git-novice/">Version Control with Git</a></li> </ul> Fri, 05 May 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/git-collaboration.html https://evanwill.github.io/_drafts/notes/git-collaboration.html Markdown on Jekyll <p>Jekyll uses Markdown <code class="language-plaintext highlighter-rouge">.md</code> to simplify creating the base content for a site. The original spec is from <a href="https://daringfireball.net/projects/markdown/">Daring Fireball</a>, intended to be simple and intuitive like writing an email. GitHub added extra features to the Markdown used for comments and writing throughout their site, called <a href="https://help.github.com/articles/basic-writing-and-formatting-syntax/">GitHub markdown flavor</a>. Their <a href="https://guides.github.com/features/mastering-markdown/">Mastering Markdown Guide</a> is a good quickie tutorial.</p> <p>By default, Jekyll uses the Ruby based <a href="https://kramdown.gettalong.org/">kramdown</a> library to convert Markdown. Kramdown supports a few more extras beyond the standard syntax, such as attributes, footnotes, and typographic symbols. Check the <a href="https://kramdown.gettalong.org/syntax.html">kramdown syntax</a> for details.</p> <h2 id="tips">Tips</h2> <h3 id="white-space">White space</h3> <p>Although Markdown is simple, it is important to remember that white space, blank lines, and tabs matter. If you are getting unexpected results when rendering, check your white space.</p> <h3 id="add-attributes-to-links">Add attributes to links</h3> <p>Kramdown allows you to add additional attributes to links. I often add a target, like this: <code class="language-plaintext highlighter-rouge">[example](https://example.com){:target="_blank" rel="noopener"}</code>.</p> <h3 id="intermix-with-html">Intermix with HTML</h3> <p>All HTML is valid Markdown, but by default Markdown converters ignore Markdown inside HTML tags. For example, <code class="language-plaintext highlighter-rouge">&lt;div&gt; # Header One&lt;/div&gt;</code> won’t render as an <code class="language-plaintext highlighter-rouge">&lt;h1&gt;</code>. However, with Jekyll’s kramdown, you can add the attribute <code class="language-plaintext highlighter-rouge">markdown="1"</code> to an HTML element to tell the converter to render the Markdown inside. Thus, <code class="language-plaintext highlighter-rouge">&lt;div markdown="1"&gt; # Header One&lt;/div&gt;</code> will render as <code class="language-plaintext highlighter-rouge">&lt;div&gt;&lt;h1&gt;Header One&lt;/h1&gt;&lt;/div&gt;</code>. This is very handy for adding special divs with ids and classes!</p> <h3 id="nesting-code-blocks">Nesting code blocks</h3> <p>I make lots of step-by-step tutorials. If you aren’t careful with code blocks nested in lists they will end up with extra spaces. The code block looks right, but when you copy and paste from the web page, they are all indented two spaces. The trick to fix this is that the code block has to line up with the first character of the list text, not with the list marker.</p> <p>E.g., this works:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. one - nest - nest ``` code block ``` - more list 2. two </code></pre></div></div> <ol> <li>one <ul> <li>nest</li> <li> <p>nest</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>code block </code></pre></div> </div> </li> <li>more list</li> </ul> </li> <li>two</li> </ol> <p>but this doesn’t:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. one - nest - nest ``` code block ``` - more list 2. two </code></pre></div></div> <ol> <li>one <ul> <li>nest</li> <li>nest</li> </ul> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> code block </code></pre></div> </div> <ul> <li>more list</li> </ul> </li> <li>two</li> </ol> Wed, 19 Apr 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/jekyll-markdown.html https://evanwill.github.io/_drafts/notes/jekyll-markdown.html OpenRefine POST request with Jython <p>It is easy to fetch links with <a href="http://openrefine.org/">OpenRefine</a> using the <em>Add column by fetching urls</em> transformation. However, many APIs use HTTP POST to send information to the server for processing. Refine’s fetch can only HTTP GET.</p> <p>To make a POST request from Refine you can use <a href="http://www.jython.org/">Jython</a> in the expression window instead of GREL. Jython is included with Refine as a <code class="language-plaintext highlighter-rouge">.jar</code> file in the <code class="language-plaintext highlighter-rouge">openrefine/webapp/jython/</code> directory. The current version is Jython 2.7 based on Python 2.7.</p> <p>Jython in the Refine expression window requires a <code class="language-plaintext highlighter-rouge">return</code> statement to fill the new cells in the transformation. For example, the standard GREL <code class="language-plaintext highlighter-rouge">value</code> would be <code class="language-plaintext highlighter-rouge">return value</code> in Jython. The basic GREL variables use brackets instead of periods in Jython, for example GREL <code class="language-plaintext highlighter-rouge">cells.column_2.value</code> would be Jython <code class="language-plaintext highlighter-rouge">cells['column_2']['value']</code>.</p> <p>To create a POST request use the standard libraries <a href="http://www.jython.org/docs/library/urllib2.html">urllib2</a> and urllib. First, get your data into the correct format using <code class="language-plaintext highlighter-rouge">urllib.urlencode()</code>. Then, construct a request with <code class="language-plaintext highlighter-rouge">urllib2.Request(url[, data][, headers])</code> and open it with <code class="language-plaintext highlighter-rouge">urllib2.urlopen(req)</code>. Use <code class="language-plaintext highlighter-rouge">read()</code> to convert the object to usable data. If the <code class="language-plaintext highlighter-rouge">data</code> parameter is used in your request it will be a POST.</p> <p>A basic GET request for a list of URLs in a column would be:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import urllib2 f = urllib2.urlopen(value) return f.read() </code></pre></div></div> <p>To do a POST, construct the request first. For example, to get the sentiment of a line of text in each cell in a column:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import urllib2, urllib url = 'http://text-processing.com/api/sentiment/' data = urllib.urlencode({'text': value}) req = urllib2.Request(url,data) post = urllib2.urlopen(req) return post.read() </code></pre></div></div> <p>In most cases urlencode is not necessary, and in the tiny Refine expression window it is more pragmatic to write it in a compressed form:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import urllib2 url = 'http://text-processing.com/api/sentiment/' return urllib2.urlopen(url,"text="+value).read() </code></pre></div></div> <p>If the API returns errors, try using GREL trim whitespace, GREL <code class="language-plaintext highlighter-rouge">escape()</code> / <code class="language-plaintext highlighter-rouge">unescape()</code>, or Jython <code class="language-plaintext highlighter-rouge">encode("utf-8")</code> And write a script that has error handling, like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import urllib2, urllib url = "http://text-processing.com/api/sentiment/" data = urllib.urlencode({"text": value.encode("utf-8")}) req = urllib2.Request(url,data) try: post = urllib2.urlopen(req) except urllib2.URLError as e: if hasattr(e, "reason"): return "Failed: ", e.reason elif hasattr(e, "code"): return "Error code: ", e.code else: response = post.read() return response </code></pre></div></div> <p>The official <a href="https://github.com/OpenRefine/OpenRefine/wiki/Jython">Refine Jython documentation</a> is pretty sparse. Refine Jython includes the standard libraries, but others can be adding using a <a href="https://github.com/OpenRefine/OpenRefine/wiki/Extending-Jython-with-pypi-modules">work around</a>.</p> Mon, 10 Apr 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/refine-post-request.html https://evanwill.github.io/_drafts/notes/refine-post-request.html CONTENTdm api tips <p>Many libraries use <a href="https://www.oclc.org/en/contentdm.html">CONTENTdm</a> to host their digital collections. You may want to harvest metadata, text, and digital objects from these repositories. CDM is not the easiest to use, but there is a few handy ways to get stuff out via URLs.</p> <p>We can access the CDM data using the <a href="https://help.oclc.org/Metadata_Services/CONTENTdm/Advanced_website_customization/API_Reference">CDM API</a>. This API is helpful because its possible to create a set of queries using <a href="https://openrefine.org/">OpenRefine</a> or a language such as <a href="https://www.python.org/">Python</a> to add the harvesting raw materials step directly to your data processing workflow.</p> <h2 id="cdm-terminology">CDM Terminology</h2> <p>The key to using the CDM API is to figure out the base URLs, the collection “Alias” (the short name represented in a collection’s url), and the item id “pointer” (the id number assigned the item by the CDM database). (<em>Note:</em> very old CDM instances also required a <code class="language-plaintext highlighter-rouge">port</code>, usually “:81”, that is no longer necessary, but still often appears in CDM documentation)</p> <p>CDM uses some terminology for the components of their API:</p> <ul> <li>CDM server number: each hosted CDM has a number which is used in two different URLs in the “contentdm.oclc.org” subdomain, which are used for different types of API calls. <ul> <li>“CDM server URL” - this is where your CDM admin is hosted, named “server” + server number, e.g. <code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/</code>. In general collection level API calls have to go to this URL.</li> <li>“CDM website URL” - this is where your public CDM instance is exposed, named “cdm” + server number, e.g. <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/</code>. Many organizations have a custom domain in front of this subdomain which should work for most API calls. In general item level API calls have to go to this URL.</li> </ul> </li> <li>“Alias” - the identifier name for an individual collection, used in URLs. If set by CDM they look like <code class="language-plaintext highlighter-rouge">p17254coll3</code>, or can be manually created looking like <code class="language-plaintext highlighter-rouge">argonaut</code>.</li> <li>“pointer” / “CONTENTdm number” - the identifier number of an individual item or object assigned by the CDM database, e.g. <code class="language-plaintext highlighter-rouge">14</code>. If harvesting metadata, this value is usually called “pointer” in XML. However, it is found in metadata export as “CONTENTdm number”.</li> </ul> <p>If you look at the URL for at a CDM item page you can find the information. For example, in:</p> <p><code class="language-plaintext highlighter-rouge">https://cdm17254.contentdm.oclc.org/digital/collection/p17254coll3/id/155/rec/1</code></p> <p>The “CDM website URL” is <code class="language-plaintext highlighter-rouge">https://cdm17254.contentdm.oclc.org</code>, collection “Alias” is <code class="language-plaintext highlighter-rouge">p17254coll3</code>, and “pointer” is <code class="language-plaintext highlighter-rouge">155</code>.</p> <p>If you know the “CDM website URL” using the “contentdm.oclc.org” subdomain, then you can find the “server url” by replacing the leading “cdm” with “server”, in this example <code class="language-plaintext highlighter-rouge">https://server17254.contentdm.oclc.org/</code>. If you know a “server URL”, you can use the API for find alias and pointers. Unfortunately, it is difficult to figure out the server url if the organization uses a custom url.</p> <p>If you have direct access the the CDM instance–skip the metadata harvesting–instead export collection metadata from the admin interface, then use the “CONTENTdm number” it provides to harvest objects out of the database (see <a href="/_drafts/notes/contentdm-meta.html">CDM metadata tips</a> info).</p> <p><em>Note:</em> it is also possible to harvest metadata via OAI PMH–however OAI PMH is even more tedious that CDM’s API and does not contain all the information necessary to harvest digital objects. In my experience, CDM’s implementation of OAI PMH is unreliable with larger collections.</p> <h2 id="collection-level-api">Collection level API</h2> <p>These calls require the OCLC server url, e.g. <code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/</code> as used in the examples below.</p> <h3 id="find-alias-and-pointers">Find Alias and Pointers</h3> <p>Get an XML list of all collections using:</p> <p><code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/dmwebservices/index.php?q=dmGetCollectionList/xml</code></p> <p>(if you prefer JSON, replace <code class="language-plaintext highlighter-rouge">/xml</code> with <code class="language-plaintext highlighter-rouge">/json</code>)</p> <p>From that XML document you can find the <code class="language-plaintext highlighter-rouge">alias</code> for a collection of interest in the <code class="language-plaintext highlighter-rouge">&lt;alias&gt;</code> element.</p> <p>Next, you want a list of items so you can find the <code class="language-plaintext highlighter-rouge">pointer</code>. There is no obvious easy way. The best way is to choose a metadata field to query that every item has (generally you’ll be safe just using the field <code class="language-plaintext highlighter-rouge">title</code> to query). Following our example, to check which metadata fields exist for a collection with <code class="language-plaintext highlighter-rouge">alias</code> “example”, use:</p> <p><code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/dmwebservices/index.php?q=dmGetCollectionFieldInfo/example/xml</code></p> <p>This list will provide the list of fields including <code class="language-plaintext highlighter-rouge">name</code> and <code class="language-plaintext highlighter-rouge">nick</code>, you have to use the nickname in API calls using the field value.</p> <p>After choosing a field, for example “title”, we can form a query to return items for the “example” collection. There are a bunch of options that must be included for the query to work, and if you don’t want to use the option you usually replace it with <code class="language-plaintext highlighter-rouge">0</code> in the url string.</p> <p><code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/dmwebservices/index.php?q=dmQuery/example/0/title/title/1024/0/0/0/0/0/xml</code></p> <p><em>Importantly, the API will only return a max of 1024 items.</em> Note the <code class="language-plaintext highlighter-rouge">1024</code> in url above is the “maxrecs” value. To get more than 1024 items, you will have to do multiple API calls, changing the value directly after “maxrecs” (e.g. <code class="language-plaintext highlighter-rouge">/1024/0/</code>, then <code class="language-plaintext highlighter-rouge">/1024/1024/</code>, etc).</p> <p>The first XML element <code class="language-plaintext highlighter-rouge">&lt;pager&gt;</code> tells you how many <code class="language-plaintext highlighter-rouge">&lt;total&gt;</code> items there are in the collection. Each item in the collection is in a <code class="language-plaintext highlighter-rouge">&lt;record&gt;</code> element with a <code class="language-plaintext highlighter-rouge">&lt;pointer&gt;</code>. Now that you have <code class="language-plaintext highlighter-rouge">pointer</code> for individual items, you can retrieve metadata or files for the items.</p> <h3 id="get-full-text">Get full text</h3> <p>Most document collections in CDM have a full text field filled by an OCR transcript. If you want to get the full text for all items in a small collection, its easy using the Query method mentioned above. The automatically populated full text field is usually called <code class="language-plaintext highlighter-rouge">full</code> in CDM. For example:</p> <p><code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/dmwebservices/index.php?q=dmQuery/example/0/full/xml</code></p> <p>However, this will only return 10 items. You can set the max number to return between 1 and 1024. So to set it to 1024, use this query:</p> <p><code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/dmwebservices/index.php?q=dmQuery/example/0/full/nosort/1024/xml</code></p> <p>Obviously, if your collection has more than a thousand items, this isn’t very helpful. However, CDM usually times out on large collections anyway, this method probably won’t work on larger collections with large full text fields. Instead, make a list of pointers, and use them to individually download metadata as shown below.</p> <h3 id="get-item-metadata">Get item metadata</h3> <p>To get an item’s full descriptive metadata, use the <code class="language-plaintext highlighter-rouge">alias</code> and <code class="language-plaintext highlighter-rouge">pointer</code>. For example, if the <code class="language-plaintext highlighter-rouge">pointer</code> is “1”:</p> <p><code class="language-plaintext highlighter-rouge">https://server12345.contentdm.oclc.org/dmwebservices/index.php?q=dmGetItemInfo/example/1/xml</code></p> <h2 id="item-level-api">Item level API</h2> <p>For these calls you will need to know the CDM URL, <code class="language-plaintext highlighter-rouge">alias</code> of the collection, and <code class="language-plaintext highlighter-rouge">pointer</code> of the item. The url will work with either the OCLC CDM address, e.g. <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/</code>, or a custom domain of an organization, e.g. <code class="language-plaintext highlighter-rouge">https://digital.lib.uidaho.edu/</code>.</p> <p>In the examples below, use CDM url <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/</code>, collection alias <code class="language-plaintext highlighter-rouge">p12345coll1</code>, and pointer <code class="language-plaintext highlighter-rouge">1</code>.</p> <ul> <li><a href="https://www.oclc.org/support/services/contentdm/help/customizing-website-help/other-customizations/contentdm-api-reference/getthumbnail.en.html#par_text_4c0f">GetThumbnail</a> - will provide a thumb for any object in the repository, “/utils/getthumbnail/collection/alias/id/pointer” - <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/utils/getthumbnail/collection/p12345coll1/id/1</code></li> <li><a href="https://www.oclc.org/support/services/contentdm/help/customizing-website-help/other-customizations/contentdm-api-reference/getfile.en.html#par_text_6545">GetFile</a> - provides a download link for PDF objects, “/utils/getfile/collection/alias/id/pointer/filename” - <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/utils/getfile/collection/p12345coll1/id/1/example.pdf</code></li> <li><a href="https://www.oclc.org/support/services/contentdm/help/customizing-website-help/other-customizations/contentdm-api-reference/getstream.en.html#par_text_2d39">GetStream</a> - provides download and playable link for video/audio objects, “/utils/getstream/collection/alias/id/pointer” - <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/utils/getstream/collection/p12345coll1/id/1</code></li> </ul> <h3 id="use-iiif-for-images">Use IIIF for Images</h3> <p>CDM now implements a <a href="https://help.oclc.org/Metadata_Services/CONTENTdm/Advanced_website_customization/API_Reference/IIIF_API_reference?sl=en">IIIF API</a> exposed at “/digital/iiif/”, <em>only</em> for collections that contain images. This is the best method for accessing images in collections.</p> <ul> <li>Get max image size: <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/digital/iiif/p12345coll1/1/full/max/0/default.jpg</code></li> <li>Get the full frame of an image at 50% size: <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/digital/iiif/p12345coll1/1/full/pct:50/0/default.jpg</code></li> <li>Get image info: <code class="language-plaintext highlighter-rouge">https://cdm12345.contentdm.oclc.org/digital/iiif/p12345coll1/1/info.json</code></li> </ul> <p>Check <a href="https://iiif.io/api/image/2.1/">IIIF Image API 2.1.1</a> docs for more possibilities. However, CDM’s implementation of IIIF has some limitations:</p> <ul> <li>using the Size parameter <code class="language-plaintext highlighter-rouge">!w,h</code> does not work, instead returns <code class="language-plaintext highlighter-rouge">max</code> instead.</li> <li>using the Size parameter <code class="language-plaintext highlighter-rouge">pct:</code> with less than 10% does not work, and will return an error message.</li> <li>if either pixel size used in Size parameter <code class="language-plaintext highlighter-rouge">w,h</code> is larger than actual dimension of the full image, it will return an error message.</li> </ul> Tue, 04 Apr 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/contentdm-tips.html https://evanwill.github.io/_drafts/notes/contentdm-tips.html Using Cygwin <p><strong>Out of date! I haven’t used this for a long time!</strong></p> <p><a href="https://cygwin.com/index.html">Cygwin</a> is a project that adds Unix style terminal to Windows. It includes hundreds of Unix command line utilities built and packaged to function natively on Windows. It includes more functionality than Git Bash (included with <a href="https://git-for-windows.github.io/">Git for Windows</a>), is open-source (unlike <a href="http://mobaxterm.mobatek.net/">MobaXterm</a>), and has a package system to install utilities (unlike <a href="https://evanwill.github.io/_drafts/notes/cmdr.html">Cmder</a>). If you are currently using Git Bash on Windows, you may want to move to Cygwin if you would like Nano Editor, Wget, and GNU Make (plus old school terminal games!).</p> <h1 id="install-cygwin">Install Cygwin</h1> <p>Download the current installation utility from the <a href="https://cygwin.com/install.html">Cygwin site</a>. I suggest the 64-bit version, <code class="language-plaintext highlighter-rouge">setup-x86_64.exe</code>. Once the file downloads, move it to a sensible permanent location as the utility is used to update and make changes to your install. For example, move it to <code class="language-plaintext highlighter-rouge">C:\cygwin-stuff</code> (by default Cygwin uses <code class="language-plaintext highlighter-rouge">C:\cygwin64</code> as its root directory).</p> <p>To get started quickly, simply double click <code class="language-plaintext highlighter-rouge">setup-x86_64.exe</code> to use the graphical installer. However, the awkward interface makes finding and selecting packages very difficult. I suggest starting on the command line, which greatly simplifies getting what you want / need.</p> <h3 id="command-line-installer">Command line installer</h3> <p>Open Windows <code class="language-plaintext highlighter-rouge">cmd</code> command prompt in the directory containing <code class="language-plaintext highlighter-rouge">setup-x86_64.exe</code>. Enter the command:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>setup-x86_64.exe -q -P nano,wget,git,chere,make,openssh,openssl,ninvaders,sl,fortune-mod,ctris </code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">-P</code> option allows you to list the extra packages you would like installed. Get the package names from the <a href="https://cygwin.com/packages/package_list.html">full package list</a> and separate each with a comma.</p> <p>The command above will start the Cygwin graphical installer with the listed packages selected in addition to the core utilities. Since all the necessary options are not specified, the GUI will ask you a few more questions (check the full <a href="https://cygwin.com/faq/faq.html#faq.setup.cli">list of CLI options</a> if you want streamline further).</p> <h3 id="graphical-installer">Graphical installer</h3> <p>The installer will ask about these options:</p> <ul> <li>Choose Download Source: “install from Internet”</li> <li>Select Root Install Directory: the folder selected in this step with become your fake Unix style root directory <code class="language-plaintext highlighter-rouge">/</code>. The default is <code class="language-plaintext highlighter-rouge">C:\cygwin64</code>, which should work for most users. Do not change it to an existing system directory! All Cygwin files will be located in this root, so you will risk over writing existing files or causing incompatibilities.</li> <li>Select Local Package Directory: this folder will be for package downloads. I usually change it to a new directory in the same location as <code class="language-plaintext highlighter-rouge">setup-x86_64.exe</code>.</li> <li>Internet connection: use default unless you have a proxy.</li> <li>Download Site: choose a mirror to download from. Any should work.</li> <li>Select Packages: This is where you can add additional packages beyond the default install–if you started with the command line options above, everything you need is already selected. Otherwise, select “Full” from the “View” drop down menu, then search to find useful packages. Click on “Skip” to mark the utility for installation. The list is not very user friendly, but poke around until you mark off everything you need.</li> </ul> <h3 id="update">Update</h3> <p>To update or install new packages, run <code class="language-plaintext highlighter-rouge">setup-x86_64.exe</code> again. Your current packages and configurations will be saved, but everything will be updated to the latest versions.</p> <h1 id="using-cygwin">Using Cygwin</h1> <p>The installer should put a shortcut on your desktop. Click it to start the terminal (this starts <code class="language-plaintext highlighter-rouge">cygwin64/bin/mintty.exe</code>, if you double click <code class="language-plaintext highlighter-rouge">cygwin64/Cygwin.bat</code> you will start in the awful Windows <code class="language-plaintext highlighter-rouge">cmd.exe</code> terminal instead).</p> <h3 id="file-system">File system</h3> <p>It is important to know that the file system is a bit wonky via the Cygwin shell. According to Cygwin, your <code class="language-plaintext highlighter-rouge">/</code> root directory is <code class="language-plaintext highlighter-rouge">C:\cygwin64</code>. Cygwin creates a home directory inside this root. This means that <code class="language-plaintext highlighter-rouge">cd ~</code> then <code class="language-plaintext highlighter-rouge">pwd</code> will read <code class="language-plaintext highlighter-rouge">/home/username</code>, but it is <em>NOT</em> your Windows user directory. Instead it is <code class="language-plaintext highlighter-rouge">C:\cygwin64\home\username</code>, your user directory in Cygwin’s root.</p> <p>To access your normal Windows file system use <code class="language-plaintext highlighter-rouge">/cygdrive/</code>. For example <code class="language-plaintext highlighter-rouge">cd /cygdrive/c</code> will bring you to <code class="language-plaintext highlighter-rouge">C:\</code>. Thus, your normal Windows user directory will typically be at <code class="language-plaintext highlighter-rouge">cd /cygdrive/c/Users/username</code>.</p> <h3 id="right-click">Right click</h3> <p>To make life a bit easier, use the <code class="language-plaintext highlighter-rouge">chere</code> package to add a Windows context menu item (i.e. right click).</p> <p>To configure, right click on your Cygwin terminal shortcut (on desktop or in start menu) and choose “Run as administrator”. Then type the command: <code class="language-plaintext highlighter-rouge">chere -i -t mintty</code>. This adds the default terminal to your context menu as “Bash Prompt Here”. Simply right click any folder and select the option to open Cygwin in that directory.</p> <p>The option can be uninstalled via Windows Control Panel like a program. To see the full options check <code class="language-plaintext highlighter-rouge">chere --help</code>.</p> Thu, 09 Mar 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/cygwin.html https://evanwill.github.io/_drafts/notes/cygwin.html CSS Animation <style> @keyframes hori { from {left: 0%;} to {left: 100%;} } @keyframes vert { from {top: 0%;} to {top: 100%;} } .area { width: 100%; height: 300px; } .box { display: block; position: relative; left:0; top:0; width: 140px; font-size: 30px; } #v-trigger, #h-trigger { display: none;} label { display: block; cursor: pointer; width: 50%; height:70px; text-align: center; border: 1px solid grey; background: yellow; } label[for="v-trigger"] { float: left; } label[for="h-trigger"] { float: right; } input#v-trigger:checked ~ .box { -webkit-animation: test 5s infinite; animation: vert 5s infinite alternate; } input#v-trigger:checked ~ .box label[for="v-trigger"] { background: green; } input#h-trigger:checked ~ .box { -webkit-animation: test 5s infinite; animation: hori 5s infinite alternate; } input#h-trigger:checked ~ .box label[for="h-trigger"] { background: green; } </style> <div class="area"> <input type="checkbox" id="v-trigger" /> <input type="checkbox" id="h-trigger" /> <div class="box"> <label for="v-trigger">&darr;</label> <label for="h-trigger">&rarr;</label> </div> </div> <p>Kind of amazing the stuff you can do with CSS with enough selectors…</p> Wed, 08 Mar 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/css-animation.html https://evanwill.github.io/_drafts/notes/css-animation.html Kids Apps on Linux <p>What if you give a little kid (3 - 6 years old) a Raspberry Pi?<br /> Better add some free and open kids games!</p> <p>Linux has had a lot of idealistic attempts to develop kid focused software. Unfortunately, most of the projects seem to fade away and are pretty dated today. Luckily, little kids really don’t care! They are tickled just to play with a computer. So, here is my list of apps that seem to successfully amuse little kids.</p> <h2 id="essentials">Essentials:</h2> <ul> <li>Potato Guy (KTuberling), <code class="language-plaintext highlighter-rouge">sudo apt-get install ktuberling</code>. Fun “stamp” game where you move stickers onto a scene such as a potato head or moonscape.</li> <li>Tux Paint, <code class="language-plaintext highlighter-rouge">sudo apt-get install tuxpaint</code>. Easy to use paint program with Tux.</li> <li>Bam Bam, <code class="language-plaintext highlighter-rouge">sudo apt-get install bambam</code>. Abstract infant game that is a lot of fun. Hitting any key or moving the mouse creates random visual and audio outputs filling the screen. The app locks to full screen, the only way to get out is to type <code class="language-plaintext highlighter-rouge">quit</code>.</li> </ul> <h2 id="good">Good:</h2> <ul> <li>GCompris, <code class="language-plaintext highlighter-rouge">sudo apt-get install gcompris</code>. A full suite of educational games, including activities that introduce using computer peripherals. Check the <a href="http://gcompris.net/index-en.html">official site</a> for more up-to-date packages.</li> <li>Childs Play, <code class="language-plaintext highlighter-rouge">sudo apt-get install childsplay</code>. A suite of games for kids, some educational, some amusing. <a href="http://www.schoolsplay.org/">Official site</a>.</li> <li>PySio Games, <code class="language-plaintext highlighter-rouge">sudo apt-get install pysiogame</code>. <a href="http://www.pygame.org">Pygame</a> based suite of games, see <a href="https://www.pysiogame.net/">official site</a>.</li> <li><code class="language-plaintext highlighter-rouge">sudo apt-get install pysycache</code>. Another <a href="http://www.pygame.org">Pygame</a> based package for younger kids to learn the mouse.</li> <li>Tux Type, <code class="language-plaintext highlighter-rouge">sudo apt-get install tuxtype</code>.</li> <li>Tux of Math Command, <code class="language-plaintext highlighter-rouge">sudo apt-get install tuxmath</code>.</li> <li>Gamine, <code class="language-plaintext highlighter-rouge">sudo apt-get install gamine</code>. Basic mouse-based “game” for very little kids.</li> <li>Debian’s educational games, <code class="language-plaintext highlighter-rouge">sudo apt-get install games-education</code>. Many of the packages above can be installed at once with this metapackage. See full <a href="https://packages.debian.org/jessie/games-education">list</a>.</li> </ul> <h2 id="games">Games</h2> <ul> <li>Classic games from KDE: <code class="language-plaintext highlighter-rouge">kblocks kbreakout kapman</code></li> <li><code class="language-plaintext highlighter-rouge">oneko</code> cat follows your mouse</li> <li><code class="language-plaintext highlighter-rouge">frozen-bubble</code></li> <li><code class="language-plaintext highlighter-rouge">ri-li</code> toy train sim</li> </ul> <h2 id="fun-with-parent-interaction">Fun with parent interaction:</h2> <ul> <li>Stellarium, <code class="language-plaintext highlighter-rouge">sudo apt-get install stellarium</code>. Night sky simulator with lots of options.</li> <li>Celestia. 3D astronomy simulator. It’s not in many repositories right now due to a history of buggy-ness, but you can get it from the <a href="https://celestiaproject.net/">official site</a>.</li> <li>VirtualLab Microscope, http://virtual.itg.uiuc.edu/</li> <li>xball, <code class="language-plaintext highlighter-rouge">sudo apt-get install xball</code>. Bouncing ball simulator.</li> </ul> <h2 id="full-distros">Full distros</h2> <ul> <li><a href="http://www.doudoulinux.org/web/english/index.html">DouDou Linux</a> is rather dated, but still works well as a totally ready to go, self-contained, live disk.</li> <li><a href="https://www.sugarlabs.org/">Sugarlabs</a> unique kid focused distro originally developed for One Laptop per child project. Check <a href="http://wiki.sugarlabs.org/go/Sugar_on_a_Stick/Installation">On a Stick</a> or on <a href="http://wiki.sugarlabs.org/go/Ubuntu">Ubuntu</a>.</li> <li><a href="http://www.ubermix.org/about.html">Ubermix</a> is for a bit older kids, but has a clever install system to make restore seamless if users mess up the system.</li> </ul> Sat, 04 Mar 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/kids-games.html https://evanwill.github.io/_drafts/notes/kids-games.html Intro to the Command Line <blockquote> <p>Mini-workshop: Does command line interface (CLI), REPL, terminal, console, or shell sound scary? Don’t worry, we’ll learn about the basic computer interface that gives you super powers! If you want to work with Raspberry Pi, Linux, or many programming languages you need a basic familiarity with the CLI. This MILL-Mini will demystify the terminal so you can use it to get things done.</p> </blockquote> <h2 id="what-is-the-shell">What is the Shell?</h2> <p>The command line is a text-based interface for efficiently getting stuff done. It’s often called the shell, terminal, console, cmd, or Bash, but ultimately the <strong>Shell</strong> is just a program on your computer like any other application. Its job is to act as a <strong>command shell</strong>, taking input from the user, ordering the computer’s operating system (OS) to execute the instructions, and returning the outputs.</p> <p>Since the 1980’s the most common way to interact with a computer is via the <strong>graphical user interface</strong> (GUI), i.e. the windows, icons, and pointers of a desktop environment. Technically this is a shell. However, when people talk about <em>the shell</em> it usually refers to a <strong>command-line interface</strong> (CLI) made up of only text in a <strong>read-evaluate-print loop</strong> (REPL).</p> <p>This means:</p> <ol> <li>you type something on the input line and press return</li> <li>the shell interprets the command</li> <li>the OS executes it</li> <li>the shell prints the output</li> <li>repeat!</li> </ol> <p>Note that the shell does not execute commands itself. It calls on hundreds of other applications in the OS to get things done. It’s the most basic way to interface with your computer short of re-wiring it!</p> <h2 id="which-shell">Which Shell?</h2> <p>There are actually a lot of shells out there! Most OS come with one as a standard application. On Windows, CMD or PowerShell are normally available. These use a syntax and set of applications unique to Windows systems.</p> <p>However, the most popular and commonly used is the Unix shell <strong>Bash</strong> (<a href="https://en.wikipedia.org/wiki/Bash_(Unix_shell)">Bourne Again SHell</a>) which is standard on Linux and Mac OS. Even if you are a Windows user, learning Bash will open up a powerful set of tools on your personal machine, in addition to familiarizing you with the standard remote interface used on almost all servers and super computers. If you want to control a Raspberry Pi or virtual machine in the cloud, you will need to use the Bash Shell.</p> <p>On Linux or Mac, you already have Bash, just open a <em>Terminal</em> and you are ready to go. On Windows there are several options to add a UNIX-like style shell:</p> <ul> <li><a href="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</a>: Windows 10 has the option to install a Ubuntu Linux subsystem which enables a native Bash shell with all the standard functionality. This is very handy, but installing takes <a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">a few steps</a>. (<a href="https://evanwill.github.io/_drafts/notes/wsl.html">WSL notes</a>)</li> <li>Git Bash: installing <a href="https://git-for-windows.github.io/">Git for Windows</a> adds the Git Bash shell. It comes with some of the standard UNIX applications (and you can <a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">add more</a>). It is easy to install, integrates with Windows context menus (right click), and works well. (alternatively, use Git Bash with <a href="https://evanwill.github.io/_drafts/notes/cmdr.html">Cmder</a>, which is fully portable, no install needed)</li> <li><a href="https://www.cygwin.com/">Cygwin</a>: a project that adds Unix style terminal to Windows including hundreds of utilities built and packaged to function natively on Windows. It includes more functionality than Git Bash and has a package system to install utilities (<a href="https://evanwill.github.io/_drafts/notes/cygwin.html">more info</a>).</li> <li><a href="http://mobaxterm.mobatek.net/">MobaXterm</a>: a non-opensource emulator similar to Cygwin with quite a bit of functionality and an optional paid version.</li> </ul> <p>The GUI window that hosts the text based CLI is often called a <strong>terminal emulator</strong>. Most people use the default that comes with your OS, but if you want to get fancy, there are a surprising number of options out there! Check out <a href="http://guake-project.org/">Guake</a> (linux, dropdown), <a href="https://hyper.is/">Hyper</a> (slick looking, html/css based), <a href="https://conemu.github.io/">ConEmu</a> (windows, tabbed), <a href="https://gnunn1.github.io/tilix-web/">Tilix</a> (linux, tiling terminal), <a href="https://github.com/Swordfish90/cool-retro-term">Cool Retro Term</a> (linux, retro emulator with flickering CRT screen look).</p> <h2 id="navigate">Navigate</h2> <p>Start up your terminal and type <code class="language-plaintext highlighter-rouge">pwd</code>.</p> <p>This command asks the shell to “print working directory”. The shell should give you some out put, like <code class="language-plaintext highlighter-rouge">/home/username</code>. That’s where we are right now! The string <code class="language-plaintext highlighter-rouge">/home/username</code> is a file path representing our current location in the file system, just like navigating the folders in the GUI explorer. Typically, on Unix systems the <code class="language-plaintext highlighter-rouge">/</code> is the root directory. All other directories are organized below it.</p> <blockquote> <p><em>Note:</em> when using Git Bash on Windows, <code class="language-plaintext highlighter-rouge">cd ~</code> should bring you to your Windows user directory, such as <code class="language-plaintext highlighter-rouge">C:\Users\username</code>. However, the Windows alternatives locate the <code class="language-plaintext highlighter-rouge">/</code> directories in a “fake” root directory, not the actual Windows file system root. For example, on Git Bash <code class="language-plaintext highlighter-rouge">cd /</code> will bring you to something like <code class="language-plaintext highlighter-rouge">C:\Program Files\Git\mingw64\</code> not <code class="language-plaintext highlighter-rouge">C:\</code>. Cygwin and MobaXterm also place the “home” directory inside the fake root. For example, when using Cygwin, <code class="language-plaintext highlighter-rouge">cd ~</code> the <code class="language-plaintext highlighter-rouge">pwd</code> will say <code class="language-plaintext highlighter-rouge">/home/username</code>, but will actually be located in the Windows <code class="language-plaintext highlighter-rouge">C:\cygwin\home\username</code>.</p> </blockquote> <p>Take a look around:</p> <ul> <li><code class="language-plaintext highlighter-rouge">ls</code> (“listing”)</li> <li><code class="language-plaintext highlighter-rouge">ls -a</code> (<code class="language-plaintext highlighter-rouge">-a</code> is a flag, it adds an option to the command, in this case to show all files including hidden ones. There is often a short and long version, <code class="language-plaintext highlighter-rouge">-a</code> or <code class="language-plaintext highlighter-rouge">--all</code>)</li> <li><code class="language-plaintext highlighter-rouge">ls --help</code> (you can use <code class="language-plaintext highlighter-rouge">--help</code> with almost any command! Linux also has a built in manual, try <code class="language-plaintext highlighter-rouge">man ls</code>)</li> <li><code class="language-plaintext highlighter-rouge">cd Desktop</code> (“change directory”)</li> <li><code class="language-plaintext highlighter-rouge">cd ..</code> (back one level)</li> <li>Save typing with <code class="language-plaintext highlighter-rouge">tab</code> complete and up arrow for command history!!</li> <li>Copy &amp; paste with your mouse or <code class="language-plaintext highlighter-rouge">ctrl+shift+C</code> / <code class="language-plaintext highlighter-rouge">ctrl+shift+V</code> (short cuts may need to be enabled in your terminal’s settings options)</li> </ul> <h2 id="work-with-files">Work with files</h2> <p>Let’s make a test directory to play in:</p> <ul> <li><code class="language-plaintext highlighter-rouge">cd ~</code> (back to home directory)</li> <li><code class="language-plaintext highlighter-rouge">cd Desktop</code></li> <li><code class="language-plaintext highlighter-rouge">mkdir test</code> (“make directory”)</li> <li><code class="language-plaintext highlighter-rouge">cd test</code></li> </ul> <p>Now lets create a file in it:</p> <ul> <li><code class="language-plaintext highlighter-rouge">echo hello world</code> (terminal repeats what you said)</li> <li><code class="language-plaintext highlighter-rouge">echo hello world &gt; test.txt</code> (the <code class="language-plaintext highlighter-rouge">&gt;</code> is <strong>redirect</strong> that prints the output to a file rather than the screen)</li> <li><code class="language-plaintext highlighter-rouge">ls</code></li> <li><code class="language-plaintext highlighter-rouge">cat test.txt</code> (“concatenate” displays one or more files in the terminal)</li> <li><code class="language-plaintext highlighter-rouge">echo more text &gt;&gt; test.txt</code> (the <code class="language-plaintext highlighter-rouge">&gt;&gt;</code> redirects the output and <strong>appends</strong> it to the end of an file. A single <code class="language-plaintext highlighter-rouge">&gt;</code> would over write the file)</li> <li><code class="language-plaintext highlighter-rouge">cat test.txt</code></li> </ul> <p>Play with it:</p> <ul> <li><code class="language-plaintext highlighter-rouge">mkdir new</code></li> <li><code class="language-plaintext highlighter-rouge">cp test.txt new/test.txt</code> (“copy”)</li> <li><code class="language-plaintext highlighter-rouge">cd new</code></li> <li><code class="language-plaintext highlighter-rouge">mkdir new2</code></li> <li><code class="language-plaintext highlighter-rouge">mv test.txt new2/test2.txt</code> (“move” changes location and/or name, be careful!)</li> <li><code class="language-plaintext highlighter-rouge">cd new2</code></li> <li><code class="language-plaintext highlighter-rouge">rm -i test2.txt</code> (“remove”, be careful there is no recycle bin!)</li> <li>wildcards <code class="language-plaintext highlighter-rouge">?</code> and <code class="language-plaintext highlighter-rouge">*</code>, try <code class="language-plaintext highlighter-rouge">grep -i "hello" *.txt</code></li> </ul> <h2 id="run-programs">Run Programs</h2> <p>Many programs run interactively inside the terminal (<em>note: these don’t work well in Git Bash, but can be installed in Cygwin</em>):</p> <ul> <li><code class="language-plaintext highlighter-rouge">nano test3.txt</code> (text editor in the terminal)</li> <li><code class="language-plaintext highlighter-rouge">python</code> (running another REPL system in the terminal)</li> <li><code class="language-plaintext highlighter-rouge">curl http://www.lib.uidaho.edu/</code> (utility to get URLs in terminal)</li> <li><code class="language-plaintext highlighter-rouge">top</code> (process monitor)</li> </ul> <h2 id="have-fun">Have Fun</h2> <p>A good way to get familiar with the commandline is with some fun and games! These demos install amusing programs (<em>note: demos based on Ubuntu. Only available on Linux or Bash on Windows Subsystem. However, most can be found in Cygwin packages.</em>)</p> <p>Train:</p> <ul> <li><code class="language-plaintext highlighter-rouge">sudo apt-get install sl</code> (apt-get is Debian / Ubuntu’s utility to find and install packages)</li> <li><code class="language-plaintext highlighter-rouge">sl</code></li> </ul> <p>Wise cow:</p> <ul> <li><code class="language-plaintext highlighter-rouge">sudo apt-get install cowsay</code></li> <li><code class="language-plaintext highlighter-rouge">cowsay "Hello world!"</code></li> <li><code class="language-plaintext highlighter-rouge">cowthink "Grass?"</code></li> <li><code class="language-plaintext highlighter-rouge">sudo apt-get install fortune</code></li> <li><code class="language-plaintext highlighter-rouge">fortune</code></li> <li><code class="language-plaintext highlighter-rouge">fortune | cowsay</code> (pipes <code class="language-plaintext highlighter-rouge">|</code> send output to another command)</li> <li><code class="language-plaintext highlighter-rouge">cowsay -l</code></li> <li><code class="language-plaintext highlighter-rouge">fortune | cowsay -f dragon</code></li> </ul> <p>Banners:</p> <ul> <li><code class="language-plaintext highlighter-rouge">sudo apt-get install figlet</code></li> <li><code class="language-plaintext highlighter-rouge">figlet Command Line!</code></li> <li><code class="language-plaintext highlighter-rouge">figlet -f slant Command Line!</code> (more font <code class="language-plaintext highlighter-rouge">-f</code> options: slant, shadow, small, smslant, smshadow, big, digital, bubble, script, smscript, lean, block, mini, banner)</li> </ul> <p>Classic games:</p> <ul> <li><code class="language-plaintext highlighter-rouge">sudo apt-get bsdgames</code></li> <li><code class="language-plaintext highlighter-rouge">tetris-bsd</code> (see <a href="http://wiki.linuxquestions.org/wiki/BSD_games">full list</a>)</li> </ul> <p>Matrix:</p> <ul> <li><code class="language-plaintext highlighter-rouge">sudo apt install cmatrix</code></li> <li><code class="language-plaintext highlighter-rouge">cmatrix</code> (try <code class="language-plaintext highlighter-rouge">-r</code>, <code class="language-plaintext highlighter-rouge">-b</code> or check options with <code class="language-plaintext highlighter-rouge">-h</code>)</li> </ul> <p>Watch Star Wars: <code class="language-plaintext highlighter-rouge">telnet towel.blinkenlights.nl</code></p> <p>Read some <a href="https://uni.xkcd.com/">xkcd</a> comics!</p> <p><a href="https://github.com/veltman/clmystery">Solve a mystery</a>…</p> <h2 id="reference">Reference</h2> <ul> <li><a href="https://ss64.com/">SS64 Command line reference</a></li> <li><a href="http://swcarpentry.github.io/shell-novice/">Shell lesson</a> from Software Carpentry</li> <li><a href="http://linuxcommand.org/tlcl.php">The Linux Command Line</a> by William Shotts</li> <li><a href="https://opensource.com/article/17/2/command-line-tools-data-analysis-linux">10 command-line tools for data analysis in Linux</a> by Jason Baker</li> <li><a href="http://rik.smith-unna.com/command_line_bootcamp/">command line bootcamp</a></li> <li><a href="https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Command_line">mdn web docs Command Line Crash Course</a></li> <li><a href="https://ubuntu.com/tutorials/command-line-for-beginners#1-overview">Ubuntu commandline fore beginners</a></li> </ul> Sat, 04 Mar 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/commandline.html https://evanwill.github.io/_drafts/notes/commandline.html Install OpenRefine on Mac <p><strong>Out of Date!</strong></p> <p>Mac seems to have issues when trying to install OpenRefine–and each version of OS X / macOS has different problems! The official instructions are on the <a href="https://github.com/OpenRefine/OpenRefine/wiki/Installation-Instructions#mac-osx">OpenRefine wiki</a>, but this list brings together resources to trouble shoot some common issues during install.</p> <ol> <li>Open Refine needs <strong>Java JRE</strong>. Go to the <a href="https://www.java.com/en/">Java page</a>, download and install the most up-to-date version for Mac. <ul> <li>OS X has a few issues with Java, many are documented at <a href="https://java.com/en/download/faq/java_mac.xml">Oracle Java on Mac OS X</a>. Older versions of Java are automatically disabled by OS X, so make sure yours is up-to-date. If you try the rest of this install process and Refine still doesn’t work, you may need the <a href="https://support.apple.com/kb/DL1572?locale=en_US">legacy Java from Apple</a>.</li> </ul> </li> <li> <p><strong>Download</strong> the latest OpenRefine <code class="language-plaintext highlighter-rouge">.dmg</code> version (as of this post <code class="language-plaintext highlighter-rouge">openrefine-mac-2.7.dmg</code>) from the <a href="https://github.com/OpenRefine/OpenRefine/releases">Releases page</a>.</p> </li> <li><strong>Install</strong> by opening the <code class="language-plaintext highlighter-rouge">.dmg</code> and dragging the OpenRefine icon into the Applications folder icon. <ul> <li>Older versions of OS X might prompt an error message: “Google Refine is damaged and can’t be opened”. This is due to <a href="https://support.apple.com/en-us/HT202491">OS X Gatekeeper</a> misidentifying Refine. If you encounter this error, you need to change a setting, in Apple menu &gt; <em>System Preferences</em> &gt; <em>Security &amp; Privacy</em> &gt; <em>General</em> tab &gt; <em>Allow applications downloaded from:</em> &gt; change to <em>Anywhere</em>.</li> </ul> </li> <li><strong>Run</strong> by double clicking on the OpenRefine icon in he Applications folder. <ul> <li>Recent versions of macOS amy give you a warning at this point saying “OpenRefine is blocked from opening because it is not from an identified developer”. Go to <em>System Preferences</em> &gt; <em>Security &amp; Privacy</em> &gt; <em>General</em> tab, and look under <em>Allow apps downloaded from</em>. It should say something about “OpenRefine” was blocked, click the <em>Open Anyway</em> button.</li> <li>OpenRefine icon should appear in your dock, and a browser window should automatically open. <em>However</em>, sometimes a browser window does not automatically open. Then manually navigate to <a href="http://localhost:3333/">http://localhost:3333/</a> or <a href="http://127.0.0.1:3333/">http://127.0.0.1:3333/</a> to find the Refine interface.</li> </ul> </li> <li><strong>Shutdown</strong> by clicking the OpenRefine icon in the dock and then typing <code class="language-plaintext highlighter-rouge">Command-Q</code>.</li> </ol> Wed, 01 Mar 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/open-refine-osx.html https://evanwill.github.io/_drafts/notes/open-refine-osx.html Handy Linux Apps <p>Search the repository at <a href="http://packages.ubuntu.com/">Ubuntu Packages</a> to find proper names to install with <code class="language-plaintext highlighter-rouge">sudo apt install</code>. If you want to install apps from outside the repositories, download the <code class="language-plaintext highlighter-rouge">.deb</code>. Install <code class="language-plaintext highlighter-rouge">.deb</code> via commandline using <code class="language-plaintext highlighter-rouge">sudo dpkg -i package-name.deb</code>, and remove with <code class="language-plaintext highlighter-rouge">sudo dpkg -r package-name</code> (note: the remove package name is not the same as the <code class="language-plaintext highlighter-rouge">.deb</code>’s name).</p> <h2 id="text-editors">Text Editors</h2> <ul> <li><a href="https://evanwill.github.io/_drafts/notes/gedit-editor.html">Gedit</a></li> <li><a href="https://atom.io/">Atom</a></li> <li><a href="https://code.visualstudio.com/">Visual Studio Code</a></li> <li><a href="http://notepadqq.altervista.org/wp/">notepadqq</a>, linux notepad++ clone</li> </ul> <h2 id="utilities">Utilities</h2> <ul> <li>Password database: <code class="language-plaintext highlighter-rouge">keepass2</code></li> <li>File renamer: <a href="https://launchpad.net/pyrenamer">pyRenamer</a>, older batch file renamer, but still works. Unique feature allows you to use a csv list to rename a batch of files.</li> <li>Screencast: <code class="language-plaintext highlighter-rouge">vokoscreen</code>, or <code class="language-plaintext highlighter-rouge">kazam</code></li> <li>File transfer/sync: <code class="language-plaintext highlighter-rouge">grsync</code> (GUI rsync), <code class="language-plaintext highlighter-rouge">meld</code> (GUI diff and merge).</li> <li>Backup: <code class="language-plaintext highlighter-rouge">deja-dup</code></li> <li>Rip DVDs: <code class="language-plaintext highlighter-rouge">handbrake</code> (note: the version in the repository is out-of-date, check the official <a href="https://handbrake.fr/">handbrake site</a> for instructions to install the latest)</li> <li>Flickr uploader: <code class="language-plaintext highlighter-rouge">frogr</code></li> <li>Ebook manager: Calibre, if you have ebooks, this helps you manage them and connect with reading devices. It also has great built in editing and conversion tools.</li> <li>Burn SD/USB images: <a href="https://www.balena.io/etcher/">Etcher</a></li> <li>Firewall: <code class="language-plaintext highlighter-rouge">ufw</code> or <code class="language-plaintext highlighter-rouge">gufw</code></li> <li><code class="language-plaintext highlighter-rouge">caffeine</code> keeps screen awake during movies</li> <li><code class="language-plaintext highlighter-rouge">virtualbox</code> VM manager, also if you ever need windows for some reason, get a legal <a href="https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/">windows VM</a></li> </ul> <h2 id="image-editing">Image editing</h2> <ul> <li>Image editing: GIMP, <code class="language-plaintext highlighter-rouge">gimp</code> (the first time you open it, click “Windows” &gt; “Single window mode” for a more usable experience). If you use raw images, check out Darktable. To play with HDR, <code class="language-plaintext highlighter-rouge">luminance-hdr</code>.</li> <li>Vector drawing: Inkscape or Vectr.</li> </ul> <h2 id="games">Games</h2> <ul> <li>SuperTux Kart, <code class="language-plaintext highlighter-rouge">supertuxkart</code></li> <li>SuperTux 2, <code class="language-plaintext highlighter-rouge">supertux</code></li> <li><a href="https://endless-sky.github.io/">Endless Sky</a>, <code class="language-plaintext highlighter-rouge">endless-sky</code></li> <li><a href="http://stabyourself.net/mari0/#download">mari0</a></li> <li><code class="language-plaintext highlighter-rouge">gweled</code></li> </ul> <h2 id="handy-distros">Handy distros</h2> <ul> <li><a href="https://volumio.org/">Volumio</a>, dedicated audio player</li> <li><a href="https://evanwill.github.io/_drafts/notes/retropie.html">RetroPie</a>, dedicated game emulator</li> </ul> Thu, 02 Feb 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/linux-apps.html https://evanwill.github.io/_drafts/notes/linux-apps.html Burn SD or USB for Raspberry Pi and more! <blockquote> <p>MILL-Mini workshop: This session will take you through the Why and How of burning ISO/IMG files to SD or USB for single board computers or installing Linux.</p> <p>If you are interested in Raspberry Pi, please see more recent <a href="https://evanwill.github.io/_drafts/notes/rpi-intro2.html">Pi intro workshop</a>. I suggest burning images for Pi using <a href="https://www.raspberrypi.com/software/">Raspberry Pi Imager</a>.</p> </blockquote> <h2 id="background">Background</h2> <p>Burning a disk image or bootable USB stick is an important task if you want to use Raspberry Pi or Linux. When you buy a Windows, Chromebook, or Mac computer, the operating system (OS) comes pre-installed. However, if you are interested in running Linux or other open OS, you will most likely have to install it yourself. Traditionally, installation was done by burning a disk image onto a CD or DVD. Since most devices no longer have optical drives, we now create bootable SD or USB instead.</p> <h2 id="copying-files-versus-burning-an-image">Copying files versus burning an image</h2> <p>A Raspberry Pi doesn’t come with an OS. To get started using your Pi, you need to add a OS to a SD card. You can simply copy <a href="https://www.raspberrypi.org/downloads/noobs/">NOOBS</a> on to an SD card, and it will magically work! But that is <strong>NOT</strong> burning a disk image. You have only copied the files on to the SD’s existing file system.</p> <p>If you want to try any other Pi OS, it will come as an IMG file. Most <a href="https://distrowatch.com/">linux distributions</a> are provided as an ISO file. IMG and ISO are exact binary copies of a storage device. If you simply copy them over to an SD, nothing will happen. The image has to be “burnt”, essentially overwriting the entire media removing the existing file system.</p> <p>So let’s get an image and burn it to some media!</p> <h2 id="1-get-an-img--iso">1. Get an IMG / ISO</h2> <p>For Raspberry Pi and other single board computers, you will usually get an IMG file representing an hard drive image. These are often zipped or in some other archive (<code class="language-plaintext highlighter-rouge">.zip</code> or <code class="language-plaintext highlighter-rouge">.xz</code>) to decrease the download size. It is not necessary to unzip. For example:</p> <ul> <li><a href="https://www.raspberrypi.org/software/">Raspberry Pi OS</a></li> <li><a href="https://volumio.org/">Volumio</a></li> </ul> <p>Linux distros are generally released as an ISO, often called a “live cd” or “live usb” meaning it can boot from the install media. For example:</p> <ul> <li><a href="https://www.ubuntu.com/">Ubuntu</a></li> <li><a href="https://neon.kde.org/">KDE Neon</a></li> </ul> <p>Some linux distros are specifically designed to be portable. You always use them from a USB stick and do not install to a hard drive. For example:</p> <ul> <li><a href="http://puppylinux.org/">Puppy Linux</a></li> <li><a href="https://www.slax.org/en/">Slax</a></li> <li><a href="http://www.porteus.org/">Porteus</a></li> </ul> <p>Many specialized utilities are also distributed as images so that they can be run from portable media to make changes to a system without a functioning OS. For example:</p> <ul> <li><a href="https://gparted.sourceforge.io/livecd.php">GParted Live</a></li> <li><a href="https://dban.org/">DBAN</a></li> <li>Anti-virus rescue CDs <ul> <li><a href="https://www.bitdefender.com/support/how-to-create-a-bitdefender-rescue-cd-627.html">Bitdefender</a></li> <li><a href="http://www.avg.com/gb-en/rescue-cd-business-edition">AVG</a></li> </ul> </li> </ul> <h2 id="2-get-media">2. Get media</h2> <p>Now you need a micro SD card for Raspberry Pi or a USB stick for linux on a computer. Be sure to get media that is bigger than the image you want to burn!</p> <ul> <li><strong>SD cards:</strong> There is a confusing variety of SD cards out there today. Look for one labelled SDHC (SDXC are incompatible with some systems), Class 10 / UHS 3. The numbers aren’t essential, but faster read/write speeds will give better performance. 8GB is standard, but I like to get at least 16GB, since the SD card will be the main hard drive for your Pi. If your computer does not have an SD slot, get a SD reader.</li> <li><strong>USB drives:</strong> Most USB drives will be fine for installing linux. However, if you want to use it as a live USB or portable desktop, look for USB 3 versions with faster read/write speeds if possible.</li> </ul> <blockquote> <p><strong>Optional: Format media.</strong> If you have previously used the media, you might want to start with a nice clean disk by re-formatting. If you are on Windows or Mac, get the official <a href="https://www.sdcard.org/downloads/formatter_4/index.html">SD Formatter</a>. This will enable you to restore SD or USB you have previously burnt, which Windows and Mac are unable to actually read. On linux, the built in formatting utilities are generally sufficient to restore and format media. If necessary use Gparted and format to fat32. However, when using Etcher, formatting before burning is rarely necessary.</p> </blockquote> <h2 id="3-get-etcher">3. Get Etcher</h2> <p><a href="https://www.balena.io/etcher/">Download Etcher</a> for your system, and extract the <code class="language-plaintext highlighter-rouge">.zip</code> file (you should get a single <code class="language-plaintext highlighter-rouge">.AppImage</code> file on Linux or an <code class="language-plaintext highlighter-rouge">.exe</code> on windows).</p> <p>Why Etcher and not the million other options out there?</p> <ul> <li>Easy to use, it automatically selects the right drives and just works!</li> <li>Can burn from archived (.zip, .7z, etc) images automatically.</li> <li>Open source, cross platform, and easy to install.</li> <li>New and actively developed (most are not).</li> <li>Fast and efficient, with built in verification of the burn.</li> </ul> <h2 id="4-burn-image">4. Burn image</h2> <p>Start up Etcher by clicking on the <code class="language-plaintext highlighter-rouge">.AppImage</code> or <code class="language-plaintext highlighter-rouge">.exe</code> file. Etcher makes the rest easy!</p> <ol> <li>Plug your media into the computer.</li> <li>Select the image.</li> <li>Select the SD/USB (if you have only one plugged in, it will be automatically selected).</li> <li>Click Flash! (you may need to authenticate at this point, since you are making changes to a drive)</li> <li>Wait. Wait…</li> <li>Remove your SD/USB.</li> </ol> <p>Now you can go play with your Raspberry Pi or try out a new Linux distro!</p> <p>Next, see <a href="https://evanwill.github.io/_drafts/notes/linux-boot-usb.html">Boot a Live USB</a> for tips about how to get the USB to boot on your computer.</p> Fri, 27 Jan 2017 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/burn-iso.html https://evanwill.github.io/_drafts/notes/burn-iso.html Gedit tips <p><a href="https://wiki.gnome.org/Apps/Gedit">Gedit</a> is the default text editor for Gnome and Ubuntu (where its called “Text Editor”). Opened with default options it seems a very basic and not very interesting or useful editor, basically like classic Notepad. However, dig a little deeper, and its a great and powerful text editor.</p> <p>Here is some tips to set it up with everything you expect from a good code editor:</p> <ol> <li>Default look: open <code class="language-plaintext highlighter-rouge">Edit</code> &gt; <code class="language-plaintext highlighter-rouge">Preferences</code>. <ul> <li>On the View tab, check “Display line numbers”, “Highlight Current Line”, and “Highlight matching brackets”.</li> <li>On the Editor tab, check “Enable automatic indentation”.</li> <li>On Font &amp; Colours tab check “Kate” theme.</li> <li>These and other view options are of course totally up to your personal preferences, but the above options are default on most code oriented editors. Note: the line view options can quickly be changed by clicking the Ln, Col information at the bottom of the document.</li> </ul> </li> <li>Spell check: click <code class="language-plaintext highlighter-rouge">Tools</code> &gt; “Highlight misspelled words”. Works like a charm! Very handy for markdown or HTML content.</li> <li>File browser: click <code class="language-plaintext highlighter-rouge">View</code> &gt; <code class="language-plaintext highlighter-rouge">Side panel</code>, then from the drop down menu above the side panel, select “File Browser”. Toggle with <code class="language-plaintext highlighter-rouge">F9</code>. This is very handy when working on a project that is a series of files in a directory.</li> <li>More plugins: Gedit ships with a series of <a href="https://wiki.gnome.org/Apps/Gedit/ShippedPlugins">standard plugins</a> that extend functionality. However, its easy to get a few more from your software repository. On Ubuntu, install some extras with <code class="language-plaintext highlighter-rouge">sudo apt-get install gedit-plugins</code>. Then head to <code class="language-plaintext highlighter-rouge">Edit</code> &gt; <code class="language-plaintext highlighter-rouge">Preferences</code> &gt; Plugins tab to see the new functionality you can enable. Personally, in addition to the standards I enable “Bracket Completion”, “Find in Files”, “Git”, “Join/Split Lines”, “Smart Spaces”, and “Text Size”.</li> </ol> <p>This will get Gedit the functionality you might expect from a code focused editor, while still remaining a lean, easy-to-use, handy app.</p> Thu, 29 Dec 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/gedit-editor.html https://evanwill.github.io/_drafts/notes/gedit-editor.html Regex tips <p><a href="https://en.wikipedia.org/wiki/Regular_expression">Regular Expressions</a> are incredibly handy when processing text files, giving you find &amp; replace super powers. Exactly how they are implemented depends on the tool you are using, both in how you enter the expressions and which functions are available. Learn, practice, and test expressions using <a href="http://regexr.com/">RegExr</a>, but keep in mind that it uses JavaScript which doesn’t implement all methods.</p> <p>Here is list of random expressions I don’t want to forget:</p> <ul> <li><a href="https://digitalaladore.wordpress.com/2015/01/18/aladore-regex/">Digital Aladore discussion</a></li> <li>find blank lines, <code class="language-plaintext highlighter-rouge">(?&lt;![\d\w\S])\n</code></li> </ul> Sat, 10 Dec 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/regex-tips.html https://evanwill.github.io/_drafts/notes/regex-tips.html Use Jekyll Deploy command <p><a href="https://github.com/vwochnik/jekyll-deploy"><code class="language-plaintext highlighter-rouge">jekyll-deploy</code></a> adds a new jekyll command, accessed on the command line as <code class="language-plaintext highlighter-rouge">jekyll deploy</code>. It allows you to add a custom config to quickly deploy the site after build to a different destination.</p> <h2 id="install">install</h2> <p>Create a file in root project directory called <code class="language-plaintext highlighter-rouge">Gemfile</code> that contains:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source "https://rubygems.org" gem 'jekyll', '3.2.1' group :jekyll_plugins do gem 'jekyll-deploy' end </code></pre></div></div> <p>Open a terminal in the project directory and type command <code class="language-plaintext highlighter-rouge">bundle install</code>. This will download and install the plugin.</p> <h2 id="configure">configure</h2> <p>Open the project’s <code class="language-plaintext highlighter-rouge">_config.yml</code>. Add deploy command to the end of the config, for example:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># deploy commands deploy: - rsync -r ./ ../../test/ </code></pre></div></div> <p>Deploy commands run from the <code class="language-plaintext highlighter-rouge">_site</code> directory and can be any command line phrase.</p> <h2 id="use">use</h2> <p>First, build your project using <code class="language-plaintext highlighter-rouge">jekyll build</code> or <code class="language-plaintext highlighter-rouge">jekyll serve</code>. Then type command <code class="language-plaintext highlighter-rouge">jekyll deploy</code>. This will activate the command you set in the config.</p> Sat, 05 Nov 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/jekyll-deploy.html https://evanwill.github.io/_drafts/notes/jekyll-deploy.html Download your Gists <p>I like <a href="https://gist.github.com/">GitHub Gists</a> a lot. Very handy service! When I start a digital odd job, I like to take notes in Gists, because otherwise I will forget what I did. Gists is a handy memory aid.</p> <p>However, I realized Gists isn’t the easiest place to find things. So this site was born. Random thoughts and notes-to-self about how to do digital odd jobs. Much of it is half baked or wacky work arounds. but it might help you get something done. At the least it helps me remember and acts as a handy personal reference source.</p> <p>To start up this blog I wanted to grab all my previous Gists. <a href="https://developer.github.com/v3/">GitHub API</a> makes this fairly easy for public content. Just choose a language that can download stuff and create files, and you can write up a script.</p> <p>In my case, all my Gist are a single Markdown file, so its very easy. I just want to get a list of my Gists, download each one, and create a copy of the <code class="language-plaintext highlighter-rouge">.md</code> locally. For me it was easiest to modify a Ruby script from <a href="https://gist.github.com/blazeeboy/9547245">blazeeboy</a>. Since my Gist are only a single file, and I wanted them all in single directory to move into a Jekyll project, my version looks like:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>#!/usr/bin/env ruby require 'open-uri' require 'json' username = evanwill # get gists puts 'Downloading gists list' gists_str = open("https://api.github.com/users/#{username}/gists").read gists = JSON.parse gists_str gists.each_with_index do |gist, index| puts "#{index+1}/#{gists.length} Downloading #{gist['url']}" gist_str = open(gist['url']).read gist = JSON.parse gist_str gist["files"].each do |file_name, file_value| File.open("#{file_name}", 'w') { |f| f.write file_value['content']} end end </code></pre></div></div> <p>Save the script as <code class="language-plaintext highlighter-rouge">getGists.rb</code> in a new directory, then run it by opening the directory in a terminal, and typing <code class="language-plaintext highlighter-rouge">ruby getGists.rb</code>. All your public Gists will be downloaded into the directory. If you want each in its own directory, check the original from <a href="https://gist.github.com/blazeeboy/9547245">blazeeboy</a>. If you need to authenticate to get private gists, there are some other options out there.</p> Tue, 01 Nov 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/get-gists.html https://evanwill.github.io/_drafts/notes/get-gists.html Update Grub boot order on multi boot system <p>If you dual boot Windows and Linux, you will probably want to change the default boot order at some point. When logged into Ubuntu, open terminal:</p> <p><code class="language-plaintext highlighter-rouge">sudo nano /etc/default/grub</code></p> <p>Change <code class="language-plaintext highlighter-rouge">GRUB_DEFAULT=</code> to the value you want, based on its position on the GRUB menu when your computer starts up (the top OS is 0). You can use the number or use the exact label like <code class="language-plaintext highlighter-rouge">GRUB_DEFAULT="Ubuntu 15"</code></p> <p>If you want to just use the same OS as was choose last time, set <code class="language-plaintext highlighter-rouge">GRUB_DEFAULT=saved</code> and add a line <code class="language-plaintext highlighter-rouge">GRUB_SAVEDEFAULT=true</code></p> <p>Set <code class="language-plaintext highlighter-rouge">GRUB_TIMEOUT=</code> to the number of seconds you want to wait until it boots the default OS.</p> <p>Exit and save the file.</p> <p>To update the actual GRUB files, you must now run:</p> <p><code class="language-plaintext highlighter-rouge">sudo update-grub</code></p> <p>done!</p> Wed, 05 Oct 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/grub-boot-order.html https://evanwill.github.io/_drafts/notes/grub-boot-order.html Using Jekyll on Windows <h2 id="static-gen-background-links">Static Gen background links:</h2> <ul> <li>lists: <a href="https://www.staticgen.com/about">StaticGen directory</a> or <a href="https://staticsitegenerators.net/">Static Site Generators</a></li> <li>“Why Static Website Generators Are The Next Big Thing” <a href="https://www.smashingmagazine.com/2015/11/modern-static-website-generators-next-big-thing/">Smashing magazine</a></li> <li><a href="https://jekyllrb.com/docs/home/">Jekyll documentation, intro</a></li> </ul> <h2 id="install-on-windows-7">Install on Windows 7</h2> <p>Jekyll does not officially support Windows, however it is cross platform (they just don’t officially write windows documentation or check for bugs). There is a <a href="https://jekyllrb.com/docs/windows/#installation">Jekyll on Windows</a> page, but it is out of date. Not everything mentioned is required any more.</p> <blockquote> <p>For more complete install info, and other platforms see <a href="https://evanwill.github.io/go-go-ghpages/0-prep.html">go-go gh-pages</a>.</p> </blockquote> <p>Here are the steps I took to get it running on Windows 7 or 10:</p> <ol> <li>Get Ruby installed: <ul> <li>Download the suggested stable version of <a href="http://rubyinstaller.org/downloads/">RubyInstaller</a> (Ruby 2.4.X (x64)+).</li> <li>Run RubyInstaller, all the defaults should be fine. On the final step, ensure the box to start the MSYS2 DevKit is checked.</li> <li>The installer will open a terminal window with options to install MSYS2 DevKit components. Choose option 3, “MSYS2 and MINGW development toolchain”, or simply press ENTER to install all the necessary dependencies. (This installer can be restarted by typing <code class="language-plaintext highlighter-rouge">ridk install</code> into a command prompt)</li> </ul> </li> <li>Install Jekyll: <ul> <li>Open a command prompt, then type <code class="language-plaintext highlighter-rouge">gem install jekyll bundler</code> (gem is Ruby’s installer, similar to Python’s pip)</li> <li>Done!</li> </ul> </li> <li>Use Jekyll: <ul> <li>To create a new demo project, open a command prompt, type <code class="language-plaintext highlighter-rouge">jekyll new testsite</code>. Jekyll will create a new directory with the given name that includes all the files necessary for a basic project. Once you understand the basics, this step is unnecessary.</li> <li>Move to the new directory, type <code class="language-plaintext highlighter-rouge">cd testsite</code></li> <li>To start working with it, type <code class="language-plaintext highlighter-rouge">jekyll serve</code>. (note: for larger sites you will want to activate incremental build, use the short command <code class="language-plaintext highlighter-rouge">jekyll s -i</code>)</li> <li>Open web browser and visit http://localhost:4000</li> <li>To stop the server, type <code class="language-plaintext highlighter-rouge">Ctrl+C</code> in the command prompt.</li> <li>While <code class="language-plaintext highlighter-rouge">jekyll serve</code> is active, Jekyll watches the project directory and builds a static html site in the directory <code class="language-plaintext highlighter-rouge">_site</code> which it serves locally.</li> <li>Jekyll watches for any changes you made to the project files and rebuilds the <code class="language-plaintext highlighter-rouge">_site</code> as necessary.</li> <li>Don’t make changes to the <code class="language-plaintext highlighter-rouge">_site</code> directory. It is generated by Jekyll from all the other files.</li> <li>Jekyll bundles together a bunch of other helpful development tools, such as <a href="http://sass-lang.com/">SASS</a> for CSS and <a href="https://shopify.github.io/liquid/">Liquid</a> for templating pages.</li> <li>When you are done developing, the contents of the <code class="language-plaintext highlighter-rouge">_site</code> directory will be copied to your host location (for example testweb or github).</li> <li>Use a good text editor, since files should be UTF-8, and there can be issues with line endings. I use <a href="https://code.visualstudio.com/">Visual Studio Code</a> which is handy for navigating the directory structure.</li> </ul> </li> </ol> <h2 id="a-tour-of-the-project-directory">A tour of the project directory</h2> <ul> <li><code class="language-plaintext highlighter-rouge">testsite</code> (the top level contains pages that will become top level pages. Edit the overall site settings in <code class="language-plaintext highlighter-rouge">_config.yml</code>. Changes to <code class="language-plaintext highlighter-rouge">_config.yml</code> are not automatically refreshed during <code class="language-plaintext highlighter-rouge">jekyll serve</code>, you have to stop the server and restart.) <ul> <li><code class="language-plaintext highlighter-rouge">_includes</code> These are modular chunks of your pages which can be called into a page layout by Liquid. For example <code class="language-plaintext highlighter-rouge">{% include head.html %}{% end raw %}</code> in a page layout would add the include <code class="language-plaintext highlighter-rouge">head.html</code> from the <code class="language-plaintext highlighter-rouge">_includes</code> directory.</li> <li><code class="language-plaintext highlighter-rouge">_layouts</code> These are basic templates for complete web pages. They are constructed out of includes. The layouts are called by files that have content to add the template structure.</li> <li><code class="language-plaintext highlighter-rouge">_posts</code> This directory contains blog posts. We are more likely to use a <code class="language-plaintext highlighter-rouge">_collections</code> directory for similar automated treatment of standardized content pages.</li> <li><code class="language-plaintext highlighter-rouge">_sass</code> This contains the modular <code class="language-plaintext highlighter-rouge">.scss</code> files that will be pulled into your main css for the site. All normal CSS is valid SCSS, but Sass adds many helpful functions and programatic features which are compiled into regular CSS automatically.</li> <li><code class="language-plaintext highlighter-rouge">_site</code> This is the built out version of your new static site.</li> <li><code class="language-plaintext highlighter-rouge">css</code> Contains the base SCSS file that will be compiled into a single CSS file for the site. You can set all your Sass varibles in one place (if you are using them) and call in your scss partials from <code class="language-plaintext highlighter-rouge">_sass</code> by using <code class="language-plaintext highlighter-rouge">@import "base";</code></li> <li>You can add other directories as needed for site assets such as <code class="language-plaintext highlighter-rouge">images</code>. They will be copied directly to the <code class="language-plaintext highlighter-rouge">_site</code> directory.</li> </ul> </li> </ul> <h2 id="example-themes-with-demos">Example Themes with demos</h2> <ul> <li><a href="http://themes.jekyllrc.org/">http://themes.jekyllrc.org/</a></li> <li><a href="http://jekyllthemes.org/">http://jekyllthemes.org/</a></li> </ul> <h2 id="on-gh-pages">On gh-pages</h2> <p>Contrary to popular belief, GitHub Pages does allow/support a few plugins. Here is the list: <a href="https://pages.github.com/versions/">https://pages.github.com/versions/</a></p> <p>Add them to your <code class="language-plaintext highlighter-rouge">_config.yml</code>, under <code class="language-plaintext highlighter-rouge">gems:</code>, not in the the gemfile (since gh-pages ignores that). They can be installed as a bundle using the <code class="language-plaintext highlighter-rouge">github-pages</code> gem. Of interest are:</p> <ul> <li>jekyll-seo-tag (GitHub <a href="https://help.github.com/articles/search-engine-optimization-for-github-pages/">info</a>, <a href="https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md">usage</a>, basically add {% raw %}<code class="language-plaintext highlighter-rouge">{% seo %}</code> to the <code class="language-plaintext highlighter-rouge">&lt;head&gt;</code> of your pages, and make sure you have all the metadata in your <code class="language-plaintext highlighter-rouge">_config.yml</code>).</li> <li>jekyll-sitemap (GitHub <a href="https://help.github.com/articles/sitemaps-for-github-pages/">info</a>, <a href="https://github.com/jekyll/jekyll-sitemap">repo</a>).</li> </ul> Mon, 03 Oct 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/jekyll-notes.html https://evanwill.github.io/_drafts/notes/jekyll-notes.html Use Git locally to collaborate <blockquote> <p>you can use Git with out a cloud service to simplify collaboration in repository on a shared drive</p> </blockquote> <h2 id="set-up-shared-repository">Set up shared repository</h2> <p>Create a directory on the shared drive to hold the repository, then <code class="language-plaintext highlighter-rouge">git init --bare</code>. By convention, bare repos are given the extension <code class="language-plaintext highlighter-rouge">.git</code>.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /t/ mkdir newRepo.git cd newRepo.git git init --bare </code></pre></div></div> <p>The bare repo is not like a normal repository. It does not have copies of the working files visible, only the full git history. Bare repos are only for sharing and collaborating on a repo, not making changes to files. You will see the working files when you clone the bare repo to a normal repository locally.</p> <p>On your local working drive, create a repository and add the bare repo as remote.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /c/ mkdir newRepo cd newRepo git init git remote add origin /t/newRepo.git echo "init" &gt; README git add README git commit -m "init" git push -u origin --all </code></pre></div></div> <h2 id="collaborate">Collaborate</h2> <p>Now some else can make a copy of <code class="language-plaintext highlighter-rouge">newRepo</code> from the shared drive <code class="language-plaintext highlighter-rouge">/t/</code>.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone /t/newRepo.git cd newRepo </code></pre></div></div> <p>Make some changes or a new branch.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git branch newFeature git checkout newFeature echo "new stuff" &gt; newfile.txt git add newfile.txt git commit -m "new file" git push --set-upstream origin newFeature </code></pre></div></div> <p>When you create a new branch you need to <code class="language-plaintext highlighter-rouge">git push --set-upstream origin newbranch</code> to set up the new branch in the bare repo.</p> <p>If you already have <code class="language-plaintext highlighter-rouge">newRepo</code>, update by pulling (this should grab any new branches).</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /c/newRepo git pull </code></pre></div></div> <p>Now when the new branch is ready for prime time, merge it into master.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /c/newRepo git pull git checkout master git merge newFeature git push </code></pre></div></div> Fri, 30 Sep 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/local-git.html https://evanwill.github.io/_drafts/notes/local-git.html PocketCHIP stuff <blockquote> <p>The makers of CHIP went out of business as of 2018 and took all their code down. If you want to keep your CHIP running, you have to rely on the community…</p> </blockquote> <h2 id="archived-stuff">Archived stuff</h2> <ul> <li><a href="http://www.chip-community.org/index.php/Main_Page">CHIP Community wiki</a></li> <li>JF Possibilities, <a href="http://www.chip-community.org/index.php/Main_Page">“CHIP is dead.. or is it?”</a> and <a href="http://chip.jfpossibilities.com/docs/pocketchip.html">mirrored the original documentation</a></li> <li>yoursunny, <a href="https://yoursunny.com/t/2018/CHIP-flash-offline/">How to Flash C.H.I.P Offline</a>.</li> <li>Thore-Krug, <a href="https://github.com/Thore-Krug/Flash-CHIP">Flash-CHIP</a></li> </ul> <h2 id="utility">Utility</h2> <p>built in calculator: <code class="language-plaintext highlighter-rouge">xcalc</code></p> <p>use the built in browser: <code class="language-plaintext highlighter-rouge">surf http://google.com</code> (need help, <code class="language-plaintext highlighter-rouge">man surf</code>)</p> <p>get a text browser: <code class="language-plaintext highlighter-rouge">sudo apt-get install lynx</code></p> <p>get a graphical browser: <code class="language-plaintext highlighter-rouge">sudo apt-get install midori</code></p> <p>get a paint program: <code class="language-plaintext highlighter-rouge">sudo apt-get install mypaint</code></p> <p>or: <code class="language-plaintext highlighter-rouge">sudo apt-get install grafx2</code></p> <p>notetaking: <code class="language-plaintext highlighter-rouge">sudo apt-get install xournal</code></p> <p>sudo apt-get install evolvotron</p> <h2 id="from-blog">From blog</h2> <p>http://blog.nextthing.co/give-your-pocketc-h-i-p-3-new-abilities-software-tutorials-from-the-community/</p> <p>http://blog.nextthing.co/heres-how-to-host-a-90s-style-doom-lan-party-using-pocketc-h-i-p/</p> <p>http://blog.nextthing.co/customize-the-hell-out-of-your-pocketc-h-i-p-install-doom-give-it-an-icon-on-the-home-screen/</p> <h2 id="fun-terminal-stuff">Fun terminal stuff</h2> <p>Watch star wars in ASCII:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install telnet</code></p> <p><code class="language-plaintext highlighter-rouge">telnet towel.blinkenlights.nl</code></p> <p>Get lots of games:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install bsdgames</code></p> <p>bsdgames includes: adventure, arithmetic, atc, backgammon, battlestar, bcd, boggle, caesar, canfield, countmail, cribbage, dab, go-fish, gomoku, hack, hangman, hunt, mille, monop, morse, number, pig, phantasia, pom, ppt, primes, quiz, random, rain, robots, rot13, sail, snake, tetris, trek, wargames, worm, worms, wump, wtf. Play bsdgames by typing the name on the terminal.</p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install ninvaders</code></p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install nethack</code></p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install 2048-cli</code></p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install moon-buggy</code></p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install robotfindskitten</code></p> <h2 id="rouge-like">rouge-like</h2> <p>http://crawl.develz.org/wordpress/</p> <p>https://sites.google.com/site/broguegame/</p> <p>http://www.adom.de/home/downloads.html</p> <h2 id="emulators">Emulators</h2> <p><code class="language-plaintext highlighter-rouge">apt-get install visualboyadvance</code> Then type <code class="language-plaintext highlighter-rouge">vba</code> to run it. Vba [rom location] to run the game.</p> <p>vice: http://www.rift.dk/blog/run-vice-on-your-pocketchip</p> <p>http://www.lemon64.com/?mainurl=http%3A//www.lemon64.com/games/list.php%3Fpublisher%3D%28Public+Domain%29</p> <p>To run VICE, type x64 from the terminal. To load a game, tap File then mount a disk, browsing to wherever you put your files.</p> <p>MEdnafen: https://bbs.nextthing.co/t/mednafen-emulator-configuration-gbc-gba-snes-nes/5027</p> <p>retroarch: https://github.com/libretro/RetroArch/wiki/Compilation-guide-(Linux)</p> <p>RetroArch doesn’t require GL. You can compile it without GL/GLES/EGL at the expense of some features (no fancy menus, only RGUI; no shaders). I’m assuming you’ll be able to compile it similarly to how it used to be compiled for rpi (note that opengl/egl/gles are disabled during the ./configure step): https://www.raspberrypi.org/forums/viewtopic.php?t=56070</p> <p>fceux</p> <h2 id="case-mods">Case mods</h2> <p>keyboard face plate, http://www.thingiverse.com/thing:1670579</p> <p>keyboard, http://www.thingiverse.com/thing:1686723</p> <p>d-pad, http://www.thingiverse.com/thing:1644139</p> <p>combine PiGrrl parts?</p> <p>source files, https://github.com/NextThingCo/PocketCHIP-Mechanical</p> Wed, 01 Jun 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pocketchip.html https://evanwill.github.io/_drafts/notes/pocketchip.html How to setup Etherpad on a cloud VM <p>Set up an Ubuntu server, then follow these directions to get an instance of Etherpad up and running! For full documentation check out the <a href="https://github.com/ether/etherpad-lite/wiki">Etherpad-lite wiki</a>.</p> <h2 id="install-dependencies">Install dependencies</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt-get install gzip git-core curl python libssl-dev pkg-config build-essential apache2 </code></pre></div></div> <h2 id="install-nodejs">Install nodejs</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get install -y nodejs </code></pre></div></div> <h2 id="create-a-non-root-user">Create a non-root user</h2> <p>add a user to install etherpad, and give it a password:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo useradd -m ether-user sudo passwd ether-user </code></pre></div></div> <h2 id="get-etherpad">Get Etherpad</h2> <p>As ether-user (<code class="language-plaintext highlighter-rouge">sudo su - ether-user</code>), grab Etherpad from the repository:</p> <p><code class="language-plaintext highlighter-rouge">git clone https://github.com/ether/etherpad-lite.git</code></p> <p>At this point you can start it with the default set up:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd etherpad-lite bin/run.sh </code></pre></div></div> <p>It will be running at server.ip.address:9001. You will have to open port 9001 in your network rules to make it available to users. But we should go a bit further to set up a <a href="https://github.com/ether/etherpad-lite/wiki/How-to-use-Etherpad-Lite-with-MySQL">proper database</a>.</p> <h1 id="set-up-db">Set up DB</h1> <p>Install MySQL <code class="language-plaintext highlighter-rouge">sudo apt-get install mysql-server</code> and set a strong password. Start up MySQL with <code class="language-plaintext highlighter-rouge">mysql -u root -p</code> then create a database and give your user access with a strong password:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>create database etherpadlite; grant CREATE,ALTER,SELECT,INSERT,UPDATE,DELETE on etherpadlite.* to ether-user@localhost identified by 'goodpassword'; FLUSH PRIVILEGES; exit </code></pre></div></div> <p>Next, edit the <code class="language-plaintext highlighter-rouge">settings.json</code> file for your Etherpad instance to add the correct details about your new database. First, look for the database setting in the file, and comment out the settings for dirtyDB like this:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/* "dbType" : "dirty", //the database specific settings "dbSettings" : { "filename" : "var/dirty.db" }, */ </code></pre></div></div> <p>Next, uncomment and edit the example given the dirty set up:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> // An Example of MySQL Configuration "dbType" : "mysql", "dbSettings" : { "user" : "ether-user", "host" : "localhost", "password": "goodpassword", "database": "etherpadlite", "charset" : "utf8mb4" }, </code></pre></div></div> <h2 id="set-up-a-proxy-to-make-your-urls-nicer">Set up a proxy to make your URLs nicer</h2> <p>The <a href="https://github.com/ether/etherpad-lite/wiki/How-to-put-Etherpad-Lite-behind-a-reverse-Proxy">wiki</a> gives directions for setting up proxies depending on your server. We will use a simple Apache proxy. Go to the Apache2 settings <code class="language-plaintext highlighter-rouge">cd /etc/apache2/sites-enabled/</code>. Edit the config file inside, <code class="language-plaintext highlighter-rouge">nano default.config</code>. Add the basic proxy described by the wiki:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;VirtualHost *:80&gt; LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so LoadModule headers_module /usr/lib/apache2/modules/mod_headers.so LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so ProxyVia On ProxyRequests Off ProxyPass / http://localhost:9001/ ProxyPassReverse / http://localhost:9001/ ProxyPreserveHost on &lt;Proxy *&gt; Options FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all &lt;/Proxy&gt; &lt;/VirtualHost&gt; </code></pre></div></div> <p>If you want to have your own index, it is easiest to change <code class="language-plaintext highlighter-rouge">ProxyPass / http://localhost:9001/</code> to one level deeper, such as <code class="language-plaintext highlighter-rouge">ProxyPass /pad/ http://localhost:9001/</code>. Then you can use the root level <code class="language-plaintext highlighter-rouge">/</code> for your own pages, in the default Apache directory <code class="language-plaintext highlighter-rouge">/var/www/html/</code>.</p> <h2 id="run-with-screen">Run with screen</h2> <p>If you just want to get Etherpad up and running without monkeying around with start up, you can run it using <code class="language-plaintext highlighter-rouge">screen</code> and detach from your terminal.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>screen sudo su - ether-user cd etherpad-lite bin/run.sh </code></pre></div></div> <p>Then type <code class="language-plaintext highlighter-rouge">ctrl+a</code> and <code class="language-plaintext highlighter-rouge">d</code>. The process will detach from your terminal and continue running. Basic Etherpad is ready!</p> Wed, 01 Jun 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/etherpad-setup.html https://evanwill.github.io/_drafts/notes/etherpad-setup.html Add more to Git Bash on Windows <p><a href="https://git-for-windows.github.io/">Git for Windows</a> comes bundled with the “Git Bash” terminal which is incredibly handy for unix-like commands on a windows machine. It is missing a few standard linux utilities, but it is easy to add ones that have a windows binary available.</p> <p>The basic idea is that <code class="language-plaintext highlighter-rouge">C:\Program Files\Git\mingw64\</code> is your <code class="language-plaintext highlighter-rouge">/</code> (“root”) directory according to Git Bash. If you go to that directory, you will find the typical linux root folder structure (<code class="language-plaintext highlighter-rouge">bin</code>, <code class="language-plaintext highlighter-rouge">etc</code>, <code class="language-plaintext highlighter-rouge">lib</code> and so on).</p> <blockquote> <p><em>note:</em> depending on how you installed it, the directory might be different. Find it by typing <code class="language-plaintext highlighter-rouge">cd /</code> then <code class="language-plaintext highlighter-rouge">pwd -W</code>. Alternatively, from the start menu, right click on the Git Bash icon and select open file location. It might be something like <code class="language-plaintext highlighter-rouge">C:\Users\name\AppData\Local\Programs\Git</code>, the <code class="language-plaintext highlighter-rouge">mingw64</code> in this directory is your root.</p> </blockquote> <p>If you are missing a utility, such as wget, track down a binary for windows and copy the files to the corresponding directories. Sometimes the windows binary have funny prefixes, so you should rename the <code class="language-plaintext highlighter-rouge">.exe</code> file to the standard name. Since <code class="language-plaintext highlighter-rouge">bin</code> is on the PATH, it will be automatically available to Git Bash.</p> <p><em>Note:</em> Some interactive utilities, such as <code class="language-plaintext highlighter-rouge">python</code> or <code class="language-plaintext highlighter-rouge">ipython</code> will not display properly with Git Bash’s mintty terminal. Try invoking them with <code class="language-plaintext highlighter-rouge">winpty</code> instead, for example <code class="language-plaintext highlighter-rouge">winpty ipython</code> will work nicely. The Git-for-Windows team is focused on supporting Git, not a full UNIX shell environment. If you are interested in more complete package, check my notes on <a href="https://evanwill.github.io/_drafts/notes/cygwin.html">Cygwin</a> or <a href="https://evanwill.github.io/_drafts/notes/cmdr.html">Cmder</a>.</p> <p>Here are some utilities to add:</p> <h2 id="wget">Wget</h2> <ul> <li>Download the latest wget binary for windows from <a href="https://eternallybored.org/misc/wget/">eternallybored</a> (they are available as a zip with documentation, or just an exe)</li> <li>If you downloaded the zip, extract all (if windows built in zip utility gives an error, use <a href="http://www.7-zip.org/">7-zip</a>).</li> <li>Rename the file <code class="language-plaintext highlighter-rouge">wget64.exe</code> to <code class="language-plaintext highlighter-rouge">wget.exe</code> if necessary.</li> <li>Move <code class="language-plaintext highlighter-rouge">wget.exe</code> to your <code class="language-plaintext highlighter-rouge">Git\mingw64\bin\</code>.</li> </ul> <p><em>Note: I have noticed some bugs when using Wget on Git Bash to create WARC files. For more complex use of Wget, consider <a href="https://evanwill.github.io/_drafts/notes/cygwin.html">Cygwin</a> instead.</em></p> <h2 id="hugo">Hugo</h2> <p><a href="http://gohugo.io/">Hugo</a> static site generator can be downloaded as a binary and does not have a installer. Dropping it into your <code class="language-plaintext highlighter-rouge">bin</code> easily adds it to your Git Bash path.</p> <ul> <li>Download the Windows 64-bit version from the <a href="https://github.com/gohugoio/hugo/releases">releases page</a>.</li> <li>Unzip, then copy <code class="language-plaintext highlighter-rouge">hugo.exe</code> into your <code class="language-plaintext highlighter-rouge">Git\mingw64\bin</code> directory.</li> </ul> <h2 id="xpdf">Xpdf</h2> <p><a href="http://www.xpdfreader.com/index.html">Xpdf</a> is a handy utility for manipulating PDF files.</p> <ul> <li>Download the <a href="http://www.xpdfreader.com/download.html">windows version “Xpdf tools”</a>.</li> <li>Extract zip.</li> <li>Copy the contents of <code class="language-plaintext highlighter-rouge">xpdf-tools-win-4.00\bin64\</code> into your <code class="language-plaintext highlighter-rouge">Git\mingw64\bin\</code>.</li> <li>Check the <a href="http://www.xpdfreader.com/support.html">docs</a> to get started with tools such as <code class="language-plaintext highlighter-rouge">pdftotext</code> and <code class="language-plaintext highlighter-rouge">pdftopng</code>.</li> </ul> <h2 id="exiftool">ExifTool</h2> <p><a href="https://sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> is a utility to read and write embedded metadata in image files.</p> <ul> <li>Download the “stand-alone Windows Executable” from the <a href="https://sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> page (this will be a <code class="language-plaintext highlighter-rouge">.zip</code> file e.g. “exiftool-11.20.zip”).</li> <li>Unzip the downloaded file.</li> <li>Inside you will find a file named <code class="language-plaintext highlighter-rouge">exiftool(-k).exe</code>. Rename it to <code class="language-plaintext highlighter-rouge">exiftool.exe</code>.</li> <li>Copy <code class="language-plaintext highlighter-rouge">exiftool.exe</code> into your <code class="language-plaintext highlighter-rouge">Git\mingw64\bin</code> directory.</li> </ul> <h2 id="make">make</h2> <ul> <li>Go to <a href="https://sourceforge.net/projects/ezwinports/files/">ezwinports</a>.</li> <li>Download <code class="language-plaintext highlighter-rouge">make-4.1-2-without-guile-w32-bin.zip</code> (get the version without guile).</li> <li>Extract zip.</li> <li>Copy the contents to your <code class="language-plaintext highlighter-rouge">Git\mingw64\</code> merging the folders, but do NOT overwrite/replace any existing files.</li> </ul> <h2 id="nano">Nano</h2> <blockquote> <p>As of 2018, recent versions of Git Bash include Nano, so this is unnecessary!</p> </blockquote> <ul> <li>Download the Nano binary from Nano <a href="https://www.nano-editor.org/dist/win32-support/">win32-support</a> page. You just need the <code class="language-plaintext highlighter-rouge">.exe</code> file, which is named <code class="language-plaintext highlighter-rouge">nano-git-0d9a7347243.exe</code> (as of this writing).</li> <li>Rename the file to <code class="language-plaintext highlighter-rouge">nano.exe</code>, and copy to the <code class="language-plaintext highlighter-rouge">mingw64\bin</code> directory.</li> <li>This version of Nano will not work with Git Bash alone, but can be invoked using <code class="language-plaintext highlighter-rouge">winpty</code>, for example, <code class="language-plaintext highlighter-rouge">winpty nano test.txt</code>.</li> </ul> Thu, 26 May 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/gitbash-windows.html https://evanwill.github.io/_drafts/notes/gitbash-windows.html Writing in Markdown <p>Markdown is a quick and simple way to write formatted documents in plaintext. It is intuitive and easy to read, but is designed to convert to HTML for easy web publishing. Writing in plaintext rather than <a href="https://www.gnu.org/proprietary/proprietary.en.html">proprietary</a> formats such as Word has many advantages:</p> <ul> <li>simple - don’t waste time in complex and frustrating formatting in Word that will be deleted by publishers anyway. This keeps your distractions to a minimum.</li> <li>sharable - any device can open and read plaintext, no special software needed, unlike Word.</li> <li>preservable - markdown is plaintext which is easy for digital preservation, unlike Word.</li> <li>version controllable - you can use the full power of Git or other version control systems, unlike Word.</li> </ul> <h2 id="github-markdown">GitHub Markdown</h2> <p>Markdown was originally developed by <a href="https://daringfireball.net/projects/markdown/">Daring Fireball</a>. However, other “flavors” of md have developed. The most popular is <a href="https://help.github.com/articles/basic-writing-and-formatting-syntax/">GitHub markdown flavor</a>, since it can be used anywhere on GitHub.</p> <p>Here are some tutorials:</p> <ul> <li>GitHub <a href="https://guides.github.com/features/mastering-markdown/">Mastering Markdown Guide</a></li> <li><a href="http://www.markdowntutorial.com/">Markdown Tutorial</a></li> <li><a href="https://www.markdownguide.org/">Markdown Guide</a></li> </ul> <h2 id="markdown-editors">Markdown editors</h2> <p>Markdown is <a href="https://en.wikipedia.org/wiki/Plain_text">plain text</a>, it’s sort of like source code for your document. You can write it in any application that supports plain text, i.e. a text editor. When working with code you should have a good text editor.</p> <p>For basic editing, Windows <a href="https://notepad-plus-plus.org/">Notepad++</a>, Mac TextEdit, or Linux Gedit are sufficient (<em>note:</em> you can use Windows Notepad, but it does not handle UTF-8 encoding or UNIX line endings that are standard for most cross platform applications). However, more advanced code editors often have plugins or features to make it easier with previews of your document. Checkout <a href="https://code.visualstudio.com/">Visual Studio Code</a> (use shortcut <code class="language-plaintext highlighter-rouge">Ctrl+Shift+V</code> to preview) or <a href="https://atom.io/">Atom</a>.</p> <p>If you want a more fully featured visual writing environment, there are also applications devoted specifically to writing in Markdown. These apps will have previews, GUI controls, and automatic export options.</p> <p>Web-based:</p> <ul> <li><a href="http://dillinger.io/">Dillinger</a></li> <li><a href="https://stackedit.io/">StackEdit</a></li> <li><a href="https://hackmd.io/">HackMD</a> (real time collaboration)</li> </ul> <p>Stand alone apps:</p> <ul> <li><a href="https://remarkableapp.github.io/index.html">Remarkable</a> - code / preview split screen.</li> <li><a href="https://www.typora.io/">Typora</a> - live preview writing focused slick new app.</li> </ul> <h2 id="rendering-markdown">Rendering Markdown</h2> <p>Markdown is human readable as plain text–it is intuitive like writing an email. However, it is designed to render as HTML. Markdown compilers are built in to many applications (like the editors above) to generate formatted versions such as HTML, .docx, or PDF.</p> <p>One option is <a href="http://pandoc.org/">Pandoc</a>, a command line utility to translate between many formats and generate new output versions, such as PDFs (via <a href="https://www.latex-project.org/about/">LaTex</a>). Check my note <a href="https://evanwill.github.io/_drafts/notes/pandoc.html">Pandoc for PDFs</a> or the <a href="http://programminghistorian.org/lessons/sustainable-authorship-in-plain-text-using-pandoc-and-markdown">Sustainable Authorship in Plain Text</a> tutorial.</p> Fri, 20 May 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/writing-markdown.html https://evanwill.github.io/_drafts/notes/writing-markdown.html UnLenovo <h2 id="things-to-do-when-you-get-a-new-lenovo-computer">Things to do when you get a new lenovo computer</h2> <ol> <li>Uninstall everything from Lenovo! Its all sketchy bloatware and you don’t need any of it at all. Seriously. Win 10 has everything you need.</li> <li>Navigate over to C:\Program Files (x86)\Lenovo and look in all the directories there and click the unistall.exe files! Cause guess what? Lenovo put some even sleezer things in there that you can’t uninstall via normal means. Then delete all the directories.</li> <li>Just to be sure–You dont need anything in this ^ directory! Customer Engagement Service (CCSDK) and others log your activities and send information to weird unsecure web locations! Yuck!</li> <li>Go into control panel, device manager, and update drivers for wifi, audio, video, intel power management.</li> <li>okay, it should be better now!</li> </ol> Tue, 15 Mar 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/un-lenovo.html https://evanwill.github.io/_drafts/notes/un-lenovo.html Pi Py Poetry, Pi Day Remix <p>Its 3:14 on 3/14 (2016)! Time for some Vandal Poem of the Day (<a href="http://poetry.lib.uidaho.edu/index.php/about/">VPOD</a>) poetry remix using OpenRefine and Python.</p> <p>First, I grabbed all of the poems from <a href="http://poetry.lib.uidaho.edu/">VPOD</a>.</p> <p>Then I parsed it all using OpenRefine.</p> <p>I Refined it down to a table with these columns: title, author, poem, words, length. Each row represents one line from a poem in the corpus. The line is in the ‘poem’ column. The ‘words’ column is a count of words in the line, created in OpenRefine with new column based on ‘poem’ &gt; length(value.ngram(1)). The ‘length’ column is character count of the line, created in OpenRefine with new column based on ‘poem’ &gt; length(value). The ‘title’ and ‘length’ are not used in this example. To simplify I sorted on ‘words’ and used only 1 through 9, since these will match the Pi digits.</p> <p>Then I went into Jupyter Notebook to get started generating poems with Python:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># import stuff import pandas as pd import random # create pandas dataframe from the poem CSV poemDF = pd.read_csv('VPODpoemLines1-9.csv') # create list with digits of Pi piDigits = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3, 8, 3, 2, 7, 9, 5, 0, 2, 8, 8, 4, 1, 9, 7, 1, 6, 9, 3, 9, 9, 3, 7, 5, 1, 0, 5, 8, 2, 0, 9, 7, 4, 9, 4, 4] </code></pre></div></div> <p>This gave me a dataframe with 3344 rows (i.e. lines of poetry. I should have brought it down to 3,141!), representing lines of from 155 poems by 18 VPOD authors. Find that info with:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>len(poemDF['author'].unique()) </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>len(poemDF['title'].unique()) </code></pre></div></div> <p>Okay, now we can make some new remix Pi Py Poems:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># create a random poem based on digits of Pi # first decide number of lines in the poem, # I based this on the approximate range observed in the corpus poemLength = random.randrange(5,60) # create a poem of that random length # the digits of Pi are the number of words per line for i in range(poemLength): if piDigits[i] == 0: print("\n") else: newLine = poemDF[poemDF['words'] == piDigits[i]].sample().values[0][2] print(newLine) </code></pre></div></div> <h2 id="some-pi-py-poems">Some Pi Py Poems:</h2> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Then more lights undefeated, as a train speeding prose Her curling makes me shiver how to open the airway of a fellow passenger it's lying and I marry you each day. Because my heart could not what they were like the residue of beets I can do so only for a moment. barrel, she broke him. She gave the worst smile: has approved all your plans, so you I could never deny it, or disown my desire No, he said. the feet black bird hunched But it's a reassuring logic that rivers freeze Now I remember something </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Because of breathing. * and the snow outside * and burning whatever is there. We'd rut a ditch by a river in nights everyone with violet towers. We scour the earth If you write “ironic detachment” we couldn't hear breaker of others' bones, parachuter, The one called Chukwu? Just one word: God. with a plastic teapot for my sister's tea party. a child's Christmas miracle that I let Can I come back up now? asks the chair my worldly nature Or burn are spelling someone's but more and more it seems it won't. It looks like smoke the mustached man with his shoulders to disappear when it is opened or closed. affix their wintry incubus, our scarves, shrink and life, less Enter a room as though it is strange. holding a jar Glass skins the wonder of them, good or bad, I know you… the skin graft on your cheek, to dream up only this. emitted light a new home, maybe you'll search and petition But it's a reassuring logic that rivers freeze like some plastic beads Yes. maybe you no longer haul those wounds with you </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>off the closets they're and trained it stranger Delivered some type of old-fashioned candy Think of the flesh on an angel's hips, pinched in our to do-- an aperture, a slur-- And blown between adjacent bridges the giant translucent light. And after the light, I eat what's put in front of me, my fear of needles, my cravings for salty food, with empty wine jugs at our heels. of the space movie we all stood in line she came over in our a phoenix preening to empty your bright dress onto the floor, fringe on brown pain Even if I have convinced you, fair, alone. a world flashes by, and opposite, certain spells to protect in the morning of not remembering with a dark beer or hand out leaflets Washed in salt The current then finger, forearm and elbow. Curl yourself No I am not afraid of the eye chart: there are experts among us The current made a circus of it. Asthma, weeping, elephants, and through my reading to a deafening applause. and hope it's clear. alive to own anything with and without blood. Cash rules On the shore, the line of unannointed undefeated, Consume me and find me worthy. You knock and knock at a door, it won't to live. Mother, feel silly in your grief. And still you'll sit by the heat in the tips of her fingers. even on holidays. the silhouette of a single red-mouthed bell; </code></pre></div></div> <p>Good Fun!</p> <h1 id="add-authors">Add Authors</h1> <p>Next I wanted to add authors to the Pi Py Poems. I modified the poem-creating loop like this:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>poemLength = random.randrange(5,60) author = 'Pi Py Poetry' # create a poem of that random length # the digits of Pi are the number of words per line for i in range(poemLength): if piDigits[i] == 0: print("\n") else: newLine = poemDF[poemDF['words'] == piDigits[i]].sample() author += ', ' + newLine.values[0][1] line = newLine.values[0][2] print(line) print('\nBy '+author) </code></pre></div></div> <p>The New poems result in a crazy looking author list, but you can track down the original lines by author (potentially). More examples are below.</p> <h1 id="more-pi-py-poetry-from-vpod">More Pi Py Poetry from VPOD</h1> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>in another room rereading in magic cochineal pants. Shifting snaps free. Sunflash, stereo store, The sage and tomato plants tanning on the veranda. The current and pretend we are lying there which said he was born I once read and you're never getting out. places to disappear but it was fooling itself, they are stuffed in every corner of a house all this silence and emptiness and rust for the certainty of home, for mills and reservoirs Every question, conversation beneath the I do remember I close the shop at six. Welcome wind, this time of year to step from the wrought-iron compartment, She's alive only a dream is so lucky. dressed like a rabbit think they're alone. Resurrection and crucifixion. Whatever you say sounds better with your thigh I float bestowing without knowing I'll admit, she's earned her orchestra seats they attempt to pull the survivor from its flood there remains more to learn. how often. Not like what they told us at all in a field, two and a half days. But I'm dry now, rereading The pay toilets where we sat without paper. Rain. There is a dawn between my legs, embarrassing covers from romance novels, their heroines And a call to joy-- a landscape, a face-- then thrown away to love the dark. I love it so much you feel sick in ways you thought not possible. sip false peace who are dead now laugh and laugh. grow especially talkative at night, senseless. By Pi Py Poetry, Laura Kasischke, C.D. Wright, Natalie Diaz, Laura Kasischke, James Arthur, Roger Reeves, Kerry James Evans, Natalie Diaz, Matthew Zapruder, Matthew Zapruder, Mark Bibbins, Dean Young, Valzhyna Mort, Laura Kasischke, James Arthur, Dean Young, Michael Dickman, Matthew Zapruder, C.D. Wright, Brenda Shaughnessy, C.D. Wright, Michael Dickman, Brenda Shaughnessy, Matthew Zapruder, Brenda Shaughnessy, Chris Abani, Mark Bibbins, Matthew Zapruder, Matthew Zapruder, Erin Belieu, Sherwin Bitsui, Lisa Olstein, Brenda Shaughnessy, Michael Dickman, Lisa Olstein, Kerry James Evans, C.D. Wright, C.D. Wright, Natalie Diaz, Brenda Shaughnessy, Erin Belieu, Sarah Lindsay, Valzhyna Mort, Lisa Olstein, Chris Abani, Matthew Zapruder, Laura Kasischke, C.D. Wright, Brenda Shaughnessy </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>but there's still being Tunisia of desert silence 6 tell us his tired children Coupling beneath my feet. I want the body's burden, could theoretically should I wish to review them. contain you, it refused sympathy, Cigarette in hand. while you sleep? Sleeping is trapped in the bill of a circling bird, and I don't bruise easily, that I am yours so two sets of passengers come eye-to-eye because your hemisphere has rolled away from the sun, turns into breath and senses a phoenix preening it's my leg lifted over my man's body. Consumers will pay more belled purple cluster, I'd rather plump-girl- books die As always I can do nothing. have forgotten fear, apparently a phoenix preening traveling toward us I stomp down a refinery, trail a scat Not your name if stars a blood orange swelling like a breast-- for slavers. In the lake, red dye bubbles up to be mauled by wolves heaven, like that will eventually like me into the earth wiping his greasy hands on a greasier rag, a bright green snake created and every house carries a legend of a captain In the oven, something breathing. Rising. Melting. hair. my brother's leg destroyed after detonation; of a neighborhood pool floats up on the heat. from the '70s a rent check or explains anything to one's family. My fear of uniforms is an old habit, comfortable. 960 antitank mines By Py Pi Poem, Michael Dickman, Laura Kasischke, Matthew Zapruder, Natalie Diaz, Matthew Zapruder, Roger Reeves, Matthew Zapruder, Lisa Olstein, Lisa Olstein, Laura Kasischke, Lisa Olstein, Erin Belieu, Brenda Shaughnessy, James Arthur, James Arthur, Brenda Shaughnessy, Valzhyna Mort, Natalie Diaz, Valzhyna Mort, Lisa Olstein, Erin Belieu, Valzhyna Mort, Matthew Zapruder, Sarah Lindsay, Natalie Diaz, Laura Kasischke, James Arthur, Michael Dickman, James Arthur, Natalie Diaz, Chris Abani, Sherwin Bitsui, Laura Kasischke, Matthew Zapruder, Dean Young, Lisa Olstein, Michael Dickman, Valzhyna Mort, Laura Kasischke, Laura Kasischke, Kerry James Evans, Erin Belieu, Matthew Zapruder, Erin Belieu, Chris Abani, Kerry James Evans </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>in the home. waistless, be there, get it? • Already you're in the air even lightning can go wrong but when the smoke having pressed not blue-veined, but full of flesh, that weren't fenced or watered. a phoenix preening only in the exit wounds, to sip at the lachrymal glands of chaos, floating through the candled dark in shiny black slacks then I wake up. Did you know a Vespa in the second person, want it to pleasuring your feet, You know your own shadow, register key. And yet, how fine it feels, my dreams mostly water. There are bulls between my legs, They stand white votives shivered in red glass on a report card. into the ocean Smoking a cigarette that he would give his life for you. into the sky diamond after then left in the shade to multiply. with a hollow pen, how to wrestle an alligator, some type of old-fashioned candy another ambulance The one called Chukwu? Just one word: God. I've never bothered with the names of flowers, that's the mortal art. * a Vespa in the second person, want it to and without your permission. O dummies dancing reading Heretics banged at the double door. By Pi Py Poetry, Brenda Shaughnessy, Brenda Shaughnessy, Brenda Shaughnessy, Michael Dickman, Dean Young, Dean Young, Matthew Zapruder, Roger Reeves, C.D. Wright, Natalie Diaz, Brenda Shaughnessy, Dean Young, Michael Dickman, Lisa Olstein, Mark Bibbins, Erin Belieu, Michael Dickman, Brenda Shaughnessy, Erin Belieu, Dean Young, Natalie Diaz, Valzhyna Mort, Natalie Diaz, Valzhyna Mort, Michael Dickman, Michael Dickman, Chris Abani, Michael Dickman, Michael Dickman, Laura Kasischke, Lisa Olstein, Laura Kasischke, Natalie Diaz, Chris Abani, Erin Belieu, James Arthur, Michael Dickman, Mark Bibbins, Roger Reeves, C.D. Wright, Natalie Diaz </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>We said despair Both Or am I alone? Imperceptible that veins blued through it Blue gourds glow and rattle like a two-man band: believe, too. puffballs tenderly bunched in my armpits. all-y, all-y, all come free with exacting coordinates I was never your Intended, whose ruby shoes throb on shelves in closets, bark the tips of its leaves with cracked amber-- are gone now; we never held them to the left of the graveyard, where the trees The throb lingering harmlessly decompose </code></pre></div></div> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>in Peru 14% Noisier Maybe they used to dead from the one who loves, walk around in the yard not making a plan. waist-high, elbow-deep-- particular I didn't come to know: I'd thank it for making it is quiet is good enough advice. [Move Four more angels to drag through the streets A foot chalking a valley black and bright beneath has approved all your plans, so you For years I could count on waking to plenty, eat another apple but forgot who must sense to sip at the lachrymal glands of chaos, aglow with determination, pursuing of shame dissolving in my throat; Can't matter it's garbage night. The moon agrees, of plastic pop-up targets The fire glowing The final arbitration. But the plain ones are patient, aren't they? And follows itself The foghorns and quickly became symbolic, bound to occur they attempt to pull the survivor from its flood in the grass the bodies believe, too. The first cell felt no call to divide. since Cousin Bobby told her about a comma Love. Hunger. Other alchemies. * were starting to cover the land and someday everyone was a thing of incomparable curvaceous length; today and i am on my knees to love the dark. I love it so much turns into breath Like a sharpshooter who knows to pull the trigger of the space movie we all stood in line on both sides, their mother invited next to the fire, a nursery for new stars. By Pi Py Poetry, Matthew Zapruder, C.D. Wright, Michael Dickman, Michael Dickman, Brenda Shaughnessy, C.D. Wright, Lisa Olstein, Erin Belieu, Mark Bibbins, Matthew Zapruder, Mark Bibbins, Roger Reeves, Roger Reeves, Laura Kasischke, Sarah Lindsay, Natalie Diaz, Matthew Zapruder, Brenda Shaughnessy, Dean Young, Sarah Lindsay, Erin Belieu, Brenda Shaughnessy, Mark Bibbins, Kerry James Evans, Laura Kasischke, Chris Abani, Erin Belieu, Brenda Shaughnessy, Michael Dickman, Sarah Lindsay, Sherwin Bitsui, Natalie Diaz, Brenda Shaughnessy, Sarah Lindsay, Sarah Lindsay, Laura Kasischke, Michael Dickman, Matthew Zapruder, Sarah Lindsay, Michael Dickman, Valzhyna Mort, Lisa Olstein, Brenda Shaughnessy, Lisa Olstein, Matthew Zapruder, Kerry James Evans, Erin Belieu, C.D. Wright </code></pre></div></div> <h2 id="and-remember-read-real-poems-daily-at-vandal-poem-of-the-day">And Remember: Read real poems daily at <a href="http://poetry.lib.uidaho.edu/">Vandal Poem of the Day</a></h2> Mon, 14 Mar 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/pi-py-poems.html https://evanwill.github.io/_drafts/notes/pi-py-poems.html Open image editing <p>Need to edit some photos? Need an alternative to absurdly expensive and user unfriendly commercial image software (i.e. photoshop)?</p> <p>Luckily, the free software community has you covered. Here are some notes about some options. If you need more tools and processing workflows, check out the resources at <a href="https://pixls.us/software/">PIXLS.US</a>.</p> <h2 id="raster-gimp">Raster: GIMP</h2> <p>An essential utility for every computer, <a href="https://www.gimp.org/">GIMP (GNU Image Manipulation Program)</a> is a complete raster graphics editing software package. Download it or install from your software repository. When you first open the application, its in the difficult to use multiple window mode. Personally, the first thing I do is click the “Window” menu and select “Single-Window Mode”. This docks the various tool bars into a single window (much like modern versions of photoshop). To me it seems much easier to use in this mode, although many power users prefer the other mode.</p> <p>Also check out <a href="https://www.darktable.org/">Darktable</a>, the “workflow application and raw developer”, kind of like Adobe Bridge.</p> <h2 id="other-handy-tools">Other handy tools</h2> <ul> <li><a href="https://inkscape.org/en/">Inkscape</a> is a decent free and open vector graphics application.</li> <li><a href="http://www.imagemagick.org">ImageMagick</a> command line image processing / creation tool. Handy for batch processes, image type conversions, or editing with another programming language. It comes installed on most linux distros, so you can just open a terminal and type something like <code class="language-plaintext highlighter-rouge">convert test.jpeg test.png</code> to start using it. Or you might resize a whole directory of images like <code class="language-plaintext highlighter-rouge">convert '*.jpg[300x300]' squares%03d.png</code> and then make them into a GIF like <code class="language-plaintext highlighter-rouge">convert *.png images.gif</code>.</li> <li><a href="http://gmic.eu/">G’MIC</a> image processing language / library / plugin.</li> <li><a href="http://hugin.sourceforge.net/">Hugin</a> Panorama stitching utility. I misuse it to create stitch nonsense together…</li> <li><a href="http://qtpfsgui.sourceforge.net/">Luminance HDR</a> HDR utility. I use it to create glitchy images from arbitrary sets of images…</li> <li><a href="http://www.sno.phy.queensu.ca/~phil/exiftool/">ExifTool</a> image metadata utility, the only reliable way to read and write photo file embedded metadata. Or you can try <a href="http://www.exiv2.org/index.html">Exiv2</a>.</li> <li><a href="http://www.irfanview.com/">Ifranview</a> if you are on Windows, this is a handy viewer with very good batch utilities built in.</li> </ul> Tue, 01 Mar 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/image-editing.html https://evanwill.github.io/_drafts/notes/image-editing.html Download metadata from flickr <p>You can bulk download stuff from flickr very easily now (which is a great feature), by going to Camera Roll, selecting things, and clicking download. Or you can bulk download your sets/albums now as well by visiting the set/album and clicking the download button. This is handy, but it doesn’t export any metadata you added to the photos in the system.</p> <p>Unfortunately, I found none of the apps are very stable. The most recent and least broken apps are:</p> <ul> <li>Flickr Downloadr, https://flickrdownloadr.com/</li> <li>FlickrMetadataSynchr, http://flickrmetadatasynchr.codeplex.com/</li> </ul> <p>Linux has one good option, but set up takes forever if you have lots of photos,</p> <ul> <li>picty, https://github.com/spillz/picty</li> </ul> <h2 id="exiftool">Exiftool</h2> <p>You want <code class="language-plaintext highlighter-rouge">exiftool</code>, nothing else consistently works to look at metadata.</p> <ul> <li>Download the complete version, http://www.sno.phy.queensu.ca/~phil/exiftool/</li> <li>extract the files</li> <li>in the extracted directory, use <code class="language-plaintext highlighter-rouge">./exiftool picture.jpg</code> to look at exif data of the pic without installing.</li> <li>use <code class="language-plaintext highlighter-rouge">./exiftool -json=picture.jpg.json picture.jpg</code> to write json metadata to the embedded exif data of the image (you get the json or xmp file from other applications).</li> </ul> Tue, 01 Mar 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/flickr-download.html https://evanwill.github.io/_drafts/notes/flickr-download.html Disable Autoplay <p>Autoplay video and audio ads and content are amazingly annoying. Anyone who lived through the era of popups knows ad creators don’t care about user experience, but I still don’t understand why they think aggressive, annoying, and abusive additions to a web page will actually help sell stuff. Maybe they are driven by analytics numbers showing users interacting with the ads–unfortunately in most cases it’s users trying to figure out how to block, disable, and dismiss the intrusion. Personally, I hate autoplay content just as much as ads, but some website seem convinced you want video and you want it to play immediately, and you don’t want to be able turn it off or hide it on your own. I mean, what do you know anyway, your just the user??</p> <p>In any case, ads that run using Flash or other plugins can and should be blocked simply by having all plugins ask before running. Many autoplay ads will be blocked by an adblocker, such as <a href="https://github.com/gorhill/uBlock">uBlock Origin</a>. However, HTML5 autoplay content videos / audio are a bit different.</p> <p>Here is some options to block them:</p> <h2 id="firefox">Firefox</h2> <ul> <li>add <a href="https://addons.mozilla.org/en-US/firefox/addon/flashstopper/">Flashstopper</a> plugin, which despite its name blocks HTML5 autoplay as well as Flash.</li> <li>If you want to go further, Firefox has a relatively new and hidden setting to prevent most from playing as you load the page, although its not perfect. In your Firefox address bar, type <code class="language-plaintext highlighter-rouge">about:config</code> to bring up the manual configurations. If you haven’t used it before, you will have to dismiss a warning about how its dangerous to modify things. Yep. Now search for <code class="language-plaintext highlighter-rouge">autoplay</code> using the box at the top. You should find a preference called <code class="language-plaintext highlighter-rouge">media.autoplay.enabled</code> with the value <code class="language-plaintext highlighter-rouge">true</code>. Right click on the value and choose <code class="language-plaintext highlighter-rouge">Toggle</code> to change it to <code class="language-plaintext highlighter-rouge">false</code>. Close the config, and restart Firefox. Most HTML5 videos set to autoplay should now be blocked! The only problem is that a lot of sites use video autoplay for content you actually want to see and haven’t implemented their videos properly to allow the user to start them manually. For example, video on Twitter doesn’t seem to work with autoplay disabled. This is either bad developing, not realizing that there is use cases where a video needs to be started manually, or just intentional anti-feature to force you to watch auto play spam if you want to watch their legitimate content.</li> </ul> <h2 id="chromium--chrome">Chromium / Chrome</h2> <ul> <li>add <a href="https://chrome.google.com/webstore/detail/disable-html5-autoplay/efdhoaajjjgckpbkoglidkeendpkolai">Disable HTML5 Autoplay</a> plugin. Unforturnately, this plugin is not actively developed (check news at the <a href="https://github.com/Eloston/disable-html5-autoplay">repository</a>). There is some hints that the functionality will move to <a href="https://github.com/gorhill/uBlock">uBlock Origin</a>.</li> <li>be sure to enable tab muting (available by default in Firefox): paste <code class="language-plaintext highlighter-rouge">chrome://flags/#enable-tab-audio-muting</code> into the address bar. Click <code class="language-plaintext highlighter-rouge">Enable</code> to toggle the feature on. Now you can click on the little speaker icon on any tab to mute the audio.</li> </ul> Tue, 01 Mar 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/autoplay.html https://evanwill.github.io/_drafts/notes/autoplay.html Text Analysis Notes <blockquote> <p>Collection of Text Analysis resources from various workshops and presentations.</p> </blockquote> <h2 id="text-analysis">Text Analysis?</h2> <p>= a messy term that encompasses many interconnected processes such as text data collection, cleaning, parsing, summary, visualization. Also known as <a href="https://en.wikipedia.org/wiki/Text_mining">text mining</a>.</p> <p>Examples: Text Annotation, <a href="https://en.wikipedia.org/wiki/Natural_language_processing">Natural Language Processing</a>, <a href="https://en.wikipedia.org/wiki/Sentiment_analysis">Sentiment Analysis</a></p> <h2 id="explore-a-text">Explore a Text</h2> <blockquote> <p>remember: Your Data == Text</p> </blockquote> <p>Juxta (digital text collation. NINES.)</p> <ul> <li><a href="http://juxtacommons.org/">Juxtacommons</a> (online version, great for sharing)</li> <li><a href="http://www.juxtasoftware.org/">desktop</a> (legacy desktop version)</li> <li>My <a href="https://digitalaladore.wordpress.com/2014/12/29/using-juxta/">Digital Aladore example</a></li> </ul> <p>Voyant Tools (suite of online text visualization tools. Stéfan Sinclair &amp; Geoffrey Rockwell)</p> <ul> <li><a href="http://voyant-tools.org/">Voyant web app</a></li> <li><a href="http://docs.voyant-tools.org/">Voyant docs</a></li> </ul> <p>Wordseer (suite of tools run on local server)</p> <ul> <li><a href="https://github.com/Wordseer/wordseer">repository</a></li> <li><a href="http://wordseer.berkeley.edu/">docs</a></li> </ul> <p>TokenX (“a text visualization, analysis, and play tool”. Brian Pytlik Zillig, U of Nebraska Libraries)</p> <ul> <li><a href="http://tokenx.unl.edu/tokenx/index.html">TokenX web app</a></li> </ul> <p>WordTree (Jason Davies)</p> <ul> <li><a href="https://www.jasondavies.com/wordtree/">Word tree web app</a></li> <li><a href="http://hint.fm/projects/wordtree/">academic explanation of word tree</a></li> </ul> <p>NLP</p> <ul> <li><a href="http://nlp.stanford.edu/software/">Stanford NLP Group</a> (a library of Java apps, e.g. <a href="http://nlp.stanford.edu:8080/ner/">named entity tagging demo</a></li> <li><a href="http://www.opencalais.com/">Open Calais</a> (API trained on web and newspaper text)</li> <li>Watson <a href="https://www.ibm.com/watson/developercloud/natural-language-understanding.html">Natural Language Understanding</a> (API trained on web content)</li> </ul> <h2 id="explore-a-corpus">Explore a Corpus</h2> <p>Topic Modeling</p> <ul> <li>Megan R. Brett, <a href="http://journalofdigitalhumanities.org/2-1/topic-modeling-a-basic-introduction-by-megan-r-brett/">“Topic Modeling: A Basic Introduction” (2012)</a></li> <li><a href="http://mallet.cs.umass.edu/">MALLET (MAchine Learning for LanguagE Toolkit)</a> (Programming Historian <a href="http://programminghistorian.org/lessons/topic-modeling-and-mallet">MALLET lesson</a>)</li> <li><a href="https://github.com/senderle/topic-modeling-tool">Topic Modeling Tool</a> (simple visual way to use part of MALLET) <ul> <li>example classroom projects: Sherlock Holmes’s London <a href="https://sherlockholmeslondondh.wordpress.com/2015/03/23/topic-modeling-assignment/">prep</a> and <a href="https://sherlockholmeslondondh.wordpress.com/2015/03/27/topic-modeling-part-2-graphing-the-results/">analysis</a>; Posner <a href="http://miriamposner.com/blog/very-basic-strategies-for-interpreting-results-from-the-topic-modeling-tool/">basic strategies</a> and <a href="https://github.com/miriamposner/tmt_get_started">tmt_get_started</a>.</li> </ul> </li> </ul> <p>Overview Docs (online tool designed for journalists to sort through huge data sets)</p> <ul> <li><a href="https://www.overviewdocs.com/">Overview web app</a></li> <li>Good <a href="https://blog.overviewdocs.com/help/">help docs</a></li> </ul> <p>Jigsaw (“Visual Analytics for Exploring and Understanding Document Collections”)</p> <ul> <li><a href="http://www.cc.gatech.edu/gvu/ii/jigsaw/">desktop app</a></li> <li><a href="http://www.iilabgt.org/webjigsaw">WebJigsaw</a></li> </ul> <p>Concordancers</p> <ul> <li><a href="http://www.laurenceanthony.net/software/antconc/">AntConc</a> (lots of software and publications from Laurence Anthony)</li> <li><a href="https://sites.google.com/site/casualconc/Home">CasualConc</a> (R package)</li> <li><a href="http://neon.niederlandistik.fu-berlin.de/en/textstat/">TextSTAT</a></li> </ul> <h2 id="explore-a-huge-corpus">Explore a Huge Corpus</h2> <blockquote> <p>Think about Big Data 3 V’s (volume, variety and velocity).</p> </blockquote> <p>Ngrams</p> <ul> <li><a href="http://bookworm.culturomics.org/">Bookworm</a></li> <li>Google Books <a href="https://books.google.com/ngrams">Ngram Viewer</a> (see <a href="https://www.ted.com/talks/what_we_learned_from_5_million_books?language=en">TED talk</a>)</li> </ul> <p>Hathi Trust <a href="https://sharc.hathitrust.org/">Research Center Portal</a> (big text data)</p> <p>Twitter analysis</p> <ul> <li>Healey &amp; Ramaswamy, <a href="http://www.csc.ncsu.edu/faculty/healey/tweet_viz/">“Visualizing Twitter Sentiment” (2013)</a></li> <li>Clement Levallois, <a href="http://www.umigon.com/">“Umigon: sentiment analysis on Tweets based on terms lists and heuristics” (2013)</a></li> <li>now everyone is doing it! <a href="https://interactive.twitter.com/">Twitter interactive</a></li> </ul> <h2 id="explore-text-with-programming">Explore Text with Programming</h2> <p>Python</p> <ul> <li>Distribution: <a href="https://www.continuum.io/downloads">Anaconda</a> (get Python 3, 64-bit)</li> <li>Tool Kit: <a href="http://www.nltk.org/">NLTK</a> (install via <code class="language-plaintext highlighter-rouge">conda install nltk</code> or <code class="language-plaintext highlighter-rouge">pip install nltk</code>)</li> <li>Learn: <a href="http://www.nltk.org/book/">NLTK Book</a> (Steven Bird, Ewan Klein, and Edward Loperm, designed to teach text analysis)</li> </ul> <p>R</p> <ul> <li>Distribution: <a href="https://cran.rstudio.com/">R</a></li> <li>IDE: <a href="https://www.rstudio.com/products/rstudio-desktop/">RStudio</a></li> <li>Learn: <a href="http://www.matthewjockers.net/text-analysis-with-r-for-students-of-literature/">Text analysis with R for students of literature</a>, Matthew L Jockers (New York : Springer-Verlag, 2014).</li> </ul> <p>Bash Shell</p> <ul> <li>The command line has lots of great functions for manipulating text files!</li> <li>Programming Historian, <a href="http://programminghistorian.org/lessons/intro-to-bash">Introduction to the Bash Commandline</a></li> <li>SWC, <a href="http://swcarpentry.github.io/shell-novice/">Unix Shell</a></li> </ul> <h2 id="tool-catalogs--directories">Tool Catalogs / Directories</h2> <ul> <li><a href="http://dirtdirectory.org/">DIRT</a> (Digital Research Tools)</li> <li><a href="http://tapor.ca/home">TAPoR3</a> (“Discover research tools for studying text”)</li> <li><a href="http://dhcommons.org/">DH Commons</a> (good place to find example projects)</li> </ul> <blockquote> <p><strong>Caution</strong>: Due to the nature of academic funding cycles, there is a lot of dead tools/projects out there, and a lot of tutorials for dead tools. Many of these tools still work, but without active maintenance they may not for long. Due to the technical and statistical nature of these tools, descriptions of what they do and how they work may be Difficult reading… Don’t be intimidated! However, it is good to be aware of the academic literature explaining the tools and algorithms since you may need to cite them to validate the techniques in your own work.</p> </blockquote> <h2 id="helpful-dh-resources">Helpful DH Resources</h2> <ul> <li><a href="http://programminghistorian.org/">Programming Historian</a></li> <li><a href="http://litlab.stanford.edu/pamphlets/">Stanford Litlab Pamphlets</a></li> <li>Miriam Posner <a href="http://miriamposner.com/dh101f15/index.php/tutorials-and-resources/suggested-tools/">DH 101</a> and <a href="http://miriamposner.com/blog/">blog</a>.</li> </ul> <blockquote> <p>Overheard: stopwords, “to be or not to be”</p> </blockquote> Thu, 18 Feb 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/text-analysis.html https://evanwill.github.io/_drafts/notes/text-analysis.html wget notes <p>Wget is a handy commandline utility for grabbing stuff off the web. It is built into most UNIX systems. If you are on windows, install <a href="https://git-scm.com/">Git for Windows</a> which comes packaged with <code class="language-plaintext highlighter-rouge">Git Bash</code>, a very handy UNIX terminal emulator (note: check if Git Bash has wget installed by typing <code class="language-plaintext highlighter-rouge">wget --version</code>. If it is not installed, check this <a href="https://evanwill.github.io/_drafts/notes/gitbash-windows.html">note</a>). Other windows options are <a href="https://evanwill.github.io/_drafts/notes/cygwin.html">Cygwin</a>, <a href="http://mobaxterm.mobatek.net/">MobaXterm</a>, or <a href="https://msdn.microsoft.com/en-us/commandline/wsl/install_guide">Bash on Windows Subsystem</a>.</p> <p>See all the commands by typing <code class="language-plaintext highlighter-rouge">wget --help</code> in your terminal or visiting the <a href="http://www.gnu.org/software/wget/manual/wget.html">man page</a>.</p> <h2 id="download-files-from-a-list">Download files from a list</h2> <p>Create a plain text list of urls you want to download, one per line. Use the <code class="language-plaintext highlighter-rouge">-i</code> option to pass that list to wget.</p> <p><code class="language-plaintext highlighter-rouge">wget -i download-file-list.txt</code></p> <h2 id="download-all-files-of-a-type-from-a-domain">Download all files of a type from a domain</h2> <p>Use the <code class="language-plaintext highlighter-rouge">-r</code> (recursive) and <code class="language-plaintext highlighter-rouge">-A</code> (accept) options. For example, download all PDFs:</p> <p><code class="language-plaintext highlighter-rouge">wget -r -A.pdf http://page-with-pdfs.com/</code></p> <p>limit to file type: <code class="language-plaintext highlighter-rouge">--accept html</code></p> <h2 id="check-dead-links">Check dead links</h2> <p><code class="language-plaintext highlighter-rouge">wget --spider -o test.log -e robots=off -w 5 --random-wait --mirror --page-requisites --no-parent http://www.example.com</code></p> <h2 id="fully-mirror-a-site">Fully mirror a site</h2> <p>Download everything you need to have an exact copy of a full site locally:</p> <p><code class="language-plaintext highlighter-rouge">wget --mirror --convert-links --adjust-extension --page-requisites --wait=2 --random-wait http://example.org</code></p> <p>If you only want files from a specific set of domains use <code class="language-plaintext highlighter-rouge">--domains=LIST</code> with a comma separated list. If you just want to crawl part of a domain use <code class="language-plaintext highlighter-rouge">--no-parent</code> flag. If the site has redirects to send you to an authorative version of a page, you might want to use <code class="language-plaintext highlighter-rouge">--trust-server-names</code>, which will name the files based on the file URL rather than the original URL (before redirects).</p> <h2 id="warc-web-archive-options">WARC web archive options</h2> <p><a href="https://www.loc.gov/preservation/digital/formats/fdd/fdd000236.shtml">WARC</a> is a web archive format that stores page content, response headers, and metadata for a group of web pages. One WARC can contain all the pages gathered during a web harvest. In addition to HTML documents, it can contain binary content such as images.</p> <p>To create a WARC for any wget crawl, simply add the <code class="language-plaintext highlighter-rouge">--warc-file="filename"</code> flag to the command. Wget will harvest the site assets as normal, but additionally create a WARC compressed as a <code class="language-plaintext highlighter-rouge">.gz</code> file. For larger sites it’s a good idea to add <code class="language-plaintext highlighter-rouge">--warc-max-size=1G</code> to limit the max size of each WARC so they don’t get too big.</p> <p>Combined with a mirror, it might look like:</p> <p><code class="language-plaintext highlighter-rouge">wget --mirror --wait=2 --random-wait --warc-file="example.org-archive" http://example.org</code></p> <p>If necessary you can also send a different user agent if the server refuses to give content to wget’s default one, like <code class="language-plaintext highlighter-rouge">--user-agent=Mozilla</code>. Occasionally it might be necessary to ignore robot.txt for archival purposes, add <code class="language-plaintext highlighter-rouge">-e robots=off</code> to the command.</p> <p>If you want to view your WARC later, use <a href="https://github.com/webrecorder/webrecorderplayer-electron">Webrecorder Player</a>.</p> <h2 id="download-a-file-and-change-the-filename">Download a file and change the filename</h2> <p>Let say you have an API with funny url that gives you an image. Wget might save it with some bizarre filename. You can change the file name with the <code class="language-plaintext highlighter-rouge">--output-document</code> option (<code class="language-plaintext highlighter-rouge">-O</code>). For example:</p> <p><code class="language-plaintext highlighter-rouge">wget -O new.jpg "http://example.org?CISOROOT=HJCCC&amp;CISOPTR=9&amp;action=2&amp;DMSCALE=100&amp;DMWIDTH=9000&amp;DMHEIGHT=9000&amp;DMX=0&amp;DMY=0&amp;DMTEXT=&amp;DMROTATE=0"</code></p> Fri, 15 Jan 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/wget-notes.html https://evanwill.github.io/_drafts/notes/wget-notes.html Handy Raspberry Pi Commands <p>cheat sheet of tips mainly for headless RPI</p> <h2 id="first-time-set-up">First time set up</h2> <p>default password for “pi” is “raspberry”</p> <p>First time set up: <code class="language-plaintext highlighter-rouge">sudo raspi-config</code></p> <p>update everything: <code class="language-plaintext highlighter-rouge">sudo apt-get update &amp;&amp; sudo apt-get upgrade</code></p> <h2 id="general">General</h2> <p>start GUI: <code class="language-plaintext highlighter-rouge">startx </code></p> <p>shut down: <code class="language-plaintext highlighter-rouge">sudo shutdown -h now</code></p> <h2 id="ssh">SSH</h2> <p>ssh into the pi: <code class="language-plaintext highlighter-rouge">ssh [email protected]</code></p> <p>copy files to pi: <code class="language-plaintext highlighter-rouge">scp filename [email protected]:~/destination/foldername/</code></p> <p>copy files From pi: <code class="language-plaintext highlighter-rouge">scp [email protected]:~/source/file /destination/directory/</code></p> <h2 id="vnc---desktop-sharing">VNC - desktop sharing</h2> <p>install VNC: https://www.raspberrypi.org/documentation/remote-access/vnc/</p> <p>start a vnc server: <code class="language-plaintext highlighter-rouge">vncserver :0 -geometry 800x600 -depth 16</code></p> <p>stop: <code class="language-plaintext highlighter-rouge">vncserver -kill :0</code></p> <h2 id="networking">Networking</h2> <p>check network config and get ip address: <code class="language-plaintext highlighter-rouge">ifconfig </code></p> <p>edit config: <code class="language-plaintext highlighter-rouge">sudo nano /etc/network/interfaces</code></p> <h2 id="startup">Startup</h2> <p>edit startup: <code class="language-plaintext highlighter-rouge">sudo nano /etc/rc.local</code></p> <h2 id="mount-usb-drive">Mount USB drive</h2> <ol> <li>plug in the usb drive</li> <li>find what the drive is called with <code class="language-plaintext highlighter-rouge">ls -l /dev/disk/by-uuid/</code>, normally it will be /sda1</li> <li>create a directory to connect to the drive, i.e. a mount point: <code class="language-plaintext highlighter-rouge">sudo mkdir /media/usb</code></li> <li>make the main user, i.e. <code class="language-plaintext highlighter-rouge">pi</code>, the owner of the mount point: <code class="language-plaintext highlighter-rouge">sudo chown -R pi:pi /media/usb</code></li> <li>mount the drive: <code class="language-plaintext highlighter-rouge">sudo mount /dev/sda1 /media/usb -o uid=pi,gid=pi</code> (replace /dev/sda1 with your actual drive name if it is not the usual setup)</li> </ol> <h2 id="use-a-hdmi-to-vga-adapter">Use a HDMI to VGA adapter</h2> <p>If you are trying to use an HDMI to VGA adapter, the pi will not detect the HDMI screen and will default to using composite video only. You need to edit your <code class="language-plaintext highlighter-rouge">/boot/config.txt</code> file on the pi’s SD card to manually tell it to use HDMI. See eLinux RPiconfig for full info <a href="http://elinux.org/RPiconfig">about config.txt</a>.</p> <ol> <li>Put your pi’s SD card in a computer’s card reader.</li> <li>Find config.txt in the boot directory (which will likely be the only thing you can see from your computer).</li> <li>Open <code class="language-plaintext highlighter-rouge">/boot/config.txt</code> in an editor.</li> <li>Uncomment the line <code class="language-plaintext highlighter-rouge">hdmi_safe=1</code></li> <li>save</li> </ol> <h2 id="opengl">OpenGL</h2> <p>On rpi2 with the newest version of Raspbian Stretch, you can enable a new hardware OpenGL driver. Run <code class="language-plaintext highlighter-rouge">sudo raspi-config</code>, look in Advanced &gt; GL Driver. Select the new driver, then select finish and reboot the pi.</p> <p>Try it out with a few OpenGL games:</p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install neverball</code></p> <p><code class="language-plaintext highlighter-rouge">sudo apt-get install oolite</code></p> Tue, 05 Jan 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/handy-pi-commands.html https://evanwill.github.io/_drafts/notes/handy-pi-commands.html Template note <p>Basic template for _drafts notes.</p> <p>My standard demo list:</p> <ul> <li>dog</li> <li>cat</li> <li>muffins</li> </ul> Fri, 01 Jan 2016 00:00:00 +0000 https://evanwill.github.io/_drafts/notes/template.html https://evanwill.github.io/_drafts/notes/template.html