Indesign conditional text styling using ExtendScript - adobe-indesign

Does anyone know if it's possible to style text a certain way using ExtendScript, only when a certain condition is met for the paragraph in question?
I've cobbled together an ExtendScript script that I use in InDesign to fix text styles when they aren't fixed properly by the Paragraph Style tool, and it works well so far - changing Courier and Arial Unicode text to Times New Roman and fixing the font size - but i would really like to include a function that changes Times New Roman Italic to Times New Roman Bold Italic - but ONLY when the paragraph it appears in has a first letter that is set in Univers. Is there a way I can include an 'if' statement that will only trigger this style change in those circumstances?
Here's my existing code:
var mydoc = app.activeDocument;
var theFontSize = [
'Courier New','16','Courier New','8.75',
'Times New Roman','16','Times New Roman','8.75',
];
for (i = 0; i < (theFontSize.length/4); i++) {
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findTextPreferences.appliedFont = theFontSize[i*4];
if (theFontSize[(i*4)+1] != ''){
app.findTextPreferences.pointSize = theFontSize[(i*4)+1];
};
app.changeTextPreferences.appliedFont = theFontSize[(i*4)+2];
if (theFontSize[(i*4)+3] != ''){
app.changeTextPreferences.pointSize = theFontSize[(i*4)+3];
};
mydoc.changeText();
};
var theFontReplacements = [
'Courier New','Regular','Times New Roman','Regular',
'Courier New','Italic','Times New Roman','Italic',
'Courier New','Bold','Times New Roman','Bold',
'Courier New','Bold Italic','Times New Roman','Bold Italic',
'Courier New','75 Black','Univers','75 Black',
'Arial Unicode MS','Regular','Times New Roman','Regular',
];
for (i = 0; i < (theFontReplacements.length/4); i++) {
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;
app.findTextPreferences.appliedFont = theFontReplacements[i*4];
if (theFontReplacements[(i*4)+1] != ''){
app.findTextPreferences.fontStyle = theFontReplacements[(i*4)+1];
};
app.changeTextPreferences.appliedFont = theFontReplacements[(i*4)+2];
if (theFontReplacements[(i*4)+3] != ''){
app.changeTextPreferences.fontStyle = theFontReplacements[(i*4)+3];
};
mydoc.changeText();
};
app.findTextPreferences = NothingEnum.nothing;
app.changeTextPreferences = NothingEnum.nothing;

This should get you started. It will be slower than using changeText, but I don’t think you can do what you’re asking with changeText.
// Change applied font of text set in Times New Roman Italic in paragraphs whose first character is set in Univers to Times New Roman Bold Italic
app.findTextPreferences.appliedFont = 'Times New Roman';
app.findTextPreferences.fontStyle = 'Italic';
var foundItems = app.activeDocument.findText(); // Set foundItems to all results of search according to app.findTextPreferences
for (var i = 0; i < foundItems.length; i++) { // For each result found
var item = foundItems[i];
if (item.paragraphs[0].characters[0].appliedFont.name.indexOf('Univers') == 0) { // If item’s first enclosing paragraph’s first character’s font name starts with “Univers”
item.appliedFont = 'Times New Roman\tBold Italic'; // Set item’s font to Times New Roman italic
}
};

Related

How to reducing spacing between paragraphs IText 7?

How can I reduce the line spacing between "Section 1" and "Alert" using IText 7?
These are values stored in the table of ​database
<h3 style=color:#0000ff;><strong>Section 1</strong></h3>
<h4><strong>- Alert</strong></h4>
I have tried without success these links because don't changing the line spacing between "Section 1" and "Alert"
https://kb.itextpdf.com/home/it7kb/faq/how-to-change-the-line-spacing-of-text
How to adjust spacing between paragraphs in iText7
My code below
if (dt.Rows.Count > 0)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
contents = new Paragraph(dt.Rows[i]["contents"].ToString())
.SetTextAlignment(TextAlignment.JUSTIFIED)
.SetFontSize(12)
.SetMultipliedLeading(0.0f);
List<IElement> lst = HtmlConverter.ConvertToElements(dt.Rows[i]["contents"].ToString()).ToList();
for (int j = 0; j < lst.Count; j++)
{
IBlockElement element = (IBlockElement)lst[j];
if (dt.Rows[i]["contents"].ToString().StartsWith("<h3 style=color:#0000ff;><strong>Section"))
{
contents.SetFontSize(12)
.SetBold()
.SetFontColor(ColorConstants.BLUE)
.SetMultipliedLeading(0.0f);
}
else if (dt.Rows[i]["contents"].ToString().StartsWith("<h4><strong>- "))
{
contents.SetFontSize(10)
.SetBold()
.SetFontColor(ColorConstants.BLACK)
.SetMultipliedLeading(0.0f);
}
else
{
contents.SetFontSize(10)
.SetFontColor(ColorConstants.BLACK)
.SetMultipliedLeading(0.0f);
}
document.Add(element);
}
}
dest = filename.ToString();
}
You're creating a Paragraph objects (called contents) from the HTML strings and applying properties to it, but not adding those objects to the document. You're also creating a List of elements by having HtmlConverter process the HTML strings. Those elements are added to the documents.
So it's expected that none of the properties that are set on contents are visible in the PDF document.
You can simply rely on HtmlConverter to process the CSS properties.
String[] htmls = {
"<h3 style=\"color:#0000ff;\"><strong>Section 1</strong></h3>",
"<h4><strong>- Alert</strong></h4>"
};
PdfWriter writer = new PdfWriter("SO66694693.pdf");
PdfDocument pdfDoc = new PdfDocument(writer);
Document document = new Document(pdfDoc);
for (int i = 0; i < htmls.Length; i++)
{
IList<IElement> lst = HtmlConverter.ConvertToElements(htmls[i]);
for (int j = 0; j < lst.Count; j++)
{
IBlockElement element = (IBlockElement)lst[j];
document.Add(element);
}
}
document.Close();
Output:
When adjusting the bottom margin on the first element and the top margin on the second element:
"<h3 style=\"color:#0000ff;margin-bottom: 0px;\"><strong>Section 1</strong></h3>",
"<h4 style=\"margin-top: 0px;\"><strong>- Alert</strong></h4>"
Output:
If you prefer to change the properties using SetMargin(), SetMarginBottom(), etc, instead of CSS properties, make sure you're doing that on the objects you're actually adding to the document.

