• Login
Community
  • Login

How to implement Notetab outline files?

Scheduled Pinned Locked Moved General Discussion
udl
5 Posts 3 Posters 872 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.
  • D
    David Spector
    last edited by David Spector Sep 27, 2019, 2:52 PM Sep 27, 2019, 2:49 PM

    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
    • E
      Ekopalypse
      last edited by Sep 27, 2019, 3:04 PM

      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
      • P
        PeterJones
        last edited by PeterJones Sep 27, 2019, 3:33 PM Sep 27, 2019, 3:33 PM

        @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
        • D
          David Spector
          last edited by David Spector Sep 27, 2019, 4:43 PM Sep 27, 2019, 4:40 PM

          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
          • D
            David Spector
            last edited by Oct 3, 2019, 4:00 PM

            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
            5 out of 5
            • First post
              5/5
              Last post
            The Community of users of the Notepad++ text editor.
            Powered by NodeBB | Contributors