Back

If your email is not recognized and you believe it should be, please contact us.

  • You must be logged in to reply to this topic.Login

Edit script to convert certain paragraph-style to sidenotes.

Return to Member Forum

  • Author
    Posts
    • #82141
      Ari Singer
      Member

      Hi, I’m not familiar with writing scripts so this is my question.
      I found an excellent script by Peter Kahrel (www.kahrel.plus.com) which takes all footnotes and converts it side-notes by anchoring text frames with an object style applied to place it at the side of the page. It’s a very powerful script, but it is not precisely what I’m looking for.
      I would like to create “side-headers” that give a glimpse of what the adjacent paragraph is about. So I would like the script should take every instance of text which has the “SIDE HEADER” paragraph-style applied, cut it out and paste it in a small text frame that should be anchored in beginning of the following paragraph (which has the “BODY TEXT” paragraph-style applied), and stay at the side of that text.
      Basically, it’s exactly what the script does, just that instead of selecting the footnotes, I want it to select any text that has a certain paragraph-style, and anchor the frame in the following paragraph.

      I would be very grateful to anyone who could help me with this.

      Following is the original script:

      //DESCRIPTION: Convert InDesign’s footnotes to dynamic sidenotes
      // Peter Kahrel – http://www.kahrel.plus.com

      //#target indesign

      // Only CS4 and later
      if (parseInt (app.version) > 5 && app.documents.length > 0)
      {
      try {foot_to_side (app.documents[0], “sidenote”)}
      catch (e) {alert (e.message + ” (line ” + e.line + “)”)};
      }

      function foot_to_side (doc, stylename)
      {
      var side_frame, endnote, footn, endnote_link, reference;
      var dimensions = sidenote_coordinates (doc);
      var win = create_message (40, “Sidenotes”);
      win.show();
      var styles = check_styles (doc, stylename, dimensions);
      var stories = find_stories (doc);
      for (var j = 0; j < stories.length; j++)
      {
      if (stories[j].footnotes.length > 0)
      {
      footn = stories[j].footnotes;
      for (var i = footn.length-1; i > -1; i–)
      {
      win.message.text = “Story ” + String (j) + ” — ” + “note ” + String (i);

      // must delete the note marker here to ensure that fit() works ok
      delete_notemarkers (footn[i].texts[0]);

      // Create a frame at the footnote reference’s position
      side_frame = add_frame (footn[i].storyOffset, styles.o_style, dimensions.width);

      // Move the footnote’s contents to the new frame
      endnote = footn[i].texts[0].move (LocationOptions.after, side_frame.insertionPoints[0]);

      // Apply sidenote text style
      endnote.applyParagraphStyle (styles.ps_numbered, false);
      if (endnote.paragraphs.length > 1)
      endnote.paragraphs.itemByRange (1,-1).applyParagraphStyle (styles.ps, false);

      if (dimensions.numbered == true)
      {
      // Create cross-reference — three steps
      endnote_link = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
      reference = doc.crossReferenceSources.add (footn[i].storyOffset, styles.cr_format);
      doc.hyperlinks.add (reference, endnote_link, {visible: false});
      }

      side_frame.fit (FitOptions.frameToContent);
      } // for var i

      // now delete the notes from the text
      delete_notemarkers (stories[j]);
      } // if stories[j]
      } // for var j
      win.message.parent.close ();
      if (dimensions.numbered == true)
      {
      //doc.paragraphStyles.item(‘n’).numberingFormat = get_format(n_styles.selection.index);
      //doc.paragraphStyles.item(‘n’).numberingStartAt = 1;
      doc.crossReferenceSources.everyItem().update();
      }
      }

      function find_stories (doc)
      {
      var array = [];
      // no selection: return all stories
      if (app.selection.length == 0)
      {
      return doc.stories.everyItem().getElements();
      }
      else
      {
      try {app.selection[0].parentStory; return [app.selection[0].parentStory]}
      catch (e) {alert (“Invalid selection”, “Convert footnotes”, true); exit ()}
      }
      }

      function add_frame (ins_point, style, width)
      {
      var sidebar = ins_point.textFrames.add ();
      if (parseInt (app.version) < 8)
      { // Maybe this isn’t needed in any version, but we’ll leave it.
      sidebar.geometricBounds = [0, 0, “20pt”, width];
      }
      sidebar.label = style.name;
      sidebar.appliedObjectStyle = style;
      return sidebar
      }

      function delete_notemarkers (there)
      {
      app.findGrepPreferences = app.changeGrepPreferences = null;
      app.findChangeGrepOptions.includeFootnotes = true;
      app.findGrepPreferences.findWhat = ‘~F’;
      there.changeGrep ();
      }

      function check_styles (doc, s, sidenote)
      {
      var styles = text_styles (doc, s, sidenote);
      footnote_options (doc);
      if (doc.objectStyles.item (s) == null)
      {
      with (doc.objectStyles.add ({name: s}))
      {
      // Store the width of the frame so we can use that later when adding notes semi-manually
      // We’ll store the value in points (Don’t do this any longer, frames are set to fixed width
      //label = convert_units (sidenote.width, “pt”);
      basedOn = doc.objectStyles[0];
      enableParagraphStyle = true;
      appliedParagraphStyle = styles.ps_numbered;
      enableStroke = true;
      strokeWeight = 0;
      enableAnchoredObjectOptions = true;
      with (anchoredObjectSettings)
      {
      spineRelative = true;
      anchoredPosition = AnchorPosition.anchored;
      anchorPoint = AnchorPoint.topRightAnchor;
      //horizontalReferencePoint = AnchoredRelativeTo.columnEdge;
      horizontalReferencePoint = AnchoredRelativeTo.pageMargins;
      anchorXoffset = sidenote.gutter;
      horizontalAlignment = HorizontalAlignment.leftAlign;
      verticalReferencePoint = VerticallyRelativeTo.capheight;
      pinPosition = true;
      }
      enableTextFrameGeneralOptions = true;
      textFramePreferences.useFixedColumnWidth = true;
      textFramePreferences.textColumnFixedWidth = sidenote.width;
      } // with
      } // if (doc.objectStyles.item (s) == null)
      styles.o_style = doc.objectStyles.item (s);
      return styles;
      }

      function text_styles (doc, n, sidenote)
      {
      // unnumbered par. style for second and further paragraphs in a note
      var ps_next = doc.footnoteOptions.footnoteTextStyle;
      ps_next.justification = Justification.toBindingSide;
      // create a new par style, based on ps_next, for the numbered (first) paragraph in each note
      var numpar = ps_next.name.replace (/[\[\]]/g, “”) + “_numbered”;
      try {
      var ps_num = doc.paragraphStyles.add ({name: numpar, basedOn: ps_next});
      }
      catch (_) {var ps_num = doc.paragraphStyles.item (numpar)};

      if (sidenote.numbered == true)
      {
      try
      {
      var numlist = doc.numberingLists.add ({name: n});
      numlist.continueNumbersAcrossStories = true;
      numlist.continueNumbersAcrossDocuments = true;
      ps_num.numberingFormat = sidenote.number_format;
      ps_num.numberingStartAt = sidenote.start_number;
      } catch (_) {var numlist = doc.numberingLists.item (n)};

      // create char. style for references if no char style is set in the Footnote options window
      if (doc.footnoteOptions.footnoteMarkerStyle == doc.characterStyles[0])
      {
      try
      {
      var cue_style = doc.characterStyles.add ({name: n + “_reference”});
      cue_style.position = Position.superscript;
      } catch (_) {var cue_style = doc.characterStyles.item (n + “_reference”)};
      }
      else
      var cue_style = doc.footnoteOptions.footnoteMarkerStyle;

      // char style for the numbers in the notes
      try
      {
      var char_style = doc.characterStyles.add ({name: n + “_number”});
      } catch (_) {};

      try
      {
      var cr = doc.crossReferenceFormats.add ({name: n});
      cr.appliedCharacterStyle = cue_style;
      cr.buildingBlocks.add (BuildingBlockTypes.paragraphNumberBuildingBlock);
      } catch (_) {var cr = doc.crossReferenceFormats.item (n)};

      try
      {
      ps_num.appliedNumberingList = numlist;
      ps_num.bulletsAndNumberingListType = ListType.numberedList;
      ps_num.tabList = [{position: “12pt”, alignment: TabStopAlignment.leftAlign}];
      ps_num.numberingCharacterStyle = char_style;
      } catch (_) {};
      }
      return {ps_numbered: ps_num, ps: ps_next, cr_format: cr}
      }

      function footnote_options (doc) {doc.footnoteOptions.separatorText = “”;}

      // Interface =================================================================

      function sidenote_coordinates (doc)
      {
      var number_styles = [‘1, 2, 3, 4. . .’,
      ‘01,02,03…’,
      ‘I, II, III, IV…’,
      ‘i, ii, iii, iv…’,
      ‘A, B, C, D,…’,
      ‘a, b, c, d…’,
      ‘001,002,003…’,
      ‘0001,0002,0003…’,
      ];

      var w = new Window (‘dialog’, ‘Sidenotes’, undefined, {closeButton: false});
      var doc_unit = doc_units ();
      //~ w.alignChildren = [‘right’, ‘top’];
      w.alignChildren = ‘fill’;
      var main = w.add (‘panel’);
      main.alignChildren = [‘right’, ‘top’];
      main.orientation = ‘column’;
      var g1 = main.add (‘group’);
      g1.add (‘statictext’, undefined, ‘Width of the notes: ‘);
      var width = g1.add (‘edittext’);
      width.characters = 12;
      width.text = convert_units (“70 pt”, doc_unit);
      width.active = true;
      var g2 = main.add (‘group’);
      g2.add (‘statictext’, undefined, ‘Space between note and text: ‘);
      var space = g2.add (‘edittext’);
      space.text = convert_units (“12 pt”, doc_unit);
      space.characters = 12;

      var numbering_group = w.add (‘panel {orientation: “row”}’); // numbering_group.orientation= “stack”

      var numbered = numbering_group.add (‘checkbox {text: “\u00A0Numbering”, alignment: [“left”,”top”]}’);

      var panel = numbering_group.add (‘panel {alignChildren: “right”}’);

      var g1 = panel.add (‘group’);
      g1.add (‘statictext’, undefined, ‘Style:’);
      var n_styles = g1.add (‘dropdownlist’, undefined, number_styles);
      n_styles.preferredSize.width = 100;

      var g2 = panel.add (‘group’);
      g2.add (‘statictext’, undefined, ‘Start at:’);
      var start_value = g2.add (‘edittext’, undefined, ‘1’);
      start_value.preferredSize.width = 100;

      numbered.value = true;
      n_styles.selection = 0;

      numbered.onClick = function ()
      {
      panel.enabled = this.value;
      }

      start_value.onDeactivate = function ()
      {
      if (this.text.search (/^\d+$/) < 0)
      {
      alert (‘Enter an arabic number.’);
      start_value.active = true;
      }
      }

      var buttons = w.add (‘group’);
      buttons.orientation = ‘row’;
      buttons.alignChildren = [‘right’, ‘bottom’];
      buttons.add (‘button’, undefined, ‘OK’);
      buttons.add (‘button’, undefined, ‘Cancel’, {name: ‘cancel’});

      width.onChange = function () {width.text = convert_units (width.text, doc_unit)};
      space.onChange = function () {space.text = convert_units (space.text, doc_unit)};

      if (w.show () == 2) exit ();

      return {width: width.text,
      gutter: space.text,
      numbered: numbered.value,
      number_format: get_format(n_styles.selection.index),
      start_number: Number (start_value.text)
      }
      }

      function get_format (index)
      {
      return [
      NumberingStyle.ARABIC,
      NumberingStyle.SINGLE_LEADING_ZEROS,
      NumberingStyle.UPPER_ROMAN,
      NumberingStyle.LOWER_ROMAN,
      NumberingStyle.UPPER_LETTERS,
      NumberingStyle.LOWER_LETTERS,
      NumberingStyle.DOUBLE_LEADING_ZEROS,
      NumberingStyle.TRIPLE_LEADING_ZEROS][index];
      }

      function convert_units (n, to)
      {
      var m = [];
      m[“ag”] = 5.1428571428;
      m[“p”] = 12.0000000000;
      m[“mm”] = 2.8346456692;
      m[“cm”] = 28.3464566929;
      m[“in”] = 72.00000000;
      m[“c”] = 12.7878751998;
      m[“tr”] = 3.0112500000; // traditional point — but we don’t do anything with it yet
      m[“pt”] = 1.0000000000;
      obj = fix_measurement (n);
      var temp = (obj.amount * m[obj.unit]) / m[to];
      return output_format (temp, to)
      }

      // Add the target unit to the amount, either suffixed pt, ag, mm, cm, in,
      // or infixed p or c

      function output_format (amount, target)
      {
      amount = amount.toFixed (3).replace (/\.?0+$/g, “”);
      if (target.length == 2) // two-character unit: pt, mm, etc.
      return String (amount) + ” ” + target;
      else // “p” or “c”
      {
      // calculate the decimal
      var decimal = (Number (amount) – parseInt (amount)) * 12;
      // return the integer part of the result + infix + formatted decimal
      return parseInt (amount) + target + decimal;
      }
      }

      function fix_measurement (n)
      {
      // infixed “p” and “c” to decimal suffixes: 3p4 > 3.5 p
      n = n.replace (/(\d+)([pc])([.\d]+)$/, function () {return Number (arguments[1]) + Number (arguments[3]/12) + arguments[2]});
      // add unit if necessary
      n = n.replace (/(\d)$/, “$1” + doc_units (app.documents[0]))
      // split on unit
      var temp = n.split (/(ag|cm|mm|c|pt|p|in)$/);
      if (temp.length == 1)
      return {amount: Number (temp[0]), unit: doc_units ()};
      else
      return {amount: Number (temp[0]), unit: temp[1]};
      }

      function doc_units ()
      {
      switch (app.documents[0].viewPreferences.horizontalMeasurementUnits)
      {
      case 2051106676: return ‘ag’;
      case 2053336435: return ‘cm’;
      case 2053335395: return ‘c’;
      case 2053729891: return ‘in’;
      case 2053729892: return ‘in’;
      case 2053991795: return ‘mm’;
      case 2054187363: return ‘p’;
      case 2054188905: return ‘pt’;
      }
      }

      function errorM (m)
      {
      alert (m, “Error”, true)
      exit ()
      }

      function progress_bar (stop, title)
      {
      var w = new Window (‘palette’, title);
      w.pbar = w.add (‘progressbar’, undefined, 0, stop);
      w.pbar.preferredSize.width = 300;
      return w;
      }

      function create_message (le, title)
      {
      var w = new Window (“palette”, title);
      w.alignChildren = [“left”, “top”];
      w.message = w.add (“statictext”, undefined, “”);
      w.message.characters = le;
      return w;
      }

    • #93685
      Anonymous
      Inactive

      Did you find a solution? I am looking for the exact same thing.

    • #93687

      (^/)

    • #93690
      David Blatner
      Keymaster

      Olav Martin Kvern created a “convert to side heading” script for when we wrote Real World InDesign. It takes a heading paragraph into an anchored frame and moves the frame to the correct position. However, I tried it now and it’s not working… do you want me to ask Ole if he can fix it?

      • #14340005
        Agata Czapiewska
        Participant

        Hi, David, it would be really great if the script you have mentioned could be updated to work with InDesign 2021. I would certainly buy it.

      • #14340021
        David Blatner
        Keymaster

        @Agata: Do the other scripts here in this thread work for you?

      • #14340074
        Agata Czapiewska
        Participant

        The one that converts footnotes to sidenotes works, but that’s not what I’m looking for. I would like to make ome paragraph style jump to the margin into pre-defined anchored frames. Because I am no expert in writing scripts, I am looking for a ready-to-go script that I can download and start using without editing it. I hope it is possible.

      • #14340079

        See above!

        (^/)

    • #93693

      I wrote something for our german forum years ago: The script assumes a object-style “SIDE HEADER” with textframe width, auto height and anchoring options.

      var curDoc = app.documents[0]; 
       
      // Zurücksetzen der Sucheinstellungen   
      app.findGrepPreferences = app.changeGrepPreferences = null; 
      // Setzen der Sucheinstellungen   
      app.findGrepPreferences.appliedParagraphStyle = curDoc.paragraphStyles.itemByName("SIDE HEADER"); 
       
      // Suchen und Ergebnisse in Variable speichern   
      var results = curDoc.findGrep(true);   
       
      // Den Text in einen neuen Rahmen verschieben   
      for (var n = 0; n < results.length; n++) {
          
        var curResult = results[n];
        var a = curResult.insertionPoints[-1];
        var newTf = a.textFrames.add();
        newTf.appliedObjectStyle = curDoc.objectStyles.itemByName("SIDE HEADER");
      
        var myTextToMove = curResult.characters.itemByRange(0,-1);
        myTextToMove.move(LocationOptions.AFTER, newTf.insertionPoints[0]);
       
        // Zurücksetzen der Sucheinstellungen   
        app.findGrepPreferences = app.changeGrepPreferences = null;
        // Suchen nach
        app.findGrepPreferences.findWhat = "r+"; 
        // Ändern in
        app.changeGrepPreferences.changeTo = "";
        // Alle Ändern
        newTf.changeGrep();
      }  
       
      // Zurücksetzen der Sucheinstellungen   
      app.findGrepPreferences = app.changeGrepPreferences = null;
      
      
      Kai
Viewing 4 reply threads
  • The forum ‘General InDesign Topics (CLOSED)’ is closed to new topics and replies.
Forum Ads