Copy link to clipboard
Copied
Hello!
I would like to ask for suggestions concerning a new project that came to me. The client wants a book that will have three columns throughout:
ENGLISH | HEBREW | GREEK
Each column is essentially a translation of the other, so I am using a three-column text frame on a master page with grids to keep them aligned. However, I am facing two issues:
1. When the English content in Column 1 reaches the end of the page, it doesn't spill over to Column 1 on the next page. Instead, it moves over to Column 2 even though I'm using manual column breaks as I go.
Another thread here recommended I change the Keep settings and set "Keep with Nexf" to 0, which I did for all the styles, but that didn't work.
So, is there a way/plug-in to keep the text flowing in the same column from page to page? Of course, the 3-column text frames on all pages are linked.
2. Another way of doing this, which is more tedious, might be three separate text frames with each language independent of the other. I could go this route, but then I would lose the ability to have headings span all three columns.
So, is there a way to have text span across text frames? I'm very much trying to avoid resizing the height of each frame and adding a new frame just for headings, because there will most likely be some repagination in the future and it's quite messy.
Thanks in advance!
Hi @ibnabouna:
This is a challenging layout. The answer is no to being able to span a heading across three separate text frames. Span only works when you have one text frame with multiple columns defined within it. You could go old-school and draw one new frame that spans all three columns on the page and then have three separate frames, for one for each language underneath, as you mentioned.
As for the automatic spill-over, that only going to work if you have three separate frames, one for
...Copy link to clipboard
Copied
Sounds like you could *almost* put it all in one big table, which would solve part of the issue but create other issues, eg. how to get the text into the table, one language per table column (script might be best) and table cells won't break across pages which I assume would be a problem in your case.
Any chance you could post screen shot or pdf of a representative page or couple of pages showing how they should break?
- Mark
Copy link to clipboard
Copied
Thank you so much for chiming in.
I tried using tables in the past, but the problem is that InDesign will not allow large chunks of text in a cell to split across the page, so one might end up with a quarter page or more of white space as the whole row shifts down to the next page. It works if you have small "chunks" of text that are about the same height, but in my document, this is not the case.
As much as I tried to find a plugin or other script to help InDesign in this respect, it seems there is no easy way of doing this short of manually creating a bunch of text frames and hoping for the best.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hi @ibnabouna:
This is a challenging layout. The answer is no to being able to span a heading across three separate text frames. Span only works when you have one text frame with multiple columns defined within it. You could go old-school and draw one new frame that spans all three columns on the page and then have three separate frames, for one for each language underneath, as you mentioned.
As for the automatic spill-over, that only going to work if you have three separate frames, one for each language. Otherwise, there is going to be a lot of cutting and pasting to try to keep the languages in the correct columns after edits.
Neither option is ideal, but I'd chose the one I'm showing below because it would be slightly easier to control. If you follow the text threads/frame colors you can see how I have the frames connected. I'm making the assumption that you're going have heads in the middle of a page which would be the most problematic. Because the column lengths will never match up when you have multiple languages, you can use column breaks to force the text to hop over the middle-of-the-page heads and onto the next threaded frame.
~Barb
Copy link to clipboard
Copied
What I've done, when I've needed a single headline to cross three paralell text columns, is to just use a single-cell table. Tables can extend beyond the boundaries of the frame without issue. Much less elegant than Barb's solution, but many fewer clicks.
However, I've never bothered to get primary text frames on master pages working, so I just draw a bunch of parallel text frames and thread them by hand (usually with Rorohiko's Text Stitch, which I've been using since forever ago to speed up frame-threading in these situations).
Copy link to clipboard
Copied
Thank you for those recommendations! I'll have to check out Text Stitch.
Copy link to clipboard
Copied
Thank you, Barb. Yes, this is the approach I decided on after trying the other options. It's still quite tedious, since all of the blocks of text are related to each other and must line up horizontally, but thankfully, it is workable with some effort.
Copy link to clipboard
Copied
Hi @ibnabouna, I was intrigued by this problem and I've written a script idea called "Align Paragraphs". It's a slightly complicated set up, as you can imagine, but I'll attach a sample document that you can use to see what I've done. I've put a bit of documentation in the script itself, too.
UPDATE 2024-09-08: I have re-written this script from ground up, and i think it is now much easier to use, and better. See documentation in the script listing. And definitely try out the attached demo.indd.
- Mark
The script makes the markers line up.
You can have as many parallel text columns as you like.
/**
* @file Align Parallel Paragraphs.js
*
* Purpose: to align "marked" paragraphs across different stories.
*
* This is useful for situations with "parallel" text threads,
* for example, a layout where each page has a column of English,
* a column of Hebrew, and a column of Greek (the texts are
* translations and semantically linked). It is desired that
* every subheading line up across the different languages
* to make comparison by the reader easy.
*
* To achieve this scenario, you would add a marker to every paragraph
* that needed to line up, in this case to each subheading.
*
* Set up:
*
* 0. Your document must have:
* - "Alignment Marker" object style (suggest specify size and non-printing)
* - "Spacer" paragraph style (suggest with tiny 0.01 leading, 0 paragraph spacing)
*
* 1. Create a non-printing marker triangle and apply "Alignment Marker" object style.
* The top of the marker's geometric bounds will be the alignment point.
*
* 2. Copy/paste a marker at the start of every line you want to align.
* Note: every time you add a marker, you must add one for each story.
* The script will attempt to align these "sets" of markers, eg. if you have 3 stories
* it will align the first marker of each story, and then align the second marker, etc.
*
* Usage:
* 1. Select multiple text frames, each having a separate story.
* 2. Run script.
*
* Technical:
* - the spacing is done by adding a "spacer" paragraph (with "Spacer" paragraph style)
* directly before the paragraph to be aligned, and setting its `spaceAfter`
* - all "spacer" paragraphs will be removed every time the script is re-run.
* - `settings.reset: true` will remove spacer paragraphs, but perform no alignments.
*
* @author m1b
* @version 2024-09-08
* @discussion https://community.adobe.com/t5/indesign-discussions/3-column-multilingual-book-with-spanning-headers/td-p/12923098
*/
function main() {
var settings = {
markerStyleName: 'Alignment Marker',
spacerParagraphStyleName: 'Spacer',
reset: false,
};
if (
0 == app.documents.length
|| app.activeDocument.selection.length < 2
)
return alert('Please select two or more text frames and try again.');
app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
var doc = settings.doc = app.activeDocument,
frames = doc.selection,
stories = [],
unique = {};
// check that we have the styles we need
var markerStyle = settings.doc.objectStyles.itemByName(settings.markerStyleName),
spacerParagraphStyle = settings.doc.paragraphStyles.itemByName(settings.spacerParagraphStyleName);
if (!markerStyle.isValid)
return alert('Marker object style "' + settings.markerStyleName + '" is invalid.');
if (!spacerParagraphStyle.isValid)
return alert('Spacer paragraph style "' + settings.spacerParagraphStyleName + '" is invalid.');
// collect the stories
for (var i = 0; i < frames.length; i++) {
if (
!frames[i].hasOwnProperty('parentStory')
|| unique[frames[i].parentStory.id]
)
continue;
stories.push(frames[i].parentStory)
unique[frames[i].parentStory.id] = true;
}
// remove all spacer paragraphs
app.findGrepPreferences = NothingEnum.NOTHING;
app.changeGrepPreferences = NothingEnum.NOTHING;
app.findGrepPreferences.appliedParagraphStyle = spacerParagraphStyle;
for (var i = 0, found; i < stories.length; i++) {
found = stories[i].findGrep();
for (var j = found.length - 1; j >= 0; j--)
found[j].remove();
stories[i].recompose();
}
if (settings.reset)
return;
// collect markers from the stories
var allMarkers = [];
for (var i = 0, markers; i < stories.length; i++) {
allMarkers[i] = [];
markers = stories[i].polygons;
markerLoop:
for (var j = 0; j < markers.length; j++) {
if (markers[j].appliedObjectStyle.name !== settings.markerStyleName)
continue markerLoop;
allMarkers[i].push(markers[j]);
}
}
// get number of alignments
var alignmentCount = Infinity;
for (var i = 0; i < allMarkers.length; i++)
alignmentCount = Math.min(alignmentCount, allMarkers[i].length);
// collect "alignments", which are sets of markers, one from each story
var alignments = [];
for (var i = 0; i < alignmentCount; i++) {
alignments[i] = [];
for (var j = 0; j < stories.length; j++)
alignments[i][j] = allMarkers[j].shift();
}
// process each alignment
for (var i = 0, markers, pageIndex, height; i < alignments.length; i++) {
markers = alignments[i];
pageIndex = -Infinity;
height = -Infinity;
// calculate the alignment's page index and height
for (var j = 0, marker; j < markers.length; j++) {
marker = markers[j];
page = marker.parentPage;
if (!page)
throw new Error('Marker "' + marker.toSpecifier() + '" is not on a Page.');
pageIndex = Math.max(pageIndex, page.documentOffset);
if (pageIndex === page.documentOffset)
height = Math.max(height, marker.geometricBounds[0]);
}
// align each marker
for (var j = 0; j < markers.length; j++)
alignMarker(markers[j], pageIndex, height);
}
/**
* Align `marker` to page
* @version 2024-09-08
* @param {Polygon} marker - an anchored page item.
* @param {Number} pageIndex - the alignment page.
* @param {Number} height - the alignment Y coordinate.
* @param {Number} [tolerance] - if the alignment required is less than this, don't bother (default: 0.001 pts).
*/
function alignMarker(marker, pageIndex, height, tolerance) {
if (undefined == tolerance)
tolerance = 0.001;
// add page breaks until marker is on the right page
while (pageIndex > marker.parentPage.documentOffset) {
marker.parent.paragraphs[0].insertionPoints[0].contents = SpecialCharacters.PAGE_BREAK;
marker.parent.parentStory.paragraphs.previousItem(marker.parent.paragraphs[0]).appliedParagraphStyle = spacerParagraphStyle;
marker.parent.parentStory.recompose();
}
// the distance to the alignment height
var dy = marker.geometricBounds[0] - height;
if (Math.abs(dy) < tolerance)
// already aligned
return;
var spacerParagraph = marker.parent.parentStory.paragraphs.previousItem(marker.parent.paragraphs[0]);
if (
undefined == spacerParagraph
|| !spacerParagraph.isValid
|| spacerParagraph.parentTextFrames[0] !== marker.parent.parentTextFrames[0]
|| spacerParagraph.appliedParagraphStyle !== spacerParagraphStyle
) {
// create the spacer paragraph
marker.parent.paragraphs[0].insertionPoints[0].contents = '\r';
spacerParagraph = marker.parent.parentStory.paragraphs.previousItem(marker.parent.paragraphs[0]);
spacerParagraph.appliedParagraphStyle = spacerParagraphStyle;
}
// after adding the spacer paragraph, recalculate this
dy = marker.geometricBounds[0] - height;
if (dy > 0)
throw new Error('Marker "' + marker.toSpecifier() + '" cannot be aligned due to bad sorting!');
spacerParagraph.spaceAfter -= dy;
};
};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Align Parallel Paragraphs');
Copy link to clipboard
Copied
Wow. I'm speechless at this effort.
I haven't had a chance to try it, but it looks very promising as an indispensable aid for these types of complicated layouts.
I'll report back when I have a chance to set it up with my content.
Again, this is really incredible.
Copy link to clipboard
Copied
Please tell me you tried what m1b did with the script
Copy link to clipboard
Copied
Just For Comments:
I've studied this matter since years. When time, I will explore a "3 flows" update! …
(^/) The Jedi
Copy link to clipboard
Copied
Hello,
Amazing... This is quite impressive! I can tell it has the polish of being worked on for a long time.
Yes, please do update us if it can work on a three-column layout!
Copy link to clipboard
Copied
Nice!
Copy link to clipboard
Copied
Ooooooh!!
Amazing
Find more inspiration, events, and resources on the new Adobe Community
Explore Now