Skip to main content
This topic is closed to new replies. Start a new post to keep the conversation going.

8 replies

m1b
Community Expert
Community Expert
June 14, 2022

Hi @paata01, I was interested in this problem and I've had a go to solve it. I've written a script that opens the svg, changes the font-family and saves it (in the same folder, but with a timestamp appended—it doesn't overwrite the original) and then opens the altered svg in Illustrator for you to check. I don't have Nexa Rust Slab, so I've used everyone's favourite font for this test. It works for me on your test file. Can you try it out?

- Mark

 

 

/*

    Open SVG Replacing Attribute.js
    for Adobe Illustrator 2022

    by m1b
    here: https://community.adobe.com/t5/illustrator-discussions/saving-amazon-customizable-product-svg-as-png-with-the-same-font-customer-specified/m-p/13002413/thread-id/325024

    Reads svg file and replaces all found attributes
    with a supplied value.

    Example:
    openSVGReplacingAttribute('font-family', 'Comic Sans');

*/


// get the font
var myFontName = 'ComicSansMS';

if (app.textFonts.isFontAvailable(myFontName)) {

    var myFontFamilyName = app.textFonts.getByName(myFontName).family,
        doc = openSVGReplacingAttribute('font-family', myFontFamilyName, true);

}

else alert('The font "' + myFontName + '" not found. Please check font name and try again.');



/**
 * Asks for SVG file, then replaces target XML
 * attribute value and re-saves the SVG file
 * with timestamp and opens changed file.
 * @param {String} attr - the attribute to replace
 * @param {String} value - the replacement value
 */
function openSVGReplacingAttribute(attr, value) {
    var f = chooseFile('svg');
    if (!f) return;

    var svg = readFile(f);
    if (!svg) return;

    var xml = new XML(svg),
        elements = xml.descendants(),
        len = elements.length();

    for (var i = 0; i < len; i++) {
        var found = elements[i]['@' + attr].toString();
        if (found)
            elements[i]['@' + attr] = value;
    }
    var newFilePath = f.fsName.replace(/\.svg$/, '_' + getISOTimeStamp() + '.svg'),
        newFile = writeFile(newFilePath, xml.toString(), false);

    return (app.open(newFile));
}




/**
 * Generate ISO-8601-like timestamp string.
 * YYYY-MM-DD_HHMM
 * @param {Date} [date] - the date (leave undefined for now)
 * @param {String} [delimiter] - string to delimit values, default = '-'
 * @param {Boolean} [showTimeDelimiter] - show delimiter between hours and minutes
 * @returns {String}
 */
function getISOTimeStamp(date, delimiter, showTimeDelimiter) {
    // if no Date supplied, use today
    date = date || new Date();
    delimiter = delimiter || '-';
    var timeDelimiter = showTimeDelimiter ? delimiter : '',

        datePart = [
            date.getFullYear(),
            ('0' + (date.getMonth() + 1)).slice(-2),
            ('0' + date.getDate()).slice(-2)
        ].join(delimiter),

        timePart = [
            ('0' + date.getHours()).slice(-2),
            ('0' + date.getMinutes()).slice(-2)
        ].join(timeDelimiter);;

    return datePart + '_' + timePart;
}


/**
 * Write text to file.
 * @param {String} path - path to file
 * @param {String} data - the payload to write
 * @param {Boolean} append - overwrite (false) or append (true)
 * @returns {File} the written file
 */
function writeFile(path, data, append) {
    var success,
        writeMode = append == true ? 'a' : 'w';
    try {
        var file = new File(path);
        file.open(writeMode);
        file.encoding = "UTF8";
        success = file.write(data);
        file.close();
    } catch (error) {
        success = false;
        alert('writeFile failed: ' + error.message);
    }
    if (success)
        return file;
}



/**
 * Shows open file dialog and
 * filters for file extension.
 * @param {String} [fileExtension] - default 'txt'
 * @returns {File}
 */
function chooseFile(fileExtension) {
    fileExtension == fileExtension || 'txt';
    fileExtension = fileExtension.replace('.', '');

    var f, fsFilter;
    if ($.os.match("Windows")) {
        fsFilter = "*." + fileExtension;
    } else {
        var regex = RegExp('\.' + fileExtension, 'i');
        fsFilter = function (f) { return (regex.test(f.name) || f.constructor.name == 'Folder') };
    };

    f = File.openDialog("Please select the '" + fileExtension + "' File", fsFilter, false);

    if (f != undefined && f.exists) return f;
}



/**
 * Read a file and return contents.
 * Will ask for file if no path is supplied.
 * @param {String} [path] - path to file
 * @param {String} [fileExtension] - default = 'txt'
 * @returns {String} file contents
 */
function readFile(path, fileExtension) {
    fileExtension = fileExtension || 'txt';
    fileExtension = fileExtension.replace('.', '');

    var f;
    if (path == undefined) {
        f = chooseFile(fileExtension);
    } else {
        f = File(path);
    }

    if (!f || !f.exists)
        return;

    f.open('r');
    var data = f.read();

    if (data == undefined)
        throw Error('readFile: Could not read data.');

    return data;
}

 

  

P.S. If you know the correct font family string you can remove all the stuff at the start about checking if font exists and just send the font family string to the function call:

openSVGReplacingAttribute('font-family', 'Nexa Rust Slab');
paata01Author
Known Participant
June 14, 2022

Thank you so much! really appreciate it. two questions:

1. will SVG file have font info, should it be auto-recognized what font customer specified, because specified font color does transfer correctly. 

2. Where and how should I implement this script. 

again thanks!

m1b
Community Expert
Community Expert
June 15, 2022

@paata01 wrote:

1. will SVG file have font info, should it be auto-recognized what font customer specified, because specified font color does transfer correctly. 

Do you mean can you determine (automatically) the font from the svg file? I doubt it. It has been encoded. For example, the font in your sample file is called "font-5e97b458-3c83-4f3c-b6b9-90". I have no way of knowing anything else about it exept to download the .woff file that's linked in the svg and look at it. Try opening the svg file in text editor to see the link.

 


2. Where and how should I implement this script. 

again thanks!


Save it as a plain text file (make sure it is plain text, not rich text or anything else) and call it "Open SVG Replacing Attribute.js". Then:

For Windows, put it here: C:\Program Files\Adobe\Adobe Illustrator\Presets\en_US\Scripts, or

for Mac, put it here: Applications>Adobe Illustrator>Presets>en_US>Scripts.

* The folder names in bold may be slightly different, eg. Adobe Illustrator 2022, or a different locale code. Make sure you put it in the right version's folder.

- Mark