Community
    • Login

    How to implement Notetab outline files?

    Scheduled Pinned Locked Moved General Discussion
    udl
    5 Posts 3 Posters 865 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • David SpectorD
      David Spector
      last edited by David Spector

      I’m moving to NPP from Notetab Pro because it doesn’t handle Unicode. So far, the only feature I’m having trouble with is Notetab Outline files (with an extension of .otl), which have an index of named entries, and text for each entry. An Outline file displays one entry at a time, hiding all the others. It is a way of combining many files of related text into one text file. I want to implement Outline files as a User Defined Language, so I can use Code Folding to hide all but one entry at a time.

      Here is an example of a Notetab outline file, showing its actual rather than displayed content:

      = V4 Outline MultiLine NoSorting TabWidth=30
      
      H="A"
      Text for heading A
      
      H="B"
      Text for heading B
      
      

      The NPP XML file is quite long, so I won’t include it here, but all I’ve defined is in the Menu > Language > Define your language > Folder & Default tab > “Folding in code 1 style” section.

      Open contains H=" and Close contains ((EOL)).

      This almost works, but when I close (hide) entry (heading) A, it also closes heading B and all the rest of the headings, if any. Perhaps it’s doing a greedy regular expression match instead of ungreedy.

      Can anyone suggest an improvement?

      1 Reply Last reply Reply Quote 0
      • EkopalypseE
        Ekopalypse
        last edited by

        UDL doesn’t do regex at all. It goes through each char and checks the condition.

        UDL works best if it has unique tags like let’s say open H= and close !H
        but not sure if this can be done in your case. Maybe a fake comment
        can be used to define the closing tag?

        1 Reply Last reply Reply Quote 1
        • PeterJonesP
          PeterJones
          last edited by PeterJones

          @David-Spector said,

          Close contains ((EOL)).

          I think the problem is that ((EOL)) doesn’t mean quite what you think it means. If you look at https://ivan-radic.github.io/udl-documentation/delimiters/, where ((EOL)) has the most examples, it’s always ending the match on the same line that the match started. It’s not matching the first blank line – it’s matching the first end-of-line after the start.

          However, in Folding rules, that doesn’t make sense, because you cannot fold from the start of a line to the end of that same line. It appears the Folding rules ignore ((EOL)) completely.

          I did verify that you can use (( blah1 blah2 )) to get it to close on either blah1 or blah2, so it’s not completely igorning the ((...)) notation.

          Can anyone suggest an improvement?

          I thought of setting Open and Middle to H=", and leaving Close empty; unfortunately, that’s got two problems: 1) it never closes; 2) if there were some way to close it, it’s actually nesting those, rather than treating the middle H=" as a Middle. :-(

          I think @Ekopalypse has the best idea.

          Either that, or find/write/contract-out-for a true lexer plugin that properly handles the structure. (Or play with the UDL 2.1 code, and see if you can implement a fix, like a (( )) notation that indicates blank line … maybe ((EOLEOL)), and then put in a Pull Request.)

          Unfortunately, UDL – though nice – is not meant to replace all the possibilities inherent in a true lexer plugin.

          1 Reply Last reply Reply Quote 2
          • David SpectorD
            David Spector
            last edited by David Spector

            I substituted \n for ((EOL)) and the behavior was the same: you can’t fold and unfold each entry separately.

            The UDL parser is working fine, but not defining each entry as a separate item.

            I’ll try the “end of entry” suggestion soon.

            1 Reply Last reply Reply Quote 0
            • David SpectorD
              David Spector
              last edited by

              I’ve got this task done. It should be useful to others moving from NoteTab to Notepad++.

              I’ve added an end-of-outline-entry symbol “End=Entry” that should appear at the end of each entry. I’ve also written a migration program in PHP to insert these end-of-outline-entry symbols automatically into outline files (.otl). I’m using the “.out” extension for the output of this program. These .out files will be “outline” files in Notepad++.

              Here is the migration program:

              <?php
              
              //--------------------------------------------------------------------//
              //		Program to migrate .otl files to .out files
              //		Springtime Software, David Spector, 10/3/19, public domain.
              //--------------------------------------------------------------------//
              
              define("NL","
              ");
              $FileName=GetGetArg();
              $PathIn="$FileName.otl";
              $PathOut="$FileName.out";
              $C=file_get_contents($PathIn,true);
              $Lines=explode(NL,$C);
              
              // Delete two header lines
              array_shift($Lines);
              array_shift($Lines);
              
              $firstLine=true;
              $bloat=0;
              foreach ($Lines as $n=>$Line)
              	{
              	$R=preg_match('@^H=@',$Line,$F);
              	if ($R && !$firstLine)
              		{
              		array_splice($Lines,$n+$bloat,0,"End=Entry");
              		++$bloat;
              		}
              	$firstLine=false;
              	}
              
              // Terminate last entry
              array_splice($Lines,$n+$bloat+1,0,"End=Entry");
              
              $C=implode("\n",$Lines);
              
              $BytesOrFalse=file_put_contents($PathOut,$C);
              
              function GetGetArg()
              	{
              	foreach ($_GET as $ArgName=>$ArgVal)
              		{
              		return $ArgName;
              		} // Each expected arg
              	} // GetGetArg
              ?>
              
              1 Reply Last reply Reply Quote 2
              • First post
                Last post
              The Community of users of the Notepad++ text editor.
              Powered by NodeBB | Contributors