Skip to main content
Known Participant
April 23, 2020
Answered

Script to sort list of Bible references in Bible order

  • April 23, 2020
  • 3 replies
  • 5439 views

Hello,

Is anyone aware of a script that will sort a list of Bible references into the order the books appear in the Bible (i.e., beginning with Genesis)? Each reference is in its own paragraph, beginning with the name of the book.

If there isn’t a specific script for that, a script where you can map a list to a sort number and do the sort that way would also be great (e.g., Genesis = 1, Exodus = 2, and so on).

Thank you.

Correct answer Magnus Gaarde

You'll certainly have to add some sort key because there is no way that the book order is predictable. A custom script with the book order hard coded is possible, but that's not straightforward.

One possibility is to add sort keys at the beginning of the entries. The keys can be numbers or letters. If you use numbers, use double-digit numbers if the number of books is larger than 9 (as you see I've no idea about the bible). You can leave the keys in place for future sorts if you want: apply a character style to them that hides them (apply 0.1 points type size, 1% horizontal scale, paper colour).

To sort the list you can use the script that Brian mentioned, but it is very slow. A quicker script is here:

https://creativepro.com/files/kahrel/indesign/sort.html


This is funny. I was just working on that solution.
It might be clunky and have potential issues but this is it so far:


Application.prototype.main = function() {
var theParagraphs = app.selection[0].paragraphs.everyItem().getElements();
 
//Add indexOf to prototype Array
Array.prototype.indexOf = function (elem, fromIndex){  
fromIndex = Number(fromIndex) || 0;  
var len = this.length;  
if (fromIndex < 0){  
fromIndex += len;  
}  
for(var i=fromIndex;i<this.length;i++){  
if(this[i] == elem){  
return i;  
}  
}  
return -1;  
}  
 
 
var bookList = ["Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings", "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job", "Psalms", "Proverbs", "Ecclesiastes", "Song of Solomon", "Isaiah", "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai", "Zechariah", "Malachi", "Tobit", "Judith", "Ecclesiasticus (Sirach)", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation"];
 
var newList = [];
var bookNumber, bookName;
 
 
 
for (var i = 0; i < theParagraphs.length; i++) {
newList.push(theParagraphs[i].contents);
}
 
//add double digit sorting numbers
for (var i = 0; i < newList.length; i++) {
bookName = newList[i].split(" ")[0];
if (bookName == "1"||bookName == "2"||bookName == "3") {
bookName = newList[i].split(" ")[0] + " " + newList[i].split(" ")[1];
}
 
if (bookList.indexOf(bookName)<9) {
bookNumber = "0" +(bookList.indexOf(bookName)+1) + "_";
}
else{
bookNumber = (bookList.indexOf(bookName)+1) + "_";
}
newList[i] = bookNumber + newList[i];
}
 
//sort list
newList = newList.sort();
 
 
//this part removes the sorting-number
for (var i = 0; i < newList.length; i++) {
newList[i] = newList[i].replace(/^\d+_/g, "");
}
 
//paragraphs contents updated
for (var i = 0; i < theParagraphs.length; i++) {
theParagraphs[i].contents = newList[i];
}
 
 
}
 
app.doScript('app.main();',ScriptLanguage.JAVASCRIPT,undefined,UndoModes.ENTIRE_SCRIPT, undefined);



 

 

edit: added ^ to grep replace

3 replies

Willi Adelberger
Community Expert
Community Expert
May 5, 2020

I need it often because I typeset many Christian (Evangellical, Theological) books, but in German. But in German the order of the epistles is different and (this is not relevant here) the number of chapters and verses in the old testament and in Acts are different than in English, only messianic Bibles (like CJB) have the same chapter number and verse numbers.

Participating Frequently
May 5, 2020

If you want it to work with German Bibles you have to change the contents of the bookList array to the correct German book names. 

I know the chapter/verse can differ from translation to translation but as long as you put in the correct bookList that should not matter. 

 

Feel free to modify as you please. 

 

Jongware
Community Expert
Community Expert
April 24, 2020

Can you post a snippet of sample text, as it appears now and how you'd like to have it sorted?

Would you run such a script on an entire document, or on a selected story or text frame, or only in a selected text?

Known Participant
May 4, 2020

Here are two short lists that might give a better idea. The first is in alphabetical order and the second is in the order the books appear in the Bible.

 

List 1
Deuteronomy 1:37
Exodus 12:1–28
Genesis 1
Joshua 10
Judges 11:1–12:40
Leviticus 1–7
Numbers 1:50, 53
Ruth 4:11

 

List 2
Genesis 1
Exodus 12:1–28
Leviticus 1–7
Numbers 1:50, 53
Deuteronomy 1:37
Joshua 10
Judges 11:1–12:40
Ruth 4:11

Inspiring
February 24, 2022
Update:
Script now keeps styling while sorting.
(Still clunky and potentially faulty. Use at your own risk.)
 
 
Application.prototype.main = function() {
var theDoc = app.activeDocument;
var theParagraphs = app.selection[0].paragraphs.everyItem().getElements();
 
//Add indexOf to prototype Array
Array.prototype.indexOf = function (elem, fromIndex){  
fromIndex = Number(fromIndex) || 0;  
var len = this.length;  
if (fromIndex < 0){  
fromIndex += len;  
}  
for(var i=fromIndex;i<this.length;i++){  
if(this[i] == elem){  
return i;  
}  
}  
return -1;  
}  
 
 
//List of Bible booknames in correct order
var bookList = ["Genesis", "Exodus", "Leviticus", "Numbers", "Deuteronomy", "Joshua", "Judges", "Ruth", "1 Samuel", "2 Samuel", "1 Kings", "2 Kings", "1 Chronicles", "2 Chronicles", "Ezra", "Nehemiah", "Esther", "Job", "Psalms", "Proverbs", "Ecclesiastes", "Song of Solomon", "Isaiah", "Jeremiah", "Lamentations", "Ezekiel", "Daniel", "Hosea", "Joel", "Amos", "Obadiah", "Jonah", "Micah", "Nahum", "Habakkuk", "Zephaniah", "Haggai", "Zechariah", "Malachi", "Tobit", "Judith", "Ecclesiasticus (Sirach)", "Matthew", "Mark", "Luke", "John", "Acts", "Romans", "1 Corinthians", "2 Corinthians", "Galatians", "Ephesians", "Philippians", "Colossians", "1 Thessalonians", "2 Thessalonians", "1 Timothy", "2 Timothy", "Titus", "Philemon", "Hebrews", "James", "1 Peter", "2 Peter", "1 John", "2 John", "3 John", "Jude", "Revelation"];
 
var newList = [];//array to hold numbered list of booknames
var sortedList = [];//array to hold numbered and javascript sorted list of booknames. Just text no styling.
var bookNumber, bookName;
 
for (var i = 0; i < theParagraphs.length; i++) {
newList.push(theParagraphs[i].contents);
sortedList.push(theParagraphs[i].contents);
}
 
//add double digit sorting numbers to newList array
for (var i = 0; i < newList.length; i++) {
bookName = newList[i].split(" ")[0];
if (bookName == "1"||bookName == "2"||bookName == "3") {
bookName = newList[i].split(" ")[0] + " " + newList[i].split(" ")[1];
}
 
if (bookList.indexOf(bookName)<9) {
bookNumber = "0" +(bookList.indexOf(bookName)+1) + "_";
}
else{
bookNumber = (bookList.indexOf(bookName)+1) + "_";
}
newList[i] = bookNumber + newList[i];
sortedList[i] = bookNumber + sortedList[i];
}
 
//sort text list
sortedList = sortedList.sort()
 
//Make temporary text frame to hold paragraphs with styling
var newFrame = theDoc.pages[0].textFrames.add();
var newStory = newFrame.parentStory;
 
for (var i = 0; i < theParagraphs.length; i++) {
theParagraphs[i].duplicate(LocationOptions.AT_END,newStory);
}
var newParas = newStory.paragraphs.everyItem().getElements();
 
 
//add double digit sorting numbers to paragraphs in new frame
for (var i = 0; i < newParas.length; i++) {
var paraContent = newParas[i].contents;
bookName = paraContent.split(" ")[0];
if (bookName == "1"||bookName == "2"||bookName == "3") {
bookName = paraContent.split(" ")[0] + " " + paraContent.split(" ")[1];
}
 
if (bookList.indexOf(bookName)<9) {
bookNumber = "0" +(bookList.indexOf(bookName)+1) + "_";
}
else{
bookNumber = (bookList.indexOf(bookName)+1) + "_";
}
newParas[i].insertionPoints[0].contents = bookNumber;
newParas = newStory.paragraphs.everyItem().getElements();
}
newParas = newStory.paragraphs.everyItem().getElements();
 
 
//find the correct order based on the sorted list
for (var i = 0; i < sortedList.length; i++) {
var paragraphToMove = newList.indexOf(sortedList[i]);
theParagraphs[i].contents = "";
var movedPara = newParas[paragraphToMove].move(LocationOptions.before, theParagraphs[i]);
movedPara.characters.itemByRange(0,2).remove();
}
//remove temporary text frame
newFrame.remove();
 
}
app.doScript('app.main();',ScriptLanguage.JAVASCRIPT,undefined,UndoModes.ENTIRE_SCRIPT, "sortBibleBooks_v2");

This script is awesome, thanks SO much! I'm using it for sorting a Scripture index which has headings with the name of the book, and then the index, like so: 

Genesis

    Genesis 1

    Genesis 2

Exodus

    Exodus 5

    Exodus 6

 

Unfortunately, this script separates the headings from the entries (which have numbers after them). 😞 😞 So after sorting, all the headings have been sorted separately at the beginning of the index, and then the entries were sorted separately after that. Is there any way to modify the script so that it leaves the heading without a number as the first, and then lists all other entries after it? 

brian_p_dts
Community Expert
Community Expert
April 24, 2020

The pre-installed sample Sort Paragraphs script could probably be reconfigured to handle your use case, but it would take some lifting. In its base form it only sorts alphabetically, but I would start there.