#@+leo-ver=4-thin #@+node:ekr.20031218072017.329:@thin ../doc/leoNotes.txt #@@nocolor This contains my notes for the Leo project. #@+all #@+node:ekr.20031218072017.365:How to... #@+node:ekr.20031218072017.366:How to add and remove files from CVS repository use the command line option in the admin menu to do the following: add leoConfig.py and leoConfig.txt cvs add leoConfig.txt cvs add leoConfig.py (then do commit) remove readme*.doc remove files from working area (done) cvs remove readme1.doc cvs remove readme2.doc ... (then do commit) #@nonl #@-node:ekr.20031218072017.366:How to add and remove files from CVS repository #@+node:ekr.20031218072017.384:How to export syntax colored code preserving colors Scite has the option to "Export as html" and "export as rtf", and it will be full of colour and fonts - and you can define them in properties, so it will be the same as during editing. #@nonl #@-node:ekr.20031218072017.384:How to export syntax colored code preserving colors #@+node:ekr.20031218072017.385:How to Increase environment space To increase the size of environment space, add the following to config.sys: shell=C:\windows\command\command.com /p:4096 Notes: 1. The path C:\windows\command\command.com may vary. Check you system for the location of command.com. 2. This works for versions of Windows prior to Me. On Me you set the registry somehow. No information on XP. #@nonl #@-node:ekr.20031218072017.385:How to Increase environment space #@+node:ekr.20031218072017.386:How to remove cursed newlines: use binary mode teknico ( Nicola Larosa ) RE: Removing '\r' characters? 2002-09-16 14:27 > I am plowing through old bug reports, and I found the following, from whom > I don't know: That's from me, *again*. You are kindly advised to stop forgetting the attribution to all my bug reports. ;^) >> - Source files still have the dreaded \r in them. Why don't you switch >> to \n only, once and for all, and live happily ever after? ;^) > I sure whould like to do that, and I'm not sure how to do this. All > versions of the read code attempt to remove '\r' characters, and all > versions of the write code write '\n' only for newlines. Sorry for being a bit vague, I was talking about the Leo source files themselves. I don't know what you use to edit them, ;^))) but in version 3.6 they still have \r\n as end-of-line. If Leo itself does not solve the problem, may I suggest the Tools/scripts/crlf.py script in the Python source distibution? It's nice and simple, and skips binary files, too. That's what I use every time I install a new version of Leo. :^) #@+node:ekr.20031218072017.387:The solution Under unix, python writes "\n" as "\n"; under windows, it writes it as "\r\n". The unix python interpreter ignores trailing "\r" in python source files. There are no such guarantees for other languages. Unix users should be able to get rid of the cosmetically detrimental "\r" either by running dos2unix on the offending files, or, if they're part of a .leo project, reading them into leo and writing them out again. By: edream ( Edward K. Ream ) RE: Removing '\r' characters? 2002-09-17 09:34 Oh, I see. Thanks very much for this clarification. Just to make sure I understand you: the problem with '\r' characters is that: 1. I am creating LeoPy.leo and LeoDocs.leo on Windows and 2. People are then using these files on Linux. and the way to remove the '\r' characters: 1. I could run dos2unix on all distributed files just before committing to CVS or making a final distribution or 2. People could, say, do the following: Step 1: Read and Save the .leo files, thereby eliminating the '\r' in those files and Step 2: Use the Write @file nodes command on all derived files to clear the '\r' in those files. Do you agree so far? > Under unix, python writes "\n" as "\n"; under windows, it writes it as "\r\n". I am going to see if there is any way to get Python to write a "raw" '\n' to a file. I think there must be. This would solve the problem once and for all. Thanks again for this most helpful comment. Edward #@nonl #@-node:ekr.20031218072017.387:The solution #@+node:ekr.20031218072017.388:cursed newline answer In 2.3 you can open files with the "U" flag and get "universal newline" support: % python Python 2.3a0 (#86, Sep 4 2002, 21:13:00) [GCC 2.96 20000731 (Mandrake Linux 8.1 2.96-0.62mdk)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> f = open("crlf.txt") >>> line = f.readline() >>> line 'This is an example of what I have come to call the "cursed newline" problem,\r\n' >>> f = open("crlf.txt", "rU") >>> line = f.readline() >>> line 'This is an example of what I have come to call the "cursed newline" problem,\n' #@-node:ekr.20031218072017.388:cursed newline answer #@+node:ekr.20031218072017.389:cursed newline answer 2 > You can open the file in 'binary' mode (adding 'b' to the mode string) and > the file will contain '\r\n' on both platforms (and any other platforms.) Nope. Exactly wrong. In 2.2 and those before, when files are opened in *text* mode (no "b") then reading them will provide Unix-style line endings (newline only). When you open files in binary mode then you see the bytes stored in the file. On Unix systems there's no difference in the contents of a file whether in binary or text mode. On Windows a file is shorter by the number of carriage returns. On the Mac I have no idea what they do. Probably just carriage returns, to be different :-) 2.3 will be a bit more flexible about such mattrers. #@-node:ekr.20031218072017.389:cursed newline answer 2 #@-node:ekr.20031218072017.386:How to remove cursed newlines: use binary mode #@+node:ekr.20031218072017.390:How to run Pychecker import pychecker.checker ; import leo #@nonl #@-node:ekr.20031218072017.390:How to run Pychecker #@+node:ekr.20031218072017.391:How to use CVS branches @nocolor I have a fair bit of expertise on CVS branches. It's late at night, so I don't have time for a long soapbox spiel at the moment. I will try to post something tomorrow. The brief picture is: * Check out code from CVS at the point you want to create the branch. * Make sure none of the files in your sandbox is modified. * Create the branch (cvs tag -b branchname). The branch name must start with a letter (upper or lower case) and thereafter can have alphanumeric characters, hyphens, and underscores (no periods or spaces). * The branch is created on the repository, but your sandbox is still checked out on the main branch. To check out on the new branch, do "cvs up -r branchname". When you want to merge changes back into the main branch, you can use "cvs up -r MAIN" to retrieve the main branch, then "cvs up -j branchname" to merge changes, then "cvs commit" to commit the merged version to the main branch AFTER YOU HAVE VERIFIED IT. I would recommend caution with merging because as you have noted, leo files are not well set up for CVS. They don't merge well because of inconsistent sentinel values. You may want to look at manually merging changes back into the main branch until leo implements invariant unique (UUID) sentinel indices. This will not hurt your ability to use branches, only your ability to automatically merge changes from one branch onto another. #@nonl #@-node:ekr.20031218072017.391:How to use CVS branches #@+node:ekr.20031218072017.392:Python Notes & HowTo's... #@+node:ekr.20031218072017.393:What's new for each version: New in 2.2 (Do not use) - Iterators/Generators - Nested Scopes - New Classes The what's new for each version: http://www.amk.ca/python/2.0/ http://www.amk.ca/python/2.1/ #@+node:ekr.20031218072017.394:@url http://www.python.org/2.3/highlights.html #@-node:ekr.20031218072017.394:@url http://www.python.org/2.3/highlights.html #@+node:ekr.20031218072017.395:@url http://www.amk.ca/python/2.1/ #@-node:ekr.20031218072017.395:@url http://www.amk.ca/python/2.1/ #@+node:ekr.20031218072017.396:@url http://www.amk.ca/python/2.0/ #@-node:ekr.20031218072017.396:@url http://www.amk.ca/python/2.0/ #@-node:ekr.20031218072017.393:What's new for each version: #@+node:ekr.20031218072017.397:Default values & keyword arguments @nocolor 1. You specify default values of _formal parameters_ in a def statement. 2. You specify keywords arguments in a _function call_. 3. An argument list must have any positional arguments followed by any keyword arguments, where the keywords must be chosen from the formal parameter names. It's not important whether a formal parameter has a default value or not. 4. No argument may receive a value more than once. 5. When a final formal parameter of the form **name is present, it receives a dictionary containing all keyword arguments whose keyword doesn't correspond to a formal parameter. EKR Notes: 1. I have been confusing default values with keyword arguments. _Any_ formal parameter may be specified with a keyword argument! 2. Arbitrary keyword params can be used if the def has an **arg. #@nonl #@-node:ekr.20031218072017.397:Default values & keyword arguments #@+node:ekr.20031218072017.398:How to call any Python method from the C API In general, everything you can do in Python is accessible through the C API. lines = block.split('\n'); > That will be lines = PyObject_CallMethod(block, "split", "s", "\n"); #@-node:ekr.20031218072017.398:How to call any Python method from the C API #@+node:ekr.20031218072017.399:How to run Python programs easily on NT,2K,XP #@+node:ekr.20031218072017.400:setting the PATHEXT env var It is worth noting that NT, Win2K and XP all have an alternative which is to add .PY to the PATHEXT environment variable. Then you can run any .PY file directly just by typing the name of the script without the extension. e.g. C:\>set PATHEXT=.COM;.EXE;.BAT;.CMD C:\>set PATH=%PATH%;c:\python22\tools\Scripts C:\>google 'google' is not recognized as an internal or external command, operable program or batch file. C:\>set PATHEXT=.COM;.EXE;.BAT;.CMD;.PY C:\>google Usage: C:\python22\tools\Scripts\google.py querystring C:\> #@-node:ekr.20031218072017.400:setting the PATHEXT env var #@+node:ekr.20031218072017.401:Yet another Python .bat wrapper >> It has a header of just one line. All the ugly stuff is at the end. >> >> ------------------------------------------------------------------- >> goto ="python" >> >> # Python code goes here >> >> ''' hybrid python/batch footer: >> @:="python" >> @python.exe %0 %1 %2 %3 %4 %5 %6 %7 %8 %9 >> @if errorlevel 9009 echo Python may be downloaded from >www.python.org/download >> @rem ''' >> ------------------------------------------------------------------- >> >> Oren >> > It's for running python scripts on windows, without having to type: [\]python[.exe] [*] and almost takes the place of the "shabang" line at the top of *nix scripts. #@-node:ekr.20031218072017.401:Yet another Python .bat wrapper #@-node:ekr.20031218072017.399:How to run Python programs easily on NT,2K,XP #@-node:ekr.20031218072017.392:Python Notes & HowTo's... #@+node:ekr.20031218072017.367:How to add support for a new language @nocolor - Add a new entries in << define global data structures >> app - Add a new Tk.Radiobutton in <> - Add an entry to the languages list in <> - Add a list of the keywords of the language to << define colorizer keywords >> N.B.: the name of this list must be x_keywords, where x is the entry in language in step a. - Add any language-specifig code to leoColor.colorizeAnyLanguage. For most languages nothing need be done in this step. TESTS - Test the syntax coloring for the new language by using the @language directive. - Test workings of the Preferences Panel by choosing the language in the panel and by looking at code that is _not_ under control of an @language directive. - Test the leoConfig.txt by setting default_target_language to the name of the new language. When you restart Leo, the new language should be selected in the Prefs panel. - Remove leoConfig.txt, select the new language in the Prefs panel, and save the .leo file. Open the file with a text editor and check to make sure that the tag (near the top) contains an entry like this: but with the name of your new language instead of "Python". - Create an @root node and verify that you can Tangle it. @color #@nonl #@+node:ekr.20031218072017.368:<< define global data structures >> app # Internally, lower case is used for all language names. self.language_delims_dict = { "actionscript" : "// /* */", #jason 2003-07-03 "c" : "// /* */", # C, C++ or objective C. "csharp" : "// /* */", # C# "css" : "/* */", # 4/1/04 "cweb" : "@q@ @>", # Use the "cweb hack" "elisp" : ";", "forth" : "_\\_ _(_ _)_", # Use the "REM hack" "fortran" : "C", "fortran90" : "!", "html" : "", "java" : "// /* */", "latex" : "%", "pascal" : "// { }", "perl" : "#", "perlpod" : "# __=pod__ __=cut__", # 9/25/02: The perlpod hack. "php" : "//", "plain" : "#", # We must pick something. "python" : "#", "rapidq" : "'", # fil 2004-march-11 "rebol" : ";", # jason 2003-07-03 "shell" : "#", # shell scripts "tcltk" : "#", "unknown" : "#" } # Set when @comment is seen. self.language_extension_dict = { "actionscript" : "as", #jason 2003-07-03 "c" : "c", "css" : "css", # 4/1/04 "cweb" : "w", "elisp" : "el", "forth" : "forth", "fortran" : "f", "fortran90" : "f", "html" : "html", "java" : "java", "latex" : "tex", # 1/8/04 "noweb" : "nw", "pascal" : "p", "perl" : "perl", "perlpod" : "perl", "php" : "php", "plain" : "txt", "python" : "py", "rapidq" : "bas", # fil 2004-march-11 "rebol" : "r", # jason 2003-07-03 "shell" : "sh", # DS 4/1/04 "tex" : "tex", "tcltk" : "tcl", "unknown" : "txt" } # Set when @comment is seen. self.extension_dict = { "as" : "actionscript", "bas" : "rapidq", "c" : "c", "css" : "css", "el" : "elisp", "forth" : "forth", "f" : "fortran90", # or fortran ? "html" : "html", "java" : "java", "noweb" : "nw", "p" : "pascal", "perl" : "perl", "php" : "php", "py" : "python", "r" : "rebol", "sh" : "shell", "tex" : "tex", "txt" : "plain", "tcl" : "tcltk", "w" : "cweb" } #@-node:ekr.20031218072017.368:<< define global data structures >> app #@+node:ekr.20031218072017.369:<< Create the Target Language frame >> frame # Frame and title w,target = gui.create_labeled_frame (outer,caption="Default Target Language") w.pack(padx=2,pady=2,expand=1,fill="x") # Frames for two columns of radio buttons lt = Tk.Frame(target) rt = Tk.Frame(target) lt.pack(side="left") rt.pack(side="right") # Left column of radio buttons. left_data = [ ("ActionScript", "actionscript"), ("C#", "csharp"), ("C/C++", "c"), ("CSS", "css"), ("CWEB", "cweb"), ("elisp", "elisp"), ("HTML", "html"), ("Java", "java"), ("LaTeX", "latex"), ("Pascal","pascal")] for text,value in left_data: button = Tk.Radiobutton(lt,anchor="w",text=text, variable=self.lang_var,value=value,command=self.set_lang) button.pack(fill="x") # Right column of radio buttons. right_data = [ ("Perl", "perl"), ("Perl+POD", "perlpod"), ("PHP", "php"), ("Plain Text", "plain"), ("Python", "python"), ("RapidQ", "rapidq"), ("Rebol", "rebol"), ("Shell", "shell"), ("tcl/tk", "tcltk")] for text,value in right_data: button = Tk.Radiobutton(rt,anchor="w",text=text, variable=self.lang_var,value=value,command=self.set_lang) button.pack(fill="x") #@nonl #@-node:ekr.20031218072017.369:<< Create the Target Language frame >> frame #@+node:ekr.20031218072017.370:<< configure language-specific settings >> colorizer # Define has_string, keywords, single_comment_start, block_comment_start, block_comment_end. if self.language == "cweb": # Use C comments, not cweb sentinel comments. delim1,delim2,delim3 = g.set_delims_from_language("c") elif self.comment_string: delim1,delim2,delim3 = g.set_delims_from_string(self.comment_string) elif self.language == "plain": # 1/30/03 delim1,delim2,delim3 = None,None,None else: delim1,delim2,delim3 = g.set_delims_from_language(self.language) self.single_comment_start = delim1 self.block_comment_start = delim2 self.block_comment_end = delim3 # A strong case can be made for making this code as fast as possible. # Whether this is compatible with general language descriptions remains to be seen. self.case_sensitiveLanguage = self.language not in case_insensitiveLanguages self.has_string = self.language != "plain" if self.language == "plain": self.string_delims = () elif self.language in ("elisp","html"): self.string_delims = ('"') else: self.string_delims = ("'",'"') self.has_pp_directives = self.language in ("c","csharp","cweb","latex") # The list of languages for which keywords exist. # Eventually we might just use language_delims_dict.keys() languages = [ "actionscript","c","csharp","css","cweb","elisp","html","java","latex", "pascal","perl","perlpod","php","python","rapidq","rebol","shell","tcltk"] self.keywords = [] if self.language == "cweb": for i in self.c_keywords: self.keywords.append(i) for i in self.cweb_keywords: self.keywords.append(i) else: for name in languages: if self.language==name: # g.trace("setting keywords for",name) self.keywords = getattr(self, name + "_keywords") # Color plain text unless we are under the control of @nocolor. # state = g.choose(self.flag,"normal","nocolor") state = self.setFirstLineState() if 1: # 10/25/02: we color both kinds of references in cweb mode. self.lb = "<<" self.rb = ">>" else: self.lb = g.choose(self.language == "cweb","@<","<<") self.rb = g.choose(self.language == "cweb","@>",">>") #@nonl #@-node:ekr.20031218072017.370:<< configure language-specific settings >> colorizer #@+node:ekr.20031218072017.371:<< define colorizer keywords >> colorizer @others cweb_keywords = c_keywords perlpod_keywords = perl_keywords #@nonl #@+node:ekr.20031218072017.372:actionscript keywords actionscript_keywords = [ #Jason 2003-07-03 #Actionscript keywords for Leo adapted from UltraEdit syntax highlighting "break", "call", "continue", "delete", "do", "else", "false", "for", "function", "goto", "if", "in", "new", "null", "return", "true", "typeof", "undefined", "var", "void", "while", "with", "#include", "catch", "constructor", "prototype", "this", "try", "_parent", "_root", "__proto__", "ASnative", "abs", "acos", "appendChild", "asfunction", "asin", "atan", "atan2", "attachMovie", "attachSound", "attributes", "BACKSPACE", "CAPSLOCK", "CONTROL", "ceil", "charAt", "charCodeAt", "childNodes", "chr", "cloneNode", "close", "concat", "connect", "cos", "createElement", "createTextNode", "DELETEKEY", "DOWN", "docTypeDecl", "duplicateMovieClip", "END", "ENTER", "ESCAPE", "enterFrame", "entry", "equal", "eval", "evaluate", "exp", "firstChild", "floor", "fromCharCode", "fscommand", "getAscii", "getBeginIndex", "getBounds", "getBytesLoaded", "getBytesTotal", "getCaretIndex", "getCode", "getDate", "getDay", "getEndIndex", "getFocus", "getFullYear", "getHours", "getMilliseconds", "getMinutes", "getMonth", "getPan", "getProperty", "getRGB", "getSeconds", "getTime", "getTimer", "getTimezoneOffset", "getTransform", "getURL", "getUTCDate", "getUTCDay", "getUTCFullYear", "getUTCHours", "getUTCMilliseconds", "getUTCMinutes", "getUTCMonth", "getUTCSeconds", "getVersion", "getVolume", "getYear", "globalToLocal", "gotoAndPlay", "gotoAndStop", "HOME", "haschildNodes", "hide", "hitTest", "INSERT", "Infinity", "ifFrameLoaded", "ignoreWhite", "indexOf", "insertBefore", "int", "isDown", "isFinite", "isNaN", "isToggled", "join", "keycode", "keyDown", "keyUp", "LEFT", "LN10", "LN2", "LOG10E", "LOG2E", "lastChild", "lastIndexOf", "length", "load", "loaded", "loadMovie", "loadMovieNum", "loadVariables", "loadVariablesNum", "localToGlobal", "log", "MAX_VALUE", "MIN_VALUE", "max", "maxscroll", "mbchr", "mblength", "mbord", "mbsubstring", "min", "NEGATIVE_INFINITY", "NaN", "newline", "nextFrame", "nextScene", "nextSibling", "nodeName", "nodeType", "nodeValue", "on", "onClipEvent", "onClose", "onConnect", "onData", "onLoad", "onXML", "ord", "PGDN", "PGUP", "PI", "POSITIVE_INFINITY", "parentNode", "parseFloat", "parseInt", "parseXML", "play", "pop", "pow", "press", "prevFrame", "previousSibling", "prevScene", "print", "printAsBitmap", "printAsBitmapNum", "printNum", "push", "RIGHT", "random", "release", "removeMovieClip", "removeNode", "reverse", "round", "SPACE", "SQRT1_2", "SQRT2", "scroll", "send", "sendAndLoad", "set", "setDate", "setFocus", "setFullYear", "setHours", "setMilliseconds", "setMinutes", "setMonth", "setPan", "setProperty", "setRGB", "setSeconds", "setSelection", "setTime", "setTransform", "setUTCDate", "setUTCFullYear", "setUTCHours", "setUTCMilliseconds", "setUTCMinutes", "setUTCMonth", "setUTCSeconds", "setVolume", "setYear", "shift", "show", "sin", "slice", "sort", "start", "startDrag", "status", "stop", "stopAllSounds", "stopDrag", "substr", "substring", "swapDepths", "splice", "split", "sqrt", "TAB", "tan", "targetPath", "tellTarget", "toggleHighQuality", "toLowerCase", "toString", "toUpperCase", "trace", "UP", "UTC", "unescape", "unloadMovie", "unLoadMovieNum", "unshift", "updateAfterEvent", "valueOf", "xmlDecl", "_alpha", "_currentframe", "_droptarget", "_focusrect", "_framesloaded", "_height", "_highquality", "_name", "_quality", "_rotation", "_soundbuftime", "_target", "_totalframes", "_url", "_visible", "_width", "_x", "_xmouse", "_xscale", "_y", "_ymouse", "_yscale", "and", "add", "eq", "ge", "gt", "le", "lt", "ne", "not", "or", "Array", "Boolean", "Color", "Date", "Key", "Math", "MovieClip", "Mouse", "Number", "Object", "Selection", "Sound", "String", "XML", "XMLSocket" ] #@nonl #@-node:ekr.20031218072017.372:actionscript keywords #@+node:ekr.20040206072057:c# keywords csharp_keywords = [ "abstract","as", "base","bool","break","byte", "case","catch","char","checked","class","const","continue", "decimal","default","delegate","do","double", "else","enum","event","explicit","extern", "false","finally","fixed","float","for","foreach", "get","goto", "if","implicit","in","int","interface","internal","is", "lock","long", "namespace","new","null", "object","operator","out","override", "params","partial","private","protected","public", "readonly","ref","return", "sbyte","sealed","set","short","sizeof","stackalloc", "static","string","struct","switch", "this","throw","true","try","typeof", "uint","ulong","unchecked","unsafe","ushort","using", "value","virtual","void","volatile", "where","while", "yield"] #@nonl #@-node:ekr.20040206072057:c# keywords #@+node:ekr.20031218072017.373:c/c++ keywords c_keywords = [ # C keywords "auto","break","case","char","continue", "default","do","double","else","enum","extern", "float","for","goto","if","int","long","register","return", "short","signed","sizeof","static","struct","switch", "typedef","union","unsigned","void","volatile","while", # C++ keywords "asm","bool","catch","class","const","const_cast", "delete","dynamic_cast","explicit","false","friend", "inline","mutable","namespace","new","operator", "private","protected","public","reinterpret_cast","static_cast", "template","this","throw","true","try", "typeid","typename","using","virtual","wchar_t"] #@nonl #@-node:ekr.20031218072017.373:c/c++ keywords #@+node:ekr.20040401103539:css keywords css_keywords = [ #html tags "address", "applet", "area", "a", "base", "basefont", "big", "blockquote", "body", "br", "b", "caption", "center", "cite", "code", "dd", "dfn", "dir", "div", "dl", "dt", "em", "font", "form", "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html", "img", "input", "isindex", "i", "kbd", "link", "li", "link", "map", "menu", "meta", "ol", "option", "param", "pre", "p", "samp", "select", "small", "span", "strike", "strong", "style", "sub", "sup", "table", "td", "textarea", "th", "title", "tr", "tt", "ul", "u", "var", #units "mm", "cm", "in", "pt", "pc", "em", "ex", "px", #colors "aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "purple", "red", "silver", "teal", "yellow", "white", #important directive "!important", #font rules "font", "font-family", "font-style", "font-variant", "font-weight", "font-size", #font values "cursive", "fantasy", "monospace", "normal", "italic", "oblique", "small-caps", "bold", "bolder", "lighter", "medium", "larger", "smaller", "serif", "sans-serif", #background rules "background", "background-color", "background-image", "background-repeat", "background-attachment", "background-position", #background values "contained", "none", "top", "center", "bottom", "left", "right", "scroll", "fixed", "repeat", "repeat-x", "repeat-y", "no-repeat", #text rules "word-spacing", "letter-spacing", "text-decoration", "vertical-align", "text-transform", "text-align", "text-indent", "text-transform", "text-shadow", "unicode-bidi", "line-height", #text values "normal", "none", "underline", "overline", "blink", "sub", "super", "middle", "top", "text-top", "text-bottom", "capitalize", "uppercase", "lowercase", "none", "left", "right", "center", "justify", "line-through", #box rules "margin", "margin-top", "margin-bottom", "margin-left", "margin-right", "margin", "padding-top", "padding-bottom", "padding-left", "padding-right", "border", "border-width", "border-style", "border-top", "border-top-width", "border-top-style", "border-bottom", "border-bottom-width", "border-bottom-style", "border-left", "border-left-width", "border-left-style", "border-right", "border-right-width", "border-right-style", "border-color", #box values "width", "height", "float", "clear", "auto", "thin", "medium", "thick", "left", "right", "none", "both", "none", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", #display rules "display", "white-space", "min-width", "max-width", "min-height", "max-height", "outline-color", "outline-style", "outline-width", #display values "run-in", "inline-block", "list-item", "block", "inline", "none", "normal", "pre", "nowrap", "table-cell", "table-row", "table-row-group", "table-header-group", "inline-table", "table-column", "table-column-group", "table-cell", "table-caption" #list rules "list-style", "list-style-type", "list-style-image", "list-style-position", #list values "disc", "circle", "square", "decimal", "decimal-leading-zero", "none", "lower-roman", "upper-roman", "lower-alpha", "upper-alpha", "lower-latin", "upper-latin", #table rules "border-collapse", "caption-side", #table-values "empty-cells", "table-layout", #misc values/rules "counter-increment", "counter-reset", "marker-offset", "z-index", "cursor", "direction", "marks", "quotes", "clip", "content", "orphans", "overflow", "visibility", #aural rules "pitch", "range", "pitch-during", "cue-after", "pause-after", "cue-before", "pause-before", "speak-header", "speak-numeral", "speak-punctuation", "speed-rate", "play-during", "voice-family", #aural values "stress", "azimuth", "elevation", "pitch", "richness", "volume", "page-break", "page-after", "page-inside"] #@nonl #@-node:ekr.20040401103539:css keywords #@+node:ekr.20031218072017.374:elisp keywords # EKR: needs more work. elisp_keywords = [ # Maybe... "error","princ", # More typical of other lisps... "apply","eval", "t","nil", "and","or","not", "cons","car","cdr", "cond", "defconst","defun","defvar", "eq","ne","equal","gt","ge","lt","le", "if", "let", "mapcar", "prog","progn", "set","setq", "type-of", "unless", "when","while"] #@nonl #@-node:ekr.20031218072017.374:elisp keywords #@+node:ekr.20031218072017.375:html keywords # No longer used by syntax colorer. html_keywords = [] if 0: # Not used at present. unused_keywords = [ # html constructs. "a","body","cf", "h1","h2","h3","h4","h5","h6", "head","html","hr", "i","img","li","lu","meta", "p","title","ul", # Common tags "caption","col","colgroup", "table","tbody","td","tfoot","th","thead","tr", "script","style"] html_specials = [ "<%","%>" ] #@nonl #@-node:ekr.20031218072017.375:html keywords #@+node:ekr.20031218072017.376:java keywords java_keywords = [ "abstract","boolean","break","byte","byvalue", "case","cast","catch","char","class","const","continue", "default","do","double","else","extends", "false","final","finally","float","for","future", "generic","goto","if","implements","import","inner", "instanceof","int","interface","long","native", "new","null","operator","outer", "package","private","protected","public","rest","return", "short","static","super","switch","synchronized", "this","throw","transient","true","try", "var","void","volatile","while"] #@nonl #@-node:ekr.20031218072017.376:java keywords #@+node:ekr.20031218072017.377:latex keywords #If you see two idenitical words, with minor capitalization differences #DO NOT ASSUME that they are the same word. For example \vert produces #a single vertical line and \Vert produces a double vertical line #Marcus A. Martin. latex_special_keyword_characters = "@(){}%" latex_keywords = [ #special keyworlds "\\%", # 11/9/03 "\\@", "\\(", "\\)", "\\{", "\\}", #A "\\acute", "\\addcontentsline", "\\addtocontents", "\\addtocounter", "\\address", "\\addtolength", "\\addvspace", "\\AE", "\\ae", "\\aleph", "\\alph", "\\angle", "\\appendix", "\\approx", "\\arabic", "\\arccos", "\\arcsin", "\\arctan", "\\ast", "\\author", #B "\\b", "\\backmatter", "\\backslash", "\\bar", "\\baselineskip", "\\baselinestretch", "\\begin", "\\beta", "\\bezier", "\\bf", "\\bfseries", "\\bibitem", "\\bigcap", "\\bigcup", "\\bigodot", "\\bigoplus", "\\bigotimes", "\\bigskip", "\\biguplus", "\\bigvee", "\\bigwedge", "\\bmod", "\\boldmath", "\\Box", "\\breve", "\\bullet", #C "\\c", "\\cal", "\\caption", "\\cdot", "\\cdots", "\\centering", "\\chapter", "\\check", "\\chi", "\\circ", "\\circle", "\\cite", "\\cleardoublepage", "\\clearpage", "\\cline", "\\closing", "\\clubsuit", "\\coprod", "\\copywright", "\\cos", "\\cosh", "\\cot", "\\coth", "csc", #D "\\d", "\\dag", "\\dashbox", "\\date", "\\ddag", "\\ddot", "\\ddots", "\\decl", "\\deg", "\\Delta", "\\delta", "\\depthits", "\\det", "\\DH", "\\dh", "\\Diamond", "\\diamondsuit", "\\dim", "\\div", "\\DJ", "\\dj", "\\documentclass", "\\documentstyle", "\\dot", "\\dotfil", "\\downarrow", #E "\\ell", "\\em", "\\emph", "\\end", "\\enlargethispage", "\\ensuremath", "\\enumi", "\\enuii", "\\enumiii", "\\enuiv", "\\epsilon", "\\equation", "\\equiv", "\\eta", "\\example", "\\exists", "\\exp", #F "\\fbox", "\\figure", "\\flat", "\\flushbottom", "\\fnsymbol", "\\footnote", "\\footnotemark", "\\fotenotesize", "\\footnotetext", "\\forall", "\\frac", "\\frame", "\\framebox", "\\frenchspacing", "\\frontmatter", #G "\\Gamma", "\\gamma", "\\gcd", "\\geq", "\\gg", "\\grave", "\\guillemotleft", "\\guillemotright", "\\guilsinglleft", "\\guilsinglright", #H "\\H", "\\hat", "\\hbar", "\\heartsuit", "\\heightits", "\\hfill", "\\hline", "\\hom", "\\hrulefill", "\\hspace", "\\huge", "\\Huge", "\\hyphenation" #I "\\Im", "\\imath", "\\include", "includeonly", "indent", "\\index", "\\inf", "\\infty", "\\input", "\\int", "\\iota", "\\it", "\\item", "\\itshape", #J "\\jmath", "\\Join", #K "\\k", "\\kappa", "\\ker", "\\kill", #L "\\label", "\\Lambda", "\\lambda", "\\langle", "\\large", "\\Large", "\\LARGE", "\\LaTeX", "\\LaTeXe", "\\ldots", "\\leadsto", "\\left", "\\Leftarrow", "\\leftarrow", "\\lefteqn", "\\leq", "\\lg", "\\lhd", "\\lim", "\\liminf", "\\limsup", "\\line", "\\linebreak", "\\linethickness", "\\linewidth", "\\listfiles", "\\ll", "\\ln", "\\location", "\\log", "\\Longleftarrow", "\\longleftarrow", "\\Longrightarrow", "longrightarrow", #M "\\mainmatter", "\\makebox", "\\makeglossary", "\\makeindex","\\maketitle", "\\markboth", "\\markright", "\\mathbf", "\\mathcal", "\\mathit", "\\mathnormal", "\\mathop", "\\mathrm", "\\mathsf", "\\mathtt", "\\max", "\\mbox", "\\mdseries", "\\medskip", "\\mho", "\\min", "\\mp", "\\mpfootnote", "\\mu", "\\multicolumn", "\\multiput", #N "\\nabla", "\\natural", "\\nearrow", "\\neq", "\\newcommand", "\\newcounter", "\\newenvironment", "\\newfont", "\\newlength", "\\newline", "\\newpage", "\\newsavebox", "\\newtheorem", "\\NG", "\\ng", "\\nocite", "\\noindent", "\\nolinbreak", "\\nopagebreak", "\\normalsize", "\\not", "\\nu", "nwarrow", #O "\\Omega", "\\omega", "\\onecolumn", "\\oint", "\\opening", "\\oval", "\\overbrace", "\\overline", #P "\\P", "\\page", "\\pagebreak", "\\pagenumbering", "\\pageref", "\\pagestyle", "\\par", "\\parbox", "\\paragraph", "\\parindent", "\\parskip", "\\part", "\\partial", "\\per", "\\Phi", "\\phi", "\\Pi", "\\pi", "\\pm", "\\pmod", "\\pounds", "\\prime", "\\printindex", "\\prod", "\\propto", "\\protext", "\\providecomamnd", "\\Psi", "\\psi", "\\put", #Q "\\qbezier", "\\quoteblbase", "\\quotesinglbase", #R "\\r", "\\raggedbottom", "\\raggedleft", "\\raggedright", "\\raisebox", "\\rangle", "\\Re", "\\ref", "\\renewcommand", "\\renewenvironment", "\\rhd", "\\rho", "\\right", "\\Rightarrow", "\\rightarrow", "\\rm", "\\rmfamily", "\\Roman", "\\roman", "\\rule", #S "\\s", "\\samepage", "\\savebox", "\\sbox", "\\sc", "\\scriptsize", "\\scshape", "\\searrow", "\\sec", "\\section", "\\setcounter", "\\setlength", "\\settowidth", "\\settodepth", "\\settoheight", "\\settowidth", "\\sf", "\\sffamily", "\\sharp", "\\shortstack", "\\Sigma", "\\sigma", "\\signature", "\\sim", "\\simeq", "\\sin", "\\sinh", "\\sl", "\\SLiTeX", "\\slshape", "\\small", "\\smallskip", "\\spadesuit", "\\sqrt", "\\sqsubset", "\\sqsupset", "\\SS", "\\stackrel", "\\star", "\\subsection", "\\subset", "\\subsubsection", "\\sum", "\\sup", "\\supressfloats", "\\surd", "\\swarrow", #T "\\t", "\\table", "\\tableofcontents", "\\tabularnewline", "\\tan", "\\tanh", "\\tau", "\\telephone", "\\TeX", "\\textbf", "\\textbullet", "\\textcircled", "\\textcompworkmark", "\\textemdash", "\\textendash", "\\textexclamdown", "\\textheight", "\\textquestiondown", "\\textquoteblleft", "\\textquoteblright", "\\textquoteleft", "\\textperiod", "\\textquotebl", "\\textquoteright", "\\textmd", "\\textit", "\\textrm", "\\textsc", "\\textsl", "\\textsf", "\\textsuperscript", "\\texttt", "\\textup", "\\textvisiblespace", "\\textwidth", "\\TH", "\\th", "\\thanks", "\\thebibligraphy", "\\Theta", "theta", "\\tilde", "\\thinlines", "\\thispagestyle", "\\times", "\\tiny", "\\title", "\\today", "\\totalheightits", "\\triangle", "\\tt", "\\ttfamily", "\\twocoloumn", "\\typeout", "\\typein", #U "\\u", "\\underbrace", "\\underline", "\\unitlength", "\\unlhd", "\\unrhd", "\\Uparrow", "\\uparrow", "\\updownarrow", "\\upshape", "\\Upsilon", "\\upsilon", "\\usebox", "\\usecounter", "\\usepackage", #V "\\v", "\\value", "\\varepsilon", "\\varphi", "\\varpi", "\\varrho", "\\varsigma", "\\vartheta", "\\vdots", "\\vec", "\\vector", "\\verb", "\\Vert", "\\vert", "\\vfill", "\\vline", "\\vphantom", "\\vspace", #W "\\widehat", "\\widetilde", "\\widthits", "\\wp", #X "\\Xi", "\\xi", #Z "\\zeta" ] #@nonl #@-node:ekr.20031218072017.377:latex keywords #@+node:ekr.20031218072017.378:pascal keywords pascal_keywords = [ "and","array","as","begin", "case","const","class","constructor","cdecl" "div","do","downto","destructor","dispid","dynamic", "else","end","except","external", "false","file","for","forward","function","finally", "goto","if","in","is","label","library", "mod","message","nil","not","nodefault""of","or","on", "procedure","program","packed","pascal", "private","protected","public","published", "record","repeat","raise","read","register", "set","string","shl","shr","stdcall", "then","to","true","type","try","until","unit","uses", "var","virtual","while","with","xor" # object pascal "asm","absolute","abstract","assembler","at","automated", "finalization", "implementation","inherited","initialization","inline","interface", "object","override","resident","resourcestring", "threadvar", # limited contexts "exports","property","default","write","stored","index","name" ] #@nonl #@-node:ekr.20031218072017.378:pascal keywords #@+node:ekr.20031218072017.379:perl keywords perl_keywords = [ "continue","do","else","elsif","format","for","format","for","foreach", "if","local","package","sub","tr","unless","until","while","y", # Comparison operators "cmp","eq","ge","gt","le","lt","ne", # Matching ooperators "m","s", # Unary functions "alarm","caller","chdir","cos","chroot","exit","eval","exp", "getpgrp","getprotobyname","gethostbyname","getnetbyname","gmtime", "hex","int","length","localtime","log","ord","oct", "require","reset","rand","rmdir","readlink", "scalar","sin","sleep","sqrt","srand","umask", # Transfer ops "next","last","redo","go","dump", # File operations... "select","open", # FL ops "binmode","close","closedir","eof", "fileno","getc","getpeername","getsockname","lstat", "readdir","rewinddir","stat","tell","telldir","write", # FL2 ops "bind","connect","flock","listen","opendir", "seekdir","shutdown","truncate", # FL32 ops "accept","pipe", # FL3 ops "fcntl","getsockopt","ioctl","read", "seek","send","sysread","syswrite", # FL4 & FL5 ops "recv","setsocket","socket","socketpair", # Array operations "pop","shift","split","delete", # FLIST ops "sprintf","grep","join","pack", # LVAL ops "chop","defined","study","undef", # f0 ops "endhostent","endnetent","endservent","endprotoent", "endpwent","endgrent","fork", "getgrent","gethostent","getlogin","getnetent","getppid", "getprotoent","getpwent","getservent", "setgrent","setpwent","time","times","wait","wantarray", # f1 ops "getgrgid","getgrnam","getprotobynumber","getpwnam","getpwuid", "sethostent","setnetent","setprotoent","setservent", # f2 ops "atan2","crypt", "gethostbyaddr","getnetbyaddr","getpriority","getservbyname","getservbyport", "index","link","mkdir","msgget","rename", "semop","setpgrp","symlink","unpack","waitpid", # f2 or 3 ops "index","rindex","substr", # f3 ops "msgctl","msgsnd","semget","setpriority","shmctl","shmget","vec", # f4 & f5 ops "semctl","shmread","shmwrite","msgrcv", # Assoc ops "dbmclose","each","keys","values", # List ops "chmod","chown","die","exec","kill", "print","printf","return","reverse", "sort","system","syscall","unlink","utime","warn"] #@nonl #@-node:ekr.20031218072017.379:perl keywords #@+node:ekr.20031218072017.380:php keywords php_keywords = [ # 08-SEP-2002 DTHEIN "__CLASS__", "__FILE__", "__FUNCTION__", "__LINE__", "and", "as", "break", "case", "cfunction", "class", "const", "continue", "declare", "default", "do", "else", "elseif", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "eval", "extends", "for", "foreach", "function", "global", "if", "new", "old_function", "or", "static", "switch", "use", "var", "while", "xor" ] # The following are supposed to be followed by () php_paren_keywords = [ "array", "die", "echo", "empty", "exit", "include", "include_once", "isset", "list", "print", "require", "require_once", "return", "unset" ] # The following are handled by special case code: # "" #@-node:ekr.20031218072017.380:php keywords #@+node:ekr.20031218072017.381:python keywords python_keywords = [ "and", "del", "for", "is", "raise", "assert", "elif", "from", "lambda", "return", "break", "else", "global", "not", "try", "class", "except", "if", "or", "yield", "continue", "exec", "import", "pass", "while", "def", "finally", "in", "print"] #@nonl #@-node:ekr.20031218072017.381:python keywords #@+node:ekr.20040331145826:rapidq keywords rapidq_keywords = [ # Syntax file for RapidQ "$APPTYPE","$DEFINE","$ELSE","$ENDIF","$ESCAPECHARS","$IFDEF","$IFNDEF", "$INCLUDE","$MACRO","$OPTIMIZE","$OPTION","$RESOURCE","$TYPECHECK","$UNDEF", "ABS","ACOS","ALIAS","AND","AS","ASC","ASIN","ATAN","ATN","BIN$","BIND","BYTE", "CALL","CALLBACK","CALLFUNC","CASE","CEIL","CHDIR","CHDRIVE","CHR$","CINT", "CLNG","CLS","CODEPTR","COMMAND$","COMMANDCOUNT","CONSOLE","CONST","CONSTRUCTOR", "CONVBASE$","COS","CREATE","CSRLIN","CURDIR$","DATA","DATE$","DEC","DECLARE", "DEFBYTE","DEFDBL","DEFDWORD","DEFINT","DEFLNG","DEFSHORT","DEFSNG","DEFSTR", "DEFWORD","DELETE$","DIM","DIR$","DIREXISTS","DO","DOEVENTS","DOUBLE","DWORD", "ELSE","ELSEIF","END","ENVIRON","ENVIRON$","EVENT","EXIT","EXP","EXTENDS", "EXTRACTRESOURCE","FIELD$","FILEEXISTS","FIX","FLOOR","FOR","FORMAT$","FRAC", "FUNCTION","FUNCTIONI","GET$","GOSUB","GOTO","HEX$","IF","INC","INITARRAY", "INKEY$","INP","INPUT","INPUT$","INPUTHANDLE","INSERT$","INSTR","INT","INTEGER", "INV","IS","ISCONSOLE","KILL","KILLMESSAGE","LBOUND","LCASE$","LEFT$","LEN", "LFLUSH","LIB","LIBRARYINST","LOCATE","LOG","LONG","LOOP","LPRINT","LTRIM$", "MEMCMP","MESSAGEBOX","MESSAGEDLG","MID$","MKDIR","MOD","MOUSEX","MOUSEY", "NEXT","NOT","OFF","ON","OR","OUT","OUTPUTHANDLE","PARAMSTR$","PARAMSTRCOUNT", "PARAMVAL","PARAMVALCOUNT","PCOPY","PEEK","PLAYWAV","POKE","POS","POSTMESSAGE", "PRINT","PROPERTY","QUICKSORT","RANDOMIZE","REDIM","RENAME","REPLACE$", "REPLACESUBSTR$","RESOURCE","RESOURCECOUNT","RESTORE","RESULT","RETURN", "REVERSE$","RGB","RIGHT$","RINSTR","RMDIR","RND","ROUND","RTRIM$","RUN", "SCREEN","SELECT","SENDER","SENDMESSAGE","SETCONSOLETITLE","SGN","SHELL", "SHL","SHORT","SHOWMESSAGE","SHR","SIN","SINGLE","SIZEOF","SLEEP","SOUND", "SPACE$","SQR","STACK","STATIC","STEP","STR$","STRF$","STRING","STRING$", "SUB","SUBI","SWAP","TALLY","TAN","THEN","TIME$","TIMER","TO","TYPE","UBOUND", "UCASE$","UNLOADLIBRARY","UNTIL","VAL","VARIANT","VARPTR","VARPTR$","VARTYPE", "WEND","WHILE","WITH","WORD","XOR"] #@nonl #@-node:ekr.20040331145826:rapidq keywords #@+node:ekr.20031218072017.382:rebol keywords rebol_keywords = [ #Jason 2003-07-03 #based on UltraEdit syntax highlighting "about", "abs", "absolute", "add", "alert", "alias", "all", "alter", "and", "and~", "any", "append", "arccosine", "arcsine", "arctangent", "array", "ask", "at", "back", "bind", "boot-prefs", "break", "browse", "build-port", "build-tag", "call", "caret-to-offset", "catch", "center-face", "change", "change-dir", "charset", "checksum", "choose", "clean-path", "clear", "clear-fields", "close", "comment", "complement", "compose", "compress", "confirm", "continue-post", "context", "copy", "cosine", "create-request", "crypt", "cvs-date", "cvs-version", "debase", "decode-cgi", "decode-url", "decompress", "deflag-face", "dehex", "delete", "demo", "desktop", "detab", "dh-compute-key", "dh-generate-key", "dh-make-key", "difference", "dirize", "disarm", "dispatch", "divide", "do", "do-boot", "do-events", "do-face", "do-face-alt", "does", "dsa-generate-key", "dsa-make-key", "dsa-make-signature", "dsa-verify-signature", "echo", "editor", "either", "else", "emailer", "enbase", "entab", "exclude", "exit", "exp", "extract", "fifth", "find", "find-key-face", "find-window", "flag-face", "first", "flash", "focus", "for", "forall", "foreach", "forever", "form", "forskip", "fourth", "free", "func", "function", "get", "get-modes", "get-net-info", "get-style", "halt", "has", "head", "help", "hide", "hide-popup", "if", "import-email", "in", "inform", "input", "insert", "insert-event-func", "intersect", "join", "last", "launch", "launch-thru", "layout", "license", "list-dir", "load", "load-image", "load-prefs", "load-thru", "log-10", "log-2", "log-e", "loop", "lowercase", "make", "make-dir", "make-face", "max", "maximum", "maximum-of", "min", "minimum", "minimum-of", "mold", "multiply", "negate", "net-error", "next", "not", "now", "offset-to-caret", "open", "open-events", "or", "or~", "parse", "parse-email-addrs", "parse-header", "parse-header-date", "parse-xml", "path-thru", "pick", "poke", "power", "prin", "print", "probe", "protect", "protect-system", "q", "query", "quit", "random", "read", "read-io", "read-net", "read-thru", "reboot", "recycle", "reduce", "reform", "rejoin", "remainder", "remold", "remove", "remove-event-func", "rename", "repeat", "repend", "replace", "request", "request-color", "request-date", "request-download", "request-file", "request-list", "request-pass", "request-text", "resend", "return", "reverse", "rsa-encrypt", "rsa-generate-key", "rsa-make-key", "save", "save-prefs", "save-user", "scroll-para", "second", "secure", "select", "send", "send-and-check", "set", "set-modes", "set-font", "set-net", "set-para", "set-style", "set-user", "set-user-name", "show", "show-popup", "sine", "size-text", "skip", "sort", "source", "split-path", "square-root", "stylize", "subtract", "switch", "tail", "tangent", "textinfo", "third", "throw", "throw-on-error", "to", "to-binary", "to-bitset", "to-block", "to-char", "to-date", "to-decimal", "to-email", "to-event", "to-file", "to-get-word", "to-hash", "to-hex", "to-idate", "to-image", "to-integer", "to-issue", "to-list", "to-lit-path", "to-lit-word", "to-local-file", "to-logic", "to-money", "to-none", "to-pair", "to-paren", "to-path", "to-rebol-file", "to-refinement", "to-set-path", "to-set-word", "to-string", "to-tag", "to-time", "to-tuple", "to-url", "to-word", "trace", "trim", "try", "unfocus", "union", "unique", "uninstall", "unprotect", "unset", "until", "unview", "update", "upgrade", "uppercase", "usage", "use", "vbug", "view", "view-install", "view-prefs", "wait", "what", "what-dir", "while", "write", "write-io", "xor", "xor~", "action!", "any-block!", "any-function!", "any-string!", "any-type!", "any-word!", "binary!", "bitset!", "block!", "char!", "datatype!", "date!", "decimal!", "email!", "error!", "event!", "file!", "function!", "get-word!", "hash!", "image!", "integer!", "issue!", "library!", "list!", "lit-path!", "lit-word!", "logic!", "money!", "native!", "none!", "number!", "object!", "op!", "pair!", "paren!", "path!", "port!", "refinement!", "routine!", "series!", "set-path!", "set-word!", "string!", "struct!", "symbol!", "tag!", "time!", "tuple!", "unset!", "url!", "word!", "any-block?", "any-function?", "any-string?", "any-type?", "any-word?", "binary?", "bitset?", "block?", "char?", "connected?", "crypt-strength?", "datatype?", "date?", "decimal?", "dir?", "email?", "empty?", "equal?", "error?", "even?", "event?", "exists?", "exists-key?", "file?", "flag-face?", "found?", "function?", "get-word?", "greater-or-equal?", "greater?", "hash?", "head?", "image?", "in-window?", "index?", "info?", "input?", "inside?", "integer?", "issue?", "length?", "lesser-or-equal?", "lesser?", "library?", "link-app?", "link?", "list?", "lit-path?", "lit-word?", "logic?", "modified?", "money?", "native?", "negative?", "none?", "not-equal?", "number?", "object?", "odd?", "offset?", "op?", "outside?", "pair?", "paren?", "path?", "port?", "positive?", "refinement?", "routine?", "same?", "screen-offset?", "script?", "series?", "set-path?", "set-word?", "size?", "span?", "strict-equal?", "strict-not-equal?", "string?", "struct?", "tag?", "tail?", "time?", "tuple?", "type?", "unset?", "url?", "value?", "view?", "within?", "word?", "zero?" ] #@nonl #@-node:ekr.20031218072017.382:rebol keywords #@+node:ekr.20040401111125:shell keywords shell_keywords = [ # reserved keywords "case","do","done","elif","else","esac","fi", "for","if","in","then", "until","while", "break","cd","chdir","continue","eval","exec", "exit","kill","newgrp","pwd","read","readonly", "return","shift","test","trap","ulimit", "umask","wait" ] #@nonl #@-node:ekr.20040401111125:shell keywords #@+node:ekr.20031218072017.383:tcl/tk keywords tcltk_keywords = [ # Only the tcl keywords are here. "after", "append", "array", "bgerror", "binary", "break", "catch", "cd", "clock", "close", "concat", "continue", "dde", "encoding", "eof", "eval", "exec", "exit", "expr", "fblocked", "fconfigure","fcopy", "file", "fileevent", "filename", "flush", "for", "foreach", "format", "gets", "glob", "global", "history", "if", "incr", "info", "interp", "join", "lappend", "lindex", "linsert", "list", "llength", "load", "lrange", "lreplace", "lsearch", "lsort", "memory", "msgcat", "namespace", "open", "package", "parray", "pid", "proc", "puts", "pwd", "read", "regexp", "registry", "regsub", "rename", "resource", "return", "scan", "seek", "set", "socket", "source", "split", "string", "subst", "switch", "tell", "time", "trace", "unknown", "unset", "update", "uplevel", "upvar", "variable", "vwait", "while" ] #@nonl #@-node:ekr.20031218072017.383:tcl/tk keywords #@-node:ekr.20031218072017.371:<< define colorizer keywords >> colorizer #@-node:ekr.20031218072017.367:How to add support for a new language #@-node:ekr.20031218072017.365:How to... #@+node:ekr.20040706072605:Ideas for later... #@+node:EKR.20040512082621:HTML widgets #@+node:EKR.20040512082621.1:htmllib.tcl http://sourceforge.net/forum/message.php?msg_id=2565345 By: nobody I just met a nice TCL-based html help viewer bundled with the evaluation version of Fujitsu-Siemens OpenFT for Unix (see fujitsu-siemens.com/products/software/openseas/openft.html) It is based on a TCL library htmllib.tcl, written by Stephen Uhler in 1995 while working in Sun's TCL group.Iit seemts that this lib is owned by Sun and i'm not certain about license. It is freely downloadable, anyway. The usage is really simple -- you have to create a text widget, a string variable containing html text and a link callback, then feed all three to the library routine. It should be not hard pythonize this process. see http://www.usenix.org/publications/login/1999-8/features/tclsh.html, ftp://ftp.scriptics.com/pub/tcl/misc/html_library-0.3.tar.gz or just google for htmllib.tcl #@-node:EKR.20040512082621.1:htmllib.tcl #@-node:EKR.20040512082621:HTML widgets #@+node:ekr.20040226085005:Java notes @nocolor http://sourceforge.net/forum/message.php?msg_id=2442609 By: nobody >>Anyway, I can import java, javax, javax.swing. And I just created my first JTree. good man. You will probably be subclassing JApplet. You subclass a Java class like this: class EdwardsApplet(JApplet): pass Id recommend getting the SDK javadoc on your PC or have a good link to the SDK javadoc. Read the JApplet doc in the Swing package. The thing to keep in mind is that you will be adding things to the JApplet's content pane, which will be using a Layout Manager. I believe the default for it is the BorderLayout. This means after you get a reference to the ContentPane, you should be able to add your components with: cp = getContentPane() cp.add( JTree() , BorderLayout.EAST ) Ill have to look at how Jython should package applets but you will be using, I believe, a program called appletviewer that comes with the JDK to view your applet. Remember that Jython is a couple of versions behind CPython, so stick to only features available in 2.1. As is, you will be calling things like you did in Python. The Jython home page might have tips on building an applet. What would be cool is if Leo could be totally packaged as a Jython applet, then a demoer could test a pretty full fledged Leo throught there browser. :) ______________________________________________________________________ You are receiving this email because you elected to monitor this forum. To stop monitoring this forum, login to SourceForge.net and visit: https://sourceforge.net/forum/unmonitor.php?forum_id=10226 #@-node:ekr.20040226085005:Java notes #@+node:ekr.20040125121407:Leo & Emacs @nocolor #@nonl #@+node:ekr.20040125121407.1:comment https://sourceforge.net/forum/message.php?msg_id=2389876 By: randomandy Is it only me who sees this as a question on how to reinvent the wheel? (or in the case of emacs, how to reinvent the everything.) Leo and Python both seem so well suited as wonderful hierarchal glue programs. And both are so elegant in the way their simple functionality brings such power and order to the cause. It just seems it would be a shame to take something so novel and unique and try to turn it into yet another huge text editor. I'm with Danny on this one. The ideal solution is to find the most elegant and seamless way to splice one's own beloved text editor (or multipurpose editor/OS) in with the Leo paradigm. Have Leo hand off the text duties to the editor, or have the editor deliver heirarchy commands to Leo. I'm also quite curious if this makes a good tie in with SciTE. SciTE produces stunningly readible language highlighting/formatting. Could it be employed for basic cell text display, and then for heavier editing, a keystroke or button could open the cell text in one's preferred weapons grade text editor? Scintilla also has a similarly beautiful code-to-html and code-to-pdf capability that seems very suited to the literary part of the Leo paradigm: publication. It would be nice if that code could be exploited as well. This Leo is really a marvelous work. It's transforming the way I think (i.e. making it possible again). Nice work, Edward. #@-node:ekr.20040125121407.1:comment #@+node:ekr.20040125121407.2:comment By: dannyobrien ( danny o'brien ) RE: What would it take to turn Leo into Emacs 2003-12-23 09:18 I agree with the embedding; I've used the vim plugin and it works well, but actually embedding the editor directly into the text field of leo (and allowing a range of keyboard shortcuts for eg headline editing) would be perfect. There is some support for this in gvim, the GUI version of vim that comes as standard. This can be run so as its GUI is "embedded" in another GTK widget, using that library's GtkSocket/GtkPlug system. A quick demo of that (and how to do it in python) is here: http://www.daa.com.au/pipermail/pygtk/2003-October/006185.html To see this working with gvim, run the second (socket.py) program on that page then type gvim --socketid I'm not sure how you could do this in other widget libraries - I don't know much about X Windows, but I suppose it would need support in vim as well as the widget set. #@-node:ekr.20040125121407.2:comment #@+node:ekr.20040125121407.3:comment https://sourceforge.net/forum/message.php?msg_id=2388448 By: mdawson I use XEmacs as my text editor. The first thing I did when evaluating Leo was to set up "open with" to use XEmacs for editing Leo body text. My progress so far: - my Open_With Plugin opens a Leo node as a foreground buffer in XEmacs, or a background (invisible) buffer in XEmacs. - my Open_Tree Plugin opens a sub-tree of Leo nodes as background buffers in XEmacs. - my filename modification plugin changes the temporary file names used by Leo so that they can be spotted more easily in an XEmacs buffer listing (e.g. ibuffer). - an elisp function to kill all XEmacs Leo buffers at once. - another elisp function to indent and unindent the Leo comments in derived Python source, which improves the readability of code. - my setup of the elisp Multiple-Major-Modes XEmacs package, so that XEmacs is in text-mode in Leo @doc sections, and the correct language mode in @code sections. Any of these might be able to be adapted for your own use. They should all work with Emacs as well as XEmacs, but I've not tested that. These are all outlined in Appendix "C. XEmacs Text Editor" of the document at: http://devguide.leo.marshallresearch.ca and the Leo outline that contains them is available at: http://leo.marshallresearch.ca ---------------------------------------- Michael Dawson #@-node:ekr.20040125121407.3:comment #@-node:ekr.20040125121407:Leo & Emacs #@+node:ekr.20040107064101.5:Zope notes #@+node:ekr.20040107065006:posting @nocolor Yes he's absolutely right -- focus on the ZODB. ..stay alway from ZTP. ZPT, TPZ, CMF, Plone and all that other stuff for now. I jsut came accross a handy slide show overview from last spring: http://jace.seacrow.com/tech/zope/blug-zodb BerkeyDB Storage is cool too and fits Leo well I think. plays nicely wiht ZODB standalnioe and in Zope. #@-node:ekr.20040107065006:posting #@+node:ekr.20040107064854:example Code from ZODG import FileStorage,DB from Persistence import Persistent # Connect to db. # FileStorage is standard: entire db is stored in a single file. storage = FileStorage.FileStorage("/tmp/test-filestorage.fs") db = DB.(storage) conn = db.open() # Get the root of the db. root = conn.root() # Defining user classes. class leoData(Persistent): pass # Commit or revert. get_transaction().commit() get_transaction().abort() #@nonl #@-node:ekr.20040107064854:example Code #@+node:ekr.20040107080609.1:Zshell @nocolor By: jasonic ( Jason Cunliffe ) ZShell 2003-12-31 22:25 Hi, Just another friendly reminder to check out Jerome Alet's ZShell, one of Zope's best kept secrets: http://www.librelogiciel.com/software/ ZShell : Manipulate the Zope Object DataBase with Unix shell like commands and also ZShellScripts : Unifies the Zope notion of Scripts and provides several Script interpreters : Python, Unix shell , Lisp, Perl, PHP, Ruby, and Zope ZShell Not only for obvious usefullness, but also as a valuable study of Python access to the ZODB. JAXML is cool too.. http://www.librelogiciel.com/software/jaxml/action_Presentation - Jason #@nonl #@-node:ekr.20040107080609.1:Zshell #@+node:ekr.20040107064854.1:@url http://zope.org/Products/StandaloneZODB #@-node:ekr.20040107064854.1:@url http://zope.org/Products/StandaloneZODB #@+node:ekr.20040107064854.2:@url http://jace.seacrow.com/tech/zope/blug-zodb #@-node:ekr.20040107064854.2:@url http://jace.seacrow.com/tech/zope/blug-zodb #@-node:ekr.20040107064101.5:Zope notes #@+node:ekr.20031218072017.404:LeoN, Zope & collaboration info @nocolor #@nonl #@+node:ekr.20031218072017.405:Kent Tenny Notes @nocolor Outlook: server for email, addresses & calendar. Groupware. Chandler similar. Zope: back end is ZODB. Zope like an OS: run Python code on Zope. Zope: another way to access Leo files. Maybe twisted is better? Wiki anology: edit Leo files with browser. Write through the web. longrun.org Wiki principles: - Sharing is 90% of collaboration. - Zope: Subscribe to a wiki: email when page changes. - RSS: xml that defines piece of info(tile,url,abstract) - Client has a list of rss feeds: an xml file. - List of intesting people: notified when they say something. Two goals: - publish Leo files - edit Leo files Brother needs cvs. Kent not so worried about cvs. -Leo file is a web site! - Helper layer between user and OS. - Look at aap project. Author of vim. a-p.org - Replacement for make in Python. Automating tool. - Expert prepares Leo file. User uses it. #@nonl #@-node:ekr.20031218072017.405:Kent Tenny Notes #@+node:ekr.20031218072017.406:url's #@+node:ekr.20031218072017.407:@url http://24.243.129.68:8080/members/sandbox #@-node:ekr.20031218072017.407:@url http://24.243.129.68:8080/members/sandbox #@+node:ekr.20031218072017.408:@url http://www.zopelabs.com/cookbook #@-node:ekr.20031218072017.408:@url http://www.zopelabs.com/cookbook #@+node:ekr.20031218072017.409:@url http://zwiki.org/FrontPage Zope implementation of wiki #@-node:ekr.20031218072017.409:@url http://zwiki.org/FrontPage Zope implementation of wiki #@-node:ekr.20031218072017.406:url's #@+node:ekr.20031218072017.410:Collaboration & Sharing #@+node:ekr.20031218072017.411:From Rodrigo Developers Forum By: rodrigo_b ( Rodrigo Benenson ) RE: Leo over the network 2003-05-10 00:06 So this is my first proposal: Requirements -------------------- * Read remote outlines. ** With Leo clients. ** Over the web. * Edit remote outlines. * Import remote outlines (retrieve outlines from the web). * Synchronize local outlines with remote ones (web to local and local to web). * Publish outlines (send outlines to the web). * The Leo client have to be keept lighweigth. * The Leo remote outline access server should be a lighweigth daemon. * This daemon should automagically render HTML from the outlines. * The outlines should be editable from the web and via Leo client. * Concurency management is must. * The remote servers should be included in the leo client as leo nodes (just like leo files, but remotes). "@leo-outline leo.server.org:854" * By this way I could have access to local server nodes. "@leo-outline localhost:854" * The remote server should offer one and only one big outline with sub nodes, and so on, and so on... * At least the concurency should be managed as "when someone write, all the other ones only can read" * It is better if Leo devellop simultaneaously some hypertext/wiki extensions. ---------------------------- End of requeriments This requeriments requires a client-server architecture, with basic commands as: - Update node - Lock/release node - Edit outline - Download outline - Upload outline well that is by the moment, I hope that we will be able to create a Finite, clear, requeriments list for this branch of Leo. RodrigoB. #@-node:ekr.20031218072017.411:From Rodrigo #@-node:ekr.20031218072017.410:Collaboration & Sharing #@+node:ekr.20031218072017.412:Zope #@+node:ekr.20031218072017.413:From Rodrigo re: Zope. Open Discussion https://sourceforge.net/forum/message.php?msg_id=2007586 By: rodrigo_b z2.py, >Supposing that that I did find this file, what would I be looking for? This is the Main script, the principal program, the code that startup all the servers, the only python program that make run Zope, it the code called by start.py, and it is the one to which you pass the command lines. With the command line you can indicate which services to start up at which ports. This is IMPORTANT. Also you can enable/disable the Debug mode. python z2.py --help will give you some infos about what I'm talking about. In linux the debug or not debug mode, enable the console or daemon mode (that means 'background task mode'). In windows, I'm not sure that disabling the debug mode will be enough. I know that at the install time you can setup Zope as a Windows Service, so it will start automatically every time Windows Startup, and it will not open a console window. But first look at the debug mode. Start.bat give some defaults command lines to z2.py Webdav, >What issues are involved in this choice, and why should I care today? from www.webdav.org What is WebDAV? Briefly: WebDAV stands for "Web-based Distributed Authoring and Versioning". It is a set of extensions to the HTTP protocol which allows users to collaboratively edit and manage files on remote web servers. For example that means that you can open you Windows Explorer (from your mail I understand that you work on an MsWindows OS), tip the url "localhost:%i"%(your webdav port) and you will be able to navigate, view and edit the Zope Objects just as a normal file system (well, almost). WebDav is a standard and there are Python implementations. WebDav is support by Oscom. WebDav is cool. WebDav is the 'highest level tool'. ZODB, >Does that mean that gnx's aren't needed with Zope? Could Leo nodes live in the ZODB? You have to thinks to ZODB just as what it is: a Persistent Object Database. Most objects in Zope are Persistents, that mean that their instances do not die when you shutdown the server. The ZODB store his data in it own format. I think that GNX should be keeped. You have to basic ways to put nodes into Zope. First: the hard way: create a new Product (Products are something like Zope plugins) that is based on the Leo code, but were there is no node storage, instead the node should be Persistents. Then add rendering code to this objects. Leo node object + Persistence + ZClass + Rendering Code -> Leo Zope node. Additionaly you should create an Folder like object that should be an 'Leo Outline Zope Object', actuating as an Leo nodes container. This shema is similar to the Zwiki way, with a Zwiki Web and the Zwiki Pages. Second: Use A zope folder just as Leo manage the @file nodes. Let have simple DTMLDocuments, edited via WebDav, with , and stuff like that. The Leo import/export that nodes. RodrigoB. #@-node:ekr.20031218072017.413:From Rodrigo re: Zope. #@+node:ekr.20031218072017.414:Clarification from Kent Tenny Open Discussion https://sourceforge.net/forum/message.php?msg_id=2009081 By: ktenney Edward, I don't see ZLeo replacing Leo, rather a method of accessing Leo files. When I write, I almost always want it to be web accessable, so that I can access it from any browser, and so that I can share it easily. I would like myfile.leo to live at http://longrun.org/leo/myfile.leo. It can be read and written to from any browser (according to how permissions are configured) The page describing how to configure Apache would be found at http://longrun.org/leo/myfile.leo/Apache/configure The only requirement to work with Leo files is a browser. I wouldn't want to lose the capability to edit outside the browser, using a standalone version of Leo or Zope's ExternalEditor product. ExternalEditor allows me to click an icon to open the page I'm viewing in any editor. I could open it in Leo as a Leo file, or open just the page in Vim (http://vim.sourceforge.net/index.php) Zope is ponderous, I think of it as more of a platform than an application. My understanding of how Zope works grows slowly, in the mean time my focus is on _products_. Installing a product in Zope is like installing an application in Windows or Linux. One of the most evolved products is Plone/CMF http://plone.org which is basically a turnkey web site. twisted http://twistedmatrix.com is a brilliant set of network programming tools. That's all I know about it. I'm not sure about Chandler (http://www.osafoundation.org/) (they did choose Python and ZODB http://www.osafoundation.org/technology.htm) You might try subscribing to a Zope mailing list or two http://www.zope.org/Resources/MailingLists The community of users and developers is very important to Zope. Thanks, Kent #@-node:ekr.20031218072017.414:Clarification from Kent Tenny #@+node:ekr.20031218072017.415:From Rodrigo re: ip Open Discussion https://sourceforge.net/forum/message.php?msg_id=2007817 By: rodrigo_b If zope is running some server then this server will be accesible from your network if and only if there is no firewall in the way. The people can access to your services using (normally on internet you do not have a domain name) your_ip:the_service_port Example: zope http service on port 8080 on your machine. When you connect to internet your machine got an extra IP. Then simple put on the web browser http://your_conexion_ip:8080 and Tada you will see the root_zope/index_html object rendered intro HTML. Most of the ISP give you a dinamic IP. Some companies provides you dinamic IP Domain Name services, allowing to attach a domain name to your machine dinamically (each time you reconect). then you can have: http://leo.edward.com:8080/ The 8080 stuff can be avoied if you setup zope to use the standard port 80 for HTTP service. With this in mind you can access ftp ftp://your_ip_or_domain_name:8021 or webdav, or anything else. #@-node:ekr.20031218072017.415:From Rodrigo re: ip #@+node:ekr.20031218072017.416:Other servers Open Discussion https://sourceforge.net/forum/message.php?msg_id=2007832 By: rodrigo_b I would made a warning. Zope IT IS NOT the only way to obtain an local HTTP server, pythonic and flexible. There is a lot of other way. Also Zope IT IS NOT THE BEST pythonic http/ftp/webdav or anything server aviable. I think that we should define better What we want to do? before choosing the tool. As I said, I had already used Zope, I choosed it because of very specific features, but nothing indicate that Zope is the best way to get Leo to the colaborative network universe. I think that we should at least consider: - SimpleHTTPServer - To take of the Medusa Server from Zope (that is use Zope code in the standard Leo distribution, avoying dependences) - Twisted matrix (I had no experience with it, but it looks much more flexible/powerfull) Zope provides you a specific framework, you have to match you application to this framework, Zope (in my opinion) it is not a tool, it's an ambient. It's seems that Edward it is new in the web oriented software, I think it has a lot of potencialities and it will benefits Leo devellopment. Please Edward, look at Zope as an example but not as THE options. Think about what can be done, what should be done, and then we will take the best tool. Anyway my opinion: - SimpleHTTP server: usefull, it is in python, not very eficiente, just http server - Medusa: usefull, very eficiente, just http server... - Twisted Matrix: very powerfull, fresh comunity, confusing documentation, a new paradigm, a devellopment tool. - Zope: powerfull, eficient, comes with battery included, bad documentation, to very paradigm oriented, the apps have to fit the paradigm, don't believe all the promises, strong enthousiast comunity, poor web examples. RodrigoB. #@-node:ekr.20031218072017.416:Other servers #@+node:ekr.20031218072017.417:Is my ip public? https://sourceforge.net/forum/message.php?msg_id=2007962 By: bwmulder Since no one else answered this question, let me take a first take on the question: If you are connected to the internet, people can use your IP number to connect to your computer. This IP number is often given dynamically, though some DSL providers give you fixed IP numbers for an additional fee. If you did not ask for fixed IP numbers, you probably have an dynamic IP number (I think). An IP number consist of four digits. A connection to the (example) IP number 111.222.333.444 can by made via the request http://111.222.333.444 If you have a dynamic IP number, and your Internet provider provides you with some space to publish HTML, you could, via a script, upload your current IP number dynamically. You might also consider buying a domain name. In this case, people can use the domain name to connect to your computer instead of the IP number. Another consideration are firewalls. Normally, you want a firewall isolating your computer from attacks from the Internet. I firewall can be some additional software. I am currently using a router, a piece of hardware, as a firewall. Windows XP has firewall software build in. You might have to configure your firewall to let requests for your server go through. Finally, you might want to check the agreement you entered with your Internet service provider, if you are allowed to run a server from your connection. It might become a problem if your server becomes very popular. #@-node:ekr.20031218072017.417:Is my ip public? #@+node:ekr.20031218072017.418:Back ends for storing/retrieving nodes: Paul Paterson Open Discussion https://sourceforge.net/forum/message.php?msg_id=2009279 By: paulpaterson What I see Zope offering is an alternative way of storing and retrieving nodes. What you also get for "free" with Zope is concurrent access, security, http/ftp/webdav access to the same node information etc. The hidden price you pay is that Zope is big and many users will have other tools which can provide these facilities also. So, my thinking is that we can abstract the basic idea (alternative ways of storing and retrieving node information) into Leo and then let the magic really happen in the concrete implementation stage. What does this mean? Well, we could change Leo so that whenever it goes to retrieve Headline or Body it goes to a Node Server object to do that. The Node Server object uses whatever method it wants to retrieve or set the information. The Node server would also be responsible for telling Leo what child nodes an object has and whether they are clones or not. The cool part is that we could implement different kinds of Node server to talk to different back-ends. These can then be thought of as drivers. So we might have, - a file system driver where all information is stored in files and directories - a database driver where the DB stores all information - an ftp driver - a Zope driver - the default Leo driver People could write a driver to their own back end storage system. What is the advantage of this? Well, the magic really happens in the back-end. If you choose a back end which supports versioning, security, concurrent working, web access, etc etc then Leo now supports them. If you choose a back-end which supports dynamic mark-up or some other fancy stuff then Leo supports it. The key is that Leo doesn't need to bind itself to any one system to achieve this - the end user can install the relevant driver, configure the back-end and just go with it. Paul #@-node:ekr.20031218072017.418:Back ends for storing/retrieving nodes: Paul Paterson #@+node:ekr.20031218072017.419:From Paul Paterson Ok, I'll have a bash in a rough order or when things occurred... 1. Everything is web based. I had the same problem you did. I ran the thing and said, "ok, so what did it do". Others have pointed you in the right direction now with visiting http://localhost:8080 and http://localhost:8080/manage to view the site and mange it respectively. If you are running WinNT, 2000 or XP you can also run Zope as a service, which is much more convenient as you don't need the console window open all the time. 2. Everything in Zope is an object. Ok, you'll see this a lot. The best thing to do is think "wow, cool" and then forget it again as you probably wont really see how this helps at all until you get much deeper into Zope. 3. DTML allows you to construct web pages by piecing together bits much like writing a program from functions. In fact you will find DTML is a lot like tangling Leo's @root nodes. Here's a bit... DTML allows you to assemble web pages much like Leo tangles documents

