screenshot of the jpegoptim help page

List of random snippets

The following is a random list of things I sometimes need and always forget. So I decided to write them down for quick reference.
The non-browser/web ones of these are based on Ubuntu, but they should work pretty much simular on any linux system.
I think I may need to start categorising them...for now it is just this list.

- Run a specific Drupal cron task -

Sometimes, while developing, it can be very usefull to be able to run just a single crontask instead of a complete cron run.
To do this we can use:

1
drush php-eval '[MY_MODULE]_cron();'
Where [MY_MODULE] is of course the name of your module.

- Easily re-use your terminal commands -

Add these lines to your ~/.inputrc (create the file if it doesn't exist):

1
2
"\e[A": history-search-backward
"\e[B": history-search-forward

To load the file, run

1
bind -f ~/.inputrc
or restart your terminal (or logout/in).

Now if you start typing the first few characters of the command you want to execute - like: "wget" and then you use your up arrow you will browse exclusively through your history of wget-commands (instead of all other commands used in the meantime). Superhandy!

- Using emoji's -

To use emoji's or special characters you can always look for your desired character and copy / paste it. This will work fine. (provided the correct text-encoding, usually UTF-8, is set)

Another method is using the numerical representation - or codepoints.
These look something like this:
U+1F354
The "1F354" is the actual number. The "U+" needs to be replaced with something else. What that is depends on the context in which you wish to use it.
in html replace it with: "&#x" so it looks like 🍔 (you need to add a semi-column ; at the end too)
in css: "\0" so use it like: content: "\01F354";
in javascript: "0x" use it like: document.body.innerText = String.fromCodePoint(0x1F354);

- Use Grep to find a specific string within multiple files -

If for some reason (like e.g. replace a url) you need to find a specific word or phrase within multiple files, grep can be used. the following command will return a list of matches:

1
grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -r or -R is recursive,
  • -n is line number, and
  • -w stands for match the whole word.
  • -l can be added to just return the file name of matching files.

Since this will potentially return a lot of text it is very usefull to just write the results to a text-file.

1
grep -rnw './' -e 'www.example.com' >> files_with_example_url.txt

It will look something like this

1
2
./index.html:949:  Onze advocaten zijn specialisten. In het zoekscherm links op deze pagina vindt u snel een advocaat bij u in de buurt. Wilt u een <strong>gratis eerste advies</strong>? Maak dan gebruik van ons gratis&nbsp;<a href="http://www.example.com/default.asp"><strong>example</strong></a>. Geheel vrijblijvend.&nbsp; &nbsp;</p>
./index.html:969:  Onze advocaten zijn specialisten. Ze helpen u graag! <a href="http://www.example.com/default.asp"><strong>example</strong></a>. Geheel vrijblijvend.&nbsp; &nbsp;</p>

- Wget: Mirroring a site for offline usage or archiving

There are good reasons to decide to turn your cms-driven site into a bunch of static html-pages. It speeds up the page load, it is safe, it is maintenance-free and often a lot smaller too.

There are several methods to do this effectively. The best two options are using Httrack or using Wget. Although Httrack may be more advanced I prefer using Wget --mirror. It is very simpel and fast! This works best with some additional flags.
--adjust-extension and --convert-links work together. --adjust-extension changes the file extensions (like .php or .asp etc.) to .html .
--convert-links changes any links found in the files to the new filenames created by wget.
The --restrict-file-names=windows turn the query questionmark into an @-symbol. This helps making the files work offline (without any server).

So the final command looks like this:

1
2
wget --mirror --recursive --convert-links --adjust-extension --page-requisites --span-hosts --domains example.com --restrict-file-names=windows https://www.example.com/
 

It is good to realise that some things still require manual work. Forms for example won't work, search driven pages will not display correctly. Those things need to be dealt with seperately.

- Drupal console: Export the configuration for an entity

The following command will get you yml files inside your module config/install directory.

1
drupal config:export:entity [arguments] [options]

for example:

1
drupal config:export:entity node_type page --module="demo" --optional-config --remove-uuid  --remove-config-hash

Notice the "--optional-config" flag! This will put the files inside of the optional directory instead of install. This will make it a soft requirement and it will be installed only when all dependencies are met, else it will simply install the module without it.

More tips and tricks here: https://drupalconsole.com/docs/en/commands/config-export-entity/

- Cutting up an images in equal parts.

This requires imagemagick.

Split it into 5 equal parts (maintaining original height)

1
convert image.png -crop 1x5@ cropped_%d.png

or split into specific sizes, leaving whatever is leftover as the last image.

1
convert -crop 100%x200 image.png cropped_%d.png

For more advanced stuff see this example: https://stackoverflow.com/questions/23888287/split-image-into-parts/24579271

- Resizing images in bulk.

This requires imagemagick.
resize images recusively with a max width of 1200px (in this example)

1
find . -iname \*.jpg -exec convert -verbose -quality 100 -resize x1200\> "{}" "{}" \;

This requires jpegoptim.
Optimise images recusively
optimise to 80% quality & 75% filessize & save them in './folder'

1
jpegoptim -m 80 -v --size=75% -t -d folder *.jpg

- Get all images from a domain into the current directory.

1
wget -nd -H -r -P ./ -A jpeg,jpg,bmp,gif,png https://www.example.com -e robots=off

  • -nd prevents the creation of a directory hierarchy (i.e. no directories).
  • -H: span hosts (wget doesn't download files from different domains or subdomains by default)
  • -r enables recursive retrieval. See Recursive Download for more information.
  • -P sets the directory prefix where all files and directories are saved to.
  • -A sets a whitelist for retrieving only certain file types.
see more: http://www.gnu.org/software/wget/manual/wget.html#Types-of-Files

- Render .png's from .pdf pages

In the poppler-utils packages there is the utility pdftoppm capable of converting pages from a pdf file to ppm, png or jpeg format:

1
pdftoppm -png file.pdf prefix
will produce prefix-01.png etc. for each page. By default the resolution is 150dpi.
Increase the resolution (for higher quality output) as follows:
1
pdftoppm -rx 300 -ry 300 -png file.pdf prefix
To print only one page, use
1
pdftoppm -f N -singlefile -png file.pdf prefix
where N is the page number, beginning with 1.


- Extract original images from a PDF

Another thing that can be very usefull is the abillty to extract all the original images used in the PDF and save them as PNG.

First extract them. They will be named and numbered, e.g: myimages-000, myimages-001. You can ofcourse name them anything you want.

1
pdfimages original.pdf ./myimages
This will get you a bunch of .ppm-files. You can convert those to png with:
1
mogrify -format png ./myimages*.ppm
and finally to remove the ppm-files use:
1
rm ./myimages*.ppm

- Copy files from local to remote, using scp

I am always confused when wanting to use scp. What was it again? Local - Remote? Remote - Local? Both are possible, depending on what you want to do. Basically it comes down to this:

1
scp <source> <destination>
Your source can be either the remote server or your local computer and vice versa.

EXAMPLE:
copy a local dir called 'archive' to a remote servers public folder.
1
scp -rp -P 1902 ./archive/ you@remote-server-ip:/var/www/htdocs/files
-r = recursive -p = preserve system metadata -P = provide portnumber 1902 = portnumber user@ip = username on the remote server (either by name or ip) :path/to/dir
see more variations on UNIX stackexchange.

- Recursively operate on all directories or files (in a specific directory)

To recursively give directories read&execute privileges:

1
find /path/to/base/dir -type d -exec chmod 755 {} +
To recursively give files read privileges:
1
find /path/to/base/dir -type f -exec chmod 644 {} +

- Sass: Background-image with retina mixin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@mixin background-image-retina($file, $type, $width, $height) {
  background-image: url($file + '.' + $type);
 
  @media (-webkit-min-device-pixel-ratio: 2), (-moz-min-device-pixel-ratio: 2) {
    & {
      background-image: url($file + '@2x.' + $type);
      -webkit-background-size: $width $height;
    }
  }
  /*this could be extended with other ratios* */
}
 
/* Example */
#foo {
  @include background-image-retina('foobar', 'png', 10px, 20px);
}

*see: screensiz.es for details on many different devices.

- CSS: Attribute selector

The attribute selector is any attribute that’s inside of an HTML element

1
2
3
4
5
6
7
8
9
10
11
a[href]{}                            /*all links with an hyperlink reference*/
a[name] {}                           /*all named links*/
a[href^="http"]{}                    /*all links that <em>start with (^)</em> 'http'*/
a[href^="#"]{}                       /*all anchor-links*/
a[href$=".pdf"]{}                    /*all links that <em>end with ($)</em> a specific filetype*/
div[class]{...}                      /*all divs with *any* class*/
img[src^="/images"]{}                /*all images from a specific source*/
img[alt~="word"]{}                   /*all image with the word "word" in the alt. The ~ is a whitespace selector*/
img[src|="-hyphened"]{}              /*all images with "-hyphened" in their src. The | is a hyphen selector.*/
[class*="partial"]{}                 /*any element with the word "partial" in its class: p.partial1, h3.partial-12*/
div[style*="border-color: red"]{}    /*any div with an <em>inline style</em> of border-color:red*/

see: this blog

- AudioSprite | Howler: Create an audio sprite

An audio sprite is, like an imagesprite, a single file with multiple sources combined, seperated by some 'whitespace'.
In this case 1 second of silence. It is usefull for working with audio in webprojects.
This example is based on Howler.js but it is pretty simular for other libraries like Lime.js or create.js This requires this audiosprite script.

1
audiosprite --output soundfx --format howler -c 2 *.mp3

- Markup Quotes

screenshot quote
Quotes :before and :after

A simple and little known way to markup quotes.

1
2
3
blockquote { quotes: '\201c' '\201d'; }
blockquote:before { content: open-quote; }
blockquote:after  { content: close-quote; }

The \201c here is Unicode for a left curly double quote. You could also simply write the double quotes directly in the rule for blockquote:

1
blockquote { quotes: '“' '”'}

open-quote and close-quote are special values for the content property, which refer to the strings given as values for the quotes property.
The nicest thing is: this can be set for any element. So you can easily set different quotes symbols per context (like a different language or another type of page).

- Sublime select specific elements with regex

screenshot regex search
Find variable phrases between fixed strings

Using the following regex it is possible to manipulate many recurring strings with slight differences (like urls for example).

1
([\w\W]+?)

Anything before and after this expression are constants in the strings you want to select, wrapped around anything that is not simular in those strings.
So this makes it very usefull for selecting things like ids or names, making it easy to change the markup or copy only specific parts of your file (like all image-urls in a document for example).

This would select any href

1
href="([\w\W]+?)"
or a url:
1
(http)([\w\W]+?)(?=")
1
(http)(.+?)(?=")

- Google query manipulators

Within google you can use specific terms and symbols to limit or extend your query.

  • " ""find this entire string"
  • -find this but -not -this
  • ORfind this OR this
  • intext:any of these within the pagetext
  • allintext:all these words (somewhere) within pagetext
  • allintitle:all words within pagetitle
  • allinurl:all words within pageurl
  • site:nu.nl "this phrase on nu.nl"
  • related:nu.nl simular sites to nu.nl
  • location:Rotterdam
  • filetype:Rotterdam
  • ~simular
  • *wildcard

- Change what a key does (Ubuntu)

My key for <\tab> has been used too many times!. It broke. This is really annoying!

Luckily it is quite easy to asign another key to work as <\tab>. Here is how:

run

1
xev
on a command line and find the keycode for the key (UK its keycode 49) then run
1
xmodmap -e "keycode 49 = Tab"
replacing the keycode from xev when you press that key. You should now have a remapped key !

to save these you need to run

1
xmodmap -pke >~/.Xmodmap
update you need a modifier too
1
xmodmap -e "keycode 49 = Tab asciitilde"
should work