How can I add disparate chunks to a PdfPCell using iTextSharp?

How can I concatenate disparate chunks and add them to a paragraph, the paragraph to a cell, then the cell to a table using iTextSharp (in generating a PDF file)?
I am able to get to a certain "place" in my PDF file generation, so that it looks like so (the right side of the page is blank, as it should be):
This is the code I'm using for that:
using (var ms = new MemoryStream())
{
using (var doc = new Document(PageSize.A4, 50, 50, 25, 25))
{
//Create a writer that's bound to our PDF abstraction and our stream
using (var writer = PdfWriter.GetInstance(doc, ms))
{
//Open the document for writing
doc.Open();
var courierBold11Font = FontFactory.GetFont(FontFactory.COURIER_BOLD, 11, BaseColor.BLACK);
var docTitle = new Paragraph("Mark Twain", courierBold11Font);
doc.Add(docTitle);
var timesRoman9Font = FontFactory.GetFont("Times Roman", 9, BaseColor.BLACK);
var subTitle = new Paragraph("Roughing It", timesRoman9Font);
doc.Add(subTitle);
var courier9RedFont = FontFactory.GetFont("Courier", 9, BaseColor.RED);
var importantNotice = new Paragraph("'All down but nine; set 'em up on the other alley, pard' - Scotty Briggs", courier9RedFont);
importantNotice.Leading = 0;
importantNotice.MultipliedLeading = 0.9F; // reduce the width between lines in the paragraph with these two settings
PdfPTable table = new PdfPTable(1);
PdfPCell cellImportantNote = new PdfPCell(importantNotice);
cellImportantNote.BorderWidth = PdfPCell.NO_BORDER;
table.WidthPercentage = 50;
table.HorizontalAlignment = Element.ALIGN_LEFT;
table.AddCell(cellImportantNote);
doc.Add(table);
doc.Close();
}
var bytes = ms.ToArray();
String PDFTestOutputFileName = String.Format("iTextSharp_{0}.pdf", DateTime.Now.ToShortTimeString());
PDFTestOutputFileName = PDFTestOutputFileName.Replace(":", "_");
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), PDFTestOutputFileName);
File.WriteAllBytes(testFile, bytes);
MessageBox.Show(String.Format("{0} written", PDFTestOutputFileName));
}
}
However, I need to break up the red text so that part of it is bolded, parts of it are anchor tags/hrefs, etc.
I thought I could do it this way:
var courier9RedBoldFont = FontFactory.GetFont(FontFactory.COURIER_BOLD, 9, BaseColor.RED);
// Build up chunkified version of "important notice"
Chunk boldpart = new Chunk("All down but nine - set 'em up on the other alley, pard", courier9RedBoldFont);
Chunk attribution = new Chunk("Scotty Briggs", courier9RedFont);
PdfPTable tbl = new PdfPTable(1);
tbl.WidthPercentage = 50;
tbl.HorizontalAlignment = Element.ALIGN_LEFT;
var par = new Paragraph();
par.Chunks.Add(boldpart);
par.Chunks.Add(attribution );
PdfPCell chunky = new PdfPCell(par);
chunky.BorderWidth = PdfPCell.NO_BORDER;
tbl.AddCell(chunky);
doc.Add(tbl);
...but that's not adding anything at all to the PDF file, but why not? Doesn't a cell take a paragraph, and cannot a paragraph be comprised of Chunks?
Instead of para.Chunks.Add() just use par.Add(); The Chunks that are returned from Paragraph actually come from the base class Phrase. If you look at the code for that property you'll see that the collection returned is actually a temporary collection created on the fly so it is effectively read-only.

Photoshop scripting mantain same file name and whitespace