For instance, have a look at how this page is constructed

The bit is like a < < name > > directive. It effectively inserts the object (could be HTML, an image or something more complex) in the current page. To see this snippet in action you can visit my server at http://24.243.129.68:8080/members/sandbox/index_html To see the code, visit http://24.243.129.68:8080/members/sandbox/manage (username=edream, pwd=leo) and then click on the index_html to see the main DTML. Feel free to mess around in here but please don't publish the IP address as my ISP doesn't allow servers! 4. There is a lot of power in Zope products. Try going to www.zope.org and seeing what is available. As an example I put a Wiki in the sandbox area http://24.243.129.68:8080/members/sandbox/edswiki 5. If you are looking for a good book to begin with then steer clear of "The Zope Book"! If you don't mind paying then "The book of Zope" is a much better introduction. When you have read this then "The Zope Book" will make some sense but really I found this book tremendously hard to get through. 6. Web standards are very cool! Zope supports FTP. Point your favourite FTP tool to, ftp://24.243.129.68:8021/members/sandbox/ Or try using WebDav by creating a network place pointing to http://24.243.129.68:8080/members/sandbox You can then use windows explorer or an ftp tool to browse your objects. 7. Everything is an object! I can't do justice to the concept of Acquisition here but by the time you have messed around with Zope a bit you should start to see how acquisition starts to make things really work like classes in Python. I realize this isn't very coherent - if I get a spare moment this weekend I'll knock up a quick demo showing Leo interacting with Zope. Regards, Paul #@-node:ekr.20031218072017.419:From Paul Paterson #@-node:ekr.20031218072017.412:Zope #@+node:ekr.20031218072017.420:Jabber Open Discussion https://sourceforge.net/forum/message.php?msg_id=2016634 By: jasonic I have been thinking about LeoZopeWiki integration. I am a recovering Zope addict [1999-2001] :-) I believe Zope offers a very valuable client and server for Leo. I think Ed higlighted the distinction of collboration vs. sharing. So consdering that re: Leo and CVS , Leo and Zope, Leo and wikis, I had another idea this morning.. LEO+JABBER Jabber is an open XML-based instant messaging and *presence* system. Although Jabber is typically used for IM chat, its core designers have a much bigger vision in mind. Jabber Software Foundation http://www.jabber.org/ O'Reilly Book http://www.oreilly.com/catalog/jabber/ Python Jabber library http://jabberpy.sourceforge.net/ CVS etc all depend on runing diff on posted static files which are checked in or out. Clearly valuable, and good for __sharing__ but not so suitable as the communication paradigm needed for collboration. Wikis and Zope all suffer from problem of versioning and the time delay and lack of timely communications to their cobtributors. There is no 'shared state' or persistence in the collaboration beyond their own files or objectdatabases. For example if two people want to edit a wiki or Zope site, they have an imeedaiet problem of knowing whether or not the someone else is working one it already. Score: Sharing 1 Collaboration 0 Two or more people wanting to edit a common project based on Leo have the same dilemma. They can check the leo file into a wiki, Zope or CVS, but they still don't have direct communication at teh content level. score: Sharing 1 Collaboration 0 PROPOSAL: LeoJabber 1. Integrate a Jabber client into Leo 2. Add special Leo module to jabberd [Jabber's server daemon] Leo-based developers could work in direct communication with each other allowing them to add, edit and comment nodes in a shared le-space, local or remote. Static publishing via upload/import etc all still apply. LeoJabber would mean subscribing developers could immediately be aware of changes and then apply whatever strategy is appropriate for handling them, such as: a. autoUpdate() b. makeNewNode() c. runDiffFunctions() d. notifyPartners() e. notifyPublic() etc.. Jabber via its presencing mechanism offers real-time and just-in time communcations. If you are logged out, then mesages are queued. An open Jabber message session is actually one long piece of XML data passed over an XMLSocket :-) Sounds like a great fit for Leo - All Jabber configs are XML. - Good smart open source community. - Similar open embracing philsophy as Leo - Jabber connects diverse messaging systems., MSN, AOL etc [Most are close/proprietary, though the trend is toward greater openness and connectivity] - Many Jabber clients already. There is even one written in Flash so that any webpage can participate. Embedding Jabber in Leo would allow 'discussion' threads to be integrated. Developers need to bounce idea and notes around just as this forum does. But often they need to be more provate or more focused on project specifics. WORKFLOW It is important to know which code is uptodate, but arguably, even *more* important is to know which people and what discussions are uptodate. And if not, what their status is. The larger, longer the more global the develpoment office/project, the more this is true. IM [instant messaging] are popular largely becuae they offer direct communication with status feedback to crucial people's workflow: "off-line", "on-line", "back-soon", "later" etc Jabber extends this idea to create a platform for any presence application. That is its long term-goal. So in a Leo deevlopment project, that presence might apply to adding status mesages such as "making changes" "new version" "debugging" "review only" "major re-write" or perhaps status/presence woudl be used for much lower level Leo-specific purposes. "new node" "cloned to .." "@file imported" "version uploaded" etc I am not suggesting that Leo forget CVS or file upload storage. But I think Jabber may truly provide the Missing Link, literally for Leo collaboration. Jabber Software Foundation http://www.jabber.org/ O'Reilly Book http://www.oreilly.com/catalog/jabber/ Python Jabber library http://jabberpy.sourceforge.net/ hope this makes sense Jason #@-node:ekr.20031218072017.420:Jabber #@-node:ekr.20031218072017.404:LeoN, Zope & collaboration info #@-node:ekr.20040706072605:Ideas for later... #@+node:ekr.20040104162835.8:Mac notes: Dan Winkler #@+node:ekr.20040104162835.9:Porting notes Here's Apple's documentation on making Unix software run on OS X: http://developer.apple.com/documentation/Porting/Conceptual/ PortingUnix/index.html #@-node:ekr.20040104162835.9:Porting notes #@+node:ekr.20040104162835.10:$Path, etc. In general, Unix commands can go anywhere and they're found by the shell using the $PATH variable. To know what your path is, type "echo $PATH" at the shell. Typically you'll have new things added to your path by a file called .login in your home directory. This runs when you log in and then the settings are inherited by all the shells you run. You can also type the full path to something if you want to invoke it that way, such as "/usr/local/bin/python". Fink puts everything underneath /sw so as to avoid conflicting with Apple's versions of things. If you can't invoke a file, it might be that it's not set to be executable. If you do "ls -l" you'll see files listed with their permissions. You'll see some of r, w, and x meaning read, write and execute. These appear three times for owner, group, and everyone. You can do "chmod +x filename" to make it executable for the owner or you can use numbers as in "chmod 755 file name" which sets rwx for the owner (7 = 111 in binary = rwx) and rx for group and everyone (5 = 101 in binary = r_x). I know this might seem confusing at first but the fact that things won't execute without being set executable is a big curb on viruses. In fact, there are no OS X viruses yet. Anyway, it's all a matter of what you're used to. Windows seems confusing to someone new to it too. #@-node:ekr.20040104162835.10:$Path, etc. #@+node:ekr.20040104162835.11:which python You can type "which python" to find out which version of python (or any other command) will run. #@-node:ekr.20040104162835.11:which python #@+node:ekr.20040104162835.12:get info That error message (from import _tkinter) makes it sound like you are somehow running the text-only version of Python that came with OS X... except you said you deleted that. You can use "get info" in the finder to check and set which program will be used to open a given file. So you can select your main leo.py file (or whichever the one you start with is), do get info on it, and tell it to open with the MacPython launcher that you want. Then you should be able to double click it to open it. That's what I do to run Leo on my Mac. #@-node:ekr.20040104162835.12:get info #@+node:ekr.20040104162835.13:Fink & aqua Yes, fink does have pre-built Pythons, both 2.1 and 2.2. (If you don't see them it probably means you don't have the right servers listed in your /sw/etc/apt/sources.list file.) However, the versions of Python you'd get through fink are set up to run under X Windows, which I don't think is what you want. I think what you want is MacPython which can run Tk programs like Leo under Aqua. That's what I use these days. I can tell from your question that you don't understand the following differences between the versions of Python available: 1) The version that comes with OS X is a text only one which doesn't have Tk. Leo can't run under that. Also, I hate Apple for including this instead of one that does have Tk and I hope they'll fix it some day. 2) You can get a version of Python from fink with has Tk but which runs under X Windows. I don't think you want that. 3). You can also get MacPython which has Tk but it's a version of Tk that uses the Aqua windowing system, not X Windows. So Tk can either be present or not and if it is present it can use either X Windows or Aqua. You want it present and using Aqua, I think. #@-node:ekr.20040104162835.13:Fink & aqua #@+node:ekr.20040104162835.14:Mac, Fink, etc. > 1. The python that FC installs is MacPython. I think that because the > MacPython docs talk about Fink. Nope. The python installed by FC knows nothing about the Mac. It thinks it's running on a Unix machine. And it uses a version of Tk which thinks it's running on a Unix machine. The window standard on Unix is called X (or X11 or XFree86, all the same thing). So the main reason to run Leo this way would be to get an idea of how it works for Unix/Linux users. But when programs run under X, they don't look like Mac programs. They don't get all those glossy, translucent widgets that Aqua provides. They really look like they would on a Unix/Linux machine. Aqua is the native windowing system on Mac. MacPython is set up to work with it. Most Mac users will want Leo to work this way. That's what I do. > > > I have the TkTclAquBI (Batteries included) installer. Is installing > this > enough to get Leo to work with Aqua? Do I have to de-install the > present tk stuff that I installed with FC? Yes, I think that's all I installed to get Tk to work under Aqua. You don't have to deinstall the FC stuff. All the FC stuff lives in its own world under /sw and runs under X. It won't conflict with the Mac world. #@-node:ekr.20040104162835.14:Mac, Fink, etc. #@+node:ekr.20040104162835.15:Double clicking on Linux Double-clickable things (i.e. Macintosh applications) are usually actually folders with a name that ends in .app. The file you found is probably executable only from the command line, not by double clicking it. So I think if you run it from the command line it will work but will not know about Tk because Apple's version was built without Tk support. You can also execute the .app programs from the command line by using the open command, so "open foo.app" will do the same thing as double clicking on foo in the finder (the .app extension is suppressed). The idea behind this is that an application can look like just one opaque icon in the finder but actually have all its resources nicely organized in subfolders. #@-node:ekr.20040104162835.15:Double clicking on Linux #@+node:ekr.20040104162835.16:Getting Leo on Fink Commander FC gets its list of packages from the servers listed in /sw/etc/apt/sources.list. So you can put Leo into any server and people can add it to their sources.list or you can talk to the people who run the default servers and get Leo hosted there (better). #@-node:ekr.20040104162835.16:Getting Leo on Fink Commander #@-node:ekr.20040104162835.8:Mac notes: Dan Winkler #@+node:ekr.20031218072017.421:Early Milestones #@+node:ekr.20031218072017.422:02/03/02 Leo 0.08 released #@-node:ekr.20031218072017.422:02/03/02 Leo 0.08 released #@+node:ekr.20031218072017.423:12/17/01 ** Leo 0.05 released #@-node:ekr.20031218072017.423:12/17/01 ** Leo 0.05 released #@+node:ekr.20031218072017.424:12/16/01 Leo becomes functional leo.py reads and writes exactly like LeoCB #@nonl #@-node:ekr.20031218072017.424:12/16/01 Leo becomes functional #@+node:ekr.20031218072017.425:12/13/01 Syntax coloring works Amazing. I wrote some dummy code last night, read up on indices this morning, and got everything to work in a couple of hours. The result is very fast: no optimization is needed for Leo. I love Tkinter! Added c.recolor and tree.recolor routines. This hooks should be called whenever the body text changes. Apparently there is no "OnTextChanged" event in Tk. #@nonl #@-node:ekr.20031218072017.425:12/13/01 Syntax coloring works #@+node:ekr.20031218072017.426:12/09/01 Tree now drawn properly #@-node:ekr.20031218072017.426:12/09/01 Tree now drawn properly #@+node:ekr.20031218072017.427:12/05/01 Tree works with Tkinter #@-node:ekr.20031218072017.427:12/05/01 Tree works with Tkinter #@+node:ekr.20031218072017.428:11/10/01 ** began conversion to tk This marked my complete frustration with wxLeo and wxPython, and the real beginning of the work on leo.py. #@nonl #@-node:ekr.20031218072017.428:11/10/01 ** began conversion to tk #@+node:ekr.20031218072017.429:10/26/01 First successful read of .leo file w/ @file nodes #@-node:ekr.20031218072017.429:10/26/01 First successful read of .leo file w/ @file nodes #@+node:ekr.20031218072017.430:9/29/01 c2py: Totally in love with Python I am totally in love with Python. Everything is so much easier: Automatic debugging, no declarations, no types, no compilation. Great data structures. Even without single stepping the debugging is easy. All major aspects of c2py are now complete. #@nonl #@-node:ekr.20031218072017.430:9/29/01 c2py: Totally in love with Python #@+node:ekr.20031218072017.431:ca. 9/1/01 began work on wxPython version of Leo I am not sure exactly when this happened. The details apparently have been lost. There was a time when I was experimenting with Python and wxPython, and a time when I was working on wxWindows version of Leo. #@nonl #@-node:ekr.20031218072017.431:ca. 9/1/01 began work on wxPython version of Leo #@-node:ekr.20031218072017.421:Early Milestones #@+node:ekr.20031218072017.434:Unused code @ignore @language python @color #@nonl #@+node:EKR.20040505090056:From perfect import script @ignore #@nonl #@+node:EKR.20040505090056.1:class sentinel_squasher class sentinel_squasher: """ The heart of the script. Creates files without sentinels from files with sentinels. Propagates changes in the files without sentinels back to the files with sentinels. """ @others #@nonl #@+node:EKR.20040505090056.2:report_mismatch # was check_lines_for_equality def report_mismatch (self,lines1,lines2,message,lines1_message,lines2_message): """ Generate a report when something goes wrong. """ print '='*20 print message if 0: print lines1_message print '-'*20 for line in lines1: print line, print '='*20 print lines2_message print '-'*20 for line in lines2: print line, print "length of files",len(lines1),len(lines2) if len(lines1) == len(lines2): i = 0 while 1: if lines1[i] != lines2[i]: print "first mismatched lines:" print lines1[i] print lines2[i] break i += 1 #@nonl #@-node:EKR.20040505090056.2:report_mismatch #@+node:EKR.20040505090056.3:create_mapping def create_mapping (self,lines,marker): """ 'lines' is a list of lines of a file with sentinels. Returns: result: lines with all sentinels removed. mapping: a list such that result[mapping[i]] == lines[i] for all i in range(len(result)) """ mapping = [] ; result = [] for i in xrange(len(lines)): line = lines[i] if not is_sentinel(line,marker): result.append(line) mapping.append(i) # Create a last mapping entry for copy_sentinels. mapping.append(i) return result, mapping #@nonl #@-node:EKR.20040505090056.3:create_mapping #@+node:EKR.20040505090056.4:old code #@+node:EKR.20040505090056.5:OLDcopy_sentinels @ Sentinels are NEVER deleted by this script. If code is replaced, or deleted, then we must make sure that the sentinels are still in the Leo file. We detect sentinel lines by checking for gaps in the mapping. @c def OLDcopy_sentinels (self,writer,leo_reader,mapping,startline,endline): """ Copy lines from leo_reader to writer if those lines contain sentinels. Copy all sentinels after the current reader postion up to, but not including, mapping[endline]. """ j_last = mapping[startline] i = startline + 1 while i <= endline: j = mapping[i] if j_last + 1 != j: leo_reader.sync(j_last + 1) # Copy the deleted sentinels that comprise the gap. while leo_reader.index() < j: line = leo_reader.get() if testing: print "Copy sentinels:", line, writer.push(line) j_last = j ; i += 1 leo_reader.sync(mapping[endline]) #@nonl #@-node:EKR.20040505090056.5:OLDcopy_sentinels #@+node:EKR.20040505090056.6:OLDpull_source def pull_source(self, sourcefile, targetfile): """ Propagate the changes of targetfile back to sourcefile. sourcefile has sentinels, and targetfile does not. This is the heart of the script. """ print testing if testing: g.trace(sourcefile,targetfile) << init pull_source vars >> << establish the loop invariant >> for tag, i1, i2, j1, j2 in matcher.get_opcodes(): if testing: print ; print "opcode",tag,i1,i2,j1,j2 ; print << update and check the loop invariant >> if tag == 'equal': << handle 'equal' tag >> elif tag == 'replace': << handle 'replace' tag >> elif tag == 'delete': << handle 'delete' tag >> elif tag == 'insert': << handle 'insert' tag >> else: assert 0 << copy the sentinels at the end of the file >> written = write_if_changed(writer.getlines(),targetfile,sourcefile) if written: <> #@+node:EKR.20040505090056.7:<< init pull_source vars >> marker = marker_from_extension(sourcefile) # The sentinel comment marker. sourcelines = file(sourcefile).readlines() # Has sentinels. targetlines = file(targetfile).readlines() # No sentinels. strippedSourceLines,mapping = self.create_mapping(sourcelines,marker) writer = sourcewriter() # Accumulates the new file. i_reader = sourcereader(strippedSourceLines) # Unmodified file, no sentinels. j_reader = sourcereader(targetlines) # Modified file, no sentinels. leo_reader = sourcereader(sourcelines) # The file with sentinels. matcher = difflib.SequenceMatcher(None,strippedSourceLines,targetlines) #@nonl #@-node:EKR.20040505090056.7:<< init pull_source vars >> #@+node:EKR.20040505090056.8:<> @ We compare the 'targetlines' with 'strippedSourceLines' and propagate the changes back into 'writer' while making sure that all sentinels of 'sourcelines' are copied as well. The loop invariant is that all three readers are in sync. Also, writer has accumulated the new file, which is going to replace leo_reader. @c # Check that all ranges returned by get_opcodes() are contiguous i2_old = j2_old = -1 # Copy the sentinels at the beginning of the file. while leo_reader.index() < mapping[0]: line = leo_reader.get() writer.push(line) #@nonl #@-node:EKR.20040505090056.8:<> #@+node:EKR.20040505090056.9:<< update and check the loop invariant>> # We need the ranges returned by get_opcodes to completely cover the source lines being compared. # We also need the ranges not to overlap. if i2_old != -1: assert i2_old == i1 assert j2_old == j1 i2_old = i2 ; j2_old = j2 @ Loosely speaking, the loop invariant is that we have processed everything up to, but not including, the lower bound of the ranges returned by the iterator. We have to check the three readers, i_reader, j_reader, and leo_reader. For the writer, the filter must reproduce the modified file up until, but not including, j1. In addition, all the sentinels of the original Leo file, up until mapping[i1], must be present in the new_source_file. @code # Check the loop invariant. assert i_reader.i == i1 assert j_reader.i == j1 assert leo_reader.i == mapping[i1] if testing: # A bit costly. t_sourcelines,t_sentinel_lines = push_filter_lines(writer.lines, marker) # Check that we have all the modifications so far. assert t_sourcelines == j_reader.lines[:j1] # Check that we kept all sentinels so far. assert t_sentinel_lines == push_filter_lines(leo_reader.lines[:leo_reader.i], marker)[1] #@nonl #@-node:EKR.20040505090056.9:<< update and check the loop invariant>> #@+node:EKR.20040505090056.10:<< handle 'equal' tag >> # nothing is to be done. Leave the Leo file alone. # Copy the lines from the leo file to the new sourcefile. # This loop copies both text and sentinels. while leo_reader.index() <= mapping[i2 - 1]: line = leo_reader.get() if 0: if testing: print "Equal: ", line, writer.push(line) if testing: print "Equal: synch i", i_reader.i, i2 print "Equal: synch j", j_reader.i, j2 i_reader.sync(i2) j_reader.sync(j2) # now we must copy the sentinels which might follow the lines which were equal. self.copy_sentinels(writer,leo_reader,mapping, i2 - 1, i2) #@nonl #@-node:EKR.20040505090056.10:<< handle 'equal' tag >> #@+node:EKR.20040505090056.11:<< handle 'replace' tag >> @ Replace lines that may span sentinels. For now, we put all the new contents after the first sentinels. A more complex approach: run the difflib across the different lines and try to construct a mapping changed line => orignal line. @c while j_reader.index() < j2: line = j_reader.get() if testing: print "Replace:", line, writer.push(line) # Copy the sentinels which might be between the changed code. self.copy_sentinels(writer,leo_reader,mapping,i1,i2) i_reader.sync(i2) #@nonl #@-node:EKR.20040505090056.11:<< handle 'replace' tag >> #@+node:EKR.20040505090056.12:<< handle 'delete' tag >> # We have to delete lines. # However, we NEVER delete sentinels, so they must be copied over. if testing: print "Delete: synch i", i_reader.i, i1 print "Delete: synch j", j_reader.i, j1 # sync the readers j_reader.sync(j2) i_reader.sync(i2) self.copy_sentinels(writer, leo_reader, mapping, i1, i2) #@nonl #@-node:EKR.20040505090056.12:<< handle 'delete' tag >> #@+node:EKR.20040505090056.13:<< handle 'insert' tag >> while j_reader.index() < j2: line = j_reader.get() if testing: print "insert: ", line, writer.push(line) # Since (only) lines are inserted, we do not have to reposition any reader. #@nonl #@-node:EKR.20040505090056.13:<< handle 'insert' tag >> #@+node:EKR.20040505090056.14:<< copy the sentinels at the end of the file >> while leo_reader.index() < leo_reader.size(): line = leo_reader.get() writer.push(line) if testing: print "Copy last line",line #@nonl #@-node:EKR.20040505090056.14:<< copy the sentinels at the end of the file >> #@+node:EKR.20040505090056.15:<> @ For the initial usage, we check that the output actually makes sense. We check two things: 1. Applying a 'push' operation will produce the modified file. 2. Our new sourcefile still has the same sentinels as the replaced one. @c s_outlines,sentinel_lines = push_filter(sourcefile) # Check that 'push' will re-create the changed file. if s_outlines != targetlines: self.report_mismatch(s_outlines, targetlines, "Pull did not work as expected", "Content of sourcefile:", "Content of modified file:") # Check that no sentinels got lost. old_sentinel_lines = push_filter_lines(leo_reader.lines[:leo_reader.i], marker)[1] if sentinel_lines != old_sentinel_lines: self.report_mismatch(sentinel_lines, old_sentinel_lines, "Pull modified sentinel lines:", "Current sentinel lines:", "Old sentinel lines:") #@nonl #@-node:EKR.20040505090056.15:<> #@-node:EKR.20040505090056.6:OLDpull_source #@-node:EKR.20040505090056.4:old code #@+node:EKR.20040505090056.16:pull_source def pull_source(self,sourcefile,targetfile): """ Propagate the changes of targetfile back to sourcefile. sourcefile has sentinels, and targetfile does not. """ if testing: g.trace(sourcefile,targetfile) << init pull_source vars >> << establish the loop invariant >> for tag, i1, i2, j1, j2 in matcher.get_opcodes(): if testing: print ; print "Opcode",tag,i1,i2,j1,j2 ; print << update and check the loop invariant >> if tag == 'equal': << handle 'equal' tag >> elif tag == 'replace': << handle 'replace' tag >> elif tag == 'delete': << handle 'delete' tag >> elif tag == 'insert': << handle 'insert' tag >> else: assert 0,"bad tag" << copy the sentinels at the end of the file >> written = write_if_changed(write_lines,targetfile,sourcefile) if written: <> #@+node:EKR.20040505090056.17:<< init pull_source vars >> marker = marker_from_extension(sourcefile) # The sentinel comment marker. sourceLines = file(sourcefile).readlines() # Has sentinels. targetLines = file(targetfile).readlines() # No sentinels. strippedSourceLines,mapping = self.create_mapping(sourceLines,marker) write_lines = [] i_lines = strippedSourceLines j_lines = targetLines fat_lines = sourceLines i_pos = j_pos = fat_pos = 0 matcher = difflib.SequenceMatcher(None,strippedSourceLines,targetLines) #@nonl #@-node:EKR.20040505090056.17:<< init pull_source vars >> #@+node:EKR.20040505090056.18:<> @ We compare the 'targetLines' with 'strippedSourceLines' and propagate the changes back into 'write_lines' while making sure that all sentinels of 'sourceLines' are copied as well. @c # Check that all ranges returned by get_opcodes() are contiguous i2_old = j2_old = -1 # Copy the sentinels at the beginning of the file. while fat_pos < mapping[0]: line = fat_lines[fat_pos] write_lines.append(line) if testing: print "copy initial line",fat_pos,line fat_pos += 1 #@nonl #@-node:EKR.20040505090056.18:<> #@+node:EKR.20040505090056.19:<< update and check the loop invariant>> # We need the ranges returned by get_opcodes to completely cover the source lines being compared. # We also need the ranges not to overlap. if i2_old != -1: assert i2_old == i1,"i2_old==i1" assert j2_old == j1,"j2_old==j1" i2_old = i2 ; j2_old = j2 # Check the loop invariants. assert i_pos == i1,"i_pos==i1" assert j_pos == j1,"j_pos==j1" assert fat_pos == mapping[i1],"fat_pos == mapping[i1]" if 0: # not yet. if testing: # A bit costly. t_sourcelines,t_sentinel_lines = push_filter_lines(write_lines, marker) # Check that we have all the modifications so far. assert t_sourcelines == j_lines[:j1],"t_sourcelines == j_lines[:j1]" # Check that we kept all sentinels so far. assert t_sentinel_lines == push_filter_lines(fat_lines[:fat_pos], marker)[1] #@nonl #@-node:EKR.20040505090056.19:<< update and check the loop invariant>> #@+node:EKR.20040505090056.20:<< handle 'equal' tag >> # nothing is to be done. Leave the Leo file alone. # Copy the lines from the leo file to the new sourcefile. # This loop copies both text and sentinels. # while leo_reader.index() <= mapping[i2 - 1]: while fat_pos <= mapping[i2-1]: line = fat_lines[fat_pos] if 0: if testing: print "Equal: copying ", line, write_lines.append(line) # writer.push(line) fat_pos += 1 if testing: print "Equal: synch i", i_pos,i2 print "Equal: synch j", j_pos,j2 i_pos = i2 j_pos = j2 # Copy the sentinels which might follow the lines. fat_pos = self.copy_sentinels(write_lines,fat_lines,fat_pos,mapping,i2-1,i2) #@nonl #@-node:EKR.20040505090056.20:<< handle 'equal' tag >> #@+node:EKR.20040505090056.21:<< handle 'replace' tag >> @ Replace lines that may span sentinels. For now, we put all the new contents after the first sentinels. A more complex approach: run the difflib across the different lines and try to construct a mapping changed line => orignal line. @c while j_pos < j2: line = j_lines[j_pos] if testing: print "Replace:", line, write_lines.append(line) j_pos += 1 # Copy the sentinels which might be between the changed code. fat_pos = self.copy_sentinels(write_lines,fat_lines,fat_pos,mapping,i1,i2) i_pos = i2 #@nonl #@-node:EKR.20040505090056.21:<< handle 'replace' tag >> #@+node:EKR.20040505090056.22:<< handle 'delete' tag >> if testing: print "delete: i",i_pos,i1 print "delete: j",j_pos,j1 # Synch the import streams. j_pos = j2 i_pos = i2 # Restore any deleted sentinels. fat_pos = self.copy_sentinels(write_lines,fat_lines,fat_pos,mapping,i1,i2) #@nonl #@-node:EKR.20040505090056.22:<< handle 'delete' tag >> #@+node:EKR.20040505090056.23:<< handle 'insert' tag >> while j_pos < j2: line = j_lines[j_pos] if testing: print "Insert:", line, write_lines.append(line) j_pos += 1 # We do not have to reposition any input stream. #@nonl #@-node:EKR.20040505090056.23:<< handle 'insert' tag >> #@+node:EKR.20040505090056.24:<< copy the sentinels at the end of the file >> while fat_pos < len(fat_lines): line = fat_lines[fat_pos] write_lines.append(line) if testing: print "appending last line",line fat_pos += 1 #@nonl #@-node:EKR.20040505090056.24:<< copy the sentinels at the end of the file >> #@+node:EKR.20040505090056.25:<> # Check that 'push' will re-create the changed file. strippedLines,sentinel_lines = push_filter(sourcefile) if strippedLines != targetLines: self.report_mismatch(strippedLines, targetLines, "Pull did not work as expected", "Content of sourcefile:", "Content of modified file:") # Check that no sentinels got lost. old_strippedLines,old_sentinel_lines = push_filter_lines(sourceLines, marker) if sentinel_lines != old_sentinel_lines: self.report_mismatch(sentinel_lines, old_sentinel_lines, "Pull modified sentinel lines:", "Current sentinel lines:", "Old sentinel lines:") #@nonl #@-node:EKR.20040505090056.25:<> #@-node:EKR.20040505090056.16:pull_source #@+node:EKR.20040505090056.26:copy_sentinels @ This script retains _all_ sentinels in the fat file. If lines are replaced, or deleted, we restore deleted sentinel lines by checking for gaps in the mapping. @c def copy_sentinels (self,write_lines,fat_lines,fat_pos,mapping,startline,endline): """ Copy sentinel lines from fat_lines to write_lines. Copy all sentinels _after_ the current reader postion up to, but not including, mapping[endline]. """ j_last = mapping[startline] i = startline + 1 while i <= endline: j = mapping[i] if j_last + 1 != j: fat_pos = j_last + 1 # Copy the deleted sentinels that comprise the gap. while fat_pos < j: line = fat_lines[fat_pos] write_lines.append(line) if testing: print "Copy sentinels:",fat_pos,line, fat_pos += 1 j_last = j ; i += 1 fat_pos = mapping[endline] return fat_pos #@nonl #@-node:EKR.20040505090056.26:copy_sentinels #@-node:EKR.20040505090056.1:class sentinel_squasher #@+node:EKR.20040505090056.27:class sourcereader class sourcereader: """ A simple class to read lines sequentially. The class keeps an internal index, so that each call to get returns the next line. Index returns the internal index, and sync advances the index to the the desired line. The index is the *next* line to be returned. The line numbering starts from 0. """ @others #@+node:EKR.20040505090056.28:__init__ def __init__(self, lines): self.lines = lines self.length = len(self.lines) self.i = 0 #@-node:EKR.20040505090056.28:__init__ #@+node:EKR.20040505090056.29:index def index(self): return self.i #@-node:EKR.20040505090056.29:index #@+node:EKR.20040505090056.30:get def get(self): result = self.lines[self.i] self.i += 1 return result #@nonl #@-node:EKR.20040505090056.30:get #@+node:EKR.20040505090056.31:sync def sync(self, i): self.i = i #@-node:EKR.20040505090056.31:sync #@+node:EKR.20040505090056.32:size def size(self): return self.length #@-node:EKR.20040505090056.32:size #@+node:EKR.20040505090056.33:atEnd def atEnd(self): return self.index >= self.length #@nonl #@-node:EKR.20040505090056.33:atEnd #@-node:EKR.20040505090056.27:class sourcereader #@+node:EKR.20040505090056.34:class sourcewriter class sourcewriter: """ Convenience class to capture output to a file. """ @others #@+node:EKR.20040505090056.35:__init__ def __init__(self): self.i = 0 self.lines = [] #@-node:EKR.20040505090056.35:__init__ #@+node:EKR.20040505090056.36:push def push(self, line): self.lines.append(line) self.i += 1 #@-node:EKR.20040505090056.36:push #@+node:EKR.20040505090056.37:index def index(self): return self.i #@-node:EKR.20040505090056.37:index #@+node:EKR.20040505090056.38:getlines def getlines(self): return self.lines #@-node:EKR.20040505090056.38:getlines #@-node:EKR.20040505090056.34:class sourcewriter #@+node:EKR.20040505090056.39:copy_time def copy_time(sourcefilename, targetfilename): """ Set the modification time of target file to the modification time of sourcefile. """ st = os.stat(sourcefilename) if hasattr(os, 'utime'): os.utime(targetfilename, (st.st_atime, st.st_mtime)) elif hasattr(os, 'mtime'): os.mtime(targetfilename, st.st_mtime) else: print "copy_time can not set file modification time." #@nonl #@-node:EKR.20040505090056.39:copy_time #@+node:EKR.20040505090056.40:create_ext def create_ext(extensions=('.py', '.c', '.cpp', '.h', '.bat'), directory=".", sourcedir=None): """ Convenience script: calls create_leo_subdirectory for all files in 'directory' with an extension in 'extensions'. NOTE THAT IF BOTH A DIRECTORY AND A SOURCEDIR ARE SPECIFIED, THIS SCRIPT WILL DELETE THE WHOLE DIRECTORY 'directory'. """ if sourcedir: # For quick testing, we make a copy of a directory. if os.path.exists(directory): shutil.rmtree(directory) shutil.copytree(sourcedir, directory) # Not sure if this is necessary, but let's delete all .pyc files map(os.unlink, [os.path.join(root, filename) for root, dirs, files in os.walk(directory) for filename in files if os.path.splitext(filename)[1] == '.pyc']) files = [f for f in os.listdir(directory) if os.path.splitext(f)[1] in extensions] create_leo_subdirectory (files, directory) #@nonl #@-node:EKR.20040505090056.40:create_ext #@+node:EKR.20040505090056.41:create_leo_subdirectory def create_leo_subdirectory(files, directory="."): """ Moves 'files' into a Leo subdirectory. 'files' are replaced with files without sentinels. files is the list of files which should be shuffled to the subdirectory. - Checks if a Leo subdirectory exists. If yes, does nothing. - Moves the files to the Leo subdirectory. - Creates files without sentinels in the original directory. """ from os.path import exists, join, split, splitext assert exists(directory) targetfiles = [join(directory,element) for element in files] missing_files = [filename for filename in targetfiles if not exists(filename)] assert len(missing_files) == 0,"Files do not exist:%s" % missing_files leo_directory = join(directory, "Leo") if exists(leo_directory): print "Directory already exists. Exit" return os.mkdir(leo_directory) pairs = [split(filename) for filename in targetfiles] sourcefiles = [join(dir, 'Leo', name) for dir, name in pairs] full_filenames = zip(sourcefiles, targetfiles) for targetfile, sourcefile in full_filenames: os.rename(sourcefile, targetfile) push(full_filenames) #@-node:EKR.20040505090056.41:create_leo_subdirectory #@+node:EKR.20040505090056.42:is_sentinel def is_sentinel(line, marker): """ Check if line starts with a Leo marker. Leo markers are filtered away by this script. Leo markers start with a comment character, which dependends on the language used. That's why the marker is passed in. """ return line.lstrip().startswith(marker) #@nonl #@-node:EKR.20040505090056.42:is_sentinel #@+node:EKR.20040505090056.43:marker_from_extension def marker_from_extension(filename): """ Tries to guess the sentinel leadin comment from the filename extension. This code should probably be shared with the main Leo code. """ root, ext = os.path.splitext(filename) if ext == '.tmp': root, ext = os.path.splitext(root) if ext in ('.h', '.c'): marker = "//@" elif ext in (".py", ".cfg", ".bat", ".ksh"): marker = "#@" else: assert 0, "extension %s not handled by this plugin" % ext return marker #@nonl #@-node:EKR.20040505090056.43:marker_from_extension #@+node:EKR.20040505090056.44:push_file def push_file(sourcefilename, targetfilename): outlines, sentinel_lines = push_filter(sourcefilename) write_if_changed(outlines, sourcefilename, targetfilename) #@nonl #@-node:EKR.20040505090056.44:push_file #@+node:EKR.20040505090056.45:push_filter def push_filter(sourcefilename): """ Removes sentinels from the lines of 'sourcefilename'. """ return push_filter_lines( file(sourcefilename).readlines(), marker_from_extension(sourcefilename)) #@-node:EKR.20040505090056.45:push_filter #@+node:EKR.20040505090056.46:push_filter_lines def push_filter_lines(lines, marker): """ Removes sentinels from lines. """ result = [] ; sentinel_lines = [] for line in lines: if is_sentinel(line, marker): sentinel_lines.append(line) else: result.append(line) return result, sentinel_lines #@nonl #@-node:EKR.20040505090056.46:push_filter_lines #@+node:EKR.20040505090056.47:write_if_changed def write_if_changed(lines, sourcefilename, targetfilename): """ Replaces target file if it is not the same as 'lines', and makes the modification date of target file the same as the source file. Optionally backs up the overwritten file. """ copy = not os.path.exists(targetfilename) or lines != file(targetfilename).readlines() if testing: if copy: print "Copying", sourcefilename, "to", targetfilename, "without sentinals" else: print "files are identical" if copy: if do_backups: << make backup file >> outfile = open(targetfilename, "w") for line in lines: outfile.write(line) outfile.close() copy_time(sourcefilename,targetfilename) return copy #@+node:EKR.20040505090056.48:<< make backup file >> # Keep the old file around while we are debugging this script if os.path.exists(targetfilename): count = 0 backupname = "%s.~%s~" % (targetfilename, count) while os.path.exists(backupname): count += 1 backupname = "%s.~%s~" % (targetfilename, count) os.rename(targetfilename, backupname) if testing: print "backup file in ", backupname #@nonl #@-node:EKR.20040505090056.48:<< make backup file >> #@-node:EKR.20040505090056.47:write_if_changed #@-node:EKR.20040505090056:From perfect import script #@+node:ekr.20040301201418:c.convertTreeToSharedNodes (for conversion) # WARNING: this only works if not g.sharedNodes. def convertTreeToSharedNodes(self): c = self # Return if the tree has already been converted. v = c.rootVnode() while v: if v._firstChild and not v._firstChild._parent: # print ; print "already converted" return v = v.threadNext() # Init. v = c.rootVnode() while v: v.t.vnodeList = [] v = v.threadNext() # Create a list of cloned nodes: v = c.rootVnode() ; cloneList = [] while v: if v.isCloned(): # print "clone",v cloneList.append(v) v = v.threadNext() # Set _firstChild in tnodes. v = c.rootVnode() while v: child = v.firstChild() # Careful: set the field only the first time we see a shared tree. # This logic must match the logic below. if child: if not hasattr(v.t,"_firstChild"): v.t._firstChild = child else: v.t._firstChild = None v = v.threadNext() v = c.rootVnode() while v: if child and not hasattr(v.t,"_firstChild"): v.t._firstChild = child v = v.threadNext() # Set v.t.vnodeList. v = c.rootVnode() while v: # Careful: only set one value for non-cloned joined nodes. if v in cloneList: # Cloned try: v.t.vnodeList.append(v) except: v.t.vnodeList = [v] elif not hasattr(v.t,"vnodeList"): # Maybe joined. v.t.vnodeList = [v] v = v.threadNext() # Clear _parent field of any node whose parent is a clone. v = c.rootVnode() ; clearList = [] for v in cloneList: child = v.firstChild() while child: clearList.append(child) child = child.next() for v in clearList: v._parent = None #@nonl #@-node:ekr.20040301201418:c.convertTreeToSharedNodes (for conversion) #@+node:ekr.20031218072017.3380:v.edit_text def edit_text (self): v = self ; c = v.c ; p = c.currentPosition() g.trace("ooooops") #import traceback ; traceback.print_stack() pairs = self.c.frame.tree.getEditTextDict(v) for p2,t2 in pairs: if p.equal(p2): # g.trace("found",t2) return t2 return None #@nonl #@-node:ekr.20031218072017.3380:v.edit_text #@-node:ekr.20031218072017.434:Unused code #@-all #@nonl #@-node:ekr.20031218072017.329:@thin ../doc/leoNotes.txt #@-leo