Eklavya's Blog - Tutorialhttps://sharmaeklavya2.github.io/blog/2023-01-12T00:00:00+05:30The No-Brainer Dal Recipe2021-09-06T00:00:00+05:302021-09-06T00:00:00+05:30Eklavya Sharmatag:sharmaeklavya2.github.io,2021-09-06:/blog/easy-dal.html<p>This article gives a very simple recipe for cooking dal, invented by my mom. It's easier than the recipes I found on the internet, and easier than the recipes that my friends use. This recipe is great if you want to reduce the time you spend cooking or if you're new to cooking and want to start simple.</p><p>This article gives a very simple recipe for cooking dal, invented by my mom.
It's easier than the recipes I found on the internet,
and easier than the recipes that my friends use.
This recipe is great if you want to reduce the time you spend cooking
or if you're new to cooking and want to start simple.</p>
<p>But before that, I'll give two disclaimers:</p>
<ol>
<li>This recipe tastes good, but you can get slightly better-tasting dal by putting in more effort.
However, I like this recipe, I'm not picky about what I eat, and I want to save time,
so I'll stick to this article's recipe for the foreseeable future.</li>
<li>My mom often uses a better recipe. Don't judge her cooking skills based on this article's recipe!</li>
</ol>
<h2 id="what-is-dal">What is dal?<a class="headerlink" href="#what-is-dal" title="Permanent link">¶</a></h2>
<p>I'll start from the basics for non-Indian readers of this article.</p>
<p>Dal is basically a traditional Indian dish where you boil seeds
(from the Leguminosae family of plants) in water and add spices.</p>
<p>You can't use <em>any</em> seeds
because only some species of seeds taste good as dal.
These are some of the popular ones
(these are Indian names; I don't know what they're called in English):</p>
<ol>
<li>Toor (a.k.a. Arhar)</li>
<li>Yellow moong (a.k.a. yellow mung)</li>
<li>Green moong (a.k.a. green mung)</li>
<li>Yellow/Orange masoor</li>
<li>Black masoor</li>
<li>White/Yellow urad</li>
<li>Black urad</li>
<li>Chana</li>
</ol>
<p>All of these taste different, but the recipe for cooking them is almost the same,
so you can get a lot of variety without learning much cooking.</p>
<p>The black/brown/green ones have their seed coat,
and the white/yellow/orange ones do not.</p>
<p>You can find bags of these seeds in Indian stores.
In the US, you'll find 2-pound and 4-pound bags (0.91 kg and 1.81 kg).
All these seeds are dicotyledonous, i.e., they have two cotyledons.
To cook dal, make sure you buy seeds that are already split into two parts.</p>
<div class="gallery">
<figure>
<img src="https://sharmaeklavya2.github.io/blog/img/food/green-moong-split.jpg" alt="Split green moong seeds" />
<figcaption class="success">Split green moong seeds. Use these for dal.</figcaption>
</figure>
<figure>
<img src="https://sharmaeklavya2.github.io/blog/img/food/green-moong-whole.jpg" alt="Whole green moong seeds" />
<figcaption class="danger">Whole green moong seeds. Do NOT use these for dal.</figcaption>
</figure>
</div>
<p>Dal is a very inexpensive source of food.
In Champaign, Illinois, a 2-pound bag of dal costs between $3 and $3.5.
Half a glass of dal seeds is a meal-for-two
since they absorb water and swell up when they're cooked.</p>
<p>Dal is a good source of protein.
It has much less protein than meat or eggs, but it has enough protein
that you won't get protein deficiency if you eat it once a day.
(Though if you're looking to build serious muscle,
like if you're bodybuilding, then dal alone is unlikely to suffice).</p>
<p>Most people in India eat dal with either rice or roti
(roti is like an Indian version of tortilla).
You can also eat it with toasted bread.
I like rice with toor dal and black masoor dal
and roti/bread with the other dals.</p>
<h2 id="ingredients-and-utensils">Ingredients and Utensils<a class="headerlink" href="#ingredients-and-utensils" title="Permanent link">¶</a></h2>
<ol>
<li>1/2 glass of dal seeds</li>
<li>water</li>
<li>1 teaspoon of cooking oil / butter / ghee</li>
<li>1/2 teaspoon salt</li>
<li>0.4 heaped teaspoon turmeric powder</li>
<li>0.4 heaped teaspoon coriander powder</li>
<li>0.2 heaped teaspoon red chili powder (optional)</li>
<li>1/2 teaspoon cumin seeds</li>
<li>1 pinch hing (a.k.a. powdered asafoetida)</li>
<li>0 to 1 teaspoon Garam masala (optional)</li>
</ol>
<p>You need a pressure cooker to cook dal,
because at higher pressures, the boiling point of water is
more than 100°C (212°F), so dal will cook better and faster.</p>
<p>The amount of water you need depends on how thick you want your dal to be
and what kind of seeds you're using. I usually use roughly:</p>
<ul>
<li>1.75 to 2 glasses of water for toor dal.</li>
<li>2.5 glasses of water for green moong.</li>
<li>2.25 glasses of water for all other dals.</li>
</ul>
<p>It's hard to measure 0.4 teaspoons of turmeric powder and coriander powder.
So you can just mix them beforehand.
I mixed 200 grams of turmeric powder, 200 grams of coriander powder
and 100 grams of red chili powder and put it in a box.
Now I just use 1 heaped teaspoon of this mixture
each time I cook dal.</p>
<p>I haven't cooked black masoor dal yet,
and my mom said that this recipe isn't very appropriate for black masoor.
This recipe works well for black urad dal,
but you'll get much better results with a better recipe
(like <a href="https://en.wikipedia.org/wiki/Dal_makhani">Dal Makhani</a>).
You should soak black urad dal in water for at least 1 hour (preferably several hours)
before you start cooking. The amount of water used for soaking plus
the amount added afterwards should equal around 2.25 glasses.</p>
<p>I like to mix yellow moong with orange masoor (2:1 ratio)
and white urad and chana (3:1 ratio).
Other than these, I don't mix different kinds of seeds.</p>
<h2 id="recipe">Recipe<a class="headerlink" href="#recipe" title="Permanent link">¶</a></h2>
<p>Basically you sautée cumin and hing for a few seconds in a pressure cooker,
then add water, dal, spices, salt, and then close the pressure cooker's lid and wait.
Here are the steps in more detail:</p>
<ol>
<li>Put a pressure cooker on the stove and set the heat to medium.
Start the exhaust fan.</li>
<li>Add a teaspoon or two of cooking oil / butter / ghee.</li>
<li>Add 1/2 teaspoon of cumin seeds and a pinch of hing to the oil / butter / ghee
(You may want the oil to heat up before adding these.
I don't know if waiting makes a difference.)</li>
<li>Fill a glass with water.
If the water is warm/hot, cooking will take less time.</li>
<li>Wait for the cumin seeds to start splattering or bubbling.
Then wait for 15 to 90 seconds.
Then add the glass of water.</li>
<li>Set the stove to high heat (the highest setting).</li>
<li>Add 1/2 glass of dal.</li>
<li>Add the rest of the water.</li>
<li>Add 1/2 teaspoon salt.</li>
<li>Add turmeric powder, coriander powder and (optionally) chili powder.</li>
<li>Stir with a spoon.</li>
<li>Close the lid of the pressure cooker and wait for the cooker to shout.</li>
<li>After it shouts, set the stove to medium heat.</li>
<li>Turn off the stove after 8 to 10 minutes.
(The cooker may shout a few times while the stove is on; that's fine.)
For toor dal, 7 minutes may suffice.
For dals with seed coat, you can maybe go up to 12 minutes if you want it softer.</li>
<li>Wait for 20 to 30 minutes for the cooker to cool down.</li>
<li>Remove the cooker's whistle and open the lid.</li>
<li>(Optional) Add at most 1 teaspoon garam masala.</li>
<li>(Optional) Add butter / ghee / cream.</li>
<li>Stir the dal with a large spoon to make it homogeneous.</li>
</ol>
<h2 id="tweaking-and-troubleshooting">Tweaking and Troubleshooting<a class="headerlink" href="#tweaking-and-troubleshooting" title="Permanent link">¶</a></h2>
<p>You may want to try varying the amount of spices and water to your preferences.</p>
<p>If you find that the dal is too thick/dry after opening the cooker, you can fix it:
Add some more water, turn on the stove to high heat and bring it to a boil
without closing the lid of the pressure cooker.
As soon as it starts boiling, turn off the stove.</p>
<p>Dal doesn't have much fat. You can fix this by adding butter or cream
(people trying to lose weight may disagree that 'fix' is the right word here).
This also improves the taste.</p>
<p>The cooking time after the first shout is independent of the amount of dal you're cooking.
This is because the rate of cooking only depends on the temperature,
and that's fixed to the boiling point of water.
If you increase the stove's heat, the food will still take the same time to cook;
the extra thermal energy will just be used to convert water to steam, i.e., wasted.</p>
<p><strong>Credits</strong>: Thanks mom for this awesome recipe!
Thanks <a href="https://tanvibajpai.com">Tanvi Bajpai</a> for suggesting a good title.</p>A Comprehensive Guide to Customizing your MacBook2019-07-12T00:00:00+05:302023-01-12T00:00:00+05:30Eklavya Sharmatag:sharmaeklavya2.github.io,2019-07-12:/blog/customize-macos.html<p>This post contains a list of all the things I did to customize my MacBook. Most instructions here are useful only for programmers and power users.</p><p>I recently got a new laptop - a MacBook Air!
I customized it so that it's easy for me to use.
Major changes include:</p>
<ul>
<li>Moving data from my old laptop to my new laptop.</li>
<li>Installing and configuring software for basic necessities, programming and writing content.</li>
<li>Setting up a nice environment on my <a href="https://en.wikipedia.org/wiki/Terminal_emulator">terminal</a>.</li>
</ul>
<p>As I made all these changes to my new laptop, I noted down the steps that I took for future reference.
I think they could be useful to others, so here they are, as a blog post.</p>
<p>This post is written for macOS Mojave.
You may have to modify some instructions if you're using a newer macOS.
If you're not using macOS, you can still get a similar working environment on Linux,
but you'll have to make major modifications to the instructions below.</p>
<p>You can also refer to this <a href="https://sharmaeklavya2.github.io/blog/img/macos-customize-graph.dot.svg">dependency graph</a>
(<a href="https://sharmaeklavya2.github.io/blog/img/macos-customize-graph.dot">source code</a>).</p>
<div class="toc"><span class="toctitle">Table of Contents</span><ul>
<li><a href="#basic-setup">Basic setup</a><ul>
<li><a href="#system-preferences">System Preferences</a></li>
<li><a href="#finder-preferences">Finder preferences</a></li>
<li><a href="#install-google-chrome-and-sync-profile">Install Google Chrome and sync profile</a></li>
<li><a href="#textedit-preferences">TextEdit preferences</a></li>
</ul>
</li>
<li><a href="#terminal-and-shell">Terminal and Shell</a><ul>
<li><a href="#terminalapp-preferences">Terminal.app preferences</a></li>
<li><a href="#installing-xcode-command-line-tools">Installing Xcode command-line tools</a></li>
<li><a href="#dotfiles">Dotfiles</a></li>
<li><a href="#install-homebrew">Install Homebrew</a></li>
<li><a href="#install-tmux">Install tmux</a></li>
</ul>
</li>
<li><a href="#install-command-line-programs">Install command-line programs</a><ul>
<li><a href="#mactex">MacTex</a></li>
<li><a href="#python-and-packages">Python and packages</a></li>
<li><a href="#other-useful-programs">Other useful programs</a></li>
</ul>
</li>
<li><a href="#transfer-backed-up-data">Transfer backed-up data</a><ul>
<li><a href="#reorganizing-data-and-backup">Reorganizing data and backup</a></li>
<li><a href="#ntfs-drivers-for-macos">NTFS drivers for macOS</a></li>
<li><a href="#install-dropbox-and-use-symlinks">Install Dropbox and use symlinks</a></li>
<li><a href="#wallpapers-and-profile-picture">Wallpapers and profile picture</a></li>
</ul>
</li>
<li><a href="#customize-vim">Customize Vim</a><ul>
<li><a href="#install-newer-vim">Install newer Vim</a></li>
<li><a href="#install-pathogen">Install Pathogen</a></li>
<li><a href="#get-vim-plugins">Get Vim plugins</a></li>
<li><a href="#install-youcompleteme">Install YouCompleteMe</a></li>
<li><a href="#fix-vim-locale-error">Fix Vim locale error</a></li>
</ul>
</li>
<li><a href="#install-nginx-and-serve-website-mirrors">Install Nginx and serve website mirrors</a><ul>
<li><a href="#install-and-run-nginx">Install and run Nginx</a></li>
<li><a href="#enable-nginx-autoindex">Enable nginx autoindex</a></li>
<li><a href="#serve-my-websites-with-nginx">Serve my websites with Nginx</a></li>
<li><a href="#security">Security</a></li>
</ul>
</li>
</ul>
</div>
<h2 id="basic-setup">Basic setup<a class="headerlink" href="#basic-setup" title="Permanent link">¶</a></h2>
<ul>
<li><strong>Connect to a WiFi network</strong>, since we'll be downloading a lot of stuff.</li>
<li><strong>Update your OS</strong>.</li>
<li>macOS will offer a <strong>tour of the OS</strong>. Take that if you're new to macOS.</li>
<li><strong>Remove useless apps from dock</strong>: right-click on the app in the dock, go to Options and uncheck 'Keep in Dock'.</li>
</ul>
<h3 id="system-preferences">System Preferences<a class="headerlink" href="#system-preferences" title="Permanent link">¶</a></h3>
<p>Click the Apple logo in the top-left corner of your screen and choose 'System Preferences'.
Here you can customize most aspects of your operating system.
If you have the time, go through each of the items and choose the options which make sense to you.
These are the changes which I made:</p>
<ul>
<li>General: Use dark theme (Appearance: Dark).</li>
<li>Dock:<ul>
<li>Position on screen: Left.</li>
<li>Uncheck 'Show recent applications in Dock'.</li>
</ul>
</li>
<li>Language and Region: Select 'English (US)' as the primary language.
I live in India, so the default was 'English (India)',
but I changed it because I generally follow US spelling.
I don't want my spell-checker to highlight 'color' and 'center' as misspelled words.</li>
<li>Keyboard: Input Sources: Hide input menu in menu bar.</li>
<li>Display: Choose Resolution as Scaled and choose the large size.</li>
<li>Bluetooth: Show Bluetooth in menu bar.</li>
<li>Sharing:<ul>
<li>Change hostname. The hostname shows up in the terminal prompt, so I want it to be short.</li>
<li>Allow remote login via SSH.</li>
</ul>
</li>
<li>Siri: Disable Siri. I rarely use it.</li>
<li>Date and Time: In the 'Clock' tab, check 'Display time with seconds' and 'show date'.</li>
<li>Accessibility: Siri: 'Enable type to Siri' if you don't want to disable Siri
but want to talk to it by typing instead of speaking.</li>
</ul>
<h3 id="finder-preferences">Finder preferences<a class="headerlink" href="#finder-preferences" title="Permanent link">¶</a></h3>
<p>Finder is the file manager in macOS.</p>
<ul>
<li>Finder preferences (<code>Cmd + ,</code>):<ul>
<li>General: Show hard disk and connected servers on desktop.</li>
<li>Sidebar: Select useful locations.</li>
<li>Advanced:<ul>
<li>Show all filename extensions.</li>
<li>Keep folders on top in windows.</li>
<li>Search current folder when performing a search.</li>
</ul>
</li>
</ul>
</li>
<li>Go to 'View' in Finder's menu bar:<ul>
<li>Show view options (<code>Cmd + J</code>): 'Sort by Name' and 'Use as Defaults'.</li>
<li>Show path bar.</li>
</ul>
</li>
<li>Press <code>Cmd + Shift + .</code> to enable viewing hidden files.</li>
</ul>
<h3 id="install-google-chrome-and-sync-profile">Install Google Chrome and sync profile<a class="headerlink" href="#install-google-chrome-and-sync-profile" title="Permanent link">¶</a></h3>
<p>I prefer Google Chrome over Safari.
I made Chrome the default browser.
I also synced my account to get all my bookmarks and extensions.</p>
<h3 id="textedit-preferences">TextEdit preferences<a class="headerlink" href="#textedit-preferences" title="Permanent link">¶</a></h3>
<p>TextEdit is the default plain-text and rich-text editor bundled with macOS.</p>
<p>I usually use <a href="https://en.wikipedia.org/wiki/Vim_(text_editor)">Vim</a> for text editing.
Vim is far superior to TextEdit in terms of advanced functionality,
like customizability, syntax highlighting, find-and-replace, etc.
But having a lightweight GUI text editor can be handy.</p>
<p>TextEdit preferences (<code>Cmd + ,</code>):</p>
<ul>
<li>Format: plain text. This is needed to prevent new instances of TextEdit from opening a rich-text editor.</li>
<li>Font: Menlo, size 16.</li>
<li>Disable 'Correct spelling automatically'.</li>
<li>Display HTML files as HTML code.</li>
<li>Disable 'add .txt extension to plain text files'. This is needed if you have to edit extensionless files.</li>
</ul>
<h2 id="terminal-and-shell"><span style="background-color: rgba(255, 204, 0, 0.3)"/>Terminal and Shell</span><a class="headerlink" href="#terminal-and-shell" title="Permanent link">¶</a></h2>
<p>If you're an aspiring programmer or power user, you should get to know the command-line.
For this blog post, I'm going to assume that you know how to run commands from the shell and
you know the meaning of the following words:
terminal emulator, shell, prompt, home directory, current working directory.
In case you don't, here's a nice short tutorial by TreeHouse:
<a href="https://blog.teamtreehouse.com/introduction-to-the-mac-os-x-command-line">Introduction to the Mac OS X Command Line</a>.</p>
<h3 id="terminalapp-preferences">Terminal.app preferences<a class="headerlink" href="#terminalapp-preferences" title="Permanent link">¶</a></h3>
<p>Terminal.app is the default terminal emulator on macOS.
There are better alternatives, like <a href="https://www.iterm2.com/features.html">iTerm2</a>,
but Terminal.app is good enough for me, so I didn't bother installing iTerm2.</p>
<h4 id="creating-a-new-profile-with-the-solarized-color-scheme">Creating a new profile with the Solarized color scheme<a class="headerlink" href="#creating-a-new-profile-with-the-solarized-color-scheme" title="Permanent link">¶</a></h4>
<p>Terminal.app has multiple profiles available.
Each profile specifies the color scheme, font face, font size and many other settings.
Instead of making changes to the default profile,
we're going to create a new profile with our changes.</p>
<p>I use the <a href="https://ethanschoonover.com/solarized/">Solarized</a> color scheme for my terminal because:</p>
<ul>
<li>It is an eye-pleasing color scheme. It works well with Vim's syntax highlighting.</li>
<li>Solarized is a popular color scheme, so it's available on many terminal emulators, text editors, IDEs, etc.
This helps me get a unified look-and-feel when switching programs or platforms.</li>
</ul>
<p>Even though Solarized isn't available out-of-the-box for Terminal.app,
the advantages above outweigh the effort required to set it up on the terminal.</p>
<ul>
<li>Download the <a href="https://raw.githubusercontent.com/tomislav/osx-terminal.app-colors-solarized/master/Solarized%20Dark.terminal">Solarized dark theme for Terminal.app</a>. Open it in finder and double-click on it.</li>
<li>macOS will say that the file cannot be opened because it is not from an identified developer.
Go to 'System Preferences > Security > General' and press 'Open Anyway' (don't worry; it's not an executable).</li>
<li>Open terminal, 'Preferences > Profiles', select 'Solarized Dark' and press the 'Default' button.
Now restart Terminal.app and you'll see the dark blue background of the Solarized color scheme.</li>
</ul>
<h4 id="other-preferences">Other preferences<a class="headerlink" href="#other-preferences" title="Permanent link">¶</a></h4>
<ul>
<li>In the 'Preferences > Profile > Text' tab, set opacity to 85% and font size to 16.</li>
<li>In the 'Preferences > Profile > Window' tab, deselect 'restore text when reopening windows'.</li>
</ul>
<h3 id="installing-xcode-command-line-tools">Installing <a href="http://osxdaily.com/2014/02/12/install-command-line-tools-mac-os-x/">Xcode command-line tools</a><a class="headerlink" href="#installing-xcode-command-line-tools" title="Permanent link">¶</a></h3>
<p>The 'Xcode command-line tools' consist of command-line applications that are
very common in Unix-like environments, like git, gcc, make, perl.</p>
<p>Run <code>xcode-select --install</code> from a terminal.
A dialog box will pop up. Select install.
You should probably connect to a power source before doing this
because macOS is going to suggest you do so.</p>
<h3 id="dotfiles">Dotfiles<a class="headerlink" href="#dotfiles" title="Permanent link">¶</a></h3>
<p>Dotfiles colloquially refers to configuration files placed in the home directory.
These files' names start with a dot (<code>.</code>).
Common examples are <code>.bash_profile</code>, <code>.vimrc</code> and <code>.gitconfig</code>.</p>
<p>I have put all my dotfiles in a Github repository at
<a href="https://github.com/sharmaeklavya2/dotfiles"><code>sharmaeklavya2/dotfiles</code></a>.
You can find detailed instructions for setting them up in the repository's readme.
Here is a brief version:</p>
<div class="codehilite"><pre><span></span><code>git clone https://github.com/sharmaeklavya2/dotfiles.git
cd dotfiles
./scripts/make_links.py
shopt -s dotglob nullglob
mv _links/.bashrc _links/.bash_profile
mv _links/* ~
</code></pre></div>
<p>Now either restart your terminal or run <code>source ~/.bash_profile</code>.
If you executed the above instructions correctly,
the first thing you'll notice is the improved, colorful prompt.</p>
<p>My dotfiles are written with the Solarized terminal color scheme in mind.
If you're not using Solarized, you may want to modify or omit using <code>.dircolors</code> and <code>.vimrc</code>.</p>
<p>I also recommend using the <code>git-prompt.sh</code> utility script, which will display useful information
about git repositories (like branch, dirty status, etc) in your prompt.
To do this, download <a href="https://raw.githubusercontent.com/git/git/master/contrib/completion/git-prompt.sh">git-prompt.sh</a>
to <code>~/ext_bin/git-prompt.sh</code>. The <code>~/.bash_profile</code> will use it to modify the prompt.</p>
<p>I also recommend adding the line <code>export HISTSIZE=100000</code> to either <code>~/.env</code> or <code>~/.bash_profile</code>
to increase your shell input history size.</p>
<h3 id="install-homebrew">Install <a href="https://brew.sh/">Homebrew</a><a class="headerlink" href="#install-homebrew" title="Permanent link">¶</a></h3>
<p>Homebrew (a.k.a. brew) is a package manager, which means it's like a terminal version of the App Store.
You can install programs (called packages by brew) by simply writing commands on the terminal:</p>
<div class="codehilite"><pre><span></span><code>brew install name-of-package
</code></pre></div>
<p>According to <a href="https://brew.sh/">brew's website</a>, brew can be installed by typing this into the terminal:</p>
<div class="codehilite"><pre><span></span><code>/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
</code></pre></div>
<p>Installation may require superuser permissions.</p>
<h3 id="install-tmux">Install <a href="https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/">tmux</a><a class="headerlink" href="#install-tmux" title="Permanent link">¶</a></h3>
<p>I usually need multiple shells to be open.
I can use Terminal.app's 'tabs' (<code>Cmd + T</code>) to achieve this.
But I use tmux instead since it has more features.
Also, if you SSH to a server that has tmux installed,
you can open multiple shells on the server on a single SSH session.</p>
<p>To install, run <code>brew install tmux</code>.</p>
<p>Brew will check for updates every time you run it.
To prevent that from happening, add <code>export HOMEBREW_NO_AUTO_UPDATE=1</code>
to <code>~/.bash_profile</code> or <code>~/.env</code>.</p>
<h2 id="install-command-line-programs"><span style="background-color: rgba(0, 255, 102, 0.3)">Install command-line programs</span><a class="headerlink" href="#install-command-line-programs" title="Permanent link">¶</a></h2>
<h3 id="mactex">MacTex<a class="headerlink" href="#mactex" title="Permanent link">¶</a></h3>
<p>MacTex is a suite of programs for typesetting documents using TeX and LaTeX.
LaTeX is a great system for writing professional-looking mathematical documents.</p>
<p>You can install MacTex using a GUI installer, but I did it using <code>brew install --cask mactex</code>.</p>
<h3 id="python-and-packages">Python and packages<a class="headerlink" href="#python-and-packages" title="Permanent link">¶</a></h3>
<p>macOS has Python 2 pre-installed, but we should use Python 3, since
<a href="https://www.anaconda.com/end-of-life-eol-for-python-2-7-is-coming-are-you-ready/">Python 2 will reach EOL</a>
on Jan 1, 2020.</p>
<p>Run <code>brew install python3</code>. That will install <code>python3</code> and <a href="https://pip.pypa.io/en/stable/"><code>pip3</code></a>.</p>
<p>I use <a href="https://docs.python.org/3/tutorial/venv.html">python virtual environments</a>.
I use one big virtualenv where I install all commonly used packages,
and I create application-specific virtualenvs for large applications that I'm developing.</p>
<p>Run <code>pip3 install virtualenv</code> to install the <code>virtualenv</code> tool.
Run <code>virtualenv /path/to/venv/ -p python3</code> to create a python3 virtualenv.</p>
<p>Activate the virtualenv using <code>source /path/to/venv/bin/activate</code>.
Now all python commands and applications you run will use this virtualenv.</p>
<p>I usually install python packages only when required,
but some are useful enough that I installed them in the beginning:</p>
<div class="codehilite"><pre><span></span><code>pip install ipython requests jinja2 pipdeptree flake8 grip
</code></pre></div>
<p>These packages are useful for math and computation:</p>
<div class="codehilite"><pre><span></span><code>pip install numpy scipy pandas matplotlib seaborn sympy
</code></pre></div>
<h3 id="other-useful-programs">Other useful programs<a class="headerlink" href="#other-useful-programs" title="Permanent link">¶</a></h3>
<ul>
<li>Although git is provided by the Xcode command line tools,
a more recent version can be obtained using <code>brew install git</code>.</li>
<li>To be able to write and run Java programs, install openjdk: <code>brew install openjdk</code>.</li>
<li>Node.js and npm: <code>brew install node</code>.</li>
<li>Other useful programs that can be <code>brew install</code>ed:
<a href="https://github.com/mookid/diffr/"><code>diffr</code></a>,
<a href="https://linux.die.net/man/1/dos2unix"><code>dos2unix</code></a>,
<a href="https://en.wikipedia.org/wiki/Htop"><code>htop</code></a>,
<a href="https://github.com/hanslub42/rlwrap/"><code>rlwrap</code></a>,
<a href="https://graphviz.org"><code>graphviz</code></a>,
<a href="https://ffmpeg.org"><code>ffmpeg</code></a>,
<a href="https://pandoc.org"><code>pandoc</code></a>,
<a href="https://github.com/ytdl-org/youtube-dl/"><code>youtube-dl</code></a>.</li>
</ul>
<h2 id="transfer-backed-up-data"><span style="background-color: rgba(0, 136, 255, 0.3)">Transfer backed-up data</span><a class="headerlink" href="#transfer-backed-up-data" title="Permanent link">¶</a></h2>
<h3 id="reorganizing-data-and-backup">Reorganizing data and backup<a class="headerlink" href="#reorganizing-data-and-backup" title="Permanent link">¶</a></h3>
<p>There are many places where I store my files:</p>
<ul>
<li>My laptop's SSD (which is small enough for all my files to not fit on it).</li>
<li>My external hard drive.</li>
<li>My <a href="https://www.dropbox.com/">Dropbox</a> account.</li>
<li><a href="https://github.com/sharmaeklavya2">My Github repositories</a>.</li>
<li>My Android phone.</li>
</ul>
<p>Some of my files are stored on more than one of the above locations.
Sometimes the files on one storage medium get updated but not others.
This made it very difficult for me to manage them without the risk of accidentally losing some files.</p>
<p>To mitigate this problem, I did a massive reorganization of my files before moving them to my new laptop.
I organized them into folders based on the kind of content and access patterns
and demarcated which folders will be on which storage mediums.</p>
<p>I moved my frequently-changing content to Dropbox.
I use the Dropbox desktop app which syncs my files online in real-time.
On my external hard drive, I have an up-to-date backup of content that rarely changes.</p>
<p>If you use git for your code, make sure to push all unpushed code on your old computer
to an online remote to avoid losing data.</p>
<h3 id="ntfs-drivers-for-macos">NTFS drivers for macOS<a class="headerlink" href="#ntfs-drivers-for-macos" title="Permanent link">¶</a></h3>
<p>My external hard drive is NTFS-formatted, but macOS cannot write to NTFS drives; it can only read from them.
This was problematic when I was transferring my files from my old laptop (which was also a MacBook)
to my external hard drive. There are 3 options available:</p>
<ul>
<li>Somehow reformat the external drive to FAT32 without losing data.</li>
<li>Install an open-source NTFS driver.
It's hard to make them work and you have to mount/unmount via command-line.</li>
<li>Install a paid NTFS driver, like <a href="https://www.paragon-software.com/home/ntfs-mac/">Paragon</a>.
These work seamlessly, but are either expensive or offer a limited-time trial version.</li>
</ul>
<p>Fortunately, my external hard drive was a Seagate product.
Seagate offers a <a href="https://www.seagate.com/in/en/support/downloads/item/ntfs-driver-for-mac-os-master-dl/">free-of-charge version of Paragon's NTFS driver</a>
which only works on Seagate drives.</p>
<h3 id="install-dropbox-and-use-symlinks">Install Dropbox and use symlinks<a class="headerlink" href="#install-dropbox-and-use-symlinks" title="Permanent link">¶</a></h3>
<p>I installed <a href="https://www.dropbox.com/install">Dropbox's desktop app</a> on my new laptop.
This app creates a directory at <code>~/Dropbox</code> and downloads all your online content into it.
Anything you put in this directory will get synced to your online account.</p>
<p>Dropbox has the limitation that it will only sync files inside <code>~/Dropbox</code>.
If I ever change my mind about what to sync, I'll have to move things in and out of <code>~/Dropbox</code>.
If you're a command-line user, you'll know how annoying it can be to change frequently-used paths.</p>
<p>To solve this problem, I placed all my files outside <code>~/Dropbox</code>
and created <a href="https://kb.iu.edu/d/abbe">symlinks</a> to them which I placed in <code>~/Dropbox</code>.</p>
<p><strong>Edit</strong>: This no longer works, since
<a href="http://www.paulingraham.com/dropbox-and-symlinks.html">Dropbox removed support for using external symlinks</a>.
Now I place my files inside Dropbox and created symlinks to access them from outside <code>~/Dropbox</code>.</p>
<h3 id="wallpapers-and-profile-picture">Wallpapers and profile picture<a class="headerlink" href="#wallpapers-and-profile-picture" title="Permanent link">¶</a></h3>
<p>After transferring files from my external hard drive to my new laptop,
I configured macOS to use my custom wallpapers instead of the system-default ones
and use my profile picture on the lock screen.</p>
<h2 id="customize-vim"><span style="background-color: rgba(255, 0, 0, 0.3)">Customize Vim</span><a class="headerlink" href="#customize-vim" title="Permanent link">¶</a></h2>
<h3 id="install-newer-vim">Install newer Vim<a class="headerlink" href="#install-newer-vim" title="Permanent link">¶</a></h3>
<p>Although macOS comes with <code>vim</code> pre-installed, that version of Vim was compiled without some important features.
You can see which features are installed by running <code>vim --version</code>.</p>
<p>Run <code>brew install vim</code> to install a newer, better Vim.
Alternatively, you can install MacVim (<code>brew install macvim</code>).
This will not replace the old vim; the old vim can still be accessed at <code>/usr/bin/vim</code>.</p>
<h3 id="install-pathogen">Install <a href="https://github.com/tpope/vim-pathogen">Pathogen</a><a class="headerlink" href="#install-pathogen" title="Permanent link">¶</a></h3>
<div class="codehilite"><pre><span></span><code>mkdir -p ~/.vim/autoload ~/.vim/bundle && \
curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim
</code></pre></div>
<p>Add <code>execute pathogen#infect()</code> to your <code>.vimrc</code>.
If you're using <a href="https://github.com/sharmaeklavya2/dotfiles">my dotfiles</a>,
you'll already have it in your <code>.vimrc</code>.</p>
<h3 id="get-vim-plugins">Get Vim plugins<a class="headerlink" href="#get-vim-plugins" title="Permanent link">¶</a></h3>
<p>Just go to <code>~/.vim/bundle</code> and clone the git repositories of the plugins you need.
You can see the list of plugins that I use at
<a href="https://github.com/sharmaeklavya2/dotfiles/blob/master/vimpackages.txt"><code>vimpackages.txt</code></a> in my dotfiles.</p>
<p>If you're using my dotfiles, you can run <code>./scripts/get_vim_packages.py</code>.
This will download the vim plugins from <code>vimpackages.txt</code> and place them in a directory named <code>vim_bundle</code>.
<a href="https://kb.iu.edu/d/abbe">Symlink</a> <code>vim_bundle</code> to <code>~/.vim/bundle</code>.</p>
<h3 id="install-youcompleteme">Install <a href="https://github.com/ycm-core/YouCompleteMe">YouCompleteMe</a><a class="headerlink" href="#install-youcompleteme" title="Permanent link">¶</a></h3>
<p>YouCompleteMe is a vim plugin for code auto-completion.
To install this plugin:</p>
<ul>
<li>Run <code>brew install cmake</code>.</li>
<li><code>cd ~/.vim/bundle ; git clone --recursive https://github.com/ycm-core/YouCompleteMe.git ; cd YouCompleteMe</code>.</li>
<li>If you use a python virtualenv, switch to it and then run <code>./install.py</code>.
If you don't switch to the virtualenv before running <code>./install.py</code>,
python auto-complete may not work for external libraries installed in that virtualenv.</li>
</ul>
<p>You should read <a href="https://github.com/ycm-core/YouCompleteMe">the documentation</a>
for more detailed installation instructions. This is important if you
want good completion for C, C++, Java, Rust, Go or JavaScript
(Python auto-complete works out-of-the-box and I'm okay with rudimentary auto-complete for other languages).</p>
<p>The documentation says that MacVim is required,
but I'm able to use YouCompleteMe with Vim installed via <code>brew install vim</code>.</p>
<h3 id="fix-vim-locale-error">Fix Vim locale error<a class="headerlink" href="#fix-vim-locale-error" title="Permanent link">¶</a></h3>
<p>You may get error messages like this when you start Vim:</p>
<div class="codehilite"><pre><span></span><code>Warning: Failed to set locale category LC_NUMERIC to en_IN.
Warning: Failed to set locale category LC_TIME to en_IN.
Warning: Failed to set locale category LC_COLLATE to en_IN.
Warning: Failed to set locale category LC_MONETARY to en_IN.
Warning: Failed to set locale category LC_MESSAGES to en_IN.
</code></pre></div>
<p>Fix this by adding <code>export LC_ALL=en_US.UTF-8</code> to <code>~/.bash_profile</code> or <code>~/.env</code>
(<a href="https://discourse.brew.sh/t/failed-to-set-locale-category-lc-numeric-to-en-ru/5092">brew forum post</a>).</p>
<h2 id="install-nginx-and-serve-website-mirrors"><span style="background-color: rgba(170, 0, 255, 0.3)">Install Nginx and serve website mirrors</span><a class="headerlink" href="#install-nginx-and-serve-website-mirrors" title="Permanent link">¶</a></h2>
<p>I use <a href="https://nginx.org/en/">Nginx</a> to serve static content.
It's useful to access local websites that I downloaded or created.</p>
<h3 id="install-and-run-nginx">Install and run Nginx<a class="headerlink" href="#install-and-run-nginx" title="Permanent link">¶</a></h3>
<div class="codehilite"><pre><span></span><code>brew install nginx
nginx
</code></pre></div>
<p>Now go to http://localhost:8080. You should see a welcome page from Nginx.</p>
<h3 id="enable-nginx-autoindex">Enable nginx autoindex<a class="headerlink" href="#enable-nginx-autoindex" title="Permanent link">¶</a></h3>
<p>Go to <code>/usr/local/etc/nginx/nginx.conf</code> and
add <code>autoindex on;</code> to '<code>http</code> > <code>server</code> > <code>location /</code>'.
You may also wish to change the port from 8080 to something else by changing the <code>listen</code> value.</p>
<p>Then rename <code>/usr/local/var/www/index.html</code> to <code>/usr/local/var/www/index.html~</code>.</p>
<p>After making these changes, run <code>nginx -s reload</code> for the changes to take effect.</p>
<p>Visit http://localhost:8080 again. Now instead of seeing the welcome page,
you should see the list of files in <code>/usr/local/var/www</code>.</p>
<h3 id="serve-my-websites-with-nginx">Serve my websites with Nginx<a class="headerlink" href="#serve-my-websites-with-nginx" title="Permanent link">¶</a></h3>
<p>I had backed up compressed archives of my websites to my external hard disk.
I copied the websites from there, uncompressed them, and placed them in <code>/usr/local/var/www</code>.</p>
<p>You can put symlinks in <code>/usr/local/var/www</code>, but <code>/usr/local/var/www</code> itself cannot be a symlink.</p>
<h3 id="security">Security<a class="headerlink" href="#security" title="Permanent link">¶</a></h3>
<p>Anyone on your network can see your files in <code>/usr/local/var/www</code>,
so you should be careful about what you put there to preserve your privacy.</p>
<p>You can <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04">set password authentication for Nginx</a>,
but if someone is eavesdropping, they can
<a href="https://en.wikipedia.org/wiki/Basic_access_authentication#Security">easily recover your password</a>.</p>
<p>If you want to prevent others on your network from accessing the http server,
you can restrict Nginx to work on <code>localhost</code> only.
To do this, go to <code>/usr/local/etc/nginx/nginx.conf</code> and
change <code>listen 8080;</code> to <code>listen localhost:8080;</code>.
This is somewhat secure, but not secure against a talented attacker
(see <a href="https://security.stackexchange.com/q/86773">https://security.stackexchange.com/q/86773</a>).</p>Making a keyboard-navigable collapsible without JavaScript2018-11-01T00:00:00+05:302020-09-13T00:00:00+05:30Eklavya Sharmatag:sharmaeklavya2.github.io,2018-11-01:/blog/css-collapsible.html<p>A 'collapsible' is content whose visibility can be toggled by clicking something. However, users without a mouse should also be able to open the collapsed content. This article explains how to make a keyboard-navigable collapsible without using JavaScript.</p><p>A 'collapsible' is content whose visibility can be toggled. Here is an example:</p>
<div class="collapsible" style="clear: both">
<label for="checkbox0" class="collapsor-lbl"> Click me </label>
<div class="focus-capturer" tabindex="0">
<input id="checkbox0" class="collapsor" type="checkbox" />
<div class="collapsible-content">
<p>This is the body of the collapsible. Its visibility can be toggled using the 'click me' button.</p>
<p>Here we will learn how to make such a collapsible without using JavaScript.</p>
</div>
</div>
</div>
<p>In this article, we'll look at how to make one.</p>
<p><strong>Important update</strong>: This article talks about a hacky solution to
make a collapsible without using JavaScript.
I recently (September 2020) found a much simpler, cleaner and semantic solution
using the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details"><code><details></code></a> tag.</p>
<div class="toc"><span class="toctitle">Table of Contents</span><ul>
<li><a href="#skeleton">Skeleton</a></li>
<li><a href="#collapsibility">Collapsibility</a></li>
<li><a href="#accessibility">Accessibility</a></li>
</ul>
</div>
<h2 id="skeleton">Skeleton<a class="headerlink" href="#skeleton" title="Permanent link">¶</a></h2>
<p>Let's first create the basic structure without collapsibility.</p>
<p>HTML:</p>
<div class="codehilite"><pre><span></span><code><span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsible"</span><span class="p">></span>
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsor-lbl"</span><span class="p">></span> Click me <span class="p"></</span><span class="nt">div</span><span class="p">></span>
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsible-content"</span><span class="p">></span>
This is the body of the collapsible.
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
</code></pre></div>
<p>CSS (for beautification):</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">collapsible</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">max-width</span><span class="p">:</span><span class="w"> </span><span class="mi">40</span><span class="kt">em</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">border</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="kt">px</span><span class="w"> </span><span class="kc">solid</span><span class="w"> </span><span class="kc">black</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">border-radius</span><span class="p">:</span><span class="w"> </span><span class="mf">0.5</span><span class="kt">rem</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="p">.</span><span class="nc">collapsor-lbl</span><span class="p">:</span><span class="nd">hover</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">background-color</span><span class="p">:</span><span class="w"> </span><span class="nb">rgba</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mf">0.1</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="p">.</span><span class="nc">collapsor-lbl</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">text-align</span><span class="p">:</span><span class="w"> </span><span class="kc">center</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">padding</span><span class="p">:</span><span class="w"> </span><span class="mf">0.5</span><span class="kt">rem</span><span class="w"> </span><span class="mi">1</span><span class="kt">rem</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="p">.</span><span class="nc">collapsible-content</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">padding</span><span class="p">:</span><span class="w"> </span><span class="mf">0.5</span><span class="kt">rem</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="k">border-top</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="kt">px</span><span class="w"> </span><span class="kc">solid</span><span class="w"> </span><span class="kc">black</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This is what the output looks like:</p>
<div class="collapsible">
<div class="collapsor-lbl"> Click me </div>
<div class="collapsible-content" style="display: block">
This is the body of the collapsible.
</div>
</div>
<h2 id="collapsibility">Collapsibility<a class="headerlink" href="#collapsibility" title="Permanent link">¶</a></h2>
<p>To add collapsibility, we're going to use a checkbox.
I read about it on the blog post
'<a href="https://alligator.io/css/collapsible/">Implementing A Pure CSS Collapsible</a>' by alligator.io.</p>
<ul>
<li>A checkbox maintains state about whether it's checked or not.
We can use that to maintain state about whether our collapsible has been clicked or not.</li>
<li>We can use the CSS style <code>display:none</code> to make the checkbox disappear, but still retain its functionality.</li>
<li>We can use the CSS pseudo-selector <code>:checked</code> to select a checked checkbox.</li>
<li>We will make sure that <code>.collapsible-content</code> is a sibling of the checkbox.
Then we can use the CSS sibling combinator '<code>~</code>' to select it.
When used together with <code>:checked</code> on checkbox, we can select <code>.collapsible-content</code> only when the checkbox is checked.</li>
</ul>
<p>Change the HTML to this:</p>
<div class="codehilite"><pre><span></span><code><span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsible"</span><span class="p">></span>
<span class="p"><</span><span class="nt">input</span> <span class="na">id</span><span class="o">=</span><span class="s">"checkbox1"</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsor"</span> <span class="na">type</span><span class="o">=</span><span class="s">"checkbox"</span> <span class="p">/></span>
<span class="p"><</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">"checkbox1"</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsor-lbl"</span><span class="p">></span> Click me <span class="p"></</span><span class="nt">label</span><span class="p">></span>
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsible-content"</span><span class="p">></span>
This is the body of the collapsible.
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
</code></pre></div>
<p>Add this CSS:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">collapsor-lbl</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">block</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="p">.</span><span class="nc">collapsor</span><span class="o">,</span><span class="w"> </span><span class="p">.</span><span class="nc">collapsible-content</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">none</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="p">.</span><span class="nc">collapsor</span><span class="p">:</span><span class="nd">checked</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="p">.</span><span class="nc">collapsible-content</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">block</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Output:</p>
<div class="collapsible">
<input id="checkbox1" class="collapsor" type="checkbox" />
<label for="checkbox1" class="collapsor-lbl"> Click me </label>
<div class="collapsible-content">
This is the body of the collapsible.
</div>
</div>
<h2 id="accessibility">Accessibility<a class="headerlink" href="#accessibility" title="Permanent link">¶</a></h2>
<blockquote>
<p>Web accessibility is the inclusive practice of ensuring there are no barriers that
prevent interaction with, or access to websites, by people with disabilities.
<footer><a href="https://en.wikipedia.org/wiki/Web_accessibility">Wikipedia article on Web Accessibility</a></footer></p>
</blockquote>
<p>I once had a mouse that sometimes stopped functioning, so I can feel a bit of the pain of users who cannot use a mouse.
Also, some people <em>like</em> using the keyboard for navigation and it would be bad to force them to use a mouse.</p>
<p>I don't know much about web accessibility standards and what it takes for my websites to be fully accessible,
but the least I can do is make my pages keyboard-navigable.</p>
<p>The <a href="https://alligator.io/css/collapsible/#a-note-on-accessibility">blog post by alligator.io</a>
says how to make a collapsible using only CSS, but to make it accessible they had to use JavaScript.
I, however, have a way of doing it without JavaScript.</p>
<p>When navigating a web page using the tab key, certain HTML elements have the potential of receiving focus.
This generally includes links (<code><a></code> tags) and form elements (<code><input></code> tags).
When an element receives focus, it gets the <code>:focus</code> CSS pseudo-class.
Also, that element and all its descendants get the <code>:focus-within</code> class.</p>
<p>We will therefore wrap <code>.collapsible-content</code> within a <code><div></code>.
We will make that <code><div></code> capable of receiving focus via tab by setting the attribute <code>tabindex</code> to <code>"0"</code>.
Then whenever that div has the <code>:focus-within</code> pseudo-class set,
we will set <code>display: block</code> on <code>.collapsible-content</code>.</p>
<p>Change the HTML to this:</p>
<div class="codehilite"><pre><span></span><code><span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsible"</span><span class="p">></span>
<span class="p"><</span><span class="nt">label</span> <span class="na">for</span><span class="o">=</span><span class="s">"checkbox2"</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsor-lbl"</span><span class="p">></span> Click me <span class="p"></</span><span class="nt">label</span><span class="p">></span>
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"focus-capturer"</span> <span class="na">tabindex</span><span class="o">=</span><span class="s">"0"</span><span class="p">></span>
<span class="p"><</span><span class="nt">input</span> <span class="na">id</span><span class="o">=</span><span class="s">"checkbox2"</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsor"</span> <span class="na">type</span><span class="o">=</span><span class="s">"checkbox"</span> <span class="p">/></span>
<span class="p"><</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">"collapsible-content"</span><span class="p">></span>
<span class="p"><</span><span class="nt">p</span><span class="p">></span>This is the body of the collapsible.<span class="p"><</span><span class="nt">p</span><span class="p">></span>
<span class="p"><</span><span class="nt">ul</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">""</span><span class="p">></span>link1<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">""</span><span class="p">></span>link2<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
<span class="p"><</span><span class="nt">li</span><span class="p">><</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">""</span><span class="p">></span>link3<span class="p"></</span><span class="nt">a</span><span class="p">></</span><span class="nt">li</span><span class="p">></span>
<span class="p"></</span><span class="nt">ul</span><span class="p">></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
<span class="p"></</span><span class="nt">div</span><span class="p">></span>
</code></pre></div>
<p>Add this CSS:</p>
<div class="codehilite"><pre><span></span><code><span class="p">.</span><span class="nc">focus-capturer</span><span class="p">:</span><span class="nd">focus-within</span><span class="w"> </span><span class="p">.</span><span class="nc">collapsible-content</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">block</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>Output:</p>
<div class="collapsible">
<label for="checkbox2" class="collapsor-lbl"> Click me </label>
<div class="focus-capturer" tabindex="0">
<input id="checkbox2" class="collapsor" type="checkbox" />
<div class="collapsible-content">
<p>This is the body of the collapsible.</p>
<ul>
<li><a href="">link1</a></li>
<li><a href="">link2</a></li>
<li><a href="">link3</a></li>
</ul>
</div>
</div>
</div>
<p>Try using the tab key to navigate all the 3 links in the collapsible.
When the focus moves out of the collapsible, it closes (unless you had clicked on it to open it).</p>How to juggle 3 balls in 1 hand2017-11-14T00:00:00+05:302017-11-14T00:00:00+05:30Eklavya Sharmatag:sharmaeklavya2.github.io,2017-11-14:/blog/3-in-1.html<p>I discovered a simpler way of learning to juggle 3 balls in 1 hand.</p><p>
<video class="dark-filter" autoplay muted loop width="160" height="240"
src="https://sharmaeklavya2.github.io/blog/img/siteswaps/60.gif.mp4" alt="juggling 3 balls in 1 hand" title="60"></video>
</p>
<p>3 balls in 1 hand, a.k.a. 3-in-1, is definitely not an easy pattern,
mostly because of the speed, accuracy and strength/stamina required to do it.
I could learn to do it because I came up with good prerequisites,
which I will describe in this article.
It still took me a few months to learn it, though, and I still haven't mastered it.</p>
<p>Throughout this tutorial, I'll assume that you want to juggle 3 balls in your right hand.
If you want to juggle with your left hand, just mirror-invert all instructions here.
In all <a href="https://en.wikipedia.org/wiki/Siteswap">siteswaps</a> mentioned here,
the first throw will be from the right hand.</p>
<p>First of all, you should have mastered the 3 ball shower (siteswap <code>51</code>) to almost perfection.
There are 2 mirror-images of the shower.
You must perfect the one where the left hand makes the horizontal pass
(i.e. siteswap <code>51</code>, not <code>15</code>).</p>
<p>Then you must learn to make a type-6 throw.
While juggling <code>51</code>, replace one of the type-5 throws by a type-6 throw.
It'll look similar to <code>6151505151515151</code>.</p>
<figure>
<video class="dark-filter" autoplay muted loop width="160" height="240"
src="https://sharmaeklavya2.github.io/blog/img/siteswaps/6151505151515151.gif.mp4"
alt="juggling 51 with occasional type-6 throws"></video>
<figcaption>6151505151515151</figcaption>
</figure>
<p>Practice this until you find it easy to replace a type-5 throw by a type-6 throw.</p>
<p>Now practice <code>615150</code>, then <code>6051</code> and then <code>606150</code>.</p>
<div class="gallery">
<figure>
<video class="dark-filter" autoplay muted loop width="160" height="240"
src="https://sharmaeklavya2.github.io/blog/img/siteswaps/615150.gif.mp4" alt="pattern 615150"></video>
<figcaption>615150</figcaption>
</figure>
<figure>
<video class="dark-filter" autoplay muted loop width="160" height="240"
src="https://sharmaeklavya2.github.io/blog/img/siteswaps/6051.gif.mp4" alt="pattern 6051"></video>
<figcaption>6051</figcaption>
</figure>
<figure>
<video class="dark-filter" autoplay muted loop width="160" height="240"
src="https://sharmaeklavya2.github.io/blog/img/siteswaps/606150.gif.mp4" alt="pattern 606150"></video>
<figcaption>606150</figcaption>
</figure>
</div>
<p>You may also want to try out other variations.
After you get good at these, you can finally try 3-in-1.</p>
<p>You may also like this <a href="https://www.youtube.com/watch?v=z2k3ugex7Kw">video tutorial by Chris Taibbi</a>.</p>