2 changed files with 124 additions and 25 deletions
@ -1,26 +1,118 @@
|
||||
#!/bin/bash |
||||
|
||||
# Usage examples: |
||||
# ./cat-md file1.txt file2.txt # Output multiple files as markdown |
||||
# ./cat-md directory/ # Output all files in a directory |
||||
# ./cat-md file.txt | xclip -selection clipboard # Copy output to X11 clipboard |
||||
# ./cat-md file.txt | xsel --clipboard --input # Alternative using xsel |
||||
|
||||
for path in "$@"; do |
||||
if [ -d "$path" ]; then |
||||
# If it's a directory, call ourselves with each file in it (non-recursively) |
||||
for file in "$path"/*; do |
||||
if [ -f "$file" ]; then |
||||
"$0" "$file" |
||||
fi |
||||
done |
||||
elif [ -f "$path" ]; then |
||||
# If it's a file, output the path and content |
||||
echo "$path:" |
||||
echo '```' |
||||
cat "$path" |
||||
echo |
||||
echo '```' |
||||
echo |
||||
fi |
||||
set -euo pipefail |
||||
|
||||
# --- Defaults --- |
||||
COPY=true |
||||
CLIP_CMD="" |
||||
|
||||
# --- Detect clipboard tool --- |
||||
detect_clipboard() { |
||||
if command -v xclip &> /dev/null; then |
||||
CLIP_CMD="xclip -selection clipboard" |
||||
elif command -v xsel &> /dev/null; then |
||||
CLIP_CMD="xsel --clipboard --input" |
||||
else |
||||
CLIP_CMD="" |
||||
fi |
||||
} |
||||
|
||||
# --- Help --- |
||||
usage() { |
||||
cat << 'EOF' |
||||
cat-md — concatenate files as a Markdown code block, copy to clipboard. |
||||
|
||||
Usage: |
||||
cat-md [OPTIONS] [FILE|DIR]... |
||||
|
||||
Each file is printed as: |
||||
path/to/file: |
||||
`` ` |
||||
<contents> |
||||
`` ` |
||||
|
||||
Directories are expanded non-recursively (all files inside). |
||||
|
||||
Options: |
||||
-n, --no-copy Print to stdout only, skip clipboard copy |
||||
-h, --help Show this help and exit |
||||
|
||||
Examples: |
||||
cat-md file1.txt file2.txt |
||||
cat-md src/ |
||||
cat-md -n file.txt # no clipboard |
||||
cat-md file.txt | wl-copy # Wayland clipboard (manual override) |
||||
|
||||
Requirements (one of): |
||||
xclip — X11 clipboard (preferred) |
||||
xsel — alternative X11 clipboard tool |
||||
EOF |
||||
exit 0 |
||||
} |
||||
|
||||
# --- Parse arguments --- |
||||
ARGS=() |
||||
while [[ $# -gt 0 ]]; do |
||||
case "$1" in |
||||
-n | --no-copy) |
||||
COPY=false |
||||
shift |
||||
;; |
||||
-h | --help) usage ;; |
||||
--) |
||||
shift |
||||
ARGS+=("$@") |
||||
break |
||||
;; |
||||
-*) |
||||
echo "Unknown option: $1" >&2 |
||||
echo "Try -h for help." >&2 |
||||
exit 1 |
||||
;; |
||||
*) |
||||
ARGS+=("$1") |
||||
shift |
||||
;; |
||||
esac |
||||
done |
||||
|
||||
# --- Validate --- |
||||
if [[ ${#ARGS[@]} -eq 0 ]]; then |
||||
echo "Error: no files or directories provided. Try -h for help." >&2 |
||||
exit 1 |
||||
fi |
||||
|
||||
detect_clipboard |
||||
|
||||
if $COPY && [[ -z "$CLIP_CMD" ]]; then |
||||
echo "Warning: neither xclip nor xsel found. Output will go to stdout only." >&2 |
||||
COPY=false |
||||
fi |
||||
|
||||
# --- Generate output --- |
||||
generate() { |
||||
for path in "$@"; do |
||||
if [[ -d "$path" ]]; then |
||||
for file in "$path"/*; do |
||||
if [[ -f "$file" ]]; then |
||||
generate "$file" |
||||
fi |
||||
done |
||||
elif [[ -f "$path" ]]; then |
||||
echo "$path:" |
||||
echo '```' |
||||
cat "$path" |
||||
echo |
||||
echo '```' |
||||
echo |
||||
fi |
||||
done |
||||
} |
||||
|
||||
if $COPY; then |
||||
generate "${ARGS[@]}" | $CLIP_CMD |
||||
echo "Copied to clipboard." >&2 |
||||
else |
||||
generate "${ARGS[@]}" |
||||
fi |
||||
|
||||
|
||||
Loading…
Reference in new issue