I'm trying to add a layer to some images and then save them.
The problem is that many images have whitespace in the name. When I try to save the whitespaces are replaced with "-", but I want mantain the same name.
For example an image called "Google Analytics.png" become "Google-Analytics.png". But I need to preserve the name without that extra "-".
My code:
function SavePNG(saveFile){
var file = new File(saveFile);
var pngOpts = new ExportOptionsSaveForWeb;
pngOpts.format = SaveDocumentType.PNG
pngOpts.PNG8 = false;
pngOpts.transparency = false;
pngOpts.interlaced = false;
pngOpts.quality = 100;
$.writeln(file)
app.activeDocument.exportDocument(file,ExportType.SAVEFORWEB,pngOpts);
}
Try using saveAs instead of exportDocument; it'll respect the name of the file you give it. The options are yours to change:
var myfile = "C:\\temp\\Google Analytics.png";
SavePNG(saveFile)
function savePNG(saveFile)
{
// save out the image
var pngFile = new File(filepath);
pngSaveOptions = new PNGSaveOptions();
pngSaveOptions.embedColorProfile = true;
pngSaveOptions.formatOptions = FormatOptions.STANDARDBASELINE;
pngSaveOptions.matte = MatteType.NONE;
pngSaveOptions.quality = 1;
activeDocument.saveAs(pngFile, pngSaveOptions, false, Extension.LOWERCASE);
}

InDesign: ExtendScript to list fonts and extended font information

I need to list detailed information about the fonts used in a set of inDesign documents. The information I need is essentially accessible through the menu item Type › Find Fonts… (as explained here) but going through each font in every document and writing down the information is not feasible.
I can find much of the information in the Font objects underdocument.fonts and my question is how to access or generate the extended properties found in the panel below:
Character count for the given font
Pages where the font occurs
Edit: The document.fonts array also doesn't seem to include missing fonts.
Well, here's a brute-force strategy for character counting. It iterates through every character textStyleRange in the document and checks its applied font. Edit: Updated to use textStyleRanges. Much faster than going through every character.
var document = app.open(new File(Folder.desktop.fsName + "/test/test.indd"));
try {
var fontMultiset = countCharsInFonts(document);
// For each font, display its character count.
var fonts = document.fonts.everyItem().getElements();
for (var i = 0; i < fonts.length; i++) {
var fontName = fonts[i].fullName;
$.writeln(fontName + ": " + fontMultiset[fontName]);
}
}
finally {
document.close();
}
function countCharsInFonts(document) {
// Create the font multiset.
var fontMultiset = {
add: function add(fontName, number) {
if (this.hasOwnProperty(fontName)) {
this[fontName] += number;
}
else {
this[fontName] = number;
}
},
};
// For every textStyleRange in the document, add its applied font to the multiset.
var stories = document.stories.everyItem().getElements();
for (var i = 0; i < stories.length; i++) {
var story = stories[i];
var textStyleRanges = story.textStyleRanges.everyItem().getElements();
for (var j = 0; j < textStyleRanges.length; j++) {
fontMultiset.add(textStyleRanges[j].appliedFont.fullName, textStyleRanges[j].length);
}
}
// For any fonts that aren't applied in the document, set the character count to 0.
var fonts = document.fonts.everyItem().getElements();
for (var i = 0; i < fonts.length; i++) {
var fontName = fonts[i].fullName;
if (!fontMultiset.hasOwnProperty(fontName)) {
fontMultiset[fontName] = 0;
}
}
return fontMultiset;
}

Abcpdf copyable/selectable text

i'm using websupergoos abcpdf to convert html pages to pdf via addimageurl.
Works great, but the resulting pdf does not allow the user to select text and copy. All is one 'image'.
Is it possible to do this? Which are the settings to use?
This is my current code. The commented "flatten" does not seem to do anything relevant. The HttpStream simply forewards the pdf to users as a doc.
var doc = new Doc();
doc.HtmlOptions.UseScript = true;
doc.Units = "mm";
doc.MediaBox.String = "0 0 210 297";
doc.Rect.String = doc.MediaBox.String;
doc.Rect.Inset(10.0, 10.0);
doc.SetInfo(0, "License", abcpdfkey);
doc.HtmlOptions.UseScript = true;
doc.HtmlOptions.AddMovies = true;
doc.HtmlOptions.RetryCount = 0;
doc.HtmlOptions.ContentCount = 1;
doc.Page = doc.AddPage();
for (int i = doc.AddImageUrl(url); doc.Chainable(i); i = doc.AddImageToChain(i))
{
doc.Page = doc.AddPage();
}
int pageCount = doc.PageCount;
for (int j = 1; j <= pageCount; j++)
{
doc.PageNumber = j;
// doc.Flatten();
}
this.HttpStream(doc.GetData(), filename);
Before sending the PDF to the HTTP stream, you can set the encryption properties
The CanCopy Property sets if the user can copy text from the PDF
To set it add the following code:
doc.Encryption.CanCopy = true;
You may need to set doc.Encryption.CanExtract as well

Resources