Specific ZotFile workflow with Zotero7 file renaming rules

edited August 15, 2024
Taking in consideration the suggestion of @AbeJellinek in https://forums.zotero.org/discussion/comment/470158/#Comment_470158, I ask here for how to migrate to the Zotero File Renaming syntax my ZotFile workflow.

I summarize the main characteristics and copy below the preferences:
Format for all item types: "{%a}{-%y}{-%t}", so generally, authors-year-title
Marked additional settings:
-Delimiter between multiple authors: and
-Replace blanks (no blanks)
-Truncate title after . or : or ?
-Maximum length of title 80
-Maximum number of authors 2
-Number of authors to display when authors are omitted 1
-Add suffix when authors are omitted: etal
-Remove special characters (diacritics) from filename
-Only work with pdf,doc,docx,txt,rtf,djvu,epub

Thanks for your help!

user_pref("extensions.zotfile.authors_delimiter", "and");
user_pref("extensions.zotfile.etal", "etal");
user_pref("extensions.zotfile.import", false);
user_pref("extensions.zotfile.removeDiacritics", true);
user_pref("extensions.zotfile.renameFormat", "{%a}{-%y}{-%t}");
user_pref("extensions.zotfile.renameFormat_patent", "{%a}{-%y}{-%t}");
user_pref("extensions.zotfile.replace_blanks", true);
user_pref("extensions.zotfile.source_dir_ff", false);
  • edited August 12, 2024
    The following template should be close to what you're looking for:

    {{ if {{ authors match="[^,]+,[^,]+,[^,]+" }} }}
    {{ authors max="1" suffix="-etal" }}
    {{ else }}
    {{ authors join=" and " }}
    {{ endif }}
    {{ year prefix="-"}}
    {{ title truncate="80" replaceFrom="(\.|:|\?)(.*?)$" prefix="-" }}


    File renaming template currently does not support counting authors, but we can use a regular expression to check if there are at least three authors. If that's the case, the first branch executes, producing author-etal. If there are fewer than three authors, the second branch executes, producing author and author.

    Next, we display the year, prefixing it with a hyphen ("-").

    Finally, we add the title, which uses regex to remove everything after a period (.), colon (:), or question mark (?). The title is truncated at 80 characters.

    Zotero will always produce a valid filename, as special characters that are not allowed in filenames are removed in the final step.
    -Only work with pdf,doc,docx,txt,rtf,djvu,epub
    This can be specified using a hidden pref extensions.zotero.autoRenameFiles.fileTypes as explained on the file renaming page.
  • Thanks @tnajdek

    It only lacks replacing blanks with, for example, no character or "_" (in particular I would use {{authors join="_and_"}}). How should I proceed to get this?
  • edited August 14, 2024
    I couldn't find any documentation, but by looking at the source code, it seems that replace_blanks converts spaces to underscores in the final file name.

    In the new Zotero templating system, you would need to specify this as case for every field where spaces might occur, something like:

    {{ if {{ authors match="[^,]+,[^,]+,[^,]+" }} }}
    {{ authors max="1" suffix="-etal" case="snake" }}
    {{ else }}
    {{ authors join=" and " case="snake" }}
    {{ endif }}
    {{ year prefix="-" }}
    {{ title truncate="80" replaceFrom="(\.|:|\?)(.*?)$" prefix="-" case="snake" }}



  • edited August 15, 2024
    @tnajdek @AbeJellinek

    I see that specifying `case = "snake"` also makes all to be lower case.

    Instead, could I do replaceFrom="\s+" replaceTo="_" regexOpts="g"?

    https://github.com/zotero/zotero/blob/b1b06cedde9fe09fea1e95162c51ef27b45a8e2d/chrome/content/zotero/xpcom/attachments.js#L2329-L2353

    switch (textCase) {
    case 'upper':
    value = value.toUpperCase();
    break;
    case 'lower':
    value = value.toLowerCase();
    break;
    case 'sentence':
    value = value.slice(0, 1).toUpperCase() + value.slice(1);
    break;
    case 'title':
    value = Zotero.Utilities.capitalizeTitle(value, true);
    break;
    case 'hyphen':
    value = value.replace(/\s+-/g, '-').replace(/-\s+/g, '-');
    value = value.toLowerCase().replace(/\s+/g, '-');
    break;
    case 'snake':
    value = value.replace(/\s+_/g, '_').replace(/_\s+/g, '_');
    value = value.toLowerCase().replace(/\s+/g, '_');
    break;
    case 'camel':
    value = value.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase());
    break;
    }
  • That would work, except we've already used replaceFrom for the title, and there is currently no support for specifying more than one replacement for a value.

    I'm afraid going with all lowercase 'snake_case' is the closest that the current Zotero template-based file renaming can do to match your naming pattern.
  • edited August 12, 2024
    @tnajdek Then
    {{ title truncate="80" replaceFrom="(\.|:|\?)(.*?)$" prefix="-" case="snake" }}
    {{ title replaceFrom="\s+" replaceTo="_" regexOpts="g" }}
    wouldn't work (as in the code you suggests there are multiple lines for authors)?
  • edited August 12, 2024
    No, that would insert title twice, formatted in two different ways. My earlier template includes if/else switch to pick one or the other way of formatting the authors field.
  • edited August 12, 2024
    @tnajdek I see. Thanks for the help! (and please, consider a feature request adding support for specifying more than one replacement for a value or adding more case='' options)
  • edited August 14, 2024
    @tnajdek Hi, I am so excited that the code really help me! Thanks a lot! By the way, is there a blank before and after authors? How can I do to eliminate it?

    This is my setting:
    {{ if {{ authors match="[^,]+,[^,]+,[^,]+" }} }}
    {{ authors max="1" suffix=" et al" }}
    {{ else }}
    {{ authors join="_" }}
    {{ endif }}

    https://s3.amazonaws.com/zotero.org/images/forums/u9553762/o8bqhxmlrh8x1agn0icy.png
  • Ensure there is no space character at the end of the line, as Zotero will not inject extra spaces. Also, make sure you are using the most recent version of Zotero, as earlier beta versions might have replaced newline characters with spaces.

    https://s3.amazonaws.com/zotero.org/images/forums/u3978561/qy40i86hukcejrdpo4dk.png
  • @tnajdek The problem is completely what you say in the first suggestion! I checked my setting and found that there is some space characters at the end of some lines. Thank you for this contribution!
  • From the documentation, we can use `replaceFrom` for the title with the `regexOpts` flag to remove all the white space. By the way, I am also curious about how to post the code in the form of a Markdown code block. @tnajdek

    @iagogv This template may be helpful for you.
    ```
    {{ if {{ authors match="[^,]+,[^,]+,[^,]+" }} }}
    {{ authors max="1" suffix="_etal" }}
    {{ else }}
    {{ authors join=" and " replaceFrom="\s+" replaceTo="_" regexOpts="g" }}
    {{ endif }}
    {{ year prefix="-" }}
    {{ title truncate="80" replaceFrom="(\.|:|\?)(.*?)$" prefix="-" replaceFrom="\s+" replaceTo="_" regexOpts="g" }}
    ```
  • @RamonMi

    Unfortunately, the last part of your template won't work, as you can only specify one set of replaceFrom/replaceTo per variable. As I explained above, using case="snake" is the best the current system can do.
    By the way, I am also curious about how to post the code in the form of a Markdown code block.
    The forum supports a small subset of HTML tags. For code blocks, I'm using <code>.
  • Thank you @tnajdek. I got it. I didn't notice earlier that only one replaceFrom is allowed per variable.
Sign In or Register to comment.