DEV Community

Diego Carrasco Gubernatis
Diego Carrasco Gubernatis

Posted on • Originally published at diegocarrasco.com on

How to manage multiple AsciiDoc Chapter Files: Copy, Merge, and Customize

TL;DR

Manage multiple AsciiDoc chapter files efficiently with a customizable bash script that supports copying and merging chapters in different languages. This script allows you to concatenate, copy, or merge chapter files with flexible options for language codes, prefixes, output destinations and with recursive file search.

Context

I work a lot with AsciiDoc files. I write documentation, books and even part of this site with it. Sometimes I need to merge some files or copy their content to a new file. This is the case with the new novel I'm writing.

Because of reasons, I decided to write it in 3 languages in parallel: spanish, german and english.

I use include::file.adoc[] to manage multiple files and merge them into a final version. This way I can write each chapter in each language in different files, and then include them in a final file as follows:

= title of the book
:author: Diego Carrasco
// here comes more metadata and config stuff.

include::chapter_00.adoc[]

include::chapter_01.adoc[]

include::chapter_02.adoc[]

include::chapter_03.adoc[]

Enter fullscreen mode Exit fullscreen mode

I'm already by chapter 15, which means I have 45 files plus the main ones. (15 files per language).

Again, because of reasons, I needed to copy the content of all the chapter from a specific language to my clipboard - or at least to a new file.

To streamline this, I made a bash script that helps me automate the process of concatenating, merging, or copying chapter files. This script is designed to handle these tasks while providing support for different languages, prefixes, and output formats.

As I tend to forget these stuff, I make a note here.

NOTE: This script does actually work on any kind of text file, just change the prefix 😁

Steps

1. The Bash Script

Create a new file manage_chapters.sh and paste the following:

DISCLAIMER: I am in no way responsible for any damage to your files. This script is provided as is. Always read the script before using it.

#!/bin/bash

usage() {
echo "Usage: $0 [-c xx] [-l yy] [-p prefix] [-o output\_file] [-r]"
echo " -c xx : Specify chapter numbers (e.g., '01 02 03' or '\*' for all)"
echo " -l yy : Specify language code (e.g., 'es' for Spanish)"
echo " -p prefix : Specify file prefix (default: 'chapter\_')"
echo " -o output\_file : Merge into a file instead of copying to clipboard"
echo " -r : Search recursively in subdirectories"
exit 1
}

chapters=""
language=""
prefix="chapter\_"
output\_file=""
recursive=""

while getopts "c:l:p:o:r" opt; do
case $opt in
c) chapters="$OPTARG" ;;
l) language="$OPTARG" ;;
p) prefix="$OPTARG" ;;
o) output\_file="$OPTARG" ;;
r) recursive="-r" ;;
*) usage ;;
esac
done

if [-z "$chapters"]; then
usage
fi

if ["$chapters" = "\*"]; then
pattern="${prefix}\*.adoc"
else
pattern="${prefix}@(${chapters// /|}).adoc"
fi

if [-n "$language"]; then
pattern="${pattern%.adoc}.${language}.adoc"
fi

if [-n "$recursive"]; then
find\_cmd="find . -type f -name"
else
find\_cmd="find . -maxdepth 1 -type f -name"
fi

content=$(eval "$find\_cmd \"$pattern\"" | sort | xargs cat)

if [-z "$content"]; then
echo "No matching files found."
exit 1
fi

if [-n "$output\_file"]; then
echo "$content" > "$output\_file"
echo "All matching chapter contents merged into '$output\_file'"
else
# Check if xclip is available (Linux)
if command -v xclip &> /dev/null; then
echo "$content" | xclip -selection clipboard
echo "All matching chapter contents copied to clipboard as a single text using xclip."
# Check if pbcopy is available (macOS)
elif command -v pbcopy &> /dev/null; then
echo "$content" | pbcopy
echo "All matching chapter contents copied to clipboard as a single text using pbcopy."
else
echo "No clipboard utility found. Please install xclip (Linux) or use pbcopy (macOS)."
exit 1
fi
fi

Enter fullscreen mode Exit fullscreen mode

2. How It Works

  • Command-line options : You can specify chapters (-c), a language code (-l), a custom file prefix (-p), and an output file (-o).
  • Pattern construction : The script dynamically generates a filename pattern based on the options provided.
  • Finding matching files : It uses the find command to locate all matching files within the current directory.
  • File concatenation : The xargs cat command is used to concatenate the contents of the found files into one string.
  • Clipboard support : If no output file is provided, the script copies the concatenated content to the clipboard using either xclip (Linux) or pbcopy (macOS).
  • Option -r to enable recursive searching.

3. Usage Examples

Here are a few example scenarios where this script can be helpful:

Example 1: Copy all chapters to clipboard (default behavior)
./manage_chapters.sh -c "\*"

Enter fullscreen mode Exit fullscreen mode
Example 2: Merge specific chapters into a file
./manage_chapters.sh -c "01 02 03" -o merged_chapters.adoc

Enter fullscreen mode Exit fullscreen mode
Example 3: Copy chapters with a different prefix
./manage_chapters.sh -c "\*" -p "section\_"

Enter fullscreen mode Exit fullscreen mode
Example 4: Merge language-specific chapters into a file
./manage_chapters.sh -c "\*" -l es -o spanish_chapters.adoc

Enter fullscreen mode Exit fullscreen mode
Example 5: Copy chapters with a custom prefix and specific language
./manage_chapters.sh -c "01 02" -p "part\_" -l de

Enter fullscreen mode Exit fullscreen mode
Example 6: Recursive search in all subdirectories:
./manage_chapters.sh -c "\*" -r

Enter fullscreen mode Exit fullscreen mode
Example 7: Recursive search for specific chapters and language
./manage_chapters.sh -c "01 02" -l es -r

Enter fullscreen mode Exit fullscreen mode

Key Features

  • Flexible Chapter Selection : Select specific chapters or use wildcards to include all.
  • Language Support : Handle different language versions of chapters easily by specifying the language code.
  • Customizable File Prefix : The ability to change file prefixes allows the script to adapt to different project structures or naming conventions.
  • Clipboard or File Output : Depending on your needs, choose to merge chapters into a file or copy the concatenated content directly to the clipboard.

I hope this helps you in your AsciiDoc adventures :)

Top comments (0)