marc walter

Using Prism with marked for static syntax highlighting

2017-09-27

This content is built from markdown files to static html. Syntax highlighting for code snippets is also generated during this step. It is very easy to add syntax-highlighting only in the browser, but I wanted to remove the necessary JavaScript dependencies from the HTML code and the additional rendering effort for the browser.

Example

let ab = { cde: 1, fg: 'h' }
console.log(`Variable ab = ${ab}`)

// comment
ab.i = 17
read more

CSS styles in elm-reactor and pretty check boxes

2017-08-16 (Last updated on 2018-09-01)

Elm-reactor is a great tool to get started in elm.
It supports a time-traveling debugger, downloads the necessary packages and is generally nice to work with.

A problem though is that for styling you usually need to write inline-styles. This is sometimes fine, but if I want to concentrate on the elm code and add separate styles I usually pick another tool like create-elm-app.

But it is possible to add a style tag to the main view function and the css styles are applied to the document.
After the initial exploration, I can move the styles to a dedicated file.

If this iframe is not displayed, open [the file directly](./choose.min.html).

This uses checkboxes I adapted from a really nice example by @valerypatorius on codepen.

The trick

Render a style node and specify the content as a multiline string.

module Main exposing (main)

import Html exposing (Html, div, h1, text)
import Html.Attributes exposing (class)

main =
    div []
        [ Html.node "style" [] [ text css ]
        , h1 [] [ text "Example" ]
        ]

css =
    """/* injected css */
html {
    background-color: #f0c;
    color: #fff!important;
}
"""

code

read more

Feedback form with mail in PHP

2017-06-03

A simple form that I used to receive feedback from people on a web page. The web app uses JavaScript and only works on current browsers. I receive feedback if JavaScript is executed in the user's browser and the UserAgent of the browser (browser and operating system name and version).

This snippet only needs one file to both display the form and to receive the information.
Also needed is a configured mail server to send this information to me and the user (if she wishes it).

read more

How to configure a visual diff or merge tool in git on Windows

2016-10-15

Resolving merge conflicts can get confusing very fast, a nice GUI tool to facilitate this job is meld. It supports three-way file comparison to see the two different code versions and the currently merged file in the middle.

meld three-way file comparision
Image source http://meldmerge.org/features.html

To resolve the merge conflict with meld using the git-mergetool like this

git mergetool -y <filename>

Only a small change to the ~/.gitconfig file is needed.

On Windows, open %userprofile%\.gitconfig and then configure meld as diff and merge tool like this:

[diff]
    tool = meld
[difftool "meld"]
    cmd = \"C:\\Program Files (x86)\\Meld\\Meld.exe\" $LOCAL $REMOTE
[merge]
    tool = meld
[mergetool "meld"]
    cmd = \"C:\\Program Files (x86)\\Meld\\Meld.exe\" $PWD/$LOCAL $PWD/$BASE $PWD/$REMOTE --output=$PWD/$MERGED

For a little more information on the variables used, look at this stackoverlow comment.

Require a local node.js module from an unknown parent folder

2016-07-18

Require code somewhere upwards in the file tree without knowing the specific number of parent folders needed.
The tree is traversed synchronously.
Code is available on github.

Motivation/Usage

Instead of writing code like this:

try {
  var abc = require('./abc.js');
} catch (ex) {
  try {
    abc = require('../../abc.js');
  } catch (err) {
    abc = require('../../../abc.js');
  }
}

I rather want to write something like this:

var requireUp = require('require-upwards');
var abc = requireUp('abc.js');

Limiting the number of checked folders

Version 1.1 adds an optional parameter to limit the maximum number of iterations.

Given this folder structure:

fixtures
 ├─fix.js
 └─11
   ├─a.js
   └─baum

When starting from the folder fixtures/11/baum

requireUp('fix.js', 1)
# will throw an Error
requireUp('fix.js', 2)
# will return the content of fixtures/fix.js

Tests

Unit tests are located in the folder ./test. To run them, execute

npm run test --silent

Useful npm scripts and snippets

2016-04-17

Execute mocha tests without installing mocha globally

Works both on Windows and Mac
Add to package.json: (Info: Also forces mocha to print the full stack trace when errors occur).

[...]
"scripts": {
  "test": "node ./node_modules/mocha/bin/_mocha --full-trace test"
},
[...]

Then execute npm test on the command line to run all tests from the test folder.

Run istanbul code coverage and mocha tests without installing either globally

Works both on Windows and Mac
Add to package.json: (Info: Also sets the folder for the report)

[...]
"scripts": {
  "cover": "node node_modules/istanbul/lib/cli.js cover --dir test_coverage node_modules/mocha/bin/_mocha test"
},
[...]

Then execute npm run cover on the command line to generate the reports.

Get a list of globally installed packages

E.g. useful when switching between node.js versions

npm list -g --depth=0

Example output:

