#!/usr/bin/env bash set -euo pipefail if (( $# < 2 )); then echo "Usage: $0 [pattern2 ...]" >&2 echo "Example: $0 . '*.lua' '*.vim' '*.py'" >&2 exit 1 fi root=$1 shift if [[ ! -d "$root" ]]; then echo "Error: not a directory: $root" >&2 exit 1 fi get_lang() { local file=$1 local base ext base=$(basename -- "$file") ext=${base##*.} # no extension if [[ "$base" == "$ext" ]]; then printf '' return fi case "${ext,,}" in sh|bash) printf 'bash' ;; zsh) printf 'zsh' ;; fish) printf 'fish' ;; ps1) printf 'powershell' ;; bat|cmd) printf 'bat' ;; js|mjs|cjs) printf 'javascript' ;; ts|mts|cts) printf 'typescript' ;; jsx) printf 'jsx' ;; tsx) printf 'tsx' ;; py) printf 'python' ;; rb) printf 'ruby' ;; php) printf 'php' ;; pl) printf 'perl' ;; lua) printf 'lua' ;; vim) printf 'vim' ;; c) printf 'c' ;; h) printf 'c' ;; cpp|cc|cxx|hpp|hh|hxx) printf 'cpp' ;; cs) printf 'csharp' ;; java) printf 'java' ;; kt|kts) printf 'kotlin' ;; go) printf 'go' ;; rs) printf 'rust' ;; swift) printf 'swift' ;; sql) printf 'sql' ;; xml) printf 'xml' ;; html|htm) printf 'html' ;; css) printf 'css' ;; scss) printf 'scss' ;; json) printf 'json' ;; yaml|yml) printf 'yaml' ;; toml) printf 'toml' ;; ini|cfg) printf 'ini' ;; conf) printf 'conf' ;; md) printf 'markdown' ;; tex) printf 'tex' ;; dockerfile) printf 'dockerfile' ;; *) printf '%s' "${ext,,}" ;; esac } find_args=( "$root" -type f '(' ) first=1 for pattern in "$@"; do if (( first )); then first=0 else find_args+=( -o ) fi find_args+=( -name "$pattern" ) done find_args+=( ')' -print0 ) find "${find_args[@]}" | while IFS= read -r -d '' file; do lang=$(get_lang "$file") printf '### %s\n' "$file" printf '```%s\n' "$lang" cat -- "$file" if [[ -s "$file" && $(tail -c1 -- "$file" | wc -l) -eq 0 ]]; then printf '\n' fi printf '```\n\n' done