-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoffline-search-index.cc87445138f79fa504946b933e6174e6.json
1 lines (1 loc) · 105 KB
/
offline-search-index.cc87445138f79fa504946b933e6174e6.json
1
[{"body":"Here are a few common (and uncommon) tasks you can perform from the command-line.\nSet up new project $ git clone ... $ git submodule init $ git submodule update Start work $ git checkout main $ git pull $ git checkout branch-name $ git merge main // resolve merge conflicts, if any This helps keep things up-to-date when working with others.\nThere are considerations and alternatives.\nWork task $ git status $ git add //... $ git commit -m \"Relevant and descriptive commit message\" $ git push $ git checkout main $ git pull Clone repo wiki $ git clone \u003cproject-url\u003e.wiki.git Fix commit message typo $ git commit --amend -m \"Commit message without typos.\" Not guaranteed; best if run before making additional changes.\nList recently updated branches $ git branch --sort=-committerdate This displays results in descending order.\nTo display in ascending order, remove the hyphen (-) after --sort=.\nRevert file $ git checkout -- \u003cfilename\u003e Show branch remote origin $ git branch -vv Show unmerged commits $ git branch --no-merged main Unstage commit $ git restore --staged \u003cfile\u003e View config $ git config --list Vital statistics First post: 14 May 2024. ","categories":"","description":"A cheatsheet to common (and not-so-common) command-line tasks","excerpt":"A cheatsheet to common (and not-so-common) command-line tasks","ref":"/tips/git/console-commands/","tags":"","title":"Git console commands"},{"body":"Once established, git workflows go fairly smoothly.\nAt some point, you might realize that a branch pull request (PR) includes commits that it shouldn’t.\nAlternatively, your local default branch (main or master for older projects) has somehow managed to get ahead of the remote origin.\nTo fix things, you need to:\nReplace the broken branch Replace the broken pull request Replace broken branch For the most part, you can’t selectively remove commits from a pull request.\nInstead you need to replace the broken branch with a new one.\nTo do so:\nReview the commits in the broken PR Determine (and save) the commit IDs for the changes you want to keep Create a new branch and then add the selected commits in your new branch Discard the original branch Here’s how it works:\nDetermine and save the IDs for the commits you want to keep:\n$ git checkout broken-branch $ git log If you’re lucky, you just need the first commit ID displayed in the log.\nCreate and check out a new branch\n$ git checkout broken-branch-update $ git log Tip: Consider linking the branch names. Here, I’ve added update to the previous branch name so that a future reviewer might recognize the connection between the branches. Such consistency can help when looking back weeks or months later.\nReset the new branch to a known baseline, such as your remote default branch (origin/main).\n$ git fetch origin main $ git reset --hard origin/main If you receive an error saying Fatal: could not read from remote repository, it’s likely one of the following:\nYou’ve mistyped origin: verify the name of your upstream remote and try again. Your current working directory isn’t (yet) part of your remote branch. Change to a shared directory and try again. Your session credentials have expired; renew your session and try again. Add the desired commits from the original branch:\n$ git cherry-pick saved-commit-id Run this for each saved commit ID.\nReview your local files and commit your changes.\nWhen satisfied, push your new branch:\n$ git push origin broken-branch-upd:broken-branch-upd To finish: create a new pull request (which should be blissfully free from other commits), delete the original (broken) PR, and then clean up your local branches.\nBefore adding additional commits to your new PR, consider pushing a small edit within the scope of the PR. If this triggers an upstream warning that “changes aren’t tracked remotely,” use the text in the error to set up remote tracking.\n$ git push --set-upstream origin broken-branch-upd Consider doing this now to avoid future surprises.\nReset local default Once you’ve replaced broken branches and pull requests, you will likely need to reset your local default branch (main) to your remote default (origin/main).\nTo begin, check out main, investigate the differences between your local copy and your upstream remote, and then resolve any differences. (Most have likely been resolved while replacing broken ranches.)\nWhen things look good, reset your local default (main) to your remote default (origin/main):\n$ git checkout main $ git fetch origin main $ git reset --hard origin/main $ git status On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean Once the working tree is clean, you’re ready to resume your normal activities.\nVital statistics Update\n7 May 2024 - Rewritten to reflect current style and conventions Tested\n8 March 2017 using git 2.10.1, MacOS Sierra 10.12.3 Source material Based on Stack Overflow Question #25955822.\n(My mileage varied, so I wrote this and added my comments.) ","categories":"","description":"Shows how to clean up branches after mistakes happen.","excerpt":"Shows how to clean up branches after mistakes happen.","ref":"/tips/git/fix-default-branch-mistake/","tags":"","title":"Fix broken branches and main mistakes"},{"body":"When trying to push a commit using git from the command-line, you receive a GH007 remote error:\nremote: error: GH007: Your push would publish a private email address. Here, you’ve likely:\nConfigured your local copy of git to use the email address associated with your GitHub account Enabled the Keep my email addresses private option in your Github profile settings. The error is Github’s way of enforcing the privacy of your email address.\nTo fix things, you can:\nConfigure git to use your noreply email address (displayed in GitHub email settings) (Preferred) Deactivate email privacy (Not recommended) If you choose the former, you also need to reset the commit to use the noreply address.\nHere are the steps:\nUse Github email settings to determine your noreply address. (Consider coping it to the Clipboard.)\nUpdate email address in local config:\n$ git config --global user.email\nReset the commit\n$ git reset --soft HEAD ~1\nAdd, commit, and push your changes.\n$ git add . $ git commit -m \"My commit message\" $ git push The commit should now succeed.\nTo learn more:\nBlocking command line pushes (GitHub, reviewed 12 May 2024)\nSetting commit email address: (GitHub, reviewed 12 May 2024)\nVital statistics First post: 12 May 2024 Source: Based, in part, on Stack Overflow question #43378060 ","categories":"","description":"How to resolve GH007 remote errors related to private email addresses.","excerpt":"How to resolve GH007 remote errors related to private email addresses.","ref":"/tips/git/remote-privacy-errors/","tags":"","title":"Email privacy error"},{"body":"If you’re using Docsy as your Hugo theme, your code blocks might not render correctly in dark mode.\nTo fix this quickly, create a CSS rule that sets the background-color for \u003cpre\u003e elements that are children of the .highlight class.\nHere’s one way to do this:\nIn your assets/scss folder, create (or edit) _style_project.scss.\nDeclare the following rule:\n/* Fix dark mode code rendering */ .highlight pre { background-color: var(--td-pre-bg) !important; } Here, --td-pre-bg evaluates to the background color value defined by your theme.\nSave your changes and rebuild your project.\nYour code blocks should now be more readable in dark mode.\nTo learn more about _styles_project.scss, see Project style files (Docsy)\nVital statistics Last tested with:\nHugo v0.0125.5+extended Docsy v0.10.0 16 May 2024: First post\n","categories":"","description":"How to get code to render in dark mode using docsy theme.","excerpt":"How to get code to render in dark mode using docsy theme.","ref":"/tips/doc/hugo/dark-mode-code-docsy/","tags":"","title":"Fix dark mode code block"},{"body":"Here some practical tips for Microsoft Excel.\nStrikethrough text To draw a line (or strike through) text in a cell:\nEdit the cell Select the text Press Ctrl+5 (Windows) Here, 5 represents the key in the number row of your keyboard, not the center key in a number pad.\nFor best results, format the cell to wrap overflow text.\nString formula functions Here are a few macros to help manipulate text strings\nFind character in text Use SEARCH to find a character within a string.\nExample:\nGiven a cell (I2) containing F:\\Stuff\\accessibility\\a_element.htm:\n=SEARCH(\"\\\", I2) Returns 14\nTrim from string Use RIGHT to remove characters from the beginning of a string and LEFT to remove characters from the end.\nExample:\nGiven a cell (D2) containing F:\\Stuff\\accessibility\\a_element.htm:\n=RIGHT(D2,LEN(D2)-23) Returns a_element.htm\nReturn variable substring Combine these functions to return text based on the location of a character within a larger string.\nExample:\nGiven a cell (I2) containing accessibility\\accessibility\\a_element.htm:\n=LEFT( I2, SEARCH(\"\\\", I2 )-1) Returns the first folder name (accessibility).\nDate formula functions Here are a few ways to use date functions in formulas.\nYears from UTC dates When working with dates expressed as string values, such as UTC data values, use string functions to reduce the value to one that can be converted to a date.\nExample:\nGiven a cell (E2) containing Wed, 14 Jun 2017 07:00:00 GMT:\n=YEAR(DATEVALUE(LEFT(E2,10))) Returns 2017.\nQuarters from UTC dates Similar techniques can be used in more advanced cases.\nSuppose you have a UTC date value and you want to turn that into a value appropriate for planning (17Q2):\nDetermine the numeric month of the date:\n=YEAR(DATEVALUE(LEFT(E2,10))) // E2 contains UTC date string Calculate the quarter for the numeric month:\n=IF(H2\u003c4, 1, IF(H2\u003c7,2,IF(H2\u003c9,3,4))) // H2 contains numeric month Assemble YYQQ string result:\n=CONCATENATE(RIGHT(G2,2),\"Q\",I2) Here:\nCell G2 contains the two digit year. Cell I2 contains the quarter calculated earlier. ","categories":"","description":"Assorted tips and advice for Microsoft Excel.","excerpt":"Assorted tips and advice for Microsoft Excel.","ref":"/tips/apps/excel-tips/","tags":"","title":"Excel tips"},{"body":"Style guides define rules for using language in a given context.\nThese rules provide a “common voice” that customers recognize and expect when working with professional content.\nA good style guide improves your writing and overall effectiveness.\nRecommended guides For technical docs, consider adopting one of the following:\nGoogle developer doc style guide Microsoft Writing Style Guide Each guide was developed by the publisher using research and customer focus groups. Each is actively tested, reviewed, and maintained by their respective organizations.\nAdopting either guide helps you create better docs.\nFor best results, adopt one as your primary resource and use others as supplements. This leads to more informed editorial decisions, especially when trying to decide whether it’s time break the rules.\nOther style guides Other guides exist, including:\nApple Style Guide Red Hat Technical Writing Style Guide Salesforce Style Guide for Documentation and User Interface Text Ubuntu: Canonical Documentation Style Guide This discussion focuses mainly on editorial style guides.\nThe term style guide can also refer to:\nDesign style guides, also known as visual style guides, which describe interface design and the use of visual controls.\nExamples include:\nGoogle Material Design guidelines Apple Human Interface Guidelines\nBranding style guides, which companies use to present consistent messages to consumers and to protect their brand names, trade dress, and trademarks.\nProject style guides define “house rules” for projects and organizations.\nThese generally describe exceptions to other resources and generally reflect specific decisions made by the editorial team.\nIf you’re new to a team, consider asking whether there is a project style guide–even when familiar with the primary style guide.\nMore editorial resources When your style guide doesn’t answer a particular question, consider these resources:\nMerriam-Webster (modern spelling, usage, and thesaurus) Oxford English Dictionary (legacy language, archaic terms, and alternate uses) The Chicago Manual of Style (book or subscription) The Elements of Style, by William Strunk \u0026 E.B. White (Fourth edition available at Internet Archive) Purdue University Online Writing Lab (OWL) National Archives (NARA) Principles of Clear Writing Historical guidelines Modern technical writing style is based on plain language, a set of guidelines originally developed for the Plain Writing Act of 2010.\nThese guidelines emphasize brief, clear docs with direct language. See Voice \u0026 tone to learn more.\nEarlier approaches include:\nSimplified Technical English (STE), a set of standards originating in the aerospace industry during the 1980s.\nSTE was designed to reduce confusion, especially among readers who did not understand English as a native language.\nMany guidelines assumed that technology would never be able to accurately translate content in real time.\nSTE writing rules were designed to minimize confusion. Because many languages do not support contractions, for example, STE forbade their use.\nAs a result, content written to STE guidelines can seem formal, stiff, and stilted (especially to modern ears).\nMicrosoft Manual of Style (MMOS)\nBased in part on STE, the MMOS was considered a primary resource for technical publications at Microsoft for more than two decades.\nEarly versions were called the Microsoft Manual of Style for Technical Publications (MSTP).\nMicrosoft invested heavily in technical writing as a discipline, which helped MSTP become a standard resource for other technical writing teams.\nIn 2018, MMOS was superseded (replaced) by the Microsoft Writing Style Guide.\nVital statistics 12 May 2024: Updated and reworked for current standards 15 June 2017: Updated and expanded First post: 29 Jan 2017 ","categories":"","description":"Defines \"style guide\" as a term and offers recommendations.","excerpt":"Defines \"style guide\" as a term and offers recommendations.","ref":"/tips/doc/style-guides/","tags":"","title":"Style guides"},{"body":"If, for whatever reason, you’re using Microsoft Word 2011 for the Mac, the following tips may help:\nIf the tabs don’t respond to mouse clicks, try clicking the very top pixel of the tab (or as close to it as you can manage).\nFor some unknown reason, this seems to do the trick.\nThe A footer of section _x_ is set outside the printable area of this page error indicates that the footer (or header) is larger than the non-printable area of the page.\nTo fix this:\nSelect the Header and Footer tab.\nIn the Position section, set the Header from Top and Footer from Bottom fields to appropriate values.\nIf you’re unsure, try 0.5. (The actual minimum value varies according to the printer.)\nThis problem tends to appear in documents edited and saved on devices using different pages sizes.\nBecause paper sizes vary between countries and geographic regions, page size defaults change when you open a document.\nThis can push page margins, headers, and footers beyond expected ranges.\nWhen transferring files between different countries, regions, and languages, use care to verify the Page Setup and Default Language settings before printing or redistributing the document.\nTo update (regenerate) a table of contents (toc), move the cursor inside the toc and then press F9.\nRevision marks consume a lot of memory.\nIf the document requires several seconds to render or navigate, try clearing previous revision marks.\nThe following keyboard shortcuts help manage list and paragraph indents:\nPromote bullet one level (move right): [Shift] + [Control] + [Right arrow] Demote bullet one level (move left): [Shift] + [Control] + [Left arrow] Indent paragraph one tab stop (move right): [Control] + [Shift] + [M] Unindent paragraph one tab stop (move left): [Shift] + [Command] + [M] To convert legacy Word documents to other formats, take a look at pandoc\nBackground Prior to the release of Word 2016 for the Mac, Word 2011 was the latest version of the word processor available for Mac devices.\nGiven the longevity of older Mac devices, it’s entirely possible that someone somewhere is still struggling to get their copy working.\nVital statistics 15 February 2024: Article updated to current style. 31 January 2017: Adding additional tips and fixes. 28 January 2017: Original post ","categories":"","description":"Tips and advice for Word 2011 for the Mac.","excerpt":"Tips and advice for Word 2011 for the Mac.","ref":"/tips/apps/word-2011-tips/","tags":"","title":"Word 2011 tips and fixes"},{"body":"Git for Windows includes a tool called Git Bash, which gives you a bash shell you can use to run git via the command line.\nTo set the Git Bash default directory, change the Start in field on the Shortcut tab of the Git Bash properties.\nHere’s how:\nRight-click the Git Bash icon in the taskbar to display the taskbar shortcut menu.\nRight-click the Git Bash command in the taskbar shortcut menu and then select Properties.\nIf the Target field includes the -cd-to-home option, remove it.\nSet Start in to the directory you wish to use.\nUse the Windows cmd path naming convention, instead of Unix.\nFor example: c:\\mypath\\myrepos instead of /c/mypath/myrepos.\nWhen finished, select OK or press Enter.\nIf necessary, exit and restart Git Bash.\nVital statistics 7 May 2024: Rewritten and updated for site revamp 2 June 2018: First post ","categories":"","description":"How to change the default directory for Git Bash","excerpt":"How to change the default directory for Git Bash","ref":"/tips/git/git-bash-default-path/","tags":"","title":"Set Git Bash default path"},{"body":"By default, the JavaScript Array.sort() function sorts arrays according to character placement within a character set. For most web content, this is UTF-8.\nHowever, this may not always be an ideal result.\nHere, we show how to define a custom sort order in JavaScript.\nProcess array To illustrate, consider the following book titles, organized roughly by the year they were first published.\nA Study in Scarlet The Sign of Four The Adventures of Sherlock Holmes The Memoirs of Sherlock Holmes The Hound of the Baskervilles The Return of Sherlock Holmes His Last Bow The Valley of Fear The Case-Book of Sherlock Holmes To print an array containing these titles to a web page, you might use something like this:\nvar iTotal = astrTitles.length; if ( iTotal \u003e 0 ) { for ( var iTitles = 0; iTitles \u003c iTotal; iTitles++ ) { var str = astrTitles[ iTitles ]; writeTitle( str ); } } Here, the writeTitle() function represents the code needed to display the title on the target device.\nfunction writeTitle( strTitle ) { var obj = document.getElementById( \"pOutput\" ); obj.textContent += strTitle + \"\\n\"; } Example 1: A JavaScript function to write string values to a webpage. (Try it out)\nSort an array When asked to sort the array alphabetically, you might call the Array.sort() function:\nvar iTotal = astrTitles.length; if ( iTotal \u003e 0 ) { astrTitles.sort(); for ( var iTitles = 0, iTitles++, iTitles \u003c iTotal ) { writeTitle( astrTitles[ iTitles ] ); } } Example 2: JavaScript code to sort an array before process it. (Try it out)\nWhen run, this leads to the following:\nA Study in Scarlet His Last Bow The Adventures of Sherlock Holmes The Case-Book of Sherlock Holmes The Hound of the Baskervilles The Memoirs of Sherlock Holmes The Return of Sherlock Holmes The Sign of Four The Valley of Fear From a technical view, these might be the results you expect; however, your users might have different ideas.\nMove leading articles As an alternative, consider:\nAdventures of Sherlock Holmes, The Case-Book of Sherlock Holmes, The His Last Bow Hound of the Baskervilles, The Memoirs of Sherlock Holmes, The Return of Sherlock Holmes, The Sign of Four, The Study in Scarlet, A Valley of Fear, The Here, leading articles (a, an, and the) are moved to the end of the title. To some, these results are clearer and more logical.\nThis strategy is common to business filing systems and known by different names, including dictionary sorting and alphabetic collation.\nFor a detailed look, see Section 4.6 (PDF) of “Guidelines for Alphabetical Arrangement of Letters and Sorting of Numerals and Other Symbols”, by Hans H. Wellisch, 1999 National Information Standards Organization (NISO) Technical Report TR02-1999.\nTo create a custom function that does this in JavaScript, you might use something along these lines:\nfunction moveLeadingArticle( sInput ) { var sResult = sInput.toLocaleLowerCase(); var aArticles = [ 'a', 'an', 'the' ]; var aWords = sResult.split(/\\s/); if ( aArticles.indexOf( aWords[0] ) \u003e -1 ) { sResult = aWords.slice( 1 ).join( ' ' ); sResult += ', ' + aWords[0]; } return sResult; } Example 3: A custom function to move leading titles to the end of an input string. (Try it out)\nHere, the input parameter value is:\nConverted to lowercase. Split into individual words. The first word is compared to a list of known articles (a, an , the). When a title starts with an article, the article is moved to the end of the title. Here are a couple of examples:\nmoveLeadingArticle( \"His Last Bow\" ) returns his last bow\nmoveLeadingArticle( \"The Sign of Four\" ) returns sign of four, the\nCustom sort order You can create a custom sort order by passing an anonymous function to the Array.sort() function.\nvar iTotal = astrTitles.length; if ( iTotal \u003e 0 ) { if ( aResultsArray.length \u003e 1 ) { aResultsArray.sort( function( a, b ) { var SortTermA = moveLeadingArticle( a ); var SortTermB = moveLeadingArticle( b ); return SortTermA.localeCompare( SortTermB ); } ); } Example 4: Performing a custom sort using an anonymous function. (Try it out)\nHere, the anonymous function calls the custom function when comparing string values. When run, these titles are sorted in dictionary order (shown earlier).\nExample #3 shows this in action.\nInternational concerns This example essentially demonstrates how to perform a custom sort using JavaScript.\nUnfortunately, the actual algorithm relies on a specific behavior used to sort titles written in English using Latin characters. It might be useful for book lists, music collections, or even video games involving extensive player inventory systems.\nBeyond these cases, the example might have limited value. It doesn’t account for alternate alphabets, collation patterns, or even languages that do not support articles.\nFrom an Internationalization (I18N) perspective, this technique implements an edge-case scenario used for a single language. (I18N is the art of writing apps to support users and their native assumptions.)\nIf you’re designing a (potentially) global solution, it may be wise to take a few moments to consider:\nDictionary sorting has not been codified as a standards-based collation technique. As a result, it’s not supported by commonly-used libraries. Exceptions require custom code, which complicates maintenance and potentially hinders performance. There may be insufficient resources to support edge cases at a global scale. American sorting conventions may not scale effectively to other English speakers. The Intl.collator() object is typically suggested as a good resource for international concerns. (Unfortunately, few options seem to support this specific scenario for English.)\nAs with many such discussions, you’ll have to balance customer satisfaction against practical development resources.\nTo learn more about I18N, see:\nHandling character encodings in HTML and CSS (W3C) International Components for Unicode (ICU) The Unicode Common Local Data Repository (CLDR) Vital statistics Updated: 8 May 2024 - Rewritten to align to current style guidelines, support the site revamp, and discuss the I18N perspective. First post: 26 January 2017 ","categories":"","description":"Shows how create a custom sort order in JavaScript.","excerpt":"Shows how create a custom sort order in JavaScript.","ref":"/tips/javascript/dictionary-sorting/","tags":"","title":"Dictionary sorting in JavaScript"},{"body":"Windows uses privilege elevation prompts (also known as user account controls or UACs) to confirm administrative actions, such as installing new software, deleting files from sensitive locations, and so on.\nElevation prompt behavior has changed since the original Window Vista introduction, however, the experience can be jarring, especially if you routinely switch between devices running different versions of Windows.\nA few keyboard shortcuts have remained consistent through multiple versions of Windows, including:\nTo quickly accept an elevation prompt, press Left arrow and then press `Enter. To cancel a prompt, press Esc (the escape key). In many (though not all) versions of Windows, you can use Spacebar to select the default button in an elevation prompt. In my experience, the first shortcut is the most widely supported. There’s no guarantee that will continue in future Windows releases.\nHistorical perspective Many find elevation prompts to be annoying. Oddly, this was the original intention.\nWhile I personally appreciate the opportunity to avoid accidentally deleting an important file, I know this isn’t a universal view.\nMore info User account control: How it works (Microsoft Learn)\n“User Access Control in a nutshell”, by Roger Grimes, CSO Magazine, 1 Apr 2008.\n“Protect your Windows network from excessive administrator rights”, Susan Bradley, CSO Magazine, 15 Jul 2020.\nVital statistics Updated 06 May 2024: Rewrote to reflect current style and layout. 27 Jan 2017: Original post ","categories":"","description":"Describes how to use the keyboard to manage Windows elevation prompts.","excerpt":"Describes how to use the keyboard to manage Windows elevation prompts.","ref":"/tips/windows/elevation-prompt-shortcuts/","tags":"","title":"Keyboard shortcuts for elevation prompts"},{"body":"An uncommon bit of website maintenance involves reviewing or updating links on a webpage.\nTypically, you want a list of the URLs specified in anchor elements (\u003ca href=\"...\"\u003e\u003c/a\u003e).\nThis means you want a list of the URLs specified in the HREF attribute of anchors.\nLike many tasks, this can be more complicated than it first appears.\nList webpage links Use the Document.links property to get a list of the links on a webpage.\nDocument.links returns an HTMLCollection object, which is a list of Element objects.\nThis list include anchor elements, but it can also include other things, such as SVG images, MathML objects, and more.\nNot every element has an HREF attribute. For best results, make sure the attribute exists before trying to read its value.\nHere’s one way to do this:\nlet aryLinks = document.links; for (const key in aryLinks ) { let obj = aryLinks[key]; if (typeof obj === 'object' \u0026\u0026 obj != null \u0026\u0026 'getAttribute' in obj) { console.log(obj.getAttribute(\"href\")); } }; Example #1: JavaScript code to list a webpage’s links to the browser console.\nSort and remove duplicates To try this out, use the Copy to Clipboard button and then paste it into the Console tab of your browser developer tools.\nAs you review the results, you might notice a few things:\nThere are a lot of links\nThey’re ordered by appearance in the page structure\nThere are duplicates\nWhile there are good reasons behind these observations, you might want to sort the list and remove duplicates.\nHere’s one way to do this:\nlet aryLinks = document.links; let aryURLs = new Array(); for (const key in aryLinks ) { let obj = aryLinks[key]; if (typeof obj === 'object' \u0026\u0026 obj != null \u0026\u0026 'getAttribute' in obj) { const sURL = obj.getAttribute(\"href\"); if ( aryURLs.indexOf( sURL) == -1 ) { aryURLs.push( sURL ); } } }; for (const item in aryURLs.sort()) { console.log( aryURLs[ item ] ); } Example #2: Extracting links, and listing unique URLs as sorted results.\nInstead of directly logging the target URL, this version add a second step.\nIt uses a second array to collect unique ULRs and then sorts the results before printing them to the console.\nVital statistics 10 May 2024: First post, based on private notes. ","categories":"","description":"How to use JavaScript to list and sort links on a webpage.","excerpt":"How to use JavaScript to list and sort links on a webpage.","ref":"/tips/javascript/extract-webpage-links/","tags":"","title":"Extract links from a webpage"},{"body":"Tenets are guiding project principles; they outline and frame design thinking.\nHere are the ones I generally start with.\nDocs are features Many teams treat docs as afterthoughts. Like good software, good docs require design, forethought, and planning.\nEffective docs follow the product lifecycle: design, implementation, review, and maintenance.\nTreat doc reviews as seriously as code reviews. Reviewers need to be proactive and timely in their feedback.\nFeedback must be specific, clear, and actionable.\nDocs solve problems Good docs help people solve problems.\nBefore starting an article, identify the audience and the problem.\nThis defines the intent:\n“As a developer, I want to back up my database.”\n“As a new customer, I want to update my profile.”\n“As an admin, I need to limit access.”\nLike feedback, intent must be specific, clear, and actionable.\nThe article’s complete when it meets the intent. Everything else is extra (and probably goes elsewhere).\nWhen you review an article, test it against the intent.\nSolve first; explain later Most people are in a hurry; they’re trying to answer a specific question.\nGive them the answer. Let them decide what to do next.\nDetails, analysis, and architecture come later.\nWhen planning docs, remember “Breadth, then depth.”\nWork priorities in descending order. Finish what you can with what you have.\nCover basics first and then go deeper. Balance resources, priorities, and feedback.\nWhen you do focus on specifics, start with things relevant to many users, rather than a few.\nWrite for modern audience We have short attention spans and too many distractions. We tend to scan for relevance before diving deep. (Think tl;dr for, well, everything.)\nThis means:\nDesign for scanning. Use simple sentences, short paragraphs, and lots of whitespace.\nBe brief. Be clear. Save details for later.\nUse everyday language rather than industry jargon.\nIf you must use jargon, define it–especially TLAs (three-letter acronyms) and abbrs (abbreviations).\nUse informal language when it’s common.\nExample: app instead of application, info instead of information.\nWhen trying to decide between formal vs. casual language, choose business casual.\nDon’t assume readers have the same context or background knowledge.\nShow empathy: be direct when things are not ideal. At the very least, don’t be a jerk.\nDocs cannot teach everything Docs help people learn the basics and become self-sufficient.\nIt’s tempting to document every behavior and error condition. Yet, too much detail can overwhelm.\nConsider practical limits and diminishing returns.\nThe more you write, the more you have to maintain.\nStart with the 80/20 rule. Let feedback and metrics inform updates.\nPublish, then perfect Unpublished docs help no one.\nDocs don’t need to be perfect to publish. You can always push an update.\nFigure out what you can do with what you have. Do it and then iterate.\nMistakes are OK. Accept, learn, and move on.\nIt’s OK to focus You don’t have to accept (or use) every good idea.\nAccept feedback and contributions openly; use those that serve the intent.\nIf something doesn’t fit, throw it in the backlog and file a follow-up ticket.\nActively maintain, review, and triage your backlog. Make time for quality sprints.\nLog and prioritize all requests. Work date-sensitive items in descending priority order.\nMore about tenets Tenets are part of the Amazon design process. They answer questions that aren’t otherwise addressed by your project docs.\nAt Amazon, every project is expected to feature tenets prominently. (Some projects post tenets publically.)\nBy tradition, tenets are introduced the subtitle “Unless you can think of better ones.” This reminds people that tenets can, should, and do change as projects evolve.\nI use tenets to:\nSet expectations Outline direction Enable conversation These tenets are part of (nearly) every project I work on. (I don’t always tell people about them.)\nUnless you can think of better ones…\n","categories":"","description":"Guiding principles for doc projects...unless you can think of better ones.","excerpt":"Guiding principles for doc projects...unless you can think of better …","ref":"/tips/doc/tenets/","tags":"","title":"Doc project tenets"},{"body":"Docs, to some degree, represent the voice of your organization.\nPeople respond well to a friendly, helpful tone that is easy-to-read.\nThese principles help.\nUse one clear intent Good docs help users solve problems.\nBefore working on a doc, understand the audience you’re trying to reach and the problem being solved.\nThis is called the intent and is typically expressed as as follows:\n“As a \u003crole\u003e, I want to \u003csolve a problem\u003e.\nExamples:\n“As a developer, I want to back up my database.” “As a novice, I want to create a doc website.” “As a new writer, I want to check the readability of my content.” Good intents helps:\nWriters organize content and know when to stop. Reviewers know the limits and scope of the article. If you’re having trouble outlining an article, take time to consider the intent carefully.\nBe brief Modern readers are in a hurry.\nThey’re not reading your content for entertainment; they’re trying to solve problems.\nDesign accordingly:\nBe direct and concise.\nWrite simple sentences and minimize discussion.\nWrite the simple case first; discuss complications later.\nThe acronym tl;dr is a useful guidepost.\nBe scannable Few people read for depth initially.\nInstead, they scan webpages and try to pick out relevant details before diving deeper.\nStructure your docs accordingly:\nUse short sentences, small paragraphs, and lots of white space.\nMinimize distractions and limit decorations (rules, frames, and blocks of color).\nAvoid distractions, such as elements that move (animated images, autoplay videos, and so on.)\nMove complicated or detailed discussions below summarized answers.\nUse everyday language Many industries have terms and language specific to their domains.\nDon’t assume that your readers know these terms or search on them.\nAs an example, consider the following terms:\nfinetune headunit ingest inference upsert Can you define them clearly? Can your readers? How about people who aren’t already using your product or service?\nInstead, use plain language; define industry terms and jargon.\nShow empathy Some things are hard or complicated. Be up front about it.\nAt the very least, don’t be a jerk.\nDon’t describe something as quick or easy when it’s neither.\nRemove marketing hype and hyperbole.\nFocus on objective, reproducible facts.\nWe’re all learning. Be gentle.\nVital statistics 10 May 2024: First post for this website ","categories":"","description":"Principles for clear, readable docs.","excerpt":"Principles for clear, readable docs.","ref":"/tips/doc/voice-tone-principles/","tags":"","title":"Voice \u0026 tone principles"},{"body":"Here are some tips related to specific apps.\n","categories":"","description":"Tips for various apps","excerpt":"Tips for various apps","ref":"/tips/apps/","tags":"","title":"App tips and tricks"},{"body":"Node.js can help maintain doc experiences through automation. You can use it to:\nDetect file changes in source repositories.\nFix pathname issues in doc source files\nRepair broken (or incomplete) markup\nUpdate pipeline config files\nGenerate index pages, tag clouds, and other supporting content.\nTasks like these frequently require a list of files in a given directory, along with any child directories.\nHere’s one way to generate such a list:\n// rudimentary command line handling. var strFilePath = process.argv[ 2 ]; if ( ( strFilePath == null ) || ( strFilePath == \"\" ) || ( strFilePath == undefined ) ) { console.log( \"Declaration error: Target folder not specified.\" ); return; } // Normalize and verify the input parameter value var p = require( \"path\" ); var strFilePath = p.resolve( strFilePath ); var fs = require( \"fs\" ); var pathStat = fs.statSync( strFullFilename ); if ( pathStat.isDirectory() == false ) { console.log( \"Declaration error: '\" + strFullFilename + \"' is not a folder.\" ); return; } // Prepare the result object var oResults = new Object; oResults.paths = []; oResults.paths.push( strFilePath ); oResults.files = []; // Scan every folder found; make sure we can them all for ( var xDir = 0; xDir \u003c ( oResults.paths.length ); xDir++ ) { var sCurrDir = oResults.paths[ xDir ]; var aThisDir = fs.readdirSync( sCurrDir ); for ( var xThisFile = 0; xThisFile \u003c ( aThisDir.length ); xThisFile++ ) { var strFullFilename = sCurrDir + \"/\" + aThisDir[ xThisFile ]; var xTFStat = fs.statSync( strFullFilename ); if ( xTFStat.isFile() ) { oResults.files.push( strFullFilename ); } else { if ( xTFStat.isDirectory() ) { oResults.paths.push( strFullFilename ); } else { console.log( \"Skipping \", strFullFilename, \"; not a file or folder.\" ); } } } } console.log( JSON.stringify( oResults, undefined, 3 ) ); This example:\nVerifies the parameter value supplied by the caller. Unless a valid directory is provided, an error appears and the script ends.\nScans the target directory and tests each file tested.\nAdds filenames to the files property array and child directories to the paths property array.\nBecause the outer loop relies on paths, child directories are processed.\nYou’ll notice the file evaluation block includes an else for unexpected results.\nWhen the outer loop completes, the oResults object is ready for the next step. here, the results are logged to the console.\nAlternate approach Mind you, there are easier ways to generate a list of files, including a simple shell command:\n$ find ~/projects/mydocsite/_site -name \"*.html\" \u003e filelist.txt In many cases, this might be a preferred solution.\nIf you need additional processing, the earlier approach can help get you started.\nVital statistics 15 Feb 2024: Migrated to new site and style Lasted tested February 2017: Node: v7.4.0 4 Feb 2017: First post ","categories":"","description":"Recursively generate a list of files located in a directory.","excerpt":"Recursively generate a list of files located in a directory.","ref":"/tips/nodejs/collect-filenames/","tags":"","title":"Collect filenames with Node.js"},{"body":"This article shows how to create and use a custom Node module\nNode.js module design is based on CommonJS module specification, though sources vary on the intent and history. (Some sources vary when describing intent and history.)\nTo begin, move reusable functions into a separate JavaScript file (called mymodules.js in this example):\n// myModule.js module.exports.isBlank = function( inputValue ) { var blnResult = ( ( inputValue == undefined ) || ( inputValue == null ) || ( inputValue == \"\" ) ); return blnResult; } module.exports.collectFilenames = function( strTargetPath ) { var oResults = new Object; oResults.paths = []; oResults.paths.push( strTargetPath ); oResults.files = []; var fs = require( 'fs' ); for ( var xDir = 0; xDir \u003c ( oResults.paths.length ); xDir++ ) { var sCurrDir = oResults.paths[ xDir ]; var aThisDir = fs.readdirSync( sCurrDir ); for ( var xThisFile = 0; xThisFile \u003c ( aThisDir.length ); xThisFile++ ) { var strFullFilename = sCurrDir + \"/\" + aThisDir[ xThisFile ]; var xTFStat = fs.statSync( strFullFilename ); if ( xTFStat.isFile() ) { oResults.files.push( strFullFilename ); } else { if ( xTFStat.isDirectory() ) { oResults.paths.push( strFullFilename ); } else { console.log( \"Skipping \", strFullFilename, \"; not a file or directory.\" ); } } } } return oResults.files; } The collectFilenames function shown here is slightly different from the one introduced in Collect filenames. Here, it returns an array of strings an object.\nLimiting the return type to a simple data type gives the module more flexibility, especially with older clients. Subtle errors are easier and calling code tends to be more concise and clearer.\nFunction declaration changes Function declarations have changed as well because Node modules require you to assign functions to the modules.exports object. Thus, your calling code needs to change as well:\nmodule.exports.isBlank = function( inputValue ) { ... } module.exports.collectFilenames = function( strTargetPath ) { ... } As of Node v0.1.16, the module reference is optional for exports defined in the same file.\nCustom module use Once the module is created, you calling code looks something like this:\nvar nbt = require( \"./myModule\"); var fs = require( \"fs\" ); var strFilePath = process.argv[ 2 ]; if ( nbt.isBlank( strFilePath ) ) { console.log( \"Declaration error: Cleanup directory not specified.\" ); return; } var p = require( \"path\" ); var strFilePath = p.resolve( strFilePath ); var aFilenames = []; aFilenames = nbt.collectFilenames( strFilePath ); console.log( JSON.stringify( aFilenames, undefined, 3 ) ); What remains is generally focused on the specific task. Note: If you receive an \"Error: Cannot find module 'example' error when you require your module, try adding a directory reference:\nvar nbt = require( \"./myModule\"); Here, we assume that myModule is located in the same directory as the calling script.\nAdjust as needed to reflect your application structure.\nMore info Node’s full module documentation CommonJS module specification npm’s Creating Node.js Modules tutorial. Node.js, Require, and Exports, by Karl Seguin. How to Node: Creating Custom Modules, by Tim Craswell (archived). Vital statistics 15 Feb 2024: Migrated to new site and style Lasted tested February 2017: Node: v7.4.0 12 Feb 2017: First post ","categories":"","description":"Shows how to create and call a custom Node.js module.","excerpt":"Shows how to create and call a custom Node.js module.","ref":"/tips/nodejs/create-node-modules/","tags":"","title":"Create custom Node.js modules"},{"body":"","categories":"","description":"CSS examples, recipes, and related tidbits.","excerpt":"CSS examples, recipes, and related tidbits.","ref":"/tips/web/css/","tags":"","title":"Cascading style sheets (CSS)"},{"body":"Here are some tools, resources, and guidelines for creating docs.\nDiagrams Draw.io (also known as diagrams.net) can make visually pleasing diagrams with minimal effort.\nSome tips:\nIf your diagram contains an element with wrapped text, design that element first and then use it as the starting point for the rest of your elements.\nStrongly recommend using a mouse, trackball, or precision pointing device. Alignment is difficult when using gestures or other touch interface controls.\nSet a background color in document properties; otherwise, your final diagram might be transparent.\nIf saving is problematic, save to your local device and then move the file to your intended destination.\nasciiflow creates simple line drawing diagrams using ASCII line drawing characters. Helpful for text file illustrations.\nPencil project is a cross-platform Visio alternative.\nSee also Hugo Markdown MKDocs ","categories":"","description":"Practical guidelines for creating good docs and help with related tools.","excerpt":"Practical guidelines for creating good docs and help with related …","ref":"/tips/doc/","tags":"","title":"Doc guidelines, standards, and tools"},{"body":" “[M]any of the truths we cling to depend greatly on our own point of view.”\n– Obi-Wan Kenobi, “Star Wars Episode VI: Return of the Jedi” (1983)\nOccasionally, I’m asked I’m a particular Lance Leonard.\nI’ll admit to being a Lance Leonard, but perhaps not the Lance Leonard you’re looking for. (“Haven’t you heard? I come in six-packs.”)\nFor example, I am *not*:\nA conservative politician from New Jersey. (You’ve likely reversed the names, not to mention the, well, never mind. It’s not that sort of site.)\nFormerly of any confection or beverage companies; the email addresses are close, but different. Please look again.\nAnd, since the subject’s been broached… Dude. It’s embarrassing to receive someone else’s private correspondence—especially correspondence that really should remain, well, private.\nThe senior executives of my acquaintance usually know someone who can help them obtain unique digital identities. Has your mileage varied? ‘Nuff said?\nIn the insurance game. Nope; I’m a technical guy…a geek through and through. And I’ve got the funny-shaped dice to prove it.\nDead…at least not yet. That may change at some point and I cannot guarantee that I’ll be able to update the site accordingly.\nYou’ve been warned.\nI suppose I should admit that I’ve:\nBeen to New Jersey (Still miss footlongs on the waterfront) Lived in California (Santa Cruz, if you must know) Done project work for a notable beverage company Worked for a life insurance/investment company Played dead on stage But those are all meaningless coincidences typical in a life of adventure. None of them mean I’m the guy you’re looking for. Nope. Nuh-uh. I didn’t do it. No one saw me do it. Can’t prove a thing. Pay no attention to the geek behind the content. You can go about your business. Move along. Move along.\nOh, one last thing… Even if I might be the guy you think you’re looking for, I very probably can’t help you locate the person you lost track of way back when.\nLife is frequently weird. The once-possible sometimes becomes the opportunity-missed, the forever-broken, the legally-constrained, the ethically-restrained, and so on.\nAs certain a Formican once noted repetitiously, “Change happens.” Roll with it.\nMore plainly: If I say I cannot help you, I probably can’t…and I may not be in a position to explain why. Please respect that.\nAnd, yes, my sense of humor has been influenced by Douglas Adams, Charles Addams, Harlan Ellison, Monty Python, Leslie Charteris, Neil Gaiman, Terry Prachett, Piers Anthony, and more. Why do you ask?\n","categories":"","description":"Assorted things you should know about me and my sense of humor.","excerpt":"Assorted things you should know about me and my sense of humor.","ref":"/about/fair-warnings/","tags":"","title":"Fair warnings"},{"body":"","categories":"","description":"Covers git-based version control, including GitHub and related concepts.","excerpt":"Covers git-based version control, including GitHub and related …","ref":"/tips/git/","tags":"","title":"Git, GitHub, \u0026 related"},{"body":"The \u003cdetails\u003e element (also known as the disclosure element) hides content until a user chooses to view it. You can use this element to reduce the visual impact of large content blocks, such as extended source code, detailed configuration files, videos, and so on.\nBy default, \u003cdetails\u003e hides content until the user chooses to view it.\nThe \u003cdetails\u003e element is a core HTML element supported by many modern browsers.\nExample Here’s an example of the \u003cdetails\u003e element:\nExpand to view an image The Pale Blue Dot - Revisited (2020)\nThis is an updated version of the Pale Blue Dot, a photo taken by Voyager 1 near the planet Saturn on Valentine’s Day 1990.\nIn the words of astronomer Carl Sagan, this image shows our home. “That’s us… [T]he pale blue dot, the only home we’ve ever known.”\nPhoto credit: The Pale Blue Dot (2020 variant), copied from NASA’s Astronomy Picture of the Day (APOD), 14 Feb 2020 entry. Credits: Voyager Project, NASA, and JPL-Caltech.\nHere, the \u003cdetails\u003e element hides a large image. When you display the image, the rest of the content is pushed down the page.\nUsers unfamiliar with your site may not realize the additional content exists. By hiding content by default, you allow the user to choose when to view it.\nFor best results, design web experiences to support users who engage content in different ways.\nSource The code underlying the example is:\n\u003cdetails\u003e \u003csummary\u003eExpand to view an important image\u003c/summary\u003e \u003cp\u003e\u003cem\u003eThe Pale Blue Dot - Revisited (2020)\u003c/em\u003e\u003c/p\u003e \u003cimg src=\"/images/astro/pale-blue-dot-2020.jpeg\" alt=\"...\"\u003e \u003c!-- details removed for brevity --\u003e \u003c/details\u003e CSS improvements You can use traditional CSS techniques to improve the experience, as shown here:\ndetails { border:1px solid #fafafc; border-radius:4px; padding:.5em .5em 0 } summary { font-style:italic; background-color:#f5f5f5; margin:-.5em -.5em 0; padding:.5em } .details\u003esummary::before { font-style:normal; content:\"\\1F3A6 \" } details[open] { padding:.5em } details:hover { border:1px solid #ddd; box-shadow:#ccc 1px 1px 1px } An interactive demo shows these properties in action.\nVital statistics 4 Jun 2024: Minor edits to improve readability and article focus. 23 May 2024: First post ","categories":"","description":"Describes the \u0026lt;details\u0026gt; element, which lets you hide content until the user chooses to display it.","excerpt":"Describes the \u003cdetails\u003e element, which lets you hide content until the …","ref":"/tips/web/html/details-element/","tags":"","title":"Hide details until needed"},{"body":"Articles ","categories":"","description":"An assortment of idea related to HTML and webpage markup.","excerpt":"An assortment of idea related to HTML and webpage markup.","ref":"/tips/web/html/","tags":"","title":"HTML samples, ticks, and tidbits"},{"body":"","categories":"","description":"","excerpt":"","ref":"/scribbles/journal/","tags":"","title":"Journal"},{"body":"Many modern browsers indent list items 40 pixels by default.\nWhen a nested list contains more three or more levels, the default indent becomes more pronounced.\nYou can use padding-inline-start to control this, as shown in the following examples:\nBrowser default (40px) Custom indent (16px) Base item Shapes Circle Influence Fifths Social Square Town Meal Deal Triangle Acute Right Obtuse Colors Red Antares Betelgeuse VY Canis Majoris Blue Alpha Camelopardis Cygnus X-1 Mintaka Yellow Sol Chalawan Tau Ceti Kingdoms Animal Felis catus Chiroptera Corvus corax Vegetable Broccoli Cauliflower Kale Mineral Tungsten Cinnabar Corundum Base item Shapes Circle Influence Fifths Social Square Town Meal Deal Triangle Acute Right Obtuse Colors Red Antares Betelgeuse VY Canis Majoris Blue Alpha Camelopardis Cygnus X-1 Mintaka Yellow Sol Chalawan Tau Ceti Kingdoms Animal Felis catus Chiroptera Corvus corax Vegetable Broccoli Cauliflower Kale Mineral Tungsten Cinnabar Corundum Here, the first example shows the typical browser default (40px) and the second reduces this to 16px, as shown in this CSS rule:\n.example-list-indent-16 ul { padding-inline-start: 16px; } Framework impact Common web design design frameworks, such as Bootstrap, often reset (or reboot) browser style defaults to simplify cross-browser design.\nThese changes can affect the list indent. For example, this site defaults to a list indent of 32px because its theme incorporates Bootstrap.\nAs a result, you may need to experiment to achieve your desired results.\nVital statistics 4 Jun 2024: First post ","categories":"","description":"Shows one way to control the space used to indent nested list items.","excerpt":"Shows one way to control the space used to indent nested list items.","ref":"/tips/web/css/list-indents/","tags":"","title":"Nested list item indent"},{"body":"Use the column-width property to display lists in columns that flow like newspaper stories.\nHere’s an example:\nAbyssinian\nAmerican Shorthair\nArabian Mau\nBengal\nCalico\nChartreux\nHimalayan\nKorat\nMaine Coon\nManx\nMinuet\nNorwegian Forest Cat\nPersian\nRagdoll\nSiamese\nSnowshoe\nTortoiseshell\nYork Chocolate\nTo learn more, including how to style the columns, see Multiple-column layout (Mozilla developer).\nInline examples Here, the list is specified using an inline style parameter applied to an unordered list (\u003cul\u003e) element.\nHTML Markdown \u003cul style=\"column-width: 15em;\"\u003e \u003cli\u003eAbyssinian\u003c/li\u003e \u003cli\u003eAmerican Shorthair\u003c/li\u003e \u003cli\u003eArabian Mau\u003c/li\u003e \u003cli\u003eBengal\u003c/li\u003e \u003cli\u003eCalico\u003c/li\u003e \u003cli\u003eChartreux\u003c/li\u003e \u003cli\u003eHimalayan\u003c/li\u003e \u003cli\u003eKorat\u003c/li\u003e \u003cli\u003eMaine Coon\u003c/li\u003e \u003cli\u003eManx\u003c/li\u003e \u003cli\u003eMinuet\u003c/li\u003e \u003cli\u003eNorwegian Forest Cat\u003c/li\u003e \u003cli\u003ePersian\u003c/li\u003e \u003cli\u003eRagdoll\u003c/li\u003e \u003cli\u003eSiamese\u003c/li\u003e \u003cli\u003eSnowshoe\u003c/li\u003e \u003cli\u003eTortoiseshell\u003c/li\u003e \u003cli\u003eYork Chocolate\u003c/li\u003e - Abyssinian - American Shorthair - Arabian Mau - Bengal - Calico - Chartreux - Himalayan - Korat - Maine Coon - Manx - Minuet - Norwegian Forest Cat - Persian - Ragdoll - Siamese - Snowshoe - Tortoiseshell - York Chocolate { style:\"column-width: 15em;\"} If you’re using a static site generator that implements CommonMark or other Markdown extensions, you might be able to achieve the same result using Markdown.\nHugo support Sites based on Hugo need to activate block level support for the Markdown attributes extension.\nVital statistics 23 May 2024: First post ","categories":"","description":"Shows a simple way to create newspaper-style columns where list content flows vertically.","excerpt":"Shows a simple way to create newspaper-style columns where list …","ref":"/tips/web/css/newspapers-columns/","tags":"","title":"Simple newspaper columns"},{"body":"This section covers Node.js, npm, and more.\nNode.js lets you run JavaScript on a server or similar context, which in turn lets you use the language to perform administrative and operations tasks.\nThis section includes a few tips to help get you started.\nMore info ","categories":"","description":"Node.js tips, tricks, and one-liners.","excerpt":"Node.js tips, tricks, and one-liners.","ref":"/tips/nodejs/","tags":"","title":"Node.js, npm, and more"},{"body":" “Now that I do know it, I shall do my best to forget it.”\n– Sherlock Holmes, “A Study in Scarlet”, by Sir Arthur Conan Doyle (1887)\nI don’t track you or how you use the site.\nI don’t record any personally identifying information (PII).\nNo cookies are saved to your device, so there’s nothing to opt in to…or out of.\nAt some point, I may add analytics to help understand how people use the site in general.\nWhen I do that, I’ll update things as needed. The plan is to review data in aggregate in order to judge trends, interest, and so on.\nIf I learn you stopped by, I’ll keep that to myself.\nSince I’m not tracking anything, there’s nothing to share, sell, delete, or otherwise abuse.\nThat’s my policy and I’m sticking to it.\n","categories":"","description":"My privacy policy (such as it is).","excerpt":"My privacy policy (such as it is).","ref":"/about/privacy-policy/","tags":"","title":"Privacy policy"},{"body":" A paradox?\nA paradox, A most ingenious paradox!\nWe’ve quips and quibbles heard in flocks!\nBut none to beat this paradox!\n– Ruth \u0026 Frederic, “The Pirates of Penzance”,\nAct II (Scene 19), by W.S. Gilbert \u0026 Arthur Sullivan, 1879\nThe site’s name is based, in part, on lyrics from The Pirates of Penzance. (It’s also a subtle nod to one of my earliest doc roles and, yes, there’s a small story or few.)\nOne can also argue that it’s a malapropism because quips are meant to humorously infer tips and quibbles lead to scribbles. (Or did I mean kits and kibbles?)\nYou can argue whatever you like, but I should probably point out that wordplay is an essential part of my sense of identity and my sense of humor. (I’ve been told I play with words the way my cats play with strings.)\n","categories":"","description":"A bit about the name of the site.","excerpt":"A bit about the name of the site.","ref":"/about/site-name/","tags":"","title":"The site name"},{"body":"","categories":"","description":"","excerpt":"","ref":"/scribbles/thoughts/","tags":"","title":"Random thoughts"},{"body":"Tips answer questions I’ve had while learning or using various bits of technology.\nThey’re organized into categories that make sense to me.\n","categories":"","description":"","excerpt":"Tips answer questions I’ve had while learning or using various bits of …","ref":"/tips/","tags":"","title":"Tips"},{"body":"The xml2js module provides a convenient way to convert XML to JSON using Node.js:\nvar fs = require( 'fs' ), x2j = require( 'xml2js' ); var sInputFile = \"books.xml;\" var p = new x2j.Parser(); var sXMLData = fs.readFileSync( sInputFile, 'utf8' ); p.parseString( sXMLData, function( err, result ) { var s = JSON.stringify( result, undefined, 3 ); console.log( \"Result\" + \"\\n\", s, \"\\n\" ); }); Here, the input file (books.xml) is read into a string variable and then parsed.\nThe result is passed to an anonymous function that formats it before printing it to the console.\nWhen XML elements contain attributes, this version creates an attribute object named $ on the parent and then assigns the values as children of the attribute object.\nTo place attributes as direct children of the parent object (without the intervening $ object), set the mergeAttrs option to true when declaring the parser:\nvar p = new x2j.Parser( { mergeAttrs: true } ); To learn more, see the xml2js docs.\nVital statistics 15 Feb 2024: Migrated to new site and style Lasted tested January 2017: Node: v7.4.0 npm v4.05 xml2js v0.4.17 MacOS 10.12.3 29 Jan 2017: First post ","categories":"","description":"Shows one way to use Node.js to convert XML to JSON","excerpt":"Shows one way to use Node.js to convert XML to JSON","ref":"/tips/nodejs/xml-to-json/","tags":"","title":"Convert XML to JSON"},{"body":"When working with multiple monitors, it’s possible for open windows to be left offscreen.\nI’ve see this happen when:\nTraveling with a laptop normally hooked up to external monitors when docked at home.\nUsing a KVM switch to share a monitor between different machines.\nMost of the time, windows adjust to the new display area. Every so often, however, one remains in its original position. It’s open and responds to input. Because it’s offscreen, you can’t see what’s going on.\nTo bring the window into view, select Move from the window’s system menu and then use the keyboard arrow keys.\nKeyboard shortcuts To open the system menu using the keyboard:\nActivate the window using Alt+Tab or by selecting it through the Taskbar.\nPress Alt+Spacebar (to open the system menu), press M (to select the Move command), and then use the arrow keys to move the window into the display area.\nIt’s a bit clumsy, but it does work.\nWindows taskbar If you’re using Windows 10 (or later), you can use the taskbar to open a window’s system menu:\nPress and hold the Shift key Right-click the taskbar icon for the window you want to move. Select Move from the menu and then use the arrow keys. Vital statistics Updated: 7 May 2024 - Reworked and refactored for website revamp. Last tested: September 2018 - Windows 10 Enterprise, version 1809. ","categories":"","description":"Describes how to bring an offscreen window into view.","excerpt":"Describes how to bring an offscreen window into view.","ref":"/tips/windows/recover-offscreen-window/","tags":"","title":"Recover offscreen window"},{"body":"This section collects tidbits related to JavaScript, Node.js, and related topics\n","categories":"","description":"Tips for JavaScript, Node.js, and related.","excerpt":"Tips for JavaScript, Node.js, and related.","ref":"/tips/javascript/","tags":"","title":"JavaScript, Node.js, and related"},{"body":"Here’s what I have for Apple Macintosh operating systems, aka Mac, MacOS, OS/X, and so on.\nIt’s a bit of a grab bag at the moment. I’ll add additional material over time.\nFinder Hidden files Finder hides system files (and folders) by default.\nTo view hidden files for the current Finder session, press Shift + Command + . (period).\nThis is a toggle setting. Press the key to hide the files.\nTo always display hidden files, start terminal and then run:\n$ defaults write com.apple.Finder AppleShowAllFiles true` To hide system files by default, run the this command with false as the final parameter.\nYou need to restart all Finder instances to pick up changes. To do so quickly, run:\n$ killall Finder Homebrew Homebrew is a popular package manager for macOS, generally run from the command line (Terminal).\nSet up instructions are on the Homebrew site (brew.sh).\nTo keep everything up-to-date:\nbrew update brew outdated brew upgrade For best results, consider running brew doctor twice before starting this process. (There are times when it seems to help.)\nTo learn more, see the brew FAQs (brew.sh).\nSafari Enable developer tools Safari hides View Source and Developer tools by default.\nTo show them:\nStart Safari and then use the menu to select Safari \u003e Settings.\nFrom the Advanced tab of the Settings dialog, place a checkmark next to Show features for web developers\nWhen you do this:\na Develop tab appears in the Settings dialog a Develop menu appears in the app menu The Developer tools can help troubleshoot website issues.\nTo open the Console, for example, use the Safari menu to select Develop \u003e Show JavaScript Console.\nVital statistics 20 Jun 2024: Minor edits 9 May 2024: First post ","categories":"","description":"Apple Macintosh operating systems are covered here.","excerpt":"Apple Macintosh operating systems are covered here.","ref":"/tips/mac/","tags":"","title":"Mac, MacOS, and OS/X"},{"body":"This page is a preview of things to come.\nIf you’re seeing it, well, welcome…I guess.\n(It’s supposed to be private. So, shhhhh. )\nInvestigate Need Review request Identify source material Outline initial requirements Design solution Determine scope \u0026 effort Identify \u0026 prioritize tasks Confirm assumptions Fill knowledge gaps Plan the work Identify \u0026 prioritize tasks Identify epics \u0026 phases Initial content outlines Work the plan Rough draft based on outline Verify steps \u0026 procedures Initial screenshots/examples Evaluate readability \u0026 style Review Item 1 Item 2 item 3 Iterate Evaluate results Adjust plans \u0026 phases Schedule next steps ","categories":"","description":"","excerpt":"This page is a preview of things to come.\nIf you’re seeing it, well, …","ref":"/preview/","tags":"","title":"Preview page"},{"body":"Scribbles (or quibbles, if you prefer) are generally random write-ups and opinions, much like any average blog post.\nMajor categories include:\nJournal - Discusses the site and my experiences building/maintaining it.\nThoughts - Observations and essays on a variety of subjects, generally tech related.\nTrifles - Random bits and bobs, generally meant to be thought provoking or (potentially) amusing.\n","categories":"","description":"Assorted write-ups, generally presented as blog posts.","excerpt":"Assorted write-ups, generally presented as blog posts.","ref":"/scribbles/","tags":"","title":"Scribbles"},{"body":"Hugo is a static site generator that creates websites from Markdown. It’s typically used to create documentation sites (like this one).\nHere, I collect relevant links, tips, and tricks.\nServe local site To preview local changes:\n$ hugo serve By default, Hugo publishes your preview to https://lanceleonard.com.\nYou can also use command-line options to customize Hugo’s behavior.\nFor example:\n$ hugo serve --disableFastRender --ignoreCache --logLevel warn These options tell Hugo to fully rebuild the entire site when updating the local preview and to display more error messages.\nTo learn more, use Hugo’s built-in help:\n$ hugo -help Show version To display the Hugo version number (or to see if it’s installed):\n$ hugo version hugo v0.125.5+extended darwin/amd64 BuildDate=2024-05-01T15:22:11Z VendorInfo=brew This example shows that the extended version of Hugo v0.125.5 is installed.\nHide content There are times when you’ll want to hide content from from different views.\nFor example, an article might:\nBe in progress and not quite ready for public consumption Have to wait for another article Serve as a bridging element without having public content Here are different ways to hide content.\nHide article content Use HTML comments to hide content within an article.\n## Section 1 \u003c!-- ## Section 2 in progress --\u003e ## Section 3 This keeps the content from rendering on the published webpage; however, it’s still published in the source.\nUse care when working with sensitive content.\nSet draft mode Use draft mode to keep articles private.\nDo this in the article’s front matter:\n--- title: \"My article title\" description: \"My article description\" draft: true --- If a doc appears in the table of contents (TOC) after setting this option, verify that you’ve set the value as shown.\nTo illustrate, you might accidentally add a semicolon to the end of the line (a common mistake). While this is a syntax error, Hugo doesn’t generate a warning. Instead, it simply ignores the directive.\nTo list articles currently in draft mode:\n$ hugo list drafts For details, see the Hugo reference page.\nExclude from contents To exclude an article from the navigation menu displayed along the left side of the page, hide it from the table of contents (toc):\n--- title: \"My article title\" description: \"My article description\" toc_hide: true --- Hide summary By default, article descriptions appear in index pages as article summaries.\nYou can hide descriptions from the index page by updating the article’s front matter:\n--- title: \"My article title\" description: \"My article description\" hide_summary: true --- Vital statistics 16 May 2024: Added version section 8 May 2024: First post: ","categories":"","description":"Tips and tricks for Hugo, a static site generator.","excerpt":"Tips and tricks for Hugo, a static site generator.","ref":"/tips/doc/hugo/","tags":"","title":"Hugo"},{"body":"Markdown is a lightweight markup language used to create websites and other publications. Based on text, it’s an easy way to format content.\nThere are multiple “flavors” of Markdown, including:\nCommonMark Github-Flavored Markdow (GFM) kramdown Markown Extra MultiMarkdown R Markdown and more…. Each flavor adds to the basic Markdown capabilities. [MarkdownGuide] provides a reference to the most common Markdown extensions.\nIn addition, there are multiple Markdown parsers, also called processors, that each vary slightly in the features they support and how they suppot them.\nWhen working with Markdown, take time to learn the flavor and parser that you’re using. Doing so can only help you in the long run.\nHere are some useful tools and resources.\nAmpersand in headings Use the HTML entity to specify an ampersand (\u0026) in a heading:\n### C\u0026#35; Sample Backticks inline To place a backtick in inline code (`), start and close your inline code block with two backticks:\n`` ` `` Comments Markdown comments:\n[//]:# (Comment text) You can also use HTML comments (\u003c!-- (stuff) --\u003e).\nLine breaks To force (hard code) a line break:\nLeave two spaces at the end of a line\nUse \u003cbr\u003e elements.\nList indents Markdown supports multi-paragraph lists; however, they can be tricky to pull off.\nIf you’re having problems keeping the indents straight (especially when using bulleted lists), check that:\nYou’re indenting consistently; that is, all bullets in the list have the same number of spaces in front of each bullet and each level is likewise consistent.\nBlank lines between bullet paragraphs are indented to match the level of the following paragraph.\nThat each bullet is followed by just one space (that is, that some bullets don’t add additional spaces before the content)\nYou’re consistently using four spaces to indent child items; a single character slip can throw off the entire list.\nYou indent the starting and closing backticks of code blocks: \"\\n ```\".\nTables Basics Tables require at least three lines:\n| Name | Description | |-------|---------------| | Row 1 | Explanation 1 | | Row 2 | Explanation 2 | | Row 3 | Explanation 3 | Which leads to:\nName Description Row 1 Explanation 1 Row 2 Explanation 2 Row 3 Explanation 3 Notes:\nIt’s not strictly necessary (or always practical) to align each column in the source. It’s easier to read (and therefore to maintain), but it’s not necessary.\nIn the separator line, columns must be define using at least three hyphens (---).\nColumn alignment | Left | Center | Right | |---------|:-------:|--------:| | `:---` | `:---:` | `---:` | | Alpha | Apple | Alpha | | Beta | Banana | Bravo | | Gamma | Cherry | Charlie | Leads to:\nLeft Center Right :--- :---: ---: Alpha Apple Alpha Beta Banana Bravo Gamma Cherry Charlie Syntax reference Markdown basic syntax reference (Markdown Guide) Github Markdown reference: A more complete reference focused on CommonMark/GFM Converting Markdown GD2md-html is a Chrome extension that converts Google docs to Markdown.\nPandoc bills itself as your Swiss Army for converting docs from one format to another.\nWritage is a Microsoft Word addon that converts DOC files to Markdown. Available for Mac and Windows.\n","categories":"","description":"Markdown is a text-based markup language used for docs and other publications.","excerpt":"Markdown is a text-based markup language used for docs and other …","ref":"/tips/doc/markdown/","tags":"","title":"Markdown"},{"body":"MKDocs is a static-site generator that converts Markdown source files into fully formed websites.\nCheck version Use --version to display the current MkDocs version:\n$ mkdocs --version Hide footer ad Early versions of MkDocs include a small “ad” in the footer of your webpages (“Documentation built wwith MKDocs”).\nYou can hide this by adding a CSS rule to hide the message or by removing it from your site’s template.\nHide with CSS To hide the ad using CSS:\nIn your project’s /docs/ folder, add the following rule to a custom style sheet:\nfooter :last-child { display: none; } Verify that your custom style sheet is declared in your site’s project configuration (mydocs.yml)\nsite_name: My example site exta_css: - hidefooter.css Here, we assume your custom CSS file is named hidefooter.css.\nIf you’re working with an earlier version of MKDocs, you may need to tweak the CSS rule. In version v0.15.x, for example, MKDocs placed its ad in a \u003ccenter\u003e element (now deprecated).\nTo hide the footer in this version:\ncenter { display: none; } Update template You can also update the template to remove the ad entirely:\nInstall a copy of the basic theme into a your project.\nUpdate mkdocs.yml to refer to your new theme:\ntheme_dir: \u003ccustom-template\u003e Update base.html to remove the “Built with” line (line 189 as of this writing).\nSave, build, and deploy as usual.\nCustomize templates MKDocs uses Jinja2 as its templating engine. To learn more, see:\nMkDocs: “Developing themes Jinja2 docs Vital statistics 8 May 2024: Rewritten and updated for site revamp 15 March 2017: First post ","categories":"","description":"Tips and tricks for MKDocs, a static site generator.","excerpt":"Tips and tricks for MKDocs, a static site generator.","ref":"/tips/doc/mkdocs/","tags":"","title":"MKDocs"},{"body":"Package managers vary between distributions (distros).\nHere’s a starting list:\nOperating system (distro) Package manager MacOS (OS/X) brew Alpine Linux apk Amazon Linux dnf (AL2023)\nyum (AL2 and earlier) archlinux pacman Debian (v8+)\nUbuntu (v13.10+) apt-get Fedora Linux dnf (v22+)\nyum (v21 and earlier) FreeBSD pkg gentoo linux emerge OpenBSD/NetBSD pkg_add openSUSE zypper Raspberry Pi (Raspbian) Varies, typically apt or pip Red Hat Enterprise (RHEL) (v7+) yum Slackware sbopkg ","categories":"","description":"Common distributions and their package managers.","excerpt":"Common distributions and their package managers.","ref":"/tips/unix/package-managers/","tags":"","title":"Package managers"},{"body":"Pandoc helps convert documents, such as Word .DOCX files or PDF documents, to alternate formats, like Markdown and others.\nConversion can require a bit of tinkering. The following tips can help.\nSimple conversion To use Pandoc to convert a document to a new format:\n$ pandoc source.docx -o target.md By default, many details are inferred from the input parameters. In this example:\nThe input file (source) is assumed to be a Microsoft Word .DOCX file The output file (target) is assumed to be a Markdown .MD file. Use parameters to control these decisions.\nFor example, --to (-t) controls the variation (or flavor) of Markdown used to format the output file. Valid options vary and include values such as markdown, markdown_strict, gfm, and more.\nOther supported options include:\n--from (-f) \u003cinput_format\u003e --read (-r) is an alias for --from --write (-w) is an alias for --to HTML and Markdown When converting Markdown mixed with HTML, use --from to improve conversion results:\n$ pandoc markdown.md -f markdown+raw_html To learn more, see the Markdown section of the pandoc manual.\nExtract images To extract images from your source doc, add the --extract-media parameter.\nThis requires a value specifying the directory where extracted images should be saved. (The directory must exist before the conversion.)\nExamples:\n$ pandoc spec.docx -o output.md -t commonmark --extract-media=img/ $ pandoc api.docx -o api/_index.md.md -t gfm --extract-media=./img Be sure to validate your input files before converting them. Images cannot be extracted from files that don’t include them.\nThis may seem obvious, but some export results vary according to the format. In 2020, for example, Jira’s “Export to Word” feature excluded images but included them when exporting to PDFs.\nIn contrast, PDFs created by Acrobat Pro DC (v2020.013.20074) required specific settings to include images when exporting .DOCX files. (From View Results, select the Settings icon and then locate Layout Settings. Here, activate Retain Flowing Text and deactivate Include Comments.)\nTable conversion By default, Pandoc converts tables to HTML tables, especially when the source tables include lines breaks or multiple paragraphs.\nIn such cases, you can:\nTry using --to gfm (or an alternate Markdown syntax)\nTry alternate conversion tools, such as h2m.\nModify the source doc for conversion and then later revert the problematic content.\nThe latter option is a multi-step process:\nUse Word’s search and replace feature to replace paragraph marks (^P) with text symbols that don’t otherwise appear in the content (example: \u003c*\u003e).\nConvert the modified document.\nUpdate the converted results to replace your text symbols with \u003cbr\u003e tags or other choices.\nVital statistics 23 May 2024: First post ","categories":"","description":"Helpful tips for using pandoc to convert documents to Markdown","excerpt":"Helpful tips for using pandoc to convert documents to Markdown","ref":"/tips/doc/pandoc/","tags":"","title":"Pandoc conversion tips"},{"body":"This section provides help that applies to multiple operating systems and contexts, including:\nServer-based versions of Unix, such as FreeBSD Linux distributions, like Debian, RedHat, and Raspberry Pi OS Various command-line consoles, including Mac Terminal, Git Bash, and Windows Subsystem for Linux (WSL). Resources \u0026 links Certificates\nPublic key certificates (explains chain of trust and includes an interesting graphic) (Wikipedia) IETF RFS 5280: X.509 public key certificates (IETF) How to decode an SSL certificate (ShellHacks) Generate certificates for localhost (Let’s Encrypt) ag: The Silver Searcher: Fast alternative to grep \u0026 ack; ignores dot files, which means it’s useful for maintenance scripts and cleanup.\nMore info ","categories":"","description":"Tips and reminders that apply to Unix and similar operating systems.","excerpt":"Tips and reminders that apply to Unix and similar operating systems.","ref":"/tips/unix/","tags":"","title":"Unix general tips"},{"body":"Here is a quick cheat sheet for the vi text editor:\nThere are two modes: Command and Insert.\nThe word INSERT appears in the bottom left corner of the screen when that mode is active.\nIf you’re not sure what mode you’re in, press Esc to go into Command mode.\nTo move the cursor in command mode:\nH (left) J (right) K (up) L (right) Press I to activate Insert mode.\nWhen finished, go to Command mode and then type:\n:wd to save :q! to discard changes Background Like the Spanish Inquisition, the vi editor shows up unexpectedly. I’ve seen it appear when:\nHaving to resolve merge conflicts in git Working with console windows in cloud environments Because I don’t normally use the editor, I tend to forget how to save changes and close it.\nVital statistics Last update: 12 May 20224: Refactored for the new site. First post: 21 September 2017 ","categories":"","description":"A quick cheat sheet for the vi editor","excerpt":"A quick cheat sheet for the vi editor","ref":"/tips/unix/vi-cheat-sheet/","tags":"","title":"Vi editor cheat sheet"},{"body":"Web browsers Helpful tools Resources and references for HTML and CSS:\nWorld Wide Web Consortium (W3C, also W3): Home of the standards that describe how things are supposed to work, including: HTML, CSS, Web accessibility, and more.\nMozilla developer docs: Practical (and ad-free) references to HTML, CSS, and related topics, including useful details such as browser compatibility charts, links to defining specifications, and more.\nCan I Use…?: Extensive and detailed reference to feature availability across various browsers. Describes issues and frequently includes workarounds.\nCompart Unicode character reference: Surprisingly useful (and currently ad-free.)\nDeveloper tools Many web browsers provide developer tools to help investigate and troubleshoot websites.\nHere’s how to activate and open them in major browsers.\nApple Safari (included with MacOS) Hidden by default; Use Settings to change Use Safari Develop menu to open desired tool Brave Browser Menu \u003e More Tools \u003e Web Developer Tools Keyboard: Mac: Opt + Cmd + I, Windows: Ctrl+Shift+I Google Chrome Menu \u003e More Tools \u003e Developer Tools Keyboard: Mac: Opt + Cmd + I, Windows: Ctrl+Shift+I Microsoft Edge| Menu \u003e More Tools \u003e Developer Tools Keyboard: Mac: Opt + Cmd + I, Windows: Ctrl+Shift+I Mozilla Firefox Menu () \u003e More Tools \u003e Developer Tools Keyboard: Mac: Opt + Cmd + I, Windows: Ctrl+Shift+I Web servers DNS alias IP address When setting up a DNS record alias (ANAME or CNAME), you often need to know the IP address to assign to the alias.\nIf, for whatever reason, you don’t know the IP address, use the dig command to discover it:\n$ dig example.github.io +nostats +nocomments +nocmd ","categories":"","description":"Content related to websites, including HTML, CSS, design, troubleshooting, and more","excerpt":"Content related to websites, including HTML, CSS, design, …","ref":"/tips/web/","tags":"","title":"Web: browsers, design, markup, and more"},{"body":"This section collects tidbits related to Microsoft Windows.\nAssorted links and utilities These links are things I need from time to time. Your interests may vary:\nChocolately: Package manager for Windows\nCreate directory tree on Windows (SuperUser)\nSychronize files between directories (FreeFileSync)\nWindows 8.x: Make a bootable flash drive\nReset Windows XP admin password (I have more than a few older PCs.)\nScreensaver source code, for those times when you feel like recreating older OS experiences.\nWindows keyboard shortcuts as supported by the Slim X1 bluetooth keyboard\n(Links do not imply endorsement or encouragement.)\nArticles ","categories":"","description":"Microsoft Windows tips and administration help.","excerpt":"Microsoft Windows tips and administration help.","ref":"/tips/windows/","tags":"","title":"Windows and related topics"},{"body":" This is the personal site for Lance Leonard, a technical writer, programmer, creative problem solver, and cat herder currently operating somewhere in the vicinity of Seattle, WA USA. The site is part portfolio, part personal knowledgebase, and part…well, whatever you can get out of it.\nContact info: LinkedIn | Mastodon\nDisclaimer Opinions and ideas expressed on this site are my own and do not necessarily reflect the views of my employer, family, friends, or anyone able to rub two synapses together.\nInformation is provided as-is with no guarantee as to accuracy, completeness, fitness of purpose, etc, and so on.\nI warrant only that things worked on my devices well enough to write up. I’ve tried to draw conclusions based on reproducible results and verifiable sources. I do make mistakes and I’ve been known to be wrong.\nRemember, though: information on the Internet grows stale over time. Your mileage may, and perhaps should, vary. If it does, that’s your own lookout. Burn after reading; the Secretary disavows all knowledge.\nErrors and feedback If you find a typo or technical error, please let me know.\nMy response will likely depend on:\nMy ability to replicate your findings Your level of professionalism/courtesy The phase of the moon Other secret ingredients unlikely to be revealed at the moment Please understand.\nGenerative AI use The site’s content is researched, written, and edited by hand (as you can probably tell by the everpresent “tpyos”).\nI do not use generative AI models to generate code or to create content. All errors and mistakes are human-generated.\nIf, at any point, I incorporate AI-generated content into the site, I will label it accordingly.\n(Honestly, I’m surprised I feel it necessary to include this statement. But here we are.)\nVital statistics Updates 17 July 2024: Minor updates \u0026 edits. 6 May 2024: Reviewed \u0026 updated for site revamp 1 June 2018: Minor edits 26 January 2017: original post See also ","categories":"","description":"","excerpt":" This is the personal site for Lance Leonard, a technical writer, …","ref":"/about/","tags":"","title":"About the Site"},{"body":" “In this world, there are only two tragedies.\nOne is not getting what one wants, and the other is getting it.\nThe last is much the worst, the last is the real tragedy!”\n– Mr. Dumby, “Lady Windermere’s Fan: A Play About a Good Woman”, by Oscar Wilde (1892)\nJuly 2024 29 July 2024: Minor changes \u0026 edits.\n15 July 2024:\nNew thought: Bingo card redux Minor updates to the Mac tips. New thought: Six week progress report. Moved [Node.js] and the doc tools content to new locations to simplify navigation. Internal: new article research and prep. Minor edits \u0026 updates (RL has been a bit chaotic.) June 2024 12 June 2024: Assorted odds and ends\nNew thought: Is Phoenix on your bingo card? New thought: Success qualities for tech writers Added two new sections to Scribbles: Thoughts, an infrequently-updated collection of musings, opinions, and other blog posts. Trifles, a collection of amusements, ephemera, and assorted curiosities. Added new tips to the Markdown section. Continued working to automate and improve the publishing pipeline. Other minor updates, fixes, and tweaks. 8 Jun 2024: More quality improvements\nAdded new CSS article: List item indents. Internal: Updated breadcrumb partial to hide breadcrumbs on individual pages. (Note to self: see content/_index.md for sample use.) Internal: Updated breadcrumb separators Fixed a problem with redirects leading to 404 errors, along with a few outdated links. The 404 handler has been customized. Resolved issues with external search (🤞). Additional tweaks and fixes. 3 Jun 2024: Quality updates\nThe sidebar now shows expand and collapse markers. A broken link on the home page has been fixed. (Sorry.) Minor functionality improvements to the home page. Fixed spacing issues for lists with nested paragraphs. Minor formatting changes/fixes throughout the site. May 2024 23 May 2024: New articles and other improvements\nThe landing page has been tweaked to help discoverability. Initial articles have been added to the HTML and CSS sections (more soon). An article with Pandoc conversion tips has been added. Minor edits and fixes. 17 May 2025: Minor style fixes \u0026 new content\nDOC-11: Fixed legibility issues with code blocks in dark mode. Minor updates to the Hugo section. Other style tweaks and cleanup. 15 May 2024: More cleanup and some new content\nAdded package manager reference to Unix section Added common console commands to Git section. Added a new section for apps. Started adding content to Node.js section. DOC-15: Verified redirects for old article URLs. DOC-14: Finished migrating earlier articles. Minor customizations and cleanup (more typos, go fig.) 13 May 2024: Migration review \u0026 cleanup\nMany typos fixed. (Many typos.) Added Style guides to Docs section. Added Email privacy error to Git section. Add post describing the Initial migration experience to Scribbles 10 May 2024: Site migrated to new look \u0026 layout.\n7 May 2024: Internal preview and progress sync\n1 May 2024: Begin converting the site to Hugo.\nSeveral driving reasons, including:\nCreate and present a more professional portfolio of writing samples Share knowledge Simplify site maintenance Experiment with new features/tools Demonstrate technical expertise beyond writing To learn more, see Restarting the engines.\nEarlier changes have been archived.\n","categories":"","description":"Change happens. Here's what's happened here recently.","excerpt":"Change happens. Here's what's happened here recently.","ref":"/about/changelog/","tags":"","title":"Changelog"},{"body":"Here is a list of terms and idioms used on the site.\nPull request (PR) Pull requests (PRs) are groups of changes to be checked in to a git-based repository. While working on a git project, you save changes by commiting them to the project.\nWhen you complete a task or set of related changes, you package them into a pull request so they can be merged into the project.\n","categories":"","description":"","excerpt":"Here is a list of terms and idioms used on the site.\nPull request (PR) …","ref":"/tips/glossary/","tags":"","title":"Glossary"},{"body":"So…a couple of weeks ago, I posted about a family event that unexpectedly upended my work schedule. It was a positive event (child birth), one that got me thinking about work/life balance, integrity, personal priorities, and so on.\nLast Friday, I received another reminder of such things: my wife’s oldest had been in a serious car accident and her prognosis was, at that time, unknown. (She’s got a long, painful recovery ahead of her, but she survived.)\nMy wife immediately packed a bag and headed for the hospital (a few hours away).\nMy oldest grandchild also started driving to the hospital. While she was on her way, her boyfriend was involved in a separate car accident and severely hurt. My granddaughter had originally planned to be in the same car at the same time. Had that happened, it’s highly unlikely she would have survived.\nThus, we very nearly had a double tragedy in short order.\nThat’s given me much to think about over the past few days.\nI know it’s not pleasant to think about personal issues, especially when you’re focused on work or technical issues.Yet, life events happen. We can’t ignore them just because they’re hard or make us uncomfortable. My family may have avoided the double tragedy, but many don’t.\nPeople we know and respect deal with such things on a regular basis. We often don’t even realize the things going on outside of the current project.\nI stand behind my earlier post: Life is short. It’s over before you know it. Do the thing when it needs to be done.\nSay what needs to be said when it needs to be said; otherwise, you may not have the opportunity. If you feel the impulse to say something nice, do so. If you feel gratitude, express it. If you need something, ask for it. Comfort. Engage. Interact.\nThe only way things get better is if we’re active… and proactive… in making them better. Get involved.\nThat’s my take and I’m not going to apologize for it.\n","categories":"","description":"Not all random events are tragic, but some encourage further reflection.","excerpt":"Not all random events are tragic, but some encourage further …","ref":"/scribbles/thoughts/bingo-card-redux/","tags":"","title":"Bingo card redux"},{"body":"It’s been several weeks since I began reimplementing the website. It’s been an interesting experience to say the least. It’s fun to create something new and watch it come together. It’s also a little aggravating to find things that slipped through and need to be cleaned up. It’s also educational to overcome bits of friction to create a better experience.\nPerhaps it’s time to take stock.\nWhat’s gone well? Well, here’s a high-level look at the recent changes:\nMigrated the site to a new stack (changing from MKDocs to Hugo) Learned (and adapted) a new template (Docsy) Tweaked and fixed a few layout choices Added navigation improvements Rewritten several topics to reflect my current style (while adding new topics) Fixed a number of (relatively) minor CSS bugs/choices None of these tasks have been unexpected.\nSome have been trivial; others have required a bit of investigation, experimentation, and patience. (All good qualities to bring to any migration.)\nTo be honest, I’ve been a bit surprised that things haven’t been more difficult. Yes, there have been a few missteps and glitches. However, most things have been relatively easy to take care.\nI actually feel good enough about the site to show it to others for their feedback. (And, yes, that’s an improvement over the previous design.)\nThe site was originally created to share writing samples with prospective employers. Now that there’s a solid foundation, I’ve been able to expand scope beyond a few curated topics. Now, you can get a sense of my design thinking, my organizational approaches, and even a bit of my personality.\nWhat could have gone better?\nSome problems might’ve been avoided with more mindful planning and more rigorous testing. (This seems a bit speculative and/or obvious.)\nI think overall progress has been good, especially when factoring in competing demands: family concerns, unplanned travel, and other challenges.\nIt’s tempting to wonder if I’ve used my time as wisely as I could have. (Again, this seems speculative.) I suppose the most honest answer is “Maybe…?” Time value depends on perspective. And I try to prioritize the most important things in each moment. You’re free to disagree with my choices, if you like.\nArmchair quarterbacking aside, I’m not sure there have been many major issues. Yes, broken links should have been noticed during unit review. And, yes, some of my initial organizational ideas haven’t been as successful as I’d hoped.\nHowever, these seem like natural artifacts of the agile development process. We do what we can in the time available and then we iterate to improve things over time. Whatever missteps I’ve made, things have clearly improved.\nI think the new foundation enables a number of possibilities that weren’t feasible with the earlier design.\nI will say this: I feel more engaged with the site…and more motivated to continue improving it. Perhaps that’s the best benefit of all.\nLet’s see what happens, shall we?\n","categories":"","description":"Let's see how things are going.","excerpt":"Let's see how things are going.","ref":"/scribbles/journal/six-week-progress/","tags":"","title":"Six week progress report"},{"body":"When I woke up this morning, I did not have “Visit Phoenix, Arizona” on my bingo card. Especially this close to Summer, when temperatures are over 100 degrees F.\nNo, I had “drink coffee,” “play with cats,” “work on my site,” “meet with team members,” and so on.\nAt 9:50 am, a text: “Water just broke.”\nI immediately booked a flight, packed a bag, and flew to Phoenix to be near my daughter and her husband for the birth of their first child.\nWe know the tech world changes rapidly: directions change, requirements change, schedules change, and (of course) lives change.\nOne moment, you’re working on a ticket and then suddenly you learn your role has been eliminated.\nOne moment, you’re trying to figure out your workday. In the next, you’re planning a quick trip into the high desert.\nOne moment, you’re trying to solve a thorny problem and the next thing you know, you’re in the hospital getting an EKG.\nIt’s cliche to say that “Change happens,” but that doesn’t change the simple reality that change really is the only constant.\nWe talk a lot about “work/life balance.” And it’s really easy to get caught up in the corporate drama.\nDon’t lose sight of the real moments in life. In a few years, which will you remember most? The temporary success of some business objective…or the family member you supported when they needed you? Which will you value most? Seems like an easy answer to me.\nIf you’re in an environment where family is not the easy answer, get out. ASAP. Find a role where families are factored into the priorities, no matter what. Find leadership that tells you to do whatever you need in order to protect and care for your own.\nYes, there are times when you need to make a tough call. But family should always be an easy call. Especially in the unexpected moments of change and import.\nA lot of companies claim integrity as a corporate value. The truth of that commitment is revealed in the behavior of their leaders and managers.\nIf they don’t walk the talk, especially when it’s hard, they don’t have integrity. They don’t have your back…and they shouldn’t benefit from your time, energy, passion, or creativity.\nThat’s my take. Your mileage may vary.\nVital statistics First post: 11 June 2024 ","categories":"","description":"What does Phoenix, Arizona have to do with bingo cards?","excerpt":"What does Phoenix, Arizona have to do with bingo cards?","ref":"/scribbles/thoughts/phoenix-bingo-card/","tags":"","title":"Is Phoenix on your bingo card?"},{"body":"A few years ago, I interviewed for a tech writing role.\nWhile chatting with two team members and their manager, I asked, “What single quality would help someone succeed in this role?”\nEveryone thought for a moment before replying.\nThe teammates said, respectively: Curiosity and Humility.\nThe manager said, “Kindness, which is different than Nice.”\nI like asking this question in interviews because it’s not one many people plan for. The answers are often unscripted and can lead to unexpected points of clarity.\nI really liked those answers; I felt them resonate.\nI didn’t get that particular role, but I learned something. I value the experience.\nCompassionate tech values At about the same time, I coincidentally ran across April Wensel’s Compassionate tech values:\nHumility \u003e Ego Inclusion \u003e Elitism Cooperation \u003e Competition Learning \u003e Being smart Being a mentor \u003e Being a “rockstar” Again, these resonated.\nThey continue to resonate, especially when I find myself in environments that, um…., prefer other values.\nI try to hold myself accountable by reminding myself of the values that resonate within me.\nYour mileage may vary.\nVital statistics First post: 10 June 2024 ","categories":"","description":"A few qualities worth further meditation","excerpt":"A few qualities worth further meditation","ref":"/scribbles/thoughts/success-qualities/","tags":"","title":"Qualities for successful tech writers"},{"body":"“Reliable” sources tell me these quotes were overheard in (or near) Quark’s bar on Freecloud (Alpha Doradus):\nWhat is this talk of software ‘releases’?\nKlingons do not ‘release’ software; our software ESCAPES, leaving a bloody trail of designers and testers in its wake!\nThis code is a piece of gagh! You have no honor!\nA TRUE Klingon warrior does not comment his code!\nBy filing this bug report, you have questioned my family honor. Prepare to die!\nYou question the worthiness of my Code?! I should kill you where you stand!\nOur competitors are without honor!\nSpecifications are for the weak and timid!\nThis machine is a piece of GAGH! I need more processors if I am to do battle with this code!\nPerhaps it IS a good day to Die! I say we ship it!\nMy program has just dumped Stova Core!\nBehold, the keyboard of Kahless! The greatest Klingon code warrior that ever lived!\nYou cannot really appreciate Dilbert unless you’ve read it in the original Klingon.\nIndentation?! - I shall show you proper indentation…on your skull!\nKlingon function calls do not have ‘parameters’ - they have ‘arguments’ – and they ALWAYS WIN THEM.\nDebugging? Klingons do not debug. Our software does not coddle the weak.\nI have challenged the entire quality assurance team to a Bat-Leth contest. They will not concern us again.\nOur users will know fear and cower before our software! Ship it! Ship it and let them flee like the targs they are!\nCry havoc and let slip the docs of war.\n(Originally collected from multiple ‘Net sources, sadly lost over time.)\nVital statistics First post here: 8 June 2024 Originally collected on PerlMonks, 28 Feb 2001, ported for preservation. ","categories":"","description":"A collection of quotes allegedly overheard from Klingon code warriors","excerpt":"A collection of quotes allegedly overheard from Klingon code warriors","ref":"/scribbles/trifles/klingon-coder/","tags":"","title":"The Compleat Klingon Coder"},{"body":"The site has been been updated to a new look. It has more content and a more professional pipeline.\nI have to admit that I was a little worried when starting the migration process, even though I’ve been working with (or near) the new toolset for some time.\nPart of my nervousness stems from earlier experiences, which have included some rather…dramatic results.\nNo matter how well you plan, something always seems to go sideways. And, truth be told, there were a couple of glitches along the way. (Fortunately, I noticed and resolved things quickly.)\nThe new site is built using Hugo in conjunction with the Docsy theme. It’s deployed using Github pages, which should be fine for the amount of traffic I get. (I do have a scaling plan in case things blow up, but I highly doubt that’s going to happen.)\nContent is maintained in a private repo and updates are synchronized to a public repo. (I plan to write a couple of articles walking through the process.)\nThis approach and architecture is meant to show what you can accomplish with minimal investment. Except for domain registration, the site currently relies on free services.\nA number of companies take similar approaches for their docs. Microsoft, for example, maintains private and public repos for Microsoft Learn, their doc site. They get the benefit of public contributions while securing product release plans until they’re ready to be unveiled.\nSo how long did this makeover take? Roughly ten days from start to finish:\nA prototype was “publishable” in three days.\nGranted, I wouldn’t have wanted to publish that version, but I could have if pressed.\nThe following week was spent testing, tweaking, and refining.\nThis included reworking previous articles, adding support material, and writing new articles.\nThe actual site migration took about 30 minutes overall.\nTiming started with adding a notice to the previous version of the site, just in case things went terribly wrong.\nI considered migration complete when the public URLs were updated.\nMigration was handled carefully. Each step was tested and verified.\nThis helped identify a few issues and I’ve filed tickets accordingly. (Yes, I have a private Jira project to track work for the site.)\nI think the new site works at least as well as the earlier one. That may seem like a modest win (table stakes, some would say). And, yet…how many times have we seen larger projects stumble because of less attention to detail?\nSo here we are. Is the site everything I imagined? Not entirely. But, I think it is an improvement and it sets a solid foundation for additional work.\nWith luck, the next major update will happen within days. And, with more luck (and diligence), that will only be the beginning.\nQapla'!\n","categories":"","description":"The site has been updated. Let's take stock.\n","excerpt":"The site has been updated. Let's take stock.\n","ref":"/scribbles/journal/initial-migration/","tags":"","title":"Initial migration complete"},{"body":"Welcome back to the ongoing work-in-progress. I’m blowing off the dust, sweeping away the cobwebs, and setting up new things.\nThis site serves as a practical portfolio and personal knowledgebase. It provides writing samples and illustrates my approach to technical writing. It also shares knowledge and lessons learned during my technical adventures.\nI hope the content is engaging, practical, and has at least a bit of value. (I’m still trying to chase down the various typos, so you’ll have to forgive a few rough edges.)\nThe initial version of the site was built using MKDocs, a static site generator used to create websites from Markdown.\nThe new version uses Hugo, which I find to be a bit more capable and extensible than MkDocs. (That’s a personal opinion; your mileage may vary.)\nThis post marks the beginning of the new journey. I’m using this to learn a new theme and to refine my technical skills/knowledge.\nInitially, I plan to mine my personal notes for content. I’m also working on backend improvements to improve discoverability, reduce maintenance, and so on.\nFuture posts will discuss various aspects of the process. For now, I’m working on the general site structure and initial content.\nThanks for joining me on this journey. Hail and well met!\n","categories":"","description":"A new version is afoot; here are the whats, whys, and wherefores.","excerpt":"A new version is afoot; here are the whats, whys, and wherefores.","ref":"/scribbles/journal/restart-engines/","tags":"","title":"Restart the engines"},{"body":"Choose your greeting:\nHail and well met! Greetings, lifeform. Goooood Eeeeevvvening. Hello troubleshooter. Buh-doop beep? BLAAAT! Oh. It’s you. It’s been a looong time. How’ve you been? After many promises, multiple unfinished prototypes, and much pondering, it’s finally online. The site, I mean.\nHere, you’ll find technical articles and posts related to things I’m working on, lessons I’ve learned, solutions I’ve found, and other thoughts I thought worth sharing.\nFeel free to browse, but I do ask that shenanigans be kept to a minimum…unless, of course, I’m allowed to be rambunctious as well. In that event, well, it’s off to the races… (off to the races…)\nSee About for the rules (such as they are).\nThings are a bit sparse at the moment, but that’s because I’m still pulling things together.\nFor the near future, I’m keeping it simple. Eventually, I’ll need to complicate things a bit, but hopefully not too much.\nIn Scribbles, I generally follow a light, bloggy style…except when I don’t.\nFormal articles appear in Tips. Yes, there’s a marked style difference, by design. Navigation shortcuts, search, and other traditional features are being added over time.\nComments are not currently enabled, so you’ll need to provide feedback one of the contact points on the about page. All well-intentioned feedback is appreciated.\nIf you find anything useful, feel free to share and enjoy (share and enjoy). Please give credit where credit is due. You may not pinch and poach. If something’s useful, cite where you found it.\nIf you feel I’ve not cited things correctly, let me know so I can take appropriate action.\nThings are a bit of a mess at the moment, but the style will settle down and start telling you things you need to know. I hope.\n","categories":"","description":"Hello, welcome! Choose your greeting and learn what's going on.","excerpt":"Hello, welcome! Choose your greeting and learn what's going on.","ref":"/scribbles/journal/first-post/","tags":"","title":"First post: Don't panic"},{"body":"","categories":"","description":"","excerpt":"","ref":"/categories/","tags":"","title":"Categories"},{"body":" 🧩 Tips Now includes tips for: CSS Docs Excel Git HTML Markdown MKDocs Hugo JavaScript Mac Node.js Pandoc Unix Windows Word More soon!\n📘 Scribbles Scribbles are posts with news, commentary, \u0026 other random thoughts. Recently posted:\n8 July: Bingo card redux? 14 June: Six week progress report 11 June: Is Phoenix on your bingo card? 10 June: Qualities for successful tech writers Also, see: About and Changelog ","categories":"","description":"A personal portfolio and technical knowledgebase","excerpt":"A personal portfolio and technical knowledgebase","ref":"/","tags":"","title":"Lance's Quips \u0026 Quibbles"},{"body":"","categories":"","description":"","excerpt":"","ref":"/search/","tags":"","title":"Search Results"},{"body":"","categories":"","description":"","excerpt":"","ref":"/tags/","tags":"","title":"Tags"},{"body":"Here, you’ll find things that don’t neatly fit elsewhere.\n“The Pleasures and Pains of Coffee,” by Honoré de Balzac Zen Pencils - Isaac Asimov: A lifetime of learning (among others) Steampunk Curse Generator, via Lori Alden’s Brassbright Chronicle. Like everything else on the site, they’re provided as-is.\nYour interest will likely vary, based on who you are and what you’re into.\nVital statistics First post: 10 June 2024 See also ","categories":"","description":"","excerpt":"Here, you’ll find things that don’t neatly fit elsewhere.\n“The …","ref":"/scribbles/trifles/","tags":"","title":"Trifles and Tidbits"}]