> npm list -g --depth=0
C:\Program Files\nodejs
+-- eslint-cli@1.1.0
+-- grunt@1.0.1
+-- gulp@3.9.1
+-- istanbul@0.4.3
+-- mocha@2.4.5
+-- nodemon@1.9.2
+-- npm@3.8.6
`-- webpack@1.13.0

Using Bitmasks in JavaScript

2016-03-05

Bitmasks are useful (e.g. for State Machines) and also usable in JavaScript.

Attention: The maximum value for the mask in JS is 2^31-1 (maximum value of int in JS).

Initial usage

No enums available, so use an object instead to create a Bitmask:

var States = {
    HINT: 1,
    NOTICE: 2,
    WARNING: 4,
    ERROR: 8,
    FATAL: 16
};

And use it like this:

var a = States.NOTICE;

a & States.HINT // returns 0

a & States.NOTICE // returns 2 (States.NOTICE)

Checking values against the mask

Two ways of checking the mask:

if ((a & States.NOTICE) === States.NOTICE) console.log(true);

if (a & States.NOTICE) console.log(true);

As long as the value 0 is not part of the Bitmask, the second way works as expected.

read more

Show notifications from scripts in node.js

2016-01-03

So that I never forget when I need it: The module node-notifier can be used to display desktop notifications on windows_, _mac and linux with notify-osd or libnotify-bin.

Example

Straight from the official doc.

const notifier = require('node-notifier');
// String 
notifier.notify('Title', 'Message');

// Object 
notifier.notify({
  'title': 'My notification',
  'message': 'Hello, there!'
});

Another example

From file notify-sample.js adapted from the official doc.

const notifier = require('node-notifier');
const path = require('path');

let options = {
  title: 'Wake up',
  message: "It's time!",
  icon: path.join(__dirname, 'emilia.jpg'), // Absolute path (doesn't work on balloons)
  sound: true, // Only Notification Center or Windows Toasters
}

notifier.notify(options)

What the notification looks like

on win10

read more

Generating a checksum over files or folders in node.js

2015-11-05

I needed a node.js module that generates hashes over files and folders. It should only create a hash over the text content and not over the file properties.

Further Requirements:

  • Return the same hash if the content is the same (do not check for file attributes)
  • Generate a hash over a folder structure
    • Generate the hash over a folder structure using only one loop
  • Support both promises and error-first callbacks
  • unit tests that document the behavior and not only that it does not crash

Entry folder-hash

Description

Create a hash checksum over a folder or a file.
The hashes are propagated upwards, the hash that is returned for a folder is generated over all the hashes of its children.
The hashes are generated with the sha1 algorithm and returned in base64 encoding.

The returned information looks like this:

{ name: 'test', 
  hash: 'qmUXLCsTQGOEF6p0w9V78MC7sJI=',
  children: [
    { name: 'helper', 
      hash: 'x1CX3yVH3UuLTw7zcSitSs/PbGE=',
      children: [
        { name: 'helper.js', hash: 'pHYwd8k/oZV01oABTz9MC8KovkU=' }
      ] },
    { name: 'test.js', hash: 'L/vqpdQhxmD5w62k24m4TuZJ1PM=' }
  ] 
}

Each file returns a name and a hash, and each folder returns additionally an array of children (file or folder elements).

Usage

With promises

var hasher = require('folder-hash');
// e.g. pass element path directly
hasher.hashElement(__dirname).then(function (hash) {
  console.log('Result for folder "' + __dirname + '":');
  console.log(hash.toString());
});

With callbacks

var hasher = require('folder-hash');
// e.g. pass element name and folder path separately
hasher.hashElement('node_modules', __dirname, function (error, hash)) {
  if (error) return console.error('hashing failed:', error);
  console.log('Result for folder "node_modules" in directory "' + __dirname + '":');
  console.log(hash.toString());
});

Behavior

The module meets all of my requirements. The further behavior is documented and verified in the unit tests. Execute npm test or mocha test, and have a look at the test subfolder.

Code

Available on github

Copy folders that contain files with specific extensions

2015-10-15

Recently I used a tool to re-tag and move my music library. This left me a neatly organized music library and also with a music folder that contained a lot of folders that only contained e.g. the album cover (in various formats). But some songs were not picked up by the auto-tagging mechanism, so some music files still persisted in that folder.

That is why I created a script that traverses the folder structure and copies all folders that (directly) contain at least one file out of a list of desired file types (e.g. '.mp3').

Situation

If I would run the script on this folder:

C:\tagged
├─Der dicke Polizist
│ └─und die Hoffnung stirbt zuletzt!
│    folder.jpg
└─ZSK
  ├─[2004] From Protest to Resistance
  │ ├─ folder.jpg
  │ └─ Kein Mensch ist illegal.mp3
  └─[2015] Herz für die Sache
      folder.jpg

I would expect this outcome:

C:\contains_music\tagged
└─ZSK
  └─[2004] From Protest to Resistance
    ├─ folder.jpg
    └─ Kein Mensch ist illegal.mp3

Solution

Criteria

  1. Each album that still contains music should be copied.
  2. But if an album contains no more music should not be copied.
  3. If an artist's folder does not contain any music (also not in subdirectories), it should not be copied

Reasoning

Write a recursive function that walks the directory tree and copies a folder if it contains at least one file with one of the desired file extensions.
If it does not contain any of those files, don't copy it - this will also suffice for criteria 3.

read more